static void _fill_clip(NAV_TITLE *title, MPLS_CLIP *mpls_clip, uint8_t connection_condition, uint32_t in_time, uint32_t out_time, unsigned pi_angle_count, NAV_CLIP *clip, unsigned ref, uint32_t *pos, uint32_t *time) { char *path; clip->title = title; clip->ref = ref; if (title->angle >= pi_angle_count) { clip->angle = 0; } else { clip->angle = title->angle; } strncpy(clip->name, mpls_clip[clip->angle].clip_id, 5); strncpy(&clip->name[5], ".m2ts", 6); clip->clip_id = atoi(mpls_clip[clip->angle].clip_id); path = str_printf("%s"DIR_SEP"BDMV"DIR_SEP"CLIPINF"DIR_SEP"%s.clpi", title->root, mpls_clip[clip->angle].clip_id); clpi_free(clip->cl); clip->cl = clpi_parse(path, 0); X_FREE(path); if (clip->cl == NULL) { clip->start_pkt = 0; clip->end_pkt = 0; return; } switch (connection_condition) { case 5: case 6: clip->start_pkt = 0; clip->connection = CONNECT_SEAMLESS; break; default: if (ref) { clip->start_pkt = clpi_lookup_spn(clip->cl, in_time, 1, mpls_clip[clip->angle].stc_id); } else { clip->start_pkt = 0; } clip->connection = CONNECT_NON_SEAMLESS; break; } clip->end_pkt = clpi_lookup_spn(clip->cl, out_time, 0, mpls_clip[clip->angle].stc_id); clip->in_time = in_time; clip->out_time = out_time; clip->pos = *pos; *pos += clip->end_pkt - clip->start_pkt; clip->start_time = *time; *time += clip->out_time - clip->in_time; }
// Search for random access point closest to the requested time // Time is in 45khz ticks NAV_CLIP* nav_time_search(NAV_TITLE *title, uint32_t tick, uint32_t *clip_pkt, uint32_t *out_pkt) { uint32_t pos, len; MPLS_PI *pi; NAV_CLIP *clip; unsigned ii; pos = 0; for (ii = 0; ii < title->pl->list_count; ii++) { pi = &title->pl->play_item[ii]; len = pi->out_time - pi->in_time; if (tick < pos + len) break; pos += len; } if (ii == title->pl->list_count) { clip = &title->clip_list.clip[ii-1]; *clip_pkt = clip->end_pkt; } else { clip = &title->clip_list.clip[ii]; if (clip->cl != NULL) { *clip_pkt = clpi_lookup_spn(clip->cl, tick - pos + pi->in_time, 1, title->pl->play_item[clip->ref].clip[clip->angle].stc_id); } else { *clip_pkt = clip->start_pkt; } } *out_pkt = clip->pos + *clip_pkt - clip->start_pkt; return clip; }
static void _fill_mark(NAV_TITLE *title, NAV_MARK *mark, int entry) { MPLS_PL *pl = title->pl; MPLS_PLM *plm; MPLS_PI *pi; NAV_CLIP *clip; plm = &pl->play_mark[entry]; mark->plm = plm; mark->mark_type = plm->mark_type; mark->clip_ref = plm->play_item_ref; clip = &title->clip_list.clip[mark->clip_ref]; if (clip->cl != NULL) { mark->clip_pkt = clpi_lookup_spn(clip->cl, plm->time, 1, title->pl->play_item[mark->clip_ref].clip[title->angle].stc_id); } else { mark->clip_pkt = clip->start_pkt; } mark->title_pkt = clip->title_pkt + mark->clip_pkt; mark->clip_time = plm->time; // Calculate start of mark relative to beginning of playlist if (plm->play_item_ref < title->clip_list.count) { clip = &title->clip_list.clip[plm->play_item_ref]; pi = &pl->play_item[plm->play_item_ref]; mark->title_time = clip->title_time + plm->time - pi->in_time; } }
// Search for random access point closest to the requested time // Time is in 45khz ticks relative to the beginning of a specific clip void nav_clip_time_search(NAV_CLIP *clip, uint32_t tick, uint32_t *clip_pkt, uint32_t *out_pkt) { if (tick >= clip->out_time) { *clip_pkt = clip->end_pkt; } else { if (clip->cl != NULL) { *clip_pkt = clpi_lookup_spn(clip->cl, tick, 1, clip->title->pl->play_item[clip->ref].clip[clip->angle].stc_id); } else { *clip_pkt = clip->start_pkt; } } *out_pkt = clip->pos + *clip_pkt - clip->start_pkt; }
// Search for random access point closest to the requested time // Time is in 45khz ticks NAV_CLIP* nav_time_search(NAV_TITLE *title, uint32_t tick, uint32_t *clip_pkt, uint32_t *out_pkt) { uint32_t pos, len; MPLS_PI *pi = NULL; NAV_CLIP *clip; unsigned ii; if (!title->pl) { BD_DEBUG(DBG_NAV | DBG_CRIT, "Time search failed (title not opened)\n"); return NULL; } if (title->pl->list_count < 1) { BD_DEBUG(DBG_NAV | DBG_CRIT, "Time search failed (empty playlist)\n"); return NULL; } pos = 0; for (ii = 0; ii < title->pl->list_count; ii++) { pi = &title->pl->play_item[ii]; len = pi->out_time - pi->in_time; if (tick < pos + len) break; pos += len; } if (ii == title->pl->list_count) { clip = &title->clip_list.clip[ii-1]; *clip_pkt = clip->end_pkt; } else { clip = &title->clip_list.clip[ii]; if (clip->cl != NULL) { *clip_pkt = clpi_lookup_spn(clip->cl, tick - pos + pi->in_time, 1, title->pl->play_item[clip->ref].clip[clip->angle].stc_id); if (*clip_pkt < clip->start_pkt) { *clip_pkt = clip->start_pkt; } } else { *clip_pkt = clip->start_pkt; } } *out_pkt = clip->title_pkt + *clip_pkt - clip->start_pkt; return clip; }
NAV_CLIP* nav_set_angle(NAV_TITLE *title, NAV_CLIP *clip, unsigned angle) { char *path; int ii; uint32_t pos = 0; uint32_t time = 0; if (title == NULL) { return clip; } if (angle > 8) { // invalid angle return clip; } if (angle == title->angle) { // no change return clip; } title->angle = angle; // Find length in packets and end_pkt for each clip title->packets = 0; for (ii = 0; ii < title->pl->list_count; ii++) { MPLS_PI *pi; NAV_CLIP *clip; pi = &title->pl->play_item[ii]; clip = &title->clip_list.clip[ii]; if (title->angle >= pi->angle_count) { clip->angle = 0; } else { clip->angle = title->angle; } clpi_free(clip->cl); clip->ref = ii; strncpy(clip->name, pi->clip[clip->angle].clip_id, 5); strncpy(&clip->name[5], ".m2ts", 6); clip->clip_id = atoi(pi->clip[clip->angle].clip_id); path = str_printf("%s"DIR_SEP"BDMV"DIR_SEP"CLIPINF"DIR_SEP"%s.clpi", title->root, pi->clip[clip->angle].clip_id); clip->cl = clpi_parse(path, 0); X_FREE(path); if (clip->cl == NULL) { clip->start_pkt = 0; clip->end_pkt = 0; continue; } switch (pi->connection_condition) { case 5: case 6: clip->start_pkt = 0; clip->connection = CONNECT_SEAMLESS; break; default: clip->start_pkt = clpi_lookup_spn(clip->cl, pi->in_time, 1, pi->clip[clip->angle].stc_id); clip->connection = CONNECT_NON_SEAMLESS; break; } clip->end_pkt = clpi_lookup_spn(clip->cl, pi->out_time, 0, pi->clip[clip->angle].stc_id); clip->in_time = pi->in_time; clip->out_time = pi->out_time; clip->pos = pos; pos += clip->end_pkt - clip->start_pkt; clip->start_time = time; time += clip->out_time - clip->in_time; } _extrapolate_title(title); return clip; }