aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2023-07-07 11:31:53 +0200
committerAnton Khirnov <anton@khirnov.net>2023-07-15 11:02:11 +0200
commitdff3a283cd8c71802d43fbbbfcf57fb479784a24 (patch)
tree5ad71cc5725849df33d2c4b15b42846e9889585f
parent4d06742b93394b6265fb32640ee7bb36f4fe1a06 (diff)
downloadffmpeg-dff3a283cd8c71802d43fbbbfcf57fb479784a24.tar.gz
fftools/ffmpeg: rework -enc_time_base handling
Read the timebase from FrameData rather than the input stream. This should fix #10393 and generally be more reliable. Replace the use of '-1' to indicate demuxing timebase with the string 'demux'. Also allow to request filter timebase with '-enc_time_base filter'.
-rw-r--r--doc/ffmpeg.texi7
-rw-r--r--fftools/ffmpeg.h6
-rw-r--r--fftools/ffmpeg_enc.c16
-rw-r--r--fftools/ffmpeg_mux_init.c31
-rw-r--r--tests/fate/video.mak2
5 files changed, 44 insertions, 18 deletions
diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index 6769f8d305..59e9fbfcb2 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -1812,10 +1812,11 @@ Assign a default value according to the media type.
For video - use 1/framerate, for audio - use 1/samplerate.
-@item -1
-Use the input stream timebase when possible.
+@item demux
+Use the timebase from the demuxer.
-If an input stream is not available, the default timebase will be used.
+@item filter
+Use the timebase from the filtergraph.
@item >0
Use the provided number as the timebase.
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 97aa4d716e..f45ddf33b2 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -56,6 +56,7 @@
#define FFMPEG_ROTATION_METADATA 1
#define FFMPEG_OPT_QPHIST 1
#define FFMPEG_OPT_ADRIFT_THRESHOLD 1
+#define FFMPEG_OPT_ENC_TIME_BASE_NUM 1
enum VideoSyncMethod {
VSYNC_AUTO = -1,
@@ -66,6 +67,11 @@ enum VideoSyncMethod {
VSYNC_DROP,
};
+enum EncTimeBase {
+ ENC_TIME_BASE_DEMUX = -1,
+ ENC_TIME_BASE_FILTER = -2,
+};
+
#define MAX_STREAMS 1024 /* arbitrary sanity check value */
enum HWAccelID {
diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c
index 0e2285c5a2..1489b2f179 100644
--- a/fftools/ffmpeg_enc.c
+++ b/fftools/ffmpeg_enc.c
@@ -264,8 +264,20 @@ int enc_open(OutputStream *ost, AVFrame *frame)
fr.num, fr.den, 65535);
}
- enc_ctx->time_base = ost->enc_timebase.num > 0 ? ost->enc_timebase :
- av_inv_q(fr);
+ if (ost->enc_timebase.num == ENC_TIME_BASE_DEMUX) {
+ if (fd->dec.tb.num <= 0 || fd->dec.tb.den <= 0) {
+ av_log(ost, AV_LOG_ERROR,
+ "Demuxing timebase not available - cannot use it for encoding\n");
+ return AVERROR(EINVAL);
+ }
+
+ enc_ctx->time_base = fd->dec.tb;
+ } else if (ost->enc_timebase.num == ENC_TIME_BASE_FILTER) {
+ enc_ctx->time_base = frame->time_base;
+ } else {
+ enc_ctx->time_base = ost->enc_timebase.num > 0 ? ost->enc_timebase :
+ av_inv_q(fr);
+ }
if (!(enc_ctx->time_base.num && enc_ctx->time_base.den))
enc_ctx->time_base = frame->time_base;
diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c
index 2dba76b82b..6458414b5f 100644
--- a/fftools/ffmpeg_mux_init.c
+++ b/fftools/ffmpeg_mux_init.c
@@ -1171,20 +1171,27 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type,
MATCH_PER_STREAM_OPT(enc_time_bases, str, enc_time_base, oc, st);
if (enc_time_base) {
AVRational q;
- if (av_parse_ratio(&q, enc_time_base, INT_MAX, 0, NULL) < 0 ||
- q.den <= 0) {
- av_log(ost, AV_LOG_FATAL, "Invalid time base: %s\n", enc_time_base);
- return AVERROR(EINVAL);
- }
- if (q.num < 0) {
- if (!ost->ist) {
- av_log(ost, AV_LOG_FATAL,
- "Cannot use input stream timebase for encoding - "
- "no input stream available\n");
- return AVERROR(EINVAL);
+ if (!strcmp(enc_time_base, "demux")) {
+ q = (AVRational){ ENC_TIME_BASE_DEMUX, 0 };
+ } else if (!strcmp(enc_time_base, "filter")) {
+ q = (AVRational){ ENC_TIME_BASE_FILTER, 0 };
+ } else {
+ ret = av_parse_ratio(&q, enc_time_base, INT_MAX, 0, NULL);
+ if (ret < 0 || q.den <= 0
+#if !FFMPEG_OPT_ENC_TIME_BASE_NUM
+ || q.num < 0
+#endif
+ ) {
+ av_log(ost, AV_LOG_FATAL, "Invalid time base: %s\n", enc_time_base);
+ return ret < 0 ? ret : AVERROR(EINVAL);
}
- q = ost->ist->st->time_base;
+#if FFMPEG_OPT_ENC_TIME_BASE_NUM
+ if (q.num < 0)
+ av_log(ost, AV_LOG_WARNING, "-enc_time_base -1 is deprecated,"
+ " use -enc_timebase demux\n");
+#endif
}
+
ost->enc_timebase = q;
}
} else {
diff --git a/tests/fate/video.mak b/tests/fate/video.mak
index a2011d0dad..4e7a77537f 100644
--- a/tests/fate/video.mak
+++ b/tests/fate/video.mak
@@ -270,7 +270,7 @@ FATE_VIDEO-$(call FRAMECRC, MXG, MXPEG) += fate-mxpeg
fate-mxpeg: CMD = framecrc -idct simple -flags +bitexact -i $(TARGET_SAMPLES)/mxpeg/m1.mxg -an
FATE_NUV += fate-nuv-rtjpeg
-fate-nuv-rtjpeg: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/nuv/Today.nuv -an -enc_time_base -1
+fate-nuv-rtjpeg: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/nuv/Today.nuv -an -enc_time_base demux
FATE_NUV += fate-nuv-rtjpeg-fh
fate-nuv-rtjpeg-fh: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/nuv/rtjpeg_frameheader.nuv -an