~ubuntu-branches/ubuntu/utopic/libav/utopic

« back to all changes in this revision

Viewing changes to libavfilter/vf_pad.c

  • Committer: Package Import Robot
  • Author(s): Reinhard Tartler
  • Date: 2012-12-21 15:32:13 UTC
  • mto: (1.2.18)
  • mto: This revision was merged to the branch mainline in revision 34.
  • Revision ID: package-import@ubuntu.com-20121221153213-fudzrugjzivtv0wp
Tags: upstream-9~beta3
ImportĀ upstreamĀ versionĀ 9~beta3

Show diffs side-by-side

added added

removed removed

Lines of Context:
106
106
    uint8_t *line[4];
107
107
    int      line_step[4];
108
108
    int hsub, vsub;         ///< chroma subsampling values
109
 
    int needs_copy;
110
109
} PadContext;
111
110
 
112
111
static av_cold int init(AVFilterContext *ctx, const char *args)
303
302
    return 0;
304
303
}
305
304
 
306
 
static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
 
305
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
307
306
{
308
307
    PadContext *pad = inlink->dst->priv;
309
 
    AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0);
310
 
    AVFilterBufferRef *for_next_filter;
311
 
    int plane, ret = 0;
 
308
    AVFilterBufferRef *out = avfilter_ref_buffer(in, ~0);
 
309
    int plane, needs_copy;
312
310
 
313
 
    if (!outpicref)
 
311
    if (!out) {
 
312
        avfilter_unref_bufferp(&in);
314
313
        return AVERROR(ENOMEM);
 
314
    }
315
315
 
