Merge remote-tracking branch 'qatar/master'

* qatar/master:
  FATE: fix the asyncts test
  build: Drop gcc-specific warning flag from header compilation rule
  FATE: add a test for the asyncts audio filter.
  matroskadec: return more correct error code on read error.
  buffersrc: check ff_get_audio_buffer() for errors.
  lavfi: check all ff_get_video_buffer() calls for errors.
  lavfi: check all avfilter_ref_buffer() calls for errors.
  vf_select: avoid an unnecessary avfilter_ref_buffer().
  buffersrc: avoid creating unnecessary buffer reference
  lavfi: use avfilter_unref_bufferp() where appropriate.
  vf_fps: add more error checks.
  vf_fps: fix a memleak on malloc failure.
  lavfi: check all ff_start_frame/draw_slice/end_frame calls for errors
  lavfi: add error handling to end_frame().
  lavfi: add error handling to draw_slice().
  lavfi: add error handling to start_frame().

Conflicts:
	Makefile
	ffplay.c
	libavfilter/buffersrc.c
	libavfilter/vf_boxblur.c
	libavfilter/vf_drawtext.c
	libavfilter/vf_fade.c
	libavfilter/vf_frei0r.c
	libavfilter/vf_hflip.c
	libavfilter/vf_overlay.c
	libavfilter/vf_pad.c
	libavfilter/vf_scale.c
	libavfilter/video.c
	libavfilter/vsrc_color.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Michael Niedermayer 2012-07-22 22:57:02 +02:00
commit 88beb2df98
64 changed files with 764 additions and 376 deletions

View File

@ -54,7 +54,7 @@ COMPILE_S = $(call COMPILE,AS)
$(COMPILE_S) $(COMPILE_S)
%.ho: %.h %.ho: %.h
$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused -c -o $@ -x c $< $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ -x c $<
%.ver: %.v %.ver: %.v
$(Q)sed 's/$$MAJOR/$($(basename $(@F))_VERSION_MAJOR)/' $^ > $@ $(Q)sed 's/$$MAJOR/$($(basename $(@F))_VERSION_MAJOR)/' $^ > $@

View File

@ -248,7 +248,7 @@ static void join_uninit(AVFilterContext *ctx)
for (i = 0; i < ctx->nb_inputs; i++) { for (i = 0; i < ctx->nb_inputs; i++) {
av_freep(&ctx->input_pads[i].name); av_freep(&ctx->input_pads[i].name);
avfilter_unref_buffer(s->input_frames[i]); avfilter_unref_bufferp(&s->input_frames[i]);
} }
av_freep(&s->channels); av_freep(&s->channels);
@ -402,7 +402,7 @@ static void join_free_buffer(AVFilterBuffer *buf)
int i; int i;
for (i = 0; i < priv->nb_in_buffers; i++) for (i = 0; i < priv->nb_in_buffers; i++)
avfilter_unref_buffer(priv->in_buffers[i]); avfilter_unref_bufferp(&priv->in_buffers[i]);
av_freep(&priv->in_buffers); av_freep(&priv->in_buffers);
av_freep(&buf->priv); av_freep(&buf->priv);

View File

