[FFmpeg-devel] [PATCH 15/15] lavc/proresdec: add videotoolbox hwaccel
rcombs
rcombs at rcombs.me
Sat Nov 13 23:09:16 EET 2021
---
configure | 2 +
libavcodec/hwaccels.h | 1 +
libavcodec/proresdec2.c | 12 +++++-
libavcodec/videotoolbox.c | 77 ++++++++++++++++++++++++++++++++++++++-
4 files changed, 89 insertions(+), 3 deletions(-)
diff --git a/configure b/configure
index 2c6dd59e62..6983b8af7a 100755
--- a/configure
+++ b/configure
@@ -3054,6 +3054,8 @@ mpeg4_vdpau_hwaccel_deps="vdpau"
mpeg4_vdpau_hwaccel_select="mpeg4_decoder"
mpeg4_videotoolbox_hwaccel_deps="videotoolbox"
mpeg4_videotoolbox_hwaccel_select="mpeg4_decoder"
+prores_videotoolbox_hwaccel_deps="videotoolbox"
+prores_videotoolbox_hwaccel_select="prores_decoder"
vc1_d3d11va_hwaccel_deps="d3d11va"
vc1_d3d11va_hwaccel_select="vc1_decoder"
vc1_d3d11va2_hwaccel_deps="d3d11va"
diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h
index 65e778f3e4..1e7b464950 100644
--- a/libavcodec/hwaccels.h
+++ b/libavcodec/hwaccels.h
@@ -60,6 +60,7 @@ extern const AVHWAccel ff_mpeg4_nvdec_hwaccel;
extern const AVHWAccel ff_mpeg4_vaapi_hwaccel;
extern const AVHWAccel ff_mpeg4_vdpau_hwaccel;
extern const AVHWAccel ff_mpeg4_videotoolbox_hwaccel;
+extern const AVHWAccel ff_prores_videotoolbox_hwaccel;
extern const AVHWAccel ff_vc1_d3d11va_hwaccel;
extern const AVHWAccel ff_vc1_d3d11va2_hwaccel;
extern const AVHWAccel ff_vc1_dxva2_hwaccel;
diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c
index 5b1d7da693..719194f21e 100644
--- a/libavcodec/proresdec2.c
+++ b/libavcodec/proresdec2.c
@@ -33,6 +33,7 @@
#include "avcodec.h"
#include "get_bits.h"
+#include "hwconfig.h"
#include "idctdsp.h"
#include "internal.h"
#include "profiles.h"
@@ -268,12 +269,15 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,
}
if (pix_fmt != ctx->pix_fmt) {
-#define HWACCEL_MAX 0
+#define HWACCEL_MAX (CONFIG_PRORES_VIDEOTOOLBOX_HWACCEL)
enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmtp = pix_fmts;
int ret;
ctx->pix_fmt = pix_fmt;
+#if CONFIG_PRORES_VIDEOTOOLBOX_HWACCEL
+ *fmtp++ = AV_PIX_FMT_VIDEOTOOLBOX;
+#endif
*fmtp++ = ctx->pix_fmt;
*fmtp = AV_PIX_FMT_NONE;
@@ -864,4 +868,10 @@ const AVCodec ff_prores_decoder = {
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS,
.profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
+ .hw_configs = (const AVCodecHWConfigInternal *const []) {
+#if CONFIG_PRORES_VIDEOTOOLBOX_HWACCEL
+ HWACCEL_VIDEOTOOLBOX(prores),
+#endif
+ NULL
+ },
};
diff --git a/libavcodec/videotoolbox.c b/libavcodec/videotoolbox.c
index 9ca84e873d..029c1c09c7 100644
--- a/libavcodec/videotoolbox.c
+++ b/libavcodec/videotoolbox.c
@@ -32,6 +32,7 @@
#include "h264dec.h"
#include "hevcdec.h"
#include "mpegvideo.h"
+#include "proresdec.h"
#include <Availability.h>
#include <TargetConditionals.h>
@@ -183,7 +184,6 @@ CFDataRef ff_videotoolbox_avcc_extradata_create(AVCodecContext *avctx)
int pps_size = escape_ps(NULL, h->ps.pps->data, h->ps.pps->data_size);
int vt_extradata_size;
uint8_t *vt_extradata;
- int i;
vt_extradata_size = 6 + 2 + sps_size + 3 + pps_size;
vt_extradata = av_malloc(vt_extradata_size);
@@ -870,6 +870,31 @@ static int videotoolbox_start(AVCodecContext *avctx)
case AV_CODEC_ID_MPEG4 :
videotoolbox->cm_codec_type = kCMVideoCodecType_MPEG4Video;
break;
+ case AV_CODEC_ID_PRORES :
+ switch (avctx->codec_tag) {
+ case MKTAG('a','p','c','o'):
+ videotoolbox->cm_codec_type = kCMVideoCodecType_AppleProRes422Proxy;
+ break;
+ case MKTAG('a','p','c','s'):
+ videotoolbox->cm_codec_type = kCMVideoCodecType_AppleProRes422LT;
+ break;
+ case MKTAG('a','p','c','n'):
+ videotoolbox->cm_codec_type = kCMVideoCodecType_AppleProRes422;
+ break;
+ case MKTAG('a','p','c','h'):
+ videotoolbox->cm_codec_type = kCMVideoCodecType_AppleProRes422HQ;
+ break;
+ case MKTAG('a','p','4','h'):
+ videotoolbox->cm_codec_type = kCMVideoCodecType_AppleProRes4444;
+ break;
+ case MKTAG('a','p','4','x'):
+ videotoolbox->cm_codec_type = kCMVideoCodecType_AppleProRes4444XQ;
+ break;
+ default:
+ videotoolbox->cm_codec_type = avctx->codec_tag;
+ av_log(avctx, AV_LOG_WARNING, "Unknown prores profile %d\n", avctx->codec_tag);
+ }
+ break;
case AV_CODEC_ID_VP9 :
videotoolbox->cm_codec_type = kCMVideoCodecType_VP9;
break;
@@ -877,6 +902,14 @@ static int videotoolbox_start(AVCodecContext *avctx)
break;
}
+#ifdef __MAC_10_9
+ if (avctx->codec_id == AV_CODEC_ID_PRORES) {
+ if (__builtin_available(macOS 10.9, *)) {
+ VTRegisterProfessionalVideoWorkflowVideoDecoders();
+ }
+ }
+#endif
+
#ifdef __MAC_10_11
if (__builtin_available(macOS 10.11, *)) {
VTRegisterSupplementalVideoDecoderIfAvailable(videotoolbox->cm_codec_type);
@@ -1065,6 +1098,30 @@ static int videotoolbox_mpeg_end_frame(AVCodecContext *avctx)
return ff_videotoolbox_common_end_frame(avctx, frame);
}
+static int videotoolbox_prores_start_frame(AVCodecContext *avctx,
+ const uint8_t *buffer,
+ uint32_t size)
+{
+ return 0;
+}
+
+static int videotoolbox_prores_decode_slice(AVCodecContext *avctx,
+ const uint8_t *buffer,
+ uint32_t size)
+{
+ VTContext *vtctx = avctx->internal->hwaccel_priv_data;
+
+ return ff_videotoolbox_buffer_copy(vtctx, buffer, size);
+}
+
+static int videotoolbox_prores_end_frame(AVCodecContext *avctx)
+{
+ ProresContext *ctx = avctx->priv_data;
+ AVFrame *frame = ctx->frame;
+
+ return ff_videotoolbox_common_end_frame(avctx, frame);
+}
+
static enum AVPixelFormat videotoolbox_best_pixel_format(AVCodecContext *avctx) {
const AVPixFmtDescriptor *descriptor = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
if (!descriptor)
@@ -1076,7 +1133,8 @@ static enum AVPixelFormat videotoolbox_best_pixel_format(AVCodecContext *avctx)
return AV_PIX_FMT_AYUV64;
#if HAVE_KCVPIXELFORMATTYPE_444YPCBCR16BIPLANARVIDEORANGE
- if (depth > 10)
+ // ProRes has issues when decoding to 10-bit, so always use 16
+ if (depth > 10 || avctx->codec_id == AV_CODEC_ID_PRORES)
return descriptor->log2_chroma_w == 0 ? AV_PIX_FMT_P416 : AV_PIX_FMT_P216;
#endif
@@ -1288,6 +1346,21 @@ const AVHWAccel ff_mpeg4_videotoolbox_hwaccel = {
.priv_data_size = sizeof(VTContext),
};
+const AVHWAccel ff_prores_videotoolbox_hwaccel = {
+ .name = "prores_videotoolbox",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_PRORES,
+ .pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX,
+ .alloc_frame = ff_videotoolbox_alloc_frame,
+ .start_frame = videotoolbox_prores_start_frame,
+ .decode_slice = videotoolbox_prores_decode_slice,
+ .end_frame = videotoolbox_prores_end_frame,
+ .frame_params = ff_videotoolbox_frame_params,
+ .init = ff_videotoolbox_common_init,
+ .uninit = ff_videotoolbox_uninit,
+ .priv_data_size = sizeof(VTContext),
+};
+
static AVVideotoolboxContext *av_videotoolbox_alloc_context_with_pix_fmt(enum AVPixelFormat pix_fmt,
bool full_range)
{
--
2.33.1
More information about the ffmpeg-devel
mailing list