Commit 72550238 authored by Gildas Bazin's avatar Gildas Bazin

* modules/demux/dvdnav.c: added parsing of DVD style MRLs.
* modules/demux/ps.h: small cosmetic changes.
parent 279ac9b3
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* dvdnav.c: DVD module using the dvdnav library. * dvdnav.c: DVD module using the dvdnav library.
***************************************************************************** *****************************************************************************
* Copyright (C) 2004 VideoLAN * Copyright (C) 2004 VideoLAN
* $Id: dvdnav.c,v 1.2 2004/01/18 13:39:32 gbazin Exp $ * $Id: dvdnav.c,v 1.3 2004/01/18 16:02:40 gbazin Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -75,7 +75,8 @@ vlc_module_end(); ...@@ -75,7 +75,8 @@ vlc_module_end();
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
static ssize_t AccessRead ( input_thread_t *, byte_t *, size_t ); /* dummy */ static ssize_t AccessRead( input_thread_t *, byte_t *, size_t ); /* dummy */
static char *ParseCL( vlc_object_t *, char *, vlc_bool_t, int *, int *, int *);
typedef struct typedef struct
{ {
...@@ -120,10 +121,8 @@ struct demux_sys_t ...@@ -120,10 +121,8 @@ struct demux_sys_t
vlc_bool_t b_es_out_ok; vlc_bool_t b_es_out_ok;
}; };
static int DemuxControl( demux_t *, int, va_list ); static int DemuxControl( demux_t *, int, va_list );
static int DemuxDemux ( demux_t * ); static int DemuxDemux ( demux_t * );
static int DemuxBlock ( demux_t *, uint8_t *pkt, int i_pkt ); static int DemuxBlock ( demux_t *, uint8_t *pkt, int i_pkt );
enum enum
...@@ -147,24 +146,37 @@ static int AccessOpen( vlc_object_t *p_this ) ...@@ -147,24 +146,37 @@ static int AccessOpen( vlc_object_t *p_this )
{ {
input_thread_t *p_input = (input_thread_t *)p_this; input_thread_t *p_input = (input_thread_t *)p_this;
dvdnav_t *dvdnav; dvdnav_t *dvdnav;
int i_title, i_chapter, i_angle;
char *psz_name;
vlc_value_t val; vlc_value_t val;
vlc_bool_t b_force;
/* We try only if we are forced */ /* We try only if we are forced */
if( p_input->psz_demux && if( p_input->psz_demux && *p_input->psz_demux &&
*p_input->psz_demux &&
strcmp( p_input->psz_demux, "dvdnav" ) ) strcmp( p_input->psz_demux, "dvdnav" ) )
{ {
msg_Warn( p_input, "dvdnav access discarded (demuxer forced)" ); msg_Warn( p_input, "dvdnav access discarded (demuxer forced)" );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
b_force = (p_input->psz_access && !strcmp(p_input->psz_access, "dvdnav")) ?
VLC_TRUE : VLC_FALSE;
psz_name = ParseCL( VLC_OBJECT(p_input), p_input->psz_name, b_force,
&i_title, &i_chapter, &i_angle );
if( !psz_name )
{
return VLC_EGENERIC;
}
/* Test dvdnav */ /* Test dvdnav */
if( dvdnav_open( &dvdnav, p_input->psz_name ) != DVDNAV_STATUS_OK ) if( dvdnav_open( &dvdnav, psz_name ) != DVDNAV_STATUS_OK )
{ {
msg_Warn( p_input, "cannot open dvdnav" ); msg_Warn( p_input, "cannot open dvdnav" );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
dvdnav_close( dvdnav ); dvdnav_close( dvdnav );
free( psz_name );
/* Fill p_input fields */ /* Fill p_input fields */
p_input->pf_read = AccessRead; p_input->pf_read = AccessRead;
...@@ -209,6 +221,67 @@ static ssize_t AccessRead( input_thread_t *p_input, byte_t *p_buffer, ...@@ -209,6 +221,67 @@ static ssize_t AccessRead( input_thread_t *p_input, byte_t *p_buffer,
return i_len; return i_len;
} }
/*****************************************************************************
* ParseCL: parse command line
*****************************************************************************/
static char *ParseCL( vlc_object_t *p_this, char *psz_name, vlc_bool_t b_force,
int *i_title, int *i_chapter, int *i_angle )
{
char *psz_parser, *psz_source, *psz_next;
psz_source = strdup( psz_name );
if( psz_source == NULL ) return NULL;
*i_title = 0;
*i_chapter = 1;
*i_angle = 1;
/* Start with the end, because you could have :
* dvdnav:/Volumes/my@toto/VIDEO_TS@1,1
* (yes, this is kludgy). */
for( psz_parser = psz_source + strlen(psz_source) - 1;
psz_parser >= psz_source && *psz_parser != '@';
psz_parser-- );
if( psz_parser >= psz_source && *psz_parser == '@' )
{
/* Found options */
*psz_parser = '\0';
++psz_parser;
*i_title = (int)strtol( psz_parser, &psz_next, 10 );
if( *psz_next )
{
psz_parser = psz_next + 1;
*i_chapter = (int)strtol( psz_parser, &psz_next, 10 );
if( *psz_next )
{
*i_angle = (int)strtol( psz_next + 1, NULL, 10 );
}
}
}
*i_title = *i_title >= 0 ? *i_title : 0;
*i_chapter = *i_chapter ? *i_chapter : 1;
*i_angle = *i_angle ? *i_angle : 1;
if( !*psz_source )
{
free( psz_source );
if( !b_force )
{
return NULL;
}
psz_source = config_GetPsz( p_this, "dvd" );
if( !psz_source ) return NULL;
}
msg_Dbg( p_this, "dvdroot=%s title=%d chapter=%d angle=%d",
psz_source, *i_title, *i_chapter, *i_angle );
return psz_source;
}
/***************************************************************************** /*****************************************************************************
* DemuxOpen: * DemuxOpen:
*****************************************************************************/ *****************************************************************************/
...@@ -217,6 +290,8 @@ static int DemuxOpen( vlc_object_t *p_this ) ...@@ -217,6 +290,8 @@ static int DemuxOpen( vlc_object_t *p_this )
demux_t *p_demux = (demux_t*)p_this; demux_t *p_demux = (demux_t*)p_this;
demux_sys_t *p_sys; demux_sys_t *p_sys;
vlc_value_t val, text; vlc_value_t val, text;
int i_title, i_titles, i_chapter, i_chapters, i_angle, i;
char *psz_name;
if( strcmp( p_demux->psz_access, "dvdnav" ) || if( strcmp( p_demux->psz_access, "dvdnav" ) ||
strcmp( p_demux->psz_demux, "dvdnav" ) ) strcmp( p_demux->psz_demux, "dvdnav" ) )
...@@ -225,6 +300,13 @@ static int DemuxOpen( vlc_object_t *p_this ) ...@@ -225,6 +300,13 @@ static int DemuxOpen( vlc_object_t *p_this )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
psz_name = ParseCL( VLC_OBJECT(p_demux), p_demux->psz_path, VLC_TRUE,
&i_title, &i_chapter, &i_angle );
if( !psz_name )
{
return VLC_EGENERIC;
}
/* Init p_sys */ /* Init p_sys */
p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) ); p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
memset( p_sys, 0, sizeof( demux_sys_t ) ); memset( p_sys, 0, sizeof( demux_sys_t ) );
...@@ -238,11 +320,12 @@ static int DemuxOpen( vlc_object_t *p_this ) ...@@ -238,11 +320,12 @@ static int DemuxOpen( vlc_object_t *p_this )
p_sys->b_es_out_ok = VLC_FALSE; p_sys->b_es_out_ok = VLC_FALSE;
/* Open dvdnav */ /* Open dvdnav */
if( dvdnav_open( &p_sys->dvdnav, p_demux->psz_path ) != DVDNAV_STATUS_OK ) if( dvdnav_open( &p_sys->dvdnav, psz_name ) != DVDNAV_STATUS_OK )
{ {
msg_Warn( p_demux, "cannot open dvdnav" ); msg_Warn( p_demux, "cannot open dvdnav" );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
free( psz_name );
/* Configure dvdnav */ /* Configure dvdnav */
if( dvdnav_set_readahead_flag( p_sys->dvdnav, 1 ) != DVDNAV_STATUS_OK ) if( dvdnav_set_readahead_flag( p_sys->dvdnav, 1 ) != DVDNAV_STATUS_OK )
...@@ -267,6 +350,20 @@ static int DemuxOpen( vlc_object_t *p_this ) ...@@ -267,6 +350,20 @@ static int DemuxOpen( vlc_object_t *p_this )
dvdnav_err_to_string( p_sys->dvdnav ) ); dvdnav_err_to_string( p_sys->dvdnav ) );
} }
/* Find out number of titles/chapters */
dvdnav_get_number_of_titles( p_sys->dvdnav, &i_titles );
for( i = 1; i <= i_titles; i++ )
{
i_chapters = 0;
dvdnav_get_number_of_parts( p_sys->dvdnav, i, &i_chapters );
}
if( dvdnav_title_play( p_sys->dvdnav, i_title ) !=
DVDNAV_STATUS_OK )
{
msg_Warn( p_demux, "cannot set title/chapter" );
}
/* Get p_input and create variable */ /* Get p_input and create variable */
p_sys->p_input = p_sys->p_input =
vlc_object_find( p_demux, VLC_OBJECT_INPUT, FIND_ANYWHERE ); vlc_object_find( p_demux, VLC_OBJECT_INPUT, FIND_ANYWHERE );
...@@ -335,7 +432,6 @@ static void DemuxClose( vlc_object_t *p_this ) ...@@ -335,7 +432,6 @@ static void DemuxClose( vlc_object_t *p_this )
var_Destroy( p_sys->p_input, "color" ); var_Destroy( p_sys->p_input, "color" );
var_Destroy( p_sys->p_input, "contrast" ); var_Destroy( p_sys->p_input, "contrast" );
vlc_object_release( p_sys->p_input ); vlc_object_release( p_sys->p_input );
dvdnav_close( p_sys->dvdnav ); dvdnav_close( p_sys->dvdnav );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ps.h: Program Stream demuxer helper * ps.h: Program Stream demuxer helper
***************************************************************************** *****************************************************************************
* Copyright (C) 2004 VideoLAN * Copyright (C) 2004 VideoLAN
* $Id: ps.h,v 1.2 2004/01/17 23:51:50 fenrir Exp $ * $Id: ps.h,v 1.3 2004/01/18 16:02:40 gbazin Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -53,31 +53,31 @@ static inline int ps_track_fill( ps_track_t *tk, int i_id ) ...@@ -53,31 +53,31 @@ static inline int ps_track_fill( ps_track_t *tk, int i_id )
{ {
if( ( i_id&0xf8 ) == 0x88 ) if( ( i_id&0xf8 ) == 0x88 )
{ {
es_format_Init( &tk->fmt, AUDIO_ES, VLC_FOURCC( 'd', 't', 's', ' ' ) ); es_format_Init( &tk->fmt, AUDIO_ES, VLC_FOURCC('d','t','s',' ') );
tk->i_skip = 1; tk->i_skip = 1;
} }
else if( ( i_id&0xf0 ) == 0x80 ) else if( ( i_id&0xf0 ) == 0x80 )
{ {
es_format_Init( &tk->fmt, AUDIO_ES, VLC_FOURCC( 'a', '5', '2', ' ' ) ); es_format_Init( &tk->fmt, AUDIO_ES, VLC_FOURCC('a','5','2',' ') );
tk->i_skip = 4; tk->i_skip = 4;
} }
else if( ( i_id&0xe0 ) == 0x20 ) else if( ( i_id&0xe0 ) == 0x20 )
{ {
es_format_Init( &tk->fmt, SPU_ES, VLC_FOURCC( 's', 'p', 'u', ' ' ) ); es_format_Init( &tk->fmt, SPU_ES, VLC_FOURCC('s','p','u',' ') );
tk->i_skip = 1; tk->i_skip = 1;
} }
else if( ( i_id&0xf0 ) == 0xa0 ) else if( ( i_id&0xf0 ) == 0xa0 )
{ {
es_format_Init( &tk->fmt, AUDIO_ES, VLC_FOURCC( 'l', 'p', 'c', 'm' ) ); es_format_Init( &tk->fmt, AUDIO_ES, VLC_FOURCC('l','p','c','m') );
tk->i_skip = 1; tk->i_skip = 1;
} }
else if( ( i_id&0xff ) == 0x70 ) else if( ( i_id&0xff ) == 0x70 )
{ {
es_format_Init( &tk->fmt, SPU_ES, VLC_FOURCC( 'o', 'g', 't', ' ' ) ); es_format_Init( &tk->fmt, SPU_ES, VLC_FOURCC('o','g','t',' ') );
} }
else if( ( i_id&0xfc ) == 0x00 ) else if( ( i_id&0xfc ) == 0x00 )
{ {
es_format_Init( &tk->fmt, SPU_ES, VLC_FOURCC( 'c', 'v', 'd', ' ' ) ); es_format_Init( &tk->fmt, SPU_ES, VLC_FOURCC('c','v','d',' ') );
} }
else else
{ {
...@@ -89,11 +89,11 @@ static inline int ps_track_fill( ps_track_t *tk, int i_id ) ...@@ -89,11 +89,11 @@ static inline int ps_track_fill( ps_track_t *tk, int i_id )
{ {
if( ( i_id&0xf0 ) == 0xe0 ) if( ( i_id&0xf0 ) == 0xe0 )
{ {
es_format_Init( &tk->fmt, VIDEO_ES, VLC_FOURCC( 'm', 'p', 'g', 'v' ) ); es_format_Init( &tk->fmt, VIDEO_ES, VLC_FOURCC('m','p','g','v') );
} }
else if( ( i_id&0xe0 ) == 0xc0 ) else if( ( i_id&0xe0 ) == 0xc0 )
{ {
es_format_Init( &tk->fmt, AUDIO_ES, VLC_FOURCC( 'm', 'p', 'g', 'a' ) ); es_format_Init( &tk->fmt, AUDIO_ES, VLC_FOURCC('m','p','g','a') );
} }
else else
{ {
...@@ -145,7 +145,8 @@ static inline int ps_pkt_size( uint8_t *p, int i_peek ) ...@@ -145,7 +145,8 @@ static inline int ps_pkt_size( uint8_t *p, int i_peek )
} }
/* parse a PACK PES */ /* parse a PACK PES */
static inline int ps_pkt_parse_pack( block_t *p_pkt, int64_t *pi_scr, int *pi_mux_rate ) static inline int ps_pkt_parse_pack( block_t *p_pkt, int64_t *pi_scr,
int *pi_mux_rate )
{ {
uint8_t *p = p_pkt->p_buffer; uint8_t *p = p_pkt->p_buffer;
if( p_pkt->i_buffer >= 14 && (p[4] >> 6) == 0x01 ) if( p_pkt->i_buffer >= 14 && (p[4] >> 6) == 0x01 )
...@@ -178,7 +179,8 @@ static inline int ps_pkt_parse_pack( block_t *p_pkt, int64_t *pi_scr, int *pi_mu ...@@ -178,7 +179,8 @@ static inline int ps_pkt_parse_pack( block_t *p_pkt, int64_t *pi_scr, int *pi_mu
} }
/* Parse a SYSTEM PES */ /* Parse a SYSTEM PES */
static inline int ps_pkt_parse_system( block_t *p_pkt, ps_track_t tk[PS_TK_COUNT] ) static inline int ps_pkt_parse_system( block_t *p_pkt,
ps_track_t tk[PS_TK_COUNT] )
{ {
uint8_t *p = &p_pkt->p_buffer[6 + 3 + 1 + 1 + 1]; uint8_t *p = &p_pkt->p_buffer[6 + 3 + 1 + 1 + 1];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment