From: Jan Ekström <jan.ekst...@24i.com> This way the timestamp adjustments do not have to be manually undone in case of failure and need to recover/retry.
Fixes an issue where the timestamp adjustment would be re-done over and over again when recovery by muxing the same AVPacket again is attempted. Would become visible if the fifo muxer's time base and the output muxer's time base do not match (by the value either becoming smaller and smaller, or larger and larger). Signed-off-by: Jan Ekström <jan.ekst...@24i.com> --- libavformat/fifo.c | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/libavformat/fifo.c b/libavformat/fifo.c index 17748e94ce..aa8bea6d5a 100644 --- a/libavformat/fifo.c +++ b/libavformat/fifo.c @@ -43,6 +43,8 @@ typedef struct FifoContext { int queue_size; AVThreadMessageQueue *queue; + AVPacket *out_pkt; + pthread_t writer_thread; /* Return value of last write_trailer_call */ @@ -181,6 +183,7 @@ static int fifo_thread_write_packet(FifoThreadContext *ctx, AVPacket *pkt) AVFormatContext *avf = ctx->avf; FifoContext *fifo = avf->priv_data; AVFormatContext *avf2 = fifo->avf; + AVPacket *out_pkt = fifo->out_pkt; AVRational src_tb, dst_tb; int ret, s_idx; @@ -198,14 +201,34 @@ static int fifo_thread_write_packet(FifoThreadContext *ctx, AVPacket *pkt) } } - s_idx = pkt->stream_index; + // We will be muxing a packet, so clone it by utilizing references. + // This way we do not have to undo any of the tweaking for timestamps etc + // that we are doing in this function in case another attempt through + // recovery is required. + if ((ret = av_packet_ref(out_pkt, pkt)) < 0) { + av_log(avf, AV_LOG_ERROR, + "Error creating a new reference for output packet (%s)!\n", + av_err2str(ret)); + return ret; + } + + s_idx = out_pkt->stream_index; 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); - ret = av_write_frame(avf2, pkt); - if (ret >= 0) - av_packet_unref(pkt); + av_packet_rescale_ts(out_pkt, src_tb, dst_tb); + + ret = av_write_frame(avf2, out_pkt); + + // Always clear the output packet, as we have no more use for it. + av_packet_unref(out_pkt); + + if (ret < 0) + return ret; + + // We hit success, unref the actual source packet. + av_packet_unref(pkt); + return ret; } @@ -525,6 +548,11 @@ static int fifo_init(AVFormatContext *avf) return ret; } + if (!(fifo->out_pkt = av_packet_alloc())) { + av_log(avf, AV_LOG_ERROR, "Failed to allocate output packet!\n"); + return AVERROR(ENOMEM); + } + ret = fifo_mux_init(avf, oformat, avf->url); if (ret < 0) return ret; @@ -650,6 +678,7 @@ static void fifo_deinit(AVFormatContext *avf) av_thread_message_queue_free(&fifo->queue); if (fifo->overflow_flag_lock_initialized) pthread_mutex_destroy(&fifo->overflow_flag_lock); + av_packet_free(&fifo->out_pkt); } #define OFFSET(x) offsetof(FifoContext, x) -- 2.29.2 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".