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(&current_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                                         &current_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(&current_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(&current_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