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

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

Issue 852103002: Revert of Add accelerated video decoder interface, VP8 and H.264 implementations and hook up to V4L2SVDA (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 11 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
OLDNEW
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/numerics/safe_conversions.h" 10 #include "base/numerics/safe_conversions.h"
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 81
82 curr_input_id_ = -1; 82 curr_input_id_ = -1;
83 frame_num_ = 0; 83 frame_num_ = 0;
84 prev_frame_num_ = -1; 84 prev_frame_num_ = -1;
85 prev_frame_num_offset_ = -1; 85 prev_frame_num_offset_ = -1;
86 86
87 prev_ref_has_memmgmnt5_ = false; 87 prev_ref_has_memmgmnt5_ = false;
88 prev_ref_top_field_order_cnt_ = -1; 88 prev_ref_top_field_order_cnt_ = -1;
89 prev_ref_pic_order_cnt_msb_ = -1; 89 prev_ref_pic_order_cnt_msb_ = -1;
90 prev_ref_pic_order_cnt_lsb_ = -1; 90 prev_ref_pic_order_cnt_lsb_ = -1;
91 prev_ref_field_ = VaapiH264Picture::FIELD_NONE; 91 prev_ref_field_ = H264Picture::FIELD_NONE;
92 92
93 vaapi_wrapper_->DestroyPendingBuffers(); 93 vaapi_wrapper_->DestroyPendingBuffers();
94 94
95 ref_pic_list0_.clear(); 95 ref_pic_list0_.clear();
96 ref_pic_list1_.clear(); 96 ref_pic_list1_.clear();
97 97
98 for (DecSurfacesInUse::iterator it = decode_surfaces_in_use_.begin(); 98 for (DecSurfacesInUse::iterator it = decode_surfaces_in_use_.begin();
99 it != decode_surfaces_in_use_.end(); ) { 99 it != decode_surfaces_in_use_.end(); ) {
100 int poc = it->second->poc(); 100 int poc = it->second->poc();
101 // Must be incremented before UnassignSurfaceFromPoC as this call 101 // Must be incremented before UnassignSurfaceFromPoC as this call
(...skipping 17 matching lines...) Expand all
119 available_va_surfaces_.push_back(va_surface); 119 available_va_surfaces_.push_back(va_surface);
120 } 120 }
121 121
122 // Fill |va_pic| with default/neutral values. 122 // Fill |va_pic| with default/neutral values.
123 static void InitVAPicture(VAPictureH264* va_pic) { 123 static void InitVAPicture(VAPictureH264* va_pic) {
124 memset(va_pic, 0, sizeof(*va_pic)); 124 memset(va_pic, 0, sizeof(*va_pic));
125 va_pic->picture_id = VA_INVALID_ID; 125 va_pic->picture_id = VA_INVALID_ID;
126 va_pic->flags = VA_PICTURE_H264_INVALID; 126 va_pic->flags = VA_PICTURE_H264_INVALID;
127 } 127 }
128 128
129 void VaapiH264Decoder::FillVAPicture(VAPictureH264* va_pic, 129 void VaapiH264Decoder::FillVAPicture(VAPictureH264 *va_pic, H264Picture* pic) {
130 VaapiH264Picture* pic) {
131 DCHECK(pic); 130 DCHECK(pic);
132 131
133 DecodeSurface* dec_surface = DecodeSurfaceByPoC(pic->pic_order_cnt); 132 DecodeSurface* dec_surface = DecodeSurfaceByPoC(pic->pic_order_cnt);
134 if (!dec_surface) { 133 if (!dec_surface) {
135 // Cannot provide a ref picture, will corrupt output, but may be able 134 // Cannot provide a ref picture, will corrupt output, but may be able
136 // to recover. 135 // to recover.
137 InitVAPicture(va_pic); 136 InitVAPicture(va_pic);
138 return; 137 return;
139 } 138 }
140 139
141 va_pic->picture_id = dec_surface->va_surface()->id(); 140 va_pic->picture_id = dec_surface->va_surface()->id();
142 va_pic->frame_idx = pic->frame_num; 141 va_pic->frame_idx = pic->frame_num;
143 va_pic->flags = 0; 142 va_pic->flags = 0;
144 143
145 switch (pic->field) { 144 switch (pic->field) {
146 case VaapiH264Picture::FIELD_NONE: 145 case H264Picture::FIELD_NONE:
147 break; 146 break;
148 case VaapiH264Picture::FIELD_TOP: 147 case H264Picture::FIELD_TOP:
149 va_pic->flags |= VA_PICTURE_H264_TOP_FIELD; 148 va_pic->flags |= VA_PICTURE_H264_TOP_FIELD;
150 break; 149 break;
151 case VaapiH264Picture::FIELD_BOTTOM: 150 case H264Picture::FIELD_BOTTOM:
152 va_pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD; 151 va_pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD;
153 break; 152 break;
154 } 153 }
155 154
156 if (pic->ref) { 155 if (pic->ref) {
157 va_pic->flags |= pic->long_term ? VA_PICTURE_H264_LONG_TERM_REFERENCE 156 va_pic->flags |= pic->long_term ? VA_PICTURE_H264_LONG_TERM_REFERENCE
158 : VA_PICTURE_H264_SHORT_TERM_REFERENCE; 157 : VA_PICTURE_H264_SHORT_TERM_REFERENCE;
159 } 158 }
160 159
161 va_pic->TopFieldOrderCnt = pic->top_field_order_cnt; 160 va_pic->TopFieldOrderCnt = pic->top_field_order_cnt;
162 va_pic->BottomFieldOrderCnt = pic->bottom_field_order_cnt; 161 va_pic->BottomFieldOrderCnt = pic->bottom_field_order_cnt;
163 } 162 }
164 163
165 int VaapiH264Decoder::FillVARefFramesFromDPB(VAPictureH264 *va_pics, 164 int VaapiH264Decoder::FillVARefFramesFromDPB(VAPictureH264 *va_pics,
166 int num_pics) { 165 int num_pics) {
167 VaapiH264DPB::Pictures::reverse_iterator rit; 166 H264DPB::Pictures::reverse_iterator rit;
168 int i; 167 int i;
169 168
170 // Return reference frames in reverse order of insertion. 169 // Return reference frames in reverse order of insertion.
171 // Libva does not document this, but other implementations (e.g. mplayer) 170 // Libva does not document this, but other implementations (e.g. mplayer)
172 // do it this way as well. 171 // do it this way as well.
173 for (rit = dpb_.rbegin(), i = 0; rit != dpb_.rend() && i < num_pics; ++rit) { 172 for (rit = dpb_.rbegin(), i = 0; rit != dpb_.rend() && i < num_pics; ++rit) {
174 if ((*rit)->ref) 173 if ((*rit)->ref)
175 FillVAPicture(&va_pics[i++], *rit); 174 FillVAPicture(&va_pics[i++], *rit);
176 } 175 }
177 176
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 } 415 }
417 } 416 }
418 } 417 }
419 418
420 for (int i = 0; i < 32; ++i) { 419 for (int i = 0; i < 32; ++i) {
421 InitVAPicture(&slice_param.RefPicList0[i]); 420 InitVAPicture(&slice_param.RefPicList0[i]);
422 InitVAPicture(&slice_param.RefPicList1[i]); 421 InitVAPicture(&slice_param.RefPicList1[i]);
423 } 422 }
424 423
425 int i; 424 int i;
426 VaapiH264Picture::PtrVector::iterator it; 425 H264Picture::PtrVector::iterator it;
427 for (it = ref_pic_list0_.begin(), i = 0; it != ref_pic_list0_.end() && *it; 426 for (it = ref_pic_list0_.begin(), i = 0; it != ref_pic_list0_.end() && *it;
428 ++it, ++i) 427 ++it, ++i)
429 FillVAPicture(&slice_param.RefPicList0[i], *it); 428 FillVAPicture(&slice_param.RefPicList0[i], *it);
430 for (it = ref_pic_list1_.begin(), i = 0; it != ref_pic_list1_.end() && *it; 429 for (it = ref_pic_list1_.begin(), i = 0; it != ref_pic_list1_.end() && *it;
431 ++it, ++i) 430 ++it, ++i)
432 FillVAPicture(&slice_param.RefPicList1[i], *it); 431 FillVAPicture(&slice_param.RefPicList1[i], *it);
433 432
434 return vaapi_wrapper_->SubmitBuffer(VASliceParameterBufferType, 433 return vaapi_wrapper_->SubmitBuffer(VASliceParameterBufferType,
435 sizeof(VASliceParameterBufferH264), 434 sizeof(VASliceParameterBufferH264),
436 &slice_param); 435 &slice_param);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 DVLOG(1) << "Failed decoding picture"; 493 DVLOG(1) << "Failed decoding picture";
495 return false; 494 return false;
496 } 495 }
497 496
498 return true; 497 return true;
499 } 498 }
500 499
501 bool VaapiH264Decoder::InitCurrPicture(media::H264SliceHeader* slice_hdr) { 500 bool VaapiH264Decoder::InitCurrPicture(media::H264SliceHeader* slice_hdr) {
502 DCHECK(curr_pic_.get()); 501 DCHECK(curr_pic_.get());
503 502
504 memset(curr_pic_.get(), 0, sizeof(VaapiH264Picture)); 503 memset(curr_pic_.get(), 0, sizeof(H264Picture));
505 504
506 curr_pic_->idr = slice_hdr->idr_pic_flag; 505 curr_pic_->idr = slice_hdr->idr_pic_flag;
507 506
508 if (slice_hdr->field_pic_flag) { 507 if (slice_hdr->field_pic_flag) {
509 curr_pic_->field = slice_hdr->bottom_field_flag 508 curr_pic_->field = slice_hdr->bottom_field_flag ? H264Picture::FIELD_BOTTOM
510 ? VaapiH264Picture::FIELD_BOTTOM 509 : H264Picture::FIELD_TOP;
511 : VaapiH264Picture::FIELD_TOP;
512 } else { 510 } else {
513 curr_pic_->field = VaapiH264Picture::FIELD_NONE; 511 curr_pic_->field = H264Picture::FIELD_NONE;
514 } 512 }
515 513
516 curr_pic_->ref = slice_hdr->nal_ref_idc != 0; 514 curr_pic_->ref = slice_hdr->nal_ref_idc != 0;
517 // This assumes non-interlaced stream. 515 // This assumes non-interlaced stream.
518 curr_pic_->frame_num = curr_pic_->pic_num = slice_hdr->frame_num; 516 curr_pic_->frame_num = curr_pic_->pic_num = slice_hdr->frame_num;
519 517
520 if (!CalculatePicOrderCounts(slice_hdr)) 518 if (!CalculatePicOrderCounts(slice_hdr))
521 return false; 519 return false;
522 520
523 // Try to get an empty surface to decode this picture to. 521 // Try to get an empty surface to decode this picture to.
(...skipping 29 matching lines...) Expand all
553 curr_pic_->pic_order_cnt_lsb = pic_order_cnt_lsb; 551 curr_pic_->pic_order_cnt_lsb = pic_order_cnt_lsb;
554 552
555 switch (sps->pic_order_cnt_type) { 553 switch (sps->pic_order_cnt_type) {
556 case 0: 554 case 0:
557 // See spec 8.2.1.1. 555 // See spec 8.2.1.1.
558 int prev_pic_order_cnt_msb, prev_pic_order_cnt_lsb; 556 int prev_pic_order_cnt_msb, prev_pic_order_cnt_lsb;
559 if (slice_hdr->idr_pic_flag) { 557 if (slice_hdr->idr_pic_flag) {
560 prev_pic_order_cnt_msb = prev_pic_order_cnt_lsb = 0; 558 prev_pic_order_cnt_msb = prev_pic_order_cnt_lsb = 0;
561 } else { 559 } else {
562 if (prev_ref_has_memmgmnt5_) { 560 if (prev_ref_has_memmgmnt5_) {
563 if (prev_ref_field_ != VaapiH264Picture::FIELD_BOTTOM) { 561 if (prev_ref_field_ != H264Picture::FIELD_BOTTOM) {
564 prev_pic_order_cnt_msb = 0; 562 prev_pic_order_cnt_msb = 0;
565 prev_pic_order_cnt_lsb = prev_ref_top_field_order_cnt_; 563 prev_pic_order_cnt_lsb = prev_ref_top_field_order_cnt_;
566 } else { 564 } else {
567 prev_pic_order_cnt_msb = 0; 565 prev_pic_order_cnt_msb = 0;
568 prev_pic_order_cnt_lsb = 0; 566 prev_pic_order_cnt_lsb = 0;
569 } 567 }
570 } else { 568 } else {
571 prev_pic_order_cnt_msb = prev_ref_pic_order_cnt_msb_; 569 prev_pic_order_cnt_msb = prev_ref_pic_order_cnt_msb_;
572 prev_pic_order_cnt_lsb = prev_ref_pic_order_cnt_lsb_; 570 prev_pic_order_cnt_lsb = prev_ref_pic_order_cnt_lsb_;
573 } 571 }
574 } 572 }
575 573
576 DCHECK_NE(max_pic_order_cnt_lsb_, 0); 574 DCHECK_NE(max_pic_order_cnt_lsb_, 0);
577 if ((pic_order_cnt_lsb < prev_pic_order_cnt_lsb) && 575 if ((pic_order_cnt_lsb < prev_pic_order_cnt_lsb) &&
578 (prev_pic_order_cnt_lsb - pic_order_cnt_lsb >= 576 (prev_pic_order_cnt_lsb - pic_order_cnt_lsb >=
579 max_pic_order_cnt_lsb_ / 2)) { 577 max_pic_order_cnt_lsb_ / 2)) {
580 curr_pic_->pic_order_cnt_msb = prev_pic_order_cnt_msb + 578 curr_pic_->pic_order_cnt_msb = prev_pic_order_cnt_msb +
581 max_pic_order_cnt_lsb_; 579 max_pic_order_cnt_lsb_;
582 } else if ((pic_order_cnt_lsb > prev_pic_order_cnt_lsb) && 580 } else if ((pic_order_cnt_lsb > prev_pic_order_cnt_lsb) &&
583 (pic_order_cnt_lsb - prev_pic_order_cnt_lsb > 581 (pic_order_cnt_lsb - prev_pic_order_cnt_lsb >
584 max_pic_order_cnt_lsb_ / 2)) { 582 max_pic_order_cnt_lsb_ / 2)) {
585 curr_pic_->pic_order_cnt_msb = prev_pic_order_cnt_msb - 583 curr_pic_->pic_order_cnt_msb = prev_pic_order_cnt_msb -
586 max_pic_order_cnt_lsb_; 584 max_pic_order_cnt_lsb_;
587 } else { 585 } else {
588 curr_pic_->pic_order_cnt_msb = prev_pic_order_cnt_msb; 586 curr_pic_->pic_order_cnt_msb = prev_pic_order_cnt_msb;
589 } 587 }
590 588
591 if (curr_pic_->field != VaapiH264Picture::FIELD_BOTTOM) { 589 if (curr_pic_->field != H264Picture::FIELD_BOTTOM) {
592 curr_pic_->top_field_order_cnt = curr_pic_->pic_order_cnt_msb + 590 curr_pic_->top_field_order_cnt = curr_pic_->pic_order_cnt_msb +
593 pic_order_cnt_lsb; 591 pic_order_cnt_lsb;
594 } 592 }
595 593
596 if (curr_pic_->field != VaapiH264Picture::FIELD_TOP) { 594 if (curr_pic_->field != H264Picture::FIELD_TOP) {
597 // TODO posciak: perhaps replace with pic->field? 595 // TODO posciak: perhaps replace with pic->field?
598 if (!slice_hdr->field_pic_flag) { 596 if (!slice_hdr->field_pic_flag) {
599 curr_pic_->bottom_field_order_cnt = curr_pic_->top_field_order_cnt + 597 curr_pic_->bottom_field_order_cnt = curr_pic_->top_field_order_cnt +
600 slice_hdr->delta_pic_order_cnt_bottom; 598 slice_hdr->delta_pic_order_cnt_bottom;
601 } else { 599 } else {
602 curr_pic_->bottom_field_order_cnt = curr_pic_->pic_order_cnt_msb + 600 curr_pic_->bottom_field_order_cnt = curr_pic_->pic_order_cnt_msb +
603 pic_order_cnt_lsb; 601 pic_order_cnt_lsb;
604 } 602 }
605 } 603 }
606 break; 604 break;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 // frame_num_in_pic_order_cnt_cycle is verified < 255 in parser 642 // frame_num_in_pic_order_cnt_cycle is verified < 255 in parser
645 for (int i = 0; i <= frame_num_in_pic_order_cnt_cycle; ++i) 643 for (int i = 0; i <= frame_num_in_pic_order_cnt_cycle; ++i)
646 expected_pic_order_cnt += sps->offset_for_ref_frame[i]; 644 expected_pic_order_cnt += sps->offset_for_ref_frame[i];
647 } 645 }
648 646
649 if (!slice_hdr->nal_ref_idc) 647 if (!slice_hdr->nal_ref_idc)
650 expected_pic_order_cnt += sps->offset_for_non_ref_pic; 648 expected_pic_order_cnt += sps->offset_for_non_ref_pic;
651 649
652 if (!slice_hdr->field_pic_flag) { 650 if (!slice_hdr->field_pic_flag) {
653 curr_pic_->top_field_order_cnt = expected_pic_order_cnt + 651 curr_pic_->top_field_order_cnt = expected_pic_order_cnt +
654 slice_hdr->delta_pic_order_cnt0; 652 slice_hdr->delta_pic_order_cnt[0];
655 curr_pic_->bottom_field_order_cnt = curr_pic_->top_field_order_cnt + 653 curr_pic_->bottom_field_order_cnt = curr_pic_->top_field_order_cnt +
656 sps->offset_for_top_to_bottom_field + 654 sps->offset_for_top_to_bottom_field +
657 slice_hdr->delta_pic_order_cnt1; 655 slice_hdr->delta_pic_order_cnt[1];
658 } else if (!slice_hdr->bottom_field_flag) { 656 } else if (!slice_hdr->bottom_field_flag) {
659 curr_pic_->top_field_order_cnt = expected_pic_order_cnt + 657 curr_pic_->top_field_order_cnt = expected_pic_order_cnt +
660 slice_hdr->delta_pic_order_cnt0; 658 slice_hdr->delta_pic_order_cnt[0];
661 } else { 659 } else {
662 curr_pic_->bottom_field_order_cnt = expected_pic_order_cnt + 660 curr_pic_->bottom_field_order_cnt = expected_pic_order_cnt +
663 sps->offset_for_top_to_bottom_field + 661 sps->offset_for_top_to_bottom_field +
664 slice_hdr->delta_pic_order_cnt0; 662 slice_hdr->delta_pic_order_cnt[0];
665 } 663 }
666 break; 664 break;
667 } 665 }
668 666
669 case 2: 667 case 2:
670 // See spec 8.2.1.3. 668 // See spec 8.2.1.3.
671 if (prev_has_memmgmnt5_) 669 if (prev_has_memmgmnt5_)
672 prev_frame_num_offset_ = 0; 670 prev_frame_num_offset_ = 0;
673 671
674 if (slice_hdr->idr_pic_flag) 672 if (slice_hdr->idr_pic_flag)
(...skipping 23 matching lines...) Expand all
698 curr_pic_->top_field_order_cnt = temp_pic_order_cnt; 696 curr_pic_->top_field_order_cnt = temp_pic_order_cnt;
699 } 697 }
700 break; 698 break;
701 699
702 default: 700 default:
703 DVLOG(1) << "Invalid pic_order_cnt_type: " << sps->pic_order_cnt_type; 701 DVLOG(1) << "Invalid pic_order_cnt_type: " << sps->pic_order_cnt_type;
704 return false; 702 return false;
705 } 703 }
706 704
707 switch (curr_pic_->field) { 705 switch (curr_pic_->field) {
708 case VaapiH264Picture::FIELD_NONE: 706 case H264Picture::FIELD_NONE:
709 curr_pic_->pic_order_cnt = std::min(curr_pic_->top_field_order_cnt, 707 curr_pic_->pic_order_cnt = std::min(curr_pic_->top_field_order_cnt,
710 curr_pic_->bottom_field_order_cnt); 708 curr_pic_->bottom_field_order_cnt);
711 break; 709 break;
712 case VaapiH264Picture::FIELD_TOP: 710 case H264Picture::FIELD_TOP:
713 curr_pic_->pic_order_cnt = curr_pic_->top_field_order_cnt; 711 curr_pic_->pic_order_cnt = curr_pic_->top_field_order_cnt;
714 break; 712 break;
715 case VaapiH264Picture::FIELD_BOTTOM: 713 case H264Picture::FIELD_BOTTOM:
716 curr_pic_->pic_order_cnt = curr_pic_->bottom_field_order_cnt; 714 curr_pic_->pic_order_cnt = curr_pic_->bottom_field_order_cnt;
717 break; 715 break;
718 } 716 }
719 717
720 return true; 718 return true;
721 } 719 }
722 720
723 void VaapiH264Decoder::UpdatePicNums() { 721 void VaapiH264Decoder::UpdatePicNums() {
724 for (VaapiH264DPB::Pictures::iterator it = dpb_.begin(); it != dpb_.end(); 722 for (H264DPB::Pictures::iterator it = dpb_.begin(); it != dpb_.end(); ++it) {
725 ++it) { 723 H264Picture* pic = *it;
726 VaapiH264Picture* pic = *it;
727 DCHECK(pic); 724 DCHECK(pic);
728 if (!pic->ref) 725 if (!pic->ref)
729 continue; 726 continue;
730 727
731 // Below assumes non-interlaced stream. 728 // Below assumes non-interlaced stream.
732 DCHECK_EQ(pic->field, VaapiH264Picture::FIELD_NONE); 729 DCHECK_EQ(pic->field, H264Picture::FIELD_NONE);
733 if (pic->long_term) { 730 if (pic->long_term) {
734 pic->long_term_pic_num = pic->long_term_frame_idx; 731 pic->long_term_pic_num = pic->long_term_frame_idx;
735 } else { 732 } else {
736 if (pic->frame_num > frame_num_) 733 if (pic->frame_num > frame_num_)
737 pic->frame_num_wrap = pic->frame_num - max_frame_num_; 734 pic->frame_num_wrap = pic->frame_num - max_frame_num_;
738 else 735 else
739 pic->frame_num_wrap = pic->frame_num; 736 pic->frame_num_wrap = pic->frame_num;
740 737
741 pic->pic_num = pic->frame_num_wrap; 738 pic->pic_num = pic->frame_num_wrap;
742 } 739 }
743 } 740 }
744 } 741 }
745 742
746 struct PicNumDescCompare { 743 struct PicNumDescCompare {
747 bool operator()(const VaapiH264Picture* a, const VaapiH264Picture* b) const { 744 bool operator()(const H264Picture* a, const H264Picture* b) const {
748 return a->pic_num > b->pic_num; 745 return a->pic_num > b->pic_num;
749 } 746 }
750 }; 747 };
751 748
752 struct LongTermPicNumAscCompare { 749 struct LongTermPicNumAscCompare {
753 bool operator()(const VaapiH264Picture* a, const VaapiH264Picture* b) const { 750 bool operator()(const H264Picture* a, const H264Picture* b) const {
754 return a->long_term_pic_num < b->long_term_pic_num; 751 return a->long_term_pic_num < b->long_term_pic_num;
755 } 752 }
756 }; 753 };
757 754
758 void VaapiH264Decoder::ConstructReferencePicListsP( 755 void VaapiH264Decoder::ConstructReferencePicListsP(
759 media::H264SliceHeader* slice_hdr) { 756 media::H264SliceHeader* slice_hdr) {
760 // RefPicList0 (8.2.4.2.1) [[1] [2]], where: 757 // RefPicList0 (8.2.4.2.1) [[1] [2]], where:
761 // [1] shortterm ref pics sorted by descending pic_num, 758 // [1] shortterm ref pics sorted by descending pic_num,
762 // [2] longterm ref pics by ascending long_term_pic_num. 759 // [2] longterm ref pics by ascending long_term_pic_num.
763 DCHECK(ref_pic_list0_.empty() && ref_pic_list1_.empty()); 760 DCHECK(ref_pic_list0_.empty() && ref_pic_list1_.empty());
764 // First get the short ref pics... 761 // First get the short ref pics...
765 dpb_.GetShortTermRefPicsAppending(ref_pic_list0_); 762 dpb_.GetShortTermRefPicsAppending(ref_pic_list0_);
766 size_t num_short_refs = ref_pic_list0_.size(); 763 size_t num_short_refs = ref_pic_list0_.size();
767 764
768 // and sort them to get [1]. 765 // and sort them to get [1].
769 std::sort(ref_pic_list0_.begin(), ref_pic_list0_.end(), PicNumDescCompare()); 766 std::sort(ref_pic_list0_.begin(), ref_pic_list0_.end(), PicNumDescCompare());
770 767
771 // Now get long term pics and sort them by long_term_pic_num to get [2]. 768 // Now get long term pics and sort them by long_term_pic_num to get [2].
772 dpb_.GetLongTermRefPicsAppending(ref_pic_list0_); 769 dpb_.GetLongTermRefPicsAppending(ref_pic_list0_);
773 std::sort(ref_pic_list0_.begin() + num_short_refs, ref_pic_list0_.end(), 770 std::sort(ref_pic_list0_.begin() + num_short_refs, ref_pic_list0_.end(),
774 LongTermPicNumAscCompare()); 771 LongTermPicNumAscCompare());
775 772
776 // Cut off if we have more than requested in slice header. 773 // Cut off if we have more than requested in slice header.
777 ref_pic_list0_.resize(slice_hdr->num_ref_idx_l0_active_minus1 + 1); 774 ref_pic_list0_.resize(slice_hdr->num_ref_idx_l0_active_minus1 + 1);
778 } 775 }
779 776
780 struct POCAscCompare { 777 struct POCAscCompare {
781 bool operator()(const VaapiH264Picture* a, const VaapiH264Picture* b) const { 778 bool operator()(const H264Picture* a, const H264Picture* b) const {
782 return a->pic_order_cnt < b->pic_order_cnt; 779 return a->pic_order_cnt < b->pic_order_cnt;
783 } 780 }
784 }; 781 };
785 782
786 struct POCDescCompare { 783 struct POCDescCompare {
787 bool operator()(const VaapiH264Picture* a, const VaapiH264Picture* b) const { 784 bool operator()(const H264Picture* a, const H264Picture* b) const {
788 return a->pic_order_cnt > b->pic_order_cnt; 785 return a->pic_order_cnt > b->pic_order_cnt;
789 } 786 }
790 }; 787 };
791 788
792 void VaapiH264Decoder::ConstructReferencePicListsB( 789 void VaapiH264Decoder::ConstructReferencePicListsB(
793 media::H264SliceHeader* slice_hdr) { 790 media::H264SliceHeader* slice_hdr) {
794 // RefPicList0 (8.2.4.2.3) [[1] [2] [3]], where: 791 // RefPicList0 (8.2.4.2.3) [[1] [2] [3]], where:
795 // [1] shortterm ref pics with POC < curr_pic's POC sorted by descending POC, 792 // [1] shortterm ref pics with POC < curr_pic's POC sorted by descending POC,
796 // [2] shortterm ref pics with POC > curr_pic's POC by ascending POC, 793 // [2] shortterm ref pics with POC > curr_pic's POC by ascending POC,
797 // [3] longterm ref pics by ascending long_term_pic_num. 794 // [3] longterm ref pics by ascending long_term_pic_num.
798 DCHECK(ref_pic_list0_.empty() && ref_pic_list1_.empty()); 795 DCHECK(ref_pic_list0_.empty() && ref_pic_list1_.empty());
799 dpb_.GetShortTermRefPicsAppending(ref_pic_list0_); 796 dpb_.GetShortTermRefPicsAppending(ref_pic_list0_);
800 size_t num_short_refs = ref_pic_list0_.size(); 797 size_t num_short_refs = ref_pic_list0_.size();
801 798
802 // First sort ascending, this will put [1] in right place and finish [2]. 799 // First sort ascending, this will put [1] in right place and finish [2].
803 std::sort(ref_pic_list0_.begin(), ref_pic_list0_.end(), POCAscCompare()); 800 std::sort(ref_pic_list0_.begin(), ref_pic_list0_.end(), POCAscCompare());
804 801
805 // Find first with POC > curr_pic's POC to get first element in [2]... 802 // Find first with POC > curr_pic's POC to get first element in [2]...
806 VaapiH264Picture::PtrVector::iterator iter; 803 H264Picture::PtrVector::iterator iter;
807 iter = std::upper_bound(ref_pic_list0_.begin(), ref_pic_list0_.end(), 804 iter = std::upper_bound(ref_pic_list0_.begin(), ref_pic_list0_.end(),
808 curr_pic_.get(), POCAscCompare()); 805 curr_pic_.get(), POCAscCompare());
809 806
810 // and sort [1] descending, thus finishing sequence [1] [2]. 807 // and sort [1] descending, thus finishing sequence [1] [2].
811 std::sort(ref_pic_list0_.begin(), iter, POCDescCompare()); 808 std::sort(ref_pic_list0_.begin(), iter, POCDescCompare());
812 809
813 // Now add [3] and sort by ascending long_term_pic_num. 810 // Now add [3] and sort by ascending long_term_pic_num.
814 dpb_.GetLongTermRefPicsAppending(ref_pic_list0_); 811 dpb_.GetLongTermRefPicsAppending(ref_pic_list0_);
815 std::sort(ref_pic_list0_.begin() + num_short_refs, ref_pic_list0_.end(), 812 std::sort(ref_pic_list0_.begin() + num_short_refs, ref_pic_list0_.end(),
816 LongTermPicNumAscCompare()); 813 LongTermPicNumAscCompare());
(...skipping 28 matching lines...) Expand all
845 std::swap(ref_pic_list1_[0], ref_pic_list1_[1]); 842 std::swap(ref_pic_list1_[0], ref_pic_list1_[1]);
846 843
847 // Per 8.2.4.2 it's possible for num_ref_idx_lX_active_minus1 to indicate 844 // Per 8.2.4.2 it's possible for num_ref_idx_lX_active_minus1 to indicate
848 // there should be more ref pics on list than we constructed. 845 // there should be more ref pics on list than we constructed.
849 // Those superfluous ones should be treated as non-reference. 846 // Those superfluous ones should be treated as non-reference.
850 ref_pic_list0_.resize(slice_hdr->num_ref_idx_l0_active_minus1 + 1); 847 ref_pic_list0_.resize(slice_hdr->num_ref_idx_l0_active_minus1 + 1);
851 ref_pic_list1_.resize(slice_hdr->num_ref_idx_l1_active_minus1 + 1); 848 ref_pic_list1_.resize(slice_hdr->num_ref_idx_l1_active_minus1 + 1);
852 } 849 }
853 850
854 // See 8.2.4 851 // See 8.2.4
855 int VaapiH264Decoder::PicNumF(VaapiH264Picture* pic) { 852 int VaapiH264Decoder::PicNumF(H264Picture *pic) {
856 if (!pic) 853 if (!pic)
857 return -1; 854 return -1;
858 855
859 if (!pic->long_term) 856 if (!pic->long_term)
860 return pic->pic_num; 857 return pic->pic_num;
861 else 858 else
862 return max_pic_num_; 859 return max_pic_num_;
863 } 860 }
864 861
865 // See 8.2.4 862 // See 8.2.4
866 int VaapiH264Decoder::LongTermPicNumF(VaapiH264Picture* pic) { 863 int VaapiH264Decoder::LongTermPicNumF(H264Picture *pic) {
867 if (pic->ref && pic->long_term) 864 if (pic->ref && pic->long_term)
868 return pic->long_term_pic_num; 865 return pic->long_term_pic_num;
869 else 866 else
870 return 2 * (max_long_term_frame_idx_ + 1); 867 return 2 * (max_long_term_frame_idx_ + 1);
871 } 868 }
872 869
873 // Shift elements on the |v| starting from |from| to |to|, inclusive, 870 // Shift elements on the |v| starting from |from| to |to|, inclusive,
874 // one position to the right and insert pic at |from|. 871 // one position to the right and insert pic at |from|.
875 static void ShiftRightAndInsert(VaapiH264Picture::PtrVector* v, 872 static void ShiftRightAndInsert(H264Picture::PtrVector *v,
876 int from, 873 int from,
877 int to, 874 int to,
878 VaapiH264Picture* pic) { 875 H264Picture* pic) {
879 // Security checks, do not disable in Debug mode. 876 // Security checks, do not disable in Debug mode.
880 CHECK(from <= to); 877 CHECK(from <= to);
881 CHECK(to <= std::numeric_limits<int>::max() - 2); 878 CHECK(to <= std::numeric_limits<int>::max() - 2);
882 // Additional checks. Debug mode ok. 879 // Additional checks. Debug mode ok.
883 DCHECK(v); 880 DCHECK(v);
884 DCHECK(pic); 881 DCHECK(pic);
885 DCHECK((to + 1 == static_cast<int>(v->size())) || 882 DCHECK((to + 1 == static_cast<int>(v->size())) ||
886 (to + 2 == static_cast<int>(v->size()))); 883 (to + 2 == static_cast<int>(v->size())));
887 884
888 v->resize(to + 2); 885 v->resize(to + 2);
889 886
890 for (int i = to + 1; i > from; --i) 887 for (int i = to + 1; i > from; --i)
891 (*v)[i] = (*v)[i - 1]; 888 (*v)[i] = (*v)[i - 1];
892 889
893 (*v)[from] = pic; 890 (*v)[from] = pic;
894 } 891 }
895 892
896 bool VaapiH264Decoder::ModifyReferencePicList(media::H264SliceHeader* slice_hdr, 893 bool VaapiH264Decoder::ModifyReferencePicList(media::H264SliceHeader* slice_hdr,
897 int list) { 894 int list) {
898 int num_ref_idx_lX_active_minus1; 895 int num_ref_idx_lX_active_minus1;
899 VaapiH264Picture::PtrVector* ref_pic_listx; 896 H264Picture::PtrVector* ref_pic_listx;
900 media::H264ModificationOfPicNum* list_mod; 897 media::H264ModificationOfPicNum* list_mod;
901 898
902 // This can process either ref_pic_list0 or ref_pic_list1, depending on 899 // This can process either ref_pic_list0 or ref_pic_list1, depending on
903 // the list argument. Set up pointers to proper list to be processed here. 900 // the list argument. Set up pointers to proper list to be processed here.
904 if (list == 0) { 901 if (list == 0) {
905 if (!slice_hdr->ref_pic_list_modification_flag_l0) 902 if (!slice_hdr->ref_pic_list_modification_flag_l0)
906 return true; 903 return true;
907 904
908 list_mod = slice_hdr->ref_list_l0_modifications; 905 list_mod = slice_hdr->ref_list_l0_modifications;
909 num_ref_idx_lX_active_minus1 = ref_pic_list0_.size() - 1; 906 num_ref_idx_lX_active_minus1 = ref_pic_list0_.size() - 1;
(...skipping 11 matching lines...) Expand all
921 918
922 DCHECK_GE(num_ref_idx_lX_active_minus1, 0); 919 DCHECK_GE(num_ref_idx_lX_active_minus1, 0);
923 920
924 // Spec 8.2.4.3: 921 // Spec 8.2.4.3:
925 // Reorder pictures on the list in a way specified in the stream. 922 // Reorder pictures on the list in a way specified in the stream.
926 int pic_num_lx_pred = curr_pic_->pic_num; 923 int pic_num_lx_pred = curr_pic_->pic_num;
927 int ref_idx_lx = 0; 924 int ref_idx_lx = 0;
928 int pic_num_lx_no_wrap; 925 int pic_num_lx_no_wrap;
929 int pic_num_lx; 926 int pic_num_lx;
930 bool done = false; 927 bool done = false;
931 VaapiH264Picture* pic; 928 H264Picture* pic;
932 for (int i = 0; i < media::H264SliceHeader::kRefListModSize && !done; ++i) { 929 for (int i = 0; i < media::H264SliceHeader::kRefListModSize && !done; ++i) {
933 switch (list_mod->modification_of_pic_nums_idc) { 930 switch (list_mod->modification_of_pic_nums_idc) {
934 case 0: 931 case 0:
935 case 1: 932 case 1:
936 // Modify short reference picture position. 933 // Modify short reference picture position.
937 if (list_mod->modification_of_pic_nums_idc == 0) { 934 if (list_mod->modification_of_pic_nums_idc == 0) {
938 // Subtract given value from predicted PicNum. 935 // Subtract given value from predicted PicNum.
939 pic_num_lx_no_wrap = pic_num_lx_pred - 936 pic_num_lx_no_wrap = pic_num_lx_pred -
940 (static_cast<int>(list_mod->abs_diff_pic_num_minus1) + 1); 937 (static_cast<int>(list_mod->abs_diff_pic_num_minus1) + 1);
941 // Wrap around max_pic_num_ if it becomes < 0 as result 938 // Wrap around max_pic_num_ if it becomes < 0 as result
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1017 } 1014 }
1018 1015
1019 // Per NOTE 2 in 8.2.4.3.2, the ref_pic_listx size in the above loop is 1016 // Per NOTE 2 in 8.2.4.3.2, the ref_pic_listx size in the above loop is
1020 // temporarily made one element longer than the required final list. 1017 // temporarily made one element longer than the required final list.
1021 // Resize the list back to its required size. 1018 // Resize the list back to its required size.
1022 ref_pic_listx->resize(num_ref_idx_lX_active_minus1 + 1); 1019 ref_pic_listx->resize(num_ref_idx_lX_active_minus1 + 1);
1023 1020
1024 return true; 1021 return true;
1025 } 1022 }
1026 1023
1027 bool VaapiH264Decoder::OutputPic(VaapiH264Picture* pic) { 1024 bool VaapiH264Decoder::OutputPic(H264Picture* pic) {
1028 DCHECK(!pic->outputted); 1025 DCHECK(!pic->outputted);
1029 pic->outputted = true; 1026 pic->outputted = true;
1030 last_output_poc_ = pic->pic_order_cnt; 1027 last_output_poc_ = pic->pic_order_cnt;
1031 1028
1032 DecodeSurface* dec_surface = DecodeSurfaceByPoC(pic->pic_order_cnt); 1029 DecodeSurface* dec_surface = DecodeSurfaceByPoC(pic->pic_order_cnt);
1033 if (!dec_surface) 1030 if (!dec_surface)
1034 return false; 1031 return false;
1035 1032
1036 DCHECK_GE(dec_surface->input_id(), 0); 1033 DCHECK_GE(dec_surface->input_id(), 0);
1037 DVLOG(4) << "Posting output task for POC: " << pic->pic_order_cnt 1034 DVLOG(4) << "Posting output task for POC: " << pic->pic_order_cnt
1038 << " input_id: " << dec_surface->input_id(); 1035 << " input_id: " << dec_surface->input_id();
1039 output_pic_cb_.Run(dec_surface->input_id(), dec_surface->va_surface()); 1036 output_pic_cb_.Run(dec_surface->input_id(), dec_surface->va_surface());
1040 1037
1041 return true; 1038 return true;
1042 } 1039 }
1043 1040
1044 void VaapiH264Decoder::ClearDPB() { 1041 void VaapiH264Decoder::ClearDPB() {
1045 // Clear DPB contents, marking the pictures as unused first. 1042 // Clear DPB contents, marking the pictures as unused first.
1046 for (VaapiH264DPB::Pictures::iterator it = dpb_.begin(); it != dpb_.end(); 1043 for (H264DPB::Pictures::iterator it = dpb_.begin(); it != dpb_.end(); ++it)
1047 ++it)
1048 UnassignSurfaceFromPoC((*it)->pic_order_cnt); 1044 UnassignSurfaceFromPoC((*it)->pic_order_cnt);
1049 1045
1050 dpb_.Clear(); 1046 dpb_.Clear();
1051 last_output_poc_ = std::numeric_limits<int>::min(); 1047 last_output_poc_ = std::numeric_limits<int>::min();
1052 } 1048 }
1053 1049
1054 bool VaapiH264Decoder::OutputAllRemainingPics() { 1050 bool VaapiH264Decoder::OutputAllRemainingPics() {
1055 // Output all pictures that are waiting to be outputted. 1051 // Output all pictures that are waiting to be outputted.
1056 FinishPrevFrameIfPresent(); 1052 FinishPrevFrameIfPresent();
1057 VaapiH264Picture::PtrVector to_output; 1053 H264Picture::PtrVector to_output;
1058 dpb_.GetNotOutputtedPicsAppending(to_output); 1054 dpb_.GetNotOutputtedPicsAppending(to_output);
1059 // Sort them by ascending POC to output in order. 1055 // Sort them by ascending POC to output in order.
1060 std::sort(to_output.begin(), to_output.end(), POCAscCompare()); 1056 std::sort(to_output.begin(), to_output.end(), POCAscCompare());
1061 1057
1062 VaapiH264Picture::PtrVector::iterator it; 1058 H264Picture::PtrVector::iterator it;
1063 for (it = to_output.begin(); it != to_output.end(); ++it) { 1059 for (it = to_output.begin(); it != to_output.end(); ++it) {
1064 if (!OutputPic(*it)) { 1060 if (!OutputPic(*it)) {
1065 DVLOG(1) << "Failed to output pic POC: " << (*it)->pic_order_cnt; 1061 DVLOG(1) << "Failed to output pic POC: " << (*it)->pic_order_cnt;
1066 return false; 1062 return false;
1067 } 1063 }
1068 } 1064 }
1069 1065
1070 return true; 1066 return true;
1071 } 1067 }
1072 1068
(...skipping 21 matching lines...) Expand all
1094 return false; 1090 return false;
1095 } 1091 }
1096 dpb_.Clear(); 1092 dpb_.Clear();
1097 last_output_poc_ = std::numeric_limits<int>::min(); 1093 last_output_poc_ = std::numeric_limits<int>::min();
1098 } 1094 }
1099 1095
1100 // curr_pic_ should have either been added to DPB or discarded when finishing 1096 // curr_pic_ should have either been added to DPB or discarded when finishing
1101 // the last frame. DPB is responsible for releasing that memory once it's 1097 // the last frame. DPB is responsible for releasing that memory once it's
1102 // not needed anymore. 1098 // not needed anymore.
1103 DCHECK(!curr_pic_.get()); 1099 DCHECK(!curr_pic_.get());
1104 curr_pic_.reset(new VaapiH264Picture); 1100 curr_pic_.reset(new H264Picture);
1105 CHECK(curr_pic_.get()); 1101 CHECK(curr_pic_.get());
1106 1102
1107 if (!InitCurrPicture(slice_hdr)) 1103 if (!InitCurrPicture(slice_hdr))
1108 return false; 1104 return false;
1109 1105
1110 DCHECK_GT(max_frame_num_, 0); 1106 DCHECK_GT(max_frame_num_, 0);
1111 1107
1112 UpdatePicNums(); 1108 UpdatePicNums();
1113 1109
1114 // Send parameter buffers before each new picture, before the first slice. 1110 // Send parameter buffers before each new picture, before the first slice.
1115 if (!SendPPS()) 1111 if (!SendPPS())
1116 return false; 1112 return false;
1117 1113
1118 if (!SendIQMatrix()) 1114 if (!SendIQMatrix())
1119 return false; 1115 return false;
1120 1116
1121 if (!QueueSlice(slice_hdr)) 1117 if (!QueueSlice(slice_hdr))
1122 return false; 1118 return false;
1123 1119
1124 return true; 1120 return true;
1125 } 1121 }
1126 1122
1127 bool VaapiH264Decoder::HandleMemoryManagementOps() { 1123 bool VaapiH264Decoder::HandleMemoryManagementOps() {
1128 // 8.2.5.4 1124 // 8.2.5.4
1129 for (unsigned int i = 0; i < arraysize(curr_pic_->ref_pic_marking); ++i) { 1125 for (unsigned int i = 0; i < arraysize(curr_pic_->ref_pic_marking); ++i) {
1130 // Code below does not support interlaced stream (per-field pictures). 1126 // Code below does not support interlaced stream (per-field pictures).
1131 media::H264DecRefPicMarking* ref_pic_marking = 1127 media::H264DecRefPicMarking* ref_pic_marking =
1132 &curr_pic_->ref_pic_marking[i]; 1128 &curr_pic_->ref_pic_marking[i];
1133 VaapiH264Picture* to_mark; 1129 H264Picture* to_mark;
1134 int pic_num_x; 1130 int pic_num_x;
1135 1131
1136 switch (ref_pic_marking->memory_mgmnt_control_operation) { 1132 switch (ref_pic_marking->memory_mgmnt_control_operation) {
1137 case 0: 1133 case 0:
1138 // Normal end of operations' specification. 1134 // Normal end of operations' specification.
1139 return true; 1135 return true;
1140 1136
1141 case 1: 1137 case 1:
1142 // Mark a short term reference picture as unused so it can be removed 1138 // Mark a short term reference picture as unused so it can be removed
1143 // if outputted. 1139 // if outputted.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 } else { 1173 } else {
1178 DVLOG(1) << "Invalid short term ref pic num to mark as long ref"; 1174 DVLOG(1) << "Invalid short term ref pic num to mark as long ref";
1179 return false; 1175 return false;
1180 } 1176 }
1181 break; 1177 break;
1182 1178
1183 case 4: { 1179 case 4: {
1184 // Unmark all reference pictures with long_term_frame_idx over new max. 1180 // Unmark all reference pictures with long_term_frame_idx over new max.
1185 max_long_term_frame_idx_ 1181 max_long_term_frame_idx_
1186 = ref_pic_marking->max_long_term_frame_idx_plus1 - 1; 1182 = ref_pic_marking->max_long_term_frame_idx_plus1 - 1;
1187 VaapiH264Picture::PtrVector long_terms; 1183 H264Picture::PtrVector long_terms;
1188 dpb_.GetLongTermRefPicsAppending(long_terms); 1184 dpb_.GetLongTermRefPicsAppending(long_terms);
1189 for (size_t i = 0; i < long_terms.size(); ++i) { 1185 for (size_t i = 0; i < long_terms.size(); ++i) {
1190 VaapiH264Picture* pic = long_terms[i]; 1186 H264Picture* pic = long_terms[i];
1191 DCHECK(pic->ref && pic->long_term); 1187 DCHECK(pic->ref && pic->long_term);
1192 // Ok to cast, max_long_term_frame_idx is much smaller than 16bit. 1188 // Ok to cast, max_long_term_frame_idx is much smaller than 16bit.
1193 if (pic->long_term_frame_idx > 1189 if (pic->long_term_frame_idx >
1194 static_cast<int>(max_long_term_frame_idx_)) 1190 static_cast<int>(max_long_term_frame_idx_))
1195 pic->ref = false; 1191 pic->ref = false;
1196 } 1192 }
1197 break; 1193 break;
1198 } 1194 }
1199 1195
1200 case 5: 1196 case 5:
1201 // Unmark all reference pictures. 1197 // Unmark all reference pictures.
1202 dpb_.MarkAllUnusedForRef(); 1198 dpb_.MarkAllUnusedForRef();
1203 max_long_term_frame_idx_ = -1; 1199 max_long_term_frame_idx_ = -1;
1204 curr_pic_->mem_mgmt_5 = true; 1200 curr_pic_->mem_mgmt_5 = true;
1205 break; 1201 break;
1206 1202
1207 case 6: { 1203 case 6: {
1208 // Replace long term reference pictures with current picture. 1204 // Replace long term reference pictures with current picture.
1209 // First unmark if any existing with this long_term_frame_idx... 1205 // First unmark if any existing with this long_term_frame_idx...
1210 VaapiH264Picture::PtrVector long_terms; 1206 H264Picture::PtrVector long_terms;
1211 dpb_.GetLongTermRefPicsAppending(long_terms); 1207 dpb_.GetLongTermRefPicsAppending(long_terms);
1212 for (size_t i = 0; i < long_terms.size(); ++i) { 1208 for (size_t i = 0; i < long_terms.size(); ++i) {
1213 VaapiH264Picture* pic = long_terms[i]; 1209 H264Picture* pic = long_terms[i];
1214 DCHECK(pic->ref && pic->long_term); 1210 DCHECK(pic->ref && pic->long_term);
1215 // Ok to cast, long_term_frame_idx is much smaller than 16bit. 1211 // Ok to cast, long_term_frame_idx is much smaller than 16bit.
1216 if (pic->long_term_frame_idx == 1212 if (pic->long_term_frame_idx ==
1217 static_cast<int>(ref_pic_marking->long_term_frame_idx)) 1213 static_cast<int>(ref_pic_marking->long_term_frame_idx))
1218 pic->ref = false; 1214 pic->ref = false;
1219 } 1215 }
1220 1216
1221 // and mark the current one instead. 1217 // and mark the current one instead.
1222 curr_pic_->ref = true; 1218 curr_pic_->ref = true;
1223 curr_pic_->long_term = true; 1219 curr_pic_->long_term = true;
(...skipping 26 matching lines...) Expand all
1250 max_long_term_frame_idx_ = 0; 1246 max_long_term_frame_idx_ = 0;
1251 } else { 1247 } else {
1252 curr_pic_->long_term = false; 1248 curr_pic_->long_term = false;
1253 max_long_term_frame_idx_ = -1; 1249 max_long_term_frame_idx_ = -1;
1254 } 1250 }
1255 } else { 1251 } else {
1256 if (!curr_pic_->adaptive_ref_pic_marking_mode_flag) { 1252 if (!curr_pic_->adaptive_ref_pic_marking_mode_flag) {
1257 // If non-IDR, and the stream does not indicate what we should do to 1253 // If non-IDR, and the stream does not indicate what we should do to
1258 // ensure DPB doesn't overflow, discard oldest picture. 1254 // ensure DPB doesn't overflow, discard oldest picture.
1259 // See spec 8.2.5.3. 1255 // See spec 8.2.5.3.
1260 if (curr_pic_->field == VaapiH264Picture::FIELD_NONE) { 1256 if (curr_pic_->field == H264Picture::FIELD_NONE) {
1261 DCHECK_LE(dpb_.CountRefPics(), 1257 DCHECK_LE(dpb_.CountRefPics(),
1262 std::max<int>(parser_.GetSPS(curr_sps_id_)->max_num_ref_frames, 1258 std::max<int>(parser_.GetSPS(curr_sps_id_)->max_num_ref_frames,
1263 1)); 1259 1));
1264 if (dpb_.CountRefPics() == 1260 if (dpb_.CountRefPics() ==
1265 std::max<int>(parser_.GetSPS(curr_sps_id_)->max_num_ref_frames, 1261 std::max<int>(parser_.GetSPS(curr_sps_id_)->max_num_ref_frames,
1266 1)) { 1262 1)) {
1267 // Max number of reference pics reached, 1263 // Max number of reference pics reached,
1268 // need to remove one of the short term ones. 1264 // need to remove one of the short term ones.
1269 // Find smallest frame_num_wrap short reference picture and mark 1265 // Find smallest frame_num_wrap short reference picture and mark
1270 // it as unused. 1266 // it as unused.
1271 VaapiH264Picture* to_unmark = dpb_.GetLowestFrameNumWrapShortRefPic(); 1267 H264Picture* to_unmark = dpb_.GetLowestFrameNumWrapShortRefPic();
1272 if (to_unmark == NULL) { 1268 if (to_unmark == NULL) {
1273 DVLOG(1) << "Couldn't find a short ref picture to unmark"; 1269 DVLOG(1) << "Couldn't find a short ref picture to unmark";
1274 return; 1270 return;
1275 } 1271 }
1276 to_unmark->ref = false; 1272 to_unmark->ref = false;
1277 } 1273 }
1278 } else { 1274 } else {
1279 // Shouldn't get here. 1275 // Shouldn't get here.
1280 DVLOG(1) << "Interlaced video not supported."; 1276 DVLOG(1) << "Interlaced video not supported.";
1281 report_error_to_uma_cb_.Run(INTERLACED_STREAM); 1277 report_error_to_uma_cb_.Run(INTERLACED_STREAM);
1282 } 1278 }
1283 } else { 1279 } else {
1284 // Stream has instructions how to discard pictures from DPB and how 1280 // Stream has instructions how to discard pictures from DPB and how
1285 // to mark/unmark existing reference pictures. Do it. 1281 // to mark/unmark existing reference pictures. Do it.
1286 // Spec 8.2.5.4. 1282 // Spec 8.2.5.4.
1287 if (curr_pic_->field == VaapiH264Picture::FIELD_NONE) { 1283 if (curr_pic_->field == H264Picture::FIELD_NONE) {
1288 HandleMemoryManagementOps(); 1284 HandleMemoryManagementOps();
1289 } else { 1285 } else {
1290 // Shouldn't get here. 1286 // Shouldn't get here.
1291 DVLOG(1) << "Interlaced video not supported."; 1287 DVLOG(1) << "Interlaced video not supported.";
1292 report_error_to_uma_cb_.Run(INTERLACED_STREAM); 1288 report_error_to_uma_cb_.Run(INTERLACED_STREAM);
1293 } 1289 }
1294 } 1290 }
1295 } 1291 }
1296 } 1292 }
1297 1293
1298 bool VaapiH264Decoder::FinishPicture() { 1294 bool VaapiH264Decoder::FinishPicture() {
1299 DCHECK(curr_pic_.get()); 1295 DCHECK(curr_pic_.get());
1300 1296
1301 // Finish processing previous picture. 1297 // Finish processing previous picture.
1302 // Start by storing previous reference picture data for later use, 1298 // Start by storing previous reference picture data for later use,
1303 // if picture being finished is a reference picture. 1299 // if picture being finished is a reference picture.
1304 if (curr_pic_->ref) { 1300 if (curr_pic_->ref) {
1305 ReferencePictureMarking(); 1301 ReferencePictureMarking();
1306 prev_ref_has_memmgmnt5_ = curr_pic_->mem_mgmt_5; 1302 prev_ref_has_memmgmnt5_ = curr_pic_->mem_mgmt_5;
1307 prev_ref_top_field_order_cnt_ = curr_pic_->top_field_order_cnt; 1303 prev_ref_top_field_order_cnt_ = curr_pic_->top_field_order_cnt;
1308 prev_ref_pic_order_cnt_msb_ = curr_pic_->pic_order_cnt_msb; 1304 prev_ref_pic_order_cnt_msb_ = curr_pic_->pic_order_cnt_msb;
1309 prev_ref_pic_order_cnt_lsb_ = curr_pic_->pic_order_cnt_lsb; 1305 prev_ref_pic_order_cnt_lsb_ = curr_pic_->pic_order_cnt_lsb;
1310 prev_ref_field_ = curr_pic_->field; 1306 prev_ref_field_ = curr_pic_->field;
1311 } 1307 }
1312 prev_has_memmgmnt5_ = curr_pic_->mem_mgmt_5; 1308 prev_has_memmgmnt5_ = curr_pic_->mem_mgmt_5;
1313 prev_frame_num_offset_ = curr_pic_->frame_num_offset; 1309 prev_frame_num_offset_ = curr_pic_->frame_num_offset;
1314 1310
1315 // Remove unused (for reference or later output) pictures from DPB, marking 1311 // Remove unused (for reference or later output) pictures from DPB, marking
1316 // them as such. 1312 // them as such.
1317 for (VaapiH264DPB::Pictures::iterator it = dpb_.begin(); it != dpb_.end(); 1313 for (H264DPB::Pictures::iterator it = dpb_.begin(); it != dpb_.end(); ++it) {
1318 ++it) {
1319 if ((*it)->outputted && !(*it)->ref) 1314 if ((*it)->outputted && !(*it)->ref)
1320 UnassignSurfaceFromPoC((*it)->pic_order_cnt); 1315 UnassignSurfaceFromPoC((*it)->pic_order_cnt);
1321 } 1316 }
1322 dpb_.DeleteUnused(); 1317 dpb_.DeleteUnused();
1323 1318
1324 DVLOG(4) << "Finishing picture, entries in DPB: " << dpb_.size(); 1319 DVLOG(4) << "Finishing picture, entries in DPB: " << dpb_.size();
1325 1320
1326 // Whatever happens below, curr_pic_ will stop managing the pointer to the 1321 // Whatever happens below, curr_pic_ will stop managing the pointer to the
1327 // picture after this function returns. The ownership will either be 1322 // picture after this function returns. The ownership will either be
1328 // transferred to DPB, if the image is still needed (for output and/or 1323 // transferred to DPB, if the image is still needed (for output and/or
1329 // reference), or the memory will be released if we manage to output it here 1324 // reference), or the memory will be released if we manage to output it here
1330 // without having to store it for future reference. 1325 // without having to store it for future reference.
1331 scoped_ptr<VaapiH264Picture> pic(curr_pic_.release()); 1326 scoped_ptr<H264Picture> pic(curr_pic_.release());
1332 1327
1333 // Get all pictures that haven't been outputted yet. 1328 // Get all pictures that haven't been outputted yet.
1334 VaapiH264Picture::PtrVector not_outputted; 1329 H264Picture::PtrVector not_outputted;
1335 // TODO(posciak): pass as pointer, not reference (violates coding style). 1330 // TODO(posciak): pass as pointer, not reference (violates coding style).
1336 dpb_.GetNotOutputtedPicsAppending(not_outputted); 1331 dpb_.GetNotOutputtedPicsAppending(not_outputted);
1337 // Include the one we've just decoded. 1332 // Include the one we've just decoded.
1338 not_outputted.push_back(pic.get()); 1333 not_outputted.push_back(pic.get());
1339 1334
1340 // Sort in output order. 1335 // Sort in output order.
1341 std::sort(not_outputted.begin(), not_outputted.end(), POCAscCompare()); 1336 std::sort(not_outputted.begin(), not_outputted.end(), POCAscCompare());
1342 1337
1343 // Try to output as many pictures as we can. A picture can be output, 1338 // Try to output as many pictures as we can. A picture can be output,
1344 // if the number of decoded and not yet outputted pictures that would remain 1339 // if the number of decoded and not yet outputted pictures that would remain
1345 // in DPB afterwards would at least be equal to max_num_reorder_frames. 1340 // in DPB afterwards would at least be equal to max_num_reorder_frames.
1346 // If the outputted picture is not a reference picture, it doesn't have 1341 // If the outputted picture is not a reference picture, it doesn't have
1347 // to remain in the DPB and can be removed. 1342 // to remain in the DPB and can be removed.
1348 VaapiH264Picture::PtrVector::iterator output_candidate = 1343 H264Picture::PtrVector::iterator output_candidate = not_outputted.begin();
1349 not_outputted.begin();
1350 size_t num_remaining = not_outputted.size(); 1344 size_t num_remaining = not_outputted.size();
1351 while (num_remaining > max_num_reorder_frames_) { 1345 while (num_remaining > max_num_reorder_frames_) {
1352 int poc = (*output_candidate)->pic_order_cnt; 1346 int poc = (*output_candidate)->pic_order_cnt;
1353 DCHECK_GE(poc, last_output_poc_); 1347 DCHECK_GE(poc, last_output_poc_);
1354 if (!OutputPic(*output_candidate)) 1348 if (!OutputPic(*output_candidate))
1355 return false; 1349 return false;
1356 1350
1357 if (!(*output_candidate)->ref) { 1351 if (!(*output_candidate)->ref) {
1358 // Current picture hasn't been inserted into DPB yet, so don't remove it 1352 // Current picture hasn't been inserted into DPB yet, so don't remove it
1359 // if we managed to output it immediately. 1353 // if we managed to output it immediately.
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1489 1483
1490 max_pic_order_cnt_lsb_ = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4); 1484 max_pic_order_cnt_lsb_ = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1491 max_frame_num_ = 1 << (sps->log2_max_frame_num_minus4 + 4); 1485 max_frame_num_ = 1 << (sps->log2_max_frame_num_minus4 + 4);
1492 1486
1493 int level = sps->level_idc; 1487 int level = sps->level_idc;
1494 int max_dpb_mbs = LevelToMaxDpbMbs(level); 1488 int max_dpb_mbs = LevelToMaxDpbMbs(level);
1495 if (max_dpb_mbs == 0) 1489 if (max_dpb_mbs == 0)
1496 return false; 1490 return false;
1497 1491
1498 size_t max_dpb_size = std::min(max_dpb_mbs / (width_mb * height_mb), 1492 size_t max_dpb_size = std::min(max_dpb_mbs / (width_mb * height_mb),
1499 static_cast<int>(VaapiH264DPB::kDPBMaxSize)); 1493 static_cast<int>(H264DPB::kDPBMaxSize));
1500 DVLOG(1) << "Codec level: " << level << ", DPB size: " << max_dpb_size; 1494 DVLOG(1) << "Codec level: " << level << ", DPB size: " << max_dpb_size;
1501 if (max_dpb_size == 0) { 1495 if (max_dpb_size == 0) {
1502 DVLOG(1) << "Invalid DPB Size"; 1496 DVLOG(1) << "Invalid DPB Size";
1503 return false; 1497 return false;
1504 } 1498 }
1505 1499
1506 dpb_.set_max_num_pics(max_dpb_size); 1500 dpb_.set_max_num_pics(max_dpb_size);
1507 1501
1508 if (!UpdateMaxNumReorderFrames(sps)) 1502 if (!UpdateMaxNumReorderFrames(sps))
1509 return false; 1503 return false;
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
1697 break; 1691 break;
1698 } 1692 }
1699 } 1693 }
1700 } 1694 }
1701 1695
1702 size_t VaapiH264Decoder::GetRequiredNumOfPictures() { 1696 size_t VaapiH264Decoder::GetRequiredNumOfPictures() {
1703 return dpb_.max_num_pics() + kPicsInPipeline; 1697 return dpb_.max_num_pics() + kPicsInPipeline;
1704 } 1698 }
1705 1699
1706 } // namespace content 1700 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/vaapi_h264_decoder.h ('k') | content/common/gpu/media/vaapi_h264_dpb.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698