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