summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libavfilter/formats.c26
-rw-r--r--libavfilter/internal.h12
-rw-r--r--libavfilter/sink_buffer.c49
3 files changed, 76 insertions, 11 deletions
diff --git a/libavfilter/formats.c b/libavfilter/formats.c
index ff4d49dd5d..fa2c1be4bb 100644
--- a/libavfilter/formats.c
+++ b/libavfilter/formats.c
@@ -93,6 +93,32 @@ int ff_fmt_is_in(int fmt, const int *fmts)
return 0;
}
+#define COPY_INT_LIST(list_copy, list, type) { \
+ int count = 0; \
+ if (list) \
+ for (count = 0; list[count] != -1; count++) \
+ ; \
+ list_copy = av_calloc(count+1, sizeof(type)); \
+ if (list_copy) { \
+ memcpy(list_copy, list, sizeof(type) * count); \
+ list_copy[count] = -1; \
+ } \
+}
+
+int *ff_copy_int_list(const int * const list)
+{
+ int *ret = NULL;
+ COPY_INT_LIST(ret, list, int);
+ return ret;
+}
+
+int64_t *ff_copy_int64_list(const int64_t * const list)
+{
+ int64_t *ret = NULL;
+ COPY_INT_LIST(ret, list, int64_t);
+ return ret;
+}
+
#define MAKE_FORMAT_LIST() \
AVFilterFormats *formats; \
int count = 0; \
diff --git a/libavfilter/internal.h b/libavfilter/internal.h
index 9f28a839df..227fe6243d 100644
--- a/libavfilter/internal.h
+++ b/libavfilter/internal.h
@@ -69,6 +69,18 @@ void ff_avfilter_default_free_buffer(AVFilterBuffer *buf);
/** Tell is a format is contained in the provided list terminated by -1. */
int ff_fmt_is_in(int fmt, const int *fmts);
+/**
+ * Return a copy of a list of integers terminated by -1, or NULL in
+ * case of copy failure.
+ */
+int *ff_copy_int_list(const int * const list);
+
+/**
+ * Return a copy of a list of 64-bit integers, or NULL in case of
+ * copy failure.
+ */
+int64_t *ff_copy_int64_list(const int64_t * const list);
+
/* Functions to parse audio format arguments */
/**
diff --git a/libavfilter/sink_buffer.c b/libavfilter/sink_buffer.c
index e572385419..926362bef8 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
@@ -169,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;
@@ -192,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,
@@ -225,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;
@@ -256,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,