static void _findMetaXMLfiles(META_ROOT *meta, const char *device_path) { BD_DIR_H *dir; BD_DIRENT ent; char *path = NULL; path = str_printf("%s" DIR_SEP "BDMV" DIR_SEP "META" DIR_SEP "DL", device_path); dir = dir_open(path); if (dir == NULL) { BD_DEBUG(DBG_DIR, "Failed to open meta dir %s\n", path); X_FREE(path); return; } int res; for (res = dir_read(dir, &ent); !res; res = dir_read(dir, &ent)) { if (ent.d_name[0] == '.') continue; else if (ent.d_name != NULL && strncasecmp(ent.d_name, "bdmt_", 5) == 0) { uint8_t i = meta->dl_count; meta->dl_count++; meta->dl_entries = realloc(meta->dl_entries, (meta->dl_count*sizeof(META_DL))); meta->dl_entries[i].filename = str_dup(ent.d_name); strncpy(meta->dl_entries[i].language_code, ent.d_name+5,3); meta->dl_entries[i].language_code[3] = '\0'; str_tolower(meta->dl_entries[i].language_code); } } dir_close(dir); X_FREE(path); }
void meta_free(META_ROOT **p) { (void)p; #ifdef HAVE_LIBXML2 if (p && *p) { uint8_t i; for (i = 0; i < (*p)->dl_count; i++) { uint32_t t; for (t = 0; t < (*p)->dl_entries[i].toc_count; t++) { XML_FREE((*p)->dl_entries[i].toc_entries[t].title_name); } for (t = 0; t < (*p)->dl_entries[i].thumb_count; t++) { XML_FREE((*p)->dl_entries[i].thumbnails[t].path); } X_FREE((*p)->dl_entries[i].toc_entries); X_FREE((*p)->dl_entries[i].thumbnails); X_FREE((*p)->dl_entries[i].filename); XML_FREE((*p)->dl_entries[i].di_name); XML_FREE((*p)->dl_entries[i].di_alternative); } X_FREE((*p)->dl_entries); X_FREE(*p); } #endif }
static int _load_aes_keys(bdplus_aes_key_t *aes_keys, const char *base) { char *path = str_printf("%s/" AES_KEYS_FILE, base); uint8_t *keys; uint32_t size = 0; uint32_t num_keys, ii; if (!path) { return -1; } keys = (uint8_t *)file_load(path, &size); X_FREE(path); num_keys = size / 16; if (num_keys > MAX_AES_KEYS) { num_keys = MAX_AES_KEYS; } if (num_keys * 16 != size) { BD_DEBUG(DBG_FILE | DBG_CRIT, "Invalid AES key file size\n"); } for (ii = 0; ii < num_keys; ii++) { memcpy(aes_keys[ii].key, keys + 16*ii, 16); } X_FREE(keys); return num_keys > 6 ? (int)num_keys : -1; }
void indx_free(INDX_ROOT **p) { if (p && *p) { X_FREE((*p)->titles); X_FREE(*p); } }
static inline char *_utf8_to_cp(const char *utf8) { int wlen = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0); if (wlen <= 0) { return NULL; } wchar_t *wide = (wchar_t *)malloc(wlen * sizeof(wchar_t)); if (!wide) { return NULL; } if (!MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wide, wlen)) { X_FREE(wide); return NULL; } size_t len = WideCharToMultiByte(CP_ACP, 0, wide, -1, NULL, 0, NULL, NULL); if (len <= 0) { X_FREE(wide); return NULL; } char *out = (char *)malloc(len); if (out != NULL) { if (!WideCharToMultiByte(CP_ACP, 0, wide, -1, out, len, NULL, NULL)) { X_FREE(out); } } X_FREE(wide); return out; }
void bd_registers_free(BD_REGISTERS *p) { if (p) { bd_mutex_destroy(&p->mutex); X_FREE(p->cb); } X_FREE(p); }
static void _stream_close(BD_FILE_H *fp) { DEC_STREAM *st = (DEC_STREAM *)fp->internal; if (st->bdplus) { libbdplus_m2ts_close(&st->bdplus); } st->fp->close(st->fp); X_FREE(fp->internal); X_FREE(fp); }
static void _parseManifestNode(xmlNode * a_node, META_DL *disclib) { xmlNode *cur_node = NULL; xmlChar *tmp; for (cur_node = a_node; cur_node; cur_node = cur_node->next) { if (cur_node->type == XML_ELEMENT_NODE) { if (xmlStrEqual(cur_node->parent->name, BAD_CAST_CONST "title")) { if (xmlStrEqual(cur_node->name, BAD_CAST_CONST "name")) { disclib->di_name = (char*)xmlNodeGetContent(cur_node); } if (xmlStrEqual(cur_node->name, BAD_CAST_CONST "alternative")) { disclib->di_alternative = (char*)xmlNodeGetContent(cur_node); } if (xmlStrEqual(cur_node->name, BAD_CAST_CONST "numSets")) { disclib->di_num_sets = atoi((char*)(tmp = xmlNodeGetContent(cur_node))); xmlFree(tmp); } if (xmlStrEqual(cur_node->name, BAD_CAST_CONST "setNumber")) { disclib->di_set_number = atoi((char*)(tmp = xmlNodeGetContent(cur_node))); xmlFree(tmp); } } else if (xmlStrEqual(cur_node->parent->name, BAD_CAST_CONST "tableOfContents")) { if (xmlStrEqual(cur_node->name, BAD_CAST_CONST "titleName") && (tmp = xmlGetProp(cur_node, BAD_CAST_CONST "titleNumber"))) { int i = disclib->toc_count; disclib->toc_count++; disclib->toc_entries = realloc(disclib->toc_entries, (disclib->toc_count*sizeof(META_TITLE))); disclib->toc_entries[i].title_number = atoi((const char*)tmp); disclib->toc_entries[i].title_name = (char*)xmlNodeGetContent(cur_node); X_FREE(tmp); } } else if (xmlStrEqual(cur_node->parent->name, BAD_CAST_CONST "description")) { if (xmlStrEqual(cur_node->name, BAD_CAST_CONST "thumbnail") && (tmp = xmlGetProp(cur_node, BAD_CAST_CONST "href"))) { uint8_t i = disclib->thumb_count; disclib->thumb_count++; disclib->thumbnails = realloc(disclib->thumbnails, (disclib->thumb_count*sizeof(META_THUMBNAIL))); disclib->thumbnails[i].path = (char *)tmp; if ((tmp = xmlGetProp(cur_node, BAD_CAST_CONST "size"))) { int x = 0, y = 0; sscanf((const char*)tmp, "%ix%i", &x, &y); disclib->thumbnails[i].xres = x; disclib->thumbnails[i].yres = y; X_FREE(tmp); } else { disclib->thumbnails[i].xres = disclib->thumbnails[i].yres = -1; } } } } _parseManifestNode(cur_node->children, disclib); } }
static int _load_ram(bdplus_ram_t **p, const char *base, uint32_t address, const char *file) { bdplus_ram_t *ram; if (!*p) { *p = calloc(1, sizeof(bdplus_ram_t)); if (!*p) { return 0; } } ram = *p; void *tmp = ram->area; ram->area = realloc(ram->area, (ram->num_area + 1) * sizeof(*ram->area)); if (!ram->area) { X_FREE(tmp); BD_DEBUG(DBG_CRIT, "out of memory\n"); return 0; } memset(&ram->area[ram->num_area], 0, sizeof(ram->area[ram->num_area])); ram->area[ram->num_area].start_address = address; if (!strcmp(file, "PSR")) { ram->area[ram->num_area].type = MEM_TYPE_PSR; BD_DEBUG(DBG_BDPLUS, "mapped PSR register file to 0x%x\n", address); } else if (!strcmp(file, "GPR")) { ram->area[ram->num_area].type = MEM_TYPE_PSR; BD_DEBUG(DBG_BDPLUS, "mapped GPR register file to 0x%x\n", address); } else { /* load from file */ char *path = str_printf("%s/%s", base, file); if (!path) { return 0; } ram->area[ram->num_area].memory = file_load(path, &ram->area[ram->num_area].size); ram->area[ram->num_area].mem = ram->area[ram->num_area].memory; X_FREE(path); if (!ram->area[ram->num_area].mem) { return 0; } BD_DEBUG(DBG_BDPLUS, "mapped %d bytes from %s to 0x%x\n", ram->area[ram->num_area].size, file, address); } ram->num_area++; return 1; }
static void _ram_free(bdplus_ram_t **pp) { if (pp && *pp) { unsigned int ii; for (ii = 0; ii < (*pp)->num_area; ii++) { X_FREE((*pp)->area[ii].memory); } X_FREE((*pp)->area); X_FREE(*pp); } }
static void _dev_free(bdplus_dev_t **pp) { if (pp && *pp) { unsigned ii; for (ii = 0; ii < MAX_DEV_DISCOVERY; ii++) { X_FREE((*pp)[ii].mem); } X_FREE(*pp); } }
void bdplus_config_free(bdplus_config_t **p_config) { if (*p_config) { _ram_free(&(*p_config)->ram); _dev_free(&(*p_config)->dev); X_FREE((*p_config)->aes_keys); X_FREE((*p_config)->ecdsa_keys); X_FREE(*p_config); } }
static void _clean_effect_sequence(BD_IG_EFFECT_SEQUENCE *p) { unsigned ii; for (ii = 0; ii < p->num_effects; ii++) { _clean_effect(&p->effect[ii]); } X_FREE(p->effect); X_FREE(p->window); }
void mobj_free(MOBJ_OBJECTS **p) { if (p && *p) { int i; for (i = 0 ; i < (*p)->num_objects; i++) { X_FREE((*p)->objects[i].cmds); } X_FREE((*p)->objects); X_FREE(*p); } }
BDPLUS_FILE_H *file_open_default(void *handle, const char* file_name) { const char *device_root = handle; char *file_path; BDPLUS_FILE_H *file; FILE *fp; file_path = str_printf("%s"DIR_SEP"%s", device_root, file_name); if (!file_path) { BD_DEBUG(DBG_CRIT, "out of memory\n"); return NULL; } fp = fopen(file_path, "rb"); X_FREE(file_path); if (!fp) { return NULL; } file = calloc(1, sizeof(BDPLUS_FILE_H)); file->internal = fp; file->close = _file_close; file->seek = _file_seek; file->read = _file_read; return file; }
void pg_display_set_free(PG_DISPLAY_SET **s) { if (s && *s) { unsigned ii; for (ii = 0; ii < (*s)->num_object; ii++) { pg_clean_object(&(*s)->object[ii]); } ig_free_interactive(&(*s)->ics); X_FREE((*s)->window); X_FREE((*s)->object); X_FREE((*s)->palette); X_FREE(*s); } }
static void _file_close(BDPLUS_FILE_H *file) { if (file) { fclose((FILE *)file->internal); X_FREE(file); } }
static const char *_bdj_buda_root(BDJ_STORAGE *storage) { const char *root; char *cache_home; if (storage->no_persistent_storage) { return NULL; } if (!storage->cache_root) { root = getenv("LIBBLURAY_CACHE_ROOT"); if (root) { return root; } cache_home = file_get_cache_home(); if (cache_home) { storage->cache_root = str_printf("%s" DIR_SEP "bluray" DIR_SEP "bluray.bindingunit.root" DIR_SEP, cache_home); X_FREE(cache_home); BD_DEBUG(DBG_BDJ, "LIBBLURAY_CACHE_ROOT not set, using %s\n", storage->cache_root); } if (!storage->cache_root) { BD_DEBUG(DBG_BDJ | DBG_CRIT, "WARNING: BD-J cache root not set\n"); } } return storage->cache_root; }
void ig_free_interactive(BD_IG_INTERACTIVE **p) { if (p && *p) { _clean_interactive_composition(&(*p)->interactive_composition); X_FREE(*p); } }
void pg_free_composition(BD_PG_COMPOSITION **p) { if (p && *p) { pg_clean_composition(*p); X_FREE(*p); } }
void m2ts_demux_free(M2TS_DEMUX **p) { if (p && *p) { pes_buffer_free(&(*p)->buf); X_FREE(*p); } }
static int _save_page_state(GRAPHICS_CONTROLLER *gc) { if (!gc->bog_data) { GC_ERROR("_save_page_state(): no bog data !\n"); return -1; } PG_DISPLAY_SET *s = gc->igs; BD_IG_PAGE *page = NULL; unsigned page_id = bd_psr_read(gc->regs, PSR_MENU_PAGE_ID); unsigned ii; page = _find_page(&s->ics->interactive_composition, page_id); if (!page) { GC_ERROR("_save_page_state(): unknown page #%d (have %d pages)\n", page_id, s->ics->interactive_composition.num_pages); return -1; } /* copy enabled button state, clear draw state */ X_FREE(gc->saved_bog_data); gc->saved_bog_data = calloc(page->num_bogs, sizeof(*gc->saved_bog_data)); for (ii = 0; ii < page->num_bogs; ii++) { gc->saved_bog_data[ii].enabled_button = gc->bog_data[ii].enabled_button; gc->saved_bog_data[ii].animate_indx = gc->bog_data[ii].animate_indx >= 0 ? 0 : -1; } return 1; }
void bdj_close(BDJAVA *bdjava) { JNIEnv *env; int attach; jclass shutdown_class; jmethodID shutdown_id; if (!bdjava) { return; } if ((*bdjava->jvm)->GetEnv(bdjava->jvm, (void**)&env, JNI_VERSION_1_6) != JNI_OK) { (*bdjava->jvm)->AttachCurrentThread(bdjava->jvm, (void**)&env, NULL); attach = 1; } if (bdj_get_method(env, &shutdown_class, &shutdown_id, "org/videolan/Libbluray", "shutdown", "()V")) { (*env)->CallStaticVoidMethod(env, shutdown_class, shutdown_id); (*env)->DeleteLocalRef(env, shutdown_class); } if (attach) { (*bdjava->jvm)->DetachCurrentThread(bdjava->jvm); } (*bdjava->jvm)->DestroyJavaVM(bdjava->jvm); dl_dlclose(bdjava->h_libjvm); X_FREE(bdjava); }
/* Resize the string */ int str_resize(str_t *str, size_t reqlen) { size_t nsize; char *nstr; if (reqlen <= str->size) return STR_TRUE; /* Double the size each time, amortized cost is 2 */ nsize = 1; while (nsize < reqlen) nsize <<= 1; nstr = (char*)X_MALLOC(nsize); if (!nstr) return STR_FALSE; if (str->c_str) { memcpy(nstr, str->c_str, str->size); if (str->is_owner) X_FREE(str->c_str); } str->c_str = nstr; str->is_owner = 1; str->size = nsize; return STR_TRUE; }
static void dir_close_posix(BD_DIR_H *dir) { if (dir) { #if defined(_WIN32) dir_data_t *priv = dir->internal; _findclose(priv->handle); X_FREE(dir->internal); #else closedir((DIR *)dir->internal); #endif BD_DEBUG(DBG_DIR, "Closed POSIX dir (%p)\n", dir); X_FREE(dir); } }
static char *_avchd_file_name(const char *rel_path) { static const char map[][2][6] = { { ".mpls", ".MPL" }, { ".clpi", ".CPI" }, { ".m2ts", ".MTS" }, { ".bdmv", ".BDM" }, }; char *avchd_path = str_dup(rel_path); char *name = avchd_path ? strrchr(avchd_path, DIR_SEP_CHAR) : NULL; char *dot = name ? strrchr(name, '.') : NULL; size_t i; if (dot) { /* take up to 8 chars from file name */ for (i = 0; *name && name < dot && i < 9; i++, name++) { *name = toupper(*name); } /* convert extension */ for (i = 0; i < sizeof(map) / sizeof(map[0]); i++) { if (!strcmp(dot, map[i][0])) { strcpy(name, map[i][1]); return avchd_path; } } } /* failed */ X_FREE(avchd_path); return NULL; }
static BD_DIR_H *_combine_dirs(BD_DIR_H *ovl, BD_DIR_H *rom) { BD_DIR_H *dp = calloc(1, sizeof(BD_DIR_H)); BD_DIRENT entry; if (dp) { dp->read = _comb_dir_read; dp->close = _comb_dir_close; dp->internal = calloc(1, sizeof(COMB_DIR)); if (!dp->internal) { X_FREE(dp); goto out; } while (!dir_read(ovl, &entry)) { _comb_dir_append(dp, &entry); } while (!dir_read(rom, &entry)) { _comb_dir_append(dp, &entry); } } out: dir_close(ovl); dir_close(rom); return dp; }
char *str_printf(const char *fmt, ...) { /* Guess we need no more than 100 bytes. */ va_list ap; int len; int size = 100; char *tmp, *str = NULL; while (1) { tmp = realloc(str, size); if (tmp == NULL) { X_FREE(str); return NULL; } str = tmp; /* Try to print in the allocated space. */ va_start(ap, fmt); len = vsnprintf(str, size, fmt, ap); va_end(ap); /* If that worked, return the string. */ if (len > -1 && len < size) { return str; } /* Else try again with more space. */ if (len > -1) /* glibc 2.1 */ size = len+1; /* precisely what is needed */ else /* glibc 2.0 */ size *= 2; /* twice the old size */ } }
BD_AACS *libaacs_load(void) { BD_AACS *p = calloc(1, sizeof(BD_AACS)); p->h_libaacs = _open_libaacs(); if (!p->h_libaacs) { X_FREE(p); return NULL; } BD_DEBUG(DBG_BLURAY, "Loading aacs library (%p)\n", p->h_libaacs); *(void **)(&p->decrypt_unit) = dl_dlsym(p->h_libaacs, "aacs_decrypt_unit"); *(void **)(&p->get_vid) = dl_dlsym(p->h_libaacs, "aacs_get_vid"); *(void **)(&p->get_pmsn) = dl_dlsym(p->h_libaacs, "aacs_get_pmsn"); *(void **)(&p->get_device_binding_id) = dl_dlsym(p->h_libaacs, "aacs_get_device_binding_id"); *(void **)(&p->get_device_nonce) = dl_dlsym(p->h_libaacs, "aacs_get_device_nonce"); if (!p->decrypt_unit) { BD_DEBUG(DBG_BLURAY | DBG_CRIT, "libaacs dlsym failed! (%p)\n", p->h_libaacs); libaacs_unload(&p); return NULL; } BD_DEBUG(DBG_BLURAY, "Loaded libaacs (%p)\n", p->h_libaacs); if (file_open != file_open_default()) { BD_DEBUG(DBG_BLURAY, "Registering libaacs filesystem handler %p (%p)\n", (void *)(intptr_t)file_open, p->h_libaacs); DL_CALL(p->h_libaacs, aacs_register_file, file_open); } return p; }
BD_FILE_H *dec_open_stream(BD_DEC *dec, BD_FILE_H *fp, uint32_t clip_id) { DEC_STREAM *st; BD_FILE_H *p = calloc(1, sizeof(BD_FILE_H)); if (!p) { return NULL; } st = calloc(1, sizeof(DEC_STREAM)); if (!st) { X_FREE(p); return NULL; } st->fp = fp; if (dec->bdplus) { st->bdplus = libbdplus_m2ts(dec->bdplus, clip_id, 0); } if (dec->aacs) { st->aacs = dec->aacs; if (!dec->use_menus) { /* There won't be title events --> need to manually reset AACS CPS */ libaacs_select_title(dec->aacs, 0xffff); } } p->internal = st; p->read = _stream_read; p->seek = _stream_seek; p->tell = _stream_tell; p->close = _stream_close; return p; }