MythTV  master
H264Parser.h
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 /*******************************************************************
3  * H264Parser
4  *
5  * Distributed as part of MythTV (www.mythtv.org)
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  ********************************************************************/
22 
23 #ifndef H264PARSER_H
24 #define H264PARSER_H
25 
26 // OMG this is a hack. Buried several layers down in FFmpeg includes
27 // is an include of unistd.h that using GCC will foricibly redefine
28 // NULL back to the wrong value. (Maybe just on ARM?) Include
29 // unistd.h up front so that the subsequent inclusions will be
30 // skipped, and then define NULL to the right value.
31 #include <unistd.h>
32 #undef NULL
33 #define NULL nullptr
34 
35 #include <QString>
36 #include <cstdint>
37 #include "mythconfig.h"
38 #include "compat.h" // for uint on Darwin, MinGW
39 
40 #ifndef INT_BIT
41 #define INT_BIT (CHAR_BIT * sizeof(int))
42 #endif
43 
44 // copied from libavutil/internal.h
45 extern "C" {
46 // Grr. NULL keeps getting redefined back to 0
47 #undef NULL
48 #define NULL nullptr
49 #include "libavutil/common.h" // for AV_GCC_VERSION_AT_LEAST()
50 }
51 #ifndef av_alias
52 #if HAVE_ATTRIBUTE_MAY_ALIAS && (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(3,3)
53 # define av_alias __attribute__((may_alias))
54 #else
55 # define av_alias
56 #endif
57 #endif
58 
59 extern "C" {
60 // Grr. NULL keeps getting redefined back to 0
61 #undef NULL
62 #define NULL nullptr
63 #include "libavcodec/get_bits.h"
64 }
65 
66 class FrameRate;
67 
68 class H264Parser {
69  public:
70 
71  enum {
73  };
74 
75  // ITU-T Rec. H.264 table 7-1
77  UNKNOWN = 0,
78  SLICE = 1, // 1 - 5 are VCL NAL units
79  SLICE_DPA = 2,
80  SLICE_DPB = 3,
81  SLICE_DPC = 4,
82  SLICE_IDR = 5,
83  SEI = 6,
84  SPS = 7,
85  PPS = 8,
88  END_STREAM = 11,
90  SPS_EXT = 13,
92  SPS_subset = 15,
95  };
96 
97  enum SEI_type {
102  };
103 
104  /*
105  slice_type values in the range 5..9 specify, in addition to the
106  coding type of the current slice, that all other slices of the
107  current coded picture shall have a value of slice_type equal to
108  the current value of slice_type or equal to the current value of
109  slice_type – 5.
110  */
111  enum SLICE_type {
112  SLICE_P = 0,
113  SLICE_B = 1,
114  SLICE_I = 2,
115  SLICE_SP = 3,
116  SLICE_SI = 4,
123  };
124 
125  enum frame_type {
126  FRAME = 'F',
127  FIELD_TOP = 'T',
129  };
130 
131  H264Parser(void);
132  H264Parser(const H264Parser& rhs);
133  ~H264Parser(void) {delete [] m_rbspBuffer;}
134 
135  uint32_t addBytes(const uint8_t *bytes,
136  uint32_t byte_count,
137  uint64_t stream_offset);
138  void Reset(void);
139 
140  static QString NAL_type_str(uint8_t type);
141 
142  bool stateChanged(void) const { return m_stateChanged; }
143 
144  uint8_t lastNALtype(void) const { return m_nalUnitType; }
145 
146  frame_type FieldType(void) const
147  {
148  if (m_bottomFieldFlag == -1)
149  return FRAME;
151  }
152 
153  bool onFrameStart(void) const { return m_onFrame; }
154  bool onKeyFrameStart(void) const { return m_onKeyFrame; }
155 
156  uint pictureWidth(void) const { return m_picWidth; }
157  uint pictureHeight(void) const { return m_picHeight; }
158  uint pictureWidthCropped(void) const;
159  uint pictureHeightCropped(void) const;
160 
163  uint aspectRatio(void) const;
164  double frameRate(void) const;
165  void getFrameRate(FrameRate &result) const;
166  uint getRefFrames(void) const;
167 
168  uint64_t frameAUstreamOffset(void) const {return m_frameStartOffset;}
169  uint64_t keyframeAUstreamOffset(void) const {return m_keyframeStartOffset;}
170  uint64_t SPSstreamOffset(void) const {return m_spsOffset;}
171 
172  // == NAL_type AU_delimiter: primary_pic_type = 5
173  static bool isKeySlice(uint slice_type)
174  {
175  return (slice_type == SLICE_I ||
176  slice_type == SLICE_SI ||
177  slice_type == SLICE_I_a ||
178  slice_type == SLICE_SI_a);
179  }
180 
181  static bool NALisSlice(uint8_t nal_type)
182  {
183  return (nal_type == SLICE ||
184  nal_type == SLICE_DPA ||
185  nal_type == SLICE_IDR);
186  }
187 
188  void use_I_forKeyframes(bool val) { m_iIsKeyframe = val; }
189  bool using_I_forKeyframes(void) const { return m_iIsKeyframe; }
190 
191  uint32_t GetTimeScale(void) const { return m_timeScale; }
192 
193  uint32_t GetUnitsInTick(void) const { return m_unitsInTick; }
194 
195  void parse_SPS(uint8_t *sps, uint32_t sps_size,
196  bool& interlaced, int32_t& max_ref_frames);
197 
198  void reset_SPS(void) { m_seenSps = false; }
199  bool seen_SPS(void) const { return m_seenSps; }
200 
201  bool found_AU(void) const { return m_auPending; }
202 
203  private:
204  enum constants {EXTENDED_SAR = 255};
205 
206  inline void set_AU_pending(void)
207  {
208  if (!m_auPending)
209  {
210  m_auPending = true;
213  }
214  }
215 
216  bool new_AU(void);
217  void resetRBSP(void);
218  bool fillRBSP(const uint8_t *byteP, uint32_t byte_count,
219  bool found_start_code);
220  void processRBSP(bool rbsp_complete);
221  bool decode_Header(GetBitContext *gb);
222  void decode_SPS(GetBitContext *gb);
223  void decode_PPS(GetBitContext * gb);
224  void decode_SEI(GetBitContext * gb);
225  void vui_parameters(GetBitContext * gb);
226 
227  bool m_auPending {false};
228  bool m_stateChanged {false};
229  bool m_seenSps {false};
231  bool m_isKeyframe {false};
232  bool m_iIsKeyframe {true};
233 
234  uint32_t m_syncAccumulator {0xffffffff};
235  uint8_t *m_rbspBuffer {nullptr};
236  uint32_t m_rbspBufferSize {188 * 2};
237  uint32_t m_rbspIndex {0};
238  uint32_t m_consecutiveZeros {0};
239  bool m_haveUnfinishedNAL {false};
240 
241  int m_prevFrameNum {-1};
242  int m_frameNum {-1};
246  int8_t m_prevFieldPicFlag {-1};
247  int8_t m_fieldPicFlag {-1};
249  int8_t m_bottomFieldFlag {-1};
250  uint8_t m_prevNALRefIdc {111}; // != [0|1|2|3]
251  uint8_t m_nalRefIdc {111}; // != [0|1|2|3]
253  uint8_t m_picOrderCntType {0};
259  int m_deltaPicOrderCnt[2] {0};
263  uint m_idrPicId {65536};
264 
268 
271  int8_t m_frameMbsOnlyFlag {-1};
274  int8_t m_chromaFormatIdc {1};
275 
278 // uint m_picWidthInMbs {0};
279 // uint m_picHeightInMapUnits {0};
286  uint8_t m_aspectRatioIdc {0};
289  uint32_t m_unitsInTick {0};
290  uint32_t m_timeScale {0};
291  bool m_fixedRate {false};
292 
293  uint64_t m_pktOffset {0};
294  uint64_t m_auOffset {0};
295  uint64_t m_frameStartOffset {0};
296  uint64_t m_keyframeStartOffset {0};
297  uint64_t m_spsOffset {0};
298  bool m_onFrame {false};
299  bool m_onKeyFrame {false};
300 };
301 
302 #endif /* H264PARSER_H */
bool new_AU(void)
Definition: H264Parser.cpp:219
void decode_SEI(GetBitContext *gb)
uint64_t m_spsOffset
Definition: H264Parser.h:297
uint32_t GetUnitsInTick(void) const
Definition: H264Parser.h:193
int m_frameNum
Definition: H264Parser.h:242
int m_picOrderCntLsb
Definition: H264Parser.h:255
bool m_fixedRate
Definition: H264Parser.h:291
uint64_t m_frameStartOffset
Definition: H264Parser.h:295
bool onKeyFrameStart(void) const
Definition: H264Parser.h:154
void use_I_forKeyframes(bool val)
Definition: H264Parser.h:188
uint8_t m_prevNalUnitType
Definition: H264Parser.h:260
int m_prevFrameNum
Definition: H264Parser.h:241
uint64_t m_auOffset
Definition: H264Parser.h:294
bool m_separateColourPlaneFlag
Definition: H264Parser.h:270
bool m_iIsKeyframe
Definition: H264Parser.h:232
int8_t m_picOrderPresentFlag
Definition: H264Parser.h:272
bool decode_Header(GetBitContext *gb)
Definition: H264Parser.cpp:634
bool m_isKeyframe
Definition: H264Parser.h:231
bool m_auPending
Definition: H264Parser.h:227
int8_t m_prevFieldPicFlag
Definition: H264Parser.h:246
int m_prevPicOrderCntLsb
Definition: H264Parser.h:254
bool m_onKeyFrame
Definition: H264Parser.h:299
uint m_numRefFrames
Definition: H264Parser.h:276
int m_prevDeltaPicOrderCntBottom
Definition: H264Parser.h:256
void parse_SPS(uint8_t *sps, uint32_t sps_size, bool &interlaced, int32_t &max_ref_frames)
int8_t m_prevBottomFieldFlag
Definition: H264Parser.h:248
uint aspectRatio(void) const
Computes aspect ratio from picture size and sample aspect ratio.
uint8_t m_prevNALRefIdc
Definition: H264Parser.h:250
uint m_log2MaxFrameNum
Definition: H264Parser.h:265
uint m_frameCropBottomOffset
Definition: H264Parser.h:285
int m_prevPicParameterSetId
Definition: H264Parser.h:244
uint pictureWidthCropped(void) const
void Reset(void)
Definition: H264Parser.cpp:103
bool fillRBSP(const uint8_t *byteP, uint32_t byte_count, bool found_start_code)
Definition: H264Parser.cpp:345
bool m_stateChanged
Definition: H264Parser.h:228
uint8_t m_nalRefIdc
Definition: H264Parser.h:251
uint m_log2MaxPicOrderCntLsb
Definition: H264Parser.h:266
uint m_redundantPicCnt
Definition: H264Parser.h:277
uint m_sliceType
Definition: H264Parser.h:243
uint64_t SPSstreamOffset(void) const
Definition: H264Parser.h:170
void vui_parameters(GetBitContext *gb)
~H264Parser(void)
Definition: H264Parser.h:133
uint m_frameCropLeftOffset
Definition: H264Parser.h:282
int m_prevDeltaPicOrderCnt[2]
Definition: H264Parser.h:258
bool m_onFrame
Definition: H264Parser.h:298
bool m_auContainsKeyframeMessage
Definition: H264Parser.h:230
int m_deltaPicOrderCnt[2]
Definition: H264Parser.h:259
uint m_picHeight
Definition: H264Parser.h:281
void getFrameRate(FrameRate &result) const
uint8_t m_deltaPicOrderAlwaysZeroFlag
Definition: H264Parser.h:269
bool m_seenSps
Definition: H264Parser.h:229
uint64_t frameAUstreamOffset(void) const
Definition: H264Parser.h:168
uint8_t * m_rbspBuffer
Definition: H264Parser.h:235
uint32_t m_consecutiveZeros
Definition: H264Parser.h:238
uint m_sarWidth
Definition: H264Parser.h:287
void set_AU_pending(void)
Definition: H264Parser.h:206
unsigned int uint
Definition: compat.h:140
bool onFrameStart(void) const
Definition: H264Parser.h:153
bool stateChanged(void) const
Definition: H264Parser.h:142
int m_picParameterSetId
Definition: H264Parser.h:245
static bool NALisSlice(uint8_t nal_type)
Definition: H264Parser.h:181
uint8_t lastNALtype(void) const
Definition: H264Parser.h:144
uint m_frameCropTopOffset
Definition: H264Parser.h:284
uint64_t m_keyframeStartOffset
Definition: H264Parser.h:296
uint8_t m_aspectRatioIdc
Definition: H264Parser.h:286
void decode_PPS(GetBitContext *gb)
void processRBSP(bool rbsp_complete)
Definition: H264Parser.cpp:553
int m_deltaPicOrderCntBottom
Definition: H264Parser.h:257
uint32_t addBytes(const uint8_t *bytes, uint32_t byte_count, uint64_t stream_offset)
Definition: H264Parser.cpp:422
static QString NAL_type_str(uint8_t type)
Definition: H264Parser.cpp:183
uint8_t m_prevPicOrderCntType
Definition: H264Parser.h:252
uint getRefFrames(void) const
uint m_picWidth
Definition: H264Parser.h:280
uint32_t m_syncAccumulator
Definition: H264Parser.h:234
uint m_idrPicId
Definition: H264Parser.h:263
uint m_frameCropRightOffset
Definition: H264Parser.h:283
int8_t m_bottomFieldFlag
Definition: H264Parser.h:249
double frameRate(void) const
frame_type FieldType(void) const
Definition: H264Parser.h:146
void resetRBSP(void)
Definition: H264Parser.cpp:338
uint32_t m_unitsInTick
Definition: H264Parser.h:289
bool m_haveUnfinishedNAL
Definition: H264Parser.h:239
static bool isKeySlice(uint slice_type)
Definition: H264Parser.h:173
void reset_SPS(void)
Definition: H264Parser.h:198
uint m_prevIdrPicId
Definition: H264Parser.h:262
void decode_SPS(GetBitContext *gb)
Definition: H264Parser.cpp:830
int8_t m_fieldPicFlag
Definition: H264Parser.h:247
uint64_t m_pktOffset
Definition: H264Parser.h:293
uint pictureHeight(void) const
Definition: H264Parser.h:157
uint pictureWidth(void) const
Definition: H264Parser.h:156
uint8_t m_nalUnitType
Definition: H264Parser.h:261
uint32_t GetTimeScale(void) const
Definition: H264Parser.h:191
uint64_t keyframeAUstreamOffset(void) const
Definition: H264Parser.h:169
uint8_t m_picOrderCntType
Definition: H264Parser.h:253
uint m_sarHeight
Definition: H264Parser.h:288
int8_t m_frameMbsOnlyFlag
Definition: H264Parser.h:271
bool found_AU(void) const
Definition: H264Parser.h:201
uint32_t m_timeScale
Definition: H264Parser.h:290
bool using_I_forKeyframes(void) const
Definition: H264Parser.h:189
uint32_t m_rbspBufferSize
Definition: H264Parser.h:236
H264Parser(void)
Definition: H264Parser.cpp:94
int8_t m_redundantPicCntPresentFlag
Definition: H264Parser.h:273
uint32_t m_rbspIndex
Definition: H264Parser.h:237
int8_t m_chromaFormatIdc
Definition: H264Parser.h:274
bool seen_SPS(void) const
Definition: H264Parser.h:199
uint pictureHeightCropped(void) const
uint m_seqParameterSetId
Definition: H264Parser.h:267