blob: 0c56f851ddfd8486687eece27042950866986109 [file] [log] [blame]
// Copyright 2021 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_VAAPI_TEST_AV1_DECODER_H_
#define MEDIA_GPU_VAAPI_TEST_AV1_DECODER_H_
#include <memory>
#include <vector>
#include "media/filters/ivf_parser.h"
#include "media/gpu/vaapi/test/video_decoder.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
// For libgav1::ObuSequenceHeader. absl::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 media {
namespace vaapi_test {
class ScopedVAConfig;
class ScopedVAContext;
class SharedVASurface;
class VaapiDevice;
constexpr size_t kAv1NumRefFrames = libgav1::kNumReferenceFrameTypes;
// An Av1Decoder decodes AV1-encoded IVF streams using direct libva calls.
class Av1Decoder : public VideoDecoder {
public:
Av1Decoder(std::unique_ptr<IvfParser> ivf_parser,
const VaapiDevice& va_device,
SharedVASurface::FetchPolicy fetch_policy);
Av1Decoder(const Av1Decoder&) = delete;
Av1Decoder& operator=(const Av1Decoder&) = delete;
~Av1Decoder() override;
// VideoDecoder implementation.
VideoDecoder::Result DecodeNextFrame() override;
private:
enum class ParsingResult {
kFailed,
kOk,
kEOStream,
};
// Reads an OBU frame, if there is one available.
// If an |obu_parser_| didn't exist and there is data to be read,
// |obu_parser_| will be created. If there is an existing
// |current_sequence_header_|, this will be passed to the ObuParser that is
// created. If successful (indicated by returning VideoDecoder::kOk), then the
// fields |ivf_frame_header_|, |ivf_frame_data_|, and |current_frame_| will be
// set upon completion.
ParsingResult ReadNextFrame(libgav1::RefCountedBufferPtr& current_frame);
// Refreshes current |ref_frames_| to refer to |surface|, |display_surfaces_|
// to refer to |display_surface|, and |state_| to refer to |current_frame|
// according to |refresh_frame_flags|.
void RefreshReferenceSlots(uint8_t refresh_frame_flags,
scoped_refptr<SharedVASurface> surface,
libgav1::RefCountedBufferPtr current_frame,
scoped_refptr<SharedVASurface> display_surface);
IvfFrameHeader ivf_frame_header_{};
const uint8_t* ivf_frame_data_ = nullptr;
// VA handles.
std::unique_ptr<ScopedVAConfig> va_config_;
std::unique_ptr<ScopedVAContext> va_context_;
// AV1-specific data.
std::unique_ptr<libgav1::ObuParser> obu_parser_;
std::unique_ptr<libgav1::BufferPool> buffer_pool_;
std::unique_ptr<libgav1::DecoderState> state_;
absl::optional<libgav1::ObuSequenceHeader> current_sequence_header_;
std::vector<scoped_refptr<SharedVASurface>> ref_frames_;
// If film grain is applied, the film grain surface is stored in
// |display_surfaces_|. Otherwise, matches |ref_frames_|.
std::vector<scoped_refptr<SharedVASurface>> display_surfaces_;
};
} // namespace vaapi_test
} // namespace media
#endif // MEDIA_GPU_VAAPI_TEST_AV1_DECODER_H_