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 {
88  m_rbspBuffer = new uint8_t[m_rbspBufferSize];
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 EXTENDED_SAR:
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  m_sarWidth = m_sarHeight = 0;
337 
338  if (br.next_bit()) //overscan_info_present_flag
339  br.next_bit(); //overscan_appropriate_flag
340 
341  if (br.next_bit()) //video_signal_type_present_flag
342  {
343  br.get_bits(3); //video_format
344  br.next_bit(); //video_full_range_flag
345  if (br.next_bit()) // colour_description_present_flag
346  {
347  br.get_bits(8); // colour_primaries
348  br.get_bits(8); // transfer_characteristics
349  br.get_bits(8); // matrix_coefficients
350  }
351  }
352 
353  if (br.next_bit()) //chroma_loc_info_present_flag
354  {
355  br.get_ue_golomb(); //chroma_sample_loc_type_top_field ue(v)
356  br.get_ue_golomb(); //chroma_sample_loc_type_bottom_field ue(v)
357  }
358 
359  if (hevc)
360  {
361  br.next_bit(); // get_neutral_chroma_indication_flag u(1)
362  br.next_bit(); // field_seq_flag u(1);
363  br.next_bit(); // frame_field_info_present_flag u(1);
364  if (br.next_bit()) { // default_display_window_flag u(1);
365  br.get_ue_golomb(); // def_disp_win_left_offset ue(v);
366  br.get_ue_golomb(); // def_disp_win_right_offset ue(v);
367  br.get_ue_golomb(); // def_disp_win_top_offset ue(v);
368  br.get_ue_golomb(); // def_disp_win_bottom_offset ue(v);
369  }
370  }
371 
372  if (br.next_bit()) //timing_info_present_flag
373  {
374  m_unitsInTick = br.get_bits(32); // num_units_in_tick
375  m_timeScale = br.get_bits(32); // time_scale
376  m_fixedRate = (br.get_bits(1) != 0U);
377 
378  LOG(VB_RECORD, LOG_DEBUG,
379  QString("VUI unitsInTick %1 timeScale %2 fixedRate %3")
380  .arg(m_unitsInTick)
381  .arg(m_timeScale)
382  .arg(m_fixedRate));
383  }
384 }
385 
387 {
388 
389  double aspect = 0.0;
390 
391  if (m_picHeight)
392  aspect = pictureWidthCropped() / (double)pictureHeightCropped();
393 
394  switch (m_aspectRatioIdc)
395  {
396  case 0: // Unspecified
397  case 1: // 1:1
398  break;
399  case 2:
400  // 12:11
401  aspect *= 1.0909090909090908;
402  break;
403  case 3:
404  // 10:11
405  aspect *= 0.90909090909090906;
406  break;
407  case 4:
408  // 16:11
409  aspect *= 1.4545454545454546;
410  break;
411  case 5:
412  // 40:33
413  aspect *= 1.2121212121212122;
414  break;
415  case 6:
416  // 24:11
417  aspect *= 2.1818181818181817;
418  break;
419  case 7:
420  // 20:11
421  aspect *= 1.8181818181818181;
422  break;
423  case 8:
424  // 32:11
425  aspect *= 2.9090909090909092;
426  break;
427  case 9:
428  // 80:33
429  aspect *= 2.4242424242424243;
430  break;
431  case 10:
432  // 18:11
433  aspect *= 1.6363636363636365;
434  break;
435  case 11:
436  // 15:11
437  aspect *= 1.3636363636363635;
438  break;
439  case 12:
440  // 64:33
441  aspect *= 1.9393939393939394;
442  break;
443  case 13:
444  // 160:99
445  aspect *= 1.6161616161616161;
446  break;
447  case 14:
448  // 4:3
449  aspect *= 1.3333333333333333;
450  break;
451  case 15:
452  // 3:2
453  aspect *= 1.5;
454  break;
455  case 16:
456  // 2:1
457  aspect *= 2.0;
458  break;
459  case EXTENDED_SAR:
460  if (m_sarHeight)
461  aspect *= m_sarWidth / (double)m_sarHeight;
462  else
463  aspect = 0.0;
464  break;
465  }
466 
467  // TODO use an integer-based Rational number instead of floating point
468  static constexpr double eps = 1E-5;
469  if (aspect == 0.0)
470  return 0;
471  if (fabs(aspect - 1.3333333333333333) < eps)
472  return 2;
473  if (fabs(aspect - 1.7777777777777777) < eps)
474  return 3;
475  if (fabs(aspect - 2.21) < eps)
476  return 4;
477 
478  return aspect * 1000000;
479 }
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::EXTENDED_SAR
static constexpr uint8_t EXTENDED_SAR
Definition: H2645Parser.h:103
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
strings.h
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:386
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