Hi,
Attached is a preliminary patch that enables runtime loading of external
libraries via dlopen and friends. Dynamic loading is a build time option
(--enable-dynamic-loading) and if it is not activated the libs are
linked as usual (still no dependency to dlopen required).
The patch is intended as a basis for a discussion and therefore the
following applies:
- only libmp3lame and libva will by dynamically loaded atm
- only tested on linux atm
- deregistering not implemented (dlclose)
- versioning (which version of a lib should be loaded?)
- library usage counter missing
- ...?
What do you think?
Thanks,
Marc
diff --git a/configure b/configure
index 94f9432..5787101 100755
--- a/configure
+++ b/configure
@@ -101,6 +101,8 @@ Licensing options:
Configuration options:
--disable-static do not build static libraries [no]
--enable-shared build shared libraries [no]
+ --enable-dynamic-loading enable runtime detection of installed libraries
+ (disables compile time linking of third party libs)
--enable-small optimize for size instead of speed
--disable-runtime-cpudetect disable detecting cpu capabilities at runtime (smaller binary)
--enable-gray enable full grayscale support (slower color)
@@ -1079,6 +1081,15 @@ check_lib(){
check_header $header && check_func $func "$@" && add_extralibs "$@"
}
+check_ext_lib() {
+ log check_ext_lib "$@"
+ header="$1"
+ func="$2"
+ shift 2
+ check_header $header && check_func $func "$@"
+ enabled dynamic_loading || add_extralibs "$@"
+}
+
check_lib2(){
log check_lib2 "$@"
headers="$1"
@@ -1192,6 +1203,14 @@ require(){
check_lib $header $func "$@" || die "ERROR: $name not found"
}
+require_extlib(){
+ name="$1"
+ header="$2"
+ func="$3"
+ shift 3
+ check_ext_lib $header $func "$@" || die "ERROR: $name not found"
+}
+
require2(){
name="$1"
headers="$2"
@@ -1432,6 +1451,7 @@ FEATURE_LIST="
small
static
swscale_alpha
+ dynamic_loading
"
HWACCEL_LIST="
@@ -4855,6 +4875,10 @@ for func in $MATH_FUNCS; do
eval check_mathfunc $func \${${func}_args:-1}
done
+enabled dynamic_loading && { { check_lib2 "windows.h" LoadLibrary; } ||
+ { check_lib2 "dlfcn.h" dlopen -ldl; } ||
+ die "ERROR: LoadLibrary/dlopen not found for dynamic-loading"; }
+
# these are off by default, so fail if requested and not available
enabled avfoundation_indev && { check_header_oc AVFoundation/AVFoundation.h || disable avfoundation_indev; }
enabled avisynth && { { check_lib2 "windows.h" LoadLibrary; } ||
@@ -4887,7 +4911,7 @@ enabled libgsm && { for gsm_hdr in "gsm.h" "gsm/gsm.h"; do
done || die "ERROR: libgsm not found"; }
enabled libilbc && require libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc
enabled libmodplug && require_pkg_config libmodplug libmodplug/modplug.h ModPlug_Load
-enabled libmp3lame && require "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame
+enabled libmp3lame && require_extlib "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame
enabled libnut && require libnut libnut.h nut_demuxer_init -lnut
enabled libopencore_amrnb && require libopencore_amrnb opencore-amrnb/interf_dec.h Decoder_Interface_init -lopencore-amrnb
enabled libopencore_amrwb && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb
@@ -5109,7 +5133,7 @@ int main(void) { IDirectXVideoDecoder *o = NULL; IDirectXVideoDecoder_Release(o)
EOF
enabled vaapi &&
- check_lib va/va.h vaInitialize -lva ||
+ check_ext_lib va/va.h vaInitialize -lva ||
disable vaapi
enabled vdpau &&
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 99467bb..4928b20 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -3228,7 +3228,7 @@ typedef struct AVCodec {
/**
* Initialize codec static data, called from avcodec_register().
*/
- void (*init_static_data)(struct AVCodec *codec);
+ int (*init_static_data)(struct AVCodec *codec);
int (*init)(AVCodecContext *);
int (*encode_sub)(AVCodecContext *, uint8_t *buf, int buf_size,
@@ -3373,6 +3373,11 @@ typedef struct AVHWAccel {
void (*decode_mb)(struct MpegEncContext *s);
/**
+ * Initialize codec static data, called from av_register_hwaccel().
+ */
+ int (*init_static_data)(struct AVHWAccel *hwaccel);
+
+ /**
* Initialize the hwaccel private data.
*
* This will be called from ff_get_format(), after hwaccel and
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index f4e12e8..fbfb8b8 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -45,6 +45,20 @@
# define STRIDE_ALIGN 8
#endif
+
+#if CONFIG_DYNAMIC_LOADING
+#define FUNC_DEF(struct_name, func_name) {#func_name, (void **)&struct_name.func_name, NULL}
+#else
+#define FUNC_DEF(struct_name, func_name) {#func_name, (void **)&struct_name.func_name, func_name}
+#endif
+
+typedef struct FuncDef {
+ const char *func_name;
+ void **dest_func_ptr;
+ void *source_func_ptr;
+} FuncDef;
+
+
typedef struct FramePool {
/**
* Pools for each data plane. For audio all the planes have the same size,
@@ -266,4 +280,6 @@ int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt);
*/
int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame);
+int resolve_symbols(const char *library_name, void **dlhandle, FuncDef *func_defs);
+
#endif /* AVCODEC_INTERNAL_H */
diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c
index e33919b..4dca65f 100644
--- a/libavcodec/libmp3lame.c
+++ b/libavcodec/libmp3lame.c
@@ -40,6 +40,46 @@
#define BUFFER_SIZE (7200 + 2 * MPA_FRAME_SIZE + MPA_FRAME_SIZE / 4+1000) // FIXME: Buffer size to small? Adding 1000 to make up for it.
+#define TOSTRING(x) #x
+#define STR(x) TOSTRING(x)
+#ifdef _WIN32
+#define LIBRARY_PREFIX
+#else
+#define LIBRARY_PREFIX lib
+#endif
+
+#define LIBRARY_SHORT_NAME mp3lame
+#define LIBRARY_NAME STR(LIBRARY_PREFIX) STR(LIBRARY_SHORT_NAME) SLIBSUF
+
+
+static struct LAMESymbols {
+ void *dlhandle;
+
+ int (*lame_close)(lame_global_flags *);
+ int (*lame_encode_buffer_float)( lame_global_flags* gfp, const float pcm_l [],
+ const float pcm_r [], const int nsamples, unsigned char* mp3buf, const int mp3buf_size);
+ int (*lame_encode_buffer) (lame_global_flags* gfp, const short int buffer_l [],
+ const short int buffer_r [], const int nsamples, unsigned char* mp3buf, const int mp3buf_size);
+ int (*lame_encode_buffer_int)( lame_global_flags* gfp, const int buffer_l [],
+ const int buffer_r [], const int nsamples, unsigned char* mp3buf, const int mp3buf_size);
+ int (*lame_encode_flush)( lame_global_flags * gfp, unsigned char* mp3buf, int size);
+ lame_global_flags* (*lame_init)(void);
+ int (*lame_set_num_channels)(lame_global_flags *, int);
+ int (*lame_set_mode)(lame_global_flags *, MPEG_mode);
+ int (*lame_set_in_samplerate)(lame_global_flags *, int);
+ int (*lame_set_out_samplerate)(lame_global_flags *, int);
+ int (*lame_set_quality)(lame_global_flags *, int);
+ int (*lame_set_VBR)(lame_global_flags *, vbr_mode);
+ int (*lame_set_VBR_quality)(lame_global_flags *, float);
+ int (*lame_set_VBR_mean_bitrate_kbps)(lame_global_flags *, int);
+ int (*lame_set_brate)(lame_global_flags *, int);
+ int (*lame_set_bWriteVbrTag)(lame_global_flags *, int);
+ int (*lame_set_disable_reservoir)(lame_global_flags *, int);
+ int (*lame_init_params)(lame_global_flags *);
+ int (*lame_get_encoder_delay)(const lame_global_flags *);
+ int (*lame_get_framesize)(const lame_global_flags *);
+} LAMESymbols;
+
typedef struct LAMEContext {
AVClass *class;
AVCodecContext *avctx;
@@ -83,7 +123,7 @@ static av_cold int mp3lame_encode_close(AVCodecContext *avctx)
ff_af_queue_close(&s->afq);
- lame_close(s->gfp);
+ LAMESymbols.lame_close(s->gfp);
return 0;
}
@@ -95,52 +135,52 @@ static av_cold int mp3lame_encode_init(AVCodecContext *avctx)
s->avctx = avctx;
/* initialize LAME and get defaults */
- if (!(s->gfp = lame_init()))
+ if (!(s->gfp = LAMESymbols.lame_init()))
return AVERROR(ENOMEM);
- lame_set_num_channels(s->gfp, avctx->channels);
- lame_set_mode(s->gfp, avctx->channels > 1 ? s->joint_stereo ? JOINT_STEREO : STEREO : MONO);
+ LAMESymbols.lame_set_num_channels(s->gfp, avctx->channels);
+ LAMESymbols.lame_set_mode(s->gfp, avctx->channels > 1 ? s->joint_stereo ? JOINT_STEREO : STEREO : MONO);
/* sample rate */
- lame_set_in_samplerate (s->gfp, avctx->sample_rate);
- lame_set_out_samplerate(s->gfp, avctx->sample_rate);
+ LAMESymbols.lame_set_in_samplerate (s->gfp, avctx->sample_rate);
+ LAMESymbols.lame_set_out_samplerate(s->gfp, avctx->sample_rate);
/* algorithmic quality */
if (avctx->compression_level != FF_COMPRESSION_DEFAULT)
- lame_set_quality(s->gfp, avctx->compression_level);
+ LAMESymbols.lame_set_quality(s->gfp, avctx->compression_level);
/* rate control */
if (avctx->flags & CODEC_FLAG_QSCALE) { // VBR
- lame_set_VBR(s->gfp, vbr_default);
- lame_set_VBR_quality(s->gfp, avctx->global_quality / (float)FF_QP2LAMBDA);
+ LAMESymbols.lame_set_VBR(s->gfp, vbr_default);
+ LAMESymbols.lame_set_VBR_quality(s->gfp, avctx->global_quality / (float)FF_QP2LAMBDA);
} else {
if (avctx->bit_rate) {
if (s->abr) { // ABR
- lame_set_VBR(s->gfp, vbr_abr);
- lame_set_VBR_mean_bitrate_kbps(s->gfp, avctx->bit_rate / 1000);
+ LAMESymbols.lame_set_VBR(s->gfp, vbr_abr);
+ LAMESymbols.lame_set_VBR_mean_bitrate_kbps(s->gfp, avctx->bit_rate / 1000);
} else // CBR
- lame_set_brate(s->gfp, avctx->bit_rate / 1000);
+ LAMESymbols.lame_set_brate(s->gfp, avctx->bit_rate / 1000);
}
}
/* do not get a Xing VBR header frame from LAME */
- lame_set_bWriteVbrTag(s->gfp,0);
+ LAMESymbols.lame_set_bWriteVbrTag(s->gfp,0);
/* bit reservoir usage */
- lame_set_disable_reservoir(s->gfp, !s->reservoir);
+ LAMESymbols.lame_set_disable_reservoir(s->gfp, !s->reservoir);
/* set specified parameters */
- if (lame_init_params(s->gfp) < 0) {
+ if (LAMESymbols.lame_init_params(s->gfp) < 0) {
ret = -1;
goto error;
}
/* get encoder delay */
- avctx->initial_padding = lame_get_encoder_delay(s->gfp) + 528 + 1;
+ avctx->initial_padding = LAMESymbols.lame_get_encoder_delay(s->gfp) + 528 + 1;
ff_af_queue_init(avctx, &s->afq);
- avctx->frame_size = lame_get_framesize(s->gfp);
+ avctx->frame_size = LAMESymbols.lame_get_framesize(s->gfp);
/* allocate float sample buffers */
if (avctx->sample_fmt == AV_SAMPLE_FMT_FLTP) {
@@ -192,10 +232,10 @@ static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
if (frame) {
switch (avctx->sample_fmt) {
case AV_SAMPLE_FMT_S16P:
- ENCODE_BUFFER(lame_encode_buffer, int16_t, frame->data);
+ ENCODE_BUFFER(LAMESymbols.lame_encode_buffer, int16_t, frame->data);
break;
case AV_SAMPLE_FMT_S32P:
- ENCODE_BUFFER(lame_encode_buffer_int, int32_t, frame->data);
+ ENCODE_BUFFER(LAMESymbols.lame_encode_buffer_int, int32_t, frame->data);
break;
case AV_SAMPLE_FMT_FLTP:
if (frame->linesize[0] < 4 * FFALIGN(frame->nb_samples, 8)) {
@@ -208,7 +248,7 @@ static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
32768.0f,
FFALIGN(frame->nb_samples, 8));
}
- ENCODE_BUFFER(lame_encode_buffer_float, float, s->samples_flt);
+ ENCODE_BUFFER(LAMESymbols.lame_encode_buffer_float, float, s->samples_flt);
break;
default:
return AVERROR_BUG;
@@ -216,7 +256,7 @@ static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
} else if (!s->afq.frame_alloc) {
lame_result = 0;
} else {
- lame_result = lame_encode_flush(s->gfp, s->buffer + s->buffer_index,
+ lame_result = LAMESymbols.lame_encode_flush(s->gfp, s->buffer + s->buffer_index,
s->buffer_size - s->buffer_index);
}
if (lame_result < 0) {
@@ -274,6 +314,45 @@ static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
return 0;
}
+static av_cold int init_static_data(AVCodec *codec) {
+ struct FuncDef funcDefs[] = {
+ FUNC_DEF(LAMESymbols, lame_init),
+ FUNC_DEF(LAMESymbols, lame_close),
+ FUNC_DEF(LAMESymbols, lame_encode_buffer_float),
+ FUNC_DEF(LAMESymbols, lame_encode_buffer),
+ FUNC_DEF(LAMESymbols, lame_encode_buffer_int),
+ FUNC_DEF(LAMESymbols, lame_encode_flush),
+ FUNC_DEF(LAMESymbols, lame_set_num_channels),
+ FUNC_DEF(LAMESymbols, lame_set_mode),
+ FUNC_DEF(LAMESymbols, lame_set_in_samplerate),
+ FUNC_DEF(LAMESymbols, lame_set_out_samplerate),
+ FUNC_DEF(LAMESymbols, lame_set_quality),
+ FUNC_DEF(LAMESymbols, lame_set_VBR),
+ FUNC_DEF(LAMESymbols, lame_set_VBR_quality),
+ FUNC_DEF(LAMESymbols, lame_set_VBR_mean_bitrate_kbps),
+ FUNC_DEF(LAMESymbols, lame_set_brate),
+ FUNC_DEF(LAMESymbols, lame_set_bWriteVbrTag),
+ FUNC_DEF(LAMESymbols, lame_set_disable_reservoir),
+ FUNC_DEF(LAMESymbols, lame_init_params),
+ FUNC_DEF(LAMESymbols, lame_get_encoder_delay),
+ FUNC_DEF(LAMESymbols, lame_get_framesize),
+ { NULL },
+ };
+
+ /* libopus.0.dylib
+ libz.1.1.3.dylib
+
+ opus-0.dll
+ x264-142.dll
+ vpx-1.dll
+ vpx-1.3.dll
+ vpx-1.3.0.dll
+ */
+ return resolve_symbols(LIBRARY_NAME, &LAMESymbols.dlhandle, funcDefs);
+ }
+
+
+
#define OFFSET(x) offsetof(LAMEContext, x)
#define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
@@ -305,6 +384,7 @@ AVCodec ff_libmp3lame_encoder = {
.type = AVMEDIA_TYPE_AUDIO,
.id = AV_CODEC_ID_MP3,
.priv_data_size = sizeof(LAMEContext),
+ .init_static_data = init_static_data,
.init = mp3lame_encode_init,
.encode2 = mp3lame_encode_frame,
.close = mp3lame_encode_close,
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 1ec5cae..2520e69 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -69,6 +69,25 @@
#include "libavutil/ffversion.h"
const char av_codec_ffversion[] = "FFmpeg version " FFMPEG_VERSION;
+#if CONFIG_DYNAMIC_LOADING
+ #ifdef _WIN32
+ #include <windows.h>
+ #undef EXTERN_C
+ #define AVISYNTH_LIB "avisynth"
+ #else
+ #include <dlfcn.h>
+ #if defined (__APPLE__)
+ #define AVISYNTH_LIB "libavxsynth.dylib"
+ #else
+ #define AVISYNTH_LIB "libavxsynth.so"
+ #endif /* __APPLE__ */
+
+ #define LoadLibrary(x) dlopen(x, RTLD_LAZY)
+ #define GetProcAddress dlsym
+ #define FreeLibrary dlclose
+ #endif /* _WIN32 */
+#endif /* CONFIG_DYNAMIC_LOADING */
+
#if HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS2THREADS
static int default_lockmgr_cb(void **arg, enum AVLockOp op)
{
@@ -201,12 +220,13 @@ av_cold void avcodec_register(AVCodec *codec)
p = last_avcodec;
codec->next = NULL;
+ if (codec->init_static_data)
+ if (codec->init_static_data(codec))
+ return;
+
while(*p || avpriv_atomic_ptr_cas((void * volatile *)p, NULL, codec))
p = &(*p)->next;
last_avcodec = &codec->next;
-
- if (codec->init_static_data)
- codec->init_static_data(codec);
}
#if FF_API_EMU_EDGE
@@ -3544,6 +3564,11 @@ void av_register_hwaccel(AVHWAccel *hwaccel)
{
AVHWAccel **p = last_hwaccel;
hwaccel->next = NULL;
+
+ if (hwaccel->init_static_data)
+ if (hwaccel->init_static_data(hwaccel))
+ return;
+
while(*p || avpriv_atomic_ptr_cas((void * volatile *)p, NULL, hwaccel))
p = &(*p)->next;
last_hwaccel = &hwaccel->next;
@@ -3799,3 +3824,71 @@ const uint8_t *avpriv_find_start_code(const uint8_t *av_restrict p,
return p + 4;
}
+
+int resolve_symbols(const char *library_name, void **dlhandle, FuncDef *func_defs) {
+ FuncDef *defs = func_defs;
+
+#if CONFIG_DYNAMIC_LOADING
+ char *error;
+
+ /*todo we need a usage counter to prevent unregistering when still in use*/
+ if (*dlhandle) {
+ av_log(NULL, AV_LOG_DEBUG, "Library %s already loaded\n", library_name);
+ return 0;
+ }
+
+ *dlhandle = LoadLibrary(library_name);
+ if (!*dlhandle) {
+ av_log(NULL, AV_LOG_DEBUG, "%s\n", dlerror());
+ return -1;
+ }
+ av_log(NULL, AV_LOG_DEBUG, "Library %s successfully loaded\n", library_name);
+
+ while (defs->func_name) {
+#ifndef _WIN32
+ dlerror(); /* Clear any existing error */
+#endif
+ *defs->dest_func_ptr = GetProcAddress(*dlhandle, defs->func_name);
+
+#ifdef _WIN32
+ if (!*defs->dest_func_ptr) {
+ error = [80];
+ snprintf(error, 80, "failed to resolve symbol %s", defs->func_name);
+ }
+#else
+ error = dlerror();
+#endif
+ if (error) {
+ av_log(NULL, AV_LOG_ERROR, "%s\n", error);
+ goto fail;
+ }
+ av_log(NULL, AV_LOG_DEBUG, "Symbol %s successfully resolved in library %s\n", defs->func_name, library_name);
+
+ defs++;
+ }
+ return 0;
+
+fail:
+ FreeLibrary(*dlhandle);
+ *dlhandle = NULL;
+
+ defs = func_defs;
+ while (defs->func_name) {
+ *defs->dest_func_ptr = NULL;
+ defs++;
+ }
+
+ return -1;
+
+#else
+ /* Note: in principle we could use dlopen() to resolve the symbols when
+ * the library is linked in but to support also platforms that don't have
+ * dlopen() we simply assign the function pointers instead.
+ */
+ while (defs->func_name) {
+ *defs->dest_func_ptr = defs->source_func_ptr;
+ defs++;
+ }
+ return 0;
+#endif /* CONFIG_DYNAMIC_LOADING */
+}
diff --git a/libavcodec/vaapi.c b/libavcodec/vaapi.c
index 15531e4..2cf85d7 100644
--- a/libavcodec/vaapi.c
+++ b/libavcodec/vaapi.c
@@ -30,12 +30,51 @@
* @{
*/
+#define TOSTRING(x) #x
+#define STR(x) TOSTRING(x)
+#ifdef _WIN32
+#define LIBRARY_PREFIX
+#else
+#define LIBRARY_PREFIX lib
+#endif
+
+#define LIBRARY_SHORT_NAME va
+#define LIBRARY_NAME STR(LIBRARY_PREFIX) STR(LIBRARY_SHORT_NAME) SLIBSUF
+
+static struct VAAPISymbols {
+ void *dlhandle;
+
+ VAStatus (*vaDestroyBuffer)(VADisplay dpy, VABufferID buffer_id);
+ VAStatus (*vaUnmapBuffer)(VADisplay dpy, VABufferID buf_id);
+ VAStatus (*vaBeginPicture)(VADisplay dpy, VAContextID context, VASurfaceID render_target);
+ VAStatus (*vaRenderPicture)(VADisplay dpy, VAContextID context, VABufferID *buffers, int num_buffers);
+ VAStatus (*vaEndPicture)(VADisplay dpy, VAContextID context);
+ VAStatus (*vaCreateBuffer)(VADisplay dpy, VAContextID context, VABufferType type, unsigned int size,
+ unsigned int num_elements, void *data, VABufferID *buf_id);
+ VAStatus (*vaMapBuffer)(VADisplay dpy, VABufferID buf_id, void **pbuf);
+} VAAPISymbols;
+
+av_cold int init_static_data(AVHWAccel *hwaccel) {
+ struct FuncDef funcDefs[] = {
+ FUNC_DEF(VAAPISymbols, vaDestroyBuffer),
+ FUNC_DEF(VAAPISymbols, vaUnmapBuffer),
+ FUNC_DEF(VAAPISymbols, vaBeginPicture),
+ FUNC_DEF(VAAPISymbols, vaRenderPicture),
+ FUNC_DEF(VAAPISymbols, vaEndPicture),
+ FUNC_DEF(VAAPISymbols, vaCreateBuffer),
+ FUNC_DEF(VAAPISymbols, vaMapBuffer),
+ { NULL },
+ };
+
+ return resolve_symbols(LIBRARY_NAME, &VAAPISymbols.dlhandle, funcDefs);
+}
+
static void destroy_buffers(VADisplay display, VABufferID *buffers, unsigned int n_buffers)
{
unsigned int i;
for (i = 0; i < n_buffers; i++) {
if (buffers[i]) {
- vaDestroyBuffer(display, buffers[i]);
+ VAAPISymbols.vaDestroyBuffer(display, buffers[i]);
buffers[i] = 0;
}
}
@@ -49,33 +88,33 @@ int ff_vaapi_render_picture(struct vaapi_context *vactx, VASurfaceID surface)
if (!vactx->pic_param_buf_id)
return 0;
- vaUnmapBuffer(vactx->display, vactx->pic_param_buf_id);
+ VAAPISymbols.vaUnmapBuffer(vactx->display, vactx->pic_param_buf_id);
va_buffers[n_va_buffers++] = vactx->pic_param_buf_id;
if (vactx->iq_matrix_buf_id) {
- vaUnmapBuffer(vactx->display, vactx->iq_matrix_buf_id);
+ VAAPISymbols.vaUnmapBuffer(vactx->display, vactx->iq_matrix_buf_id);
va_buffers[n_va_buffers++] = vactx->iq_matrix_buf_id;
}
if (vactx->bitplane_buf_id) {
- vaUnmapBuffer(vactx->display, vactx->bitplane_buf_id);
+ VAAPISymbols.vaUnmapBuffer(vactx->display, vactx->bitplane_buf_id);
va_buffers[n_va_buffers++] = vactx->bitplane_buf_id;
}
- if (vaBeginPicture(vactx->display, vactx->context_id,
+ if (VAAPISymbols.vaBeginPicture(vactx->display, vactx->context_id,
surface) != VA_STATUS_SUCCESS)
return -1;
- if (vaRenderPicture(vactx->display, vactx->context_id,
+ if (VAAPISymbols.vaRenderPicture(vactx->display, vactx->context_id,
va_buffers, n_va_buffers) != VA_STATUS_SUCCESS)
return -1;
- if (vaRenderPicture(vactx->display, vactx->context_id,
+ if (VAAPISymbols.vaRenderPicture(vactx->display, vactx->context_id,
vactx->slice_buf_ids,
vactx->n_slice_buf_ids) != VA_STATUS_SUCCESS)
return -1;
- if (vaEndPicture(vactx->display, vactx->context_id) != VA_STATUS_SUCCESS)
+ if (VAAPISymbols.vaEndPicture(vactx->display, vactx->context_id) != VA_STATUS_SUCCESS)
return -1;
return 0;
@@ -98,7 +137,7 @@ int ff_vaapi_commit_slices(struct vaapi_context *vactx)
vactx->slice_buf_ids = slice_buf_ids;
slice_param_buf_id = 0;
- if (vaCreateBuffer(vactx->display, vactx->context_id,
+ if (VAAPISymbols.vaCreateBuffer(vactx->display, vactx->context_id,
VASliceParameterBufferType,
vactx->slice_param_size,
vactx->slice_count, vactx->slice_params,
@@ -107,7 +146,7 @@ int ff_vaapi_commit_slices(struct vaapi_context *vactx)
vactx->slice_count = 0;
slice_data_buf_id = 0;
- if (vaCreateBuffer(vactx->display, vactx->context_id,
+ if (VAAPISymbols.vaCreateBuffer(vactx->display, vactx->context_id,
VASliceDataBufferType,
vactx->slice_data_size,
1, (void *)vactx->slice_data,
@@ -126,9 +165,9 @@ static void *alloc_buffer(struct vaapi_context *vactx, int type, unsigned int si
void *data = NULL;
*buf_id = 0;
- if (vaCreateBuffer(vactx->display, vactx->context_id,
+ if (VAAPISymbols.vaCreateBuffer(vactx->display, vactx->context_id,
type, size, 1, NULL, buf_id) == VA_STATUS_SUCCESS)
- vaMapBuffer(vactx->display, *buf_id, &data);
+ VAAPISymbols.vaMapBuffer(vactx->display, *buf_id, &data);
return data;
}
diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
index 8eb8a66..8860c1a 100644
--- a/libavcodec/vaapi_h264.c
+++ b/libavcodec/vaapi_h264.c
@@ -356,6 +356,7 @@ AVHWAccel ff_h264_vaapi_hwaccel = {
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_H264,
.pix_fmt = AV_PIX_FMT_VAAPI_VLD,
+ .init_static_data = init_static_data,
.start_frame = vaapi_h264_start_frame,
.end_frame = vaapi_h264_end_frame,
.decode_slice = vaapi_h264_decode_slice,
diff --git a/libavcodec/vaapi_internal.h b/libavcodec/vaapi_internal.h
index 918c718..8783a0d 100644
--- a/libavcodec/vaapi_internal.h
+++ b/libavcodec/vaapi_internal.h
@@ -35,6 +35,8 @@
* @{
*/
+av_cold int init_static_data(AVHWAccel *hwaccel);
+
/** Extract VASurfaceID from an AVFrame */
static inline VASurfaceID ff_vaapi_get_surface_id(AVFrame *pic)
{
diff --git a/libavcodec/vaapi_mpeg2.c b/libavcodec/vaapi_mpeg2.c
index 0d9059b..11ff207 100644
--- a/libavcodec/vaapi_mpeg2.c
+++ b/libavcodec/vaapi_mpeg2.c
@@ -138,6 +138,7 @@ AVHWAccel ff_mpeg2_vaapi_hwaccel = {
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_MPEG2VIDEO,
.pix_fmt = AV_PIX_FMT_VAAPI_VLD,
+ .init_static_data = init_static_data,
.start_frame = vaapi_mpeg2_start_frame,
.end_frame = ff_vaapi_mpeg_end_frame,
.decode_slice = vaapi_mpeg2_decode_slice,
diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c
index bba46d3..d1b0f5e 100644
--- a/libavcodec/vaapi_vc1.c
+++ b/libavcodec/vaapi_vc1.c
@@ -339,6 +339,7 @@ AVHWAccel ff_wmv3_vaapi_hwaccel = {
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_WMV3,
.pix_fmt = AV_PIX_FMT_VAAPI_VLD,
+ .init_static_data = init_static_data,
.start_frame = vaapi_vc1_start_frame,
.end_frame = ff_vaapi_mpeg_end_frame,
.decode_slice = vaapi_vc1_decode_slice,
@@ -350,6 +351,7 @@ AVHWAccel ff_vc1_vaapi_hwaccel = {
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_VC1,
.pix_fmt = AV_PIX_FMT_VAAPI_VLD,
+ .init_static_data = init_static_data,
.start_frame = vaapi_vc1_start_frame,
.end_frame = ff_vaapi_mpeg_end_frame,
.decode_slice = vaapi_vc1_decode_slice,
_______________________________________________
ffmpeg-devel mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel