blob: 8816c5d83aeff41a5b6cfe19e2d069794b80fc95 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/gpu/vaapi/vp8_vaapi_video_decoder_delegate.h"
#include "base/callback_helpers.h"
#include "base/trace_event/trace_event.h"
#include "media/gpu/decode_surface_handler.h"
#include "media/gpu/vaapi/va_surface.h"
#include "media/gpu/vaapi/vaapi_common.h"
#include "media/gpu/vaapi/vaapi_utils.h"
#include "media/gpu/vaapi/vaapi_wrapper.h"
namespace media {
VP8VaapiVideoDecoderDelegate::VP8VaapiVideoDecoderDelegate(
DecodeSurfaceHandler<VASurface>* const vaapi_dec,
scoped_refptr<VaapiWrapper> vaapi_wrapper)
: VaapiVideoDecoderDelegate(vaapi_dec,
std::move(vaapi_wrapper),
base::DoNothing(),
nullptr) {}
VP8VaapiVideoDecoderDelegate::~VP8VaapiVideoDecoderDelegate() {
DCHECK(!iq_matrix_);
DCHECK(!prob_buffer_);
DCHECK(!picture_params_);
DCHECK(!slice_params_);
}
scoped_refptr<VP8Picture> VP8VaapiVideoDecoderDelegate::CreateVP8Picture() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
const auto va_surface = vaapi_dec_->CreateSurface();
if (!va_surface)
return nullptr;
return new VaapiVP8Picture(std::move(va_surface));
}
bool VP8VaapiVideoDecoderDelegate::SubmitDecode(
scoped_refptr<VP8Picture> pic,
const Vp8ReferenceFrameVector& reference_frames) {
TRACE_EVENT0("media,gpu", "VP8VaapiVideoDecoderDelegate::SubmitDecode");
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
const auto va_surface_id = pic->AsVaapiVP8Picture()->va_surface()->id();
DCHECK_NE(va_surface_id, VA_INVALID_SURFACE);
VAIQMatrixBufferVP8 iq_matrix_buf{};
VAProbabilityDataBufferVP8 prob_buf{};
VAPictureParameterBufferVP8 pic_param{};
VASliceParameterBufferVP8 slice_param{};
const Vp8FrameHeader* const header = pic->frame_hdr.get();
DCHECK(header);
FillVP8DataStructures(*header, reference_frames, &iq_matrix_buf, &prob_buf,
&pic_param, &slice_param);
if (!iq_matrix_) {
iq_matrix_ = vaapi_wrapper_->CreateVABuffer(VAIQMatrixBufferType,
sizeof(iq_matrix_buf));
if (!iq_matrix_)
return false;
}
if (!prob_buffer_) {
prob_buffer_ = vaapi_wrapper_->CreateVABuffer(VAProbabilityBufferType,
sizeof(prob_buf));
if (!prob_buffer_)
return false;
}
if (!picture_params_) {
picture_params_ = vaapi_wrapper_->CreateVABuffer(
VAPictureParameterBufferType, sizeof(pic_param));
if (!picture_params_)
return false;
}
if (!slice_params_) {
slice_params_ = vaapi_wrapper_->CreateVABuffer(VASliceParameterBufferType,
sizeof(slice_param));
if (!slice_params_)
return false;
}
// |encoded_data| cannot be reused even when it's of the appropriate size, due
// to strange stutterings in e.g. Gen 9.5.
std::unique_ptr<ScopedVABuffer> encoded_data =
vaapi_wrapper_->CreateVABuffer(VASliceDataBufferType, header->frame_size);
if (!encoded_data)
return false;
return vaapi_wrapper_->MapAndCopyAndExecute(
va_surface_id,
{{iq_matrix_->id(),
{iq_matrix_->type(), iq_matrix_->size(), &iq_matrix_buf}},
{prob_buffer_->id(),
{prob_buffer_->type(), prob_buffer_->size(), &prob_buf}},
{picture_params_->id(),
{picture_params_->type(), picture_params_->size(), &pic_param}},
{slice_params_->id(),
{slice_params_->type(), slice_params_->size(), &slice_param}},
{encoded_data->id(),
{encoded_data->type(), header->frame_size, header->data}}});
}
bool VP8VaapiVideoDecoderDelegate::OutputPicture(
scoped_refptr<VP8Picture> pic) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
const VaapiVP8Picture* vaapi_pic = pic->AsVaapiVP8Picture();
vaapi_dec_->SurfaceReady(vaapi_pic->va_surface(), vaapi_pic->bitstream_id(),
vaapi_pic->visible_rect(),
vaapi_pic->get_colorspace());
return true;
}
void VP8VaapiVideoDecoderDelegate::OnVAContextDestructionSoon() {
// Destroy the member ScopedVABuffers below since they refer to a VAContextID
// that will be destroyed soon.
iq_matrix_.reset();
prob_buffer_.reset();
picture_params_.reset();
slice_params_.reset();
}
} // namespace media