From 27bcf55f459e038e81f09c17e72e6d44898b9015 Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Thu, 2 Jun 2011 15:43:21 +0200 Subject: [PATCH] vsrc_buffer: add flags param to av_vsrc_buffer_add_video_buffer_ref The new flags parameter allows to specify if the video ref to add should overwrite the cache, if the flag is not set vsrc_buffer will complain and abort; otherwise it will clean the already cached video ref before to overwrite it, thus avoiding a leak. --- doc/APIchanges | 4 ++++ ffmpeg.c | 3 ++- libavfilter/avcodec.h | 5 ++++- libavfilter/avfilter.h | 2 +- libavfilter/vsrc_buffer.c | 22 ++++++++++++++-------- libavfilter/vsrc_buffer.h | 11 ++++++++++- 6 files changed, 35 insertions(+), 12 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 937846ec62..a15e4a2e52 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,10 @@ libavutil: 2011-04-18 API changes, most recent first: +2011-06-06 - xxxxxx - lavfi 2.13.0 - vsrc_buffer.h + Make av_vsrc_buffer_add_video_buffer_ref() accepts an additional + flags parameter in input. + 2011-06-03 - xxxxxx - lavfi 2.12.0 - avfilter_link_free() Add avfilter_link_free() function. diff --git a/ffmpeg.c b/ffmpeg.c index fb619e7777..b18224b039 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -1691,7 +1691,8 @@ static int output_packet(AVInputStream *ist, int ist_index, picture.sample_aspect_ratio = ist->st->sample_aspect_ratio; picture.pts = ist->pts; - av_vsrc_buffer_add_frame(ost->input_video_filter, &picture); + av_vsrc_buffer_add_frame(ost->input_video_filter, + &picture, AV_VSRC_BUF_FLAG_OVERWRITE); } frame_available = ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO || !ost->output_video_filter || avfilter_poll_frame(ost->output_video_filter->inputs[0]); diff --git a/libavfilter/avcodec.h b/libavfilter/avcodec.h index 74434e819d..4eed6b2d2c 100644 --- a/libavfilter/avcodec.h +++ b/libavfilter/avcodec.h @@ -30,6 +30,7 @@ #include "libavcodec/avcodec.h" // AVFrame #include "avfilter.h" +#include "vsrc_buffer.h" /** * Copy the frame properties of src to dst, without copying the actual @@ -49,9 +50,11 @@ AVFilterBufferRef *avfilter_get_video_buffer_ref_from_frame(const AVFrame *frame * Add frame data to buffer_src. * * @param buffer_src pointer to a buffer source context + * @param flags a combination of AV_VSRC_BUF_FLAG_* flags * @return >= 0 in case of success, a negative AVERROR code in case of * failure */ -int av_vsrc_buffer_add_frame(AVFilterContext *buffer_src, const AVFrame *frame); +int av_vsrc_buffer_add_frame(AVFilterContext *buffer_src, + const AVFrame *frame, int flags); #endif /* AVFILTER_AVCODEC_H */ diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index 4ff68cd180..c7612f2004 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -26,7 +26,7 @@ #include "libavutil/samplefmt.h" #define LIBAVFILTER_VERSION_MAJOR 2 -#define LIBAVFILTER_VERSION_MINOR 12 +#define LIBAVFILTER_VERSION_MINOR 13 #define LIBAVFILTER_VERSION_MICRO 0 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vsrc_buffer.c b/libavfilter/vsrc_buffer.c index 9ba7d4ee47..246444b3ac 100644 --- a/libavfilter/vsrc_buffer.c +++ b/libavfilter/vsrc_buffer.c @@ -37,18 +37,23 @@ typedef struct { char sws_param[256]; } BufferSourceContext; -int av_vsrc_buffer_add_video_buffer_ref(AVFilterContext *buffer_filter, AVFilterBufferRef *picref) +int av_vsrc_buffer_add_video_buffer_ref(AVFilterContext *buffer_filter, + AVFilterBufferRef *picref, int flags) { BufferSourceContext *c = buffer_filter->priv; AVFilterLink *outlink = buffer_filter->outputs[0]; int ret; if (c->picref) { - av_log(buffer_filter, AV_LOG_ERROR, - "Buffering several frames is not supported. " - "Please consume all available frames before adding a new one.\n" - ); - //return -1; + if (flags & AV_VSRC_BUF_FLAG_OVERWRITE) { + avfilter_unref_buffer(c->picref); + c->picref = NULL; + } else { + av_log(buffer_filter, AV_LOG_ERROR, + "Buffering several frames is not supported. " + "Please consume all available frames before adding a new one.\n"); + return AVERROR(EINVAL); + } } if (picref->video->w != c->w || picref->video->h != c->h || picref->format != c->pix_fmt) { @@ -109,14 +114,15 @@ int av_vsrc_buffer_add_video_buffer_ref(AVFilterContext *buffer_filter, AVFilter #if CONFIG_AVCODEC #include "avcodec.h" -int av_vsrc_buffer_add_frame(AVFilterContext *buffer_src, const AVFrame *frame) +int av_vsrc_buffer_add_frame(AVFilterContext *buffer_src, + const AVFrame *frame, int flags) { int ret; AVFilterBufferRef *picref = avfilter_get_video_buffer_ref_from_frame(frame, AV_PERM_WRITE); if (!picref) return AVERROR(ENOMEM); - ret = av_vsrc_buffer_add_video_buffer_ref(buffer_src, picref); + ret = av_vsrc_buffer_add_video_buffer_ref(buffer_src, picref, flags); picref->buf->data[0] = NULL; avfilter_unref_buffer(picref); diff --git a/libavfilter/vsrc_buffer.h b/libavfilter/vsrc_buffer.h index c717f3dae4..b661d414ea 100644 --- a/libavfilter/vsrc_buffer.h +++ b/libavfilter/vsrc_buffer.h @@ -28,13 +28,22 @@ #include "avfilter.h" +/** + * Tell av_vsrc_buffer_add_video_buffer_ref() to overwrite the already + * cached video buffer with the new added one, otherwise the function + * will complain and exit. + */ +#define AV_VSRC_BUF_FLAG_OVERWRITE 1 + /** * Add video buffer data in picref to buffer_src. * * @param buffer_src pointer to a buffer source context + * @param flags a combination of AV_VSRC_BUF_FLAG_* flags * @return >= 0 in case of success, a negative AVERROR code in case of * failure */ -int av_vsrc_buffer_add_video_buffer_ref(AVFilterContext *buffer_src, AVFilterBufferRef *picref); +int av_vsrc_buffer_add_video_buffer_ref(AVFilterContext *buffer_src, + AVFilterBufferRef *picref, int flags); #endif /* AVFILTER_VSRC_BUFFER_H */