[FFmpeg-devel] [PATCH v2 1/3] avformat/fifo: add options to slow down writing packets to match real time approximately
Tao Zhang
nowerzt at gmail.com
Fri May 8 02:52:55 EEST 2020
Marton Balint <cus at passwd.hu> 于2020年5月7日周四 下午6:23写道:
>
>
>
> 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.
Yes, I have. Please ignore above Reviewed-by
>
> 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.
I didn't try using a buffer based approach in fifo.c. If you're
willing to post such RFC patch, I'm OK. Thanks
>
> 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".
> _______________________________________________
> 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