| @@ -34,6 +34,7 @@ · 33 unmodified lines |
| 34 | 34 | #include "libavutil/imgutils.h" |
| 35 | 35 | #include "libavutil/mem.h" |
| 36 | 36 | #include "libavutil/pixdesc.h" |
| 37 | +#include "libavutil/timecode_internal.h" |
| 37 | 38 | #include "libavutil/mathematics.h" |
| 38 | 39 | #include "libavutil/mastering_display_metadata.h" |
| 39 | 40 | #include "atsc_a53.h" |
| @@ -1417,6 +1418,11 @@ static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx) · 1377 unmodified lines |
| 1417 | 1418 | } |
| 1418 | 1419 | #endif |
| 1419 | 1420 | |
| 1421 | +#ifdef NVENC_HAVE_TIME_CODE |
| 1422 | + if (ctx->s12m_tc) |
| 1423 | + h264->enableTimeCode = 1; |
| 1424 | +#endif |
| 1425 | + |
| 1420 | 1426 | return 0; |
| 1421 | 1427 | } |
| 1422 | 1428 | |
| @@ -2420,7 +2426,52 @@ static int nvenc_upload_frame(AVCodecContext *avctx, const AVFrame *frame, · 997 unmodified lines |
| 2420 | 2426 | } |
| 2421 | 2427 | } |
| 2422 | 2428 | |
| 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, |
| 2424 | 2475 | NV_ENC_PIC_PARAMS *params, |
| 2425 | 2476 | NV_ENC_SEI_PAYLOAD *sei_data, |
| 2426 | 2477 | int sei_count) |
| @@ -2438,6 +2489,11 @@ static void nvenc_codec_specific_pic_params(AVCodecContext *avctx, · 11 unmodified lines |
| 2438 | 2489 | params->codecPicParams.h264PicParams.seiPayloadArrayCnt = sei_count; |
| 2439 | 2490 | } |
| 2440 | 2491 | |
| 2492 | +#ifdef NVENC_HAVE_TIME_CODE |
| 2493 | + if (ctx->s12m_tc) |
| 2494 | + nvenc_fill_time_code(avctx, frame, ¶ms->codecPicParams.h264PicParams.timeCode); |
| 2495 | +#endif |
| 2496 | + |
| 2441 | 2497 | break; |
| 2442 | 2498 | case AV_CODEC_ID_HEVC: |
| 2443 | 2499 | params->codecPicParams.hevcPicParams.sliceMode = |
| @@ -2739,7 +2795,7 @@ static int prepare_sei_data_array(AVCodecContext *avctx, const AVFrame *frame) · 295 unmodified lines |
| 2739 | 2795 | } |
| 2740 | 2796 | } |
| 2741 | 2797 | |
| 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)) { |
| 2743 | 2799 | void *tc_data = NULL; |
| 2744 | 2800 | size_t tc_size = 0; |
| 2745 | 2801 | |
| @@ -3046,7 +3102,7 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) · 300 unmodified lines |
| 3046 | 3102 | if (res < 0) |
| 3047 | 3103 | return res; |
| 3048 | 3104 | |
| 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); |
| 3050 | 3106 | } else { |
| 3051 | 3107 | pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS; |
| 3052 | 3108 | } |