[FFmpeg-devel] [PATCH] lavc/videotoolboxenc: Add support for HEVC with Alpha.
Rick Kern
kernrj at gmail.com
Fri Mar 19 20:52:55 EET 2021
On Tue, Mar 16, 2021 at 5:59 AM <bouno at rouge.plala.or.jp> wrote:
> Greetings,
>
> Thank you for your help in advance.
> Unfortunately, my patch, which add support the "HEVC with alpha" profile
> to the videotoolbox encoder, has not been reviewed for nearly three weeks.
> Would it be possible to give me why nobody has reviewed my patch?
>
> Regards,
>
> Hironori Bono
> E-mail: bouno at rouge.plala.or.jp
>
> -----Original Message-----
> From: ffmpeg-devel <ffmpeg-devel-bounces at ffmpeg.org> On Behalf Of
> bouno at rouge.plala.or.jp
> Sent: Tuesday, February 23, 2021 2:02 PM
> To: ffmpeg-devel at ffmpeg.org
> Cc: Hironori Bono <bouno at rouge.plala.or.jp>
> Subject: [FFmpeg-devel] [PATCH] lavc/videotoolboxenc: Add support for HEVC
> with Alpha.
>
> From: Hironori Bono <bouno at rouge.plala.or.jp>
>
> This change supports the "HEVC Video with Alpha" profile introduced in
> WWDC 2019 <https://developer.apple.com/videos/play/wwdc2019/506/>. (This
> change is a partial fix for Ticket #7965.)
>
> For example, the following command converts an animation PNG file to an
> HEVC with Alpha video:
> ./ffmpeg -i fate-suite/apng/clock.png -c:v hevc_videotoolbox -allow_sw 1
> -alpha_quality 0.75 -vtag hvc1 clock.mov
>
> (This change uses the "HEVC Video with Alpha" profile only when the
> '-alpha_quality' value is not 0 for backward compatibility.)
>
> Signed-off-by: Hironori Bono <bouno at rouge.plala.or.jp>
>
Applied
> ---
> configure | 2 ++
> libavcodec/videotoolboxenc.c | 47 +++++++++++++++++++++++++++++++++---
> 2 files changed, 46 insertions(+), 3 deletions(-)
>
> diff --git a/configure b/configure
> index 336301cb40..63adf131b9 100755
> --- a/configure
> +++ b/configure
> @@ -2288,6 +2288,7 @@ TOOLCHAIN_FEATURES="
>
> TYPES_LIST="
> kCMVideoCodecType_HEVC
> + kCMVideoCodecType_HEVCWithAlpha
> kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange
> kCVImageBufferTransferFunction_SMPTE_ST_2084_PQ
> kCVImageBufferTransferFunction_ITU_R_2100_HLG
> @@ -6211,6 +6212,7 @@ enabled avfoundation && { enabled videotoolbox && {
> check_lib coreservices CoreServices/CoreServices.h
> UTGetOSTypeFromString "-framework CoreServices"
> check_func_headers CoreMedia/CMFormatDescription.h
> kCMVideoCodecType_HEVC "-framework CoreMedia"
> + check_func_headers CoreMedia/CMFormatDescription.h
> kCMVideoCodecType_HEVCWithAlpha "-framework CoreMedia"
> check_func_headers CoreVideo/CVPixelBuffer.h
> kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange "-framework CoreVideo"
> check_func_headers CoreVideo/CVImageBuffer.h
> kCVImageBufferTransferFunction_SMPTE_ST_2084_PQ "-framework CoreVideo"
> check_func_headers CoreVideo/CVImageBuffer.h
> kCVImageBufferTransferFunction_ITU_R_2100_HLG "-framework CoreVideo"
> diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c
> index c487d2dc60..9d3c7e29dc 100644
> --- a/libavcodec/videotoolboxenc.c
> +++ b/libavcodec/videotoolboxenc.c
> @@ -40,6 +40,10 @@
> enum { kCMVideoCodecType_HEVC = 'hvc1' }; #endif
>
> +#if !HAVE_KCMVIDEOCODECTYPE_HEVCWITHALPHA
> +enum { kCMVideoCodecType_HEVCWithAlpha = 'muxa' }; #endif
> +
> #if !HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE
> enum { kCVPixelFormatType_420YpCbCr10BiPlanarFullRange = 'xf20' }; enum
> { kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange = 'x420' }; @@ -88,6
> +92,7 @@ static struct{
> CFStringRef kVTProfileLevel_HEVC_Main10_AutoLevel;
>
> CFStringRef kVTCompressionPropertyKey_RealTime;
> + CFStringRef kVTCompressionPropertyKey_TargetQualityForAlpha;
>
> CFStringRef
> kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder;
> CFStringRef
> kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder;
> @@ -147,6 +152,8 @@ static void loadVTEncSymbols(){
> GET_SYM(kVTProfileLevel_HEVC_Main10_AutoLevel,
> "HEVC_Main10_AutoLevel");
>
> GET_SYM(kVTCompressionPropertyKey_RealTime, "RealTime");
> + GET_SYM(kVTCompressionPropertyKey_TargetQualityForAlpha,
> + "TargetQualityForAlpha");
>
>
> GET_SYM(kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder,
> "EnableHardwareAcceleratedVideoEncoder");
> @@ -222,6 +229,7 @@ typedef struct VTEncContext {
>
> int64_t allow_sw;
> int64_t require_sw;
> + double alpha_quality;
>
> bool flushing;
> bool has_b_frames;
> @@ -392,11 +400,17 @@ static int count_nalus(size_t length_code_size,
> return 0;
> }
>
> -static CMVideoCodecType get_cm_codec_type(enum AVCodecID id)
> +static CMVideoCodecType get_cm_codec_type(enum AVCodecID id,
> + enum AVPixelFormat fmt,
> + double alpha_quality)
> {
> switch (id) {
> case AV_CODEC_ID_H264: return kCMVideoCodecType_H264;
> - case AV_CODEC_ID_HEVC: return kCMVideoCodecType_HEVC;
> + case AV_CODEC_ID_HEVC:
> + if (fmt == AV_PIX_FMT_BGRA && alpha_quality > 0.0) {
> + return kCMVideoCodecType_HEVCWithAlpha;
> + }
> + return kCMVideoCodecType_HEVC;
> default: return 0;
> }
> }
> @@ -786,6 +800,8 @@ static int get_cv_pixel_format(AVCodecContext* avctx,
> *av_pixel_format = range == AVCOL_RANGE_JPEG ?
>
> kCVPixelFormatType_420YpCbCr8PlanarFullRange :
>
> kCVPixelFormatType_420YpCbCr8Planar;
> + } else if (fmt == AV_PIX_FMT_BGRA) {
> + *av_pixel_format = kCVPixelFormatType_32BGRA;
> } else if (fmt == AV_PIX_FMT_P010LE) {
> *av_pixel_format = range == AVCOL_RANGE_JPEG ?
>
> kCVPixelFormatType_420YpCbCr10BiPlanarFullRange :
> @@ -1114,6 +1130,20 @@ static int vtenc_create_encoder(AVCodecContext
> *avctx,
> }
> }
>
> + if (vtctx->codec_id == AV_CODEC_ID_HEVC) {
> + if (avctx->pix_fmt == AV_PIX_FMT_BGRA && vtctx->alpha_quality >
> 0.0) {
> + CFNumberRef alpha_quality_num =
> CFNumberCreate(kCFAllocatorDefault,
> +
> kCFNumberDoubleType,
> +
> &vtctx->alpha_quality);
> + if (!alpha_quality_num) return AVERROR(ENOMEM);
> +
> + status = VTSessionSetProperty(vtctx->session,
> +
> compat_keys.kVTCompressionPropertyKey_TargetQualityForAlpha,
> + alpha_quality_num);
> + CFRelease(alpha_quality_num);
> + }
> + }
> +
> if (profile_level) {
> status = VTSessionSetProperty(vtctx->session,
>
> kVTCompressionPropertyKey_ProfileLevel,
> @@ -1326,7 +1356,7 @@ static int vtenc_configure_encoder(AVCodecContext
> *avctx)
> CFNumberRef gamma_level = NULL;
> int status;
>
> - codec_type = get_cm_codec_type(avctx->codec_id);
> + codec_type = get_cm_codec_type(avctx->codec_id, avctx->pix_fmt,
> + vtctx->alpha_quality);
> if (!codec_type) {
> av_log(avctx, AV_LOG_ERROR, "Error: no mapping for AVCodecID
> %d\n", avctx->codec_id);
> return AVERROR(EINVAL);
> @@ -2036,6 +2066,14 @@ static int get_cv_pixel_info(
> strides[2] = frame ? frame->linesize[2] : (avctx->width + 1) / 2;
> break;
>
> + case AV_PIX_FMT_BGRA:
> + *plane_count = 1;
> +
> + widths [0] = avctx->width;
> + heights[0] = avctx->height;
> + strides[0] = frame ? frame->linesize[0] : avctx->width * 4;
> + break;
> +
> case AV_PIX_FMT_P010LE:
> *plane_count = 2;
> widths[0] = avctx->width;
> @@ -2534,6 +2572,7 @@ static const enum AVPixelFormat hevc_pix_fmts[] = {
> AV_PIX_FMT_VIDEOTOOLBOX,
> AV_PIX_FMT_NV12,
> AV_PIX_FMT_YUV420P,
> + AV_PIX_FMT_BGRA,
> AV_PIX_FMT_P010LE,
> AV_PIX_FMT_NONE
> };
> @@ -2611,6 +2650,8 @@ static const AVOption hevc_options[] = {
> { "main", "Main Profile", 0, AV_OPT_TYPE_CONST, { .i64 =
> HEVC_PROF_MAIN }, INT_MIN, INT_MAX, VE, "profile" },
> { "main10", "Main10 Profile", 0, AV_OPT_TYPE_CONST, { .i64 =
> HEVC_PROF_MAIN10 }, INT_MIN, INT_MAX, VE, "profile" },
>
> + { "alpha_quality", "Compression quality for the alpha channel",
> + OFFSET(alpha_quality), AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, 0.0, 1.0,
> + VE },
> +
> COMMON_OPTIONS
> { NULL },
> };
> --
> 2.24.3 (Apple Git-128)
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email ffmpeg-devel-request at ffmpeg.org
> with subject "unsubscribe".
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
More information about the ffmpeg-devel
mailing list