X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Fsink_buffer.c;h=926362bef8817d7565395815460dceec50a06731;hb=d1c28e35300130f0ee28a3e5bbeb2cea403fad57;hp=1c4996708a616e87e4e690b18d351ce62a6ea5b7;hpb=8d4e44993a87a9b230c5c87cf892dd58adcebcc4;p=ffmpeg diff --git a/libavfilter/sink_buffer.c b/libavfilter/sink_buffer.c index 1c4996708a6..926362bef88 100644 --- a/libavfilter/sink_buffer.c +++ b/libavfilter/sink_buffer.c @@ -26,6 +26,7 @@ #include "libavutil/fifo.h" #include "avfilter.h" #include "buffersink.h" +#include "internal.h" AVBufferSinkParams *av_buffersink_params_alloc(void) { @@ -58,12 +59,12 @@ typedef struct { 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 @@ -140,6 +141,14 @@ int av_buffersink_get_buffer_ref(AVFilterContext *ctx, 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) @@ -161,16 +170,26 @@ static av_cold int vsink_init(AVFilterContext *ctx, const char *args, void *opaq 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; @@ -184,16 +203,16 @@ AVFilter avfilter_vsink_buffersink = { .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 */ @@ -217,13 +236,29 @@ static av_cold int asink_init(AVFilterContext *ctx, const char *args, void *opaq } 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; @@ -248,16 +283,16 @@ AVFilter avfilter_asink_abuffersink = { .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 */