[PR] avcodec/nvenc: write AV1 timecode metadata in AV1 syntax (PR #23863)
michaelni via ffmpeg-devel <[email protected]> Tue, 21 Jul 2026 03:22:44 -0000
| Newsgroups | gmane.comp.video.ffmpeg.devel |
|---|---|
| Message-ID | <178460416490.59.16303049658958099686@29965ddac10e> |
PR #23863 opened by michaelni URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23863 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23863.patch Fixes: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/20610 Untested: no working nvidia setup on this box >From 85dbf470b3466a615dcf11d10645e2fe4e5a8b23 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 21 Jul 2026 04:47:29 +0200 Subject: [PATCH] avcodec/nvenc: write AV1 timecode metadata in AV1 syntax Fixes: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/20610 Untested: no working nvidia setup on this box --- libavcodec/nvenc.c | 48 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index dffbb67652..91c2ec815c 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -43,6 +43,7 @@ #include "codec_desc.h" #include "encode.h" #include "internal.h" +#include "put_bits.h" #define CHECK_CU(x) FF_CUDA_CHECK_DL(avctx, dl_fn->cuda_dl, x) @@ -2723,6 +2724,43 @@ static int output_ready(AVCodecContext *avctx, int flush) return (nb_ready > 0) && (nb_ready + nb_pending >= ctx->async_depth); } +#if CONFIG_AV1_NVENC_ENCODER +static int alloc_av1_timecode_metadata(const AVFrame *frame, AVRational rate, + void **data, size_t *size) +{ + const AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_S12M_TIMECODE); + const uint32_t *tc = (const uint32_t*)sd->data; + unsigned hh, mm, ss, ff, drop; + PutBitContext pb; + + *data = NULL; + if (!(tc[0] & 3)) + return 0; + + ff_timecode_set_smpte(&drop, &hh, &mm, &ss, &ff, rate, tc[1], 0, 0); + + *size = 5; + *data = av_malloc(*size); + if (!*data) + return AVERROR(ENOMEM); + + init_put_bits(&pb, *data, *size); + put_bits(&pb, 5, 0); // counting_type + put_bits(&pb, 1, 1); // full_timestamp_flag + put_bits(&pb, 1, 0); // discontinuity_flag + put_bits(&pb, 1, drop); // cnt_dropped_flag + put_bits(&pb, 9, ff); // n_frames + put_bits(&pb, 6, ss); // seconds_value + put_bits(&pb, 6, mm); // minutes_value + put_bits(&pb, 5, hh); // hours_value + put_bits(&pb, 5, 1); // time_offset_length + put_bits(&pb, 1, 0); // time_offset_value + flush_put_bits(&pb); + + return 0; +} +#endif + static int prepare_sei_data_array(AVCodecContext *avctx, const AVFrame *frame) { NvencContext *ctx = avctx->priv_data; @@ -2765,8 +2803,16 @@ static int prepare_sei_data_array(AVCodecContext *avctx, const AVFrame *frame) if (ctx->s12m_tc && avctx->codec->id != AV_CODEC_ID_H264 && av_frame_get_side_data(frame, AV_FRAME_DATA_S12M_TIMECODE)) { void *tc_data = NULL; size_t tc_size = 0; + int ret; - if (ff_alloc_timecode_sei(frame, avctx->framerate, 0, &tc_data, &tc_size) < 0) { +#if CONFIG_AV1_NVENC_ENCODER + if (avctx->codec->id == AV_CODEC_ID_AV1) + ret = alloc_av1_timecode_metadata(frame, avctx->framerate, &tc_data, &tc_size); + else +#endif + ret = ff_alloc_timecode_sei(frame, avctx->framerate, 0, &tc_data, &tc_size); + + if (ret < 0) { av_log(ctx, AV_LOG_ERROR, "Not enough memory for timecode sei, skipping\n"); } -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]