History

avcodec/nvenc: add time code writing for h264

Timo Rothenpieler committed 1 year ago

Commit e567dca1 parent 31ca6c13 files · +63 −3Browse files

Showing the changes to libavcodec (3 of 3 files). Show all

Unified · Split

3 files
  1. libavcodec/nvenc.c +59 −3
  2. libavcodec/nvenc.h +1 −0
  3. libavcodec/nvenc_h264.c +3 −0
libavcodec/nvenc.c+59−3
@@ -34,6 +34,7 @@ · 33 unmodified lines
3434 #include "libavutil/imgutils.h"
3535 #include "libavutil/mem.h"
3636 #include "libavutil/pixdesc.h"
37+#include "libavutil/timecode_internal.h"
3738 #include "libavutil/mathematics.h"
3839 #include "libavutil/mastering_display_metadata.h"
3940 #include "atsc_a53.h"
@@ -1417,6 +1418,11 @@ static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx) · 1377 unmodified lines
14171418 }
14181419 #endif
14191420
1421+#ifdef NVENC_HAVE_TIME_CODE
1422+ if (ctx->s12m_tc)
1423+ h264->enableTimeCode = 1;
1424+#endif
1425+
14201426 return 0;
14211427 }
14221428
@@ -2420,7 +2426,52 @@ static int nvenc_upload_frame(AVCodecContext *avctx, const AVFrame *frame, · 997 unmodified lines
24202426 }
24212427 }
24222428
2423−static void nvenc_codec_specific_pic_params(AVCodecContext *avctx,
2429+#ifdef NVENC_HAVE_TIME_CODE
2430+static void nvenc_fill_time_code(AVCodecContext *avctx, const AVFrame *frame, NV_ENC_TIME_CODE *time_code)
2431+{
2432+ AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_S12M_TIMECODE);
2433+
2434+ if (sd) {
2435+ uint32_t *tc = (uint32_t*)sd->data;
2436+ int cnt = FFMIN(tc[0], FF_ARRAY_ELEMS(time_code->clockTimestamp));
2437+
2438+ switch (cnt) {
2439+ case 0:
2440+ time_code->displayPicStruct = NV_ENC_PIC_STRUCT_DISPLAY_FRAME;
2441+ time_code->skipClockTimestampInsertion = 1;
2442+ break;
2443+ case 2:
2444+ time_code->displayPicStruct = NV_ENC_PIC_STRUCT_DISPLAY_FRAME_DOUBLING;
2445+ break;
2446+ case 3:
2447+ time_code->displayPicStruct = NV_ENC_PIC_STRUCT_DISPLAY_FRAME_TRIPLING;
2448+ break;
2449+ default:
2450+ time_code->displayPicStruct = NV_ENC_PIC_STRUCT_DISPLAY_FRAME;
2451+ break;
2452+ }
2453+
2454+ for (int i = 0; i < cnt; i++) {
2455+ unsigned hh, mm, ss, ff, drop;
2456+ ff_timecode_set_smpte(&drop, &hh, &mm, &ss, &ff, avctx->framerate, tc[i + 1], 0, 0);
2457+
2458+ time_code->clockTimestamp[i].countingType = 0;
2459+ time_code->clockTimestamp[i].discontinuityFlag = 0;
2460+ time_code->clockTimestamp[i].cntDroppedFrames = drop;
2461+ time_code->clockTimestamp[i].nFrames = ff;
2462+ time_code->clockTimestamp[i].secondsValue = ss;
2463+ time_code->clockTimestamp[i].minutesValue = mm;
2464+ time_code->clockTimestamp[i].hoursValue = hh;
2465+ time_code->clockTimestamp[i].timeOffset = 0;
2466+ }
2467+ } else {
2468+ time_code->displayPicStruct = NV_ENC_PIC_STRUCT_DISPLAY_FRAME;
2469+ time_code->skipClockTimestampInsertion = 1;
2470+ }
2471+}
2472+#endif
2473+
2474+static void nvenc_codec_specific_pic_params(AVCodecContext *avctx, const AVFrame *frame,
24242475 NV_ENC_PIC_PARAMS *params,
24252476 NV_ENC_SEI_PAYLOAD *sei_data,
24262477 int sei_count)
@@ -2438,6 +2489,11 @@ static void nvenc_codec_specific_pic_params(AVCodecContext *avctx, · 11 unmodified lines
24382489 params->codecPicParams.h264PicParams.seiPayloadArrayCnt = sei_count;
24392490 }
24402491
2492+#ifdef NVENC_HAVE_TIME_CODE
2493+ if (ctx->s12m_tc)
2494+ nvenc_fill_time_code(avctx, frame, &params->codecPicParams.h264PicParams.timeCode);
2495+#endif
2496+
24412497 break;
24422498 case AV_CODEC_ID_HEVC:
24432499 params->codecPicParams.hevcPicParams.sliceMode =
@@ -2739,7 +2795,7 @@ static int prepare_sei_data_array(AVCodecContext *avctx, const AVFrame *frame) · 295 unmodified lines
27392795 }
27402796 }
27412797
2742− if (ctx->s12m_tc && av_frame_get_side_data(frame, AV_FRAME_DATA_S12M_TIMECODE)) {
2798+ if (ctx->s12m_tc && avctx->codec->id != AV_CODEC_ID_H264 && av_frame_get_side_data(frame, AV_FRAME_DATA_S12M_TIMECODE)) {
27432799 void *tc_data = NULL;
27442800 size_t tc_size = 0;
27452801
@@ -3046,7 +3102,7 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) · 300 unmodified lines
30463102 if (res < 0)
30473103 return res;
30483104
3049− nvenc_codec_specific_pic_params(avctx, &pic_params, ctx->sei_data, sei_count);
3105+ nvenc_codec_specific_pic_params(avctx, frame, &pic_params, ctx->sei_data, sei_count);
30503106 } else {
30513107 pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
30523108 }
libavcodec/nvenc.h+1−0
@@ -96,6 +96,7 @@ typedef void ID3D11Device; · 95 unmodified lines
9696 #define NVENC_HAVE_LOOKAHEAD_LEVEL
9797 #define NVENC_HAVE_UHQ_TUNING
9898 #define NVENC_HAVE_UNIDIR_B
99+#define NVENC_HAVE_TIME_CODE // added in 12.0, but incomplete until 12.2
99100 #endif
100101
101102 // SDK 13.0 compile time feature checks
libavcodec/nvenc_h264.c+3−0
@@ -199,6 +199,9 @@ static const AVOption options[] = { · 198 unmodified lines
199199 { "middle", "", 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, VE, .unit = "b_ref_mode" },
200200 #endif
201201 { "a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
202+#ifdef NVENC_HAVE_TIME_CODE
203+ { "s12m_tc", "Use timecode (if available)", OFFSET(s12m_tc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
204+#endif
202205 { "dpb_size", "Specifies the DPB size used for encoding (0 means automatic)",
203206 OFFSET(dpb_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
204207 #ifdef NVENC_HAVE_MULTIPASS

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t