Merge commit '7e2561fa8313982aa21f7657953eedeeb33b210d'
[ffmpeg.git] / libavfilter / vf_hwupload_cuda.c
index 0ab5276..1e47ada 100644 (file)
@@ -1,24 +1,23 @@
 /*
- * 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
  */
 
 #include "libavutil/buffer.h"
 #include "libavutil/hwcontext.h"
-#include "libavutil/hwcontext_cuda.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
 
@@ -35,60 +34,14 @@ typedef struct CudaUploadContext {
     AVBufferRef *hwframe;
 } CudaUploadContext;
 
-static void cudaupload_ctx_free(AVHWDeviceContext *ctx)
-{
-    AVCUDADeviceContext *hwctx = ctx->hwctx;
-    cuCtxDestroy(hwctx->cuda_ctx);
-}
-
 static av_cold int cudaupload_init(AVFilterContext *ctx)
 {
     CudaUploadContext *s = ctx->priv;
+    char buf[64] = { 0 };
 
-    AVHWDeviceContext   *device_ctx;
-    AVCUDADeviceContext *device_hwctx;
-    CUdevice device;
-    CUcontext cuda_ctx = NULL, dummy;
-    CUresult err;
-    int ret;
-
-    err = cuInit(0);
-    if (err != CUDA_SUCCESS) {
-        av_log(ctx, AV_LOG_ERROR, "Could not initialize the CUDA driver API\n");
-        return AVERROR_UNKNOWN;
-    }
-
-    err = cuDeviceGet(&device, s->device_idx);
-    if (err != CUDA_SUCCESS) {
-        av_log(ctx, AV_LOG_ERROR, "Could not get the device number %d\n", s->device_idx);
-        return AVERROR_UNKNOWN;
-    }
-
-    err = cuCtxCreate(&cuda_ctx, 0, device);
-    if (err != CUDA_SUCCESS) {
-        av_log(ctx, AV_LOG_ERROR, "Error creating a CUDA context\n");
-        return AVERROR_UNKNOWN;
-    }
-
-    cuCtxPopCurrent(&dummy);
-
-    s->hwdevice = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_CUDA);
-    if (!s->hwdevice) {
-        cuCtxDestroy(cuda_ctx);
-        return AVERROR(ENOMEM);
-    }
-
-    device_ctx       = (AVHWDeviceContext*)s->hwdevice->data;
-    device_ctx->free = cudaupload_ctx_free;
+    snprintf(buf, sizeof(buf), "%d", s->device_idx);
 
-    device_hwctx = device_ctx->hwctx;
-    device_hwctx->cuda_ctx = cuda_ctx;
-
-    ret = av_hwdevice_ctx_init(s->hwdevice);
-    if (ret < 0)
-        return ret;
-
-    return 0;
+    return av_hwdevice_ctx_create(&s->hwdevice, AV_HWDEVICE_TYPE_CUDA, buf, NULL, 0);
 }
 
 static av_cold void cudaupload_uninit(AVFilterContext *ctx)
@@ -101,6 +54,8 @@ static av_cold void cudaupload_uninit(AVFilterContext *ctx)
 
 static int cudaupload_query_formats(AVFilterContext *ctx)
 {
+    int ret;
+
     static const enum AVPixelFormat input_pix_fmts[] = {
         AV_PIX_FMT_NV12, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV444P,
         AV_PIX_FMT_NONE,
@@ -109,10 +64,17 @@ static int cudaupload_query_formats(AVFilterContext *ctx)
         AV_PIX_FMT_CUDA, AV_PIX_FMT_NONE,
     };
     AVFilterFormats *in_fmts  = ff_make_format_list(input_pix_fmts);
-    AVFilterFormats *out_fmts = ff_make_format_list(output_pix_fmts);
+    AVFilterFormats *out_fmts;
 
-    ff_formats_ref(in_fmts,  &ctx->inputs[0]->out_formats);
-    ff_formats_ref(out_fmts, &ctx->outputs[0]->in_formats);
+    ret = ff_formats_ref(in_fmts, &ctx->inputs[0]->out_formats);
+    if (ret < 0)
+        return ret;
+
+    out_fmts = ff_make_format_list(output_pix_fmts);
+
+    ret = ff_formats_ref(out_fmts, &ctx->outputs[0]->in_formats);
+    if (ret < 0)
+        return ret;
 
     return 0;
 }
@@ -134,8 +96,8 @@ static int cudaupload_config_output(AVFilterLink *outlink)
     hwframe_ctx            = (AVHWFramesContext*)s->hwframe->data;
     hwframe_ctx->format    = AV_PIX_FMT_CUDA;
     hwframe_ctx->sw_format = inlink->format;
-    hwframe_ctx->width     = FFALIGN(inlink->w, 16);
-    hwframe_ctx->height    = FFALIGN(inlink->h, 16);
+    hwframe_ctx->width     = inlink->w;
+    hwframe_ctx->height    = inlink->h;
 
     ret = av_hwframe_ctx_init(s->hwframe);
     if (ret < 0)
@@ -151,7 +113,7 @@ static int cudaupload_config_output(AVFilterLink *outlink)
 static int cudaupload_filter_frame(AVFilterLink *link, AVFrame *in)
 {
     AVFilterContext   *ctx = link->dst;
-    CudaUploadContext   *s = ctx->priv;
+    AVFilterLink  *outlink = ctx->outputs[0];
 
     AVFrame *out = NULL;
     int ret;
@@ -185,18 +147,13 @@ fail:
 }
 
 #define OFFSET(x) offsetof(CudaUploadContext, x)
-#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
-static const AVOption options[] = {
-    { "device", "Number of the device to use", OFFSET(device_idx), AV_OPT_TYPE_INT, { .i64 = 0 }, .flags = FLAGS },
+#define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
+static const AVOption cudaupload_options[] = {
+    { "device", "Number of the device to use", OFFSET(device_idx), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
     { NULL },
 };
 
-static const AVClass cudaupload_class = {
-    .class_name = "cudaupload",
-    .item_name  = av_default_item_name,
-    .option     = options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
+AVFILTER_DEFINE_CLASS(cudaupload);
 
 static const AVFilterPad cudaupload_inputs[] = {
     {
@@ -218,7 +175,7 @@ static const AVFilterPad cudaupload_outputs[] = {
 
 AVFilter ff_vf_hwupload_cuda = {
     .name        = "hwupload_cuda",
-    .description = NULL_IF_CONFIG_SMALL("Upload a system memory frame to a CUDA device"),
+    .description = NULL_IF_CONFIG_SMALL("Upload a system memory frame to a CUDA device."),
 
     .init      = cudaupload_init,
     .uninit    = cudaupload_uninit,