Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(814)

Side by Side Diff: content/common/gpu/media/h264_parser.cc

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

Powered by Google App Engine
This is Rietveld 408576698