mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-14 00:09:24 +01:00
Merge pull request #9188 from jordan-woyak/stop-caring-about-old-avcodec-versions
VideoCommon/FrameDump: Remove code for older versions of avcodec.
This commit is contained in:
commit
7f66de062c
@ -33,12 +33,6 @@ extern "C" {
|
|||||||
#include "VideoCommon/OnScreenDisplay.h"
|
#include "VideoCommon/OnScreenDisplay.h"
|
||||||
#include "VideoCommon/VideoConfig.h"
|
#include "VideoCommon/VideoConfig.h"
|
||||||
|
|
||||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55, 28, 1)
|
|
||||||
#define AV_CODEC_FLAG_GLOBAL_HEADER CODEC_FLAG_GLOBAL_HEADER
|
|
||||||
#define av_frame_alloc avcodec_alloc_frame
|
|
||||||
#define av_frame_free avcodec_free_frame
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct FrameDumpContext
|
struct FrameDumpContext
|
||||||
{
|
{
|
||||||
AVFormatContext* format = nullptr;
|
AVFormatContext* format = nullptr;
|
||||||
@ -75,27 +69,12 @@ void InitAVCodec()
|
|||||||
static bool first_run = true;
|
static bool first_run = true;
|
||||||
if (first_run)
|
if (first_run)
|
||||||
{
|
{
|
||||||
#if LIBAVCODEC_VERSION_MICRO >= 100 && LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100)
|
|
||||||
av_register_all();
|
|
||||||
#endif
|
|
||||||
// TODO: We never call avformat_network_deinit.
|
// TODO: We never call avformat_network_deinit.
|
||||||
avformat_network_init();
|
avformat_network_init();
|
||||||
first_run = false;
|
first_run = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AVStreamCopyContext(AVStream* stream, AVCodecContext* codec_context)
|
|
||||||
{
|
|
||||||
#if (LIBAVCODEC_VERSION_MICRO >= 100 && LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 33, 100)) || \
|
|
||||||
(LIBAVCODEC_VERSION_MICRO < 100 && LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 5, 0))
|
|
||||||
|
|
||||||
stream->time_base = codec_context->time_base;
|
|
||||||
return avcodec_parameters_from_context(stream->codecpar, codec_context) >= 0;
|
|
||||||
#else
|
|
||||||
return avcodec_copy_context(stream->codec, codec_context) >= 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GetDumpPath(const std::string& extension, std::time_t time, u32 index)
|
std::string GetDumpPath(const std::string& extension, std::time_t time, u32 index)
|
||||||
{
|
{
|
||||||
if (!g_Config.sDumpPath.empty())
|
if (!g_Config.sDumpPath.empty())
|
||||||
@ -127,52 +106,6 @@ std::string GetDumpPath(const std::string& extension, std::time_t time, u32 inde
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ReceivePacket(AVCodecContext* avctx, AVPacket* pkt, int* got_packet)
|
|
||||||
{
|
|
||||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 37, 100)
|
|
||||||
return avcodec_encode_video2(avctx, pkt, nullptr, got_packet);
|
|
||||||
#else
|
|
||||||
*got_packet = 0;
|
|
||||||
|
|
||||||
const int error = avcodec_receive_packet(avctx, pkt);
|
|
||||||
if (!error)
|
|
||||||
*got_packet = 1;
|
|
||||||
|
|
||||||
if (error == AVERROR(EAGAIN) || error == AVERROR_EOF)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return error;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int SendFrameAndReceivePacket(AVCodecContext* avctx, AVPacket* pkt, AVFrame* frame, int* got_packet)
|
|
||||||
{
|
|
||||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 37, 100)
|
|
||||||
return avcodec_encode_video2(avctx, pkt, frame, got_packet);
|
|
||||||
#else
|
|
||||||
*got_packet = 0;
|
|
||||||
|
|
||||||
const int error = avcodec_send_frame(avctx, frame);
|
|
||||||
if (error)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
return ReceivePacket(avctx, pkt, got_packet);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void WritePacket(AVPacket& pkt, const FrameDumpContext& context)
|
|
||||||
{
|
|
||||||
av_packet_rescale_ts(&pkt, context.codec->time_base, context.stream->time_base);
|
|
||||||
|
|
||||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(56, 60, 100)
|
|
||||||
if (context.codec->coded_frame->key_frame)
|
|
||||||
pkt.flags |= AV_PKT_FLAG_KEY;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pkt.stream_index = context.stream->index;
|
|
||||||
av_interleaved_write_frame(context.format, &pkt);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
bool FrameDump::Start(int w, int h)
|
bool FrameDump::Start(int w, int h)
|
||||||
@ -294,21 +227,19 @@ bool FrameDump::CreateVideoFile()
|
|||||||
m_context->scaled_frame->width = m_context->width;
|
m_context->scaled_frame->width = m_context->width;
|
||||||
m_context->scaled_frame->height = m_context->height;
|
m_context->scaled_frame->height = m_context->height;
|
||||||
|
|
||||||
#if LIBAVCODEC_VERSION_MAJOR >= 55
|
|
||||||
if (av_frame_get_buffer(m_context->scaled_frame, 1))
|
if (av_frame_get_buffer(m_context->scaled_frame, 1))
|
||||||
return false;
|
return false;
|
||||||
#else
|
|
||||||
if (avcodec_default_get_buffer(m_context->codec, m_context->scaled_frame))
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_context->stream = avformat_new_stream(m_context->format, codec);
|
m_context->stream = avformat_new_stream(m_context->format, codec);
|
||||||
if (!m_context->stream || !AVStreamCopyContext(m_context->stream, m_context->codec))
|
if (!m_context->stream ||
|
||||||
|
avcodec_parameters_from_context(m_context->stream->codecpar, m_context->codec) < 0)
|
||||||
{
|
{
|
||||||
ERROR_LOG(VIDEO, "Could not create stream");
|
ERROR_LOG(VIDEO, "Could not create stream");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_context->stream->time_base = m_context->codec->time_base;
|
||||||
|
|
||||||
NOTICE_LOG(VIDEO, "Opening file %s for dumping", dump_path.c_str());
|
NOTICE_LOG(VIDEO, "Opening file %s for dumping", dump_path.c_str());
|
||||||
if (avio_open(&m_context->format->pb, dump_path.c_str(), AVIO_FLAG_WRITE) < 0 ||
|
if (avio_open(&m_context->format->pb, dump_path.c_str(), AVIO_FLAG_WRITE) < 0 ||
|
||||||
avformat_write_header(m_context->format, nullptr))
|
avformat_write_header(m_context->format, nullptr))
|
||||||
@ -392,45 +323,44 @@ void FrameDump::AddFrame(const FrameData& frame)
|
|||||||
m_context->last_pts = pts;
|
m_context->last_pts = pts;
|
||||||
m_context->scaled_frame->pts = pts;
|
m_context->scaled_frame->pts = pts;
|
||||||
|
|
||||||
// Encode and write the image.
|
if (const int error = avcodec_send_frame(m_context->codec, m_context->scaled_frame))
|
||||||
AVPacket pkt;
|
|
||||||
av_init_packet(&pkt);
|
|
||||||
|
|
||||||
int got_packet = 0;
|
|
||||||
const int error =
|
|
||||||
SendFrameAndReceivePacket(m_context->codec, &pkt, m_context->scaled_frame, &got_packet);
|
|
||||||
|
|
||||||
if (error)
|
|
||||||
{
|
{
|
||||||
ERROR_LOG(VIDEO, "Error while encoding video: %d", error);
|
ERROR_LOG(VIDEO, "Error while encoding video: %d", error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (got_packet)
|
ProcessPackets();
|
||||||
WritePacket(pkt, *m_context);
|
|
||||||
|
|
||||||
HandleDelayedPackets();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrameDump::HandleDelayedPackets()
|
void FrameDump::ProcessPackets()
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
AVPacket pkt;
|
AVPacket pkt;
|
||||||
av_init_packet(&pkt);
|
av_init_packet(&pkt);
|
||||||
|
|
||||||
int got_packet = 0;
|
const int receive_error = avcodec_receive_packet(m_context->codec, &pkt);
|
||||||
const int error = ReceivePacket(m_context->codec, &pkt, &got_packet);
|
|
||||||
if (error)
|
if (receive_error == AVERROR(EAGAIN) || receive_error == AVERROR_EOF)
|
||||||
{
|
{
|
||||||
ERROR_LOG(VIDEO, "Error while encoding delayed frames: %d", error);
|
// We have processed all available packets.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!got_packet)
|
if (receive_error)
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(VIDEO, "Error receiving packet: {}", receive_error);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
WritePacket(pkt, *m_context);
|
av_packet_rescale_ts(&pkt, m_context->codec->time_base, m_context->stream->time_base);
|
||||||
|
pkt.stream_index = m_context->stream->index;
|
||||||
|
|
||||||
|
if (const int write_error = av_interleaved_write_frame(m_context->format, &pkt))
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(VIDEO, "Error writing packet: {}", write_error);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,15 +369,14 @@ void FrameDump::Stop()
|
|||||||
if (!IsStarted())
|
if (!IsStarted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 37, 100)
|
|
||||||
// Signal end of stream to encoder.
|
// Signal end of stream to encoder.
|
||||||
if (const int flush_error = avcodec_send_frame(m_context->codec, nullptr))
|
if (const int flush_error = avcodec_send_frame(m_context->codec, nullptr))
|
||||||
WARN_LOG_FMT(VIDEO, "Error sending flush packet: {}", flush_error);
|
WARN_LOG_FMT(VIDEO, "Error sending flush packet: {}", flush_error);
|
||||||
#endif
|
|
||||||
|
|
||||||
HandleDelayedPackets();
|
ProcessPackets();
|
||||||
av_write_trailer(m_context->format);
|
av_write_trailer(m_context->format);
|
||||||
CloseVideoFile();
|
CloseVideoFile();
|
||||||
|
|
||||||
NOTICE_LOG(VIDEO, "Stopping frame dump");
|
NOTICE_LOG(VIDEO, "Stopping frame dump");
|
||||||
OSD::AddMessage("Stopped dumping frames");
|
OSD::AddMessage("Stopped dumping frames");
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ private:
|
|||||||
bool CreateVideoFile();
|
bool CreateVideoFile();
|
||||||
void CloseVideoFile();
|
void CloseVideoFile();
|
||||||
void CheckForConfigChange(const FrameData&);
|
void CheckForConfigChange(const FrameData&);
|
||||||
void HandleDelayedPackets();
|
void ProcessPackets();
|
||||||
|
|
||||||
#if defined(HAVE_FFMPEG)
|
#if defined(HAVE_FFMPEG)
|
||||||
std::unique_ptr<FrameDumpContext> m_context;
|
std::unique_ptr<FrameDumpContext> m_context;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user