mirror of
https://github.com/PabloMK7/citra.git
synced 2024-12-04 20:04:59 +01:00
FFmpeg: adapt to ffmpeg7 for dumping. (#248)
* FFmpeg: update layout api for ffmpeg 6.x and ffmpeg 7. After ffmpeg 5.1, it is deprecated, and has been completely removed in ffmpeg 7. Our current project is using 6.0 headers, modifying it will not have any side effects. Since lavu 57.24.100(ffmpeg 5.1) * FFmpeg: dynamic_library and dumping adapt to ffmpeg7.1. But keeping support for older versions. * externals/library-headers: update ffmpeg to 7.1
This commit is contained in:
parent
7d00f47c5e
commit
cdce02607a
5 changed files with 64 additions and 15 deletions
2
externals/library-headers
vendored
2
externals/library-headers
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 3b3e28dbe6d033395ce2967fa8030825e7b89de7
|
||||
Subproject commit 9fb99108ee5c630ca365c8fa4a11087b84e1f58b
|
|
@ -27,7 +27,7 @@ static const std::unordered_map<AVOptionType, const char*> TypeNameMap{{
|
|||
{AV_OPT_TYPE_STRING, QT_TR_NOOP("string")},
|
||||
{AV_OPT_TYPE_DICT, QT_TR_NOOP("dictionary")},
|
||||
{AV_OPT_TYPE_VIDEO_RATE, QT_TR_NOOP("video rate")},
|
||||
{AV_OPT_TYPE_CHANNEL_LAYOUT, QT_TR_NOOP("channel layout")},
|
||||
{AV_OPT_TYPE_CHLAYOUT, QT_TR_NOOP("channel layout")},
|
||||
}};
|
||||
|
||||
static const std::unordered_map<AVOptionType, const char*> TypeDescriptionMap{{
|
||||
|
@ -39,7 +39,7 @@ static const std::unordered_map<AVOptionType, const char*> TypeDescriptionMap{{
|
|||
{AV_OPT_TYPE_DICT,
|
||||
QT_TR_NOOP("Comma-splitted list of <key>=<value>. Do not put spaces.")},
|
||||
{AV_OPT_TYPE_VIDEO_RATE, QT_TR_NOOP("<num>/<den>, or preset values like 'pal'.")},
|
||||
{AV_OPT_TYPE_CHANNEL_LAYOUT, QT_TR_NOOP("Hexadecimal channel layout mask starting with '0x'.")},
|
||||
{AV_OPT_TYPE_CHLAYOUT, QT_TR_NOOP("Hexadecimal channel layout mask starting with '0x'.")},
|
||||
}};
|
||||
|
||||
/// Get the preset values of an option. returns {display value, real value}
|
||||
|
|
|
@ -65,6 +65,9 @@ avcodec_find_encoder_by_name_func avcodec_find_encoder_by_name;
|
|||
avcodec_free_context_func avcodec_free_context;
|
||||
avcodec_get_class_func avcodec_get_class;
|
||||
avcodec_get_hw_config_func avcodec_get_hw_config;
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100) // lavc 61.13.100
|
||||
avcodec_get_supported_config_func avcodec_get_supported_config;
|
||||
#endif
|
||||
avcodec_open2_func avcodec_open2;
|
||||
avcodec_parameters_from_context_func avcodec_parameters_from_context;
|
||||
avcodec_receive_frame_func avcodec_receive_frame;
|
||||
|
@ -232,6 +235,9 @@ static bool LoadAVCodec() {
|
|||
LOAD_SYMBOL(avcodec, avcodec_free_context);
|
||||
LOAD_SYMBOL(avcodec, avcodec_get_class);
|
||||
LOAD_SYMBOL(avcodec, avcodec_get_hw_config);
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100) // lavc 61.13.100
|
||||
LOAD_SYMBOL(avcodec, avcodec_get_supported_config);
|
||||
#endif
|
||||
LOAD_SYMBOL(avcodec, avcodec_open2);
|
||||
LOAD_SYMBOL(avcodec, avcodec_parameters_from_context);
|
||||
LOAD_SYMBOL(avcodec, avcodec_receive_frame);
|
||||
|
|
|
@ -114,6 +114,10 @@ typedef const AVCodec* (*avcodec_find_encoder_by_name_func)(const char*);
|
|||
typedef void (*avcodec_free_context_func)(AVCodecContext**);
|
||||
typedef const AVClass* (*avcodec_get_class_func)();
|
||||
typedef const AVCodecHWConfig* (*avcodec_get_hw_config_func)(const AVCodec*, int);
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100) // lavc 61.13.100
|
||||
typedef int (*avcodec_get_supported_config_func)(const AVCodecContext*, const AVCodec*,
|
||||
enum AVCodecConfig, unsigned, const void**, int*);
|
||||
#endif
|
||||
typedef int (*avcodec_open2_func)(AVCodecContext*, const AVCodec*, AVDictionary**);
|
||||
typedef int (*avcodec_parameters_from_context_func)(AVCodecParameters* par, const AVCodecContext*);
|
||||
typedef int (*avcodec_receive_frame_func)(AVCodecContext*, AVFrame*);
|
||||
|
@ -138,6 +142,9 @@ extern avcodec_find_encoder_by_name_func avcodec_find_encoder_by_name;
|
|||
extern avcodec_free_context_func avcodec_free_context;
|
||||
extern avcodec_get_class_func avcodec_get_class;
|
||||
extern avcodec_get_hw_config_func avcodec_get_hw_config;
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100) // lavc 61.13.100
|
||||
extern avcodec_get_supported_config_func avcodec_get_supported_config;
|
||||
#endif
|
||||
extern avcodec_open2_func avcodec_open2;
|
||||
extern avcodec_parameters_from_context_func avcodec_parameters_from_context;
|
||||
extern avcodec_receive_frame_func avcodec_receive_frame;
|
||||
|
|
|
@ -171,12 +171,21 @@ bool FFmpegVideoStream::Init(FFmpegMuxer& muxer, const Layout::FramebufferLayout
|
|||
codec_context->gop_size = 12;
|
||||
|
||||
// Get pixel format for codec
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100) // lavc 61.13.100
|
||||
const enum AVPixelFormat* pix_fmts = NULL;
|
||||
int ret = FFmpeg::avcodec_get_supported_config(NULL, codec, AV_CODEC_CONFIG_PIX_FORMAT, 0,
|
||||
(const void**)&pix_fmts, NULL);
|
||||
#else
|
||||
const enum AVPixelFormat* pix_fmts = codec->pix_fmts;
|
||||
int ret = 0;
|
||||
#endif
|
||||
|
||||
auto options = ToAVDictionary(Settings::values.video_encoder_options);
|
||||
auto pixel_format_opt = FFmpeg::av_dict_get(options, "pixel_format", nullptr, 0);
|
||||
if (pixel_format_opt) {
|
||||
sw_pixel_format = FFmpeg::av_get_pix_fmt(pixel_format_opt->value);
|
||||
} else if (codec->pix_fmts) {
|
||||
sw_pixel_format = GetPixelFormat(codec_context.get(), codec->pix_fmts);
|
||||
} else if (ret >= 0 && pix_fmts) {
|
||||
sw_pixel_format = GetPixelFormat(codec_context.get(), pix_fmts);
|
||||
} else {
|
||||
sw_pixel_format = AV_PIX_FMT_YUV420P;
|
||||
}
|
||||
|
@ -285,11 +294,20 @@ void FFmpegVideoStream::ProcessFrame(VideoFrame& frame) {
|
|||
}
|
||||
|
||||
bool FFmpegVideoStream::InitHWContext(const AVCodec* codec) {
|
||||
for (std::size_t i = 0; codec->pix_fmts[i] != AV_PIX_FMT_NONE; ++i) {
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100) // lavc 61.13.100
|
||||
const enum AVPixelFormat* pix_fmts = NULL;
|
||||
int ret = FFmpeg::avcodec_get_supported_config(NULL, codec, AV_CODEC_CONFIG_PIX_FORMAT, 0,
|
||||
(const void**)&pix_fmts, NULL);
|
||||
#else
|
||||
const enum AVPixelFormat* pix_fmts = codec->pix_fmts;
|
||||
int ret = 0;
|
||||
#endif
|
||||
|
||||
for (std::size_t i = 0; (ret >= 0 && pix_fmts) && (pix_fmts[i] != AV_PIX_FMT_NONE); ++i) {
|
||||
const AVCodecHWConfig* config;
|
||||
for (int j = 0;; ++j) {
|
||||
config = FFmpeg::avcodec_get_hw_config(codec, j);
|
||||
if (!config || config->pix_fmt == codec->pix_fmts[i]) {
|
||||
if (!config || config->pix_fmt == pix_fmts[i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -303,7 +321,7 @@ bool FFmpegVideoStream::InitHWContext(const AVCodec* codec) {
|
|||
continue;
|
||||
}
|
||||
|
||||
codec_context->pix_fmt = codec->pix_fmts[i];
|
||||
codec_context->pix_fmt = pix_fmts[i];
|
||||
|
||||
// Create HW device context
|
||||
AVBufferRef* hw_device_context;
|
||||
|
@ -351,7 +369,7 @@ bool FFmpegVideoStream::InitHWContext(const AVCodec* codec) {
|
|||
|
||||
AVHWFramesContext* hw_frames_context =
|
||||
reinterpret_cast<AVHWFramesContext*>(hw_frames_context_ref->data);
|
||||
hw_frames_context->format = codec->pix_fmts[i];
|
||||
hw_frames_context->format = pix_fmts[i];
|
||||
hw_frames_context->sw_format = sw_pixel_format;
|
||||
hw_frames_context->width = codec_context->width;
|
||||
hw_frames_context->height = codec_context->height;
|
||||
|
@ -455,6 +473,7 @@ bool FFmpegAudioStream::Init(FFmpegMuxer& muxer) {
|
|||
}
|
||||
|
||||
frame_count = 0;
|
||||
int ret;
|
||||
|
||||
// Initialize audio codec
|
||||
const AVCodec* codec =
|
||||
|
@ -468,16 +487,33 @@ bool FFmpegAudioStream::Init(FFmpegMuxer& muxer) {
|
|||
// Configure audio codec context
|
||||
codec_context->codec_type = AVMEDIA_TYPE_AUDIO;
|
||||
codec_context->bit_rate = Settings::values.audio_bitrate;
|
||||
if (codec->sample_fmts) {
|
||||
codec_context->sample_fmt = codec->sample_fmts[0];
|
||||
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100) // lavc 61.13.100
|
||||
const enum AVSampleFormat* sample_fmts = NULL;
|
||||
ret = FFmpeg::avcodec_get_supported_config(NULL, codec, AV_CODEC_CONFIG_SAMPLE_FORMAT, 0,
|
||||
(const void**)&sample_fmts, NULL);
|
||||
#else
|
||||
const enum AVSampleFormat* sample_fmts = codec->sample_fmts;
|
||||
ret = 0;
|
||||
#endif
|
||||
if (ret >= 0 && sample_fmts) {
|
||||
codec_context->sample_fmt = sample_fmts[0];
|
||||
} else {
|
||||
codec_context->sample_fmt = AV_SAMPLE_FMT_S16P;
|
||||
}
|
||||
|
||||
if (codec->supported_samplerates) {
|
||||
codec_context->sample_rate = codec->supported_samplerates[0];
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100) // lavc 61.13.100
|
||||
const int* supported_samplerates = NULL;
|
||||
ret = FFmpeg::avcodec_get_supported_config(NULL, codec, AV_CODEC_CONFIG_SAMPLE_RATE, 0,
|
||||
(const void**)&supported_samplerates, NULL);
|
||||
#else
|
||||
const int* supported_samplerates = codec->supported_samplerates;
|
||||
ret = 0;
|
||||
#endif
|
||||
if (ret >= 0 && supported_samplerates) {
|
||||
codec_context->sample_rate = supported_samplerates[0];
|
||||
// Prefer native sample rate if supported
|
||||
const int* ptr = codec->supported_samplerates;
|
||||
const int* ptr = supported_samplerates;
|
||||
while ((*ptr)) {
|
||||
if ((*ptr) == AudioCore::native_sample_rate) {
|
||||
codec_context->sample_rate = AudioCore::native_sample_rate;
|
||||
|
@ -956,7 +992,7 @@ std::string FormatDefaultValue(const AVOption* option,
|
|||
case AV_OPT_TYPE_VIDEO_RATE: {
|
||||
return ToStdString(option->default_val.str);
|
||||
}
|
||||
case AV_OPT_TYPE_CHANNEL_LAYOUT: {
|
||||
case AV_OPT_TYPE_CHLAYOUT: {
|
||||
return fmt::format("{:#x}", option->default_val.i64);
|
||||
}
|
||||
default:
|
||||
|
|
Loading…
Reference in a new issue