306
static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
305
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
308
307
PadContext *pad = inlink->dst->priv;
309
AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0);
310
AVFilterBufferRef *for_next_filter;
308
AVFilterBufferRef *out = avfilter_ref_buffer(in, ~0);
309
int plane, needs_copy;
312
avfilter_unref_bufferp(&in);
314
313
return AVERROR(ENOMEM);
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;
320
av_assert0(outpicref->buf->w>0 && outpicref->buf->h>0);
320
av_assert0(out->buf->w > 0 && out->buf->h > 0);
322
if(outpicref->format != outpicref->buf->format) //unsupported currently
322
if (out->format != out->buf->format) //unsupported currently
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];
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)
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))
335
pad->needs_copy= plane < 4 && outpicref->data[plane];
334
needs_copy = plane < 4 && out->data[plane];
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));
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));
342
avfilter_unref_bufferp(&in);
343
343
return AVERROR(ENOMEM);
345
avfilter_copy_buffer_ref_props(outpicref, inpicref);
348
outpicref->video->w = pad->w;
349
outpicref->video->h = pad->h;
351
for_next_filter = avfilter_ref_buffer(outpicref, ~0);
352
if (!for_next_filter) {
353
ret = AVERROR(ENOMEM);
357
ret = ff_start_frame(inlink->dst->outputs[0], for_next_filter);
361
inlink->dst->outputs[0]->out_buf = outpicref;
365
avfilter_unref_bufferp(&outpicref);
369
static int end_frame(AVFilterLink *link)
371
return ff_end_frame(link->dst->outputs[0]);
374
static int draw_send_bar_slice(AVFilterLink *link, int y, int h, int slice_dir, int before_slice)
376
PadContext *pad = link->dst->priv;
377
int bar_y, bar_h = 0, ret = 0;
379
if (slice_dir * before_slice == 1 && y == pad->y) {
383
} else if (slice_dir * before_slice == -1 && (y + h) == (pad->y + pad->in_h)) {
385
bar_y = pad->y + pad->in_h;
386
bar_h = pad->h - pad->in_h - pad->y;
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);
399
static int draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
401
PadContext *pad = link->dst->priv;
402
AVFilterBufferRef *outpic = link->dst->outputs[0]->out_buf;
403
AVFilterBufferRef *inpic = link->cur_buf;
408
y &= ~((1 << pad->vsub) - 1);
409
h &= ~((1 << pad->vsub) - 1);
413
draw_send_bar_slice(link, y, h, slice_dir, 1);
346
avfilter_copy_buffer_ref_props(out, in);
349
out->video->w = pad->w;
350
out->video->h = pad->h;
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);
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);
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);
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);
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);
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);
379
pad->x + pad->in_w, pad->y, pad->w - pad->x - pad->in_w,
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);
437
386
static const AVFilterPad avfilter_vf_pad_inputs[] = {