Browse code

vf_pad: switch to filter_frame

Based on patch by Anton Khirnov
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Michael Niedermayer authored on 2012/11/29 04:48:42
Showing 1 changed files
... ...
@@ -88,7 +88,6 @@ typedef struct {
88 88
     uint8_t rgba_color[4];  ///< color for the padding area
89 89
     FFDrawContext draw;
90 90
     FFDrawColor color;
91
-    int needs_copy;
92 91
 } PadContext;
93 92
 
94 93
 static av_cold int init(AVFilterContext *ctx, const char *args)
... ...
@@ -263,129 +262,84 @@ static int does_clip(PadContext *pad, AVFilterBufferRef *outpicref, int plane, i
263 263
     return 0;
264 264
 }
265 265
 
266
-static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
266
+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
267 267
 {
268 268
     PadContext *pad = inlink->dst->priv;
269
-    AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0);
270
-    AVFilterBufferRef *for_next_filter;
271
-    int plane, ret = 0;
269
+    AVFilterBufferRef *out = avfilter_ref_buffer(in, ~0);
270
+    int plane, needs_copy;
272 271
 
273
-    if (!outpicref)
272
+    if (!out) {
273
+        avfilter_unref_bufferp(&in);
274 274
         return AVERROR(ENOMEM);
275
+    }
275 276
 
