From 79c3d8332ce4cf0ab194b212676a8c5fee7436fc Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 12 Jul 2022 11:25:09 +0200 Subject: lavc/nvenc: pass through frame durations to encoded packets --- libavcodec/nvenc.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 11bd21f365..5b3c6d704b 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -156,6 +156,11 @@ static int nvenc_print_error(AVCodecContext *avctx, NVENCSTATUS err, return ret; } +typedef struct FrameTiming { + int64_t pts; + int64_t duration; +} FrameTiming; + typedef struct GUIDTuple { const GUID guid; int flags; @@ -1611,7 +1616,7 @@ static av_cold int nvenc_setup_surfaces(AVCodecContext *avctx) if (!ctx->surfaces) return AVERROR(ENOMEM); - ctx->timestamp_list = av_fifo_alloc2(ctx->nb_surfaces, sizeof(int64_t), 0); + ctx->timestamp_list = av_fifo_alloc2(ctx->nb_surfaces, sizeof(FrameTiming), 0); if (!ctx->timestamp_list) return AVERROR(ENOMEM); @@ -2026,18 +2031,22 @@ static void nvenc_codec_specific_pic_params(AVCodecContext *avctx, } } -static inline void timestamp_queue_enqueue(AVFifo *queue, int64_t timestamp) +static inline void timestamp_queue_enqueue(AVFifo *queue, int64_t pts, int64_t duration) { + FrameTiming timestamp = { .pts = pts, .duration = duration }; av_fifo_write(queue, ×tamp, 1); } -static inline int64_t timestamp_queue_dequeue(AVFifo *queue) +static inline int64_t timestamp_queue_dequeue(AVFifo *queue, int64_t *duration) { - int64_t timestamp = AV_NOPTS_VALUE; + FrameTiming timestamp = { .pts = AV_NOPTS_VALUE }; // The following call might fail if the queue is empty. av_fifo_read(queue, ×tamp, 1); - return timestamp; + if (duration) + *duration = timestamp.duration; + + return timestamp.pts; } static int nvenc_set_timestamp(AVCodecContext *avctx, @@ -2047,7 +2056,7 @@ static int nvenc_set_timestamp(AVCodecContext *avctx, NvencContext *ctx = avctx->priv_data; pkt->pts = params->outputTimeStamp; - pkt->dts = timestamp_queue_dequeue(ctx->timestamp_list); + pkt->dts = timestamp_queue_dequeue(ctx->timestamp_list, &pkt->duration); pkt->dts -= FFMAX(ctx->encode_config.frameIntervalP - 1, 0) * FFMAX(avctx->ticks_per_frame, 1); @@ -2167,7 +2176,7 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSur return 0; error: - timestamp_queue_dequeue(ctx->timestamp_list); + timestamp_queue_dequeue(ctx->timestamp_list, NULL); error2: av_free(slice_offsets); @@ -2471,7 +2480,7 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) if (frame && frame->buf[0]) { av_fifo_write(ctx->output_surface_queue, &in_surf, 1); - timestamp_queue_enqueue(ctx->timestamp_list, frame->pts); + timestamp_queue_enqueue(ctx->timestamp_list, frame->pts, frame->duration); } /* all the pending buffers are now ready for output */ -- cgit v1.2.3