On Thu, Jan 05, 2017 at 12:11:33PM +0100, Matthieu Bouron wrote: > --- > libavfilter/framepool.c | 109 > ++++++++++++++++++++++++++++++++++++++++++++++++ > libavfilter/framepool.h | 36 +++++++++++++++- > 2 files changed, 144 insertions(+), 1 deletion(-) > > diff --git a/libavfilter/framepool.c b/libavfilter/framepool.c > index 36c6e8fd04..588dcb6da2 100644 > --- a/libavfilter/framepool.c > +++ b/libavfilter/framepool.c > @@ -20,6 +20,7 @@ > > #include "framepool.h" > #include "libavutil/avassert.h" > +#include "libavutil/avutil.h" > #include "libavutil/buffer.h" > #include "libavutil/frame.h" > #include "libavutil/imgutils.h" > @@ -28,8 +29,18 @@ > > struct FFFramePool { > > + enum AVMediaType type; > + > + /* video */ > int width; > int height; > + > + /* audio */ > + int planes; > + int channels; > + int nb_samples; > + > + /* common */ > int format; > int align; > int linesize[4]; > @@ -54,6 +65,7 @@ FFFramePool *ff_frame_pool_video_init(AVBufferRef* > (*alloc)(int size), > if (!pool) > return NULL; > > + pool->type = AVMEDIA_TYPE_VIDEO; > pool->width = width; > pool->height = height; > pool->format = format; > @@ -104,6 +116,44 @@ fail: > return NULL; > } > > +FFFramePool *ff_frame_pool_audio_init(AVBufferRef* (*alloc)(int size), > + int channels, > + int nb_samples, > + enum AVSampleFormat format, > + int align) > +{ > + int ret, planar; > + FFFramePool *pool; > + > + pool = av_mallocz(sizeof(FFFramePool)); > + if (!pool) > + return NULL; > + > + planar = av_sample_fmt_is_planar(format); > + > + pool->type = AVMEDIA_TYPE_AUDIO; > + pool->planes = planar ? channels : 1; > + pool->channels = channels; > + pool->nb_samples = nb_samples; > + pool->format = format; > + pool->align = align; > + > + ret = av_samples_get_buffer_size(&pool->linesize[0], channels, > + nb_samples, format, 0); > + if (ret < 0) > + goto fail; > + > + pool->pools[0] = av_buffer_pool_init(pool->linesize[0], NULL); > + if (!pool->pools[0]) > + goto fail; > + > + return pool; > + > +fail: > + ff_frame_pool_uninit(&pool); > + return NULL; > +} > + > int ff_frame_pool_get_video_config(FFFramePool *pool, > int *width, > int *height, > @@ -113,6 +163,8 @@ int ff_frame_pool_get_video_config(FFFramePool *pool, > if (!pool) > return AVERROR(EINVAL); > > + av_assert0(pool->type == AVMEDIA_TYPE_VIDEO); > + > *width = pool->width; > *height = pool->height; > *format = pool->format; > @@ -121,6 +173,24 @@ int ff_frame_pool_get_video_config(FFFramePool *pool, > return 0; > } > > +int ff_frame_pool_get_audio_config(FFFramePool *pool, > + int *channels, > + int *nb_samples, > + enum AVSampleFormat *format, > + int *align) > +{ > + if (!pool) > + return AVERROR(EINVAL); > + > + av_assert0(pool->type == AVMEDIA_TYPE_AUDIO); > + > + *channels = pool->channels; > + *nb_samples = pool->nb_samples; > + *format = pool->format; > + *align = pool->align; > + > + return 0; > +} > > AVFrame *ff_frame_pool_get(FFFramePool *pool) > { > @@ -133,6 +203,8 @@ AVFrame *ff_frame_pool_get(FFFramePool *pool) > return NULL; > } > > + switch(pool->type) { > + case AVMEDIA_TYPE_VIDEO: > desc = av_pix_fmt_desc_get(pool->format); > if (!desc) { > goto fail; > @@ -167,6 +239,43 @@ AVFrame *ff_frame_pool_get(FFFramePool *pool) > } > > frame->extended_data = frame->data; > + break; > + case AVMEDIA_TYPE_AUDIO: > + frame->nb_samples = pool->nb_samples; > + av_frame_set_channels(frame, pool->channels); > + frame->format = pool->format; > + frame->linesize[0] = pool->linesize[0]; > + > + if (pool->planes > AV_NUM_DATA_POINTERS) { > + frame->extended_data = av_mallocz_array(pool->planes, > + > sizeof(*frame->extended_data)); > + frame->nb_extended_buf = pool->planes - AV_NUM_DATA_POINTERS; > + frame->extended_buf = av_mallocz_array(frame->nb_extended_buf, > + > sizeof(*frame->extended_buf)); > + if (!frame->extended_data || !frame->extended_buf) > + goto fail; > + } else { > + frame->extended_data = frame->data; > + av_assert0(frame->nb_extended_buf == 0); > + } > + > + for (i = 0; i < FFMIN(pool->planes, AV_NUM_DATA_POINTERS); i++) { > + frame->buf[i] = av_buffer_pool_get(pool->pools[0]); > + if (!frame->buf[i]) > + goto fail; > + frame->extended_data[i] = frame->data[i] = frame->buf[i]->data; > + } > + for (i = 0; i < frame->nb_extended_buf; i++) { > + frame->extended_buf[i] = av_buffer_pool_get(pool->pools[0]); > + if (!frame->extended_buf[i]) > + goto fail; > + frame->extended_data[i + AV_NUM_DATA_POINTERS] = > frame->extended_buf[i]->data; > + } > + > + break; > + default: > + av_assert0(0); > + } > > return frame; > fail: > diff --git a/libavfilter/framepool.h b/libavfilter/framepool.h > index 4824824894..e5560e4c6e 100644 > --- a/libavfilter/framepool.h > +++ b/libavfilter/framepool.h > @@ -41,7 +41,7 @@ typedef struct FFFramePool FFFramePool; > * @param height height of each frame in this pool > * @param format format of each frame in this pool > * @param align buffers alignement of each frame in this pool > - * @return newly created frame pool on success, NULL on error. > + * @return newly created video frame pool on success, NULL on error. > */ > FFFramePool *ff_frame_pool_video_init(AVBufferRef* (*alloc)(int size), > int width, > @@ -50,6 +50,24 @@ FFFramePool *ff_frame_pool_video_init(AVBufferRef* > (*alloc)(int size), > int align); > > /** > + * Allocate and initialize an audio frame pool. > + * > + * @param alloc a function that will be used to allocate new frame buffers > when > + * the pool is empty. May be NULL, then the default allocator will be used > + * (av_buffer_alloc()). > + * @param channels channels of each frame in this pool > + * @param nb_samples number of samples of each frame in this pool > + * @param format format of each frame in this pool > + * @param align buffers alignement of each frame in this pool > + * @return newly created audio frame pool on success, NULL on error. > + */ > +FFFramePool *ff_frame_pool_audio_init(AVBufferRef* (*alloc)(int size), > + int channels, > + int samples, > + enum AVSampleFormat format, > + int align); > + > +/** > * Deallocate the frame pool. It is safe to call this function while > * some of the allocated frame are still in use. > * > @@ -73,6 +91,22 @@ int ff_frame_pool_get_video_config(FFFramePool *pool, > int *align); > > /** > + * Get the audio frame pool configuration. > + * > + * @param channels channels of each frame in this pool > + * @param nb_samples number of samples of each frame in this pool > + * @param format format of each frame in this pool > + * @param align buffers alignement of each frame in this pool > + * @return 0 on success, a negative AVERROR otherwise. > + */ > +int ff_frame_pool_get_audio_config(FFFramePool *pool, > + int *channels, > + int *nb_samples, > + enum AVSampleFormat *format, > + int *align); > + > + > +/** > * Allocate a new AVFrame, reussing old buffers from the pool when available. > * This function may be called simultaneously from multiple threads. > * > -- > 2.11.0 >
Ping. _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel