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 ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel