Merge commit '1bd986ed4b0e95ded368a8eeb5c044853c090f9b'
[ffmpeg.git] / libavutil / hwcontext.c
index ff9fe99..7f8e227 100644 (file)
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -32,10 +32,16 @@ static const HWContextType * const hw_table[] = {
 #if CONFIG_CUDA
     &ff_hwcontext_type_cuda,
 #endif
+#if CONFIG_D3D11VA
+    &ff_hwcontext_type_d3d11va,
+#endif
+#if CONFIG_LIBDRM
+    &ff_hwcontext_type_drm,
+#endif
 #if CONFIG_DXVA2
     &ff_hwcontext_type_dxva2,
 #endif
-#if CONFIG_LIBMFX
+#if CONFIG_QSV
     &ff_hwcontext_type_qsv,
 #endif
 #if CONFIG_VAAPI
@@ -44,15 +50,21 @@ static const HWContextType * const hw_table[] = {
 #if CONFIG_VDPAU
     &ff_hwcontext_type_vdpau,
 #endif
+#if CONFIG_VIDEOTOOLBOX
+    &ff_hwcontext_type_videotoolbox,
+#endif
     NULL,
 };
 
-const char *hw_type_names[] = {
+static const char *const hw_type_names[] = {
     [AV_HWDEVICE_TYPE_CUDA]   = "cuda",
+    [AV_HWDEVICE_TYPE_DRM]    = "drm",
     [AV_HWDEVICE_TYPE_DXVA2]  = "dxva2",
+    [AV_HWDEVICE_TYPE_D3D11VA] = "d3d11va",
     [AV_HWDEVICE_TYPE_QSV]    = "qsv",
     [AV_HWDEVICE_TYPE_VAAPI]  = "vaapi",
     [AV_HWDEVICE_TYPE_VDPAU]  = "vdpau",
+    [AV_HWDEVICE_TYPE_VIDEOTOOLBOX] = "videotoolbox",
 };
 
 enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name)
@@ -228,7 +240,7 @@ AVBufferRef *av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
     AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)device_ref_in->data;
     const HWContextType  *hw_type = device_ctx->internal->hw_type;
     AVHWFramesContext *ctx;
-    AVBufferRef *buf, *device_ref = NULL;;
+    AVBufferRef *buf, *device_ref = NULL;
 
     ctx = av_mallocz(sizeof(*ctx));
     if (!ctx)
@@ -455,6 +467,11 @@ int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
         // and map the frame immediately.
         AVFrame *src_frame;
 
+        frame->format = ctx->format;
+        frame->hw_frames_ctx = av_buffer_ref(hwframe_ref);
+        if (!frame->hw_frames_ctx)
+            return AVERROR(ENOMEM);
+
         src_frame = av_frame_alloc();
         if (!src_frame)
             return AVERROR(ENOMEM);
@@ -464,7 +481,8 @@ int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
         if (ret < 0)
             return ret;
 
-        ret = av_hwframe_map(frame, src_frame, 0);
+        ret = av_hwframe_map(frame, src_frame,
+                             ctx->internal->source_allocation_map_flags);
         if (ret) {
             av_log(ctx, AV_LOG_ERROR, "Failed to map frame into derived "
                    "frame context: %d.\n", ret);
@@ -633,6 +651,10 @@ int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ref_ptr,
     goto fail;
 
 done:
+    ret = av_hwdevice_ctx_init(dst_ref);
+    if (ret < 0)
+        goto fail;
+
     *dst_ref_ptr = dst_ref;
     return 0;
 
@@ -816,7 +838,20 @@ int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx,
         goto fail;
     }
 
-    ret = av_hwframe_ctx_init(dst_ref);
+    dst->internal->source_allocation_map_flags =
+        flags & (AV_HWFRAME_MAP_READ      |
+                 AV_HWFRAME_MAP_WRITE     |
+                 AV_HWFRAME_MAP_OVERWRITE |
+                 AV_HWFRAME_MAP_DIRECT);
+
+    ret = AVERROR(ENOSYS);
+    if (src->internal->hw_type->frames_derive_from)
+        ret = src->internal->hw_type->frames_derive_from(dst, src, flags);
+    if (ret == AVERROR(ENOSYS) &&
+        dst->internal->hw_type->frames_derive_to)
+        ret = dst->internal->hw_type->frames_derive_to(dst, src, flags);
+    if (ret == AVERROR(ENOSYS))
+        ret = 0;
     if (ret)
         goto fail;