summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/input/libdvdnav/Makefile.am1
-rw-r--r--src/input/libdvdnav/decoder.c184
-rw-r--r--src/input/libdvdnav/decoder.h6
-rw-r--r--src/input/libdvdnav/diff_against_cvs.patch16
-rw-r--r--src/input/libdvdnav/dvd_types.h3
-rw-r--r--src/input/libdvdnav/dvdnav.c90
-rw-r--r--src/input/libdvdnav/dvdnav.h861
-rw-r--r--src/input/libdvdnav/dvdnav_events.h256
-rw-r--r--src/input/libdvdnav/highlight.c4
-rw-r--r--src/input/libdvdnav/navigation.c31
-rw-r--r--src/input/libdvdnav/searching.c16
-rw-r--r--src/input/libdvdnav/vm.c43
-rw-r--r--src/input/libdvdnav/vm.h5
-rw-r--r--src/input/libdvdnav/vmcmd.c209
-rw-r--r--src/input/libdvdnav/vmcmd.h6
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 */