[go: nahoru, domu]

blob: 021959f1bd565d56109b295ce64507481c97ee47 [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
Hirokazu Honda10df95d2019-07-19 19:31:439#include "base/feature_list.h"
Avi Drissmand70f89a2023-01-11 23:52:5510#include "base/functional/bind.h"
mostynb6682b1c42016-04-19 10:17:3011#include "base/logging.h"
Hirokazu Honda967b9192019-08-27 00:59:4212#include "build/build_config.h"
Yuta Hijikata29f67812020-10-24 01:15:4413#include "build/chromeos_buildflags.h"
posciakd94b2b082015-09-18 04:03:4014#include "media/base/limits.h"
Hirokazu Honda10df95d2019-07-19 19:31:4315#include "media/base/media_switches.h"
mark a. foltz36b42b3962023-10-24 16:58:5116#include "media/base/platform_features.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
Jeffrey Kardatzkea8feeae2023-08-15 20:10:1626 if (!decoder_buffer.has_side_data() ||
27 decoder_buffer.side_data()->spatial_layers.empty()) {
Hirokazu Hondafb2681c2021-10-29 03:53:5928 return true;
Jeffrey Kardatzkea8feeae2023-08-15 20:10:1629 }
Hirokazu Hondafb2681c2021-10-29 03:53:5930
Hirokazu Hondabbf7f402022-04-04 08:13:4931 bool enable_vp9_ksvc =
mark a. foltz36b42b3962023-10-24 16:58:5132 // V4L2 stateless decoder does not support VP9 kSVC streams.
33 // See comments in media::IsVp9kSVCHWDecodingEnabled().
34#if BUILDFLAG(IS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
Hirokazu Hondabbf7f402022-04-04 08:13:4935 false;
Shuhai Pengfe10fd02021-11-11 03:20:5936#else
mark a. foltz36b42b3962023-10-24 16:58:5137 media::IsVp9kSVCHWDecodingEnabled();
38#endif // BUILDFLAG(IS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
Hirokazu Hondabbf7f402022-04-04 08:13:4939
40 if (!enable_vp9_ksvc) {
mark a. foltz36b42b3962023-10-24 16:58:5141 DLOG(ERROR) << "VP9 k-SVC hardware decoding is disabled";
Hirokazu Hondafb2681c2021-10-29 03:53:5942 return false;
Hirokazu Honda10df95d2019-07-19 19:31:4343 }
44
Jeffrey Kardatzkea8feeae2023-08-15 20:10:1645 size_t num_of_layers = decoder_buffer.side_data()->spatial_layers.size();
Hirokazu Honda10df95d2019-07-19 19:31:4346 if (num_of_layers > 3u) {
47 DLOG(WARNING) << "The maximum number of spatial layers in VP9 is three";
Hirokazu Hondafb2681c2021-10-29 03:53:5948 return false;
Hirokazu Honda10df95d2019-07-19 19:31:4349 }
Hirokazu Hondafb2681c2021-10-29 03:53:5950
Jeffrey Kardatzkea8feeae2023-08-15 20:10:1651 frame_sizes = decoder_buffer.side_data()->spatial_layers;
Hirokazu Hondafb2681c2021-10-29 03:53:5952 return true;
Hirokazu Honda10df95d2019-07-19 19:31:4353}
Hirokazu Honda7ec32652019-11-22 09:40:2154
55VideoCodecProfile VP9ProfileToVideoCodecProfile(uint8_t profile) {
56 switch (profile) {
57 case 0:
58 return VP9PROFILE_PROFILE0;
59 case 1:
60 return VP9PROFILE_PROFILE1;
61 case 2:
62 return VP9PROFILE_PROFILE2;
63 case 3:
64 return VP9PROFILE_PROFILE3;
65 default:
66 return VIDEO_CODEC_PROFILE_UNKNOWN;
67 }
68}
69
Hirokazu Honda963303782020-12-03 05:57:0470bool IsValidBitDepth(uint8_t bit_depth, VideoCodecProfile profile) {
71 // Spec 7.2.
72 switch (profile) {
73 case VP9PROFILE_PROFILE0:
74 case VP9PROFILE_PROFILE1:
75 return bit_depth == 8u;
76 case VP9PROFILE_PROFILE2:
77 case VP9PROFILE_PROFILE3:
78 return bit_depth == 10u || bit_depth == 12u;
79 default:
Peter Boström0ce6af602023-05-15 21:27:2480 NOTREACHED_NORETURN();
Hirokazu Honda963303782020-12-03 05:57:0481 }
82}
Hirokazu Honda790d98e2020-12-04 03:41:4883
Qiu Jianlin2153ac02022-08-18 04:13:1584VideoChromaSampling GetVP9ChromaSampling(const Vp9FrameHeader& frame_header) {
85 // Spec section 7.2.2
86 uint8_t subsampling_x = frame_header.subsampling_x;
87 uint8_t subsampling_y = frame_header.subsampling_y;
88 if (subsampling_x == 0 && subsampling_y == 0) {
89 return VideoChromaSampling::k444;
90 } else if (subsampling_x == 1u && subsampling_y == 0u) {
91 return VideoChromaSampling::k422;
92 } else if (subsampling_x == 1u && subsampling_y == 1u) {
93 return VideoChromaSampling::k420;
94 } else {
95 DLOG(WARNING) << "Unknown chroma sampling format.";
96 return VideoChromaSampling::kUnknown;
97 }
Hirokazu Honda790d98e2020-12-04 03:41:4898}
Hirokazu Honda10df95d2019-07-19 19:31:4399} // namespace
100
posciakd94b2b082015-09-18 04:03:40101VP9Decoder::VP9Accelerator::VP9Accelerator() {}
102
103VP9Decoder::VP9Accelerator::~VP9Accelerator() {}
104
Fredrik Hubinette3cebc622018-10-27 01:01:12105VP9Decoder::VP9Decoder(std::unique_ptr<VP9Accelerator> accelerator,
Hirokazu Honda7ec32652019-11-22 09:40:21106 VideoCodecProfile profile,
Drew Davenporteb9cb952023-01-31 00:29:39107 const VideoColorSpace& container_color_space)
posciak77118c92016-08-28 13:18:39108 : state_(kNeedStreamMetadata),
Fredrik Hubinette3cebc622018-10-27 01:01:12109 container_color_space_(container_color_space),
Hirokazu Honda7ec32652019-11-22 09:40:21110 // TODO(hiroh): Set profile to UNKNOWN.
111 profile_(profile),
Miguel Casas2d5ecad82018-02-22 19:03:05112 accelerator_(std::move(accelerator)),
Fritz Koeniga10f1e82023-11-01 20:41:30113 parser_(accelerator_->NeedsCompressedHeaderParsed()) {}
posciakd94b2b082015-09-18 04:03:40114
Miguel Casas2d5ecad82018-02-22 19:03:05115VP9Decoder::~VP9Decoder() = default;
posciakd94b2b082015-09-18 04:03:40116
Hirokazu Honda23132c32019-07-09 14:31:20117void VP9Decoder::SetStream(int32_t id, const DecoderBuffer& decoder_buffer) {
118 const uint8_t* ptr = decoder_buffer.data();
119 const size_t size = decoder_buffer.data_size();
120 const DecryptConfig* decrypt_config = decoder_buffer.decrypt_config();
121
posciakd94b2b082015-09-18 04:03:40122 DCHECK(ptr);
123 DCHECK(size);
Pawel Osciakec6e21b2018-03-19 09:13:06124 DVLOG(4) << "New input stream id: " << id << " at: " << (void*)ptr
125 << " size: " << size;
126 stream_id_ = id;
Hirokazu Hondafb2681c2021-10-29 03:53:59127 std::vector<uint32_t> frame_sizes;
128 if (!GetSpatialLayerFrameSize(decoder_buffer, frame_sizes)) {
129 SetError();
130 return;
Ted Meyer0b35c5fd2018-11-27 22:29:29131 }
Hirokazu Hondafb2681c2021-10-29 03:53:59132
133 parser_.SetStream(ptr, size, frame_sizes,
134 decrypt_config ? decrypt_config->Clone() : nullptr);
posciakd94b2b082015-09-18 04:03:40135}
136
137bool VP9Decoder::Flush() {
138 DVLOG(2) << "Decoder flush";
139 Reset();
140 return true;
141}
142
143void VP9Decoder::Reset() {
144 curr_frame_hdr_ = nullptr;
Jeffrey Kardatzke48ebdb692021-01-11 22:05:02145 decrypt_config_.reset();
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13146 pending_pic_.reset();
Sreerenj Balachandran1beb5482019-04-03 03:40:05147
148 ref_frames_.Clear();
posciakd94b2b082015-09-18 04:03:40149
150 parser_.Reset();
151
Jose Lopes24d1cda82020-02-21 13:22:36152 if (state_ == kDecoding) {
posciakd94b2b082015-09-18 04:03:40153 state_ = kAfterReset;
Jose Lopes24d1cda82020-02-21 13:22:36154 }
posciakd94b2b082015-09-18 04:03:40155}
156
157VP9Decoder::DecodeResult VP9Decoder::Decode() {
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13158 while (true) {
Hirokazu Hondafb2681c2021-10-29 03:53:59159 if (state_ == kError)
160 return kDecodeError;
161
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13162 // If we have a pending picture to decode, try that first.
163 if (pending_pic_) {
Jeffrey Kardatzke4ed4e332020-12-05 00:32:15164 VP9Accelerator::Status status =
165 DecodeAndOutputPicture(std::move(pending_pic_));
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13166 if (status == VP9Accelerator::Status::kFail) {
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13167 SetError();
168 return kDecodeError;
169 }
170 if (status == VP9Accelerator::Status::kTryAgain)
171 return kTryAgain;
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13172 }
173
posciakd94b2b082015-09-18 04:03:40174 // Read a new frame header if one is not awaiting decoding already.
175 if (!curr_frame_hdr_) {
Hirokazu Honda10df95d2019-07-19 19:31:43176 gfx::Size allocate_size;
xhwang60f96672016-06-14 21:47:53177 std::unique_ptr<Vp9FrameHeader> hdr(new Vp9FrameHeader());
Ted Meyer0b35c5fd2018-11-27 22:29:29178 Vp9Parser::Result res =
Jeffrey Kardatzke48ebdb692021-01-11 22:05:02179 parser_.ParseNextFrame(hdr.get(), &allocate_size, &decrypt_config_);
posciakd94b2b082015-09-18 04:03:40180 switch (res) {
xhwang60f96672016-06-14 21:47:53181 case Vp9Parser::kOk:
brusi_roy8e7155962016-09-14 18:22:58182 curr_frame_hdr_ = std::move(hdr);
Hirokazu Honda10df95d2019-07-19 19:31:43183 curr_frame_size_ = allocate_size;
posciakd94b2b082015-09-18 04:03:40184 break;
185
xhwang60f96672016-06-14 21:47:53186 case Vp9Parser::kEOStream:
posciakd94b2b082015-09-18 04:03:40187 return kRanOutOfStreamData;
188
xhwang60f96672016-06-14 21:47:53189 case Vp9Parser::kInvalidStream:
posciakd94b2b082015-09-18 04:03:40190 DVLOG(1) << "Error parsing stream";
191 SetError();
192 return kDecodeError;
kcwue5a9a6292016-08-17 03:40:02193
194 case Vp9Parser::kAwaitingRefresh:
posciak77118c92016-08-28 13:18:39195 DVLOG(4) << "Awaiting context update";
196 return kNeedContextUpdate;
posciakd94b2b082015-09-18 04:03:40197 }
198 }
199
200 if (state_ != kDecoding) {
201 // Not kDecoding, so we need a resume point (a keyframe), as we are after
202 // reset or at the beginning of the stream. Drop anything that is not
203 // a keyframe in such case, and continue looking for a keyframe.
Sreerenj Balachandran57163302018-11-28 02:45:57204 // Only exception is when the stream/sequence starts with an Intra only
205 // frame.
206 if (curr_frame_hdr_->IsKeyframe() ||
207 (curr_frame_hdr_->IsIntra() && pic_size_.IsEmpty())) {
posciakd94b2b082015-09-18 04:03:40208 state_ = kDecoding;
209 } else {
210 curr_frame_hdr_.reset();
Jeffrey Kardatzke48ebdb692021-01-11 22:05:02211 decrypt_config_.reset();
posciakd94b2b082015-09-18 04:03:40212 continue;
213 }
214 }
215
216 if (curr_frame_hdr_->show_existing_frame) {
217 // This frame header only instructs us to display one of the
218 // previously-decoded frames, but has no frame data otherwise. Display
219 // and continue decoding subsequent frames.
kcwue5a9a6292016-08-17 03:40:02220 size_t frame_to_show = curr_frame_hdr_->frame_to_show_map_idx;
Sreerenj Balachandran1beb5482019-04-03 03:40:05221 if (frame_to_show >= kVp9NumRefFrames ||
222 !ref_frames_.GetFrame(frame_to_show)) {
posciakd94b2b082015-09-18 04:03:40223 DVLOG(1) << "Request to show an invalid frame";
224 SetError();
225 return kDecodeError;
226 }
227
Chih-Yu Huangcd5181e2018-10-23 06:33:06228 // Duplicate the VP9Picture and set the current bitstream id to keep the
229 // correct timestamp.
Sreerenj Balachandran1beb5482019-04-03 03:40:05230 scoped_refptr<VP9Picture> pic =
231 ref_frames_.GetFrame(frame_to_show)->Duplicate();
Chih-Yu Huangcd5181e2018-10-23 06:33:06232 pic->set_bitstream_id(stream_id_);
Dan Sanders9d1177622023-08-15 19:39:11233 pic->frame_hdr = std::move(curr_frame_hdr_);
Chih-Yu Huangcd5181e2018-10-23 06:33:06234 if (!accelerator_->OutputPicture(std::move(pic))) {
posciakd94b2b082015-09-18 04:03:40235 SetError();
236 return kDecodeError;
237 }
238
Jeffrey Kardatzke48ebdb692021-01-11 22:05:02239 decrypt_config_.reset();
posciakd94b2b082015-09-18 04:03:40240 continue;
241 }
242
Hirokazu Honda10df95d2019-07-19 19:31:43243 gfx::Size new_pic_size = curr_frame_size_;
Hirokazu Honda436cf27b2019-05-21 10:44:39244 gfx::Rect new_render_rect(curr_frame_hdr_->render_width,
245 curr_frame_hdr_->render_height);
Hirokazu Hondacffd0ef2020-02-28 03:32:31246 // For safety, check the validity of render size or leave it as pic size.
Hirokazu Honda436cf27b2019-05-21 10:44:39247 if (!gfx::Rect(new_pic_size).Contains(new_render_rect)) {
248 DVLOG(1) << "Render size exceeds picture size. render size: "
249 << new_render_rect.ToString()
250 << ", picture size: " << new_pic_size.ToString();
Hirokazu Hondacffd0ef2020-02-28 03:32:31251 new_render_rect = gfx::Rect(new_pic_size);
Hirokazu Honda436cf27b2019-05-21 10:44:39252 }
Hirokazu Honda7ec32652019-11-22 09:40:21253 VideoCodecProfile new_profile =
254 VP9ProfileToVideoCodecProfile(curr_frame_hdr_->profile);
255 if (new_profile == VIDEO_CODEC_PROFILE_UNKNOWN) {
256 VLOG(1) << "Invalid profile: " << curr_frame_hdr_->profile;
257 return kDecodeError;
258 }
Hirokazu Honda963303782020-12-03 05:57:04259 if (!IsValidBitDepth(curr_frame_hdr_->bit_depth, new_profile)) {
260 DVLOG(1) << "Invalid bit depth="
261 << base::strict_cast<int>(curr_frame_hdr_->bit_depth)
262 << ", profile=" << GetProfileName(new_profile);
263 return kDecodeError;
264 }
Qiu Jianlin2153ac02022-08-18 04:13:15265 VideoChromaSampling new_chroma_sampling =
266 GetVP9ChromaSampling(*curr_frame_hdr_);
267 if (new_chroma_sampling != chroma_sampling_) {
268 chroma_sampling_ = new_chroma_sampling;
Qiu Jianlin2153ac02022-08-18 04:13:15269 }
270
271 if (chroma_sampling_ != VideoChromaSampling::k420) {
Hirokazu Honda790d98e2020-12-04 03:41:48272 DVLOG(1) << "Only YUV 4:2:0 is supported";
273 return kDecodeError;
274 }
posciakd94b2b082015-09-18 04:03:40275
Saifuddin Hitawalae2e6d482023-05-31 19:33:28276 VideoColorSpace new_color_space;
277 // For VP9, container color spaces override video stream color spaces.
278 if (container_color_space_.IsSpecified()) {
279 new_color_space = container_color_space_;
280 } else if (curr_frame_hdr_->GetColorSpace().IsSpecified()) {
281 new_color_space = curr_frame_hdr_->GetColorSpace();
282 }
283
Hirokazu Honda436cf27b2019-05-21 10:44:39284 DCHECK(!new_pic_size.IsEmpty());
Miguel Casasc4d75842023-04-25 04:37:00285
Dale Curtis7164e402023-10-10 22:18:03286 bool is_color_space_change = false;
287 if (base::FeatureList::IsEnabled(kAVDColorSpaceChanges)) {
288 is_color_space_change = new_color_space.IsSpecified() &&
289 new_color_space != picture_color_space_;
290 }
291
Miguel Casasc4d75842023-04-25 04:37:00292 const bool is_pic_size_different = new_pic_size != pic_size_;
293 const bool is_pic_size_larger = new_pic_size.width() > pic_size_.width() ||
294 new_pic_size.height() > pic_size_.height();
295 const bool is_new_configuration_different_enough =
296 (ignore_resolution_changes_to_smaller_for_testing_
297 ? is_pic_size_larger
298 : is_pic_size_different) ||
Dale Curtis7164e402023-10-10 22:18:03299 new_profile != profile_ || curr_frame_hdr_->bit_depth != bit_depth_ ||
300 is_color_space_change;
Miguel Casasc4d75842023-04-25 04:37:00301
302 if (is_new_configuration_different_enough) {
Hirokazu Honda7ec32652019-11-22 09:40:21303 DVLOG(1) << "New profile: " << GetProfileName(new_profile)
Miguel Casasc4d75842023-04-25 04:37:00304 << ", new resolution: " << new_pic_size.ToString()
305 << ", new bit depth: "
Dale Curtis7164e402023-10-10 22:18:03306 << base::strict_cast<int>(curr_frame_hdr_->bit_depth)
307 << ", new color space: " << new_color_space.ToString();
posciakd94b2b082015-09-18 04:03:40308
Sreerenj Balachandran57163302018-11-28 02:45:57309 if (!curr_frame_hdr_->IsKeyframe() &&
Hirokazu Honda7ec32652019-11-22 09:40:21310 !(curr_frame_hdr_->IsIntra() && pic_size_.IsEmpty())) {
posciakd94b2b082015-09-18 04:03:40311 // TODO(posciak): This is doable, but requires a few modifications to
312 // VDA implementations to allow multiple picture buffer sets in flight.
Dongseong Hwang4f20ebb2018-06-07 00:28:20313 // http://crbug.com/832264
Sreerenj Balachandran57163302018-11-28 02:45:57314 DVLOG(1) << "Resolution change currently supported for keyframes and "
315 "sequence begins with Intra only when there is no prior "
316 "frames in the context";
Dongseong Hwang4f20ebb2018-06-07 00:28:20317 if (++size_change_failure_counter_ > kVPxMaxNumOfSizeChangeFailures) {
318 SetError();
319 return kDecodeError;
320 }
321
322 curr_frame_hdr_.reset();
Jeffrey Kardatzke48ebdb692021-01-11 22:05:02323 decrypt_config_.reset();
Dongseong Hwang4f20ebb2018-06-07 00:28:20324 return kRanOutOfStreamData;
posciakd94b2b082015-09-18 04:03:40325 }
326
327 // TODO(posciak): This requires us to be on a keyframe (see above) and is
328 // required, because VDA clients expect all surfaces to be returned before
Hirokazu Honda7ec32652019-11-22 09:40:21329 // they can cycle surface sets after receiving kConfigChange.
posciakd94b2b082015-09-18 04:03:40330 // This is only an implementation detail of VDAs and can be improved.
Sreerenj Balachandran1beb5482019-04-03 03:40:05331 ref_frames_.Clear();
posciakd94b2b082015-09-18 04:03:40332
333 pic_size_ = new_pic_size;
Hirokazu Honda436cf27b2019-05-21 10:44:39334 visible_rect_ = new_render_rect;
Hirokazu Honda7ec32652019-11-22 09:40:21335 profile_ = new_profile;
Hirokazu Honda963303782020-12-03 05:57:04336 bit_depth_ = curr_frame_hdr_->bit_depth;
Saifuddin Hitawalae2e6d482023-05-31 19:33:28337 picture_color_space_ = new_color_space;
Dongseong Hwang4f20ebb2018-06-07 00:28:20338 size_change_failure_counter_ = 0;
Hirokazu Honda7ec32652019-11-22 09:40:21339 return kConfigChange;
posciakd94b2b082015-09-18 04:03:40340 }
341
Jeffrey Kardatzke4ed4e332020-12-05 00:32:15342 scoped_refptr<VP9Picture> pic = accelerator_->CreateVP9Picture();
343 if (!pic) {
posciakd94b2b082015-09-18 04:03:40344 return kRanOutOfSurfaces;
Jose Lopes24d1cda82020-02-21 13:22:36345 }
johnylin74410872017-06-19 13:05:30346 DVLOG(2) << "Render resolution: " << new_render_rect.ToString();
347
Jeffrey Kardatzke4ed4e332020-12-05 00:32:15348 pic->set_visible_rect(new_render_rect);
349 pic->set_bitstream_id(stream_id_);
Fredrik Hubinette3cebc622018-10-27 01:01:12350
Jeffrey Kardatzke48ebdb692021-01-11 22:05:02351 pic->set_decrypt_config(std::move(decrypt_config_));
Ted Meyer0b35c5fd2018-11-27 22:29:29352
Saifuddin Hitawalae2e6d482023-05-31 19:33:28353 // Set the color space for the picture.
354 pic->set_colorspace(picture_color_space_);
posciakd94b2b082015-09-18 04:03:40355
Jeffrey Kardatzke4ed4e332020-12-05 00:32:15356 pic->frame_hdr = std::move(curr_frame_hdr_);
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13357
Jeffrey Kardatzke4ed4e332020-12-05 00:32:15358 VP9Accelerator::Status status = DecodeAndOutputPicture(std::move(pic));
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13359 if (status == VP9Accelerator::Status::kFail) {
posciakd94b2b082015-09-18 04:03:40360 SetError();
361 return kDecodeError;
362 }
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13363 if (status == VP9Accelerator::Status::kTryAgain)
364 return kTryAgain;
posciakd94b2b082015-09-18 04:03:40365 }
366}
367
posciak77118c92016-08-28 13:18:39368void VP9Decoder::UpdateFrameContext(
Ted Meyer4fac4f62019-05-08 22:57:15369 scoped_refptr<VP9Picture> pic,
Jose Lopes24d1cda82020-02-21 13:22:36370 Vp9Parser::ContextRefreshCallback context_refresh_cb) {
Dale Curtise25163812018-09-21 22:13:39371 DCHECK(context_refresh_cb);
posciak77118c92016-08-28 13:18:39372 Vp9FrameContext frame_ctx;
373 memset(&frame_ctx, 0, sizeof(frame_ctx));
374
Ted Meyer4fac4f62019-05-08 22:57:15375 if (!accelerator_->GetFrameContext(std::move(pic), &frame_ctx)) {
posciak77118c92016-08-28 13:18:39376 SetError();
377 return;
378 }
379
Jose Lopes24d1cda82020-02-21 13:22:36380 std::move(context_refresh_cb).Run(frame_ctx);
posciak77118c92016-08-28 13:18:39381}
382
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13383VP9Decoder::VP9Accelerator::Status VP9Decoder::DecodeAndOutputPicture(
384 scoped_refptr<VP9Picture> pic) {
posciakd94b2b082015-09-18 04:03:40385 DCHECK(!pic_size_.IsEmpty());
386 DCHECK(pic->frame_hdr);
387
Chih-Yu Huangcc6b1b92019-12-19 08:57:16388 base::OnceClosure done_cb;
Jose Lopes24d1cda82020-02-21 13:22:36389 Vp9Parser::ContextRefreshCallback context_refresh_cb =
posciak77118c92016-08-28 13:18:39390 parser_.GetContextRefreshCb(pic->frame_hdr->frame_context_idx);
Jose Lopes24d1cda82020-02-21 13:22:36391 if (context_refresh_cb) {
392 done_cb =
393 base::BindOnce(&VP9Decoder::UpdateFrameContext, base::Unretained(this),
394 pic, std::move(context_refresh_cb));
395 }
posciak77118c92016-08-28 13:18:39396
397 const Vp9Parser::Context& context = parser_.context();
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13398 VP9Accelerator::Status status = accelerator_->SubmitDecode(
399 pic, context.segmentation(), context.loop_filter(), ref_frames_,
400 std::move(done_cb));
Jeffrey Kardatzke4ed4e332020-12-05 00:32:15401 if (status != VP9Accelerator::Status::kOk) {
402 if (status == VP9Accelerator::Status::kTryAgain)
403 pending_pic_ = std::move(pic);
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13404 return status;
Jeffrey Kardatzke4ed4e332020-12-05 00:32:15405 }
posciakd94b2b082015-09-18 04:03:40406
407 if (pic->frame_hdr->show_frame) {
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13408 if (!accelerator_->OutputPicture(pic))
409 return VP9Accelerator::Status::kFail;
posciakd94b2b082015-09-18 04:03:40410 }
411
Ted Meyer4fac4f62019-05-08 22:57:15412 ref_frames_.Refresh(std::move(pic));
Jeffrey Kardatzke5e36baf2020-11-20 22:17:13413 return status;
posciakd94b2b082015-09-18 04:03:40414}
415
416void VP9Decoder::SetError() {
417 Reset();
418 state_ = kError;
419}
420
421gfx::Size VP9Decoder::GetPicSize() const {
422 return pic_size_;
423}
424
Hirokazu Honda436cf27b2019-05-21 10:44:39425gfx::Rect VP9Decoder::GetVisibleRect() const {
426 return visible_rect_;
427}
428
Hirokazu Honda7ec32652019-11-22 09:40:21429VideoCodecProfile VP9Decoder::GetProfile() const {
430 return profile_;
431}
432
Hirokazu Honda963303782020-12-03 05:57:04433uint8_t VP9Decoder::GetBitDepth() const {
434 return bit_depth_;
435}
436
Qiu Jianlina790b3d2022-07-29 03:09:44437VideoChromaSampling VP9Decoder::GetChromaSampling() const {
Qiu Jianlin2153ac02022-08-18 04:13:15438 return chroma_sampling_;
Qiu Jianlina790b3d2022-07-29 03:09:44439}
440
Saifuddin Hitawalae2e6d482023-05-31 19:33:28441VideoColorSpace VP9Decoder::GetVideoColorSpace() const {
442 return picture_color_space_;
443}
444
Sida Zhuc4276442022-12-03 03:54:24445absl::optional<gfx::HDRMetadata> VP9Decoder::GetHDRMetadata() const {
446 // VP9 only allow HDR metadata exists in the container.
447 return absl::nullopt;
448}
449
posciakd94b2b082015-09-18 04:03:40450size_t VP9Decoder::GetRequiredNumOfPictures() const {
Miguel Casas477a7062019-01-04 19:13:45451 constexpr size_t kPicsInPipeline = limits::kMaxVideoFrames + 1;
452 return kPicsInPipeline + GetNumReferenceFrames();
453}
454
455size_t VP9Decoder::GetNumReferenceFrames() const {
Miguel Casas3dd7e562019-02-14 17:38:46456 // Maximum number of reference frames
457 return kVp9NumRefFrames;
posciakd94b2b082015-09-18 04:03:40458}
459
markdittmer6e70beb82016-05-02 05:40:47460} // namespace media