276
-    for (plane = 0; plane < 4 && outpicref->data[plane] && pad->draw.pixelstep[plane]; plane++) {
277
+    for (plane = 0; plane < 4 && out->data[plane] && pad->draw.pixelstep[plane]; plane++) {
277 278
         int hsub = pad->draw.hsub[plane];
278 279
         int vsub = pad->draw.vsub[plane];
279 280
 
280
-        av_assert0(outpicref->buf->w>0 && outpicref->buf->h>0);
281
+        av_assert0(out->buf->w > 0 && out->buf->h > 0);
281 282
 
282
-        if(outpicref->format != outpicref->buf->format) //unsupported currently
283
+        if (out->format != out->buf->format) //unsupported currently
283 284
             break;
284 285
 
285
-        outpicref->data[plane] -=   (pad->x  >> hsub) * pad->draw.pixelstep[plane]
286
-                                  + (pad->y  >> vsub) * outpicref->linesize[plane];
286
+        out->data[plane] -= (pad->x  >> hsub) * pad->draw.pixelstep[plane] +
287
+                            (pad->y  >> vsub) * out->linesize[plane];
287 288
 
288
-        if(   does_clip(pad, outpicref, plane, hsub, vsub, 0, 0)
289
-           || does_clip(pad, outpicref, plane, hsub, vsub, 0, pad->h-1)
290
-           || does_clip(pad, outpicref, plane, hsub, vsub, pad->w-1, 0)
291
-           || does_clip(pad, outpicref, plane, hsub, vsub, pad->w-1, pad->h-1)
292
-          )
289
+        if (does_clip(pad, out, plane, hsub, vsub, 0,                   0) ||
290
+            does_clip(pad, out, plane, hsub, vsub, 0,          pad->h - 1) ||
291
+            does_clip(pad, out, plane, hsub, vsub, pad->w - 1,          0) ||
292
+            does_clip(pad, out, plane, hsub, vsub, pad->w - 1, pad->h - 1))
293 293
             break;
294 294
     }
295
-    pad->needs_copy= plane < 4 && outpicref->data[plane] || !(outpicref->perms & AV_PERM_WRITE);
296
-    if(pad->needs_copy){
295
+    needs_copy = plane < 4 && out->data[plane] || !(out->perms & AV_PERM_WRITE);
296
+    if (needs_copy) {
297 297
         av_log(inlink->dst, AV_LOG_DEBUG, "Direct padding impossible allocating new frame\n");
298
-        avfilter_unref_buffer(outpicref);
299
-        outpicref = ff_get_video_buffer(inlink->dst->outputs[0], AV_PERM_WRITE | AV_PERM_NEG_LINESIZES,
300
-                                        FFMAX(inlink->w, pad->w),
301
-                                        FFMAX(inlink->h, pad->h));
302
-        if (!outpicref)
298
+        avfilter_unref_buffer(out);
299
+        out = ff_get_video_buffer(inlink->dst->outputs[0], AV_PERM_WRITE | AV_PERM_NEG_LINESIZES,
300
+                                  FFMAX(inlink->w, pad->w),
301
+                                  FFMAX(inlink->h, pad->h));
302
+        if (!out) {
303
+            avfilter_unref_bufferp(&in);
303 304
             return AVERROR(ENOMEM);
305
+        }
304 306
 
305
-        avfilter_copy_buffer_ref_props(outpicref, inpicref);
307
+        avfilter_copy_buffer_ref_props(out, in);
306 308
     }
307 309
 
308
-    outpicref->video->w = pad->w;
309
-    outpicref->video->h = pad->h;
310
-
311
-    for_next_filter = avfilter_ref_buffer(outpicref, ~0);
312
-    if (!for_next_filter) {
313
-        ret = AVERROR(ENOMEM);
314
-        goto fail;
315
-    }
316
-
317
-    ret = ff_start_frame(inlink->dst->outputs[0], for_next_filter);
318
-    if (ret < 0)
319
-        goto fail;
320
-
321
-    inlink->dst->outputs[0]->out_buf = outpicref;
322
-    return 0;
310
+    out->video->w = pad->w;
311
+    out->video->h = pad->h;
323 312
 
324
-fail:
325
-    avfilter_unref_bufferp(&outpicref);
326
-    return ret;
327
-}
328
-
329
-static int draw_send_bar_slice(AVFilterLink *link, int y, int h, int slice_dir, int before_slice)
330
-{
331
-    PadContext *pad = link->dst->priv;
332
-    int bar_y, bar_h = 0, ret = 0;
333
-
334
-    if        (slice_dir * before_slice ==  1 && y == pad->y) {
335
-        /* top bar */
336
-        bar_y = 0;
337
-        bar_h = pad->y;
338
-    } else if (slice_dir * before_slice == -1 && (y + h) == (pad->y + pad->in_h)) {
339
-        /* bottom bar */
340
-        bar_y = pad->y + pad->in_h;
341
-        bar_h = pad->h - pad->in_h - pad->y;
313
+    /* top bar */
314
+    if (pad->y) {
315
+        ff_fill_rectangle(&pad->draw, &pad->color,
316
+                          out->data, out->linesize,
317
+                          0, 0, pad->w, pad->y);
342 318
     }
343 319
 
344
-    if (bar_h) {
320
+    /* bottom bar */
321
+    if (pad->h > pad->y + pad->in_h) {
345 322
         ff_fill_rectangle(&pad->draw, &pad->color,
346
-                          link->dst->outputs[0]->out_buf->data,
347
-                          link->dst->outputs[0]->out_buf->linesize,
348
-                          0, bar_y, pad->w, bar_h);
349
-        ret = ff_draw_slice(link->dst->outputs[0], bar_y, bar_h, slice_dir);
323
+                          out->data, out->linesize,
324
+                          0, pad->y + pad->in_h, pad->w, pad->h - pad->y - pad->in_h);
350 325
     }
351
-    return ret;
352
-}
353
-
354
-static int draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
355
-{
356
-    PadContext *pad = link->dst->priv;
357
-    AVFilterBufferRef *outpic = link->dst->outputs[0]->out_buf;
358
-    AVFilterBufferRef *inpic = link->cur_buf;
359
-    int ret;
360
-
361
-    y += pad->y;
362
-
363
-    y = ff_draw_round_to_sub(&pad->draw, 1, -1, y);
364
-    h = ff_draw_round_to_sub(&pad->draw, 1, -1, h);
365
-
366
-    if (!h)
367
-        return 0;
368
-    draw_send_bar_slice(link, y, h, slice_dir, 1);
369 326
 
370 327
     /* left border */
371
-    ff_fill_rectangle(&pad->draw, &pad->color, outpic->data, outpic->linesize,
372
-                      0, y, pad->x, h);
328
+    ff_fill_rectangle(&pad->draw, &pad->color, out->data, out->linesize,
329
+                      0, pad->y, pad->x, in->video->h);
373 330
 
374
-    if(pad->needs_copy){
331
+    if (needs_copy) {
375 332
         ff_copy_rectangle2(&pad->draw,
376
-                           outpic->data, outpic->linesize,
377
-                           inpic ->data, inpic ->linesize,
378
-                           pad->x, y, 0, y - pad->y, inpic->video->w, h);
333
+                          out->data, out->linesize, in->data, in->linesize,
334
+                          pad->x, pad->y, 0, 0, in->video->w, in->video->h);
379 335
     }
380 336
 
381 337
     /* right border */
382
-    ff_fill_rectangle(&pad->draw, &pad->color, outpic->data, outpic->linesize,
383
-                      pad->x + pad->in_w, y, pad->w - pad->x - pad->in_w, h);
384
-    ret = ff_draw_slice(link->dst->outputs[0], y, h, slice_dir);
385
-    if (ret < 0)
386
-        return ret;
338
+    ff_fill_rectangle(&pad->draw, &pad->color, out->data, out->linesize,
339
+                      pad->x + pad->in_w, pad->y, pad->w - pad->x - pad->in_w,
340
+                      in->video->h);
387 341
 
388
-    return draw_send_bar_slice(link, y, h, slice_dir, -1);
342
+    avfilter_unref_bufferp(&in);
343
+    return ff_filter_frame(inlink->dst->outputs[0], out);
389 344
 }
390 345
 
391 346
 static const AVFilterPad avfilter_vf_pad_inputs[] = {
... ...
@@ -394,8 +348,7 @@ static const AVFilterPad avfilter_vf_pad_inputs[] = {
394 394
         .type             = AVMEDIA_TYPE_VIDEO,
395 395
         .config_props     = config_input,
396 396
         .get_video_buffer = get_video_buffer,
397
-        .start_frame      = start_frame,
398
-        .draw_slice       = draw_slice,
397
+        .filter_frame     = filter_frame,
399 398
     },
400 399
     { NULL }
401 400
 };