[go: nahoru, domu]

blob: d8974e000288b0fa18a8fb14a053e0c51d2e7e84 [file] [log] [blame]
Avi Drissmand387f0922022-09-14 20:51:311// Copyright 2015 The Chromium Authors
posciakd94b2b082015-09-18 04:03:402// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
markdittmer6e70beb82016-05-02 05:40:475#include "media/gpu/vp9_decoder.h"
mostynb6682b1c42016-04-19 10:17:306
7#include <memory>
8
posciak77118c92016-08-28 13:18:399#include "base/bind.h"
Hirokazu Honda10df95d2019-07-19 19:31:4310#include "base/feature_list.h"
mostynb6682b1c42016-04-19 10:17:3011#include "base/logging.h"
Qiu Jianlin2153ac02022-08-18 04:13:1512#include "base/metrics/histogram_functions.h"
Hirokazu Honda967b9192019-08-27 00:59:4213#include "build/build_config.h"
Yuta Hijikata29f67812020-10-24 01:15:4414#include "build/chromeos_buildflags.h"
posciakd94b2b082015-09-18 04:03:4015#include "media/base/limits.h"
Hirokazu Honda10df95d2019-07-19 19:31:4316#include "media/base/media_switches.h"
markdittmer6e70beb82016-05-02 05:40:4717#include "media/gpu/vp9_decoder.h"
posciakd94b2b082015-09-18 04:03:4018
markdittmer6e70beb82016-05-02 05:40:4719namespace media {
posciakd94b2b082015-09-18 04:03:4020
Hirokazu Honda10df95d2019-07-19 19:31:4321namespace {
Hirokazu Hondafb2681c2021-10-29 03:53:5922bool GetSpatialLayerFrameSize(const DecoderBuffer& decoder_buffer,
23 std::vector<uint32_t>& frame_sizes) {
24 frame_sizes.clear();
25
Hirokazu Honda10df95d2019-07-19 19:31:4326 const uint32_t* cue_data =
27 reinterpret_cast<const uint32_t*>(decoder_buffer.side_data());
Hirokazu Hondafb2681c2021-10-29 03:53:5928 if (!cue_data)
29 return true;
30
Hirokazu Hondabbf7f402022-04-04 08:13:4931 bool enable_vp9_ksvc =
Shuhai Pengfe10fd02021-11-11 03:20:5932// On windows, currently only d3d11 supports decoding VP9 kSVC stream, we
33// shouldn't combine the switch kD3D11Vp9kSVCHWDecoding to kVp9kSVCHWDecoding
34// due to we want keep returning false to MediaCapability.
Xiaohan Wangd4983e82022-01-15 06:19:3735#if BUILDFLAG(IS_WIN)
Hirokazu Hondabbf7f402022-04-04 08:13:4936 base::FeatureList::IsEnabled(media::kD3D11Vp9kSVCHWDecoding);
Xiaohan Wangc33487932022-04-22 23:37:2137#elif BUILDFLAG(IS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
Hirokazu Hondabbf7f402022-04-04 08:13:4938 // V4L2 stateless API decoder is not capable of decoding VP9 k-SVC stream.
39 false;
Shuhai Pengfe10fd02021-11-11 03:20:5940#else
Hirokazu Hondabbf7f402022-04-04 08:13:4941 base::FeatureList::IsEnabled(media::kVp9kSVCHWDecoding);
42#endif
43
44 if (!enable_vp9_ksvc) {
Hirokazu Hondafb2681c2021-10-29 03:53:5945 DLOG(ERROR) << "Vp9 k-SVC hardware decoding is disabled";
46 return false;
Hirokazu Honda10df95d2019-07-19 19:31:4347 }
48
49 size_t num_of_layers = decoder_buffer.side_data_size() / sizeof(uint32_t);
50 if (num_of_layers > 3u) {
51 DLOG(WARNING) << "The maximum number of spatial layers in VP9 is three";
Hirokazu Hondafb2681c2021-10-29 03:53:5952 return false;
Hirokazu Honda10df95d2019-07-19 19:31:4353 }
Hirokazu Hondafb2681c2021-10-29 03:53:5954
55 frame_sizes = std::vector<uint32_t>(cue_data, cue_data + num_of_layers);
56 return true;
Hirokazu Honda10df95d2019-07-19 19:31:4357}
Hirokazu Honda7ec32652019-11-22 09:40:2158
59VideoCodecProfile VP9ProfileToVideoCodecProfile(uint8_t profile) {
60 switch (profile) {
61 case 0:
62 return VP9PROFILE_PROFILE0;
63 case 1:
64 return VP9PROFILE_PROFILE1;
65 case 2:
66 return VP9PROFILE_PROFILE2;
67 case 3:
68 return VP9PROFILE_PROFILE3;
69 default:
70 return VIDEO_CODEC_PROFILE_UNKNOWN;
71 }
72}
73
Hirokazu Honda963303782020-12-03 05:57:0474bool IsValidBitDepth(uint8_t bit_depth, VideoCodecProfile profile) {
75 // Spec 7.2.
76 switch (profile) {
77 case VP9PROFILE_PROFILE0:
78 case VP9PROFILE_PROFILE1:
79 return bit_depth == 8u;
80 case VP9PROFILE_PROFILE2:
81 case VP9PROFILE_PROFILE3:
82 return bit_depth == 10u || bit_depth == 12u;
83 default:
84 NOTREACHED();
85 return false;
86 }
87}
Hirokazu Honda790d98e2020-12-04 03:41:4888
Qiu Jianlin2153ac02022-08-18 04:13:1589VideoChromaSampling GetVP9ChromaSampling(const Vp9FrameHeader& frame_header) {
90 // Spec section 7.2.2
91 uint8_t subsampling_x = frame_header.subsampling_x;
92 uint8_t subsampling_y = frame_header.subsampling_y;
93 if (subsampling_x == 0 && subsampling_y == 0) {
94 return VideoChromaSampling::k444;
95 } else if (subsampling_x == 1u && subsampling_y == 0u) {
96 return VideoChromaSampling::k422;
97 } else if (subsampling_x == 1u && subsampling_y == 1u) {
98 return VideoChromaSampling::k420;
99 } else {
100 DLOG(WARNING) << "Unknown chroma sampling format.";
101 return VideoChromaSampling::kUnknown;
102 }
Hirokazu Honda790d98e2020-12-04 03:41:48103}
Hirokazu Honda10df95d2019-07-19 19:31:43104} // namespace
105
posciakd94b2b082015-09-18 04:03:40106VP9Decoder::VP9Accelerator::VP9Accelerator() {}
107
108VP9Decoder::VP9Accelerator::~VP9Accelerator() {}
109
Miguel Casas71b9dc42022-03-05 02:45:41110bool VP9Decoder::VP9Accelerator::SupportsContextProbabilityReadback() const {
111 return false;
112}
113
Fredrik Hubinette3cebc622018-10-27 01:01:12114VP9Decoder::VP9Decoder(std::unique_ptr<VP9Accelerator> accelerator,
Hirokazu Honda7ec32652019-11-22 09:40:21115 VideoCodecProfile profile,
Miguel Casas2c14d4b2022-11-21 20:50:21116 const VideoColorSpace& container_color_space,
117 bool ignore_resolution_changes_to_smaller)
posciak77118c92016-08-28 13:18:39118 : state_(kNeedStreamMetadata),
Fredrik Hubinette3cebc622018-10-27 01:01:12119 container_color_space_(container_color_space),
Miguel Casas2c14d4b2022-11-21 20:50:21120 ignore_resolution_changes_to_smaller_(
121 ignore_resolution_changes_to_smaller),
Hirokazu Honda7ec32652019-11-22 09:40:21122 // TODO(hiroh): Set profile to UNKNOWN.
123 profile_(profile),
Miguel Casas2d5ecad82018-02-22 19:03:05124 accelerator_(std::move(accelerator)),
Miguel Casas4eab0212022-03-13 17:32:52125 parser_(accelerator_->NeedsCompressedHeaderParsed(),
Miguel Casas71b9dc42022-03-05 02:45:41126 accelerator_->SupportsContextProbabilityReadback()) {}
posciakd94b2b082015-09-18 04:03:40127
Miguel Casas2d5ecad82018-02-22 19:03:05128VP9Decoder::~VP9Decoder() = default;
posciakd94b2b082015-09-18 04:03:40129
Hirokazu Honda23132c32019-07-09 14:31:20130void VP9Decoder::SetStream(int32_t id, const DecoderBuffer& decoder_buffer) {
131 const uint8_t* ptr = decoder_buffer.data();
132 const size_t size = decoder_buffer.data_size();
133 const DecryptConfig* decrypt_config = decoder_buffer.decrypt_config();
134
posciakd94b2b082015-09-18 04:03:40135 DCHECK(ptr);
136 DCHECK(size);
Pawel Osciakec6e21b2018-03-19 09:13:06137 DVLOG(4) << "New input stream id: " << id << " at: " << (void*)ptr
138 << " size: " << size;
139 stream_id_ = id;
Hirokazu Hondafb2681c2021-10-29 03:53:59140 std::vector<uint32_t> frame_sizes;
141 if (!GetSpatialLayerFrameSize(decoder_buffer, frame_sizes)) {
142 SetError();
143 return;
Ted Meyer0b35c5fd2018-11-27 22:29:29144 }
Hirokazu Hondafb2681c2021-10-29 03:53:59145
146 parser_.SetStream(ptr, size, frame_sizes,
147 decrypt_config ? decrypt_config->Clone() : nullptr);
posciakd94b2b082015-09-18 04:03:40148}
149
150bool VP9Decoder::Flush() {
151 DVLOG(2) << "Decoder flush";
152 Reset();
153 return true;
154}
155
156void VP9Decoder::Reset() {
157 curr_frame_hdr_ = nullptr;
Jeffrey Kardatzke48ebdb692021-01-11 22:05:02158 decrypt_config_.reset();
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13159 pending_pic_.reset();
Sreerenj Balachandran1beb5482019-04-03 03:40:05160
161 ref_frames_.Clear();
posciakd94b2b082015-09-18 04:03:40162
163 parser_.Reset();
164
Jose Lopes24d1cda82020-02-21 13:22:36165 if (state_ == kDecoding) {
posciakd94b2b082015-09-18 04:03:40166 state_ = kAfterReset;
Jose Lopes24d1cda82020-02-21 13:22:36167 }
posciakd94b2b082015-09-18 04:03:40168}
169
170VP9Decoder::DecodeResult VP9Decoder::Decode() {
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13171 while (true) {
Hirokazu Hondafb2681c2021-10-29 03:53:59172 if (state_ == kError)
173 return kDecodeError;
174
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13175 // If we have a pending picture to decode, try that first.
176 if (pending_pic_) {
Jeffrey Kardatzke4ed4e332020-12-05 00:32:15177 VP9Accelerator::Status status =
178 DecodeAndOutputPicture(std::move(pending_pic_));
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13179 if (status == VP9Accelerator::Status::kFail) {
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13180 SetError();
181 return kDecodeError;
182 }
183 if (status == VP9Accelerator::Status::kTryAgain)
184 return kTryAgain;
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13185 }
186
posciakd94b2b082015-09-18 04:03:40187 // Read a new frame header if one is not awaiting decoding already.
188 if (!curr_frame_hdr_) {
Hirokazu Honda10df95d2019-07-19 19:31:43189 gfx::Size allocate_size;
xhwang60f96672016-06-14 21:47:53190 std::unique_ptr<Vp9FrameHeader> hdr(new Vp9FrameHeader());
Ted Meyer0b35c5fd2018-11-27 22:29:29191 Vp9Parser::Result res =
Jeffrey Kardatzke48ebdb692021-01-11 22:05:02192 parser_.ParseNextFrame(hdr.get(), &allocate_size, &decrypt_config_);
posciakd94b2b082015-09-18 04:03:40193 switch (res) {
xhwang60f96672016-06-14 21:47:53194 case Vp9Parser::kOk:
brusi_roy8e7155962016-09-14 18:22:58195 curr_frame_hdr_ = std::move(hdr);
Hirokazu Honda10df95d2019-07-19 19:31:43196 curr_frame_size_ = allocate_size;
posciakd94b2b082015-09-18 04:03:40197 break;
198
xhwang60f96672016-06-14 21:47:53199 case Vp9Parser::kEOStream:
posciakd94b2b082015-09-18 04:03:40200 return kRanOutOfStreamData;
201
xhwang60f96672016-06-14 21:47:53202 case Vp9Parser::kInvalidStream:
posciakd94b2b082015-09-18 04:03:40203 DVLOG(1) << "Error parsing stream";
204 SetError();
205 return kDecodeError;
kcwue5a9a6292016-08-17 03:40:02206
207 case Vp9Parser::kAwaitingRefresh:
posciak77118c92016-08-28 13:18:39208 DVLOG(4) << "Awaiting context update";
209 return kNeedContextUpdate;
posciakd94b2b082015-09-18 04:03:40210 }
211 }
212
213 if (state_ != kDecoding) {
214 // Not kDecoding, so we need a resume point (a keyframe), as we are after
215 // reset or at the beginning of the stream. Drop anything that is not
216 // a keyframe in such case, and continue looking for a keyframe.
Sreerenj Balachandran57163302018-11-28 02:45:57217 // Only exception is when the stream/sequence starts with an Intra only
218 // frame.
219 if (curr_frame_hdr_->IsKeyframe() ||
220 (curr_frame_hdr_->IsIntra() && pic_size_.IsEmpty())) {
posciakd94b2b082015-09-18 04:03:40221 state_ = kDecoding;
222 } else {
223 curr_frame_hdr_.reset();
Jeffrey Kardatzke48ebdb692021-01-11 22:05:02224 decrypt_config_.reset();
posciakd94b2b082015-09-18 04:03:40225 continue;
226 }
227 }
228
229 if (curr_frame_hdr_->show_existing_frame) {
230 // This frame header only instructs us to display one of the
231 // previously-decoded frames, but has no frame data otherwise. Display
232 // and continue decoding subsequent frames.
kcwue5a9a6292016-08-17 03:40:02233 size_t frame_to_show = curr_frame_hdr_->frame_to_show_map_idx;
Sreerenj Balachandran1beb5482019-04-03 03:40:05234 if (frame_to_show >= kVp9NumRefFrames ||
235 !ref_frames_.GetFrame(frame_to_show)) {
posciakd94b2b082015-09-18 04:03:40236 DVLOG(1) << "Request to show an invalid frame";
237 SetError();
238 return kDecodeError;
239 }
240
Chih-Yu Huangcd5181e2018-10-23 06:33:06241 // Duplicate the VP9Picture and set the current bitstream id to keep the
242 // correct timestamp.
Sreerenj Balachandran1beb5482019-04-03 03:40:05243 scoped_refptr<VP9Picture> pic =
244 ref_frames_.GetFrame(frame_to_show)->Duplicate();
Chih-Yu Huangcd5181e2018-10-23 06:33:06245 if (pic == nullptr) {
246 DVLOG(1) << "Failed to duplicate the VP9Picture.";
247 SetError();
248 return kDecodeError;
249 }
250 pic->set_bitstream_id(stream_id_);
251 if (!accelerator_->OutputPicture(std::move(pic))) {
posciakd94b2b082015-09-18 04:03:40252 SetError();
253 return kDecodeError;
254 }
255
256 curr_frame_hdr_.reset();
Jeffrey Kardatzke48ebdb692021-01-11 22:05:02257 decrypt_config_.reset();
posciakd94b2b082015-09-18 04:03:40258 continue;
259 }
260
Hirokazu Honda10df95d2019-07-19 19:31:43261 gfx::Size new_pic_size = curr_frame_size_;
Hirokazu Honda436cf27b2019-05-21 10:44:39262 gfx::Rect new_render_rect(curr_frame_hdr_->render_width,
263 curr_frame_hdr_->render_height);
Hirokazu Hondacffd0ef2020-02-28 03:32:31264 // For safety, check the validity of render size or leave it as pic size.
Hirokazu Honda436cf27b2019-05-21 10:44:39265 if (!gfx::Rect(new_pic_size).Contains(new_render_rect)) {
266 DVLOG(1) << "Render size exceeds picture size. render size: "
267 << new_render_rect.ToString()
268 << ", picture size: " << new_pic_size.ToString();
Hirokazu Hondacffd0ef2020-02-28 03:32:31269 new_render_rect = gfx::Rect(new_pic_size);
Hirokazu Honda436cf27b2019-05-21 10:44:39270 }
Hirokazu Honda7ec32652019-11-22 09:40:21271 VideoCodecProfile new_profile =
272 VP9ProfileToVideoCodecProfile(curr_frame_hdr_->profile);
273 if (new_profile == VIDEO_CODEC_PROFILE_UNKNOWN) {
274 VLOG(1) << "Invalid profile: " << curr_frame_hdr_->profile;
275 return kDecodeError;
276 }
Hirokazu Honda963303782020-12-03 05:57:04277 if (!IsValidBitDepth(curr_frame_hdr_->bit_depth, new_profile)) {
278 DVLOG(1) << "Invalid bit depth="
279 << base::strict_cast<int>(curr_frame_hdr_->bit_depth)
280 << ", profile=" << GetProfileName(new_profile);
281 return kDecodeError;
282 }
Qiu Jianlin2153ac02022-08-18 04:13:15283 VideoChromaSampling new_chroma_sampling =
284 GetVP9ChromaSampling(*curr_frame_hdr_);
285 if (new_chroma_sampling != chroma_sampling_) {
286 chroma_sampling_ = new_chroma_sampling;
287 base::UmaHistogramEnumeration(
288 "Media.PlatformVideoDecoding.ChromaSampling", chroma_sampling_);
289 }
290
291 if (chroma_sampling_ != VideoChromaSampling::k420) {
Hirokazu Honda790d98e2020-12-04 03:41:48292 DVLOG(1) << "Only YUV 4:2:0 is supported";
293 return kDecodeError;
294 }
posciakd94b2b082015-09-18 04:03:40295
Hirokazu Honda436cf27b2019-05-21 10:44:39296 DCHECK(!new_pic_size.IsEmpty());
Miguel Casas2c14d4b2022-11-21 20:50:21297
298 const bool is_pic_size_different = new_pic_size != pic_size_;
299 const bool is_pic_size_larger = new_pic_size.width() > pic_size_.width() ||
300 new_pic_size.height() > pic_size_.height();
301 const bool is_new_configuration_different_enough =
302 (ignore_resolution_changes_to_smaller_ ? is_pic_size_larger
303 : is_pic_size_different) ||
304 new_profile != profile_ || curr_frame_hdr_->bit_depth != bit_depth_;
305
306 if (is_new_configuration_different_enough) {
Hirokazu Honda7ec32652019-11-22 09:40:21307 DVLOG(1) << "New profile: " << GetProfileName(new_profile)
Miguel Casas2c14d4b2022-11-21 20:50:21308 << ", new resolution: " << new_pic_size.ToString()
309 << ", new bit depth: "
Hirokazu Honda963303782020-12-03 05:57:04310 << base::strict_cast<int>(curr_frame_hdr_->bit_depth);
posciakd94b2b082015-09-18 04:03:40311
Sreerenj Balachandran57163302018-11-28 02:45:57312 if (!curr_frame_hdr_->IsKeyframe() &&
Hirokazu Honda7ec32652019-11-22 09:40:21313 !(curr_frame_hdr_->IsIntra() && pic_size_.IsEmpty())) {
posciakd94b2b082015-09-18 04:03:40314 // TODO(posciak): This is doable, but requires a few modifications to
315 // VDA implementations to allow multiple picture buffer sets in flight.
Dongseong Hwang4f20ebb2018-06-07 00:28:20316 // http://crbug.com/832264
Sreerenj Balachandran57163302018-11-28 02:45:57317 DVLOG(1) << "Resolution change currently supported for keyframes and "
318 "sequence begins with Intra only when there is no prior "
319 "frames in the context";
Dongseong Hwang4f20ebb2018-06-07 00:28:20320 if (++size_change_failure_counter_ > kVPxMaxNumOfSizeChangeFailures) {
321 SetError();
322 return kDecodeError;
323 }
324
325 curr_frame_hdr_.reset();
Jeffrey Kardatzke48ebdb692021-01-11 22:05:02326 decrypt_config_.reset();
Dongseong Hwang4f20ebb2018-06-07 00:28:20327 return kRanOutOfStreamData;
posciakd94b2b082015-09-18 04:03:40328 }
329
330 // TODO(posciak): This requires us to be on a keyframe (see above) and is
331 // required, because VDA clients expect all surfaces to be returned before
Hirokazu Honda7ec32652019-11-22 09:40:21332 // they can cycle surface sets after receiving kConfigChange.
posciakd94b2b082015-09-18 04:03:40333 // This is only an implementation detail of VDAs and can be improved.
Sreerenj Balachandran1beb5482019-04-03 03:40:05334 ref_frames_.Clear();
posciakd94b2b082015-09-18 04:03:40335
336 pic_size_ = new_pic_size;
Hirokazu Honda436cf27b2019-05-21 10:44:39337 visible_rect_ = new_render_rect;
Hirokazu Honda7ec32652019-11-22 09:40:21338 profile_ = new_profile;
Hirokazu Honda963303782020-12-03 05:57:04339 bit_depth_ = curr_frame_hdr_->bit_depth;
Dongseong Hwang4f20ebb2018-06-07 00:28:20340 size_change_failure_counter_ = 0;
Hirokazu Honda7ec32652019-11-22 09:40:21341 return kConfigChange;
posciakd94b2b082015-09-18 04:03:40342 }
343
Jeffrey Kardatzke4ed4e332020-12-05 00:32:15344 scoped_refptr<VP9Picture> pic = accelerator_->CreateVP9Picture();
345 if (!pic) {
posciakd94b2b082015-09-18 04:03:40346 return kRanOutOfSurfaces;
Jose Lopes24d1cda82020-02-21 13:22:36347 }
johnylin74410872017-06-19 13:05:30348 DVLOG(2) << "Render resolution: " << new_render_rect.ToString();
349
Jeffrey Kardatzke4ed4e332020-12-05 00:32:15350 pic->set_visible_rect(new_render_rect);
351 pic->set_bitstream_id(stream_id_);
Fredrik Hubinette3cebc622018-10-27 01:01:12352
Jeffrey Kardatzke48ebdb692021-01-11 22:05:02353 pic->set_decrypt_config(std::move(decrypt_config_));
Ted Meyer0b35c5fd2018-11-27 22:29:29354
Fredrik Hubinette3cebc622018-10-27 01:01:12355 // For VP9, container color spaces override video stream color spaces.
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13356 if (container_color_space_.IsSpecified())
Jeffrey Kardatzke4ed4e332020-12-05 00:32:15357 pic->set_colorspace(container_color_space_);
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13358 else if (curr_frame_hdr_)
Jeffrey Kardatzke4ed4e332020-12-05 00:32:15359 pic->set_colorspace(curr_frame_hdr_->GetColorSpace());
posciakd94b2b082015-09-18 04:03:40360
Jeffrey Kardatzke4ed4e332020-12-05 00:32:15361 pic->frame_hdr = std::move(curr_frame_hdr_);
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13362
Jeffrey Kardatzke4ed4e332020-12-05 00:32:15363 VP9Accelerator::Status status = DecodeAndOutputPicture(std::move(pic));
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13364 if (status == VP9Accelerator::Status::kFail) {
posciakd94b2b082015-09-18 04:03:40365 SetError();
366 return kDecodeError;
367 }
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13368 if (status == VP9Accelerator::Status::kTryAgain)
369 return kTryAgain;
posciakd94b2b082015-09-18 04:03:40370 }
371}
372
posciak77118c92016-08-28 13:18:39373void VP9Decoder::UpdateFrameContext(
Ted Meyer4fac4f62019-05-08 22:57:15374 scoped_refptr<VP9Picture> pic,
Jose Lopes24d1cda82020-02-21 13:22:36375 Vp9Parser::ContextRefreshCallback context_refresh_cb) {
Dale Curtise25163812018-09-21 22:13:39376 DCHECK(context_refresh_cb);
posciak77118c92016-08-28 13:18:39377 Vp9FrameContext frame_ctx;
378 memset(&frame_ctx, 0, sizeof(frame_ctx));
379
Ted Meyer4fac4f62019-05-08 22:57:15380 if (!accelerator_->GetFrameContext(std::move(pic), &frame_ctx)) {
posciak77118c92016-08-28 13:18:39381 SetError();
382 return;
383 }
384
Jose Lopes24d1cda82020-02-21 13:22:36385 std::move(context_refresh_cb).Run(frame_ctx);
posciak77118c92016-08-28 13:18:39386}
387
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13388VP9Decoder::VP9Accelerator::Status VP9Decoder::DecodeAndOutputPicture(
389 scoped_refptr<VP9Picture> pic) {
posciakd94b2b082015-09-18 04:03:40390 DCHECK(!pic_size_.IsEmpty());
391 DCHECK(pic->frame_hdr);
392
Chih-Yu Huangcc6b1b92019-12-19 08:57:16393 base::OnceClosure done_cb;
Jose Lopes24d1cda82020-02-21 13:22:36394 Vp9Parser::ContextRefreshCallback context_refresh_cb =
posciak77118c92016-08-28 13:18:39395 parser_.GetContextRefreshCb(pic->frame_hdr->frame_context_idx);
Jose Lopes24d1cda82020-02-21 13:22:36396 if (context_refresh_cb) {
397 done_cb =
398 base::BindOnce(&VP9Decoder::UpdateFrameContext, base::Unretained(this),
399 pic, std::move(context_refresh_cb));
400 }
posciak77118c92016-08-28 13:18:39401
402 const Vp9Parser::Context& context = parser_.context();
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13403 VP9Accelerator::Status status = accelerator_->SubmitDecode(
404 pic, context.segmentation(), context.loop_filter(), ref_frames_,
405 std::move(done_cb));
Jeffrey Kardatzke4ed4e332020-12-05 00:32:15406 if (status != VP9Accelerator::Status::kOk) {
407 if (status == VP9Accelerator::Status::kTryAgain)
408 pending_pic_ = std::move(pic);
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13409 return status;
Jeffrey Kardatzke4ed4e332020-12-05 00:32:15410 }
posciakd94b2b082015-09-18 04:03:40411
412 if (pic->frame_hdr->show_frame) {
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13413 if (!accelerator_->OutputPicture(pic))
414 return VP9Accelerator::Status::kFail;
posciakd94b2b082015-09-18 04:03:40415 }
416
Ted Meyer4fac4f62019-05-08 22:57:15417 ref_frames_.Refresh(std::move(pic));
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13418 return status;
posciakd94b2b082015-09-18 04:03:40419}
420
421void VP9Decoder::SetError() {
422 Reset();
423 state_ = kError;
424}
425
426gfx::Size VP9Decoder::GetPicSize() const {
427 return pic_size_;
428}
429
Hirokazu Honda436cf27b2019-05-21 10:44:39430gfx::Rect VP9Decoder::GetVisibleRect() const {
431 return visible_rect_;
432}
433
Hirokazu Honda7ec32652019-11-22 09:40:21434VideoCodecProfile VP9Decoder::GetProfile() const {
435 return profile_;
436}
437
Hirokazu Honda963303782020-12-03 05:57:04438uint8_t VP9Decoder::GetBitDepth() const {
439 return bit_depth_;
440}
441
Qiu Jianlina790b3d2022-07-29 03:09:44442VideoChromaSampling VP9Decoder::GetChromaSampling() const {
Qiu Jianlin2153ac02022-08-18 04:13:15443 return chroma_sampling_;
Qiu Jianlina790b3d2022-07-29 03:09:44444}
445
Sida Zhuc4276442022-12-03 03:54:24446absl::optional<gfx::HDRMetadata> VP9Decoder::GetHDRMetadata() const {
447 // VP9 only allow HDR metadata exists in the container.
448 return absl::nullopt;
449}
450
posciakd94b2b082015-09-18 04:03:40451size_t VP9Decoder::GetRequiredNumOfPictures() const {
Miguel Casas477a7062019-01-04 19:13:45452 constexpr size_t kPicsInPipeline = limits::kMaxVideoFrames + 1;
453 return kPicsInPipeline + GetNumReferenceFrames();
454}
455
456size_t VP9Decoder::GetNumReferenceFrames() const {
Miguel Casas3dd7e562019-02-14 17:38:46457 // Maximum number of reference frames
458 return kVp9NumRefFrames;
posciakd94b2b082015-09-18 04:03:40459}
460
markdittmer6e70beb82016-05-02 05:40:47461} // namespace media