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