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

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

Issue 177583002: VAVDA: Switch to using max_num_reorder_frames. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/stl_util.h" 11 #include "base/stl_util.h"
11 #include "content/common/gpu/media/vaapi_h264_decoder.h" 12 #include "content/common/gpu/media/vaapi_h264_decoder.h"
12 13
13 namespace content { 14 namespace content {
14 15
15 // Decode surface, used for decoding and reference. input_id comes from client 16 // Decode surface, used for decoding and reference. input_id comes from client
16 // and is associated with the surface that was produced as the result 17 // and is associated with the surface that was produced as the result
17 // of decoding a bitstream buffer with that id. 18 // of decoding a bitstream buffer with that id.
18 class VaapiH264Decoder::DecodeSurface { 19 class VaapiH264Decoder::DecodeSurface {
19 public: 20 public:
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 } 56 }
56 57
57 VaapiH264Decoder::VaapiH264Decoder( 58 VaapiH264Decoder::VaapiH264Decoder(
58 VaapiWrapper* vaapi_wrapper, 59 VaapiWrapper* vaapi_wrapper,
59 const OutputPicCB& output_pic_cb, 60 const OutputPicCB& output_pic_cb,
60 const ReportErrorToUmaCB& report_error_to_uma_cb) 61 const ReportErrorToUmaCB& report_error_to_uma_cb)
61 : max_pic_order_cnt_lsb_(0), 62 : max_pic_order_cnt_lsb_(0),
62 max_frame_num_(0), 63 max_frame_num_(0),
63 max_pic_num_(0), 64 max_pic_num_(0),
64 max_long_term_frame_idx_(0), 65 max_long_term_frame_idx_(0),
66 max_num_reorder_frames_(0),
65 curr_sps_id_(-1), 67 curr_sps_id_(-1),
66 curr_pps_id_(-1), 68 curr_pps_id_(-1),
67 vaapi_wrapper_(vaapi_wrapper), 69 vaapi_wrapper_(vaapi_wrapper),
68 output_pic_cb_(output_pic_cb), 70 output_pic_cb_(output_pic_cb),
69 report_error_to_uma_cb_(report_error_to_uma_cb) { 71 report_error_to_uma_cb_(report_error_to_uma_cb) {
70 Reset(); 72 Reset();
71 state_ = kNeedStreamMetadata; 73 state_ = kNeedStreamMetadata;
72 } 74 }
73 75
74 VaapiH264Decoder::~VaapiH264Decoder() { 76 VaapiH264Decoder::~VaapiH264Decoder() {
(...skipping 1247 matching lines...) Expand 10 before | Expand all | Expand 10 after
1322 // 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
1323 // without having to store it for future reference. 1325 // without having to store it for future reference.
1324 scoped_ptr<H264Picture> pic(curr_pic_.release()); 1326 scoped_ptr<H264Picture> pic(curr_pic_.release());
1325 1327
1326 // Get all pictures that haven't been outputted yet. 1328 // Get all pictures that haven't been outputted yet.
1327 H264Picture::PtrVector not_outputted; 1329 H264Picture::PtrVector not_outputted;
1328 // TODO(posciak): pass as pointer, not reference (violates coding style). 1330 // TODO(posciak): pass as pointer, not reference (violates coding style).
1329 dpb_.GetNotOutputtedPicsAppending(not_outputted); 1331 dpb_.GetNotOutputtedPicsAppending(not_outputted);
1330 // Include the one we've just decoded. 1332 // Include the one we've just decoded.
1331 not_outputted.push_back(pic.get()); 1333 not_outputted.push_back(pic.get());
1334
1332 // Sort in output order. 1335 // Sort in output order.
1333 std::sort(not_outputted.begin(), not_outputted.end(), POCAscCompare()); 1336 std::sort(not_outputted.begin(), not_outputted.end(), POCAscCompare());
1334 1337
1335 // 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,
1336 // if its POC is next after the previously outputted one (which means 1339 // if the number of decoded and not yet outputted pictures that would remain
1337 // last_output_poc_ + 2, because POCs are incremented by 2 to accommodate 1340 // in DPB afterwards would at least be equal to max_num_reorder_frames.
1338 // fields when decoding interleaved streams). POC can also be equal to
1339 // last outputted picture's POC when it wraps around back to 0.
1340 // 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
1341 // to remain in the DPB and can be removed. 1342 // to remain in the DPB and can be removed.
1342 H264Picture::PtrVector::iterator output_candidate = not_outputted.begin(); 1343 H264Picture::PtrVector::iterator output_candidate = not_outputted.begin();
1343 for (; output_candidate != not_outputted.end() && 1344 size_t num_remaining = not_outputted.size();
1344 (*output_candidate)->pic_order_cnt <= last_output_poc_ + 2; 1345 while (num_remaining > max_num_reorder_frames_) {
1345 ++output_candidate) {
1346 int poc = (*output_candidate)->pic_order_cnt; 1346 int poc = (*output_candidate)->pic_order_cnt;
1347 DCHECK_GE(poc, last_output_poc_); 1347 DCHECK_GE(poc, last_output_poc_);
1348 if (!OutputPic(*output_candidate)) 1348 if (!OutputPic(*output_candidate))
1349 return false; 1349 return false;
1350 1350
1351 if (!(*output_candidate)->ref) { 1351 if (!(*output_candidate)->ref) {
1352 // 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
1353 // if we managed to output it immediately. 1353 // if we managed to output it immediately.
1354 if (*output_candidate != pic) 1354 if (*output_candidate != pic)
1355 dpb_.DeleteByPOC(poc); 1355 dpb_.DeleteByPOC(poc);
1356 // Mark as unused. 1356 // Mark as unused.
1357 UnassignSurfaceFromPoC(poc); 1357 UnassignSurfaceFromPoC(poc);
1358 } 1358 }
1359
1360 ++output_candidate;
1361 --num_remaining;
1359 } 1362 }
1360 1363
1361 // If we haven't managed to output the picture that we just decoded, or if 1364 // If we haven't managed to output the picture that we just decoded, or if
1362 // it's a reference picture, we have to store it in DPB. 1365 // it's a reference picture, we have to store it in DPB.
1363 if (!pic->outputted || pic->ref) { 1366 if (!pic->outputted || pic->ref) {
1364 if (dpb_.IsFull()) { 1367 if (dpb_.IsFull()) {
1365 // If we haven't managed to output anything to free up space in DPB 1368 // If we haven't managed to output anything to free up space in DPB
1366 // to store this picture, it's an error in the stream. 1369 // to store this picture, it's an error in the stream.
1367 DVLOG(1) << "Could not free up space in DPB!"; 1370 DVLOG(1) << "Could not free up space in DPB!";
1368 return false; 1371 return false;
(...skipping 23 matching lines...) Expand all
1392 case 42: return 34816; 1395 case 42: return 34816;
1393 case 50: return 110400; 1396 case 50: return 110400;
1394 case 51: // fallthrough 1397 case 51: // fallthrough
1395 case 52: return 184320; 1398 case 52: return 184320;
1396 default: 1399 default:
1397 DVLOG(1) << "Invalid codec level (" << level << ")"; 1400 DVLOG(1) << "Invalid codec level (" << level << ")";
1398 return 0; 1401 return 0;
1399 } 1402 }
1400 } 1403 }
1401 1404
1405 bool VaapiH264Decoder::UpdateMaxNumReorderFrames(const media::H264SPS* sps) {
1406 if (sps->vui_parameters_present_flag && sps->bitstream_restriction_flag) {
1407 max_num_reorder_frames_ =
1408 base::checked_cast<size_t>(sps->max_num_reorder_frames);
1409 if (max_num_reorder_frames_ > dpb_.max_num_pics()) {
1410 DVLOG(1)
1411 << "max_num_reorder_frames present, but larger than MaxDpbFrames ("
1412 << max_num_reorder_frames_ << " > " << dpb_.max_num_pics() << ")";
1413 max_num_reorder_frames_ = 0;
1414 return false;
1415 }
1416 return true;
1417 }
1418
1419 // max_num_reorder_frames not present, infer from profile/constraints
1420 // (see VUI semantics in spec).
1421 if (sps->constraint_setx_flag[3]) {
1422 switch (sps->profile_idc) {
1423 case 44:
1424 case 86:
1425 case 100:
1426 case 110:
1427 case 122:
1428 case 244:
1429 max_num_reorder_frames_ = 0;
1430 break;
1431 default:
1432 max_num_reorder_frames_ = dpb_.max_num_pics();
1433 break;
1434 }
1435 } else {
1436 max_num_reorder_frames_ = dpb_.max_num_pics();
1437 }
1438
1439 return true;
1440 }
1441
1402 bool VaapiH264Decoder::ProcessSPS(int sps_id, bool* need_new_buffers) { 1442 bool VaapiH264Decoder::ProcessSPS(int sps_id, bool* need_new_buffers) {
1403 const media::H264SPS* sps = parser_.GetSPS(sps_id); 1443 const media::H264SPS* sps = parser_.GetSPS(sps_id);
1404 DCHECK(sps); 1444 DCHECK(sps);
1405 DVLOG(4) << "Processing SPS"; 1445 DVLOG(4) << "Processing SPS";
1406 1446
1407 *need_new_buffers = false; 1447 *need_new_buffers = false;
1408 1448
1409 if (sps->frame_mbs_only_flag == 0) { 1449 if (sps->frame_mbs_only_flag == 0) {
1410 DVLOG(1) << "frame_mbs_only_flag != 1 not supported"; 1450 DVLOG(1) << "frame_mbs_only_flag != 1 not supported";
1411 report_error_to_uma_cb_.Run(FRAME_MBS_ONLY_FLAG_NOT_ONE); 1451 report_error_to_uma_cb_.Run(FRAME_MBS_ONLY_FLAG_NOT_ONE);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1452 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),
1453 static_cast<int>(H264DPB::kDPBMaxSize)); 1493 static_cast<int>(H264DPB::kDPBMaxSize));
1454 DVLOG(1) << "Codec level: " << level << ", DPB size: " << max_dpb_size; 1494 DVLOG(1) << "Codec level: " << level << ", DPB size: " << max_dpb_size;
1455 if (max_dpb_size == 0) { 1495 if (max_dpb_size == 0) {
1456 DVLOG(1) << "Invalid DPB Size"; 1496 DVLOG(1) << "Invalid DPB Size";
1457 return false; 1497 return false;
1458 } 1498 }
1459 1499
1460 dpb_.set_max_num_pics(max_dpb_size); 1500 dpb_.set_max_num_pics(max_dpb_size);
1461 1501
1502 if (!UpdateMaxNumReorderFrames(sps))
1503 return false;
1504 DVLOG(1) << "max_num_reorder_frames: " << max_num_reorder_frames_;
1505
1462 *need_new_buffers = true; 1506 *need_new_buffers = true;
1463 return true; 1507 return true;
1464 } 1508 }
1465 1509
1466 bool VaapiH264Decoder::ProcessPPS(int pps_id) { 1510 bool VaapiH264Decoder::ProcessPPS(int pps_id) {
1467 const media::H264PPS* pps = parser_.GetPPS(pps_id); 1511 const media::H264PPS* pps = parser_.GetPPS(pps_id);
1468 DCHECK(pps); 1512 DCHECK(pps);
1469 1513
1470 curr_pps_id_ = pps->pic_parameter_set_id; 1514 curr_pps_id_ = pps->pic_parameter_set_id;
1471 1515
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
1637 break; 1681 break;
1638 } 1682 }
1639 } 1683 }
1640 } 1684 }
1641 1685
1642 size_t VaapiH264Decoder::GetRequiredNumOfPictures() { 1686 size_t VaapiH264Decoder::GetRequiredNumOfPictures() {
1643 return dpb_.max_num_pics() + kPicsInPipeline; 1687 return dpb_.max_num_pics() + kPicsInPipeline;
1644 } 1688 }
1645 1689
1646 } // namespace content 1690 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698