diff options
author | posciak@chromium.org <posciak@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-07 00:53:50 +0000 |
---|---|---|
committer | posciak@chromium.org <posciak@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-07 00:53:50 +0000 |
commit | 2d8e3e885e59a89056326553121b2fa1c3c00385 (patch) | |
tree | e312f4a5ed933ca66fcd541a6f86c90f822c5beb /content/common/gpu/media/vaapi_h264_decoder.cc | |
parent | 119e2fe4ad036fbee20658784d429e2bc00c6588 (diff) | |
download | chromium_src-2d8e3e885e59a89056326553121b2fa1c3c00385.zip chromium_src-2d8e3e885e59a89056326553121b2fa1c3c00385.tar.gz chromium_src-2d8e3e885e59a89056326553121b2fa1c3c00385.tar.bz2 |
VAVDA: Calculate number of required pictures depending on codec level.
Instead of always allocating maximum required number of pictures (16) by
H264 spec, check the codec level and calculate the required number of
pictures (DPB size).
Also, remove check for frame_mbs_only_flag, which was not correct and
is handled differently elsewhere.
BUG=136376
TEST=videotestmatrix
Review URL: https://chromiumcodereview.appspot.com/12209030
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@181123 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/common/gpu/media/vaapi_h264_decoder.cc')
-rw-r--r-- | content/common/gpu/media/vaapi_h264_decoder.cc | 64 |
1 files changed, 51 insertions, 13 deletions
diff --git a/content/common/gpu/media/vaapi_h264_decoder.cc b/content/common/gpu/media/vaapi_h264_decoder.cc index 02df1aa..4f26d47 100644 --- a/content/common/gpu/media/vaapi_h264_decoder.cc +++ b/content/common/gpu/media/vaapi_h264_decoder.cc @@ -1571,7 +1571,7 @@ bool VaapiH264Decoder::ModifyReferencePicList(H264SliceHeader *slice_hdr, ref_pic_listx = &ref_pic_list1_; } - DCHECK_GT(num_ref_idx_lX_active_minus1, 0); + DCHECK_GE(num_ref_idx_lX_active_minus1, 0); // Spec 8.2.4.3: // Reorder pictures on the list in a way specified in the stream. @@ -2035,16 +2035,35 @@ bool VaapiH264Decoder::FinishPicture() { return true; } +static int LevelToMaxDpbMbs(int level) { + // See table A-1 in spec. + switch (level) { + case 10: return 396; + case 11: return 900; + case 12: // fallthrough + case 13: // fallthrough + case 20: return 2376; + case 21: return 4752; + case 22: // fallthrough + case 30: return 8100; + case 31: return 18000; + case 32: return 20480; + case 40: // fallthrough + case 41: return 32768; + case 42: return 34816; + case 50: return 110400; + case 51: // fallthrough + case 52: return 184320; + default: + DVLOG(1) << "Invalid codec level (" << level << ")"; + return 0; + } +} + bool VaapiH264Decoder::ProcessSPS(int sps_id) { const H264SPS* sps = parser_.GetSPS(sps_id); DCHECK(sps); - if (sps->frame_mbs_only_flag == 0) { - // Fields/interlaced video not supported. - DVLOG(1) << "frame_mbs_only_flag != 1 not supported"; - return false; - } - if (sps->gaps_in_frame_num_value_allowed_flag) { DVLOG(1) << "Gaps in frame numbers not supported"; return false; @@ -2052,11 +2071,21 @@ bool VaapiH264Decoder::ProcessSPS(int sps_id) { curr_sps_id_ = sps->seq_parameter_set_id; - // Calculate picture height/width (spec 7.4.2.1.1, 7.4.3). - int width = 16 * (sps->pic_width_in_mbs_minus1 + 1); - int height = 16 * (2 - sps->frame_mbs_only_flag) * + // Calculate picture height/width in macroblocks and pixels + // (spec 7.4.2.1.1, 7.4.3). + int width_mb = sps->pic_width_in_mbs_minus1 + 1; + int height_mb = (2 - sps->frame_mbs_only_flag) * (sps->pic_height_in_map_units_minus1 + 1); + int width = 16 * width_mb; + int height = 16 * height_mb; + + DVLOG(1) << "New picture size: " << width << "x" << height; + if (width == 0 || height == 0) { + DVLOG(1) << "Invalid picture size!"; + return false; + } + if ((pic_width_ != -1 || pic_height_ != -1) && (width != pic_width_ || height != pic_height_)) { DVLOG(1) << "Picture size changed mid-stream"; @@ -2065,11 +2094,21 @@ bool VaapiH264Decoder::ProcessSPS(int sps_id) { pic_width_ = width; pic_height_ = height; - DVLOG(1) << "New picture size: " << pic_width_ << "x" << pic_height_; max_pic_order_cnt_lsb_ = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4); max_frame_num_ = 1 << (sps->log2_max_frame_num_minus4 + 4); + int level = sps->level_idc; + int max_dpb_mbs = LevelToMaxDpbMbs(level); + if (max_dpb_mbs == 0) + return false; + + size_t max_dpb_size = std::min(max_dpb_mbs / (width_mb * height_mb), + static_cast<int>(H264DPB::kDPBMaxSize)); + DVLOG(1) << "Codec level: " << level << ", DPB size: " << max_dpb_size; + + dpb_.set_max_num_pics(max_dpb_size); + return true; } @@ -2300,9 +2339,8 @@ VaapiH264Decoder::DecResult VaapiH264Decoder::DecodeOneFrame(int32 input_id) { } } -// static size_t VaapiH264Decoder::GetRequiredNumOfPictures() { - return kNumReqPictures; + return dpb_.max_num_pics() + kPicsInPipeline; } // static |