* [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