lavc: replace deprecated items

Some AVCodec properties like pix_fmts or sample_fmts are marked as
deprecated and should be replaced by avcodec_get_supported_config()
in current FFmpeg.

Created compat functions to get rid of deprecate warnings running with
both old and new FFmpeg.
This commit is contained in:
Martin Pulec
2024-11-12 14:57:18 +01:00
parent 875c585dc3
commit 8b94de582c
4 changed files with 88 additions and 16 deletions

View File

@@ -299,9 +299,10 @@ static void *libavcodec_init(audio_codec_t audio_codec, audio_codec_direction_t
}
/* check that a given sample format is supported by the encoder */
static int check_sample_fmt(const AVCodec *codec, enum AVSampleFormat sample_fmt)
static int
check_sample_fmt(const AVCodecContext *ctx, enum AVSampleFormat sample_fmt)
{
const enum AVSampleFormat *p = codec->sample_fmts;
const enum AVSampleFormat *p = avc_get_supported_sample_fmts(ctx, NULL);
while (*p != AV_SAMPLE_FMT_NONE) {
if (*p == sample_fmt)
@@ -367,7 +368,7 @@ static bool reinitialize_encoder(struct libavcodec_codec_state *s, struct audio_
s->codec_ctx->sample_fmt = AV_SAMPLE_FMT_NONE;
for (int i = 0; i < count; ++i) {
if (check_sample_fmt(s->codec, sample_fmts[i])) {
if (check_sample_fmt(s->codec_ctx, sample_fmts[i])) {
s->codec_ctx->sample_fmt = sample_fmts[i];
break;
}
@@ -375,10 +376,12 @@ static bool reinitialize_encoder(struct libavcodec_codec_state *s, struct audio_
if (s->codec_ctx->sample_fmt == AV_SAMPLE_FMT_NONE) {
int i = 0;
while (s->codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE) {
if (s->codec->sample_fmts[i] != AV_SAMPLE_FMT_DBL &&
s->codec->sample_fmts[i] != AV_SAMPLE_FMT_DBLP) {
s->codec_ctx->sample_fmt = s->codec->sample_fmts[i];
const enum AVSampleFormat *sample_fmts =
avc_get_supported_sample_fmts(s->codec_ctx, NULL);
while (sample_fmts[i] != AV_SAMPLE_FMT_NONE) {
if (sample_fmts[i] != AV_SAMPLE_FMT_DBL &&
sample_fmts[i] != AV_SAMPLE_FMT_DBLP) {
s->codec_ctx->sample_fmt = sample_fmts[i];
break;
}
i++;
@@ -736,7 +739,7 @@ static const int *libavcodec_get_sample_rates(void *state)
{
struct libavcodec_codec_state *s = (struct libavcodec_codec_state *) state;
return s->codec->supported_samplerates;
return avc_get_supported_sample_rates(s->codec_ctx, NULL);
}
static void cleanup_common(struct libavcodec_codec_state *s)

View File

@@ -347,4 +347,61 @@ get_avpixfmts_names(const enum AVPixelFormat *pixfmts)
}
return buf;
}
/**
* @param ctx may be nullptr if codec is not
* @param codec may be nullptr if ctx is not
*
* If passed ctx, values such as `strict_std_compliance` may afect the result.
*/
static const void *
avc_get_supported_config(const AVCodecContext *ctx, const AVCodec *codec,
enum AVCodecConfig config)
{
#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(61, 13, 100)
const void *ret = NULL;
int unused_count = 0;
const int rc = avcodec_get_supported_config(
ctx, codec, config, /*flags*/ 0, &ret,
&unused_count);
if (rc != 0) {
MSG(ERROR, "Cannot get list of supported config %d for %s!\n",
(int) config, codec->name);
return NULL;
}
return ret;
#else
abort(); // cannot reach here (shouldn't be called)
#endif
}
///< @copydoc avc_get_supported_config
const enum AVPixelFormat *
avc_get_supported_pix_fmts(const AVCodecContext *ctx, const AVCodec *codec)
{
#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(61, 13, 100)
return avc_get_supported_config(ctx, codec, AV_CODEC_CONFIG_PIX_FORMAT);
#else
return codec->pix_fmts;
#endif
}
///< @copydoc avc_get_supported_config
const enum AVSampleFormat *
avc_get_supported_sample_fmts(const AVCodecContext *ctx, const AVCodec *codec)
{
#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(61, 13, 100)
return avc_get_supported_config(ctx, codec, AV_CODEC_CONFIG_SAMPLE_FORMAT);
#else
return codec->pix_fmts;
#endif
}
///< @copydoc avc_get_supported_config
const int *avc_get_supported_sample_rates(const AVCodecContext *ctx, const AVCodec *codec)
{
#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(61, 13, 100)
return avc_get_supported_config(ctx, codec, AV_CODEC_CONFIG_SAMPLE_RATE);
#else
return codec->supported_samplerates;
#endif
}
/* vi: set expandtab sw=8: */

View File

@@ -122,6 +122,13 @@ struct audio_desc audio_desc_from_av_frame(const AVFrame *frm);
enum AVSampleFormat audio_bps_to_av_sample_fmt(int bps, bool planar);
const char *get_avpixfmts_names(const enum AVPixelFormat *pixfmts);
const enum AVPixelFormat *avc_get_supported_pix_fmts(const AVCodecContext *ctx,
const AVCodec *codec);
const enum AVSampleFormat *
avc_get_supported_sample_fmts(const AVCodecContext *ctx, const AVCodec *codec);
const int *avc_get_supported_sample_rates(const AVCodecContext *ctx,
const AVCodec *codec);
#ifdef __cplusplus
}
#endif

View File

@@ -480,7 +480,8 @@ handle_help(bool full, string const &req_encoder, string const &req_codec)
avcodec_find_encoder_by_name(req_encoder.c_str());
if (codec != nullptr) {
cout << "\n";
print_codec_supp_pix_fmts(codec->pix_fmts);
print_codec_supp_pix_fmts(
avc_get_supported_pix_fmts(nullptr, codec));
} else {
MSG(ERROR, "Cannot open encoder: %s\n",
req_encoder.c_str());
@@ -1123,11 +1124,11 @@ try_open_remaining_pixfmts(state_video_compress_libav *s, video_desc desc,
return AV_PIX_FMT_NONE;
#endif
unsigned usable_fmt_cnt = 0;
if (codec->pix_fmts == nullptr) {
if (avc_get_supported_pix_fmts(nullptr, codec) == nullptr) {
return AV_PIX_FMT_NONE;
}
for (const auto *pix = codec->pix_fmts; *pix != AV_PIX_FMT_NONE;
++pix) {
for (const auto *pix = avc_get_supported_pix_fmts(nullptr, codec);
*pix != AV_PIX_FMT_NONE; ++pix) {
usable_fmt_cnt += 1;
}
if (usable_fmt_cnt == fmts_tried.size()) {
@@ -1136,8 +1137,8 @@ try_open_remaining_pixfmts(state_video_compress_libav *s, video_desc desc,
LOG(LOG_LEVEL_WARNING) << MOD_NAME "No direct decoder format for: "
<< get_codec_name(desc.color_spec)
<< ". Trying to convert with swscale instead.\n";
for (const auto *pix = codec->pix_fmts; *pix != AV_PIX_FMT_NONE;
++pix) {
for (const auto *pix = avc_get_supported_pix_fmts(nullptr, codec);
*pix != AV_PIX_FMT_NONE; ++pix) {
const AVPixFmtDescriptor *fmt_desc = av_pix_fmt_desc_get(*pix);
if (fmts_tried.count(*pix) == 1 || fmt_desc == nullptr ||
(fmt_desc->flags & AV_PIX_FMT_FLAG_HWACCEL) != 0U) {
@@ -1179,7 +1180,10 @@ static bool configure_with(struct state_video_compress_libav *s, struct video_de
apply_blacklist(requested_pix_fmt, codec->name);
auto requested_pix_fmt_it = requested_pix_fmt.cbegin();
set<AVPixelFormat> fmts_tried;
while ((pix_fmt = get_first_matching_pix_fmt(requested_pix_fmt_it, requested_pix_fmt.cend(), codec->pix_fmts)) != AV_PIX_FMT_NONE) {
while ((pix_fmt = get_first_matching_pix_fmt(
requested_pix_fmt_it, requested_pix_fmt.cend(),
avc_get_supported_pix_fmts(nullptr, codec))) !=
AV_PIX_FMT_NONE) {
fmts_tried.insert(pix_fmt);
if(try_open_codec(s, pix_fmt, desc, ug_codec, codec)){
break;
@@ -1187,7 +1191,8 @@ static bool configure_with(struct state_video_compress_libav *s, struct video_de
}
if (pix_fmt == AV_PIX_FMT_NONE || log_level >= LOG_LEVEL_VERBOSE) {
print_pix_fmts(requested_pix_fmt, codec->pix_fmts);
print_pix_fmts(requested_pix_fmt,
avc_get_supported_pix_fmts(nullptr, codec));
}
if (pix_fmt == AV_PIX_FMT_NONE && get_commandline_param("lavc-use-codec") == NULL) {