MythTV  master
H2645Parser.cpp
Go to the documentation of this file.
1 // MythTV headers
2 #include "H2645Parser.h"
3 #include <iostream>
4 
6 #include "recorders/dtvrecorder.h" // for FrameRate and ScanType
7 #include "bitreader.h"
8 
9 #include <cmath>
10 #include <strings.h>
11 
12 /*
13  Most of the comments below were cut&paste from ITU-T Rec. H.264
14  as found here: http://www.itu.int/rec/T-REC-H.264/e
15  */
16 
17 /*
18  Useful definitions:
19 
20  * access unit: A set of NAL units always containing exactly one
21  primary coded picture. In addition to the primary coded picture, an
22  access unit may also contain one or more redundant coded pictures
23  or other NAL units not containing slices or slice data partitions
24  of a coded picture. The decoding of an access unit always results
25  in a decoded picture.
26 
27  * instantaneous decoding refresh (IDR) access unit: An access unit in
28  which the primary coded picture is an IDR picture.
29 
30  * instantaneous decoding refresh (IDR) picture: A coded picture
31  containing only slices with I or SI slice types that causes the
32  decoding process to mark all reference pictures as "unused for
33  reference" immediately after decoding the IDR picture. After the
34  decoding of an IDR picture all following coded pictures in decoding
35  order can be decoded without inter prediction from any picture
36  decoded prior to the IDR picture. The first picture of each coded
37  video sequence is an IDR picture.
38 
39  * NAL unit: A syntax structure containing an indication of the type
40  of data to follow and bytes containing that data in the form of an
41  RBSP interspersed as necessary with emulation prevention bytes.
42 
43  * raw byte sequence payload (RBSP): A syntax structure containing an
44  integer number of bytes that is encapsulated in a NAL unit. An RBSP
45  is either empty or has the form of a string of data bits containing
46  syntax elements followed by an RBSP stop bit and followed by zero
47  or more subsequent bits equal to 0.
48 
49  * raw byte sequence payload (RBSP) stop bit: A bit equal to 1 present
50  within a raw byte sequence payload (RBSP) after a string of data
51  bits. The location of the end of the string of data bits within an
52  RBSP can be identified by searching from the end of the RBSP for
53  the RBSP stop bit, which is the last non-zero bit in the RBSP.
54 
55  * parity: The parity of a field can be top or bottom.
56 
57  * picture: A collective term for a field or a frame.
58 
59  * picture parameter set: A syntax structure containing syntax
60  elements that apply to zero or more entire coded pictures as
61  determined by the m_picParameterSetId syntax element found in each
62  slice header.
63 
64  * primary coded picture: The coded representation of a picture to be
65  used by the decoding process for a bitstream conforming to this
66  Recommendation | International Standard. The primary coded picture
67  contains all macroblocks of the picture. The only pictures that
68  have a normative effect on the decoding process are primary coded
69  pictures. See also redundant coded picture.
70 
71  * VCL: Video Coding Layer
72 
73  - The VCL is specified to efficiently represent the content of the
74  video data. The NAL is specified to format that data and provide
75  header information in a manner appropriate for conveyance on a
76  variety of communication channels or storage media. All data are
77  contained in NAL units, each of which contains an integer number of
78  bytes. A NAL unit specifies a generic format for use in both
79  packet-oriented and bitstream systems. The format of NAL units for
80  both packet-oriented transport and byte stream is identical except
81  that each NAL unit can be preceded by a start code prefix and extra
82  padding bytes in the byte stream format.
83 
84 */
85 
87  : m_rbspBuffer(new uint8_t[m_rbspBufferSize])
88 {
89  if (m_rbspBuffer == nullptr)
90  m_rbspBufferSize = 0;
91 }
92 
94 {
95  m_stateChanged = false;
96  m_seenSPS = false;
97  m_isKeyframe = false;
98  m_spsOffset = 0;
99 
100  m_syncAccumulator = 0xffffffff;
101  m_auPending = false;
102 
103  m_picWidth = 0;
104  m_picHeight = 0;
109  m_aspectRatioIdc = 0;
110  m_sarWidth = 0;
111  m_sarHeight = 0;
112  m_unitsInTick = 0;
113  m_timeScale = 0;
114  m_fixedRate = false;
115 
116  m_pktOffset = 0;
117  m_auOffset = 0;
118  m_frameStartOffset = 0;
120  m_onFrame = false;
121  m_onKeyFrame = false;
122 
123  m_chromaFormatIdc = 1;
125 }
126 
128 {
129  m_rbspIndex = 0;
130  m_consecutiveZeros = 0;
131  m_haveUnfinishedNAL = false;
132 }
133 
134 bool H2645Parser::fillRBSP(const uint8_t *byteP, uint32_t byte_count,
135  bool found_start_code)
136 {
137  uint32_t required_size = m_rbspIndex + byte_count;
138  if (m_rbspBufferSize < required_size)
139  {
140  // Round up to packet size
141  required_size = ((required_size / 188) + 1) * 188;
142 
143  /* Need a bigger buffer */
144  auto *new_buffer = new uint8_t[required_size];
145 
146  if (new_buffer == nullptr)
147  {
148  /* Allocation failed. Discard the new bytes */
149  LOG(VB_GENERAL, LOG_ERR,
150  "H2645Parser::fillRBSP: FAILED to allocate RBSP buffer!");
151  return false;
152  }
153 
154  /* Copy across bytes from old buffer */
155  memcpy(new_buffer, m_rbspBuffer, m_rbspIndex);
156  delete [] m_rbspBuffer;
157  m_rbspBuffer = new_buffer;
158  m_rbspBufferSize = required_size;
159  }
160 
161 /*
162  NumBytesInNalUnit is set equal to the number of bytes starting
163  with the byte at the current position in the byte stream up to and
164  including the last byte that precedes the location of one or more
165  of the following conditions:
166  – A subsequent byte-aligned three-byte sequence equal to 0x000000,
167  – A subsequent byte-aligned three-byte sequence equal to 0x000001,
168 */
169 
170 
171  /* Fill rbsp while we have data */
172  while (byte_count)
173  {
174  /* Copy the byte into the rbsp, unless it
175  * is the 0x03 in a 0x000003 */
176  if (m_consecutiveZeros < 2 || *byteP != 0x03)
177  m_rbspBuffer[m_rbspIndex++] = *byteP;
178 
179  if (*byteP == 0)
181  else
182  m_consecutiveZeros = 0;
183 
184  ++byteP;
185  --byte_count;
186  }
187 
188  /* If we've found the next start code then that, plus the first byte of
189  * the next NAL, plus the preceding zero bytes will all be in the rbsp
190  * buffer. Move rbsp_index back to the end of the actual rbsp data. We
191  * need to know the correct size of the rbsp to decode some NALs.
192  */
193  if (found_start_code)
194  {
195  if (m_rbspIndex >= 4)
196  {
197  m_rbspIndex -= 4;
198  while (m_rbspIndex > 0 && m_rbspBuffer[m_rbspIndex - 1] == 0)
199  --m_rbspIndex;
200  }
201  else
202  {
203  /* This should never happen. */
204  LOG(VB_GENERAL, LOG_ERR,
205  QString("H2645Parser::fillRBSP: Found start code, rbsp_index "
206  "is %1 but it should be >4")
207  .arg(m_rbspIndex));
208  }
209  }
210 
211  return true;
212 }
213 
214 /* Video Usability Information */
216 {
217  /*
218  aspect_ratio_info_present_flag equal to 1 specifies that
219  m_aspectRatioIdc is present. aspect_ratio_info_present_flag
220  equal to 0 specifies that m_aspectRatioIdc is not present.
221  */
222  if (br.next_bit()) //aspect_ratio_info_present_flag
223  {
224  /*
225  m_aspectRatioIdc specifies the value of the sample aspect
226  ratio of the luma samples. Table E-1 shows the meaning of
227  the code. When m_aspectRatioIdc indicates Extended_SAR, the
228  sample aspect ratio is represented by m_sarWidth and
229  m_sarHeight. When the m_aspectRatioIdc syntax element is not
230  present, m_aspectRatioIdc value shall be inferred to be
231  equal to 0.
232  */
233  m_aspectRatioIdc = br.get_bits(8);
234 
235  switch (m_aspectRatioIdc)
236  {
237  case 0: // NOLINT(bugprone-branch-clone)
238  // Unspecified
239  break;
240  case 1:
241  // 1:1
242  /*
243  1280x720 16:9 frame without overscan
244  1920x1080 16:9 frame without overscan (cropped from 1920x1088)
245  640x480 4:3 frame without overscan
246  */
247  break;
248  case 2:
249  // 12:11
250  /*
251  720x576 4:3 frame with horizontal overscan
252  352x288 4:3 frame without overscan
253  */
254  break;
255  case 3:
256  // 10:11
257  /*
258  720x480 4:3 frame with horizontal overscan
259  352x240 4:3 frame without overscan
260  */
261  break;
262  case 4:
263  // 16:11
264  /*
265  720x576 16:9 frame with horizontal overscan
266  540x576 4:3 frame with horizontal overscan
267  */
268  break;
269  case 5:
270  // 40:33
271  /*
272  720x480 16:9 frame with horizontal overscan
273  540x480 4:3 frame with horizontal overscan
274  */
275  break;
276  case 6:
277  // 24:11
278  /*
279  352x576 4:3 frame without overscan
280  540x576 16:9 frame with horizontal overscan
281  */
282  break;
283  case 7:
284  // 20:11
285  /*
286  352x480 4:3 frame without overscan
287  480x480 16:9 frame with horizontal overscan
288  */
289  break;
290  case 8:
291  // 32:11
292  /*
293  352x576 16:9 frame without overscan
294  */
295  break;
296  case 9:
297  // 80:33
298  /*
299  352x480 16:9 frame without overscan
300  */
301  break;
302  case 10:
303  // 18:11
304  /*
305  480x576 4:3 frame with horizontal overscan
306  */
307  break;
308  case 11:
309  // 15:11
310  /*
311  480x480 4:3 frame with horizontal overscan
312  */
313  break;
314  case 12:
315  // 64:33
316  /*
317  540x576 16:9 frame with horizontal overscan
318  */
319  break;
320  case 13:
321  // 160:99
322  /*
323  540x576 16:9 frame with horizontal overscan
324  */
325  break;
326  case kExtendedSar:
327  m_sarWidth = br.get_bits(16);
328  m_sarHeight = br.get_bits(16);
329  LOG(VB_RECORD, LOG_DEBUG,
330  QString("sarWidth %1 sarHeight %2")
331  .arg(m_sarWidth).arg(m_sarHeight));
332  break;
333  }
334  }
335  else
336  {
337  m_sarWidth = m_sarHeight = 0;
338  }
339 
340  if (br.next_bit()) //overscan_info_present_flag
341  br.next_bit(); //overscan_appropriate_flag
342 
343  if (br.next_bit()) //video_signal_type_present_flag
344  {
345  br.get_bits(3); //video_format
346  br.next_bit(); //video_full_range_flag
347  if (br.next_bit()) // colour_description_present_flag
348  {
349  br.get_bits(8); // colour_primaries
350  br.get_bits(8); // transfer_characteristics
351  br.get_bits(8); // matrix_coefficients
352  }
353  }
354 
355  if (br.next_bit()) //chroma_loc_info_present_flag
356  {
357  br.get_ue_golomb(); //chroma_sample_loc_type_top_field ue(v)
358  br.get_ue_golomb(); //chroma_sample_loc_type_bottom_field ue(v)
359  }
360 
361  if (hevc)
362  {
363  br.next_bit(); // get_neutral_chroma_indication_flag u(1)
364  br.next_bit(); // field_seq_flag u(1);
365  br.next_bit(); // frame_field_info_present_flag u(1);
366  if (br.next_bit()) { // default_display_window_flag u(1);
367  br.get_ue_golomb(); // def_disp_win_left_offset ue(v);
368  br.get_ue_golomb(); // def_disp_win_right_offset ue(v);
369  br.get_ue_golomb(); // def_disp_win_top_offset ue(v);
370  br.get_ue_golomb(); // def_disp_win_bottom_offset ue(v);
371  }
372  }
373 
374  if (br.next_bit()) //timing_info_present_flag
375  {
376  m_unitsInTick = br.get_bits(32); // num_units_in_tick
377  m_timeScale = br.get_bits(32); // time_scale
378  m_fixedRate = (br.get_bits(1) != 0U);
379 
380  LOG(VB_RECORD, LOG_DEBUG,
381  QString("VUI unitsInTick %1 timeScale %2 fixedRate %3")
382  .arg(m_unitsInTick)
383  .arg(m_timeScale)
384  .arg(m_fixedRate));
385  }
386 }
387 
389 {
390 
391  double aspect = 0.0;
392 
393  if (m_picHeight)
394  aspect = pictureWidthCropped() / (double)pictureHeightCropped();
395 
396  switch (m_aspectRatioIdc)
397  {
398  case 0: // Unspecified
399  case 1: // 1:1
400  break;
401  case 2:
402  // 12:11
403  aspect *= 1.0909090909090908;
404  break;
405  case 3:
406  // 10:11
407  aspect *= 0.90909090909090906;
408  break;
409  case 4:
410  // 16:11
411  aspect *= 1.4545454545454546;
412  break;
413  case 5:
414  // 40:33
415  aspect *= 1.2121212121212122;
416  break;
417  case 6:
418  // 24:11
419  aspect *= 2.1818181818181817;
420  break;
421  case 7:
422  // 20:11
423  aspect *= 1.8181818181818181;
424  break;
425  case 8:
426  // 32:11
427  aspect *= 2.9090909090909092;
428  break;
429  case 9:
430  // 80:33
431  aspect *= 2.4242424242424243;
432  break;
433  case 10:
434  // 18:11
435  aspect *= 1.6363636363636365;
436  break;
437  case 11:
438  // 15:11
439  aspect *= 1.3636363636363635;
440  break;
441  case 12:
442  // 64:33
443  aspect *= 1.9393939393939394;
444  break;
445  case 13:
446  // 160:99
447  aspect *= 1.6161616161616161;
448  break;
449  case 14:
450  // 4:3
451  aspect *= 1.3333333333333333;
452  break;
453  case 15:
454  // 3:2
455  aspect *= 1.5;
456  break;
457  case 16:
458  // 2:1
459  aspect *= 2.0;
460  break;
461  case kExtendedSar:
462  if (m_sarHeight)
463  aspect *= m_sarWidth / (double)m_sarHeight;
464  else
465  aspect = 0.0;
466  break;
467  }
468 
469  // TODO use an integer-based Rational number instead of floating point
470  static constexpr double eps = 1E-5;
471  if (aspect == 0.0)
472  return 0;
473  if (fabs(aspect - 1.3333333333333333) < eps)
474  return 2;
475  if (fabs(aspect - 1.7777777777777777) < eps)
476  return 3;
477  if (fabs(aspect - 2.21) < eps)
478  return 4;
479 
480  return aspect * 1000000;
481 }
H2645Parser::m_seenSPS
bool m_seenSPS
Definition: H2645Parser.h:151
H2645Parser::m_frameCropRightOffset
uint m_frameCropRightOffset
Definition: H2645Parser.h:132
H2645Parser::m_frameStartOffset
uint64_t m_frameStartOffset
Definition: H2645Parser.h:116
H2645Parser::fillRBSP
bool fillRBSP(const uint8_t *byteP, uint32_t byte_count, bool found_start_code)
Definition: H2645Parser.cpp:134
H2645Parser::m_separateColourPlaneFlag
bool m_separateColourPlaneFlag
Definition: H2645Parser.h:152
H2645Parser::m_sarWidth
uint m_sarWidth
Definition: H2645Parser.h:137
dtvrecorder.h
H2645Parser::m_keyframeStartOffset
uint64_t m_keyframeStartOffset
Definition: H2645Parser.h:117
H2645Parser::pictureWidthCropped
virtual uint pictureWidthCropped(void) const =0
H2645Parser::pictureHeightCropped
virtual uint pictureHeightCropped(void) const =0
H2645Parser::m_unitsInTick
uint32_t m_unitsInTick
Definition: H2645Parser.h:126
H2645Parser::m_picWidth
uint m_picWidth
Definition: H2645Parser.h:135
H2645Parser::m_pktOffset
uint64_t m_pktOffset
Definition: H2645Parser.h:118
H2645Parser::m_frameCropLeftOffset
uint m_frameCropLeftOffset
Definition: H2645Parser.h:131
H2645Parser::Reset
virtual void Reset(void)
Definition: H2645Parser.cpp:93
BitReader::get_bits
uint32_t get_bits(unsigned n)
Read 0-32 bits.
Definition: bitreader.h:86
H2645Parser::m_rbspBufferSize
uint32_t m_rbspBufferSize
Definition: H2645Parser.h:122
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
H2645Parser.h
H2645Parser::m_aspectRatioIdc
uint8_t m_aspectRatioIdc
Definition: H2645Parser.h:140
bitreader.h
H2645Parser::vui_parameters
void vui_parameters(BitReader &br, bool hevc)
Definition: H2645Parser.cpp:215
BitReader
Definition: bitreader.h:38
mythlogging.h
H2645Parser::m_rbspIndex
uint32_t m_rbspIndex
Definition: H2645Parser.h:123
H2645Parser::m_consecutiveZeros
uint32_t m_consecutiveZeros
Definition: H2645Parser.h:121
H2645Parser::m_fixedRate
bool m_fixedRate
Definition: H2645Parser.h:145
H2645Parser::m_frameCropBottomOffset
uint m_frameCropBottomOffset
Definition: H2645Parser.h:130
H2645Parser::m_rbspBuffer
uint8_t * m_rbspBuffer
Definition: H2645Parser.h:139
H2645Parser::m_auOffset
uint64_t m_auOffset
Definition: H2645Parser.h:115
H2645Parser::m_auPending
bool m_auPending
Definition: H2645Parser.h:144
H2645Parser::m_onKeyFrame
bool m_onKeyFrame
Definition: H2645Parser.h:150
uint
unsigned int uint
Definition: compat.h:81
H2645Parser::m_spsOffset
uint64_t m_spsOffset
Definition: H2645Parser.h:119
H2645Parser::m_stateChanged
bool m_stateChanged
Definition: H2645Parser.h:153
H2645Parser::m_timeScale
uint32_t m_timeScale
Definition: H2645Parser.h:125
H2645Parser::m_onFrame
bool m_onFrame
Definition: H2645Parser.h:149
H2645Parser::m_isKeyframe
bool m_isKeyframe
Definition: H2645Parser.h:147
H2645Parser::m_haveUnfinishedNAL
bool m_haveUnfinishedNAL
Definition: H2645Parser.h:146
H2645Parser::m_frameCropTopOffset
uint m_frameCropTopOffset
Definition: H2645Parser.h:133
H2645Parser::m_syncAccumulator
uint32_t m_syncAccumulator
Definition: H2645Parser.h:124
H2645Parser::m_chromaFormatIdc
int8_t m_chromaFormatIdc
Definition: H2645Parser.h:142
H2645Parser::aspectRatio
uint aspectRatio(void) const
Computes aspect ratio from picture size and sample aspect ratio.
Definition: H2645Parser.cpp:388
H2645Parser::m_picHeight
uint m_picHeight
Definition: H2645Parser.h:134
H2645Parser::m_sarHeight
uint m_sarHeight
Definition: H2645Parser.h:136
BitReader::next_bit
bool next_bit()
Definition: bitreader.h:84
H2645Parser::resetRBSP
void resetRBSP(void)
Definition: H2645Parser.cpp:127
BitReader::get_ue_golomb
int get_ue_golomb()
Read an unsigned Exp-Golomb code in the range 0 to 8190 (2^13 - 2).
Definition: bitreader.h:105
H2645Parser::H2645Parser
H2645Parser(void)
Definition: H2645Parser.cpp:86
H2645Parser::kExtendedSar
static constexpr uint8_t kExtendedSar
Definition: H2645Parser.h:103