📄 ifo.c
字号:
if ( p_ifo->vmg.parental_inf.p_parental_mask != NULL ) free( p_ifo->vmg.parental_inf.p_parental_mask ); if ( p_ifo->vmg.parental_inf.p_parental_desc != NULL ) free( p_ifo->vmg.parental_inf.p_parental_desc ); } if( p_ifo->vmg.manager_inf.i_title_unit_start_sector ) { FreeTitleUnit( &p_ifo->vmg.title_unit ); } if( p_ifo->vmg.manager_inf.i_title_inf_start_sector ) { free( p_ifo->vmg.title_inf.p_attr ); } FreeTitle( &p_ifo->vmg.title ); free( p_ifo ); return;}/* * Function common to Video Manager and Video Title set Processing *//***************************************************************************** * ReadTitle : Fills the title structure. ***************************************************************************** * Titles are logical stream units that correspond to a whole inside the dvd. * Several title can point to the same part of the physical DVD, and give * map to different anglesfor instance. *****************************************************************************/static int ReadTitle( ifo_t * p_ifo, title_t * p_title, int i_block, int i_bytes ){ uint8_t p_buf[DVD_LB_SIZE]; uint8_t * p_tmp; int i_start; uint16_t i_audio; uint32_t i_spu; int i; p_tmp = FillBuffer( p_ifo, p_buf, i_block ) + i_bytes; i_start = p_ifo->i_pos; /*fprintf( stderr, "PGC @ %d + %d\n", p_ifo->i_pos, i_bytes ); */ DumpBytes( p_ifo, p_buf, &p_tmp, 2); p_title->i_chapter_nb = ReadByte( p_ifo, p_buf, &p_tmp ); p_title->i_cell_nb = ReadByte( p_ifo, p_buf, &p_tmp ); /*fprintf( stderr, "title: Prg: %d Cell: %d\n",p_title->i_chapter_nb,p_title->i_cell_nb ); */ p_title->i_play_time = ReadDouble( p_ifo, p_buf, &p_tmp ); p_title->i_prohibited_user_op = ReadDouble( p_ifo, p_buf, &p_tmp ); for( i = 0 ; i < 8 ; i++ ) { i_audio = ReadWord( p_ifo, p_buf, &p_tmp ); p_title->pi_audio_status[i].i_foo = i_audio & 0xff; i_audio >>= 8; p_title->pi_audio_status[i].i_position = i_audio & 0x07; i_audio >>= 7; p_title->pi_audio_status[i].i_available = i_audio; } for( i = 0 ; i < 32 ; i++ ) { i_spu = ReadDouble( p_ifo, p_buf, &p_tmp ); p_title->pi_spu_status[i].i_position_pan = i_spu & 0x1f; i_spu >>= 8; p_title->pi_spu_status[i].i_position_letter = i_spu & 0x1f; i_spu >>= 8; p_title->pi_spu_status[i].i_position_wide = i_spu & 0x1f; i_spu >>= 8; p_title->pi_spu_status[i].i_position_43 = i_spu & 0x1f; i_spu >>= 7; p_title->pi_spu_status[i].i_available = i_spu; } p_title->i_next_title_num = ReadWord( p_ifo, p_buf, &p_tmp ); p_title->i_prev_title_num = ReadWord( p_ifo, p_buf, &p_tmp ); p_title->i_go_up_title_num = ReadWord( p_ifo, p_buf, &p_tmp ); p_title->i_still_time = ReadByte( p_ifo, p_buf, &p_tmp ); p_title->i_play_mode = ReadByte( p_ifo, p_buf, &p_tmp ); for( i = 0 ; i < 16 ; i++ ) { /* FIXME : We have to erase the extra bit */ p_title->pi_yuv_color[i] = ReadDouble( p_ifo, p_buf, &p_tmp ); } p_title->i_command_start_byte = ReadWord( p_ifo, p_buf, &p_tmp ); p_title->i_chapter_map_start_byte = ReadWord( p_ifo, p_buf, &p_tmp ); p_title->i_cell_play_start_byte = ReadWord( p_ifo, p_buf, &p_tmp ); p_title->i_cell_pos_start_byte = ReadWord( p_ifo, p_buf, &p_tmp ); /* parsing of command_t */ if( p_title->i_command_start_byte ) { p_tmp = FillBuffer( p_ifo, p_buf, i_start + OFF2LB( p_title->i_command_start_byte + i_bytes ) ) + ( (p_title->i_command_start_byte + i_bytes) & 0x7ff ); /* header */ p_title->command.i_pre_command_nb = ReadWord( p_ifo, p_buf, &p_tmp ); p_title->command.i_post_command_nb = ReadWord( p_ifo, p_buf, &p_tmp ); p_title->command.i_cell_command_nb = ReadWord( p_ifo, p_buf, &p_tmp ); DumpBytes( p_ifo, p_buf, &p_tmp, 2 ); /* pre-title commands */ if( p_title->command.i_pre_command_nb ) { p_title->command.p_pre_command = malloc( p_title->command.i_pre_command_nb * sizeof(command_desc_t) ); if( p_title->command.p_pre_command == NULL ) { return -1; } for( i = 0 ; i < p_title->command.i_pre_command_nb ; i++ ) { p_title->command.p_pre_command[i] = ReadQuad( p_ifo, p_buf, &p_tmp ); } } else { p_title->command.p_pre_command = NULL; } /* post-title commands */ if( p_title->command.i_post_command_nb ) { p_title->command.p_post_command = malloc( p_title->command.i_post_command_nb * sizeof(command_desc_t) ); if( p_title->command.p_post_command == NULL ) { return -1; } for( i = 0 ; i < p_title->command.i_post_command_nb ; i++ ) { p_title->command.p_post_command[i] = ReadQuad( p_ifo, p_buf, &p_tmp ); } } else { p_title->command.p_post_command = NULL; } /* cell commands */ if( p_title->command.i_cell_command_nb ) { p_title->command.p_cell_command = malloc( p_title->command.i_cell_command_nb * sizeof(command_desc_t) ); if( p_title->command.p_cell_command == NULL ) { return -1; } for( i = 0 ; i < p_title->command.i_cell_command_nb ; i++ ) { p_title->command.p_cell_command[i] = ReadQuad( p_ifo, p_buf, &p_tmp ); } } else { p_title->command.p_cell_command = NULL; } } /* parsing of chapter_map_t: it gives the entry cell for each chapter */ if( p_title->i_chapter_map_start_byte ) { p_ifo->i_pos = dvdcss_seek( p_ifo->dvdhandle, OFF2LB( i_start + p_title->i_chapter_map_start_byte ), DVDCSS_NOFLAGS ); p_title->chapter_map.pi_start_cell = malloc( p_title->i_chapter_nb * sizeof(chapter_map_t) ); if( p_title->chapter_map.pi_start_cell == NULL ) { return -1; } ReadBytes( p_ifo, p_buf, &p_tmp, p_title->chapter_map.pi_start_cell, p_title->i_chapter_nb ); } else { p_title->chapter_map.pi_start_cell = NULL; } /* parsing of cell_play_t */ if( p_title->i_cell_play_start_byte ) { p_tmp = FillBuffer( p_ifo, p_buf, i_start + OFF2LB( p_title->i_cell_play_start_byte+i_bytes ) ) + ( (p_title->i_cell_play_start_byte+i_bytes) & 0x7ff ); p_title->p_cell_play = malloc( p_title->i_cell_nb * sizeof(cell_play_t) ); if( p_title->p_cell_play == NULL ) { return -1; } for( i = 0 ; i < p_title->i_cell_nb ; i++ ) {#define PLAY p_title->p_cell_play[i] PLAY.i_category = ReadWord( p_ifo, p_buf, &p_tmp ); PLAY.i_still_time = ReadByte( p_ifo, p_buf, &p_tmp ); PLAY.i_command_nb = ReadByte( p_ifo, p_buf, &p_tmp ); PLAY.i_play_time = ReadDouble( p_ifo, p_buf, &p_tmp ); PLAY.i_first_sector = ReadDouble( p_ifo, p_buf, &p_tmp ); PLAY.i_first_ilvu_vobu_esector = ReadDouble( p_ifo, p_buf, &p_tmp ); PLAY.i_last_vobu_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp ); PLAY.i_last_sector = ReadDouble( p_ifo, p_buf, &p_tmp );#undef PLAY } } /* Parsing of cell_pos_t */ if( p_title->i_cell_pos_start_byte ) { p_tmp = FillBuffer( p_ifo, p_buf, i_start + OFF2LB( p_title->i_cell_pos_start_byte + i_bytes ) ) + ( (p_title->i_cell_pos_start_byte + i_bytes) & 0x7ff ); p_title->p_cell_pos = malloc( p_title->i_cell_nb * sizeof(cell_pos_t) ); if( p_title->p_cell_pos == NULL ) { return -1; } for( i = 0 ; i < p_title->i_cell_nb ; i++ ) { p_title->p_cell_pos[i].i_vob_id = ReadWord( p_ifo, p_buf, &p_tmp ); DumpBytes( p_ifo, p_buf, &p_tmp, 1 ); p_title->p_cell_pos[i].i_cell_id = ReadByte( p_ifo, p_buf, &p_tmp ); } } return 0;}/***************************************************************************** * FreeTitle: frees alla structure allocated by a call to ReadTitle *****************************************************************************/static int FreeTitle( title_t * p_title ){ if( p_title->i_command_start_byte ) { if( p_title->command.i_pre_command_nb ) { free( p_title->command.p_pre_command ); } if( p_title->command.i_post_command_nb ) { free( p_title->command.p_post_command ); } if( p_title->command.i_cell_command_nb ) { free( p_title->command.p_cell_command ); } } if( p_title->i_chapter_map_start_byte ) { free( p_title->chapter_map.pi_start_cell ); } if( p_title->i_cell_play_start_byte ) { free( p_title->p_cell_play ); } if( p_title->i_cell_pos_start_byte ) { free( p_title->p_cell_pos ); } return 0;}/***************************************************************************** * ReadUnitInf : Fills Menu Language Unit Table/ PGC Info Table *****************************************************************************/static int ReadUnitInf( ifo_t * p_ifo, unit_inf_t * p_unit_inf, int i_block, int i_bytes ){ 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_bytes; i_start = p_ifo->i_pos; /*fprintf( stderr, "Unit\n" ); */ p_unit_inf->i_title_nb = ReadWord( p_ifo, p_buf, &p_tmp ); /*fprintf( stderr, "Unit nb: %d\n", p_unit_inf->i_title_nb ); */ DumpBytes( p_ifo, p_buf, &p_tmp, 2 ); p_unit_inf->i_last_byte = ReadDouble( p_ifo, p_buf, &p_tmp ); p_unit_inf->p_title = malloc( p_unit_inf->i_title_nb * sizeof(unit_title_t) ); if( p_unit_inf->p_title == NULL ) { return -1; } for( i = 0 ; i < p_unit_inf->i_title_nb ; i++ ) {#define TITLE p_unit_inf->p_title[i] TITLE.i_category_mask = ReadByte( p_ifo, p_buf, &p_tmp ); TITLE.i_category = ReadByte( p_ifo, p_buf, &p_tmp ); /*fprintf( stderr, "cat mask %d: %x cat %x\n", i, TITLE.i_category_mask, TITLE.i_category ); */ TITLE.i_parental_mask = ReadWord( p_ifo, p_buf, &p_tmp ); TITLE.i_title_start_byte = ReadDouble( p_ifo, p_buf, &p_tmp );#undef TITLE } for( i = 0 ; i < p_unit_inf->i_title_nb ; i++ ) { /*fprintf( stderr, "Unit: PGC %d @ %d\n", i, p_ifo->i_pos ); */ ReadTitle( p_ifo, &p_unit_inf->p_title[i].title, i_start + OFF2LB( p_unit_inf->p_title[i].i_title_start_byte + i_bytes ), (p_unit_inf->p_title[i].i_title_start_byte+i_bytes) & 0x7ff ); } return 0;}/***************************************************************************** * FreeUnitInf : frees a structure allocated by ReadUnit *****************************************************************************/static int FreeUnitInf( unit_inf_t * p_unit_inf ){ int i; if( p_unit_inf->p_title != NULL ) { for( i = 0 ; i < p_unit_inf->i_title_nb ; i++ ) { FreeTitle( &p_unit_inf->p_title[i].title ); } free( p_unit_inf->p_title ); } return 0;}/***************************************************************************** * ReadTitleUnit: Fills the Title Unit structure. *****************************************************************************/static int ReadTitleUnit( ifo_t * p_ifo, title_unit_t * p_title_unit, int i_block ){ uint8_t p_buf[DVD_LB_SIZE]; uint8_t * p_tmp; int i; int i_start; p_tmp = FillBuffer( p_ifo, p_buf, i_block ); i_start = p_ifo->i_pos; /*fprintf( stderr, "Unit Table\n" ); */ p_title_unit->i_unit_nb = ReadWord( p_ifo, p_buf, &p_tmp ); DumpBytes( p_ifo, p_buf, &p_tmp, 2 ); p_title_unit->i_last_byte = ReadDouble( p_ifo, p_buf, &p_tmp ); /*fprintf(stderr, "Unit: nb %d last %d\n", p_title_unit->i_unit_nb, p_title_unit->i_last_byte ); */ p_title_unit->p_unit = malloc( p_title_unit->i_unit_nb * sizeof(unit_t) ); if( p_title_unit->p_unit == NULL ) { return -1; } for( i = 0 ; i < p_title_unit->i_unit_nb ; i++ ) { /*ReadBytes( p_ifo, p_buf, &p_tmp, p_title_unit->p_unit[i].ps_lang_code, 2 ); */ p_title_unit->p_unit[i].i_lang_code = ReadWord( p_ifo, p_buf, &p_tmp ); /*fprintf( stderr, "lang %d %x\n", i,p_title_unit->p_unit[i].i_lang_code ); */ DumpBytes( p_ifo, p_buf, &p_tmp, 1 ); p_title_unit->p_unit[i].i_existence_mask = ReadByte( p_ifo, p_buf, &p_tmp ); p_title_unit->p_unit[i].i_unit_inf_start_byte = ReadDouble( p_ifo, p_buf, &p_tmp ); } p_title_unit->p_unit_inf = malloc( p_title_unit->i_unit_nb * sizeof(unit_inf_t) ); if( p_title_unit->p_unit_inf == NULL ) { return -1; } for( i = 0 ; i < p_title_unit->i_unit_nb ; i++ ) { ReadUnitInf( p_ifo, &p_title_unit->p_unit_inf[i], i_start + OFF2LB( p_title_unit->p_unit[i].i_unit_inf_start_byte ), p_title_unit->p_unit[i].i_unit_inf_start_byte & 0x7ff ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -