DASH Media Packaging SDK
 All Classes Namespaces Functions Variables Typedefs Enumerator
h264_parser.cc
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "packager/media/filters/h264_parser.h"
6 
7 #include "packager/base/logging.h"
8 #include "packager/base/memory/scoped_ptr.h"
9 #include "packager/base/stl_util.h"
10 #include "packager/media/base/buffer_reader.h"
11 
12 namespace edash_packager {
13 namespace media {
14 
15 // Implemented according to ISO/IEC 14496-10:2005 7.4.2.1 Sequence parameter set
16 // RBSP semantics.
17 bool ExtractResolutionFromSps(const H264SPS& sps,
18  uint32_t* coded_width,
19  uint32_t* coded_height,
20  uint32_t* pixel_width,
21  uint32_t* pixel_height) {
22  int crop_x = 0;
23  int crop_y = 0;
24  if (sps.frame_cropping_flag) {
25  int sub_width_c = 0;
26  int sub_height_c = 0;
27  // Table 6-1.
28  switch (sps.chroma_format_idc) {
29  case 0: // monochrome
30  // SubWidthC and SubHeightC are not defined for monochrome. For ease of
31  // computation afterwards, assign both to 1.
32  sub_width_c = 1;
33  sub_height_c = 1;
34  break;
35  case 1: // 4:2:0
36  sub_width_c = 2;
37  sub_height_c = 2;
38  break;
39  case 2: // 4:2:2
40  sub_width_c = 2;
41  sub_height_c = 1;
42  break;
43  case 3: // 4:4:4
44  sub_width_c = 1;
45  sub_height_c = 1;
46  break;
47  default:
48  LOG(ERROR) << "Unexpected chroma_format_idc " << sps.chroma_format_idc;
49  return false;
50  }
51 
52  // Formula 7-16, 7-17, 7-18, 7-19.
53  int crop_unit_x = sub_width_c;
54  int crop_unit_y = sub_height_c * (2 - (sps.frame_mbs_only_flag ? 1 : 0));
55  crop_x = crop_unit_x *
56  (sps.frame_crop_left_offset + sps.frame_crop_right_offset);
57  crop_y = crop_unit_y *
58  (sps.frame_crop_top_offset + sps.frame_crop_bottom_offset);
59  }
60 
61  // Formula 7-10, 7-11.
62  int pic_width_in_mbs = sps.pic_width_in_mbs_minus1 + 1;
63  *coded_width = pic_width_in_mbs * 16 - crop_x;
64 
65  // Formula 7-13, 7-15.
66  int pic_height_in_mbs = (2 - (sps.frame_mbs_only_flag ? 1 : 0)) *
67  (sps.pic_height_in_map_units_minus1 + 1);
68  *coded_height = pic_height_in_mbs * 16 - crop_y;
69 
70  // 0 means it wasn't in the SPS and therefore assume 1.
71  *pixel_width = sps.sar_width == 0 ? 1 : sps.sar_width;
72  *pixel_height = sps.sar_height == 0 ? 1 : sps.sar_height;
73  DVLOG(2) << "Found coded_width: " << *coded_width
74  << " coded_height: " << *coded_height
75  << " pixel_width: " << *pixel_width
76  << " pixel_height: " << *pixel_height;
77  return true;
78 }
79 
80 bool H264SliceHeader::IsPSlice() const {
81  return (slice_type % 5 == kPSlice);
82 }
83 
84 bool H264SliceHeader::IsBSlice() const {
85  return (slice_type % 5 == kBSlice);
86 }
87 
88 bool H264SliceHeader::IsISlice() const {
89  return (slice_type % 5 == kISlice);
90 }
91 
92 bool H264SliceHeader::IsSPSlice() const {
93  return (slice_type % 5 == kSPSlice);
94 }
95 
96 bool H264SliceHeader::IsSISlice() const {
97  return (slice_type % 5 == kSISlice);
98 }
99 
100 H264SPS::H264SPS() {
101  memset(this, 0, sizeof(*this));
102 }
103 
104 H264PPS::H264PPS() {
105  memset(this, 0, sizeof(*this));
106 }
107 
108 H264SliceHeader::H264SliceHeader() {
109  memset(this, 0, sizeof(*this));
110 }
111 
112 H264SEIMessage::H264SEIMessage() {
113  memset(this, 0, sizeof(*this));
114 }
115 
116 #define READ_BITS_OR_RETURN(num_bits, out) \
117  do { \
118  int _out; \
119  if (!br->ReadBits(num_bits, &_out)) { \
120  DVLOG(1) \
121  << "Error in stream: unexpected EOS while trying to read " #out; \
122  return kInvalidStream; \
123  } \
124  *out = _out; \
125  } while (0)
126 
127 #define READ_BOOL_OR_RETURN(out) \
128  do { \
129  int _out; \
130  if (!br->ReadBits(1, &_out)) { \
131  DVLOG(1) \
132  << "Error in stream: unexpected EOS while trying to read " #out; \
133  return kInvalidStream; \
134  } \
135  *out = _out != 0; \
136  } while (0)
137 
138 #define READ_UE_OR_RETURN(out) \
139  do { \
140  if (ReadUE(br, out) != kOk) { \
141  DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \
142  return kInvalidStream; \
143  } \
144  } while (0)
145 
146 #define READ_SE_OR_RETURN(out) \
147  do { \
148  if (ReadSE(br, out) != kOk) { \
149  DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \
150  return kInvalidStream; \
151  } \
152  } while (0)
153 
154 #define IN_RANGE_OR_RETURN(val, min, max) \
155  do { \
156  if ((val) < (min) || (val) > (max)) { \
157  DVLOG(1) << "Error in stream: invalid value, expected " #val " to be" \
158  << " in range [" << (min) << ":" << (max) << "]" \
159  << " found " << (val) << " instead"; \
160  return kInvalidStream; \
161  } \
162  } while (0)
163 
164 #define TRUE_OR_RETURN(a) \
165  do { \
166  if (!(a)) { \
167  DVLOG(1) << "Error in stream: invalid value, expected " << #a; \
168  return kInvalidStream; \
169  } \
170  } while (0)
171 
172 enum AspectRatioIdc {
173  kExtendedSar = 255,
174 };
175 
176 // ISO 14496 part 10
177 // VUI parameters: Table E-1 "Meaning of sample aspect ratio indicator"
178 static const int kTableSarWidth[] = {
179  0, 1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2
180 };
181 static const int kTableSarHeight[] = {
182  0, 1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1
183 };
184 COMPILE_ASSERT(arraysize(kTableSarWidth) == arraysize(kTableSarHeight),
185  sar_tables_must_have_same_size);
186 
187 H264Parser::H264Parser() {}
188 
189 H264Parser::~H264Parser() {
190  STLDeleteValues(&active_SPSes_);
191  STLDeleteValues(&active_PPSes_);
192 }
193 
194 const H264PPS* H264Parser::GetPPS(int pps_id) {
195  return active_PPSes_[pps_id];
196 }
197 
198 const H264SPS* H264Parser::GetSPS(int sps_id) {
199  return active_SPSes_[sps_id];
200 }
201 
202 H264Parser::Result H264Parser::ReadUE(H264BitReader* br, int* val) {
203  int num_bits = -1;
204  int bit;
205  int rest;
206 
207  // Count the number of contiguous zero bits.
208  do {
209  READ_BITS_OR_RETURN(1, &bit);
210  num_bits++;
211  } while (bit == 0);
212 
213  if (num_bits > 31)
214  return kInvalidStream;
215 
216  // Calculate exp-Golomb code value of size num_bits.
217  *val = (1 << num_bits) - 1;
218 
219  if (num_bits > 0) {
220  READ_BITS_OR_RETURN(num_bits, &rest);
221  *val += rest;
222  }
223 
224  return kOk;
225 }
226 
227 H264Parser::Result H264Parser::ReadSE(H264BitReader* br, int* val) {
228  int ue;
229  Result res;
230 
231  // See Chapter 9 in the spec.
232  res = ReadUE(br, &ue);
233  if (res != kOk)
234  return res;
235 
236  if (ue % 2 == 0)
237  *val = -(ue / 2);
238  else
239  *val = ue / 2 + 1;
240 
241  return kOk;
242 }
243 
244 // Default scaling lists (per spec).
245 static const int kDefault4x4Intra[kH264ScalingList4x4Length] = {
246  6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42, };
247 
248 static const int kDefault4x4Inter[kH264ScalingList4x4Length] = {
249  10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34, };
250 
251 static const int kDefault8x8Intra[kH264ScalingList8x8Length] = {
252  6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23,
253  23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27,
254  27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31,
255  31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42, };
256 
257 static const int kDefault8x8Inter[kH264ScalingList8x8Length] = {
258  9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21,
259  21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24,
260  24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27,
261  27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35, };
262 
263 static inline void DefaultScalingList4x4(
264  int i,
265  int scaling_list4x4[][kH264ScalingList4x4Length]) {
266  DCHECK_LT(i, 6);
267 
268  if (i < 3)
269  memcpy(scaling_list4x4[i], kDefault4x4Intra, sizeof(kDefault4x4Intra));
270  else if (i < 6)
271  memcpy(scaling_list4x4[i], kDefault4x4Inter, sizeof(kDefault4x4Inter));
272 }
273 
274 static inline void DefaultScalingList8x8(
275  int i,
276  int scaling_list8x8[][kH264ScalingList8x8Length]) {
277  DCHECK_LT(i, 6);
278 
279  if (i % 2 == 0)
280  memcpy(scaling_list8x8[i], kDefault8x8Intra, sizeof(kDefault8x8Intra));
281  else
282  memcpy(scaling_list8x8[i], kDefault8x8Inter, sizeof(kDefault8x8Inter));
283 }
284 
285 static void FallbackScalingList4x4(
286  int i,
287  const int default_scaling_list_intra[],
288  const int default_scaling_list_inter[],
289  int scaling_list4x4[][kH264ScalingList4x4Length]) {
290  static const int kScalingList4x4ByteSize =
291  sizeof(scaling_list4x4[0][0]) * kH264ScalingList4x4Length;
292 
293  switch (i) {
294  case 0:
295  memcpy(scaling_list4x4[i], default_scaling_list_intra,
296  kScalingList4x4ByteSize);
297  break;
298 
299  case 1:
300  memcpy(scaling_list4x4[i], scaling_list4x4[0], kScalingList4x4ByteSize);
301  break;
302 
303  case 2:
304  memcpy(scaling_list4x4[i], scaling_list4x4[1], kScalingList4x4ByteSize);
305  break;
306 
307  case 3:
308  memcpy(scaling_list4x4[i], default_scaling_list_inter,
309  kScalingList4x4ByteSize);
310  break;
311 
312  case 4:
313  memcpy(scaling_list4x4[i], scaling_list4x4[3], kScalingList4x4ByteSize);
314  break;
315 
316  case 5:
317  memcpy(scaling_list4x4[i], scaling_list4x4[4], kScalingList4x4ByteSize);
318  break;
319 
320  default:
321  NOTREACHED();
322  break;
323  }
324 }
325 
326 static void FallbackScalingList8x8(
327  int i,
328  const int default_scaling_list_intra[],
329  const int default_scaling_list_inter[],
330  int scaling_list8x8[][kH264ScalingList8x8Length]) {
331  static const int kScalingList8x8ByteSize =
332  sizeof(scaling_list8x8[0][0]) * kH264ScalingList8x8Length;
333 
334  switch (i) {
335  case 0:
336  memcpy(scaling_list8x8[i], default_scaling_list_intra,
337  kScalingList8x8ByteSize);
338  break;
339 
340  case 1:
341  memcpy(scaling_list8x8[i], default_scaling_list_inter,
342  kScalingList8x8ByteSize);
343  break;
344 
345  case 2:
346  memcpy(scaling_list8x8[i], scaling_list8x8[0], kScalingList8x8ByteSize);
347  break;
348 
349  case 3:
350  memcpy(scaling_list8x8[i], scaling_list8x8[1], kScalingList8x8ByteSize);
351  break;
352 
353  case 4:
354  memcpy(scaling_list8x8[i], scaling_list8x8[2], kScalingList8x8ByteSize);
355  break;
356 
357  case 5:
358  memcpy(scaling_list8x8[i], scaling_list8x8[3], kScalingList8x8ByteSize);
359  break;
360 
361  default:
362  NOTREACHED();
363  break;
364  }
365 }
366 
367 H264Parser::Result H264Parser::ParseScalingList(H264BitReader* br,
368  int size,
369  int* scaling_list,
370  bool* use_default) {
371  // See chapter 7.3.2.1.1.1.
372  int last_scale = 8;
373  int next_scale = 8;
374  int delta_scale;
375 
376  *use_default = false;
377 
378  for (int j = 0; j < size; ++j) {
379  if (next_scale != 0) {
380  READ_SE_OR_RETURN(&delta_scale);
381  IN_RANGE_OR_RETURN(delta_scale, -128, 127);
382  next_scale = (last_scale + delta_scale + 256) & 0xff;
383 
384  if (j == 0 && next_scale == 0) {
385  *use_default = true;
386  return kOk;
387  }
388  }
389 
390  scaling_list[j] = (next_scale == 0) ? last_scale : next_scale;
391  last_scale = scaling_list[j];
392  }
393 
394  return kOk;
395 }
396 
397 H264Parser::Result H264Parser::ParseSPSScalingLists(H264BitReader* br,
398  H264SPS* sps) {
399  // See 7.4.2.1.1.
400  bool seq_scaling_list_present_flag;
401  bool use_default;
402  Result res;
403 
404  // Parse scaling_list4x4.
405  for (int i = 0; i < 6; ++i) {
406  READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag);
407 
408  if (seq_scaling_list_present_flag) {
409  res = ParseScalingList(br,
410  arraysize(sps->scaling_list4x4[i]),
411  sps->scaling_list4x4[i],
412  &use_default);
413  if (res != kOk)
414  return res;
415 
416  if (use_default)
417  DefaultScalingList4x4(i, sps->scaling_list4x4);
418 
419  } else {
420  FallbackScalingList4x4(
421  i, kDefault4x4Intra, kDefault4x4Inter, sps->scaling_list4x4);
422  }
423  }
424 
425  // Parse scaling_list8x8.
426  for (int i = 0; i < ((sps->chroma_format_idc != 3) ? 2 : 6); ++i) {
427  READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag);
428 
429  if (seq_scaling_list_present_flag) {
430  res = ParseScalingList(br,
431  arraysize(sps->scaling_list8x8[i]),
432  sps->scaling_list8x8[i],
433  &use_default);
434  if (res != kOk)
435  return res;
436 
437  if (use_default)
438  DefaultScalingList8x8(i, sps->scaling_list8x8);
439 
440  } else {
441  FallbackScalingList8x8(
442  i, kDefault8x8Intra, kDefault8x8Inter, sps->scaling_list8x8);
443  }
444  }
445 
446  return kOk;
447 }
448 
449 H264Parser::Result H264Parser::ParsePPSScalingLists(H264BitReader* br,
450  const H264SPS& sps,
451  H264PPS* pps) {
452  // See 7.4.2.2.
453  bool pic_scaling_list_present_flag;
454  bool use_default;
455  Result res;
456 
457  for (int i = 0; i < 6; ++i) {
458  READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag);
459 
460  if (pic_scaling_list_present_flag) {
461  res = ParseScalingList(br,
462  arraysize(pps->scaling_list4x4[i]),
463  pps->scaling_list4x4[i],
464  &use_default);
465  if (res != kOk)
466  return res;
467 
468  if (use_default)
469  DefaultScalingList4x4(i, pps->scaling_list4x4);
470 
471  } else {
472  if (sps.seq_scaling_matrix_present_flag) {
473  // Table 7-2 fallback rule A in spec.
474  FallbackScalingList4x4(
475  i, kDefault4x4Intra, kDefault4x4Inter, pps->scaling_list4x4);
476  } else {
477  // Table 7-2 fallback rule B in spec.
478  FallbackScalingList4x4(i,
479  sps.scaling_list4x4[0],
480  sps.scaling_list4x4[3],
481  pps->scaling_list4x4);
482  }
483  }
484  }
485 
486  if (pps->transform_8x8_mode_flag) {
487  for (int i = 0; i < ((sps.chroma_format_idc != 3) ? 2 : 6); ++i) {
488  READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag);
489 
490  if (pic_scaling_list_present_flag) {
491  res = ParseScalingList(br,
492  arraysize(pps->scaling_list8x8[i]),
493  pps->scaling_list8x8[i],
494  &use_default);
495  if (res != kOk)
496  return res;
497 
498  if (use_default)
499  DefaultScalingList8x8(i, pps->scaling_list8x8);
500 
501  } else {
502  if (sps.seq_scaling_matrix_present_flag) {
503  // Table 7-2 fallback rule A in spec.
504  FallbackScalingList8x8(
505  i, kDefault8x8Intra, kDefault8x8Inter, pps->scaling_list8x8);
506  } else {
507  // Table 7-2 fallback rule B in spec.
508  FallbackScalingList8x8(i,
509  sps.scaling_list8x8[0],
510  sps.scaling_list8x8[1],
511  pps->scaling_list8x8);
512  }
513  }
514  }
515  }
516  return kOk;
517 }
518 
519 H264Parser::Result H264Parser::ParseAndIgnoreHRDParameters(
520  H264BitReader* br, bool* hrd_parameters_present) {
521  int data;
522  READ_BOOL_OR_RETURN(&data); // {nal,vcl}_hrd_parameters_present_flag
523  if (!data)
524  return kOk;
525 
526  *hrd_parameters_present = true;
527 
528  int cpb_cnt_minus1;
529  READ_UE_OR_RETURN(&cpb_cnt_minus1);
530  IN_RANGE_OR_RETURN(cpb_cnt_minus1, 0, 31);
531  READ_BITS_OR_RETURN(8, &data); // bit_rate_scale, cpb_size_scale
532  for (int i = 0; i <= cpb_cnt_minus1; ++i) {
533  READ_UE_OR_RETURN(&data); // bit_rate_value_minus1[i]
534  READ_UE_OR_RETURN(&data); // cpb_size_value_minus1[i]
535  READ_BOOL_OR_RETURN(&data); // cbr_flag
536  }
537  READ_BITS_OR_RETURN(20, &data); // cpb/dpb delays, etc.
538 
539  return kOk;
540 }
541 
542 H264Parser::Result H264Parser::ParseVUIParameters(H264BitReader* br,
543  H264SPS* sps) {
544  bool aspect_ratio_info_present_flag;
545  READ_BOOL_OR_RETURN(&aspect_ratio_info_present_flag);
546  if (aspect_ratio_info_present_flag) {
547  int aspect_ratio_idc;
548  READ_BITS_OR_RETURN(8, &aspect_ratio_idc);
549  if (aspect_ratio_idc == kExtendedSar) {
550  READ_BITS_OR_RETURN(16, &sps->sar_width);
551  READ_BITS_OR_RETURN(16, &sps->sar_height);
552  } else {
553  const int max_aspect_ratio_idc = arraysize(kTableSarWidth) - 1;
554  IN_RANGE_OR_RETURN(aspect_ratio_idc, 0, max_aspect_ratio_idc);
555  sps->sar_width = kTableSarWidth[aspect_ratio_idc];
556  sps->sar_height = kTableSarHeight[aspect_ratio_idc];
557  }
558  }
559 
560  int data;
561  // Read and ignore overscan and video signal type info.
562  READ_BOOL_OR_RETURN(&data); // overscan_info_present_flag
563  if (data)
564  READ_BOOL_OR_RETURN(&data); // overscan_appropriate_flag
565 
566  READ_BOOL_OR_RETURN(&data); // video_signal_type_present_flag
567  if (data) {
568  READ_BITS_OR_RETURN(3, &data); // video_format
569  READ_BOOL_OR_RETURN(&data); // video_full_range_flag
570  READ_BOOL_OR_RETURN(&data); // colour_description_present_flag
571  if (data)
572  READ_BITS_OR_RETURN(24, &data); // color description syntax elements
573  }
574 
575  READ_BOOL_OR_RETURN(&data); // chroma_loc_info_present_flag
576  if (data) {
577  READ_UE_OR_RETURN(&data); // chroma_sample_loc_type_top_field
578  READ_UE_OR_RETURN(&data); // chroma_sample_loc_type_bottom_field
579  }
580 
581  // Read and ignore timing info.
582  READ_BOOL_OR_RETURN(&data); // timing_info_present_flag
583  if (data) {
584  READ_BITS_OR_RETURN(16, &data); // num_units_in_tick
585  READ_BITS_OR_RETURN(16, &data); // num_units_in_tick
586  READ_BITS_OR_RETURN(16, &data); // time_scale
587  READ_BITS_OR_RETURN(16, &data); // time_scale
588  READ_BOOL_OR_RETURN(&data); // fixed_frame_rate_flag
589  }
590 
591  // Read and ignore NAL HRD parameters, if present.
592  bool hrd_parameters_present = false;
593  Result res = ParseAndIgnoreHRDParameters(br, &hrd_parameters_present);
594  if (res != kOk)
595  return res;
596 
597  // Read and ignore VCL HRD parameters, if present.
598  res = ParseAndIgnoreHRDParameters(br, &hrd_parameters_present);
599  if (res != kOk)
600  return res;
601 
602  if (hrd_parameters_present) // One of NAL or VCL params present is enough.
603  READ_BOOL_OR_RETURN(&data); // low_delay_hrd_flag
604 
605  READ_BOOL_OR_RETURN(&data); // pic_struct_present_flag
606  READ_BOOL_OR_RETURN(&sps->bitstream_restriction_flag);
607  if (sps->bitstream_restriction_flag) {
608  READ_BOOL_OR_RETURN(&data); // motion_vectors_over_pic_boundaries_flag
609  READ_UE_OR_RETURN(&data); // max_bytes_per_pic_denom
610  READ_UE_OR_RETURN(&data); // max_bits_per_mb_denom
611  READ_UE_OR_RETURN(&data); // log2_max_mv_length_horizontal
612  READ_UE_OR_RETURN(&data); // log2_max_mv_length_vertical
613  READ_UE_OR_RETURN(&sps->max_num_reorder_frames);
614  READ_UE_OR_RETURN(&sps->max_dec_frame_buffering);
615  TRUE_OR_RETURN(sps->max_dec_frame_buffering >= sps->max_num_ref_frames);
616  IN_RANGE_OR_RETURN(
617  sps->max_num_reorder_frames, 0, sps->max_dec_frame_buffering);
618  }
619 
620  return kOk;
621 }
622 
623 static void FillDefaultSeqScalingLists(H264SPS* sps) {
624  for (int i = 0; i < 6; ++i)
625  for (int j = 0; j < kH264ScalingList4x4Length; ++j)
626  sps->scaling_list4x4[i][j] = 16;
627 
628  for (int i = 0; i < 6; ++i)
629  for (int j = 0; j < kH264ScalingList8x8Length; ++j)
630  sps->scaling_list8x8[i][j] = 16;
631 }
632 
633 H264Parser::Result H264Parser::ParseSPS(const Nalu& nalu, int* sps_id) {
634  // See 7.4.2.1.
635  int data;
636  Result res;
637  H264BitReader reader;
638  reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
639  H264BitReader* br = &reader;
640 
641  *sps_id = -1;
642 
643  scoped_ptr<H264SPS> sps(new H264SPS());
644 
645  READ_BITS_OR_RETURN(8, &sps->profile_idc);
646  READ_BOOL_OR_RETURN(&sps->constraint_set0_flag);
647  READ_BOOL_OR_RETURN(&sps->constraint_set1_flag);
648  READ_BOOL_OR_RETURN(&sps->constraint_set2_flag);
649  READ_BOOL_OR_RETURN(&sps->constraint_set3_flag);
650  READ_BOOL_OR_RETURN(&sps->constraint_set4_flag);
651  READ_BOOL_OR_RETURN(&sps->constraint_set5_flag);
652  READ_BITS_OR_RETURN(2, &data); // reserved_zero_2bits
653  READ_BITS_OR_RETURN(8, &sps->level_idc);
654  READ_UE_OR_RETURN(&sps->seq_parameter_set_id);
655  TRUE_OR_RETURN(sps->seq_parameter_set_id < 32);
656 
657  if (sps->profile_idc == 100 || sps->profile_idc == 110 ||
658  sps->profile_idc == 122 || sps->profile_idc == 244 ||
659  sps->profile_idc == 44 || sps->profile_idc == 83 ||
660  sps->profile_idc == 86 || sps->profile_idc == 118 ||
661  sps->profile_idc == 128) {
662  READ_UE_OR_RETURN(&sps->chroma_format_idc);
663  TRUE_OR_RETURN(sps->chroma_format_idc < 4);
664 
665  if (sps->chroma_format_idc == 3)
666  READ_BOOL_OR_RETURN(&sps->separate_colour_plane_flag);
667 
668  READ_UE_OR_RETURN(&sps->bit_depth_luma_minus8);
669  TRUE_OR_RETURN(sps->bit_depth_luma_minus8 < 7);
670 
671  READ_UE_OR_RETURN(&sps->bit_depth_chroma_minus8);
672  TRUE_OR_RETURN(sps->bit_depth_chroma_minus8 < 7);
673 
674  READ_BOOL_OR_RETURN(&sps->qpprime_y_zero_transform_bypass_flag);
675  READ_BOOL_OR_RETURN(&sps->seq_scaling_matrix_present_flag);
676 
677  if (sps->seq_scaling_matrix_present_flag) {
678  DVLOG(4) << "Scaling matrix present";
679  res = ParseSPSScalingLists(br, sps.get());
680  if (res != kOk)
681  return res;
682  } else {
683  FillDefaultSeqScalingLists(sps.get());
684  }
685  } else {
686  sps->chroma_format_idc = 1;
687  FillDefaultSeqScalingLists(sps.get());
688  }
689 
690  if (sps->separate_colour_plane_flag)
691  sps->chroma_array_type = 0;
692  else
693  sps->chroma_array_type = sps->chroma_format_idc;
694 
695  READ_UE_OR_RETURN(&sps->log2_max_frame_num_minus4);
696  TRUE_OR_RETURN(sps->log2_max_frame_num_minus4 < 13);
697 
698  READ_UE_OR_RETURN(&sps->pic_order_cnt_type);
699  TRUE_OR_RETURN(sps->pic_order_cnt_type < 3);
700 
701  sps->expected_delta_per_pic_order_cnt_cycle = 0;
702  if (sps->pic_order_cnt_type == 0) {
703  READ_UE_OR_RETURN(&sps->log2_max_pic_order_cnt_lsb_minus4);
704  TRUE_OR_RETURN(sps->log2_max_pic_order_cnt_lsb_minus4 < 13);
705  } else if (sps->pic_order_cnt_type == 1) {
706  READ_BOOL_OR_RETURN(&sps->delta_pic_order_always_zero_flag);
707  READ_SE_OR_RETURN(&sps->offset_for_non_ref_pic);
708  READ_SE_OR_RETURN(&sps->offset_for_top_to_bottom_field);
709  READ_UE_OR_RETURN(&sps->num_ref_frames_in_pic_order_cnt_cycle);
710  TRUE_OR_RETURN(sps->num_ref_frames_in_pic_order_cnt_cycle < 255);
711 
712  for (int i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; ++i) {
713  READ_SE_OR_RETURN(&sps->offset_for_ref_frame[i]);
714  sps->expected_delta_per_pic_order_cnt_cycle +=
715  sps->offset_for_ref_frame[i];
716  }
717  }
718 
719  READ_UE_OR_RETURN(&sps->max_num_ref_frames);
720  READ_BOOL_OR_RETURN(&sps->gaps_in_frame_num_value_allowed_flag);
721 
722  if (sps->gaps_in_frame_num_value_allowed_flag)
723  return kUnsupportedStream;
724 
725  READ_UE_OR_RETURN(&sps->pic_width_in_mbs_minus1);
726  READ_UE_OR_RETURN(&sps->pic_height_in_map_units_minus1);
727 
728  READ_BOOL_OR_RETURN(&sps->frame_mbs_only_flag);
729  if (!sps->frame_mbs_only_flag)
730  READ_BOOL_OR_RETURN(&sps->mb_adaptive_frame_field_flag);
731 
732  READ_BOOL_OR_RETURN(&sps->direct_8x8_inference_flag);
733 
734  READ_BOOL_OR_RETURN(&sps->frame_cropping_flag);
735  if (sps->frame_cropping_flag) {
736  READ_UE_OR_RETURN(&sps->frame_crop_left_offset);
737  READ_UE_OR_RETURN(&sps->frame_crop_right_offset);
738  READ_UE_OR_RETURN(&sps->frame_crop_top_offset);
739  READ_UE_OR_RETURN(&sps->frame_crop_bottom_offset);
740  }
741 
742  READ_BOOL_OR_RETURN(&sps->vui_parameters_present_flag);
743  if (sps->vui_parameters_present_flag) {
744  DVLOG(4) << "VUI parameters present";
745  res = ParseVUIParameters(br, sps.get());
746  if (res != kOk)
747  return res;
748  }
749 
750  // If an SPS with the same id already exists, replace it.
751  *sps_id = sps->seq_parameter_set_id;
752  delete active_SPSes_[*sps_id];
753  active_SPSes_[*sps_id] = sps.release();
754 
755  return kOk;
756 }
757 
758 H264Parser::Result H264Parser::ParsePPS(const Nalu& nalu, int* pps_id) {
759  // See 7.4.2.2.
760  const H264SPS* sps;
761  Result res;
762  H264BitReader reader;
763  reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
764  H264BitReader* br = &reader;
765 
766  *pps_id = -1;
767 
768  scoped_ptr<H264PPS> pps(new H264PPS());
769 
770  READ_UE_OR_RETURN(&pps->pic_parameter_set_id);
771  READ_UE_OR_RETURN(&pps->seq_parameter_set_id);
772  TRUE_OR_RETURN(pps->seq_parameter_set_id < 32);
773 
774  sps = GetSPS(pps->seq_parameter_set_id);
775  TRUE_OR_RETURN(sps);
776 
777  READ_BOOL_OR_RETURN(&pps->entropy_coding_mode_flag);
778  READ_BOOL_OR_RETURN(&pps->bottom_field_pic_order_in_frame_present_flag);
779 
780  READ_UE_OR_RETURN(&pps->num_slice_groups_minus1);
781  if (pps->num_slice_groups_minus1 > 1) {
782  DVLOG(1) << "Slice groups not supported";
783  return kUnsupportedStream;
784  }
785 
786  READ_UE_OR_RETURN(&pps->num_ref_idx_l0_default_active_minus1);
787  TRUE_OR_RETURN(pps->num_ref_idx_l0_default_active_minus1 < 32);
788 
789  READ_UE_OR_RETURN(&pps->num_ref_idx_l1_default_active_minus1);
790  TRUE_OR_RETURN(pps->num_ref_idx_l1_default_active_minus1 < 32);
791 
792  READ_BOOL_OR_RETURN(&pps->weighted_pred_flag);
793  READ_BITS_OR_RETURN(2, &pps->weighted_bipred_idc);
794  TRUE_OR_RETURN(pps->weighted_bipred_idc < 3);
795 
796  READ_SE_OR_RETURN(&pps->pic_init_qp_minus26);
797  IN_RANGE_OR_RETURN(pps->pic_init_qp_minus26, -26, 25);
798 
799  READ_SE_OR_RETURN(&pps->pic_init_qs_minus26);
800  IN_RANGE_OR_RETURN(pps->pic_init_qs_minus26, -26, 25);
801 
802  READ_SE_OR_RETURN(&pps->chroma_qp_index_offset);
803  IN_RANGE_OR_RETURN(pps->chroma_qp_index_offset, -12, 12);
804  pps->second_chroma_qp_index_offset = pps->chroma_qp_index_offset;
805 
806  READ_BOOL_OR_RETURN(&pps->deblocking_filter_control_present_flag);
807  READ_BOOL_OR_RETURN(&pps->constrained_intra_pred_flag);
808  READ_BOOL_OR_RETURN(&pps->redundant_pic_cnt_present_flag);
809 
810  if (br->HasMoreRBSPData()) {
811  READ_BOOL_OR_RETURN(&pps->transform_8x8_mode_flag);
812  READ_BOOL_OR_RETURN(&pps->pic_scaling_matrix_present_flag);
813 
814  if (pps->pic_scaling_matrix_present_flag) {
815  DVLOG(4) << "Picture scaling matrix present";
816  res = ParsePPSScalingLists(br, *sps, pps.get());
817  if (res != kOk)
818  return res;
819  }
820 
821  READ_SE_OR_RETURN(&pps->second_chroma_qp_index_offset);
822  }
823 
824  // If a PPS with the same id already exists, replace it.
825  *pps_id = pps->pic_parameter_set_id;
826  delete active_PPSes_[*pps_id];
827  active_PPSes_[*pps_id] = pps.release();
828 
829  return kOk;
830 }
831 
832 H264Parser::Result H264Parser::ParseRefPicListModification(
833  H264BitReader* br,
834  int num_ref_idx_active_minus1,
835  H264ModificationOfPicNum* ref_list_mods) {
836  H264ModificationOfPicNum* pic_num_mod;
837 
838  if (num_ref_idx_active_minus1 >= 32)
839  return kInvalidStream;
840 
841  for (int i = 0; i < 32; ++i) {
842  pic_num_mod = &ref_list_mods[i];
843  READ_UE_OR_RETURN(&pic_num_mod->modification_of_pic_nums_idc);
844  TRUE_OR_RETURN(pic_num_mod->modification_of_pic_nums_idc < 4);
845 
846  switch (pic_num_mod->modification_of_pic_nums_idc) {
847  case 0:
848  case 1:
849  READ_UE_OR_RETURN(&pic_num_mod->abs_diff_pic_num_minus1);
850  break;
851 
852  case 2:
853  READ_UE_OR_RETURN(&pic_num_mod->long_term_pic_num);
854  break;
855 
856  case 3:
857  // Per spec, list cannot be empty.
858  if (i == 0)
859  return kInvalidStream;
860  return kOk;
861 
862  default:
863  return kInvalidStream;
864  }
865  }
866 
867  // If we got here, we didn't get loop end marker prematurely,
868  // so make sure it is there for our client.
869  int modification_of_pic_nums_idc;
870  READ_UE_OR_RETURN(&modification_of_pic_nums_idc);
871  TRUE_OR_RETURN(modification_of_pic_nums_idc == 3);
872 
873  return kOk;
874 }
875 
876 H264Parser::Result H264Parser::ParseRefPicListModifications(
877  H264BitReader* br, H264SliceHeader* shdr) {
878  Result res;
879 
880  if (!shdr->IsISlice() && !shdr->IsSISlice()) {
881  READ_BOOL_OR_RETURN(&shdr->ref_pic_list_modification_flag_l0);
882  if (shdr->ref_pic_list_modification_flag_l0) {
883  res = ParseRefPicListModification(br, shdr->num_ref_idx_l0_active_minus1,
884  shdr->ref_list_l0_modifications);
885  if (res != kOk)
886  return res;
887  }
888  }
889 
890  if (shdr->IsBSlice()) {
891  READ_BOOL_OR_RETURN(&shdr->ref_pic_list_modification_flag_l1);
892  if (shdr->ref_pic_list_modification_flag_l1) {
893  res = ParseRefPicListModification(br, shdr->num_ref_idx_l1_active_minus1,
894  shdr->ref_list_l1_modifications);
895  if (res != kOk)
896  return res;
897  }
898  }
899 
900  return kOk;
901 }
902 
903 H264Parser::Result H264Parser::ParseWeightingFactors(
904  H264BitReader* br,
905  int num_ref_idx_active_minus1,
906  int chroma_array_type,
907  int luma_log2_weight_denom,
908  int chroma_log2_weight_denom,
909  H264WeightingFactors* w_facts) {
910  int def_luma_weight = 1 << luma_log2_weight_denom;
911  int def_chroma_weight = 1 << chroma_log2_weight_denom;
912 
913  for (int i = 0; i < num_ref_idx_active_minus1 + 1; ++i) {
914  READ_BOOL_OR_RETURN(&w_facts->luma_weight_flag);
915  if (w_facts->luma_weight_flag) {
916  READ_SE_OR_RETURN(&w_facts->luma_weight[i]);
917  IN_RANGE_OR_RETURN(w_facts->luma_weight[i], -128, 127);
918 
919  READ_SE_OR_RETURN(&w_facts->luma_offset[i]);
920  IN_RANGE_OR_RETURN(w_facts->luma_offset[i], -128, 127);
921  } else {
922  w_facts->luma_weight[i] = def_luma_weight;
923  w_facts->luma_offset[i] = 0;
924  }
925 
926  if (chroma_array_type != 0) {
927  READ_BOOL_OR_RETURN(&w_facts->chroma_weight_flag);
928  if (w_facts->chroma_weight_flag) {
929  for (int j = 0; j < 2; ++j) {
930  READ_SE_OR_RETURN(&w_facts->chroma_weight[i][j]);
931  IN_RANGE_OR_RETURN(w_facts->chroma_weight[i][j], -128, 127);
932 
933  READ_SE_OR_RETURN(&w_facts->chroma_offset[i][j]);
934  IN_RANGE_OR_RETURN(w_facts->chroma_offset[i][j], -128, 127);
935  }
936  } else {
937  for (int j = 0; j < 2; ++j) {
938  w_facts->chroma_weight[i][j] = def_chroma_weight;
939  w_facts->chroma_offset[i][j] = 0;
940  }
941  }
942  }
943  }
944 
945  return kOk;
946 }
947 
948 H264Parser::Result H264Parser::ParsePredWeightTable(H264BitReader* br,
949  const H264SPS& sps,
950  H264SliceHeader* shdr) {
951  READ_UE_OR_RETURN(&shdr->luma_log2_weight_denom);
952  TRUE_OR_RETURN(shdr->luma_log2_weight_denom < 8);
953 
954  if (sps.chroma_array_type != 0)
955  READ_UE_OR_RETURN(&shdr->chroma_log2_weight_denom);
956  TRUE_OR_RETURN(shdr->chroma_log2_weight_denom < 8);
957 
958  Result res = ParseWeightingFactors(br,
959  shdr->num_ref_idx_l0_active_minus1,
960  sps.chroma_array_type,
961  shdr->luma_log2_weight_denom,
962  shdr->chroma_log2_weight_denom,
963  &shdr->pred_weight_table_l0);
964  if (res != kOk)
965  return res;
966 
967  if (shdr->IsBSlice()) {
968  res = ParseWeightingFactors(br,
969  shdr->num_ref_idx_l1_active_minus1,
970  sps.chroma_array_type,
971  shdr->luma_log2_weight_denom,
972  shdr->chroma_log2_weight_denom,
973  &shdr->pred_weight_table_l1);
974  if (res != kOk)
975  return res;
976  }
977 
978  return kOk;
979 }
980 
981 H264Parser::Result H264Parser::ParseDecRefPicMarking(H264BitReader* br,
982  H264SliceHeader* shdr) {
983  if (shdr->idr_pic_flag) {
984  READ_BOOL_OR_RETURN(&shdr->no_output_of_prior_pics_flag);
985  READ_BOOL_OR_RETURN(&shdr->long_term_reference_flag);
986  } else {
987  READ_BOOL_OR_RETURN(&shdr->adaptive_ref_pic_marking_mode_flag);
988 
989  H264DecRefPicMarking* marking;
990  if (shdr->adaptive_ref_pic_marking_mode_flag) {
991  size_t i;
992  for (i = 0; i < arraysize(shdr->ref_pic_marking); ++i) {
993  marking = &shdr->ref_pic_marking[i];
994 
995  READ_UE_OR_RETURN(&marking->memory_mgmnt_control_operation);
996  if (marking->memory_mgmnt_control_operation == 0)
997  break;
998 
999  if (marking->memory_mgmnt_control_operation == 1 ||
1000  marking->memory_mgmnt_control_operation == 3)
1001  READ_UE_OR_RETURN(&marking->difference_of_pic_nums_minus1);
1002 
1003  if (marking->memory_mgmnt_control_operation == 2)
1004  READ_UE_OR_RETURN(&marking->long_term_pic_num);
1005 
1006  if (marking->memory_mgmnt_control_operation == 3 ||
1007  marking->memory_mgmnt_control_operation == 6)
1008  READ_UE_OR_RETURN(&marking->long_term_frame_idx);
1009 
1010  if (marking->memory_mgmnt_control_operation == 4)
1011  READ_UE_OR_RETURN(&marking->max_long_term_frame_idx_plus1);
1012 
1013  if (marking->memory_mgmnt_control_operation > 6)
1014  return kInvalidStream;
1015  }
1016 
1017  if (i == arraysize(shdr->ref_pic_marking)) {
1018  DVLOG(1) << "Ran out of dec ref pic marking fields";
1019  return kUnsupportedStream;
1020  }
1021  }
1022  }
1023 
1024  return kOk;
1025 }
1026 
1027 H264Parser::Result H264Parser::ParseSliceHeader(const Nalu& nalu,
1028  H264SliceHeader* shdr) {
1029  // See 7.4.3.
1030  const H264SPS* sps;
1031  const H264PPS* pps;
1032  Result res;
1033  H264BitReader reader;
1034  reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
1035  H264BitReader* br = &reader;
1036 
1037  memset(shdr, 0, sizeof(*shdr));
1038 
1039  shdr->idr_pic_flag = (nalu.type() == 5);
1040  shdr->nal_ref_idc = nalu.ref_idc();
1041  shdr->nalu_data = nalu.data() + nalu.header_size();
1042  shdr->nalu_size = nalu.payload_size();
1043 
1044  READ_UE_OR_RETURN(&shdr->first_mb_in_slice);
1045  READ_UE_OR_RETURN(&shdr->slice_type);
1046  TRUE_OR_RETURN(shdr->slice_type < 10);
1047 
1048  READ_UE_OR_RETURN(&shdr->pic_parameter_set_id);
1049 
1050  pps = GetPPS(shdr->pic_parameter_set_id);
1051  TRUE_OR_RETURN(pps);
1052 
1053  sps = GetSPS(pps->seq_parameter_set_id);
1054  TRUE_OR_RETURN(sps);
1055 
1056  if (sps->separate_colour_plane_flag) {
1057  DVLOG(1) << "Interlaced streams not supported";
1058  return kUnsupportedStream;
1059  }
1060 
1061  READ_BITS_OR_RETURN(sps->log2_max_frame_num_minus4 + 4, &shdr->frame_num);
1062  if (!sps->frame_mbs_only_flag) {
1063  READ_BOOL_OR_RETURN(&shdr->field_pic_flag);
1064  if (shdr->field_pic_flag) {
1065  DVLOG(1) << "Interlaced streams not supported";
1066  return kUnsupportedStream;
1067  }
1068  }
1069 
1070  if (shdr->idr_pic_flag)
1071  READ_UE_OR_RETURN(&shdr->idr_pic_id);
1072 
1073  if (sps->pic_order_cnt_type == 0) {
1074  READ_BITS_OR_RETURN(sps->log2_max_pic_order_cnt_lsb_minus4 + 4,
1075  &shdr->pic_order_cnt_lsb);
1076  if (pps->bottom_field_pic_order_in_frame_present_flag &&
1077  !shdr->field_pic_flag)
1078  READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt_bottom);
1079  }
1080 
1081  if (sps->pic_order_cnt_type == 1 && !sps->delta_pic_order_always_zero_flag) {
1082  READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt[0]);
1083  if (pps->bottom_field_pic_order_in_frame_present_flag &&
1084  !shdr->field_pic_flag)
1085  READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt[1]);
1086  }
1087 
1088  if (pps->redundant_pic_cnt_present_flag) {
1089  READ_UE_OR_RETURN(&shdr->redundant_pic_cnt);
1090  TRUE_OR_RETURN(shdr->redundant_pic_cnt < 128);
1091  }
1092 
1093  if (shdr->IsBSlice())
1094  READ_BOOL_OR_RETURN(&shdr->direct_spatial_mv_pred_flag);
1095 
1096  if (shdr->IsPSlice() || shdr->IsSPSlice() || shdr->IsBSlice()) {
1097  READ_BOOL_OR_RETURN(&shdr->num_ref_idx_active_override_flag);
1098  if (shdr->num_ref_idx_active_override_flag) {
1099  READ_UE_OR_RETURN(&shdr->num_ref_idx_l0_active_minus1);
1100  if (shdr->IsBSlice())
1101  READ_UE_OR_RETURN(&shdr->num_ref_idx_l1_active_minus1);
1102  } else {
1103  shdr->num_ref_idx_l0_active_minus1 =
1104  pps->num_ref_idx_l0_default_active_minus1;
1105  if (shdr->IsBSlice()) {
1106  shdr->num_ref_idx_l1_active_minus1 =
1107  pps->num_ref_idx_l1_default_active_minus1;
1108  }
1109  }
1110  }
1111  if (shdr->field_pic_flag) {
1112  TRUE_OR_RETURN(shdr->num_ref_idx_l0_active_minus1 < 32);
1113  TRUE_OR_RETURN(shdr->num_ref_idx_l1_active_minus1 < 32);
1114  } else {
1115  TRUE_OR_RETURN(shdr->num_ref_idx_l0_active_minus1 < 16);
1116  TRUE_OR_RETURN(shdr->num_ref_idx_l1_active_minus1 < 16);
1117  }
1118 
1119  if (nalu.type() == Nalu::H264_CodedSliceExtension) {
1120  return kUnsupportedStream;
1121  } else {
1122  res = ParseRefPicListModifications(br, shdr);
1123  if (res != kOk)
1124  return res;
1125  }
1126 
1127  if ((pps->weighted_pred_flag && (shdr->IsPSlice() || shdr->IsSPSlice())) ||
1128  (pps->weighted_bipred_idc == 1 && shdr->IsBSlice())) {
1129  res = ParsePredWeightTable(br, *sps, shdr);
1130  if (res != kOk)
1131  return res;
1132  }
1133 
1134  if (nalu.ref_idc() != 0) {
1135  res = ParseDecRefPicMarking(br, shdr);
1136  if (res != kOk)
1137  return res;
1138  }
1139 
1140  if (pps->entropy_coding_mode_flag && !shdr->IsISlice() &&
1141  !shdr->IsSISlice()) {
1142  READ_UE_OR_RETURN(&shdr->cabac_init_idc);
1143  TRUE_OR_RETURN(shdr->cabac_init_idc < 3);
1144  }
1145 
1146  READ_SE_OR_RETURN(&shdr->slice_qp_delta);
1147 
1148  if (shdr->IsSPSlice() || shdr->IsSISlice()) {
1149  if (shdr->IsSPSlice())
1150  READ_BOOL_OR_RETURN(&shdr->sp_for_switch_flag);
1151  READ_SE_OR_RETURN(&shdr->slice_qs_delta);
1152  }
1153 
1154  if (pps->deblocking_filter_control_present_flag) {
1155  READ_UE_OR_RETURN(&shdr->disable_deblocking_filter_idc);
1156  TRUE_OR_RETURN(shdr->disable_deblocking_filter_idc < 3);
1157 
1158  if (shdr->disable_deblocking_filter_idc != 1) {
1159  READ_SE_OR_RETURN(&shdr->slice_alpha_c0_offset_div2);
1160  IN_RANGE_OR_RETURN(shdr->slice_alpha_c0_offset_div2, -6, 6);
1161 
1162  READ_SE_OR_RETURN(&shdr->slice_beta_offset_div2);
1163  IN_RANGE_OR_RETURN(shdr->slice_beta_offset_div2, -6, 6);
1164  }
1165  }
1166 
1167  if (pps->num_slice_groups_minus1 > 0) {
1168  DVLOG(1) << "Slice groups not supported";
1169  return kUnsupportedStream;
1170  }
1171 
1172  size_t epb = br->NumEmulationPreventionBytesRead();
1173  shdr->header_bit_size = (shdr->nalu_size - epb) * 8 - br->NumBitsLeft();
1174 
1175  return kOk;
1176 }
1177 
1178 H264Parser::Result H264Parser::ParseSEI(const Nalu& nalu,
1179  H264SEIMessage* sei_msg) {
1180  int byte;
1181  H264BitReader reader;
1182  reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
1183  H264BitReader* br = &reader;
1184 
1185  memset(sei_msg, 0, sizeof(*sei_msg));
1186 
1187  READ_BITS_OR_RETURN(8, &byte);
1188  while (byte == 0xff) {
1189  sei_msg->type += 255;
1190  READ_BITS_OR_RETURN(8, &byte);
1191  }
1192  sei_msg->type += byte;
1193 
1194  READ_BITS_OR_RETURN(8, &byte);
1195  while (byte == 0xff) {
1196  sei_msg->payload_size += 255;
1197  READ_BITS_OR_RETURN(8, &byte);
1198  }
1199  sei_msg->payload_size += byte;
1200 
1201  DVLOG(4) << "Found SEI message type: " << sei_msg->type
1202  << " payload size: " << sei_msg->payload_size;
1203 
1204  switch (sei_msg->type) {
1205  case H264SEIMessage::kSEIRecoveryPoint:
1206  READ_UE_OR_RETURN(&sei_msg->recovery_point.recovery_frame_cnt);
1207  READ_BOOL_OR_RETURN(&sei_msg->recovery_point.exact_match_flag);
1208  READ_BOOL_OR_RETURN(&sei_msg->recovery_point.broken_link_flag);
1209  READ_BITS_OR_RETURN(2, &sei_msg->recovery_point.changing_slice_group_idc);
1210  break;
1211 
1212  default:
1213  DVLOG(4) << "Unsupported SEI message";
1214  break;
1215  }
1216 
1217  return kOk;
1218 }
1219 
1220 } // namespace media
1221 } // namespace edash_packager