From patchwork Fri May 17 09:55:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lance Wang X-Patchwork-Id: 13184 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 36F85447D11 for ; Fri, 17 May 2019 12:56:42 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 07D5C68A451; Fri, 17 May 2019 12:56:42 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pl1-f195.google.com (mail-pl1-f195.google.com [209.85.214.195]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 33F3F689C22 for ; Fri, 17 May 2019 12:56:35 +0300 (EEST) Received: by mail-pl1-f195.google.com with SMTP id y3so3152278plp.0 for ; Fri, 17 May 2019 02:56:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=KvZZX1Mwkpqe+BGL3NhdvEnt69oA9CCDuXRRgb2UNQk=; b=CKXLOm6AirMs3tkwJI1H784kyT4TY6oGriO1D6dESTRR9u40r0r8Q7qqcdC41ygiaZ rGcQ+v3B14fUbfzlS+GMzoKhviekEY5I3K0QGxd6R4y5BL+FhyRatL5AXTHK40Bpfiam qNUMjZOZcx7ZG4bVK+o6PaTuQfUAnMbxBu/Fd5BsTDx3CX7X72lwUFxtNJ8MFEHWzq2G x1uw8tp00ytSVFV94ieZuKD85h0ql3AKsfrAoOwId5sHSBCzvSwgKBaqVm+xe1AKQHsQ Pa+m5U1+aUT9fbNkux5IUGkLXr7YrAd7HJSGLgsVtCo1OYBGeKKLxUkoGCxrEGBmz/NM 7NKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=KvZZX1Mwkpqe+BGL3NhdvEnt69oA9CCDuXRRgb2UNQk=; b=jEF+UmkC9U7nK4ydbQpNPiYsmapdX61hweQEyoGKVknQs2CIARDg2gWCc2Iu2I8MB3 s91/Gm2oXK0e1OkeFaGzuGKvk3HMoj6n4CxusULu0zH2Z8Rrdk+scolnvaIOxC0c2CUt 2n0gVrfHbbU4DfJyjZDEbGUQbAC+vkb2z2hX/1+DFWbEjgKSVreDYu6ESGTmHRchCtkt qgKiebPY1fMT1amqEXwbTuAB8kO8MuHMTnLg41AAEEFeYvYqE18b6U1gxRb4zfeFRL5L EFBQqrb+2HoRqlcPurRqNlo+TpaIRQ0Dvgaya2NNuZsC31sA0oRCjfugYSucxxY5IacH cGeA== X-Gm-Message-State: APjAAAWKWQG6jvs0lapxVTzrOzfH2VKIkYyKNy+Hj3TOflEd5AkccPQk J0ehiFI+0smFulDZeUqnnjxnBBv8Z/U= X-Google-Smtp-Source: APXvYqwNY4Ho0gL7ZzwI6TNuOPChgYtHMK7qUOCjzjKgVk7NWaaqxfob27/nJ8dq06yGXyjzT1tATA== X-Received: by 2002:a17:902:d24:: with SMTP id 33mr55013231plu.148.1558086993275; Fri, 17 May 2019 02:56:33 -0700 (PDT) Received: from localhost.localdomain ([47.90.99.151]) by smtp.gmail.com with ESMTPSA id j64sm6088845pfb.126.2019.05.17.02.56.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 17 May 2019 02:56:32 -0700 (PDT) From: lance.lmwang@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Fri, 17 May 2019 17:55:38 +0800 Message-Id: <20190517095538.32264-2-lance.lmwang@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190517095538.32264-1-lance.lmwang@gmail.com> References: <20190517095538.32264-1-lance.lmwang@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/2] avcodec/nvenc: add master display and light level sei data for hdr10 X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 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: Limin Wang Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Limin Wang --- libavcodec/nvenc.c | 73 +++++++++++++++++++++++++++++++++++++++++ libavcodec/nvenc.h | 1 + libavcodec/nvenc_hevc.c | 2 ++ 3 files changed, 76 insertions(+) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 77eb9918a4..55547d4246 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -22,6 +22,9 @@ #include "config.h" #include "nvenc.h" +#include "cbs_h265.h" +#include "hevc_sei.h" +#include "put_bits.h" #include "libavutil/hwcontext_cuda.h" #include "libavutil/hwcontext.h" @@ -30,6 +33,7 @@ #include "libavutil/avassert.h" #include "libavutil/mem.h" #include "libavutil/pixdesc.h" +#include "libavutil/mastering_display_metadata.h" #include "internal.h" #define CHECK_CU(x) FF_CUDA_CHECK_DL(avctx, dl_fn->cuda_dl, x) @@ -2110,6 +2114,75 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) } } + if (ctx->hdr) { + AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA); + + if (sd) { + AVMasteringDisplayMetadata *mdm = (AVMasteringDisplayMetadata *)sd->data; + // HEVC uses a g,b,r ordering, which we convert to a more natural r,g,b + const int mapping[3] = {2, 0, 1}; + const int chroma_den = 50000; + const int luma_den = 10000; + + if (mdm->has_primaries && mdm->has_luminance) { + H265RawSEIMasteringDisplayColourVolume smd; + + for (i = 0; i < 3; i++) { + const int j = mapping[i]; + smd.display_primaries_x[i] = chroma_den * av_q2d(mdm->display_primaries[j][0]); + smd.display_primaries_y[i] = chroma_den * av_q2d( mdm->display_primaries[j][1]); + } + + smd.white_point_x = chroma_den * av_q2d(mdm->white_point[0]); + smd.white_point_y = chroma_den * av_q2d(mdm->white_point[1]); + smd.max_display_mastering_luminance = luma_den * av_q2d(mdm->max_luminance); + smd.min_display_mastering_luminance = luma_den * av_q2d(mdm->min_luminance); + + sei_data[sei_count].payloadSize = sizeof(H265RawSEIMasteringDisplayColourVolume); + sei_data[sei_count].payloadType = HEVC_SEI_TYPE_MASTERING_DISPLAY_INFO; + sei_data[sei_count].payload = av_mallocz(sei_data[sei_count].payloadSize); + if (sei_data[sei_count].payload) { + PutBitContext pb; + + init_put_bits(&pb, sei_data[sei_count].payload, sei_data[sei_count].payloadSize); + for (i = 0; i < 3; i++) { + put_bits(&pb, 16, smd.display_primaries_x[i]); + put_bits(&pb, 16, smd.display_primaries_y[i]); + } + put_bits(&pb, 16, smd.white_point_x); + put_bits(&pb, 16, smd.white_point_y); + put_bits(&pb, 32, smd.max_display_mastering_luminance); + put_bits(&pb, 32, smd.min_display_mastering_luminance); + flush_put_bits(&pb); + + sei_count ++; + } + } + } + + sd = av_frame_get_side_data(frame, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL); + if (sd) { + AVContentLightMetadata *clm = (AVContentLightMetadata *)sd->data; + H265RawSEIContentLightLevelInfo clli; + + clli.max_content_light_level = FFMIN(clm->MaxCLL, 65535); + clli.max_pic_average_light_level = FFMIN(clm->MaxFALL, 65535); + + sei_data[sei_count].payloadSize = sizeof(H265RawSEIContentLightLevelInfo); + sei_data[sei_count].payloadType = HEVC_SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO; + sei_data[sei_count].payload = av_mallocz(sei_data[sei_count].payloadSize); + if (sei_data[sei_count].payload) { + PutBitContext pb; + + init_put_bits(&pb, sei_data[sei_count].payload, sei_data[sei_count].payloadSize); + put_bits(&pb, 16, clli.max_content_light_level); + put_bits(&pb, 16, clli.max_pic_average_light_level); + flush_put_bits(&pb); + + sei_count ++; + } + } + } nvenc_codec_specific_pic_params(avctx, &pic_params, sei_data, sei_count); } else { pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS; diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index ddd6168409..952e691147 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -192,6 +192,7 @@ typedef struct NvencContext int coder; int b_ref_mode; int a53_cc; + int hdr; } NvencContext; int ff_nvenc_encode_init(AVCodecContext *avctx); diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c index d567d960ba..ea7580acb6 100644 --- a/libavcodec/nvenc_hevc.c +++ b/libavcodec/nvenc_hevc.c @@ -127,6 +127,8 @@ static const AVOption options[] = { { "each", "", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, VE, "b_ref_mode" }, { "middle", "", 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, VE, "b_ref_mode" }, #endif + { "hdr","Include HDR metadata for mastering display colour volume and content light level information", + OFFSET(hdr),AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, { NULL } };