]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/bsf.c
avutil: remove deprecated AVClass.child_class_next
[ffmpeg] / libavcodec / bsf.c
index d3a9db57f7fe003506ac769d380d502390a6e113..9d67ea5395222972a6283afa7bec4e7f4a9807d6 100644 (file)
 #include "libavutil/avstring.h"
 #include "libavutil/bprint.h"
 
-#include "avcodec.h"
 #include "bsf.h"
+#include "bsf_internal.h"
+#include "codec_desc.h"
+#include "codec_par.h"
 
 #define IS_EMPTY(pkt) (!(pkt)->data && !(pkt)->side_data_elems)
 
@@ -43,14 +45,15 @@ void av_bsf_free(AVBSFContext **pctx)
         return;
     ctx = *pctx;
 
-    if (ctx->filter->close)
-        ctx->filter->close(ctx);
+    if (ctx->internal) {
+        if (ctx->filter->close)
+            ctx->filter->close(ctx);
+        av_packet_free(&ctx->internal->buffer_pkt);
+        av_freep(&ctx->internal);
+    }
     if (ctx->filter->priv_class && ctx->priv_data)
         av_opt_free(ctx->priv_data);
 
-    if (ctx->internal)
-        av_packet_free(&ctx->internal->buffer_pkt);
-    av_freep(&ctx->internal);
     av_freep(&ctx->priv_data);
 
     avcodec_parameters_free(&ctx->par_in);
@@ -77,7 +80,7 @@ static const AVClass bsf_class = {
     .item_name        = bsf_to_name,
     .version          = LIBAVUTIL_VERSION_INT,
     .child_next       = bsf_child_next,
-    .child_class_next = ff_bsf_child_class_next,
+    .child_class_iterate = ff_bsf_child_class_iterate,
     .category         = AV_CLASS_CATEGORY_BITSTREAM_FILTER,
 };
 
@@ -105,20 +108,6 @@ int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **pctx)
         ret = AVERROR(ENOMEM);
         goto fail;
     }
-
-    bsfi = av_mallocz(sizeof(*bsfi));
-    if (!bsfi) {
-        ret = AVERROR(ENOMEM);
-        goto fail;
-    }
-    ctx->internal = bsfi;
-
-    bsfi->buffer_pkt = av_packet_alloc();
-    if (!bsfi->buffer_pkt) {
-        ret = AVERROR(ENOMEM);
-        goto fail;
-    }
-
     /* allocate priv data and init private options */
     if (filter->priv_data_size) {
         ctx->priv_data = av_mallocz(filter->priv_data_size);
@@ -131,6 +120,20 @@ int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **pctx)
             av_opt_set_defaults(ctx->priv_data);
         }
     }
+    /* Allocate AVBSFInternal; must happen after priv_data has been allocated
+     * so that a filter->close needing priv_data is never called without. */
+    bsfi = av_mallocz(sizeof(*bsfi));
+    if (!bsfi) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
+    ctx->internal = bsfi;
+
+    bsfi->buffer_pkt = av_packet_alloc();
+    if (!bsfi->buffer_pkt) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
 
     *pctx = ctx;
     return 0;
@@ -154,9 +157,9 @@ int av_bsf_init(AVBSFContext *ctx)
                    "bitstream filter '%s'. Supported codecs are: ",
                    desc ? desc->name : "unknown", ctx->par_in->codec_id, ctx->filter->name);
             for (i = 0; ctx->filter->codec_ids[i] != AV_CODEC_ID_NONE; i++) {
-                desc = avcodec_descriptor_get(ctx->filter->codec_ids[i]);
+                enum AVCodecID codec_id = ctx->filter->codec_ids[i];
                 av_log(ctx, AV_LOG_ERROR, "%s (%d) ",
-                       desc ? desc->name : "unknown", ctx->filter->codec_ids[i]);
+                       avcodec_get_name(codec_id), codec_id);
             }
             av_log(ctx, AV_LOG_ERROR, "\n");
             return AVERROR(EINVAL);
@@ -431,7 +434,7 @@ int av_bsf_list_append(AVBSFList *lst, AVBSFContext *bsf)
     return av_dynarray_add_nofree(&lst->bsfs, &lst->nb_bsfs, bsf);
 }
 
-int av_bsf_list_append2(AVBSFList *lst, const char *bsf_name, AVDictionary ** options)
+static int bsf_list_append_internal(AVBSFList *lst, const char *bsf_name, const char *options, AVDictionary ** options_dict)
 {
     int ret;
     const AVBitStreamFilter *filter;
@@ -445,8 +448,20 @@ int av_bsf_list_append2(AVBSFList *lst, const char *bsf_name, AVDictionary ** op
     if (ret < 0)
         return ret;
 
-    if (options) {
-        ret = av_opt_set_dict2(bsf, options, AV_OPT_SEARCH_CHILDREN);
+    if (options && filter->priv_class) {
+        const AVOption *opt = av_opt_next(bsf->priv_data, NULL);
+        const char * shorthand[2] = {NULL};
+
+        if (opt)
+            shorthand[0] = opt->name;
+
+        ret = av_opt_set_from_string(bsf->priv_data, options, shorthand, "=", ":");
+        if (ret < 0)
+            goto end;
+    }
+
+    if (options_dict) {
+        ret = av_opt_set_dict2(bsf, options_dict, AV_OPT_SEARCH_CHILDREN);
         if (ret < 0)
             goto end;
     }
@@ -460,6 +475,11 @@ end:
     return ret;
 }
 
+int av_bsf_list_append2(AVBSFList *lst, const char *bsf_name, AVDictionary ** options)
+{
+    return bsf_list_append_internal(lst, bsf_name, NULL, options);
+}
+
 int av_bsf_list_finalize(AVBSFList **lst, AVBSFContext **bsf)
 {
     int ret = 0;
@@ -486,33 +506,15 @@ end:
     return ret;
 }
 
-static int bsf_parse_single(const char *str, AVBSFList *bsf_lst)
+static int bsf_parse_single(char *str, AVBSFList *bsf_lst)
 {
-    char *bsf_name, *bsf_options_str, *buf;
-    AVDictionary *bsf_options = NULL;
-    int ret = 0;
-
-    if (!(buf = av_strdup(str)))
-        return AVERROR(ENOMEM);
+    char *bsf_name, *bsf_options_str;
 
-    bsf_name = av_strtok(buf, "=", &bsf_options_str);
-    if (!bsf_name) {
-        ret = AVERROR(EINVAL);
-        goto end;
-    }
-
-    if (bsf_options_str) {
-        ret = av_dict_parse_string(&bsf_options, bsf_options_str, "=", ":", 0);
-        if (ret < 0)
-            goto end;
-    }
-
-    ret = av_bsf_list_append2(bsf_lst, bsf_name, &bsf_options);
+    bsf_name = av_strtok(str, "=", &bsf_options_str);
+    if (!bsf_name)
+        return AVERROR(EINVAL);
 
-end:
-    av_dict_free(&bsf_options);
-    av_free(buf);
-    return ret;
+    return bsf_list_append_internal(bsf_lst, bsf_name, bsf_options_str, NULL);
 }
 
 int av_bsf_list_parse_str(const char *str, AVBSFContext **bsf_lst)