Commit 859da545 authored by Hirokazu Honda's avatar Hirokazu Honda Committed by Commit Bot

media/gpu: Add AcceleratedVideoDecoder for AV1

This CL adds an implementation of AcceleratedVideoDecoder for
AV1, AV1Decoder and a few necessary classes for it. They use
libgav1 parser and structures. Since libgav1 is built in
ChromeOS, AV1Decoder is built for ChromeOS x86 targets only.

Bug: 1029212, 1000988
Test: video_decode_accelerator_tests test-25fps.av1.ivf --use_vd
Test: av1_decoder_unittest
Change-Id: Id9d0be18484006005803ae409e45c2028d44c315
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2397997
Commit-Queue: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: default avatarAndres Calderon Jaramillo <andrescj@chromium.org>
Cr-Commit-Position: refs/heads/master@{#827593}
parent 62693518
......@@ -297,6 +297,7 @@ source_set("common") {
]
}
public_deps = []
deps = [
":buildflags",
"//base",
......@@ -307,6 +308,17 @@ source_set("common") {
"//ui/gfx:memory_buffer",
"//ui/gfx/geometry",
]
if (is_ash && use_vaapi) {
assert(use_libgav1_parser)
sources += [
"av1_decoder.cc",
"av1_decoder.h",
"av1_picture.cc",
"av1_picture.h",
]
public_deps += [ "//third_party/libgav1:libgav1" ]
}
}
source_set("command_buffer_helper") {
......@@ -524,6 +536,12 @@ source_set("unit_tests") {
if (use_v4l2_codec || use_vaapi) {
sources += [ "vp8_decoder_unittest.cc" ]
}
if (is_ash && use_vaapi) {
sources += [ "av1_decoder_unittest.cc" ]
deps += [ "//third_party/ffmpeg" ]
}
if (is_win && enable_library_cdms) {
sources += [
"windows/d3d11_copying_texture_wrapper_unittest.cc",
......
This diff is collapsed.
// Copyright 2020 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.
#ifndef MEDIA_GPU_AV1_DECODER_H_
#define MEDIA_GPU_AV1_DECODER_H_
#include <array>
#include <memory>
#include "base/containers/span.h"
#include "base/macros.h"
#include "base/sequence_checker.h"
#include "media/base/video_codecs.h"
#include "media/base/video_color_space.h"
#include "media/gpu/accelerated_video_decoder.h"
#include "media/gpu/media_gpu_export.h"
#include "third_party/libgav1/src/src/utils/constants.h"
// For libgav1::RefCountedBufferPtr.
#include "third_party/libgav1/src/src/buffer_pool.h"
// For libgav1::ObuSequenceHeader. base::Optional demands ObuSequenceHeader to
// fulfill std::is_trivially_constructible if it is forward-declared. But
// ObuSequenceHeader doesn't.
#include "third_party/libgav1/src/src/obu_parser.h"
namespace libgav1 {
struct DecoderState;
struct ObuFrameHeader;
template <typename T>
class Vector;
} // namespace libgav1
namespace media {
class AV1Picture;
using AV1ReferenceFrameVector =
std::array<scoped_refptr<AV1Picture>, libgav1::kNumReferenceFrameTypes>;
// Clients of this class are expected to pass an AV1 OBU stream and are expected
// to provide an implementation of AV1Accelerator for offloading final steps
// of the decoding process.
//
// This class must be created, called and destroyed on a single thread, and
// does nothing internally on any other thread.
class MEDIA_GPU_EXPORT AV1Decoder : public AcceleratedVideoDecoder {
public:
class MEDIA_GPU_EXPORT AV1Accelerator {
public:
AV1Accelerator() = default;
virtual ~AV1Accelerator() = default;
AV1Accelerator(const AV1Accelerator&) = delete;
AV1Accelerator& operator=(const AV1Accelerator&) = delete;
// Creates an AV1Picture that the AV1Decoder can use to store some of the
// information needed to request accelerated decoding. This picture is later
// passed when calling SubmitDecode() so that the AV1Accelerator can submit
// the decode request to the driver. It may also be stored for use as
// reference to decode other pictures.
// When a picture is no longer needed by the decoder, it will just drop
// its reference to it, and it may do so at any time.
// Note that this may return nullptr if the accelerator is not able to
// provide any new pictures at the given time. The decoder must handle this
// case and treat it as normal, returning kRanOutOfSurfaces from Decode().
virtual scoped_refptr<AV1Picture> CreateAV1Picture(bool apply_grain) = 0;
// Submits |pic| to the driver for accelerated decoding. The following
// parameters are also passed:
// - |sequence_header|: the current OBU sequence header.
// - |ref_frames|: the pictures used as reference for decoding |pic|.
// - |tile_buffers|: tile information.
// - |data|: the entire data of the DecoderBuffer set by
// AV1Decoder::SetStream().
// Note that returning from this method does not mean that the decode
// process is finished, but the caller may drop its references to |pic|
// and |ref_frames| immediately, and |data| does not need to remain valid
// after this method returns.
// Returns true when successful, false otherwise.
virtual bool SubmitDecode(
const AV1Picture& pic,
const libgav1::ObuSequenceHeader& sequence_header,
const AV1ReferenceFrameVector& ref_frames,
const libgav1::Vector<libgav1::TileBuffer>& tile_buffers,
base::span<const uint8_t> data) = 0;
// Schedules output (display) of |pic|.
// Note that returning from this method does not mean that |pic| has already
// been outputted (displayed), but guarantees that all pictures will be
// outputted in the same order as this method was called for them, and that
// they are decoded before outputting (assuming SubmitDecode() has been
// called for them beforehand).
// Returns true when successful, false otherwise.
virtual bool OutputPicture(const AV1Picture& pic) = 0;
};
AV1Decoder(std::unique_ptr<AV1Accelerator> accelerator,
VideoCodecProfile profile);
~AV1Decoder() override;
AV1Decoder(const AV1Decoder&) = delete;
AV1Decoder& operator=(const AV1Decoder&) = delete;
// AcceleratedVideoDecoder implementation.
void SetStream(int32_t id, const DecoderBuffer& decoder_buffer) override;
bool Flush() override WARN_UNUSED_RESULT;
void Reset() override;
DecodeResult Decode() override WARN_UNUSED_RESULT;
gfx::Size GetPicSize() const override;
gfx::Rect GetVisibleRect() const override;
VideoCodecProfile GetProfile() const override;
size_t GetRequiredNumOfPictures() const override;
size_t GetNumReferenceFrames() const override;
private:
// Returns whether the current stream contains a new OBU sequence header.
bool HasNewSequenceHeader() const;
bool DecodeAndOutputPicture(
scoped_refptr<AV1Picture> pic,
const libgav1::Vector<libgav1::TileBuffer>& tile_buffers);
void UpdateReferenceFrames(scoped_refptr<AV1Picture> pic);
void ClearReferenceFrames();
bool CheckAndCleanUpReferenceFrames();
void ClearCurrentFrame();
DecodeResult DecodeInternal();
bool on_error_ = false;
std::unique_ptr<libgav1::BufferPool> buffer_pool_;
std::unique_ptr<libgav1::DecoderState> state_;
std::unique_ptr<libgav1::ObuParser> parser_;
const std::unique_ptr<AV1Accelerator> accelerator_;
AV1ReferenceFrameVector ref_frames_;
base::Optional<libgav1::ObuSequenceHeader> current_sequence_header_;
base::Optional<libgav1::ObuFrameHeader> current_frame_header_;
libgav1::RefCountedBufferPtr current_frame_;
gfx::Rect visible_rect_;
gfx::Size frame_size_;
VideoCodecProfile profile_;
int32_t stream_id_ = 0;
const uint8_t* stream_ = nullptr;
size_t stream_size_ = 0;
SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace media
#endif // MEDIA_GPU_AV1_DECODER_H_
This diff is collapsed.
// Copyright 2020 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/av1_picture.h"
#include <memory>
namespace media {
AV1Picture::AV1Picture() = default;
AV1Picture::~AV1Picture() = default;
scoped_refptr<AV1Picture> AV1Picture::Duplicate() {
scoped_refptr<AV1Picture> dup_pic = CreateDuplicate();
if (!dup_pic)
return nullptr;
// Copy members of AV1Picture and CodecPicture.
// A proper bitstream id is set in AV1Decoder.
// Note that decrypt_config_ is not used in here, so skip copying it.
dup_pic->frame_header = frame_header;
dup_pic->set_bitstream_id(bitstream_id());
dup_pic->set_visible_rect(visible_rect());
dup_pic->set_colorspace(get_colorspace());
return dup_pic;
}
scoped_refptr<AV1Picture> AV1Picture::CreateDuplicate() {
return nullptr;
}
} // namespace media
// Copyright 2020 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.
#ifndef MEDIA_GPU_AV1_PICTURE_H_
#define MEDIA_GPU_AV1_PICTURE_H_
#include <memory>
#include "media/gpu/codec_picture.h"
#include "media/gpu/media_gpu_export.h"
#include "third_party/libgav1/src/src/utils/types.h"
namespace media {
// AV1Picture carries the parsed frame header needed for decoding an AV1 frame.
// It also owns the decoded frame itself.
class MEDIA_GPU_EXPORT AV1Picture : public CodecPicture {
public:
AV1Picture();
AV1Picture(const AV1Picture&) = delete;
AV1Picture& operator=(const AV1Picture&) = delete;
// Create a duplicate instance and copy the data to it. It is used to support
// the AV1 show_existing_frame feature. Return the scoped_refptr pointing to
// the duplicate instance, or nullptr on failure.
scoped_refptr<AV1Picture> Duplicate();
libgav1::ObuFrameHeader frame_header = {};
protected:
~AV1Picture() override;
private:
// Create a duplicate instance.
virtual scoped_refptr<AV1Picture> CreateDuplicate();
};
} // namespace media
#endif // MEDIA_GPU_AV1_PICTURE_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment