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 @@
* dvdnav.c: DVD module using the dvdnav library.
*****************************************************************************
* 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>
*
......@@ -75,7 +75,8 @@ vlc_module_end();
/*****************************************************************************
* 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
{
......@@ -120,10 +121,8 @@ struct demux_sys_t
vlc_bool_t b_es_out_ok;
};
static int DemuxControl( demux_t *, int, va_list );
static int DemuxDemux ( demux_t * );
static int DemuxBlock ( demux_t *, uint8_t *pkt, int i_pkt );
enum
......@@ -147,24 +146,37 @@ static int AccessOpen( vlc_object_t *p_this )
{
input_thread_t *p_input = (input_thread_t *)p_this;
dvdnav_t *dvdnav;
int i_title, i_chapter, i_angle;
char *psz_name;
vlc_value_t val;
vlc_bool_t b_force;
/* We try only if we are forced */
if( p_input->psz_demux &&
*p_input->psz_demux &&
if( p_input->psz_demux && *p_input->psz_demux &&
strcmp( p_input->psz_demux, "dvdnav" ) )
{
msg_Warn( p_input, "dvdnav access discarded (demuxer forced)" );
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 */
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" );
return VLC_EGENERIC;
}
dvdnav_close( dvdnav );
free( psz_name );
/* Fill p_input fields */
p_input->pf_read = AccessRead;
......@@ -209,6 +221,67 @@ static ssize_t AccessRead( input_thread_t *p_input, byte_t *p_buffer,
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:
*****************************************************************************/
......@@ -217,6 +290,8 @@ static int DemuxOpen( vlc_object_t *p_this )
demux_t *p_demux = (demux_t*)p_this;
demux_sys_t *p_sys;
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" ) ||
strcmp( p_demux->psz_demux, "dvdnav" ) )
......@@ -225,6 +300,13 @@ static int DemuxOpen( vlc_object_t *p_this )
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 */
p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
memset( p_sys, 0, sizeof( demux_sys_t ) );
......@@ -238,11 +320,12 @@ static int DemuxOpen( vlc_object_t *p_this )
p_sys->b_es_out_ok = VLC_FALSE;
/* 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" );
return VLC_EGENERIC;
}
free( psz_name );
/* Configure dvdnav */
if( dvdnav_set_readahead_flag( p_sys->dvdnav, 1 ) != DVDNAV_STATUS_OK )
......@@ -267,6 +350,20 @@ static int DemuxOpen( vlc_object_t *p_this )
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 */
p_sys->p_input =
vlc_object_find( p_demux, VLC_OBJECT_INPUT, FIND_ANYWHERE );
......@@ -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, "contrast" );
vlc_object_release( p_sys->p_input );
dvdnav_close( p_sys->dvdnav );
......
......@@ -2,7 +2,7 @@
* ps.h: Program Stream demuxer helper
*****************************************************************************
* 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>
*
......@@ -53,31 +53,31 @@ static inline int ps_track_fill( ps_track_t *tk, int i_id )
{
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;
}
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;
}
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;
}
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;
}
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 )
{
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
{
......@@ -89,11 +89,11 @@ static inline int ps_track_fill( ps_track_t *tk, int i_id )
{
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 )
{
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
{
......@@ -145,7 +145,8 @@ static inline int ps_pkt_size( uint8_t *p, int i_peek )
}
/* 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;
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
}
/* 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];
......
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