Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH 01/15] fftools/ffmpeg_hw: move hw_device_setup_for_decode() to ffmpeg_dec
@ 2023-05-23 13:58 Anton Khirnov
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 02/15] fftools/ffmpeg_hw: move hw_device_setup_for_encode() to ffmpeg_enc Anton Khirnov
                   ` (13 more replies)
  0 siblings, 14 replies; 16+ messages in thread
From: Anton Khirnov @ 2023-05-23 13:58 UTC (permalink / raw)
  To: ffmpeg-devel

This function is entangled with decoder setup, so it is more decoding
code rather than ffmpeg_hw code. This will allow making more decoder
state private in the future.
---
 fftools/ffmpeg.h     |   5 +-
 fftools/ffmpeg_dec.c | 145 ++++++++++++++++++++++++++++++++++++++++
 fftools/ffmpeg_hw.c  | 153 ++-----------------------------------------
 3 files changed, 153 insertions(+), 150 deletions(-)

diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 45be3b1823..895edbd6d6 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -795,10 +795,13 @@ void enc_stats_write(OutputStream *ost, EncStats *es,
                      uint64_t frame_num);
 
 HWDevice *hw_device_get_by_name(const char *name);
+HWDevice *hw_device_get_by_type(enum AVHWDeviceType type);
 int hw_device_init_from_string(const char *arg, HWDevice **dev);
+int hw_device_init_from_type(enum AVHWDeviceType type,
+                             const char *device,
+                             HWDevice **dev_out);
 void hw_device_free_all(void);
 
-int hw_device_setup_for_decode(InputStream *ist);
 int hw_device_setup_for_encode(OutputStream *ost);
 /**
  * Get a hardware device to be used with this filtergraph.
diff --git a/fftools/ffmpeg_dec.c b/fftools/ffmpeg_dec.c
index e06747d9c4..0a470c4854 100644
--- a/fftools/ffmpeg_dec.c
+++ b/fftools/ffmpeg_dec.c
@@ -528,6 +528,151 @@ static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat
     return *p;
 }
 
+static HWDevice *hw_device_match_by_codec(const AVCodec *codec)
+{
+    const AVCodecHWConfig *config;
+    HWDevice *dev;
+    int i;
+    for (i = 0;; i++) {
+        config = avcodec_get_hw_config(codec, i);
+        if (!config)
+            return NULL;
+        if (!(config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX))
+            continue;
+        dev = hw_device_get_by_type(config->device_type);
+        if (dev)
+            return dev;
+    }
+}
+
+static int hw_device_setup_for_decode(InputStream *ist)
+{
+    const AVCodecHWConfig *config;
+    enum AVHWDeviceType type;
+    HWDevice *dev = NULL;
+    int err, auto_device = 0;
+
+    if (ist->hwaccel_device) {
+        dev = hw_device_get_by_name(ist->hwaccel_device);
+        if (!dev) {
+            if (ist->hwaccel_id == HWACCEL_AUTO) {
+                auto_device = 1;
+            } else if (ist->hwaccel_id == HWACCEL_GENERIC) {
+                type = ist->hwaccel_device_type;
+                err = hw_device_init_from_type(type, ist->hwaccel_device,
+                                               &dev);
+            } else {
+                // This will be dealt with by API-specific initialisation
+                // (using hwaccel_device), so nothing further needed here.
+                return 0;
+            }
+        } else {
+            if (ist->hwaccel_id == HWACCEL_AUTO) {
+                ist->hwaccel_device_type = dev->type;
+            } else if (ist->hwaccel_device_type != dev->type) {
+                av_log(NULL, AV_LOG_ERROR, "Invalid hwaccel device "
+                       "specified for decoder: device %s of type %s is not "
+                       "usable with hwaccel %s.\n", dev->name,
+                       av_hwdevice_get_type_name(dev->type),
+                       av_hwdevice_get_type_name(ist->hwaccel_device_type));
+                return AVERROR(EINVAL);
+            }
+        }
+    } else {
+        if (ist->hwaccel_id == HWACCEL_AUTO) {
+            auto_device = 1;
+        } else if (ist->hwaccel_id == HWACCEL_GENERIC) {
+            type = ist->hwaccel_device_type;
+            dev = hw_device_get_by_type(type);
+
+            // When "-qsv_device device" is used, an internal QSV device named
+            // as "__qsv_device" is created. Another QSV device is created too
+            // if "-init_hw_device qsv=name:device" is used. There are 2 QSV devices
+            // if both "-qsv_device device" and "-init_hw_device qsv=name:device"
+            // are used, hw_device_get_by_type(AV_HWDEVICE_TYPE_QSV) returns NULL.
+            // To keep back-compatibility with the removed ad-hoc libmfx setup code,
+            // call hw_device_get_by_name("__qsv_device") to select the internal QSV
+            // device.
+            if (!dev && type == AV_HWDEVICE_TYPE_QSV)
+                dev = hw_device_get_by_name("__qsv_device");
+
+            if (!dev)
+                err = hw_device_init_from_type(type, NULL, &dev);
+        } else {
+            dev = hw_device_match_by_codec(ist->dec);
+            if (!dev) {
+                // No device for this codec, but not using generic hwaccel
+                // and therefore may well not need one - ignore.
+                return 0;
+            }
+        }
+    }
+
+    if (auto_device) {
+        int i;
+        if (!avcodec_get_hw_config(ist->dec, 0)) {
+            // Decoder does not support any hardware devices.
+            return 0;
+        }
+        for (i = 0; !dev; i++) {
+            config = avcodec_get_hw_config(ist->dec, i);
+            if (!config)
+                break;
+            type = config->device_type;
+            dev = hw_device_get_by_type(type);
+            if (dev) {
+                av_log(NULL, AV_LOG_INFO, "Using auto "
+                       "hwaccel type %s with existing device %s.\n",
+                       av_hwdevice_get_type_name(type), dev->name);
+            }
+        }
+        for (i = 0; !dev; i++) {
+            config = avcodec_get_hw_config(ist->dec, i);
+            if (!config)
+                break;
+            type = config->device_type;
+            // Try to make a new device of this type.
+            err = hw_device_init_from_type(type, ist->hwaccel_device,
+                                           &dev);
+            if (err < 0) {
+                // Can't make a device of this type.
+                continue;
+            }
+            if (ist->hwaccel_device) {
+                av_log(NULL, AV_LOG_INFO, "Using auto "
+                       "hwaccel type %s with new device created "
+                       "from %s.\n", av_hwdevice_get_type_name(type),
+                       ist->hwaccel_device);
+            } else {
+                av_log(NULL, AV_LOG_INFO, "Using auto "
+                       "hwaccel type %s with new default device.\n",
+                       av_hwdevice_get_type_name(type));
+            }
+        }
+        if (dev) {
+            ist->hwaccel_device_type = type;
+        } else {
+            av_log(NULL, AV_LOG_INFO, "Auto hwaccel "
+                   "disabled: no device found.\n");
+            ist->hwaccel_id = HWACCEL_NONE;
+            return 0;
+        }
+    }
+
+    if (!dev) {
+        av_log(NULL, AV_LOG_ERROR, "No device available "
+               "for decoder: device type %s needed for codec %s.\n",
+               av_hwdevice_get_type_name(type), ist->dec->name);
+        return err;
+    }
+
+    ist->dec_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref);
+    if (!ist->dec_ctx->hw_device_ctx)
+        return AVERROR(ENOMEM);
+
+    return 0;
+}
+
 int dec_open(InputStream *ist)
 {
     const AVCodec *codec = ist->dec;
diff --git a/fftools/ffmpeg_hw.c b/fftools/ffmpeg_hw.c
index e67145211c..d28257a1d6 100644
--- a/fftools/ffmpeg_hw.c
+++ b/fftools/ffmpeg_hw.c
@@ -27,7 +27,7 @@
 static int nb_hw_devices;
 static HWDevice **hw_devices;
 
-static HWDevice *hw_device_get_by_type(enum AVHWDeviceType type)
+HWDevice *hw_device_get_by_type(enum AVHWDeviceType type)
 {
     HWDevice *found = NULL;
     int i;
@@ -242,9 +242,9 @@ fail:
     goto done;
 }
 
-static int hw_device_init_from_type(enum AVHWDeviceType type,
-                                    const char *device,
-                                    HWDevice **dev_out)
+int hw_device_init_from_type(enum AVHWDeviceType type,
+                             const char *device,
+                             HWDevice **dev_out)
 {
     AVBufferRef *device_ref = NULL;
     HWDevice *dev;
@@ -297,151 +297,6 @@ void hw_device_free_all(void)
     nb_hw_devices = 0;
 }
 
-static HWDevice *hw_device_match_by_codec(const AVCodec *codec)
-{
-    const AVCodecHWConfig *config;
-    HWDevice *dev;
-    int i;
-    for (i = 0;; i++) {
-        config = avcodec_get_hw_config(codec, i);
-        if (!config)
-            return NULL;
-        if (!(config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX))
-            continue;
-        dev = hw_device_get_by_type(config->device_type);
-        if (dev)
-            return dev;
-    }
-}
-
-int hw_device_setup_for_decode(InputStream *ist)
-{
-    const AVCodecHWConfig *config;
-    enum AVHWDeviceType type;
-    HWDevice *dev = NULL;
-    int err, auto_device = 0;
-
-    if (ist->hwaccel_device) {
-        dev = hw_device_get_by_name(ist->hwaccel_device);
-        if (!dev) {
-            if (ist->hwaccel_id == HWACCEL_AUTO) {
-                auto_device = 1;
-            } else if (ist->hwaccel_id == HWACCEL_GENERIC) {
-                type = ist->hwaccel_device_type;
-                err = hw_device_init_from_type(type, ist->hwaccel_device,
-                                               &dev);
-            } else {
-                // This will be dealt with by API-specific initialisation
-                // (using hwaccel_device), so nothing further needed here.
-                return 0;
-            }
-        } else {
-            if (ist->hwaccel_id == HWACCEL_AUTO) {
-                ist->hwaccel_device_type = dev->type;
-            } else if (ist->hwaccel_device_type != dev->type) {
-                av_log(NULL, AV_LOG_ERROR, "Invalid hwaccel device "
-                       "specified for decoder: device %s of type %s is not "
-                       "usable with hwaccel %s.\n", dev->name,
-                       av_hwdevice_get_type_name(dev->type),
-                       av_hwdevice_get_type_name(ist->hwaccel_device_type));
-                return AVERROR(EINVAL);
-            }
-        }
-    } else {
-        if (ist->hwaccel_id == HWACCEL_AUTO) {
-            auto_device = 1;
-        } else if (ist->hwaccel_id == HWACCEL_GENERIC) {
-            type = ist->hwaccel_device_type;
-            dev = hw_device_get_by_type(type);
-
-            // When "-qsv_device device" is used, an internal QSV device named
-            // as "__qsv_device" is created. Another QSV device is created too
-            // if "-init_hw_device qsv=name:device" is used. There are 2 QSV devices
-            // if both "-qsv_device device" and "-init_hw_device qsv=name:device"
-            // are used, hw_device_get_by_type(AV_HWDEVICE_TYPE_QSV) returns NULL.
-            // To keep back-compatibility with the removed ad-hoc libmfx setup code,
-            // call hw_device_get_by_name("__qsv_device") to select the internal QSV
-            // device.
-            if (!dev && type == AV_HWDEVICE_TYPE_QSV)
-                dev = hw_device_get_by_name("__qsv_device");
-
-            if (!dev)
-                err = hw_device_init_from_type(type, NULL, &dev);
-        } else {
-            dev = hw_device_match_by_codec(ist->dec);
-            if (!dev) {
-                // No device for this codec, but not using generic hwaccel
-                // and therefore may well not need one - ignore.
-                return 0;
-            }
-        }
-    }
-
-    if (auto_device) {
-        int i;
-        if (!avcodec_get_hw_config(ist->dec, 0)) {
-            // Decoder does not support any hardware devices.
-            return 0;
-        }
-        for (i = 0; !dev; i++) {
-            config = avcodec_get_hw_config(ist->dec, i);
-            if (!config)
-                break;
-            type = config->device_type;
-            dev = hw_device_get_by_type(type);
-            if (dev) {
-                av_log(NULL, AV_LOG_INFO, "Using auto "
-                       "hwaccel type %s with existing device %s.\n",
-                       av_hwdevice_get_type_name(type), dev->name);
-            }
-        }
-        for (i = 0; !dev; i++) {
-            config = avcodec_get_hw_config(ist->dec, i);
-            if (!config)
-                break;
-            type = config->device_type;
-            // Try to make a new device of this type.
-            err = hw_device_init_from_type(type, ist->hwaccel_device,
-                                           &dev);
-            if (err < 0) {
-                // Can't make a device of this type.
-                continue;
-            }
-            if (ist->hwaccel_device) {
-                av_log(NULL, AV_LOG_INFO, "Using auto "
-                       "hwaccel type %s with new device created "
-                       "from %s.\n", av_hwdevice_get_type_name(type),
-                       ist->hwaccel_device);
-            } else {
-                av_log(NULL, AV_LOG_INFO, "Using auto "
-                       "hwaccel type %s with new default device.\n",
-                       av_hwdevice_get_type_name(type));
-            }
-        }
-        if (dev) {
-            ist->hwaccel_device_type = type;
-        } else {
-            av_log(NULL, AV_LOG_INFO, "Auto hwaccel "
-                   "disabled: no device found.\n");
-            ist->hwaccel_id = HWACCEL_NONE;
-            return 0;
-        }
-    }
-
-    if (!dev) {
-        av_log(NULL, AV_LOG_ERROR, "No device available "
-               "for decoder: device type %s needed for codec %s.\n",
-               av_hwdevice_get_type_name(type), ist->dec->name);
-        return err;
-    }
-
-    ist->dec_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref);
-    if (!ist->dec_ctx->hw_device_ctx)
-        return AVERROR(ENOMEM);
-
-    return 0;
-}
-
 int hw_device_setup_for_encode(OutputStream *ost)
 {
     const AVCodecHWConfig *config;
-- 
2.39.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [FFmpeg-devel] [PATCH 02/15] fftools/ffmpeg_hw: move hw_device_setup_for_encode() to ffmpeg_enc
  2023-05-23 13:58 [FFmpeg-devel] [PATCH 01/15] fftools/ffmpeg_hw: move hw_device_setup_for_decode() to ffmpeg_dec Anton Khirnov
@ 2023-05-23 13:58 ` Anton Khirnov
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 03/15] fftools/ffmpeg_enc: use AVFrame.hw_frames_ctx for encoder hw setup Anton Khirnov
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Anton Khirnov @ 2023-05-23 13:58 UTC (permalink / raw)
  To: ffmpeg-devel

This function is entangled with encoder setup, so it is more encoding
code rather than ffmpeg_hw code. This will allow making more encoder
state private in the future.
---
 fftools/ffmpeg.h     |  1 -
 fftools/ffmpeg_enc.c | 55 ++++++++++++++++++++++++++++++++++++++++++++
 fftools/ffmpeg_hw.c  | 55 --------------------------------------------
 3 files changed, 55 insertions(+), 56 deletions(-)

diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 895edbd6d6..927e402f7c 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -802,7 +802,6 @@ int hw_device_init_from_type(enum AVHWDeviceType type,
                              HWDevice **dev_out);
 void hw_device_free_all(void);
 
-int hw_device_setup_for_encode(OutputStream *ost);
 /**
  * Get a hardware device to be used with this filtergraph.
  * The returned reference is owned by the callee, the caller
diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c
index 9b81d14922..7d99d9270b 100644
--- a/fftools/ffmpeg_enc.c
+++ b/fftools/ffmpeg_enc.c
@@ -103,6 +103,61 @@ fail:
     return AVERROR(ENOMEM);
 }
 
+static int hw_device_setup_for_encode(OutputStream *ost)
+{
+    const AVCodecHWConfig *config;
+    HWDevice *dev = NULL;
+    AVBufferRef *frames_ref = NULL;
+    int i;
+
+    if (ost->filter) {
+        frames_ref = av_buffersink_get_hw_frames_ctx(ost->filter->filter);
+        if (frames_ref &&
+            ((AVHWFramesContext*)frames_ref->data)->format ==
+            ost->enc_ctx->pix_fmt) {
+            // Matching format, will try to use hw_frames_ctx.
+        } else {
+            frames_ref = NULL;
+        }
+    }
+
+    for (i = 0;; i++) {
+        config = avcodec_get_hw_config(ost->enc_ctx->codec, i);
+        if (!config)
+            break;
+
+        if (frames_ref &&
+            config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX &&
+            (config->pix_fmt == AV_PIX_FMT_NONE ||
+             config->pix_fmt == ost->enc_ctx->pix_fmt)) {
+            av_log(ost->enc_ctx, AV_LOG_VERBOSE, "Using input "
+                   "frames context (format %s) with %s encoder.\n",
+                   av_get_pix_fmt_name(ost->enc_ctx->pix_fmt),
+                   ost->enc_ctx->codec->name);
+            ost->enc_ctx->hw_frames_ctx = av_buffer_ref(frames_ref);
+            if (!ost->enc_ctx->hw_frames_ctx)
+                return AVERROR(ENOMEM);
+            return 0;
+        }
+
+        if (!dev &&
+            config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX)
+            dev = hw_device_get_by_type(config->device_type);
+    }
+
+    if (dev) {
+        av_log(ost->enc_ctx, AV_LOG_VERBOSE, "Using device %s "
+               "(type %s) with %s encoder.\n", dev->name,
+               av_hwdevice_get_type_name(dev->type), ost->enc_ctx->codec->name);
+        ost->enc_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref);
+        if (!ost->enc_ctx->hw_device_ctx)
+            return AVERROR(ENOMEM);
+    } else {
+        // No device required, or no device available.
+    }
+    return 0;
+}
+
 static void set_encoder_id(OutputFile *of, OutputStream *ost)
 {
     const char *cname = ost->enc_ctx->codec->name;
diff --git a/fftools/ffmpeg_hw.c b/fftools/ffmpeg_hw.c
index d28257a1d6..4a0b346fe1 100644
--- a/fftools/ffmpeg_hw.c
+++ b/fftools/ffmpeg_hw.c
@@ -297,61 +297,6 @@ void hw_device_free_all(void)
     nb_hw_devices = 0;
 }
 
-int hw_device_setup_for_encode(OutputStream *ost)
-{
-    const AVCodecHWConfig *config;
-    HWDevice *dev = NULL;
-    AVBufferRef *frames_ref = NULL;
-    int i;
-
-    if (ost->filter) {
-        frames_ref = av_buffersink_get_hw_frames_ctx(ost->filter->filter);
-        if (frames_ref &&
-            ((AVHWFramesContext*)frames_ref->data)->format ==
-            ost->enc_ctx->pix_fmt) {
-            // Matching format, will try to use hw_frames_ctx.
-        } else {
-            frames_ref = NULL;
-        }
-    }
-
-    for (i = 0;; i++) {
-        config = avcodec_get_hw_config(ost->enc_ctx->codec, i);
-        if (!config)
-            break;
-
-        if (frames_ref &&
-            config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX &&
-            (config->pix_fmt == AV_PIX_FMT_NONE ||
-             config->pix_fmt == ost->enc_ctx->pix_fmt)) {
-            av_log(ost->enc_ctx, AV_LOG_VERBOSE, "Using input "
-                   "frames context (format %s) with %s encoder.\n",
-                   av_get_pix_fmt_name(ost->enc_ctx->pix_fmt),
-                   ost->enc_ctx->codec->name);
-            ost->enc_ctx->hw_frames_ctx = av_buffer_ref(frames_ref);
-            if (!ost->enc_ctx->hw_frames_ctx)
-                return AVERROR(ENOMEM);
-            return 0;
-        }
-
-        if (!dev &&
-            config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX)
-            dev = hw_device_get_by_type(config->device_type);
-    }
-
-    if (dev) {
-        av_log(ost->enc_ctx, AV_LOG_VERBOSE, "Using device %s "
-               "(type %s) with %s encoder.\n", dev->name,
-               av_hwdevice_get_type_name(dev->type), ost->enc_ctx->codec->name);
-        ost->enc_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref);
-        if (!ost->enc_ctx->hw_device_ctx)
-            return AVERROR(ENOMEM);
-    } else {
-        // No device required, or no device available.
-    }
-    return 0;
-}
-
 static int hwaccel_retrieve_data(AVCodecContext *avctx, AVFrame *input)
 {
     InputStream *ist = avctx->opaque;
-- 
2.39.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [FFmpeg-devel] [PATCH 03/15] fftools/ffmpeg_enc: use AVFrame.hw_frames_ctx for encoder hw setup
  2023-05-23 13:58 [FFmpeg-devel] [PATCH 01/15] fftools/ffmpeg_hw: move hw_device_setup_for_decode() to ffmpeg_dec Anton Khirnov
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 02/15] fftools/ffmpeg_hw: move hw_device_setup_for_encode() to ffmpeg_enc Anton Khirnov
@ 2023-05-23 13:58 ` Anton Khirnov
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 04/15] fftools/ffmpeg: fail earlier on text/bitmap subtitles mismatch Anton Khirnov
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Anton Khirnov @ 2023-05-23 13:58 UTC (permalink / raw)
  To: ffmpeg-devel

It should be the same as the one that can be extracted from the filter
and does not require access to outside data.
---
 fftools/ffmpeg_enc.c | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c
index 7d99d9270b..59e9466420 100644
--- a/fftools/ffmpeg_enc.c
+++ b/fftools/ffmpeg_enc.c
@@ -103,22 +103,18 @@ fail:
     return AVERROR(ENOMEM);
 }
 
-static int hw_device_setup_for_encode(OutputStream *ost)
+static int hw_device_setup_for_encode(OutputStream *ost, AVBufferRef *frames_ref)
 {
     const AVCodecHWConfig *config;
     HWDevice *dev = NULL;
-    AVBufferRef *frames_ref = NULL;
     int i;
 
-    if (ost->filter) {
-        frames_ref = av_buffersink_get_hw_frames_ctx(ost->filter->filter);
-        if (frames_ref &&
-            ((AVHWFramesContext*)frames_ref->data)->format ==
-            ost->enc_ctx->pix_fmt) {
-            // Matching format, will try to use hw_frames_ctx.
-        } else {
-            frames_ref = NULL;
-        }
+    if (frames_ref &&
+        ((AVHWFramesContext*)frames_ref->data)->format ==
+        ost->enc_ctx->pix_fmt) {
+        // Matching format, will try to use hw_frames_ctx.
+    } else {
+        frames_ref = NULL;
     }
 
     for (i = 0;; i++) {
@@ -388,7 +384,7 @@ int enc_open(OutputStream *ost, AVFrame *frame)
 
     av_dict_set(&ost->encoder_opts, "flags", "+frame_duration", AV_DICT_MULTIKEY);
 
-    ret = hw_device_setup_for_encode(ost);
+    ret = hw_device_setup_for_encode(ost, frame ? frame->hw_frames_ctx : NULL);
     if (ret < 0) {
         av_log(ost, AV_LOG_ERROR,
                "Encoding hardware device setup failed: %s\n", av_err2str(ret));
-- 
2.39.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [FFmpeg-devel] [PATCH 04/15] fftools/ffmpeg: fail earlier on text/bitmap subtitles mismatch
  2023-05-23 13:58 [FFmpeg-devel] [PATCH 01/15] fftools/ffmpeg_hw: move hw_device_setup_for_decode() to ffmpeg_dec Anton Khirnov
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 02/15] fftools/ffmpeg_hw: move hw_device_setup_for_encode() to ffmpeg_enc Anton Khirnov
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 03/15] fftools/ffmpeg_enc: use AVFrame.hw_frames_ctx for encoder hw setup Anton Khirnov
@ 2023-05-23 13:58 ` Anton Khirnov
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 05/15] fftools/ffmpeg: drop outdated comments Anton Khirnov
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Anton Khirnov @ 2023-05-23 13:58 UTC (permalink / raw)
  To: ffmpeg-devel

Checking whether the user requested an unsupported conversion between
text and bitmap subtitles can be done immediately when creating the
output stream.
---
 fftools/ffmpeg_enc.c      | 18 ------------------
 fftools/ffmpeg_mux_init.c | 17 +++++++++++++++++
 2 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c
index 59e9466420..f023657a07 100644
--- a/fftools/ffmpeg_enc.c
+++ b/fftools/ffmpeg_enc.c
@@ -345,24 +345,6 @@ int enc_open(OutputStream *ost, AVFrame *frame)
                    dec_ctx->subtitle_header_size);
             enc_ctx->subtitle_header_size = dec_ctx->subtitle_header_size;
         }
-        if (ist && ist->dec->type == AVMEDIA_TYPE_SUBTITLE &&
-            enc_ctx->codec_type == AVMEDIA_TYPE_SUBTITLE) {
-            int input_props = 0, output_props = 0;
-            AVCodecDescriptor const *input_descriptor =
-                avcodec_descriptor_get(ist->dec->id);
-            AVCodecDescriptor const *output_descriptor =
-                avcodec_descriptor_get(enc_ctx->codec_id);
-            if (input_descriptor)
-                input_props = input_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
-            if (output_descriptor)
-                output_props = output_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
-            if (input_props && output_props && input_props != output_props) {
-                av_log(ost, AV_LOG_ERROR,
-                       "Subtitle encoding currently only possible from text to text "
-                       "or bitmap to bitmap");
-                return AVERROR_INVALIDDATA;
-            }
-        }
 
         break;
     default:
diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c
index b73791acee..56f9d1215c 100644
--- a/fftools/ffmpeg_mux_init.c
+++ b/fftools/ffmpeg_mux_init.c
@@ -822,6 +822,13 @@ static void new_stream_subtitle(Muxer *mux, const OptionsContext *o,
 
     if (ost->enc_ctx) {
         AVCodecContext *subtitle_enc = ost->enc_ctx;
+
+        AVCodecDescriptor const *input_descriptor =
+            avcodec_descriptor_get(ost->ist->par->codec_id);
+        AVCodecDescriptor const *output_descriptor =
+            avcodec_descriptor_get(subtitle_enc->codec_id);
+        int input_props = 0, output_props = 0;
+
         char *frame_size = NULL;
 
         MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, mux->fc, st);
@@ -829,6 +836,16 @@ static void new_stream_subtitle(Muxer *mux, const OptionsContext *o,
             av_log(ost, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
             exit_program(1);
         }
+        if (input_descriptor)
+            input_props = input_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
+        if (output_descriptor)
+            output_props = output_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
+        if (input_props && output_props && input_props != output_props) {
+            av_log(ost, AV_LOG_ERROR,
+                   "Subtitle encoding currently only possible from text to text "
+                   "or bitmap to bitmap\n");
+            exit_program(1);
+        }
     }
 }
 
-- 
2.39.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [FFmpeg-devel] [PATCH 05/15] fftools/ffmpeg: drop outdated comments
  2023-05-23 13:58 [FFmpeg-devel] [PATCH 01/15] fftools/ffmpeg_hw: move hw_device_setup_for_decode() to ffmpeg_dec Anton Khirnov
                   ` (2 preceding siblings ...)
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 04/15] fftools/ffmpeg: fail earlier on text/bitmap subtitles mismatch Anton Khirnov
@ 2023-05-23 13:58 ` Anton Khirnov
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 06/15] fftools/ffmpeg_demux: only print demuxing stats if demuxing actually started Anton Khirnov
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Anton Khirnov @ 2023-05-23 13:58 UTC (permalink / raw)
  To: ffmpeg-devel

---
 fftools/ffmpeg.c       | 1 -
 fftools/ffmpeg_demux.c | 1 -
 2 files changed, 2 deletions(-)

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index c70d38755b..1fc13b3e29 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -1431,7 +1431,6 @@ int main(int argc, char **argv)
         exit_program(1);
     }
 
-    /* file converter / grab */
     if (nb_output_files <= 0) {
         av_log(NULL, AV_LOG_FATAL, "At least one output file must be specified\n");
         exit_program(1);
diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c
index 401ae1f850..7318abc6d9 100644
--- a/fftools/ffmpeg_demux.c
+++ b/fftools/ffmpeg_demux.c
@@ -1569,7 +1569,6 @@ int ifile_open(const OptionsContext *o, const char *filename)
 
     d->thread_queue_size = o->thread_queue_size;
 
-    /* update the current parameters so that they match the one of the input stream */
     add_input_streams(o, d);
 
     /* dump the file content */
-- 
2.39.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [FFmpeg-devel] [PATCH 06/15] fftools/ffmpeg_demux: only print demuxing stats if demuxing actually started
  2023-05-23 13:58 [FFmpeg-devel] [PATCH 01/15] fftools/ffmpeg_hw: move hw_device_setup_for_decode() to ffmpeg_dec Anton Khirnov
                   ` (3 preceding siblings ...)
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 05/15] fftools/ffmpeg: drop outdated comments Anton Khirnov
@ 2023-05-23 13:58 ` Anton Khirnov
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 07/15] fftools/ffmpeg_demux: initialize nb_streams_warn Anton Khirnov
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Anton Khirnov @ 2023-05-23 13:58 UTC (permalink / raw)
  To: ffmpeg-devel

If the transcoding process never got to reading any packets from this
input then printing stats is just pointless noise.
---
 fftools/ffmpeg_demux.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c
index 7318abc6d9..ed8d5d165a 100644
--- a/fftools/ffmpeg_demux.c
+++ b/fftools/ffmpeg_demux.c
@@ -113,6 +113,8 @@ typedef struct Demuxer {
     int                   thread_queue_size;
     pthread_t             thread;
     int                   non_blocking;
+
+    int                   read_started;
 } Demuxer;
 
 typedef struct DemuxMsg {
@@ -734,6 +736,8 @@ static int thread_start(Demuxer *d)
         goto fail;
     }
 
+    d->read_started = 1;
+
     return 0;
 fail:
     av_thread_message_queue_free(&d->in_thread_queue);
@@ -833,7 +837,7 @@ void ifile_close(InputFile **pf)
 
     thread_stop(d);
 
-    if (f->ctx)
+    if (d->read_started)
         demux_final_stats(d);
 
     for (int i = 0; i < f->nb_streams; i++)
-- 
2.39.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [FFmpeg-devel] [PATCH 07/15] fftools/ffmpeg_demux: initialize nb_streams_warn
  2023-05-23 13:58 [FFmpeg-devel] [PATCH 01/15] fftools/ffmpeg_hw: move hw_device_setup_for_decode() to ffmpeg_dec Anton Khirnov
                   ` (4 preceding siblings ...)
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 06/15] fftools/ffmpeg_demux: only print demuxing stats if demuxing actually started Anton Khirnov
@ 2023-05-23 13:58 ` Anton Khirnov
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 08/15] fftools/ffmpeg_demux: skip unused/attachment streams in final stats Anton Khirnov
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Anton Khirnov @ 2023-05-23 13:58 UTC (permalink / raw)
  To: ffmpeg-devel

Fixes spurious new-stream warnings for unused streams after
9429624a76107020b5911f8307f366fed386b336
---
 fftools/ffmpeg_demux.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c
index ed8d5d165a..bd267aa0ce 100644
--- a/fftools/ffmpeg_demux.c
+++ b/fftools/ffmpeg_demux.c
@@ -1543,6 +1543,7 @@ int ifile_open(const OptionsContext *o, const char *filename)
     d->loop = o->loop;
     d->duration = 0;
     d->time_base = (AVRational){ 1, 1 };
+    d->nb_streams_warn = ic->nb_streams;
 
     f->format_nots = !!(ic->iformat->flags & AVFMT_NOTIMESTAMPS);
 
-- 
2.39.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [FFmpeg-devel] [PATCH 08/15] fftools/ffmpeg_demux: skip unused/attachment streams in final stats
  2023-05-23 13:58 [FFmpeg-devel] [PATCH 01/15] fftools/ffmpeg_hw: move hw_device_setup_for_decode() to ffmpeg_dec Anton Khirnov
                   ` (5 preceding siblings ...)
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 07/15] fftools/ffmpeg_demux: initialize nb_streams_warn Anton Khirnov
@ 2023-05-23 13:58 ` Anton Khirnov
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 09/15] fftools/ffmpeg_dec: add decoder private data Anton Khirnov
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Anton Khirnov @ 2023-05-23 13:58 UTC (permalink / raw)
  To: ffmpeg-devel

No useful information can be printed for them.
---
 fftools/ffmpeg_demux.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c
index bd267aa0ce..33322ac565 100644
--- a/fftools/ffmpeg_demux.c
+++ b/fftools/ffmpeg_demux.c
@@ -781,6 +781,9 @@ static void demux_final_stats(Demuxer *d)
         DemuxStream  *ds = ds_from_ist(ist);
         enum AVMediaType type = ist->par->codec_type;
 
+        if (ist->discard || type == AVMEDIA_TYPE_ATTACHMENT)
+            continue;
+
         total_size    += ds->data_size;
         total_packets += ds->nb_packets;
 
-- 
2.39.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [FFmpeg-devel] [PATCH 09/15] fftools/ffmpeg_dec: add decoder private data
  2023-05-23 13:58 [FFmpeg-devel] [PATCH 01/15] fftools/ffmpeg_hw: move hw_device_setup_for_decode() to ffmpeg_dec Anton Khirnov
                   ` (6 preceding siblings ...)
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 08/15] fftools/ffmpeg_demux: skip unused/attachment streams in final stats Anton Khirnov
@ 2023-05-23 13:58 ` Anton Khirnov
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 10/15] fftools/ffmpeg_dec: move InputStream.pkt to Decoder Anton Khirnov
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Anton Khirnov @ 2023-05-23 13:58 UTC (permalink / raw)
  To: ffmpeg-devel

Move InputStream.decoded_frame to it.

Analogous to what has been previously done for all the other major
components.
---
 fftools/ffmpeg.h       |  5 ++++-
 fftools/ffmpeg_dec.c   | 46 +++++++++++++++++++++++++++++++++++++++++-
 fftools/ffmpeg_demux.c |  7 ++-----
 3 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 927e402f7c..92e56ee80c 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -324,6 +324,8 @@ typedef struct FilterGraph {
     int         nb_outputs;
 } FilterGraph;
 
