leozhang (12020-04-29): > Signed-off-by: leozhang <[email protected]> > --- > doc/muxers.texi | 3 +++ > libavformat/fifo.c | 19 +++++++++++++++++++ > 2 files changed, 22 insertions(+) > > diff --git a/doc/muxers.texi b/doc/muxers.texi > index a74cbc4..5140c00 100644 > --- a/doc/muxers.texi > +++ b/doc/muxers.texi > @@ -2274,6 +2274,9 @@ queue overflow or failure. This option is set to 0 > (false) by default. > @item output_delay > Time to delay output, in microseconds. Default value is 0. >
> +@item paced
> +If set to 1 (true), write packets in paced way. Default value is 0 (false).
This does not explain to somebody who does not already know. Please have
a look at the doc for the filter "realtime" and use a similar wording,
preferably with cross-references.
> +
> @end table
>
> @subsection Examples
> diff --git a/libavformat/fifo.c b/libavformat/fifo.c
> index bdecf2d..81b7e9e 100644
> --- a/libavformat/fifo.c
> +++ b/libavformat/fifo.c
> @@ -79,6 +79,12 @@ typedef struct FifoContext {
>
> /* Time to delay output, in microseconds */
> uint64_t output_delay;
> +
> + /* If set to 1, write packets in paced way */
> + int paced;
> +
> + /* Time to start */
> + uint64_t start_time;
The return value of av_gettime_relative() is signed.
> } FifoContext;
>
> typedef struct FifoThreadContext {
> @@ -184,6 +190,14 @@ static int fifo_thread_write_packet(FifoThreadContext
> *ctx, AVPacket *pkt)
> src_tb = avf->streams[s_idx]->time_base;
> dst_tb = avf2->streams[s_idx]->time_base;
> av_packet_rescale_ts(pkt, src_tb, dst_tb);
> + if (fifo->paced) {
> + uint64_t pts = av_rescale_q(pkt->dts, dst_tb, AV_TIME_BASE_Q);
> + uint64_t now = av_gettime_relative() - fifo->start_time;
> + av_assert0(now >= fifo->output_delay);
av_gettime_relative() is not guaranteed to be monotonic, an assert is
not acceptable here.
> + if (pts > now - fifo->output_delay) {
You probably need to make provisions for when the process was paused and
then resumed, and for timestamps discontinuities.
> + av_usleep(pts - (now - fifo->output_delay));
The argument to av_usleep() is unsigned, you are passing uint64_t, it
can overflow.
> + }
> + }
>
> ret = av_write_frame(avf2, pkt);
> if (ret >= 0)
> @@ -515,6 +529,8 @@ static int fifo_init(AVFormatContext *avf)
> return AVERROR(ret);
> fifo->overflow_flag_lock_initialized = 1;
>
> + fifo->start_time = av_gettime_relative();
> +
> return 0;
> }
>
> @@ -637,6 +653,9 @@ static const AVOption options[] = {
> {"output_delay", "Time to delay output, in microseconds",
> OFFSET(output_delay),
> AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX,
> AV_OPT_FLAG_ENCODING_PARAM},
>
> + {"paced", "Write packets in paced way", OFFSET(paced),
> + AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
> +
> {NULL},
> };
>
Regards,
--
Nicolas George
signature.asc
Description: PGP signature
_______________________________________________ ffmpeg-devel mailing list [email protected] https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email [email protected] with subject "unsubscribe".