@ -261,8 +261,11 @@ struct AVFilterPad {
* picture inside the link structure. * picture inside the link structure.
* *
* Input video pads only. * Input video pads only.
*
* @return >= 0 on success, a negative AVERROR on error. picref will be
* unreferenced by the caller in case of error.
*/ */
void (*start_frame)(AVFilterLink *link, AVFilterBufferRef *picref); int (*start_frame)(AVFilterLink *link, AVFilterBufferRef *picref);
/** /**
* Callback function to get a video buffer. If NULL, the filter system will * Callback function to get a video buffer. If NULL, the filter system will
@ -287,16 +290,20 @@ struct AVFilterPad {
* in the link structure during start_frame(). * in the link structure during start_frame().
* *
* Input video pads only. * Input video pads only.
*
* @return >= 0 on success, a negative AVERROR on error.
*/ */
void (*end_frame)(AVFilterLink *link); int (*end_frame)(AVFilterLink *link);
/** /**
* Slice drawing callback. This is where a filter receives video data * Slice drawing callback. This is where a filter receives video data
* and should do its processing. * and should do its processing.
* *
* Input video pads only. * Input video pads only.
*
* @return >= 0 on success, a negative AVERROR on error.
*/ */
void (*draw_slice)(AVFilterLink *link, int y, int height, int slice_dir); int (*draw_slice)(AVFilterLink *link, int y, int height, int slice_dir);
/** /**
* Samples filtering callback. This is where a filter receives audio data * Samples filtering callback. This is where a filter receives audio data
@ -385,7 +392,7 @@ enum AVMediaType avfilter_pad_get_type(AVFilterPad *pads, int pad_idx);
/** default handler for end_frame() for video inputs */ /** default handler for end_frame() for video inputs */
attribute_deprecated attribute_deprecated
void avfilter_default_end_frame(AVFilterLink *link); int avfilter_default_end_frame(AVFilterLink *link);
/** /**
* Filter definition. This defines the pads a filter contains, and all the * Filter definition. This defines the pads a filter contains, and all the

View File

@ -47,20 +47,16 @@ static av_cold void uninit(AVFilterContext *ctx)
av_audio_fifo_free(sink->audio_fifo); av_audio_fifo_free(sink->audio_fifo);
} }
static void start_frame(AVFilterLink *link, AVFilterBufferRef *buf) static int start_frame(AVFilterLink *link, AVFilterBufferRef *buf)
{ {
BufferSinkContext *s = link->dst->priv; BufferSinkContext *s = link->dst->priv;
// av_assert0(!s->cur_buf); // av_assert0(!s->cur_buf);
s->cur_buf = buf; s->cur_buf = buf;
link->cur_buf = NULL; link->cur_buf = NULL;
};
static int filter_samples(AVFilterLink *link, AVFilterBufferRef *buf)
{
start_frame(link, buf);
return 0; return 0;
} };
int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf) int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf)
{ {
@ -166,7 +162,7 @@ AVFilter avfilter_asink_abuffer = {
.inputs = (const AVFilterPad[]) {{ .name = "default", .inputs = (const AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_AUDIO, .type = AVMEDIA_TYPE_AUDIO,
.filter_samples = filter_samples, .filter_samples = start_frame,
.min_perms = AV_PERM_READ, .min_perms = AV_PERM_READ,
.needs_fifo = 1 }, .needs_fifo = 1 },
{ .name = NULL }}, { .name = NULL }},

View File

@ -382,19 +382,19 @@ static int request_frame(AVFilterLink *link)
switch (link->type) { switch (link->type) {
case AVMEDIA_TYPE_VIDEO: case AVMEDIA_TYPE_VIDEO:
ff_start_frame(link, avfilter_ref_buffer(buf, ~0)); if ((ret = ff_start_frame(link, buf)) < 0 ||
ff_draw_slice(link, 0, link->h, 1); (ret = ff_draw_slice(link, 0, link->h, 1)) < 0 ||
ff_end_frame(link); (ret = ff_end_frame(link)) < 0)
return ret;
break; break;
case AVMEDIA_TYPE_AUDIO: case AVMEDIA_TYPE_AUDIO:
ret = ff_filter_samples(link, avfilter_ref_buffer(buf, ~0)); ret = ff_filter_samples(link, buf);
break; break;
default: default:
avfilter_unref_bufferp(&buf);
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
avfilter_unref_buffer(buf);
return ret; return ret;
} }

View File

@ -99,7 +99,7 @@ static int config_output_props(AVFilterLink *outlink)
return 0; return 0;
} }
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
AVFilterLink *outlink = ctx->outputs[0]; AVFilterLink *outlink = ctx->outputs[0];
@ -113,7 +113,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
} }
inlink->cur_buf = NULL; inlink->cur_buf = NULL;
ff_start_frame(outlink, picref); return ff_start_frame(outlink, picref);
} }
static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples) static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)

View File

@ -65,17 +65,18 @@ static av_cold void uninit(AVFilterContext *ctx)
for (buf = fifo->root.next; buf; buf = tmp) { for (buf = fifo->root.next; buf; buf = tmp) {
tmp = buf->next; tmp = buf->next;
avfilter_unref_buffer(buf->buf); avfilter_unref_bufferp(&buf->buf);
av_free(buf); av_free(buf);
} }
avfilter_unref_buffer(fifo->buf_out); avfilter_unref_bufferp(&fifo->buf_out);
} }
static int add_to_queue(AVFilterLink *inlink, AVFilterBufferRef *buf) static int add_to_queue(AVFilterLink *inlink, AVFilterBufferRef *buf)
{ {
FifoContext *fifo = inlink->dst->priv; FifoContext *fifo = inlink->dst->priv;
inlink->cur_buf = NULL;
fifo->last->next = av_mallocz(sizeof(Buf)); fifo->last->next = av_mallocz(sizeof(Buf));
if (!fifo->last->next) { if (!fifo->last->next) {
avfilter_unref_buffer(buf); avfilter_unref_buffer(buf);
@ -88,12 +89,6 @@ static int add_to_queue(AVFilterLink *inlink, AVFilterBufferRef *buf)
return 0; return 0;
} }
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
{
add_to_queue(inlink, buf);
inlink->cur_buf = NULL;
}
static void queue_pop(FifoContext *s) static void queue_pop(FifoContext *s)
{ {
Buf *tmp = s->root.next->next; Buf *tmp = s->root.next->next;
@ -103,9 +98,15 @@ static void queue_pop(FifoContext *s)
s->root.next = tmp; s->root.next = tmp;
} }
static void end_frame(AVFilterLink *inlink) { } static int end_frame(AVFilterLink *inlink)
{
return 0;
}
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { } static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
{
return 0;
}
/** /**
* Move data pointers and pts offset samples forward. * Move data pointers and pts offset samples forward.
@ -168,6 +169,9 @@ static int return_audio_frame(AVFilterContext *ctx)
queue_pop(s); queue_pop(s);
} else { } else {
buf_out = avfilter_ref_buffer(head, AV_PERM_READ); buf_out = avfilter_ref_buffer(head, AV_PERM_READ);
if (!buf_out)
return AVERROR(ENOMEM);
buf_out->audio->nb_samples = link->request_samples; buf_out->audio->nb_samples = link->request_samples;
buffer_offset(link, head, link->request_samples); buffer_offset(link, head, link->request_samples);
} }
@ -240,9 +244,11 @@ static int request_frame(AVFilterLink *outlink)
* so we don't have to worry about dereferencing it ourselves. */ * so we don't have to worry about dereferencing it ourselves. */
switch (outlink->type) { switch (outlink->type) {
case AVMEDIA_TYPE_VIDEO: case AVMEDIA_TYPE_VIDEO:
ff_start_frame(outlink, fifo->root.next->buf); if ((ret = ff_start_frame(outlink, fifo->root.next->buf)) < 0 ||
ff_draw_slice (outlink, 0, outlink->h, 1); (ret = ff_draw_slice(outlink, 0, outlink->h, 1)) < 0 ||
ff_end_frame (outlink); (ret = ff_end_frame(outlink)) < 0)
return ret;
queue_pop(fifo); queue_pop(fifo);
break; break;
case AVMEDIA_TYPE_AUDIO: case AVMEDIA_TYPE_AUDIO:
@ -272,7 +278,7 @@ AVFilter avfilter_vf_fifo = {
.inputs = (const AVFilterPad[]) {{ .name = "default", .inputs = (const AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO, .type = AVMEDIA_TYPE_VIDEO,
.get_video_buffer= ff_null_get_video_buffer, .get_video_buffer= ff_null_get_video_buffer,
.start_frame = start_frame, .start_frame = add_to_queue,
.draw_slice = draw_slice, .draw_slice = draw_slice,
.end_frame = end_frame, .end_frame = end_frame,
.rej_perms = AV_PERM_REUSE2, }, .rej_perms = AV_PERM_REUSE2, },

View File

@ -93,6 +93,9 @@ struct AVFilterPad {
* picture inside the link structure. * picture inside the link structure.
* *
* Input video pads only. * Input video pads only.
*
* @return >= 0 on success, a negative AVERROR on error. picref will be
* unreferenced by the caller in case of error.
*/ */
void (*start_frame)(AVFilterLink *link, AVFilterBufferRef *picref); void (*start_frame)(AVFilterLink *link, AVFilterBufferRef *picref);
@ -119,16 +122,20 @@ struct AVFilterPad {
* in the link structure during start_frame(). * in the link structure during start_frame().
* *
* Input video pads only. * Input video pads only.
*
* @return >= 0 on success, a negative AVERROR on error.
*/ */
void (*end_frame)(AVFilterLink *link); int (*end_frame)(AVFilterLink *link);
/** /**
* Slice drawing callback. This is where a filter receives video data * Slice drawing callback. This is where a filter receives video data
* and should do its processing. * and should do its processing.
* *
* Input video pads only. * Input video pads only.
*
* @return >= 0 on success, a negative AVERROR on error.
*/ */
void (*draw_slice)(AVFilterLink *link, int y, int height, int slice_dir); int (*draw_slice)(AVFilterLink *link, int y, int height, int slice_dir);
/** /**
* Samples filtering callback. This is where a filter receives audio data * Samples filtering callback. This is where a filter receives audio data

View File

@ -96,7 +96,7 @@ static av_cold void common_uninit(AVFilterContext *ctx)
} }
} }
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
BufferSinkContext *buf = inlink->dst->priv; BufferSinkContext *buf = inlink->dst->priv;
@ -108,7 +108,7 @@ static void end_frame(AVFilterLink *inlink)
av_log(ctx, AV_LOG_ERROR, av_log(ctx, AV_LOG_ERROR,
"Cannot buffer more frames. Consume some available frames " "Cannot buffer more frames. Consume some available frames "
"before adding new ones.\n"); "before adding new ones.\n");
return; return AVERROR(ENOMEM);
} }
} }
@ -124,6 +124,7 @@ static void end_frame(AVFilterLink *inlink)
(char *)av_x_if_null(ctx->name, ctx->filter->name)); (char *)av_x_if_null(ctx->name, ctx->filter->name));
buf->warning_limit *= 10; buf->warning_limit *= 10;
} }
return 0;
} }
void av_buffersink_set_frame_size(AVFilterContext *ctx, unsigned frame_size) void av_buffersink_set_frame_size(AVFilterContext *ctx, unsigned frame_size)

View File

@ -63,32 +63,47 @@ static void split_uninit(AVFilterContext *ctx)
av_freep(&ctx->output_pads[i].name); av_freep(&ctx->output_pads[i].name);
} }
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
int i; int i, ret = 0;
for (i = 0; i < ctx->nb_outputs; i++) for (i = 0; i < ctx->nb_outputs; i++) {
ff_start_frame(ctx->outputs[i], AVFilterBufferRef *buf_out = avfilter_ref_buffer(picref, ~AV_PERM_WRITE);
avfilter_ref_buffer(picref, ~AV_PERM_WRITE)); if (!buf_out)
return AVERROR(ENOMEM);
ret = ff_start_frame(ctx->outputs[i], buf_out);
if (ret < 0)
break;
}
return ret;
} }
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
int i; int i, ret = 0;
for (i = 0; i < ctx->nb_outputs; i++) for (i = 0; i < ctx->nb_outputs; i++) {
ff_draw_slice(ctx->outputs[i], y, h, slice_dir); ret = ff_draw_slice(ctx->outputs[i], y, h, slice_dir);
if (ret < 0)
break;
}
return ret;
} }
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
int i; int i, ret = 0;
for (i = 0; i < ctx->nb_outputs; i++) for (i = 0; i < ctx->nb_outputs; i++) {
ff_end_frame(ctx->outputs[i]); ret = ff_end_frame(ctx->outputs[i]);
if (ret < 0)
break;
}
return ret;
} }
AVFilter avfilter_vf_split = { AVFilter avfilter_vf_split = {
@ -114,8 +129,14 @@ static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref)
int i, ret = 0; int i, ret = 0;
for (i = 0; i < ctx->nb_outputs; i++) { for (i = 0; i < ctx->nb_outputs; i++) {
ret = ff_filter_samples(inlink->dst->outputs[i], AVFilterBufferRef *buf_out = avfilter_ref_buffer(samplesref,
avfilter_ref_buffer(samplesref, ~AV_PERM_WRITE)); ~AV_PERM_WRITE);
if (!buf_out) {
ret = AVERROR(ENOMEM);
break;
}
ret = ff_filter_samples(inlink->dst->outputs[i], buf_out);
if (ret < 0) if (ret < 0)
break; break;
} }

View File

@ -326,13 +326,24 @@ static int movie_request_frame(AVFilterLink *outlink)
return ret; return ret;
outpicref = avfilter_ref_buffer(movie->picref, ~0); outpicref = avfilter_ref_buffer(movie->picref, ~0);
ff_start_frame(outlink, outpicref); if (!outpicref) {
ff_draw_slice(outlink, 0, outlink->h, 1); ret = AVERROR(ENOMEM);
ff_end_frame(outlink); goto fail;
avfilter_unref_buffer(movie->picref); }
movie->picref = NULL;
return 0; ret = ff_start_frame(outlink, outpicref);
if (ret < 0)
goto fail;
ret = ff_draw_slice(outlink, 0, outlink->h, 1);
if (ret < 0)
goto fail;
ret = ff_end_frame(outlink);
fail:
avfilter_unref_bufferp(&movie->picref);
return ret;
} }
AVFilter avfilter_vsrc_movie = { AVFilter avfilter_vsrc_movie = {

View File

@ -59,7 +59,7 @@ static int config_input(AVFilterLink *inlink)
return 0; return 0;
} }
static void draw_slice(AVFilterLink *inlink, int y0, int h, int slice_dir) static int draw_slice(AVFilterLink *inlink, int y0, int h, int slice_dir)
{ {
AlphaExtractContext *extract = inlink->dst->priv; AlphaExtractContext *extract = inlink->dst->priv;
AVFilterBufferRef *cur_buf = inlink->cur_buf; AVFilterBufferRef *cur_buf = inlink->cur_buf;
@ -91,7 +91,7 @@ static void draw_slice(AVFilterLink *inlink, int y0, int h, int slice_dir)
linesize); linesize);
} }
} }
ff_draw_slice(inlink->dst->outputs[0], y0, h, slice_dir); return ff_draw_slice(inlink->dst->outputs[0], y0, h, slice_dir);
} }
AVFilter avfilter_vf_alphaextract = { AVFilter avfilter_vf_alphaextract = {

View File

@ -95,8 +95,8 @@ static int config_output(AVFilterLink *outlink)
return 0; return 0;
} }
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) {} static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) {return 0;}
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) {} static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) {return 0;}
static void draw_frame(AVFilterContext *ctx, static void draw_frame(AVFilterContext *ctx,
AVFilterBufferRef *main_buf, AVFilterBufferRef *main_buf,
@ -130,7 +130,7 @@ static void draw_frame(AVFilterContext *ctx,
ff_draw_slice(ctx->outputs[0], 0, h, 1); ff_draw_slice(ctx->outputs[0], 0, h, 1);
} }
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
AlphaMergeContext *merge = ctx->priv; AlphaMergeContext *merge = ctx->priv;
@ -157,6 +157,7 @@ static void end_frame(AVFilterLink *inlink)
ff_end_frame(ctx->outputs[0]); ff_end_frame(ctx->outputs[0]);
avfilter_unref_buffer(alpha_buf); avfilter_unref_buffer(alpha_buf);
} }
return 0;
} }
static int request_frame(AVFilterLink *outlink) static int request_frame(AVFilterLink *outlink)

View File

@ -51,13 +51,13 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
return 0; return 0;
} }
static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
{ {
AspectContext *aspect = link->dst->priv; AspectContext *aspect = link->dst->priv;
picref->video->sample_aspect_ratio = aspect->ratio; picref->video->sample_aspect_ratio = aspect->ratio;
link->cur_buf = NULL; link->cur_buf = NULL;
ff_start_frame(link->dst->outputs[0], picref); return ff_start_frame(link->dst->outputs[0], picref);
} }
#if CONFIG_SETDAR_FILTER #if CONFIG_SETDAR_FILTER

View File

@ -157,7 +157,7 @@ static int config_input(AVFilterLink *inlink)
return 0; return 0;
} }
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { return 0; }
/* libass stores an RGBA color in the format RRGGBBTT, where TT is the transparency level */ /* libass stores an RGBA color in the format RRGGBBTT, where TT is the transparency level */
#define AR(c) ( (c)>>24) #define AR(c) ( (c)>>24)
@ -180,7 +180,7 @@ static void overlay_ass_image(AssContext *ass, AVFilterBufferRef *picref,
} }
} }
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
AVFilterLink *outlink = ctx->outputs[0]; AVFilterLink *outlink = ctx->outputs[0];
@ -197,7 +197,7 @@ static void end_frame(AVFilterLink *inlink)
overlay_ass_image(ass, picref, image); overlay_ass_image(ass, picref, image);
ff_draw_slice(outlink, 0, picref->video->h, 1); ff_draw_slice(outlink, 0, picref->video->h, 1);
ff_end_frame(outlink); return ff_end_frame(outlink);
} }
AVFilter avfilter_vf_ass = { AVFilter avfilter_vf_ass = {

View File

@ -56,7 +56,7 @@ static int query_formats(AVFilterContext *ctx)
return 0; return 0;
} }
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
BBoxContext *bbox = ctx->priv; BBoxContext *bbox = ctx->priv;
@ -86,7 +86,7 @@ static void end_frame(AVFilterLink *inlink)
av_log(ctx, AV_LOG_INFO, "\n"); av_log(ctx, AV_LOG_INFO, "\n");
bbox->frame++; bbox->frame++;
ff_end_frame(inlink->dst->outputs[0]); return ff_end_frame(inlink->dst->outputs[0]);
} }
AVFilter avfilter_vf_bbox = { AVFilter avfilter_vf_bbox = {

View File

@ -146,7 +146,7 @@ static int request_frame(AVFilterLink *outlink)
return ret; return ret;
} }
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
BlackDetectContext *blackdetect = ctx->priv; BlackDetectContext *blackdetect = ctx->priv;
@ -160,10 +160,10 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
p += picref->linesize[0]; p += picref->linesize[0];
} }
ff_draw_slice(ctx->outputs[0], y, h, slice_dir); return ff_draw_slice(ctx->outputs[0], y, h, slice_dir);
} }
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
BlackDetectContext *blackdetect = ctx->priv; BlackDetectContext *blackdetect = ctx->priv;
@ -194,7 +194,7 @@ static void end_frame(AVFilterLink *inlink)
blackdetect->last_picref_pts = picref->pts; blackdetect->last_picref_pts = picref->pts;
blackdetect->frame_count++; blackdetect->frame_count++;
blackdetect->nb_black_pixels = 0; blackdetect->nb_black_pixels = 0;
ff_end_frame(inlink->dst->outputs[0]); return ff_end_frame(inlink->dst->outputs[0]);
} }
AVFilter avfilter_vf_blackdetect = { AVFilter avfilter_vf_blackdetect = {

View File

@ -77,7 +77,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
return 0; return 0;
} }
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
BlackFrameContext *blackframe = ctx->priv; BlackFrameContext *blackframe = ctx->priv;
@ -91,10 +91,10 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
p += picref->linesize[0]; p += picref->linesize[0];
} }
ff_draw_slice(ctx->outputs[0], y, h, slice_dir); return ff_draw_slice(ctx->outputs[0], y, h, slice_dir);
} }
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
BlackFrameContext *blackframe = ctx->priv; BlackFrameContext *blackframe = ctx->priv;
@ -114,7 +114,7 @@ static void end_frame(AVFilterLink *inlink)
blackframe->frame++; blackframe->frame++;
blackframe->nblack = 0; blackframe->nblack = 0;
ff_end_frame(inlink->dst->outputs[0]); return ff_end_frame(inlink->dst->outputs[0]);
} }
AVFilter avfilter_vf_blackframe = { AVFilter avfilter_vf_blackframe = {

View File

@ -301,9 +301,9 @@ static void vblur(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_li
h, radius, power, temp); h, radius, power, temp);
} }
static void null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { } static int null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { return 0; }
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
BoxBlurContext *boxblur = ctx->priv; BoxBlurContext *boxblur = ctx->priv;
@ -328,7 +328,7 @@ static void end_frame(AVFilterLink *inlink)
boxblur->temp); boxblur->temp);
ff_draw_slice(outlink, 0, inlink->h, 1); ff_draw_slice(outlink, 0, inlink->h, 1);
avfilter_default_end_frame(inlink); return avfilter_default_end_frame(inlink);
} }
AVFilter avfilter_vf_boxblur = { AVFilter avfilter_vf_boxblur = {

View File

@ -340,7 +340,7 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms, int
return picref; return picref;
} }
static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
{ {
AVFilterContext *ctx = link->dst; AVFilterContext *ctx = link->dst;
ColorMatrixContext *color = ctx->priv; ColorMatrixContext *color = ctx->priv;
@ -348,10 +348,10 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
color->outpicref = outpicref; color->outpicref = outpicref;
ff_start_frame(link->dst->outputs[0], outpicref); return ff_start_frame(link->dst->outputs[0], outpicref);
} }
static void end_frame(AVFilterLink *link) static int end_frame(AVFilterLink *link)
{ {
AVFilterContext *ctx = link->dst; AVFilterContext *ctx = link->dst;
ColorMatrixContext *color = ctx->priv; ColorMatrixContext *color = ctx->priv;
@ -365,10 +365,10 @@ static void end_frame(AVFilterLink *link)
process_frame_uyvy422(color, out, link->cur_buf); process_frame_uyvy422(color, out, link->cur_buf);
ff_draw_slice(ctx->outputs[0], 0, link->dst->outputs[0]->h, 1); ff_draw_slice(ctx->outputs[0], 0, link->dst->outputs[0]->h, 1);
ff_end_frame(ctx->outputs[0]); return ff_end_frame(ctx->outputs[0]);
} }
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { return 0; }
AVFilter avfilter_vf_colormatrix = { AVFilter avfilter_vf_colormatrix = {
.name = "colormatrix", .name = "colormatrix",

View File

@ -259,7 +259,7 @@ static int config_output(AVFilterLink *link)
return 0; return 0;
} }
static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
{ {
AVFilterContext *ctx = link->dst; AVFilterContext *ctx = link->dst;
CropContext *crop = ctx->priv; CropContext *crop = ctx->priv;
@ -267,6 +267,9 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
int i; int i;
ref2 = avfilter_ref_buffer(picref, ~0); ref2 = avfilter_ref_buffer(picref, ~0);
if (!ref2)
return AVERROR(ENOMEM);
ref2->video->w = crop->w; ref2->video->w = crop->w;
ref2->video->h = crop->h; ref2->video->h = crop->h;
@ -310,16 +313,16 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
ref2->data[3] += crop->x * crop->max_step[3]; ref2->data[3] += crop->x * crop->max_step[3];
} }
ff_start_frame(link->dst->outputs[0], ref2); return ff_start_frame(link->dst->outputs[0], ref2);
} }
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)
{ {
AVFilterContext *ctx = link->dst; AVFilterContext *ctx = link->dst;
CropContext *crop = ctx->priv; CropContext *crop = ctx->priv;
if (y >= crop->y + crop->h || y + h <= crop->y) if (y >= crop->y + crop->h || y + h <= crop->y)
return; return 0;
if (y < crop->y) { if (y < crop->y) {
h -= crop->y - y; h -= crop->y - y;
@ -328,15 +331,15 @@ static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
if (y + h > crop->y + crop->h) if (y + h > crop->y + crop->h)
h = crop->y + crop->h - y; h = crop->y + crop->h - y;
ff_draw_slice(ctx->outputs[0], y - crop->y, h, slice_dir); return ff_draw_slice(ctx->outputs[0], y - crop->y, h, slice_dir);
} }
static void end_frame(AVFilterLink *link) static int end_frame(AVFilterLink *link)
{ {
CropContext *crop = link->dst->priv; CropContext *crop = link->dst->priv;
crop->var_values[VAR_N] += 1.0; crop->var_values[VAR_N] += 1.0;
ff_end_frame(link->dst->outputs[0]); return ff_end_frame(link->dst->outputs[0]);
} }
AVFilter avfilter_vf_crop = { AVFilter avfilter_vf_crop = {

View File

@ -114,7 +114,7 @@ static int config_input(AVFilterLink *inlink)
return 0; return 0;
} }
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
CropDetectContext *cd = ctx->priv; CropDetectContext *cd = ctx->priv;
@ -191,7 +191,7 @@ static void end_frame(AVFilterLink *inlink)
w, h, x, y); w, h, x, y);
} }
ff_end_frame(inlink->dst->outputs[0]); return ff_end_frame(inlink->dst->outputs[0]);
} }
AVFilter avfilter_vf_cropdetect = { AVFilter avfilter_vf_cropdetect = {

View File

@ -209,27 +209,48 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
return 0; return 0;
} }
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
{ {
AVFilterLink *outlink = inlink->dst->outputs[0]; AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *outpicref; AVFilterBufferRef *outpicref = NULL, *for_next_filter;
int ret = 0;
if (inpicref->perms & AV_PERM_PRESERVE) { if (inpicref->perms & AV_PERM_PRESERVE) {
outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE,
outlink->w, outlink->h); outlink->w, outlink->h);
if (!outpicref)
return AVERROR(ENOMEM);
avfilter_copy_buffer_ref_props(outpicref, inpicref); avfilter_copy_buffer_ref_props(outpicref, inpicref);
outpicref->video->w = outlink->w; outpicref->video->w = outlink->w;
outpicref->video->h = outlink->h; outpicref->video->h = outlink->h;
} else } else {
outpicref = avfilter_ref_buffer(inpicref, ~0); outpicref = avfilter_ref_buffer(inpicref, ~0);
if (!outpicref)
return AVERROR(ENOMEM);
}
for_next_filter = avfilter_ref_buffer(outpicref, ~0);
if (for_next_filter)
ret = ff_start_frame(outlink, for_next_filter);
else
ret = AVERROR(ENOMEM);
if (ret < 0) {
avfilter_unref_bufferp(&outpicref);
return ret;
}
outlink->out_buf = outpicref; outlink->out_buf = outpicref;
ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); return 0;
} }
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
{
return 0;
}
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
DelogoContext *delogo = inlink->dst->priv; DelogoContext *delogo = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0]; AVFilterLink *outlink = inlink->dst->outputs[0];
@ -239,6 +260,7 @@ static void end_frame(AVFilterLink *inlink)
int hsub0 = av_pix_fmt_descriptors[inlink->format].log2_chroma_w; int hsub0 = av_pix_fmt_descriptors[inlink->format].log2_chroma_w;
int vsub0 = av_pix_fmt_descriptors[inlink->format].log2_chroma_h; int vsub0 = av_pix_fmt_descriptors[inlink->format].log2_chroma_h;
int plane; int plane;
int ret;
for (plane = 0; plane < 4 && inpicref->data[plane]; plane++) { for (plane = 0; plane < 4 && inpicref->data[plane]; plane++) {
int hsub = plane == 1 || plane == 2 ? hsub0 : 0; int hsub = plane == 1 || plane == 2 ? hsub0 : 0;
@ -253,8 +275,10 @@ static void end_frame(AVFilterLink *inlink)
delogo->show, direct); delogo->show, direct);
} }
ff_draw_slice(outlink, 0, inlink->h, 1); if ((ret = ff_draw_slice(outlink, 0, inlink->h, 1)) < 0 ||
ff_end_frame(outlink); (ret = ff_end_frame(outlink)) < 0)
return ret;
return 0;
} }
AVFilter avfilter_vf_delogo = { AVFilter avfilter_vf_delogo = {

View File

@ -425,7 +425,7 @@ static av_cold void uninit(AVFilterContext *ctx)
av_freep(&deshake->avctx); av_freep(&deshake->avctx);
} }
static void end_frame(AVFilterLink *link) static int end_frame(AVFilterLink *link)
{ {
DeshakeContext *deshake = link->dst->priv; DeshakeContext *deshake = link->dst->priv;
AVFilterBufferRef *in = link->cur_buf; AVFilterBufferRef *in = link->cur_buf;
@ -529,11 +529,12 @@ static void end_frame(AVFilterLink *link)
// Draw the transformed frame information // Draw the transformed frame information
ff_draw_slice(link->dst->outputs[0], 0, link->h, 1); ff_draw_slice(link->dst->outputs[0], 0, link->h, 1);
ff_end_frame(link->dst->outputs[0]); return ff_end_frame(link->dst->outputs[0]);
} }
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)
{ {
return 0;
} }
AVFilter avfilter_vf_deshake = { AVFilter avfilter_vf_deshake = {

View File

@ -94,7 +94,7 @@ static int config_input(AVFilterLink *inlink)
return 0; return 0;
} }
static void draw_slice(AVFilterLink *inlink, int y0, int h, int slice_dir) static int draw_slice(AVFilterLink *inlink, int y0, int h, int slice_dir)
{ {
DrawBoxContext *drawbox = inlink->dst->priv; DrawBoxContext *drawbox = inlink->dst->priv;
int plane, x, y, xb = drawbox->x, yb = drawbox->y; int plane, x, y, xb = drawbox->x, yb = drawbox->y;
@ -120,7 +120,7 @@ static void draw_slice(AVFilterLink *inlink, int y0, int h, int slice_dir)
} }
} }
ff_draw_slice(inlink->dst->outputs[0], y0, h, 1); return ff_draw_slice(inlink->dst->outputs[0], y0, h, 1);
} }
AVFilter avfilter_vf_drawbox = { AVFilter avfilter_vf_drawbox = {

View File

@ -780,14 +780,18 @@ static int draw_text(AVFilterContext *ctx, AVFilterBufferRef *picref,
return 0; return 0;
} }
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
{
return 0;
}
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
AVFilterLink *outlink = ctx->outputs[0]; AVFilterLink *outlink = ctx->outputs[0];
DrawTextContext *dtext = ctx->priv; DrawTextContext *dtext = ctx->priv;
AVFilterBufferRef *picref = inlink->cur_buf; AVFilterBufferRef *picref = inlink->cur_buf;
int ret;
dtext->var_values[VAR_T] = picref->pts == AV_NOPTS_VALUE ? dtext->var_values[VAR_T] = picref->pts == AV_NOPTS_VALUE ?
NAN : picref->pts * av_q2d(inlink->time_base); NAN : picref->pts * av_q2d(inlink->time_base);
@ -801,8 +805,10 @@ static void end_frame(AVFilterLink *inlink)
dtext->var_values[VAR_N] += 1.0; dtext->var_values[VAR_N] += 1.0;
ff_draw_slice(outlink, 0, picref->video->h, 1); if ((ret = ff_draw_slice(outlink, 0, picref->video->h, 1)) < 0 ||
ff_end_frame(outlink); (ret = ff_end_frame(outlink)) < 0)
return ret;
return 0;
} }
AVFilter avfilter_vf_drawtext = { AVFilter avfilter_vf_drawtext = {

View File

@ -214,7 +214,7 @@ static void fade_plane(int y, int h, int w,
} }
} }
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
{ {
FadeContext *fade = inlink->dst->priv; FadeContext *fade = inlink->dst->priv;
AVFilterBufferRef *outpic = inlink->cur_buf; AVFilterBufferRef *outpic = inlink->cur_buf;
@ -255,20 +255,23 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
} }
} }
ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); return ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir);
} }
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
FadeContext *fade = inlink->dst->priv; FadeContext *fade = inlink->dst->priv;
int ret;
ff_end_frame(inlink->dst->outputs[0]); ret = ff_end_frame(inlink->dst->outputs[0]);
if (fade->frame_index >= fade->start_frame && if (fade->frame_index >= fade->start_frame &&
fade->frame_index <= fade->stop_frame) fade->frame_index <= fade->stop_frame)
fade->factor += fade->fade_per_frame; fade->factor += fade->fade_per_frame;
fade->factor = av_clip_uint16(fade->factor); fade->factor = av_clip_uint16(fade->factor);
fade->frame_index++; fade->frame_index++;
return ret;
} }
AVFilter avfilter_vf_fade = { AVFilter avfilter_vf_fade = {

View File

@ -116,21 +116,35 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms, int
return ff_get_video_buffer(outlink, perms, w, h); return ff_get_video_buffer(outlink, perms, w, h);
} }
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
AVFilterLink *outlink = ctx->outputs[0]; AVFilterLink *outlink = ctx->outputs[0];
AVFilterBufferRef *outpicref, *for_next_filter; AVFilterBufferRef *outpicref, *for_next_filter;
int ret = 0;
outpicref = avfilter_ref_buffer(inpicref, ~0); outpicref = avfilter_ref_buffer(inpicref, ~0);
outlink->out_buf = outpicref; if (!outpicref)
return AVERROR(ENOMEM);
for_next_filter = avfilter_ref_buffer(outpicref, ~0); for_next_filter = avfilter_ref_buffer(outpicref, ~0);
ff_start_frame(outlink, for_next_filter); if (!for_next_filter) {
avfilter_unref_bufferp(&outpicref);
return AVERROR(ENOMEM);
}
ret = ff_start_frame(outlink, for_next_filter);
if (ret < 0) {
avfilter_unref_bufferp(&outpicref);
return ret;
}
outlink->out_buf = outpicref;
return 0;
} }
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
FieldOrderContext *fieldorder = ctx->priv; FieldOrderContext *fieldorder = ctx->priv;
@ -144,11 +158,12 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
* and that complexity will be added later */ * and that complexity will be added later */
if ( !inpicref->video->interlaced if ( !inpicref->video->interlaced
|| inpicref->video->top_field_first == fieldorder->dst_tff) { || inpicref->video->top_field_first == fieldorder->dst_tff) {
ff_draw_slice(outlink, y, h, slice_dir); return ff_draw_slice(outlink, y, h, slice_dir);
} }
return 0;
} }
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
FieldOrderContext *fieldorder = ctx->priv; FieldOrderContext *fieldorder = ctx->priv;
@ -212,7 +227,7 @@ static void end_frame(AVFilterLink *inlink)
"not interlaced or field order already correct\n"); "not interlaced or field order already correct\n");
} }
ff_end_frame(outlink); return ff_end_frame(outlink);
} }
AVFilter avfilter_vf_fieldorder = { AVFilter avfilter_vf_fieldorder = {

View File

@ -143,9 +143,11 @@ static int request_frame(AVFilterLink *outlink)
buf->pts = av_rescale_q(s->first_pts, ctx->inputs[0]->time_base, buf->pts = av_rescale_q(s->first_pts, ctx->inputs[0]->time_base,
outlink->time_base) + s->frames_out; outlink->time_base) + s->frames_out;
ff_start_frame(outlink, buf); if ((ret = ff_start_frame(outlink, buf)) < 0 ||
ff_draw_slice(outlink, 0, outlink->h, 1); (ret = ff_draw_slice(outlink, 0, outlink->h, 1)) < 0 ||
ff_end_frame(outlink); (ret = ff_end_frame(outlink)) < 0)
return ret;
s->frames_out++; s->frames_out++;
} }
return 0; return 0;
@ -159,28 +161,33 @@ static int write_to_fifo(AVFifoBuffer *fifo, AVFilterBufferRef *buf)
int ret; int ret;
if (!av_fifo_space(fifo) && if (!av_fifo_space(fifo) &&
(ret = av_fifo_realloc2(fifo, 2*av_fifo_size(fifo)))) (ret = av_fifo_realloc2(fifo, 2*av_fifo_size(fifo)))) {
avfilter_unref_bufferp(&buf);
return ret; return ret;
}
av_fifo_generic_write(fifo, &buf, sizeof(buf), NULL); av_fifo_generic_write(fifo, &buf, sizeof(buf), NULL);
return 0; return 0;
} }
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
FPSContext *s = ctx->priv; FPSContext *s = ctx->priv;
AVFilterLink *outlink = ctx->outputs[0]; AVFilterLink *outlink = ctx->outputs[0];
AVFilterBufferRef *buf = inlink->cur_buf; AVFilterBufferRef *buf = inlink->cur_buf;
int64_t delta; int64_t delta;
int i; int i, ret;
inlink->cur_buf = NULL; inlink->cur_buf = NULL;
s->frames_in++; s->frames_in++;
/* discard frames until we get the first timestamp */ /* discard frames until we get the first timestamp */
if (s->pts == AV_NOPTS_VALUE) { if (s->pts == AV_NOPTS_VALUE) {
if (buf->pts != AV_NOPTS_VALUE) { if (buf->pts != AV_NOPTS_VALUE) {
write_to_fifo(s->fifo, buf); ret = write_to_fifo(s->fifo, buf);
if (ret < 0)
return ret;
s->first_pts = s->pts = buf->pts; s->first_pts = s->pts = buf->pts;
} else { } else {
av_log(ctx, AV_LOG_WARNING, "Discarding initial frame(s) with no " av_log(ctx, AV_LOG_WARNING, "Discarding initial frame(s) with no "
@ -188,13 +195,12 @@ static void end_frame(AVFilterLink *inlink)
avfilter_unref_buffer(buf); avfilter_unref_buffer(buf);
s->drop++; s->drop++;
} }
return; return 0;
} }
/* now wait for the next timestamp */ /* now wait for the next timestamp */
if (buf->pts == AV_NOPTS_VALUE) { if (buf->pts == AV_NOPTS_VALUE) {
write_to_fifo(s->fifo, buf); return write_to_fifo(s->fifo, buf);
return;
} }
/* number of output frames */ /* number of output frames */
@ -211,10 +217,10 @@ static void end_frame(AVFilterLink *inlink)
av_fifo_generic_read(s->fifo, &tmp, sizeof(tmp), NULL); av_fifo_generic_read(s->fifo, &tmp, sizeof(tmp), NULL);
flush_fifo(s->fifo); flush_fifo(s->fifo);
write_to_fifo(s->fifo, tmp); ret = write_to_fifo(s->fifo, tmp);
avfilter_unref_buffer(buf); avfilter_unref_buffer(buf);
return; return ret;
} }
/* can output >= 1 frames */ /* can output >= 1 frames */
@ -224,31 +230,51 @@ static void end_frame(AVFilterLink *inlink)
/* duplicate the frame if needed */ /* duplicate the frame if needed */
if (!av_fifo_size(s->fifo) && i < delta - 1) { if (!av_fifo_size(s->fifo) && i < delta - 1) {
AVFilterBufferRef *dup = avfilter_ref_buffer(buf_out, AV_PERM_READ);
av_log(ctx, AV_LOG_DEBUG, "Duplicating frame.\n"); av_log(ctx, AV_LOG_DEBUG, "Duplicating frame.\n");
write_to_fifo(s->fifo, avfilter_ref_buffer(buf_out, AV_PERM_READ)); if (dup)
ret = write_to_fifo(s->fifo, dup);
else
ret = AVERROR(ENOMEM);
if (ret < 0) {
avfilter_unref_bufferp(&buf_out);
avfilter_unref_bufferp(&buf);
return ret;
}
s->dup++; s->dup++;
} }
buf_out->pts = av_rescale_q(s->first_pts, inlink->time_base, buf_out->pts = av_rescale_q(s->first_pts, inlink->time_base,
outlink->time_base) + s->frames_out; outlink->time_base) + s->frames_out;
ff_start_frame(outlink, buf_out); if ((ret = ff_start_frame(outlink, buf_out)) < 0 ||
ff_draw_slice(outlink, 0, outlink->h, 1); (ret = ff_draw_slice(outlink, 0, outlink->h, 1)) < 0 ||
ff_end_frame(outlink); (ret = ff_end_frame(outlink)) < 0) {
avfilter_unref_bufferp(&buf);
return ret;
}
s->frames_out++; s->frames_out++;
} }
flush_fifo(s->fifo); flush_fifo(s->fifo);
write_to_fifo(s->fifo, buf); ret = write_to_fifo(s->fifo, buf);
s->pts = s->first_pts + av_rescale_q(s->frames_out, outlink->time_base, inlink->time_base); s->pts = s->first_pts + av_rescale_q(s->frames_out, outlink->time_base, inlink->time_base);
return ret;
} }
static void null_start_frame(AVFilterLink *link, AVFilterBufferRef *buf) static int null_start_frame(AVFilterLink *link, AVFilterBufferRef *buf)
{ {
return 0;
} }
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
{ {
return 0;
} }
AVFilter avfilter_vf_fps = { AVFilter avfilter_vf_fps = {

View File

@ -340,20 +340,26 @@ static int query_formats(AVFilterContext *ctx)
return 0; return 0;
} }
static void null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { } static int null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
{
return 0;
}
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
Frei0rContext *frei0r = inlink->dst->priv; Frei0rContext *frei0r = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0]; AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *inpicref = inlink->cur_buf; AVFilterBufferRef *inpicref = inlink->cur_buf;
AVFilterBufferRef *outpicref = outlink->out_buf; AVFilterBufferRef *outpicref = outlink->out_buf;
int ret;
frei0r->update(frei0r->instance, inpicref->pts * av_q2d(inlink->time_base) * 1000, frei0r->update(frei0r->instance, inpicref->pts * av_q2d(inlink->time_base) * 1000,
(const uint32_t *)inpicref->data[0], (const uint32_t *)inpicref->data[0],
(uint32_t *)outpicref->data[0]); (uint32_t *)outpicref->data[0]);
ff_draw_slice(outlink, 0, outlink->h, 1); if ((ret = ff_draw_slice(outlink, 0, outlink->h, 1)) ||
ff_end_frame(outlink); (ret = ff_end_frame(outlink)) < 0)
return ret;
return 0;
} }
AVFilter avfilter_vf_frei0r = { AVFilter avfilter_vf_frei0r = {
@ -432,18 +438,38 @@ static int source_request_frame(AVFilterLink *outlink)
{ {
Frei0rContext *frei0r = outlink->src->priv; Frei0rContext *frei0r = outlink->src->priv;
AVFilterBufferRef *picref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); AVFilterBufferRef *picref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
AVFilterBufferRef *buf_out;
int ret;
if (!picref)
return AVERROR(ENOMEM);
picref->video->sample_aspect_ratio = (AVRational) {1, 1}; picref->video->sample_aspect_ratio = (AVRational) {1, 1};
picref->pts = frei0r->pts++; picref->pts = frei0r->pts++;
picref->pos = -1; picref->pos = -1;
ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0)); buf_out = avfilter_ref_buffer(picref, ~0);
if (!buf_out) {
ret = AVERROR(ENOMEM);
goto fail;
}
ret = ff_start_frame(outlink, buf_out);
if (ret < 0)
goto fail;
frei0r->update(frei0r->instance, av_rescale_q(picref->pts, frei0r->time_base, (AVRational){1,1000}), frei0r->update(frei0r->instance, av_rescale_q(picref->pts, frei0r->time_base, (AVRational){1,1000}),
NULL, (uint32_t *)picref->data[0]); NULL, (uint32_t *)picref->data[0]);
ff_draw_slice(outlink, 0, outlink->h, 1); ret = ff_draw_slice(outlink, 0, outlink->h, 1);
ff_end_frame(outlink); if (ret < 0)
goto fail;
ret = ff_end_frame(outlink);
fail:
avfilter_unref_buffer(picref); avfilter_unref_buffer(picref);
return 0; return ret;
} }
AVFilter avfilter_vsrc_frei0r_src = { AVFilter avfilter_vsrc_frei0r_src = {

View File

@ -180,32 +180,53 @@ static int config_input(AVFilterLink *inlink)
return 0; return 0;
} }
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
{ {
AVFilterLink *outlink = inlink->dst->outputs[0]; AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *outpicref; AVFilterBufferRef *outpicref = NULL, *for_next_filter;
int ret = 0;
if (inpicref->perms & AV_PERM_PRESERVE) { if (inpicref->perms & AV_PERM_PRESERVE) {
outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
if (!outpicref)
return AVERROR(ENOMEM);
avfilter_copy_buffer_ref_props(outpicref, inpicref); avfilter_copy_buffer_ref_props(outpicref, inpicref);
outpicref->video->w = outlink->w; outpicref->video->w = outlink->w;
outpicref->video->h = outlink->h; outpicref->video->h = outlink->h;
} else } else {
outpicref = avfilter_ref_buffer(inpicref, ~0); outpicref = avfilter_ref_buffer(inpicref, ~0);
if (!outpicref)
return AVERROR(ENOMEM);
}
for_next_filter = avfilter_ref_buffer(outpicref, ~0);
if (for_next_filter)
ret = ff_start_frame(outlink, for_next_filter);
else
ret = AVERROR(ENOMEM);
if (ret < 0) {
avfilter_unref_bufferp(&outpicref);
return ret;
}
outlink->out_buf = outpicref; outlink->out_buf = outpicref;
ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); return 0;
} }
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
{
return 0;
}
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
GradFunContext *gf = inlink->dst->priv; GradFunContext *gf = inlink->dst->priv;
AVFilterBufferRef *inpic = inlink->cur_buf; AVFilterBufferRef *inpic = inlink->cur_buf;
AVFilterLink *outlink = inlink->dst->outputs[0]; AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *outpic = outlink->out_buf; AVFilterBufferRef *outpic = outlink->out_buf;
int p; int p, ret;
for (p = 0; p < 4 && inpic->data[p]; p++) { for (p = 0; p < 4 && inpic->data[p]; p++) {
int w = inlink->w; int w = inlink->w;
@ -223,8 +244,10 @@ static void end_frame(AVFilterLink *inlink)
av_image_copy_plane(outpic->data[p], outpic->linesize[p], inpic->data[p], inpic->linesize[p], w, h); av_image_copy_plane(outpic->data[p], outpic->linesize[p], inpic->data[p], inpic->linesize[p], w, h);
} }
ff_draw_slice(outlink, 0, inlink->h, 1); if ((ret = ff_draw_slice(outlink, 0, inlink->h, 1)) < 0 ||
ff_end_frame(outlink); (ret = ff_end_frame(outlink)) < 0)
return ret;
return 0;
} }
AVFilter avfilter_vf_gradfun = { AVFilter avfilter_vf_gradfun = {

View File

@ -83,7 +83,7 @@ static int config_props(AVFilterLink *inlink)
return 0; return 0;
} }
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
{ {
AVFilterLink *outlink = inlink->dst->outputs[0]; AVFilterLink *outlink = inlink->dst->outputs[0];
@ -95,10 +95,10 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
if (av_pix_fmt_descriptors[inlink->format].flags & PIX_FMT_PAL) if (av_pix_fmt_descriptors[inlink->format].flags & PIX_FMT_PAL)
memcpy(inlink->dst->outputs[0]->out_buf->data[1], picref->data[1], AVPALETTE_SIZE); memcpy(inlink->dst->outputs[0]->out_buf->data[1], picref->data[1], AVPALETTE_SIZE);
ff_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0)); return ff_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0));
} }
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
{ {
FlipContext *flip = inlink->dst->priv; FlipContext *flip = inlink->dst->priv;
AVFilterBufferRef *inpic = inlink->cur_buf; AVFilterBufferRef *inpic = inlink->cur_buf;
@ -159,7 +159,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
} }
} }
ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); return ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir);
} }
AVFilter avfilter_vf_hflip = { AVFilter avfilter_vf_hflip = {

View File

@ -290,9 +290,12 @@ static int config_input(AVFilterLink *inlink)
return 0; return 0;
} }
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
{
return 0;
}
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
HQDN3DContext *hqdn3d = inlink->dst->priv; HQDN3DContext *hqdn3d = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0]; AVFilterLink *outlink = inlink->dst->outputs[0];
@ -300,6 +303,7 @@ static void end_frame(AVFilterLink *inlink)
AVFilterBufferRef *outpic = outlink->out_buf; AVFilterBufferRef *outpic = outlink->out_buf;
int cw = inpic->video->w >> hqdn3d->hsub; int cw = inpic->video->w >> hqdn3d->hsub;
int ch = inpic->video->h >> hqdn3d->vsub; int ch = inpic->video->h >> hqdn3d->vsub;
int ret;
deNoise(inpic->data[0], outpic->data[0], deNoise(inpic->data[0], outpic->data[0],
hqdn3d->Line, &hqdn3d->Frame[0], inpic->video->w, inpic->video->h, hqdn3d->Line, &hqdn3d->Frame[0], inpic->video->w, inpic->video->h,
@ -320,8 +324,10 @@ static void end_frame(AVFilterLink *inlink)
hqdn3d->Coefs[2], hqdn3d->Coefs[2],
hqdn3d->Coefs[3]); hqdn3d->Coefs[3]);
ff_draw_slice(outlink, 0, inpic->video->h, 1); if ((ret = ff_draw_slice(outlink, 0, inpic->video->h, 1)) < 0 ||
ff_end_frame(outlink); (ret = ff_end_frame(outlink)) < 0)
return ret;
return 0;
} }
AVFilter avfilter_vf_hqdn3d = { AVFilter avfilter_vf_hqdn3d = {

View File

@ -169,7 +169,7 @@ static void filter(AVFilterContext *ctx)
av_log(ctx, AV_LOG_DEBUG, "Single frame:%s, Multi frame:%s\n", type2str(type), type2str(idet->last_type)); av_log(ctx, AV_LOG_DEBUG, "Single frame:%s, Multi frame:%s\n", type2str(type), type2str(idet->last_type));
} }
static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
{ {
AVFilterContext *ctx = link->dst; AVFilterContext *ctx = link->dst;
IDETContext *idet = ctx->priv; IDETContext *idet = ctx->priv;
@ -181,21 +181,21 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
idet->next = picref; idet->next = picref;
if (!idet->cur) if (!idet->cur)
return; return 0;
if (!idet->prev) if (!idet->prev)
idet->prev = avfilter_ref_buffer(idet->cur, AV_PERM_READ); idet->prev = avfilter_ref_buffer(idet->cur, AV_PERM_READ);
ff_start_frame(ctx->outputs[0], avfilter_ref_buffer(idet->cur, AV_PERM_READ)); return ff_start_frame(ctx->outputs[0], avfilter_ref_buffer(idet->cur, AV_PERM_READ));
} }
static void end_frame(AVFilterLink *link) static int end_frame(AVFilterLink *link)
{ {
AVFilterContext *ctx = link->dst; AVFilterContext *ctx = link->dst;
IDETContext *idet = ctx->priv; IDETContext *idet = ctx->priv;
if (!idet->cur) if (!idet->cur)
return; return 0;
if (!idet->csp) if (!idet->csp)
idet->csp = &av_pix_fmt_descriptors[link->format]; idet->csp = &av_pix_fmt_descriptors[link->format];
@ -205,7 +205,7 @@ static void end_frame(AVFilterLink *link)
filter(ctx); filter(ctx);
ff_draw_slice(ctx->outputs[0], 0, link->h, 1); ff_draw_slice(ctx->outputs[0], 0, link->h, 1);
ff_end_frame(ctx->outputs[0]); return ff_end_frame(ctx->outputs[0]);
} }
static int request_frame(AVFilterLink *link) static int request_frame(AVFilterLink *link)
@ -311,7 +311,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
return 0; return 0;
} }
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { return 0; }
AVFilter avfilter_vf_idet = { AVFilter avfilter_vf_idet = {
.name = "idet", .name = "idet",

View File

@ -67,7 +67,10 @@ static int query_formats(AVFilterContext *ctx)
return 0; return 0;
} }
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
{
return 0;
}
typedef struct { typedef struct {
const char *name; const char *name;
@ -351,7 +354,7 @@ static av_cold void uninit(AVFilterContext *ctx)
memset(ocv, 0, sizeof(*ocv)); memset(ocv, 0, sizeof(*ocv));
} }
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
OCVContext *ocv = ctx->priv; OCVContext *ocv = ctx->priv;
@ -359,14 +362,17 @@ static void end_frame(AVFilterLink *inlink)
AVFilterBufferRef *inpicref = inlink ->cur_buf; AVFilterBufferRef *inpicref = inlink ->cur_buf;
AVFilterBufferRef *outpicref = outlink->out_buf; AVFilterBufferRef *outpicref = outlink->out_buf;
IplImage inimg, outimg; IplImage inimg, outimg;
int ret;
fill_iplimage_from_picref(&inimg , inpicref , inlink->format); fill_iplimage_from_picref(&inimg , inpicref , inlink->format);
fill_iplimage_from_picref(&outimg, outpicref, inlink->format); fill_iplimage_from_picref(&outimg, outpicref, inlink->format);
ocv->end_frame_filter(ctx, &inimg, &outimg); ocv->end_frame_filter(ctx, &inimg, &outimg);
fill_picref_from_iplimage(outpicref, &outimg, inlink->format); fill_picref_from_iplimage(outpicref, &outimg, inlink->format);
ff_draw_slice(outlink, 0, outlink->h, 1); if ((ret = ff_draw_slice(outlink, 0, outlink->h, 1)) < 0 ||
ff_end_frame(outlink); (ret = ff_end_frame(outlink)) < 0)
return ret;
return 0;
} }
AVFilter avfilter_vf_ocv = { AVFilter avfilter_vf_ocv = {

View File

@ -275,7 +275,7 @@ static int config_props(AVFilterLink *inlink)
return 0; return 0;
} }
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
LutContext *lut = ctx->priv; LutContext *lut = ctx->priv;
@ -332,7 +332,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
} }
} }
ff_draw_slice(outlink, y, h, slice_dir); return ff_draw_slice(outlink, y, h, slice_dir);
} }
static const AVFilterPad inputs[] = { static const AVFilterPad inputs[] = {

View File

@ -848,15 +848,17 @@ static int request_frame(AVFilterLink *outlink)
return ret; return ret;
} }
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
{ {
return 0;
} }
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
{ {
return 0;
} }
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
MPContext *m = inlink->dst->priv; MPContext *m = inlink->dst->priv;
AVFilterBufferRef *inpic = inlink->cur_buf; AVFilterBufferRef *inpic = inlink->cur_buf;
@ -883,6 +885,7 @@ static void end_frame(AVFilterLink *inlink)
av_log(m->avfctx, AV_LOG_DEBUG, "put_image() says skip\n"); av_log(m->avfctx, AV_LOG_DEBUG, "put_image() says skip\n");
} }
free_mp_image(mpi); free_mp_image(mpi);
return 0;
} }
AVFilter avfilter_vf_mp = { AVFilter avfilter_vf_mp = {

View File

@ -145,8 +145,7 @@ static av_cold void uninit(AVFilterContext *ctx)
av_freep(&over->x_expr); av_freep(&over->x_expr);
av_freep(&over->y_expr); av_freep(&over->y_expr);
if (over->overpicref) avfilter_unref_bufferp(&over->overpicref);
avfilter_unref_bufferp(&over->overpicref);
ff_bufqueue_discard_all(&over->queue_main); ff_bufqueue_discard_all(&over->queue_main);
ff_bufqueue_discard_all(&over->queue_over); ff_bufqueue_discard_all(&over->queue_over);
} }
@ -506,7 +505,7 @@ static void flush_frames(AVFilterContext *ctx)
while (!try_push_frame(ctx)); while (!try_push_frame(ctx));
} }
static void start_frame_main(AVFilterLink *inlink, AVFilterBufferRef *inpicref) static int start_frame_main(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
OverlayContext *over = ctx->priv; OverlayContext *over = ctx->priv;
@ -519,9 +518,10 @@ static void start_frame_main(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
av_assert1(inpicref == inlink->cur_buf); av_assert1(inpicref == inlink->cur_buf);
inlink->cur_buf = NULL; inlink->cur_buf = NULL;
} }
return 0;
} }
static void draw_slice_main(AVFilterLink *inlink, int y, int h, int slice_dir) static int draw_slice_main(AVFilterLink *inlink, int y, int h, int slice_dir)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
OverlayContext *over = ctx->priv; OverlayContext *over = ctx->priv;
@ -536,10 +536,10 @@ static void draw_slice_main(AVFilterLink *inlink, int y, int h, int slice_dir)
over->overpicref->video->w, over->overpicref->video->h, over->overpicref->video->w, over->overpicref->video->h,
y, outpicref->video->w, h); y, outpicref->video->w, h);
} }
ff_draw_slice(outlink, y, h, slice_dir); return ff_draw_slice(outlink, y, h, slice_dir);
} }
static void end_frame_main(AVFilterLink *inlink) static int end_frame_main(AVFilterLink *inlink)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
AVFilterLink *outlink = ctx->outputs[0]; AVFilterLink *outlink = ctx->outputs[0];
@ -547,15 +547,16 @@ static void end_frame_main(AVFilterLink *inlink)
flush_frames(ctx); flush_frames(ctx);
if (!outpicref) if (!outpicref)
return; return 0;
ff_end_frame(ctx->outputs[0]); return ff_end_frame(ctx->outputs[0]);
} }
static void start_frame_over(AVFilterLink *inlink, AVFilterBufferRef *inpicref) static int start_frame_over(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
{ {
return 0;
} }
static void end_frame_over(AVFilterLink *inlink) static int end_frame_over(AVFilterLink *inlink)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
OverlayContext *over = ctx->priv; OverlayContext *over = ctx->priv;
@ -566,7 +567,7 @@ static void end_frame_over(AVFilterLink *inlink)
inpicref->pts = av_rescale_q(inpicref->pts, ctx->inputs[OVERLAY]->time_base, inpicref->pts = av_rescale_q(inpicref->pts, ctx->inputs[OVERLAY]->time_base,
ctx->outputs[0]->time_base); ctx->outputs[0]->time_base);
ff_bufqueue_add(ctx, &over->queue_over, inpicref); ff_bufqueue_add(ctx, &over->queue_over, inpicref);
try_push_frame(ctx); return try_push_frame(ctx);
} }
static int request_frame(AVFilterLink *outlink) static int request_frame(AVFilterLink *outlink)
@ -597,7 +598,10 @@ static int request_frame(AVFilterLink *outlink)
return 0; return 0;
} }
static void null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { } static int null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
{
return 0;
}
AVFilter avfilter_vf_overlay = { AVFilter avfilter_vf_overlay = {
.name = "overlay", .name = "overlay",

View File

@ -226,6 +226,9 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms, int
h + (pad->h - pad->in_h)); h + (pad->h - pad->in_h));
int plane; int plane;
if (!picref)
return NULL;
picref->video->w = w; picref->video->w = w;
picref->video->h = h; picref->video->h = h;
@ -259,12 +262,15 @@ static int does_clip(PadContext *pad, AVFilterBufferRef *outpicref, int plane, i
return 0; return 0;
} }
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
{ {
PadContext *pad = inlink->dst->priv; PadContext *pad = inlink->dst->priv;
AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0); AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0);
AVFilterBufferRef *for_next_filter; AVFilterBufferRef *for_next_filter;
int plane; int plane, ret = 0;
if (!outpicref)
return AVERROR(ENOMEM);
for (plane = 0; plane < 4 && outpicref->data[plane] && pad->draw.pixelstep[plane]; plane++) { for (plane = 0; plane < 4 && outpicref->data[plane] && pad->draw.pixelstep[plane]; plane++) {
int hsub = pad->draw.hsub[plane]; int hsub = pad->draw.hsub[plane];
@ -292,22 +298,37 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
outpicref = ff_get_video_buffer(inlink->dst->outputs[0], AV_PERM_WRITE | AV_PERM_NEG_LINESIZES, outpicref = ff_get_video_buffer(inlink->dst->outputs[0], AV_PERM_WRITE | AV_PERM_NEG_LINESIZES,
FFMAX(inlink->w, pad->w), FFMAX(inlink->w, pad->w),
FFMAX(inlink->h, pad->h)); FFMAX(inlink->h, pad->h));
if (!outpicref)
return AVERROR(ENOMEM);
avfilter_copy_buffer_ref_props(outpicref, inpicref); avfilter_copy_buffer_ref_props(outpicref, inpicref);
} }
inlink->dst->outputs[0]->out_buf = outpicref;
outpicref->video->w = pad->w; outpicref->video->w = pad->w;
outpicref->video->h = pad->h; outpicref->video->h = pad->h;
for_next_filter = avfilter_ref_buffer(outpicref, ~0); for_next_filter = avfilter_ref_buffer(outpicref, ~0);
ff_start_frame(inlink->dst->outputs[0], for_next_filter); 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; 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) { if (slice_dir * before_slice == 1 && y == pad->y) {
/* top bar */ /* top bar */
@ -324,15 +345,17 @@ static void draw_send_bar_slice(AVFilterLink *link, int y, int h, int slice_dir,
link->dst->outputs[0]->out_buf->data, link->dst->outputs[0]->out_buf->data,
link->dst->outputs[0]->out_buf->linesize, link->dst->outputs[0]->out_buf->linesize,
0, bar_y, pad->w, bar_h); 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; PadContext *pad = link->dst->priv;
AVFilterBufferRef *outpic = link->dst->outputs[0]->out_buf; AVFilterBufferRef *outpic = link->dst->outputs[0]->out_buf;
AVFilterBufferRef *inpic = link->cur_buf; AVFilterBufferRef *inpic = link->cur_buf;
int ret;
y += pad->y; y += pad->y;
@ -340,7 +363,7 @@ static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
h = ff_draw_round_to_sub(&pad->draw, 1, -1, h); h = ff_draw_round_to_sub(&pad->draw, 1, -1, h);
if (!h) if (!h)
return; return 0;
draw_send_bar_slice(link, y, h, slice_dir, 1); draw_send_bar_slice(link, y, h, slice_dir, 1);
/* left border */ /* left border */
@ -357,9 +380,11 @@ static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
/* right border */ /* right border */
ff_fill_rectangle(&pad->draw, &pad->color, outpic->data, outpic->linesize, 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); 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 = { AVFilter avfilter_vf_pad = {

View File

@ -51,16 +51,18 @@ static int config_props(AVFilterLink *inlink)
return 0; return 0;
} }
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
{ {
PixdescTestContext *priv = inlink->dst->priv; PixdescTestContext *priv = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0]; AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *outpicref; AVFilterBufferRef *outpicref, *for_next_filter;
int i; int i, ret = 0;
outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE,
outlink->w, outlink->h);
if (!outpicref)
return AVERROR(ENOMEM);
outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE,
outlink->w, outlink->h);
outpicref = outlink->out_buf;
avfilter_copy_buffer_ref_props(outpicref, picref); avfilter_copy_buffer_ref_props(outpicref, picref);
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
@ -78,10 +80,22 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
priv->pix_desc->flags & PIX_FMT_PSEUDOPAL) priv->pix_desc->flags & PIX_FMT_PSEUDOPAL)
memcpy(outpicref->data[1], picref->data[1], AVPALETTE_SIZE); memcpy(outpicref->data[1], picref->data[1], AVPALETTE_SIZE);
ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); for_next_filter = avfilter_ref_buffer(outpicref, ~0);
if (for_next_filter)
ret = ff_start_frame(outlink, for_next_filter);
else
ret = AVERROR(ENOMEM);
if (ret < 0) {
avfilter_unref_bufferp(&outpicref);
return ret;
}
outlink->out_buf = outpicref;
return 0;
} }
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
{ {
PixdescTestContext *priv = inlink->dst->priv; PixdescTestContext *priv = inlink->dst->priv;
AVFilterBufferRef *inpic = inlink->cur_buf; AVFilterBufferRef *inpic = inlink->cur_buf;
@ -108,7 +122,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
} }
} }
ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); return ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir);
} }
AVFilter avfilter_vf_pixdesctest = { AVFilter avfilter_vf_pixdesctest = {

View File

@ -472,7 +472,7 @@ static void blur_image(int ***mask,
} }
} }
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
{ {
AVFilterLink *outlink = inlink->dst->outputs[0]; AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *outpicref; AVFilterBufferRef *outpicref;
@ -487,10 +487,10 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
outpicref = inpicref; outpicref = inpicref;
outlink->out_buf = outpicref; outlink->out_buf = outpicref;
ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); return ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0));
} }
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
RemovelogoContext *removelogo = inlink->dst->priv; RemovelogoContext *removelogo = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0]; AVFilterLink *outlink = inlink->dst->outputs[0];
@ -515,7 +515,7 @@ static void end_frame(AVFilterLink *inlink)
inlink->w/2, inlink->h/2, direct, &removelogo->half_mask_bbox); inlink->w/2, inlink->h/2, direct, &removelogo->half_mask_bbox);
ff_draw_slice(outlink, 0, inlink->h, 1); ff_draw_slice(outlink, 0, inlink->h, 1);
ff_end_frame(outlink); return ff_end_frame(outlink);
} }
static void uninit(AVFilterContext *ctx) static void uninit(AVFilterContext *ctx)
@ -540,7 +540,7 @@ static void uninit(AVFilterContext *ctx)
} }
} }
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { return 0; }
AVFilter avfilter_vf_removelogo = { AVFilter avfilter_vf_removelogo = {
.name = "removelogo", .name = "removelogo",

View File

@ -272,11 +272,12 @@ fail:
return ret; return ret;
} }
static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
{ {
ScaleContext *scale = link->dst->priv; ScaleContext *scale = link->dst->priv;
AVFilterLink *outlink = link->dst->outputs[0]; AVFilterLink *outlink = link->dst->outputs[0];
AVFilterBufferRef *outpicref; AVFilterBufferRef *outpicref, *for_next_filter;
int ret = 0;
if( picref->video->w != link->w if( picref->video->w != link->w
|| picref->video->h != link->h || picref->video->h != link->h
@ -295,19 +296,23 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
if (!scale->sws) { if (!scale->sws) {
ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0)); outpicref = avfilter_ref_buffer(picref, ~0);
return; if (!outpicref)
return AVERROR(ENOMEM);
return ff_start_frame(outlink, outpicref);
} }
scale->hsub = av_pix_fmt_descriptors[link->format].log2_chroma_w; scale->hsub = av_pix_fmt_descriptors[link->format].log2_chroma_w;
scale->vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h; scale->vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h;
outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_ALIGN, outlink->w, outlink->h); outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_ALIGN, outlink->w, outlink->h);
if (!outpicref)
return AVERROR(ENOMEM);
avfilter_copy_buffer_ref_props(outpicref, picref); avfilter_copy_buffer_ref_props(outpicref, picref);
outpicref->video->w = outlink->w; outpicref->video->w = outlink->w;
outpicref->video->h = outlink->h; outpicref->video->h = outlink->h;
outlink->out_buf = outpicref;
if(scale->output_is_pal) if(scale->output_is_pal)
ff_set_systematic_pal2(outpicref->data[1], outlink->format == PIX_FMT_PAL8 ? PIX_FMT_BGR8 : outlink->format); ff_set_systematic_pal2(outpicref->data[1], outlink->format == PIX_FMT_PAL8 ? PIX_FMT_BGR8 : outlink->format);
@ -317,7 +322,19 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
INT_MAX); INT_MAX);
scale->slice_y = 0; scale->slice_y = 0;
ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); for_next_filter = avfilter_ref_buffer(outpicref, ~0);
if (for_next_filter)
ret = ff_start_frame(outlink, for_next_filter);
else
ret = AVERROR(ENOMEM);
if (ret < 0) {
avfilter_unref_bufferp(&outpicref);
return ret;
}
outlink->out_buf = outpicref;
return 0;
} }
static int scale_slice(AVFilterLink *link, struct SwsContext *sws, int y, int h, int mul, int field) static int scale_slice(AVFilterLink *link, struct SwsContext *sws, int y, int h, int mul, int field)
@ -346,14 +363,13 @@ static int scale_slice(AVFilterLink *link, struct SwsContext *sws, int y, int h,
out,out_stride); out,out_stride);
} }
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)
{ {
ScaleContext *scale = link->dst->priv; ScaleContext *scale = link->dst->priv;
int out_h; int out_h, ret;
if (!scale->sws) { if (!scale->sws) {
ff_draw_slice(link->dst->outputs[0], y, h, slice_dir); return ff_draw_slice(link->dst->outputs[0], y, h, slice_dir);
return;
} }
if (scale->slice_y == 0 && slice_dir == -1) if (scale->slice_y == 0 && slice_dir == -1)
@ -369,9 +385,10 @@ static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
if (slice_dir == -1) if (slice_dir == -1)
scale->slice_y -= out_h; scale->slice_y -= out_h;
ff_draw_slice(link->dst->outputs[0], scale->slice_y, out_h, slice_dir); ret = ff_draw_slice(link->dst->outputs[0], scale->slice_y, out_h, slice_dir);
if (slice_dir == 1) if (slice_dir == 1)
scale->slice_y += out_h; scale->slice_y += out_h;
return ret;
} }
AVFilter avfilter_vf_scale = { AVFilter avfilter_vf_scale = {

View File

@ -269,12 +269,13 @@ static int select_frame(AVFilterContext *ctx, AVFilterBufferRef *picref)
return res; return res;
} }
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
{ {
SelectContext *select = inlink->dst->priv; SelectContext *select = inlink->dst->priv;
select->select = select_frame(inlink->dst, picref); select->select = select_frame(inlink->dst, picref);
if (select->select) { if (select->select) {
AVFilterBufferRef *buf_out;
/* frame was requested through poll_frame */ /* frame was requested through poll_frame */
if (select->cache_frames) { if (select->cache_frames) {
if (!av_fifo_space(select->pending_frames)) if (!av_fifo_space(select->pending_frames))
@ -283,29 +284,36 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
else else
av_fifo_generic_write(select->pending_frames, &picref, av_fifo_generic_write(select->pending_frames, &picref,
sizeof(picref), NULL); sizeof(picref), NULL);
return; return 0;
} }
ff_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(picref, ~0)); buf_out = avfilter_ref_buffer(picref, ~0);
if (!buf_out)
return AVERROR(ENOMEM);
return ff_start_frame(inlink->dst->outputs[0], buf_out);
} }
return 0;
} }
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
{ {
SelectContext *select = inlink->dst->priv; SelectContext *select = inlink->dst->priv;
if (select->select && !select->cache_frames) if (select->select && !select->cache_frames)
ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); return ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir);
return 0;
} }
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
SelectContext *select = inlink->dst->priv; SelectContext *select = inlink->dst->priv;
if (select->select) { if (select->select) {
if (select->cache_frames) if (select->cache_frames)
return; return 0;
ff_end_frame(inlink->dst->outputs[0]); return ff_end_frame(inlink->dst->outputs[0]);
} }
return 0;
} }
static int request_frame(AVFilterLink *outlink) static int request_frame(AVFilterLink *outlink)
@ -317,12 +325,14 @@ static int request_frame(AVFilterLink *outlink)
if (av_fifo_size(select->pending_frames)) { if (av_fifo_size(select->pending_frames)) {
AVFilterBufferRef *picref; AVFilterBufferRef *picref;
int ret;
av_fifo_generic_read(select->pending_frames, &picref, sizeof(picref), NULL); av_fifo_generic_read(select->pending_frames, &picref, sizeof(picref), NULL);
ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0)); if ((ret = ff_start_frame(outlink, picref)) < 0 ||
ff_draw_slice(outlink, 0, outlink->h, 1); (ret = ff_draw_slice(outlink, 0, outlink->h, 1)) < 0 ||
ff_end_frame(outlink); (ret = ff_end_frame(outlink)) < 0);
avfilter_unref_buffer(picref);
return 0; return ret;
} }
while (!select->select) { while (!select->select) {

View File

@ -69,7 +69,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
return 0; return 0;
} }
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
{ {
SetFieldContext *setfield = inlink->dst->priv; SetFieldContext *setfield = inlink->dst->priv;
AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0); AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0);
@ -80,7 +80,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
outpicref->video->interlaced = 1; outpicref->video->interlaced = 1;
outpicref->video->top_field_first = setfield->mode; outpicref->video->top_field_first = setfield->mode;
} }
ff_start_frame(inlink->dst->outputs[0], outpicref); return ff_start_frame(inlink->dst->outputs[0], outpicref);
} }
AVFilter avfilter_vf_setfield = { AVFilter avfilter_vf_setfield = {

View File

@ -92,12 +92,15 @@ static int config_input(AVFilterLink *inlink)
#define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d)) #define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d))
#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) #define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
{ {
SetPTSContext *setpts = inlink->dst->priv; SetPTSContext *setpts = inlink->dst->priv;
double d; double d;
AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0); AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0);
if (!outpicref)
return AVERROR(ENOMEM);
if (isnan(setpts->var_values[VAR_STARTPTS])) if (isnan(setpts->var_values[VAR_STARTPTS]))
setpts->var_values[VAR_STARTPTS] = TS2D(inpicref->pts); setpts->var_values[VAR_STARTPTS] = TS2D(inpicref->pts);
@ -121,7 +124,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
setpts->var_values[VAR_N] += 1.0; setpts->var_values[VAR_N] += 1.0;
setpts->var_values[VAR_PREV_INPTS ] = TS2D(inpicref ->pts); setpts->var_values[VAR_PREV_INPTS ] = TS2D(inpicref ->pts);
setpts->var_values[VAR_PREV_OUTPTS] = TS2D(outpicref->pts); setpts->var_values[VAR_PREV_OUTPTS] = TS2D(outpicref->pts);
ff_start_frame(inlink->dst->outputs[0], outpicref); return ff_start_frame(inlink->dst->outputs[0], outpicref);
} }
static av_cold void uninit(AVFilterContext *ctx) static av_cold void uninit(AVFilterContext *ctx)

View File

@ -41,7 +41,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
return 0; return 0;
} }
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
ShowInfoContext *showinfo = ctx->priv; ShowInfoContext *showinfo = ctx->priv;
@ -81,7 +81,7 @@ static void end_frame(AVFilterLink *inlink)
av_log(ctx, AV_LOG_INFO, "]\n"); av_log(ctx, AV_LOG_INFO, "]\n");
showinfo->frame++; showinfo->frame++;
ff_end_frame(inlink->dst->outputs[0]); return ff_end_frame(inlink->dst->outputs[0]);
} }
AVFilter avfilter_vf_showinfo = { AVFilter avfilter_vf_showinfo = {

View File

@ -59,7 +59,7 @@ static int config_props(AVFilterLink *link)
return 0; return 0;
} }
static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
{ {
SliceContext *slice = link->dst->priv; SliceContext *slice = link->dst->priv;
@ -75,27 +75,34 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
av_log(link->dst, AV_LOG_DEBUG, "h:%d\n", slice->h); av_log(link->dst, AV_LOG_DEBUG, "h:%d\n", slice->h);
link->cur_buf = NULL; link->cur_buf = NULL;
ff_start_frame(link->dst->outputs[0], picref); return ff_start_frame(link->dst->outputs[0], picref);
} }
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)
{ {
SliceContext *slice = link->dst->priv; SliceContext *slice = link->dst->priv;
int y2; int y2, ret = 0;
if (slice_dir == 1) { if (slice_dir == 1) {
for (y2 = y; y2 + slice->h <= y + h; y2 += slice->h) for (y2 = y; y2 + slice->h <= y + h; y2 += slice->h) {
ff_draw_slice(link->dst->outputs[0], y2, slice->h, slice_dir); ret = ff_draw_slice(link->dst->outputs[0], y2, slice->h, slice_dir);
if (ret < 0)
return ret;
}
if (y2 < y + h) if (y2 < y + h)
ff_draw_slice(link->dst->outputs[0], y2, y + h - y2, slice_dir); return ff_draw_slice(link->dst->outputs[0], y2, y + h - y2, slice_dir);
} else if (slice_dir == -1) { } else if (slice_dir == -1) {
for (y2 = y + h; y2 - slice->h >= y; y2 -= slice->h) for (y2 = y + h; y2 - slice->h >= y; y2 -= slice->h) {
ff_draw_slice(link->dst->outputs[0], y2 - slice->h, slice->h, slice_dir); ret = ff_draw_slice(link->dst->outputs[0], y2 - slice->h, slice->h, slice_dir);
if (ret < 0)
return ret;
}
if (y2 > y) if (y2 > y)
ff_draw_slice(link->dst->outputs[0], y, y2 - y, slice_dir); return ff_draw_slice(link->dst->outputs[0], y, y2 - y, slice_dir);
} }
return 0;
} }
AVFilter avfilter_vf_slicify = { AVFilter avfilter_vf_slicify = {

View File

@ -302,9 +302,9 @@ static int config_output(AVFilterLink *outlink)
return 0; return 0;
} }
static void null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { } static int null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { return 0; }
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
AVFilterLink *outlink = inlink->dst->outputs[0]; AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *inpicref = inlink->cur_buf; AVFilterBufferRef *inpicref = inlink->cur_buf;
@ -315,7 +315,7 @@ static void end_frame(AVFilterLink *inlink)
inlink->w, inlink->h); inlink->w, inlink->h);
ff_draw_slice(outlink, 0, outlink->h, 1); ff_draw_slice(outlink, 0, outlink->h, 1);
ff_end_frame(outlink); return ff_end_frame(outlink);
} }
AVFilter avfilter_vf_super2xsai = { AVFilter avfilter_vf_super2xsai = {

View File

@ -46,7 +46,7 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms,
return picref; return picref;
} }
static void start_frame(AVFilterLink *link, AVFilterBufferRef *inpicref) static int start_frame(AVFilterLink *link, AVFilterBufferRef *inpicref)
{ {
AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0); AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0);
@ -56,7 +56,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *inpicref)
outpicref->linesize[1] = inpicref->linesize[2]; outpicref->linesize[1] = inpicref->linesize[2];
outpicref->linesize[2] = inpicref->linesize[1]; outpicref->linesize[2] = inpicref->linesize[1];
ff_start_frame(link->dst->outputs[0], outpicref); return ff_start_frame(link->dst->outputs[0], outpicref);
} }
static int query_formats(AVFilterContext *ctx) static int query_formats(AVFilterContext *ctx)

View File

@ -68,7 +68,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
return 0; return 0;
} }
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
{ {
int i, j; int i, j;
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
@ -86,6 +86,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
} }
p += picref->linesize[0]; p += picref->linesize[0];
} }
return 0;
} }
/** /**
@ -106,7 +107,7 @@ static double frame_sum_square_err(const int *hist, const double *median)
return sum_sq_err; return sum_sq_err;
} }
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
int i, j, best_frame_idx = 0; int i, j, best_frame_idx = 0;
double avg_hist[HIST_SIZE] = {0}, sq_err, min_sq_err = -1; double avg_hist[HIST_SIZE] = {0}, sq_err, min_sq_err = -1;
@ -122,7 +123,7 @@ static void end_frame(AVFilterLink *inlink)
// no selection until the buffer of N frames is filled up // no selection until the buffer of N frames is filled up
if (thumb->n < thumb->n_frames - 1) { if (thumb->n < thumb->n_frames - 1) {
thumb->n++; thumb->n++;
return; return 0;
} }
// average histogram of the N frames // average histogram of the N frames
@ -156,7 +157,7 @@ static void end_frame(AVFilterLink *inlink)
ff_start_frame(outlink, picref); ff_start_frame(outlink, picref);
thumb->frames[best_frame_idx].buf = NULL; thumb->frames[best_frame_idx].buf = NULL;
ff_draw_slice(outlink, 0, inlink->h, 1); ff_draw_slice(outlink, 0, inlink->h, 1);
ff_end_frame(outlink); return ff_end_frame(outlink);
} }
static av_cold void uninit(AVFilterContext *ctx) static av_cold void uninit(AVFilterContext *ctx)
@ -170,7 +171,7 @@ static av_cold void uninit(AVFilterContext *ctx)
av_freep(&thumb->frames); av_freep(&thumb->frames);
} }
static void null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) { } static int null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) { return 0; }
static int request_frame(AVFilterLink *link) static int request_frame(AVFilterLink *link)
{ {

View File

@ -96,23 +96,23 @@ static int config_props(AVFilterLink *outlink)
* buffers are fed to start_frame in the order they were obtained from * buffers are fed to start_frame in the order they were obtained from
* get_buffer (think B-frames). */ * get_buffer (think B-frames). */
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
TileContext *tile = ctx->priv; TileContext *tile = ctx->priv;
AVFilterLink *outlink = ctx->outputs[0]; AVFilterLink *outlink = ctx->outputs[0];
if (tile->current) if (tile->current)
return; return 0;
outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE,
outlink->w, outlink->h); outlink->w, outlink->h);
avfilter_copy_buffer_ref_props(outlink->out_buf, picref); avfilter_copy_buffer_ref_props(outlink->out_buf, picref);
outlink->out_buf->video->w = outlink->w; outlink->out_buf->video->w = outlink->w;
outlink->out_buf->video->h = outlink->h; outlink->out_buf->video->h = outlink->h;
ff_start_frame(outlink, outlink->out_buf); return ff_start_frame(outlink, outlink->out_buf);
} }
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
TileContext *tile = ctx->priv; TileContext *tile = ctx->priv;
@ -126,6 +126,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
x0, y0 + y, 0, y, inlink->cur_buf->video->w, h); x0, y0 + y, 0, y, inlink->cur_buf->video->w, h);
/* TODO if tile->w == 1 && slice_dir is always 1, we could draw_slice /* TODO if tile->w == 1 && slice_dir is always 1, we could draw_slice
* immediately. */ * immediately. */
return 0;
} }
static void draw_blank_frame(AVFilterContext *ctx) static void draw_blank_frame(AVFilterContext *ctx)
@ -153,14 +154,15 @@ static void end_last_frame(AVFilterContext *ctx)
tile->current = 0; tile->current = 0;
} }
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
TileContext *tile = ctx->priv; TileContext *tile = ctx->priv;
avfilter_unref_buffer(inlink->cur_buf); avfilter_unref_bufferp(&inlink->cur_buf);
if (++tile->current == tile->w * tile->h) if (++tile->current == tile->w * tile->h)
end_last_frame(ctx); end_last_frame(ctx);
return 0;
} }
static int request_frame(AVFilterLink *outlink) static int request_frame(AVFilterLink *outlink)

View File

@ -198,7 +198,7 @@ void copy_picture_field(uint8_t *dst[4], int dst_linesize[4],
} }
} }
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
TInterlaceContext *tinterlace = ctx->priv; TInterlaceContext *tinterlace = ctx->priv;
@ -206,9 +206,10 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
avfilter_unref_buffer(tinterlace->cur); avfilter_unref_buffer(tinterlace->cur);
tinterlace->cur = tinterlace->next; tinterlace->cur = tinterlace->next;
tinterlace->next = picref; tinterlace->next = picref;
return 0;
} }
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
AVFilterLink *outlink = ctx->outputs[0]; AVFilterLink *outlink = ctx->outputs[0];
@ -220,7 +221,7 @@ static void end_frame(AVFilterLink *inlink)
/* we need at least two frames */ /* we need at least two frames */
if (!tinterlace->cur) if (!tinterlace->cur)
return; return 0;
switch (tinterlace->mode) { switch (tinterlace->mode) {
case MODE_MERGE: /* move the odd frame into the upper field of the new image, even into case MODE_MERGE: /* move the odd frame into the upper field of the new image, even into
@ -324,6 +325,8 @@ static void end_frame(AVFilterLink *inlink)
ff_end_frame(outlink); ff_end_frame(outlink);
tinterlace->frame++; tinterlace->frame++;
return 0;
} }
static int poll_frame(AVFilterLink *outlink) static int poll_frame(AVFilterLink *outlink)
@ -359,7 +362,7 @@ static int request_frame(AVFilterLink *outlink)
return 0; return 0;
} }
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { return 0; }
AVFilter avfilter_vf_tinterlace = { AVFilter avfilter_vf_tinterlace = {
.name = "tinterlace", .name = "tinterlace",

View File

@ -114,12 +114,16 @@ static int config_props_output(AVFilterLink *outlink)
return 0; return 0;
} }
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
{ {
AVFilterLink *outlink = inlink->dst->outputs[0]; AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *buf_out;
outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE,
outlink->w, outlink->h); outlink->w, outlink->h);
if (!outlink->out_buf)
return AVERROR(ENOMEM);
outlink->out_buf->pts = picref->pts; outlink->out_buf->pts = picref->pts;
if (picref->video->sample_aspect_ratio.num == 0) { if (picref->video->sample_aspect_ratio.num == 0) {
@ -129,16 +133,19 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
outlink->out_buf->video->sample_aspect_ratio.den = picref->video->sample_aspect_ratio.num; outlink->out_buf->video->sample_aspect_ratio.den = picref->video->sample_aspect_ratio.num;
} }
ff_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0)); buf_out = avfilter_ref_buffer(outlink->out_buf, ~0);
if (!buf_out)
return AVERROR(ENOMEM);
return ff_start_frame(outlink, buf_out);
} }
static void end_frame(AVFilterLink *inlink) static int end_frame(AVFilterLink *inlink)
{ {
TransContext *trans = inlink->dst->priv; TransContext *trans = inlink->dst->priv;
AVFilterBufferRef *inpic = inlink->cur_buf; AVFilterBufferRef *inpic = inlink->cur_buf;
AVFilterBufferRef *outpic = inlink->dst->outputs[0]->out_buf; AVFilterBufferRef *outpic = inlink->dst->outputs[0]->out_buf;
AVFilterLink *outlink = inlink->dst->outputs[0]; AVFilterLink *outlink = inlink->dst->outputs[0];
int plane; int plane, ret;
for (plane = 0; outpic->data[plane]; plane++) { for (plane = 0; outpic->data[plane]; plane++) {
int hsub = plane == 1 || plane == 2 ? trans->hsub : 0; int hsub = plane == 1 || plane == 2 ? trans->hsub : 0;
@ -189,11 +196,13 @@ static void end_frame(AVFilterLink *inlink)
} }
} }
ff_draw_slice(outlink, 0, outpic->video->h, 1); if ((ret = ff_draw_slice(outlink, 0, outpic->video->h, 1)) < 0 ||
ff_end_frame(outlink); (ret = ff_end_frame(outlink)) < 0)
return ret;
return 0;
} }
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { return 0; }
AVFilter avfilter_vf_transpose = { AVFilter avfilter_vf_transpose = {
.name = "transpose", .name = "transpose",

View File

@ -213,24 +213,28 @@ static av_cold void uninit(AVFilterContext *ctx)
free_filter_param(&unsharp->chroma); free_filter_param(&unsharp->chroma);
} }
static void end_frame(AVFilterLink *link) static int end_frame(AVFilterLink *link)
{ {
UnsharpContext *unsharp = link->dst->priv; UnsharpContext *unsharp = link->dst->priv;
AVFilterBufferRef *in = link->cur_buf; AVFilterBufferRef *in = link->cur_buf;
AVFilterBufferRef *out = link->dst->outputs[0]->out_buf; AVFilterBufferRef *out = link->dst->outputs[0]->out_buf;
int cw = SHIFTUP(link->w, unsharp->hsub); int cw = SHIFTUP(link->w, unsharp->hsub);
int ch = SHIFTUP(link->h, unsharp->vsub); int ch = SHIFTUP(link->h, unsharp->vsub);
int ret;
apply_unsharp(out->data[0], out->linesize[0], in->data[0], in->linesize[0], link->w, link->h, &unsharp->luma); apply_unsharp(out->data[0], out->linesize[0], in->data[0], in->linesize[0], link->w, link->h, &unsharp->luma);
apply_unsharp(out->data[1], out->linesize[1], in->data[1], in->linesize[1], cw, ch, &unsharp->chroma); apply_unsharp(out->data[1], out->linesize[1], in->data[1], in->linesize[1], cw, ch, &unsharp->chroma);
apply_unsharp(out->data[2], out->linesize[2], in->data[2], in->linesize[2], cw, ch, &unsharp->chroma); apply_unsharp(out->data[2], out->linesize[2], in->data[2], in->linesize[2], cw, ch, &unsharp->chroma);
ff_draw_slice(link->dst->outputs[0], 0, link->h, 1); if ((ret = ff_draw_slice(link->dst->outputs[0], 0, link->h, 1)) < 0 ||
ff_end_frame(link->dst->outputs[0]); (ret = ff_end_frame(link->dst->outputs[0])) < 0)
return ret;
return 0;
} }
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)
{ {
return 0;
} }
AVFilter avfilter_vf_unsharp = { AVFilter avfilter_vf_unsharp = {

View File

@ -52,6 +52,9 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms,
return ff_default_get_video_buffer(link, perms, w, h); return ff_default_get_video_buffer(link, perms, w, h);
picref = ff_get_video_buffer(link->dst->outputs[0], perms, w, h); picref = ff_get_video_buffer(link->dst->outputs[0], perms, w, h);
if (!picref)
return NULL;
for (i = 0; i < 4; i ++) { for (i = 0; i < 4; i ++) {
int vsub = i == 1 || i == 2 ? flip->vsub : 0; int vsub = i == 1 || i == 2 ? flip->vsub : 0;
@ -64,12 +67,15 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms,
return picref; return picref;
} }
static void start_frame(AVFilterLink *link, AVFilterBufferRef *inpicref) static int start_frame(AVFilterLink *link, AVFilterBufferRef *inpicref)
{ {
FlipContext *flip = link->dst->priv; FlipContext *flip = link->dst->priv;
AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0); AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0);
int i; int i;
if (!outpicref)
return AVERROR(ENOMEM);
for (i = 0; i < 4; i ++) { for (i = 0; i < 4; i ++) {
int vsub = i == 1 || i == 2 ? flip->vsub : 0; int vsub = i == 1 || i == 2 ? flip->vsub : 0;
@ -79,14 +85,14 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *inpicref)
} }
} }
ff_start_frame(link->dst->outputs[0], outpicref); return ff_start_frame(link->dst->outputs[0], outpicref);
} }
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)
{ {
AVFilterContext *ctx = link->dst; AVFilterContext *ctx = link->dst;
ff_draw_slice(ctx->outputs[0], link->h - (y+h), h, -1 * slice_dir); return ff_draw_slice(ctx->outputs[0], link->h - (y+h), h, -1 * slice_dir);
} }
AVFilter avfilter_vf_vflip = { AVFilter avfilter_vf_vflip = {

View File

@ -156,11 +156,11 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms, int w,
return picref; return picref;
} }
static void return_frame(AVFilterContext *ctx, int is_second) static int return_frame(AVFilterContext *ctx, int is_second)
{ {
YADIFContext *yadif = ctx->priv; YADIFContext *yadif = ctx->priv;
AVFilterLink *link= ctx->outputs[0]; AVFilterLink *link= ctx->outputs[0];
int tff; int tff, ret;
if (yadif->parity == -1) { if (yadif->parity == -1) {
tff = yadif->cur->video->interlaced ? tff = yadif->cur->video->interlaced ?
@ -172,6 +172,9 @@ static void return_frame(AVFilterContext *ctx, int is_second)
if (is_second) { if (is_second) {
yadif->out = ff_get_video_buffer(link, AV_PERM_WRITE | AV_PERM_PRESERVE | yadif->out = ff_get_video_buffer(link, AV_PERM_WRITE | AV_PERM_PRESERVE |
AV_PERM_REUSE, link->w, link->h); AV_PERM_REUSE, link->w, link->h);
if (!yadif->out)
return AVERROR(ENOMEM);
avfilter_copy_buffer_ref_props(yadif->out, yadif->cur); avfilter_copy_buffer_ref_props(yadif->out, yadif->cur);
yadif->out->video->interlaced = 0; yadif->out->video->interlaced = 0;
} }
@ -192,15 +195,19 @@ static void return_frame(AVFilterContext *ctx, int is_second)
} else { } else {
yadif->out->pts = AV_NOPTS_VALUE; yadif->out->pts = AV_NOPTS_VALUE;
} }
ff_start_frame(ctx->outputs[0], yadif->out); ret = ff_start_frame(ctx->outputs[0], yadif->out);
if (ret < 0)
return ret;
} }
ff_draw_slice(ctx->outputs[0], 0, link->h, 1); if ((ret = ff_draw_slice(ctx->outputs[0], 0, link->h, 1)) < 0 ||
ff_end_frame(ctx->outputs[0]); (ret = ff_end_frame(ctx->outputs[0])) < 0)
return ret;
yadif->frame_pending = (yadif->mode&1) && !is_second; yadif->frame_pending = (yadif->mode&1) && !is_second;
return 0;
} }
static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
{ {
AVFilterContext *ctx = link->dst; AVFilterContext *ctx = link->dst;
YADIFContext *yadif = ctx->priv; YADIFContext *yadif = ctx->priv;
@ -217,46 +224,52 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
yadif->next = picref; yadif->next = picref;
if (!yadif->cur) if (!yadif->cur)
return; return 0;
if (yadif->auto_enable && !yadif->cur->video->interlaced) { if (yadif->auto_enable && !yadif->cur->video->interlaced) {
yadif->out = avfilter_ref_buffer(yadif->cur, AV_PERM_READ); yadif->out = avfilter_ref_buffer(yadif->cur, AV_PERM_READ);
avfilter_unref_buffer(yadif->prev); if (!yadif->out)
yadif->prev = NULL; return AVERROR(ENOMEM);
avfilter_unref_bufferp(&yadif->prev);
if (yadif->out->pts != AV_NOPTS_VALUE) if (yadif->out->pts != AV_NOPTS_VALUE)
yadif->out->pts *= 2; yadif->out->pts *= 2;
ff_start_frame(ctx->outputs[0], yadif->out); return ff_start_frame(ctx->outputs[0], yadif->out);
return;
} }
if (!yadif->prev) if (!yadif->prev &&
yadif->prev = avfilter_ref_buffer(yadif->cur, AV_PERM_READ); !(yadif->prev = avfilter_ref_buffer(yadif->cur, AV_PERM_READ)))
return AVERROR(ENOMEM);
yadif->out = ff_get_video_buffer(ctx->outputs[0], AV_PERM_WRITE | AV_PERM_PRESERVE | yadif->out = ff_get_video_buffer(ctx->outputs[0], AV_PERM_WRITE | AV_PERM_PRESERVE |
AV_PERM_REUSE, link->w, link->h); AV_PERM_REUSE, link->w, link->h);
if (!yadif->out)
return AVERROR(ENOMEM);
avfilter_copy_buffer_ref_props(yadif->out, yadif->cur); avfilter_copy_buffer_ref_props(yadif->out, yadif->cur);
yadif->out->video->interlaced = 0; yadif->out->video->interlaced = 0;
if (yadif->out->pts != AV_NOPTS_VALUE) if (yadif->out->pts != AV_NOPTS_VALUE)
yadif->out->pts *= 2; yadif->out->pts *= 2;
ff_start_frame(ctx->outputs[0], yadif->out); return ff_start_frame(ctx->outputs[0], yadif->out);
} }
static void end_frame(AVFilterLink *link) static int end_frame(AVFilterLink *link)
{ {
AVFilterContext *ctx = link->dst; AVFilterContext *ctx = link->dst;
YADIFContext *yadif = ctx->priv; YADIFContext *yadif = ctx->priv;
if (!yadif->out) if (!yadif->out)
return; return 0;
if (yadif->auto_enable && !yadif->cur->video->interlaced) { if (yadif->auto_enable && !yadif->cur->video->interlaced) {
ff_draw_slice(ctx->outputs[0], 0, link->h, 1); int ret = ff_draw_slice(ctx->outputs[0], 0, link->h, 1);
ff_end_frame(ctx->outputs[0]); if (ret >= 0)
return; ret = ff_end_frame(ctx->outputs[0]);
return ret;
} }
return_frame(ctx, 0); return_frame(ctx, 0);
return 0;
} }
static int request_frame(AVFilterLink *link) static int request_frame(AVFilterLink *link)
@ -279,6 +292,9 @@ static int request_frame(AVFilterLink *link)
if (ret == AVERROR_EOF && yadif->cur) { if (ret == AVERROR_EOF && yadif->cur) {
AVFilterBufferRef *next = avfilter_ref_buffer(yadif->next, AV_PERM_READ); AVFilterBufferRef *next = avfilter_ref_buffer(yadif->next, AV_PERM_READ);
if (!next)
return AVERROR(ENOMEM);
next->pts = yadif->next->pts * 2 - yadif->cur->pts; next->pts = yadif->next->pts * 2 - yadif->cur->pts;
start_frame(link->src->inputs[0], next); start_frame(link->src->inputs[0], next);
@ -323,9 +339,9 @@ static av_cold void uninit(AVFilterContext *ctx)
{ {
YADIFContext *yadif = ctx->priv; YADIFContext *yadif = ctx->priv;
if (yadif->prev) avfilter_unref_buffer(yadif->prev); if (yadif->prev) avfilter_unref_bufferp(&yadif->prev);
if (yadif->cur ) avfilter_unref_buffer(yadif->cur ); if (yadif->cur ) avfilter_unref_bufferp(&yadif->cur );
if (yadif->next) avfilter_unref_buffer(yadif->next); if (yadif->next) avfilter_unref_bufferp(&yadif->next);
} }
static int query_formats(AVFilterContext *ctx) static int query_formats(AVFilterContext *ctx)
@ -381,7 +397,10 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
return 0; return 0;
} }
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
{
return 0;
}
static int config_props(AVFilterLink *link) static int config_props(AVFilterLink *link)
{ {

View File

@ -149,13 +149,15 @@ AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms, int w, int
return ret; return ret;
} }
void ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) int ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
{ {
AVFilterBufferRef *buf_out = avfilter_ref_buffer(picref, ~0); AVFilterBufferRef *buf_out = avfilter_ref_buffer(picref, ~0);
ff_start_frame(link->dst->outputs[0], buf_out); if (!buf_out)
return AVERROR(ENOMEM);
return ff_start_frame(link->dst->outputs[0], buf_out);
} }
static void default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) static int default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
{ {
AVFilterLink *outlink = NULL; AVFilterLink *outlink = NULL;
@ -163,21 +165,37 @@ static void default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
outlink = inlink->dst->outputs[0]; outlink = inlink->dst->outputs[0];
if (outlink) { if (outlink) {
AVFilterBufferRef *buf_out;
outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
if (!outlink->out_buf)
return AVERROR(ENOMEM);
avfilter_copy_buffer_ref_props(outlink->out_buf, picref); avfilter_copy_buffer_ref_props(outlink->out_buf, picref);
outlink->out_buf->video->w = outlink->w; outlink->out_buf->video->w = outlink->w;
outlink->out_buf->video->h = outlink->h; outlink->out_buf->video->h = outlink->h;
ff_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0)); buf_out = avfilter_ref_buffer(outlink->out_buf, ~0);
if (!buf_out)
return AVERROR(ENOMEM);
return ff_start_frame(outlink, buf_out);
} }
return 0;
}
static void clear_link(AVFilterLink *link)
{
avfilter_unref_bufferp(&link->cur_buf);
avfilter_unref_bufferp(&link->src_buf);
avfilter_unref_bufferp(&link->out_buf);
} }
/* XXX: should we do the duplicating of the picture ref here, instead of /* XXX: should we do the duplicating of the picture ref here, instead of
* forcing the source filter to do it? */ * forcing the source filter to do it? */
void ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
{ {
void (*start_frame)(AVFilterLink *, AVFilterBufferRef *); int (*start_frame)(AVFilterLink *, AVFilterBufferRef *);
AVFilterPad *dst = link->dstpad; AVFilterPad *dst = link->dstpad;
int perms = picref->perms; int ret, perms = picref->perms;
AVFilterCommand *cmd= link->dst->command_queue; AVFilterCommand *cmd= link->dst->command_queue;
int64_t pts; int64_t pts;
@ -196,6 +214,11 @@ void ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
link->dstpad->min_perms, link->dstpad->rej_perms); link->dstpad->min_perms, link->dstpad->rej_perms);
link->cur_buf = ff_get_video_buffer(link, dst->min_perms, link->w, link->h); link->cur_buf = ff_get_video_buffer(link, dst->min_perms, link->w, link->h);
if (!link->cur_buf) {
avfilter_unref_bufferp(&picref);
return AVERROR(ENOMEM);
}
link->src_buf = picref; link->src_buf = picref;
avfilter_copy_buffer_ref_props(link->cur_buf, link->src_buf); avfilter_copy_buffer_ref_props(link->cur_buf, link->src_buf);
@ -215,22 +238,26 @@ void ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
cmd= link->dst->command_queue; cmd= link->dst->command_queue;
} }
pts = link->cur_buf->pts; pts = link->cur_buf->pts;
start_frame(link, link->cur_buf); ret = start_frame(link, link->cur_buf);
ff_update_link_current_pts(link,link->cur_buf ? link->cur_buf->pts : pts); ff_update_link_current_pts(link,link->cur_buf ? link->cur_buf->pts : pts);
if (ret < 0)
clear_link(link);
return ret;
} }
void ff_null_start_frame_keep_ref(AVFilterLink *inlink, int ff_null_start_frame_keep_ref(AVFilterLink *inlink,
AVFilterBufferRef *picref) AVFilterBufferRef *picref)
{ {
ff_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(picref, ~0)); return ff_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(picref, ~0));
} }
void ff_null_end_frame(AVFilterLink *link) int ff_null_end_frame(AVFilterLink *link)
{ {
ff_end_frame(link->dst->outputs[0]); return ff_end_frame(link->dst->outputs[0]);
} }
static void default_end_frame(AVFilterLink *inlink) static int default_end_frame(AVFilterLink *inlink)
{ {
AVFilterLink *outlink = NULL; AVFilterLink *outlink = NULL;
@ -238,37 +265,32 @@ static void default_end_frame(AVFilterLink *inlink)
outlink = inlink->dst->outputs[0]; outlink = inlink->dst->outputs[0];
if (outlink) { if (outlink) {
ff_end_frame(outlink); return ff_end_frame(outlink);
} }
return 0;
} }
void ff_end_frame(AVFilterLink *link) int ff_end_frame(AVFilterLink *link)
{ {
void (*end_frame)(AVFilterLink *); int (*end_frame)(AVFilterLink *);
int ret;
if (!(end_frame = link->dstpad->end_frame)) if (!(end_frame = link->dstpad->end_frame))
end_frame = default_end_frame; end_frame = default_end_frame;
end_frame(link); ret = end_frame(link);
/* unreference the source picture if we're feeding the destination filter clear_link(link);
* a copied version dues to permission issues */
if (link->src_buf) { return ret;
avfilter_unref_buffer(link->src_buf);
link->src_buf = NULL;
}
if(link->cur_buf != link->out_buf)
avfilter_unref_bufferp(&link->cur_buf);
link->cur_buf = NULL;
avfilter_unref_bufferp(&link->out_buf);
} }
void ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) int ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
{ {
ff_draw_slice(link->dst->outputs[0], y, h, slice_dir); return ff_draw_slice(link->dst->outputs[0], y, h, slice_dir);
} }
static void default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) static int default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
{ {
AVFilterLink *outlink = NULL; AVFilterLink *outlink = NULL;
@ -276,14 +298,15 @@ static void default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir
outlink = inlink->dst->outputs[0]; outlink = inlink->dst->outputs[0];
if (outlink) if (outlink)
ff_draw_slice(outlink, y, h, slice_dir); return ff_draw_slice(outlink, y, h, slice_dir);
return 0;
} }
void ff_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) int ff_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
{ {
uint8_t *src[4], *dst[4]; uint8_t *src[4], *dst[4];
int i, j, vsub; int i, j, vsub, ret;
void (*draw_slice)(AVFilterLink *, int, int, int); int (*draw_slice)(AVFilterLink *, int, int, int);
FF_TPRINTF_START(NULL, draw_slice); ff_tlog_link(NULL, link, 0); ff_tlog(NULL, " y:%d h:%d dir:%d\n", y, h, slice_dir); FF_TPRINTF_START(NULL, draw_slice); ff_tlog_link(NULL, link, 0); ff_tlog(NULL, " y:%d h:%d dir:%d\n", y, h, slice_dir);
@ -317,11 +340,14 @@ void ff_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
if (!(draw_slice = link->dstpad->draw_slice)) if (!(draw_slice = link->dstpad->draw_slice))
draw_slice = default_draw_slice; draw_slice = default_draw_slice;
draw_slice(link, y, h, slice_dir); ret = draw_slice(link, y, h, slice_dir);
if (ret < 0)
clear_link(link);
return ret;
} }
void avfilter_default_end_frame(AVFilterLink *inlink) int avfilter_default_end_frame(AVFilterLink *inlink)
{ {
default_end_frame(inlink); return default_end_frame(inlink);
} }

