diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/input/libdvdnav/Makefile.am | 1 | ||||
-rw-r--r-- | src/input/libdvdnav/decoder.c | 184 | ||||
-rw-r--r-- | src/input/libdvdnav/decoder.h | 6 | ||||
-rw-r--r-- | src/input/libdvdnav/diff_against_cvs.patch | 16 | ||||
-rw-r--r-- | src/input/libdvdnav/dvd_types.h | 3 | ||||
-rw-r--r-- | src/input/libdvdnav/dvdnav.c | 90 | ||||
-rw-r--r-- | src/input/libdvdnav/dvdnav.h | 861 | ||||
-rw-r--r-- | src/input/libdvdnav/dvdnav_events.h | 256 | ||||
-rw-r--r-- | src/input/libdvdnav/highlight.c | 4 | ||||
-rw-r--r-- | src/input/libdvdnav/navigation.c | 31 | ||||
-rw-r--r-- | src/input/libdvdnav/searching.c | 16 | ||||
-rw-r--r-- | src/input/libdvdnav/vm.c | 43 | ||||
-rw-r--r-- | src/input/libdvdnav/vm.h | 5 | ||||
-rw-r--r-- | src/input/libdvdnav/vmcmd.c | 209 | ||||
-rw-r--r-- | src/input/libdvdnav/vmcmd.h | 6 |
15 files changed, 863 insertions, 868 deletions
diff --git a/src/input/libdvdnav/Makefile.am b/src/input/libdvdnav/Makefile.am index 25fffce5d..bcf32eebe 100644 --- a/src/input/libdvdnav/Makefile.am +++ b/src/input/libdvdnav/Makefile.am @@ -1,6 +1,7 @@ DVD_CFLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE \ -I$(top_srcdir)/src/input/libdvdread/ +AM_CPPFLAGS = -DDVDNAV_COMPILE AM_CFLAGS = $(DVD_CFLAGS) @ANSI_FLAGS@ noinst_LTLIBRARIES = libdvdnav.la diff --git a/src/input/libdvdnav/decoder.c b/src/input/libdvdnav/decoder.c index ba605bc0b..154bac848 100644 --- a/src/input/libdvdnav/decoder.c +++ b/src/input/libdvdnav/decoder.c @@ -18,7 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: decoder.c,v 1.7 2003/03/29 13:19:08 mroi Exp $ + * $Id: decoder.c,v 1.8 2003/04/07 18:10:45 mroi Exp $ * */ @@ -42,7 +42,7 @@ uint32_t vm_getbits(command_t *command, int start, int count) { if (count == 0) return 0; - if ( ((count+start) > 64) || + if ( ((start - count) < -1) || (count > 32) || (start > 63) || (count < 0) || @@ -50,8 +50,8 @@ uint32_t vm_getbits(command_t *command, int start, int count) { fprintf(MSG_OUT, "libdvdnav: Bad call to vm_getbits. Parameter out of range\n"); assert(0); } - bit_mask >>= start; - bits = 64-count-start; + bit_mask >>= 63 - start; + bits = start + 1 - count; examining = ((bit_mask >> bits) << bits ); command->examined |= examining; result = (command->instruction & bit_mask) >> bits; @@ -110,11 +110,11 @@ static uint16_t eval_reg(command_t* command, uint8_t reg) { /* Eval register or immediate data. AAAA_AAAA BBBB_BBBB, if immediate use all 16 bits for data else use lower eight bits for the system or general purpose register. */ -static uint16_t eval_reg_or_data(command_t* command, int32_t imm, int32_t byte) { +static uint16_t eval_reg_or_data(command_t* command, int32_t imm, int32_t start) { if(imm) { /* immediate */ - return vm_getbits(command, (byte*8), 16); + return vm_getbits(command, start, 16); } else { - return eval_reg(command, vm_getbits(command, ((byte + 1)*8), 8)); + return eval_reg(command, vm_getbits(command, (start - 8), 8)); } } @@ -122,11 +122,11 @@ static uint16_t eval_reg_or_data(command_t* command, int32_t imm, int32_t byte) xBBB_BBBB, if immediate use all 7 bits for data else use lower four bits for the general purpose register number. */ /* Evaluates gprm or data depending on bit, data is in byte n */ -uint16_t eval_reg_or_data_2(command_t* command, int32_t imm, int32_t byte) { +uint16_t eval_reg_or_data_2(command_t* command, int32_t imm, int32_t start) { if(imm) /* immediate */ - return vm_getbits(command, ((byte*8)+1), 7); + return vm_getbits(command, (start - 1), 7); else - return get_GPRM(command->registers, (vm_getbits(command, ((byte*8)+4), 4)) ); + return get_GPRM(command->registers, (vm_getbits(command, (start - 4), 4)) ); } @@ -157,10 +157,10 @@ static int32_t eval_compare(uint8_t operation, uint16_t data1, uint16_t data2) { /* Evaluate if version 1. Has comparison data in byte 3 and 4-5 (immediate or register) */ static int32_t eval_if_version_1(command_t* command) { - uint8_t op = vm_getbits(command, 9, 3); + uint8_t op = vm_getbits(command, 54, 3); if(op) { - return eval_compare(op, eval_reg(command, vm_getbits(command, 24, 8)), - eval_reg_or_data(command, vm_getbits(command, 8, 1), 4)); + return eval_compare(op, eval_reg(command, vm_getbits(command, 39, 8)), + eval_reg_or_data(command, vm_getbits(command, 55, 1), 31)); } return 1; } @@ -168,10 +168,10 @@ static int32_t eval_if_version_1(command_t* command) { /* Evaluate if version 2. This version only compares register which are in byte 6 and 7 */ static int32_t eval_if_version_2(command_t* command) { - uint8_t op = vm_getbits(command, 9, 3); + uint8_t op = vm_getbits(command, 54, 3); if(op) { - return eval_compare(op, eval_reg(command, vm_getbits(command, 48, 8)), - eval_reg(command, vm_getbits(command, 56, 8))); + return eval_compare(op, eval_reg(command, vm_getbits(command, 15, 8)), + eval_reg(command, vm_getbits(command, 7, 8))); } return 1; } @@ -179,10 +179,10 @@ static int32_t eval_if_version_2(command_t* command) { /* Evaluate if version 3. Has comparison data in byte 2 and 6-7 (immediate or register) */ static int32_t eval_if_version_3(command_t* command) { - uint8_t op = vm_getbits(command, 9, 3); + uint8_t op = vm_getbits(command, 54, 3); if(op) { - return eval_compare(op, eval_reg(command, vm_getbits(command, 16, 8)), - eval_reg_or_data(command, vm_getbits(command, 8, 1), 6)); + return eval_compare(op, eval_reg(command, vm_getbits(command, 47, 8)), + eval_reg_or_data(command, vm_getbits(command, 55, 1), 15)); } return 1; } @@ -191,10 +191,10 @@ static int32_t eval_if_version_3(command_t* command) { Has comparison data in byte 1 and 4-5 (immediate or register) The register in byte 1 is only the lowe nibble (4 bits) */ static int32_t eval_if_version_4(command_t* command) { - uint8_t op = vm_getbits(command, 9, 3); + uint8_t op = vm_getbits(command, 54, 3); if(op) { - return eval_compare(op, eval_reg(command, vm_getbits(command, 12, 4)), - eval_reg_or_data(command, vm_getbits(command, 8, 1), 4)); + return eval_compare(op, eval_reg(command, vm_getbits(command, 51, 4)), + eval_reg_or_data(command, vm_getbits(command, 55, 1), 31)); } return 1; } @@ -204,20 +204,20 @@ static int32_t eval_if_version_4(command_t* command) { static int32_t eval_special_instruction(command_t* command, int32_t cond) { int32_t line, level; - switch(vm_getbits(command, 12, 4)) { + switch(vm_getbits(command, 51, 4)) { case 0: /* NOP */ line = 0; return cond ? line : 0; case 1: /* Goto line */ - line = vm_getbits(command, 56, 8); + line = vm_getbits(command, 7, 8); return cond ? line : 0; case 2: /* Break */ /* max number of rows < 256, so we will end this set */ line = 256; return cond ? 256 : 0; case 3: /* Set temporary parental level and goto */ - line = vm_getbits(command, 56, 8); - level = vm_getbits(command, 52, 4); + line = vm_getbits(command, 7, 8); + level = vm_getbits(command, 11, 4); if(cond) { /* This always succeeds now, if we want real parental protection */ /* we need to ask the user and have passwords and stuff. */ @@ -232,8 +232,8 @@ static int32_t eval_special_instruction(command_t* command, int32_t cond) { Return 1 if link, or 0 if no link Actual link instruction is in return_values parameter */ static int32_t eval_link_subins(command_t* command, int32_t cond, link_t *return_values) { - uint16_t button = vm_getbits(command, 48, 6); - uint8_t linkop = vm_getbits(command, 59, 5); + uint16_t button = vm_getbits(command, 15, 6); + uint8_t linkop = vm_getbits(command, 4, 5); if(linkop > 0x10) return 0; /* Unknown Link by Sub-Instruction command */ @@ -249,29 +249,29 @@ static int32_t eval_link_subins(command_t* command, int32_t cond, link_t *return Return 1 if link, or 0 if no link Actual link instruction is in return_values parameter */ static int32_t eval_link_instruction(command_t* command, int32_t cond, link_t *return_values) { - uint8_t op = vm_getbits(command, 12, 4); + uint8_t op = vm_getbits(command, 51, 4); switch(op) { case 1: return eval_link_subins(command, cond, return_values); case 4: return_values->command = LinkPGCN; - return_values->data1 = vm_getbits(command, 49, 15); + return_values->data1 = vm_getbits(command, 14, 15); return cond; case 5: return_values->command = LinkPTTN; - return_values->data1 = vm_getbits(command, 54, 10); - return_values->data2 = vm_getbits(command, 48, 6); + return_values->data1 = vm_getbits(command, 9, 10); + return_values->data2 = vm_getbits(command, 15, 6); return cond; case 6: return_values->command = LinkPGN; - return_values->data1 = vm_getbits(command, 57, 7); - return_values->data2 = vm_getbits(command, 48, 6); + return_values->data1 = vm_getbits(command, 6, 7); + return_values->data2 = vm_getbits(command, 15, 6); return cond; case 7: return_values->command = LinkCN; - return_values->data1 = vm_getbits(command, 56, 8); - return_values->data2 = vm_getbits(command, 48, 6); + return_values->data1 = vm_getbits(command, 7, 8); + return_values->data2 = vm_getbits(command, 15, 6); return cond; } return 0; @@ -283,64 +283,64 @@ static int32_t eval_link_instruction(command_t* command, int32_t cond, link_t *r actual jump instruction is in return_values parameter */ static int32_t eval_jump_instruction(command_t* command, int32_t cond, link_t *return_values) { - switch(vm_getbits(command, 12, 4)) { + switch(vm_getbits(command, 51, 4)) { case 1: return_values->command = Exit; return cond; case 2: return_values->command = JumpTT; - return_values->data1 = vm_getbits(command, 41, 7); + return_values->data1 = vm_getbits(command, 22, 7); return cond; case 3: return_values->command = JumpVTS_TT; - return_values->data1 = vm_getbits(command, 41, 7); + return_values->data1 = vm_getbits(command, 22, 7); return cond; case 5: return_values->command = JumpVTS_PTT; - return_values->data1 = vm_getbits(command, 41, 7); - return_values->data2 = vm_getbits(command, 22, 10); + return_values->data1 = vm_getbits(command, 22, 7); + return_values->data2 = vm_getbits(command, 41, 10); return cond; case 6: - switch(vm_getbits(command, 40, 2)) { + switch(vm_getbits(command, 23, 2)) { case 0: return_values->command = JumpSS_FP; return cond; case 1: return_values->command = JumpSS_VMGM_MENU; - return_values->data1 = vm_getbits(command, 44, 4); + return_values->data1 = vm_getbits(command, 19, 4); return cond; case 2: return_values->command = JumpSS_VTSM; - return_values->data1 = vm_getbits(command, 32, 8); - return_values->data2 = vm_getbits(command, 24, 8); - return_values->data3 = vm_getbits(command, 44, 4); + return_values->data1 = vm_getbits(command, 31, 8); + return_values->data2 = vm_getbits(command, 39, 8); + return_values->data3 = vm_getbits(command, 19, 4); return cond; case 3: return_values->command = JumpSS_VMGM_PGC; - return_values->data1 = vm_getbits(command, 17, 15); + return_values->data1 = vm_getbits(command, 46, 15); return cond; } break; case 8: - switch(vm_getbits(command, 40, 2)) { + switch(vm_getbits(command, 23, 2)) { case 0: return_values->command = CallSS_FP; - return_values->data1 = vm_getbits(command, 32, 8); + return_values->data1 = vm_getbits(command, 31, 8); return cond; case 1: return_values->command = CallSS_VMGM_MENU; - return_values->data1 = vm_getbits(command, 44, 4); - return_values->data2 = vm_getbits(command, 32, 8); + return_values->data1 = vm_getbits(command, 19, 4); + return_values->data2 = vm_getbits(command, 31, 8); return cond; case 2: return_values->command = CallSS_VTSM; - return_values->data1 = vm_getbits(command, 44, 4); - return_values->data2 = vm_getbits(command, 32, 8); + return_values->data1 = vm_getbits(command, 19, 4); + return_values->data2 = vm_getbits(command, 31, 8); return cond; case 3: return_values->command = CallSS_VMGM_PGC; - return_values->data1 = vm_getbits(command, 17, 15); - return_values->data2 = vm_getbits(command, 32, 8); + return_values->data1 = vm_getbits(command, 46, 15); + return_values->data2 = vm_getbits(command, 31, 8); return cond; } break; @@ -354,11 +354,11 @@ static int32_t eval_system_set(command_t* command, int32_t cond, link_t *return_ int32_t i; uint16_t data, data2; - switch(vm_getbits(command, 4, 4)) { + switch(vm_getbits(command, 59, 4)) { case 1: /* Set system reg 1 &| 2 &| 3 (Audio, Subp. Angle) */ for(i = 1; i <= 3; i++) { - if(vm_getbits(command, ((2 + i)*8), 1)) { - data = eval_reg_or_data_2(command, vm_getbits(command, 3, 1), 2 + i); + if(vm_getbits(command, 63 - ((2 + i)*8), 1)) { + data = eval_reg_or_data_2(command, vm_getbits(command, 60, 1), (47 - (i*8))); if(cond) { command->registers->SPRM[i] = data; } @@ -366,17 +366,17 @@ static int32_t eval_system_set(command_t* command, int32_t cond, link_t *return_ } break; case 2: /* Set system reg 9 & 10 (Navigation timer, Title PGC number) */ - data = eval_reg_or_data(command, vm_getbits(command, 3, 1), 2); - data2 = vm_getbits(command, 40, 8); /* ?? size */ + data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 47); + data2 = vm_getbits(command, 23, 8); /* ?? size */ if(cond) { command->registers->SPRM[9] = data; /* time */ command->registers->SPRM[10] = data2; /* pgcN */ } break; case 3: /* Mode: Counter / Register + Set */ - data = eval_reg_or_data(command, vm_getbits(command, 3, 1), 2); - data2 = vm_getbits(command, 44, 4); - if(vm_getbits(command, 40, 1)) { + data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 47); + data2 = vm_getbits(command, 19, 4); + if(vm_getbits(command, 23, 1)) { command->registers->GPRM_mode[data2] |= 1; /* Set bit 0 */ } else { command->registers->GPRM_mode[data2] &= ~ 0x01; /* Reset bit 0 */ @@ -386,13 +386,13 @@ static int32_t eval_system_set(command_t* command, int32_t cond, link_t *return_ } break; case 6: /* Set system reg 8 (Highlighted button) */ - data = eval_reg_or_data(command, vm_getbits(command, 3, 1), 4); /* Not system reg!! */ + data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 31); /* Not system reg!! */ if(cond) { command->registers->SPRM[8] = data; } break; } - if(vm_getbits(command, 12, 4)) { + if(vm_getbits(command, 51, 4)) { return eval_link_instruction(command, cond, return_values); } return 0; @@ -426,21 +426,25 @@ static void eval_set_op(command_t* command, int32_t op, int32_t reg, int32_t reg break; case 5: tmp = get_GPRM(command->registers, reg) * data; - if(tmp >= shortmax) tmp = shortmax; + if(tmp > shortmax) tmp = shortmax; set_GPRM(command->registers, reg, (uint16_t)tmp); break; case 6: if (data != 0) { set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) / data) ); } else { - set_GPRM(command->registers, reg, 0); /* Avoid that divide by zero! */ + set_GPRM(command->registers, reg, 0xffff); /* Avoid that divide by zero! */ } break; case 7: - set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) % data) ); + if (data != 0) { + set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) % data) ); + } else { + set_GPRM(command->registers, reg, 0xffff); /* Avoid that divide by zero! */ + } break; - case 8: /* SPECIAL CASE - RND! */ - set_GPRM(command->registers, reg, ((uint16_t) ((float) data * rand()/(RAND_MAX+1.0))) ); + case 8: /* SPECIAL CASE - RND! Return numbers between 1 and data. */ + set_GPRM(command->registers, reg, 1 + ((uint16_t) ((float) data * rand()/(RAND_MAX+1.0))) ); break; case 9: set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) & data) ); @@ -456,10 +460,10 @@ static void eval_set_op(command_t* command, int32_t op, int32_t reg, int32_t reg /* Evaluate set instruction, combined with either Link or Compare. */ static void eval_set_version_1(command_t* command, int32_t cond) { - uint8_t op = vm_getbits(command, 4, 4); - uint8_t reg = vm_getbits(command, 28, 4); /* FIXME: This is different from vmcmd.c!!! */ - uint8_t reg2 = vm_getbits(command, 44, 4); - uint16_t data = eval_reg_or_data(command, vm_getbits(command, 3, 1), 4); + uint8_t op = vm_getbits(command, 59, 4); + uint8_t reg = vm_getbits(command, 35, 4); /* FIXME: This is different from vmcmd.c!!! */ + uint8_t reg2 = vm_getbits(command, 19, 4); + uint16_t data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 31); if(cond) { eval_set_op(command, op, reg, reg2, data); @@ -469,10 +473,10 @@ static void eval_set_version_1(command_t* command, int32_t cond) { /* Evaluate set instruction, combined with both Link and Compare. */ static void eval_set_version_2(command_t* command, int32_t cond) { - uint8_t op = vm_getbits(command, 4, 4); - uint8_t reg = vm_getbits(command, 12, 4); - uint8_t reg2 = vm_getbits(command, 28, 4); /* FIXME: This is different from vmcmd.c!!! */ - uint16_t data = eval_reg_or_data(command, vm_getbits(command, 3, 1), 2); + uint8_t op = vm_getbits(command, 59, 4); + uint8_t reg = vm_getbits(command, 51, 4); + uint8_t reg2 = vm_getbits(command, 35, 4); /* FIXME: This is different from vmcmd.c!!! */ + uint16_t data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 47); if(cond) { eval_set_op(command, op, reg, reg2, data); @@ -498,7 +502,7 @@ static int32_t eval_command(uint8_t *bytes, registers_t* registers, link_t *retu command.registers = registers; memset(return_values, 0, sizeof(link_t)); - switch(vm_getbits(&command, 0, 3)) { /* three first old_bits */ + switch(vm_getbits(&command, 63, 3)) { /* three first old_bits */ case 0: /* Special instructions */ cond = eval_if_version_1(&command); res = eval_special_instruction(&command, cond); @@ -508,7 +512,7 @@ static int32_t eval_command(uint8_t *bytes, registers_t* registers, link_t *retu } break; case 1: /* Link/jump instructions */ - if(vm_getbits(&command, 3, 1)) { + if(vm_getbits(&command, 60, 1)) { cond = eval_if_version_2(&command); res = eval_jump_instruction(&command, cond, return_values); } else { @@ -527,7 +531,7 @@ static int32_t eval_command(uint8_t *bytes, registers_t* registers, link_t *retu case 3: /* Set instructions, either Compare or Link may be used */ cond = eval_if_version_3(&command); eval_set_version_1(&command, cond); - if(vm_getbits(&command, 12, 4)) { + if(vm_getbits(&command, 51, 4)) { res = eval_link_instruction(&command, cond, return_values); } if(res) @@ -541,6 +545,7 @@ static int32_t eval_command(uint8_t *bytes, registers_t* registers, link_t *retu res = -1; break; case 5: /* Compare -> (Set and Link Sub-Instruction) */ + /* FIXME: These are wrong. Need to be updated from vmcmd.c */ cond = eval_if_version_4(&command); eval_set_version_2(&command, cond); res = eval_link_subins(&command, cond, return_values); @@ -548,6 +553,7 @@ static int32_t eval_command(uint8_t *bytes, registers_t* registers, link_t *retu res = -1; break; case 6: /* Compare -> Set, allways Link Sub-Instruction */ + /* FIXME: These are wrong. Need to be updated from vmcmd.c */ cond = eval_if_version_4(&command); eval_set_version_2(&command, cond); res = eval_link_subins(&command, /*True*/ 1, return_values); @@ -555,7 +561,7 @@ static int32_t eval_command(uint8_t *bytes, registers_t* registers, link_t *retu res = -1; break; default: /* Unknown command */ - fprintf(MSG_OUT, "libdvdnav: WARNING: Unknown Command=%x\n", vm_getbits(&command, 0, 3)); + fprintf(MSG_OUT, "libdvdnav: WARNING: Unknown Command=%x\n", vm_getbits(&command, 63, 3)); assert(0); } /* Check if there are bits not yet examined */ @@ -578,10 +584,10 @@ int32_t vmEval_CMD(vm_cmd_t commands[], int32_t num_commands, #ifdef TRACE /* DEBUG */ fprintf(MSG_OUT, "libdvdnav: Registers before transaction\n"); - vmPrint_registers( registers ); + vm_print_registers( registers ); fprintf(MSG_OUT, "libdvdnav: Full list of commands to execute\n"); for(i = 0; i < num_commands; i++) - vmPrint_CMD(i, &commands[i]); + vm_print_cmd(i, &commands[i]); fprintf(MSG_OUT, "libdvdnav: --------------------------------------------\n"); fprintf(MSG_OUT, "libdvdnav: Single stepping commands\n"); #endif @@ -591,7 +597,7 @@ int32_t vmEval_CMD(vm_cmd_t commands[], int32_t num_commands, int32_t line; #ifdef TRACE - vmPrint_CMD(i, &commands[i]); + vm_print_cmd(i, &commands[i]); #endif line = eval_command(&commands[i].bytes[0], registers, return_values); @@ -599,7 +605,7 @@ int32_t vmEval_CMD(vm_cmd_t commands[], int32_t num_commands, if (line < 0) { /* Link command */ #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: Registers after transaction\n"); - vmPrint_registers( registers ); + vm_print_registers( registers ); fprintf(MSG_OUT, "libdvdnav: eval: Doing Link/Jump/Call\n"); #endif return 1; @@ -616,7 +622,7 @@ int32_t vmEval_CMD(vm_cmd_t commands[], int32_t num_commands, memset(return_values, 0, sizeof(link_t)); #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: Registers after transaction\n"); - vmPrint_registers( registers ); + vm_print_registers( registers ); #endif return 0; } @@ -689,7 +695,7 @@ static char *linkcmd2str(link_cmd_t cmd) { return "*** (bug)"; } -void vmPrint_LINK(link_t value) { +void vm_print_link(link_t value) { char *cmd = linkcmd2str(value.command); switch(value.command) { @@ -745,7 +751,7 @@ void vmPrint_LINK(link_t value) { } } -void vmPrint_registers( registers_t *registers ) { +void vm_print_registers( registers_t *registers ) { int32_t i; fprintf(MSG_OUT, "libdvdnav: # "); for(i = 0; i < 24; i++) diff --git a/src/input/libdvdnav/decoder.h b/src/input/libdvdnav/decoder.h index 16e2cc8d0..0d7e5e401 100644 --- a/src/input/libdvdnav/decoder.h +++ b/src/input/libdvdnav/decoder.h @@ -18,7 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: decoder.h,v 1.6 2003/03/29 13:19:08 mroi Exp $ + * $Id: decoder.h,v 1.7 2003/04/07 18:10:46 mroi Exp $ * */ @@ -109,10 +109,10 @@ uint32_t vm_getbits(command_t* command, int start, int count); #ifdef TRACE /* for debugging: prints a link in readable form */ -void vmPrint_LINK(link_t value); +void vm_print_link(link_t value); /* for debugging: dumps VM registers */ -void vmPrint_registers( registers_t *registers ); +void vm_print_registers( registers_t *registers ); #endif #endif /* DECODER_H_INCLUDED */ diff --git a/src/input/libdvdnav/diff_against_cvs.patch b/src/input/libdvdnav/diff_against_cvs.patch index cf3a0ddad..a68b867e4 100644 --- a/src/input/libdvdnav/diff_against_cvs.patch +++ b/src/input/libdvdnav/diff_against_cvs.patch @@ -42,20 +42,20 @@ this = (dvdnav_t*)malloc(sizeof(dvdnav_t)); --- src/input/libdvdnav/dvdnav.h Thu Jul 25 17:26:00 2002 +++ src/input/libdvdnav/dvdnav.h Fri Aug 9 22:01:19 2002 -@@ -40,8 +40,8 @@ - /* Various useful types */ - #include "dvd_types.h" +@@ -41,8 +41,8 @@ + # include <dvdnav/dvd_types.h> + #endif -#include <dvdread/dvd_reader.h> -#include <dvdread/ifo_types.h> /* For vm_cmd_t */ +#include "dvd_reader.h" +#include "ifo_types.h" /* For vm_cmd_t */ - /** - * Opaque data-type can be viewed as a 'DVD handle'. You should get + + /********************************************************************* --- src/input/libdvdnav/dvdnav_events.h Fri Jul 5 16:55:04 2002 +++ src/input/libdvdnav/dvdnav_events.h Fri Aug 9 22:01:50 2002 -@@ -24,9 +24,9 @@ +@@ -28,9 +28,9 @@ #ifndef DVDNAV_EVENTS_H_INCLUDED #define DVDNAV_EVENTS_H_INCLUDED @@ -66,8 +66,8 @@ +#include "dvd_reader.h" +#include "nav_types.h" - /** - * \file dvdnav_events.h + + /* --- src/input/libdvdnav/dvdnav_internal.h Fri Aug 2 15:01:39 2002 +++ src/input/libdvdnav/dvdnav_internal.h Fri Aug 9 22:02:18 2002 @@ -1,3 +1,4 @@ diff --git a/src/input/libdvdnav/dvd_types.h b/src/input/libdvdnav/dvd_types.h index 2c6967b8e..bd4bdd0fd 100644 --- a/src/input/libdvdnav/dvd_types.h +++ b/src/input/libdvdnav/dvd_types.h @@ -18,7 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: dvd_types.h,v 1.2 2002/09/20 12:53:53 mroi Exp $ + * $Id: dvd_types.h,v 1.3 2003/04/07 18:10:47 mroi Exp $ * */ @@ -48,6 +48,7 @@ typedef enum { * DVD Menu */ typedef enum { + DVD_MENU_Escape = 0, /**< TBD */ DVD_MENU_Title = 2, /**< TBD */ DVD_MENU_Root = 3, /**< TBD */ DVD_MENU_Subpicture = 4, /**< TBD */ diff --git a/src/input/libdvdnav/dvdnav.c b/src/input/libdvdnav/dvdnav.c index a42c06bfc..6b4609a14 100644 --- a/src/input/libdvdnav/dvdnav.c +++ b/src/input/libdvdnav/dvdnav.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: dvdnav.c,v 1.23 2003/04/06 13:09:38 mroi Exp $ + * $Id: dvdnav.c,v 1.24 2003/04/07 18:10:47 mroi Exp $ * */ @@ -471,6 +471,9 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, unsigned char **buf, } } this->position_current.hop_channel = this->position_next.hop_channel; + /* update VOBU info */ + this->vobu.vobu_start = this->position_next.cell_start + this->position_next.block; + this->vobu.vobu_next = 0; /* Make blockN == vobu_length to do expected_nav */ this->vobu.vobu_length = 0; this->vobu.blockN = 0; @@ -590,7 +593,7 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, unsigned char **buf, cell_event->pgN = state->pgN; cell_event->cell_length = dvdnav_convert_time(&state->pgc->cell_playback[state->cellN-1].playback_time); - + cell_event->pg_length = 0; /* Find start cell of program. */ first_cell_nr = state->pgc->program_map[state->pgN-1]; @@ -613,7 +616,7 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, unsigned char **buf, for (i = 1; i < state->pgc->program_map[state->pgN-1]; i++) cell_event->pg_start += dvdnav_convert_time(&state->pgc->cell_playback[i - 1].playback_time); - + this->position_current.cell = this->position_next.cell; this->position_current.cell_restart = this->position_next.cell_restart; this->position_current.cell_start = this->position_next.cell_start; @@ -821,9 +824,15 @@ dvdnav_status_t dvdnav_get_title_string(dvdnav_t *this, const char **title_str) uint8_t dvdnav_get_video_aspect(dvdnav_t *this) { uint8_t retval; - if(!this) + if(!this) { + printerr("Passed a NULL pointer."); return -1; - + } + if(!this->started) { + printerr("Virtual DVD machine not started."); + return -1; + } + pthread_mutex_lock(&this->vm_lock); retval = (uint8_t)vm_get_video_aspect(this->vm); pthread_mutex_unlock(&this->vm_lock); @@ -834,8 +843,14 @@ uint8_t dvdnav_get_video_aspect(dvdnav_t *this) { uint8_t dvdnav_get_video_scale_permission(dvdnav_t *this) { uint8_t retval; - if(!this) + if(!this) { + printerr("Passed a NULL pointer."); return -1; + } + if(!this->started) { + printerr("Virtual DVD machine not started."); + return -1; + } pthread_mutex_lock(&this->vm_lock); retval = (uint8_t)vm_get_video_scale_permission(this->vm); @@ -847,8 +862,14 @@ uint8_t dvdnav_get_video_scale_permission(dvdnav_t *this) { uint16_t dvdnav_audio_stream_to_lang(dvdnav_t *this, uint8_t stream) { audio_attr_t attr; - if(!this) + if(!this) { + printerr("Passed a NULL pointer."); return -1; + } + if(!this->started) { + printerr("Virtual DVD machine not started."); + return -1; + } pthread_mutex_lock(&this->vm_lock); attr = vm_get_audio_attr(this->vm, stream); @@ -863,8 +884,14 @@ uint16_t dvdnav_audio_stream_to_lang(dvdnav_t *this, uint8_t stream) { uint16_t dvdnav_spu_stream_to_lang(dvdnav_t *this, uint8_t stream) { subp_attr_t attr; - if(!this) + if(!this) { + printerr("Passed a NULL pointer."); + return -1; + } + if(!this->started) { + printerr("Virtual DVD machine not started."); return -1; + } pthread_mutex_lock(&this->vm_lock); attr = vm_get_subp_attr(this->vm, stream); @@ -879,11 +906,18 @@ uint16_t dvdnav_spu_stream_to_lang(dvdnav_t *this, uint8_t stream) { int8_t dvdnav_get_audio_logical_stream(dvdnav_t *this, uint8_t audio_num) { int8_t retval; - if(!this) + if(!this) { + printerr("Passed a NULL pointer."); + return -1; + } + if(!this->started) { + printerr("Virtual DVD machine not started."); return -1; + } pthread_mutex_lock(&this->vm_lock); if (!this->vm->state.pgc) { + printerr("No current PGC."); pthread_mutex_unlock(&this->vm_lock); return -1; } @@ -896,11 +930,18 @@ int8_t dvdnav_get_audio_logical_stream(dvdnav_t *this, uint8_t audio_num) { int8_t dvdnav_get_spu_logical_stream(dvdnav_t *this, uint8_t subp_num) { int8_t retval; - if(!this) + if(!this) { + printerr("Passed a NULL pointer."); return -1; + } + if(!this->started) { + printerr("Virtual DVD machine not started."); + return -1; + } pthread_mutex_lock(&this->vm_lock); if (!this->vm->state.pgc) { + printerr("No current PGC."); pthread_mutex_unlock(&this->vm_lock); return -1; } @@ -913,11 +954,18 @@ int8_t dvdnav_get_spu_logical_stream(dvdnav_t *this, uint8_t subp_num) { int8_t dvdnav_get_active_audio_stream(dvdnav_t *this) { int8_t retval; - if(!this) + if(!this) { + printerr("Passed a NULL pointer."); + return -1; + } + if(!this->started) { + printerr("Virtual DVD machine not started."); return -1; + } pthread_mutex_lock(&this->vm_lock); if (!this->vm->state.pgc) { + printerr("No current PGC."); pthread_mutex_unlock(&this->vm_lock); return -1; } @@ -930,11 +978,18 @@ int8_t dvdnav_get_active_audio_stream(dvdnav_t *this) { int8_t dvdnav_get_active_spu_stream(dvdnav_t *this) { int8_t retval; - if(!this) + if(!this) { + printerr("Passed a NULL pointer."); + return -1; + } + if(!this->started) { + printerr("Virtual DVD machine not started."); return -1; + } pthread_mutex_lock(&this->vm_lock); if (!this->vm->state.pgc) { + printerr("No current PGC."); pthread_mutex_unlock(&this->vm_lock); return -1; } @@ -947,8 +1002,14 @@ int8_t dvdnav_get_active_spu_stream(dvdnav_t *this) { static int8_t dvdnav_is_domain(dvdnav_t *this, domain_t domain) { int8_t retval; - if (!this || !this->started) + if(!this) { + printerr("Passed a NULL pointer."); + return -1; + } + if(!this->started) { + printerr("Virtual DVD machine not started."); return -1; + } pthread_mutex_lock(&this->vm_lock); retval = (this->vm->state.domain == domain); @@ -1029,6 +1090,9 @@ uint32_t dvdnav_get_next_still_flag(dvdnav_t *this) { /* * $Log: dvdnav.c,v $ + * Revision 1.24 2003/04/07 18:10:47 mroi + * merging libdvdnav, since some nice fixes took place + * * Revision 1.23 2003/04/06 13:09:38 mroi * report start of PG as well * diff --git a/src/input/libdvdnav/dvdnav.h b/src/input/libdvdnav/dvdnav.h index fb8aa866e..67a82c69d 100644 --- a/src/input/libdvdnav/dvdnav.h +++ b/src/input/libdvdnav/dvdnav.h @@ -17,14 +17,13 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: dvdnav.h,v 1.8 2003/03/25 13:17:21 mroi Exp $ + * $Id: dvdnav.h,v 1.9 2003/04/07 18:10:48 mroi Exp $ * */ -/** - * \file dvdnav.h - * The main file you should include if you want to access dvdnav - * functionality. +/* + * This is the main header file applications should include if they want + * to access dvdnav functionality. */ #ifndef DVDNAV_H_INCLUDED @@ -34,182 +33,161 @@ extern "C" { #endif -/* Defines the various events and dvdnav_event_t */ -#include "dvdnav_events.h" - -/* Various useful types */ -#include "dvd_types.h" +#ifdef DVDNAV_COMPILE +# include "dvdnav_events.h" +# include "dvd_types.h" +#else +# include <dvdnav/dvdnav_events.h> +# include <dvdnav/dvd_types.h> +#endif #include "dvd_reader.h" #include "ifo_types.h" /* For vm_cmd_t */ -/** + +/********************************************************************* + * dvdnav data types * + *********************************************************************/ + +/* * Opaque data-type can be viewed as a 'DVD handle'. You should get * a pointer to a dvdnav_t from the dvdnav_open() function. - * \sa dvdnav_open() + * Never call free() on the pointer, you have to give it back with + * dvdnav_close(). */ typedef struct dvdnav_s dvdnav_t; -/* Status */ +/* Status as reported by most of libdvdnav's functions */ typedef int dvdnav_status_t; +/* + * Unless otherwise stated, all functions return DVDNAV_STATUS_OK if + * they succeeded, otherwise DVDNAV_STATUS_ERR is returned and the error may + * be obtained by calling dvdnav_err_to_string(). + */ #define DVDNAV_STATUS_ERR 0 #define DVDNAV_STATUS_OK 1 -/** - * \defgroup init Initialisation & housekeeping functions + +/********************************************************************* + * initialisation & housekeeping functions * + *********************************************************************/ + +/* * These functions allow you to open a DVD device and associate it * with a dvdnav_t. - * - * Unless otherwise stated, all functions return DVDNAV_STATUS_OK if - * they succeeded, otherwise DVDNAV_STATUS_ERR is returned and the error may - * be obtained by calling dvdnav_err_to_string(). - * - * A minimal <tt>libdvdnav</tt> program should always call dvdnav_open() - * and dvdnav_close(). - * - * \par Example: - * \include minimal.c - * - * @{ */ -/** - * Attempts to open the DVD drive at the specifiec path and pre-cache - * any CSS-keys that your hacked libdvdread may use. +/* + * Attempts to open the DVD drive at the specified path and pre-cache + * the CSS-keys. libdvdread is used to access the DVD, so any source + * supported by libdvdread can be given with "path". Currently, + * libdvdread can access: DVD drives, DVD image files, DVD file-by-file + * copies. * - * \param dest Pointer to a dvdnav_t pointer to fill in. - * \param path Any libdvdread acceptable path + * The resulting dvdnav_t handle will be written to *dest. */ -dvdnav_status_t dvdnav_open(dvdnav_t** dest, const char *path); +dvdnav_status_t dvdnav_open(dvdnav_t **dest, const char *path); -/** +/* * Closes a dvdnav_t previously opened with dvdnav_open(), freeing any * memory associated with it. - * - * \param self dvdnav_t to close. */ dvdnav_status_t dvdnav_close(dvdnav_t *self); -/** - * Resets the virtual machine and buffers in a previously opened dvdnav - * - * \param self dvdnav_t to reset. +/* + * Resets the DVD virtual machine and cache buffers. */ dvdnav_status_t dvdnav_reset(dvdnav_t *self); -/** +/* * Fills a pointer with a value pointing to a string describing - * the path associated with an open dvdnav_t. It assigns it NULL + * the path associated with an open dvdnav_t. It assigns *path to NULL * on error. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param path Pointer to char* to fill in. */ -dvdnav_status_t dvdnav_path(dvdnav_t *self, const char** path); +dvdnav_status_t dvdnav_path(dvdnav_t *self, const char **path); -/** +/* * Returns a human-readable string describing the last error. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \returns A pointer to said string. */ const char* dvdnav_err_to_string(dvdnav_t *self); -/** \@} */ -/** - * \defgroup char Changing and Reading DVD Player characteristics - * +/********************************************************************* + * changing and reading DVD player characteristics * + *********************************************************************/ + +/* * These functions allow you to manipulate the various global characteristics * of the DVD playback engine. - * - * @{ */ -/** - * Returns the region mask (bit 0 set implies region 1, bit 1 set implies +/* + * Sets the region mask (bit 0 set implies region 1, bit 1 set implies * region 2, etc) of the virtual machine. Generally you will only need to set * this if you are playing RCE discs which query the virtual machine as to its * region setting. * - * \par Note: - * This has <b>nothing</b> to do with the region setting of the DVD drive. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param region Pointer to an int which will receive the region code mask. + * This has _nothing_ to do with the region setting of the DVD drive. */ -dvdnav_status_t dvdnav_get_region_mask(dvdnav_t *self, int *region); +dvdnav_status_t dvdnav_set_region_mask(dvdnav_t *self, int region_mask); -/** - * Sets the region mask of the virtual machine. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param mask 0x00..0xff -- the desired region mask. +/* + * Returns the region mask (bit 0 set implies region 1, bit 1 set implies + * region 2, etc) of the virtual machine. * - * \sa dvdnav_get_region_mask() + * This has _nothing_ to do with the region setting of the DVD drive. */ -dvdnav_status_t dvdnav_set_region_mask(dvdnav_t *self, int mask); +dvdnav_status_t dvdnav_get_region_mask(dvdnav_t *self, int *region_mask); -/** +/* * Specify whether read-ahead caching should be used. You may not want this if your * decoding engine does its own buffering. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param use_readahead 0 - no, 1 - yes - */ -dvdnav_status_t dvdnav_set_readahead_flag(dvdnav_t *self, int use_readahead); - -/** - * Query whether readahead caching/buffering will be used. * - * \param self Pointer to dvdnav_t associated with this operation. - * \param flag Pointer to int to recieve flag value. + * The default read-ahead cache does not use an additional thread for the reading + * (see read_cache.c for a threaded cache, but note that this code is currently + * unmaintained). It prebuffers on VOBU level by reading ahead several buffers + * on every read request. The speed of this prebuffering has been optimized to + * also work on slow DVD drives. * - * \sa dvdnav_get_readahead_flag() + * If in addition you want to prevent memcpy's to improve performance, have a look + * at dvdnav_get_next_cache_block(). */ -dvdnav_status_t dvdnav_get_readahead_flag(dvdnav_t *self, int* flag); +dvdnav_status_t dvdnav_set_readahead_flag(dvdnav_t *self, int read_ahead_flag); -/** +/* + * Query whether read-ahead caching/buffering will be used. + */ +dvdnav_status_t dvdnav_get_readahead_flag(dvdnav_t *self, int *read_ahead_flag); + +/* * Specify whether the positioning works PGC or PG based. - * Programs (PGs) on DVDs are similar to Chapters and the program chain (PGC) + * Programs (PGs) on DVDs are similar to Chapters and a program chain (PGC) * usually covers a whole feature. This affects the behaviour of the - * functions dvdnav_get_position() and dvdnav_sector_search(). + * functions dvdnav_get_position() and dvdnav_sector_search(). See there. * Default is PG based positioning. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param pgc 0 - PG based, 1 - PGC based */ -dvdnav_status_t dvdnav_set_PGC_positioning_flag(dvdnav_t *self, int pgc); +dvdnav_status_t dvdnav_set_PGC_positioning_flag(dvdnav_t *self, int pgc_based_flag); -/** +/* * Query whether positioning is PG or PGC based. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param flag Pointer to int to recieve flag value. - * - * \sa dvdnav_set_PGC_positioning_flag() */ -dvdnav_status_t dvdnav_get_PGC_positioning_flag(dvdnav_t *self, int *flag); +dvdnav_status_t dvdnav_get_PGC_positioning_flag(dvdnav_t *self, int *pgc_based_flag); -/** - * @} - */ -/** - * \defgroup data Reading Data - * +/********************************************************************* + * reading data * + *********************************************************************/ + +/* * These functions are used to poll the playback enginge and actually get data * off the DVD. - * - * @{ */ -/** +/* * Attempts to get the next block off the DVD and copies it into the buffer 'buf'. * If there is any special actions that may need to be performed, the value - * pointed to by 'event' gets set - * accordingly. + * pointed to by 'event' gets set accordingly. * * If 'event' is DVDNAV_BLOCK_OK then 'buf' is filled with the next block * (note that means it has to be at /least/ 2048 bytes big). 'len' is @@ -218,312 +196,211 @@ dvdnav_status_t dvdnav_get_PGC_positioning_flag(dvdnav_t *self, int *flag); * Otherwise, buf is filled with an appropriate event structure and * len is set to the length of that structure. * - * \param self Pointer to dvdnav_t associated with this operation. - * \param buf Buffer (at least 2048 octets) to fill with next block/event structure. - * \param event Pointer to int to get event type. - * \param len Pointer to int to get the number of octets written into buf. + * See the dvdnav_events.h header for information on the various events. */ dvdnav_status_t dvdnav_get_next_block(dvdnav_t *self, unsigned char *buf, int *event, int *len); -/** +/* * This basically does the same as dvdnav_get_next_block. The only difference is * that it avoids a memcopy, when the requested block was found in the cache. * I such a case (cache hit) this function will return a different pointer than * the one handed in, pointing directly into the relevant block in the cache. - * Those pointer must _never_ be freed but instead returned to the library via + * Those pointers must _never_ be freed but instead returned to the library via * dvdnav_free_cache_block(). - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param buf Buffer (at least 2048 octets) to fill with next block/event structure. - * A different buffer might be returned, if the block was found in the internal cache. - * \param event Pointer to int to get event type. - * \param len Pointer to int to get the number of octets written into buf. */ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *self, unsigned char **buf, int *event, int *len); -/** +/* * All buffers which came from the internal cache (when dvdnav_get_next_cache_block() * returned a buffer different from the one handed in) have to be freed with this * function. Although handing in other buffers not from the cache doesn't cause any harm. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param buf Buffer received from internal cache. */ dvdnav_status_t dvdnav_free_cache_block(dvdnav_t *self, unsigned char *buf); -/** - * Get video aspect code. +/* + * If we are currently in a still-frame this function skips it. * - * \param self Pointer to dvdnav_t associated with this operation. - * - * \returns Video aspect ratio code, 0 -- 4:3, 2 -- 16:9 + * See also the DVDNAV_STILL_FRAME event. */ -uint8_t dvdnav_get_video_aspect(dvdnav_t *self); +dvdnav_status_t dvdnav_still_skip(dvdnav_t *self); -/** - * Get video scaling permissions. +/* + * If we are currently in WAIT state, that is: the application is required to + * wait for its fifos to become empty, calling this signals libdvdnav that this + * is achieved and that it can continue. * - * \param self Pointer to dvdnav_t associated with this operation. - * - * \returns Video scaling permissions, bit0 - deny letterboxing, bit1 - deny pan&scan + * See also the DVDNAV_WAIT event. */ -uint8_t dvdnav_get_video_scale_permission(dvdnav_t *self); - -/** - * Return a string describing the title. This is an ID string encoded on the - * disc byt the author. In many cases this is a descriptive string such as - * `<tt>THE_MATRIX</tt>' but sometimes is sigularly uninformative such as - * `<tt>PDVD-011421</tt>'. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param title_str Pointer to C-style string to receive a string describing the title. - */ -dvdnav_status_t dvdnav_get_title_string(dvdnav_t *self, const char **title_str); +dvdnav_status_t dvdnav_wait_skip(dvdnav_t *self); -/** - * @} +/* + * Returns the still time from the currently playing cell. + * The still time is given in seconds with 0xff meaning an indefinite still. + * + * This function can be used to detect still frames before they are reached. + * Some players might need this to prepare for a frame to be shown for a + * longer time than usual. */ +uint32_t dvdnav_get_next_still_flag(dvdnav_t *self); -/** - * \defgroup nav Navigation Commands +/* + * Stops playback. The next event obtained with one of the get_next_block + * functions will be a DVDNAV_STOP event. * - * @{ + * It is not required to call this before dvdnav_close(). */ +dvdnav_status_t dvdnav_stop(dvdnav_t *self); + + +/********************************************************************* + * title/part navigation * + *********************************************************************/ -/** +/* * Returns the number of titles on the disk. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param titles Pointer to int to receive number of titles. */ dvdnav_status_t dvdnav_get_number_of_titles(dvdnav_t *self, int *titles); -/** - * Returns the number of programs within the current title. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param titles int to select title. - * \param parts Pointer to int to receive number of parts. +/* + * Returns the number of parts within the given title. */ dvdnav_status_t dvdnav_get_number_of_parts(dvdnav_t *self, int title, int *parts); -/** - * If we are currently in a still-frame this function skips it (or attempts to). - * This might fail if this still-frame is of infinite duration as most DVD - * authors wouldn't expect you to be able to do this <tt>:)</tt> - * - * \param self Pointer to dvdnav_t associated with this operation. - */ -dvdnav_status_t dvdnav_still_skip(dvdnav_t *self); - -/** - * If we are currently in WAIT state, that is: the application is required to - * wait for its fifos to become empty, calling this signals libdvdnav that this - * is achieved and that it can continue. - * - * \param self Pointer to dvdnav_t associated with this operation. - */ -dvdnav_status_t dvdnav_wait_skip(dvdnav_t *self); - -/** - * Returns the still time status from the next cell - * - * \param self Pointer to dvdnav_t associated with this operation. - */ -uint32_t dvdnav_get_next_still_flag(dvdnav_t *self); - -/** - * Plays a specified title of the DVD. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param title 1..99 -- Title number to play. +/* + * Plays the specified title of the DVD from its beginning (that is: part 1). */ dvdnav_status_t dvdnav_title_play(dvdnav_t *self, int title); -/** - * Plays the specifiec title, starting from the specified part. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param title 1..99 -- Title number to play. - * \param part 1..999 -- Part to start from. +/* + * Plays the specified title, starting from the specified part. */ dvdnav_status_t dvdnav_part_play(dvdnav_t *self, int title, int part); -/** +/* * Play the specified amount of parts of the specified title of * the DVD then STOP. * - * \par Note: * Currently unimplemented! - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param title 1..99 -- Title number to play. - * \param part 1..999 -- Part to start from. - * \param parts_to_play 1..999 -- Number of parts to play. */ dvdnav_status_t dvdnav_part_play_auto_stop(dvdnav_t *self, int title, int part, int parts_to_play); -/** - * Play the specified title starting from the specified time +/* + * Play the specified title starting from the specified time. * - * \par Note: * Currently unimplemented! - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param title 1..99 -- Title number to play. - * \param time Timecode to start from (hours, minutes, seconds + frames). */ dvdnav_status_t dvdnav_time_play(dvdnav_t *self, int title, unsigned long int time); -/** - * Stops playing the current title (causes a STOP action in - * dvdnav_get_next_block()). - * - * \param self Pointer to dvdnav_t associated with this operation. - * - * \sa dvdnav_get_next_block() - */ -dvdnav_status_t dvdnav_stop(dvdnav_t *self); - -/** - * Stop playing current title and play the "GoUp"-program chain - * (which generally leads to the title menu or a higer-level menu). - * - * \param self Pointer to dvdnav_t associated with this operation. - */ -dvdnav_status_t dvdnav_go_up(dvdnav_t *self); - -/** +/* * Stop playing the current position and jump to the specified menu. * - * \param self Pointer to dvdnav_t associated with this operation. - * \param menu Which menu to call (see DVDMenuID_t). - * - * \sa DVDMenuID_t (from <tt>libdvdread</tt>) + * See also DVDMenuID_t from libdvdread */ dvdnav_status_t dvdnav_menu_call(dvdnav_t *self, DVDMenuID_t menu); -/** - * Return the title number and part currently being played or - * -1 if in a menu. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param title Pointer to into which will receive the current title number. - * \param part Pointer to into which will receive the current part number. +/* + * Return the title number and part currently being played. + * A title of 0 indicates, we are in a menu. In this case, part + * is set to the current menu's ID. */ dvdnav_status_t dvdnav_current_title_info(dvdnav_t *self, int *title, - int *part); + int *part); -/** - * @} +/* + * Return the current position (in blocks) within the current + * title and the length (in blocks) of said title. + * + * Current implementation is wrong and likely to behave unpredictably! + * Use is discouraged! */ +dvdnav_status_t dvdnav_get_position_in_title(dvdnav_t *self, + unsigned int *pos, + unsigned int *len); -/** - * \defgroup search Searching +/* + * This function is only available for compatibility reasons. * - * @{ + * Stop playing the current position and start playback of the current title + * from the specified part. */ +dvdnav_status_t dvdnav_part_search(dvdnav_t *self, int part); -/** - * Stop playing the current position and start playback of the title - * from the specified timecode. - * - * \par Note: - * Currently unimplemented! - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param time Timecode to start from. - */ -dvdnav_status_t dvdnav_time_search(dvdnav_t *self, - unsigned long int time); -/** +/********************************************************************* + * program chain/program navigation * + *********************************************************************/ + +/* * Stop playing the current position and start playback from the last * VOBU boundary before the given sector. The sector number is not * meant to be an absolute physical DVD sector, but a relative sector * in the current program. This function cannot leave the current * program and will fail, if asked to do so. - * - * from the specified sector offset. * - * \param self Pointer to dvdnav_t associated with this operation. - * \param offset Sector offset to start from. - * \param origin Start from here, start or end. + * If program chain based positioning is enabled + * (see dvdnav_set_PGC_positioning_flag()), this will seek to the relative + * sector inside the current program chain. + * + * 'origin' can be one of SEEK_SET, SEEK_CUR, SEEK_END as defined in + * fcntl.h. */ dvdnav_status_t dvdnav_sector_search(dvdnav_t *self, unsigned long int offset, int origin); -/** - * Stop playing the current position and start playback of the current title - * from the specified part (chapter). +/* + * Stop playing the current position and start playback of the title + * from the specified timecode. * - * \param self Pointer to dvdnav_t associated with this operation. - * \param part 1..999 -- Part to start from. + * Currently unimplemented! */ -dvdnav_status_t dvdnav_part_search(dvdnav_t *self, int part); +dvdnav_status_t dvdnav_time_search(dvdnav_t *self, + unsigned long int time); -/** +/* + * Stop playing current position and play the "GoUp"-program chain. + * (which generally leads to the title menu or a higer-level menu). + */ +dvdnav_status_t dvdnav_go_up(dvdnav_t *self); + +/* * Stop playing the current position and start playback at the * previous program (if it exists). - * - * \param self Pointer to dvdnav_t associated with this operation. */ dvdnav_status_t dvdnav_prev_pg_search(dvdnav_t *self); -/** +/* * Stop playing the current position and start playback at the * first program. - * - * \param self Pointer to dvdnav_t associated with this operation. */ dvdnav_status_t dvdnav_top_pg_search(dvdnav_t *self); -/** +/* * Stop playing the current position and start playback at the * next program (if it exists). - * - * \param self Pointer to dvdnav_t associated with this operation. */ dvdnav_status_t dvdnav_next_pg_search(dvdnav_t *self); -/** +/* * Return the current position (in blocks) within the current * program and the length (in blocks) of current program. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param pos Pointer to unsigned int to get the current position. - * \param len Pointer to unsinged int to hold the length of the current program. + * + * If program chain based positioning is enabled + * (see dvdnav_set_PGC_positioning_flag()), this will return the + * relative position in and the length of the current program chain. */ dvdnav_status_t dvdnav_get_position(dvdnav_t *self, unsigned int *pos, unsigned int *len); -/** - * Return the current position (in blocks) within the current - * title and the length (in blocks) of said title. - * - * \par Note: - * Current implementation is wrong and likely to behave unpredictably. - * Use is discouraged. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param pos Pointer to unsigned int to get the current position. - * \param len Pointer to unsinged int to hold the length of the current title. - */ -dvdnav_status_t dvdnav_get_position_in_title(dvdnav_t *self, - unsigned int *pos, - unsigned int *len); -/** - * @} - */ +/********************************************************************* + * menu highlights * + *********************************************************************/ -/** - * \defgroup highlight Highlights - * +/* * Most functions related to highlights take a NAV PCI packet as a parameter. * While you can get the such a packet from libdvdnav, for players with internal * FIFOs, this will result in errors, because due to the FIFO length, libdvdnav will @@ -531,407 +408,223 @@ dvdnav_status_t dvdnav_get_position_in_title(dvdnav_t *self, * Therefore, player applications who have a NAV packet available, which is * better in sync with the actual playback should always pass this one to these * functions. - * - * @{ */ -/** +/* * Get the currently highlighted button - * number (1..36) or 0 if no button is highlighed. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param button Pointer to the value to fill in. + * number (1..36) or 0 if no button is highlighted. */ -dvdnav_status_t dvdnav_get_current_highlight(dvdnav_t *self, int* button); +dvdnav_status_t dvdnav_get_current_highlight(dvdnav_t *self, int *button); -/** +/* * Returns the Presentation Control Information (PCI) structure associated * with the current position. * - * \param self Pointer to dvdnav_t associated with this operation. - * - * \sa pci_t (in <tt>libdvdread</tt>) + * Read the general notes above. + * See also libdvdreads nav_types.h for definition of pci_t. */ pci_t* dvdnav_get_current_nav_pci(dvdnav_t *self); -/** - * Returns the DSI (data seach information) structure associated +/* + * Returns the DSI (data search information) structure associated * with the current position. * - * \param self Pointer to dvdnav_t associated with this operation. - * - * \sa pci_t (in <tt>libdvdread</tt>) + * Read the general notes above. + * See also libdvdreads nav_types.h for definition of dsi_t. */ dsi_t* dvdnav_get_current_nav_dsi(dvdnav_t *self); -/** +/* * Get the area associated with a certain button. - * - * \param nav_pci Pointer to the PCI structure you may have got via - * dvdnav_get_current_nav_pci(). - * - * \param button Button number to query. - * \param mode 0..3 -- Button mode to query. - * \param highlight Pointer to dvdnav_highlight_area_t to fill in. - * - * \sa dvdnav_highlight_area_t */ -dvdnav_status_t dvdnav_get_highlight_area(pci_t* nav_pci , int32_t button, int32_t mode, - dvdnav_highlight_area_t* highlight); +dvdnav_status_t dvdnav_get_highlight_area(pci_t *nav_pci , int32_t button, int32_t mode, + dvdnav_highlight_area_t *highlight); -/** +/* * Move button highlight around as suggested by function name (e.g. with arrow keys). - * - * \param self Pointer to dvdnav_t associated with this operation. */ dvdnav_status_t dvdnav_upper_button_select(dvdnav_t *self, pci_t *pci); - -/** - * Move button highlight around as suggested by function name (e.g. with arrow keys). - * - * \param self Pointer to dvdnav_t associated with this operation. - */ - dvdnav_status_t dvdnav_lower_button_select(dvdnav_t *self, pci_t *pci); - -/** - * Move button highlight around as suggested by function name (e.g. with arrow keys). - * - * \param self Pointer to dvdnav_t associated with this operation. - */ dvdnav_status_t dvdnav_right_button_select(dvdnav_t *self, pci_t *pci); - -/** - * Move button highlight around as suggested by function name (e.g. with arrow keys). - * - * \param self Pointer to dvdnav_t associated with this operation. - */ dvdnav_status_t dvdnav_left_button_select(dvdnav_t *self, pci_t *pci); -/** - * Activate (press) the currently highlighted button. - * \param self Pointer to dvdnav_t associated with this operation. +/* + * Activate ("press") the currently highlighted button. */ dvdnav_status_t dvdnav_button_activate(dvdnav_t *self, pci_t *pci); -/** +/* * Highlight a specific button. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param button 1..39 -- Button number to activate. */ dvdnav_status_t dvdnav_button_select(dvdnav_t *self, pci_t *pci, int button); -/** - * Activate (press) specified button. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param button 1..39 -- Button number to activate. +/* + * Activate ("press") specified button. */ dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *self, pci_t *pci, int button); -/** +/* * Activate (press) a button and execute specified command. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param cmd DVD Command to execute. */ dvdnav_status_t dvdnav_button_activate_cmd(dvdnav_t *self, int32_t button, vm_cmd_t *cmd); -/** - * Select button at specified (image) co-ordinates. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param x X co-ordinate in image. - * \param y Y xo-ordinate in image. +/* + * Select button at specified video frame coordinates. */ dvdnav_status_t dvdnav_mouse_select(dvdnav_t *self, pci_t *pci, int x, int y); -/** - * Activate (press) button at specified co-ordinates. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param x X co-ordinate in image. - * \param y Y xo-ordinate in image. +/* + * Activate ("press") button at specified video frame coordinates. */ dvdnav_status_t dvdnav_mouse_activate(dvdnav_t *self, pci_t *pci, int x, int y); -/** - * @} - */ -/** - * \defgroup languages Languages - * - * @{ +/********************************************************************* + * languages * + *********************************************************************/ + +/* + * The language codes expected by these functions are two character + * codes as defined in ISO639. */ -/** +/* * Set which menu language we should use. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param code 2 char ISO639 Language code in a C-style string. */ dvdnav_status_t dvdnav_menu_language_select(dvdnav_t *self, char *code); -/** +/* * Set which audio language we should use. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param code 2 char ISO639 Language code in a C-style string. */ dvdnav_status_t dvdnav_audio_language_select(dvdnav_t *self, char *code); -/** +/* * Set which spu language we should use. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param code 2 char ISO639 Language code in a C-style string. */ dvdnav_status_t dvdnav_spu_language_select(dvdnav_t *self, char *code); -/** - * @} - */ -/** - * \defgroup streams Sub-Picture Unit (Subtitles) and Audio Streams - * - * All these commands manipulate the audio/subtitle stream numbers that the - * player engine thinks is playing. Note that all the streams are still returned - * multiplexed by dvdnav_get_next_block(). You should try to make sure that the - * MPEG demuxer and the player engine both have the same thoughts on what stream the - * user is currently listening to. - * - * \sa dvdnav_get_next_block() - * - * @{ - */ - -/** - * Set a specific PHYSICAL MPEG stream. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param audio 0..7 -- Stream number. - */ -dvdnav_status_t dvdnav_physical_audio_stream_change(dvdnav_t *self, - int audio); +/********************************************************************* + * obtaining stream attributes * + *********************************************************************/ -/** - * Set a specific logical audio stream. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param audio 0..7 -- Stream number. - */ -dvdnav_status_t dvdnav_logical_audio_stream_change(dvdnav_t *self, - int audio); - -/** - * Set the int pointed to to the current PHYSICAL audio - * stream. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param audio Pointer to int which will receive value. - */ -dvdnav_status_t dvdnav_get_physical_audio_stream(dvdnav_t *self, int* audio); - -/** - * Set the int pointed to to the current LOGICAL audio - * stream. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param audio Pointer to int which will receive value. - */ -dvdnav_status_t dvdnav_get_logical_audio_stream(dvdnav_t *self, int* audio); - -/** - * Set a specific PHYSICAL MPEG SPU stream and whether it should be - * displayed. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param stream 0..31 or 63 (dummy) -- Stram number. - * \param display: 0..1 -- Is this actually being displayed? - */ -dvdnav_status_t dvdnav_physical_spu_stream_change(dvdnav_t *self, - int stream, int display); - -/** - * Set a specific LOGICAL SPU stream and whether it should be - * displayed. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param stream 0..31 or 63 (dummy) -- Stram number. - * \param display: 0..1 -- Is this actually being displayed? +/* + * Return a string describing the title of the DVD. + * This is an ID string encoded on the disc by the author. In many cases + * this is a descriptive string such as `THE_MATRIX' but sometimes is sigularly + * uninformative such as `PDVD-011421'. Some DVD authors even forget to set this, + * so you may also read the default of the authoring software they used, like + * `DVDVolume'. */ -dvdnav_status_t dvdnav_logical_spu_stream_change(dvdnav_t *self, - int stream, int display); +dvdnav_status_t dvdnav_get_title_string(dvdnav_t *self, const char **title_str); -/** - * Set the ints pointed to to the current PHYSICAL SPU - * stream & display flag. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param stream Pointer which will receive value. - * \param display Pointer which will receive value. +/* + * Get video aspect code. + * The aspect code does only change on VTS boundaries. + * See the DVDNAV_VTS_CHANGE event. + * + * 0 -- 4:3, 2 -- 16:9 */ -dvdnav_status_t dvdnav_get_physical_spu_stream(dvdnav_t *self, - int* stream, int* display); +uint8_t dvdnav_get_video_aspect(dvdnav_t *self); -/** - * Set the ints pointed to to the current LOGICAL SPU - * stream & display flag. +/* + * Get video scaling permissions. + * The scaling permission does only change on VTS boundaries. + * See the DVDNAV_VTS_CHANGE event. * - * \param self Pointer to dvdnav_t associated with this operation. - * \param stream Pointer which will receive value. - * \param display Pointer which will receive value. + * bit0 set = deny letterboxing, bit1 set = deny pan&scan */ -dvdnav_status_t dvdnav_get_logical_spu_stream(dvdnav_t *self, - int* stream, int* disply); +uint8_t dvdnav_get_video_scale_permission(dvdnav_t *self); -/** - * Converts a *logical* audio stream id into country code - * (returns <tt>0xffff</tt> if no such stream). - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param stream Stream number +/* + * Converts a *logical* audio stream id into language code + * (returns 0xffff if no such stream). */ uint16_t dvdnav_audio_stream_to_lang(dvdnav_t *self, uint8_t stream); -/** +/* * Converts a *logical* subpicture stream id into country code - * (returns <tt>0xffff</tt> if no such stream). - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param stream Stream number + * (returns 0xffff if no such stream). */ uint16_t dvdnav_spu_stream_to_lang(dvdnav_t *self, uint8_t stream); -/** - * Converts a *physical* audio stream id into a logical stream number - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param audio_num Stream number +/* + * Converts a *physical* (MPEG) audio stream id into a logical stream number. */ int8_t dvdnav_get_audio_logical_stream(dvdnav_t *self, uint8_t audio_num); -/** - * Converts a *physical* subpicture stream id into a logical stream number - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param subp_num Stream number +/* + * Converts a *physical* (MPEG) subpicture stream id into a logical stream number. */ int8_t dvdnav_get_spu_logical_stream(dvdnav_t *self, uint8_t subp_num); -/** +/* * Get active audio stream. - * - * \param self Pointer to dvdnav_t associated with this operation. */ int8_t dvdnav_get_active_audio_stream(dvdnav_t *self); -/** +/* * Get active spu stream. - * - * \param self Pointer to dvdnav_t associated with this operation. */ int8_t dvdnav_get_active_spu_stream(dvdnav_t *self); -/** - * @} - */ -/** - * \defgroup angles Multiple angles - * - * The <tt>libdvdnav</tt> library abstracts away the difference between seamless and +/********************************************************************* + * multiple angles * + *********************************************************************/ + +/* + * The libdvdnav library abstracts away the difference between seamless and * non-seamless angles. From the point of view of the programmer you just set the - * angle number and all is well in the world. + * angle number and all is well in the world. You will always see only the + * selected angle coming from the get_next_block functions. * - * \par Note: + * Note: * It is quite possible that some tremendously strange DVD feature might change the * angle number from under you. Generally you should always view the results from * dvdnav_get_angle_info() as definitive only up to the next time you call * dvdnav_get_next_block(). - * - * @{ */ -/** +/* * Sets the current angle. If you try to follow a non existant angle * the call fails. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param angle 1..9 -- Currentl angle to follow. */ dvdnav_status_t dvdnav_angle_change(dvdnav_t *self, int angle); -/** +/* * Returns the current angle and number of angles present. - * - * \param self Pointer to dvdnav_t associated with this operation. - * \param current_angle Pointer to int which will get the current angle. - * \param number_of_angles Pointer to int which will get the number of angles. */ -dvdnav_status_t dvdnav_get_angle_info(dvdnav_t *self, int* current_angle, +dvdnav_status_t dvdnav_get_angle_info(dvdnav_t *self, int *current_angle, int *number_of_angles); -/** - * @} - */ - -/** - * \defgroup domain Domain Queries - * - * The following functions can be used to query whether we are in - * particular domains or not. - * - * @{ - */ +/********************************************************************* + * domain queries * + *********************************************************************/ -/** - * Are we in the First Play domain. (Menu) - * \param self Pointer to dvdnav_t associated with this operation. - * \returns -1 on failure, 1 if condition is true, 0 if condition is false +/* + * Are we in the First Play domain? */ int8_t dvdnav_is_domain_fp(dvdnav_t *self); -/** - * Are we in the Video management Menu domain. (Menu) - * \param self Pointer to dvdnav_t associated with this operation. - * \returns -1 on failure, 1 if condition is true, 0 if condition is false +/* + * Are we in the Video management Menu domain? */ int8_t dvdnav_is_domain_vmgm(dvdnav_t *self); -/** - * Are we in the Video Title Menu domain (Menu) - * \param self Pointer to dvdnav_t associated with this operation. - * \returns -1 on failure, 1 if condition is true, 0 if condition is false +/* + * Are we in the Video Title Menu domain? */ int8_t dvdnav_is_domain_vtsm(dvdnav_t *self); -/** - * Are we in the Video Title domain (playing movie)? - * \param self Pointer to dvdnav_t associated with this operation. - * \returns -1 on failure, 1 if condition is true, 0 if condition is false +/* + * Are we in the Video Title Set domain? */ int8_t dvdnav_is_domain_vts(dvdnav_t *self); -/** - * @} - */ - -/* - * The following info appears on the front page of the reference manual. It is - * included here to keep it with the main dvdnav source files. The copyright notice - * refers to the comments _only_. All machine-readable source code is covered by - * the copyright notice at the top of this file. - * - * Oh, and the official language of the documentation is English -- - * English English (as in the English spoken in England) not US English. - */ #ifdef __cplusplus } diff --git a/src/input/libdvdnav/dvdnav_events.h b/src/input/libdvdnav/dvdnav_events.h index 4d08665d3..492321533 100644 --- a/src/input/libdvdnav/dvdnav_events.h +++ b/src/input/libdvdnav/dvdnav_events.h @@ -17,10 +17,14 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: dvdnav_events.h,v 1.10 2003/04/06 13:09:38 mroi Exp $ + * $Id: dvdnav_events.h,v 1.11 2003/04/07 18:10:48 mroi Exp $ * */ +/* + * This header defines events and event types + */ + #ifndef DVDNAV_EVENTS_H_INCLUDED #define DVDNAV_EVENTS_H_INCLUDED @@ -28,105 +32,213 @@ #include "dvd_reader.h" #include "nav_types.h" -/** - * \file dvdnav_events.h - * This header defines events and event types - */ -/*** EVENTS ***/ +/* + * DVDNAV_BLOCK_OK + * + * A regular data block from the DVD has been returned. + * This one should be demuxed and decoded for playback. + */ +#define DVDNAV_BLOCK_OK 0 -#define DVDNAV_BLOCK_OK 0 /*!< The next block was returned */ -#define DVDNAV_NOP 1 /*!< No action should be taken */ -#define DVDNAV_STILL_FRAME 2 /*!< The preceeding block was the last in a still frame */ -#define DVDNAV_SPU_STREAM_CHANGE 3 /*!< The SPU stream was changed */ -#define DVDNAV_AUDIO_STREAM_CHANGE 4 /*!< The Audio stream was changed */ -#define DVDNAV_VTS_CHANGE 5 /*!< We have changed VTS */ -#define DVDNAV_CELL_CHANGE 6 /*!< We have jumped to a new cell */ -#define DVDNAV_NAV_PACKET 7 /*!< The packet just passed was a NAV packet */ -#define DVDNAV_STOP 8 /*!< The last block was final, no more are coming */ -#define DVDNAV_HIGHLIGHT 9 /*!< Change highlight region */ -#define DVDNAV_SPU_CLUT_CHANGE 10 /*!< SPU CLUT changed */ -#define DVDNAV_HOP_CHANNEL 12 /*!< Sent when non-seemless stream change has happed */ -#define DVDNAV_WAIT 13 /*!< The application should wait for its fifos to run dry */ +/* + * DVDNAV_NOP + * + * Just ignore this. + */ +#define DVDNAV_NOP 1 -/*** EVENT TYPES ***/ -/** - * Structure providing information on DVDNAV_STILL_FRAME events. +/* + * DVDNAV_STILL_FRAME + * + * We have reached a still frame. The player application should wait + * the amount of time specified by the still's length while still handling + * user input to make menus and other interactive stills work. + * The last delivered frame should be kept showing. + * Once the still has timed out, call dvdnav_skip_still(). + * A length of 0xff means an infinite still which has to be skipped + * indirectly by some user interaction. */ +#define DVDNAV_STILL_FRAME 2 + typedef struct { - int length; /*!< - The length (in seconds) the still frame - should be displayed for, or 0xff if - indefinite. */ + /* The length (in seconds) the still frame should be displayed for, + * or 0xff if infinite. */ + int length; } dvdnav_still_event_t; -/** - * Structure providing information on DVDNAV_SPU_STREAM_CHANGE events. + +/* + * DVDNAV_SPU_STREAM_CHANGE + * + * Inform the SPU decoding/overlaying engine to switch SPU channels. */ +#define DVDNAV_SPU_STREAM_CHANGE 3 + typedef struct { - int physical_wide; /*!< The physical (MPEG) stream number for widescreen display. */ - int physical_letterbox; /*!< The physical (MPEG) stream number for letterboxed display. */ - int physical_pan_scan; /*!< The physical (MPEG) stream number for pan&scan display. */ - int logical; /*!< The logical (DVD) stream number. */ + /* The physical (MPEG) stream number for widescreen SPU display. + * Use this, if you blend the SPU on an anamorphic image before + * unsqueezing it. */ + int physical_wide; + + /* The physical (MPEG) stream number for letterboxed display. + * Use this, if you blend the SPU on an anamorphic image after + * unsqueezing it. */ + int physical_letterbox; + + /* The physical (MPEG) stream number for pan&scan display. + * Use this, if you blend the SPU on an anamorphic image after + * unsqueezing it the pan&scan way. */ + int physical_pan_scan; + + /* The logical (DVD) stream number. */ + int logical; } dvdnav_spu_stream_change_event_t; -/** - * Structure providing information on DVDNAV_AUDIO_STREAM_CHANGE events. + +/* + * DVDNAV_AUDIO_STREAM_CHANGE + * + * Inform the audio decoder to switch channels. */ +#define DVDNAV_AUDIO_STREAM_CHANGE 4 + typedef struct { - int physical; /*!< The physical (MPEG) stream number. */ - int logical; /*!< The logical (DVD) stream number. */ + /* The physical (MPEG) stream number. */ + int physical; + + /* The logical (DVD) stream number. */ + int logical; } dvdnav_audio_stream_change_event_t; -/** - * Structure providing information on DVDNAV_VTS_CHANGE events. + +/* + * DVDNAV_VTS_CHANGE + * + * Some status information like video aspect and video scale permissions do + * not change inside a VTS. Therefore this event can be used to query such + * information only when necessary and update the decoding/displaying + * accordingly. */ +#define DVDNAV_VTS_CHANGE 5 + typedef struct { - int old_vtsN; /*!< The old VTS number */ - dvd_read_domain_t old_domain; /*!< The old domain */ - int new_vtsN; /*!< The new VTS number */ - dvd_read_domain_t new_domain; /*!< The new domain */ + int old_vtsN; /* the old VTS number */ + dvd_read_domain_t old_domain; /* the old domain */ + int new_vtsN; /* the new VTS number */ + dvd_read_domain_t new_domain; /* the new domain */ } dvdnav_vts_change_event_t; -/** - * Structure providing information on DVDNAV_CELL_CHANGE events. + +/* + * DVDNAV_CELL_CHANGE + * + * Some status information like the current Title and Part numbers do not + * change inside a cell. Therefore this event can be used to query such + * information only when necessary and update the decoding/displaying + * accordingly. + * Some useful information for accurate time display is also reported + * together with this event. */ +#define DVDNAV_CELL_CHANGE 6 + typedef struct { - int cellN; /*!< The new cell number */ - int pgN; /*!< The current program number */ - int64_t cell_length; /*!< The length of the current cell in PTS ticks */ - int64_t pg_length; /*!< The length of the current program in PTS ticks */ - int64_t pgc_length; /*!< The length of the current program chain in PTS ticks */ - int64_t cell_start; /*!< The start time of the current cell relatively to the PGC in PTS ticks */ - int64_t pg_start; /*!< The start time of the current PG relatively to the PGC in PTS ticks */ + int cellN; /* the new cell number */ + int pgN; /* the current program number */ + int64_t cell_length; /* the length of the current cell in PTS ticks */ + int64_t pg_length; /* the length of the current program in PTS ticks */ + int64_t pgc_length; /* the length of the current program chain in PTS ticks */ + int64_t cell_start; /* the start time of the current cell relatively to the PGC in PTS ticks */ + int64_t pg_start; /* the start time of the current PG relatively to the PGC in PTS ticks */ } dvdnav_cell_change_event_t; -/* FIXME: These are unused. */ -#if 0 -/** - * Structure providing information on DVDNAV_NAV_PACKET events. + +/* + * DVDNAV_NAV_PACKET + * + * NAV packets are useful for various purposes. They define the button + * highlight areas and VM commands of DVD menus, so they should in any + * case be sent to the SPU decoder/overlaying engine for the menus to work. + * NAV packets also provide a way to detect PTS discontinuities, because + * they carry the start and end PTS values for the current VOBU. + * (pci.vobu_s_ptm and pci.vobu_e_ptm) Whenever the start PTS of the + * current NAV does not match the end PTS of the previous NAV, a PTS + * discontinuity has occured. + * NAV packets can also be used for time display, because they are + * timestamped relatively to the current Cell. */ -typedef struct { - pci_t *pci; - dsi_t *dsi; -} dvdnav_nav_packet_event_t; -#endif - -/** - * Structure providing information on DVDNAV_HIGHLIGHT events. - * The event only fills in display and buttonN. - * The rest can be get with dvdnav_get_highlight_area(). +#define DVDNAV_NAV_PACKET 7 + + +/* + * DVDNAV_STOP + * + * Applications should end playback here. A subsequent dvdnav_get_next_block() + * call will restart the VM from the beginning of the DVD. */ +#define DVDNAV_STOP 8 + + +/* + * DVDNAV_HIGHLIGHT + * + * The current button highlight changed. Inform the overlaying engine to + * highlight a different button. Please note, that at the moment only mode 1 + * highlights are reported this way. That means, when the button highlight + * has been moved around by some function call, you will receive an event + * telling you the new button. But when a button gets activated, you have + * to handle the mode 2 highlighting (that is some different colour the + * button turns to on activation) in your application. + */ +#define DVDNAV_HIGHLIGHT 9 + typedef struct { - int display; /*!< 0 - hide, 1 - show, entries below only guaranteed useful - if this is '1' */ - uint32_t palette; /*!< The CLUT entries for the highlight palette - (4-bits per entry -> 4 entries) */ - uint16_t sx,sy,ex,ey; /*!< The start/end x,y positions */ - uint32_t pts; /*!< Highlight PTS to match with SPU */ - uint32_t buttonN; /*!< Button number for the SPU decoder. */ + /* highlight mode: 0 - hide, 1 - show, 2 - activate, currently always 1 */ + int display; + + /* FIXME: these fields are currently not set */ + uint32_t palette; /* The CLUT entries for the highlight palette + (4-bits per entry -> 4 entries) */ + uint16_t sx,sy,ex,ey; /* The start/end x,y positions */ + uint32_t pts; /* Highlight PTS to match with SPU */ + + /* button number for the SPU decoder/overlaying engine */ + uint32_t buttonN; } dvdnav_highlight_event_t; + +/* + * DVDNAV_SPU_CLUT_CHANGE + * + * Inform the SPU decoder/overlaying engine to update its colour lookup table. + * The CLUT is given as 16 uint32_t's in the buffer. + */ +#define DVDNAV_SPU_CLUT_CHANGE 10 + + +/* + * DVDNAV_HOP_CHANNEL + * + * A non-seamless operation has been performed. Applications can drop all + * their internal fifo's content, which will speed up the response. + */ +#define DVDNAV_HOP_CHANNEL 12 + + +/* + * DVDNAV_WAIT + * + * We have reached a point in DVD playback, where timing is critical. + * Player application with internal fifos can introduce state + * inconsistencies, because libdvdnav is always the fifo's length + * ahead in the stream compared to what the application sees. + * Such applications should wait until their fifos are empty + * when they receive this type of event. + * Once this is achieved, call dvdnav_skip_wait(). + */ +#define DVDNAV_WAIT 13 + + #endif /* DVDNAV_EVENTS_H_INCLUDED */ diff --git a/src/input/libdvdnav/highlight.c b/src/input/libdvdnav/highlight.c index 16c3a509c..cc41d8c09 100644 --- a/src/input/libdvdnav/highlight.c +++ b/src/input/libdvdnav/highlight.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: highlight.c,v 1.11 2003/03/29 13:19:09 mroi Exp $ + * $Id: highlight.c,v 1.12 2003/04/07 18:10:49 mroi Exp $ * */ @@ -175,7 +175,7 @@ static void nav_print_BTNIT(btni_t *btni_table, int btngr_ns, int btn_ns) { fprintf(MSG_OUT, "libdvdnav: %02x ", btni->cmd.bytes[k]); } fprintf(MSG_OUT, "| "); - vmPrint_mnemonic(&btni->cmd); + vm_print_mnemonic(&btni->cmd); fprintf(MSG_OUT, "\n"); } } diff --git a/src/input/libdvdnav/navigation.c b/src/input/libdvdnav/navigation.c index 07567bd1b..07d4a2759 100644 --- a/src/input/libdvdnav/navigation.c +++ b/src/input/libdvdnav/navigation.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: navigation.c,v 1.7 2003/03/29 13:19:09 mroi Exp $ + * $Id: navigation.c,v 1.8 2003/04/07 18:10:50 mroi Exp $ * */ @@ -110,15 +110,24 @@ dvdnav_status_t dvdnav_current_title_info(dvdnav_t *this, int *title, int *part) pthread_mutex_unlock(&this->vm_lock); return S_ERR; } - if (this->vm->state.domain != VTS_DOMAIN) { - printerr("Not in VTS domain."); + if ( (this->vm->state.domain == VTSM_DOMAIN) + || (this->vm->state.domain == VMGM_DOMAIN) ) { + /* Get current Menu ID: into *part. */ + vm_get_current_menu(this->vm, part); + if (*part > -1) { + *title = 0; + pthread_mutex_unlock(&this->vm_lock); + return S_OK; + } + } + if (this->vm->state.domain == VTS_DOMAIN) { + retval = vm_get_current_title_part(this->vm, title, part); pthread_mutex_unlock(&this->vm_lock); - return S_ERR; + return retval ? S_OK : S_ERR; } - retval = vm_get_current_title_part(this->vm, title, part); + printerr("Not in a title or menu."); pthread_mutex_unlock(&this->vm_lock); - - return retval ? S_OK : S_ERR; + return S_ERR; } dvdnav_status_t dvdnav_title_play(dvdnav_t *this, int title) { @@ -153,6 +162,12 @@ dvdnav_status_t dvdnav_part_play(dvdnav_t *this, int title, int part) { pthread_mutex_unlock(&this->vm_lock); return S_ERR; } + if((part < 1) || (part > this->vm->vmgi->tt_srpt->title[title-1].nr_of_ptts)) { + printerr("Part out of range."); + pthread_mutex_unlock(&this->vm_lock); + return S_ERR; + } + retval = vm_jump_title_part(this->vm, title, part); if (retval) this->vm->hop_channel++; @@ -188,7 +203,7 @@ dvdnav_status_t dvdnav_stop(dvdnav_t *this) { } pthread_mutex_lock(&this->vm_lock); - vm_stop(this->vm); + this->vm->stopped = 1; pthread_mutex_unlock(&this->vm_lock); return S_OK; } diff --git a/src/input/libdvdnav/searching.c b/src/input/libdvdnav/searching.c index a09b7b04f..1efc1a67d 100644 --- a/src/input/libdvdnav/searching.c +++ b/src/input/libdvdnav/searching.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: searching.c,v 1.13 2003/03/29 13:19:09 mroi Exp $ + * $Id: searching.c,v 1.14 2003/04/07 18:10:50 mroi Exp $ * */ @@ -357,6 +357,20 @@ dvdnav_status_t dvdnav_menu_call(dvdnav_t *this, DVDMenuID_t menu) { /* make a copy of current VM and try to navigate the copy to the menu */ try_vm = vm_new_copy(this->vm); + if ( (menu == DVD_MENU_Escape) && (this->vm->state.domain != VTS_DOMAIN)) { + /* Try resume */ + if (vm_jump_resume(try_vm) && !try_vm->stopped) { + /* merge changes on success */ + vm_merge(this->vm, try_vm); + vm_free_copy(try_vm); + this->position_current.still = 0; + this->vm->hop_channel++; + pthread_mutex_unlock(&this->vm_lock); + return S_OK; + } + } + if (menu == DVD_MENU_Escape) menu = DVD_MENU_Title; + if (vm_jump_menu(try_vm, menu) && !try_vm->stopped) { /* merge changes on success */ vm_merge(this->vm, try_vm); diff --git a/src/input/libdvdnav/vm.c b/src/input/libdvdnav/vm.c index 6e77133f1..7086a8e9a 100644 --- a/src/input/libdvdnav/vm.c +++ b/src/input/libdvdnav/vm.c @@ -19,7 +19,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: vm.c,v 1.18 2003/04/01 19:42:41 jcdutton Exp $ + * $Id: vm.c,v 1.19 2003/04/07 18:10:50 mroi Exp $ * */ @@ -479,13 +479,20 @@ int vm_jump_cell_block(vm_t *vm, int cell, int block) { } int vm_jump_title_part(vm_t *vm, int title, int part) { + link_t link; + if(!set_PTT(vm, title, part)) return 0; /* Some DVDs do not want us to jump directly into a title and have * PGC pre commands taking us back to some menu. Since we do not like that, - * we do not execute PGC pre commands but directly play the PG. */ + * we do not execute PGC pre commands that would do a jump. */ /* process_command(vm, play_PGC_PG(vm, (vm->state).pgN)); */ - process_command(vm, play_PG(vm)); + link = play_PGC_PG(vm, (vm->state).pgN); + if (link.command != PlayThis) + /* jump occured -> ignore it and play the PG anyway */ + process_command(vm, play_PG(vm)); + else + process_command(vm, link); return 1; } @@ -539,6 +546,7 @@ int vm_jump_menu(vm_t *vm, DVDMenuID_t menuid) { case VMGM_DOMAIN: switch(menuid) { case DVD_MENU_Title: + case DVD_MENU_Escape: (vm->state).domain = VMGM_DOMAIN; break; case DVD_MENU_Root: @@ -563,6 +571,16 @@ int vm_jump_menu(vm_t *vm, DVDMenuID_t menuid) { return 0; } +int vm_jump_resume(vm_t *vm) { + link_t link_values = { LinkRSM, 0, 0, 0 }; + + if (!(vm->state).rsm_vtsN) /* Do we have resume info? */ + return 0; + if (!process_command(vm, link_values)) + return 0; + return 1; +} + int vm_exec_cmd(vm_t *vm, vm_cmd_t *cmd) { link_t link_values; @@ -575,6 +593,15 @@ int vm_exec_cmd(vm_t *vm, vm_cmd_t *cmd) { /* getting information */ +int vm_get_current_menu(vm_t *vm, int *menuid) { + pgcit_t* pgcit; + int pgcn; + pgcn = (vm->state).pgcN; + pgcit = get_PGCIT(vm); + *menuid = pgcit->pgci_srp[pgcn - 1].entry_id & 0xf ; + return 1; +} + int vm_get_current_title_part(vm_t *vm, int *title_result, int *part_result) { vts_ptt_srpt_t *vts_ptt_srpt; int title, part = 0, vts_ttn; @@ -915,7 +942,7 @@ static link_t play_PGC_PG(vm_t *vm, int pgN) { link_t link_values; #ifdef TRACE - fprintf(MSG_OUT, "libdvdnav: play_PGC:"); + fprintf(MSG_OUT, "libdvdnav: play_PGC_PG:"); if((vm->state).domain != FP_DOMAIN) { fprintf(MSG_OUT, " (vm->state).pgcN (%i)\n", get_PGCN(vm)); } else { @@ -1172,7 +1199,7 @@ static int process_command(vm_t *vm, link_t link_values) { #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: Before printout starts:\n"); - vmPrint_LINK(link_values); + vm_print_link(link_values); fprintf(MSG_OUT, "libdvdnav: Link values %i %i %i %i\n", link_values.command, link_values.data1, link_values.data2, link_values.data3); vm_print_current_domain_state(vm); @@ -1570,6 +1597,7 @@ static int set_VTS_PTT(vm_t *vm, int vtsN, int vts_ttn, int part) { static int set_FP_PGC(vm_t *vm) { (vm->state).domain = FP_DOMAIN; (vm->state).pgc = vm->vmgi->first_play_pgc; + (vm->state).pgcN = vm->vmgi->vmgi_mat->first_play_pgc; return 1; } @@ -1593,6 +1621,7 @@ static int set_PGCN(vm_t *vm, int pgcN) { } (vm->state).pgc = pgcit->pgci_srp[pgcN - 1].pgc; + (vm->state).pgcN = pgcN; (vm->state).pgN = 1; if((vm->state).domain == VTS_DOMAIN) @@ -1720,6 +1749,7 @@ static int get_ID(vm_t *vm, int id) { return 0; /* error */ } +/* FIXME: we have a pgcN member in the vm's state now, so this should be obsolete */ static int get_PGCN(vm_t *vm) { pgcit_t *pgcit; int pgcN = 1; @@ -1818,6 +1848,9 @@ void vm_position_print(vm_t *vm, vm_position_t *position) { /* * $Log: vm.c,v $ + * Revision 1.19 2003/04/07 18:10:50 mroi + * merging libdvdnav, since some nice fixes took place + * * Revision 1.18 2003/04/01 19:42:41 jcdutton * Add some comments. * Remove a FIXME comment. diff --git a/src/input/libdvdnav/vm.h b/src/input/libdvdnav/vm.h index 72e99b1de..1705a7ec9 100644 --- a/src/input/libdvdnav/vm.h +++ b/src/input/libdvdnav/vm.h @@ -19,7 +19,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: vm.h,v 1.7 2003/03/29 13:19:09 mroi Exp $ + * $Id: vm.h,v 1.8 2003/04/07 18:10:52 mroi Exp $ * */ @@ -47,6 +47,7 @@ typedef struct { domain_t domain; int vtsN; /* 0 is vmgm? */ pgc_t *pgc; /* either this or 'int pgcN' is enough? */ + int pgcN; /* but provide pgcN for quick lookup */ int pgN; /* is this needed? can allways fid pgN from cellN? */ int cellN; int32_t cell_restart; /* get cell to restart */ @@ -148,9 +149,11 @@ int vm_jump_next_pg(vm_t *vm); int vm_jump_prev_pg(vm_t *vm); int vm_jump_up(vm_t *vm); int vm_jump_menu(vm_t *vm, DVDMenuID_t menuid); +int vm_jump_resume(vm_t *vm); int vm_exec_cmd(vm_t *vm, vm_cmd_t *cmd); /* getting information */ +int vm_get_current_menu(vm_t *vm, int *menuid); int vm_get_current_title_part(vm_t *vm, int *title_result, int *part_result); int vm_get_audio_stream(vm_t *vm, int audioN); int vm_get_subp_stream(vm_t *vm, int subpN, int mode); diff --git a/src/input/libdvdnav/vmcmd.c b/src/input/libdvdnav/vmcmd.c index 27b443b07..55c8e4a22 100644 --- a/src/input/libdvdnav/vmcmd.c +++ b/src/input/libdvdnav/vmcmd.c @@ -18,7 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: vmcmd.c,v 1.4 2003/03/29 13:19:09 mroi Exp $ + * $Id: vmcmd.c,v 1.5 2003/04/07 18:10:52 mroi Exp $ * */ @@ -114,22 +114,26 @@ static const char *system_reg_abbr_table[] = { NULL, NULL, }; - + static void print_system_reg(uint16_t reg) { if(reg < sizeof(system_reg_abbr_table) / sizeof(char *)) - fprintf(MSG_OUT, " %s (SRPM:%d)", system_reg_table[reg], reg); + fprintf(MSG_OUT, "%s (SRPM:%d)", system_reg_table[reg], reg); else fprintf(MSG_OUT, " WARNING: Unknown system register ( reg=%d ) ", reg); } +static void print_g_reg(uint8_t reg) { + if(reg < 16) + fprintf(MSG_OUT, "g[%" PRIu8 "]", reg); + else + fprintf(MSG_OUT, " WARNING: Unknown general register "); +} + static void print_reg(uint8_t reg) { if(reg & 0x80) print_system_reg(reg & 0x7f); else - if(reg < 16) - fprintf(MSG_OUT, " g[%" PRIu8 "]", reg); - else - fprintf(MSG_OUT, " WARNING: Unknown general register "); + print_g_reg(reg & 0x7f); } static void print_cmp_op(uint8_t op) { @@ -146,99 +150,133 @@ static void print_set_op(uint8_t op) { fprintf(MSG_OUT, " WARNING: Unknown set op "); } -static void print_reg_or_data(command_t* command, int immediate, int byte) { +static void print_reg_or_data(command_t* command, int immediate, int start) { if(immediate) { - int i = vm_getbits(command, (byte*8), 16); + int i = vm_getbits(command, start, 16); fprintf(MSG_OUT, "0x%x", i); if(isprint(i & 0xff) && isprint((i>>8) & 0xff)) fprintf(MSG_OUT, " (\"%c%c\")", (char)((i>>8) & 0xff), (char)(i & 0xff)); } else { - print_reg(vm_getbits(command, ((byte + 1)*8), 8)); + print_reg(vm_getbits(command, start - 8, 8)); } } -static void print_reg_or_data_2(command_t* command, int immediate, int byte) { +static void print_reg_or_data_2(command_t* command, int immediate, int start) { if(immediate) - fprintf(MSG_OUT, "0x%x", vm_getbits(command, ((byte*8)+1), 7)); + fprintf(MSG_OUT, "0x%x", vm_getbits(command, start - 1, 7)); else - fprintf(MSG_OUT, "g[%" PRIu8 "]", vm_getbits(command, ((byte*8)+4), 4)); + fprintf(MSG_OUT, "g[%" PRIu8 "]", vm_getbits(command, start - 4, 4)); } +static void print_reg_or_data_3(command_t* command, int immediate, int start) { + if(immediate) { + int i = vm_getbits(command, start, 16); + + fprintf(MSG_OUT, "0x%x", i); + if(isprint(i & 0xff) && isprint((i>>8) & 0xff)) + fprintf(MSG_OUT, " (\"%c%c\")", (char)((i>>8) & 0xff), (char)(i & 0xff)); + } else { + print_reg(vm_getbits(command, start, 8)); + } +} + + static void print_if_version_1(command_t* command) { - uint8_t op = vm_getbits(command, 9, 3); + uint8_t op = vm_getbits(command, 54, 3); if(op) { fprintf(MSG_OUT, "if ("); - print_reg(vm_getbits(command,24,8)); + print_g_reg(vm_getbits(command,39,8)); print_cmp_op(op); - print_reg_or_data(command, vm_getbits(command, 8,1), 4); + print_reg_or_data(command, vm_getbits(command, 55,1), 31); fprintf(MSG_OUT, ") "); } } static void print_if_version_2(command_t* command) { - uint8_t op = vm_getbits(command, 9, 3); + uint8_t op = vm_getbits(command, 54, 3); if(op) { fprintf(MSG_OUT, "if ("); - print_reg(vm_getbits(command, 48, 8)); + print_reg(vm_getbits(command, 15, 8)); print_cmp_op(op); - print_reg(vm_getbits(command, 56, 8)); + print_reg(vm_getbits(command, 7, 8)); fprintf(MSG_OUT, ") "); } } static void print_if_version_3(command_t* command) { - uint8_t op = vm_getbits(command, 9, 3); + uint8_t op = vm_getbits(command, 54, 3); if(op) { fprintf(MSG_OUT, "if ("); - print_reg(vm_getbits(command, 20, 4)); + print_g_reg(vm_getbits(command, 43, 4)); print_cmp_op(op); - print_reg_or_data(command, vm_getbits(command, 8, 1), 6); + print_reg_or_data(command, vm_getbits(command, 55, 1), 15); fprintf(MSG_OUT, ") "); } } static void print_if_version_4(command_t* command) { - uint8_t op = vm_getbits(command, 9, 3); - + uint8_t op = vm_getbits(command, 54, 3); + if(op) { fprintf(MSG_OUT, "if ("); - print_reg(vm_getbits(command, 12, 4)); + print_g_reg(vm_getbits(command, 51, 4)); print_cmp_op(op); - print_reg_or_data(command, vm_getbits(command, 8, 1), 4); + print_reg_or_data(command, vm_getbits(command, 55, 1), 31); fprintf(MSG_OUT, ") "); } } +static void print_if_version_5(command_t* command) { + uint8_t op = vm_getbits(command, 54, 3); + int set_immediate = vm_getbits(command, 60, 1); + + if(op) { + if (set_immediate) { + fprintf(MSG_OUT, "if ("); + print_g_reg(vm_getbits(command, 31, 8)); + print_cmp_op(op); + print_reg(vm_getbits(command, 23, 8)); + fprintf(MSG_OUT, ") "); + } else { + fprintf(MSG_OUT, "if ("); + print_g_reg(vm_getbits(command, 39, 8)); + print_cmp_op(op); + print_reg_or_data(command, vm_getbits(command, 55, 1), 31); + fprintf(MSG_OUT, ") "); + } + } +} + static void print_special_instruction(command_t* command) { - uint8_t op = vm_getbits(command, 12, 4); + uint8_t op = vm_getbits(command, 51, 4); switch(op) { case 0: /* NOP */ fprintf(MSG_OUT, "Nop"); break; case 1: /* Goto line */ - fprintf(MSG_OUT, "Goto %" PRIu8, vm_getbits(command, 56, 8)); + fprintf(MSG_OUT, "Goto %" PRIu8, vm_getbits(command, 7, 8)); break; case 2: /* Break */ fprintf(MSG_OUT, "Break"); break; case 3: /* Parental level */ fprintf(MSG_OUT, "SetTmpPML %" PRIu8 ", Goto %" PRIu8, - vm_getbits(command, 52, 4), vm_getbits(command, 56, 8)); + vm_getbits(command, 11, 4), vm_getbits(command, 7, 8)); break; default: fprintf(MSG_OUT, "WARNING: Unknown special instruction (%i)", - vm_getbits(command, 12, 4)); + vm_getbits(command, 51, 4)); } } static void print_linksub_instruction(command_t* command) { - int linkop = vm_getbits(command, 59, 5); - int button = vm_getbits(command, 48, 6); + int linkop = vm_getbits(command, 7, 8); + int button = vm_getbits(command, 15, 6); if(linkop < sizeof(link_table)/sizeof(char *) && link_table[linkop] != NULL) fprintf(MSG_OUT, "%s (button %" PRIu8 ")", link_table[linkop], button); @@ -247,7 +285,7 @@ static void print_linksub_instruction(command_t* command) { } static void print_link_instruction(command_t* command, int optional) { - uint8_t op = vm_getbits(command, 12, 4); + uint8_t op = vm_getbits(command, 51, 4); if(optional && op) fprintf(MSG_OUT, ", "); @@ -261,19 +299,19 @@ static void print_link_instruction(command_t* command, int optional) { print_linksub_instruction(command); break; case 4: - fprintf(MSG_OUT, "LinkPGCN %" PRIu16, vm_getbits(command, 49, 15)); + fprintf(MSG_OUT, "LinkPGCN %" PRIu16, vm_getbits(command, 14, 15)); break; case 5: fprintf(MSG_OUT, "LinkPTT %" PRIu16 " (button %" PRIu8 ")", - vm_getbits(command, 54, 10), vm_getbits(command, 48, 6)); + vm_getbits(command, 9, 10), vm_getbits(command, 15, 6)); break; case 6: fprintf(MSG_OUT, "LinkPGN %" PRIu8 " (button %" PRIu8 ")", - vm_getbits(command, 57, 7), vm_getbits(command, 48, 6)); + vm_getbits(command, 6, 7), vm_getbits(command, 15, 6)); break; case 7: fprintf(MSG_OUT, "LinkCN %" PRIu8 " (button %" PRIu8 ")", - vm_getbits(command, 56, 8), vm_getbits(command, 48, 6)); + vm_getbits(command, 7, 8), vm_getbits(command, 15, 6)); break; default: fprintf(MSG_OUT, "WARNING: Unknown link instruction"); @@ -281,54 +319,54 @@ static void print_link_instruction(command_t* command, int optional) { } static void print_jump_instruction(command_t* command) { - switch(vm_getbits(command, 12, 4)) { + switch(vm_getbits(command, 51, 4)) { case 1: fprintf(MSG_OUT, "Exit"); break; case 2: - fprintf(MSG_OUT, "JumpTT %" PRIu8, vm_getbits(command, 41, 7)); + fprintf(MSG_OUT, "JumpTT %" PRIu8, vm_getbits(command, 22, 7)); break; case 3: - fprintf(MSG_OUT, "JumpVTS_TT %" PRIu8, vm_getbits(command, 41, 7)); + fprintf(MSG_OUT, "JumpVTS_TT %" PRIu8, vm_getbits(command, 22, 7)); break; case 5: fprintf(MSG_OUT, "JumpVTS_PTT %" PRIu8 ":%" PRIu16, - vm_getbits(command, 41, 7), vm_getbits(command, 22, 10)); + vm_getbits(command, 22, 7), vm_getbits(command, 41, 10)); break; case 6: - switch(vm_getbits(command, 40, 2)) { + switch(vm_getbits(command, 23, 2)) { case 0: fprintf(MSG_OUT, "JumpSS FP"); break; case 1: - fprintf(MSG_OUT, "JumpSS VMGM (menu %" PRIu8 ")", vm_getbits(command, 44, 4)); + fprintf(MSG_OUT, "JumpSS VMGM (menu %" PRIu8 ")", vm_getbits(command, 19, 4)); break; case 2: fprintf(MSG_OUT, "JumpSS VTSM (vts %" PRIu8 ", title %" PRIu8 - ", menu %" PRIu8 ")", vm_getbits(command, 32, 8), vm_getbits(command, 24, 8), vm_getbits(command, 44, 4)); + ", menu %" PRIu8 ")", vm_getbits(command, 30, 7), vm_getbits(command, 38, 7), vm_getbits(command, 19, 4)); break; case 3: - fprintf(MSG_OUT, "JumpSS VMGM (pgc %" PRIu8 ")", vm_getbits(command, 17, 15)); + fprintf(MSG_OUT, "JumpSS VMGM (pgc %" PRIu8 ")", vm_getbits(command, 46, 15)); break; } break; case 8: - switch(vm_getbits(command, 40, 2)) { + switch(vm_getbits(command, 23, 2)) { case 0: fprintf(MSG_OUT, "CallSS FP (rsm_cell %" PRIu8 ")", - vm_getbits(command, 32, 8)); + vm_getbits(command, 31, 8)); break; case 1: fprintf(MSG_OUT, "CallSS VMGM (menu %" PRIu8 - ", rsm_cell %" PRIu8 ")", vm_getbits(command, 44, 4), vm_getbits(command, 32, 8)); + ", rsm_cell %" PRIu8 ")", vm_getbits(command, 19, 4), vm_getbits(command, 31, 8)); break; case 2: fprintf(MSG_OUT, "CallSS VTSM (menu %" PRIu8 - ", rsm_cell %" PRIu8 ")", vm_getbits(command, 44, 4), vm_getbits(command, 32, 8)); + ", rsm_cell %" PRIu8 ")", vm_getbits(command, 19, 4), vm_getbits(command, 31, 8)); break; case 3: fprintf(MSG_OUT, "CallSS VMGM (pgc %" PRIu8 ", rsm_cell %" PRIu8 ")", - vm_getbits(command, 17, 15), vm_getbits(command, 32, 8)); + vm_getbits(command, 46, 15), vm_getbits(command, 31, 8)); break; } break; @@ -339,14 +377,16 @@ static void print_jump_instruction(command_t* command) { static void print_system_set(command_t* command) { int i; +/* FIXME: What about SPRM11 ? Karaoke */ +/* Surely there must be some system set command for that ? */ - switch(vm_getbits(command, 4, 4)) { + switch(vm_getbits(command, 59, 4)) { case 1: /* Set system reg 1 &| 2 &| 3 (Audio, Subp. Angle) */ for(i = 1; i <= 3; i++) { - if(vm_getbits(command, ((2+i)*8), 1)) { + if(vm_getbits(command, 47 - (i*8), 1)) { print_system_reg(i); fprintf(MSG_OUT, " = "); - print_reg_or_data_2(command, vm_getbits(command, 3, 1), 2 + i); + print_reg_or_data_2(command, vm_getbits(command, 60, 1), 47 - (i*8) ); fprintf(MSG_OUT, " "); } } @@ -354,59 +394,72 @@ static void print_system_set(command_t* command) { case 2: /* Set system reg 9 & 10 (Navigation timer, Title PGC number) */ print_system_reg(9); fprintf(MSG_OUT, " = "); - print_reg_or_data(command, vm_getbits(command, 3, 1), 2); + print_reg_or_data(command, vm_getbits(command, 60, 1), 47); fprintf(MSG_OUT, " "); print_system_reg(10); - fprintf(MSG_OUT, " = %" PRIu8, vm_getbits(command, 40, 8)); /* ?? */ + fprintf(MSG_OUT, " = %" PRIu16, vm_getbits(command, 30, 15)); /* ?? */ break; case 3: /* Mode: Counter / Register + Set */ fprintf(MSG_OUT, "SetMode "); - if(vm_getbits(command, 40, 1)) + if(vm_getbits(command, 23, 1)) fprintf(MSG_OUT, "Counter "); else fprintf(MSG_OUT, "Register "); - print_reg(vm_getbits(command, 44, 4)); + print_g_reg(vm_getbits(command, 19, 4)); print_set_op(0x1); /* '=' */ - print_reg_or_data(command, vm_getbits(command, 3, 1), 2); + print_reg_or_data(command, vm_getbits(command, 60, 1), 47); break; case 6: /* Set system reg 8 (Highlighted button) */ print_system_reg(8); - if(vm_getbits(command, 3, 1)) /* immediate */ - fprintf(MSG_OUT, " = 0x%x (button no %d)", vm_getbits(command, 32, 16), vm_getbits(command, 32, 6)); + if(vm_getbits(command, 60, 1)) /* immediate */ + fprintf(MSG_OUT, " = 0x%x (button no %d)", vm_getbits(command, 31, 16), vm_getbits(command, 31, 6)); else - fprintf(MSG_OUT, " = g[%" PRIu8 "]", vm_getbits(command, 44, 4)); + fprintf(MSG_OUT, " = g[%" PRIu8 "]", vm_getbits(command, 19, 4)); break; default: fprintf(MSG_OUT, "WARNING: Unknown system set instruction (%i)", - vm_getbits(command, 4, 4)); + vm_getbits(command, 59, 4)); } } static void print_set_version_1(command_t* command) { - uint8_t set_op = vm_getbits(command, 4, 4); + uint8_t set_op = vm_getbits(command, 59, 4); if(set_op) { - print_reg(vm_getbits(command, 24, 8)); /* FIXME: This is different from decoder.c!!! */ + print_g_reg(vm_getbits(command, 35, 4)); print_set_op(set_op); - print_reg_or_data(command, vm_getbits(command, 3, 1), 4); + print_reg_or_data(command, vm_getbits(command, 60, 1), 31); } else { fprintf(MSG_OUT, "NOP"); } } static void print_set_version_2(command_t* command) { - uint8_t set_op = vm_getbits(command, 4, 4); + uint8_t set_op = vm_getbits(command, 59, 4); + + if(set_op) { + print_g_reg(vm_getbits(command, 51, 4)); + print_set_op(set_op); + print_reg_or_data(command, vm_getbits(command, 60, 1), 47); + } else { + fprintf(MSG_OUT, "NOP"); + } +} + +static void print_set_version_3(command_t* command) { + uint8_t set_op = vm_getbits(command, 59, 4); if(set_op) { - print_reg(vm_getbits(command, 12, 4)); + print_g_reg(vm_getbits(command, 51, 4)); print_set_op(set_op); - print_reg_or_data(command, vm_getbits(command, 3, 1), 2); + print_reg_or_data_3(command, vm_getbits(command, 60, 1), 47); } else { fprintf(MSG_OUT, "NOP"); } } -void vmPrint_mnemonic(vm_cmd_t *vm_command) { + +void vm_print_mnemonic(vm_cmd_t *vm_command) { command_t command; command.instruction =( (uint64_t) vm_command->bytes[0] << 56 ) | ( (uint64_t) vm_command->bytes[1] << 48 ) | @@ -418,13 +471,13 @@ void vmPrint_mnemonic(vm_cmd_t *vm_command) { (uint64_t) vm_command->bytes[7] ; command.examined = 0; - switch(vm_getbits(&command,0,3)) { /* three first bits */ + switch(vm_getbits(&command,63,3)) { /* three first bits */ case 0: /* Special instructions */ print_if_version_1(&command); print_special_instruction(&command); break; case 1: /* Jump/Call or Link instructions */ - if(vm_getbits(&command,3,1)) { + if(vm_getbits(&command,60,1)) { print_if_version_2(&command); print_jump_instruction(&command); } else { @@ -449,22 +502,22 @@ void vmPrint_mnemonic(vm_cmd_t *vm_command) { print_linksub_instruction(&command); break; case 5: /* Compare -> (Set and LinkSub) instructions */ - print_if_version_4(&command); + print_if_version_5(&command); fprintf(MSG_OUT, "{ "); - print_set_version_2(&command); + print_set_version_3(&command); fprintf(MSG_OUT, ", "); print_linksub_instruction(&command); fprintf(MSG_OUT, " }"); break; case 6: /* Compare -> Set, always LinkSub instructions */ - print_if_version_4(&command); + print_if_version_5(&command); fprintf(MSG_OUT, "{ "); - print_set_version_2(&command); + print_set_version_3(&command); fprintf(MSG_OUT, " } "); print_linksub_instruction(&command); break; default: - fprintf(MSG_OUT, "WARNING: Unknown instruction type (%i)", vm_getbits(&command, 0, 3)); + fprintf(MSG_OUT, "WARNING: Unknown instruction type (%i)", vm_getbits(&command, 63, 3)); } /* Check if there still are bits set that were not examined */ @@ -475,7 +528,7 @@ void vmPrint_mnemonic(vm_cmd_t *vm_command) { } } -void vmPrint_CMD(int row, vm_cmd_t *vm_command) { +void vm_print_cmd(int row, vm_cmd_t *vm_command) { int i; fprintf(MSG_OUT, "(%03d) ", row + 1); @@ -483,7 +536,7 @@ void vmPrint_CMD(int row, vm_cmd_t *vm_command) { fprintf(MSG_OUT, "%02x ", vm_command->bytes[i]); fprintf(MSG_OUT, "| "); - vmPrint_mnemonic(vm_command); + vm_print_mnemonic(vm_command); fprintf(MSG_OUT, "\n"); } diff --git a/src/input/libdvdnav/vmcmd.h b/src/input/libdvdnav/vmcmd.h index 6d3c2cb96..5a17339c9 100644 --- a/src/input/libdvdnav/vmcmd.h +++ b/src/input/libdvdnav/vmcmd.h @@ -18,7 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: vmcmd.h,v 1.5 2003/03/29 13:19:09 mroi Exp $ + * $Id: vmcmd.h,v 1.6 2003/04/07 18:10:53 mroi Exp $ * */ @@ -30,8 +30,8 @@ #include "dvdnav_internal.h" #ifdef TRACE -void vmPrint_mnemonic(vm_cmd_t *command); -void vmPrint_CMD(int row, vm_cmd_t *command); +void vm_print_mnemonic(vm_cmd_t *command); +void vm_print_cmd(int row, vm_cmd_t *command); #endif #endif /* VMCMD_H_INCLUDED */ |