blob: 8f55fa18218c2ca2d909888cfa5dfc3489858ce8 [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 GARNET_DRIVERS_VIDEO_AMLOGIC_DECODER_AMLOGIC_VIDEO_H_
#define GARNET_DRIVERS_VIDEO_AMLOGIC_DECODER_AMLOGIC_VIDEO_H_
#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/protocol/canvas.h>
#include <ddk/protocol/platform-defs.h>
#include <ddk/protocol/platform-device.h>
#include <zircon/errors.h>
#include <zircon/syscalls.h>
#include <zx/handle.h>
#include <future>
#include <memory>
#include <mutex>
#include <thread>
#include "decoder_core.h"
#include "device_ctx.h"
#include "firmware_blob.h"
#include "lib/fxl/synchronization/thread_annotations.h"
#include "registers.h"
#include "stream_buffer.h"
#include "video_decoder.h"
class AmlogicVideo final : public VideoDecoder::Owner,
public DecoderCore::Owner {
public:
AmlogicVideo();
~AmlogicVideo();
zx_status_t InitRegisters(zx_device_t* parent);
zx_status_t InitDecoder();
// VideoDecoder::Owner implementation.
DosRegisterIo* dosbus() override { return dosbus_.get(); }
zx_handle_t bti() override { return bti_.get(); }
DeviceType device_type() override { return device_type_; }
FirmwareBlob* firmware_blob() override { return firmware_.get(); }
std::unique_ptr<CanvasEntry> ConfigureCanvas(io_buffer_t* io_buffer,
uint32_t offset, uint32_t width,
uint32_t height, uint32_t wrap,
uint32_t blockmode) override;
void FreeCanvas(std::unique_ptr<CanvasEntry> canvas) override;
DecoderCore* core() override { return core_.get(); }
zx_status_t AllocateIoBuffer(io_buffer_t* buffer, size_t size,
uint32_t alignment_log2,
uint32_t flags) override;
PtsManager* pts_manager() override { return pts_manager_.get(); }
// DecoderCore::Owner implementation.
MmioRegisters* mmio() override { return registers_.get(); }
void UngateClocks() override;
void GateClocks() override;
private:
friend class TestH264;
friend class TestMpeg2;
friend class TestVP9;
friend class TestFrameProvider;
friend class CodecAdapterH264;
zx_status_t InitializeStreamBuffer(bool use_parser, uint32_t size);
zx_status_t InitializeEsParser();
zx_status_t ParseVideo(void* data, uint32_t len);
zx_status_t ProcessVideoNoParser(void* data, uint32_t len);
zx_status_t ProcessVideoNoParserAtOffset(void* data, uint32_t len,
uint32_t current_offset);
void InitializeInterrupts();
zx_device_t* parent_ = nullptr;
platform_device_protocol_t pdev_;
canvas_protocol_t canvas_;
DeviceType device_type_ = DeviceType::kUnknown;
io_buffer_t mmio_cbus_ = {};
io_buffer_t mmio_dosbus_ = {};
io_buffer_t mmio_hiubus_ = {};
io_buffer_t mmio_aobus_ = {};
io_buffer_t mmio_dmc_ = {};
std::unique_ptr<CbusRegisterIo> cbus_;
std::unique_ptr<DosRegisterIo> dosbus_;
std::unique_ptr<HiuRegisterIo> hiubus_;
std::unique_ptr<AoRegisterIo> aobus_;
std::unique_ptr<DmcRegisterIo> dmc_;
std::unique_ptr<ResetRegisterIo> reset_;
std::unique_ptr<DemuxRegisterIo> demux_;
std::unique_ptr<ParserRegisterIo> parser_;
std::unique_ptr<MmioRegisters> registers_;
std::unique_ptr<FirmwareBlob> firmware_;
std::unique_ptr<StreamBuffer> stream_buffer_;
// This buffer holds an ES start code that's used to get an interrupt when the
// parser is finished.
io_buffer_t search_pattern_ = {};
zx::handle bti_;
zx::event parser_finished_event_;
zx::handle parser_interrupt_handle_;
zx::handle vdec0_interrupt_handle_;
zx::handle vdec1_interrupt_handle_;
std::thread parser_interrupt_thread_;
std::thread vdec0_interrupt_thread_;
std::thread vdec1_interrupt_thread_;
std::unique_ptr<DecoderCore> core_;
std::unique_ptr<PtsManager> pts_manager_;
std::mutex video_decoder_lock_;
FXL_GUARDED_BY(video_decoder_lock_)
std::unique_ptr<VideoDecoder> video_decoder_;
};
#endif // GARNET_DRIVERS_VIDEO_AMLOGIC_DECODER_AMLOGIC_VIDEO_H_