[FFmpeg-devel] [PATCH v2 1/3] avformat/fifo: add options to slow down writing packets to match real time approximately
leozhang
leozhang at qiyi.com
Thu May 7 09:16:48 EEST 2020
Suggested-by: Nicolas George <george at nsup.org>
Reviewed-by: Nicolas George <george at nsup.org>
Reviewed-by: Marton Balint <cus at passwd.hu>
Reviewed-by: Andreas Rheinhardt <andreas.rheinhardt at gmail.com>
Signed-off-by: leozhang <leozhang at qiyi.com>
---
doc/muxers.texi | 21 +++++++++++++++++++++
libavformat/fifo.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 67 insertions(+)
diff --git a/doc/muxers.texi b/doc/muxers.texi
index 536433b..14528f1 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -2274,6 +2274,17 @@ certain (usually permanent) errors the recovery is not attempted even when
Specify whether to wait for the keyframe after recovering from
queue overflow or failure. This option is set to 0 (false) by default.
+ at item realtime @var{bool}
+If set to 1 (true), slow down writing packets to match real time approximately.
+This is similar to @ref{the realtime or arealtime filters,,the "realtime_002c-arealtime" section in the ffmpeg-filters manual,ffmpeg-filters}.
+Please note that in some cases without filtering, such as stream copy, you can also use it.
+
+ at item realtime_speed
+It is the same as the speed option to realtime or arealtime filters.
+
+ at item realtime_limit @var{duration}
+It is the same as the limit option to realtime or arealtime filters.
+
@end table
@subsection Examples
@@ -2291,6 +2302,16 @@ ffmpeg -re -i ... -c:v libx264 -c:a aac -f fifo -fifo_format flv -map 0:v -map 0
@end itemize
+ at itemize
+
+ at item
+Stream something to rtmp server, instead of using -re option.
+ at example
+ffmpeg -i your_input_file -c copy -map 0:v -map 0:a -f fifo -fifo_format flv -realtime 1 rtmp://example.com/live/stream_name
+ at end example
+
+ at end itemize
+
@anchor{tee}
@section tee
diff --git a/libavformat/fifo.c b/libavformat/fifo.c
index d11dc66..7acc420 100644
--- a/libavformat/fifo.c
+++ b/libavformat/fifo.c
@@ -26,6 +26,7 @@
#include "libavutil/threadmessage.h"
#include "avformat.h"
#include "internal.h"
+#include <float.h>
#define FIFO_DEFAULT_QUEUE_SIZE 60
#define FIFO_DEFAULT_MAX_RECOVERY_ATTEMPTS 0
@@ -77,6 +78,17 @@ typedef struct FifoContext {
/* Value > 0 signals queue overflow */
volatile uint8_t overflow_flag;
+ /* Slow down writing packets to match real time approximately */
+ int realtime;
+
+ /* Speed factor for the processing when realtime */
+ double realtime_speed;
+
+ /* Time limit for the pauses when realtime */
+ int64_t realtime_limit;
+
+ int64_t delta;
+ unsigned inited;
} FifoContext;
typedef struct FifoThreadContext {
@@ -183,6 +195,31 @@ static int fifo_thread_write_packet(FifoThreadContext *ctx, AVPacket *pkt)
dst_tb = avf2->streams[s_idx]->time_base;
av_packet_rescale_ts(pkt, src_tb, dst_tb);
+ if (fifo->realtime) {
+ int64_t pts = av_rescale_q(pkt->dts, dst_tb, AV_TIME_BASE_Q) / fifo->realtime_speed;
+ int64_t now = av_gettime_relative();
+ int64_t sleep = pts - now + fifo->delta;
+
+ if (!fifo->inited) {
+ sleep = 0;
+ fifo->delta = now - pts;
+ fifo->inited = 1;
+ }
+
+ if (FFABS(sleep) > fifo->realtime_limit / fifo->realtime_speed) {
+ av_log(avf, AV_LOG_WARNING, "time discontinuity detected: %"PRIi64" us, resetting\n", sleep);
+ sleep = 0;
+ fifo->delta = now - pts;
+ }
+
+ if (sleep > 0) {
+ av_log(avf, AV_LOG_DEBUG, "sleeping %"PRIi64" us\n", sleep);
+ for (; sleep > 600000000; sleep -= 600000000)
+ av_usleep(600000000);
+ av_usleep(sleep);
+ }
+ }
+
ret = av_write_frame(avf2, pkt);
if (ret >= 0)
av_packet_unref(pkt);
@@ -630,6 +667,15 @@ static const AVOption options[] = {
{"recover_any_error", "Attempt recovery regardless of type of the error", OFFSET(recover_any_error),
AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
+ {"realtime", "Slow down writing packets to match real time approximately", OFFSET(realtime),
+ AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
+
+ {"realtime_speed", "Speed factor for the processing when realtime", OFFSET(realtime_speed),
+ AV_OPT_TYPE_DOUBLE, {.dbl = 1.0}, DBL_MIN, DBL_MAX, AV_OPT_FLAG_ENCODING_PARAM},
+
+ {"realtime_limit", "Time limit for the pauses when realtime", OFFSET(realtime_limit),
+ AV_OPT_TYPE_DURATION, {.i64 = 2000000}, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM},
+
{NULL},
};
--
1.8.3.1
More information about the ffmpeg-devel
mailing list