From 7d2c836d9af04c4e745a21c46a74635d00152906 Mon Sep 17 00:00:00 2001 From: Martin Piatka Date: Thu, 5 Aug 2021 14:35:10 +0200 Subject: [PATCH] Lavd: Add videotoolbox decoding --- configure.ac | 4 +++ src/hwaccel_libav_common.c | 3 +- src/hwaccel_libav_common.h | 3 +- src/video_decompress/libavcodec.c | 48 +++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 39270630f..d403209d1 100644 --- a/configure.ac +++ b/configure.ac @@ -1674,6 +1674,10 @@ then lavc_hwacc_common=yes fi +if test $system = MacOSX; then + lavc_hwacc_common=yes +fi + if test $lavc_hwacc_common = yes then LAVC_HWACC_FLAGS="${LAVC_HWACC_FLAGS} -DHWACC_COMMON" diff --git a/src/hwaccel_libav_common.c b/src/hwaccel_libav_common.c index 0e3fc7894..10fb13709 100644 --- a/src/hwaccel_libav_common.c +++ b/src/hwaccel_libav_common.c @@ -110,7 +110,8 @@ int create_hw_frame_ctx(AVBufferRef *device_ref, if (ret < 0) { av_buffer_unref(ctx); *ctx = NULL; - log_msg(LOG_LEVEL_ERROR, "[hw accel] Unable to init hwframe_ctx!!\n\n"); + log_msg(LOG_LEVEL_ERROR, "[hw accel] Unable to init hwframe_ctx: %s\n\n", + av_err2str(ret)); return ret; } diff --git a/src/hwaccel_libav_common.h b/src/hwaccel_libav_common.h index f6f56a639..6edb2307d 100644 --- a/src/hwaccel_libav_common.h +++ b/src/hwaccel_libav_common.h @@ -64,7 +64,8 @@ struct hw_accel_state { enum { HWACCEL_NONE, HWACCEL_VDPAU, - HWACCEL_VAAPI + HWACCEL_VAAPI, + HWACCEL_VIDEOTOOLBOX } type; bool copy; ///< Specifies whether to use the copy mode diff --git a/src/video_decompress/libavcodec.c b/src/video_decompress/libavcodec.c index 48f619a22..d56c60e38 100644 --- a/src/video_decompress/libavcodec.c +++ b/src/video_decompress/libavcodec.c @@ -448,6 +448,51 @@ static bool has_conversion(enum AVPixelFormat pix_fmt, codec_t *ug_pix_fmt) { return false; } +#if HAVE_MACOSX +int videotoolbox_init(struct AVCodecContext *s, + struct hw_accel_state *state, + codec_t out_codec) +{ + AVBufferRef *device_ref = NULL; + int ret = create_hw_device_ctx(AV_HWDEVICE_TYPE_VIDEOTOOLBOX, &device_ref); + if(ret < 0) + return ret; + + AVBufferRef *hw_frames_ctx = NULL; + ret = create_hw_frame_ctx(device_ref, + s->coded_width, + s->coded_height, + AV_PIX_FMT_VIDEOTOOLBOX, + s->sw_pix_fmt, + 0, //has to be 0, ffmpeg can't allocate frames by itself + &hw_frames_ctx); + + if(ret < 0) + goto fail; + + AVFrame *frame = av_frame_alloc(); + if(!frame){ + ret = -1; + goto fail; + } + + state->type = HWACCEL_VIDEOTOOLBOX; + state->copy = true; + state->tmp_frame = frame; + + s->hw_frames_ctx = hw_frames_ctx; + s->hw_device_ctx = device_ref; + + return 0; + +fail: + av_frame_free(&state->tmp_frame); + av_buffer_unref(&device_ref); + av_buffer_unref(&hw_frames_ctx); + return ret; +} +#endif + static enum AVPixelFormat get_format_callback(struct AVCodecContext *s __attribute__((unused)), const enum AVPixelFormat *fmt) { if (log_level >= LOG_LEVEL_VERBOSE) { @@ -474,6 +519,9 @@ static enum AVPixelFormat get_format_callback(struct AVCodecContext *s __attribu #endif #ifdef HWACC_VAAPI {AV_PIX_FMT_VAAPI, vaapi_init} +#endif +#ifdef HAVE_MACOSX + {AV_PIX_FMT_VIDEOTOOLBOX, videotoolbox_init} #endif };