📄 access.c
字号:
/***************************************************************************** * access.c: access capabilities for dvdplay plugin. ***************************************************************************** * Copyright (C) 2001 VideoLAN * $Id: access.c,v 1.19 2003/08/13 01:45:13 gbazin Exp $ * * Author: St閜hane Borel <stef@via.ecp.fr> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include <stdio.h>#include <stdlib.h>#include <vlc/vlc.h>#include <vlc/input.h>#include "../../demux/mpeg/system.h"#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#include <fcntl.h>#include <sys/types.h>#include <string.h>#include <errno.h>#ifdef STRNCASECMP_IN_STRINGS_H# include <strings.h>#endif#include "dvd.h"#include "es.h"#include "tools.h"#include "intf.h"/***************************************************************************** * Local prototypes *****************************************************************************//* called from outside */static int dvdplay_SetArea ( input_thread_t *, input_area_t * );static int dvdplay_SetProgram ( input_thread_t *, pgrm_descriptor_t * );static ssize_t dvdplay_Read ( input_thread_t *, byte_t *, size_t );static void dvdplay_Seek ( input_thread_t *, off_t );static void pf_vmg_callback ( void*, dvdplay_event_t );/* only from inside */static int dvdNewArea( input_thread_t *, input_area_t * );static int dvdNewPGC ( input_thread_t * );static int MenusCallback( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * );/***************************************************************************** * OpenDVD: open libdvdplay *****************************************************************************/int E_(OpenDVD) ( vlc_object_t *p_this ){ input_thread_t * p_input = (input_thread_t *)p_this; char * psz_source; dvd_data_t * p_dvd; input_area_t * p_area; unsigned int i_title_nr; unsigned int i_title; unsigned int i_chapter; unsigned int i_angle; unsigned int i; vlc_value_t val, text; p_dvd = malloc( sizeof(dvd_data_t) ); if( p_dvd == NULL ) { msg_Err( p_input, "out of memory" ); return -1; } p_input->p_access_data = (void *)p_dvd; p_input->pf_read = dvdplay_Read; p_input->pf_seek = dvdplay_Seek; p_input->pf_set_area = dvdplay_SetArea; p_input->pf_set_program = dvdplay_SetProgram; /* command line */ if( ( psz_source = dvdplay_ParseCL( p_input, &i_title, &i_chapter, &i_angle ) ) == NULL ) { free( p_dvd ); return -1; } /* Open libdvdplay */ p_dvd->vmg = dvdplay_open( psz_source, pf_vmg_callback, (void*)p_input ); if( p_dvd->vmg == NULL ) { msg_Warn( p_input, "cannot open %s", psz_source ); free( psz_source ); free( p_dvd ); return -1; } /* free allocated strings */ free( psz_source ); p_dvd->p_intf = NULL; p_dvd->i_still_time = 0; /* set up input */ p_input->i_mtu = 0; /* Set stream and area data */ vlc_mutex_lock( &p_input->stream.stream_lock ); /* If we are here we can control the pace... */ p_input->stream.b_pace_control = 1; /* seek is only allowed when we have size info */ p_input->stream.b_seekable = 0; /* Initialize ES structures */ input_InitStream( p_input, sizeof( stream_ps_data_t ) ); /* disc input method */ p_input->stream.i_method = INPUT_METHOD_DVD; i_title_nr = dvdplay_title_nr( p_dvd->vmg );#define area p_input->stream.pp_areas /* Area 0 for menu */ area[0]->i_plugin_data = 0; input_DelArea( p_input, p_input->stream.pp_areas[0] ); input_AddArea( p_input, 0, 1 ); for( i = 1 ; i <= i_title_nr ; i++ ) { input_AddArea( p_input, i, dvdplay_chapter_nr( p_dvd->vmg, i ) ); area[i]->i_plugin_data = 0; }#undef area msg_Dbg( p_input, "number of titles: %d", i_title_nr ); i_title = i_title <= i_title_nr ? i_title : 0; p_area = p_input->stream.pp_areas[i_title]; p_area->i_part = i_chapter; p_input->stream.p_selected_area = NULL; /* set title, chapter, audio and subpic */ if( dvdplay_SetArea( p_input, p_area ) ) { vlc_mutex_unlock( &p_input->stream.stream_lock ); return -1; } if( i_angle <= p_input->stream.i_pgrm_number ) { dvdplay_SetProgram( p_input, p_input->stream.pp_programs[i_angle - 1] ); } vlc_mutex_unlock( &p_input->stream.stream_lock ); if( !p_input->psz_demux || !*p_input->psz_demux ) { p_input->psz_demux = "dvdplay"; } /* FIXME: we might lose variables here */ var_Create( p_input, "x-start", VLC_VAR_INTEGER ); var_Create( p_input, "y-start", VLC_VAR_INTEGER ); var_Create( p_input, "x-end", VLC_VAR_INTEGER ); var_Create( p_input, "y-end", VLC_VAR_INTEGER ); var_Create( p_input, "color", VLC_VAR_ADDRESS ); var_Create( p_input, "contrast", VLC_VAR_ADDRESS ); var_Create( p_input, "highlight", VLC_VAR_BOOL ); var_Create( p_input, "highlight-mutex", VLC_VAR_MUTEX ); /* Create a few object variables used for navigation in the interfaces */ var_Create( p_input, "dvd_menus", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE | VLC_VAR_ISCOMMAND ); text.psz_string = _("DVD menus"); var_Change( p_input, "dvd_menus", VLC_VAR_SETTEXT, &text, NULL ); var_AddCallback( p_input, "dvd_menus", MenusCallback, NULL ); val.i_int = ROOT_MENU; text.psz_string = _("Root"); var_Change( p_input, "dvd_menus", VLC_VAR_ADDCHOICE, &val, &text ); val.i_int = TITLE_MENU; text.psz_string = _("Title"); var_Change( p_input, "dvd_menus", VLC_VAR_ADDCHOICE, &val, &text ); val.i_int = PART_MENU; text.psz_string = _("Chapter"); var_Change( p_input, "dvd_menus", VLC_VAR_ADDCHOICE, &val, &text ); val.i_int = SUBPICTURE_MENU; text.psz_string = _("Subtitle"); var_Change( p_input, "dvd_menus", VLC_VAR_ADDCHOICE, &val, &text ); val.i_int = AUDIO_MENU; text.psz_string = _("Audio"); var_Change( p_input, "dvd_menus", VLC_VAR_ADDCHOICE, &val, &text ); val.i_int = ANGLE_MENU; text.psz_string = _("Angle"); var_Change( p_input, "dvd_menus", VLC_VAR_ADDCHOICE, &val, &text ); val.i_int = 99; text.psz_string = _("Resume"); var_Change( p_input, "dvd_menus", VLC_VAR_ADDCHOICE, &val, &text ); return 0;}/***************************************************************************** * CloseDVD: close libdvdplay *****************************************************************************/void E_(CloseDVD) ( vlc_object_t *p_this ){ input_thread_t * p_input = (input_thread_t *)p_this; dvd_data_t * p_dvd = (dvd_data_t *)p_input->p_access_data; var_Destroy( p_input, "highlight-mutex" ); var_Destroy( p_input, "highlight" ); var_Destroy( p_input, "x-start" ); var_Destroy( p_input, "x-end" ); var_Destroy( p_input, "y-start" ); var_Destroy( p_input, "y-end" ); var_Destroy( p_input, "color" ); var_Destroy( p_input, "contrast" ); /* close libdvdplay */ dvdplay_close( p_dvd->vmg ); free( p_dvd ); p_input->p_access_data = NULL;}/***************************************************************************** * dvdplay_SetProgram: set dvd angle. ***************************************************************************** * This is actually a hack to make angle change through vlc interface with * no need for a specific button. *****************************************************************************/static int dvdplay_SetProgram( input_thread_t * p_input, pgrm_descriptor_t * p_program ){ if( p_input->stream.p_selected_program != p_program ) { dvd_data_t * p_dvd; int i_angle; vlc_value_t val; p_dvd = (dvd_data_t*)(p_input->p_access_data); i_angle = p_program->i_number; if( !dvdplay_angle( p_dvd->vmg, i_angle ) ) { memcpy( p_program, p_input->stream.p_selected_program, sizeof(pgrm_descriptor_t) ); p_program->i_number = i_angle; p_input->stream.p_selected_program = p_program; msg_Dbg( p_input, "angle %d selected", 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 0;}/***************************************************************************** * dvdplay_SetArea: 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 dvdplay_SetArea( input_thread_t * p_input, input_area_t * p_area ){ dvd_data_t * p_dvd; vlc_value_t val; p_dvd = (dvd_data_t*)p_input->p_access_data; /* * Title selection */ if( p_area != p_input->stream.p_selected_area ) { int i_chapter; /* prevent intf to try to seek */ p_input->stream.b_seekable = 0; /* Store selected chapter */ i_chapter = p_area->i_part; dvdNewArea( p_input, p_area );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -