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 | opencl_dxva2 | 2460 | opencl_dxva2 |
| 2461 | opencl_vaapi_beignet | 2461 | opencl_vaapi_beignet |
| 2462 | opencl_vaapi_intel_media | 2462 | opencl_vaapi_intel_media |
| 2463 | opencl_videotoolbox | ||
| 2463 | perl | 2464 | perl |
| 2464 | pod2man | 2465 | pod2man |
| 2465 | texi2html | 2466 | texi2html |
| @@ -7217,6 +7218,11 @@ if enabled_all opencl d3d11va ; then · 4751 unmodified lines | |||
| 7217 | enable opencl_d3d11 | 7218 | enable opencl_d3d11 |
| 7218 | fi | 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 | enabled vdpau && | 7226 | enabled vdpau && |
| 7221 | check_cpp_condition vdpau vdpau/vdpau.h "defined VDP_DECODER_PROFILE_MPEG4_PART2_ASP" | 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 | #include "hwcontext_drm.h" | 72 | #include "hwcontext_drm.h" |
| 73 | #endif | 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 | #if HAVE_OPENCL_VAAPI_INTEL_MEDIA && CONFIG_LIBMFX | 80 | #if HAVE_OPENCL_VAAPI_INTEL_MEDIA && CONFIG_LIBMFX |
| 76 | extern int ff_qsv_get_surface_base_handle(mfxFrameSurface1 *surf, | 81 | extern int ff_qsv_get_surface_base_handle(mfxFrameSurface1 *surf, |
| 77 | enum AVHWDeviceType base_dev_typ, | 82 | enum AVHWDeviceType base_dev_typ, |
| @@ -1364,6 +1369,12 @@ static int opencl_device_derive(AVHWDeviceContext *hwdev, · 1286 unmodified lines | |||
| 1364 | break; | 1369 | break; |
| 1365 | #endif | 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 | default: | 1378 | default: |
| 1368 | err = AVERROR(ENOSYS); | 1379 | err = AVERROR(ENOSYS); |
| 1369 | break; | 1380 | break; |
| @@ -2819,6 +2830,84 @@ fail: · 1449 unmodified lines | |||
| 2819 | 2830 | ||
| 2820 | #endif | 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 | static int opencl_map_from(AVHWFramesContext *hwfc, AVFrame *dst, | 2911 | static int opencl_map_from(AVHWFramesContext *hwfc, AVFrame *dst, |
| 2823 | const AVFrame *src, int flags) | 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 | case AV_PIX_FMT_DRM_PRIME: | 2953 | case AV_PIX_FMT_DRM_PRIME: |
| 2865 | if (priv->drm_arm_mapping_usable) | 2954 | if (priv->drm_arm_mapping_usable) |
| 2866 | return opencl_map_from_drm_arm(hwfc, dst, src, flags); | 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 | #endif | 2960 | #endif |
| 2868 | } | 2961 | } |
| 2869 | return AVERROR(ENOSYS); | 2962 | return AVERROR(ENOSYS); |
| @@ -2922,6 +3015,10 @@ static int opencl_frames_derive_to(AVHWFramesContext *dst_fc, · 52 unmodified lines | |||
| 2922 | if (!priv->drm_arm_mapping_usable) | 3015 | if (!priv->drm_arm_mapping_usable) |
| 2923 | return AVERROR(ENOSYS); | 3016 | return AVERROR(ENOSYS); |
| 2924 | break; | 3017 | break; |
| 3018 | #endif | ||
| 3019 | #if HAVE_OPENCL_VIDEOTOOLBOX | ||
| 3020 | case AV_HWDEVICE_TYPE_VIDEOTOOLBOX: | ||
| 3021 | break; | ||
| 2925 | #endif | 3022 | #endif |
| 2926 | default: | 3023 | default: |
| 2927 | return AVERROR(ENOSYS); | 3024 | return AVERROR(ENOSYS); |