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