With this we can mix filters using filter_frame OR start/draw_slice/end Signed-off-by: Michael Niedermayer <michaelni@gmx.at>tags/n1.1
| @@ -162,7 +162,7 @@ static int default_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame) | |||
| return ff_filter_frame(link->dst->outputs[0], frame); | |||
| } | |||
| int ff_filter_frame_framed(AVFilterLink *link, AVFilterBufferRef *samplesref) | |||
| int ff_filter_samples_framed(AVFilterLink *link, AVFilterBufferRef *samplesref) | |||
| { | |||
| int (*filter_frame)(AVFilterLink *, AVFilterBufferRef *); | |||
| AVFilterPad *src = link->srcpad; | |||
| @@ -217,7 +217,7 @@ int ff_filter_frame_framed(AVFilterLink *link, AVFilterBufferRef *samplesref) | |||
| return ret; | |||
| } | |||
| int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *samplesref) | |||
| int ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref) | |||
| { | |||
| int insamples = samplesref->audio->nb_samples, inpos = 0, nb_samples; | |||
| AVFilterBufferRef *pbuf = link->partial_buf; | |||
| @@ -231,7 +231,7 @@ int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *samplesref) | |||
| if (!link->min_samples || | |||
| (!pbuf && | |||
| insamples >= link->min_samples && insamples <= link->max_samples)) { | |||
| return ff_filter_frame_framed(link, samplesref); | |||
| return ff_filter_samples_framed(link, samplesref); | |||
| } | |||
| /* Handle framing (min_samples, max_samples) */ | |||
| while (insamples) { | |||
| @@ -258,7 +258,7 @@ int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *samplesref) | |||
| insamples -= nb_samples; | |||
| pbuf->audio->nb_samples += nb_samples; | |||
| if (pbuf->audio->nb_samples >= link->min_samples) { | |||
| ret = ff_filter_frame_framed(link, pbuf); | |||
| ret = ff_filter_samples_framed(link, pbuf); | |||
| pbuf = NULL; | |||
| } | |||
| } | |||
| @@ -23,6 +23,7 @@ | |||
| #define AVFILTER_AUDIO_H | |||
| #include "avfilter.h" | |||
| #include "internal.h" | |||
| static const enum AVSampleFormat ff_packed_sample_fmts_array[] = { | |||
| AV_SAMPLE_FMT_U8, | |||
| @@ -74,13 +75,13 @@ AVFilterBufferRef *ff_get_audio_buffer(AVFilterLink *link, int perms, | |||
| * @return >= 0 on success, a negative AVERROR on error. The receiving filter | |||
| * is responsible for unreferencing samplesref in case of error. | |||
| */ | |||
| int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *samplesref); | |||
| int ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref); | |||
| /** | |||
| * Send a buffer of audio samples to the next link, without checking | |||
| * min_samples. | |||
| */ | |||
| int ff_filter_frame_framed(AVFilterLink *link, | |||
| AVFilterBufferRef *samplesref); | |||
| int ff_filter_samples_framed(AVFilterLink *link, | |||
| AVFilterBufferRef *samplesref); | |||
| #endif /* AVFILTER_AUDIO_H */ | |||
| @@ -343,7 +343,7 @@ int ff_request_frame(AVFilterLink *link) | |||
| if (ret == AVERROR_EOF && link->partial_buf) { | |||
| AVFilterBufferRef *pbuf = link->partial_buf; | |||
| link->partial_buf = NULL; | |||
| ff_filter_frame_framed(link, pbuf); | |||
| ff_filter_samples_framed(link, pbuf); | |||
| return 0; | |||
| } | |||
| if (ret == AVERROR_EOF) | |||
| @@ -631,3 +631,23 @@ enum AVMediaType avfilter_pad_get_type(AVFilterPad *pads, int pad_idx) | |||
| { | |||
| return pads[pad_idx].type; | |||
| } | |||
| int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame) | |||
| { | |||
| int ret; | |||
| FF_TPRINTF_START(NULL, filter_frame); ff_tlog_link(NULL, link, 1); ff_tlog(NULL, " "); ff_tlog_ref(NULL, frame, 1); | |||
| switch (link->type) { | |||
| case AVMEDIA_TYPE_VIDEO: | |||
| if((ret = ff_start_frame(link, frame)) < 0) | |||
| return ret; | |||
| if((ret = ff_draw_slice(link, 0, frame->video->h, 1)) < 0) | |||
| return ret; | |||
| if((ret = ff_end_frame(link)) < 0) | |||
| return ret; | |||
| return ret; | |||
| case AVMEDIA_TYPE_AUDIO: | |||
| return ff_filter_samples(link, frame); | |||
| default: return AVERROR(EINVAL); | |||
| } | |||
| } | |||
| @@ -368,5 +368,17 @@ AVFilterBufferRef *ff_copy_buffer_ref(AVFilterLink *outlink, | |||
| int ff_buffersink_read_compat(AVFilterContext *ctx, AVFilterBufferRef **buf); | |||
| int ff_buffersink_read_samples_compat(AVFilterContext *ctx, AVFilterBufferRef **pbuf, | |||
| int nb_samples); | |||
| /** | |||
| * Send a frame of data to the next filter. | |||
| * | |||
| * @param link the output link over which the data is being sent | |||
| * @param frame a reference to the buffer of data being sent. The | |||
| * receiving filter will free this reference when it no longer | |||
| * needs it or pass it on to the next filter. | |||
| * | |||
| * @return >= 0 on success, a negative AVERROR on error. The receiving filter | |||
| * is responsible for unreferencing frame in case of error. | |||
| */ | |||
| int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame); | |||
| #endif /* AVFILTER_INTERNAL_H */ | |||
| @@ -210,7 +210,7 @@ static int default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) | |||
| if (inlink->dst->nb_outputs) | |||
| outlink = inlink->dst->outputs[0]; | |||
| if (outlink) { | |||
| if (outlink && !inlink->dstpad->filter_frame) { | |||
| AVFilterBufferRef *buf_out; | |||
| outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); | |||
| if (!outlink->out_buf) | |||
| @@ -328,7 +328,13 @@ static int default_end_frame(AVFilterLink *inlink) | |||
| outlink = inlink->dst->outputs[0]; | |||
| if (outlink) { | |||
| return ff_end_frame(outlink); | |||
| if (inlink->dstpad->filter_frame) { | |||
| int ret = inlink->dstpad->filter_frame(inlink, inlink->cur_buf); | |||
| inlink->cur_buf = NULL; | |||
| return ret; | |||
| } else { | |||
| return ff_end_frame(outlink); | |||
| } | |||
| } | |||
| return 0; | |||
| } | |||
| @@ -360,7 +366,7 @@ static int default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) | |||
| if (inlink->dst->nb_outputs) | |||
| outlink = inlink->dst->outputs[0]; | |||
| if (outlink) | |||
| if (outlink && !inlink->dstpad->filter_frame) | |||
| return ff_draw_slice(outlink, y, h, slice_dir); | |||
| return 0; | |||
| } | |||