Browse code

lavfi/transpose: implement landscape passthrough mode

Emulate the mp=rotate passthrough mode.

Stefano Sabatini authored on 2012/09/01 18:14:27
Showing 3 changed files
... ...
@@ -3454,7 +3454,7 @@ It accepts a parameter representing an integer, which can assume the
3454 3454
 values:
3455 3455
 
3456 3456
 @table @samp
3457
-@item 0
3457
+@item 0, 4
3458 3458
 Rotate by 90 degrees counterclockwise and vertically flip (default), that is:
3459 3459
 @example
3460 3460
 L.R     L.l
... ...
@@ -3462,7 +3462,7 @@ L.R     L.l
3462 3462
 l.r     R.r
3463 3463
 @end example
3464 3464
 
3465
-@item 1
3465
+@item 1, 5
3466 3466
 Rotate by 90 degrees clockwise, that is:
3467 3467
 @example
3468 3468
 L.R     l.L
... ...
@@ -3470,7 +3470,7 @@ L.R     l.L
3470 3470
 l.r     r.R
3471 3471
 @end example
3472 3472
 
3473
-@item 2
3473
+@item 2, 6
3474 3474
 Rotate by 90 degrees counterclockwise, that is:
3475 3475
 @example
3476 3476
 L.R     R.r
... ...
@@ -3478,7 +3478,7 @@ L.R     R.r
3478 3478
 l.r     L.l
3479 3479
 @end example
3480 3480
 
3481
-@item 3
3481
+@item 3, 7
3482 3482
 Rotate by 90 degrees clockwise and vertically flip, that is:
3483 3483
 @example
3484 3484
 L.R     r.R
... ...
@@ -3487,6 +3487,9 @@ l.r     l.L
3487 3487
 @end example
3488 3488
 @end table
3489 3489
 
3490
+For values between 4-7 transposition is only done if the input video
3491
+geometry is portrait and not landscape.
3492
+
3490 3493
 @section unsharp
3491 3494
 
3492 3495
 Sharpen or blur the input video.
... ...
@@ -30,7 +30,7 @@
30 30
 
31 31
 #define LIBAVFILTER_VERSION_MAJOR  3
32 32
 #define LIBAVFILTER_VERSION_MINOR  15
33
-#define LIBAVFILTER_VERSION_MICRO 102
33
+#define LIBAVFILTER_VERSION_MICRO 103
34 34
 
35 35
 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
36 36
                                                LIBAVFILTER_VERSION_MINOR, \
... ...
@@ -45,6 +45,7 @@ typedef struct {
45 45
     /* 2    Rotate by 90 degrees counterclockwise.           */
46 46
     /* 3    Rotate by 90 degrees clockwise and vflip.        */
47 47
     int dir;
48
+    int passthrough; ///< landscape passthrough mode enabled
48 49
 } TransContext;
49 50
 
50 51
 static av_cold int init(AVFilterContext *ctx, const char *args)
... ...
@@ -55,8 +56,8 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
55 55
     if (args)
56 56
         sscanf(args, "%d", &trans->dir);
57 57
 
58
-    if (trans->dir < 0 || trans->dir > 3) {
59
-        av_log(ctx, AV_LOG_ERROR, "Invalid value %d not between 0 and 3.\n",
58
+    if (trans->dir < 0 || trans->dir > 7) {
59
+        av_log(ctx, AV_LOG_ERROR, "Invalid value %d not between 0 and 7.\n",
60 60
                trans->dir);
61 61
         return AVERROR(EINVAL);
62 62
     }
... ...
@@ -97,6 +98,18 @@ static int config_props_output(AVFilterLink *outlink)
97 97
     AVFilterLink *inlink = ctx->inputs[0];
98 98
     const AVPixFmtDescriptor *pixdesc = &av_pix_fmt_descriptors[outlink->format];
99 99
 
100
+    if (trans->dir&4) {
101
+        trans->dir &= 3;
102
+        if (inlink->w >= inlink->h) {
103
+            trans->passthrough = 1;
104
+
105
+            av_log(ctx, AV_LOG_VERBOSE,
106
+                   "w:%d h:%d -> w:%d h:%d (landscape passthrough mode)\n",
107
+                   inlink->w, inlink->h, outlink->w, outlink->h);
108
+            return 0;
109
+        }
110
+    }
111
+
100 112
     trans->hsub = av_pix_fmt_descriptors[inlink->format].log2_chroma_w;
101 113
     trans->vsub = av_pix_fmt_descriptors[inlink->format].log2_chroma_h;
102 114
 
... ...
@@ -117,11 +130,24 @@ static int config_props_output(AVFilterLink *outlink)
117 117
     return 0;
118 118
 }
119 119
 
120
+static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms, int w, int h)
121
+{
122
+    TransContext *trans = inlink->dst->priv;
123
+
124
+    return trans->passthrough ?
125
+        ff_null_get_video_buffer   (inlink, perms, w, h) :
126
+        ff_default_get_video_buffer(inlink, perms, w, h);
127
+}
128
+
120 129
 static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
121 130
 {
131
+    TransContext *trans = inlink->dst->priv;
122 132
     AVFilterLink *outlink = inlink->dst->outputs[0];
123 133
     AVFilterBufferRef *buf_out;
124 134
 
135
+    if (trans->passthrough)
136
+        return ff_null_start_frame(inlink, picref);
137
+
125 138
     outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE,
126 139
                                            outlink->w, outlink->h);
127 140
     if (!outlink->out_buf)
... ...
@@ -150,6 +176,9 @@ static int end_frame(AVFilterLink *inlink)
150 150
     AVFilterLink *outlink = inlink->dst->outputs[0];
151 151
     int plane, ret;
152 152
 
153
+    if (trans->passthrough)
154
+        return ff_null_end_frame(inlink);
155
+
153 156
     for (plane = 0; outpic->data[plane]; plane++) {
154 157
         int hsub = plane == 1 || plane == 2 ? trans->hsub : 0;
155 158
         int vsub = plane == 1 || plane == 2 ? trans->vsub : 0;
... ...
@@ -205,7 +234,12 @@ static int end_frame(AVFilterLink *inlink)
205 205
     return 0;
206 206
 }
207 207
 
208
-static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { return 0; }
208
+static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
209
+{
210
+    TransContext *trans = inlink->dst->priv;
211
+
212
+    return trans->passthrough ? ff_null_draw_slice(inlink, y, h, slice_dir) : 0;
213
+}
209 214
 
210 215
 AVFilter avfilter_vf_transpose = {
211 216
     .name      = "transpose",
... ...
@@ -218,8 +252,9 @@ AVFilter avfilter_vf_transpose = {
218 218
 
219 219
     .inputs    = (const AVFilterPad[]) {{ .name            = "default",
220 220
                                           .type            = AVMEDIA_TYPE_VIDEO,
221
+                                          .get_video_buffer= get_video_buffer,
221 222
                                           .start_frame     = start_frame,
222
-                                          .draw_slice      = null_draw_slice,
223
+                                          .draw_slice      = draw_slice,
223 224
                                           .end_frame       = end_frame,
224 225
                                           .min_perms       = AV_PERM_READ, },
225 226
                                         { .name = NULL}},