+typedef struct Decoder Decoder;
+
 typedef struct InputStream {
     const AVClass *class;
 
@@ -343,10 +345,10 @@ typedef struct InputStream {
      * concurrently by the demuxing thread.
      */
     AVCodecParameters *par;
+    Decoder *decoder;
     AVCodecContext *dec_ctx;
     const AVCodec *dec;
     const AVCodecDescriptor *codec_desc;
-    AVFrame *decoded_frame;
     AVPacket *pkt;
 
     AVRational framerate_guessed;
@@ -812,6 +814,7 @@ AVBufferRef *hw_device_for_filter(void);
 int hwaccel_decode_init(AVCodecContext *avctx);
 
 int dec_open(InputStream *ist);
+void dec_free(Decoder **pdec);
 
 /**
  * Submit a packet for decoding
diff --git a/fftools/ffmpeg_dec.c b/fftools/ffmpeg_dec.c
index 0a470c4854..f4531684d5 100644
--- a/fftools/ffmpeg_dec.c
+++ b/fftools/ffmpeg_dec.c
@@ -31,6 +31,45 @@
 
 #include "ffmpeg.h"
 
+struct Decoder {
+    AVFrame         *frame;
+};
+
+void dec_free(Decoder **pdec)
+{
+    Decoder *dec = *pdec;
+
+    if (!dec)
+        return;
+
+    av_frame_free(&dec->frame);
+
+    av_freep(pdec);
+}
+
+static int dec_alloc(Decoder **pdec)
+{
+    Decoder *dec;
+
+    *pdec = NULL;
+
+    dec = av_mallocz(sizeof(*dec));
+    if (!dec)
+        return AVERROR(ENOMEM);
+
+    dec->frame = av_frame_alloc();
+    if (!dec->frame)
+        goto fail;
+
+
+    *pdec = dec;
+
+    return 0;
+fail:
+    dec_free(&dec);
+    return AVERROR(ENOMEM);
+}
+
 static int send_frame_to_filters(InputStream *ist, AVFrame *decoded_frame)
 {
     int i, ret;
@@ -373,6 +412,7 @@ static int send_filter_eof(InputStream *ist)
 
 int dec_packet(InputStream *ist, const AVPacket *pkt, int no_eof)
 {
+    Decoder *d = ist->decoder;
     AVCodecContext *dec = ist->dec_ctx;
     const char *type_desc = av_get_media_type_string(dec->codec_type);
     int ret;
@@ -402,7 +442,7 @@ int dec_packet(InputStream *ist, const AVPacket *pkt, int no_eof)
     }
 
     while (1) {
-        AVFrame *frame = ist->decoded_frame;
+        AVFrame *frame = d->frame;
 
         update_benchmark(NULL);
         ret = avcodec_receive_frame(dec, frame);
@@ -685,6 +725,10 @@ int dec_open(InputStream *ist)
         return AVERROR(EINVAL);
     }
 
+    ret = dec_alloc(&ist->decoder);
+    if (ret < 0)
+        return ret;
+
     ist->dec_ctx->opaque                = ist;
     ist->dec_ctx->get_format            = get_format;
 
diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c
index 33322ac565..29691cf68b 100644
--- a/fftools/ffmpeg_demux.c
+++ b/fftools/ffmpeg_demux.c
@@ -815,7 +815,8 @@ static void ist_free(InputStream **pist)
     if (!ist)
         return;
 
-    av_frame_free(&ist->decoded_frame);
+    dec_free(&ist->decoder);
+
     av_packet_free(&ist->pkt);
     av_dict_free(&ist->decoder_opts);
     avsubtitle_free(&ist->prev_sub.subtitle);
@@ -1196,10 +1197,6 @@ static void add_input_streams(const OptionsContext *o, Demuxer *d)
             exit_program(1);
         }
 
-        ist->decoded_frame = av_frame_alloc();
-        if (!ist->decoded_frame)
-            report_and_exit(AVERROR(ENOMEM));
-
         ist->pkt = av_packet_alloc();
         if (!ist->pkt)
             report_and_exit(AVERROR(ENOMEM));
-- 
2.39.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [FFmpeg-devel] [PATCH 10/15] fftools/ffmpeg_dec: move InputStream.pkt to Decoder
  2023-05-23 13:58 [FFmpeg-devel] [PATCH 01/15] fftools/ffmpeg_hw: move hw_device_setup_for_decode() to ffmpeg_dec Anton Khirnov
                   ` (7 preceding siblings ...)
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 09/15] fftools/ffmpeg_dec: add decoder private data Anton Khirnov
@ 2023-05-23 13:58 ` Anton Khirnov
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 11/15] fftools/ffmpeg_dec: move timestamp estimation state " Anton Khirnov
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Anton Khirnov @ 2023-05-23 13:58 UTC (permalink / raw)
  To: ffmpeg-devel

It is purely internal to decoding.
---
 fftools/ffmpeg.h       | 1 -
 fftools/ffmpeg_dec.c   | 8 +++++++-
 fftools/ffmpeg_demux.c | 5 -----
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 92e56ee80c..b377871980 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -349,7 +349,6 @@ typedef struct InputStream {
     AVCodecContext *dec_ctx;
     const AVCodec *dec;
     const AVCodecDescriptor *codec_desc;
-    AVPacket *pkt;
 
     AVRational framerate_guessed;
 
diff --git a/fftools/ffmpeg_dec.c b/fftools/ffmpeg_dec.c
index f4531684d5..23c50cc272 100644
--- a/fftools/ffmpeg_dec.c
+++ b/fftools/ffmpeg_dec.c
@@ -33,6 +33,7 @@
 
 struct Decoder {
     AVFrame         *frame;
+    AVPacket        *pkt;
 };
 
 void dec_free(Decoder **pdec)
@@ -43,6 +44,7 @@ void dec_free(Decoder **pdec)
         return;
 
     av_frame_free(&dec->frame);
+    av_packet_free(&dec->pkt);
 
     av_freep(pdec);
 }
@@ -61,6 +63,10 @@ static int dec_alloc(Decoder **pdec)
     if (!dec->frame)
         goto fail;
 
+    dec->pkt = av_packet_alloc();
+    if (!dec->pkt)
+        goto fail;
+
 
     *pdec = dec;
 
@@ -418,7 +424,7 @@ int dec_packet(InputStream *ist, const AVPacket *pkt, int no_eof)
     int ret;
 
     if (dec->codec_type == AVMEDIA_TYPE_SUBTITLE)
-        return transcode_subtitles(ist, pkt ? pkt : ist->pkt);
+        return transcode_subtitles(ist, pkt ? pkt : d->pkt);
 
     // With fate-indeo3-2, we're getting 0-sized packets before EOF for some
     // reason. This seems like a semi-critical bug. Don't trigger EOF, and
diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c
index 29691cf68b..c65c72f556 100644
--- a/fftools/ffmpeg_demux.c
+++ b/fftools/ffmpeg_demux.c
@@ -817,7 +817,6 @@ static void ist_free(InputStream **pist)
 
     dec_free(&ist->decoder);
 
-    av_packet_free(&ist->pkt);
     av_dict_free(&ist->decoder_opts);
     avsubtitle_free(&ist->prev_sub.subtitle);
     av_frame_free(&ist->sub2video.frame);
@@ -1197,10 +1196,6 @@ static void add_input_streams(const OptionsContext *o, Demuxer *d)
             exit_program(1);
         }
 
-        ist->pkt = av_packet_alloc();
-        if (!ist->pkt)
-            report_and_exit(AVERROR(ENOMEM));
-
         if (o->bitexact)
             ist->dec_ctx->flags |= AV_CODEC_FLAG_BITEXACT;
 
-- 
2.39.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [FFmpeg-devel] [PATCH 11/15] fftools/ffmpeg_dec: move timestamp estimation state to Decoder
  2023-05-23 13:58 [FFmpeg-devel] [PATCH 01/15] fftools/ffmpeg_hw: move hw_device_setup_for_decode() to ffmpeg_dec Anton Khirnov
                   ` (8 preceding siblings ...)
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 10/15] fftools/ffmpeg_dec: move InputStream.pkt to Decoder Anton Khirnov
@ 2023-05-23 13:58 ` Anton Khirnov
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 12/15] fftools/ffmpeg: add InputStream.index Anton Khirnov
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Anton Khirnov @ 2023-05-23 13:58 UTC (permalink / raw)
  To: ffmpeg-devel

It is purely internal to decoding.
---
 fftools/ffmpeg.h       | 10 -----
 fftools/ffmpeg_dec.c   | 87 +++++++++++++++++++++++++-----------------
 fftools/ffmpeg_demux.c |  5 ---
 3 files changed, 52 insertions(+), 50 deletions(-)

diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index b377871980..d9cac95710 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -352,16 +352,6 @@ typedef struct InputStream {
 
     AVRational framerate_guessed;
 
-    // pts/estimated duration of the last decoded frame
-    // * in decoder timebase for video,
-    // * in last_frame_tb (may change during decoding) for audio
-    int64_t last_frame_pts;
-    int64_t last_frame_duration_est;
-    AVRational    last_frame_tb;
-    int           last_frame_sample_rate;
-
-    int64_t filter_in_rescale_delta_last;
-
     int64_t nb_samples; /* number of samples in the last decoded audio frame before looping */
 
     AVDictionary *decoder_opts;
diff --git a/fftools/ffmpeg_dec.c b/fftools/ffmpeg_dec.c
index 23c50cc272..c952473c16 100644
--- a/fftools/ffmpeg_dec.c
+++ b/fftools/ffmpeg_dec.c
@@ -34,6 +34,15 @@
 struct Decoder {
     AVFrame         *frame;
     AVPacket        *pkt;
+
+    // pts/estimated duration of the last decoded frame
+    // * in decoder timebase for video,
+    // * in last_frame_tb (may change during decoding) for audio
+    int64_t         last_frame_pts;
+    int64_t         last_frame_duration_est;
+    AVRational      last_frame_tb;
+    int64_t         last_filter_in_rescale_delta;
+    int             last_frame_sample_rate;
 };
 
 void dec_free(Decoder **pdec)
@@ -67,6 +76,9 @@ static int dec_alloc(Decoder **pdec)
     if (!dec->pkt)
         goto fail;
 
+    dec->last_filter_in_rescale_delta = AV_NOPTS_VALUE;
+    dec->last_frame_pts               = AV_NOPTS_VALUE;
+    dec->last_frame_tb                = (AVRational){ 1, 1 };
 
     *pdec = dec;
 
@@ -94,21 +106,22 @@ static int send_frame_to_filters(InputStream *ist, AVFrame *decoded_frame)
     return ret;
 }
 
-static AVRational audio_samplerate_update(InputStream *ist, const AVFrame *frame)
+static AVRational audio_samplerate_update(void *logctx, Decoder *d,
+                                          const AVFrame *frame)
 {
-    const int prev = ist->last_frame_tb.den;
+    const int prev = d->last_frame_tb.den;
     const int sr   = frame->sample_rate;
 
     AVRational tb_new;
     int64_t gcd;
 
-    if (frame->sample_rate == ist->last_frame_sample_rate)
+    if (frame->sample_rate == d->last_frame_sample_rate)
         goto finish;
 
     gcd  = av_gcd(prev, sr);
 
     if (prev / gcd >= INT_MAX / sr) {
-        av_log(ist, AV_LOG_WARNING,
+        av_log(logctx, AV_LOG_WARNING,
                "Audio timestamps cannot be represented exactly after "
                "sample rate change: %d -> %d\n", prev, sr);
 
@@ -123,20 +136,20 @@ static AVRational audio_samplerate_update(InputStream *ist, const AVFrame *frame
         !(frame->time_base.den % tb_new.den))
         tb_new = frame->time_base;
 
-    if (ist->last_frame_pts != AV_NOPTS_VALUE)
-        ist->last_frame_pts = av_rescale_q(ist->last_frame_pts,
-                                           ist->last_frame_tb, tb_new);
-    ist->last_frame_duration_est = av_rescale_q(ist->last_frame_duration_est,
-                                                ist->last_frame_tb, tb_new);
+    if (d->last_frame_pts != AV_NOPTS_VALUE)
+        d->last_frame_pts = av_rescale_q(d->last_frame_pts,
+                                         d->last_frame_tb, tb_new);
+    d->last_frame_duration_est = av_rescale_q(d->last_frame_duration_est,
+                                              d->last_frame_tb, tb_new);
 
-    ist->last_frame_tb          = tb_new;
-    ist->last_frame_sample_rate = frame->sample_rate;
+    d->last_frame_tb          = tb_new;
+    d->last_frame_sample_rate = frame->sample_rate;
 
 finish:
-    return ist->last_frame_tb;
+    return d->last_frame_tb;
 }
 
-static void audio_ts_process(InputStream *ist, AVFrame *frame)
+static void audio_ts_process(void *logctx, Decoder *d, AVFrame *frame)
 {
     AVRational tb_filter = (AVRational){1, frame->sample_rate};
     AVRational tb;
@@ -145,27 +158,27 @@ static void audio_ts_process(InputStream *ist, AVFrame *frame)
     // on samplerate change, choose a new internal timebase for timestamp
     // generation that can represent timestamps from all the samplerates
     // seen so far
-    tb = audio_samplerate_update(ist, frame);
-    pts_pred = ist->last_frame_pts == AV_NOPTS_VALUE ? 0 :
-               ist->last_frame_pts + ist->last_frame_duration_est;
+    tb = audio_samplerate_update(logctx, d, frame);
+    pts_pred = d->last_frame_pts == AV_NOPTS_VALUE ? 0 :
+               d->last_frame_pts + d->last_frame_duration_est;
 
     if (frame->pts == AV_NOPTS_VALUE) {
         frame->pts = pts_pred;
         frame->time_base = tb;
-    } else if (ist->last_frame_pts != AV_NOPTS_VALUE &&
+    } else if (d->last_frame_pts != AV_NOPTS_VALUE &&
                frame->pts > av_rescale_q_rnd(pts_pred, tb, frame->time_base,
                                              AV_ROUND_UP)) {
         // there was a gap in timestamps, reset conversion state
-        ist->filter_in_rescale_delta_last = AV_NOPTS_VALUE;
+        d->last_filter_in_rescale_delta = AV_NOPTS_VALUE;
     }
 
     frame->pts = av_rescale_delta(frame->time_base, frame->pts,
                                   tb, frame->nb_samples,
-                                  &ist->filter_in_rescale_delta_last, tb);
+                                  &d->last_filter_in_rescale_delta, tb);
 
-    ist->last_frame_pts          = frame->pts;
-    ist->last_frame_duration_est = av_rescale_q(frame->nb_samples,
-                                                tb_filter, tb);
+    d->last_frame_pts          = frame->pts;
+    d->last_frame_duration_est = av_rescale_q(frame->nb_samples,
+                                              tb_filter, tb);
 
     // finally convert to filtering timebase
     frame->pts       = av_rescale_q(frame->pts, tb, tb_filter);
@@ -175,6 +188,7 @@ static void audio_ts_process(InputStream *ist, AVFrame *frame)
 
 static int64_t video_duration_estimate(const InputStream *ist, const AVFrame *frame)
 {
+    const Decoder         *d = ist->decoder;
     const InputFile   *ifile = input_files[ist->file_index];
     int64_t codec_duration = 0;
 
@@ -202,9 +216,9 @@ static int64_t video_duration_estimate(const InputStream *ist, const AVFrame *fr
 
     // when timestamps are available, repeat last frame's actual duration
     // (i.e. pts difference between this and last frame)
-    if (frame->pts != AV_NOPTS_VALUE && ist->last_frame_pts != AV_NOPTS_VALUE &&
-        frame->pts > ist->last_frame_pts)
-        return frame->pts - ist->last_frame_pts;
+    if (frame->pts != AV_NOPTS_VALUE && d->last_frame_pts != AV_NOPTS_VALUE &&
+        frame->pts > d->last_frame_pts)
+        return frame->pts - d->last_frame_pts;
 
     // try frame/codec duration
     if (frame->duration > 0)
@@ -221,11 +235,13 @@ static int64_t video_duration_estimate(const InputStream *ist, const AVFrame *fr
     }
 
     // last resort is last frame's estimated duration, and 1
-    return FFMAX(ist->last_frame_duration_est, 1);
+    return FFMAX(d->last_frame_duration_est, 1);
 }
 
 static int video_frame_process(InputStream *ist, AVFrame *frame)
 {
+    Decoder *d = ist->decoder;
+
     // The following line may be required in some cases where there is no parser
     // or the parser does not has_b_frames correctly
     if (ist->par->video_delay < ist->dec_ctx->has_b_frames) {
@@ -273,13 +289,13 @@ static int video_frame_process(InputStream *ist, AVFrame *frame)
 
     // no timestamp available - extrapolate from previous frame duration
     if (frame->pts == AV_NOPTS_VALUE)
-        frame->pts = ist->last_frame_pts == AV_NOPTS_VALUE ? 0 :
-                     ist->last_frame_pts + ist->last_frame_duration_est;
+        frame->pts = d->last_frame_pts == AV_NOPTS_VALUE ? 0 :
+                     d->last_frame_pts + d->last_frame_duration_est;
 
     // update timestamp history
-    ist->last_frame_duration_est = video_duration_estimate(ist, frame);
-    ist->last_frame_pts          = frame->pts;
-    ist->last_frame_tb           = frame->time_base;
+    d->last_frame_duration_est = video_duration_estimate(ist, frame);
+    d->last_frame_pts          = frame->pts;
+    d->last_frame_tb           = frame->time_base;
 
     if (debug_ts) {
         av_log(ist, AV_LOG_INFO,
@@ -404,12 +420,13 @@ static int transcode_subtitles(InputStream *ist, const AVPacket *pkt)
 
 static int send_filter_eof(InputStream *ist)
 {
+    Decoder *d = ist->decoder;
     int i, ret;
 
     for (i = 0; i < ist->nb_filters; i++) {
-        int64_t end_pts = ist->last_frame_pts == AV_NOPTS_VALUE ? AV_NOPTS_VALUE :
-                          ist->last_frame_pts + ist->last_frame_duration_est;
-        ret = ifilter_send_eof(ist->filters[i], end_pts, ist->last_frame_tb);
+        int64_t end_pts = d->last_frame_pts == AV_NOPTS_VALUE ? AV_NOPTS_VALUE :
+                          d->last_frame_pts + d->last_frame_duration_est;
+        ret = ifilter_send_eof(ist->filters[i], end_pts, d->last_frame_tb);
         if (ret < 0)
             return ret;
     }
@@ -506,7 +523,7 @@ int dec_packet(InputStream *ist, const AVPacket *pkt, int no_eof)
             ist->samples_decoded += frame->nb_samples;
             ist->nb_samples       = frame->nb_samples;
 
-            audio_ts_process(ist, frame);
+            audio_ts_process(ist, ist->decoder, frame);
         } else {
             ret = video_frame_process(ist, frame);
             if (ret < 0) {
diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c
index c65c72f556..e02bdc3b96 100644
--- a/fftools/ffmpeg_demux.c
+++ b/fftools/ffmpeg_demux.c
@@ -1181,11 +1181,6 @@ static void add_input_streams(const OptionsContext *o, Demuxer *d)
             exit_program(1);
         }
 
-        ist->filter_in_rescale_delta_last = AV_NOPTS_VALUE;
-
-        ist->last_frame_pts = AV_NOPTS_VALUE;
-        ist->last_frame_tb  = (AVRational){ 1, 1 };
-
         ist->dec_ctx = avcodec_alloc_context3(ist->dec);
         if (!ist->dec_ctx)
             report_and_exit(AVERROR(ENOMEM));
-- 
2.39.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [FFmpeg-devel] [PATCH 12/15] fftools/ffmpeg: add InputStream.index
  2023-05-23 13:58 [FFmpeg-devel] [PATCH 01/15] fftools/ffmpeg_hw: move hw_device_setup_for_decode() to ffmpeg_dec Anton Khirnov
                   ` (9 preceding siblings ...)
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 11/15] fftools/ffmpeg_dec: move timestamp estimation state " Anton Khirnov
@ 2023-05-23 13:58 ` Anton Khirnov
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 13/15] fftools/ffmpeg_demux: log discontinuity warnings to stream context Anton Khirnov
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Anton Khirnov @ 2023-05-23 13:58 UTC (permalink / raw)
  To: ffmpeg-devel

This allows to avoid access to the underlying AVStream in many places.
---
 fftools/ffmpeg.c          |  6 +++---
 fftools/ffmpeg.h          |  2 ++
 fftools/ffmpeg_dec.c      |  6 +++---
 fftools/ffmpeg_demux.c    |  1 +
 fftools/ffmpeg_filter.c   | 10 +++++-----
 fftools/ffmpeg_mux_init.c |  2 +-
 6 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 1fc13b3e29..0539a45856 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -539,7 +539,7 @@ OutputStream *ost_iter(OutputStream *prev)
 InputStream *ist_iter(InputStream *prev)
 {
     int if_idx  = prev ? prev->file_index : 0;
-    int ist_idx = prev ? prev->st->index + 1  : 0;
+    int ist_idx = prev ? prev->index + 1  : 0;
 
     for (; if_idx < nb_input_files; if_idx++) {
         InputFile *f = input_files[if_idx];
@@ -937,7 +937,7 @@ static void print_stream_maps(void)
         for (int j = 0; j < ist->nb_filters; j++) {
             if (!filtergraph_is_simple(ist->filters[j]->graph)) {
                 av_log(NULL, AV_LOG_INFO, "  Stream #%d:%d (%s) -> %s",
-                       ist->file_index, ist->st->index, ist->dec ? ist->dec->name : "?",
+                       ist->file_index, ist->index, ist->dec ? ist->dec->name : "?",
                        ist->filters[j]->name);
                 if (nb_filtergraphs > 1)
                     av_log(NULL, AV_LOG_INFO, " (graph %d)", ist->filters[j]->graph->index);
@@ -967,7 +967,7 @@ static void print_stream_maps(void)
 
         av_log(NULL, AV_LOG_INFO, "  Stream #%d:%d -> #%d:%d",
                ost->ist->file_index,
-               ost->ist->st->index,
+               ost->ist->index,
                ost->file_index,
                ost->index);
         if (ost->enc_ctx) {
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index d9cac95710..95334825ef 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -330,6 +330,8 @@ typedef struct InputStream {
     const AVClass *class;
 
     int file_index;
+    int index;
+
     AVStream *st;
     int discard;             /* true if stream data should be discarded */
     int user_set_discard;
diff --git a/fftools/ffmpeg_dec.c b/fftools/ffmpeg_dec.c
index c952473c16..afb2612ae8 100644
--- a/fftools/ffmpeg_dec.c
+++ b/fftools/ffmpeg_dec.c
@@ -470,7 +470,7 @@ int dec_packet(InputStream *ist, const AVPacket *pkt, int no_eof)
         update_benchmark(NULL);
         ret = avcodec_receive_frame(dec, frame);
         update_benchmark("decode_%s %d.%d", type_desc,
-                         ist->file_index, ist->st->index);
+                         ist->file_index, ist->index);
 
         if (ret == AVERROR(EAGAIN)) {
             av_assert0(pkt); // should never happen during flushing
@@ -528,7 +528,7 @@ int dec_packet(InputStream *ist, const AVPacket *pkt, int no_eof)
             ret = video_frame_process(ist, frame);
             if (ret < 0) {
                 av_log(NULL, AV_LOG_FATAL, "Error while processing the decoded "
-                       "data for stream #%d:%d\n", ist->file_index, ist->st->index);
+                       "data for stream #%d:%d\n", ist->file_index, ist->index);
                 exit_program(1);
             }
         }
@@ -577,7 +577,7 @@ static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat
                            "%s hwaccel requested for input stream #%d:%d, "
                            "but cannot be initialized.\n",
                            av_hwdevice_get_type_name(config->device_type),
-                           ist->file_index, ist->st->index);
+                           ist->file_index, ist->index);
                     return AV_PIX_FMT_NONE;
                 }
                 continue;
diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c
index e02bdc3b96..828a1182f0 100644
--- a/fftools/ffmpeg_demux.c
+++ b/fftools/ffmpeg_demux.c
@@ -1025,6 +1025,7 @@ static DemuxStream *demux_stream_alloc(Demuxer *d, AVStream *st)
 
     ds->ist.st         = st;
     ds->ist.file_index = f->index;
+    ds->ist.index      = st->index;
     ds->ist.class      = &input_stream_class;
 
     snprintf(ds->log_name, sizeof(ds->log_name), "%cist#%d:%d/%s",
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 640ecec067..f37b867b31 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -1073,7 +1073,7 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
     if (fr.num && fr.den)
         av_bprintf(&args, ":frame_rate=%d/%d", fr.num, fr.den);
     snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index,
-             ist->file_index, ist->st->index);
+             ist->file_index, ist->index);
 
 
     if ((ret = avfilter_graph_create_filter(&ifilter->filter, buffer_filt, name,
@@ -1127,7 +1127,7 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
     }
 
     snprintf(name, sizeof(name), "trim_in_%d_%d",
-             ist->file_index, ist->st->index);
+             ist->file_index, ist->index);
     if (copy_ts) {
         tsoffset = f->start_time == AV_NOPTS_VALUE ? 0 : f->start_time;
         if (!start_at_zero && f->ctx->start_time != AV_NOPTS_VALUE)
@@ -1180,7 +1180,7 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
     } else
         av_bprintf(&args, ":channels=%d", ifp->ch_layout.nb_channels);
     snprintf(name, sizeof(name), "graph_%d_in_%d_%d", fg->index,
-             ist->file_index, ist->st->index);
+             ist->file_index, ist->index);
 
     if ((ret = avfilter_graph_create_filter(&ifilter->filter, abuffer_filt,
                                             name, args.str, NULL,
@@ -1189,7 +1189,7 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
     last_filter = ifilter->filter;
 
     snprintf(name, sizeof(name), "trim for input stream %d:%d",
-             ist->file_index, ist->st->index);
+             ist->file_index, ist->index);
     if (copy_ts) {
         tsoffset = f->start_time == AV_NOPTS_VALUE ? 0 : f->start_time;
         if (!start_at_zero && f->ctx->start_time != AV_NOPTS_VALUE)
@@ -1574,7 +1574,7 @@ int ifilter_send_eof(InputFilter *ifilter, int64_t pts, AVRational tb)
              ifp->type_src == AVMEDIA_TYPE_VIDEO)) {
             av_log(NULL, AV_LOG_ERROR,
                    "Cannot determine format of input stream %d:%d after EOF\n",
-                   ifp->ist->file_index, ifp->ist->st->index);
+                   ifp->ist->file_index, ifp->ist->index);
             return AVERROR_INVALIDDATA;
         }
     }
diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c
index 56f9d1215c..dc33d225df 100644
--- a/fftools/ffmpeg_mux_init.c
+++ b/fftools/ffmpeg_mux_init.c
@@ -792,7 +792,7 @@ static void new_stream_audio(Muxer *mux, const OptionsContext *o,
                     ist = ost->ist;
                 }
 
-                if (!ist || (ist->file_index == map->file_idx && ist->st->index == map->stream_idx)) {
+                if (!ist || (ist->file_index == map->file_idx && ist->index == map->stream_idx)) {
                     if (av_reallocp_array(&ost->audio_channels_map,
                                           ost->audio_channels_mapped + 1,
                                           sizeof(*ost->audio_channels_map)
-- 
2.39.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [FFmpeg-devel] [PATCH 13/15] fftools/ffmpeg_demux: log discontinuity warnings to stream context
  2023-05-23 13:58 [FFmpeg-devel] [PATCH 01/15] fftools/ffmpeg_hw: move hw_device_setup_for_decode() to ffmpeg_dec Anton Khirnov
                   ` (10 preceding siblings ...)
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 12/15] fftools/ffmpeg: add InputStream.index Anton Khirnov
@ 2023-05-23 13:58 ` Anton Khirnov
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 14/15] fftools/sync_queue: add debug logging Anton Khirnov
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 15/15] fftools/sync_queue: make sure non-limiting streams are not used as queue head Anton Khirnov
  13 siblings, 0 replies; 16+ messages in thread
From: Anton Khirnov @ 2023-05-23 13:58 UTC (permalink / raw)
  To: ffmpeg-devel

Allows simplifying the log message.
---
 fftools/ffmpeg_demux.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c
index 828a1182f0..561b4b0002 100644
--- a/fftools/ffmpeg_demux.c
+++ b/fftools/ffmpeg_demux.c
@@ -248,12 +248,10 @@ static void ts_discontinuity_detect(Demuxer *d, InputStream *ist,
             if (FFABS(delta) > 1LL * dts_delta_threshold * AV_TIME_BASE ||
                 pkt_dts + AV_TIME_BASE/10 < ds->dts) {
                 d->ts_offset_discont -= delta;
-                av_log(NULL, AV_LOG_WARNING,
-                       "timestamp discontinuity for stream #%d:%d "
-                       "(id=%d, type=%s): %"PRId64", new offset= %"PRId64"\n",
-                       ist->file_index, ist->st->index, ist->st->id,
-                       av_get_media_type_string(ist->par->codec_type),
-                       delta, d->ts_offset_discont);
+                av_log(ist, AV_LOG_WARNING,
+                       "timestamp discontinuity "
+                       "(stream id=%d): %"PRId64", new offset= %"PRId64"\n",
+                       ist->st->id, delta, d->ts_offset_discont);
                 pkt->dts -= av_rescale_q(delta, AV_TIME_BASE_Q, pkt->time_base);
                 if (pkt->pts != AV_NOPTS_VALUE)
                     pkt->pts -= av_rescale_q(delta, AV_TIME_BASE_Q, pkt->time_base);
-- 
2.39.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [FFmpeg-devel] [PATCH 14/15] fftools/sync_queue: add debug logging
  2023-05-23 13:58 [FFmpeg-devel] [PATCH 01/15] fftools/ffmpeg_hw: move hw_device_setup_for_decode() to ffmpeg_dec Anton Khirnov
                   ` (11 preceding siblings ...)
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 13/15] fftools/ffmpeg_demux: log discontinuity warnings to stream context Anton Khirnov
@ 2023-05-23 13:58 ` Anton Khirnov
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 15/15] fftools/sync_queue: make sure non-limiting streams are not used as queue head Anton Khirnov
  13 siblings, 0 replies; 16+ messages in thread
From: Anton Khirnov @ 2023-05-23 13:58 UTC (permalink / raw)
  To: ffmpeg-devel

---
 fftools/ffmpeg_mux_init.c |  4 ++--
 fftools/sync_queue.c      | 40 ++++++++++++++++++++++++++++++++++++---
 fftools/sync_queue.h      |  2 +-
 3 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c
index dc33d225df..7878789bb4 100644
--- a/fftools/ffmpeg_mux_init.c
+++ b/fftools/ffmpeg_mux_init.c
@@ -1625,7 +1625,7 @@ static int setup_sync_queues(Muxer *mux, AVFormatContext *oc, int64_t buf_size_u
      * - at least one audio encoder requires constant frame sizes
      */
     if ((of->shortest && nb_av_enc > 1) || limit_frames_av_enc || nb_audio_fs) {
-        of->sq_encode = sq_alloc(SYNC_QUEUE_FRAMES, buf_size_us);
+        of->sq_encode = sq_alloc(SYNC_QUEUE_FRAMES, buf_size_us, mux);
         if (!of->sq_encode)
             return AVERROR(ENOMEM);
 
@@ -1650,7 +1650,7 @@ static int setup_sync_queues(Muxer *mux, AVFormatContext *oc, int64_t buf_size_u
     /* if there are any additional interleaved streams, then ALL the streams
      * are also synchronized before sending them to the muxer */
     if (nb_interleaved > nb_av_enc) {
-        mux->sq_mux = sq_alloc(SYNC_QUEUE_PACKETS, buf_size_us);
+        mux->sq_mux = sq_alloc(SYNC_QUEUE_PACKETS, buf_size_us, mux);
         if (!mux->sq_mux)
             return AVERROR(ENOMEM);
 
diff --git a/fftools/sync_queue.c b/fftools/sync_queue.c
index a7aac04047..c0f33e9235 100644
--- a/fftools/sync_queue.c
+++ b/fftools/sync_queue.c
@@ -27,6 +27,7 @@
 #include "libavutil/mathematics.h"
 #include "libavutil/mem.h"
 #include "libavutil/samplefmt.h"
+#include "libavutil/timestamp.h"
 
 #include "objpool.h"
 #include "sync_queue.h"
@@ -87,6 +88,8 @@ typedef struct SyncQueueStream {
 struct SyncQueue {
     enum SyncQueueType type;
 
+    void *logctx;
+
     /* no more frames will be sent for any stream */
     int finished;
     /* sync head: the stream with the _smallest_ head timestamp
@@ -169,6 +172,11 @@ static void finish_stream(SyncQueue *sq, unsigned int stream_idx)
 {
     SyncQueueStream *st = &sq->streams[stream_idx];
 
+    if (!st->finished)
+        av_log(sq->logctx, AV_LOG_DEBUG,
+               "sq: finish %u; head ts %s\n", stream_idx,
+               av_ts2timestr(st->head_ts, &st->tb));
+
     st->finished = 1;
 
     if (st->limiting && st->head_ts != AV_NOPTS_VALUE) {
@@ -186,8 +194,14 @@ static void finish_stream(SyncQueue *sq, unsigned int stream_idx)
         for (unsigned int i = 0; i < sq->nb_streams; i++) {
             SyncQueueStream *st1 = &sq->streams[i];
             if (st != st1 && st1->head_ts != AV_NOPTS_VALUE &&
-                av_compare_ts(st->head_ts, st->tb, st1->head_ts, st1->tb) <= 0)
+                av_compare_ts(st->head_ts, st->tb, st1->head_ts, st1->tb) <= 0) {
+                if (!st1->finished)
+                    av_log(sq->logctx, AV_LOG_DEBUG,
+                           "sq: finish secondary %u; head ts %s\n", i,
+                           av_ts2timestr(st1->head_ts, &st1->tb));
+
                 st1->finished = 1;
+            }
         }
     }
 
@@ -197,6 +211,8 @@ static void finish_stream(SyncQueue *sq, unsigned int stream_idx)
             return;
     }
     sq->finished = 1;
+
+    av_log(sq->logctx, AV_LOG_DEBUG, "sq: finish queue\n");
 }
 
 static void queue_head_update(SyncQueue *sq)
@@ -306,6 +322,9 @@ static int overflow_heartbeat(SyncQueue *sq, int stream_idx)
         if (st1->head_ts != AV_NOPTS_VALUE)
             ts = FFMAX(st1->head_ts + 1, ts);
 
+        av_log(sq->logctx, AV_LOG_DEBUG, "sq: %u overflow heardbeat %s -> %s\n",
+               i, av_ts2timestr(st1->head_ts, &st1->tb), av_ts2timestr(ts, &st1->tb));
+
         stream_update_ts(sq, i, ts);
     }
 
@@ -323,6 +342,7 @@ int sq_send(SyncQueue *sq, unsigned int stream_idx, SyncQueueFrame frame)
     st = &sq->streams[stream_idx];
 
     if (frame_null(sq, frame)) {
+        av_log(sq->logctx, AV_LOG_DEBUG, "sq: %u EOF\n", stream_idx);
         finish_stream(sq, stream_idx);
         return 0;
     }
@@ -347,6 +367,9 @@ int sq_send(SyncQueue *sq, unsigned int stream_idx, SyncQueueFrame frame)
 
     ts = frame_end(sq, dst, 0);
 
+    av_log(sq->logctx, AV_LOG_DEBUG, "sq: send %u ts %s\n", stream_idx,
+           av_ts2timestr(ts, &st->tb));
+
     ret = av_fifo_write(st->fifo, &dst, 1);
     if (ret < 0) {
         frame_move(sq, frame, dst);
@@ -364,8 +387,12 @@ int sq_send(SyncQueue *sq, unsigned int stream_idx, SyncQueueFrame frame)
     else
         st->frames_sent++;
 
-    if (st->frames_sent >= st->frames_max)
+    if (st->frames_sent >= st->frames_max) {
+        av_log(sq->logctx, AV_LOG_DEBUG, "sq: %u frames_max %"PRIu64" reached\n",
+               stream_idx, st->frames_max);
+
         finish_stream(sq, stream_idx);
+    }
 
     return 0;
 }
@@ -531,6 +558,12 @@ static int receive_for_stream(SyncQueue *sq, unsigned int stream_idx,
                 st->samples_queued -= frame_samples(sq, frame);
             }
 
+            av_log(sq->logctx, AV_LOG_DEBUG,
+                   "sq: receive %u ts %s queue head %d ts %s\n", stream_idx,
+                   av_ts2timestr(frame_end(sq, frame, 0), &st->tb),
+                   sq->head_stream,
+                   st_head ? av_ts2timestr(st_head->head_ts, &st_head->tb) : "N/A");
+
             return 0;
         }
     }
@@ -630,7 +663,7 @@ void sq_frame_samples(SyncQueue *sq, unsigned int stream_idx,
     sq->align_mask = av_cpu_max_align() - 1;
 }
 
-SyncQueue *sq_alloc(enum SyncQueueType type, int64_t buf_size_us)
+SyncQueue *sq_alloc(enum SyncQueueType type, int64_t buf_size_us, void *logctx)
 {
     SyncQueue *sq = av_mallocz(sizeof(*sq));
 
@@ -639,6 +672,7 @@ SyncQueue *sq_alloc(enum SyncQueueType type, int64_t buf_size_us)
 
     sq->type                 = type;
     sq->buf_size_us          = buf_size_us;
+    sq->logctx               = logctx;
 
     sq->head_stream          = -1;
     sq->head_finished_stream = -1;
diff --git a/fftools/sync_queue.h b/fftools/sync_queue.h
index bc7cd42390..dc5acfd499 100644
--- a/fftools/sync_queue.h
+++ b/fftools/sync_queue.h
@@ -50,7 +50,7 @@ typedef struct SyncQueue SyncQueue;
  *
  * @param buf_size_us maximum duration that will be buffered in microseconds
  */
-SyncQueue *sq_alloc(enum SyncQueueType type, int64_t buf_size_us);
+SyncQueue *sq_alloc(enum SyncQueueType type, int64_t buf_size_us, void *logctx);
 void       sq_free(SyncQueue **sq);
 
 /**
-- 
2.39.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [FFmpeg-devel] [PATCH 15/15] fftools/sync_queue: make sure non-limiting streams are not used as queue head
  2023-05-23 13:58 [FFmpeg-devel] [PATCH 01/15] fftools/ffmpeg_hw: move hw_device_setup_for_decode() to ffmpeg_dec Anton Khirnov
                   ` (12 preceding siblings ...)
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 14/15] fftools/sync_queue: add debug logging Anton Khirnov
@ 2023-05-23 13:58 ` Anton Khirnov
  2023-05-24 12:01   ` James Almer
  13 siblings, 1 reply; 16+ messages in thread
From: Anton Khirnov @ 2023-05-23 13:58 UTC (permalink / raw)
  To: ffmpeg-devel

A non-limiting stream could mistakenly end up being the queue head,
which would then produce incorrect synchronization, seen e.g. in
fate-matroska-flac-extradata-update for certain number of frame threads
(e.g. 5).

Found-By: James Almer
---
 fftools/sync_queue.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/fftools/sync_queue.c b/fftools/sync_queue.c
index c0f33e9235..bc107ba4fe 100644
--- a/fftools/sync_queue.c
+++ b/fftools/sync_queue.c
@@ -217,17 +217,26 @@ static void finish_stream(SyncQueue *sq, unsigned int stream_idx)
 
 static void queue_head_update(SyncQueue *sq)
 {
+    av_assert0(sq->have_limiting);
+
     if (sq->head_stream < 0) {
+        unsigned first_limiting = UINT_MAX;
+
         /* wait for one timestamp in each stream before determining
          * the queue head */
         for (unsigned int i = 0; i < sq->nb_streams; i++) {
             SyncQueueStream *st = &sq->streams[i];
-            if (st->limiting && st->head_ts == AV_NOPTS_VALUE)
+            if (!st->limiting)
+                continue;
+            if (st->head_ts == AV_NOPTS_VALUE)
                 return;
+            if (first_limiting == UINT_MAX)
+                first_limiting = i;
         }
 
         // placeholder value, correct one will be found below
-        sq->head_stream = 0;
+        av_assert0(first_limiting < UINT_MAX);
+        sq->head_stream = first_limiting;
     }
 
     for (unsigned int i = 0; i < sq->nb_streams; i++) {
-- 
2.39.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [FFmpeg-devel] [PATCH 15/15] fftools/sync_queue: make sure non-limiting streams are not used as queue head
  2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 15/15] fftools/sync_queue: make sure non-limiting streams are not used as queue head Anton Khirnov
@ 2023-05-24 12:01   ` James Almer
  0 siblings, 0 replies; 16+ messages in thread
From: James Almer @ 2023-05-24 12:01 UTC (permalink / raw)
  To: ffmpeg-devel

On 5/23/2023 10:58 AM, Anton Khirnov wrote:
> A non-limiting stream could mistakenly end up being the queue head,
> which would then produce incorrect synchronization, seen e.g. in
> fate-matroska-flac-extradata-update for certain number of frame threads
> (e.g. 5).
> 
> Found-By: James Almer

Strictly speaking, it was FATE.

> ---
>   fftools/sync_queue.c | 13 +++++++++++--
>   1 file changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/fftools/sync_queue.c b/fftools/sync_queue.c
> index c0f33e9235..bc107ba4fe 100644
> --- a/fftools/sync_queue.c
> +++ b/fftools/sync_queue.c
> @@ -217,17 +217,26 @@ static void finish_stream(SyncQueue *sq, unsigned int stream_idx)
>   
>   static void queue_head_update(SyncQueue *sq)
>   {
> +    av_assert0(sq->have_limiting);
> +
>       if (sq->head_stream < 0) {
> +        unsigned first_limiting = UINT_MAX;
> +
>           /* wait for one timestamp in each stream before determining
>            * the queue head */
>           for (unsigned int i = 0; i < sq->nb_streams; i++) {
>               SyncQueueStream *st = &sq->streams[i];
> -            if (st->limiting && st->head_ts == AV_NOPTS_VALUE)
> +            if (!st->limiting)
> +                continue;
> +            if (st->head_ts == AV_NOPTS_VALUE)
>                   return;
> +            if (first_limiting == UINT_MAX)
> +                first_limiting = i;
>           }
>   
>           // placeholder value, correct one will be found below
> -        sq->head_stream = 0;
> +        av_assert0(first_limiting < UINT_MAX);
> +        sq->head_stream = first_limiting;
>       }
>   
>       for (unsigned int i = 0; i < sq->nb_streams; i++) {

Can confirm it fixes the issue.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2023-05-24 12:01 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-23 13:58 [FFmpeg-devel] [PATCH 01/15] fftools/ffmpeg_hw: move hw_device_setup_for_decode() to ffmpeg_dec Anton Khirnov
2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 02/15] fftools/ffmpeg_hw: move hw_device_setup_for_encode() to ffmpeg_enc Anton Khirnov
2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 03/15] fftools/ffmpeg_enc: use AVFrame.hw_frames_ctx for encoder hw setup Anton Khirnov
2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 04/15] fftools/ffmpeg: fail earlier on text/bitmap subtitles mismatch Anton Khirnov
2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 05/15] fftools/ffmpeg: drop outdated comments Anton Khirnov
2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 06/15] fftools/ffmpeg_demux: only print demuxing stats if demuxing actually started Anton Khirnov
2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 07/15] fftools/ffmpeg_demux: initialize nb_streams_warn Anton Khirnov
2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 08/15] fftools/ffmpeg_demux: skip unused/attachment streams in final stats Anton Khirnov
2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 09/15] fftools/ffmpeg_dec: add decoder private data Anton Khirnov
2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 10/15] fftools/ffmpeg_dec: move InputStream.pkt to Decoder Anton Khirnov
2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 11/15] fftools/ffmpeg_dec: move timestamp estimation state " Anton Khirnov
2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 12/15] fftools/ffmpeg: add InputStream.index Anton Khirnov
2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 13/15] fftools/ffmpeg_demux: log discontinuity warnings to stream context Anton Khirnov
2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 14/15] fftools/sync_queue: add debug logging Anton Khirnov
2023-05-23 13:58 ` [FFmpeg-devel] [PATCH 15/15] fftools/sync_queue: make sure non-limiting streams are not used as queue head Anton Khirnov
2023-05-24 12:01   ` James Almer

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git