Mercurial > libdvdnav.hg
comparison vm/vm.c @ 409:9b8bfc56a7fe src
Add dvdnav_program_play & dvdnav_current_title_program
Using title parts w/ dvdnav_part_play and dvdnav_current_title_info
is not reliable for use as chapter marks in files made from
transcoding. The start of a part does not necessarily fall strictly
inside the main title. Parts can have an intro sequence before
getting into the title. So we use program boundaries instead of
part markers to test when we have reached a chapter point during
encoding of the title. The same would apply to displaying the
current chapter during playback. The program boundaries
should be checked instead of looking for a part.
Patch from John Stebbins. Thanks!
author | erik |
---|---|
date | Fri, 30 Jul 2010 23:34:16 +0000 |
parents | 7923e813ec61 |
children | 799f85209145 |
comparison
equal
deleted
inserted
replaced
408:7923e813ec61 | 409:9b8bfc56a7fe |
---|---|
83 /* Set */ | 83 /* Set */ |
84 static int set_TT(vm_t *vm, int tt); | 84 static int set_TT(vm_t *vm, int tt); |
85 static int set_PTT(vm_t *vm, int tt, int ptt); | 85 static int set_PTT(vm_t *vm, int tt, int ptt); |
86 static int set_VTS_TT(vm_t *vm, int vtsN, int vts_ttn); | 86 static int set_VTS_TT(vm_t *vm, int vtsN, int vts_ttn); |
87 static int set_VTS_PTT(vm_t *vm, int vtsN, int vts_ttn, int part); | 87 static int set_VTS_PTT(vm_t *vm, int vtsN, int vts_ttn, int part); |
88 static int set_PROG(vm_t *vm, int tt, int pgcn, int pgn); | |
89 static int set_VTS_PROG(vm_t *vm, int vtsN, int vts_ttn, int pgcn, int pgn); | |
88 static int set_FP_PGC(vm_t *vm); | 90 static int set_FP_PGC(vm_t *vm); |
89 static int set_MENU(vm_t *vm, int menu); | 91 static int set_MENU(vm_t *vm, int menu); |
90 static int set_PGCN(vm_t *vm, int pgcN); | 92 static int set_PGCN(vm_t *vm, int pgcN); |
91 static int set_PGN(vm_t *vm); /* Set PGN based on (vm->state).CellN */ | 93 static int set_PGN(vm_t *vm); /* Set PGN based on (vm->state).CellN */ |
92 static void set_RSMinfo(vm_t *vm, int cellN, int blockN); | 94 static void set_RSMinfo(vm_t *vm, int cellN, int blockN); |
518 if ((vm->state).cellN == cell) | 520 if ((vm->state).cellN == cell) |
519 (vm->state).blockN = block; | 521 (vm->state).blockN = block; |
520 return 1; | 522 return 1; |
521 } | 523 } |
522 | 524 |
525 int vm_jump_title_program(vm_t *vm, int title, int pgcn, int pgn) { | |
526 link_t link; | |
527 | |
528 if(!set_PROG(vm, title, pgcn, pgn)) | |
529 return 0; | |
530 /* Some DVDs do not want us to jump directly into a title and have | |
531 * PGC pre commands taking us back to some menu. Since we do not like that, | |
532 * we do not execute PGC pre commands that would do a jump. */ | |
533 /* process_command(vm, play_PGC_PG(vm, (vm->state).pgN)); */ | |
534 link = play_PGC_PG(vm, (vm->state).pgN); | |
535 if (link.command != PlayThis) | |
536 /* jump occured -> ignore it and play the PG anyway */ | |
537 process_command(vm, play_PG(vm)); | |
538 else | |
539 process_command(vm, link); | |
540 return 1; | |
541 } | |
542 | |
523 int vm_jump_title_part(vm_t *vm, int title, int part) { | 543 int vm_jump_title_part(vm_t *vm, int title, int part) { |
524 link_t link; | 544 link_t link; |
525 | 545 |
526 if(!set_PTT(vm, title, part)) | 546 if(!set_PTT(vm, title, part)) |
527 return 0; | 547 return 0; |
1645 res = set_PGCN(vm, pgcN); /* This clobber's state.pgN (sets it to 1), but we don't want clobbering here. */ | 1665 res = set_PGCN(vm, pgcN); /* This clobber's state.pgN (sets it to 1), but we don't want clobbering here. */ |
1646 (vm->state).pgN = pgN; | 1666 (vm->state).pgN = pgN; |
1647 return res; | 1667 return res; |
1648 } | 1668 } |
1649 | 1669 |
1670 static int set_PROG(vm_t *vm, int tt, int pgcn, int pgn) { | |
1671 assert(tt <= vm->vmgi->tt_srpt->nr_of_srpts); | |
1672 return set_VTS_PROG(vm, vm->vmgi->tt_srpt->title[tt - 1].title_set_nr, | |
1673 vm->vmgi->tt_srpt->title[tt - 1].vts_ttn, pgcn, pgn); | |
1674 } | |
1675 | |
1676 static int set_VTS_PROG(vm_t *vm, int vtsN, int vts_ttn, int pgcn, int pgn) { | |
1677 int pgcN, pgN, res, title, part = 0; | |
1678 | |
1679 (vm->state).domain = VTS_DOMAIN; | |
1680 | |
1681 if (vtsN != (vm->state).vtsN) | |
1682 if (!ifoOpenNewVTSI(vm, vm->dvd, vtsN)) /* Also sets (vm->state).vtsN */ | |
1683 return 0; | |
1684 | |
1685 if ((vts_ttn < 1) || (vts_ttn > vm->vtsi->vts_ptt_srpt->nr_of_srpts)) { | |
1686 return 0; | |
1687 } | |
1688 | |
1689 pgcN = pgcn; | |
1690 pgN = pgn; | |
1691 | |
1692 (vm->state).TT_PGCN_REG = pgcN; | |
1693 (vm->state).TTN_REG = get_TT(vm, vtsN, vts_ttn); | |
1694 assert( (vm->state.TTN_REG) != 0 ); | |
1695 (vm->state).VTS_TTN_REG = vts_ttn; | |
1696 (vm->state).vtsN = vtsN; /* Not sure about this one. We can get to it easily from TTN_REG */ | |
1697 /* Any other registers? */ | |
1698 | |
1699 res = set_PGCN(vm, pgcN); /* This clobber's state.pgN (sets it to 1), but we don't want clobbering here. */ | |
1700 (vm->state).pgN = pgN; | |
1701 vm_get_current_title_part(vm, &title, &part); | |
1702 (vm->state).PTTN_REG = part; | |
1703 return res; | |
1704 } | |
1705 | |
1650 static int set_FP_PGC(vm_t *vm) { | 1706 static int set_FP_PGC(vm_t *vm) { |
1651 (vm->state).domain = FP_DOMAIN; | 1707 (vm->state).domain = FP_DOMAIN; |
1652 if (!vm->vmgi->first_play_pgc) { | 1708 if (!vm->vmgi->first_play_pgc) { |
1653 return set_PGCN(vm, 1); | 1709 return set_PGCN(vm, 1); |
1654 } | 1710 } |