summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2022-07-12 11:25:09 +0200
committerAnton Khirnov <anton@khirnov.net>2022-08-23 16:50:33 +0200
commit79c3d8332ce4cf0ab194b212676a8c5fee7436fc (patch)
treead8dea4a894cc2f7a7c8c77caebe7b74dc62b651
parentee05c9bdee0ff6db7f3bc97fca1044f55b505daa (diff)
lavc/nvenc: pass through frame durations to encoded packets
-rw-r--r--libavcodec/nvenc.c25
1 files 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, &timestamp, 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, &timestamp, 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 */