📄 input.c
字号:
p_input->psz_demux = "dvdread"; } return VLC_SUCCESS;}/***************************************************************************** * CloseDVD: close libdvdread *****************************************************************************/void E_(CloseDVD) ( vlc_object_t *p_this ){ input_thread_t * p_input = (input_thread_t *)p_this; thread_dvd_data_t * p_dvd = (thread_dvd_data_t *)p_input->p_access_data; /* This is a very nasty side-effect in the DVD plug-in : language * selection here influences language selection of other streams. So * unset those variables (may not be what the user wants). * FIXME FIXME FIXME FIXME FIXME FIXME FIXME --Meuuh */ config_PutInt( p_input, "audio-channel", -1 ); config_PutInt( p_input, "spu-channel", -1 ); /* close libdvdread */ DVDCloseFile( p_dvd->p_title ); ifoClose( p_dvd->p_vts_file ); ifoClose( p_dvd->p_vmg_file ); DVDClose( p_dvd->p_dvdread ); free( p_dvd ); p_input->p_access_data = NULL;}/***************************************************************************** * DvdReadSetProgram: Does nothing, a DVD is mono-program *****************************************************************************/static int DvdReadSetProgram( input_thread_t * p_input, pgrm_descriptor_t * p_program ){ if( p_input->stream.p_selected_program != p_program ) { thread_dvd_data_t * p_dvd; vlc_value_t val; p_dvd = (thread_dvd_data_t*)(p_input->p_access_data); p_dvd->i_angle = p_program->i_number; memcpy( p_program, p_input->stream.p_selected_program, sizeof(pgrm_descriptor_t) ); p_program->i_number = p_dvd->i_angle; p_input->stream.p_selected_program = p_program; msg_Dbg( p_input, "angle %d selected", p_dvd->i_angle ); /* Update the navigation variables without triggering a callback */ val.i_int = p_program->i_number; var_Change( p_input, "program", VLC_VAR_SETVALUE, &val, NULL ); } return VLC_SUCCESS;}#define p_pgc p_dvd->p_cur_pgc/***************************************************************************** * DvdReadSetArea: initialize input data for title x, chapter y. * It should be called for each user navigation request. ***************************************************************************** * Take care that i_title starts from 0 (vmg) and i_chapter start from 1. * Note that you have to take the lock before entering here. *****************************************************************************/static int DvdReadSetArea( input_thread_t * p_input, input_area_t * p_area ){ thread_dvd_data_t * p_dvd; int pgc_id = 0; int pgn = 0; vlc_value_t val; p_dvd = (thread_dvd_data_t*)p_input->p_access_data; /* we can't use the interface slider until initilization is complete */ p_input->stream.b_seekable = VLC_FALSE; if( p_area != p_input->stream.p_selected_area ) { es_descriptor_t * p_es; unsigned int i_cell = 0; unsigned int i_audio_nb = 0; unsigned int i_spu_nb = 0; unsigned int i;#define p_vmg p_dvd->p_vmg_file#define p_vts p_dvd->p_vts_file if( p_dvd->p_title != NULL ) { DVDCloseFile( p_dvd->p_title ); } if( p_vts != NULL ) { ifoClose( p_vts ); } /* Reset the Chapter position of the old title */ p_input->stream.p_selected_area->i_part = 1; /* * We have to load all title information */ /* Change the default area */ p_input->stream.p_selected_area = p_area; msg_Dbg( p_input, "open VTS %d, for title %d", p_vmg->tt_srpt->title[ p_area->i_id - 1 ].title_set_nr, p_area->i_id ); /* ifo vts */ if( ! ( p_vts = ifoOpen( p_dvd->p_dvdread, p_vmg->tt_srpt->title[ p_area->i_id - 1 ].title_set_nr ) ) ) { msg_Err( p_input, "fatal error in vts ifo" ); ifoClose( p_vmg ); DVDClose( p_dvd->p_dvdread ); return VLC_EGENERIC; } /* title position inside the selected vts */ p_dvd->i_ttn = p_vmg->tt_srpt->title[ p_area->i_id - 1 ].vts_ttn; /* * Set selected title start */ pgc_id = p_vts->vts_ptt_srpt->title[p_dvd->i_ttn-1].ptt[0].pgcn; pgn = p_vts->vts_ptt_srpt->title[p_dvd->i_ttn-1].ptt[0].pgn; p_pgc = p_vts->vts_pgcit->pgci_srp[ pgc_id - 1 ].pgc; i_cell = p_pgc->program_map[ pgn - 1 ] - 1; p_area->i_start = LB2OFF( p_dvd->p_cur_pgc->cell_playback[ i_cell ].first_sector ); msg_Dbg( p_input, "start %d vts_title %d pgc %d pgn %d", p_area->i_id, p_dvd->i_ttn, pgc_id, pgn ); /* * Find title end */ i_cell = p_dvd->p_cur_pgc->nr_of_cells - 1; p_dvd->i_end_block = p_pgc->cell_playback[ i_cell ].last_sector; p_area->i_size = LB2OFF( p_dvd->i_end_block )- p_area->i_start; msg_Dbg( p_input, "start "I64Fd" size "I64Fd" end %d", p_area->i_start , p_area->i_size, p_dvd->i_end_block ); /* * Set properties for current chapter */ /* Remeber current chapter */ p_dvd->i_chapter = p_area->i_part; p_dvd->b_eoc = VLC_FALSE; pgc_id = p_vts->vts_ptt_srpt->title[ p_dvd->i_ttn-1].ptt[p_area->i_part-1].pgcn; pgn = p_vts->vts_ptt_srpt->title[ p_dvd->i_ttn-1].ptt[p_area->i_part-1].pgn; p_pgc = p_vts->vts_pgcit->pgci_srp[pgc_id-1].pgc; p_dvd->i_pack_len = 0; p_dvd->i_next_cell = p_dvd->i_cur_cell = p_pgc->program_map[pgn-1] - 1; DvdReadFindCell( p_dvd ); p_dvd->i_next_vobu = p_dvd->i_cur_block = p_pgc->cell_playback[p_dvd->i_cur_cell].first_sector; /* * Angle management */ p_dvd->i_angle_nb = p_vmg->tt_srpt->title[p_area->i_id-1].nr_of_angles; if( p_dvd->i_angle > p_dvd->i_angle_nb ) { p_dvd->i_angle = 1; } /* * We've got enough info, time to open the title set data. */ if( ! ( p_dvd->p_title = DVDOpenFile( p_dvd->p_dvdread, p_vmg->tt_srpt->title[ p_area->i_id - 1 ].title_set_nr, DVD_READ_TITLE_VOBS ) ) ) { msg_Err( p_input, "cannot open title (VTS_%02d_1.VOB)", p_vmg->tt_srpt->title[p_area->i_id-1].title_set_nr ); ifoClose( p_vts ); ifoClose( p_vmg ); DVDClose( p_dvd->p_dvdread ); return VLC_EGENERIC; }// IfoPrintTitle( p_dvd ); /* * Destroy obsolete ES by reinitializing program 0 * and find all ES in title with ifo data */ if( p_input->stream.pp_programs != NULL ) { /* We don't use input_EndStream here since * we keep area structures */ while( p_input->stream.i_es_number ) { input_DelES( p_input, p_input->stream.pp_es[0] ); } while( p_input->stream.i_pgrm_number ) { input_DelProgram( p_input, p_input->stream.pp_programs[0] ); } if( p_input->stream.pp_selected_es ) { free( p_input->stream.pp_selected_es ); p_input->stream.pp_selected_es = NULL; } p_input->stream.i_selected_es_number = 0; } input_AddProgram( p_input, 1, sizeof( stream_ps_data_t ) ); p_input->stream.p_selected_program = p_input->stream.pp_programs[0]; for( i = 1 ; i < p_dvd->i_angle_nb ; i++ ) { input_AddProgram( p_input, i+1, 0 ); } DvdReadSetProgram( p_input, p_input->stream.pp_programs[p_dvd->i_angle-1] ); /* No PSM to read in DVD mode, we already have all information */ p_input->stream.p_selected_program->b_is_ok = VLC_TRUE; p_es = NULL; /* ES 0 -> video MPEG2 */// IfoPrintVideo( p_dvd ); p_es = input_AddES( p_input, NULL, 0xe0, VIDEO_ES, NULL, 0 ); p_es->i_stream_id = 0xe0; p_es->i_fourcc = VLC_FOURCC('m','p','g','v');#define audio_control \ p_dvd->p_vts_file->vts_pgcit->pgci_srp[pgc_id-1].pgc->audio_control[i-1] /* Audio ES, in the order they appear in .ifo */ for( i = 1 ; i <= p_vts->vtsi_mat->nr_of_vts_audio_streams ; i++ ) { int i_position = 0; uint16_t i_id;// IfoPrintAudio( p_dvd, i ); /* audio channel is active if first byte is 0x80 */ if( audio_control & 0x8000 ) { i_audio_nb++; i_position = ( audio_control & 0x7F00 ) >> 8; msg_Dbg( p_input, "audio position %d", i_position ); switch( p_vts->vtsi_mat->vts_audio_attr[i-1].audio_format ) { case 0x00: /* A52 */ i_id = ( ( 0x80 + i_position ) << 8 ) | 0xbd; p_es = input_AddES( p_input, NULL, i_id, AUDIO_ES, DecodeLanguage( p_vts->vtsi_mat->vts_audio_attr[i-1].lang_code ), 0 ); p_es->i_stream_id = 0xbd; p_es->i_fourcc = VLC_FOURCC('a','5','2','b'); break; case 0x02: case 0x03: /* MPEG audio */ i_id = 0xc0 + i_position; p_es = input_AddES( p_input, NULL, i_id, AUDIO_ES, DecodeLanguage( p_vts->vtsi_mat->vts_audio_attr[i-1].lang_code ), 0 ); p_es->i_stream_id = i_id; p_es->i_fourcc = VLC_FOURCC('m','p','g','a'); break; case 0x04: /* LPCM */ i_id = ( ( 0xa0 + i_position ) << 8 ) | 0xbd; p_es = input_AddES( p_input, NULL, i_id, AUDIO_ES, DecodeLanguage( p_vts->vtsi_mat->vts_audio_attr[i-1].lang_code ), 0 ); p_es->i_stream_id = i_id; p_es->i_fourcc = VLC_FOURCC('l','p','c','b'); break; case 0x06: /* DTS */ i_id = ( ( 0x88 + i_position ) << 8 ) | 0xbd; msg_Err( p_input, "DTS audio not handled yet" "(0x%x)", i_id ); break; default: i_id = 0; msg_Err( p_input, "unknown audio type %.2x", p_vts->vtsi_mat->vts_audio_attr[i-1].audio_format ); } } }#undef audio_control#define spu_control \ p_dvd->p_vts_file->vts_pgcit->pgci_srp[pgc_id-1].pgc->subp_control[i-1] /* Sub Picture ES */ for( i = 1 ; i <= p_vts->vtsi_mat->nr_of_vts_subp_streams; i++ ) { int i_position = 0; uint16_t i_id;// IfoPrintSpu( p_dvd, i ); msg_Dbg( p_input, "spu %d 0x%02x", i, spu_control ); if( spu_control & 0x80000000 ) { i_spu_nb++; /* there are several streams for one spu */ if( p_vts->vtsi_mat->vts_video_attr.display_aspect_ratio ) { /* 16:9 */ switch( p_vts->vtsi_mat->vts_video_attr.permitted_df ) { case 1: i_position = spu_control & 0xff; break; case 2: i_position = ( spu_control >> 8 ) & 0xff; break; default: i_position = ( spu_control >> 16 ) & 0xff; break; } } else { /* 4:3 */ i_position = ( spu_control >> 24 ) & 0x7F; } i_id = ( ( 0x20 + i_position ) << 8 ) | 0xbd; p_es = input_AddES( p_input, NULL, i_id, SPU_ES, DecodeLanguage( p_vts->vtsi_mat->vts_subp_attr[i-1].lang_code ), 0 ); p_es->i_stream_id = 0xbd; p_es->i_fourcc = VLC_FOURCC('s','p','u','b'); } }#undef spu_control /* FIXME: hack to check that the demuxer is ready, and set * the decoders */ if( p_input->p_demux ) { DvdReadLauchDecoders( p_input ); } /* Update the navigation variables without triggering a callback */ val.i_int = p_area->i_id; var_Change( p_input, "title", VLC_VAR_SETVALUE, &val, NULL ); var_Change( p_input, "chapter", VLC_VAR_CLEARCHOICES, NULL, NULL ); for( i = 1; i <= p_area->i_part_nb; i++ ) { val.i_int = i; var_Change( p_input, "chapter", VLC_VAR_ADDCHOICE, &val, NULL ); } } /* i_title >= 0 */ else { p_area = p_input->stream.p_selected_area; } /* * Chapter selection */ if( p_area->i_part != p_dvd->i_chapter ) { if( ( p_area->i_part > 0 ) && ( p_area->i_part <= p_area->i_part_nb )) { p_dvd->i_ttn = p_vmg->tt_srpt->title[p_area->i_id-1].vts_ttn; pgc_id = p_vts->vts_ptt_srpt->title[ p_dvd->i_ttn-1].ptt[p_area->i_part-1].pgcn; pgn = p_vts->vts_ptt_srpt->title[ p_dvd->i_ttn-1].ptt[p_area->i_part-1].pgn; p_pgc = p_vts->vts_pgcit->pgci_srp[ pgc_id - 1 ].pgc; p_dvd->i_cur_cell = p_pgc->program_map[ pgn - 1 ] - 1; p_dvd->i_chapter = p_area->i_part; DvdReadFindCell( p_dvd ); p_dvd->i_pack_len = 0; p_dvd->i_next_vobu = p_dvd->i_cur_block = p_pgc->cell_playback[p_dvd->i_cur_cell].first_sector; } else { p_area->i_part = p_dvd->i_chapter; } }#undef p_vts#undef p_vmg /* warn interface that something has changed */ p_area->i_tell = LB2OFF( p_dvd->i_next_vobu ) - p_area->i_start; p_input->stream.b_seekable = VLC_TRUE; p_input->stream.b_changed = VLC_TRUE; /* Update the navigation variables without triggering a callback */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -