/* load, init and query */ static int xacodec_load(sh_video_t *sh, char *filename) { vd_xanim_ctx *priv = sh->context; void *(*what_the)(); char *error; XAVID_MOD_HDR *mod_hdr; XAVID_FUNC_HDR *func; int i; // priv->file_handler = dlopen(filename, RTLD_NOW|RTLD_GLOBAL); priv->file_handler = dlopen(filename, RTLD_LAZY); if (!priv->file_handler) { error = dlerror(); if (error) mp_msg(MSGT_DECVIDEO, MSGL_FATAL, "xacodec: failed to dlopen %s while %s\n", filename, error); else mp_msg(MSGT_DECVIDEO, MSGL_FATAL, "xacodec: failed to dlopen %s\n", filename); return 0; } what_the = dlsym(priv->file_handler, "What_The"); if ((error = dlerror()) != NULL) { mp_msg(MSGT_DECVIDEO, MSGL_FATAL, "xacodec: failed to init %s while %s\n", filename, error); dlclose(priv->file_handler); return 0; } mod_hdr = what_the(); if (!mod_hdr) { mp_msg(MSGT_DECVIDEO, MSGL_FATAL, "xacodec: initializer function failed in %s\n", filename); dlclose(priv->file_handler); return 0; } mp_msg(MSGT_DECVIDEO, MSGL_V, "=== XAnim Codec ===\n"); mp_msg(MSGT_DECVIDEO, MSGL_V, " Filename: %s (API revision: %x)\n", filename, mod_hdr->api_rev); mp_msg(MSGT_DECVIDEO, MSGL_V, " Codec: %s. Rev: %s\n", mod_hdr->desc, mod_hdr->rev); if (mod_hdr->copyright) mp_msg(MSGT_DECVIDEO, MSGL_V, " %s\n", mod_hdr->copyright); if (mod_hdr->mod_author) mp_msg(MSGT_DECVIDEO, MSGL_V, " Module Author(s): %s\n", mod_hdr->mod_author); if (mod_hdr->authors) mp_msg(MSGT_DECVIDEO, MSGL_V, " Codec Author(s): %s\n", mod_hdr->authors); if (mod_hdr->api_rev > XAVID_API_REV) { mp_msg(MSGT_DECVIDEO, MSGL_FATAL, "xacodec: not supported api revision (%d) in %s\n", mod_hdr->api_rev, filename); dlclose(priv->file_handler); return 0; } func = mod_hdr->funcs; if (!func) { mp_msg(MSGT_DECVIDEO, MSGL_FATAL, "xacodec: function table error in %s\n", filename); dlclose(priv->file_handler); return 0; } mp_msg(MSGT_DECVIDEO, MSGL_DBG2, "Exported functions by codec: [functable: %p entries: %d]\n", mod_hdr->funcs, mod_hdr->num_funcs); for (i = 0; i < (int)mod_hdr->num_funcs; i++) { mp_msg(MSGT_DECVIDEO, MSGL_DBG2, " %d: %d %d [iq:%p d:%p]\n", i, func[i].what, func[i].id, func[i].iq_func, func[i].dec_func); if (func[i].what & XAVID_AVI_QUERY) { mp_msg(MSGT_DECVIDEO, MSGL_DBG2, " %p: avi init/query func (id: %d)\n", func[i].iq_func, func[i].id); priv->iq_func = (void *)func[i].iq_func; } if (func[i].what & XAVID_QT_QUERY) { mp_msg(MSGT_DECVIDEO, MSGL_DBG2, " %p: qt init/query func (id: %d)\n", func[i].iq_func, func[i].id); priv->iq_func = (void *)func[i].iq_func; } if (func[i].what & XAVID_DEC_FUNC) { mp_msg(MSGT_DECVIDEO, MSGL_DBG2, " %p: decoder func (init/query: %p) (id: %d)\n", func[i].dec_func, func[i].iq_func, func[i].id); priv->dec_func = (void *)func[i].dec_func; } } return 1; }
static int init_xadll(bgav_stream_t * s) { void *(*what_the)(); XAVID_MOD_HDR *mod_hdr; XAVID_FUNC_HDR *func; XA_CODEC_HDR codec_hdr; int i; xanim_priv_t * priv; char dll_filename[PATH_MAX]; priv = calloc(1, sizeof(*priv)); sprintf(dll_filename, "%s/%s", bgav_dll_path_xanim, "vid_3ivX.xa"); priv->dll_handle = dlopen(dll_filename, RTLD_NOW); if(!priv->dll_handle) { bgav_log(s->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "Cannot open dll %s: %s", dll_filename, dlerror()); goto fail; } what_the = dlsym(priv->dll_handle, "What_The"); if(!what_the) { bgav_log(s->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "failed to init %s", dlerror()); goto fail; } mod_hdr = what_the(); if(!mod_hdr) { bgav_log(s->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "initializer function failed"); goto fail; } if (mod_hdr->api_rev > XAVID_API_REV) { bgav_log(s->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "Unsupported api revision (%d)", mod_hdr->api_rev); goto fail; } func = mod_hdr->funcs; if (!func) { bgav_log(s->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "function table error"); goto fail; } for (i = 0; i < (int)mod_hdr->num_funcs; i++) { if (func[i].what & XAVID_AVI_QUERY) { priv->iq_func = (void *)func[i].iq_func; } if (func[i].what & XAVID_QT_QUERY) { priv->iq_func = (void *)func[i].iq_func; } if (func[i].what & XAVID_DEC_FUNC) { priv->dec_func = (void *)func[i].dec_func; } } codec_hdr.xapi_rev = XAVID_API_REV; codec_hdr.anim_hdr = malloc(4096); codec_hdr.description = "Description"; codec_hdr.compression = s->fourcc; codec_hdr.decoder = NULL; codec_hdr.x = s->data.video.format.image_width; /* ->disp_w */ codec_hdr.y = s->data.video.format.image_height; /* ->disp_h */ /* extra fields to store palette */ codec_hdr.avi_ctab_flag = 0; codec_hdr.avi_read_ext = NULL; codec_hdr.extra = NULL; codec_hdr.depth = 12; if(priv->iq_func(&codec_hdr) != CODEC_SUPPORTED) { bgav_log(s->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "Codec not supported"); goto fail; } priv->dec_func = (void *)codec_hdr.decoder; priv->decinfo.cmd = 0; priv->decinfo.skip_flag = 0; priv->decinfo.imagex = priv->decinfo.xe = codec_hdr.x; priv->decinfo.imagey = priv->decinfo.ye = codec_hdr.y; priv->decinfo.imaged = codec_hdr.depth; priv->decinfo.chdr = NULL; priv->decinfo.map_flag = 0; /* xaFALSE */ priv->decinfo.map = NULL; priv->decinfo.xs = priv->decinfo.ys = 0; priv->decinfo.special = 0; priv->decinfo.extra = codec_hdr.extra; s->decoder_priv = priv; s->data.video.format.pixelformat = GAVL_YUV_420_P; gavl_metadata_set(&s->m, GAVL_META_FORMAT, "3ivx"); free(codec_hdr.anim_hdr); return 1; fail: if(codec_hdr.anim_hdr) free(codec_hdr.anim_hdr); return 0; }