This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit fe2691b3bbe3e0cedc37f01a87e49a166d7bf917 Author: Niklas Haas <[email protected]> AuthorDate: Sun Mar 29 17:10:40 2026 +0200 Commit: Niklas Haas <[email protected]> CommitDate: Fri Apr 10 15:12:18 2026 +0200 avfilter/framepool: stack-allocate FFFramePool Saves a pointless free/alloc cycle on reinit. For the vast majority of filter links, this going to be allocated anyway; and on the occasions that it's not, the waste is marginal. Signed-off-by: Niklas Haas <[email protected]> --- libavfilter/audio.c | 2 +- libavfilter/avfilter_internal.h | 6 +- libavfilter/framepool.c | 135 +++++++++++++++++++--------------------- libavfilter/framepool.h | 16 +++-- libavfilter/video.c | 2 +- 5 files changed, 77 insertions(+), 84 deletions(-) diff --git a/libavfilter/audio.c b/libavfilter/audio.c index 0ac2e58d8c..785dac9f59 100644 --- a/libavfilter/audio.c +++ b/libavfilter/audio.c @@ -54,7 +54,7 @@ AVFrame *ff_default_get_audio_buffer(AVFilterLink *link, int nb_samples) link->format, align) < 0) return NULL; - frame = ff_frame_pool_get(li->frame_pool); + frame = ff_frame_pool_get(&li->frame_pool); if (!frame) return NULL; diff --git a/libavfilter/avfilter_internal.h b/libavfilter/avfilter_internal.h index cad4b2124b..808dd6af38 100644 --- a/libavfilter/avfilter_internal.h +++ b/libavfilter/avfilter_internal.h @@ -29,12 +29,16 @@ #include "avfilter.h" #include "filters.h" +#include "framepool.h" #include "framequeue.h" typedef struct FilterLinkInternal { FilterLink l; - struct FFFramePool *frame_pool; + /** + * Pool of frames used for allocations. + */ + FFFramePool frame_pool; /** * Queue of frames waiting to be filtered. diff --git a/libavfilter/framepool.c b/libavfilter/framepool.c index a8bb843195..fe06549789 100644 --- a/libavfilter/framepool.c +++ b/libavfilter/framepool.c @@ -28,21 +28,19 @@ #include "libavutil/mem.h" #include "libavutil/pixfmt.h" -static av_cold FFFramePool *frame_pool_video_init(int width, int height, - enum AVPixelFormat format, - int align) +static av_cold int frame_pool_video_init(int width, int height, + enum AVPixelFormat format, + int align, FFFramePool *pool) { int ret; - FFFramePool *pool = av_mallocz(sizeof(FFFramePool)); - if (!pool) - return NULL; - - pool->type = AVMEDIA_TYPE_VIDEO; - pool->width = width; - pool->height = height; - pool->pix_fmt = format; - pool->align = align; + *pool = (FFFramePool) { + .type = AVMEDIA_TYPE_VIDEO, + .width = width, + .height = height, + .pix_fmt = format, + .align = align, + }; if ((ret = av_image_check_size2(width, height, INT64_MAX, format, 0, NULL)) < 0) goto fail; @@ -60,11 +58,11 @@ static av_cold FFFramePool *frame_pool_video_init(int width, int height, linesizes[i] = pool->linesize[i]; size_t sizes[4]; - if (av_image_fill_plane_sizes(sizes, pool->pix_fmt, - FFALIGN(pool->height, align), - linesizes) < 0) { + ret = av_image_fill_plane_sizes(sizes, pool->pix_fmt, + FFALIGN(pool->height, align), + linesizes); + if (ret < 0) goto fail; - } for (int i = 0; i < 4 && sizes[i]; i++) { if (sizes[i] > SIZE_MAX - align) @@ -73,53 +71,58 @@ static av_cold FFFramePool *frame_pool_video_init(int width, int height, CONFIG_MEMORY_POISONING ? NULL : av_buffer_allocz); - if (!pool->pools[i]) + if (!pool->pools[i]) { + ret = AVERROR(ENOMEM); goto fail; + } } - return pool; + return 0; fail: - ff_frame_pool_uninit(&pool); - return NULL; + ff_frame_pool_uninit(pool); + return ret; } -static av_cold FFFramePool *frame_pool_audio_init(int channels, int nb_samples, - enum AVSampleFormat format, - int align) +static av_cold int frame_pool_audio_init(int channels, int nb_samples, + enum AVSampleFormat format, + int align, FFFramePool *pool) { int ret; - FFFramePool *pool = av_mallocz(sizeof(FFFramePool)); - if (!pool) - return NULL; - int 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->sample_fmt = format; - pool->align = align; + *pool = (FFFramePool) { + .type = AVMEDIA_TYPE_AUDIO, + .planes = planar ? channels : 1, + .channels = channels, + .nb_samples = nb_samples, + .sample_fmt = format, + .align = align, + }; ret = av_samples_get_buffer_size(&pool->linesize[0], channels, nb_samples, format, 0); if (ret < 0) goto fail; - if (pool->linesize[0] > SIZE_MAX - align) + if (pool->linesize[0] > SIZE_MAX - align) { + ret = AVERROR(EINVAL); goto fail; + } + pool->pools[0] = av_buffer_pool_init(pool->linesize[0] + align, av_buffer_allocz); - if (!pool->pools[0]) + if (!pool->pools[0]) { + ret = AVERROR(ENOMEM); goto fail; + } - return pool; + return 0; fail: - ff_frame_pool_uninit(&pool); - return NULL; + ff_frame_pool_uninit(pool); + return ret; } AVFrame *ff_frame_pool_get(FFFramePool *pool) @@ -209,65 +212,53 @@ fail: return NULL; } -av_cold void ff_frame_pool_uninit(FFFramePool **pool) +av_cold void ff_frame_pool_uninit(FFFramePool *pool) { - if (!*pool) + if (!pool->type) return; for (int i = 0; i < 4; i++) - av_buffer_pool_uninit(&(*pool)->pools[i]); + av_buffer_pool_uninit(&pool->pools[i]); - av_freep(pool); + memset(pool, 0, sizeof(*pool)); } -int ff_frame_pool_video_reinit(FFFramePool **pool, +int ff_frame_pool_video_reinit(FFFramePool *pool, int width, int height, enum AVPixelFormat format, int align) { - FFFramePool *cur = *pool; - if (cur && cur->pix_fmt == format && - FFALIGN(cur->width, cur->align) == FFALIGN(width, align) && - FFALIGN(cur->height, cur->align) == FFALIGN(height, align) && - cur->align == align) + if (pool->type == AVMEDIA_TYPE_VIDEO && + pool->pix_fmt == format && + FFALIGN(pool->width, pool->align) == FFALIGN(width, align) && + FFALIGN(pool->height, pool->align) == FFALIGN(height, align) && + pool->align == align) { - av_assert1(cur->type == AVMEDIA_TYPE_VIDEO); - cur->width = width; - cur->height = height; + pool->width = width; + pool->height = height; return 0; } - FFFramePool *new = frame_pool_video_init(width, height, format, align); - if (!new) - return AVERROR(ENOMEM); - - *pool = new; - ff_frame_pool_uninit(&cur); - return 0; + ff_frame_pool_uninit(pool); + return frame_pool_video_init(width, height, format, align, pool); } -int ff_frame_pool_audio_reinit(FFFramePool **pool, +int ff_frame_pool_audio_reinit(FFFramePool *pool, int channels, int nb_samples, enum AVSampleFormat format, int align) { - FFFramePool *cur = *pool; - if (cur && cur->sample_fmt == format && - cur->channels == channels && - cur->nb_samples == nb_samples && - cur->align == align) + if (pool->type == AVMEDIA_TYPE_AUDIO && + pool->sample_fmt == format && + pool->channels == channels && + pool->nb_samples == nb_samples && + pool->align == align) { - av_assert1(cur->type == AVMEDIA_TYPE_AUDIO); return 0; } - FFFramePool *new = frame_pool_audio_init(channels, nb_samples, format, align); - if (!new) - return AVERROR(ENOMEM); - - *pool = new; - ff_frame_pool_uninit(&cur); - return 0; + ff_frame_pool_uninit(pool); + return frame_pool_audio_init(channels, nb_samples, format, align, pool); } diff --git a/libavfilter/framepool.h b/libavfilter/framepool.h index 0f05ec56fc..64826aecdb 100644 --- a/libavfilter/framepool.h +++ b/libavfilter/framepool.h @@ -26,7 +26,7 @@ #include "libavutil/internal.h" /** - * Frame pool. This structure must be allocated with + * Frame pool. This structure must be initialized with * ff_frame_pool_{video,audio}_reinit() and freed with ff_frame_pool_uninit(). */ typedef struct FFFramePool { @@ -58,15 +58,14 @@ typedef struct FFFramePool { * provided configuration. If initialization fails, the old pool is kept * unchanged. * - * @param pool pointer to the frame pool to be reinitialized, or a pointer to - * NULL to create a new pool. + * @param pool pointer to the frame pool to be (re)initialized * @param width width of each frame in this pool * @param height height of each frame in this pool * @param format format of each frame in this pool * @param align buffers alignment of each frame in this pool * @return 0 on success, a negative AVERROR otherwise. */ -int ff_frame_pool_video_reinit(FFFramePool **pool, +int ff_frame_pool_video_reinit(FFFramePool *pool, int width, int height, enum AVPixelFormat format, @@ -77,15 +76,14 @@ int ff_frame_pool_video_reinit(FFFramePool **pool, * provided configuration. If initialization fails, the old pool is kept * unchanged. * - * @param pool pointer to the frame pool to be reinitialized, or a pointer to - * NULL to create a new pool. + * @param pool pointer to the frame pool to be (re)initialized * @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 alignment of each frame in this pool * @return 0 on success, a negative AVERROR otherwise. */ -int ff_frame_pool_audio_reinit(FFFramePool **pool, +int ff_frame_pool_audio_reinit(FFFramePool *pool, int channels, int nb_samples, enum AVSampleFormat format, @@ -95,9 +93,9 @@ int ff_frame_pool_audio_reinit(FFFramePool **pool, * Deallocate the frame pool. It is safe to call this function while * some of the allocated frame are still in use. * - * @param pool pointer to the frame pool to be freed. It will be set to NULL. + * @param pool pointer to the frame pool to be uninitialized */ -void ff_frame_pool_uninit(FFFramePool **pool); +void ff_frame_pool_uninit(FFFramePool *pool); /** * Allocate a new AVFrame, reusing old buffers from the pool when available. diff --git a/libavfilter/video.c b/libavfilter/video.c index 7c63bcac05..9be2f65448 100644 --- a/libavfilter/video.c +++ b/libavfilter/video.c @@ -69,7 +69,7 @@ AVFrame *ff_default_get_video_buffer2(AVFilterLink *link, int w, int h, int alig if (ff_frame_pool_video_reinit(&li->frame_pool, w, h, link->format, align) < 0) return NULL; - frame = ff_frame_pool_get(li->frame_pool); + frame = ff_frame_pool_get(&li->frame_pool); if (!frame) return NULL; _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