View File

@ -42,9 +42,9 @@ AVFilterBufferRef *ff_null_get_video_buffer(AVFilterLink *link, int perms, int w
AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms, AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms,
int w, int h); int w, int h);
void ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref); int ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref);
void ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir); int ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir);
void ff_null_end_frame(AVFilterLink *link); int ff_null_end_frame(AVFilterLink *link);
/** /**
* Notify the next filter of the start of a frame. * Notify the next filter of the start of a frame.
@ -54,20 +54,25 @@ void ff_null_end_frame(AVFilterLink *link);
* frame need only be valid once draw_slice() is called for that * frame need only be valid once draw_slice() is called for that
* portion. The receiving filter will free this reference when * portion. The receiving filter will free this reference when
* it no longer needs it. * it no longer needs it.
*
* @return >= 0 on success, a negative AVERROR on error. This function will
* unreference picref in case of error.
*/ */
void ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref); int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref);
/** /**
* Pass video frame along and keep an internal reference for later use. * Pass video frame along and keep an internal reference for later use.
*/ */
void ff_null_start_frame_keep_ref(AVFilterLink *inlink, AVFilterBufferRef *picref); int ff_null_start_frame_keep_ref(AVFilterLink *inlink, AVFilterBufferRef *picref);
/** /**
* Notify the next filter that the current frame has finished. * Notify the next filter that the current frame has finished.
* *
* @param link the output link the frame was sent over * @param link the output link the frame was sent over
*
* @return >= 0 on success, a negative AVERROR on error
*/ */
void ff_end_frame(AVFilterLink *link); int ff_end_frame(AVFilterLink *link);
/** /**
* Send a slice to the next filter. * Send a slice to the next filter.
@ -83,7 +88,9 @@ void ff_end_frame(AVFilterLink *link);
* from the top slice to the bottom slice if the value is 1, * from the top slice to the bottom slice if the value is 1,
* from the bottom slice to the top slice if the value is -1, * from the bottom slice to the top slice if the value is -1,
* for other values the behavior of the function is undefined. * for other values the behavior of the function is undefined.
*
* @return >= 0 on success, a negative AVERROR on error.
*/ */
void ff_draw_slice(AVFilterLink *link, int y, int h, int slice_dir); int ff_draw_slice(AVFilterLink *link, int y, int h, int slice_dir);
#endif /* AVFILTER_VIDEO_H */ #endif /* AVFILTER_VIDEO_H */

