📄 ifo.c
字号:
return 0;}/***************************************************************************** * FreeTitleUnit: frees a structure allocateed by ReadTitleUnit *****************************************************************************/static int FreeTitleUnit( title_unit_t * p_title_unit ){ int i; if( p_title_unit->p_unit_inf != NULL ) { for( i = 0 ; i < p_title_unit->i_unit_nb ; i++ ) { FreeUnitInf( &p_title_unit->p_unit_inf[i] ); } free( p_title_unit->p_unit_inf ); } return 0;}/***************************************************************************** * ReadCellInf : Fills the Cell Information structure. *****************************************************************************/static int ReadCellInf( ifo_t * p_ifo, cell_inf_t * p_cell_inf, int i_block ){ uint8_t p_buf[DVD_LB_SIZE]; uint8_t * p_tmp; int i_start; int i; p_tmp = FillBuffer( p_ifo, p_buf, i_block ); i_start = p_ifo->i_pos;/* fprintf( stderr, "CELL ADD\n" ); */ p_cell_inf->i_vob_nb = ReadWord( p_ifo, p_buf, &p_tmp ); DumpBytes( p_ifo, p_buf, &p_tmp, 2 ); p_cell_inf->i_last_byte = ReadDouble( p_ifo, p_buf, &p_tmp ); p_cell_inf->i_cell_nb = (p_cell_inf->i_last_byte + 1/* - 7*/) / sizeof(cell_map_t);/* fprintf( stderr, "Cell inf: vob %d, %d cells, last byte %d\n", p_cell_inf->i_vob_nb, p_cell_inf->i_cell_nb, p_cell_inf->i_last_byte );*/ p_cell_inf->p_cell_map = malloc( p_cell_inf->i_cell_nb *sizeof(cell_map_t) ); if( p_cell_inf->p_cell_map == NULL ) { return -1; } for( i = 0 ; i < p_cell_inf->i_cell_nb ; i++ ) {#define MAP p_cell_inf->p_cell_map[i] MAP.i_vob_id = ReadWord( p_ifo, p_buf, &p_tmp ); MAP.i_cell_id = ReadByte( p_ifo, p_buf, &p_tmp ); DumpBytes( p_ifo, p_buf, &p_tmp, 1 ); MAP.i_first_sector = ReadDouble( p_ifo, p_buf, &p_tmp );/* fprintf(stderr, "sector[%d] %d (%d)\n", i,ntohl(*(uint32_t*)(p_tmp)), p_ifo->i_pos);*/ MAP.i_last_sector = ReadDouble( p_ifo, p_buf, &p_tmp );#undef MAP } return 0;}/***************************************************************************** * FreeCellInf : frees structures allocated by ReadCellInf *****************************************************************************/static int FreeCellInf( cell_inf_t * p_cell_inf ){ free( p_cell_inf->p_cell_map ); return 0;}/***************************************************************************** * ReadVobuMap : Fills the VOBU Map structure. *****************************************************************************/static int ReadVobuMap( ifo_t * p_ifo, vobu_map_t * p_vobu_map, int i_block ){ uint8_t p_buf[DVD_LB_SIZE]; uint8_t * p_tmp; int i_start; int i, i_max; p_tmp = FillBuffer( p_ifo, p_buf, i_block ); i_start = p_ifo->i_pos; /*fprintf( stderr, "VOBU ADMAP\n" ); */ p_vobu_map->i_last_byte = ReadDouble( p_ifo, p_buf, &p_tmp ); i_max = ( i_start + p_vobu_map->i_last_byte + 1 - p_ifo->i_pos ) / sizeof(uint32_t); p_vobu_map->pi_vobu_start_sector = malloc( i_max * sizeof(uint32_t) ); if( p_vobu_map->pi_vobu_start_sector == NULL ) { return -1; } for( i = 0 ; i < i_max ; i++ ) { p_vobu_map->pi_vobu_start_sector[i] = ReadDouble( p_ifo, p_buf, &p_tmp ); } return 0;}/***************************************************************************** * FreeVobuMap: frees structures allocated by ReadVobuMap *****************************************************************************/static int FreeVobuMap( vobu_map_t * p_vobu_map ){ free( p_vobu_map->pi_vobu_start_sector ); return 0;}/* * IFO virtual machine : a set of commands that give the * interactive behaviour of the dvd */#if 0#define OP_VAL_16(i) (ntoh16( com.data.pi_16[i]))#define OP_VAL_8(i) ((com.data.pi_8[i]))static char ifo_reg[][80]={ "Menu_Language_Code", "Audio_Stream_#", "SubPicture_Stream_#", "Angle_#", "VTS_#", "VTS_Title_#", "PGC_#", "PTT_#", "Highlighted_Button_#", "Nav_Timer", "TimedPGC", "Karaoke_audio_mixing_mode", "Parental_mgmt_country_code", "Parental_Level", "Player_Video_Cfg", "Player_Audio_Cfg", "Audio_language_code_setting", "Audio_language_extension_code", "SPU_language_code_setting", "SPU_language_extension_code", "?Player_Regional_Code", "Reserved_21", "Reserved_22", "Reserved_23"};static char * IfoMath( char val ){ static char math_op[][10] = { "none", "=", "<->", /* swap */ "+=", "-=", "*=", "/=", "%=", "rnd", /* rnd */ "&=", "|=", "^=", "??", /* invalid */ "??", /* invalid */ "??", /* invalid */ "??" /* invalid */ }; return (char *) math_op[val & 0x0f];}char ifo_cmp[][10] ={ "none", "&&", "==", "!=", ">=", ">", "<", "<="};char ifo_parental[][10] ={ "0", "G", "2", "PG", "PG-13", "5", "R", "NC-17"};char ifo_menu_id[][80] ={ "-0-", "-1-", "Title (VTS menu)", "Root", "Sub-Picture", "Audio", "Angle", "Part of Title",};char * IfoMenuName( char index ){ return ifo_menu_id[index&0x07];}static void IfoRegister( uint16_t i_data, uint8_t i_direct){ if( i_direct ) { if( 0/*isalpha( i_data >> 8 & 0xff )*/ ) { printf("'%c%c'", i_data>>8&0xff, i_data&0xff); } else { printf("0x%02x", i_data); } } else { if( i_data & 0x80 ) { i_data &= 0x1f; if( i_data > 0x17 ) { printf("s[ILL]"); } else { printf("s[%s]", ifo_reg[i_data]); } } else { i_data &= 0x1f; if( i_data > 0xf ) { printf("r[ILL]"); } else { printf("r[0x%02x]", i_data); } } }}static void IfoAdvanced( uint8_t *pi_code ){ uint8_t i_cmd = pi_code[0]; printf(" { "); if( pi_code[1]>>2 ) { printf( " Highlight button %d; ", pi_code[1]>>2 ); } if( i_cmd == 0xff ) { printf( " Illegal " ); } if( i_cmd == 0x00 ) { printf( "ReSuME %d", pi_code[7] ); } else if( ( i_cmd & 0x06) == 0x02 ) { /* XX01Y */ printf ("Link to %s cell ", ( i_cmd & 0x01 ) ? "prev" : "next"); } else { printf( "advanced (0x%02x) ", i_cmd ); } printf(" } ");}static void IfoJmp( ifo_command_t com ){ printf ("jmp "); switch( com.i_sub_cmd ) { case 0x01: printf( "Exit" ); break; case 0x02: printf( "VTS 0x%02x", OP_VAL_8(3) ); break; case 0x03: printf( "This VTS Title 0x%02x", OP_VAL_8(3) ); break; case 0x05: printf( "This VTS Title 0x%02x Part 0x%04x", OP_VAL_8(3), OP_VAL_8(0)<<8|OP_VAL_8(1)); break; case 0x06:#if 0 printf ("in SystemSpace "); switch (OP_VAL_8(3)>>4) { case 0x00: printf ("to play first PGC"); break; case 0x01: { printf ("to menu \"%s\"", decode_menuname (OP_VAL_8(3))); } break; case 0x02: printf ("to VTS 0x%02x and TTN 0x%02x", OP_VAL_8(1), OP_VAL_8(2)); break; case 0x03: printf ("to VMGM PGC number 0x%02x", OP_VAL_8(0)<<8 | OP_VAL_8(1)); break; case 0x08: printf ("vts 0x%02x lu 0x%02x menu \"%s\"", OP_VAL_8(2), OP_VAL_8(1), decode_menuname (OP_VAL_8(3))); break;#else switch( OP_VAL_8(3)>>6 ) { case 0x00: printf( "to play first PGC" ); break; case 0x01: printf( "to VMG title menu (?)" ); break; case 0x02: printf( "vts 0x%02x lu 0x%02x menu \"%s\"", OP_VAL_8(2), OP_VAL_8(1), IfoMenuName( OP_VAL_8(3)&0xF ) ); break; case 0x03: printf( "vmg pgc 0x%04x (?)", ( OP_VAL_8(0)<<8) | OP_VAL_8(1) ); break;#endif } break; case 0x08:#if 0 switch(OP_VAL_8(3)>>4) { case 0x00: printf ("system first pgc"); break; case 0x01: printf ("system title menu"); break; case 0x02: printf ("system menu \"%s\"", decode_menuname (OP_VAL_8(3))); break; case 0x03: printf ("system vmg pgc %02x ????", OP_VAL_8(0)<<8|OP_VAL_8(1)); break; case 0x08: printf ("system lu 0x%02x menu \"%s\"", OP_VAL_8(2), decode_menuname (OP_VAL_8(3))); break; case 0x0c: printf ("system vmg pgc 0x%02x", OP_VAL_8(0)<<8|OP_VAL_8(1)); break; }#else /* OP_VAL_8(2) is number of cell */ /* it is processed BEFORE switch */ /* under some conditions, it is ignored */ /* I don't understand exactly what it means */ printf( " ( spec cell 0x%02X ) ", OP_VAL_8(2) ); switch( OP_VAL_8(3)>>6 ) { case 0: printf( "to FP PGC" ); break; case 1: printf( "to VMG root menu (?)" ); break; case 2: printf( "to VTS menu \"%s\" (?)", IfoMenuName(OP_VAL_8(3)&0xF) ); break; case 3: printf( "vmg pgc 0x%02x (?)", (OP_VAL_8(0)<<8)|OP_VAL_8(1) ); break; }#endif break; }}static void IfoLnk( ifo_command_t com ){ uint16_t i_button = OP_VAL_8(4)>>2; printf ("lnk to "); switch( com.i_sub_cmd ) { case 0x01: IfoAdvanced( &OP_VAL_8(4) ); break; case 0x04: printf( "PGC 0x%02x", OP_VAL_16(2) ); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -