From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id 3FC234D82B for ; Mon, 24 Feb 2025 20:52:44 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 27FD468CA54; Mon, 24 Feb 2025 22:52:19 +0200 (EET) Received: from btbn.de (btbn.de [144.76.60.213]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 5BFB368B9E4 for ; Mon, 24 Feb 2025 22:52:09 +0200 (EET) Received: from [authenticated] by btbn.de (Postfix) with ESMTPSA id C32602819FD4E; Mon, 24 Feb 2025 21:52:08 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rothenpieler.org; s=mail; t=1740430328; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=wD+DV3U4Va/uP/F0w/CyWXyGvpgAh+P6/JF0rskADnk=; b=o5GhqmYircnnJCU3hIBT61nk7roBPel2tWS0dlI4s6x67Tt3egLWBohU3bky94TpCYw3jT 0K7L4FFSMXtLCdKMk5qYNMgCW30o/K/ZZB4JqLpDsQLSpN7WtAm5y34ZeRhc++lkSD525L TJVw3cuv8uCwN9nTjKNQkpnstxJlXfnMXZi1U88CChjAAbxTDBPaTXKaOQgg6R+7MlTNul msjiEVFGELcnKnB2CFMpMFgXcXmwLXOyrnnyVFj8SJD5Yo9xfwH5G2ROu6YWei707RsOSV q5S5pY60GNg3xXSMOX8vVMpKZ9rHA64TtMwlwlKVYUKJUZnuogACCAgKk0LP4w== From: Timo Rothenpieler To: ffmpeg-devel@ffmpeg.org Date: Mon, 24 Feb 2025 21:51:50 +0100 Message-ID: <20250224205159.13620-3-timo@rothenpieler.org> X-Mailer: git-send-email 2.45.3 In-Reply-To: <20250224205159.13620-1-timo@rothenpieler.org> References: <20250224205159.13620-1-timo@rothenpieler.org> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 3/3] avcodec/nvenc: add time code writing for h264 X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Timo Rothenpieler Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: --- 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".