316
 
    for (plane = 0; plane < 4 && outpicref->data[plane]; plane++) {
 
316
    for (plane = 0; plane < 4 && out->data[plane]; plane++) {
317
317
        int hsub = (plane == 1 || plane == 2) ? pad->hsub : 0;
318
318
        int vsub = (plane == 1 || plane == 2) ? pad->vsub : 0;
319
319
 
320
 
        av_assert0(outpicref->buf->w>0 && outpicref->buf->h>0);
 
320
        av_assert0(out->buf->w > 0 && out->buf->h > 0);
321
321
 
322
 
        if(outpicref->format != outpicref->buf->format) //unsupported currently
 
322
        if (out->format != out->buf->format) //unsupported currently
323
323
            break;
324
324
 
325
 
        outpicref->data[plane] -=   (pad->x  >> hsub) * pad      ->line_step[plane]
326
 
                                  + (pad->y  >> vsub) * outpicref->linesize [plane];
 
325
        out->data[plane] -= (pad->x  >> hsub) * pad->line_step[plane] +
 
326
                            (pad->y  >> vsub) * out->linesize [plane];
327
327
 
328
 
        if(   does_clip(pad, outpicref, plane, hsub, vsub, 0, 0)
329
 
           || does_clip(pad, outpicref, plane, hsub, vsub, 0, pad->h-1)
330
 
           || does_clip(pad, outpicref, plane, hsub, vsub, pad->w-1, 0)
331
 
           || does_clip(pad, outpicref, plane, hsub, vsub, pad->w-1, pad->h-1)
332
 
          )
 
328
        if (does_clip(pad, out, plane, hsub, vsub, 0,                   0) ||
 
329
            does_clip(pad, out, plane, hsub, vsub, 0,          pad->h - 1) ||
 
330
            does_clip(pad, out, plane, hsub, vsub, pad->w - 1,          0) ||
 
331
            does_clip(pad, out, plane, hsub, vsub, pad->w - 1, pad->h - 1))
333
332
            break;
334
333
    }
335
 
    pad->needs_copy= plane < 4 && outpicref->data[plane];
336
 
    if(pad->needs_copy){
 
334
    needs_copy = plane < 4 && out->data[plane];
 
335
    if (needs_copy) {
337
336
        av_log(inlink->dst, AV_LOG_DEBUG, "Direct padding impossible allocating new frame\n");
338
 
        avfilter_unref_buffer(outpicref);
339
 
        outpicref = ff_get_video_buffer(inlink->dst->outputs[0], AV_PERM_WRITE | AV_PERM_NEG_LINESIZES,
340
 
                                        FFMAX(inlink->w, pad->w),
341
 
                                        FFMAX(inlink->h, pad->h));
342
 
        if (!outpicref)
 
337
        avfilter_unref_buffer(out);
 
338
        out = ff_get_video_buffer(inlink->dst->outputs[0], AV_PERM_WRITE | AV_PERM_NEG_LINESIZES,
 
339
                                  FFMAX(inlink->w, pad->w),
 
340
                                  FFMAX(inlink->h, pad->h));
 
341
        if (!out) {
 
342
            avfilter_unref_bufferp(&in);
343
343
            return AVERROR(ENOMEM);
344
 
 
345
 
        avfilter_copy_buffer_ref_props(outpicref, inpicref);
346
 
    }
347
 
 
348
 
    outpicref->video->w = pad->w;
349
 
    outpicref->video->h = pad->h;
350
 
 
351
 
    for_next_filter = avfilter_ref_buffer(outpicref, ~0);
352
 
    if (!for_next_filter) {
353
 
        ret = AVERROR(ENOMEM);
354
 
        goto fail;
355
 
    }
356
 
 
357
 
    ret = ff_start_frame(inlink->dst->outputs[0], for_next_filter);
358
 
    if (ret < 0)
359
 
        goto fail;
360
 
 
361
 
    inlink->dst->outputs[0]->out_buf = outpicref;
362
 
    return 0;
363
 
 
364
 
fail:
365
 
    avfilter_unref_bufferp(&outpicref);
366
 
    return ret;
367
 
}
368
 
 
369
 
static int end_frame(AVFilterLink *link)
370
 
{
371
 
    return ff_end_frame(link->dst->outputs[0]);
372
 
}
373
 
 
374
 
static int draw_send_bar_slice(AVFilterLink *link, int y, int h, int slice_dir, int before_slice)
375
 
{
376
 
    PadContext *pad = link->dst->priv;
377
 
    int bar_y, bar_h = 0, ret = 0;
378
 
 
379
 
    if        (slice_dir * before_slice ==  1 && y == pad->y) {
380
 
        /* top bar */
381
 
        bar_y = 0;
382
 
        bar_h = pad->y;
383
 
    } else if (slice_dir * before_slice == -1 && (y + h) == (pad->y + pad->in_h)) {
384
 
        /* bottom bar */
385
 
        bar_y = pad->y + pad->in_h;
386
 
        bar_h = pad->h - pad->in_h - pad->y;
387
 
    }
388
 
 
389
 
    if (bar_h) {
390
 
        ff_draw_rectangle(link->dst->outputs[0]->out_buf->data,
391
 
                          link->dst->outputs[0]->out_buf->linesize,
392
 
                          pad->line, pad->line_step, pad->hsub, pad->vsub,
393
 
                          0, bar_y, pad->w, bar_h);
394
 
        ret = ff_draw_slice(link->dst->outputs[0], bar_y, bar_h, slice_dir);
395
 
    }
396
 
    return ret;
397
 
}
398
 
 
399
 
static int draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
400
 
{
401
 
    PadContext *pad = link->dst->priv;
402
 
    AVFilterBufferRef *outpic = link->dst->outputs[0]->out_buf;
403
 
    AVFilterBufferRef *inpic = link->cur_buf;
404
 
    int ret;
405
 
 
406
 
    y += pad->y;
407
 
 
408
 
    y &= ~((1 << pad->vsub) - 1);
409
 
    h &= ~((1 << pad->vsub) - 1);
410
 
 
411
 
    if (!h)
412
 
        return 0;
413
 
    draw_send_bar_slice(link, y, h, slice_dir, 1);
 
344
        }
 
345
 
 
346
        avfilter_copy_buffer_ref_props(out, in);
 
347
    }
 
348
 
 
349
    out->video->w = pad->w;
 
350
    out->video->h = pad->h;
 
351
 
 
352
    /* top bar */
 
353
    if (pad->y) {
 
354
        ff_draw_rectangle(out->data, out->linesize,
 
355
                          pad->line, pad->line_step, pad->hsub, pad->vsub,
 
356
                          0, 0, pad->w, pad->y);
 
357
    }
 
358
 
 
359
    /* bottom bar */
 
360
    if (pad->h > pad->y + pad->in_h) {
 
361
        ff_draw_rectangle(out->data, out->linesize,
 
362
                          pad->line, pad->line_step, pad->hsub, pad->vsub,
 
363
                          0, pad->y + pad->in_h, pad->w, pad->h - pad->y - pad->in_h);
 
364
    }
414
365
 
415
366
    /* left border */
416
 
    ff_draw_rectangle(outpic->data, outpic->linesize, pad->line, pad->line_step,
417
 
                      pad->hsub, pad->vsub, 0, y, pad->x, h);
 
367
    ff_draw_rectangle(out->data, out->linesize, pad->line, pad->line_step,
 
368
                      pad->hsub, pad->vsub, 0, pad->y, pad->x, in->video->h);
418
369
 
419
 
    if(pad->needs_copy){
420
 
        ff_copy_rectangle(outpic->data, outpic->linesize,
421
 
                          inpic->data, inpic->linesize, pad->line_step,
422
 
                          pad->hsub, pad->vsub,
423
 
                          pad->x, y, y-pad->y, inpic->video->w, h);
 
370
    if (needs_copy) {
 
371
        ff_copy_rectangle(out->data, out->linesize, in->data, in->linesize,
 
372
                          pad->line_step, pad->hsub, pad->vsub,
 
373
                          pad->x, pad->y, 0, in->video->w, in->video->h);
424
374
    }
425
375
 
426
376
    /* right border */
427
 
    ff_draw_rectangle(outpic->data, outpic->linesize,
 
377
    ff_draw_rectangle(out->data, out->linesize,
428
378
                      pad->line, pad->line_step, pad->hsub, pad->vsub,
429
 
                      pad->x + pad->in_w, y, pad->w - pad->x - pad->in_w, h);
430
 
    ret = ff_draw_slice(link->dst->outputs[0], y, h, slice_dir);
431
 
    if (ret < 0)
432
 
        return ret;
 
379
                      pad->x + pad->in_w, pad->y, pad->w - pad->x - pad->in_w,
 
380
                      in->video->h);
433
381
 
434
 
    return draw_send_bar_slice(link, y, h, slice_dir, -1);
 
382
    avfilter_unref_bufferp(&in);
 
383
    return ff_filter_frame(inlink->dst->outputs[0], out);
435
384
}
436
385
 
437
386
static const AVFilterPad avfilter_vf_pad_inputs[] = {
440
389
        .type             = AVMEDIA_TYPE_VIDEO,
441
390
        .config_props     = config_input,
442
391
        .get_video_buffer = get_video_buffer,
443
 
        .start_frame      = start_frame,
444
 
        .draw_slice       = draw_slice,
445
 
        .end_frame        = end_frame,
 
392
        .filter_frame     = filter_frame,
446
393
    },
447
394
    { NULL }
448
395
};