[FFmpeg-devel] [PATCH v2 1/3] avformat/fifo: add options to slow down writing packets to match real time approximately
Marton Balint
cus at passwd.hu
Thu May 7 13:23:25 EEST 2020
On Thu, 7 May 2020, leozhang wrote:
> 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>
You seem to misunderstand the use of this tag. You should only add these
if you received an explict LGTM for your patches. This has not happened
here, you only got suggestions, and those suggestions were concerning your
earlier patch versions.
Also, what happened to the suggestion of using a buffer based approach and
using realtime only for flushing? I will code something, and see how it
goes, and will post a result as an RFC patch.
Regards,
Marton
> 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
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
More information about the ffmpeg-devel
mailing list