Mercurial > libdvdnav.hg
comparison vm.c @ 124:e404d210ff91 src
- fix vm copying when the vtsN has not yet been set
- change still detection heuristics
- small TRACE output beautification
- fix handling of PTT register
- stop the VM when LinkRSM is called without resume info set
author | mroi |
---|---|
date | Fri, 14 Mar 2003 18:47:51 +0000 |
parents | 66ca475e2a5a |
children | 69e1755625a1 |
comparison
equal
deleted
inserted
replaced
123:da88fc974592 | 124:e404d210ff91 |
---|---|
376 memcpy(target, source, sizeof(vm_t)); | 376 memcpy(target, source, sizeof(vm_t)); |
377 | 377 |
378 /* open a new vtsi handle, because the copy might switch to another VTS */ | 378 /* open a new vtsi handle, because the copy might switch to another VTS */ |
379 target->vtsi = NULL; | 379 target->vtsi = NULL; |
380 vtsN = (target->state).vtsN; | 380 vtsN = (target->state).vtsN; |
381 (target->state).vtsN = 0; | 381 if (vtsN > 0) { |
382 ifoOpenNewVTSI(target, target->dvd, vtsN); | 382 (target->state).vtsN = 0; |
383 | 383 ifoOpenNewVTSI(target, target->dvd, vtsN); |
384 /* restore pgc pointer into the new vtsi */ | 384 |
385 if (!set_PGCN(target, pgcN)) | 385 /* restore pgc pointer into the new vtsi */ |
386 assert(0); | 386 if (!set_PGCN(target, pgcN)) |
387 (target->state).pgN = pgN; | 387 assert(0); |
388 (target->state).pgN = pgN; | |
389 } | |
388 | 390 |
389 return target; | 391 return target; |
390 } | 392 } |
391 | 393 |
392 void vm_merge(vm_t *target, vm_t *source) { | 394 void vm_merge(vm_t *target, vm_t *source) { |
436 * detect such discs. I consider these discs broken, so the fix is somewhat | 438 * detect such discs. I consider these discs broken, so the fix is somewhat |
437 * broken, too. */ | 439 * broken, too. */ |
438 if (((vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_sector == | 440 if (((vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_sector == |
439 (vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_vobu_start_sector) && | 441 (vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_vobu_start_sector) && |
440 ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_sector - | 442 ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_sector - |
441 (vm->state).pgc->cell_playback[(vm->state).cellN - 1].first_sector < 250)) { | 443 (vm->state).pgc->cell_playback[(vm->state).cellN - 1].first_sector < 1024)) { |
442 int time; | 444 int time; |
445 int size = (vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_sector - | |
446 (vm->state).pgc->cell_playback[(vm->state).cellN - 1].first_sector; | |
443 time = ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.hour & 0xf0) * 36000; | 447 time = ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.hour & 0xf0) * 36000; |
444 time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.hour & 0x0f) * 3600; | 448 time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.hour & 0x0f) * 3600; |
445 time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.minute & 0xf0) * 600; | 449 time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.minute & 0xf0) * 600; |
446 time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.minute & 0x0f) * 60; | 450 time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.minute & 0x0f) * 60; |
447 time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.second & 0xf0) * 10; | 451 time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.second & 0xf0) * 10; |
448 time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.second & 0x0f) * 1; | 452 time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.second & 0x0f) * 1; |
453 if (size / time > 30) | |
454 /* datarate is too high, it might be a very short, but regular cell */ | |
455 return; | |
449 if (time > 0xff) time = 0xff; | 456 if (time > 0xff) time = 0xff; |
450 position->still = time; | 457 position->still = time; |
451 } | 458 } |
452 } | 459 } |
453 | 460 |
562 | 569 |
563 /* getting information */ | 570 /* getting information */ |
564 | 571 |
565 int vm_get_current_title_part(vm_t *vm, int *title_result, int *part_result) { | 572 int vm_get_current_title_part(vm_t *vm, int *title_result, int *part_result) { |
566 vts_ptt_srpt_t *vts_ptt_srpt; | 573 vts_ptt_srpt_t *vts_ptt_srpt; |
567 int title, part = 0, vts_ttn; | 574 int title = (vm->state).TTN_REG; |
575 int part = (vm->state).PTTN_REG; | |
576 int vts_ttn = (vm->state).VTS_TTN_REG; | |
568 int found; | 577 int found; |
569 int16_t pgcN, pgN; | 578 int16_t pgcN, pgN; |
570 | 579 |
571 vts_ptt_srpt = vm->vtsi->vts_ptt_srpt; | 580 vts_ptt_srpt = vm->vtsi->vts_ptt_srpt; |
572 pgcN = get_PGCN(vm); | 581 pgcN = get_PGCN(vm); |
591 #ifdef TRACE | 600 #ifdef TRACE |
592 if (title) { | 601 if (title) { |
593 fprintf(MSG_OUT, "libdvdnav: ************ this chapter FOUND!\n"); | 602 fprintf(MSG_OUT, "libdvdnav: ************ this chapter FOUND!\n"); |
594 fprintf(MSG_OUT, "libdvdnav: VTS_PTT_SRPT - Title %3i part %3i: PGC: %3i PG: %3i\n", | 603 fprintf(MSG_OUT, "libdvdnav: VTS_PTT_SRPT - Title %3i part %3i: PGC: %3i PG: %3i\n", |
595 title, part, | 604 title, part, |
596 vts_ptt_srpt->title[ttn-1].ptt[part-1].pgcn , | 605 vts_ptt_srpt->title[vts_ttn-1].ptt[part-1].pgcn , |
597 vts_ptt_srpt->title[ttn-1].ptt[part-1].pgn ); | 606 vts_ptt_srpt->title[vts_ttn-1].ptt[part-1].pgn ); |
598 } else { | 607 } else { |
599 fprintf(MSG_OUT, "libdvdnav: ************ this chapter NOT FOUND!\n"); | 608 fprintf(MSG_OUT, "libdvdnav: ************ this chapter NOT FOUND!\n"); |
600 } | 609 } |
601 #endif | 610 #endif |
602 if (!title) | 611 if (!title) |
856 | 865 |
857 static link_t play_PGC(vm_t *vm) { | 866 static link_t play_PGC(vm_t *vm) { |
858 link_t link_values; | 867 link_t link_values; |
859 | 868 |
860 #ifdef TRACE | 869 #ifdef TRACE |
861 fprintf(MSG_OUT, "libdvdnav: vm: play_PGC:"); | 870 fprintf(MSG_OUT, "libdvdnav: play_PGC:"); |
862 if((vm->state).domain != FP_DOMAIN) { | 871 if((vm->state).domain != FP_DOMAIN) { |
863 fprintf(MSG_OUT, " (vm->state).pgcN (%i)\n", get_PGCN(vm)); | 872 fprintf(MSG_OUT, " (vm->state).pgcN (%i)\n", get_PGCN(vm)); |
864 } else { | 873 } else { |
865 fprintf(MSG_OUT, " first_play_pgc\n"); | 874 fprintf(MSG_OUT, " first_play_pgc\n"); |
866 } | 875 } |
896 | 905 |
897 static link_t play_PGC_PG(vm_t *vm, int pgN) { | 906 static link_t play_PGC_PG(vm_t *vm, int pgN) { |
898 link_t link_values; | 907 link_t link_values; |
899 | 908 |
900 #ifdef TRACE | 909 #ifdef TRACE |
901 fprintf(MSG_OUT, "libdvdnav: vm: play_PGC:"); | 910 fprintf(MSG_OUT, "libdvdnav: play_PGC:"); |
902 if((vm->state).domain != FP_DOMAIN) { | 911 if((vm->state).domain != FP_DOMAIN) { |
903 fprintf(MSG_OUT, " (vm->state).pgcN (%i)\n", get_PGCN(vm)); | 912 fprintf(MSG_OUT, " (vm->state).pgcN (%i)\n", get_PGCN(vm)); |
904 } else { | 913 } else { |
905 fprintf(MSG_OUT, " first_play_pgc\n"); | 914 fprintf(MSG_OUT, " first_play_pgc\n"); |
906 } | 915 } |
1268 case LinkRSM: | 1277 case LinkRSM: |
1269 { | 1278 { |
1270 /* Link to Resume point */ | 1279 /* Link to Resume point */ |
1271 int i; | 1280 int i; |
1272 | 1281 |
1273 /* Check and see if there is any rsm info!! */ | 1282 /* Check and see if there is any rsm info!! */ |
1274 assert((vm->state).rsm_vtsN); | 1283 if (!(vm->state).rsm_vtsN) { |
1284 fprintf(MSG_OUT, "libdvdnav: trying to resume without any resume info set\n"); | |
1285 link_values.command = Exit; | |
1286 break; | |
1287 } | |
1288 | |
1275 (vm->state).domain = VTS_DOMAIN; | 1289 (vm->state).domain = VTS_DOMAIN; |
1276 ifoOpenNewVTSI(vm, vm->dvd, (vm->state).rsm_vtsN); | 1290 ifoOpenNewVTSI(vm, vm->dvd, (vm->state).rsm_vtsN); |
1277 set_PGCN(vm, (vm->state).rsm_pgcN); | 1291 set_PGCN(vm, (vm->state).rsm_pgcN); |
1278 | 1292 |
1279 /* These should never be set in SystemSpace and/or MenuSpace */ | 1293 /* These should never be set in SystemSpace and/or MenuSpace */ |
1518 | 1532 |
1519 pgcN = vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].ptt[part - 1].pgcn; | 1533 pgcN = vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].ptt[part - 1].pgcn; |
1520 pgN = vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].ptt[part - 1].pgn; | 1534 pgN = vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].ptt[part - 1].pgn; |
1521 | 1535 |
1522 (vm->state).TT_PGCN_REG = pgcN; | 1536 (vm->state).TT_PGCN_REG = pgcN; |
1523 (vm->state).PTTN_REG = pgN; | 1537 (vm->state).PTTN_REG = part; |
1524 (vm->state).TTN_REG = get_TT(vm, vtsN, vts_ttn); | 1538 (vm->state).TTN_REG = get_TT(vm, vtsN, vts_ttn); |
1525 assert( (vm->state.TTN_REG) != 0 ); | 1539 assert( (vm->state.TTN_REG) != 0 ); |
1526 (vm->state).VTS_TTN_REG = vts_ttn; | 1540 (vm->state).VTS_TTN_REG = vts_ttn; |
1527 (vm->state).vtsN = vtsN; /* Not sure about this one. We can get to it easily from TTN_REG */ | 1541 (vm->state).vtsN = vtsN; /* Not sure about this one. We can get to it easily from TTN_REG */ |
1528 /* Any other registers? */ | 1542 /* Any other registers? */ |
1584 playback_type_t *pb_ty; | 1598 playback_type_t *pb_ty; |
1585 if((vm->state).TTN_REG > vm->vmgi->tt_srpt->nr_of_srpts) | 1599 if((vm->state).TTN_REG > vm->vmgi->tt_srpt->nr_of_srpts) |
1586 return 0; /* ?? */ | 1600 return 0; /* ?? */ |
1587 pb_ty = &vm->vmgi->tt_srpt->title[(vm->state).TTN_REG - 1].pb_ty; | 1601 pb_ty = &vm->vmgi->tt_srpt->title[(vm->state).TTN_REG - 1].pb_ty; |
1588 if(pb_ty->multi_or_random_pgc_title == /* One_Sequential_PGC_Title */ 0) { | 1602 if(pb_ty->multi_or_random_pgc_title == /* One_Sequential_PGC_Title */ 0) { |
1589 int dummy; | 1603 int dummy, part; |
1590 #if 0 | 1604 #if 0 |
1591 /* TTN_REG can't be trusted to have a correct value here... */ | 1605 /* TTN_REG can't be trusted to have a correct value here... */ |
1592 vts_ptt_srpt_t *ptt_srpt = vtsi->vts_ptt_srpt; | 1606 vts_ptt_srpt_t *ptt_srpt = vtsi->vts_ptt_srpt; |
1593 assert((vm->state).VTS_TTN_REG <= ptt_srpt->nr_of_srpts); | 1607 assert((vm->state).VTS_TTN_REG <= ptt_srpt->nr_of_srpts); |
1594 assert(get_PGCN() == ptt_srpt->title[(vm->state).VTS_TTN_REG - 1].ptt[0].pgcn); | 1608 assert(get_PGCN() == ptt_srpt->title[(vm->state).VTS_TTN_REG - 1].ptt[0].pgcn); |
1595 assert(1 == ptt_srpt->title[(vm->state).VTS_TTN_REG - 1].ptt[0].pgn); | 1609 assert(1 == ptt_srpt->title[(vm->state).VTS_TTN_REG - 1].ptt[0].pgn); |
1596 #endif | 1610 #endif |
1597 vm_get_current_title_part(vm, &dummy, &(vm->state).pgN); | 1611 vm_get_current_title_part(vm, &dummy, &part); |
1598 (vm->state).PTTN_REG = (vm->state).pgN; | 1612 (vm->state).PTTN_REG = part; |
1599 } else { | 1613 } else { |
1600 /* FIXME: Handle RANDOM or SHUFFLE titles. */ | 1614 /* FIXME: Handle RANDOM or SHUFFLE titles. */ |
1601 fprintf(MSG_OUT, "libdvdnav: RANDOM or SHUFFLE titles are NOT handled yet.\n"); | 1615 fprintf(MSG_OUT, "libdvdnav: RANDOM or SHUFFLE titles are NOT handled yet.\n"); |
1602 } | 1616 } |
1603 } | 1617 } |
1781 #endif | 1795 #endif |
1782 | 1796 |
1783 | 1797 |
1784 /* | 1798 /* |
1785 * $Log$ | 1799 * $Log$ |
1800 * Revision 1.45 2003/03/14 18:47:51 mroi | |
1801 * - fix vm copying when the vtsN has not yet been set | |
1802 * - change still detection heuristics | |
1803 * - small TRACE output beautification | |
1804 * - fix handling of PTT register | |
1805 * - stop the VM when LinkRSM is called without resume info set | |
1806 * | |
1786 * Revision 1.44 2003/03/12 11:38:10 mroi | 1807 * Revision 1.44 2003/03/12 11:38:10 mroi |
1787 * - provide the means to make copies of the VM to try certain operations on a copy and | 1808 * - provide the means to make copies of the VM to try certain operations on a copy and |
1788 * merge the changes back on success | 1809 * merge the changes back on success |
1789 * - do not trigger an assertion when falling off a program chain, but stop the VM | 1810 * - do not trigger an assertion when falling off a program chain, but stop the VM |
1790 * | 1811 * |