[FFmpeg-devel] [PATCH] lavc/videotoolboxenc: Add support for HEVC with Alpha.

2021-02-22 Thread bouno
From: Hironori Bono 

This change supports the "HEVC Video with Alpha" profile introduced in WWDC 2019
. (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 
---
 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) {
+CFNumb

Re: [FFmpeg-devel] [PATCH] lavc/videotoolboxenc: Add support for HEVC with Alpha.

2021-03-16 Thread bouno
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: bo...@rouge.plala.or.jp

-Original Message-
From: ffmpeg-devel  On Behalf Of 
bo...@rouge.plala.or.jp
Sent: Tuesday, February 23, 2021 2:02 PM
To: ffmpeg-devel@ffmpeg.org
Cc: Hironori Bono 
Subject: [FFmpeg-devel] [PATCH] lavc/videotoolboxenc: Add support for HEVC with 
Alpha.

From: Hironori Bono 

This change supports the "HEVC Video with Alpha" profile introduced in WWDC 
2019 . (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 
---
 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 :