]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/vf_scale_cuda.c
avfilter/ebur128: prefer to use variable instead of type for sizeof
[ffmpeg] / libavfilter / vf_scale_cuda.c
index ecfd6a1c92428c409d7a9fc5cdbad19a0ed19f48..1ffb73f83182bf225b698feb37880a9557683ab9 100644 (file)
@@ -35,7 +35,7 @@
 #include "avfilter.h"
 #include "formats.h"
 #include "internal.h"
-#include "scale.h"
+#include "scale_eval.h"
 #include "video.h"
 
 static const enum AVPixelFormat supported_formats[] = {
@@ -43,7 +43,8 @@ static const enum AVPixelFormat supported_formats[] = {
     AV_PIX_FMT_NV12,
     AV_PIX_FMT_YUV444P,
     AV_PIX_FMT_P010,
-    AV_PIX_FMT_P016
+    AV_PIX_FMT_P016,
+    AV_PIX_FMT_YUV444P16,
 };
 
 #define DIV_UP(a, b) ( ((a) + (b) - 1) / (b) )
@@ -81,6 +82,9 @@ typedef struct CUDAScaleContext {
     char *w_expr;               ///< width  expression string
     char *h_expr;               ///< height expression string
 
+    int force_original_aspect_ratio;
+    int force_divisible_by;
+
     CUcontext   cu_ctx;
     CUmodule    cu_module;
     CUfunction  cu_func_uchar;
@@ -304,6 +308,9 @@ static av_cold int cudascale_config_props(AVFilterLink *outlink)
                                         &w, &h)) < 0)
         goto fail;
 
+    ff_scale_adjust_dimensions(inlink, &w, &h,
+                               s->force_original_aspect_ratio, s->force_divisible_by);
+
     if (((int64_t)h * inlink->w) > INT_MAX  ||
         ((int64_t)w * inlink->h) > INT_MAX)
         av_log(ctx, AV_LOG_ERROR, "Rescaled value for width or height is too big.\n");
@@ -389,12 +396,12 @@ static int scalecuda_resize(AVFilterContext *ctx,
                            out->data[0], out->width, out->height, out->linesize[0],
                            1);
         call_resize_kernel(ctx, s->cu_func_uchar, 1,
-                           in->data[0]+in->linesize[0]*in->height, in->width/2, in->height/2, in->linesize[0]/2,
-                           out->data[0]+out->linesize[0]*out->height, out->width/2, out->height/2, out->linesize[0]/2,
+                           in->data[1], in->width/2, in->height/2, in->linesize[0]/2,
+                           out->data[1], out->width/2, out->height/2, out->linesize[0]/2,
                            1);
         call_resize_kernel(ctx, s->cu_func_uchar, 1,
-                           in->data[0]+ ALIGN_UP((in->linesize[0]*in->height*5)/4, s->tex_alignment), in->width/2, in->height/2, in->linesize[0]/2,
-                           out->data[0]+(out->linesize[0]*out->height*5)/4, out->width/2, out->height/2, out->linesize[0]/2,
+                           in->data[2], in->width/2, in->height/2, in->linesize[0]/2,
+                           out->data[2], out->width/2, out->height/2, out->linesize[0]/2,
                            1);
         break;
     case AV_PIX_FMT_YUV444P:
@@ -403,14 +410,28 @@ static int scalecuda_resize(AVFilterContext *ctx,
                            out->data[0], out->width, out->height, out->linesize[0],
                            1);
         call_resize_kernel(ctx, s->cu_func_uchar, 1,
-                           in->data[0]+in->linesize[0]*in->height, in->width, in->height, in->linesize[0],
-                           out->data[0]+out->linesize[0]*out->height, out->width, out->height, out->linesize[0],
+                           in->data[1], in->width, in->height, in->linesize[0],
+                           out->data[1], out->width, out->height, out->linesize[0],
                            1);
         call_resize_kernel(ctx, s->cu_func_uchar, 1,
-                           in->data[0]+in->linesize[0]*in->height*2, in->width, in->height, in->linesize[0],
-                           out->data[0]+out->linesize[0]*out->height*2, out->width, out->height, out->linesize[0],
+                           in->data[2], in->width, in->height, in->linesize[0],
+                           out->data[2], out->width, out->height, out->linesize[0],
                            1);
         break;
