OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
Ami GONE FROM CHROMIUM
2012/03/21 13:16:24
Not part of this CL?
Pawel Osciak
2012/03/21 18:40:35
Yeah, looks like I was misunderstanding how rietve
Ami GONE FROM CHROMIUM
2012/03/22 17:01:36
Addressed this elsewhere, but FWIW it's always a g
| |
3 // found in the LICENSE file. | |
4 // | |
5 // This file contains an implementation of a H264 Annex-B video stream parser. | |
6 | |
7 #ifndef CONTENT_COMMON_GPU_MEDIA_H264_PARSER_H_ | |
8 #define CONTENT_COMMON_GPU_MEDIA_H264_PARSER_H_ | |
9 | |
10 #include <map> | |
11 | |
12 #include "base/basictypes.h" | |
13 #include "base/memory/scoped_ptr.h" | |
14 | |
15 // For explanations of each struct and its members, see H.264 specification | |
16 enum H264NaluType { | |
17 kH264NaluUnspecified = 0, | |
18 kH264NaluNonIDRSlice = 1, | |
19 kH264NaluIDRSlice = 5, | |
20 kH264SEIMessage = 6, | |
21 kH264NaluSPS = 7, | |
22 kH264NaluPPS = 8, | |
23 kH264NaluEOSeq = 9, | |
24 kH264NaluEOStream = 11, | |
25 }; | |
26 | |
27 struct H264NALU { | |
28 uint8* data; // After/without start code | |
29 size_t size; // From after start code to start code of next NALU (or EOS) | |
30 | |
31 uint8 nal_ref_idc; | |
32 uint8 nal_unit_type; | |
33 }; | |
34 | |
35 struct H264SPS { | |
36 uint8 profile_idc; | |
37 uint8 level_idc; | |
38 uint32 seq_parameter_set_id; | |
39 | |
40 uint8 chroma_format_idc; | |
41 bool separate_colour_plane_flag; | |
42 uint8 bit_depth_luma_minus8; | |
43 uint8 bit_depth_chroma_minus8; | |
44 bool qpprime_y_zero_transform_bypass_flag; | |
45 | |
46 bool seq_scaling_matrix_present_flag; | |
47 // Changing uint8s below to larger types will break assumptions | |
48 // in code that fills default scaling lists | |
49 uint8 scaling_list4x4[6][16]; | |
50 uint8 scaling_list8x8[6][64]; | |
51 | |
52 uint8 log2_max_frame_num_minus4; | |
53 uint8 pic_order_cnt_type; | |
54 uint8 log2_max_pic_order_cnt_lsb_minus4; | |
55 bool delta_pic_order_always_zero_flag; | |
56 int32 offset_for_non_ref_pic; | |
57 int32 offset_for_top_to_bottom_field; | |
58 uint8 num_ref_frames_in_pic_order_cnt_cycle; | |
59 int32 offset_for_ref_frame[255]; | |
60 uint32 max_num_ref_frames; | |
61 bool gaps_in_frame_num_value_allowed_flag; | |
62 uint32 pic_width_in_mbs_minus1; | |
63 uint32 pic_height_in_map_units_minus1; | |
64 bool frame_mbs_only_flag; | |
65 bool mb_adaptive_frame_field_flag; | |
66 bool direct_8x8_inference_flag; | |
67 bool frame_cropping_flag; | |
68 uint32 frame_crop_left_offset; | |
69 uint32 frame_crop_right_offset; | |
70 uint32 frame_crop_top_offset; | |
71 uint32 frame_crop_bottom_offset; | |
72 bool vui_parameters_present_flag; | |
73 | |
74 uint8 chroma_array_type; | |
75 }; | |
76 | |
77 struct H264PPS { | |
78 uint8 pic_parameter_set_id; | |
79 uint8 seq_parameter_set_id; | |
80 bool entropy_coding_mode_flag; | |
81 bool bottom_field_pic_order_in_frame_present_flag; | |
82 uint32 num_slice_groups_minus1; | |
83 // TODO slice groups not implemented | |
84 uint8 num_ref_idx_l0_default_active_minus1; | |
85 uint8 num_ref_idx_l1_default_active_minus1; | |
86 bool weighted_pred_flag; | |
87 uint8 weighted_bipred_idc; | |
88 int8 pic_init_qp_minus26; | |
89 int8 pic_init_qs_minus26; | |
90 int8 chroma_qp_index_offset; | |
91 bool deblocking_filter_control_present_flag; | |
92 bool constrained_intra_pred_flag; | |
93 bool redundant_pic_cnt_present_flag; | |
94 | |
95 bool transform_8x8_mode_flag; | |
96 | |
97 bool pic_scaling_matrix_present_flag; | |
98 uint8 scaling_list4x4[6][16]; | |
99 uint8 scaling_list8x8[6][64]; | |
100 | |
101 int32 second_chroma_qp_index_offset; | |
102 }; | |
103 | |
104 enum H264SliceType { | |
105 kH264PSlice = 0, | |
106 kH264BSlice = 1, | |
107 kH264ISlice = 2, | |
108 kH264SPSlice = 3, | |
109 kH264SISlice = 4, | |
110 }; | |
111 | |
112 struct H264ModificationOfPicNum { | |
113 uint8 modification_of_pic_nums_idc; | |
114 union { | |
115 uint32 abs_diff_pic_num_minus1; | |
116 uint32 long_term_pic_num; | |
117 }; | |
118 }; | |
119 | |
120 struct H264WeightingFactors { | |
121 bool luma_weight_flag; | |
122 bool chroma_weight_flag; | |
123 | |
124 int16 luma_weight[32]; | |
125 int16 luma_offset[32]; | |
126 int16 chroma_weight[32][2]; | |
127 int16 chroma_offset[32][2]; | |
128 }; | |
129 | |
130 struct H264DecRefPicMarking { | |
131 uint8 memory_mgmnt_control_operation; | |
132 uint32 difference_of_pic_nums_minus1; | |
133 uint32 long_term_pic_num; | |
134 uint32 long_term_frame_idx; | |
135 uint32 max_long_term_frame_idx_plus1; | |
136 }; | |
137 | |
138 struct H264SliceHeader { | |
139 enum { kRefListSize = 32 }; | |
140 enum { kRefListModSize = kRefListSize }; | |
141 | |
142 bool idr_pic_flag; // from NAL header | |
143 uint8 nal_ref_idc; // from NAL header | |
144 uint8* nalu_data; // from NAL header | |
145 size_t nalu_size; // from NAL header | |
146 size_t header_bit_size; // calculated | |
147 | |
148 uint32 first_mb_in_slice; | |
149 uint8 slice_type; | |
150 uint8 pic_parameter_set_id; | |
151 uint8 colour_plane_id; | |
152 uint32 frame_num; | |
153 bool field_pic_flag; | |
154 bool bottom_field_flag; | |
155 uint16 idr_pic_id; | |
156 uint32 pic_order_cnt_lsb; | |
157 int32 delta_pic_order_cnt_bottom; | |
158 int32 delta_pic_order_cnt[2]; | |
159 uint8 redundant_pic_cnt; | |
160 bool direct_spatial_mv_pred_flag; | |
161 | |
162 bool num_ref_idx_active_override_flag; | |
163 uint8 num_ref_idx_l0_active_minus1; | |
164 uint8 num_ref_idx_l1_active_minus1; | |
165 bool ref_pic_list_modification_flag_l0; | |
166 bool ref_pic_list_modification_flag_l1; | |
167 H264ModificationOfPicNum ref_list_l0_modifications[kRefListModSize]; | |
168 H264ModificationOfPicNum ref_list_l1_modifications[kRefListModSize]; | |
169 | |
170 uint8 luma_log2_weight_denom; | |
171 uint8 chroma_log2_weight_denom; | |
172 | |
173 bool luma_weight_l0_flag; | |
174 bool chroma_weight_l0_flag; | |
175 H264WeightingFactors pred_weight_table_l0; | |
176 | |
177 bool luma_weight_l1_flag; | |
178 bool chroma_weight_l1_flag; | |
179 H264WeightingFactors pred_weight_table_l1; | |
180 | |
181 bool no_output_of_prior_pics_flag; | |
182 bool long_term_reference_flag; | |
183 | |
184 bool adaptive_ref_pic_marking_mode_flag; | |
185 H264DecRefPicMarking ref_pic_marking[kRefListSize]; | |
186 | |
187 uint8 cabac_init_idc; | |
188 int32 slice_qp_delta; | |
189 bool sp_for_switch_flag; | |
190 int32 slice_qs_delta; | |
191 uint8 disable_deblocking_filter_idc; | |
192 int8 slice_alpha_c0_offset_div2; | |
193 int8 slice_beta_offset_div2; | |
194 }; | |
195 | |
196 enum H264SEIType { | |
197 kH264SEIRecoveryPoint = 6, | |
198 }; | |
199 | |
200 struct H264SEIRecoveryPoint { | |
201 uint32 recovery_frame_cnt; | |
202 bool exact_match_flag; | |
203 bool broken_link_flag; | |
204 uint8 changing_slice_group_idc; | |
205 }; | |
206 | |
207 struct H264SEIMessage { | |
208 int32 type; | |
209 uint32 payload_size; | |
210 union { | |
211 H264SEIRecoveryPoint recovery_point; | |
212 }; | |
213 }; | |
214 | |
215 static inline bool IsH264PSlice(H264SliceHeader* shdr) { | |
216 if (shdr) | |
217 return (shdr->slice_type % 5 == kH264PSlice); | |
218 return false; | |
219 } | |
220 | |
221 static inline bool IsH264BSlice(H264SliceHeader* shdr) { | |
222 if (shdr) | |
223 return (shdr->slice_type % 5 == kH264BSlice); | |
224 return false; | |
225 } | |
226 | |
227 static inline bool IsH264ISlice(H264SliceHeader* shdr) { | |
228 if (shdr) | |
229 return (shdr->slice_type % 5 == kH264ISlice); | |
230 return false; | |
231 } | |
232 | |
233 static inline bool IsH264SPSlice(H264SliceHeader* shdr) { | |
234 if (shdr) | |
235 return (shdr->slice_type % 5 == kH264SPSlice); | |
236 return false; | |
237 } | |
238 | |
239 static inline bool IsH264SISlice(H264SliceHeader* shdr) { | |
240 if (shdr) | |
241 return (shdr->slice_type % 5 == kH264SISlice); | |
242 return false; | |
243 } | |
244 | |
245 // Class to provide bit-granularity reading of H.264 streams | |
246 // This is not a generic bit reader class, as it takes into account | |
247 // H.264 stream-specific constraints, such as skipping emulation-prevention | |
248 // bytes and stop bits. See spec for more details. | |
249 class H264BitReader { | |
250 public: | |
251 | |
252 H264BitReader(); | |
253 ~H264BitReader(); | |
254 | |
255 bool Initialize(uint8* data, size_t size); | |
256 | |
257 // Read num_bits next bits in stream and return in out | |
258 bool ReadBits(int num_bits, uint32 *out); | |
259 | |
260 // True if any bits left in the stream | |
261 size_t NumBitsLeft() { return (bits_in_curr_byte_ + bytes_left_ * 8); } | |
262 | |
263 // See the definition of more_rbsp_data() in spec. | |
264 bool MoreRBSPData(); | |
265 | |
266 private: | |
267 | |
268 // Advance to the next byte if we are out of bits in the current byte | |
269 bool UpdateCurrByte(); | |
270 | |
271 // Pointer to the next unread byte in the stream | |
272 uint8* data_; | |
273 | |
274 // Bytes left in the stream (without the current byte) | |
275 size_t bytes_left_; | |
276 | |
277 // Contents of the current byte | |
278 uint8 curr_byte_; | |
279 | |
280 // for emulation prevention three byte detection | |
281 uint16 prev_two_bytes_; | |
282 int bits_in_curr_byte_; | |
283 | |
284 DISALLOW_COPY_AND_ASSIGN(H264BitReader); | |
285 }; | |
286 | |
287 // Class to parse an Annex-B H.264 stream, | |
288 // as specified in chapters 7 and Annex B of the H.264 spec. | |
289 class H264Parser { | |
290 public: | |
291 | |
292 enum Result { | |
293 kOk, | |
294 kInvalidStream, // error in stream | |
295 kUnsupportedStream, // stream not supported by the parser | |
296 kEOStream, // end of stream | |
297 }; | |
298 | |
299 H264Parser(); | |
300 ~H264Parser(); | |
301 | |
302 void Reset(); | |
303 // stream_size in bytes | |
304 void SetStream(uint8* stream, size_t stream_size); | |
305 | |
306 // Read the next stream to find the next NALU, identify it and return | |
307 // that information in nalu. This advances the stream to the beginning | |
308 // of this NALU, but not past it, so subsequent calls to NALU-specific | |
309 // parsing functions (ParseSPS, etc.) will parse this NALU. | |
310 // If the caller wishes to skip the current NALU, it can call this function | |
311 // again, instead of any NALU-type specific parse functions below. | |
312 Result ParseNextNalu(H264NALU* nalu); | |
313 | |
314 // Nalu-specific parsing functions. | |
315 // These should be called after ParseNextNalu(). | |
316 | |
317 // SPS and PPS are stored in the Parser and the memory for their structures | |
318 // is managed by the parser, as they can be reused across NALUs. | |
319 // To access any of them, use GetSPS()/GetPPS() using the returned id. | |
320 Result ParseSPS(int* sps_id); | |
321 Result ParsePPS(int* pps_id); | |
322 | |
323 // Slice header is not used across NALUs and can be discarded after current | |
324 // NALU, so the parser does not store them, nor does it manage their memory. | |
325 // Caller has to provide and manage it instead. | |
326 Result ParseSliceHeader(H264SliceHeader* shdr, H264NALU* nalu); | |
327 | |
328 // Return pointer to SPS/PPS with given id or NULL if not present. | |
329 // Caller should not attempt to modify/free this memory. | |
330 H264SPS* GetSPS(uint8 sps_id); | |
331 H264PPS* GetPPS(uint8 pps_id); | |
332 | |
333 Result ParseSEI(H264SEIMessage* sei_msg); | |
334 | |
335 private: | |
336 | |
337 // Exp-Golomb code parsing as specified in chapter 9.1 of the spec. | |
338 // Read one unsigned exp-Golomb code from the stream, | |
339 Result ReadUE(uint32* val); | |
340 | |
341 // Read one signed exp-Golomb code from the stream. | |
342 Result ReadSE(int32* val); | |
343 | |
344 Result ScalingList(uint8* scaling_list, int size, bool* use_default); | |
345 Result ParseSPSScalingLists(H264SPS* sps); | |
346 Result ParsePPSScalingLists(H264SPS* sps, H264PPS* pps); | |
347 | |
348 Result RefPicListModification(H264SliceHeader* shdr); | |
349 Result ParseRefPicListModification(uint8 num_ref_idx_active_minus1, | |
350 H264ModificationOfPicNum* ref_list_mods); | |
351 | |
352 Result ParsePredWeightTable(H264SliceHeader *shdr, H264SPS* sps); | |
353 | |
354 Result ParseWeightingFactors(H264WeightingFactors* w_facts, | |
355 int num_ref_idx_active_minus1, | |
356 uint8 chroma_array_type, | |
357 uint8 luma_log2_weight_denom, | |
358 uint8 chroma_log2_weight_denom); | |
359 Result ParseDecRefPicMarking(H264SliceHeader *shdr); | |
360 | |
361 // Pointer to the current NALU in the stream | |
362 uint8* stream_; | |
363 | |
364 // Bytes left in the stream after the current NALU. | |
365 size_t bytes_left_; | |
366 | |
367 H264BitReader br_; | |
368 | |
369 typedef std::map<uint8, H264SPS*> SPSById; | |
370 typedef std::map<uint8, H264PPS*> PPSById; | |
371 SPSById active_SPSes_; | |
372 PPSById active_PPSes_; | |
373 | |
374 DISALLOW_COPY_AND_ASSIGN(H264Parser); | |
375 }; | |
376 | |
377 #endif // CONTENT_COMMON_GPU_MEDIA_H264_PARSER_H_ | |
378 | |
OLD | NEW |