Commit 33fd99e1 authored by j45's avatar j45

add bd_seek_chapter and bd_seek_mark

bd_seek_chapter seeks to marks of type BD_ENTRY_MARK.  the chapter index
is an index into a list of marks that are only of BD_ENTRY_MARK type.

bd_seek_mark seeks to marks of any type.  the mark index is an index
into a list of all marks.
parent cfa1c2e7
......@@ -298,6 +298,66 @@ int64_t bd_seek_time(BLURAY *bd, uint64_t tick)
return bd->s_pos;
}
int64_t bd_seek_chapter(BLURAY *bd, int chapter)
{
uint32_t clip_pkt, out_pkt;
NAV_CLIP *clip;
// Find the closest access unit to the requested position
clip = nav_chapter_search(bd->title, chapter, &clip_pkt, &out_pkt);
if (clip->ref != bd->clip->ref) {
// The position is in a new clip
bd->clip = clip;
if (!_open_m2ts(bd)) {
return -1;
}
}
bd->s_pos = (uint64_t)out_pkt * 192;
bd->clip_pos = (uint64_t)clip_pkt * 192;
bd->clip_block_pos = (bd->clip_pos / 6144) * 6144;
file_seek(bd->fp, bd->clip_block_pos, SEEK_SET);
bd->int_buf_off = 6144;
DEBUG(DBG_BLURAY, "Seek to %"PRIu64" (%p)\n",
bd->s_pos, bd);
if (bd->bdplus_seek && bd->bdplus)
bd->bdplus_seek(bd->bdplus, bd->clip_block_pos);
return bd->s_pos;
}
int64_t bd_seek_mark(BLURAY *bd, int mark)
{
uint32_t clip_pkt, out_pkt;
NAV_CLIP *clip;
// Find the closest access unit to the requested position
clip = nav_mark_search(bd->title, mark, &clip_pkt, &out_pkt);
if (clip->ref != bd->clip->ref) {
// The position is in a new clip
bd->clip = clip;
if (!_open_m2ts(bd)) {
return -1;
}
}
bd->s_pos = (uint64_t)out_pkt * 192;
bd->clip_pos = (uint64_t)clip_pkt * 192;
bd->clip_block_pos = (bd->clip_pos / 6144) * 6144;
file_seek(bd->fp, bd->clip_block_pos, SEEK_SET);
bd->int_buf_off = 6144;
DEBUG(DBG_BLURAY, "Seek to %"PRIu64" (%p)\n",
bd->s_pos, bd);
if (bd->bdplus_seek && bd->bdplus)
bd->bdplus_seek(bd->bdplus, bd->clip_block_pos);
return bd->s_pos;
}
int64_t bd_seek(BLURAY *bd, uint64_t pos)
{
uint32_t pkt, clip_pkt, out_pkt, out_time;
......@@ -574,9 +634,9 @@ BD_TITLE_INFO* bd_get_title_info(BLURAY *bd, uint32_t title_idx)
title_info->chapters = calloc(title_info->chapter_count, sizeof(BD_TITLE_CHAPTER));
for (ii = 0; ii < title_info->chapter_count; ii++) {
title_info->chapters[ii].idx = ii;
title_info->chapters[ii].start = (uint64_t)title->chap_list.chapter[ii].title_time * 2;
title_info->chapters[ii].duration = (uint64_t)title->chap_list.chapter[ii].duration * 2;
title_info->chapters[ii].offset = (uint64_t)title->chap_list.chapter[ii].title_pkt * 192;
title_info->chapters[ii].start = (uint64_t)title->chap_list.mark[ii].title_time * 2;
title_info->chapters[ii].duration = (uint64_t)title->chap_list.mark[ii].duration * 2;
title_info->chapters[ii].offset = (uint64_t)title->chap_list.mark[ii].title_pkt * 192;
}
nav_title_close(title);
return title_info;
......
......@@ -258,6 +258,31 @@ char* nav_find_main_title(char *root)
}
}
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];
mark->clip_pkt = clpi_lookup_spn(clip->cl, plm->time, 1,
title->pl->play_item[mark->clip_ref].clip[title->angle].stc_id);
// 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;
}
}
static void
_extrapolate_title(NAV_TITLE *title)
{
......@@ -267,7 +292,7 @@ _extrapolate_title(NAV_TITLE *title)
MPLS_PL *pl = title->pl;
MPLS_PI *pi;
MPLS_PLM *plm;
NAV_CHAP *chap, *prev = NULL;
NAV_MARK *mark, *prev = NULL;
NAV_CLIP *clip;
for (ii = 0; ii < title->clip_list.count; ii++) {
......@@ -290,36 +315,24 @@ _extrapolate_title(NAV_TITLE *title)
plm = &pl->play_mark[ii];
if (plm->mark_type == BD_MARK_ENTRY) {
chap = &title->chap_list.chapter[jj];
chap->number = jj;
chap->plm = plm;
chap->clip_ref = plm->play_item_ref;
clip = &title->clip_list.clip[chap->clip_ref];
chap->clip_pkt = clpi_lookup_spn(clip->cl, plm->time, 1,
title->pl->play_item[chap->clip_ref].clip[title->angle].stc_id);
// 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];
chap->title_time = clip->title_time + plm->time - pi->in_time;
} else {
// Invalid chapter mark
continue;
}
mark = &title->chap_list.mark[jj];
_fill_mark(title, mark, ii);
mark->number = jj;
// Calculate duration of "entry" marks (chapters)
if (plm->duration != 0) {
chap->duration = plm->duration;
mark->duration = plm->duration;
} else if (prev != NULL) {
if (prev->duration == 0) {
prev->duration = chap->title_time - prev->title_time;
prev->duration = mark->title_time - prev->title_time;
}
}
prev = chap;
prev = mark;
jj++;
}
mark = &title->mark_list.mark[ii];
_fill_mark(title, mark, ii);
mark->number = ii;
}
title->chap_list.count = jj;
if (prev->duration == 0) {
......@@ -411,7 +424,8 @@ NAV_TITLE* nav_title_open(char *root, char *playlist)
}
}
title->chap_list.count = chapters;
title->chap_list.chapter = calloc(chapters, sizeof(NAV_CHAP));
title->chap_list.mark = calloc(chapters, sizeof(NAV_MARK));
title->mark_list.mark = calloc(title->pl->mark_count, sizeof(NAV_MARK));
_extrapolate_title(title);
return title;
......@@ -432,14 +446,38 @@ void nav_title_close(NAV_TITLE *title)
// Search for random access point closest to the requested packet
// Packets are 192 byte TS packets
NAV_CLIP* nav_chapter_search(NAV_TITLE *title, int chapter, uint32_t *out_pkt)
NAV_CLIP* nav_chapter_search(NAV_TITLE *title, int chapter, uint32_t *clip_pkt, uint32_t *out_pkt)
{
NAV_CLIP *clip;
if (chapter > title->chap_list.count) {
*out_pkt = title->clip_list.clip[0].start_pkt;
return &title->clip_list.clip[0];
clip = &title->clip_list.clip[0];
*clip_pkt = clip->start_pkt;
*out_pkt = clip->pos + *clip_pkt - clip->start_pkt;
return clip;
}
*out_pkt = title->chap_list.chapter[chapter].clip_pkt;
return &title->clip_list.clip[title->chap_list.chapter[chapter].clip_ref];
clip = &title->clip_list.clip[title->chap_list.mark[chapter].clip_ref];
*clip_pkt = title->chap_list.mark[chapter].clip_pkt;
*out_pkt = clip->pos + *clip_pkt - clip->start_pkt;
return clip;
}
// Search for random access point closest to the requested packet
// Packets are 192 byte TS packets
NAV_CLIP* nav_mark_search(NAV_TITLE *title, int mark, uint32_t *clip_pkt, uint32_t *out_pkt)
{
NAV_CLIP *clip;
if (mark > title->mark_list.count) {
clip = &title->clip_list.clip[0];
*clip_pkt = clip->start_pkt;
*out_pkt = clip->pos + *clip_pkt - clip->start_pkt;
return clip;
}
clip = &title->clip_list.clip[title->mark_list.mark[mark].clip_ref];
*clip_pkt = title->mark_list.mark[mark].clip_pkt;
*out_pkt = clip->pos + *clip_pkt - clip->start_pkt;
return clip;
}
// Search for random access point closest to the requested packet
......
......@@ -17,6 +17,7 @@ typedef struct nav_title_s NAV_TITLE;
typedef struct {
int number;
int mark_type;
int clip_ref;
uint32_t clip_pkt;
......@@ -26,12 +27,12 @@ typedef struct {
uint32_t duration;
MPLS_PLM *plm;
} NAV_CHAP;
} NAV_MARK;
typedef struct {
int count;
NAV_CHAP *chapter;
} NAV_CHAP_LIST;
NAV_MARK *mark;
} NAV_MARK_LIST;
typedef struct {
char name[11];
......@@ -69,7 +70,8 @@ struct nav_title_s {
uint8_t angle_count;
uint8_t angle;
NAV_CLIP_LIST clip_list;
NAV_CHAP_LIST chap_list;
NAV_MARK_LIST chap_list;
NAV_MARK_LIST mark_list;
uint32_t packets;
uint32_t duration;
......@@ -96,7 +98,8 @@ NAV_CLIP* nav_next_clip(NAV_TITLE *title, NAV_CLIP *clip);
NAV_CLIP* nav_packet_search(NAV_TITLE *title, uint32_t pkt, uint32_t *clip_pkt, uint32_t *out_pkt, uint32_t *out_time);
NAV_CLIP* nav_time_search(NAV_TITLE *title, uint32_t tick, uint32_t *clip_pkt, uint32_t *out_pkt);
void nav_clip_time_search(NAV_CLIP *clip, uint32_t tick, uint32_t *clip_pkt, uint32_t *out_pkt);
NAV_CLIP* nav_chapter_search(NAV_TITLE *title, int chapter, uint32_t *out_pkt);
NAV_CLIP* nav_chapter_search(NAV_TITLE *title, int chapter, uint32_t *clip_pkt, uint32_t *out_pkt);
NAV_CLIP* nav_mark_search(NAV_TITLE *title, int mark, uint32_t *clip_pkt, uint32_t *out_pkt);
uint32_t nav_angle_change_search(NAV_CLIP *clip, uint32_t pkt, uint32_t *time);
NAV_CLIP* nav_set_angle(NAV_TITLE *title, NAV_CLIP *clip, int angle);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment