]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/sink_buffer.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavfilter / sink_buffer.c
index bfbec7d555d4a6620034ce09f85b2666d397d02b..926362bef8817d7565395815460dceec50a06731 100644 (file)
@@ -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,7 +203,7 @@ 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,
 
@@ -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,7 +283,7 @@ 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,