mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2026-06-11 08:13:06 +00:00
swscale: add FFFramePool and use it for allocating planes
The major consequence of this is that we start allocating buffers per plane, instead of allocating one contiguous buffer. This makes the no-op/refcopy case slightly slower, but doesn't meaningfully affect the rest: yuva444p -> yuva444p, time=157/1000 us (ref=78/1000 us), speedup=0.497x slower Overall speedup=1.016x faster, min=0.983x max=1.092x However, this is a necessary consequence of the desire to allow partial plane allocations / single plane refcopies. This slowdown also does not affect vf_scale, which already uses avfilter/framepool.c (via ff_get_video_buffer). Signed-off-by: Niklas Haas <git@haasn.dev>
This commit is contained in:
@@ -12,6 +12,7 @@ OBJS = alphablend.o \
|
||||
hscale_fast_bilinear.o \
|
||||
filters.o \
|
||||
format.o \
|
||||
framepool.o \
|
||||
gamma.o \
|
||||
graph.o \
|
||||
input.o \
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "libavfilter/framepool.c"
|
||||
+25
-1
@@ -1215,6 +1215,24 @@ void sws_frame_end(SwsContext *sws)
|
||||
c->src_ranges.nb_ranges = 0;
|
||||
}
|
||||
|
||||
static int frame_alloc_buffers(SwsContext *sws, AVFrame *frame)
|
||||
{
|
||||
SwsInternal *c = sws_internal(sws);
|
||||
FFFramePool *pool = &c->frame_pool;
|
||||
|
||||
av_assert0(!frame->hw_frames_ctx);
|
||||
const int nb_planes = av_pix_fmt_count_planes(frame->format);
|
||||
for (int i = 0; i < nb_planes; i++) {
|
||||
frame->linesize[i] = pool->linesize[i];
|
||||
frame->buf[i] = av_buffer_pool_get(pool->pools[i]);
|
||||
if (!frame->buf[i])
|
||||
return AVERROR(ENOMEM);
|
||||
frame->data[i] = frame->buf[i]->data;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sws_frame_start(SwsContext *sws, AVFrame *dst, const AVFrame *src)
|
||||
{
|
||||
SwsInternal *c = sws_internal(sws);
|
||||
@@ -1390,7 +1408,7 @@ int sws_scale_frame(SwsContext *sws, AVFrame *dst, const AVFrame *src)
|
||||
if (src->buf[0] && top->noop && (!bot || bot->noop))
|
||||
return frame_ref(dst, src);
|
||||
|
||||
ret = av_frame_get_buffer(dst, 0);
|
||||
ret = frame_alloc_buffers(sws, dst);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -1457,6 +1475,12 @@ int sws_frame_setup(SwsContext *ctx, const AVFrame *dst, const AVFrame *src)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
#endif
|
||||
} else {
|
||||
/* Software frames */
|
||||
ret = ff_frame_pool_video_reinit(&s->frame_pool, dst->width, dst->height,
|
||||
dst->format, av_cpu_max_align());
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (int field = 0; field < 2; field++) {
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "swscale.h"
|
||||
#include "graph.h"
|
||||
|
||||
#include "libavfilter/framepool.h"
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/common.h"
|
||||
#include "libavutil/frame.h"
|
||||
@@ -699,6 +700,8 @@ struct SwsInternal {
|
||||
void *hw_priv; /* refstruct */
|
||||
|
||||
int is_legacy_init;
|
||||
|
||||
FFFramePool frame_pool; /* for sws_scale_frame() data allocations */
|
||||
};
|
||||
//FIXME check init (where 0)
|
||||
|
||||
|
||||
@@ -2293,6 +2293,7 @@ void sws_freeContext(SwsContext *sws)
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(c->graph); i++)
|
||||
ff_sws_graph_free(&c->graph[i]);
|
||||
ff_frame_pool_uninit(&c->frame_pool);
|
||||
|
||||
for (i = 0; i < c->nb_slice_ctx; i++)
|
||||
sws_freeContext(c->slice_ctx[i]);
|
||||
|
||||
Reference in New Issue
Block a user