#include "libavutil/fifo.h"
#include "avfilter.h"
#include "buffersink.h"
+#include "internal.h"
AVBufferSinkParams *av_buffersink_params_alloc(void)
{
AVFifoBuffer *fifo; ///< FIFO buffer of video frame references
/* only used for video */
- const enum PixelFormat *pixel_fmts; ///< list of accepted pixel formats, must be terminated with -1
+ enum PixelFormat *pixel_fmts; ///< list of accepted pixel formats, must be terminated with -1
/* only used for audio */
- const enum AVSampleFormat *sample_fmts; ///< list of accepted sample formats, terminated by AV_SAMPLE_FMT_NONE
- const int64_t *channel_layouts; ///< list of accepted channel layouts, terminated by -1
- const int *packing_fmts; ///< list of accepted packing formats, terminated by -1
+ enum AVSampleFormat *sample_fmts; ///< list of accepted sample formats, terminated by AV_SAMPLE_FMT_NONE
+ int64_t *channel_layouts; ///< list of accepted channel layouts, terminated by -1
+ int *packing_fmts; ///< list of accepted packing formats, terminated by -1
} BufferSinkContext;
#define FIFO_INIT_SIZE 8
return 0;
}
+int av_buffersink_poll_frame(AVFilterContext *ctx)
+{
+ BufferSinkContext *buf = ctx->priv;
+ AVFilterLink *inlink = ctx->inputs[0];
+
+ return av_fifo_size(buf->fifo)/sizeof(AVFilterBufferRef *) + avfilter_poll_frame(inlink);
+}
+
#if FF_API_OLD_VSINK_API
int av_vsink_buffer_get_video_buffer_ref(AVFilterContext *ctx,
AVFilterBufferRef **picref, int flags)
return AVERROR(EINVAL);
} else {
#if FF_API_OLD_VSINK_API
- buf->pixel_fmts = (const enum PixelFormat *)opaque;
+ const int *pixel_fmts = (const enum PixelFormat *)opaque;
#else
params = (AVBufferSinkParams *)opaque;
- buf->pixel_fmts = params->pixel_fmts;
+ const int *pixel_fmts = params->pixel_fmts;
#endif
+ buf->pixel_fmts = ff_copy_int_list(pixel_fmts);
+ if (!buf->pixel_fmts)
+ return AVERROR(ENOMEM);
}
return common_init(ctx);
}
+static av_cold void vsink_uninit(AVFilterContext *ctx)
+{
+ BufferSinkContext *buf = ctx->priv;
+ av_freep(&buf->pixel_fmts);
+ return common_uninit(ctx);
+}
+
static int vsink_query_formats(AVFilterContext *ctx)
{
BufferSinkContext *buf = ctx->priv;
.description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."),
.priv_size = sizeof(BufferSinkContext),
.init = vsink_init,
- .uninit = common_uninit,
+ .uninit = vsink_uninit,
.query_formats = vsink_query_formats,
- .inputs = (AVFilterPad[]) {{ .name = "default",
+ .inputs = (const AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.end_frame = end_frame,
.min_perms = AV_PERM_READ, },
{ .name = NULL }},
- .outputs = (AVFilterPad[]) {{ .name = NULL }},
+ .outputs = (const AVFilterPad[]) {{ .name = NULL }},
};
#endif /* CONFIG_BUFFERSINK_FILTER */
} else
params = (AVABufferSinkParams *)opaque;
- buf->sample_fmts = params->sample_fmts;
- buf->channel_layouts = params->channel_layouts;
- buf->packing_fmts = params->packing_fmts;
+ buf->sample_fmts = ff_copy_int_list (params->sample_fmts);
+ buf->channel_layouts = ff_copy_int64_list(params->channel_layouts);
+ buf->packing_fmts = ff_copy_int_list (params->packing_fmts);
+ if (!buf->sample_fmts || !buf->channel_layouts || !buf->sample_fmts) {
+ av_freep(&buf->sample_fmts);
+ av_freep(&buf->channel_layouts);
+ av_freep(&buf->packing_fmts);
+ return AVERROR(ENOMEM);
+ }
return common_init(ctx);
}
+static av_cold void asink_uninit(AVFilterContext *ctx)
+{
+ BufferSinkContext *buf = ctx->priv;
+
+ av_freep(&buf->sample_fmts);
+ av_freep(&buf->channel_layouts);
+ av_freep(&buf->packing_fmts);
+ return common_uninit(ctx);
+}
+
static int asink_query_formats(AVFilterContext *ctx)
{
BufferSinkContext *buf = ctx->priv;
.name = "abuffersink",
.description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."),
.init = asink_init,
- .uninit = common_uninit,
+ .uninit = asink_uninit,
.priv_size = sizeof(BufferSinkContext),
.query_formats = asink_query_formats,
- .inputs = (AVFilterPad[]) {{ .name = "default",
+ .inputs = (const AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_AUDIO,
.filter_samples = filter_samples,
.min_perms = AV_PERM_READ, },
{ .name = NULL }},
- .outputs = (AVFilterPad[]) {{ .name = NULL }},
+ .outputs = (const AVFilterPad[]) {{ .name = NULL }},
};
#endif /* CONFIG_ABUFFERSINK_FILTER */