[FFmpeg-devel] [PATCH v4 03/17] avcodec/encode: switch to avcodec_get_supported_config()

Niklas Haas ffmpeg at haasn.xyz
Wed Sep 4 14:02:32 EEST 2024


From: Niklas Haas <git at haasn.dev>

---
 libavcodec/encode.c | 90 ++++++++++++++++++++++++++++-----------------
 1 file changed, 57 insertions(+), 33 deletions(-)

diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index 34658d13d0..bc5acf985d 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -563,7 +563,8 @@ static int encode_preinit_video(AVCodecContext *avctx)
 {
     const AVCodec *c = avctx->codec;
     const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(avctx->pix_fmt);
-    int i;
+    const enum AVPixelFormat *pix_fmts;
+    int ret, i, num_pix_fmts;
 
     if (!av_get_pix_fmt_name(avctx->pix_fmt)) {
         av_log(avctx, AV_LOG_ERROR, "Invalid video pixel format: %d\n",
@@ -571,28 +572,33 @@ static int encode_preinit_video(AVCodecContext *avctx)
         return AVERROR(EINVAL);
     }
 
-    if (c->pix_fmts) {
-        for (i = 0; c->pix_fmts[i] != AV_PIX_FMT_NONE; i++)
-            if (avctx->pix_fmt == c->pix_fmts[i])
+    ret = avcodec_get_supported_config(avctx, NULL, AV_CODEC_CONFIG_PIX_FORMAT,
+                                       0, (const void **) &pix_fmts, &num_pix_fmts);
+    if (ret < 0)
+        return ret;
+
+    if (pix_fmts) {
+        for (i = 0; i < num_pix_fmts; i++)
+            if (avctx->pix_fmt == pix_fmts[i])
                 break;
-        if (c->pix_fmts[i] == AV_PIX_FMT_NONE) {
+        if (i == num_pix_fmts) {
             av_log(avctx, AV_LOG_ERROR,
                    "Specified pixel format %s is not supported by the %s encoder.\n",
                    av_get_pix_fmt_name(avctx->pix_fmt), c->name);
 
             av_log(avctx, AV_LOG_ERROR, "Supported pixel formats:\n");
-            for (int p = 0; c->pix_fmts[p] != AV_PIX_FMT_NONE; p++) {
+            for (int p = 0; pix_fmts[p] != AV_PIX_FMT_NONE; p++) {
                 av_log(avctx, AV_LOG_ERROR, "  %s\n",
-                       av_get_pix_fmt_name(c->pix_fmts[p]));
+                       av_get_pix_fmt_name(pix_fmts[p]));
             }
 
             return AVERROR(EINVAL);
         }
-        if (c->pix_fmts[i] == AV_PIX_FMT_YUVJ420P ||
-            c->pix_fmts[i] == AV_PIX_FMT_YUVJ411P ||
-            c->pix_fmts[i] == AV_PIX_FMT_YUVJ422P ||
-            c->pix_fmts[i] == AV_PIX_FMT_YUVJ440P ||
-            c->pix_fmts[i] == AV_PIX_FMT_YUVJ444P)
+        if (pix_fmts[i] == AV_PIX_FMT_YUVJ420P ||
+            pix_fmts[i] == AV_PIX_FMT_YUVJ411P ||
+            pix_fmts[i] == AV_PIX_FMT_YUVJ422P ||
+            pix_fmts[i] == AV_PIX_FMT_YUVJ440P ||
+            pix_fmts[i] == AV_PIX_FMT_YUVJ444P)
             avctx->color_range = AVCOL_RANGE_JPEG;
     }
 
@@ -646,7 +652,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
 static int encode_preinit_audio(AVCodecContext *avctx)
 {
     const AVCodec *c = avctx->codec;
-    int i;
+    const enum AVSampleFormat *sample_fmts;
+    const int *supported_samplerates;
+    const AVChannelLayout *ch_layouts;
+    int ret, i, num_sample_fmts, num_samplerates, num_ch_layouts;
 
     if (!av_get_sample_fmt_name(avctx->sample_fmt)) {
         av_log(avctx, AV_LOG_ERROR, "Invalid audio sample format: %d\n",
@@ -659,53 +668,68 @@ static int encode_preinit_audio(AVCodecContext *avctx)
         return AVERROR(EINVAL);
     }
 
-    if (c->sample_fmts) {
-        for (i = 0; c->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
-            if (avctx->sample_fmt == c->sample_fmts[i])
+    ret = avcodec_get_supported_config(avctx, NULL, AV_CODEC_CONFIG_SAMPLE_FORMAT,
+                                       0, (const void **) &sample_fmts,
+                                       &num_sample_fmts);
+    if (ret < 0)
+        return ret;
+    if (sample_fmts) {
+        for (i = 0; i < num_sample_fmts; i++) {
+            if (avctx->sample_fmt == sample_fmts[i])
                 break;
             if (avctx->ch_layout.nb_channels == 1 &&
                 av_get_planar_sample_fmt(avctx->sample_fmt) ==
-                av_get_planar_sample_fmt(c->sample_fmts[i])) {
-                avctx->sample_fmt = c->sample_fmts[i];
+                av_get_planar_sample_fmt(sample_fmts[i])) {
+                avctx->sample_fmt = sample_fmts[i];
                 break;
             }
         }
-        if (c->sample_fmts[i] == AV_SAMPLE_FMT_NONE) {
+        if (i == num_sample_fmts) {
             av_log(avctx, AV_LOG_ERROR,
                    "Specified sample format %s is not supported by the %s encoder\n",
                    av_get_sample_fmt_name(avctx->sample_fmt), c->name);
 
             av_log(avctx, AV_LOG_ERROR, "Supported sample formats:\n");
-            for (int p = 0; c->sample_fmts[p] != AV_SAMPLE_FMT_NONE; p++) {
+            for (int p = 0; sample_fmts[p] != AV_SAMPLE_FMT_NONE; p++) {
                 av_log(avctx, AV_LOG_ERROR, "  %s\n",
-                       av_get_sample_fmt_name(c->sample_fmts[p]));
+                       av_get_sample_fmt_name(sample_fmts[p]));
             }
 
             return AVERROR(EINVAL);
         }
     }
-    if (c->supported_samplerates) {
-        for (i = 0; c->supported_samplerates[i] != 0; i++)
-            if (avctx->sample_rate == c->supported_samplerates[i])
+
+    ret = avcodec_get_supported_config(avctx, NULL, AV_CODEC_CONFIG_SAMPLE_RATE,
+                                       0, (const void **) &supported_samplerates,
+                                       &num_samplerates);
+    if (ret < 0)
+        return ret;
+    if (supported_samplerates) {
+        for (i = 0; i < num_samplerates; i++)
+            if (avctx->sample_rate == supported_samplerates[i])
                 break;
-        if (c->supported_samplerates[i] == 0) {
+        if (i == num_samplerates) {
             av_log(avctx, AV_LOG_ERROR,
                    "Specified sample rate %d is not supported by the %s encoder\n",
                    avctx->sample_rate, c->name);
 
             av_log(avctx, AV_LOG_ERROR, "Supported sample rates:\n");
-            for (int p = 0; c->supported_samplerates[p]; p++)
-                av_log(avctx, AV_LOG_ERROR, "  %d\n", c->supported_samplerates[p]);
+            for (int p = 0; supported_samplerates[p]; p++)
+                av_log(avctx, AV_LOG_ERROR, "  %d\n", supported_samplerates[p]);
 
             return AVERROR(EINVAL);
         }
     }
-    if (c->ch_layouts) {
-        for (i = 0; c->ch_layouts[i].nb_channels; i++) {
-            if (!av_channel_layout_compare(&avctx->ch_layout, &c->ch_layouts[i]))
+    ret = avcodec_get_supported_config(avctx, NULL, AV_CODEC_CONFIG_CHANNEL_LAYOUT,
+                                       0, (const void **) &ch_layouts, &num_ch_layouts);
+    if (ret < 0)
+        return ret;
+    if (ch_layouts) {
+        for (i = 0; i < num_ch_layouts; i++) {
+            if (!av_channel_layout_compare(&avctx->ch_layout, &ch_layouts[i]))
                 break;
         }
-        if (!c->ch_layouts[i].nb_channels) {
+        if (i == num_ch_layouts) {
             char buf[512];
             int ret = av_channel_layout_describe(&avctx->ch_layout, buf, sizeof(buf));
             av_log(avctx, AV_LOG_ERROR,
@@ -713,8 +737,8 @@ static int encode_preinit_audio(AVCodecContext *avctx)
                    ret > 0 ? buf : "?", c->name);
 
             av_log(avctx, AV_LOG_ERROR, "Supported channel layouts:\n");
-            for (int p = 0; c->ch_layouts[p].nb_channels; p++) {
-                ret = av_channel_layout_describe(&c->ch_layouts[p], buf, sizeof(buf));
+            for (int p = 0; ch_layouts[p].nb_channels; p++) {
+                ret = av_channel_layout_describe(&ch_layouts[p], buf, sizeof(buf));
                 av_log(avctx, AV_LOG_ERROR, "  %s\n", ret > 0 ? buf : "?");
             }
             return AVERROR(EINVAL);
-- 
2.46.0



More information about the ffmpeg-devel mailing list