X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faccess%2Fdvdnav.c;h=8a67a835107771eb11e3a4a0052bba3ea832bb6a;hb=2b9b5c0c6b7a9de32d5a42755f648d5194afaf13;hp=46e66abdeb45f82f0d011a62e3d8392eeea2717c;hpb=543a14198e2fa2367468864f2c3d6df91e18c21c;p=vlc diff --git a/modules/access/dvdnav.c b/modules/access/dvdnav.c index 46e66abdeb..8a67a83510 100644 --- a/modules/access/dvdnav.c +++ b/modules/access/dvdnav.c @@ -83,22 +83,23 @@ static int Open ( vlc_object_t * ); static void Close( vlc_object_t * ); -vlc_module_begin(); - set_shortname( N_("DVD with menus") ); - set_description( N_("DVDnav Input") ); - set_category( CAT_INPUT ); - set_subcategory( SUBCAT_INPUT_ACCESS ); +vlc_module_begin () + set_shortname( N_("DVD with menus") ) + set_description( N_("DVDnav Input") ) + set_category( CAT_INPUT ) + set_subcategory( SUBCAT_INPUT_ACCESS ) add_integer( "dvdnav-angle", 1, NULL, ANGLE_TEXT, - ANGLE_LONGTEXT, false ); + ANGLE_LONGTEXT, false ) add_integer( "dvdnav-caching", DEFAULT_PTS_DELAY / 1000, NULL, - CACHING_TEXT, CACHING_LONGTEXT, true ); + CACHING_TEXT, CACHING_LONGTEXT, true ) add_bool( "dvdnav-menu", true, NULL, - MENU_TEXT, MENU_LONGTEXT, false ); - set_capability( "access_demux", 5 ); - add_shortcut( "dvd" ); - add_shortcut( "dvdnav" ); - set_callbacks( Open, Close ); -vlc_module_end(); + MENU_TEXT, MENU_LONGTEXT, false ) + set_capability( "access_demux", 5 ) + add_shortcut( "dvd" ) + add_shortcut( "dvdnav" ) + add_shortcut( "file" ) + set_callbacks( Open, Close ) +vlc_module_end () /* Shall we use libdvdnav's read ahead cache? */ #define DVD_READ_CACHE 1 @@ -166,6 +167,8 @@ static int ProbeDVD( demux_t *, char * ); static char *DemuxGetLanguageCode( demux_t *p_demux, const char *psz_var ); +static int ControlInternal( demux_t *, int, ... ); + /***************************************************************************** * DemuxOpen: *****************************************************************************/ @@ -254,15 +257,19 @@ static int Open( vlc_object_t *p_this ) msg_Warn( p_demux, "cannot set PGC positioning flag" ); } - /* Set menu language ("en") - * XXX: maybe it would be better to set it like audio/spu - * or to create a --menu-language option */ - if( dvdnav_menu_language_select( p_sys->dvdnav, (char*)LANGUAGE_DEFAULT ) != + /* Set menu language + * XXX A menu-language may be better than sub-language */ + psz_code = DemuxGetLanguageCode( p_demux, "sub-language" ); + if( dvdnav_menu_language_select( p_sys->dvdnav, psz_code ) != DVDNAV_STATUS_OK ) { msg_Warn( p_demux, "can't set menu language to '%s' (%s)", - LANGUAGE_DEFAULT, dvdnav_err_to_string( p_sys->dvdnav ) ); + psz_code, dvdnav_err_to_string( p_sys->dvdnav ) ); + /* We try to fall back to 'en' */ + if( strcmp( psz_code, LANGUAGE_DEFAULT ) ) + dvdnav_menu_language_select( p_sys->dvdnav, (char*)LANGUAGE_DEFAULT ); } + free( psz_code ); /* Set audio language */ psz_code = DemuxGetLanguageCode( p_demux, "audio-language" ); @@ -303,7 +310,7 @@ static int Open( vlc_object_t *p_this ) msg_Err( p_demux, "cannot set title (can't decrypt DVD?)" ); intf_UserFatal( p_demux, false, _("Playback failure"), _("VLC cannot set the DVD's title. It possibly " - "cannot decrypt the entire disk.") ); + "cannot decrypt the entire disc.") ); dvdnav_close( p_sys->dvdnav ); free( p_sys ); return VLC_EGENERIC; @@ -342,7 +349,7 @@ static int Open( vlc_object_t *p_this ) p_sys->p_ev = vlc_object_create( p_demux, sizeof( event_thread_t ) ); p_sys->p_ev->p_demux = p_demux; vlc_thread_create( p_sys->p_ev, "dvdnav event thread handler", EventThread, - VLC_THREAD_PRIORITY_LOW, false ); + VLC_THREAD_PRIORITY_LOW ); return VLC_SUCCESS; } @@ -566,6 +573,17 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) } } +static int ControlInternal( demux_t *p_demux, int i_query, ... ) +{ + va_list args; + int i_result; + + va_start( args, i_query ); + i_result = Control( p_demux, i_query, args ); + va_end( args ); + + return i_result; +} /***************************************************************************** * Demux: *****************************************************************************/ @@ -588,12 +606,18 @@ static int Demux( demux_t *p_demux ) { msg_Warn( p_demux, "cannot get next block (%s)", dvdnav_err_to_string( p_sys->dvdnav ) ); + if( p_demux->info.i_title == 0 ) + { + msg_Dbg( p_demux, "jumping to first title" ); + return ControlInternal( p_demux, DEMUX_SET_TITLE, 1 ) == VLC_SUCCESS ? 1 : -1; + } return -1; } switch( i_event ) { case DVDNAV_BLOCK_OK: /* mpeg block */ + p_sys->p_ev->b_still = false; DemuxBlock( p_demux, packet, i_len ); break; @@ -603,19 +627,18 @@ static int Demux( demux_t *p_demux ) case DVDNAV_STILL_FRAME: { - /* We send a dummy mpeg2 end of sequence to force still frame display */ - static const uint8_t buffer[] = { - 0x00, 0x00, 0x01, 0xe0, 0x00, 0x07, - 0x80, 0x00, 0x00, - 0x00, 0x00, 0x01, 0xB7, - }; - DemuxBlock( p_demux, buffer, sizeof(buffer) ); - - /* */ dvdnav_still_event_t *event = (dvdnav_still_event_t*)packet; vlc_mutex_lock( &p_sys->p_ev->lock ); if( !p_sys->p_ev->b_still ) { + /* We send a dummy mpeg2 end of sequence to force still frame display */ + static const uint8_t buffer[] = { + 0x00, 0x00, 0x01, 0xe0, 0x00, 0x07, + 0x80, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xB7, + }; + DemuxBlock( p_demux, buffer, sizeof(buffer) ); + msg_Dbg( p_demux, "DVDNAV_STILL_FRAME" ); msg_Dbg( p_demux, " - length=0x%x", event->length ); p_sys->p_ev->b_still = true; @@ -626,7 +649,7 @@ static int Demux( demux_t *p_demux ) else { p_sys->p_ev->i_still_end = (int64_t)event->length * - 1000000 + mdate() + p_sys->p_input->i_pts_delay; + 1000000 + mdate(); } } vlc_mutex_unlock( &p_sys->p_ev->lock ); @@ -837,12 +860,18 @@ static char *DemuxGetLanguageCode( demux_t *p_demux, const char *psz_var ) char *p; psz_lang = var_CreateGetString( p_demux, psz_var ); + if( !psz_lang ) + return strdup(LANGUAGE_DEFAULT); + /* XXX: we will use only the first value * (and ignore other ones in case of a list) */ - if( ( p = strchr( psz_lang, ',' ) ) ) *p = '\0'; + if( ( p = strchr( psz_lang, ',' ) ) ) + *p = '\0'; for( pl = p_languages; pl->psz_iso639_1 != NULL; pl++ ) { + if( *psz_lang == '\0' ) + continue; if( !strcasecmp( pl->psz_eng_name, psz_lang ) || !strcasecmp( pl->psz_native_name, psz_lang ) || !strcasecmp( pl->psz_iso639_1, psz_lang ) || @@ -1143,7 +1172,10 @@ static void ESNew( demux_t *p_demux, int i_id ) { switch( p_sys->i_aspect ) { - /* TODO Any docs somewhere ? */ + case 1: tk->fmt.video.i_aspect = VOUT_ASPECT_FACTOR; break; + case 2: tk->fmt.video.i_aspect = VOUT_ASPECT_FACTOR * 4 / 3; break; + case 3: tk->fmt.video.i_aspect = VOUT_ASPECT_FACTOR * 16 / 9; break; + case 4: tk->fmt.video.i_aspect = VOUT_ASPECT_FACTOR * 221 / 10; break; default: tk->fmt.video.i_aspect = 0; break; @@ -1242,6 +1274,8 @@ static void* EventThread( vlc_object_t *p_this ) p_ev->i_key_action = 0; p_ev->b_still = false; + int canc = vlc_savecancel (); + /* catch all key event */ var_AddCallback( p_ev->p_libvlc, "key-action", EventKey, p_ev ); @@ -1352,7 +1386,7 @@ static void* EventThread( vlc_object_t *p_this ) vlc_object_release( p_vout ); } var_DelCallback( p_ev->p_libvlc, "key-action", EventKey, p_ev ); - + vlc_restorecancel (canc); vlc_mutex_destroy( &p_ev->lock ); return NULL; @@ -1394,7 +1428,6 @@ static int ProbeDVD( demux_t *p_demux, char *psz_name ) #ifdef HAVE_SYS_STAT_H struct stat stat_info; uint8_t pi_anchor[2]; - uint16_t i_tag_id = 0; int i_fd, i_ret; if( !*psz_name ) @@ -1403,34 +1436,23 @@ static int ProbeDVD( demux_t *p_demux, char *psz_name ) return VLC_SUCCESS; } - if( stat( psz_name, &stat_info ) || !S_ISREG( stat_info.st_mode ) ) - { - /* Let dvdnav_open() do the probing */ - return VLC_SUCCESS; - } - if( (i_fd = open( psz_name, O_RDONLY )) == -1 ) { - /* Let dvdnav_open() do the probing */ - return VLC_SUCCESS; + return VLC_SUCCESS; /* Let dvdnav_open() do the probing */ } - /* Try to find the anchor (2 bytes at LBA 256) */ - i_ret = VLC_SUCCESS; - if( lseek( i_fd, 256 * DVD_VIDEO_LB_LEN, SEEK_SET ) == -1 ) + if( fstat( i_fd, &stat_info ) || !S_ISREG( stat_info.st_mode ) ) { - i_ret = VLC_EGENERIC; + close( i_fd ); + return VLC_SUCCESS; /* Let dvdnav_open() do the probing */ } - if( read( i_fd, pi_anchor, 2 ) == 2 ) - { - i_tag_id = GetWLE(pi_anchor); - if( i_tag_id != 2 ) i_ret = VLC_EGENERIC; /* Not an anchor */ - } - else - { - i_ret = VLC_EGENERIC; - } + /* Try to find the anchor (2 bytes at LBA 256) */ + i_ret = VLC_EGENERIC; + if( lseek( i_fd, 256 * DVD_VIDEO_LB_LEN, SEEK_SET ) != -1 + && read( i_fd, pi_anchor, 2 ) == 2 + && GetWLE( pi_anchor ) == 2 ) + i_ret = VLC_SUCCESS; /* Found a potential anchor */ close( i_fd );