FFmpeg: Use avcodec_get_supported_config when present

This commit is contained in:
Vicki Pfau 2025-01-02 00:11:04 -08:00
parent 4eb1dbca36
commit e29b5ac047
2 changed files with 47 additions and 14 deletions

View File

@ -38,6 +38,10 @@ CXX_GUARD_START
#define FFMPEG_USE_NEW_CH_LAYOUT #define FFMPEG_USE_NEW_CH_LAYOUT
#endif #endif
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100)
#define FFMPEG_USE_GET_SUPPORTED_CONFIG
#endif
static inline enum AVPixelFormat mColorFormatToFFmpegPixFmt(enum mColorFormat format) { static inline enum AVPixelFormat mColorFormatToFFmpegPixFmt(enum mColorFormat format) {
switch (format) { switch (format) {
#ifndef USE_LIBAV #ifndef USE_LIBAV

View File

@ -134,18 +134,28 @@ bool FFmpegEncoderSetAudio(struct FFmpegEncoder* encoder, const char* acodec, un
return false; return false;
} }
if (!codec->sample_fmts) { const enum AVSampleFormat* formats = NULL;
#ifdef FFMPEG_USE_GET_SUPPORTED_CONFIG
if (avcodec_get_supported_config(NULL, codec, AV_CODEC_CONFIG_SAMPLE_FORMAT, 0, (const void**) &formats, NULL) < 0) {
return false; return false;
} }
#else
formats = codec->sample_fmts;
#endif
if (!formats) {
return false;
}
size_t i; size_t i;
size_t j; size_t j;
int priority = INT_MAX; int priority = INT_MAX;
encoder->sampleFormat = AV_SAMPLE_FMT_NONE; encoder->sampleFormat = AV_SAMPLE_FMT_NONE;
for (i = 0; codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; ++i) { for (i = 0; formats[i] != AV_SAMPLE_FMT_NONE; ++i) {
for (j = 0; j < sizeof(priorities) / sizeof(*priorities); ++j) { for (j = 0; j < sizeof(priorities) / sizeof(*priorities); ++j) {
if (codec->sample_fmts[i] == priorities[j].format && priority > priorities[j].priority) { if (formats[i] == priorities[j].format && priority > priorities[j].priority) {
priority = priorities[j].priority; priority = priorities[j].priority;
encoder->sampleFormat = codec->sample_fmts[i]; encoder->sampleFormat = formats[i];
} }
} }
} }
@ -153,18 +163,29 @@ bool FFmpegEncoderSetAudio(struct FFmpegEncoder* encoder, const char* acodec, un
return false; return false;
} }
encoder->sampleRate = encoder->isampleRate; encoder->sampleRate = encoder->isampleRate;
if (codec->supported_samplerates) {
const int* sampleRates = NULL;
#ifdef FFMPEG_USE_GET_SUPPORTED_CONFIG
if (avcodec_get_supported_config(NULL, codec, AV_CODEC_CONFIG_SAMPLE_RATE, 0, (const void**) &sampleRates, NULL) < 0) {
return false;
}
#else
sampleRates = codec->sample_rates;
#endif
if (sampleRates) {
bool gotSampleRate = false; bool gotSampleRate = false;
int highestSampleRate = 0; int highestSampleRate = 0;
for (i = 0; codec->supported_samplerates[i]; ++i) { for (i = 0; sampleRates[i]; ++i) {
if (codec->supported_samplerates[i] > highestSampleRate) { if (sampleRates[i] > highestSampleRate) {
highestSampleRate = codec->supported_samplerates[i]; highestSampleRate = sampleRates[i];
} }
if (codec->supported_samplerates[i] < encoder->isampleRate) { if (sampleRates[i] < encoder->isampleRate) {
continue; continue;
} }
if (!gotSampleRate || encoder->sampleRate > codec->supported_samplerates[i]) { if (!gotSampleRate || encoder->sampleRate > sampleRates[i]) {
encoder->sampleRate = codec->supported_samplerates[i]; encoder->sampleRate = sampleRates[i];
gotSampleRate = true; gotSampleRate = true;
} }
} }
@ -231,11 +252,19 @@ bool FFmpegEncoderSetVideo(struct FFmpegEncoder* encoder, const char* vcodec, in
size_t j; size_t j;
int priority = INT_MAX; int priority = INT_MAX;
encoder->pixFormat = AV_PIX_FMT_NONE; encoder->pixFormat = AV_PIX_FMT_NONE;
for (i = 0; codec->pix_fmts[i] != AV_PIX_FMT_NONE; ++i) { const enum AVPixelFormat* formats;
#ifdef FFMPEG_USE_GET_SUPPORTED_CONFIG
if (avcodec_get_supported_config(NULL, codec, AV_CODEC_CONFIG_PIX_FORMAT, 0, (const void**) &formats, NULL) < 0) {
return false;
}
#else
formats = codec->pix_fmts;
#endif
for (i = 0; formats[i] != AV_PIX_FMT_NONE; ++i) {
for (j = 0; j < sizeof(priorities) / sizeof(*priorities); ++j) { for (j = 0; j < sizeof(priorities) / sizeof(*priorities); ++j) {
if (codec->pix_fmts[i] == priorities[j].format && priority > priorities[j].priority) { if (formats[i] == priorities[j].format && priority > priorities[j].priority) {
priority = priorities[j].priority; priority = priorities[j].priority;
encoder->pixFormat = codec->pix_fmts[i]; encoder->pixFormat = formats[i];
} }
} }
} }