Files
Michael Niedermayer a3f1b1e87c avutil/framepool: provide a single copy for static builds
Both libavfilter and libswscale currently put framepool.o in their regular
OBJS, defining the same four ff_frame_pool_* symbols. Loading both static
archives in full therefore fails with multiple definitions.

Move the implementation and internal header to libavutil. Include the
object in its STLIBOBJS when either consumer is enabled, and use SHLIBOBJS
for the private copies in libavfilter and libswscale. This preserves
independent builds and shared-library symbol visibility without adding
an inter-library dependency or exposing a new public API.

Verified whole-archive links with both consumers, and with each consumer
configured independently. Shared builds pass fate-filter-rgbtestsrc-gbrp12
and fate-filter-rgbtestsrc-gbrap12; static and shared video scaling and
audio volume smoke tests produce identical frame checksums. Also checked
static consumers linked against shared dependencies.

Fixes: 6c89a30ecd
Fixes: #25419
Assisted-by: Fairy
2026-10-26 16:53:24 +00:00

134 lines
3.6 KiB
C

/*
* Copyright 2007 Bobby Bingham
* Copyright Stefano Sabatini <stefasab gmail com>
* Copyright Vitor Sessak <vitor1001 gmail com>
*
* 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 <string.h>
#include <stdio.h>
#include "libavutil/buffer.h"
#include "libavutil/cpu.h"
#include "libavutil/framepool.h"
#include "libavutil/hwcontext.h"
#include "libavutil/pixfmt.h"
#include "avfilter.h"
#include "avfilter_internal.h"
#include "filters.h"
#include "video.h"
const AVFilterPad ff_video_default_filterpad[1] = {
{
.name = "default",
.type = AVMEDIA_TYPE_VIDEO,
}
};
AVFrame *ff_null_get_video_buffer(AVFilterLink *link, int w, int h)
{
return ff_get_video_buffer(link->dst->outputs[0], w, h);
}
static void set_link_props(AVFrame *frame, const AVFilterLink *link)
{
frame->sample_aspect_ratio = link->sample_aspect_ratio;
frame->colorspace = link->colorspace;
frame->color_range = link->color_range;
frame->alpha_mode = link->alpha_mode;
frame->chroma_location = link->chroma_location;
}
AVFrame *ff_default_get_video_buffer2(AVFilterLink *link, int w, int h, int align)
{
FilterLinkInternal *const li = ff_link_internal(link);
AVFrame *frame = NULL;
if (li->l.hw_frames_ctx &&
((AVHWFramesContext*)li->l.hw_frames_ctx->data)->format == link->format) {
int ret;
frame = av_frame_alloc();
if (!frame)
return NULL;
ret = av_hwframe_get_buffer(li->l.hw_frames_ctx, frame, 0);
if (ret < 0)
av_frame_free(&frame);
return frame;
}
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);
if (!frame)
return NULL;
set_link_props(frame, link);
return frame;
}
AVFrame *ff_default_get_video_buffer(AVFilterLink *link, int w, int h)
{
return ff_default_get_video_buffer2(link, w, h, av_cpu_max_align());
}
AVFrame *ff_hwupload_get_video_buffer(AVFilterLink *link, int w, int h)
{
AVBufferRef *hw_frames_ctx = ff_filter_link(link->dst->outputs[0])->hw_frames_ctx;
AVFrame *frame;
if (!hw_frames_ctx || ff_filter_link(link)->hw_frames_ctx)
return ff_default_get_video_buffer(link, w, h);
frame = av_frame_alloc();
if (!frame)
return NULL;
frame->format = link->format;
frame->width = w;
frame->height = h;
if (av_hwframe_get_transfer_buffer(hw_frames_ctx, frame) < 0) {
av_frame_free(&frame);
return NULL;
}
set_link_props(frame, link);
return frame;
}
AVFrame *ff_get_video_buffer(AVFilterLink *link, int w, int h)
{
AVFrame *ret = NULL;
FF_TPRINTF_START(NULL, get_video_buffer); ff_tlog_link(NULL, link, 1);
if (link->dstpad->get_buffer.video)
ret = link->dstpad->get_buffer.video(link, w, h);
if (!ret)
ret = ff_default_get_video_buffer(link, w, h);
return ret;
}