View File

@ -19,12 +19,14 @@
#include "avfilter.h" #include "avfilter.h"
#include "internal.h" #include "internal.h"
static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
{ {
return 0;
} }
static void end_frame(AVFilterLink *link) static int end_frame(AVFilterLink *link)
{ {
return 0;
} }
AVFilter avfilter_vsink_nullsink = { AVFilter avfilter_vsink_nullsink = {

View File

@ -149,18 +149,38 @@ static int color_request_frame(AVFilterLink *link)
{ {
ColorContext *color = link->src->priv; ColorContext *color = link->src->priv;
AVFilterBufferRef *picref = ff_get_video_buffer(link, AV_PERM_WRITE, color->w, color->h); AVFilterBufferRef *picref = ff_get_video_buffer(link, AV_PERM_WRITE, color->w, color->h);
AVFilterBufferRef *buf_out;
int ret;
if (!picref)
return AVERROR(ENOMEM);
picref->video->sample_aspect_ratio = (AVRational) {1, 1}; picref->video->sample_aspect_ratio = (AVRational) {1, 1};
picref->pts = color->pts++; picref->pts = color->pts++;
picref->pos = -1; picref->pos = -1;
ff_start_frame(link, avfilter_ref_buffer(picref, ~0)); buf_out = avfilter_ref_buffer(picref, ~0);
if (!buf_out) {
ret = AVERROR(ENOMEM);
goto fail;
}
ret = ff_start_frame(link, buf_out);
if (ret < 0)
goto fail;
ff_fill_rectangle(&color->draw, &color->color, picref->data, picref->linesize, ff_fill_rectangle(&color->draw, &color->color, picref->data, picref->linesize,
0, 0, color->w, color->h); 0, 0, color->w, color->h);
ff_draw_slice(link, 0, color->h, 1); ret = ff_draw_slice(link, 0, color->h, 1);
ff_end_frame(link); if (ret < 0)
goto fail;
ret = ff_end_frame(link);
fail:
avfilter_unref_buffer(picref); avfilter_unref_buffer(picref);
return 0; return ret;
} }
AVFilter avfilter_vsrc_color = { AVFilter avfilter_vsrc_color = {

View File

@ -134,10 +134,14 @@ static int request_frame(AVFilterLink *outlink)
{ {
TestSourceContext *test = outlink->src->priv; TestSourceContext *test = outlink->src->priv;
AVFilterBufferRef *picref; AVFilterBufferRef *picref;
int ret;
if (test->max_pts >= 0 && test->pts >= test->max_pts) if (test->max_pts >= 0 && test->pts >= test->max_pts)
return AVERROR_EOF; return AVERROR_EOF;
picref = ff_get_video_buffer(outlink, AV_PERM_WRITE, test->w, test->h); picref = ff_get_video_buffer(outlink, AV_PERM_WRITE, test->w, test->h);
if (!picref)
return AVERROR(ENOMEM);
picref->pts = test->pts++; picref->pts = test->pts++;
picref->pos = -1; picref->pos = -1;
picref->video->key_frame = 1; picref->video->key_frame = 1;
@ -147,9 +151,10 @@ static int request_frame(AVFilterLink *outlink)
test->fill_picture_fn(outlink->src, picref); test->fill_picture_fn(outlink->src, picref);
test->nb_frame++; test->nb_frame++;
ff_start_frame(outlink, picref); if ((ret = ff_start_frame(outlink, picref)) < 0 ||
ff_draw_slice(outlink, 0, test->h, 1); (ret = ff_draw_slice(outlink, 0, test->h, 1)) < 0 ||
ff_end_frame(outlink); (ret = ff_end_frame(outlink)) < 0)
return ret;
return 0; return 0;
} }

View File

@ -656,8 +656,9 @@ static int ebml_read_num(MatroskaDemuxContext *matroska, AVIOContext *pb,
av_log(matroska->ctx, AV_LOG_ERROR, av_log(matroska->ctx, AV_LOG_ERROR,
"Read error at pos. %"PRIu64" (0x%"PRIx64")\n", "Read error at pos. %"PRIu64" (0x%"PRIx64")\n",
pos, pos); pos, pos);
return pb->error ? pb->error : AVERROR(EIO);
} }
return AVERROR(EIO); /* EOS or actual I/O error */ return AVERROR_EOF;
} }
/* get the length of the EBML number */ /* get the length of the EBML number */

View File

@ -54,6 +54,7 @@ include $(SRC_PATH)/tests/fate/demux.mak
include $(SRC_PATH)/tests/fate/dfa.mak include $(SRC_PATH)/tests/fate/dfa.mak
include $(SRC_PATH)/tests/fate/dpcm.mak include $(SRC_PATH)/tests/fate/dpcm.mak
include $(SRC_PATH)/tests/fate/ea.mak include $(SRC_PATH)/tests/fate/ea.mak
include $(SRC_PATH)/tests/fate/filter.mak
include $(SRC_PATH)/tests/fate/flac.mak include $(SRC_PATH)/tests/fate/flac.mak
include $(SRC_PATH)/tests/fate/fft.mak include $(SRC_PATH)/tests/fate/fft.mak
include $(SRC_PATH)/tests/fate/h264.mak include $(SRC_PATH)/tests/fate/h264.mak

10
tests/fate/filter.mak Normal file
View File

@ -0,0 +1,10 @@
FATE_ASYNCTS += fate-filter-asyncts
fate-filter-asyncts: SRC = $(SAMPLES)/nellymoser/nellymoser-discont.flv
fate-filter-asyncts: CMD = pcm -i $(SRC) -af aresample=min_comp=0.001:min_hard_comp=0.1
fate-filter-asyncts: CMP = oneoff
fate-filter-asyncts: REF = $(SAMPLES)/nellymoser/nellymoser-discont.pcm
FATE_FILTER += $(FATE_ASYNCTS)
FATE_SAMPLES_AVCONV += $(FATE_ASYNCTS)
fate-filter: $(FATE_FILTER)