blob: 274be751220d21f969f76c550edc045bb5a2336d [file] [log] [blame]
// Copyright 2018 The Fuchsia 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 SRC_MEDIA_DRIVERS_AMLOGIC_DECODER_H264_DECODER_H_
#define SRC_MEDIA_DRIVERS_AMLOGIC_DECODER_H264_DECODER_H_
#include <vector>
#include <ddk/io-buffer.h>
#include "registers.h"
#include "src/media/lib/internal_buffer/internal_buffer.h"
#include "video_decoder.h"
class H264Decoder : public VideoDecoder {
public:
// This is the state of the actual firmware.
enum class DecoderState {
// Decoder is in a state ready to decode new frames.
kRunning,
// Decoder is paused waiting for reference frame canvases to be initialized.
kWaitingForNewFrames,
};
H264Decoder(Owner* owner, Client* client, bool is_secure)
: VideoDecoder(
// Unspecified because we don't need metrics from this decoder, as this decoder is only
// retained for problem diagnosis purposes (when diagnosing problems with the h264 multi
// decoder).
media_metrics::StreamProcessorEvents2MetricDimensionImplementation_Unspecified, owner,
client, is_secure) {
constexpr uint32_t kStreamOffsetBitWidth = 28;
pts_manager_->SetLookupBitWidth(kStreamOffsetBitWidth);
power_ref_ = std::make_unique<PowerReference>(owner_->vdec1_core());
}
~H264Decoder() override;
zx_status_t Initialize() override;
void HandleInterrupt() override;
// All H264Decoder errors require creating a new H264Decoder to recover.
void CallErrorHandler() override { client_->OnError(); }
void ReturnFrame(std::shared_ptr<VideoFrame> frame) override;
void InitializedFrames(std::vector<CodecFrame> frames, uint32_t width, uint32_t height,
uint32_t stride) override;
private:
struct ReferenceFrame {
std::shared_ptr<VideoFrame> frame;
std::unique_ptr<CanvasEntry> y_canvas;
std::unique_ptr<CanvasEntry> uv_canvas;
};
zx_status_t ResetHardware();
zx_status_t LoadSecondaryFirmware(const uint8_t* data, uint32_t firmware_size);
zx_status_t InitializeFrames(uint32_t min_frame_count, uint32_t max_frame_count, uint32_t width,
uint32_t height, uint32_t display_width, uint32_t display_height,
bool has_sar, uint32_t sar_width, uint32_t sar_height);
zx_status_t InitializeStream();
void ReceivedFrames(uint32_t frame_count);
void SwitchStreams();
void TryReturnFrames();
void OnFatalError();
std::unique_ptr<PowerReference> power_ref_;
std::optional<InternalBuffer> codec_data_;
std::optional<InternalBuffer> sei_data_buffer_;
std::optional<InternalBuffer> reference_mv_buffer_;
io_buffer_t secondary_firmware_ = {};
// All H264Decoder errors require creating a new H264Decoder to recover.
bool fatal_error_ = false;
DecoderState state_ = DecoderState::kRunning;
// These are set in InitializeFrames for use in InitializedFrames.
// next_mv_buffer_count_ and next_max_dpb_size_ are specified to the firmware, along with the
// actual number of frames. It's not immediately clear why/whether the firmware actually needs
// these in addition to actual number of frames.
uint32_t next_mv_buffer_count_ = 0;
uint32_t next_max_dpb_size_ = 0;
uint32_t display_width_ = 0;
uint32_t display_height_ = 0;
std::vector<ReferenceFrame> video_frames_;
std::vector<std::shared_ptr<VideoFrame>> returned_frames_;
};
#endif // SRC_MEDIA_DRIVERS_AMLOGIC_DECODER_H264_DECODER_H_