]> git.sesse.net Git - ffmpeg/commitdiff
lavc: factor decoder validation/setup from avcodec_open2()
authorAnton Khirnov <anton@khirnov.net>
Tue, 9 Mar 2021 10:35:47 +0000 (11:35 +0100)
committerAnton Khirnov <anton@khirnov.net>
Tue, 16 Mar 2021 10:09:36 +0000 (11:09 +0100)
libavcodec/decode.c
libavcodec/decode.h
libavcodec/utils.c

index 5f7e9bda3e81ee0d27188d5720f5655e0f1c0eb6..c8e9be3a138cc548800128eee7996980b468b0fa 100644 (file)
@@ -2004,3 +2004,44 @@ int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
     return ret;
 }
+
+int ff_decode_preinit(AVCodecContext *avctx)
+{
+    /* if the decoder init function was already called previously,
+     * free the already allocated subtitle_header before overwriting it */
+    av_freep(&avctx->subtitle_header);
+
+#if FF_API_THREAD_SAFE_CALLBACKS
+FF_DISABLE_DEPRECATION_WARNINGS
+    if ((avctx->thread_type & FF_THREAD_FRAME) &&
+        avctx->get_buffer2 != avcodec_default_get_buffer2 &&
+        !avctx->thread_safe_callbacks) {
+        av_log(avctx, AV_LOG_WARNING, "Requested frame threading with a "
+               "custom get_buffer2() implementation which is not marked as "
+               "thread safe. This is not supported anymore, make your "
+               "callback thread-safe.\n");
+    }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+    if (avctx->codec->max_lowres < avctx->lowres || avctx->lowres < 0) {
+        av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
+               avctx->codec->max_lowres);
+        avctx->lowres = avctx->codec->max_lowres;
+    }
+
+    avctx->pts_correction_num_faulty_pts =
+    avctx->pts_correction_num_faulty_dts = 0;
+    avctx->pts_correction_last_pts =
+    avctx->pts_correction_last_dts = INT64_MIN;
+
+    if (   !CONFIG_GRAY && avctx->flags & AV_CODEC_FLAG_GRAY
+        && avctx->codec_descriptor->type == AVMEDIA_TYPE_VIDEO)
+        av_log(avctx, AV_LOG_WARNING,
+               "gray decoding requested but not enabled at configuration time\n");
+    if (avctx->flags2 & AV_CODEC_FLAG2_EXPORT_MVS) {
+        avctx->export_side_data |= AV_CODEC_EXPORT_DATA_MVS;
+    }
+
+    return 0;
+}
index d4e3f5c5b510c916491585d1d24d52e7894bf2f8..a865fe954f835dd2e17f584eb09d6b35af4b2a5e 100644 (file)
@@ -85,4 +85,10 @@ int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx,
 
 int ff_attach_decode_data(AVFrame *frame);
 
+/**
+ * Perform decoder initialization and validation.
+ * Called when opening the decoder, before the AVCodec.init() call.
+ */
+int ff_decode_preinit(AVCodecContext *avctx);
+
 #endif /* AVCODEC_DECODE_H */
index 933af49c11c7b695616cf480b4adbdae5748a2aa..3eae531297e4441aadbccfbe660c1813f0c0d9b4 100644 (file)
@@ -657,11 +657,6 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
         }
     }
 
-    /* if the decoder init function was already called previously,
-     * free the already allocated subtitle_header before overwriting it */
-    if (av_codec_is_decoder(codec))
-        av_freep(&avctx->subtitle_header);
-
     if (avctx->channels > FF_SANE_NB_CHANNELS || avctx->channels < 0) {
         av_log(avctx, AV_LOG_ERROR, "Too many or invalid channels: %d\n", avctx->channels);
         ret = AVERROR(EINVAL);
@@ -687,19 +682,6 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
         goto free_and_end;
     }
 
-#if FF_API_THREAD_SAFE_CALLBACKS
-FF_DISABLE_DEPRECATION_WARNINGS
-    if ((avctx->thread_type & FF_THREAD_FRAME) &&
-        avctx->get_buffer2 != avcodec_default_get_buffer2 &&
-        !avctx->thread_safe_callbacks) {
-        av_log(avctx, AV_LOG_WARNING, "Requested frame threading with a "
-               "custom get_buffer2() implementation which is not marked as "
-               "thread safe. This is not supported anymore, make your "
-               "callback thread-safe.\n");
-    }
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
-
     avctx->codec = codec;
     if ((avctx->codec_type == AVMEDIA_TYPE_UNKNOWN || avctx->codec_type == codec->type) &&
         avctx->codec_id == AV_CODEC_ID_NONE) {
@@ -764,30 +746,12 @@ FF_ENABLE_DEPRECATION_WARNINGS
     if (!HAVE_THREADS && !(codec->caps_internal & FF_CODEC_CAP_AUTO_THREADS))
         avctx->thread_count = 1;
 
-    if (avctx->codec->max_lowres < avctx->lowres || avctx->lowres < 0) {
-        av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
-               avctx->codec->max_lowres);
-        avctx->lowres = avctx->codec->max_lowres;
-    }
-
-    if (av_codec_is_encoder(avctx->codec)) {
+    if (av_codec_is_encoder(avctx->codec))
         ret = ff_encode_preinit(avctx);
-        if (ret < 0)
-            goto free_and_end;
-    }
-
-    avctx->pts_correction_num_faulty_pts =
-    avctx->pts_correction_num_faulty_dts = 0;
-    avctx->pts_correction_last_pts =
-    avctx->pts_correction_last_dts = INT64_MIN;
-
-    if (   !CONFIG_GRAY && avctx->flags & AV_CODEC_FLAG_GRAY
-        && avctx->codec_descriptor->type == AVMEDIA_TYPE_VIDEO)
-        av_log(avctx, AV_LOG_WARNING,
-               "gray decoding requested but not enabled at configuration time\n");
-    if (avctx->flags2 & AV_CODEC_FLAG2_EXPORT_MVS) {
-        avctx->export_side_data |= AV_CODEC_EXPORT_DATA_MVS;
-    }
+    else
+        ret = ff_decode_preinit(avctx);
+    if (ret < 0)
+        goto free_and_end;
 
     if (   avctx->codec->init && (!(avctx->active_thread_type&FF_THREAD_FRAME)
         || avci->frame_thread_encoder)) {