blob: 50a3588ce98a7607a31d4c354e2a94a692328b84 [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_BIN_MEDIA_CODECS_SW_FFMPEG_CODEC_ADAPTER_FFMPEG_DECODER_H_
#define GARNET_BIN_MEDIA_CODECS_SW_FFMPEG_CODEC_ADAPTER_FFMPEG_DECODER_H_
#include <threads.h>
#include <optional>
#include <queue>
#include <lib/async-loop/cpp/loop.h>
#include <lib/fxl/synchronization/thread_annotations.h>
#include <lib/media/codec_impl/codec_adapter.h>
#include <lib/media/codec_impl/codec_input_item.h>
#include "avcodec_context.h"
#include "buffer_pool.h"
#include "mpsc_queue.h"
class CodecAdapterFfmpegDecoder : public CodecAdapter {
public:
CodecAdapterFfmpegDecoder(std::mutex& lock,
CodecAdapterEvents* codec_adapter_events);
~CodecAdapterFfmpegDecoder();
bool IsCoreCodecRequiringOutputConfigForFormatDetection() override;
void CoreCodecInit(const fuchsia::media::FormatDetails&
initial_input_format_details) override;
void CoreCodecStartStream() override;
void CoreCodecQueueInputFormatDetails(
const fuchsia::media::FormatDetails& per_stream_override_format_details)
override;
void CoreCodecQueueInputPacket(CodecPacket* packet) override;
void CoreCodecQueueInputEndOfStream() override;
void CoreCodecStopStream() override;
void CoreCodecAddBuffer(CodecPort port, const CodecBuffer* buffer) override;
void CoreCodecConfigureBuffers(
CodecPort port,
const std::vector<std::unique_ptr<CodecPacket>>& packets) override;
void CoreCodecRecycleOutputPacket(CodecPacket* packet) override;
void CoreCodecEnsureBuffersNotConfigured(CodecPort port) override;
std::unique_ptr<const fuchsia::media::StreamOutputConfig>
CoreCodecBuildNewOutputConfig(
uint64_t stream_lifetime_ordinal,
uint64_t new_output_buffer_constraints_version_ordinal,
uint64_t new_output_format_details_version_ordinal,
bool buffer_constraints_action_required) override;
void CoreCodecMidStreamOutputBufferReConfigPrepare() override;
void CoreCodecMidStreamOutputBufferReConfigFinish() override;
private:
// Processes input in a loop. Should only execute on input_processing_thread_.
// Loops for the lifetime of a stream.
void ProcessInputLoop();
// Allocates buffer for a frame for ffmpeg.
int GetBuffer(const AvCodecContext::DecodedOutputInfo& decoded_output_info,
AVCodecContext* avcodec_context, AVFrame* frame, int flags);
// Decodes frames until the decoder is empty.
void DecodeFrames();
void WaitForInputProcessingLoopToEnd();
BlockingMpscQueue<CodecInputItem> input_queue_;
BlockingMpscQueue<CodecPacket*> free_output_packets_;
BufferPool output_buffer_pool_;
std::optional<AvCodecContext::DecodedOutputInfo> decoded_output_info_
FXL_GUARDED_BY(lock_);
// This keeps buffers alive via the decoder's refcount until the client is
// done with them.
std::map<CodecPacket*, AvCodecContext::AVFramePtr> in_use_by_client_
FXL_GUARDED_BY(lock_);
uint64_t input_format_details_version_ordinal_;
async::Loop input_processing_loop_;
thrd_t input_processing_thread_;
std::unique_ptr<AvCodecContext> avcodec_context_;
};
#endif // GARNET_BIN_MEDIA_CODECS_SW_FFMPEG_CODEC_ADAPTER_FFMPEG_DECODER_H_