15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <limits> 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/numerics/safe_conversions.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/media/vaapi_h264_decoder.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Decode surface, used for decoding and reference. input_id comes from client 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// and is associated with the surface that was produced as the result 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// of decoding a bitstream buffer with that id. 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VaapiH264Decoder::DecodeSurface { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DecodeSurface(int poc, 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int32 input_id, 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_refptr<VASurface>& va_surface); 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DecodeSurface(int poc, const scoped_refptr<DecodeSurface>& dec_surface); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~DecodeSurface(); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int poc() { 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return poc_; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<VASurface> va_surface() { 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return va_surface_; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 input_id() { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return input_id_; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int poc_; 41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int32 input_id_; 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<VASurface> va_surface_; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VaapiH264Decoder::DecodeSurface::DecodeSurface( 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int poc, 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int32 input_id, 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_refptr<VASurface>& va_surface) 49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : poc_(poc), 50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) input_id_(input_id), 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) va_surface_(va_surface) { 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(va_surface_.get()); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VaapiH264Decoder::DecodeSurface::~DecodeSurface() { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)VaapiH264Decoder::VaapiH264Decoder( 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) VaapiWrapper* vaapi_wrapper, 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const OutputPicCB& output_pic_cb, 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const ReportErrorToUmaCB& report_error_to_uma_cb) 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : max_pic_order_cnt_lsb_(0), 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) max_frame_num_(0), 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) max_pic_num_(0), 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) max_long_term_frame_idx_(0), 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) max_num_reorder_frames_(0), 67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) curr_sps_id_(-1), 68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) curr_pps_id_(-1), 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) vaapi_wrapper_(vaapi_wrapper), 70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) output_pic_cb_(output_pic_cb), 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) report_error_to_uma_cb_(report_error_to_uma_cb) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Reset(); 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) state_ = kNeedStreamMetadata; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VaapiH264Decoder::~VaapiH264Decoder() { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VaapiH264Decoder::Reset() { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_.reset(); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) curr_input_id_ = -1; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_num_ = 0; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_frame_num_ = -1; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_frame_num_offset_ = -1; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_ref_has_memmgmnt5_ = false; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_ref_top_field_order_cnt_ = -1; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_ref_pic_order_cnt_msb_ = -1; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_ref_pic_order_cnt_lsb_ = -1; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_ref_field_ = H264Picture::FIELD_NONE; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) vaapi_wrapper_->DestroyPendingBuffers(); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ref_pic_list0_.clear(); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ref_pic_list1_.clear(); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (DecSurfacesInUse::iterator it = decode_surfaces_in_use_.begin(); 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) it != decode_surfaces_in_use_.end(); ) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int poc = it->second->poc(); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Must be incremented before UnassignSurfaceFromPoC as this call 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // invalidates |it|. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnassignSurfaceFromPoC(poc); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(decode_surfaces_in_use_.empty()); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dpb_.Clear(); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser_.Reset(); 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) last_output_poc_ = std::numeric_limits<int>::min(); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // If we are in kDecoding, we can resume without processing an SPS. 113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (state_ == kDecoding) 114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) state_ = kAfterReset; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void VaapiH264Decoder::ReuseSurface( 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_refptr<VASurface>& va_surface) { 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) available_va_surfaces_.push_back(va_surface); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fill |va_pic| with default/neutral values. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void InitVAPicture(VAPictureH264* va_pic) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(va_pic, 0, sizeof(*va_pic)); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_pic->picture_id = VA_INVALID_ID; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_pic->flags = VA_PICTURE_H264_INVALID; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VaapiH264Decoder::FillVAPicture(VAPictureH264 *va_pic, H264Picture* pic) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(pic); 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DecodeSurface* dec_surface = DecodeSurfaceByPoC(pic->pic_order_cnt); 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!dec_surface) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cannot provide a ref picture, will corrupt output, but may be able 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to recover. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitVAPicture(va_pic); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) va_pic->picture_id = dec_surface->va_surface()->id(); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_pic->frame_idx = pic->frame_num; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_pic->flags = 0; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (pic->field) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case H264Picture::FIELD_NONE: 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case H264Picture::FIELD_TOP: 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_pic->flags |= VA_PICTURE_H264_TOP_FIELD; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case H264Picture::FIELD_BOTTOM: 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pic->ref) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_pic->flags |= pic->long_term ? VA_PICTURE_H264_LONG_TERM_REFERENCE 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : VA_PICTURE_H264_SHORT_TERM_REFERENCE; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_pic->TopFieldOrderCnt = pic->top_field_order_cnt; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_pic->BottomFieldOrderCnt = pic->bottom_field_order_cnt; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int VaapiH264Decoder::FillVARefFramesFromDPB(VAPictureH264 *va_pics, 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_pics) { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H264DPB::Pictures::reverse_iterator rit; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Return reference frames in reverse order of insertion. 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Libva does not document this, but other implementations (e.g. mplayer) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // do it this way as well. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (rit = dpb_.rbegin(), i = 0; rit != dpb_.rend() && i < num_pics; ++rit) { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*rit)->ref) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillVAPicture(&va_pics[i++], *rit); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)VaapiH264Decoder::DecodeSurface* VaapiH264Decoder::DecodeSurfaceByPoC(int poc) { 181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DecSurfacesInUse::iterator iter = decode_surfaces_in_use_.find(poc); 182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (iter == decode_surfaces_in_use_.end()) { 183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DVLOG(1) << "Could not find surface assigned to POC: " << poc; 184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return NULL; 185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return iter->second.get(); 188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool VaapiH264Decoder::AssignSurfaceToPoC(int32 input_id, int poc) { 191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (available_va_surfaces_.empty()) { 192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DVLOG(1) << "No VA Surfaces available"; 193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return false; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) linked_ptr<DecodeSurface> dec_surface(new DecodeSurface( 197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) poc, input_id, available_va_surfaces_.back())); 198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) available_va_surfaces_.pop_back(); 199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DVLOG(4) << "POC " << poc 201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << " will use surface " << dec_surface->va_surface()->id(); 202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool inserted = decode_surfaces_in_use_.insert( 204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::make_pair(poc, dec_surface)).second; 205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(inserted); 206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return true; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VaapiH264Decoder::UnassignSurfaceFromPoC(int poc) { 211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DecSurfacesInUse::iterator it = decode_surfaces_in_use_.find(poc); 212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (it == decode_surfaces_in_use_.end()) { 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Asked to unassign an unassigned POC " << poc; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DVLOG(4) << "POC " << poc << " no longer using VA surface " 218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << it->second->va_surface()->id(); 219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) decode_surfaces_in_use_.erase(it); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VaapiH264Decoder::SendPPS() { 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const media::H264PPS* pps = parser_.GetPPS(curr_pps_id_); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(pps); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const media::H264SPS* sps = parser_.GetSPS(pps->seq_parameter_set_id); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(sps); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(curr_pic_.get()); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VAPictureParameterBufferH264 pic_param; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&pic_param, 0, sizeof(VAPictureParameterBufferH264)); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FROM_SPS_TO_PP(a) pic_param.a = sps->a; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FROM_SPS_TO_PP2(a, b) pic_param.b = sps->a; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_SPS_TO_PP2(pic_width_in_mbs_minus1, picture_width_in_mbs_minus1); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This assumes non-interlaced video 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_SPS_TO_PP2(pic_height_in_map_units_minus1, 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) picture_height_in_mbs_minus1); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_SPS_TO_PP(bit_depth_luma_minus8); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_SPS_TO_PP(bit_depth_chroma_minus8); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef FROM_SPS_TO_PP 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef FROM_SPS_TO_PP2 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FROM_SPS_TO_PP_SF(a) pic_param.seq_fields.bits.a = sps->a; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FROM_SPS_TO_PP_SF2(a, b) pic_param.seq_fields.bits.b = sps->a; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_SPS_TO_PP_SF(chroma_format_idc); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_SPS_TO_PP_SF2(separate_colour_plane_flag, 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) residual_colour_transform_flag); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_SPS_TO_PP_SF(gaps_in_frame_num_value_allowed_flag); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_SPS_TO_PP_SF(frame_mbs_only_flag); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_SPS_TO_PP_SF(mb_adaptive_frame_field_flag); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_SPS_TO_PP_SF(direct_8x8_inference_flag); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic_param.seq_fields.bits.MinLumaBiPredSize8x8 = (sps->level_idc >= 31); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_SPS_TO_PP_SF(log2_max_frame_num_minus4); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_SPS_TO_PP_SF(pic_order_cnt_type); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_SPS_TO_PP_SF(log2_max_pic_order_cnt_lsb_minus4); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_SPS_TO_PP_SF(delta_pic_order_always_zero_flag); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef FROM_SPS_TO_PP_SF 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef FROM_SPS_TO_PP_SF2 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FROM_PPS_TO_PP(a) pic_param.a = pps->a; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_PPS_TO_PP(num_slice_groups_minus1); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic_param.slice_group_map_type = 0; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic_param.slice_group_change_rate_minus1 = 0; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_PPS_TO_PP(pic_init_qp_minus26); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_PPS_TO_PP(pic_init_qs_minus26); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_PPS_TO_PP(chroma_qp_index_offset); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_PPS_TO_PP(second_chroma_qp_index_offset); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef FROM_PPS_TO_PP 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FROM_PPS_TO_PP_PF(a) pic_param.pic_fields.bits.a = pps->a; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FROM_PPS_TO_PP_PF2(a, b) pic_param.pic_fields.bits.b = pps->a; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_PPS_TO_PP_PF(entropy_coding_mode_flag); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_PPS_TO_PP_PF(weighted_pred_flag); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_PPS_TO_PP_PF(weighted_bipred_idc); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_PPS_TO_PP_PF(transform_8x8_mode_flag); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic_param.pic_fields.bits.field_pic_flag = 0; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_PPS_TO_PP_PF(constrained_intra_pred_flag); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_PPS_TO_PP_PF2(bottom_field_pic_order_in_frame_present_flag, 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic_order_present_flag); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_PPS_TO_PP_PF(deblocking_filter_control_present_flag); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_PPS_TO_PP_PF(redundant_pic_cnt_present_flag); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic_param.pic_fields.bits.reference_pic_flag = curr_pic_->ref; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef FROM_PPS_TO_PP_PF 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef FROM_PPS_TO_PP_PF2 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic_param.frame_num = curr_pic_->frame_num; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitVAPicture(&pic_param.CurrPic); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillVAPicture(&pic_param.CurrPic, curr_pic_.get()); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Init reference pictures' array. 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 16; ++i) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitVAPicture(&pic_param.ReferenceFrames[i]); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // And fill it with picture info from DPB. 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillVARefFramesFromDPB(pic_param.ReferenceFrames, 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arraysize(pic_param.ReferenceFrames)); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic_param.num_ref_frames = sps->max_num_ref_frames; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return vaapi_wrapper_->SubmitBuffer(VAPictureParameterBufferType, 306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) sizeof(VAPictureParameterBufferH264), 307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &pic_param); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VaapiH264Decoder::SendIQMatrix() { 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const media::H264PPS* pps = parser_.GetPPS(curr_pps_id_); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(pps); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VAIQMatrixBufferH264 iq_matrix_buf; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&iq_matrix_buf, 0, sizeof(VAIQMatrixBufferH264)); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pps->pic_scaling_matrix_present_flag) { 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 6; ++i) { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < 16; ++j) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iq_matrix_buf.ScalingList4x4[i][j] = pps->scaling_list4x4[i][j]; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 2; ++i) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < 64; ++j) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iq_matrix_buf.ScalingList8x8[i][j] = pps->scaling_list8x8[i][j]; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const media::H264SPS* sps = parser_.GetSPS(pps->seq_parameter_set_id); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(sps); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 6; ++i) { 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < 16; ++j) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iq_matrix_buf.ScalingList4x4[i][j] = sps->scaling_list4x4[i][j]; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 2; ++i) { 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < 64; ++j) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iq_matrix_buf.ScalingList8x8[i][j] = sps->scaling_list8x8[i][j]; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return vaapi_wrapper_->SubmitBuffer(VAIQMatrixBufferType, 342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) sizeof(VAIQMatrixBufferH264), 343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &iq_matrix_buf); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool VaapiH264Decoder::SendVASliceParam(media::H264SliceHeader* slice_hdr) { 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const media::H264PPS* pps = parser_.GetPPS(slice_hdr->pic_parameter_set_id); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(pps); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const media::H264SPS* sps = parser_.GetSPS(pps->seq_parameter_set_id); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(sps); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VASliceParameterBufferH264 slice_param; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&slice_param, 0, sizeof(VASliceParameterBufferH264)); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_param.slice_data_size = slice_hdr->nalu_size; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_param.slice_data_offset = 0; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_param.slice_data_flag = VA_SLICE_DATA_FLAG_ALL; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_param.slice_data_bit_offset = slice_hdr->header_bit_size; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SHDRToSP(a) slice_param.a = slice_hdr->a; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHDRToSP(first_mb_in_slice); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_param.slice_type = slice_hdr->slice_type % 5; 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHDRToSP(direct_spatial_mv_pred_flag); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO posciak: make sure parser sets those even when override flags 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in slice header is off. 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHDRToSP(num_ref_idx_l0_active_minus1); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHDRToSP(num_ref_idx_l1_active_minus1); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHDRToSP(cabac_init_idc); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHDRToSP(slice_qp_delta); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHDRToSP(disable_deblocking_filter_idc); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHDRToSP(slice_alpha_c0_offset_div2); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHDRToSP(slice_beta_offset_div2); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (((slice_hdr->IsPSlice() || slice_hdr->IsSPSlice()) && 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pps->weighted_pred_flag) || 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (slice_hdr->IsBSlice() && pps->weighted_bipred_idc == 1)) { 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHDRToSP(luma_log2_weight_denom); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHDRToSP(chroma_log2_weight_denom); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHDRToSP(luma_weight_l0_flag); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHDRToSP(luma_weight_l1_flag); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHDRToSP(chroma_weight_l0_flag); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHDRToSP(chroma_weight_l1_flag); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i <= slice_param.num_ref_idx_l0_active_minus1; ++i) { 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_param.luma_weight_l0[i] = 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_hdr->pred_weight_table_l0.luma_weight[i]; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_param.luma_offset_l0[i] = 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_hdr->pred_weight_table_l0.luma_offset[i]; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < 2; ++j) { 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_param.chroma_weight_l0[i][j] = 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_hdr->pred_weight_table_l0.chroma_weight[i][j]; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_param.chroma_offset_l0[i][j] = 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_hdr->pred_weight_table_l0.chroma_offset[i][j]; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (slice_hdr->IsBSlice()) { 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i <= slice_param.num_ref_idx_l1_active_minus1; ++i) { 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_param.luma_weight_l1[i] = 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_hdr->pred_weight_table_l1.luma_weight[i]; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_param.luma_offset_l1[i] = 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_hdr->pred_weight_table_l1.luma_offset[i]; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < 2; ++j) { 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_param.chroma_weight_l1[i][j] = 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_hdr->pred_weight_table_l1.chroma_weight[i][j]; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_param.chroma_offset_l1[i][j] = 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_hdr->pred_weight_table_l1.chroma_offset[i][j]; 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 32; ++i) { 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitVAPicture(&slice_param.RefPicList0[i]); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitVAPicture(&slice_param.RefPicList1[i]); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H264Picture::PtrVector::iterator it; 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (it = ref_pic_list0_.begin(), i = 0; it != ref_pic_list0_.end() && *it; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it, ++i) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillVAPicture(&slice_param.RefPicList0[i], *it); 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (it = ref_pic_list1_.begin(), i = 0; it != ref_pic_list1_.end() && *it; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it, ++i) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillVAPicture(&slice_param.RefPicList1[i], *it); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return vaapi_wrapper_->SubmitBuffer(VASliceParameterBufferType, 434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) sizeof(VASliceParameterBufferH264), 435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &slice_param); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VaapiH264Decoder::SendSliceData(const uint8* ptr, size_t size) { 439868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Can't help it, blame libva... 440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void* non_const_ptr = const_cast<uint8*>(ptr); 441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return vaapi_wrapper_->SubmitBuffer(VASliceDataBufferType, size, 442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) non_const_ptr); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool VaapiH264Decoder::PrepareRefPicLists(media::H264SliceHeader* slice_hdr) { 446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ref_pic_list0_.clear(); 447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ref_pic_list1_.clear(); 448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Fill reference picture lists for B and S/SP slices. 450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (slice_hdr->IsPSlice() || slice_hdr->IsSPSlice()) { 451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ConstructReferencePicListsP(slice_hdr); 452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return ModifyReferencePicList(slice_hdr, 0); 453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (slice_hdr->IsBSlice()) { 456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ConstructReferencePicListsB(slice_hdr); 457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return ModifyReferencePicList(slice_hdr, 0) && 458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ModifyReferencePicList(slice_hdr, 1); 459f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 460f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 461f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 462f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 463f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool VaapiH264Decoder::QueueSlice(media::H264SliceHeader* slice_hdr) { 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(curr_pic_.get()); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!PrepareRefPicLists(slice_hdr)) 468f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SendVASliceParam(slice_hdr)) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SendSliceData(slice_hdr->nalu_data, slice_hdr->nalu_size)) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// TODO(posciak) start using vaMapBuffer instead of vaCreateBuffer wherever 480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// possible. 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VaapiH264Decoder::DecodePicture() { 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(curr_pic_.get()); 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 484868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DVLOG(4) << "Decoding POC " << curr_pic_->pic_order_cnt; 485868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DecodeSurface* dec_surface = DecodeSurfaceByPoC(curr_pic_->pic_order_cnt); 486868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!dec_surface) { 487868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DVLOG(1) << "Asked to decode an invalid POC " << curr_pic_->pic_order_cnt; 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 491116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!vaapi_wrapper_->ExecuteAndDestroyPendingBuffers( 492116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dec_surface->va_surface()->id())) { 493868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DVLOG(1) << "Failed decoding picture"; 494868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return false; 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 497868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return true; 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool VaapiH264Decoder::InitCurrPicture(media::H264SliceHeader* slice_hdr) { 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(curr_pic_.get()); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(curr_pic_.get(), 0, sizeof(H264Picture)); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->idr = slice_hdr->idr_pic_flag; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (slice_hdr->field_pic_flag) { 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->field = slice_hdr->bottom_field_flag ? H264Picture::FIELD_BOTTOM 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : H264Picture::FIELD_TOP; 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->field = H264Picture::FIELD_NONE; 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->ref = slice_hdr->nal_ref_idc != 0; 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This assumes non-interlaced stream. 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->frame_num = curr_pic_->pic_num = slice_hdr->frame_num; 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CalculatePicOrderCounts(slice_hdr)) 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try to get an empty surface to decode this picture to. 522868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!AssignSurfaceToPoC(curr_input_id_, curr_pic_->pic_order_cnt)) { 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Failed getting a free surface for a picture"; 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->long_term_reference_flag = slice_hdr->long_term_reference_flag; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->adaptive_ref_pic_marking_mode_flag = 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_hdr->adaptive_ref_pic_marking_mode_flag; 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the slice header indicates we will have to perform reference marking 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // process after this picture is decoded, store required data for that 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // purpose. 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (slice_hdr->adaptive_ref_pic_marking_mode_flag) { 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPILE_ASSERT(sizeof(curr_pic_->ref_pic_marking) == 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(slice_hdr->ref_pic_marking), 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ref_pic_marking_array_sizes_do_not_match); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(curr_pic_->ref_pic_marking, slice_hdr->ref_pic_marking, 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(curr_pic_->ref_pic_marking)); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool VaapiH264Decoder::CalculatePicOrderCounts( 5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) media::H264SliceHeader* slice_hdr) { 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(curr_sps_id_, -1); 5485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const media::H264SPS* sps = parser_.GetSPS(curr_sps_id_); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pic_order_cnt_lsb = slice_hdr->pic_order_cnt_lsb; 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->pic_order_cnt_lsb = pic_order_cnt_lsb; 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (sps->pic_order_cnt_type) { 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0: 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See spec 8.2.1.1. 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int prev_pic_order_cnt_msb, prev_pic_order_cnt_lsb; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (slice_hdr->idr_pic_flag) { 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_pic_order_cnt_msb = prev_pic_order_cnt_lsb = 0; 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prev_ref_has_memmgmnt5_) { 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prev_ref_field_ != H264Picture::FIELD_BOTTOM) { 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_pic_order_cnt_msb = 0; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_pic_order_cnt_lsb = prev_ref_top_field_order_cnt_; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_pic_order_cnt_msb = 0; 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_pic_order_cnt_lsb = 0; 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_pic_order_cnt_msb = prev_ref_pic_order_cnt_msb_; 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_pic_order_cnt_lsb = prev_ref_pic_order_cnt_lsb_; 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(max_pic_order_cnt_lsb_, 0); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((pic_order_cnt_lsb < prev_pic_order_cnt_lsb) && 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (prev_pic_order_cnt_lsb - pic_order_cnt_lsb >= 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_pic_order_cnt_lsb_ / 2)) { 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->pic_order_cnt_msb = prev_pic_order_cnt_msb + 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_pic_order_cnt_lsb_; 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((pic_order_cnt_lsb > prev_pic_order_cnt_lsb) && 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (pic_order_cnt_lsb - prev_pic_order_cnt_lsb > 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_pic_order_cnt_lsb_ / 2)) { 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->pic_order_cnt_msb = prev_pic_order_cnt_msb - 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_pic_order_cnt_lsb_; 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->pic_order_cnt_msb = prev_pic_order_cnt_msb; 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (curr_pic_->field != H264Picture::FIELD_BOTTOM) { 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->top_field_order_cnt = curr_pic_->pic_order_cnt_msb + 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic_order_cnt_lsb; 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (curr_pic_->field != H264Picture::FIELD_TOP) { 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO posciak: perhaps replace with pic->field? 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!slice_hdr->field_pic_flag) { 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->bottom_field_order_cnt = curr_pic_->top_field_order_cnt + 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_hdr->delta_pic_order_cnt_bottom; 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->bottom_field_order_cnt = curr_pic_->pic_order_cnt_msb + 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic_order_cnt_lsb; 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: { 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See spec 8.2.1.2. 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prev_has_memmgmnt5_) 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_frame_num_offset_ = 0; 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (slice_hdr->idr_pic_flag) 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->frame_num_offset = 0; 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (prev_frame_num_ > slice_hdr->frame_num) 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->frame_num_offset = prev_frame_num_offset_ + max_frame_num_; 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->frame_num_offset = prev_frame_num_offset_; 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int abs_frame_num = 0; 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sps->num_ref_frames_in_pic_order_cnt_cycle != 0) 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) abs_frame_num = curr_pic_->frame_num_offset + slice_hdr->frame_num; 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) abs_frame_num = 0; 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (slice_hdr->nal_ref_idc == 0 && abs_frame_num > 0) 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) --abs_frame_num; 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int expected_pic_order_cnt = 0; 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (abs_frame_num > 0) { 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sps->num_ref_frames_in_pic_order_cnt_cycle == 0) { 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Invalid num_ref_frames_in_pic_order_cnt_cycle " 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "in stream"; 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pic_order_cnt_cycle_cnt = (abs_frame_num - 1) / 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sps->num_ref_frames_in_pic_order_cnt_cycle; 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frame_num_in_pic_order_cnt_cycle = (abs_frame_num - 1) % 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sps->num_ref_frames_in_pic_order_cnt_cycle; 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_pic_order_cnt = pic_order_cnt_cycle_cnt * 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sps->expected_delta_per_pic_order_cnt_cycle; 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // frame_num_in_pic_order_cnt_cycle is verified < 255 in parser 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i <= frame_num_in_pic_order_cnt_cycle; ++i) 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_pic_order_cnt += sps->offset_for_ref_frame[i]; 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!slice_hdr->nal_ref_idc) 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_pic_order_cnt += sps->offset_for_non_ref_pic; 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!slice_hdr->field_pic_flag) { 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->top_field_order_cnt = expected_pic_order_cnt + 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_hdr->delta_pic_order_cnt[0]; 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->bottom_field_order_cnt = curr_pic_->top_field_order_cnt + 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sps->offset_for_top_to_bottom_field + 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_hdr->delta_pic_order_cnt[1]; 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!slice_hdr->bottom_field_flag) { 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->top_field_order_cnt = expected_pic_order_cnt + 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_hdr->delta_pic_order_cnt[0]; 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->bottom_field_order_cnt = expected_pic_order_cnt + 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sps->offset_for_top_to_bottom_field + 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_hdr->delta_pic_order_cnt[0]; 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See spec 8.2.1.3. 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prev_has_memmgmnt5_) 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_frame_num_offset_ = 0; 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (slice_hdr->idr_pic_flag) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->frame_num_offset = 0; 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (prev_frame_num_ > slice_hdr->frame_num) 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->frame_num_offset = prev_frame_num_offset_ + max_frame_num_; 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->frame_num_offset = prev_frame_num_offset_; 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int temp_pic_order_cnt; 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (slice_hdr->idr_pic_flag) { 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp_pic_order_cnt = 0; 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!slice_hdr->nal_ref_idc) { 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp_pic_order_cnt = 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2 * (curr_pic_->frame_num_offset + slice_hdr->frame_num) - 1; 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp_pic_order_cnt = 2 * (curr_pic_->frame_num_offset + 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slice_hdr->frame_num); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!slice_hdr->field_pic_flag) { 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->top_field_order_cnt = temp_pic_order_cnt; 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->bottom_field_order_cnt = temp_pic_order_cnt; 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (slice_hdr->bottom_field_flag) { 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->bottom_field_order_cnt = temp_pic_order_cnt; 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->top_field_order_cnt = temp_pic_order_cnt; 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Invalid pic_order_cnt_type: " << sps->pic_order_cnt_type; 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (curr_pic_->field) { 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case H264Picture::FIELD_NONE: 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->pic_order_cnt = std::min(curr_pic_->top_field_order_cnt, 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->bottom_field_order_cnt); 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case H264Picture::FIELD_TOP: 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->pic_order_cnt = curr_pic_->top_field_order_cnt; 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case H264Picture::FIELD_BOTTOM: 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->pic_order_cnt = curr_pic_->bottom_field_order_cnt; 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VaapiH264Decoder::UpdatePicNums() { 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (H264DPB::Pictures::iterator it = dpb_.begin(); it != dpb_.end(); ++it) { 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H264Picture* pic = *it; 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(pic); 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pic->ref) 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Below assumes non-interlaced stream. 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(pic->field, H264Picture::FIELD_NONE); 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pic->long_term) { 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic->long_term_pic_num = pic->long_term_frame_idx; 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pic->frame_num > frame_num_) 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic->frame_num_wrap = pic->frame_num - max_frame_num_; 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic->frame_num_wrap = pic->frame_num; 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic->pic_num = pic->frame_num_wrap; 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PicNumDescCompare { 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator()(const H264Picture* a, const H264Picture* b) const { 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return a->pic_num > b->pic_num; 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct LongTermPicNumAscCompare { 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator()(const H264Picture* a, const H264Picture* b) const { 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return a->long_term_pic_num < b->long_term_pic_num; 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void VaapiH264Decoder::ConstructReferencePicListsP( 7565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) media::H264SliceHeader* slice_hdr) { 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RefPicList0 (8.2.4.2.1) [[1] [2]], where: 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // [1] shortterm ref pics sorted by descending pic_num, 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // [2] longterm ref pics by ascending long_term_pic_num. 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ref_pic_list0_.empty() && ref_pic_list1_.empty()); 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First get the short ref pics... 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dpb_.GetShortTermRefPicsAppending(ref_pic_list0_); 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t num_short_refs = ref_pic_list0_.size(); 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and sort them to get [1]. 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::sort(ref_pic_list0_.begin(), ref_pic_list0_.end(), PicNumDescCompare()); 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now get long term pics and sort them by long_term_pic_num to get [2]. 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dpb_.GetLongTermRefPicsAppending(ref_pic_list0_); 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::sort(ref_pic_list0_.begin() + num_short_refs, ref_pic_list0_.end(), 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LongTermPicNumAscCompare()); 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cut off if we have more than requested in slice header. 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ref_pic_list0_.resize(slice_hdr->num_ref_idx_l0_active_minus1 + 1); 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct POCAscCompare { 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator()(const H264Picture* a, const H264Picture* b) const { 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return a->pic_order_cnt < b->pic_order_cnt; 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct POCDescCompare { 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator()(const H264Picture* a, const H264Picture* b) const { 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return a->pic_order_cnt > b->pic_order_cnt; 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void VaapiH264Decoder::ConstructReferencePicListsB( 7905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) media::H264SliceHeader* slice_hdr) { 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RefPicList0 (8.2.4.2.3) [[1] [2] [3]], where: 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // [1] shortterm ref pics with POC < curr_pic's POC sorted by descending POC, 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // [2] shortterm ref pics with POC > curr_pic's POC by ascending POC, 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // [3] longterm ref pics by ascending long_term_pic_num. 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ref_pic_list0_.empty() && ref_pic_list1_.empty()); 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dpb_.GetShortTermRefPicsAppending(ref_pic_list0_); 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t num_short_refs = ref_pic_list0_.size(); 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First sort ascending, this will put [1] in right place and finish [2]. 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::sort(ref_pic_list0_.begin(), ref_pic_list0_.end(), POCAscCompare()); 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find first with POC > curr_pic's POC to get first element in [2]... 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H264Picture::PtrVector::iterator iter; 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter = std::upper_bound(ref_pic_list0_.begin(), ref_pic_list0_.end(), 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_.get(), POCAscCompare()); 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and sort [1] descending, thus finishing sequence [1] [2]. 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::sort(ref_pic_list0_.begin(), iter, POCDescCompare()); 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now add [3] and sort by ascending long_term_pic_num. 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dpb_.GetLongTermRefPicsAppending(ref_pic_list0_); 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::sort(ref_pic_list0_.begin() + num_short_refs, ref_pic_list0_.end(), 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LongTermPicNumAscCompare()); 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RefPicList1 (8.2.4.2.4) [[1] [2] [3]], where: 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // [1] shortterm ref pics with POC > curr_pic's POC sorted by ascending POC, 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // [2] shortterm ref pics with POC < curr_pic's POC by descending POC, 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // [3] longterm ref pics by ascending long_term_pic_num. 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dpb_.GetShortTermRefPicsAppending(ref_pic_list1_); 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_short_refs = ref_pic_list1_.size(); 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First sort by descending POC. 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::sort(ref_pic_list1_.begin(), ref_pic_list1_.end(), POCDescCompare()); 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find first with POC < curr_pic's POC to get first element in [2]... 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter = std::upper_bound(ref_pic_list1_.begin(), ref_pic_list1_.end(), 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_.get(), POCDescCompare()); 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and sort [1] ascending. 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::sort(ref_pic_list1_.begin(), iter, POCAscCompare()); 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now add [3] and sort by ascending long_term_pic_num 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dpb_.GetShortTermRefPicsAppending(ref_pic_list1_); 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::sort(ref_pic_list1_.begin() + num_short_refs, ref_pic_list1_.end(), 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LongTermPicNumAscCompare()); 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If lists identical, swap first two entries in RefPicList1 (spec 8.2.4.2.3) 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ref_pic_list1_.size() > 1 && 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::equal(ref_pic_list0_.begin(), ref_pic_list0_.end(), 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ref_pic_list1_.begin())) 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::swap(ref_pic_list1_[0], ref_pic_list1_[1]); 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Per 8.2.4.2 it's possible for num_ref_idx_lX_active_minus1 to indicate 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // there should be more ref pics on list than we constructed. 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Those superfluous ones should be treated as non-reference. 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ref_pic_list0_.resize(slice_hdr->num_ref_idx_l0_active_minus1 + 1); 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ref_pic_list1_.resize(slice_hdr->num_ref_idx_l1_active_minus1 + 1); 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See 8.2.4 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int VaapiH264Decoder::PicNumF(H264Picture *pic) { 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pic) 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pic->long_term) 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pic->pic_num; 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return max_pic_num_; 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See 8.2.4 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int VaapiH264Decoder::LongTermPicNumF(H264Picture *pic) { 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pic->ref && pic->long_term) 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pic->long_term_pic_num; 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 2 * (max_long_term_frame_idx_ + 1); 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Shift elements on the |v| starting from |from| to |to|, inclusive, 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// one position to the right and insert pic at |from|. 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void ShiftRightAndInsert(H264Picture::PtrVector *v, 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int from, 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int to, 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H264Picture* pic) { 8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Security checks, do not disable in Debug mode. 8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(from <= to); 8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(to <= std::numeric_limits<int>::max() - 2); 8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Additional checks. Debug mode ok. 8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(v); 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(pic); 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK((to + 1 == static_cast<int>(v->size())) || 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (to + 2 == static_cast<int>(v->size()))); 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v->resize(to + 2); 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = to + 1; i > from; --i) 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*v)[i] = (*v)[i - 1]; 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*v)[from] = pic; 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool VaapiH264Decoder::ModifyReferencePicList(media::H264SliceHeader* slice_hdr, 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int list) { 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_ref_idx_lX_active_minus1; 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H264Picture::PtrVector* ref_pic_listx; 8975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) media::H264ModificationOfPicNum* list_mod; 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This can process either ref_pic_list0 or ref_pic_list1, depending on 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the list argument. Set up pointers to proper list to be processed here. 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (list == 0) { 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!slice_hdr->ref_pic_list_modification_flag_l0) 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list_mod = slice_hdr->ref_list_l0_modifications; 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_ref_idx_lX_active_minus1 = ref_pic_list0_.size() - 1; 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ref_pic_listx = &ref_pic_list0_; 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!slice_hdr->ref_pic_list_modification_flag_l1) 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list_mod = slice_hdr->ref_list_l1_modifications; 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_ref_idx_lX_active_minus1 = ref_pic_list1_.size() - 1; 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ref_pic_listx = &ref_pic_list1_; 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GE(num_ref_idx_lX_active_minus1, 0); 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Spec 8.2.4.3: 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reorder pictures on the list in a way specified in the stream. 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pic_num_lx_pred = curr_pic_->pic_num; 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ref_idx_lx = 0; 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pic_num_lx_no_wrap; 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pic_num_lx; 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool done = false; 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H264Picture* pic; 9295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int i = 0; i < media::H264SliceHeader::kRefListModSize && !done; ++i) { 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (list_mod->modification_of_pic_nums_idc) { 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0: 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Modify short reference picture position. 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (list_mod->modification_of_pic_nums_idc == 0) { 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Subtract given value from predicted PicNum. 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic_num_lx_no_wrap = pic_num_lx_pred - 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (static_cast<int>(list_mod->abs_diff_pic_num_minus1) + 1); 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wrap around max_pic_num_ if it becomes < 0 as result 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of subtraction. 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pic_num_lx_no_wrap < 0) 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic_num_lx_no_wrap += max_pic_num_; 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add given value to predicted PicNum. 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic_num_lx_no_wrap = pic_num_lx_pred + 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (static_cast<int>(list_mod->abs_diff_pic_num_minus1) + 1); 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wrap around max_pic_num_ if it becomes >= max_pic_num_ as result 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of the addition. 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pic_num_lx_no_wrap >= max_pic_num_) 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic_num_lx_no_wrap -= max_pic_num_; 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For use in next iteration. 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic_num_lx_pred = pic_num_lx_no_wrap; 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pic_num_lx_no_wrap > curr_pic_->pic_num) 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic_num_lx = pic_num_lx_no_wrap - max_pic_num_; 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic_num_lx = pic_num_lx_no_wrap; 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LT(num_ref_idx_lX_active_minus1 + 1, 9615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) media::H264SliceHeader::kRefListModSize); 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic = dpb_.GetShortRefPicByPicNum(pic_num_lx); 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pic) { 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Malformed stream, no pic num " << pic_num_lx; 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShiftRightAndInsert(ref_pic_listx, ref_idx_lx, 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_ref_idx_lX_active_minus1, pic); 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ref_idx_lx++; 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int src = ref_idx_lx, dst = ref_idx_lx; 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) src <= num_ref_idx_lX_active_minus1 + 1; ++src) { 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PicNumF((*ref_pic_listx)[src]) != pic_num_lx) 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*ref_pic_listx)[dst++] = (*ref_pic_listx)[src]; 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Modify long term reference picture position. 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LT(num_ref_idx_lX_active_minus1 + 1, 9815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) media::H264SliceHeader::kRefListModSize); 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic = dpb_.GetLongRefPicByLongTermPicNum(list_mod->long_term_pic_num); 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pic) { 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Malformed stream, no pic num " 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << list_mod->long_term_pic_num; 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShiftRightAndInsert(ref_pic_listx, ref_idx_lx, 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_ref_idx_lX_active_minus1, pic); 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ref_idx_lx++; 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int src = ref_idx_lx, dst = ref_idx_lx; 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) src <= num_ref_idx_lX_active_minus1 + 1; ++src) { 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (LongTermPicNumF((*ref_pic_listx)[src]) 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) != static_cast<int>(list_mod->long_term_pic_num)) 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*ref_pic_listx)[dst++] = (*ref_pic_listx)[src]; 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 3: 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // End of modification list. 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done = true; 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // May be recoverable. 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Invalid modification_of_pic_nums_idc=" 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << list_mod->modification_of_pic_nums_idc 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " in position " << i; 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++list_mod; 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Per NOTE 2 in 8.2.4.3.2, the ref_pic_listx size in the above loop is 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // temporarily made one element longer than the required final list. 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Resize the list back to its required size. 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ref_pic_listx->resize(num_ref_idx_lX_active_minus1 + 1); 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VaapiH264Decoder::OutputPic(H264Picture* pic) { 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!pic->outputted); 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic->outputted = true; 1027868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) last_output_poc_ = pic->pic_order_cnt; 1028868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1029868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DecodeSurface* dec_surface = DecodeSurfaceByPoC(pic->pic_order_cnt); 1030868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!dec_surface) 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1033868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_GE(dec_surface->input_id(), 0); 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(4) << "Posting output task for POC: " << pic->pic_order_cnt 1035868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << " input_id: " << dec_surface->input_id(); 1036868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) output_pic_cb_.Run(dec_surface->input_id(), dec_surface->va_surface()); 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1041868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void VaapiH264Decoder::ClearDPB() { 1042868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Clear DPB contents, marking the pictures as unused first. 1043868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (H264DPB::Pictures::iterator it = dpb_.begin(); it != dpb_.end(); ++it) 1044868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) UnassignSurfaceFromPoC((*it)->pic_order_cnt); 1045868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1046868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) dpb_.Clear(); 1047a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) last_output_poc_ = std::numeric_limits<int>::min(); 1048868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1049868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1050868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool VaapiH264Decoder::OutputAllRemainingPics() { 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Output all pictures that are waiting to be outputted. 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FinishPrevFrameIfPresent(); 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H264Picture::PtrVector to_output; 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dpb_.GetNotOutputtedPicsAppending(to_output); 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sort them by ascending POC to output in order. 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::sort(to_output.begin(), to_output.end(), POCAscCompare()); 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H264Picture::PtrVector::iterator it; 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (it = to_output.begin(); it != to_output.end(); ++it) { 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!OutputPic(*it)) { 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Failed to output pic POC: " << (*it)->pic_order_cnt; 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1066868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return true; 1067868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1069868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool VaapiH264Decoder::Flush() { 10707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DVLOG(2) << "Decoder flush"; 10717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1072868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!OutputAllRemainingPics()) 1073868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return false; 1074868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1075868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ClearDPB(); 1076868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1077868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(decode_surfaces_in_use_.empty()); 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool VaapiH264Decoder::StartNewFrame(media::H264SliceHeader* slice_hdr) { 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO posciak: add handling of max_num_ref_frames per spec. 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the new frame is an IDR, output what's left to output and clear DPB 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (slice_hdr->idr_pic_flag) { 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (unless we are explicitly instructed not to do so). 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!slice_hdr->no_output_of_prior_pics_flag) { 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Output DPB contents. 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Flush()) 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dpb_.Clear(); 1093a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) last_output_poc_ = std::numeric_limits<int>::min(); 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // curr_pic_ should have either been added to DPB or discarded when finishing 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the last frame. DPB is responsible for releasing that memory once it's 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not needed anymore. 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!curr_pic_.get()); 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_.reset(new H264Picture); 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(curr_pic_.get()); 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!InitCurrPicture(slice_hdr)) 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(max_frame_num_, 0); 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdatePicNums(); 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send parameter buffers before each new picture, before the first slice. 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SendPPS()) 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SendIQMatrix()) 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!QueueSlice(slice_hdr)) 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VaapiH264Decoder::HandleMemoryManagementOps() { 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 8.2.5.4 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < arraysize(curr_pic_->ref_pic_marking); ++i) { 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Code below does not support interlaced stream (per-field pictures). 11275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) media::H264DecRefPicMarking* ref_pic_marking = 11285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &curr_pic_->ref_pic_marking[i]; 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H264Picture* to_mark; 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pic_num_x; 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (ref_pic_marking->memory_mgmnt_control_operation) { 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0: 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Normal end of operations' specification. 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mark a short term reference picture as unused so it can be removed 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if outputted. 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic_num_x = curr_pic_->pic_num - 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ref_pic_marking->difference_of_pic_nums_minus1 + 1); 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to_mark = dpb_.GetShortRefPicByPicNum(pic_num_x); 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to_mark) { 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to_mark->ref = false; 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Invalid short ref pic num to unmark"; 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mark a long term reference picture as unused so it can be removed 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if outputted. 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to_mark = dpb_.GetLongRefPicByLongTermPicNum( 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ref_pic_marking->long_term_pic_num); 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to_mark) { 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to_mark->ref = false; 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Invalid long term ref pic num to unmark"; 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 3: 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mark a short term reference picture as long term reference. 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic_num_x = curr_pic_->pic_num - 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ref_pic_marking->difference_of_pic_nums_minus1 + 1); 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to_mark = dpb_.GetShortRefPicByPicNum(pic_num_x); 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to_mark) { 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(to_mark->ref && !to_mark->long_term); 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to_mark->long_term = true; 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to_mark->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Invalid short term ref pic num to mark as long ref"; 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 4: { 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unmark all reference pictures with long_term_frame_idx over new max. 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_long_term_frame_idx_ 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) = ref_pic_marking->max_long_term_frame_idx_plus1 - 1; 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H264Picture::PtrVector long_terms; 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dpb_.GetLongTermRefPicsAppending(long_terms); 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < long_terms.size(); ++i) { 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H264Picture* pic = long_terms[i]; 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(pic->ref && pic->long_term); 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ok to cast, max_long_term_frame_idx is much smaller than 16bit. 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pic->long_term_frame_idx > 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(max_long_term_frame_idx_)) 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic->ref = false; 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 5: 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unmark all reference pictures. 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dpb_.MarkAllUnusedForRef(); 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_long_term_frame_idx_ = -1; 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->mem_mgmt_5 = true; 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 6: { 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Replace long term reference pictures with current picture. 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First unmark if any existing with this long_term_frame_idx... 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H264Picture::PtrVector long_terms; 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dpb_.GetLongTermRefPicsAppending(long_terms); 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < long_terms.size(); ++i) { 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H264Picture* pic = long_terms[i]; 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(pic->ref && pic->long_term); 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ok to cast, long_term_frame_idx is much smaller than 16bit. 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pic->long_term_frame_idx == 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(ref_pic_marking->long_term_frame_idx)) 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pic->ref = false; 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and mark the current one instead. 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->ref = true; 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->long_term = true; 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Would indicate a bug in parser. 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This method ensures that DPB does not overflow, either by removing 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reference pictures as specified in the stream, or using a sliding window 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// procedure to remove the oldest one. 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It also performs marking and unmarking pictures as reference. 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See spac 8.2.5.1. 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VaapiH264Decoder::ReferencePictureMarking() { 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (curr_pic_->idr) { 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If current picture is an IDR, all reference pictures are unmarked. 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dpb_.MarkAllUnusedForRef(); 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (curr_pic_->long_term_reference_flag) { 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->long_term = true; 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->long_term_frame_idx = 0; 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_long_term_frame_idx_ = 0; 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pic_->long_term = false; 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_long_term_frame_idx_ = -1; 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!curr_pic_->adaptive_ref_pic_marking_mode_flag) { 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If non-IDR, and the stream does not indicate what we should do to 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ensure DPB doesn't overflow, discard oldest picture. 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See spec 8.2.5.3. 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (curr_pic_->field == H264Picture::FIELD_NONE) { 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(dpb_.CountRefPics(), 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::max<int>(parser_.GetSPS(curr_sps_id_)->max_num_ref_frames, 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1)); 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dpb_.CountRefPics() == 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::max<int>(parser_.GetSPS(curr_sps_id_)->max_num_ref_frames, 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1)) { 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Max number of reference pics reached, 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // need to remove one of the short term ones. 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find smallest frame_num_wrap short reference picture and mark 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it as unused. 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H264Picture* to_unmark = dpb_.GetLowestFrameNumWrapShortRefPic(); 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to_unmark == NULL) { 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Couldn't find a short ref picture to unmark"; 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to_unmark->ref = false; 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Shouldn't get here. 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Interlaced video not supported."; 1277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) report_error_to_uma_cb_.Run(INTERLACED_STREAM); 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stream has instructions how to discard pictures from DPB and how 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to mark/unmark existing reference pictures. Do it. 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Spec 8.2.5.4. 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (curr_pic_->field == H264Picture::FIELD_NONE) { 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HandleMemoryManagementOps(); 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Shouldn't get here. 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Interlaced video not supported."; 1288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) report_error_to_uma_cb_.Run(INTERLACED_STREAM); 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VaapiH264Decoder::FinishPicture() { 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(curr_pic_.get()); 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Finish processing previous picture. 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start by storing previous reference picture data for later use, 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if picture being finished is a reference picture. 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (curr_pic_->ref) { 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReferencePictureMarking(); 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_ref_has_memmgmnt5_ = curr_pic_->mem_mgmt_5; 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_ref_top_field_order_cnt_ = curr_pic_->top_field_order_cnt; 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_ref_pic_order_cnt_msb_ = curr_pic_->pic_order_cnt_msb; 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_ref_pic_order_cnt_lsb_ = curr_pic_->pic_order_cnt_lsb; 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_ref_field_ = curr_pic_->field; 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_has_memmgmnt5_ = curr_pic_->mem_mgmt_5; 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_frame_num_offset_ = curr_pic_->frame_num_offset; 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove unused (for reference or later output) pictures from DPB, marking 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // them as such. 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (H264DPB::Pictures::iterator it = dpb_.begin(); it != dpb_.end(); ++it) { 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*it)->outputted && !(*it)->ref) 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnassignSurfaceFromPoC((*it)->pic_order_cnt); 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) dpb_.DeleteUnused(); 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DVLOG(4) << "Finishing picture, entries in DPB: " << dpb_.size(); 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Whatever happens below, curr_pic_ will stop managing the pointer to the 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // picture after this function returns. The ownership will either be 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // transferred to DPB, if the image is still needed (for output and/or 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reference), or the memory will be released if we manage to output it here 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // without having to store it for future reference. 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<H264Picture> pic(curr_pic_.release()); 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get all pictures that haven't been outputted yet. 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H264Picture::PtrVector not_outputted; 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(posciak): pass as pointer, not reference (violates coding style). 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dpb_.GetNotOutputtedPicsAppending(not_outputted); 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Include the one we've just decoded. 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) not_outputted.push_back(pic.get()); 1334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sort in output order. 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::sort(not_outputted.begin(), not_outputted.end(), POCAscCompare()); 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Try to output as many pictures as we can. A picture can be output, 1339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // if the number of decoded and not yet outputted pictures that would remain 1340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // in DPB afterwards would at least be equal to max_num_reorder_frames. 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the outputted picture is not a reference picture, it doesn't have 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to remain in the DPB and can be removed. 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H264Picture::PtrVector::iterator output_candidate = not_outputted.begin(); 1344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) size_t num_remaining = not_outputted.size(); 1345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) while (num_remaining > max_num_reorder_frames_) { 13468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int poc = (*output_candidate)->pic_order_cnt; 13478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK_GE(poc, last_output_poc_); 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!OutputPic(*output_candidate)) 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(*output_candidate)->ref) { 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Current picture hasn't been inserted into DPB yet, so don't remove it 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if we managed to output it immediately. 1354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (*output_candidate != pic) 13558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) dpb_.DeleteByPOC(poc); 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mark as unused. 13578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) UnassignSurfaceFromPoC(poc); 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1359a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1360a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ++output_candidate; 1361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) --num_remaining; 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we haven't managed to output the picture that we just decoded, or if 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it's a reference picture, we have to store it in DPB. 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pic->outputted || pic->ref) { 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dpb_.IsFull()) { 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we haven't managed to output anything to free up space in DPB 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to store this picture, it's an error in the stream. 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Could not free up space in DPB!"; 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dpb_.StorePic(pic.release()); 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static int LevelToMaxDpbMbs(int level) { 13812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // See table A-1 in spec. 13822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (level) { 13832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 10: return 396; 13842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 11: return 900; 13852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 12: // fallthrough 13862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 13: // fallthrough 13872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 20: return 2376; 13882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 21: return 4752; 13892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 22: // fallthrough 13902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 30: return 8100; 13912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 31: return 18000; 13922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 32: return 20480; 13932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 40: // fallthrough 13942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 41: return 32768; 13952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 42: return 34816; 13962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 50: return 110400; 13972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 51: // fallthrough 13982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 52: return 184320; 13992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 14002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Invalid codec level (" << level << ")"; 14012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 14022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 14032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 14042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool VaapiH264Decoder::UpdateMaxNumReorderFrames(const media::H264SPS* sps) { 1406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (sps->vui_parameters_present_flag && sps->bitstream_restriction_flag) { 1407a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) max_num_reorder_frames_ = 1408a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::checked_cast<size_t>(sps->max_num_reorder_frames); 1409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (max_num_reorder_frames_ > dpb_.max_num_pics()) { 1410a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DVLOG(1) 1411a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "max_num_reorder_frames present, but larger than MaxDpbFrames (" 1412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << max_num_reorder_frames_ << " > " << dpb_.max_num_pics() << ")"; 1413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) max_num_reorder_frames_ = 0; 1414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 1415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 1416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 1417a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 1418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // max_num_reorder_frames not present, infer from profile/constraints 1420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // (see VUI semantics in spec). 1421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (sps->constraint_set3_flag) { 1422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) switch (sps->profile_idc) { 1423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case 44: 1424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case 86: 1425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case 100: 1426a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case 110: 1427a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case 122: 1428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case 244: 1429a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) max_num_reorder_frames_ = 0; 1430a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 1431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) default: 1432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) max_num_reorder_frames_ = dpb_.max_num_pics(); 1433a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 1434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 1435a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 1436a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) max_num_reorder_frames_ = dpb_.max_num_pics(); 1437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 1438a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1439a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 1440a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 1441a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool VaapiH264Decoder::ProcessSPS(int sps_id, bool* need_new_buffers) { 14435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const media::H264SPS* sps = parser_.GetSPS(sps_id); 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(sps); 14457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DVLOG(4) << "Processing SPS"; 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1447868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *need_new_buffers = false; 1448868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (sps->frame_mbs_only_flag == 0) { 1450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DVLOG(1) << "frame_mbs_only_flag != 1 not supported"; 1451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) report_error_to_uma_cb_.Run(FRAME_MBS_ONLY_FLAG_NOT_ONE); 1452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 1453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sps->gaps_in_frame_num_value_allowed_flag) { 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Gaps in frame numbers not supported"; 1457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) report_error_to_uma_cb_.Run(GAPS_IN_FRAME_NUM); 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_sps_id_ = sps->seq_parameter_set_id; 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Calculate picture height/width in macroblocks and pixels 14642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (spec 7.4.2.1.1, 7.4.3). 14652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int width_mb = sps->pic_width_in_mbs_minus1 + 1; 14662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int height_mb = (2 - sps->frame_mbs_only_flag) * 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (sps->pic_height_in_map_units_minus1 + 1); 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gfx::Size new_pic_size(16 * width_mb, 16 * height_mb); 14707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (new_pic_size.IsEmpty()) { 14717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DVLOG(1) << "Invalid picture size: " << new_pic_size.ToString(); 14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 14732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 14742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!pic_size_.IsEmpty() && new_pic_size == pic_size_) { 14767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Already have surfaces and this SPS keeps the same resolution, 14777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // no need to request a new set. 14787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return true; 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch pic_size_ = new_pic_size; 14827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DVLOG(1) << "New picture size: " << pic_size_.ToString(); 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_pic_order_cnt_lsb_ = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4); 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_frame_num_ = 1 << (sps->log2_max_frame_num_minus4 + 4); 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int level = sps->level_idc; 14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int max_dpb_mbs = LevelToMaxDpbMbs(level); 14892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (max_dpb_mbs == 0) 14902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 14912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t max_dpb_size = std::min(max_dpb_mbs / (width_mb * height_mb), 14932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<int>(H264DPB::kDPBMaxSize)); 14942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Codec level: " << level << ", DPB size: " << max_dpb_size; 14953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (max_dpb_size == 0) { 14963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DVLOG(1) << "Invalid DPB Size"; 14973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 14983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 14992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 15002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dpb_.set_max_num_pics(max_dpb_size); 15012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1502a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!UpdateMaxNumReorderFrames(sps)) 1503a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 1504a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DVLOG(1) << "max_num_reorder_frames: " << max_num_reorder_frames_; 1505a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1506868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *need_new_buffers = true; 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VaapiH264Decoder::ProcessPPS(int pps_id) { 15115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const media::H264PPS* pps = parser_.GetPPS(pps_id); 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(pps); 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_pps_id_ = pps->pic_parameter_set_id; 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VaapiH264Decoder::FinishPrevFrameIfPresent() { 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we already have a frame waiting to be decoded, decode it and finish. 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (curr_pic_ != NULL) { 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!DecodePicture()) 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FinishPicture(); 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool VaapiH264Decoder::ProcessSlice(media::H264SliceHeader* slice_hdr) { 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev_frame_num_ = frame_num_; 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_num_ = slice_hdr->frame_num; 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prev_frame_num_ > 0 && prev_frame_num_ < frame_num_ - 1) { 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Gap in frame_num!"; 1536868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) report_error_to_uma_cb_.Run(GAPS_IN_FRAME_NUM); 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (slice_hdr->field_pic_flag == 0) 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_pic_num_ = max_frame_num_; 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_pic_num_ = 2 * max_frame_num_; 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO posciak: switch to new picture detection per 7.4.1.2.4. 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (curr_pic_ != NULL && slice_hdr->first_mb_in_slice != 0) { 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is just some more slice data of the current picture, so 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // just queue it and return. 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QueueSlice(slice_hdr); 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A new frame, so first finish the previous one before processing it... 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!FinishPrevFrameIfPresent()) 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and then start a new one. 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return StartNewFrame(slice_hdr); 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SET_ERROR_AND_RETURN() \ 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { \ 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Error during decode"; \ 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = kError; \ 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return VaapiH264Decoder::kDecodeError; \ 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (0) 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void VaapiH264Decoder::SetStream(const uint8* ptr, 15695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t size, 15705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int32 input_id) { 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ptr); 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(size); 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Got new input stream data from the client. 1575868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DVLOG(4) << "New input stream id: " << input_id << " at: " << (void*) ptr 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " size: " << size; 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser_.SetStream(ptr, size); 1578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) curr_input_id_ = input_id; 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1581868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)VaapiH264Decoder::DecResult VaapiH264Decoder::Decode() { 15825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) media::H264Parser::Result par_res; 15835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) media::H264NALU nalu; 1584868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_NE(state_, kError); 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (1) { 1587868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // If we've already decoded some of the stream (after reset, i.e. we are 1588868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // not in kNeedStreamMetadata state), we may be able to go back into 1589868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // decoding state not only starting at/resuming from an SPS, but also from 1590868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // other resume points, such as IDRs. In the latter case we need an output 1591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // surface, because we will end up decoding that IDR in the process. 1592868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Otherwise we just look for an SPS and don't produce any output frames. 1593868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (state_ != kNeedStreamMetadata && available_va_surfaces_.empty()) { 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(4) << "No output surfaces available"; 1595868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return kRanOutOfSurfaces; 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1597868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) par_res = parser_.AdvanceToNextNALU(&nalu); 15995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (par_res == media::H264Parser::kEOStream) 1600868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return kRanOutOfStreamData; 16015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else if (par_res != media::H264Parser::kOk) 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SET_ERROR_AND_RETURN(); 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(4) << "NALU found: " << static_cast<int>(nalu.nal_unit_type); 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (nalu.nal_unit_type) { 16075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case media::H264NALU::kNonIDRSlice: 1608868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // We can't resume from a non-IDR slice. 1609868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (state_ != kDecoding) 1610868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 1611868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // else fallthrough 16125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case media::H264NALU::kIDRSlice: { 1613868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(posciak): the IDR may require an SPS that we don't have 1614868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // available. For now we'd fail if that happens, but ideally we'd like 1615868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // to keep going until the next SPS in the stream. 1616868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (state_ == kNeedStreamMetadata) { 1617868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // We need an SPS, skip this IDR and keep looking. 1618868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 1619868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1620868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1621868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // If after reset, we should be able to recover from an IDR. 16225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) media::H264SliceHeader slice_hdr; 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) par_res = parser_.ParseSliceHeader(nalu, &slice_hdr); 16255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (par_res != media::H264Parser::kOk) 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SET_ERROR_AND_RETURN(); 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ProcessSlice(&slice_hdr)) 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SET_ERROR_AND_RETURN(); 1630868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1631868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) state_ = kDecoding; 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case media::H264NALU::kSPS: { 16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int sps_id; 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!FinishPrevFrameIfPresent()) 16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SET_ERROR_AND_RETURN(); 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) par_res = parser_.ParseSPS(&sps_id); 16425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (par_res != media::H264Parser::kOk) 16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SET_ERROR_AND_RETURN(); 16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool need_new_buffers = false; 1646868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ProcessSPS(sps_id, &need_new_buffers)) 16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SET_ERROR_AND_RETURN(); 1648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1649868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) state_ = kDecoding; 1650868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 16517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (need_new_buffers) { 16527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!Flush()) 16537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return kDecodeError; 1654868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 16557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch available_va_surfaces_.clear(); 16567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return kAllocateNewSurfaces; 16577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1659868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1660868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 16615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case media::H264NALU::kPPS: { 1662868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (state_ != kDecoding) 1663868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pps_id; 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!FinishPrevFrameIfPresent()) 16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SET_ERROR_AND_RETURN(); 16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) par_res = parser_.ParsePPS(&pps_id); 16715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (par_res != media::H264Parser::kOk) 16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SET_ERROR_AND_RETURN(); 16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ProcessPPS(pps_id)) 16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SET_ERROR_AND_RETURN(); 16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1677868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1680a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DVLOG(4) << "Skipping NALU type: " << nalu.nal_unit_type; 16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t VaapiH264Decoder::GetRequiredNumOfPictures() { 16872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return dpb_.max_num_pics() + kPicsInPipeline; 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 1691