mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 08:15:59 -10:00
112 lines
2.5 KiB
C++
112 lines
2.5 KiB
C++
#pragma once
|
|
|
|
#include <functional>
|
|
|
|
#include "libs/ffmpeg/FFmpegHeaders.h"
|
|
|
|
#include "cutscene/Decoder.h"
|
|
|
|
namespace cutscene {
|
|
namespace ffmpeg {
|
|
struct CodecContextParameters {
|
|
int width = -1;
|
|
int height = -1;
|
|
AVPixelFormat pixel_format = AV_PIX_FMT_NONE;
|
|
|
|
uint64_t channel_layout = 0;
|
|
int sample_rate = -1;
|
|
AVSampleFormat audio_format = AV_SAMPLE_FMT_NONE;
|
|
|
|
AVCodecID codec_id = AV_CODEC_ID_NONE;
|
|
};
|
|
|
|
struct DecoderStatus {
|
|
int videoStreamIndex = -1;
|
|
AVStream* videoStream = nullptr;
|
|
CodecContextParameters videoCodecPars;
|
|
const AVCodec* videoCodec = nullptr;
|
|
AVCodecContext* videoCodecCtx = nullptr;
|
|
|
|
int audioStreamIndex = -1;
|
|
AVStream* audioStream = nullptr;
|
|
CodecContextParameters audioCodecPars;
|
|
const AVCodec* audioCodec = nullptr;
|
|
AVCodecContext* audioCodecCtx = nullptr;
|
|
|
|
// Subtitles are a bit different since they max come from a different file
|
|
bool externalSubtitles = false;
|
|
int subtitleStreamIndex = -1;
|
|
AVStream* subtitleStream = nullptr;
|
|
CodecContextParameters subtitleCodecPars;
|
|
const AVCodec* subtitleCodec = nullptr;
|
|
AVCodecContext* subtitleCodecCtx = nullptr;
|
|
|
|
DecoderStatus();
|
|
|
|
~DecoderStatus();
|
|
|
|
DecoderStatus(const DecoderStatus&) = delete;
|
|
DecoderStatus& operator=(const DecoderStatus&) = delete;
|
|
};
|
|
|
|
template<typename Frame>
|
|
class FFMPEGStreamDecoder {
|
|
protected:
|
|
typedef Frame frame_type;
|
|
|
|
DecoderStatus* m_status = nullptr;
|
|
|
|
AVFrame* m_decodeFrame = nullptr;
|
|
|
|
SCP_queue<FramePtr<frame_type>> m_decodedFrames;
|
|
|
|
void pushFrame(FramePtr<frame_type>&& frame);
|
|
public:
|
|
explicit FFMPEGStreamDecoder(DecoderStatus* status);
|
|
virtual ~FFMPEGStreamDecoder();
|
|
|
|
FFMPEGStreamDecoder(const FFMPEGStreamDecoder&) = delete;
|
|
FFMPEGStreamDecoder& operator=(const FFMPEGStreamDecoder&) = delete;
|
|
|
|
virtual void decodePacket(AVPacket* packet) = 0;
|
|
|
|
virtual void finishDecoding() = 0;
|
|
|
|
virtual void flushBuffers() = 0;
|
|
|
|
virtual FramePtr<frame_type> getFrame();
|
|
};
|
|
|
|
template <typename Frame>
|
|
void FFMPEGStreamDecoder<Frame>::pushFrame(FramePtr<frame_type>&& frame)
|
|
{
|
|
m_decodedFrames.push(std::move(frame));
|
|
}
|
|
|
|
template <typename Frame>
|
|
FFMPEGStreamDecoder<Frame>::FFMPEGStreamDecoder(DecoderStatus* status):m_status(status)
|
|
{
|
|
m_decodeFrame = av_frame_alloc();
|
|
}
|
|
|
|
template <typename Frame>
|
|
FFMPEGStreamDecoder<Frame>::~FFMPEGStreamDecoder()
|
|
{
|
|
av_frame_free(&m_decodeFrame);
|
|
}
|
|
|
|
template <typename Frame>
|
|
FramePtr<typename FFMPEGStreamDecoder<Frame>::frame_type> FFMPEGStreamDecoder<Frame>::getFrame()
|
|
{
|
|
if (m_decodedFrames.empty()) {
|
|
return nullptr;
|
|
}
|
|
|
|
auto frame = std::move(m_decodedFrames.front());
|
|
m_decodedFrames.pop();
|
|
|
|
return frame;
|
|
}
|
|
}
|
|
}
|