int needs_copy;
} PadContext;
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
PadContext *pad = ctx->priv;
char color_string[128] = "black";
pad->in_w = ff_draw_round_to_sub(&pad->draw, 0, -1, inlink->w);
pad->in_h = ff_draw_round_to_sub(&pad->draw, 1, -1, inlink->h);
- av_log(ctx, AV_LOG_INFO, "w:%d h:%d -> w:%d h:%d x:%d y:%d color:0x%02X%02X%02X%02X\n",
+ av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d -> w:%d h:%d x:%d y:%d color:0x%02X%02X%02X%02X\n",
inlink->w, inlink->h, pad->w, pad->h, pad->x, pad->y,
pad->rgba_color[0], pad->rgba_color[1], pad->rgba_color[2], pad->rgba_color[3]);
h + (pad->h - pad->in_h));
int plane;
+ if (!picref)
+ return NULL;
+
picref->video->w = w;
picref->video->h = h;
return 0;
}
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
{
PadContext *pad = inlink->dst->priv;
AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0);
- int plane;
+ AVFilterBufferRef *for_next_filter;
+ int plane, ret = 0;
+
+ if (!outpicref)
+ return AVERROR(ENOMEM);
for (plane = 0; plane < 4 && outpicref->data[plane] && pad->draw.pixelstep[plane]; plane++) {
int hsub = pad->draw.hsub[plane];
)
break;
}
- pad->needs_copy= plane < 4 && outpicref->data[plane];
+ pad->needs_copy= plane < 4 && outpicref->data[plane] || !(outpicref->perms & AV_PERM_WRITE);
if(pad->needs_copy){
av_log(inlink->dst, AV_LOG_DEBUG, "Direct padding impossible allocating new frame\n");
avfilter_unref_buffer(outpicref);
outpicref = ff_get_video_buffer(inlink->dst->outputs[0], AV_PERM_WRITE | AV_PERM_NEG_LINESIZES,
FFMAX(inlink->w, pad->w),
FFMAX(inlink->h, pad->h));
+ if (!outpicref)
+ return AVERROR(ENOMEM);
+
avfilter_copy_buffer_ref_props(outpicref, inpicref);
}
- inlink->dst->outputs[0]->out_buf = outpicref;
-
outpicref->video->w = pad->w;
outpicref->video->h = pad->h;
- ff_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(outpicref, ~0));
+ for_next_filter = avfilter_ref_buffer(outpicref, ~0);
+ if (!for_next_filter) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ ret = ff_start_frame(inlink->dst->outputs[0], for_next_filter);
+ if (ret < 0)
+ goto fail;
+
+ inlink->dst->outputs[0]->out_buf = outpicref;
+ return 0;
+
+fail:
+ avfilter_unref_bufferp(&outpicref);
+ return ret;
}
-static void draw_send_bar_slice(AVFilterLink *link, int y, int h, int slice_dir, int before_slice)
+static int draw_send_bar_slice(AVFilterLink *link, int y, int h, int slice_dir, int before_slice)
{
PadContext *pad = link->dst->priv;
- int bar_y, bar_h = 0;
+ int bar_y, bar_h = 0, ret = 0;
if (slice_dir * before_slice == 1 && y == pad->y) {
/* top bar */
link->dst->outputs[0]->out_buf->data,
link->dst->outputs[0]->out_buf->linesize,
0, bar_y, pad->w, bar_h);
- ff_draw_slice(link->dst->outputs[0], bar_y, bar_h, slice_dir);
+ ret = ff_draw_slice(link->dst->outputs[0], bar_y, bar_h, slice_dir);
}
+ return ret;
}
-static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
+static int draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
{
PadContext *pad = link->dst->priv;
AVFilterBufferRef *outpic = link->dst->outputs[0]->out_buf;
AVFilterBufferRef *inpic = link->cur_buf;
+ int ret;
y += pad->y;
h = ff_draw_round_to_sub(&pad->draw, 1, -1, h);
if (!h)
- return;
+ return 0;
draw_send_bar_slice(link, y, h, slice_dir, 1);
/* left border */
/* right border */
ff_fill_rectangle(&pad->draw, &pad->color, outpic->data, outpic->linesize,
pad->x + pad->in_w, y, pad->w - pad->x - pad->in_w, h);
- ff_draw_slice(link->dst->outputs[0], y, h, slice_dir);
+ ret = ff_draw_slice(link->dst->outputs[0], y, h, slice_dir);
+ if (ret < 0)
+ return ret;
- draw_send_bar_slice(link, y, h, slice_dir, -1);
+ return draw_send_bar_slice(link, y, h, slice_dir, -1);
}
AVFilter avfilter_vf_pad = {
.init = init,
.query_formats = query_formats,
- .inputs = (const AVFilterPad[]) {{ .name = "default",
- .type = AVMEDIA_TYPE_VIDEO,
- .config_props = config_input,
- .get_video_buffer = get_video_buffer,
- .start_frame = start_frame,
- .draw_slice = draw_slice, },
- { .name = NULL}},
-
- .outputs = (const AVFilterPad[]) {{ .name = "default",
- .type = AVMEDIA_TYPE_VIDEO,
- .config_props = config_output, },
- { .name = NULL}},
+ .inputs = (const AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .config_props = config_input,
+ .get_video_buffer = get_video_buffer,
+ .start_frame = start_frame,
+ .draw_slice = draw_slice, },
+ { .name = NULL}},
+
+ .outputs = (const AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .config_props = config_output, },
+ { .name = NULL}},
};