The sdk av1 encoder can accept HDR metadata via mfxEncodeCtrl::ExtParam.
Unified · Split
| @@ -25,6 +25,8 @@ · 24 unmodified lines | |||
| 25 | #include <mfxvideo.h> | 25 | #include <mfxvideo.h> |
| 26 | 26 | ||
| 27 | #include "libavutil/common.h" | 27 | #include "libavutil/common.h" |
| 28 | #include "libavutil/mastering_display_metadata.h" | ||
| 29 | #include "libavutil/mem.h" | ||
| 28 | #include "libavutil/opt.h" | 30 | #include "libavutil/opt.h" |
| 29 | 31 | ||
| 30 | #include "avcodec.h" | 32 | #include "avcodec.h" |
| @@ -39,6 +41,75 @@ typedef struct QSVAV1EncContext { · 8 unmodified lines | |||
| 39 | QSVEncContext qsv; | 41 | QSVEncContext qsv; |
| 40 | } QSVAV1EncContext; | 42 | } QSVAV1EncContext; |
| 41 | 43 | ||
| 44 | static int qsv_av1_set_encode_ctrl(AVCodecContext *avctx, | ||
| 45 | const AVFrame *frame, mfxEncodeCtrl *enc_ctrl) | ||
| 46 | { | ||
| 47 | QSVAV1EncContext *q = avctx->priv_data; | ||
| 48 | AVFrameSideData *sd; | ||
| 49 | |||
| 50 | if (!frame || !QSV_RUNTIME_VERSION_ATLEAST(q->qsv.ver, 2, 11)) | ||
| 51 | return 0; | ||
| 52 | |||
| 53 | sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA); | ||
| 54 | if (sd) { | ||
| 55 | AVMasteringDisplayMetadata *mdm = (AVMasteringDisplayMetadata *)sd->data; | ||
| 56 | if (mdm->has_primaries && mdm->has_luminance) { | ||
| 57 | const int chroma_den = 1 << 16; | ||
| 58 | const int max_luma_den = 1 << 8; | ||
| 59 | const int min_luma_den = 1 << 14; | ||
| 60 | mfxExtMasteringDisplayColourVolume *mdcv = av_mallocz(sizeof(*mdcv)); | ||
| 61 | if (!mdcv) | ||
| 62 | return AVERROR(ENOMEM); | ||
| 63 | |||
| 64 | mdcv->Header.BufferId = MFX_EXTBUFF_MASTERING_DISPLAY_COLOUR_VOLUME; | ||
| 65 | mdcv->Header.BufferSz = sizeof(*mdcv); | ||
| 66 | |||
| 67 | for (int i = 0; i < 3; i++) { | ||
| 68 | mdcv->DisplayPrimariesX[i] = | ||
| 69 | av_rescale(mdm->display_primaries[i][0].num, chroma_den, | ||
| 70 | mdm->display_primaries[i][0].den); | ||
| 71 | mdcv->DisplayPrimariesY[i] = | ||
| 72 | av_rescale(mdm->display_primaries[i][1].num, chroma_den, | ||
| 73 | mdm->display_primaries[i][1].den); | ||
| 74 | } | ||
| 75 | |||
| 76 | mdcv->WhitePointX = | ||
| 77 | av_rescale(mdm->white_point[0].num, chroma_den, | ||
| 78 | mdm->white_point[0].den); | ||
| 79 | mdcv->WhitePointY = | ||
| 80 | av_rescale(mdm->white_point[1].num, chroma_den, | ||
| 81 | mdm->white_point[1].den); | ||
| 82 | |||
| 83 | mdcv->MaxDisplayMasteringLuminance = | ||
| 84 | av_rescale(mdm->max_luminance.num, max_luma_den, | ||
| 85 | mdm->max_luminance.den); | ||
| 86 | mdcv->MinDisplayMasteringLuminance = | ||
| 87 | av_rescale(mdm->min_luminance.num, min_luma_den, | ||
| 88 | mdm->min_luminance.den); | ||
| 89 | |||
| 90 | enc_ctrl->ExtParam[enc_ctrl->NumExtParam++] = (mfxExtBuffer *)mdcv; | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 94 | sd = av_frame_get_side_data(frame, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL); | ||
| 95 | if (sd) { | ||
| 96 | AVContentLightMetadata *clm = (AVContentLightMetadata *)sd->data; | ||
| 97 | mfxExtContentLightLevelInfo *clli = av_mallocz(sizeof(*clli)); | ||
| 98 | if (!clli) | ||
| 99 | return AVERROR(ENOMEM); | ||
| 100 | |||
| 101 | clli->Header.BufferId = MFX_EXTBUFF_CONTENT_LIGHT_LEVEL_INFO; | ||
| 102 | clli->Header.BufferSz = sizeof(*clli); | ||
| 103 | |||
| 104 | clli->MaxContentLightLevel = clm->MaxCLL; | ||
| 105 | clli->MaxPicAverageLightLevel = clm->MaxFALL; | ||
| 106 | |||
| 107 | enc_ctrl->ExtParam[enc_ctrl->NumExtParam++] = (mfxExtBuffer *)clli; | ||
| 108 | } | ||
| 109 | |||
| 110 | return 0; | ||
| 111 | } | ||
| 112 | |||
| 42 | static av_cold int qsv_enc_init(AVCodecContext *avctx) | 113 | static av_cold int qsv_enc_init(AVCodecContext *avctx) |
| 43 | { | 114 | { |
| 44 | QSVAV1EncContext *q = avctx->priv_data; | 115 | QSVAV1EncContext *q = avctx->priv_data; |
| @@ -61,6 +132,8 @@ static av_cold int qsv_enc_init(AVCodecContext *avctx) · 16 unmodified lines | |||
| 61 | return ret; | 132 | return ret; |
| 62 | } | 133 | } |
| 63 | 134 | ||
| 135 | q->qsv.set_encode_ctrl_cb = qsv_av1_set_encode_ctrl; | ||
| 136 | |||
| 64 | return ff_qsv_enc_init(avctx, &q->qsv); | 137 | return ff_qsv_enc_init(avctx, &q->qsv); |
| 65 | } | 138 | } |
| 66 | 139 | ||