History

avcodec/nvenc: add support for writing mastering metadata SEI messages

Including Mastering Display and Content Light Level. Requires SDK 13.0, and only supports HEVC and AV1.

James Almer committed 1 year ago

Commit 1fbe9de1 parent a8595da4 files · +91 −1Browse files

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

Unified · Split

3 files
  1. libavcodec/nvenc.c +86 −0
  2. libavcodec/nvenc.h +2 −0
  3. libavcodec/version.h +1 −1
libavcodec/nvenc.c+86−0
@@ -35,6 +35,7 @@ · 34 unmodified lines
3535 #include "libavutil/mem.h"
3636 #include "libavutil/pixdesc.h"
3737 #include "libavutil/mathematics.h"
38+#include "libavutil/mastering_display_metadata.h"
3839 #include "atsc_a53.h"
3940 #include "codec_desc.h"
4041 #include "encode.h"
@@ -1470,6 +1471,15 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx) · 1429 unmodified lines
14701471 #endif
14711472 }
14721473
1474+#ifdef NVENC_HAVE_HEVC_AND_AV1_MASTERING_METADATA
1475+ ctx->mdm = hevc->outputMasteringDisplay = !!av_frame_side_data_get(avctx->decoded_side_data,
1476+ avctx->nb_decoded_side_data,
1477+ AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
1478+ ctx->cll = hevc->outputMaxCll = !!av_frame_side_data_get(avctx->decoded_side_data,
1479+ avctx->nb_decoded_side_data,
1480+ AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
1481+#endif
1482+
14731483 #ifdef NVENC_HAVE_HEVC_CONSTRAINED_ENCODING
14741484 if (ctx->constrained_encoding)
14751485 hevc->enableConstrainedEncoding = 1;
@@ -1638,6 +1648,15 @@ static av_cold int nvenc_setup_av1_config(AVCodecContext *avctx) · 162 unmodified lines
16381648 av1->pixelBitDepthMinus8 = (IS_10BIT(ctx->data_pix_fmt) || ctx->highbitdepth) ? 2 : 0;
16391649 #endif
16401650
1651+#ifdef NVENC_HAVE_HEVC_AND_AV1_MASTERING_METADATA
1652+ ctx->mdm = av1->outputMasteringDisplay = !!av_frame_side_data_get(avctx->decoded_side_data,
1653+ avctx->nb_decoded_side_data,
1654+ AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
1655+ ctx->cll = av1->outputMaxCll = !!av_frame_side_data_get(avctx->decoded_side_data,
1656+ avctx->nb_decoded_side_data,
1657+ AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
1658+#endif
1659+
16411660 if (ctx->b_ref_mode >= 0)
16421661 av1->useBFramesAsRef = ctx->b_ref_mode;
16431662
@@ -2892,6 +2911,10 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) · 1248 unmodified lines
28922911 int res, res2;
28932912 int sei_count = 0;
28942913 int i;
2914+#ifdef NVENC_HAVE_HEVC_AND_AV1_MASTERING_METADATA
2915+ MASTERING_DISPLAY_INFO mastering_disp_info = { 0 };
2916+ CONTENT_LIGHT_LEVEL content_light_level = { 0 };
2917+#endif
28952918
28962919 NvencContext *ctx = avctx->priv_data;
28972920 NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
@@ -2956,6 +2979,69 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) · 58 unmodified lines
29562979 sei_count = res;
29572980 }
29582981
2982+#ifdef NVENC_HAVE_HEVC_AND_AV1_MASTERING_METADATA
2983+ if (ctx->mdm || ctx->cll) {
2984+ const AVFrameSideData *sd_mdm = av_frame_get_side_data(frame, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
2985+ const AVFrameSideData *sd_cll = av_frame_get_side_data(frame, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
2986+ const int chroma_den = (avctx->codec->id == AV_CODEC_ID_AV1) ? 1 << 16 : 50000;
2987+ const int max_luma_den = (avctx->codec->id == AV_CODEC_ID_AV1) ? 1 << 8 : 10000;
2988+ const int min_luma_den = (avctx->codec->id == AV_CODEC_ID_AV1) ? 1 << 14 : 10000;
2989+
2990+ if (!sd_mdm)
2991+ sd_mdm = av_frame_side_data_get(avctx->decoded_side_data,
2992+ avctx->nb_decoded_side_data,
2993+ AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
2994+ if (!sd_cll)
2995+ sd_cll = av_frame_side_data_get(avctx->decoded_side_data,
2996+ avctx->nb_decoded_side_data,
2997+ AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
2998+
2999+ if (sd_mdm) {
3000+ const AVMasteringDisplayMetadata *mdm = (AVMasteringDisplayMetadata *)sd_mdm->data;
3001+
3002+ mastering_disp_info.r.x = av_rescale(mdm->display_primaries[0][0].num, chroma_den,
3003+ mdm->display_primaries[0][0].den);
3004+ mastering_disp_info.r.y = av_rescale(mdm->display_primaries[0][1].num, chroma_den,
3005+ mdm->display_primaries[0][1].den);
3006+ mastering_disp_info.g.x = av_rescale(mdm->display_primaries[1][0].num, chroma_den,
3007+ mdm->display_primaries[1][0].den);
3008+ mastering_disp_info.g.y = av_rescale(mdm->display_primaries[1][1].num, chroma_den,
3009+ mdm->display_primaries[1][1].den);
3010+ mastering_disp_info.b.x = av_rescale(mdm->display_primaries[2][0].num, chroma_den,
3011+ mdm->display_primaries[2][0].den);
3012+ mastering_disp_info.b.y = av_rescale(mdm->display_primaries[2][1].num, chroma_den,
3013+ mdm->display_primaries[2][1].den);
3014+ mastering_disp_info.whitePoint.x = av_rescale(mdm->white_point[0].num, chroma_den,
3015+ mdm->white_point[0].den);
3016+ mastering_disp_info.whitePoint.y = av_rescale(mdm->white_point[1].num, chroma_den,
3017+ mdm->white_point[1].den);
3018+ mastering_disp_info.maxLuma = av_rescale(mdm->max_luminance.num, max_luma_den,
3019+ mdm->max_luminance.den);
3020+ mastering_disp_info.minLuma = av_rescale(mdm->min_luminance.num, min_luma_den,
3021+ mdm->min_luminance.den);
3022+
3023+ if (avctx->codec->id == AV_CODEC_ID_HEVC)
3024+ pic_params.codecPicParams.hevcPicParams.pMasteringDisplay = &mastering_disp_info;
3025+ else if (avctx->codec->id == AV_CODEC_ID_AV1)
3026+ pic_params.codecPicParams.av1PicParams.pMasteringDisplay = &mastering_disp_info;
3027+ else
3028+ return AVERROR_BUG;
3029+ }
3030+ if (sd_cll) {
3031+ const AVContentLightMetadata *cll = (AVContentLightMetadata *)sd_cll->data;
3032+
3033+ content_light_level.maxContentLightLevel = cll->MaxCLL;
3034+ content_light_level.maxPicAverageLightLevel = cll->MaxFALL;
3035+
3036+ if (avctx->codec->id == AV_CODEC_ID_HEVC)
3037+ pic_params.codecPicParams.hevcPicParams.pMaxCll = &content_light_level;
3038+ else if (avctx->codec->id == AV_CODEC_ID_AV1)
3039+ pic_params.codecPicParams.av1PicParams.pMaxCll = &content_light_level;
3040+ else
3041+ return AVERROR_BUG;
3042+ }
3043+ }
3044+#endif
29593045 res = nvenc_store_frame_data(avctx, &pic_params, frame);
29603046 if (res < 0)
29613047 return res;
libavcodec/nvenc.h+2−0
@@ -104,6 +104,7 @@ typedef void ID3D11Device; · 103 unmodified lines
104104 #define NVENC_HAVE_422_SUPPORT
105105 #define NVENC_HAVE_AV1_UHQ_TUNING
106106 #define NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
107+#define NVENC_HAVE_HEVC_AND_AV1_MASTERING_METADATA
107108 #endif
108109
109110 typedef struct NvencSurface
@@ -306,6 +307,7 @@ typedef struct NvencContext · 196 unmodified lines
306307 int lookahead_level;
307308 int unidir_b;
308309 int split_encode_mode;
310+ int mdm, cll;
309311 } NvencContext;
310312
311313 int ff_nvenc_encode_init(AVCodecContext *avctx);
libavcodec/version.h+1−1
@@ -30,7 +30,7 @@ · 29 unmodified lines
3030 #include "version_major.h"
3131
3232 #define LIBAVCODEC_VERSION_MINOR 32
33−#define LIBAVCODEC_VERSION_MICRO 100
33+#define LIBAVCODEC_VERSION_MICRO 101
3434
3535 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
3636 LIBAVCODEC_VERSION_MINOR, \

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