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

Side by Side Diff: media/gpu/h264_decoder.cc

Issue 1882373004: Migrate content/common/gpu/media code to media/gpu (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix several more bot-identified build issues Created 4 years, 8 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/callback_helpers.h" 10 #include "base/callback_helpers.h"
11 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/numerics/safe_conversions.h" 12 #include "base/numerics/safe_conversions.h"
13 #include "base/stl_util.h" 13 #include "base/stl_util.h"
14 #include "content/common/gpu/media/h264_decoder.h" 14 #include "media/gpu/h264_decoder.h"
15 15
16 namespace content { 16 namespace media {
17 17
18 H264Decoder::H264Accelerator::H264Accelerator() { 18 H264Decoder::H264Accelerator::H264Accelerator() {}
19 }
20 19
21 H264Decoder::H264Accelerator::~H264Accelerator() { 20 H264Decoder::H264Accelerator::~H264Accelerator() {}
22 }
23 21
24 H264Decoder::H264Decoder(H264Accelerator* accelerator) 22 H264Decoder::H264Decoder(H264Accelerator* accelerator)
25 : max_frame_num_(0), 23 : max_frame_num_(0),
26 max_pic_num_(0), 24 max_pic_num_(0),
27 max_long_term_frame_idx_(0), 25 max_long_term_frame_idx_(0),
28 max_num_reorder_frames_(0), 26 max_num_reorder_frames_(0),
29 accelerator_(accelerator) { 27 accelerator_(accelerator) {
30 DCHECK(accelerator_); 28 DCHECK(accelerator_);
31 Reset(); 29 Reset();
32 state_ = kNeedStreamMetadata; 30 state_ = kNeedStreamMetadata;
33 } 31 }
34 32
35 H264Decoder::~H264Decoder() { 33 H264Decoder::~H264Decoder() {}
36 }
37 34
38 void H264Decoder::Reset() { 35 void H264Decoder::Reset() {
39 curr_pic_ = nullptr; 36 curr_pic_ = nullptr;
40 curr_nalu_ = nullptr; 37 curr_nalu_ = nullptr;
41 curr_slice_hdr_ = nullptr; 38 curr_slice_hdr_ = nullptr;
42 curr_sps_id_ = -1; 39 curr_sps_id_ = -1;
43 curr_pps_id_ = -1; 40 curr_pps_id_ = -1;
44 41
45 prev_frame_num_ = -1; 42 prev_frame_num_ = -1;
46 prev_ref_frame_num_ = -1; 43 prev_ref_frame_num_ = -1;
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 164
168 curr_pic_->long_term_reference_flag = slice_hdr->long_term_reference_flag; 165 curr_pic_->long_term_reference_flag = slice_hdr->long_term_reference_flag;
169 curr_pic_->adaptive_ref_pic_marking_mode_flag = 166 curr_pic_->adaptive_ref_pic_marking_mode_flag =
170 slice_hdr->adaptive_ref_pic_marking_mode_flag; 167 slice_hdr->adaptive_ref_pic_marking_mode_flag;
171 168
172 // If the slice header indicates we will have to perform reference marking 169 // If the slice header indicates we will have to perform reference marking
173 // process after this picture is decoded, store required data for that 170 // process after this picture is decoded, store required data for that
174 // purpose. 171 // purpose.
175 if (slice_hdr->adaptive_ref_pic_marking_mode_flag) { 172 if (slice_hdr->adaptive_ref_pic_marking_mode_flag) {
176 static_assert(sizeof(curr_pic_->ref_pic_marking) == 173 static_assert(sizeof(curr_pic_->ref_pic_marking) ==
177 sizeof(slice_hdr->ref_pic_marking), 174 sizeof(slice_hdr->ref_pic_marking),
178 "Array sizes of ref pic marking do not match."); 175 "Array sizes of ref pic marking do not match.");
179 memcpy(curr_pic_->ref_pic_marking, slice_hdr->ref_pic_marking, 176 memcpy(curr_pic_->ref_pic_marking, slice_hdr->ref_pic_marking,
180 sizeof(curr_pic_->ref_pic_marking)); 177 sizeof(curr_pic_->ref_pic_marking));
181 } 178 }
182 179
183 return true; 180 return true;
184 } 181 }
185 182
186 bool H264Decoder::CalculatePicOrderCounts(scoped_refptr<H264Picture> pic) { 183 bool H264Decoder::CalculatePicOrderCounts(scoped_refptr<H264Picture> pic) {
187 const media::H264SPS* sps = parser_.GetSPS(curr_sps_id_); 184 const media::H264SPS* sps = parser_.GetSPS(curr_sps_id_);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 --abs_frame_num; 261 --abs_frame_num;
265 262
266 int expected_pic_order_cnt = 0; 263 int expected_pic_order_cnt = 0;
267 if (abs_frame_num > 0) { 264 if (abs_frame_num > 0) {
268 if (sps->num_ref_frames_in_pic_order_cnt_cycle == 0) { 265 if (sps->num_ref_frames_in_pic_order_cnt_cycle == 0) {
269 DVLOG(1) << "Invalid num_ref_frames_in_pic_order_cnt_cycle " 266 DVLOG(1) << "Invalid num_ref_frames_in_pic_order_cnt_cycle "
270 << "in stream"; 267 << "in stream";
271 return false; 268 return false;
272 } 269 }
273 270
274 int pic_order_cnt_cycle_cnt = (abs_frame_num - 1) / 271 int pic_order_cnt_cycle_cnt =
275 sps->num_ref_frames_in_pic_order_cnt_cycle; 272 (abs_frame_num - 1) / sps->num_ref_frames_in_pic_order_cnt_cycle;
276 int frame_num_in_pic_order_cnt_cycle = (abs_frame_num - 1) % 273 int frame_num_in_pic_order_cnt_cycle =
277 sps->num_ref_frames_in_pic_order_cnt_cycle; 274 (abs_frame_num - 1) % sps->num_ref_frames_in_pic_order_cnt_cycle;
278 275
279 expected_pic_order_cnt = pic_order_cnt_cycle_cnt * 276 expected_pic_order_cnt = pic_order_cnt_cycle_cnt *
280 sps->expected_delta_per_pic_order_cnt_cycle; 277 sps->expected_delta_per_pic_order_cnt_cycle;
281 // frame_num_in_pic_order_cnt_cycle is verified < 255 in parser 278 // frame_num_in_pic_order_cnt_cycle is verified < 255 in parser
282 for (int i = 0; i <= frame_num_in_pic_order_cnt_cycle; ++i) 279 for (int i = 0; i <= frame_num_in_pic_order_cnt_cycle; ++i)
283 expected_pic_order_cnt += sps->offset_for_ref_frame[i]; 280 expected_pic_order_cnt += sps->offset_for_ref_frame[i];
284 } 281 }
285 282
286 if (!pic->nal_ref_idc) 283 if (!pic->nal_ref_idc)
287 expected_pic_order_cnt += sps->offset_for_non_ref_pic; 284 expected_pic_order_cnt += sps->offset_for_non_ref_pic;
288 285
289 if (pic->field == H264Picture::FIELD_NONE) { 286 if (pic->field == H264Picture::FIELD_NONE) {
290 pic->top_field_order_cnt = 287 pic->top_field_order_cnt =
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 H264Picture::Vector* ref_pic_listx) { 527 H264Picture::Vector* ref_pic_listx) {
531 bool ref_pic_list_modification_flag_lX; 528 bool ref_pic_list_modification_flag_lX;
532 int num_ref_idx_lX_active_minus1; 529 int num_ref_idx_lX_active_minus1;
533 const media::H264ModificationOfPicNum* list_mod; 530 const media::H264ModificationOfPicNum* list_mod;
534 531
535 // This can process either ref_pic_list0 or ref_pic_list1, depending on 532 // This can process either ref_pic_list0 or ref_pic_list1, depending on
536 // the list argument. Set up pointers to proper list to be processed here. 533 // the list argument. Set up pointers to proper list to be processed here.
537 if (list == 0) { 534 if (list == 0) {
538 ref_pic_list_modification_flag_lX = 535 ref_pic_list_modification_flag_lX =
539 slice_hdr->ref_pic_list_modification_flag_l0; 536 slice_hdr->ref_pic_list_modification_flag_l0;
540 num_ref_idx_lX_active_minus1 = 537 num_ref_idx_lX_active_minus1 = slice_hdr->num_ref_idx_l0_active_minus1;
541 slice_hdr->num_ref_idx_l0_active_minus1;
542 list_mod = slice_hdr->ref_list_l0_modifications; 538 list_mod = slice_hdr->ref_list_l0_modifications;
543 } else { 539 } else {
544 ref_pic_list_modification_flag_lX = 540 ref_pic_list_modification_flag_lX =
545 slice_hdr->ref_pic_list_modification_flag_l1; 541 slice_hdr->ref_pic_list_modification_flag_l1;
546 num_ref_idx_lX_active_minus1 = 542 num_ref_idx_lX_active_minus1 = slice_hdr->num_ref_idx_l1_active_minus1;
547 slice_hdr->num_ref_idx_l1_active_minus1;
548 list_mod = slice_hdr->ref_list_l1_modifications; 543 list_mod = slice_hdr->ref_list_l1_modifications;
549 } 544 }
550 545
551 // Resize the list to the size requested in the slice header. 546 // Resize the list to the size requested in the slice header.
552 // Note that per 8.2.4.2 it's possible for num_ref_idx_lX_active_minus1 to 547 // Note that per 8.2.4.2 it's possible for num_ref_idx_lX_active_minus1 to
553 // indicate there should be more ref pics on list than we constructed. 548 // indicate there should be more ref pics on list than we constructed.
554 // Those superfluous ones should be treated as non-reference and will be 549 // Those superfluous ones should be treated as non-reference and will be
555 // initialized to nullptr, which must be handled by clients. 550 // initialized to nullptr, which must be handled by clients.
556 DCHECK_GE(num_ref_idx_lX_active_minus1, 0); 551 DCHECK_GE(num_ref_idx_lX_active_minus1, 0);
557 ref_pic_listx->resize(num_ref_idx_lX_active_minus1 + 1); 552 ref_pic_listx->resize(num_ref_idx_lX_active_minus1 + 1);
558 553
559 if (!ref_pic_list_modification_flag_lX) 554 if (!ref_pic_list_modification_flag_lX)
560 return true; 555 return true;
561 556
562 // Spec 8.2.4.3: 557 // Spec 8.2.4.3:
563 // Reorder pictures on the list in a way specified in the stream. 558 // Reorder pictures on the list in a way specified in the stream.
564 int pic_num_lx_pred = curr_pic_->pic_num; 559 int pic_num_lx_pred = curr_pic_->pic_num;
565 int ref_idx_lx = 0; 560 int ref_idx_lx = 0;
566 int pic_num_lx_no_wrap; 561 int pic_num_lx_no_wrap;
567 int pic_num_lx; 562 int pic_num_lx;
568 bool done = false; 563 bool done = false;
569 scoped_refptr<H264Picture> pic; 564 scoped_refptr<H264Picture> pic;
570 for (int i = 0; i < media::H264SliceHeader::kRefListModSize && !done; ++i) { 565 for (int i = 0; i < media::H264SliceHeader::kRefListModSize && !done; ++i) {
571 switch (list_mod->modification_of_pic_nums_idc) { 566 switch (list_mod->modification_of_pic_nums_idc) {
572 case 0: 567 case 0:
573 case 1: 568 case 1:
574 // Modify short reference picture position. 569 // Modify short reference picture position.
575 if (list_mod->modification_of_pic_nums_idc == 0) { 570 if (list_mod->modification_of_pic_nums_idc == 0) {
576 // Subtract given value from predicted PicNum. 571 // Subtract given value from predicted PicNum.
577 pic_num_lx_no_wrap = pic_num_lx_pred - 572 pic_num_lx_no_wrap =
573 pic_num_lx_pred -
578 (static_cast<int>(list_mod->abs_diff_pic_num_minus1) + 1); 574 (static_cast<int>(list_mod->abs_diff_pic_num_minus1) + 1);
579 // Wrap around max_pic_num_ if it becomes < 0 as result 575 // Wrap around max_pic_num_ if it becomes < 0 as result
580 // of subtraction. 576 // of subtraction.
581 if (pic_num_lx_no_wrap < 0) 577 if (pic_num_lx_no_wrap < 0)
582 pic_num_lx_no_wrap += max_pic_num_; 578 pic_num_lx_no_wrap += max_pic_num_;
583 } else { 579 } else {
584 // Add given value to predicted PicNum. 580 // Add given value to predicted PicNum.
585 pic_num_lx_no_wrap = pic_num_lx_pred + 581 pic_num_lx_no_wrap =
582 pic_num_lx_pred +
586 (static_cast<int>(list_mod->abs_diff_pic_num_minus1) + 1); 583 (static_cast<int>(list_mod->abs_diff_pic_num_minus1) + 1);
587 // Wrap around max_pic_num_ if it becomes >= max_pic_num_ as result 584 // Wrap around max_pic_num_ if it becomes >= max_pic_num_ as result
588 // of the addition. 585 // of the addition.
589 if (pic_num_lx_no_wrap >= max_pic_num_) 586 if (pic_num_lx_no_wrap >= max_pic_num_)
590 pic_num_lx_no_wrap -= max_pic_num_; 587 pic_num_lx_no_wrap -= max_pic_num_;
591 } 588 }
592 589
593 // For use in next iteration. 590 // For use in next iteration.
594 pic_num_lx_pred = pic_num_lx_no_wrap; 591 pic_num_lx_pred = pic_num_lx_no_wrap;
595 592
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 break; 636 break;
640 637
641 case 3: 638 case 3:
642 // End of modification list. 639 // End of modification list.
643 done = true; 640 done = true;
644 break; 641 break;
645 642
646 default: 643 default:
647 // May be recoverable. 644 // May be recoverable.
648 DVLOG(1) << "Invalid modification_of_pic_nums_idc=" 645 DVLOG(1) << "Invalid modification_of_pic_nums_idc="
649 << list_mod->modification_of_pic_nums_idc 646 << list_mod->modification_of_pic_nums_idc << " in position "
650 << " in position " << i; 647 << i;
651 break; 648 break;
652 } 649 }
653 650
654 ++list_mod; 651 ++list_mod;
655 } 652 }
656 653
657 // Per NOTE 2 in 8.2.4.3.2, the ref_pic_listx size in the above loop is 654 // Per NOTE 2 in 8.2.4.3.2, the ref_pic_listx size in the above loop is
658 // temporarily made one element longer than the required final list. 655 // temporarily made one element longer than the required final list.
659 // Resize the list back to its required size. 656 // Resize the list back to its required size.
660 ref_pic_listx->resize(num_ref_idx_lX_active_minus1 + 1); 657 ref_pic_listx->resize(num_ref_idx_lX_active_minus1 + 1);
661 658
662 return true; 659 return true;
663 } 660 }
664 661
665 void H264Decoder::OutputPic(scoped_refptr<H264Picture> pic) { 662 void H264Decoder::OutputPic(scoped_refptr<H264Picture> pic) {
666 DCHECK(!pic->outputted); 663 DCHECK(!pic->outputted);
667 pic->outputted = true; 664 pic->outputted = true;
668 665
669 if (pic->nonexisting) { 666 if (pic->nonexisting) {
670 DVLOG(4) << "Skipping output, non-existing frame_num: " << pic->frame_num; 667 DVLOG(4) << "Skipping output, non-existing frame_num: " << pic->frame_num;
671 return; 668 return;
672 } 669 }
673 670
674 DVLOG_IF(1, pic->pic_order_cnt < last_output_poc_) 671 DVLOG_IF(1, pic->pic_order_cnt < last_output_poc_)
675 << "Outputting out of order, likely a broken stream: " 672 << "Outputting out of order, likely a broken stream: " << last_output_poc_
676 << last_output_poc_ << " -> " << pic->pic_order_cnt; 673 << " -> " << pic->pic_order_cnt;
677 last_output_poc_ = pic->pic_order_cnt; 674 last_output_poc_ = pic->pic_order_cnt;
678 675
679 DVLOG(4) << "Posting output task for POC: " << pic->pic_order_cnt; 676 DVLOG(4) << "Posting output task for POC: " << pic->pic_order_cnt;
680 accelerator_->OutputPicture(pic); 677 accelerator_->OutputPicture(pic);
681 } 678 }
682 679
683 void H264Decoder::ClearDPB() { 680 void H264Decoder::ClearDPB() {
684 // Clear DPB contents, marking the pictures as unused first. 681 // Clear DPB contents, marking the pictures as unused first.
685 dpb_.Clear(); 682 dpb_.Clear();
686 last_output_poc_ = std::numeric_limits<int>::min(); 683 last_output_poc_ = std::numeric_limits<int>::min();
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
1000 997
1001 dpb_.StorePic(pic); 998 dpb_.StorePic(pic);
1002 } 999 }
1003 1000
1004 return true; 1001 return true;
1005 } 1002 }
1006 1003
1007 static int LevelToMaxDpbMbs(int level) { 1004 static int LevelToMaxDpbMbs(int level) {
1008 // See table A-1 in spec. 1005 // See table A-1 in spec.
1009 switch (level) { 1006 switch (level) {
1010 case 10: return 396; 1007 case 10:
1011 case 11: return 900; 1008 return 396;
1012 case 12: // fallthrough 1009 case 11:
1013 case 13: // fallthrough 1010 return 900;
1014 case 20: return 2376; 1011 case 12: // fallthrough
1015 case 21: return 4752; 1012 case 13: // fallthrough
1016 case 22: // fallthrough 1013 case 20:
1017 case 30: return 8100; 1014 return 2376;
1018 case 31: return 18000; 1015 case 21:
1019 case 32: return 20480; 1016 return 4752;
1020 case 40: // fallthrough 1017 case 22: // fallthrough
1021 case 41: return 32768; 1018 case 30:
1022 case 42: return 34816; 1019 return 8100;
1023 case 50: return 110400; 1020 case 31:
1024 case 51: // fallthrough 1021 return 18000;
1025 case 52: return 184320; 1022 case 32:
1023 return 20480;
1024 case 40: // fallthrough
1025 case 41:
1026 return 32768;
1027 case 42:
1028 return 34816;
1029 case 50:
1030 return 110400;
1031 case 51: // fallthrough
1032 case 52:
1033 return 184320;
1026 default: 1034 default:
1027 DVLOG(1) << "Invalid codec level (" << level << ")"; 1035 DVLOG(1) << "Invalid codec level (" << level << ")";
1028 return 0; 1036 return 0;
1029 } 1037 }
1030 } 1038 }
1031 1039
1032 bool H264Decoder::UpdateMaxNumReorderFrames(const media::H264SPS* sps) { 1040 bool H264Decoder::UpdateMaxNumReorderFrames(const media::H264SPS* sps) {
1033 if (sps->vui_parameters_present_flag && sps->bitstream_restriction_flag) { 1041 if (sps->vui_parameters_present_flag && sps->bitstream_restriction_flag) {
1034 max_num_reorder_frames_ = 1042 max_num_reorder_frames_ =
1035 base::checked_cast<size_t>(sps->max_num_reorder_frames); 1043 base::checked_cast<size_t>(sps->max_num_reorder_frames);
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 SET_ERROR_AND_RETURN(); 1305 SET_ERROR_AND_RETURN();
1298 1306
1299 DVLOG(4) << "New NALU: " << static_cast<int>(curr_nalu_->nal_unit_type); 1307 DVLOG(4) << "New NALU: " << static_cast<int>(curr_nalu_->nal_unit_type);
1300 } 1308 }
1301 1309
1302 switch (curr_nalu_->nal_unit_type) { 1310 switch (curr_nalu_->nal_unit_type) {
1303 case media::H264NALU::kNonIDRSlice: 1311 case media::H264NALU::kNonIDRSlice:
1304 // We can't resume from a non-IDR slice. 1312 // We can't resume from a non-IDR slice.
1305 if (state_ != kDecoding) 1313 if (state_ != kDecoding)
1306 break; 1314 break;
1307 // else fallthrough 1315 // else fallthrough
Pawel Osciak 2016/04/19 09:22:55 I believe the indent here was correct.
Mark Dittmer 2016/05/02 03:51:23 Done.
1308 case media::H264NALU::kIDRSlice: { 1316 case media::H264NALU::kIDRSlice: {
1309 // TODO(posciak): the IDR may require an SPS that we don't have 1317 // TODO(posciak): the IDR may require an SPS that we don't have
1310 // available. For now we'd fail if that happens, but ideally we'd like 1318 // available. For now we'd fail if that happens, but ideally we'd like
1311 // to keep going until the next SPS in the stream. 1319 // to keep going until the next SPS in the stream.
1312 if (state_ == kNeedStreamMetadata) { 1320 if (state_ == kNeedStreamMetadata) {
1313 // We need an SPS, skip this IDR and keep looking. 1321 // We need an SPS, skip this IDR and keep looking.
1314 break; 1322 break;
1315 } 1323 }
1316 1324
1317 // If after reset, we should be able to recover from an IDR. 1325 // If after reset, we should be able to recover from an IDR.
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1413 } 1421 }
1414 1422
1415 gfx::Size H264Decoder::GetPicSize() const { 1423 gfx::Size H264Decoder::GetPicSize() const {
1416 return pic_size_; 1424 return pic_size_;
1417 } 1425 }
1418 1426
1419 size_t H264Decoder::GetRequiredNumOfPictures() const { 1427 size_t H264Decoder::GetRequiredNumOfPictures() const {
1420 return dpb_.max_num_pics() + kPicsInPipeline; 1428 return dpb_.max_num_pics() + kPicsInPipeline;
1421 } 1429 }
1422 1430
1423 } // namespace content 1431 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698