Any alleged performance benefits gained from the split are purely
mythological and do not justify added code complexity.
---
libavfilter/audio.c | 47 -----------
libavfilter/audio.h | 13 ---
libavfilter/avfilter.c | 62 ++++++++++++++
libavfilter/avfilter.h | 32 ++------
libavfilter/internal.h | 54 ++++---------
libavfilter/video.c | 210 ------------------------------------------------
libavfilter/video.h | 47 -----------
7 files changed, 86 insertions(+), 379 deletions(-)
diff --git a/libavfilter/audio.c b/libavfilter/audio.c
index 48e038b..bbe12b2 100644
--- a/libavfilter/audio.c
+++ b/libavfilter/audio.c
@@ -146,50 +146,3 @@ fail:
av_freep(&samples);
return NULL;
}
-
-static int default_filter_samples(AVFilterLink *link,
- AVFilterBufferRef *samplesref)
-{
- return ff_filter_samples(link->dst->outputs[0], samplesref);
-}
-
-int ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
-{
- int (*filter_samples)(AVFilterLink *, AVFilterBufferRef *);
- AVFilterPad *dst = link->dstpad;
- AVFilterBufferRef *buf_out;
-
- FF_DPRINTF_START(NULL, filter_samples); ff_dlog_link(NULL, link, 1);
-
- if (!(filter_samples = dst->filter_samples))
- filter_samples = default_filter_samples;
-
- /* prepare to copy the samples if the buffer has insufficient permissions
*/
- if ((dst->min_perms & samplesref->perms) != dst->min_perms ||
- dst->rej_perms & samplesref->perms) {
- av_log(link->dst, AV_LOG_DEBUG,
- "Copying audio data in avfilter (have perms %x, need %x, reject
%x)\n",
- samplesref->perms, link->dstpad->min_perms,
link->dstpad->rej_perms);
-
- buf_out = ff_default_get_audio_buffer(link, dst->min_perms,
- samplesref->audio->nb_samples);
- if (!buf_out) {
- avfilter_unref_buffer(samplesref);
- return AVERROR(ENOMEM);
- }
- buf_out->pts = samplesref->pts;
- buf_out->audio->sample_rate = samplesref->audio->sample_rate;
-
- /* Copy actual data into new samples buffer */
- av_samples_copy(buf_out->extended_data, samplesref->extended_data,
- 0, 0, samplesref->audio->nb_samples,
-
av_get_channel_layout_nb_channels(link->channel_layout),
- link->format);
-
- avfilter_unref_buffer(samplesref);
- } else
- buf_out = samplesref;
-
- return filter_samples(link, buf_out);
-}
-
diff --git a/libavfilter/audio.h b/libavfilter/audio.h
index fa448e2..a377503 100644
--- a/libavfilter/audio.h
+++ b/libavfilter/audio.h
@@ -42,17 +42,4 @@ AVFilterBufferRef *ff_null_get_audio_buffer(AVFilterLink
*link, int perms,
AVFilterBufferRef *ff_get_audio_buffer(AVFilterLink *link, int perms,
int nb_samples);
-/**
- * Send a buffer of audio samples to the next filter.
- *
- * @param link the output link over which the audio samples are being
sent
- * @param samplesref a reference to the buffer of audio samples 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 samplesref in case of error.
- */
-int ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref);
-
#endif /* AVFILTER_AUDIO_H */
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index c7db857..86288f8 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -23,12 +23,16 @@
#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
+#include "libavutil/imgutils.h"
#include "libavutil/pixdesc.h"
#include "libavutil/rational.h"
+#include "libavutil/samplefmt.h"
+#include "audio.h"
#include "avfilter.h"
#include "formats.h"
#include "internal.h"
+#include "video.h"
unsigned avfilter_version(void) {
return LIBAVFILTER_VERSION_INT;
@@ -446,3 +450,61 @@ enum AVMediaType avfilter_pad_get_type(AVFilterPad *pads,
int pad_idx)
{
return pads[pad_idx].type;
}
+
+static int default_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
+{
+ return ff_filter_frame(link->dst->outputs[0], frame);
+}
+
+int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
+{
+ int (*filter_frame)(AVFilterLink *, AVFilterBufferRef *);
+ AVFilterPad *dst = link->dstpad;
+ AVFilterBufferRef *out;
+ int perms = frame->perms;
+
+ FF_DPRINTF_START(NULL, filter_frame);
+ ff_dlog_link(NULL, link, 1);
+
+ if (!(filter_frame = dst->filter_frame))
+ filter_frame = default_filter_frame;
+
+ if (frame->linesize[0] < 0)
+ perms |= AV_PERM_NEG_LINESIZES;
+ /* prepare to copy the frame if the buffer has insufficient permissions */
+ if ((dst->min_perms & perms) != dst->min_perms ||
+ dst->rej_perms & perms) {
+ av_log(link->dst, AV_LOG_DEBUG,
+ "Copying data in avfilter (have perms %x, need %x, reject
%x)\n",
+ perms, link->dstpad->min_perms, link->dstpad->rej_perms);
+
+ if (link->type == AVMEDIA_TYPE_VIDEO) {
+ out = ff_get_video_buffer(link, dst->min_perms,
+ link->w, link->h);
+ } else {
+ out = ff_get_audio_buffer(link, dst->min_perms,
+ frame->audio->nb_samples);
+ }
+ if (!out) {
+ avfilter_unref_buffer(frame);
+ return AVERROR(ENOMEM);
+ }
+ avfilter_copy_buffer_ref_props(out, frame);
+
+ if (link->type == AVMEDIA_TYPE_VIDEO) {
+ av_image_copy(out->data, out->linesize, frame->data,
frame->linesize,
+ frame->format, frame->video->w, frame->video->h);
+ } else {
+ av_samples_copy(out->extended_data, frame->extended_data,
+ 0, 0, frame->audio->nb_samples,
+
av_get_channel_layout_nb_channels(frame->audio->channel_layout),
+ frame->format);
+ }
+
+
+ avfilter_unref_buffer(frame);
+ } else
+ out = frame;
+
+ return filter_frame(link, out);
+}
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index 01d39b6..bc44f05 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -253,14 +253,7 @@ struct AVFilterPad {
int rej_perms;
/**
- * Callback called before passing the first slice of a new frame. If
- * NULL, the filter layer will default to storing a reference to the
- * picture inside the link structure.
- *
- * Input video pads only.
- *
- * @return >= 0 on success, a negative AVERROR on error. picref will be
- * unreferenced by the caller in case of error.
+ * @deprecated unused
*/
int (*start_frame)(AVFilterLink *link, AVFilterBufferRef *picref);
@@ -282,37 +275,26 @@ struct AVFilterPad {
int nb_samples);
/**
- * Callback called after the slices of a frame are completely sent. If
- * NULL, the filter layer will default to releasing the reference stored
- * in the link structure during start_frame().
- *
- * Input video pads only.
- *
- * @return >= 0 on success, a negative AVERROR on error.
+ * @deprecated unused
*/
int (*end_frame)(AVFilterLink *link);
/**
- * Slice drawing callback. This is where a filter receives video data
- * and should do its processing.
- *
- * Input video pads only.
- *
- * @return >= 0 on success, a negative AVERROR on error.
+ * @deprecated unused
*/
int (*draw_slice)(AVFilterLink *link, int y, int height, int slice_dir);
/**
- * Samples filtering callback. This is where a filter receives audio data
- * and should do its processing.
+ * Filtering callback. This is where a filter receives a frame with
+ * audio/video data and should do its processing.
*
- * Input audio pads only.
+ * Input pads only.
*
* @return >= 0 on success, a negative AVERROR on error. This function
* must ensure that samplesref is properly unreferenced on error if it
* hasn't been passed on to another filter.
*/
- int (*filter_samples)(AVFilterLink *link, AVFilterBufferRef *samplesref);
+ int (*filter_frame)(AVFilterLink *link, AVFilterBufferRef *frame);
/**
* Frame poll callback. This returns the number of immediately available
diff --git a/libavfilter/internal.h b/libavfilter/internal.h
index 6f868ae..216a355 100644
--- a/libavfilter/internal.h
+++ b/libavfilter/internal.h
@@ -64,18 +64,6 @@ struct AVFilterPad {
int rej_perms;
/**
- * Callback called before passing the first slice of a new frame. If
- * NULL, the filter layer will default to storing a reference to the
- * picture inside the link structure.
- *
- * 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);
-
- /**
* Callback function to get a video buffer. If NULL, the filter system will
* use avfilter_default_get_video_buffer().
*
@@ -93,37 +81,16 @@ struct AVFilterPad {
int nb_samples);
/**
- * Callback called after the slices of a frame are completely sent. If
- * NULL, the filter layer will default to releasing the reference stored
- * in the link structure during start_frame().
+ * Filtering callback. This is where a filter receives a frame with
+ * audio/video data and should do its processing.
*
- * Input video pads only.
- *
- * @return >= 0 on success, a negative AVERROR on error.
- */
- int (*end_frame)(AVFilterLink *link);
-
- /**
- * Slice drawing callback. This is where a filter receives video data
- * and should do its processing.
- *
- * Input video pads only.
- *
- * @return >= 0 on success, a negative AVERROR on error.
- */
- int (*draw_slice)(AVFilterLink *link, int y, int height, int slice_dir);
-
- /**
- * Samples filtering callback. This is where a filter receives audio data
- * and should do its processing.
- *
- * Input audio pads only.
+ * Input pads only.
*
* @return >= 0 on success, a negative AVERROR on error. This function
* must ensure that samplesref is properly unreferenced on error if it
* hasn't been passed on to another filter.
*/
- int (*filter_samples)(AVFilterLink *link, AVFilterBufferRef *samplesref);
+ int (*filter_frame)(AVFilterLink *link, AVFilterBufferRef *frame);
/**
* Frame poll callback. This returns the number of immediately available
@@ -237,4 +204,17 @@ int ff_poll_frame(AVFilterLink *link);
*/
int ff_request_frame(AVFilterLink *link);
+/**
+ * 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 */
diff --git a/libavfilter/video.c b/libavfilter/video.c
index 49091ad..cb68ca4 100644
--- a/libavfilter/video.c
+++ b/libavfilter/video.c
@@ -163,213 +163,3 @@ AVFilterBufferRef *ff_get_video_buffer(AVFilterLink
*link, int perms, int w, int
return ret;
}
-
-int ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
-{
- AVFilterBufferRef *buf_out = avfilter_ref_buffer(picref, ~0);
- if (!buf_out)
- return AVERROR(ENOMEM);
- return ff_start_frame(link->dst->outputs[0], buf_out);
-}
-
-// for filters that support (but don't require) outpic==inpic
-int ff_inplace_start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
-{
- AVFilterLink *outlink = inlink->dst->outputs[0];
- AVFilterBufferRef *outpicref = NULL, *for_next_filter;
- int ret = 0;
-
- if ((inpicref->perms & AV_PERM_WRITE) && !(inpicref->perms &
AV_PERM_PRESERVE)) {
- outpicref = avfilter_ref_buffer(inpicref, ~0);
- if (!outpicref)
- return AVERROR(ENOMEM);
- } else {
- 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);
- outpicref->video->w = outlink->w;
- outpicref->video->h = outlink->h;
- }
-
- 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 default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
-{
- AVFilterLink *outlink = NULL;
-
- if (inlink->dst->nb_outputs)
- outlink = inlink->dst->outputs[0];
-
- if (outlink) {
- AVFilterBufferRef *buf_out;
- 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);
- 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
- * forcing the source filter to do it? */
-int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
-{
- int (*start_frame)(AVFilterLink *, AVFilterBufferRef *);
- AVFilterPad *dst = link->dstpad;
- int ret, perms = picref->perms;
-
- FF_DPRINTF_START(NULL, start_frame); ff_dlog_link(NULL, link, 0);
av_dlog(NULL, " "); ff_dlog_ref(NULL, picref, 1);
-
- if (!(start_frame = dst->start_frame))
- start_frame = default_start_frame;
-
- if (picref->linesize[0] < 0)
- perms |= AV_PERM_NEG_LINESIZES;
- /* prepare to copy the picture if it has insufficient permissions */
- if ((dst->min_perms & perms) != dst->min_perms || dst->rej_perms & perms) {
- av_log(link->dst, AV_LOG_DEBUG,
- "frame copy needed (have perms %x, need %x, reject %x)\n",
- picref->perms,
- link->dstpad->min_perms, link->dstpad->rej_perms);
-
- 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;
- avfilter_copy_buffer_ref_props(link->cur_buf, link->src_buf);
- }
- else
- link->cur_buf = picref;
-
- ret = start_frame(link, link->cur_buf);
- if (ret < 0)
- clear_link(link);
-
- return ret;
-}
-
-int ff_null_end_frame(AVFilterLink *link)
-{
- return ff_end_frame(link->dst->outputs[0]);
-}
-
-static int default_end_frame(AVFilterLink *inlink)
-{
- AVFilterLink *outlink = NULL;
-
- if (inlink->dst->nb_outputs)
- outlink = inlink->dst->outputs[0];
-
- if (outlink) {
- return ff_end_frame(outlink);
- }
- return 0;
-}
-
-int ff_end_frame(AVFilterLink *link)
-{
- int (*end_frame)(AVFilterLink *);
- int ret;
-
- if (!(end_frame = link->dstpad->end_frame))
- end_frame = default_end_frame;
-
- ret = end_frame(link);
-
- clear_link(link);
-
- return ret;
-}
-
-int ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
-{
- return ff_draw_slice(link->dst->outputs[0], y, h, slice_dir);
-}
-
-static int default_draw_slice(AVFilterLink *inlink, int y, int h, int
slice_dir)
-{
- AVFilterLink *outlink = NULL;
-
- if (inlink->dst->nb_outputs)
- outlink = inlink->dst->outputs[0];
-
- if (outlink)
- return ff_draw_slice(outlink, y, h, slice_dir);
- return 0;
-}
-
-int ff_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
-{
- uint8_t *src[4], *dst[4];
- int i, j, vsub, ret;
- int (*draw_slice)(AVFilterLink *, int, int, int);
-
- FF_DPRINTF_START(NULL, draw_slice); ff_dlog_link(NULL, link, 0);
av_dlog(NULL, " y:%d h:%d dir:%d\n", y, h, slice_dir);
-
- /* copy the slice if needed for permission reasons */
- if (link->src_buf) {
- const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
- vsub = desc->log2_chroma_h;
-
- for (i = 0; i < 4; i++) {
- if (link->src_buf->data[i]) {
- src[i] = link->src_buf-> data[i] +
- (y >> (i==1 || i==2 ? vsub : 0)) * link->src_buf->
linesize[i];
- dst[i] = link->cur_buf->data[i] +
- (y >> (i==1 || i==2 ? vsub : 0)) *
link->cur_buf->linesize[i];
- } else
- src[i] = dst[i] = NULL;
- }
-
- for (i = 0; i < 4; i++) {
- int planew =
- av_image_get_linesize(link->format, link->cur_buf->video->w,
i);
-
- if (!src[i]) continue;
-
- for (j = 0; j < h >> (i==1 || i==2 ? vsub : 0); j++) {
- memcpy(dst[i], src[i], planew);
- src[i] += link->src_buf->linesize[i];
- dst[i] += link->cur_buf->linesize[i];
- }
- }
- }
-
- if (!(draw_slice = link->dstpad->draw_slice))
- draw_slice = default_draw_slice;
- ret = draw_slice(link, y, h, slice_dir);
- if (ret < 0)
- clear_link(link);
- return ret;
-}
diff --git a/libavfilter/video.h b/libavfilter/video.h
index 348240c..be93810 100644
--- a/libavfilter/video.h
+++ b/libavfilter/video.h
@@ -39,51 +39,4 @@ AVFilterBufferRef *ff_null_get_video_buffer(AVFilterLink
*link, int perms, int w
AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms,
int w, int h);
-int ff_inplace_start_frame(AVFilterLink *link, AVFilterBufferRef *picref);
-int ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref);
-int ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir);
-int ff_null_end_frame(AVFilterLink *link);
-
-/**
- * Notify the next filter of the start of a frame.
- *
- * @param link the output link the frame will be sent over
- * @param picref A reference to the frame about to be sent. The data for this
- * frame need only be valid once draw_slice() is called for that
- * portion. The receiving filter will free this reference when
- * it no longer needs it.
- *
- * @return >= 0 on success, a negative AVERROR on error. This function will
- * unreference picref in case of error.
- */
-int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref);
-
-/**
- * Notify the next filter that the current frame has finished.
- *
- * @param link the output link the frame was sent over
- *
- * @return >= 0 on success, a negative AVERROR on error
- */
-int ff_end_frame(AVFilterLink *link);
-
-/**
- * Send a slice to the next filter.
- *
- * Slices have to be provided in sequential order, either in
- * top-bottom or bottom-top order. If slices are provided in
- * non-sequential order the behavior of the function is undefined.
- *
- * @param link the output link over which the frame is being sent
- * @param y offset in pixels from the top of the image for this slice
- * @param h height of this slice in pixels
- * @param slice_dir the assumed direction for sending slices,
- * 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,
- * for other values the behavior of the function is undefined.
- *
- * @return >= 0 on success, a negative AVERROR on error.
- */
-int ff_draw_slice(AVFilterLink *link, int y, int h, int slice_dir);
-
#endif /* AVFILTER_VIDEO_H */
--
1.7.10.4
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel