OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <algorithm> | 5 #include <algorithm> |
6 #include <limits> | 6 #include <limits> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 dpb_.Clear(); | 56 dpb_.Clear(); |
57 parser_.Reset(); | 57 parser_.Reset(); |
58 accelerator_->Reset(); | 58 accelerator_->Reset(); |
59 last_output_poc_ = std::numeric_limits<int>::min(); | 59 last_output_poc_ = std::numeric_limits<int>::min(); |
60 | 60 |
61 // If we are in kDecoding, we can resume without processing an SPS. | 61 // If we are in kDecoding, we can resume without processing an SPS. |
62 if (state_ == kDecoding) | 62 if (state_ == kDecoding) |
63 state_ = kAfterReset; | 63 state_ = kAfterReset; |
64 } | 64 } |
65 | 65 |
66 void H264Decoder::PrepareRefPicLists(const media::H264SliceHeader* slice_hdr) { | 66 void H264Decoder::PrepareRefPicLists(const H264SliceHeader* slice_hdr) { |
67 ConstructReferencePicListsP(slice_hdr); | 67 ConstructReferencePicListsP(slice_hdr); |
68 ConstructReferencePicListsB(slice_hdr); | 68 ConstructReferencePicListsB(slice_hdr); |
69 } | 69 } |
70 | 70 |
71 bool H264Decoder::ModifyReferencePicLists( | 71 bool H264Decoder::ModifyReferencePicLists(const H264SliceHeader* slice_hdr, |
72 const media::H264SliceHeader* slice_hdr, | 72 H264Picture::Vector* ref_pic_list0, |
73 H264Picture::Vector* ref_pic_list0, | 73 H264Picture::Vector* ref_pic_list1) { |
74 H264Picture::Vector* ref_pic_list1) { | |
75 ref_pic_list0->clear(); | 74 ref_pic_list0->clear(); |
76 ref_pic_list1->clear(); | 75 ref_pic_list1->clear(); |
77 | 76 |
78 // Fill reference picture lists for B and S/SP slices. | 77 // Fill reference picture lists for B and S/SP slices. |
79 if (slice_hdr->IsPSlice() || slice_hdr->IsSPSlice()) { | 78 if (slice_hdr->IsPSlice() || slice_hdr->IsSPSlice()) { |
80 *ref_pic_list0 = ref_pic_list_p0_; | 79 *ref_pic_list0 = ref_pic_list_p0_; |
81 return ModifyReferencePicList(slice_hdr, 0, ref_pic_list0); | 80 return ModifyReferencePicList(slice_hdr, 0, ref_pic_list0); |
82 } else if (slice_hdr->IsBSlice()) { | 81 } else if (slice_hdr->IsBSlice()) { |
83 *ref_pic_list0 = ref_pic_list_b0_; | 82 *ref_pic_list0 = ref_pic_list_b0_; |
84 *ref_pic_list1 = ref_pic_list_b1_; | 83 *ref_pic_list1 = ref_pic_list_b1_; |
(...skipping 17 matching lines...) Expand all Loading... |
102 pic->nal_ref_idc = 1; | 101 pic->nal_ref_idc = 1; |
103 pic->frame_num = pic->pic_num = frame_num; | 102 pic->frame_num = pic->pic_num = frame_num; |
104 pic->adaptive_ref_pic_marking_mode_flag = false; | 103 pic->adaptive_ref_pic_marking_mode_flag = false; |
105 pic->ref = true; | 104 pic->ref = true; |
106 pic->long_term_reference_flag = false; | 105 pic->long_term_reference_flag = false; |
107 pic->field = H264Picture::FIELD_NONE; | 106 pic->field = H264Picture::FIELD_NONE; |
108 | 107 |
109 return CalculatePicOrderCounts(pic); | 108 return CalculatePicOrderCounts(pic); |
110 } | 109 } |
111 | 110 |
112 bool H264Decoder::InitCurrPicture(const media::H264SliceHeader* slice_hdr) { | 111 bool H264Decoder::InitCurrPicture(const H264SliceHeader* slice_hdr) { |
113 DCHECK(curr_pic_.get()); | 112 DCHECK(curr_pic_.get()); |
114 | 113 |
115 curr_pic_->idr = slice_hdr->idr_pic_flag; | 114 curr_pic_->idr = slice_hdr->idr_pic_flag; |
116 if (curr_pic_->idr) | 115 if (curr_pic_->idr) |
117 curr_pic_->idr_pic_id = slice_hdr->idr_pic_id; | 116 curr_pic_->idr_pic_id = slice_hdr->idr_pic_id; |
118 | 117 |
119 if (slice_hdr->field_pic_flag) { | 118 if (slice_hdr->field_pic_flag) { |
120 curr_pic_->field = slice_hdr->bottom_field_flag ? H264Picture::FIELD_BOTTOM | 119 curr_pic_->field = slice_hdr->bottom_field_flag ? H264Picture::FIELD_BOTTOM |
121 : H264Picture::FIELD_TOP; | 120 : H264Picture::FIELD_TOP; |
122 } else { | 121 } else { |
123 curr_pic_->field = H264Picture::FIELD_NONE; | 122 curr_pic_->field = H264Picture::FIELD_NONE; |
124 } | 123 } |
125 | 124 |
126 if (curr_pic_->field != H264Picture::FIELD_NONE) { | 125 if (curr_pic_->field != H264Picture::FIELD_NONE) { |
127 DVLOG(1) << "Interlaced video not supported."; | 126 DVLOG(1) << "Interlaced video not supported."; |
128 return false; | 127 return false; |
129 } | 128 } |
130 | 129 |
131 curr_pic_->nal_ref_idc = slice_hdr->nal_ref_idc; | 130 curr_pic_->nal_ref_idc = slice_hdr->nal_ref_idc; |
132 curr_pic_->ref = slice_hdr->nal_ref_idc != 0; | 131 curr_pic_->ref = slice_hdr->nal_ref_idc != 0; |
133 // This assumes non-interlaced stream. | 132 // This assumes non-interlaced stream. |
134 curr_pic_->frame_num = curr_pic_->pic_num = slice_hdr->frame_num; | 133 curr_pic_->frame_num = curr_pic_->pic_num = slice_hdr->frame_num; |
135 | 134 |
136 DCHECK_NE(curr_sps_id_, -1); | 135 DCHECK_NE(curr_sps_id_, -1); |
137 const media::H264SPS* sps = parser_.GetSPS(curr_sps_id_); | 136 const H264SPS* sps = parser_.GetSPS(curr_sps_id_); |
138 if (!sps) | 137 if (!sps) |
139 return false; | 138 return false; |
140 | 139 |
141 curr_pic_->pic_order_cnt_type = sps->pic_order_cnt_type; | 140 curr_pic_->pic_order_cnt_type = sps->pic_order_cnt_type; |
142 switch (curr_pic_->pic_order_cnt_type) { | 141 switch (curr_pic_->pic_order_cnt_type) { |
143 case 0: | 142 case 0: |
144 curr_pic_->pic_order_cnt_lsb = slice_hdr->pic_order_cnt_lsb; | 143 curr_pic_->pic_order_cnt_lsb = slice_hdr->pic_order_cnt_lsb; |
145 curr_pic_->delta_pic_order_cnt_bottom = | 144 curr_pic_->delta_pic_order_cnt_bottom = |
146 slice_hdr->delta_pic_order_cnt_bottom; | 145 slice_hdr->delta_pic_order_cnt_bottom; |
147 break; | 146 break; |
(...skipping 26 matching lines...) Expand all Loading... |
174 sizeof(slice_hdr->ref_pic_marking), | 173 sizeof(slice_hdr->ref_pic_marking), |
175 "Array sizes of ref pic marking do not match."); | 174 "Array sizes of ref pic marking do not match."); |
176 memcpy(curr_pic_->ref_pic_marking, slice_hdr->ref_pic_marking, | 175 memcpy(curr_pic_->ref_pic_marking, slice_hdr->ref_pic_marking, |
177 sizeof(curr_pic_->ref_pic_marking)); | 176 sizeof(curr_pic_->ref_pic_marking)); |
178 } | 177 } |
179 | 178 |
180 return true; | 179 return true; |
181 } | 180 } |
182 | 181 |
183 bool H264Decoder::CalculatePicOrderCounts(scoped_refptr<H264Picture> pic) { | 182 bool H264Decoder::CalculatePicOrderCounts(scoped_refptr<H264Picture> pic) { |
184 const media::H264SPS* sps = parser_.GetSPS(curr_sps_id_); | 183 const H264SPS* sps = parser_.GetSPS(curr_sps_id_); |
185 if (!sps) | 184 if (!sps) |
186 return false; | 185 return false; |
187 | 186 |
188 switch (pic->pic_order_cnt_type) { | 187 switch (pic->pic_order_cnt_type) { |
189 case 0: { | 188 case 0: { |
190 // See spec 8.2.1.1. | 189 // See spec 8.2.1.1. |
191 int prev_pic_order_cnt_msb, prev_pic_order_cnt_lsb; | 190 int prev_pic_order_cnt_msb, prev_pic_order_cnt_lsb; |
192 | 191 |
193 if (pic->idr) { | 192 if (pic->idr) { |
194 prev_pic_order_cnt_msb = prev_pic_order_cnt_lsb = 0; | 193 prev_pic_order_cnt_msb = prev_pic_order_cnt_lsb = 0; |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 }; | 380 }; |
382 | 381 |
383 struct LongTermPicNumAscCompare { | 382 struct LongTermPicNumAscCompare { |
384 bool operator()(const scoped_refptr<H264Picture>& a, | 383 bool operator()(const scoped_refptr<H264Picture>& a, |
385 const scoped_refptr<H264Picture>& b) const { | 384 const scoped_refptr<H264Picture>& b) const { |
386 return a->long_term_pic_num < b->long_term_pic_num; | 385 return a->long_term_pic_num < b->long_term_pic_num; |
387 } | 386 } |
388 }; | 387 }; |
389 | 388 |
390 void H264Decoder::ConstructReferencePicListsP( | 389 void H264Decoder::ConstructReferencePicListsP( |
391 const media::H264SliceHeader* slice_hdr) { | 390 const H264SliceHeader* slice_hdr) { |
392 // RefPicList0 (8.2.4.2.1) [[1] [2]], where: | 391 // RefPicList0 (8.2.4.2.1) [[1] [2]], where: |
393 // [1] shortterm ref pics sorted by descending pic_num, | 392 // [1] shortterm ref pics sorted by descending pic_num, |
394 // [2] longterm ref pics by ascending long_term_pic_num. | 393 // [2] longterm ref pics by ascending long_term_pic_num. |
395 ref_pic_list_p0_.clear(); | 394 ref_pic_list_p0_.clear(); |
396 | 395 |
397 // First get the short ref pics... | 396 // First get the short ref pics... |
398 dpb_.GetShortTermRefPicsAppending(&ref_pic_list_p0_); | 397 dpb_.GetShortTermRefPicsAppending(&ref_pic_list_p0_); |
399 size_t num_short_refs = ref_pic_list_p0_.size(); | 398 size_t num_short_refs = ref_pic_list_p0_.size(); |
400 | 399 |
401 // and sort them to get [1]. | 400 // and sort them to get [1]. |
(...skipping 14 matching lines...) Expand all Loading... |
416 }; | 415 }; |
417 | 416 |
418 struct POCDescCompare { | 417 struct POCDescCompare { |
419 bool operator()(const scoped_refptr<H264Picture>& a, | 418 bool operator()(const scoped_refptr<H264Picture>& a, |
420 const scoped_refptr<H264Picture>& b) const { | 419 const scoped_refptr<H264Picture>& b) const { |
421 return a->pic_order_cnt > b->pic_order_cnt; | 420 return a->pic_order_cnt > b->pic_order_cnt; |
422 } | 421 } |
423 }; | 422 }; |
424 | 423 |
425 void H264Decoder::ConstructReferencePicListsB( | 424 void H264Decoder::ConstructReferencePicListsB( |
426 const media::H264SliceHeader* slice_hdr) { | 425 const H264SliceHeader* slice_hdr) { |
427 // RefPicList0 (8.2.4.2.3) [[1] [2] [3]], where: | 426 // RefPicList0 (8.2.4.2.3) [[1] [2] [3]], where: |
428 // [1] shortterm ref pics with POC < curr_pic's POC sorted by descending POC, | 427 // [1] shortterm ref pics with POC < curr_pic's POC sorted by descending POC, |
429 // [2] shortterm ref pics with POC > curr_pic's POC by ascending POC, | 428 // [2] shortterm ref pics with POC > curr_pic's POC by ascending POC, |
430 // [3] longterm ref pics by ascending long_term_pic_num. | 429 // [3] longterm ref pics by ascending long_term_pic_num. |
431 ref_pic_list_b0_.clear(); | 430 ref_pic_list_b0_.clear(); |
432 ref_pic_list_b1_.clear(); | 431 ref_pic_list_b1_.clear(); |
433 dpb_.GetShortTermRefPicsAppending(&ref_pic_list_b0_); | 432 dpb_.GetShortTermRefPicsAppending(&ref_pic_list_b0_); |
434 size_t num_short_refs = ref_pic_list_b0_.size(); | 433 size_t num_short_refs = ref_pic_list_b0_.size(); |
435 | 434 |
436 // First sort ascending, this will put [1] in right place and finish [2]. | 435 // First sort ascending, this will put [1] in right place and finish [2]. |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 (to + 2 == static_cast<int>(v->size()))); | 513 (to + 2 == static_cast<int>(v->size()))); |
515 | 514 |
516 v->resize(to + 2); | 515 v->resize(to + 2); |
517 | 516 |
518 for (int i = to + 1; i > from; --i) | 517 for (int i = to + 1; i > from; --i) |
519 (*v)[i] = (*v)[i - 1]; | 518 (*v)[i] = (*v)[i - 1]; |
520 | 519 |
521 (*v)[from] = pic; | 520 (*v)[from] = pic; |
522 } | 521 } |
523 | 522 |
524 bool H264Decoder::ModifyReferencePicList( | 523 bool H264Decoder::ModifyReferencePicList(const H264SliceHeader* slice_hdr, |
525 const media::H264SliceHeader* slice_hdr, | 524 int list, |
526 int list, | 525 H264Picture::Vector* ref_pic_listx) { |
527 H264Picture::Vector* ref_pic_listx) { | |
528 bool ref_pic_list_modification_flag_lX; | 526 bool ref_pic_list_modification_flag_lX; |
529 int num_ref_idx_lX_active_minus1; | 527 int num_ref_idx_lX_active_minus1; |
530 const media::H264ModificationOfPicNum* list_mod; | 528 const H264ModificationOfPicNum* list_mod; |
531 | 529 |
532 // This can process either ref_pic_list0 or ref_pic_list1, depending on | 530 // This can process either ref_pic_list0 or ref_pic_list1, depending on |
533 // the list argument. Set up pointers to proper list to be processed here. | 531 // the list argument. Set up pointers to proper list to be processed here. |
534 if (list == 0) { | 532 if (list == 0) { |
535 ref_pic_list_modification_flag_lX = | 533 ref_pic_list_modification_flag_lX = |
536 slice_hdr->ref_pic_list_modification_flag_l0; | 534 slice_hdr->ref_pic_list_modification_flag_l0; |
537 num_ref_idx_lX_active_minus1 = slice_hdr->num_ref_idx_l0_active_minus1; | 535 num_ref_idx_lX_active_minus1 = slice_hdr->num_ref_idx_l0_active_minus1; |
538 list_mod = slice_hdr->ref_list_l0_modifications; | 536 list_mod = slice_hdr->ref_list_l0_modifications; |
539 } else { | 537 } else { |
540 ref_pic_list_modification_flag_lX = | 538 ref_pic_list_modification_flag_lX = |
(...skipping 14 matching lines...) Expand all Loading... |
555 return true; | 553 return true; |
556 | 554 |
557 // Spec 8.2.4.3: | 555 // Spec 8.2.4.3: |
558 // Reorder pictures on the list in a way specified in the stream. | 556 // Reorder pictures on the list in a way specified in the stream. |
559 int pic_num_lx_pred = curr_pic_->pic_num; | 557 int pic_num_lx_pred = curr_pic_->pic_num; |
560 int ref_idx_lx = 0; | 558 int ref_idx_lx = 0; |
561 int pic_num_lx_no_wrap; | 559 int pic_num_lx_no_wrap; |
562 int pic_num_lx; | 560 int pic_num_lx; |
563 bool done = false; | 561 bool done = false; |
564 scoped_refptr<H264Picture> pic; | 562 scoped_refptr<H264Picture> pic; |
565 for (int i = 0; i < media::H264SliceHeader::kRefListModSize && !done; ++i) { | 563 for (int i = 0; i < H264SliceHeader::kRefListModSize && !done; ++i) { |
566 switch (list_mod->modification_of_pic_nums_idc) { | 564 switch (list_mod->modification_of_pic_nums_idc) { |
567 case 0: | 565 case 0: |
568 case 1: | 566 case 1: |
569 // Modify short reference picture position. | 567 // Modify short reference picture position. |
570 if (list_mod->modification_of_pic_nums_idc == 0) { | 568 if (list_mod->modification_of_pic_nums_idc == 0) { |
571 // Subtract given value from predicted PicNum. | 569 // Subtract given value from predicted PicNum. |
572 pic_num_lx_no_wrap = | 570 pic_num_lx_no_wrap = |
573 pic_num_lx_pred - | 571 pic_num_lx_pred - |
574 (static_cast<int>(list_mod->abs_diff_pic_num_minus1) + 1); | 572 (static_cast<int>(list_mod->abs_diff_pic_num_minus1) + 1); |
575 // Wrap around max_pic_num_ if it becomes < 0 as result | 573 // Wrap around max_pic_num_ if it becomes < 0 as result |
(...skipping 13 matching lines...) Expand all Loading... |
589 | 587 |
590 // For use in next iteration. | 588 // For use in next iteration. |
591 pic_num_lx_pred = pic_num_lx_no_wrap; | 589 pic_num_lx_pred = pic_num_lx_no_wrap; |
592 | 590 |
593 if (pic_num_lx_no_wrap > curr_pic_->pic_num) | 591 if (pic_num_lx_no_wrap > curr_pic_->pic_num) |
594 pic_num_lx = pic_num_lx_no_wrap - max_pic_num_; | 592 pic_num_lx = pic_num_lx_no_wrap - max_pic_num_; |
595 else | 593 else |
596 pic_num_lx = pic_num_lx_no_wrap; | 594 pic_num_lx = pic_num_lx_no_wrap; |
597 | 595 |
598 DCHECK_LT(num_ref_idx_lX_active_minus1 + 1, | 596 DCHECK_LT(num_ref_idx_lX_active_minus1 + 1, |
599 media::H264SliceHeader::kRefListModSize); | 597 H264SliceHeader::kRefListModSize); |
600 pic = dpb_.GetShortRefPicByPicNum(pic_num_lx); | 598 pic = dpb_.GetShortRefPicByPicNum(pic_num_lx); |
601 if (!pic) { | 599 if (!pic) { |
602 DVLOG(1) << "Malformed stream, no pic num " << pic_num_lx; | 600 DVLOG(1) << "Malformed stream, no pic num " << pic_num_lx; |
603 return false; | 601 return false; |
604 } | 602 } |
605 ShiftRightAndInsert(ref_pic_listx, ref_idx_lx, | 603 ShiftRightAndInsert(ref_pic_listx, ref_idx_lx, |
606 num_ref_idx_lX_active_minus1, pic); | 604 num_ref_idx_lX_active_minus1, pic); |
607 ref_idx_lx++; | 605 ref_idx_lx++; |
608 | 606 |
609 for (int src = ref_idx_lx, dst = ref_idx_lx; | 607 for (int src = ref_idx_lx, dst = ref_idx_lx; |
610 src <= num_ref_idx_lX_active_minus1 + 1; ++src) { | 608 src <= num_ref_idx_lX_active_minus1 + 1; ++src) { |
611 if (PicNumF((*ref_pic_listx)[src]) != pic_num_lx) | 609 if (PicNumF((*ref_pic_listx)[src]) != pic_num_lx) |
612 (*ref_pic_listx)[dst++] = (*ref_pic_listx)[src]; | 610 (*ref_pic_listx)[dst++] = (*ref_pic_listx)[src]; |
613 } | 611 } |
614 break; | 612 break; |
615 | 613 |
616 case 2: | 614 case 2: |
617 // Modify long term reference picture position. | 615 // Modify long term reference picture position. |
618 DCHECK_LT(num_ref_idx_lX_active_minus1 + 1, | 616 DCHECK_LT(num_ref_idx_lX_active_minus1 + 1, |
619 media::H264SliceHeader::kRefListModSize); | 617 H264SliceHeader::kRefListModSize); |
620 pic = dpb_.GetLongRefPicByLongTermPicNum(list_mod->long_term_pic_num); | 618 pic = dpb_.GetLongRefPicByLongTermPicNum(list_mod->long_term_pic_num); |
621 if (!pic) { | 619 if (!pic) { |
622 DVLOG(1) << "Malformed stream, no pic num " | 620 DVLOG(1) << "Malformed stream, no pic num " |
623 << list_mod->long_term_pic_num; | 621 << list_mod->long_term_pic_num; |
624 return false; | 622 return false; |
625 } | 623 } |
626 ShiftRightAndInsert(ref_pic_listx, ref_idx_lx, | 624 ShiftRightAndInsert(ref_pic_listx, ref_idx_lx, |
627 num_ref_idx_lX_active_minus1, pic); | 625 num_ref_idx_lX_active_minus1, pic); |
628 ref_idx_lx++; | 626 ref_idx_lx++; |
629 | 627 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 DVLOG(2) << "Decoder flush"; | 699 DVLOG(2) << "Decoder flush"; |
702 | 700 |
703 if (!OutputAllRemainingPics()) | 701 if (!OutputAllRemainingPics()) |
704 return false; | 702 return false; |
705 | 703 |
706 ClearDPB(); | 704 ClearDPB(); |
707 DVLOG(2) << "Decoder flush finished"; | 705 DVLOG(2) << "Decoder flush finished"; |
708 return true; | 706 return true; |
709 } | 707 } |
710 | 708 |
711 bool H264Decoder::StartNewFrame(const media::H264SliceHeader* slice_hdr) { | 709 bool H264Decoder::StartNewFrame(const H264SliceHeader* slice_hdr) { |
712 // TODO posciak: add handling of max_num_ref_frames per spec. | 710 // TODO posciak: add handling of max_num_ref_frames per spec. |
713 CHECK(curr_pic_.get()); | 711 CHECK(curr_pic_.get()); |
714 DCHECK(slice_hdr); | 712 DCHECK(slice_hdr); |
715 | 713 |
716 curr_pps_id_ = slice_hdr->pic_parameter_set_id; | 714 curr_pps_id_ = slice_hdr->pic_parameter_set_id; |
717 const media::H264PPS* pps = parser_.GetPPS(curr_pps_id_); | 715 const H264PPS* pps = parser_.GetPPS(curr_pps_id_); |
718 if (!pps) | 716 if (!pps) |
719 return false; | 717 return false; |
720 | 718 |
721 curr_sps_id_ = pps->seq_parameter_set_id; | 719 curr_sps_id_ = pps->seq_parameter_set_id; |
722 const media::H264SPS* sps = parser_.GetSPS(curr_sps_id_); | 720 const H264SPS* sps = parser_.GetSPS(curr_sps_id_); |
723 if (!sps) | 721 if (!sps) |
724 return false; | 722 return false; |
725 | 723 |
726 max_frame_num_ = 1 << (sps->log2_max_frame_num_minus4 + 4); | 724 max_frame_num_ = 1 << (sps->log2_max_frame_num_minus4 + 4); |
727 int frame_num = slice_hdr->frame_num; | 725 int frame_num = slice_hdr->frame_num; |
728 if (slice_hdr->idr_pic_flag) | 726 if (slice_hdr->idr_pic_flag) |
729 prev_ref_frame_num_ = 0; | 727 prev_ref_frame_num_ = 0; |
730 | 728 |
731 // 7.4.3 | 729 // 7.4.3 |
732 if (frame_num != prev_ref_frame_num_ && | 730 if (frame_num != prev_ref_frame_num_ && |
(...skipping 13 matching lines...) Expand all Loading... |
746 curr_pic_.get())) | 744 curr_pic_.get())) |
747 return false; | 745 return false; |
748 | 746 |
749 return true; | 747 return true; |
750 } | 748 } |
751 | 749 |
752 bool H264Decoder::HandleMemoryManagementOps(scoped_refptr<H264Picture> pic) { | 750 bool H264Decoder::HandleMemoryManagementOps(scoped_refptr<H264Picture> pic) { |
753 // 8.2.5.4 | 751 // 8.2.5.4 |
754 for (size_t i = 0; i < arraysize(pic->ref_pic_marking); ++i) { | 752 for (size_t i = 0; i < arraysize(pic->ref_pic_marking); ++i) { |
755 // Code below does not support interlaced stream (per-field pictures). | 753 // Code below does not support interlaced stream (per-field pictures). |
756 media::H264DecRefPicMarking* ref_pic_marking = &pic->ref_pic_marking[i]; | 754 H264DecRefPicMarking* ref_pic_marking = &pic->ref_pic_marking[i]; |
757 scoped_refptr<H264Picture> to_mark; | 755 scoped_refptr<H264Picture> to_mark; |
758 int pic_num_x; | 756 int pic_num_x; |
759 | 757 |
760 switch (ref_pic_marking->memory_mgmnt_control_operation) { | 758 switch (ref_pic_marking->memory_mgmnt_control_operation) { |
761 case 0: | 759 case 0: |
762 // Normal end of operations' specification. | 760 // Normal end of operations' specification. |
763 return true; | 761 return true; |
764 | 762 |
765 case 1: | 763 case 1: |
766 // Mark a short term reference picture as unused so it can be removed | 764 // Mark a short term reference picture as unused so it can be removed |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
885 // Otherwise, fall back to default sliding window process. | 883 // Otherwise, fall back to default sliding window process. |
886 if (pic->adaptive_ref_pic_marking_mode_flag) { | 884 if (pic->adaptive_ref_pic_marking_mode_flag) { |
887 DCHECK(!pic->nonexisting); | 885 DCHECK(!pic->nonexisting); |
888 return HandleMemoryManagementOps(pic); | 886 return HandleMemoryManagementOps(pic); |
889 } else { | 887 } else { |
890 return SlidingWindowPictureMarking(); | 888 return SlidingWindowPictureMarking(); |
891 } | 889 } |
892 } | 890 } |
893 | 891 |
894 bool H264Decoder::SlidingWindowPictureMarking() { | 892 bool H264Decoder::SlidingWindowPictureMarking() { |
895 const media::H264SPS* sps = parser_.GetSPS(curr_sps_id_); | 893 const H264SPS* sps = parser_.GetSPS(curr_sps_id_); |
896 if (!sps) | 894 if (!sps) |
897 return false; | 895 return false; |
898 | 896 |
899 // 8.2.5.3. Ensure the DPB doesn't overflow by discarding the oldest picture. | 897 // 8.2.5.3. Ensure the DPB doesn't overflow by discarding the oldest picture. |
900 int num_ref_pics = dpb_.CountRefPics(); | 898 int num_ref_pics = dpb_.CountRefPics(); |
901 DCHECK_LE(num_ref_pics, std::max<int>(sps->max_num_ref_frames, 1)); | 899 DCHECK_LE(num_ref_pics, std::max<int>(sps->max_num_ref_frames, 1)); |
902 if (num_ref_pics == std::max<int>(sps->max_num_ref_frames, 1)) { | 900 if (num_ref_pics == std::max<int>(sps->max_num_ref_frames, 1)) { |
903 // Max number of reference pics reached, need to remove one of the short | 901 // Max number of reference pics reached, need to remove one of the short |
904 // term ones. Find smallest frame_num_wrap short reference picture and mark | 902 // term ones. Find smallest frame_num_wrap short reference picture and mark |
905 // it as unused. | 903 // it as unused. |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1030 return 110400; | 1028 return 110400; |
1031 case 51: // fallthrough | 1029 case 51: // fallthrough |
1032 case 52: | 1030 case 52: |
1033 return 184320; | 1031 return 184320; |
1034 default: | 1032 default: |
1035 DVLOG(1) << "Invalid codec level (" << level << ")"; | 1033 DVLOG(1) << "Invalid codec level (" << level << ")"; |
1036 return 0; | 1034 return 0; |
1037 } | 1035 } |
1038 } | 1036 } |
1039 | 1037 |
1040 bool H264Decoder::UpdateMaxNumReorderFrames(const media::H264SPS* sps) { | 1038 bool H264Decoder::UpdateMaxNumReorderFrames(const H264SPS* sps) { |
1041 if (sps->vui_parameters_present_flag && sps->bitstream_restriction_flag) { | 1039 if (sps->vui_parameters_present_flag && sps->bitstream_restriction_flag) { |
1042 max_num_reorder_frames_ = | 1040 max_num_reorder_frames_ = |
1043 base::checked_cast<size_t>(sps->max_num_reorder_frames); | 1041 base::checked_cast<size_t>(sps->max_num_reorder_frames); |
1044 if (max_num_reorder_frames_ > dpb_.max_num_pics()) { | 1042 if (max_num_reorder_frames_ > dpb_.max_num_pics()) { |
1045 DVLOG(1) | 1043 DVLOG(1) |
1046 << "max_num_reorder_frames present, but larger than MaxDpbFrames (" | 1044 << "max_num_reorder_frames present, but larger than MaxDpbFrames (" |
1047 << max_num_reorder_frames_ << " > " << dpb_.max_num_pics() << ")"; | 1045 << max_num_reorder_frames_ << " > " << dpb_.max_num_pics() << ")"; |
1048 max_num_reorder_frames_ = 0; | 1046 max_num_reorder_frames_ = 0; |
1049 return false; | 1047 return false; |
1050 } | 1048 } |
(...skipping 19 matching lines...) Expand all Loading... |
1070 } else { | 1068 } else { |
1071 max_num_reorder_frames_ = dpb_.max_num_pics(); | 1069 max_num_reorder_frames_ = dpb_.max_num_pics(); |
1072 } | 1070 } |
1073 | 1071 |
1074 return true; | 1072 return true; |
1075 } | 1073 } |
1076 | 1074 |
1077 bool H264Decoder::ProcessSPS(int sps_id, bool* need_new_buffers) { | 1075 bool H264Decoder::ProcessSPS(int sps_id, bool* need_new_buffers) { |
1078 DVLOG(4) << "Processing SPS id:" << sps_id; | 1076 DVLOG(4) << "Processing SPS id:" << sps_id; |
1079 | 1077 |
1080 const media::H264SPS* sps = parser_.GetSPS(sps_id); | 1078 const H264SPS* sps = parser_.GetSPS(sps_id); |
1081 if (!sps) | 1079 if (!sps) |
1082 return false; | 1080 return false; |
1083 | 1081 |
1084 *need_new_buffers = false; | 1082 *need_new_buffers = false; |
1085 | 1083 |
1086 if (sps->frame_mbs_only_flag == 0) { | 1084 if (sps->frame_mbs_only_flag == 0) { |
1087 DVLOG(1) << "frame_mbs_only_flag != 1 not supported"; | 1085 DVLOG(1) << "frame_mbs_only_flag != 1 not supported"; |
1088 return false; | 1086 return false; |
1089 } | 1087 } |
1090 | 1088 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1147 | 1145 |
1148 scoped_refptr<H264Picture> pic = curr_pic_; | 1146 scoped_refptr<H264Picture> pic = curr_pic_; |
1149 curr_pic_ = nullptr; | 1147 curr_pic_ = nullptr; |
1150 return FinishPicture(pic); | 1148 return FinishPicture(pic); |
1151 } | 1149 } |
1152 | 1150 |
1153 return true; | 1151 return true; |
1154 } | 1152 } |
1155 | 1153 |
1156 bool H264Decoder::HandleFrameNumGap(int frame_num) { | 1154 bool H264Decoder::HandleFrameNumGap(int frame_num) { |
1157 const media::H264SPS* sps = parser_.GetSPS(curr_sps_id_); | 1155 const H264SPS* sps = parser_.GetSPS(curr_sps_id_); |
1158 if (!sps) | 1156 if (!sps) |
1159 return false; | 1157 return false; |
1160 | 1158 |
1161 if (!sps->gaps_in_frame_num_value_allowed_flag) { | 1159 if (!sps->gaps_in_frame_num_value_allowed_flag) { |
1162 DVLOG(1) << "Invalid frame_num: " << frame_num; | 1160 DVLOG(1) << "Invalid frame_num: " << frame_num; |
1163 return false; | 1161 return false; |
1164 } | 1162 } |
1165 | 1163 |
1166 DVLOG(2) << "Handling frame_num gap: " << prev_ref_frame_num_ << "->" | 1164 DVLOG(2) << "Handling frame_num gap: " << prev_ref_frame_num_ << "->" |
1167 << frame_num; | 1165 << frame_num; |
(...skipping 11 matching lines...) Expand all Loading... |
1179 return false; | 1177 return false; |
1180 | 1178 |
1181 unused_short_term_frame_num++; | 1179 unused_short_term_frame_num++; |
1182 unused_short_term_frame_num %= max_frame_num_; | 1180 unused_short_term_frame_num %= max_frame_num_; |
1183 } | 1181 } |
1184 | 1182 |
1185 return true; | 1183 return true; |
1186 } | 1184 } |
1187 | 1185 |
1188 bool H264Decoder::IsNewPrimaryCodedPicture( | 1186 bool H264Decoder::IsNewPrimaryCodedPicture( |
1189 const media::H264SliceHeader* slice_hdr) const { | 1187 const H264SliceHeader* slice_hdr) const { |
1190 if (!curr_pic_) | 1188 if (!curr_pic_) |
1191 return true; | 1189 return true; |
1192 | 1190 |
1193 // 7.4.1.2.4, assumes non-interlaced. | 1191 // 7.4.1.2.4, assumes non-interlaced. |
1194 if (slice_hdr->frame_num != curr_pic_->frame_num || | 1192 if (slice_hdr->frame_num != curr_pic_->frame_num || |
1195 slice_hdr->pic_parameter_set_id != curr_pps_id_ || | 1193 slice_hdr->pic_parameter_set_id != curr_pps_id_ || |
1196 slice_hdr->nal_ref_idc != curr_pic_->nal_ref_idc || | 1194 slice_hdr->nal_ref_idc != curr_pic_->nal_ref_idc || |
1197 slice_hdr->idr_pic_flag != curr_pic_->idr || | 1195 slice_hdr->idr_pic_flag != curr_pic_->idr || |
1198 (slice_hdr->idr_pic_flag && | 1196 (slice_hdr->idr_pic_flag && |
1199 (slice_hdr->idr_pic_id != curr_pic_->idr_pic_id || | 1197 (slice_hdr->idr_pic_id != curr_pic_->idr_pic_id || |
1200 // If we have two consecutive IDR slices, and the second one has | 1198 // If we have two consecutive IDR slices, and the second one has |
1201 // first_mb_in_slice == 0, treat it as a new picture. | 1199 // first_mb_in_slice == 0, treat it as a new picture. |
1202 // Per spec, idr_pic_id should not be equal in this case (and we should | 1200 // Per spec, idr_pic_id should not be equal in this case (and we should |
1203 // have hit the condition above instead, see spec 7.4.3 on idr_pic_id), | 1201 // have hit the condition above instead, see spec 7.4.3 on idr_pic_id), |
1204 // but some encoders neglect changing idr_pic_id for two consecutive | 1202 // but some encoders neglect changing idr_pic_id for two consecutive |
1205 // IDRs. Work around this by checking if the next slice contains the | 1203 // IDRs. Work around this by checking if the next slice contains the |
1206 // zeroth macroblock, i.e. data that belongs to the next picture. | 1204 // zeroth macroblock, i.e. data that belongs to the next picture. |
1207 slice_hdr->first_mb_in_slice == 0))) | 1205 slice_hdr->first_mb_in_slice == 0))) |
1208 return true; | 1206 return true; |
1209 | 1207 |
1210 const media::H264SPS* sps = parser_.GetSPS(curr_sps_id_); | 1208 const H264SPS* sps = parser_.GetSPS(curr_sps_id_); |
1211 if (!sps) | 1209 if (!sps) |
1212 return false; | 1210 return false; |
1213 | 1211 |
1214 if (sps->pic_order_cnt_type == curr_pic_->pic_order_cnt_type) { | 1212 if (sps->pic_order_cnt_type == curr_pic_->pic_order_cnt_type) { |
1215 if (curr_pic_->pic_order_cnt_type == 0) { | 1213 if (curr_pic_->pic_order_cnt_type == 0) { |
1216 if (slice_hdr->pic_order_cnt_lsb != curr_pic_->pic_order_cnt_lsb || | 1214 if (slice_hdr->pic_order_cnt_lsb != curr_pic_->pic_order_cnt_lsb || |
1217 slice_hdr->delta_pic_order_cnt_bottom != | 1215 slice_hdr->delta_pic_order_cnt_bottom != |
1218 curr_pic_->delta_pic_order_cnt_bottom) | 1216 curr_pic_->delta_pic_order_cnt_bottom) |
1219 return true; | 1217 return true; |
1220 } else if (curr_pic_->pic_order_cnt_type == 1) { | 1218 } else if (curr_pic_->pic_order_cnt_type == 1) { |
1221 if (slice_hdr->delta_pic_order_cnt0 != curr_pic_->delta_pic_order_cnt0 || | 1219 if (slice_hdr->delta_pic_order_cnt0 != curr_pic_->delta_pic_order_cnt0 || |
1222 slice_hdr->delta_pic_order_cnt1 != curr_pic_->delta_pic_order_cnt1) | 1220 slice_hdr->delta_pic_order_cnt1 != curr_pic_->delta_pic_order_cnt1) |
1223 return true; | 1221 return true; |
1224 } | 1222 } |
1225 } | 1223 } |
1226 | 1224 |
1227 return false; | 1225 return false; |
1228 } | 1226 } |
1229 | 1227 |
1230 bool H264Decoder::PreprocessCurrentSlice() { | 1228 bool H264Decoder::PreprocessCurrentSlice() { |
1231 const media::H264SliceHeader* slice_hdr = curr_slice_hdr_.get(); | 1229 const H264SliceHeader* slice_hdr = curr_slice_hdr_.get(); |
1232 DCHECK(slice_hdr); | 1230 DCHECK(slice_hdr); |
1233 | 1231 |
1234 if (IsNewPrimaryCodedPicture(slice_hdr)) { | 1232 if (IsNewPrimaryCodedPicture(slice_hdr)) { |
1235 // New picture, so first finish the previous one before processing it. | 1233 // New picture, so first finish the previous one before processing it. |
1236 if (!FinishPrevFrameIfPresent()) | 1234 if (!FinishPrevFrameIfPresent()) |
1237 return false; | 1235 return false; |
1238 | 1236 |
1239 DCHECK(!curr_pic_); | 1237 DCHECK(!curr_pic_); |
1240 | 1238 |
1241 if (slice_hdr->first_mb_in_slice != 0) { | 1239 if (slice_hdr->first_mb_in_slice != 0) { |
(...skipping 14 matching lines...) Expand all Loading... |
1256 last_output_poc_ = std::numeric_limits<int>::min(); | 1254 last_output_poc_ = std::numeric_limits<int>::min(); |
1257 } | 1255 } |
1258 } | 1256 } |
1259 | 1257 |
1260 return true; | 1258 return true; |
1261 } | 1259 } |
1262 | 1260 |
1263 bool H264Decoder::ProcessCurrentSlice() { | 1261 bool H264Decoder::ProcessCurrentSlice() { |
1264 DCHECK(curr_pic_); | 1262 DCHECK(curr_pic_); |
1265 | 1263 |
1266 const media::H264SliceHeader* slice_hdr = curr_slice_hdr_.get(); | 1264 const H264SliceHeader* slice_hdr = curr_slice_hdr_.get(); |
1267 DCHECK(slice_hdr); | 1265 DCHECK(slice_hdr); |
1268 | 1266 |
1269 if (slice_hdr->field_pic_flag == 0) | 1267 if (slice_hdr->field_pic_flag == 0) |
1270 max_pic_num_ = max_frame_num_; | 1268 max_pic_num_ = max_frame_num_; |
1271 else | 1269 else |
1272 max_pic_num_ = 2 * max_frame_num_; | 1270 max_pic_num_ = 2 * max_frame_num_; |
1273 | 1271 |
1274 H264Picture::Vector ref_pic_list0, ref_pic_list1; | 1272 H264Picture::Vector ref_pic_list0, ref_pic_list1; |
1275 if (!ModifyReferencePicLists(slice_hdr, &ref_pic_list0, &ref_pic_list1)) | 1273 if (!ModifyReferencePicLists(slice_hdr, &ref_pic_list0, &ref_pic_list1)) |
1276 return false; | 1274 return false; |
1277 | 1275 |
1278 const media::H264PPS* pps = parser_.GetPPS(curr_pps_id_); | 1276 const H264PPS* pps = parser_.GetPPS(curr_pps_id_); |
1279 if (!pps) | 1277 if (!pps) |
1280 return false; | 1278 return false; |
1281 | 1279 |
1282 if (!accelerator_->SubmitSlice(pps, slice_hdr, ref_pic_list0, ref_pic_list1, | 1280 if (!accelerator_->SubmitSlice(pps, slice_hdr, ref_pic_list0, ref_pic_list1, |
1283 curr_pic_.get(), slice_hdr->nalu_data, | 1281 curr_pic_.get(), slice_hdr->nalu_data, |
1284 slice_hdr->nalu_size)) | 1282 slice_hdr->nalu_size)) |
1285 return false; | 1283 return false; |
1286 | 1284 |
1287 return true; | 1285 return true; |
1288 } | 1286 } |
(...skipping 13 matching lines...) Expand all Loading... |
1302 parser_.SetStream(ptr, size); | 1300 parser_.SetStream(ptr, size); |
1303 } | 1301 } |
1304 | 1302 |
1305 H264Decoder::DecodeResult H264Decoder::Decode() { | 1303 H264Decoder::DecodeResult H264Decoder::Decode() { |
1306 if (state_ == kError) { | 1304 if (state_ == kError) { |
1307 DVLOG(1) << "Decoder in error state"; | 1305 DVLOG(1) << "Decoder in error state"; |
1308 return kDecodeError; | 1306 return kDecodeError; |
1309 } | 1307 } |
1310 | 1308 |
1311 while (1) { | 1309 while (1) { |
1312 media::H264Parser::Result par_res; | 1310 H264Parser::Result par_res; |
1313 | 1311 |
1314 if (!curr_nalu_) { | 1312 if (!curr_nalu_) { |
1315 curr_nalu_.reset(new media::H264NALU()); | 1313 curr_nalu_.reset(new H264NALU()); |
1316 par_res = parser_.AdvanceToNextNALU(curr_nalu_.get()); | 1314 par_res = parser_.AdvanceToNextNALU(curr_nalu_.get()); |
1317 if (par_res == media::H264Parser::kEOStream) | 1315 if (par_res == H264Parser::kEOStream) |
1318 return kRanOutOfStreamData; | 1316 return kRanOutOfStreamData; |
1319 else if (par_res != media::H264Parser::kOk) | 1317 else if (par_res != H264Parser::kOk) |
1320 SET_ERROR_AND_RETURN(); | 1318 SET_ERROR_AND_RETURN(); |
1321 | 1319 |
1322 DVLOG(4) << "New NALU: " << static_cast<int>(curr_nalu_->nal_unit_type); | 1320 DVLOG(4) << "New NALU: " << static_cast<int>(curr_nalu_->nal_unit_type); |
1323 } | 1321 } |
1324 | 1322 |
1325 switch (curr_nalu_->nal_unit_type) { | 1323 switch (curr_nalu_->nal_unit_type) { |
1326 case media::H264NALU::kNonIDRSlice: | 1324 case H264NALU::kNonIDRSlice: |
1327 // We can't resume from a non-IDR slice. | 1325 // We can't resume from a non-IDR slice. |
1328 if (state_ != kDecoding) | 1326 if (state_ != kDecoding) |
1329 break; | 1327 break; |
1330 // else fallthrough | 1328 |
1331 case media::H264NALU::kIDRSlice: { | 1329 // else fallthrough |
| 1330 case H264NALU::kIDRSlice: { |
1332 // TODO(posciak): the IDR may require an SPS that we don't have | 1331 // TODO(posciak): the IDR may require an SPS that we don't have |
1333 // available. For now we'd fail if that happens, but ideally we'd like | 1332 // available. For now we'd fail if that happens, but ideally we'd like |
1334 // to keep going until the next SPS in the stream. | 1333 // to keep going until the next SPS in the stream. |
1335 if (state_ == kNeedStreamMetadata) { | 1334 if (state_ == kNeedStreamMetadata) { |
1336 // We need an SPS, skip this IDR and keep looking. | 1335 // We need an SPS, skip this IDR and keep looking. |
1337 break; | 1336 break; |
1338 } | 1337 } |
1339 | 1338 |
1340 // If after reset, we should be able to recover from an IDR. | 1339 // If after reset, we should be able to recover from an IDR. |
1341 state_ = kDecoding; | 1340 state_ = kDecoding; |
1342 | 1341 |
1343 if (!curr_slice_hdr_) { | 1342 if (!curr_slice_hdr_) { |
1344 curr_slice_hdr_.reset(new media::H264SliceHeader()); | 1343 curr_slice_hdr_.reset(new H264SliceHeader()); |
1345 par_res = | 1344 par_res = |
1346 parser_.ParseSliceHeader(*curr_nalu_, curr_slice_hdr_.get()); | 1345 parser_.ParseSliceHeader(*curr_nalu_, curr_slice_hdr_.get()); |
1347 if (par_res != media::H264Parser::kOk) | 1346 if (par_res != H264Parser::kOk) |
1348 SET_ERROR_AND_RETURN(); | 1347 SET_ERROR_AND_RETURN(); |
1349 | 1348 |
1350 if (!PreprocessCurrentSlice()) | 1349 if (!PreprocessCurrentSlice()) |
1351 SET_ERROR_AND_RETURN(); | 1350 SET_ERROR_AND_RETURN(); |
1352 } | 1351 } |
1353 | 1352 |
1354 if (!curr_pic_) { | 1353 if (!curr_pic_) { |
1355 // New picture/finished previous one, try to start a new one | 1354 // New picture/finished previous one, try to start a new one |
1356 // or tell the client we need more surfaces. | 1355 // or tell the client we need more surfaces. |
1357 curr_pic_ = accelerator_->CreateH264Picture(); | 1356 curr_pic_ = accelerator_->CreateH264Picture(); |
1358 if (!curr_pic_) | 1357 if (!curr_pic_) |
1359 return kRanOutOfSurfaces; | 1358 return kRanOutOfSurfaces; |
1360 | 1359 |
1361 if (!StartNewFrame(curr_slice_hdr_.get())) | 1360 if (!StartNewFrame(curr_slice_hdr_.get())) |
1362 SET_ERROR_AND_RETURN(); | 1361 SET_ERROR_AND_RETURN(); |
1363 } | 1362 } |
1364 | 1363 |
1365 if (!ProcessCurrentSlice()) | 1364 if (!ProcessCurrentSlice()) |
1366 SET_ERROR_AND_RETURN(); | 1365 SET_ERROR_AND_RETURN(); |
1367 | 1366 |
1368 curr_slice_hdr_.reset(); | 1367 curr_slice_hdr_.reset(); |
1369 break; | 1368 break; |
1370 } | 1369 } |
1371 | 1370 |
1372 case media::H264NALU::kSPS: { | 1371 case H264NALU::kSPS: { |
1373 int sps_id; | 1372 int sps_id; |
1374 | 1373 |
1375 if (!FinishPrevFrameIfPresent()) | 1374 if (!FinishPrevFrameIfPresent()) |
1376 SET_ERROR_AND_RETURN(); | 1375 SET_ERROR_AND_RETURN(); |
1377 | 1376 |
1378 par_res = parser_.ParseSPS(&sps_id); | 1377 par_res = parser_.ParseSPS(&sps_id); |
1379 if (par_res != media::H264Parser::kOk) | 1378 if (par_res != H264Parser::kOk) |
1380 SET_ERROR_AND_RETURN(); | 1379 SET_ERROR_AND_RETURN(); |
1381 | 1380 |
1382 bool need_new_buffers = false; | 1381 bool need_new_buffers = false; |
1383 if (!ProcessSPS(sps_id, &need_new_buffers)) | 1382 if (!ProcessSPS(sps_id, &need_new_buffers)) |
1384 SET_ERROR_AND_RETURN(); | 1383 SET_ERROR_AND_RETURN(); |
1385 | 1384 |
1386 if (state_ == kNeedStreamMetadata) | 1385 if (state_ == kNeedStreamMetadata) |
1387 state_ = kAfterReset; | 1386 state_ = kAfterReset; |
1388 | 1387 |
1389 if (need_new_buffers) { | 1388 if (need_new_buffers) { |
1390 if (!Flush()) | 1389 if (!Flush()) |
1391 return kDecodeError; | 1390 return kDecodeError; |
1392 | 1391 |
1393 curr_pic_ = nullptr; | 1392 curr_pic_ = nullptr; |
1394 curr_nalu_ = nullptr; | 1393 curr_nalu_ = nullptr; |
1395 ref_pic_list_p0_.clear(); | 1394 ref_pic_list_p0_.clear(); |
1396 ref_pic_list_b0_.clear(); | 1395 ref_pic_list_b0_.clear(); |
1397 ref_pic_list_b1_.clear(); | 1396 ref_pic_list_b1_.clear(); |
1398 | 1397 |
1399 return kAllocateNewSurfaces; | 1398 return kAllocateNewSurfaces; |
1400 } | 1399 } |
1401 break; | 1400 break; |
1402 } | 1401 } |
1403 | 1402 |
1404 case media::H264NALU::kPPS: { | 1403 case H264NALU::kPPS: { |
1405 int pps_id; | 1404 int pps_id; |
1406 | 1405 |
1407 if (!FinishPrevFrameIfPresent()) | 1406 if (!FinishPrevFrameIfPresent()) |
1408 SET_ERROR_AND_RETURN(); | 1407 SET_ERROR_AND_RETURN(); |
1409 | 1408 |
1410 par_res = parser_.ParsePPS(&pps_id); | 1409 par_res = parser_.ParsePPS(&pps_id); |
1411 if (par_res != media::H264Parser::kOk) | 1410 if (par_res != H264Parser::kOk) |
1412 SET_ERROR_AND_RETURN(); | 1411 SET_ERROR_AND_RETURN(); |
1413 | 1412 |
1414 break; | 1413 break; |
1415 } | 1414 } |
1416 | 1415 |
1417 case media::H264NALU::kAUD: | 1416 case H264NALU::kAUD: |
1418 case media::H264NALU::kEOSeq: | 1417 case H264NALU::kEOSeq: |
1419 case media::H264NALU::kEOStream: | 1418 case H264NALU::kEOStream: |
1420 if (state_ != kDecoding) | 1419 if (state_ != kDecoding) |
1421 break; | 1420 break; |
1422 | 1421 |
1423 if (!FinishPrevFrameIfPresent()) | 1422 if (!FinishPrevFrameIfPresent()) |
1424 SET_ERROR_AND_RETURN(); | 1423 SET_ERROR_AND_RETURN(); |
1425 | 1424 |
1426 break; | 1425 break; |
1427 | 1426 |
1428 default: | 1427 default: |
1429 DVLOG(4) << "Skipping NALU type: " << curr_nalu_->nal_unit_type; | 1428 DVLOG(4) << "Skipping NALU type: " << curr_nalu_->nal_unit_type; |
1430 break; | 1429 break; |
1431 } | 1430 } |
1432 | 1431 |
1433 DVLOG(4) << "NALU done"; | 1432 DVLOG(4) << "NALU done"; |
1434 curr_nalu_.reset(); | 1433 curr_nalu_.reset(); |
1435 } | 1434 } |
1436 } | 1435 } |
1437 | 1436 |
1438 gfx::Size H264Decoder::GetPicSize() const { | 1437 gfx::Size H264Decoder::GetPicSize() const { |
1439 return pic_size_; | 1438 return pic_size_; |
1440 } | 1439 } |
1441 | 1440 |
1442 size_t H264Decoder::GetRequiredNumOfPictures() const { | 1441 size_t H264Decoder::GetRequiredNumOfPictures() const { |
1443 return dpb_.max_num_pics() + kPicsInPipeline; | 1442 return dpb_.max_num_pics() + kPicsInPipeline; |
1444 } | 1443 } |
1445 | 1444 |
1446 } // namespace media | 1445 } // namespace media |
OLD | NEW |