1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file. 4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/common/gpu/media/vaapi_video_encode_accelerator.h" 6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/bind.h" 8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/callback.h" 9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/command_line.h" 10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/message_loop/message_loop_proxy.h" 11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/metrics/histogram.h" 12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/numerics/safe_conversions.h" 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/common/gpu/media/h264_dpb.h" 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/common/content_switches.h" 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/base/bind_to_current_loop.h" 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "third_party/libva/va/va_enc_h264.h" 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define DVLOGF(level) DVLOG(level) << __FUNCTION__ << "(): " 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define NOTIFY_ERROR(error, msg) \ 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch do { \ 22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SetState(kError); \ 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOGF(1) << msg; \ 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOGF(1) << "Calling NotifyError(" << error << ")"; \ 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NotifyError(error); \ 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } while (0) 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 28116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace content { 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace { 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Need 2 surfaces for each frame: one for input data and one for 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// reconstructed picture, which is later used for reference. 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst size_t kMinSurfacesToEncode = 2; 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Subjectively chosen. 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst size_t kNumInputBuffers = 4; 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst size_t kMaxNumReferenceFrames = 4; 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// We need up to kMaxNumReferenceFrames surfaces for reference, plus one 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// for input and one for encode (which will be added to the set of reference 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// frames for subsequent frames). Actual execution of HW encode is done 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// in parallel, and we want to process more frames in the meantime. 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// To have kNumInputBuffers in flight, we need a full set of reference + 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// encode surfaces (i.e. kMaxNumReferenceFrames + kMinSurfacesToEncode), and 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// (kNumInputBuffers - 1) of kMinSurfacesToEncode for the remaining frames 46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// in flight. 47116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst size_t kNumSurfaces = kMaxNumReferenceFrames + kMinSurfacesToEncode + 48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch kMinSurfacesToEncode * (kNumInputBuffers - 1); 49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// An IDR every 128 frames, an I frame every 30 and no B frames. 51116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst int kIDRPeriod = 128; 52116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst int kIPeriod = 30; 53116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst int kIPPeriod = 1; 54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst int kDefaultFramerate = 30; 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// HRD parameters (ch. E.2.2 in spec). 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst int kBitRateScale = 0; // bit_rate_scale for SPS HRD parameters. 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst int kCPBSizeScale = 0; // cpb_size_scale for SPS HRD parameters. 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst int kDefaultQP = 26; 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// All Intel codecs can do at least 4.1. 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst int kDefaultLevelIDC = 41; 64116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst int kChromaFormatIDC = 1; // 4:2:0 65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Arbitrarily chosen bitrate window size for rate control, in ms. 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst int kCPBWindowSizeMs = 1500; 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// UMA errors that the VaapiVideoEncodeAccelerator class reports. 70116680a4aac90f2aa7413d9095a592090648e557Ben Murdochenum VAVEAEncoderFailure { 71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch VAAPI_ERROR = 0, 72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch VAVEA_ENCODER_FAILURES_MAX, 73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}; 74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Round |value| up to |alignment|, which must be a power of 2. 78116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic inline size_t RoundUpToPowerOf2(size_t value, size_t alignment) { 79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Check that |alignment| is a power of 2. 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK((alignment + (alignment - 1)) == (alignment | (alignment - 1))); 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return ((value + (alignment - 1)) & ~(alignment - 1)); 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic void ReportToUMA(VAVEAEncoderFailure failure) { 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch UMA_HISTOGRAM_ENUMERATION( 86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "Media.VAVEA.EncoderFailure", 87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch failure, 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch VAVEA_ENCODER_FAILURES_MAX); 89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 91116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstruct VaapiVideoEncodeAccelerator::InputFrameRef { 92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch InputFrameRef(const scoped_refptr<media::VideoFrame>& frame, 93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool force_keyframe) 94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : frame(frame), force_keyframe(force_keyframe) {} 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const scoped_refptr<media::VideoFrame> frame; 96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const bool force_keyframe; 97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}; 98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 99116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstruct VaapiVideoEncodeAccelerator::BitstreamBufferRef { 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch BitstreamBufferRef(int32 id, scoped_ptr<base::SharedMemory> shm, size_t size) 101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : id(id), shm(shm.Pass()), size(size) {} 102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const int32 id; 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const scoped_ptr<base::SharedMemory> shm; 104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const size_t size; 105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}; 106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 107116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstd::vector<media::VideoEncodeAccelerator::SupportedProfile> 108116680a4aac90f2aa7413d9095a592090648e557Ben MurdochVaapiVideoEncodeAccelerator::GetSupportedProfiles() { 109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::vector<SupportedProfile> profiles; 110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); 1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (cmd_line->HasSwitch(switches::kDisableVaapiAcceleratedVideoEncode)) 113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return profiles; 114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::vector<media::VideoCodecProfile> hw_profiles = 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci VaapiWrapper::GetSupportedEncodeProfiles( 11734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) x_display_, base::Bind(&base::DoNothing)); 118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci media::VideoEncodeAccelerator::SupportedProfile profile; 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci profile.max_resolution.SetSize(1920, 1088); 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci profile.max_framerate_numerator = kDefaultFramerate; 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci profile.max_framerate_denominator = 1; 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (size_t i = 0; i < hw_profiles.size(); i++) { 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci profile.profile = hw_profiles[i]; 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci profiles.push_back(profile); 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return profiles; 128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 130116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic unsigned int Log2OfPowerOf2(unsigned int x) { 131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CHECK_GT(x, 0u); 132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_EQ(x & (x - 1), 0u); 133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int log = 0; 135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch while (x) { 136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch x >>= 1; 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ++log; 138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return log; 140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 142116680a4aac90f2aa7413d9095a592090648e557Ben MurdochVaapiVideoEncodeAccelerator::VaapiVideoEncodeAccelerator(Display* x_display) 143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN), 144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch mb_width_(0), 145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch mb_height_(0), 146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch output_buffer_byte_size_(0), 147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch x_display_(x_display), 148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch state_(kUninitialized), 149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch frame_num_(0), 150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch last_idr_frame_num_(0), 151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bitrate_(0), 152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch framerate_(0), 153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch cpb_size_(0), 154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch encoding_parameters_changed_(false), 155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch encoder_thread_("VAVEAEncoderThread"), 156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch child_message_loop_proxy_(base::MessageLoopProxy::current()), 157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_this_ptr_factory_(this) { 158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOGF(4); 159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_this_ = weak_this_ptr_factory_.GetWeakPtr(); 160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch max_ref_idx_l0_size_ = kMaxNumReferenceFrames; 162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch qp_ = kDefaultQP; 163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch idr_period_ = kIDRPeriod; 164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch i_period_ = kIPeriod; 165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ip_period_ = kIPPeriod; 166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 168116680a4aac90f2aa7413d9095a592090648e557Ben MurdochVaapiVideoEncodeAccelerator::~VaapiVideoEncodeAccelerator() { 169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOGF(4); 170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(!encoder_thread_.IsRunning()); 172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 174116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool VaapiVideoEncodeAccelerator::Initialize( 175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch media::VideoFrame::Format format, 176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const gfx::Size& input_visible_size, 177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch media::VideoCodecProfile output_profile, 178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32 initial_bitrate, 179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Client* client) { 180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(!encoder_thread_.IsRunning()); 182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_EQ(state_, kUninitialized); 183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOGF(1) << "Initializing VAVEA, input_format: " 185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch << media::VideoFrame::FormatToString(format) 186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch << ", input_visible_size: " << input_visible_size.ToString() 187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch << ", output_profile: " << output_profile 188116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch << ", initial_bitrate: " << initial_bitrate; 189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); 191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch client_ = client_ptr_factory_->GetWeakPtr(); 192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (output_profile < media::H264PROFILE_BASELINE || 194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch output_profile > media::H264PROFILE_MAIN) { 195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOGF(1) << "Unsupported output profile: " << output_profile; 196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (format != media::VideoFrame::I420) { 200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOGF(1) << "Unsupported input format: " 201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch << media::VideoFrame::FormatToString(format); 202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch profile_ = output_profile; 206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch visible_size_ = input_visible_size; 207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // 4:2:0 format has to be 2-aligned. 208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_EQ(visible_size_.width() % 2, 0); 209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_EQ(visible_size_.height() % 2, 0); 210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch coded_size_ = gfx::Size(RoundUpToPowerOf2(visible_size_.width(), 16), 211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RoundUpToPowerOf2(visible_size_.height(), 16)); 212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch mb_width_ = coded_size_.width() / 16; 213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch mb_height_ = coded_size_.height() / 16; 214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch output_buffer_byte_size_ = coded_size_.GetArea(); 215116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch UpdateRates(initial_bitrate, kDefaultFramerate); 217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch vaapi_wrapper_ = VaapiWrapper::Create(VaapiWrapper::kEncode, 219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch output_profile, 220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch x_display_, 221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&ReportToUMA, VAAPI_ERROR)); 222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!vaapi_wrapper_) { 223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOGF(1) << "Failed initializing VAAPI"; 224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!encoder_thread_.Start()) { 228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOGF(1) << "Failed to start encoder thread"; 229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch encoder_thread_proxy_ = encoder_thread_.message_loop_proxy(); 232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Finish the remaining initialization on the encoder thread. 234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch encoder_thread_proxy_->PostTask( 235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FROM_HERE, 236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&VaapiVideoEncodeAccelerator::InitializeTask, 237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Unretained(this))); 238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 242116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid VaapiVideoEncodeAccelerator::InitializeTask() { 243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(encoder_thread_proxy_->BelongsToCurrentThread()); 244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_EQ(state_, kUninitialized); 245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOGF(4); 246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch va_surface_release_cb_ = media::BindToCurrentLoop( 248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&VaapiVideoEncodeAccelerator::RecycleVASurfaceID, 249116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Unretained(this))); 250116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 251116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!vaapi_wrapper_->CreateSurfaces( 252116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch coded_size_, kNumSurfaces, &available_va_surface_ids_)) { 253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NOTIFY_ERROR(kPlatformFailureError, "Failed creating VASurfaces"); 254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 257116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch UpdateSPS(); 258116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GeneratePackedSPS(); 259116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 260116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch UpdatePPS(); 261116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GeneratePackedPPS(); 262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch child_message_loop_proxy_->PostTask( 264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FROM_HERE, 265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&Client::RequireBitstreamBuffers, 266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch client_, 267116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch kNumInputBuffers, 268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch coded_size_, 269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch output_buffer_byte_size_)); 270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SetState(kEncoding); 272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 274116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid VaapiVideoEncodeAccelerator::RecycleVASurfaceID( 275116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch VASurfaceID va_surface_id) { 276116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOGF(4) << "va_surface_id: " << va_surface_id; 277116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(encoder_thread_proxy_->BelongsToCurrentThread()); 278116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 279116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch available_va_surface_ids_.push_back(va_surface_id); 280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EncodeFrameTask(); 281116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 282116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 283116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid VaapiVideoEncodeAccelerator::BeginFrame(bool force_keyframe) { 284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memset(¤t_pic_, 0, sizeof(current_pic_)); 285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_pic_.frame_num = frame_num_++; 287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch frame_num_ %= idr_period_; 288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 289116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (current_pic_.frame_num % i_period_ == 0 || force_keyframe) 290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_pic_.type = media::H264SliceHeader::kISlice; 291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch else 292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_pic_.type = media::H264SliceHeader::kPSlice; 293116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 294116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (current_pic_.frame_num % idr_period_ == 0) { 295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_pic_.idr = true; 296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch last_idr_frame_num_ = current_pic_.frame_num; 297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ref_pic_list0_.clear(); 298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (current_pic_.type != media::H264SliceHeader::kBSlice) 301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_pic_.ref = true; 302116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 303116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_pic_.pic_order_cnt = current_pic_.frame_num * 2; 304116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_pic_.top_field_order_cnt = current_pic_.pic_order_cnt; 305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_pic_.pic_order_cnt_lsb = current_pic_.pic_order_cnt; 306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 307116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_encode_job_->keyframe = 308116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (current_pic_.type == media::H264SliceHeader::kISlice); 309116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 310116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOGF(4) << "Starting a new frame, type: " << current_pic_.type 311116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch << (force_keyframe ? " (forced keyframe)" : "") 312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch << " frame_num: " << current_pic_.frame_num 313116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch << " POC: " << current_pic_.pic_order_cnt; 314116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 315116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 316116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid VaapiVideoEncodeAccelerator::EndFrame() { 317116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Store the picture on the list of reference pictures and keep the list 318116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // below maximum size, dropping oldest references. 319116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (current_pic_.ref) 320116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ref_pic_list0_.push_front(current_encode_job_->recon_surface); 321116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch size_t max_num_ref_frames = 322116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::checked_cast<size_t>(current_sps_.max_num_ref_frames); 323116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch while (ref_pic_list0_.size() > max_num_ref_frames) 324116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ref_pic_list0_.pop_back(); 325116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 326116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch submitted_encode_jobs_.push(make_linked_ptr(current_encode_job_.release())); 327116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 328116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 329116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic void InitVAPicture(VAPictureH264* va_pic) { 330116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memset(va_pic, 0, sizeof(*va_pic)); 331116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch va_pic->picture_id = VA_INVALID_ID; 332116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch va_pic->flags = VA_PICTURE_H264_INVALID; 333116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 334116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 335116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool VaapiVideoEncodeAccelerator::SubmitFrameParameters() { 336116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch VAEncSequenceParameterBufferH264 seq_param; 337116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memset(&seq_param, 0, sizeof(seq_param)); 338116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 339116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define SPS_TO_SP(a) seq_param.a = current_sps_.a; 340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPS_TO_SP(seq_parameter_set_id); 341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPS_TO_SP(level_idc); 342116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 343116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch seq_param.intra_period = i_period_; 344116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch seq_param.intra_idr_period = idr_period_; 345116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch seq_param.ip_period = ip_period_; 346116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch seq_param.bits_per_second = bitrate_; 347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 348116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPS_TO_SP(max_num_ref_frames); 349116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch seq_param.picture_width_in_mbs = mb_width_; 350116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch seq_param.picture_height_in_mbs = mb_height_; 351116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 352116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define SPS_TO_SP_FS(a) seq_param.seq_fields.bits.a = current_sps_.a; 353116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPS_TO_SP_FS(chroma_format_idc); 354116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPS_TO_SP_FS(frame_mbs_only_flag); 355116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPS_TO_SP_FS(log2_max_frame_num_minus4); 356116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPS_TO_SP_FS(pic_order_cnt_type); 357116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPS_TO_SP_FS(log2_max_pic_order_cnt_lsb_minus4); 358116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#undef SPS_TO_SP_FS 359116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 360116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPS_TO_SP(bit_depth_luma_minus8); 361116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPS_TO_SP(bit_depth_chroma_minus8); 362116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 363116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPS_TO_SP(frame_cropping_flag); 364116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (current_sps_.frame_cropping_flag) { 365116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPS_TO_SP(frame_crop_left_offset); 366116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPS_TO_SP(frame_crop_right_offset); 367116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPS_TO_SP(frame_crop_top_offset); 368116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPS_TO_SP(frame_crop_bottom_offset); 369116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 370116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 371116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPS_TO_SP(vui_parameters_present_flag); 372116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define SPS_TO_SP_VF(a) seq_param.vui_fields.bits.a = current_sps_.a; 373116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPS_TO_SP_VF(timing_info_present_flag); 374116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#undef SPS_TO_SP_VF 375116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPS_TO_SP(num_units_in_tick); 376116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPS_TO_SP(time_scale); 377116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#undef SPS_TO_SP 378116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 379116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!vaapi_wrapper_->SubmitBuffer(VAEncSequenceParameterBufferType, 380116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch sizeof(seq_param), 381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &seq_param)) 382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch VAEncPictureParameterBufferH264 pic_param; 385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memset(&pic_param, 0, sizeof(pic_param)); 386116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 387116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pic_param.CurrPic.picture_id = current_encode_job_->recon_surface->id(); 388116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pic_param.CurrPic.TopFieldOrderCnt = current_pic_.top_field_order_cnt; 389116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pic_param.CurrPic.BottomFieldOrderCnt = current_pic_.bottom_field_order_cnt; 390116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pic_param.CurrPic.flags = 0; 391116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (size_t i = 0; i < arraysize(pic_param.ReferenceFrames); ++i) 393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch InitVAPicture(&pic_param.ReferenceFrames[i]); 394116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_LE(ref_pic_list0_.size(), arraysize(pic_param.ReferenceFrames)); 396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RefPicList::const_iterator iter = ref_pic_list0_.begin(); 397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (size_t i = 0; 398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch i < arraysize(pic_param.ReferenceFrames) && iter != ref_pic_list0_.end(); 399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ++iter, ++i) { 400116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pic_param.ReferenceFrames[i].picture_id = (*iter)->id(); 401116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pic_param.ReferenceFrames[i].flags = 0; 402116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 403116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 404116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pic_param.coded_buf = current_encode_job_->coded_buffer; 405116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pic_param.pic_parameter_set_id = current_pps_.pic_parameter_set_id; 406116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pic_param.seq_parameter_set_id = current_pps_.seq_parameter_set_id; 407116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pic_param.frame_num = current_pic_.frame_num; 408116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pic_param.pic_init_qp = qp_; 409116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pic_param.num_ref_idx_l0_active_minus1 = max_ref_idx_l0_size_ - 1; 410116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pic_param.pic_fields.bits.idr_pic_flag = current_pic_.idr; 411116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pic_param.pic_fields.bits.reference_pic_flag = current_pic_.ref; 412116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define PPS_TO_PP_PF(a) pic_param.pic_fields.bits.a = current_pps_.a; 413116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PPS_TO_PP_PF(entropy_coding_mode_flag); 414116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PPS_TO_PP_PF(transform_8x8_mode_flag); 415116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PPS_TO_PP_PF(deblocking_filter_control_present_flag); 416116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#undef PPS_TO_PP_PF 417116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 418116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!vaapi_wrapper_->SubmitBuffer(VAEncPictureParameterBufferType, 419116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch sizeof(pic_param), 420116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &pic_param)) 421116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 422116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch VAEncSliceParameterBufferH264 slice_param; 424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memset(&slice_param, 0, sizeof(slice_param)); 425116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 426116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch slice_param.num_macroblocks = mb_width_ * mb_height_; 427116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch slice_param.macroblock_info = VA_INVALID_ID; 428116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch slice_param.slice_type = current_pic_.type; 429116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch slice_param.pic_parameter_set_id = current_pps_.pic_parameter_set_id; 430116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch slice_param.idr_pic_id = last_idr_frame_num_; 431116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch slice_param.pic_order_cnt_lsb = current_pic_.pic_order_cnt_lsb; 432116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch slice_param.num_ref_idx_active_override_flag = true; 433116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 434116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (size_t i = 0; i < arraysize(slice_param.RefPicList0); ++i) 435116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch InitVAPicture(&slice_param.RefPicList0[i]); 436116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 437116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (size_t i = 0; i < arraysize(slice_param.RefPicList1); ++i) 438116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch InitVAPicture(&slice_param.RefPicList1[i]); 439116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 440116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_LE(ref_pic_list0_.size(), arraysize(slice_param.RefPicList0)); 441116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch iter = ref_pic_list0_.begin(); 442116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (size_t i = 0; 443116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch i < arraysize(slice_param.RefPicList0) && iter != ref_pic_list0_.end(); 444116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ++iter, ++i) { 445116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch InitVAPicture(&slice_param.RefPicList0[i]); 446116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch slice_param.RefPicList0[i].picture_id = (*iter)->id(); 447116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch slice_param.RefPicList0[i].flags = 0; 448116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 449116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 450116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!vaapi_wrapper_->SubmitBuffer(VAEncSliceParameterBufferType, 451116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch sizeof(slice_param), 452116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &slice_param)) 453116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 454116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 455116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch VAEncMiscParameterRateControl rate_control_param; 456116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memset(&rate_control_param, 0, sizeof(rate_control_param)); 457116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch rate_control_param.bits_per_second = bitrate_; 458116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch rate_control_param.target_percentage = 90; 459116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch rate_control_param.window_size = kCPBWindowSizeMs; 460116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch rate_control_param.initial_qp = qp_; 461116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch rate_control_param.rc_flags.bits.disable_frame_skip = true; 462116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 463116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!vaapi_wrapper_->SubmitVAEncMiscParamBuffer( 464116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch VAEncMiscParameterTypeRateControl, 465116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch sizeof(rate_control_param), 466116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &rate_control_param)) 467116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 468116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 469116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch VAEncMiscParameterFrameRate framerate_param; 470116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memset(&framerate_param, 0, sizeof(framerate_param)); 471116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch framerate_param.framerate = framerate_; 472116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!vaapi_wrapper_->SubmitVAEncMiscParamBuffer( 473116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch VAEncMiscParameterTypeFrameRate, 474116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch sizeof(framerate_param), 475116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &framerate_param)) 476116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 477116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 478116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch VAEncMiscParameterHRD hrd_param; 479116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memset(&hrd_param, 0, sizeof(hrd_param)); 480116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch hrd_param.buffer_size = cpb_size_; 481116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch hrd_param.initial_buffer_fullness = cpb_size_ / 2; 482116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!vaapi_wrapper_->SubmitVAEncMiscParamBuffer(VAEncMiscParameterTypeHRD, 483116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch sizeof(hrd_param), 484116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &hrd_param)) 485116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 486116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 487116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 488116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 489116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 490116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool VaapiVideoEncodeAccelerator::SubmitHeadersIfNeeded() { 491116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (current_pic_.type != media::H264SliceHeader::kISlice) 492116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 493116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 494116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Submit PPS. 495116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch VAEncPackedHeaderParameterBuffer par_buffer; 496116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memset(&par_buffer, 0, sizeof(par_buffer)); 497116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch par_buffer.type = VAEncPackedHeaderSequence; 498116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch par_buffer.bit_length = packed_sps_.BytesInBuffer() * 8; 499116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 500116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!vaapi_wrapper_->SubmitBuffer(VAEncPackedHeaderParameterBufferType, 501116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch sizeof(par_buffer), 502116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &par_buffer)) 503116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 504116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 505116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!vaapi_wrapper_->SubmitBuffer(VAEncPackedHeaderDataBufferType, 506116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.BytesInBuffer(), 507116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.data())) 508116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 509116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 510116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Submit PPS. 511116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memset(&par_buffer, 0, sizeof(par_buffer)); 512116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch par_buffer.type = VAEncPackedHeaderPicture; 513116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch par_buffer.bit_length = packed_pps_.BytesInBuffer() * 8; 514116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 515116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!vaapi_wrapper_->SubmitBuffer(VAEncPackedHeaderParameterBufferType, 516116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch sizeof(par_buffer), 517116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &par_buffer)) 518116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 519116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 520116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!vaapi_wrapper_->SubmitBuffer(VAEncPackedHeaderDataBufferType, 521116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.BytesInBuffer(), 522116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.data())) 523116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 524116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 525116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 526116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 527116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 528116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool VaapiVideoEncodeAccelerator::ExecuteEncode() { 529116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOGF(3) << "Encoding frame_num: " << current_pic_.frame_num; 530116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return vaapi_wrapper_->ExecuteAndDestroyPendingBuffers( 531116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_encode_job_->input_surface->id()); 532116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 533116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 534116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool VaapiVideoEncodeAccelerator::UploadFrame( 535116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const scoped_refptr<media::VideoFrame>& frame) { 536116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return vaapi_wrapper_->UploadVideoFrameToSurface( 537116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch frame, current_encode_job_->input_surface->id()); 538116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 539116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 540116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid VaapiVideoEncodeAccelerator::TryToReturnBitstreamBuffer() { 541116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(encoder_thread_proxy_->BelongsToCurrentThread()); 542116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 543116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (state_ != kEncoding) 544116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 545116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 546116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (submitted_encode_jobs_.empty() || available_bitstream_buffers_.empty()) 547116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 548116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 549116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch linked_ptr<BitstreamBufferRef> buffer = available_bitstream_buffers_.front(); 550116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch available_bitstream_buffers_.pop(); 551116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 552116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint8* target_data = reinterpret_cast<uint8*>(buffer->shm->memory()); 553116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 554116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch linked_ptr<EncodeJob> encode_job = submitted_encode_jobs_.front(); 555116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch submitted_encode_jobs_.pop(); 556116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 557116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch size_t data_size = 0; 558116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!vaapi_wrapper_->DownloadAndDestroyCodedBuffer( 559116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch encode_job->coded_buffer, 560116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch encode_job->input_surface->id(), 561116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch target_data, 562116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch buffer->size, 563116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &data_size)) { 564116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NOTIFY_ERROR(kPlatformFailureError, "Failed downloading coded buffer"); 565116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 566116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 567116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 568116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOGF(3) << "Returning bitstream buffer " 569116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch << (encode_job->keyframe ? "(keyframe)" : "") 570116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch << " id: " << buffer->id << " size: " << data_size; 571116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 572116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch child_message_loop_proxy_->PostTask(FROM_HERE, 573116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&Client::BitstreamBufferReady, 574116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch client_, 575116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch buffer->id, 576116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data_size, 577116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch encode_job->keyframe)); 578116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 579116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 580116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid VaapiVideoEncodeAccelerator::Encode( 581116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const scoped_refptr<media::VideoFrame>& frame, 582116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool force_keyframe) { 583116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOGF(3) << "Frame timestamp: " << frame->timestamp().InMilliseconds() 584116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch << " force_keyframe: " << force_keyframe; 585116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 586116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 587116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch encoder_thread_proxy_->PostTask( 588116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FROM_HERE, 589116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&VaapiVideoEncodeAccelerator::EncodeTask, 590116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Unretained(this), 591116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch frame, 592116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch force_keyframe)); 593116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 594116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 595116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool VaapiVideoEncodeAccelerator::PrepareNextJob() { 596116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (available_va_surface_ids_.size() < kMinSurfacesToEncode) 597116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 598116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 599116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(!current_encode_job_); 600116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_encode_job_.reset(new EncodeJob()); 601116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 602116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!vaapi_wrapper_->CreateCodedBuffer(output_buffer_byte_size_, 603116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ¤t_encode_job_->coded_buffer)) { 604116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NOTIFY_ERROR(kPlatformFailureError, "Failed creating coded buffer"); 605116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 606116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 607116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 608116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_encode_job_->input_surface = 609116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new VASurface(available_va_surface_ids_.back(), va_surface_release_cb_); 610116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch available_va_surface_ids_.pop_back(); 611116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 612116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_encode_job_->recon_surface = 613116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new VASurface(available_va_surface_ids_.back(), va_surface_release_cb_); 614116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch available_va_surface_ids_.pop_back(); 615116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 616116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Reference surfaces are needed until the job is done, but they get 617116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // removed from ref_pic_list0_ when it's full at the end of job submission. 618116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Keep refs to them along with the job and only release after sync. 619116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_encode_job_->reference_surfaces = ref_pic_list0_; 620116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 621116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 622116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 623116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 624116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid VaapiVideoEncodeAccelerator::EncodeTask( 625116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const scoped_refptr<media::VideoFrame>& frame, 626116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool force_keyframe) { 627116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(encoder_thread_proxy_->BelongsToCurrentThread()); 628116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_NE(state_, kUninitialized); 629116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 630116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch encoder_input_queue_.push( 631116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch make_linked_ptr(new InputFrameRef(frame, force_keyframe))); 632116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EncodeFrameTask(); 633116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 634116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 635116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid VaapiVideoEncodeAccelerator::EncodeFrameTask() { 636116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(encoder_thread_proxy_->BelongsToCurrentThread()); 637116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 638116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (state_ != kEncoding || encoder_input_queue_.empty()) 639116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 640116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 641116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!PrepareNextJob()) { 642116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOGF(4) << "Not ready for next frame yet"; 643116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 644116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 645116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 646116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch linked_ptr<InputFrameRef> frame_ref = encoder_input_queue_.front(); 647116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch encoder_input_queue_.pop(); 648116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 649116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!UploadFrame(frame_ref->frame)) { 650116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NOTIFY_ERROR(kPlatformFailureError, "Failed uploading source frame to HW."); 651116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 652116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 653116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 654116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch BeginFrame(frame_ref->force_keyframe || encoding_parameters_changed_); 655116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch encoding_parameters_changed_ = false; 656116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 657116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!SubmitFrameParameters()) { 658116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NOTIFY_ERROR(kPlatformFailureError, "Failed submitting frame parameters."); 659116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 660116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 661116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 662116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!SubmitHeadersIfNeeded()) { 663116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NOTIFY_ERROR(kPlatformFailureError, "Failed submitting frame headers."); 664116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 665116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 666116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 667116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!ExecuteEncode()) { 668116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NOTIFY_ERROR(kPlatformFailureError, "Failed submitting encode job to HW."); 669116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 670116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 671116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 672116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EndFrame(); 673116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch TryToReturnBitstreamBuffer(); 674116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 675116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 676116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid VaapiVideoEncodeAccelerator::UseOutputBitstreamBuffer( 677116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const media::BitstreamBuffer& buffer) { 678116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOGF(4) << "id: " << buffer.id(); 679116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 680116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 681116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (buffer.size() < output_buffer_byte_size_) { 682116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NOTIFY_ERROR(kInvalidArgumentError, "Provided bitstream buffer too small"); 683116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 684116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 685116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 686116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<base::SharedMemory> shm( 687116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new base::SharedMemory(buffer.handle(), false)); 688116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!shm->Map(buffer.size())) { 689116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NOTIFY_ERROR(kPlatformFailureError, "Failed mapping shared memory."); 690116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 691116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 692116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 693116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<BitstreamBufferRef> buffer_ref( 694116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new BitstreamBufferRef(buffer.id(), shm.Pass(), buffer.size())); 695116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 696116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch encoder_thread_proxy_->PostTask( 697116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FROM_HERE, 698116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&VaapiVideoEncodeAccelerator::UseOutputBitstreamBufferTask, 699116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Unretained(this), 700116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Passed(&buffer_ref))); 701116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 702116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 703116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid VaapiVideoEncodeAccelerator::UseOutputBitstreamBufferTask( 704116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<BitstreamBufferRef> buffer_ref) { 705116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(encoder_thread_proxy_->BelongsToCurrentThread()); 706116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_NE(state_, kUninitialized); 707116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 708116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch available_bitstream_buffers_.push(make_linked_ptr(buffer_ref.release())); 709116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch TryToReturnBitstreamBuffer(); 710116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 711116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 712116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid VaapiVideoEncodeAccelerator::RequestEncodingParametersChange( 713116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32 bitrate, 714116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32 framerate) { 715116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOGF(2) << "bitrate: " << bitrate << " framerate: " << framerate; 716116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 717116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 718116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch encoder_thread_proxy_->PostTask( 719116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FROM_HERE, 720116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind( 721116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &VaapiVideoEncodeAccelerator::RequestEncodingParametersChangeTask, 722116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Unretained(this), 723116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bitrate, 724116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch framerate)); 725116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 726116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 727116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid VaapiVideoEncodeAccelerator::UpdateRates(uint32 bitrate, 728116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32 framerate) { 729116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (encoder_thread_.IsRunning()) 730116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(encoder_thread_proxy_->BelongsToCurrentThread()); 731116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_NE(bitrate, 0u); 732116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_NE(framerate, 0u); 733116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bitrate_ = bitrate; 734116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch framerate_ = framerate; 735116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch cpb_size_ = bitrate_ * kCPBWindowSizeMs / 1000; 736116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 737116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 738116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid VaapiVideoEncodeAccelerator::RequestEncodingParametersChangeTask( 739116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32 bitrate, 740116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32 framerate) { 741116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOGF(2) << "bitrate: " << bitrate << " framerate: " << framerate; 742116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(encoder_thread_proxy_->BelongsToCurrentThread()); 743116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_NE(state_, kUninitialized); 744116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 7455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // This is a workaround to zero being temporarily, as part of the initial 7465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // setup, provided by the webrtc video encode and a zero bitrate and 7475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // framerate not being accepted by VAAPI 7485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // TODO: This code is common with v4l2_video_encode_accelerator.cc, perhaps 7495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // it could be pulled up to RTCVideoEncoder 7505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (bitrate < 1) 7515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bitrate = 1; 7525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (framerate < 1) 7535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) framerate = 1; 7545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 755116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch UpdateRates(bitrate, framerate); 756116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 757116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch UpdateSPS(); 758116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GeneratePackedSPS(); 759116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 760116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Submit new parameters along with next frame that will be processed. 761116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch encoding_parameters_changed_ = true; 762116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 763116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 764116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid VaapiVideoEncodeAccelerator::Destroy() { 765116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 766116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 767116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Can't call client anymore after Destroy() returns. 768116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch client_ptr_factory_.reset(); 769116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_this_ptr_factory_.InvalidateWeakPtrs(); 770116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 771116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Early-exit encoder tasks if they are running and join the thread. 772116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (encoder_thread_.IsRunning()) { 773116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch encoder_thread_.message_loop()->PostTask( 774116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FROM_HERE, 775116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&VaapiVideoEncodeAccelerator::DestroyTask, 776116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Unretained(this))); 777116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch encoder_thread_.Stop(); 778116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 779116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 780116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch delete this; 781116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 782116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 783116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid VaapiVideoEncodeAccelerator::DestroyTask() { 784116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOGF(2); 785116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(encoder_thread_proxy_->BelongsToCurrentThread()); 786116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SetState(kError); 787116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 788116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 789116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid VaapiVideoEncodeAccelerator::UpdateSPS() { 790116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memset(¤t_sps_, 0, sizeof(media::H264SPS)); 791116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 792116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Spec A.2 and A.3. 793116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch switch (profile_) { 794116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case media::H264PROFILE_BASELINE: 795116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Due to crbug.com/345569, we don't distinguish between constrained 796116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // and non-constrained baseline profiles. Since many codecs can't do 797116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // non-constrained, and constrained is usually what we mean (and it's a 798116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // subset of non-constrained), default to it. 799116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.profile_idc = media::H264SPS::kProfileIDCBaseline; 800116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.constraint_set0_flag = true; 801116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch break; 802116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case media::H264PROFILE_MAIN: 803116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.profile_idc = media::H264SPS::kProfileIDCMain; 804116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.constraint_set1_flag = true; 805116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch break; 806116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case media::H264PROFILE_HIGH: 807116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.profile_idc = media::H264SPS::kProfileIDCHigh; 808116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch break; 809116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch default: 810116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NOTIMPLEMENTED(); 811116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 812116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 813116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 814116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.level_idc = kDefaultLevelIDC; 815116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.seq_parameter_set_id = 0; 816116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.chroma_format_idc = kChromaFormatIDC; 817116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 818116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_GE(idr_period_, 1u << 4); 819116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.log2_max_frame_num_minus4 = Log2OfPowerOf2(idr_period_) - 4; 820116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.pic_order_cnt_type = 0; 821116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.log2_max_pic_order_cnt_lsb_minus4 = 822116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Log2OfPowerOf2(idr_period_ * 2) - 4; 823116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.max_num_ref_frames = max_ref_idx_l0_size_; 824116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 825116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.frame_mbs_only_flag = true; 826116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 827116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_GT(mb_width_, 0u); 828116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_GT(mb_height_, 0u); 829116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.pic_width_in_mbs_minus1 = mb_width_ - 1; 830116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(current_sps_.frame_mbs_only_flag); 831116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.pic_height_in_map_units_minus1 = mb_height_ - 1; 832116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 833116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (visible_size_ != coded_size_) { 834116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Visible size differs from coded size, fill crop information. 835116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.frame_cropping_flag = true; 836116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(!current_sps_.separate_colour_plane_flag); 837116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Spec table 6-1. Only 4:2:0 for now. 838116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_EQ(current_sps_.chroma_format_idc, 1); 839116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Spec 7.4.2.1.1. Crop is in crop units, which is 2 pixels for 4:2:0. 840116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const unsigned int crop_unit_x = 2; 841116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const unsigned int crop_unit_y = 2 * (2 - current_sps_.frame_mbs_only_flag); 842116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.frame_crop_left_offset = 0; 843116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.frame_crop_right_offset = 844116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (coded_size_.width() - visible_size_.width()) / crop_unit_x; 845116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.frame_crop_top_offset = 0; 846116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.frame_crop_bottom_offset = 847116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (coded_size_.height() - visible_size_.height()) / crop_unit_y; 848116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 849116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 850116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.vui_parameters_present_flag = true; 851116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.timing_info_present_flag = true; 852116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.num_units_in_tick = 1; 853116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.time_scale = framerate_ * 2; // See equation D-2 in spec. 854116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.fixed_frame_rate_flag = true; 855116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 856116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.nal_hrd_parameters_present_flag = true; 857116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // H.264 spec ch. E.2.2. 858116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.cpb_cnt_minus1 = 0; 859116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.bit_rate_scale = kBitRateScale; 860116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.cpb_size_scale = kCPBSizeScale; 861116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.bit_rate_value_minus1[0] = 862116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (bitrate_ >> 863116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (kBitRateScale + media::H264SPS::kBitRateScaleConstantTerm)) - 1; 864116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.cpb_size_value_minus1[0] = 865116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (cpb_size_ >> 866116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (kCPBSizeScale + media::H264SPS::kCPBSizeScaleConstantTerm)) - 1; 867116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.cbr_flag[0] = true; 868116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.initial_cpb_removal_delay_length_minus_1 = 869116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch media::H264SPS::kDefaultInitialCPBRemovalDelayLength - 1; 870116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.cpb_removal_delay_length_minus1 = 871116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch media::H264SPS::kDefaultInitialCPBRemovalDelayLength - 1; 872116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.dpb_output_delay_length_minus1 = 873116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch media::H264SPS::kDefaultDPBOutputDelayLength - 1; 874116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.time_offset_length = media::H264SPS::kDefaultTimeOffsetLength; 875116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.low_delay_hrd_flag = false; 876116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 877116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 878116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid VaapiVideoEncodeAccelerator::GeneratePackedSPS() { 879116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.Reset(); 880116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 881116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.BeginNALU(media::H264NALU::kSPS, 3); 882116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 883116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBits(8, current_sps_.profile_idc); 884116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(current_sps_.constraint_set0_flag); 885116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(current_sps_.constraint_set1_flag); 886116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(current_sps_.constraint_set2_flag); 887116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(current_sps_.constraint_set3_flag); 888116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(current_sps_.constraint_set4_flag); 889116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(current_sps_.constraint_set5_flag); 890116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBits(2, 0); // reserved_zero_2bits 891116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBits(8, current_sps_.level_idc); 892116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendUE(current_sps_.seq_parameter_set_id); 893116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 894116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (current_sps_.profile_idc == media::H264SPS::kProfileIDCHigh) { 895116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendUE(current_sps_.chroma_format_idc); 896116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (current_sps_.chroma_format_idc == 3) 897116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(current_sps_.separate_colour_plane_flag); 898116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendUE(current_sps_.bit_depth_luma_minus8); 899116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendUE(current_sps_.bit_depth_chroma_minus8); 900116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(current_sps_.qpprime_y_zero_transform_bypass_flag); 901116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(current_sps_.seq_scaling_matrix_present_flag); 902116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CHECK(!current_sps_.seq_scaling_matrix_present_flag); 903116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 904116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 905116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendUE(current_sps_.log2_max_frame_num_minus4); 906116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendUE(current_sps_.pic_order_cnt_type); 907116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (current_sps_.pic_order_cnt_type == 0) 908116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendUE(current_sps_.log2_max_pic_order_cnt_lsb_minus4); 909116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch else if (current_sps_.pic_order_cnt_type == 1) { 910116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CHECK(1); 911116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 912116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 913116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendUE(current_sps_.max_num_ref_frames); 914116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(current_sps_.gaps_in_frame_num_value_allowed_flag); 915116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendUE(current_sps_.pic_width_in_mbs_minus1); 916116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendUE(current_sps_.pic_height_in_map_units_minus1); 917116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 918116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(current_sps_.frame_mbs_only_flag); 919116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!current_sps_.frame_mbs_only_flag) 920116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(current_sps_.mb_adaptive_frame_field_flag); 921116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 922116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(current_sps_.direct_8x8_inference_flag); 923116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 924116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(current_sps_.frame_cropping_flag); 925116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (current_sps_.frame_cropping_flag) { 926116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendUE(current_sps_.frame_crop_left_offset); 927116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendUE(current_sps_.frame_crop_right_offset); 928116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendUE(current_sps_.frame_crop_top_offset); 929116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendUE(current_sps_.frame_crop_bottom_offset); 930116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 931116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 932116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(current_sps_.vui_parameters_present_flag); 933116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (current_sps_.vui_parameters_present_flag) { 934116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(false); // aspect_ratio_info_present_flag 935116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(false); // overscan_info_present_flag 936116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(false); // video_signal_type_present_flag 937116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(false); // chroma_loc_info_present_flag 938116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 939116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(current_sps_.timing_info_present_flag); 940116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (current_sps_.timing_info_present_flag) { 941116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBits(32, current_sps_.num_units_in_tick); 942116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBits(32, current_sps_.time_scale); 943116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(current_sps_.fixed_frame_rate_flag); 944116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 945116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 946116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(current_sps_.nal_hrd_parameters_present_flag); 947116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (current_sps_.nal_hrd_parameters_present_flag) { 948116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendUE(current_sps_.cpb_cnt_minus1); 949116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBits(4, current_sps_.bit_rate_scale); 950116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBits(4, current_sps_.cpb_size_scale); 951116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CHECK_LT(base::checked_cast<size_t>(current_sps_.cpb_cnt_minus1), 952116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch arraysize(current_sps_.bit_rate_value_minus1)); 953116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (int i = 0; i <= current_sps_.cpb_cnt_minus1; ++i) { 954116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendUE(current_sps_.bit_rate_value_minus1[i]); 955116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendUE(current_sps_.cpb_size_value_minus1[i]); 956116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(current_sps_.cbr_flag[i]); 957116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 958116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBits( 959116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 5, current_sps_.initial_cpb_removal_delay_length_minus_1); 960116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBits(5, current_sps_.cpb_removal_delay_length_minus1); 961116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBits(5, current_sps_.dpb_output_delay_length_minus1); 962116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBits(5, current_sps_.time_offset_length); 963116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 964116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 965116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(false); // vcl_hrd_parameters_flag 966116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (current_sps_.nal_hrd_parameters_present_flag) 967116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(current_sps_.low_delay_hrd_flag); 968116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 969116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(false); // pic_struct_present_flag 970116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.AppendBool(false); // bitstream_restriction_flag 971116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 972116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 973116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_sps_.FinishNALU(); 974116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 975116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 976116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid VaapiVideoEncodeAccelerator::UpdatePPS() { 977116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memset(¤t_pps_, 0, sizeof(media::H264PPS)); 978116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 979116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_pps_.seq_parameter_set_id = current_sps_.seq_parameter_set_id; 980116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_pps_.pic_parameter_set_id = 0; 981116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 982116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_pps_.entropy_coding_mode_flag = 983116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sps_.profile_idc >= media::H264SPS::kProfileIDCMain; 984116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 985116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CHECK_GT(max_ref_idx_l0_size_, 0u); 986116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_pps_.num_ref_idx_l0_default_active_minus1 = max_ref_idx_l0_size_ - 1; 987116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_pps_.num_ref_idx_l1_default_active_minus1 = 0; 988116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_LE(qp_, 51u); 989116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_pps_.pic_init_qp_minus26 = qp_ - 26; 990116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_pps_.deblocking_filter_control_present_flag = true; 991116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_pps_.transform_8x8_mode_flag = 992116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (current_sps_.profile_idc == media::H264SPS::kProfileIDCHigh); 993116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 994116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 995116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid VaapiVideoEncodeAccelerator::GeneratePackedPPS() { 996116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.Reset(); 997116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 998116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.BeginNALU(media::H264NALU::kPPS, 3); 999116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1000116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.AppendUE(current_pps_.pic_parameter_set_id); 1001116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.AppendUE(current_pps_.seq_parameter_set_id); 1002116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.AppendBool(current_pps_.entropy_coding_mode_flag); 1003116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.AppendBool( 1004116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_pps_.bottom_field_pic_order_in_frame_present_flag); 1005116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CHECK_EQ(current_pps_.num_slice_groups_minus1, 0); 1006116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.AppendUE(current_pps_.num_slice_groups_minus1); 1007116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1008116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.AppendUE(current_pps_.num_ref_idx_l0_default_active_minus1); 1009116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.AppendUE(current_pps_.num_ref_idx_l1_default_active_minus1); 1010116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1011116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.AppendBool(current_pps_.weighted_pred_flag); 1012116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.AppendBits(2, current_pps_.weighted_bipred_idc); 1013116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1014116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.AppendSE(current_pps_.pic_init_qp_minus26); 1015116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.AppendSE(current_pps_.pic_init_qs_minus26); 1016116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.AppendSE(current_pps_.chroma_qp_index_offset); 1017116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1018116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.AppendBool(current_pps_.deblocking_filter_control_present_flag); 1019116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.AppendBool(current_pps_.constrained_intra_pred_flag); 1020116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.AppendBool(current_pps_.redundant_pic_cnt_present_flag); 1021116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1022116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.AppendBool(current_pps_.transform_8x8_mode_flag); 1023116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.AppendBool(current_pps_.pic_scaling_matrix_present_flag); 1024116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(!current_pps_.pic_scaling_matrix_present_flag); 1025116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.AppendSE(current_pps_.second_chroma_qp_index_offset); 1026116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1027116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packed_pps_.FinishNALU(); 1028116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 1029116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1030116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid VaapiVideoEncodeAccelerator::SetState(State state) { 1031116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Only touch state on encoder thread, unless it's not running. 1032116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (encoder_thread_.IsRunning() && 1033116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch !encoder_thread_proxy_->BelongsToCurrentThread()) { 1034116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch encoder_thread_proxy_->PostTask( 1035116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FROM_HERE, 1036116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&VaapiVideoEncodeAccelerator::SetState, 1037116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Unretained(this), 1038116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch state)); 1039116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 1040116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 1041116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1042116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOGF(1) << "setting state to: " << state; 1043116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch state_ = state; 1044116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 1045116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1046116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid VaapiVideoEncodeAccelerator::NotifyError(Error error) { 1047116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!child_message_loop_proxy_->BelongsToCurrentThread()) { 1048116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch child_message_loop_proxy_->PostTask( 1049116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FROM_HERE, 1050116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind( 1051116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &VaapiVideoEncodeAccelerator::NotifyError, weak_this_, error)); 1052116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 1053116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 1054116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1055116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (client_) { 1056116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch client_->NotifyError(error); 1057116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch client_ptr_factory_.reset(); 1058116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 1059116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 1060116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1061116680a4aac90f2aa7413d9095a592090648e557Ben MurdochVaapiVideoEncodeAccelerator::EncodeJob::EncodeJob() 1062116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : coded_buffer(VA_INVALID_ID), keyframe(false) { 1063116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 1064116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1065116680a4aac90f2aa7413d9095a592090648e557Ben MurdochVaapiVideoEncodeAccelerator::EncodeJob::~EncodeJob() { 1066116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 1067116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1068116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace content 1069