For example: ./ffmpeg -hwaccel videotoolbox \ -hwaccel_output_format videotoolbox_vld \ -i foo.mp4 \ -vf hwmap=derive_device=opencl,transpose_opencl=dir=clock,hwmap,format=nv12 \ -c:v hevc_videotoolbox \ -c:a copy \ -b:v 2M -tag:v hvc1 bar.mp4
Unified · Split
| @@ -2460,6 +2460,7 @@ HAVE_LIST=" · 2459 unmodified lines | ||
| 2460 | 2460 | opencl_dxva2 |
| 2461 | 2461 | opencl_vaapi_beignet |
| 2462 | 2462 | opencl_vaapi_intel_media |
| 2463 | + opencl_videotoolbox | |
| 2463 | 2464 | perl |
| 2464 | 2465 | pod2man |
| 2465 | 2466 | texi2html |
| @@ -7217,6 +7218,11 @@ if enabled_all opencl d3d11va ; then · 4751 unmodified lines | ||
| 7217 | 7218 | enable opencl_d3d11 |
| 7218 | 7219 | fi |
| 7219 | 7220 | |
| 7221 | +if enabled_all opencl videotoolbox ; then | |
| 7222 | + check_func_headers OpenCL/cl_gl_ext.h clCreateImageFromIOSurfaceWithPropertiesAPPLE -framework VideoToolbox -framework OpenCL && | |
| 7223 | + enable opencl_videotoolbox | |
| 7224 | +fi | |
| 7225 | + | |
| 7220 | 7226 | enabled vdpau && |
| 7221 | 7227 | check_cpp_condition vdpau vdpau/vdpau.h "defined VDP_DECODER_PROFILE_MPEG4_PART2_ASP" |
| 7222 | 7228 | |
| @@ -72,6 +72,11 @@ · 71 unmodified lines | ||
| 72 | 72 | #include "hwcontext_drm.h" |
| 73 | 73 | #endif |
| 74 | 74 | |
| 75 | +#if HAVE_OPENCL_VIDEOTOOLBOX | |
| 76 | +#include <OpenCL/cl_gl_ext.h> | |
| 77 | +#include <VideoToolbox/VideoToolbox.h> | |
| 78 | +#endif | |
| 79 | + | |
| 75 | 80 | #if HAVE_OPENCL_VAAPI_INTEL_MEDIA && CONFIG_LIBMFX |
| 76 | 81 | extern int ff_qsv_get_surface_base_handle(mfxFrameSurface1 *surf, |
| 77 | 82 | enum AVHWDeviceType base_dev_typ, |
| @@ -1364,6 +1369,12 @@ static int opencl_device_derive(AVHWDeviceContext *hwdev, · 1286 unmodified lines | ||
| 1364 | 1369 | break; |
| 1365 | 1370 | #endif |
| 1366 | 1371 | |
| 1372 | +#if HAVE_OPENCL_VIDEOTOOLBOX | |
| 1373 | + case AV_HWDEVICE_TYPE_VIDEOTOOLBOX: | |
| 1374 | + err = opencl_device_create(hwdev, NULL, NULL, 0); | |
| 1375 | + break; | |
| 1376 | +#endif | |
| 1377 | + | |
| 1367 | 1378 | default: |
| 1368 | 1379 | err = AVERROR(ENOSYS); |
| 1369 | 1380 | break; |
| @@ -2819,6 +2830,84 @@ fail: · 1449 unmodified lines | ||
| 2819 | 2830 | |
| 2820 | 2831 | #endif |
| 2821 | 2832 | |
| 2833 | +#if HAVE_OPENCL_VIDEOTOOLBOX | |
| 2834 | + | |
| 2835 | +static void opencl_unmap_from_vt(AVHWFramesContext *hwfc, | |
| 2836 | + HWMapDescriptor *hwmap) | |
| 2837 | +{ | |
| 2838 | + uint8_t *desc = hwmap->priv; | |
| 2839 | + opencl_pool_free(hwfc, desc); | |
| 2840 | +} | |
| 2841 | + | |
| 2842 | +static int opencl_map_from_vt(AVHWFramesContext *dst_fc, AVFrame *dst, | |
| 2843 | + const AVFrame *src, int flags) | |
| 2844 | +{ | |
| 2845 | + CVPixelBufferRef pixbuf = (CVPixelBufferRef) src->data[3]; | |
| 2846 | + IOSurfaceRef io_surface_ref = CVPixelBufferGetIOSurface(pixbuf); | |
| 2847 | + cl_int err = 0; | |
| 2848 | + AVOpenCLFrameDescriptor *desc = NULL; | |
| 2849 | + AVOpenCLDeviceContext *dst_dev = dst_fc->device_ctx->hwctx; | |
| 2850 | + | |
| 2851 | + if (!io_surface_ref) { | |
| 2852 | + av_log(dst_fc, AV_LOG_ERROR, "Failed to get IOSurfaceRef\n"); | |
| 2853 | + return AVERROR_EXTERNAL; | |
| 2854 | + } | |
| 2855 | + | |
| 2856 | + desc = av_mallocz(sizeof(*desc)); | |
| 2857 | + if (!desc) | |
| 2858 | + return AVERROR(ENOMEM); | |
| 2859 | + | |
| 2860 | + for (int p = 0;; p++) { | |
| 2861 | + cl_image_format image_format; | |
| 2862 | + cl_image_desc image_desc; | |
| 2863 | + cl_iosurface_properties_APPLE props[] = { | |
| 2864 | + CL_IOSURFACE_REF_APPLE, (cl_iosurface_properties_APPLE) io_surface_ref, | |
| 2865 | + CL_IOSURFACE_PLANE_APPLE, p, | |
| 2866 | + 0 | |
| 2867 | + }; | |
| 2868 | + | |
| 2869 | + err = opencl_get_plane_format(dst_fc->sw_format, p, | |
| 2870 | + src->width, src->height, | |
| 2871 | + &image_format, &image_desc); | |
| 2872 | + if (err == AVERROR(ENOENT)) | |
| 2873 | + break; | |
| 2874 | + if (err < 0) | |
| 2875 | + goto fail; | |
| 2876 | + | |
| 2877 | + desc->planes[p] = clCreateImageFromIOSurfaceWithPropertiesAPPLE(dst_dev->context, | |
| 2878 | + opencl_mem_flags_for_mapping(flags), | |
| 2879 | + &image_format, &image_desc, | |
| 2880 | + props, &err); | |
| 2881 | + if (!desc->planes[p]) { | |
| 2882 | + av_log(dst_fc, AV_LOG_ERROR, "Failed to create image from IOSurfaceRef\n"); | |
| 2883 | + err = AVERROR(EIO); | |
| 2884 | + goto fail; | |
| 2885 | + } | |
| 2886 | + desc->nb_planes++; | |
| 2887 | + } | |
| 2888 | + | |
| 2889 | + for (int i = 0; i < desc->nb_planes; i++) | |
| 2890 | + dst->data[i] = (uint8_t *) desc->planes[i]; | |
| 2891 | + | |
| 2892 | + err = ff_hwframe_map_create(dst->hw_frames_ctx, dst, src, | |
| 2893 | + opencl_unmap_from_vt, desc); | |
| 2894 | + if (err < 0) | |
| 2895 | + goto fail; | |
| 2896 | + | |
| 2897 | + dst->width = src->width; | |
| 2898 | + dst->height = src->height; | |
| 2899 | + | |
| 2900 | + return 0; | |
| 2901 | + | |
| 2902 | +fail: | |
| 2903 | + for (int i = 0; i < desc->nb_planes; i++) | |
| 2904 | + clReleaseMemObject(desc->planes[i]); | |
| 2905 | + av_freep(&desc); | |
| 2906 | + return err; | |
| 2907 | +} | |
| 2908 | + | |
| 2909 | +#endif | |
| 2910 | + | |
| 2822 | 2911 | static int opencl_map_from(AVHWFramesContext *hwfc, AVFrame *dst, |
| 2823 | 2912 | const AVFrame *src, int flags) |
| 2824 | 2913 | { |
| @@ -2864,6 +2953,10 @@ static int opencl_map_to(AVHWFramesContext *hwfc, AVFrame *dst, · 39 unmodified lines | ||
| 2864 | 2953 | case AV_PIX_FMT_DRM_PRIME: |
| 2865 | 2954 | if (priv->drm_arm_mapping_usable) |
| 2866 | 2955 | return opencl_map_from_drm_arm(hwfc, dst, src, flags); |
| 2956 | +#endif | |
| 2957 | +#if HAVE_OPENCL_VIDEOTOOLBOX | |
| 2958 | + case AV_PIX_FMT_VIDEOTOOLBOX: | |
| 2959 | + return opencl_map_from_vt(hwfc, dst, src, flags); | |
| 2867 | 2960 | #endif |
| 2868 | 2961 | } |
| 2869 | 2962 | return AVERROR(ENOSYS); |
| @@ -2922,6 +3015,10 @@ static int opencl_frames_derive_to(AVHWFramesContext *dst_fc, · 52 unmodified lines | ||
| 2922 | 3015 | if (!priv->drm_arm_mapping_usable) |
| 2923 | 3016 | return AVERROR(ENOSYS); |
| 2924 | 3017 | break; |
| 3018 | +#endif | |
| 3019 | +#if HAVE_OPENCL_VIDEOTOOLBOX | |
| 3020 | + case AV_HWDEVICE_TYPE_VIDEOTOOLBOX: | |
| 3021 | + break; | |
| 2925 | 3022 | #endif |
| 2926 | 3023 | default: |
| 2927 | 3024 | return AVERROR(ENOSYS); |