static int _parse_index(BITSTREAM *bs, INDX_ROOT *index) { uint32_t index_len, i; index_len = bs_read(bs, 32); /* TODO: check if goes to extension data area */ if ((bs_end(bs) - bs_pos(bs))/8 < (int64_t)index_len) { BD_DEBUG(DBG_NAV | DBG_CRIT, "index.bdmv: invalid index_len %d !\n", index_len); return 0; } if (!_parse_playback_obj(bs, &index->first_play) || !_parse_playback_obj(bs, &index->top_menu)) { return 0; } index->num_titles = bs_read(bs, 16); if (!index->num_titles) { BD_DEBUG(DBG_CRIT, "empty index\n"); return 0; } index->titles = calloc(index->num_titles, sizeof(INDX_TITLE)); if (!index->titles) { BD_DEBUG(DBG_CRIT, "out of memory\n"); return 0; } if (bs_avail(bs)/(12*8) < index->num_titles) { BD_DEBUG(DBG_HDMV|DBG_CRIT, "index.bdmv: unexpected EOF\n"); return 0; } for (i = 0; i < index->num_titles; i++) { index->titles[i].object_type = bs_read(bs, 2); index->titles[i].access_type = bs_read(bs, 2); bs_skip(bs, 28); switch (index->titles[i].object_type) { case indx_object_type_hdmv: if (!_parse_hdmv_obj(bs, &index->titles[i].hdmv)) return 0; break; case indx_object_type_bdj: if (!_parse_bdj_obj(bs, &index->titles[i].bdj)) return 0; break; default: BD_DEBUG(DBG_NAV | DBG_CRIT, "index.bdmv: unknown object type %d (#%d)\n", index->titles[i].object_type, i); return 0; } } return 1; }
static int _parse_playback_obj(BITSTREAM *bs, INDX_PLAY_ITEM *obj) { obj->object_type = bs_read(bs, 2); bs_skip(bs, 30); switch (obj->object_type) { case indx_object_type_hdmv: return _parse_hdmv_obj(bs, &obj->hdmv); case indx_object_type_bdj: return _parse_bdj_obj(bs, &obj->bdj); } BD_DEBUG(DBG_NAV | DBG_CRIT, "index.bdmv: unknown object type %d\n", obj->object_type); return 0; }