From: Timo Rothenpieler <timo@rothenpieler.org> To: ffmpeg-devel@ffmpeg.org Cc: Timo Rothenpieler <timo@rothenpieler.org> Subject: [FFmpeg-devel] [PATCH 3/3] avcodec/nvenc: add time code writing for h264 Date: Mon, 24 Feb 2025 21:51:50 +0100 Message-ID: <20250224205159.13620-3-timo@rothenpieler.org> (raw) In-Reply-To: <20250224205159.13620-1-timo@rothenpieler.org> --- libavcodec/nvenc.c | 62 +++++++++++++++++++++++++++++++++++++++-- libavcodec/nvenc.h | 1 + libavcodec/nvenc_h264.c | 3 ++ 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index f9221174f0..900659f9e1 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -34,6 +34,7 @@ #include "libavutil/imgutils.h" #include "libavutil/mem.h" #include "libavutil/pixdesc.h" +#include "libavutil/timecode.h" #include "libavutil/mathematics.h" #include "libavutil/mastering_display_metadata.h" #include "atsc_a53.h" @@ -1417,6 +1418,11 @@ static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx) } #endif +#ifdef NVENC_HAVE_TIME_CODE + if (ctx->s12m_tc) + h264->enableTimeCode = 1; +#endif + return 0; } @@ -2420,7 +2426,52 @@ static int nvenc_upload_frame(AVCodecContext *avctx, const AVFrame *frame, } } -static void nvenc_codec_specific_pic_params(AVCodecContext *avctx, +#ifdef NVENC_HAVE_TIME_CODE +static void nvenc_fill_time_code(AVCodecContext *avctx, const AVFrame *frame, NV_ENC_TIME_CODE *time_code) +{ + AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_S12M_TIMECODE); + + if (sd) { + uint32_t *tc = (uint32_t*)sd->data; + int cnt = FFMIN(tc[0], FF_ARRAY_ELEMS(time_code->clockTimestamp)); + + switch (cnt) { + case 0: + time_code->displayPicStruct = NV_ENC_PIC_STRUCT_DISPLAY_FRAME; + time_code->skipClockTimestampInsertion = 1; + break; + case 2: + time_code->displayPicStruct = NV_ENC_PIC_STRUCT_DISPLAY_FRAME_DOUBLING; + break; + case 3: + time_code->displayPicStruct = NV_ENC_PIC_STRUCT_DISPLAY_FRAME_TRIPLING; + break; + default: + time_code->displayPicStruct = NV_ENC_PIC_STRUCT_DISPLAY_FRAME; + break; + } + + for (int i = 0; i < cnt; i++) { + int hh, mm, ss, ff, drop; + av_timecode_set_smpte(&drop, &hh, &mm, &ss, &ff, avctx->framerate, tc[i + 1], 0, 0); + + time_code->clockTimestamp[i].countingType = 0; + time_code->clockTimestamp[i].discontinuityFlag = 0; + time_code->clockTimestamp[i].cntDroppedFrames = drop; + time_code->clockTimestamp[i].nFrames = ff; + time_code->clockTimestamp[i].secondsValue = ss; + time_code->clockTimestamp[i].minutesValue = mm; + time_code->clockTimestamp[i].hoursValue = hh; + time_code->clockTimestamp[i].timeOffset = 0; + } + } else { + time_code->displayPicStruct = NV_ENC_PIC_STRUCT_DISPLAY_FRAME; + time_code->skipClockTimestampInsertion = 1; + } +} +#endif + +static void nvenc_codec_specific_pic_params(AVCodecContext *avctx, const AVFrame *frame, NV_ENC_PIC_PARAMS *params, NV_ENC_SEI_PAYLOAD *sei_data, int sei_count) @@ -2438,6 +2489,11 @@ static void nvenc_codec_specific_pic_params(AVCodecContext *avctx, params->codecPicParams.h264PicParams.seiPayloadArrayCnt = sei_count; } +#ifdef NVENC_HAVE_TIME_CODE + if (ctx->s12m_tc) + nvenc_fill_time_code(avctx, frame, ¶ms->codecPicParams.h264PicParams.timeCode); +#endif + break; case AV_CODEC_ID_HEVC: params->codecPicParams.hevcPicParams.sliceMode = @@ -2739,7 +2795,7 @@ static int prepare_sei_data_array(AVCodecContext *avctx, const AVFrame *frame) } } - if (ctx->s12m_tc && av_frame_get_side_data(frame, AV_FRAME_DATA_S12M_TIMECODE)) { + 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; @@ -3046,7 +3102,7 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) if (res < 0) return res; - nvenc_codec_specific_pic_params(avctx, &pic_params, ctx->sei_data, sei_count); + nvenc_codec_specific_pic_params(avctx, frame, &pic_params, ctx->sei_data, sei_count); } else { pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS; } diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index dbd18cac12..e035e123c6 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -96,6 +96,7 @@ typedef void ID3D11Device; #define NVENC_HAVE_LOOKAHEAD_LEVEL #define NVENC_HAVE_UHQ_TUNING #define NVENC_HAVE_UNIDIR_B +#define NVENC_HAVE_TIME_CODE // added in 12.0, but incomplete until 12.2 #endif // SDK 13.0 compile time feature checks diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c index c7267a082a..c3396bde91 100644 --- a/libavcodec/nvenc_h264.c +++ b/libavcodec/nvenc_h264.c @@ -199,6 +199,9 @@ static const AVOption options[] = { { "middle", "", 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, VE, .unit = "b_ref_mode" }, #endif { "a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE }, +#ifdef NVENC_HAVE_TIME_CODE + { "s12m_tc", "Use timecode (if available)", OFFSET(s12m_tc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE }, +#endif { "dpb_size", "Specifies the DPB size used for encoding (0 means automatic)", OFFSET(dpb_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, #ifdef NVENC_HAVE_MULTIPASS -- 2.45.3 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
prev parent reply other threads:[~2025-02-24 20:52 UTC|newest] Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top 2025-02-24 20:51 [FFmpeg-devel] [PATCH 1/3] avutil/timecode: add av_timecode_set_smpte Timo Rothenpieler 2025-02-24 20:51 ` [FFmpeg-devel] [PATCH 2/3] avcodec/utils: use new av_timecode_set_smpte function Timo Rothenpieler 2025-02-24 20:51 ` Timo Rothenpieler [this message]
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20250224205159.13620-3-timo@rothenpieler.org \ --to=timo@rothenpieler.org \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git