+    case AV_PIX_FMT_YUV444P16:
+        call_resize_kernel(ctx, s->cu_func_ushort, 1,
+                           in->data[0], in->width, in->height, in->linesize[0] / 2,
+                           out->data[0], out->width, out->height, out->linesize[0] / 2,
+                           2);
+        call_resize_kernel(ctx, s->cu_func_ushort, 1,
+                           in->data[1], in->width, in->height, in->linesize[1] / 2,
+                           out->data[1], out->width, out->height, out->linesize[1] / 2,
+                           2);
+        call_resize_kernel(ctx, s->cu_func_ushort, 1,
+                           in->data[2], in->width, in->height, in->linesize[2] / 2,
+                           out->data[2], out->width, out->height, out->linesize[2] / 2,
+                           2);
+        break;
     case AV_PIX_FMT_NV12:
         call_resize_kernel(ctx, s->cu_func_uchar, 1,
                            in->data[0], in->width, in->height, in->linesize[0],
@@ -418,7 +439,7 @@ static int scalecuda_resize(AVFilterContext *ctx,
                            1);
         call_resize_kernel(ctx, s->cu_func_uchar2, 2,
                            in->data[1], in->width/2, in->height/2, in->linesize[1],
-                           out->data[0] + out->linesize[0] * ((out->height + 31) & ~0x1f), out->width/2, out->height/2, out->linesize[1]/2,
+                           out->data[1], out->width/2, out->height/2, out->linesize[1]/2,
                            1);
         break;
     case AV_PIX_FMT_P010LE:
@@ -428,7 +449,7 @@ static int scalecuda_resize(AVFilterContext *ctx,
                            2);
         call_resize_kernel(ctx, s->cu_func_ushort2, 2,
                            in->data[1], in->width / 2, in->height / 2, in->linesize[1]/2,
-                           out->data[0] + out->linesize[0] * ((out->height + 31) & ~0x1f), out->width / 2, out->height / 2, out->linesize[1] / 4,
+                           out->data[1], out->width / 2, out->height / 2, out->linesize[1] / 4,
                            2);
         break;
     case AV_PIX_FMT_P016LE:
@@ -438,7 +459,7 @@ static int scalecuda_resize(AVFilterContext *ctx,
                            2);
         call_resize_kernel(ctx, s->cu_func_ushort2, 2,
                            in->data[1], in->width / 2, in->height / 2, in->linesize[1] / 2,
-                           out->data[0] + out->linesize[0] * ((out->height + 31) & ~0x1f), out->width / 2, out->height / 2, out->linesize[1] / 4,
+                           out->data[1], out->width / 2, out->height / 2, out->linesize[1] / 4,
                            2);
         break;
     default:
@@ -466,6 +487,9 @@ static int cudascale_scale(AVFilterContext *ctx, AVFrame *out, AVFrame *in)
     av_frame_move_ref(out, s->frame);
     av_frame_move_ref(s->frame, s->tmp_frame);
 
+    s->frame->width  = s->planes_out[0].width;
+    s->frame->height = s->planes_out[0].height;
+
     ret = av_frame_copy_props(out, in);
     if (ret < 0)
         return ret;
@@ -518,6 +542,11 @@ fail:
 static const AVOption options[] = {
     { "w",      "Output video width",  OFFSET(w_expr),     AV_OPT_TYPE_STRING, { .str = "iw"   }, .flags = FLAGS },
     { "h",      "Output video height", OFFSET(h_expr),     AV_OPT_TYPE_STRING, { .str = "ih"   }, .flags = FLAGS },
+    { "force_original_aspect_ratio", "decrease or increase w/h if necessary to keep the original AR", OFFSET(force_original_aspect_ratio), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 2, FLAGS, "force_oar" },
+    { "disable",  NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, 0, 0, FLAGS, "force_oar" },
+    { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, "force_oar" },
+    { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, FLAGS, "force_oar" },
+    { "force_divisible_by", "enforce that the output resolution is divisible by a defined integer when force_original_aspect_ratio is used", OFFSET(force_divisible_by), AV_OPT_TYPE_INT, { .i64 = 1}, 1, 256, FLAGS },
     { NULL },
 };