Commit 55ce4df1 authored by Stéphane Borel's avatar Stéphane Borel

*Removed an occurance of former angle item in gtk.

*Fixed a bug in ES management introduced lately in DVD/DvdRead.

*Beginning of reorganisation in DVD plugin source files, in order to try to
make it easier to understand. There is some work left though :p.

*Decreased the score for VCD plugin, as the VCD demuxer was used even
for DVD :p. It should make autodetection work.
Some comment:
-I think that VCDInit should make a test on the access plugin and be launched
only if the access plugin is VCD,
-VCDOpen shouldn't set p_input->b_error: if it fails we just try another
module,
-PSRead doesn't need to be duplicated anymore: input_ReadPS is now available
for plugins (cf Christophe's commit).

Please comment around that: I'd like to know if the behaviour I've described
is the one everyone expects.

Enjoy my new bugs :p
parent 0a3aa895
...@@ -33,7 +33,7 @@ recognizes several URL-style items: ...@@ -33,7 +33,7 @@ recognizes several URL-style items:
.B *.mpg, *.vob .B *.mpg, *.vob
Plain MPEG-1/2 files Plain MPEG-1/2 files
.TP .TP
.B dvd:<device>[@<raw device>] .B dvd:[<device>][@<raw device>][@[<title>][,[<chapter>][,<angle>]]]
DVD device (for instance dvd:/dev/dvd). The raw device is optional and DVD device (for instance dvd:/dev/dvd). The raw device is optional and
must have been prepared beforehands. must have been prepared beforehands.
.TP .TP
...@@ -140,35 +140,19 @@ displaying of all images. ...@@ -140,35 +140,19 @@ displaying of all images.
Note that vlc is not guaranteed to behave properly if you ask it to Note that vlc is not guaranteed to behave properly if you ask it to
display more images than your CPU can cope with. display more images than your CPU can cope with.
.TP .TP
.B \-t, \-\-dvdtitle <title> .B \-a, \-\-input_audio [ ac3 | lpcm | mpeg | off ]
Choose the DVD title. Most movies on DVDs start on the first title, but you may want to manually select another title.
.TP
.B \-T, \-\-dvdchapter <title>
Choose the DVD chapter. DVDs are divided into titles, which in turn are divided into chapters.
.TP
.B \-a, \-\-dvdaudio [ ac3 | lpcm | mpeg | off ]
Choose the audio channel type. Most DVDs have AC3 audio channels, but Choose the audio channel type. Most DVDs have AC3 audio channels, but
you can also have Linear PCM or MPEG layer 2 sound. Also, one might decide you can also have Linear PCM or MPEG layer 2 sound. Also, one might decide
not to activate the audio channel. not to activate the audio channel.
.TP .TP
.B \-u, \-\-dvdangle <num> .B \-c, \-\-input_channel [ 0\-15 ]
Choose the angle, available on some DVDs.
.TP
.B \-c, \-\-dvdchannel [ 0\-15 ]
Select the audio channel. Most DVDs only have one or two audio channels, Select the audio channel. Most DVDs only have one or two audio channels,
but some of them have a great number of available languages. Note that the but some of them have a great number of available languages. Note that the
audio channel will also depend on the channel type. audio channel will also depend on the channel type.
.TP .TP
.B \-s, \-\-dvdsubtitle [ 0\-31 ] .B \-s, \-\-input_subtitle [ 0\-31 ]
Select the subtitle channel, if there is one in the stream. Select the subtitle channel, if there is one in the stream.
.TP .TP
.B \-\-dvdcss-method <method>
Select the CSS decryption scheme when using libdvdcss. Usually to choose
from "disc", "title" or "key", but depends on your libdvdcss version.
.TP
.B \-\-dvdcss-verbose <level>
Select the CSS decryption verbosity level, 0, 1 or 2.
.TP
.B \-\-input <method> .B \-\-input <method>
Choose the input method, "dvd", "ps", "ts" for instance. Choose the input method, "dvd", "ps", "ts" for instance.
.TP .TP
......
dvd_SOURCES = dvd.c input_dvd.c dvd_ifo.c dvd_udf.c dvd_summary.c $(SRC_DVD_EXTRA) dvd_SOURCES = dvd.c dvd_access.c dvd_demux.c dvd_seek.c dvd_es.c dvd_ifo.c dvd_udf.c dvd_summary.c $(SRC_DVD_EXTRA)
EXTRA_DEP = ../../lib/libdvdcss.a ../../lib/libdvdcss.so EXTRA_DEP = ../../lib/libdvdcss.a ../../lib/libdvdcss.so
......
/***************************************************************************** /*****************************************************************************
* input_dvd.h: thread structure of the DVD plugin * dvd.h: thread structure of the DVD plugin
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: input_dvd.h,v 1.25 2002/03/01 01:12:28 stef Exp $ * $Id: dvd.h,v 1.1 2002/03/06 01:20:56 stef Exp $
* *
* Author: Stéphane Borel <stef@via.ecp.fr> * Author: Stéphane Borel <stef@via.ecp.fr>
* *
...@@ -36,6 +36,9 @@ typedef struct thread_dvd_data_s ...@@ -36,6 +36,9 @@ typedef struct thread_dvd_data_s
{ {
dvdcss_handle dvdhandle; /* libdvdcss handle */ dvdcss_handle dvdhandle; /* libdvdcss handle */
int i_audio_nb;
int i_spu_nb;
/* Navigation information */ /* Navigation information */
int i_title; int i_title;
int i_title_id; int i_title_id;
...@@ -57,9 +60,6 @@ typedef struct thread_dvd_data_s ...@@ -57,9 +60,6 @@ typedef struct thread_dvd_data_s
int i_start; int i_start;
int i_size; int i_size;
/* Scrambling Information */
struct css_s * p_css;
/* Structure that contains all information of the DVD */ /* Structure that contains all information of the DVD */
struct ifo_s * p_ifo; struct ifo_s * p_ifo;
......
/* input_dvd.c: DVD raw reading plugin. /* dvd_access.c: DVD access plugin.
***************************************************************************** *****************************************************************************
* This plugins should handle all the known specificities of the DVD format, * This plugins should handle all the known specificities of the DVD format,
* especially the 2048 bytes logical block size. * especially the 2048 bytes logical block size.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* -dvd_udf to find files * -dvd_udf to find files
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * Copyright (C) 1998-2001 VideoLAN
* $Id: input_dvd.c,v 1.132 2002/03/05 17:46:33 stef Exp $ * $Id: dvd_access.c,v 1.1 2002/03/06 01:20:56 stef Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -50,10 +50,6 @@ ...@@ -50,10 +50,6 @@
# include <strings.h> # include <strings.h>
#endif #endif
#if defined( WIN32 )
# include <io.h> /* read() */
#endif
#ifdef GOD_DAMN_DMCA #ifdef GOD_DAMN_DMCA
# include "dummy_dvdcss.h" # include "dummy_dvdcss.h"
#else #else
...@@ -65,16 +61,15 @@ ...@@ -65,16 +61,15 @@
#include "input_ext-dec.h" #include "input_ext-dec.h"
#include "input_ext-plugins.h" #include "input_ext-plugins.h"
#include "input_dvd.h" #include "dvd.h"
#include "dvd_es.h"
#include "dvd_seek.h"
#include "dvd_ifo.h" #include "dvd_ifo.h"
#include "dvd_summary.h" #include "dvd_summary.h"
#include "iso_lang.h" #include "iso_lang.h"
#include "debug.h" #include "debug.h"
/* how many packets DVDDemux will read in each loop */
#define DVD_READ_ONCE 64
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
...@@ -87,17 +82,7 @@ static int DVDSetProgram ( struct input_thread_s *, pgrm_descriptor_t * ); ...@@ -87,17 +82,7 @@ static int DVDSetProgram ( struct input_thread_s *, pgrm_descriptor_t * );
static int DVDRead ( struct input_thread_s *, byte_t *, size_t ); static int DVDRead ( struct input_thread_s *, byte_t *, size_t );
static void DVDSeek ( struct input_thread_s *, off_t ); static void DVDSeek ( struct input_thread_s *, off_t );
static int DVDRewind ( struct input_thread_s * ); static char * DVDParse( input_thread_t * );
static int DVDDemux ( struct input_thread_s * );
static int DVDInit ( struct input_thread_s * );
static void DVDEnd ( struct input_thread_s * );
/* called only inside */
static void DVDLaunchDecoders( input_thread_t * p_input );
static int DVDChooseAngle( thread_dvd_data_t * );
static int DVDFindCell( thread_dvd_data_t * );
static int DVDFindSector( thread_dvd_data_t * );
static int DVDChapterSelect( thread_dvd_data_t *, int );
/***************************************************************************** /*****************************************************************************
* Functions exported as capabilities. They are declared as static so that * Functions exported as capabilities. They are declared as static so that
...@@ -115,124 +100,6 @@ void _M( access_getfunctions)( function_list_t * p_function_list ) ...@@ -115,124 +100,6 @@ void _M( access_getfunctions)( function_list_t * p_function_list )
#undef input #undef input
} }
void _M( demux_getfunctions)( function_list_t * p_function_list )
{
#define demux p_function_list->functions.demux
demux.pf_init = DVDInit;
demux.pf_end = DVDEnd;
demux.pf_demux = DVDDemux;
demux.pf_rewind = DVDRewind;
#undef demux
}
/*
* Data demux functions
*/
/*****************************************************************************
* DVDInit: initializes DVD structures
*****************************************************************************/
static int DVDInit( input_thread_t * p_input )
{
if( strncmp( p_input->p_access_module->psz_name, "dvd", 3 ) )
{
return -1;
}
vlc_mutex_lock( &p_input->stream.stream_lock );
DVDLaunchDecoders( p_input );
vlc_mutex_unlock( &p_input->stream.stream_lock );
return 0;
}
/*****************************************************************************
* DVDEnd: frees unused data
*****************************************************************************/
static void DVDEnd( input_thread_t * p_input )
{
}
/*****************************************************************************
* DVDDemux
*****************************************************************************/
#define PEEK( SIZE ) \
i_result = input_Peek( p_input, &p_peek, SIZE ); \
if( i_result == -1 ) \
{ \
return( -1 ); \
} \
else if( i_result < SIZE ) \
{ \
/* EOF */ \
return( 0 ); \
}
static int DVDDemux( input_thread_t * p_input )
{
int i;
byte_t * p_peek;
data_packet_t * p_data;
ssize_t i_result;
int i_packet_size;
/* Read headers to compute payload length */
for( i = 0 ; i < DVD_READ_ONCE ; i++ )
{
/* Read what we believe to be a packet header. */
PEEK( 4 );
/* Default header */
if( U32_AT( p_peek ) != 0x1BA )
{
/* That's the case for all packets, except pack header. */
i_packet_size = U16_AT( p_peek + 4 );
}
else
{
/* MPEG-2 Pack header. */
i_packet_size = 8;
}
/* Fetch a packet of the appropriate size. */
i_result = input_SplitBuffer( p_input, &p_data, i_packet_size + 6 );
if( i_result <= 0 )
{
return( i_result );
}
/* In MPEG-2 pack headers we still have to read stuffing bytes. */
if( (p_data->p_demux_start[3] == 0xBA) && (i_packet_size == 8) )
{
size_t i_stuffing = (p_data->p_demux_start[13] & 0x7);
/* Force refill of the input buffer - though we don't care
* about p_peek. Please note that this is unoptimized. */
PEEK( i_stuffing );
p_input->p_current_data += i_stuffing;
}
input_DemuxPS( p_input, p_data );
}
return i;
}
/*****************************************************************************
* DVDRewind : reads a stream backward
*****************************************************************************/
static int DVDRewind( input_thread_t * p_input )
{
return( -1 );
}
/* /*
* Data access functions * Data access functions
*/ */
...@@ -242,216 +109,39 @@ static int DVDRewind( input_thread_t * p_input ) ...@@ -242,216 +109,39 @@ static int DVDRewind( input_thread_t * p_input )
*****************************************************************************/ *****************************************************************************/
static int DVDOpen( struct input_thread_s *p_input ) static int DVDOpen( struct input_thread_s *p_input )
{ {
struct stat stat_info;
char * psz_orig;
char * psz_parser;
char * psz_device; char * psz_device;
char * psz_raw;
char * psz_next;
dvdcss_handle dvdhandle; dvdcss_handle dvdhandle;
thread_dvd_data_t * p_dvd; thread_dvd_data_t * p_dvd;
input_area_t * p_area; input_area_t * p_area;
boolean_t b_options = 0;
int i_title = 1;
int i_chapter = 1;
int i_angle = 1;
int i; int i;
psz_orig = psz_parser = psz_device = strdup( p_input->psz_name ); p_dvd = malloc( sizeof(thread_dvd_data_t) );
if( !psz_orig ) if( p_dvd == NULL )
{
return( -1 );
}
/* Parse input string :
* [device][@rawdevice][@[title][,[chapter][,angle]]] */
while( *psz_parser && *psz_parser != '@' )
{
psz_parser++;
}
if( *psz_parser == '@' )
{
/* Maybe found raw device or option list */
*psz_parser = '\0';
psz_raw = ++psz_parser;
}
else
{
psz_raw = NULL;
}
if( *psz_parser && !strtol( psz_parser, NULL, 10 ) )
{
/* what we've found is either a raw device or a partial option
* list e.g. @,29 or both a device and a list ; search end of string */
while( *psz_parser && *psz_parser != '@' )
{
psz_parser++;
}
if( *psz_parser == '@' )
{
/* found end of raw device, and beginning of options */
*psz_parser = '\0';
++psz_parser;
b_options = 1;
}
else
{
psz_parser = psz_raw + 1;
for( i=0 ; i<3 ; i++ )
{
if( !*psz_parser )
{
/* we have only a raw device */
break;
}
if( strtol( psz_parser, NULL, 10 ) )
{
/* we have only a partial list of options, no device */
psz_parser = psz_raw;
psz_raw = NULL;
b_options = 1;
break;
}
psz_parser++;
}
}
}
else
{
/* found beginning of options ; no raw device specified */
psz_raw = NULL;
b_options = 1;
}
if( b_options )
{
/* Found options */
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 ? i_title : 1;
i_chapter = i_chapter ? i_chapter : 1;
i_angle = i_angle ? i_angle : 1;
}
if( psz_raw )
{
if( *psz_raw )
{
/* check the raw device */
if( stat( psz_raw, &stat_info ) == -1 )
{
intf_WarnMsg( 3, "dvd warning: cannot stat() raw"
" device `%s' (%s)",
psz_raw, strerror(errno));
/* put back '@' */
*(psz_raw - 1) = '@';
psz_raw = NULL;
}
else
{
char * psz_env;
#ifndef WIN32
if( !S_ISCHR(stat_info.st_mode) )
{
intf_WarnMsg( 3, "dvd warning: raw device %s is"
" not a valid char device", psz_raw );
/* put back '@' */
*(psz_raw - 1) = '@';
psz_raw = NULL;
}
else
#endif
{
psz_env = malloc( strlen("DVDCSS_RAW_DEVICE=")
+ strlen( psz_raw ) + 1 );
sprintf( psz_env, "DVDCSS_RAW_DEVICE=%s", psz_raw );
putenv( psz_env );
}
}
}
else
{
psz_raw = NULL;
}
}
if( !*psz_device )
{
if( !p_input->psz_access )
{
/* no device and no access specified: we probably don't want DVD */
free( psz_orig );
return -1;
}
psz_device = config_GetPszVariable( INPUT_DVD_DEVICE_VAR );
}
/* check block device */
if( stat( psz_device, &stat_info ) == -1 )
{
intf_ErrMsg( "input error: cannot stat() device `%s' (%s)",
psz_device, strerror(errno));
return( -1 );
}
#ifndef WIN32
if( !S_ISBLK(stat_info.st_mode) && !S_ISCHR(stat_info.st_mode) )
{ {
intf_WarnMsg( 3, "input: DVD plugin discarded" intf_ErrMsg( "dvd error: out of memory" );
" (not a valid block device)" );
return -1; return -1;
} }
#endif p_input->p_access_data = (void *)p_dvd;
if( psz_raw ) /* Parse command line */
if( !( psz_device = DVDParse( p_input ) ) )
{ {
free( p_dvd );
return -1;
} }
intf_WarnMsg( 2, "input: dvd=%s raw=%s title=%d chapter=%d angle=%d",
psz_device, psz_raw, i_title, i_chapter, i_angle );
/* /*
* set up input * set up input
*/ */
p_input->i_mtu = 0; p_input->i_mtu = 0;
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.i_method = INPUT_METHOD_DVD;
/* If we are here we can control the pace... */
p_input->stream.b_pace_control = 1;
p_input->stream.b_seekable = 1;
p_input->stream.p_selected_area->i_size = 0;
p_input->stream.p_selected_area->i_tell = 0;
vlc_mutex_unlock( &p_input->stream.stream_lock );
/* /*
* get plugin ready * get plugin ready
*/ */
dvdhandle = dvdcss_open( psz_device ); dvdhandle = dvdcss_open( psz_device );
/* free allocated strings */ /* free allocated string */
if( psz_device != psz_orig ) free( psz_device );
free( psz_device );
free( psz_orig );
if( dvdhandle == NULL ) if( dvdhandle == NULL )
...@@ -460,15 +150,7 @@ static int DVDOpen( struct input_thread_s *p_input ) ...@@ -460,15 +150,7 @@ static int DVDOpen( struct input_thread_s *p_input )
return -1; return -1;
} }
p_dvd = malloc( sizeof(thread_dvd_data_t) );
if( p_dvd == NULL )
{
intf_ErrMsg( "dvd error: out of memory" );
return -1;
}
p_dvd->dvdhandle = (dvdcss_handle) dvdhandle; p_dvd->dvdhandle = (dvdcss_handle) dvdhandle;
p_input->p_access_data = (void *)p_dvd;
if( dvdcss_seek( p_dvd->dvdhandle, 0, DVDCSS_NOFLAGS ) < 0 ) if( dvdcss_seek( p_dvd->dvdhandle, 0, DVDCSS_NOFLAGS ) < 0 )
{ {
...@@ -495,11 +177,17 @@ static int DVDOpen( struct input_thread_s *p_input ) ...@@ -495,11 +177,17 @@ static int DVDOpen( struct input_thread_s *p_input )
/* Set stream and area data */ /* Set stream and area data */
vlc_mutex_lock( &p_input->stream.stream_lock ); vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.i_method = INPUT_METHOD_DVD;
p_input->stream.b_pace_control = 1;
p_input->stream.b_seekable = 1;
p_input->stream.p_selected_area->i_size = 0;
p_input->stream.p_selected_area->i_tell = 0;
/* Initialize ES structures */ /* Initialize ES structures */
input_InitStream( p_input, sizeof( stream_ps_data_t ) ); input_InitStream( p_input, sizeof( stream_ps_data_t ) );
#define title_inf p_dvd->p_ifo->vmg.title_inf #define title_inf p_dvd->p_ifo->vmg.title_inf
intf_WarnMsg( 2, "dvd info: number of titles: %d", title_inf.i_title_nb ); intf_WarnMsg( 3, "dvd info: number of titles: %d", title_inf.i_title_nb );
#define area p_input->stream.pp_areas #define area p_input->stream.pp_areas
/* We start from 1 here since the default area 0 /* We start from 1 here since the default area 0
...@@ -527,17 +215,19 @@ static int DVDOpen( struct input_thread_s *p_input ) ...@@ -527,17 +215,19 @@ static int DVDOpen( struct input_thread_s *p_input )
} }
#undef area #undef area
p_dvd->i_title = i_title <= title_inf.i_title_nb ? i_title : 1; p_dvd->i_title = p_dvd->i_title <= title_inf.i_title_nb ?
p_dvd->i_title : 1;
#undef title_inf #undef title_inf
p_area = p_input->stream.pp_areas[p_dvd->i_title]; p_area = p_input->stream.pp_areas[p_dvd->i_title];
p_dvd->i_chapter = i_chapter < p_area->i_part_nb ? i_chapter : 1; p_dvd->i_chapter = p_dvd->i_chapter < p_area->i_part_nb ?
p_dvd->i_chapter : 1;
p_area->i_part = p_dvd->i_chapter; p_area->i_part = p_dvd->i_chapter;
p_dvd->i_angle = i_angle; p_dvd->i_audio_nb = 0;
p_dvd->i_spu_nb = 0;
/* set title, chapter, audio and subpic */ /* set title, chapter, audio and subpic */
if( DVDSetArea( p_input, p_area ) ) if( DVDSetArea( p_input, p_area ) )
{ {
...@@ -548,7 +238,6 @@ static int DVDOpen( struct input_thread_s *p_input ) ...@@ -548,7 +238,6 @@ static int DVDOpen( struct input_thread_s *p_input )
vlc_mutex_unlock( &p_input->stream.stream_lock ); vlc_mutex_unlock( &p_input->stream.stream_lock );
return 0; return 0;
} }
/***************************************************************************** /*****************************************************************************
...@@ -570,7 +259,7 @@ static void DVDClose( struct input_thread_s *p_input ) ...@@ -570,7 +259,7 @@ static void DVDClose( struct input_thread_s *p_input )
} }
/***************************************************************************** /*****************************************************************************
* DVDSetProgram: Does nothing, a DVD is mono-program * DVDSetProgram: used to change angle
*****************************************************************************/ *****************************************************************************/
static int DVDSetProgram( input_thread_t * p_input, static int DVDSetProgram( input_thread_t * p_input,
pgrm_descriptor_t * p_program ) pgrm_descriptor_t * p_program )
...@@ -583,6 +272,8 @@ static int DVDSetProgram( input_thread_t * p_input, ...@@ -583,6 +272,8 @@ static int DVDSetProgram( input_thread_t * p_input,
p_dvd = (thread_dvd_data_t*)(p_input->p_access_data); p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
i_angle = p_program->i_number; i_angle = p_program->i_number;
/* DVD is actually mono-program: we only need the current angle
* number, so copy the data between programs */
memcpy( p_program, p_input->stream.p_selected_program, memcpy( p_program, p_input->stream.p_selected_program,
sizeof(pgrm_descriptor_t) ); sizeof(pgrm_descriptor_t) );
p_program->i_number = i_angle; p_program->i_number = i_angle;
...@@ -623,11 +314,7 @@ static int DVDSetProgram( input_thread_t * p_input, ...@@ -623,11 +314,7 @@ static int DVDSetProgram( input_thread_t * p_input,
static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
{ {
thread_dvd_data_t * p_dvd; thread_dvd_data_t * p_dvd;
es_descriptor_t * p_es;
u16 i_id;
int i_vts_title; int i_vts_title;
int i_audio_nb = 0;
int i_spu_nb = 0;
int i; int i;
p_dvd = (thread_dvd_data_t*)(p_input->p_access_data); p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
...@@ -639,13 +326,12 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) ...@@ -639,13 +326,12 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
{ {
/* Reset the Chapter position of the old title */ /* Reset the Chapter position of the old title */
p_input->stream.p_selected_area->i_part = 0; p_input->stream.p_selected_area->i_part = 0;
p_input->stream.p_selected_area = p_area;
/* /*
* We have to load all title information * We have to load all title information
*/ */
/* Change the default area */ /* Change the default area */
p_input->stream.p_selected_area =
p_input->stream.pp_areas[p_area->i_id];
/* title number: it is not vts nb!, /* title number: it is not vts nb!,
* it is what appears in the interface list */ * it is what appears in the interface list */
...@@ -674,15 +360,7 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) ...@@ -674,15 +360,7 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
intf_WarnMsg( 3, "dvd: title %d vts_title %d pgc %d", intf_WarnMsg( 3, "dvd: title %d vts_title %d pgc %d",
p_dvd->i_title, i_vts_title, p_dvd->i_title_id ); p_dvd->i_title, i_vts_title, p_dvd->i_title_id );
/*
* Angle management
*/
p_dvd->i_angle_nb = vmg.title_inf.p_attr[p_dvd->i_title-1].i_angle_nb;
if( ( p_dvd->i_angle <= 0 ) || p_dvd->i_angle > p_dvd->i_angle_nb )
{
p_dvd->i_angle = 1;
}
/* /*
* Set selected title start and size * Set selected title start and size
*/ */
...@@ -738,14 +416,6 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) ...@@ -738,14 +416,6 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
p_input->stream.p_selected_area->i_start = LB2OFF( p_dvd->i_start ); p_input->stream.p_selected_area->i_start = LB2OFF( p_dvd->i_start );
p_input->stream.p_selected_area->i_size = LB2OFF( p_dvd->i_size ); p_input->stream.p_selected_area->i_size = LB2OFF( p_dvd->i_size );
#if 0
/* start at the beginning of the title */
/* FIXME: create a conf option to select whether to restart
* title or not */
p_input->stream.p_selected_area->i_tell = 0;
p_input->stream.p_selected_area->i_part = 1;
#endif
/* /*
* Destroy obsolete ES by reinitializing programs * Destroy obsolete ES by reinitializing programs
* and find all ES in title with ifo data * and find all ES in title with ifo data
...@@ -754,23 +424,14 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) ...@@ -754,23 +424,14 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
{ {
/* We don't use input_EndStream here since /* We don't use input_EndStream here since
* we keep area structures */ * we keep area structures */
while( p_input->stream.i_es_number )
/* Unselect all ES */
/*
for( i = 0 ; i < p_input->stream.i_selected_es_number ; i++ )
{ {
input_UnselectES( p_input, p_input->stream.pp_selected_es[i] ); input_DelES( p_input, p_input->stream.pp_es[0] );
} }
*/
for( i = 0 ; i < p_input->stream.i_es_number ; i++ ) while( p_input->stream.i_pgrm_number )
{ {
input_DelES( p_input, p_input->stream.pp_es[i] ); input_DelProgram( p_input, p_input->stream.pp_programs[0] );
}
for( i = 0 ; i < p_input->stream.i_pgrm_number ; i++ )
{
input_DelProgram( p_input, p_input->stream.pp_programs[i] );
} }
if( p_input->stream.pp_selected_es ) if( p_input->stream.pp_selected_es )
...@@ -780,9 +441,16 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) ...@@ -780,9 +441,16 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
} }
p_input->stream.i_selected_es_number = 0; p_input->stream.i_selected_es_number = 0;
} }
/* angle */ /*
* Angle management: angles are handled through programs
*/
p_dvd->i_angle_nb = vmg.title_inf.p_attr[p_dvd->i_title-1].i_angle_nb;
if( ( p_dvd->i_angle <= 0 ) || p_dvd->i_angle > p_dvd->i_angle_nb )
{
p_dvd->i_angle = 1;
}
input_AddProgram( p_input, 1, sizeof( stream_ps_data_t ) ); input_AddProgram( p_input, 1, sizeof( stream_ps_data_t ) );
p_input->stream.p_selected_program = p_input->stream.pp_programs[0]; p_input->stream.p_selected_program = p_input->stream.pp_programs[0];
...@@ -798,130 +466,12 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) ...@@ -798,130 +466,12 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
/* No PSM to read in DVD mode, we already have all information */ /* No PSM to read in DVD mode, we already have all information */
p_input->stream.p_selected_program->b_is_ok = 1; p_input->stream.p_selected_program->b_is_ok = 1;
p_es = NULL; DVDReadVideo( p_input );
/* ES 0 -> video MPEG2 */
IfoPrintVideo( p_dvd );
p_es = input_AddES( p_input, NULL, 0xe0, 0 );
p_es->i_stream_id = 0xe0;
p_es->i_type = MPEG2_VIDEO_ES;
p_es->i_cat = VIDEO_ES;
#define audio_status \ DVDReadAudio( p_input );
vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_audio_status[i-1]
/* Audio ES, in the order they appear in .ifo */ DVDReadSPU( p_input );
for( i = 1 ; i <= vts.manager_inf.i_audio_nb ; i++ )
{
IfoPrintAudio( p_dvd, i );
/* audio channel is active if first byte is 0x80 */
if( audio_status.i_available )
{
i_audio_nb++;
switch( vts.manager_inf.p_audio_attr[i-1].i_coding_mode )
{
case 0x00: /* AC3 */
i_id = ( ( 0x80 + audio_status.i_position ) << 8 ) | 0xbd;
p_es = input_AddES( p_input, NULL, i_id, 0 );
p_es->i_stream_id = 0xbd;
p_es->i_type = AC3_AUDIO_ES;
p_es->b_audio = 1;
p_es->i_cat = AUDIO_ES;
strcpy( p_es->psz_desc, DecodeLanguage( hton16(
vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) );
strcat( p_es->psz_desc, " (ac3)" );
break;
case 0x02:
case 0x03: /* MPEG audio */
i_id = 0xc0 + audio_status.i_position;
p_es = input_AddES( p_input, NULL, i_id, 0 );
p_es->i_stream_id = i_id;
p_es->i_type = MPEG2_AUDIO_ES;
p_es->b_audio = 1;
p_es->i_cat = AUDIO_ES;
strcpy( p_es->psz_desc, DecodeLanguage( hton16(
vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) );
strcat( p_es->psz_desc, " (mpeg)" );
break;
case 0x04: /* LPCM */
i_id = ( ( 0xa0 + audio_status.i_position ) << 8 ) | 0xbd;
p_es = input_AddES( p_input, NULL, i_id, 0 );
p_es->i_stream_id = 0xbd;
p_es->i_type = LPCM_AUDIO_ES;
p_es->b_audio = 1;
p_es->i_cat = AUDIO_ES;
strcpy( p_es->psz_desc, DecodeLanguage( hton16(
vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) );
strcat( p_es->psz_desc, " (lpcm)" );
break;
case 0x06: /* DTS */
i_id = ( ( 0x88 + audio_status.i_position ) << 8 ) | 0xbd;
intf_ErrMsg( "dvd warning: DTS audio not handled yet"
"(0x%x)", i_id );
break;
default:
i_id = 0;
intf_ErrMsg( "dvd warning: unknown audio type %.2x",
vts.manager_inf.p_audio_attr[i-1].i_coding_mode );
}
}
}
#undef audio_status
#define spu_status \
vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_spu_status[i-1]
/* Sub Picture ES */
for( i = 1 ; i <= vts.manager_inf.i_spu_nb; i++ )
{
IfoPrintSpu( p_dvd, i );
if( spu_status.i_available )
{
i_spu_nb++;
/* there are several streams for one spu */
if( vts.manager_inf.video_attr.i_ratio )
{
/* 16:9 */
switch( vts.manager_inf.video_attr.i_perm_displ )
{
case 1:
i_id = ( ( 0x20 + spu_status.i_position_pan ) << 8 )
| 0xbd;
break;
case 2:
i_id = ( ( 0x20 + spu_status.i_position_letter ) << 8 )
| 0xbd;
break;
default:
i_id = ( ( 0x20 + spu_status.i_position_wide ) << 8 )
| 0xbd;
break;
}
}
else
{
/* 4:3 */
i_id = ( ( 0x20 + spu_status.i_position_43 ) << 8 )
| 0xbd;
}
p_es = input_AddES( p_input, NULL, i_id, 0 );
p_es->i_stream_id = 0xbd;
p_es->i_type = DVD_SPU_ES;
p_es->i_cat = SPU_ES;
strcpy( p_es->psz_desc, DecodeLanguage( hton16(
vts.manager_inf.p_spu_attr[i-1].i_lang_code ) ) );
}
}
#undef spu_status
/* FIXME: hack to check that the demuxer is ready, and set /* FIXME: hack to check that the demuxer is ready, and set
* the decoders */ * the decoders */
if( p_input->p_demux_module ) if( p_input->p_demux_module )
...@@ -953,9 +503,9 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) ...@@ -953,9 +503,9 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
return -1; return -1;
} }
p_input->stream.p_selected_area->i_part = p_dvd->i_chapter;
p_input->stream.p_selected_area->i_tell = p_input->stream.p_selected_area->i_tell =
LB2OFF( p_dvd->i_start ) - p_area->i_start; LB2OFF( p_dvd->i_start ) - p_area->i_start;
p_input->stream.p_selected_area->i_part = p_dvd->i_chapter;
intf_WarnMsg( 4, "dvd info: chapter %d start at: %lld", intf_WarnMsg( 4, "dvd info: chapter %d start at: %lld",
p_area->i_part, p_area->i_tell ); p_area->i_part, p_area->i_tell );
...@@ -967,9 +517,6 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) ...@@ -967,9 +517,6 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
} }
} }
#define title \
p_dvd->p_ifo->vts.title_unit.p_title[p_dvd->i_title_id-1].title
/* warn interface that something has changed */ /* warn interface that something has changed */
p_input->stream.b_seekable = 1; p_input->stream.b_seekable = 1;
p_input->stream.b_changed = 1; p_input->stream.b_changed = 1;
...@@ -977,6 +524,8 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) ...@@ -977,6 +524,8 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
return 0; return 0;
} }
#define title \
p_dvd->p_ifo->vts.title_unit.p_title[p_dvd->i_title_id-1].title
/***************************************************************************** /*****************************************************************************
* DVDRead: reads data packets. * DVDRead: reads data packets.
...@@ -1029,7 +578,8 @@ static int DVDRead( input_thread_t * p_input, ...@@ -1029,7 +578,8 @@ static int DVDRead( input_thread_t * p_input,
p_dvd->i_title_start + p_dvd->i_sector, p_dvd->i_title_start + p_dvd->i_sector,
DVDCSS_SEEK_MPEG ) ) < 0 ) DVDCSS_SEEK_MPEG ) ) < 0 )
{ {
intf_ErrMsg( "dvd error: %s", dvdcss_error( p_dvd->dvdhandle ) ); intf_ErrMsg( "dvd error: %s",
dvdcss_error( p_dvd->dvdhandle ) );
return -1; return -1;
} }
...@@ -1062,9 +612,6 @@ static int DVDRead( input_thread_t * p_input, ...@@ -1062,9 +612,6 @@ static int DVDRead( input_thread_t * p_input,
{ {
i_block_once = i_blocks; i_block_once = i_blocks;
} }
/*
intf_WarnMsg( 2, "Sector: 0x%x Read: %d Chapter: %d", p_dvd->i_sector, i_block_once, p_dvd->i_chapter );
*/
/* Reads from DVD */ /* Reads from DVD */
i_read_blocks = dvdcss_read( p_dvd->dvdhandle, p_buffer, i_read_blocks = dvdcss_read( p_dvd->dvdhandle, p_buffer,
...@@ -1104,17 +651,10 @@ static int DVDRead( input_thread_t * p_input, ...@@ -1104,17 +651,10 @@ static int DVDRead( input_thread_t * p_input,
intf_WarnMsg( 4, "dvd info: new title" ); intf_WarnMsg( 4, "dvd info: new title" );
p_dvd->i_title++; p_dvd->i_title++;
DVDSetArea( p_input, p_input->stream.pp_areas[p_dvd->i_title] ); DVDSetArea( p_input, p_input->stream.pp_areas[p_dvd->i_title] );
vlc_mutex_unlock( &p_input->stream.stream_lock );
return LB2OFF( i_read_total );
} }
vlc_mutex_unlock( &p_input->stream.stream_lock ); vlc_mutex_unlock( &p_input->stream.stream_lock );
/*
if( i_read_blocks != i_block_once )
{
return -1;
}
*/
return LB2OFF( i_read_total ); return LB2OFF( i_read_total );
} }
...@@ -1235,238 +775,194 @@ static void DVDSeek( input_thread_t * p_input, off_t i_off ) ...@@ -1235,238 +775,194 @@ static void DVDSeek( input_thread_t * p_input, off_t i_off )
LB2OFF ( i_block ) - p_input->stream.p_selected_area->i_start; LB2OFF ( i_block ) - p_input->stream.p_selected_area->i_start;
vlc_mutex_unlock( &p_input->stream.stream_lock ); vlc_mutex_unlock( &p_input->stream.stream_lock );
intf_WarnMsg( 7, "Program Cell: %d Cell: %d Chapter: %d", intf_WarnMsg( 4, "Program Cell: %d Cell: %d Chapter: %d",
p_dvd->i_prg_cell, p_dvd->i_cell, p_dvd->i_chapter ); p_dvd->i_prg_cell, p_dvd->i_cell, p_dvd->i_chapter );
return; return;
} }
#define cell p_dvd->p_ifo->vts.cell_inf
/***************************************************************************** /*****************************************************************************
* DVDFindCell: adjust the title cell index with the program cell * DVDParse: parse command line
*****************************************************************************/ *****************************************************************************/
static int DVDFindCell( thread_dvd_data_t * p_dvd ) static char * DVDParse( input_thread_t * p_input )
{ {
int i_cell; thread_dvd_data_t * p_dvd;
int i_index; struct stat stat_info;
char * psz_parser;
i_cell = p_dvd->i_cell; char * psz_device;
i_index = p_dvd->i_prg_cell; char * psz_raw;
char * psz_next;
boolean_t b_options = 0;
int i_title = 1;
int i_chapter = 1;
int i_angle = 1;
int i;
p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
if( i_cell >= cell.i_cell_nb ) psz_parser = psz_device = strdup( p_input->psz_name );
if( !psz_parser )
{ {
return -1; return NULL;
} }
while( ( ( title.p_cell_pos[i_index].i_vob_id != /* Parse input string :
cell.p_cell_map[i_cell].i_vob_id ) || * [device][@rawdevice][@[title][,[chapter][,angle]]] */
( title.p_cell_pos[i_index].i_cell_id != while( *psz_parser && *psz_parser != '@' )
cell.p_cell_map[i_cell].i_cell_id ) ) &&
( i_cell < cell.i_cell_nb - 1 ) )
{ {
i_cell++; psz_parser++;
} }
/* if( *psz_parser == '@' )
intf_WarnMsg( 12, "FindCell: i_cell %d i_index %d found %d nb %d",
p_dvd->i_cell,
p_dvd->i_prg_cell,
i_cell,
cell.i_cell_nb );
*/
p_dvd->i_cell = i_cell;
return 0;
}
#undef cell
/*****************************************************************************
* DVDFindSector: find cell index in adress map from index in
* information table program map and give corresponding sectors.
*****************************************************************************/
static int DVDFindSector( thread_dvd_data_t * p_dvd )
{
if( p_dvd->i_sector > title.p_cell_play[p_dvd->i_prg_cell].i_end_sector )
{ {
p_dvd->i_prg_cell++; /* Maybe found raw device or option list */
*psz_parser = '\0';
if( DVDChooseAngle( p_dvd ) < 0 ) psz_raw = ++psz_parser;
{
return -1;
}
} }
else
if( DVDFindCell( p_dvd ) < 0 )
{ {
intf_ErrMsg( "dvd error: can't find sector" ); psz_raw = NULL;
return -1;
} }
/* Find start and end sectors of new cell */
#if 1
p_dvd->i_sector = __MAX(
p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_start_sector,
title.p_cell_play[p_dvd->i_prg_cell].i_start_sector );
p_dvd->i_end_sector = __MIN(
p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector,
title.p_cell_play[p_dvd->i_prg_cell].i_end_sector );
#else
p_dvd->i_sector = title.p_cell_play[p_dvd->i_prg_cell].i_start_sector;
p_dvd->i_end_sector = title.p_cell_play[p_dvd->i_prg_cell].i_end_sector;
#endif
/*
intf_WarnMsg( 12, "cell: %d sector1: 0x%x end1: 0x%x\n"
"index: %d sector2: 0x%x end2: 0x%x\n"
"category: 0x%x ilvu end: 0x%x vobu start 0x%x",
p_dvd->i_cell,
p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_start_sector,
p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector,
p_dvd->i_prg_cell,
title.p_cell_play[p_dvd->i_prg_cell].i_start_sector,
title.p_cell_play[p_dvd->i_prg_cell].i_end_sector,
title.p_cell_play[p_dvd->i_prg_cell].i_category,
title.p_cell_play[p_dvd->i_prg_cell].i_first_ilvu_vobu_esector,
title.p_cell_play[p_dvd->i_prg_cell].i_last_vobu_start_sector );
*/
return 0;
}
/*****************************************************************************
* DVDChapterSelect: find the cell corresponding to requested chapter
*****************************************************************************/
static int DVDChapterSelect( thread_dvd_data_t * p_dvd, int i_chapter )
{
/* Find cell index in Program chain for current chapter */
p_dvd->i_prg_cell = title.chapter_map.pi_start_cell[i_chapter-1] - 1;
p_dvd->i_cell = 0;
p_dvd->i_sector = 0;
DVDChooseAngle( p_dvd ); if( *psz_parser && !strtol( psz_parser, NULL, 10 ) )
/* Search for cell_index in cell adress_table and initialize
* start sector */
if( DVDFindSector( p_dvd ) < 0 )
{ {
intf_ErrMsg( "dvd error: can't select chapter" ); /* what we've found is either a raw device or a partial option
return -1; * list e.g. @,29 or both a device and a list ; search end of string */
while( *psz_parser && *psz_parser != '@' )
{
psz_parser++;
}
if( *psz_parser == '@' )
{
/* found end of raw device, and beginning of options */
*psz_parser = '\0';
++psz_parser;
b_options = 1;
}
else
{
psz_parser = psz_raw + 1;
for( i=0 ; i<3 ; i++ )
{
if( !*psz_parser )
{
/* we have only a raw device */
break;
}
if( strtol( psz_parser, NULL, 10 ) )
{
/* we have only a partial list of options, no device */
psz_parser = psz_raw;
psz_raw = NULL;
b_options = 1;
break;
}
psz_parser++;
}
}
} }
else
/* start is : beginning of vts vobs + offset to vob x */
p_dvd->i_start = p_dvd->i_title_start + p_dvd->i_sector;
/* Position the fd pointer on the right address */
if( ( p_dvd->i_start = dvdcss_seek( p_dvd->dvdhandle,
p_dvd->i_start,
DVDCSS_SEEK_MPEG ) ) < 0 )
{ {
intf_ErrMsg( "dvd error: %s", dvdcss_error( p_dvd->dvdhandle ) ); /* found beginning of options ; no raw device specified */
return -1; psz_raw = NULL;
b_options = 1;
} }
p_dvd->i_chapter = i_chapter; if( b_options )
return 0;
}
/*****************************************************************************
* DVDChooseAngle: select the cell corresponding to the selected angle
*****************************************************************************/
static int DVDChooseAngle( thread_dvd_data_t * p_dvd )
{
/* basic handling of angles */
switch( ( ( title.p_cell_play[p_dvd->i_prg_cell].i_category & 0xf000 )
>> 12 ) )
{ {
/* we enter a muli-angle section */ /* Found options */
case 0x5: i_title = (int)strtol( psz_parser, &psz_next, 10 );
p_dvd->i_prg_cell += p_dvd->i_angle - 1; if( *psz_next )
p_dvd->i_angle_cell = 0; {
break; psz_parser = psz_next + 1;
/* we exit a multi-angle section */ i_chapter = (int)strtol( psz_parser, &psz_next, 10 );
case 0x9: if( *psz_next )
case 0xd: {
p_dvd->i_prg_cell += p_dvd->i_angle_nb - p_dvd->i_angle; i_angle = (int)strtol( psz_next + 1, NULL, 10 );
break; }
} }
return 0;
}
#undef title
/*****************************************************************************
* DVDLaunchDecoders
*****************************************************************************/
static void DVDLaunchDecoders( input_thread_t * p_input )
{
thread_dvd_data_t * p_dvd;
int i_audio;
int i_spu;
p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
/* Select Video stream (always 0) */ p_dvd->i_title = i_title ? i_title : 1;
if( p_main->b_video ) p_dvd->i_chapter = i_chapter ? i_chapter : 1;
{ p_dvd->i_angle = i_angle ? i_angle : 1;
input_SelectES( p_input, p_input->stream.pp_es[0] );
} }
/* Select audio stream */ if( psz_raw )
if( p_main->b_audio )
{ {
/* For audio: first one if none or a not existing one specified */ if( *psz_raw )
i_audio = config_GetIntVariable( INPUT_CHANNEL_VAR );
if( i_audio < 0 /*|| i_audio > i_audio_nb*/ )
{
config_PutIntVariable( INPUT_CHANNEL_VAR, 1 );
i_audio = 1;
}
if( i_audio > 0 /*&& i_audio_nb > 0*/ )
{ {
if( config_GetIntVariable( AOUT_SPDIF_VAR ) || /* check the raw device */
( config_GetIntVariable( INPUT_AUDIO_VAR ) == if( stat( psz_raw, &stat_info ) == -1 )
REQUESTED_AC3 ) ) {
intf_WarnMsg( 3, "dvd warning: cannot stat() raw"
" device `%s' (%s)",
psz_raw, strerror(errno));
/* put back '@' */
*(psz_raw - 1) = '@';
psz_raw = NULL;
}
else
{ {
int i_ac3 = i_audio; char * psz_env;
while( ( p_input->stream.pp_es[i_ac3]->i_type !=
AC3_AUDIO_ES ) && ( i_ac3 <= #ifndef WIN32
p_dvd->p_ifo->vts.manager_inf.i_audio_nb ) ) if( !S_ISCHR(stat_info.st_mode) )
{ {
i_ac3++; intf_WarnMsg( 3, "dvd warning: raw device %s is"
" not a valid char device", psz_raw );
/* put back '@' */
*(psz_raw - 1) = '@';
psz_raw = NULL;
} }
if( p_input->stream.pp_es[i_ac3]->i_type == AC3_AUDIO_ES ) else
#endif
{ {
input_SelectES( p_input, psz_env = malloc( strlen("DVDCSS_RAW_DEVICE=")
p_input->stream.pp_es[i_ac3] ); + strlen( psz_raw ) + 1 );
sprintf( psz_env, "DVDCSS_RAW_DEVICE=%s", psz_raw );
putenv( psz_env );
} }
} }
else
{
input_SelectES( p_input,
p_input->stream.pp_es[i_audio] );
}
} }
} else
/* Select subtitle */
if( p_main->b_video )
{
/* for spu, default is none */
i_spu = config_GetIntVariable( INPUT_SUBTITLE_VAR );
if( i_spu < 0 /*|| i_spu > i_spu_nb*/ )
{ {
config_PutIntVariable( INPUT_SUBTITLE_VAR, 0 ); psz_raw = NULL;
i_spu = 0;
} }
if( i_spu > 0 /* && i_spu_nb > 0*/ ) }
if( !*psz_device )
{
free( psz_device );
if( !p_input->psz_access )
{ {
i_spu += p_dvd->p_ifo->vts.manager_inf.i_audio_nb; /* no device and no access specified: we probably don't want DVD */
input_SelectES( p_input, p_input->stream.pp_es[i_spu] ); return NULL;
} }
psz_device = config_GetPszVariable( INPUT_DVD_DEVICE_VAR );
} }
}
/* check block device */
if( stat( psz_device, &stat_info ) == -1 )
{
intf_ErrMsg( "input error: cannot stat() device `%s' (%s)",
psz_device, strerror(errno));
return NULL;
}
#ifndef WIN32
if( !S_ISBLK(stat_info.st_mode) && !S_ISCHR(stat_info.st_mode) )
{
intf_WarnMsg( 3, "input: DVD plugin discarded"
" (not a valid block device)" );
return NULL;
}
#endif
intf_WarnMsg( 2, "input: dvd=%s raw=%s title=%d chapter=%d angle=%d",
psz_device, psz_raw, p_dvd->i_title,
p_dvd->i_chapter, p_dvd->i_angle );
return psz_device;
}
/* dvd_demux.c: DVD demux functions.
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: dvd_demux.c,v 1.1 2002/03/06 01:20:56 stef Exp $
*
* Author: Stphane 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 <string.h>
#include <videolan/vlc.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
#ifdef STRNCASECMP_IN_STRINGS_H
# include <strings.h>
#endif
#include "stream_control.h"
#include "input_ext-intf.h"
#include "input_ext-dec.h"
#include "input_ext-plugins.h"
#include "debug.h"
/* how many packets DVDDemux will read in each loop */
#define DVD_READ_ONCE 64
/*****************************************************************************
* Local prototypes
*****************************************************************************/
/* called from outside */
static int DVDRewind ( struct input_thread_s * );
static int DVDDemux ( struct input_thread_s * );
static int DVDInit ( struct input_thread_s * );
static void DVDEnd ( struct input_thread_s * );
void DVDLaunchDecoders( input_thread_t * );
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
* we don't pollute the namespace too much.
*****************************************************************************/
void _M( demux_getfunctions)( function_list_t * p_function_list )
{
#define demux p_function_list->functions.demux
demux.pf_init = DVDInit;
demux.pf_end = DVDEnd;
demux.pf_demux = DVDDemux;
demux.pf_rewind = DVDRewind;
#undef demux
}
/*
* Data demux functions
*/
/*****************************************************************************
* DVDInit: initializes DVD structures
*****************************************************************************/
static int DVDInit( input_thread_t * p_input )
{
if( strncmp( p_input->p_access_module->psz_name, "dvd", 3 ) )
{
return -1;
}
vlc_mutex_lock( &p_input->stream.stream_lock );
DVDLaunchDecoders( p_input );
vlc_mutex_unlock( &p_input->stream.stream_lock );
return 0;
}
/*****************************************************************************
* DVDEnd: frees unused data
*****************************************************************************/
static void DVDEnd( input_thread_t * p_input )
{
}
/*****************************************************************************
* DVDDemux
*****************************************************************************/
static int DVDDemux( input_thread_t * p_input )
{
int i;
data_packet_t * p_data;
/* Read headers to compute payload length */
for( i = 0 ; i < DVD_READ_ONCE ; i++ )
{
input_ReadPS( p_input, &p_data );
input_DemuxPS( p_input, p_data );
}
return i;
}
/*****************************************************************************
* DVDRewind : reads a stream backward
*****************************************************************************/
static int DVDRewind( input_thread_t * p_input )
{
return( -1 );
}
/* dvd_es.c: functions to find and select ES
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: dvd_es.c,v 1.1 2002/03/06 01:20:56 stef Exp $
*
* Author: Stphane 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 <string.h>
#include <videolan/vlc.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
#ifdef STRNCASECMP_IN_STRINGS_H
# include <strings.h>
#endif
#ifdef GOD_DAMN_DMCA
# include "dummy_dvdcss.h"
#else
# include <videolan/dvdcss.h>
#endif
#include "stream_control.h"
#include "input_ext-intf.h"
#include "input_ext-dec.h"
#include "input_ext-plugins.h"
#include "dvd.h"
#include "dvd_ifo.h"
#include "dvd_summary.h"
#include "iso_lang.h"
#include "debug.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
void DVDLaunchDecoders( input_thread_t * p_input );
#define vmg p_dvd->p_ifo->vmg
#define vts p_dvd->p_ifo->vts
/*****************************************************************************
* DVDReadVideo
*****************************************************************************/
void DVDReadVideo( input_thread_t * p_input )
{
thread_dvd_data_t * p_dvd;
es_descriptor_t * p_es;
p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
/* ES 0 -> video MPEG2 */
IfoPrintVideo( p_dvd );
p_es = input_AddES( p_input, NULL, 0xe0, 0 );
p_es->i_stream_id = 0xe0;
p_es->i_type = MPEG2_VIDEO_ES;
p_es->i_cat = VIDEO_ES;
}
/*****************************************************************************
* DVDReadAudio
*****************************************************************************/
#define audio_status \
vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_audio_status[i-1]
void DVDReadAudio( input_thread_t * p_input )
{
thread_dvd_data_t * p_dvd;
es_descriptor_t * p_es;
int i_id;
int i;
p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
/* Audio ES, in the order they appear in .ifo */
for( i = 1 ; i <= vts.manager_inf.i_audio_nb ; i++ )
{
IfoPrintAudio( p_dvd, i );
/* audio channel is active if first byte is 0x80 */
if( audio_status.i_available )
{
p_dvd->i_audio_nb++;
switch( vts.manager_inf.p_audio_attr[i-1].i_coding_mode )
{
case 0x00: /* AC3 */
i_id = ( ( 0x80 + audio_status.i_position ) << 8 ) | 0xbd;
p_es = input_AddES( p_input, NULL, i_id, 0 );
p_es->i_stream_id = 0xbd;
p_es->i_type = AC3_AUDIO_ES;
p_es->b_audio = 1;
p_es->i_cat = AUDIO_ES;
strcpy( p_es->psz_desc, DecodeLanguage( hton16(
vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) );
strcat( p_es->psz_desc, " (ac3)" );
break;
case 0x02:
case 0x03: /* MPEG audio */
i_id = 0xc0 + audio_status.i_position;
p_es = input_AddES( p_input, NULL, i_id, 0 );
p_es->i_stream_id = i_id;
p_es->i_type = MPEG2_AUDIO_ES;
p_es->b_audio = 1;
p_es->i_cat = AUDIO_ES;
strcpy( p_es->psz_desc, DecodeLanguage( hton16(
vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) );
strcat( p_es->psz_desc, " (mpeg)" );
break;
case 0x04: /* LPCM */
i_id = ( ( 0xa0 + audio_status.i_position ) << 8 ) | 0xbd;
p_es = input_AddES( p_input, NULL, i_id, 0 );
p_es->i_stream_id = 0xbd;
p_es->i_type = LPCM_AUDIO_ES;
p_es->b_audio = 1;
p_es->i_cat = AUDIO_ES;
strcpy( p_es->psz_desc, DecodeLanguage( hton16(
vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) );
strcat( p_es->psz_desc, " (lpcm)" );
break;
case 0x06: /* DTS */
i_id = ( ( 0x88 + audio_status.i_position ) << 8 ) | 0xbd;
intf_ErrMsg( "dvd warning: DTS audio not handled yet"
"(0x%x)", i_id );
break;
default:
i_id = 0;
intf_ErrMsg( "dvd warning: unknown audio type %.2x",
vts.manager_inf.p_audio_attr[i-1].i_coding_mode );
}
}
}
}
#undef audio_status
/*****************************************************************************
* DVDReadSPU: Read subpictures ES
*****************************************************************************/
#define spu_status \
vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_spu_status[i-1]
void DVDReadSPU( input_thread_t * p_input )
{
thread_dvd_data_t * p_dvd;
es_descriptor_t * p_es;
int i_id;
int i;
p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
for( i = 1 ; i <= vts.manager_inf.i_spu_nb; i++ )
{
IfoPrintSpu( p_dvd, i );
if( spu_status.i_available )
{
p_dvd->i_spu_nb++;
/* there are several streams for one spu */
if( vts.manager_inf.video_attr.i_ratio )
{
/* 16:9 */
switch( vts.manager_inf.video_attr.i_perm_displ )
{
case 1:
i_id = ( ( 0x20 + spu_status.i_position_pan ) << 8 )
| 0xbd;
break;
case 2:
i_id = ( ( 0x20 + spu_status.i_position_letter ) << 8 )
| 0xbd;
break;
default:
i_id = ( ( 0x20 + spu_status.i_position_wide ) << 8 )
| 0xbd;
break;
}
}
else
{
/* 4:3 */
i_id = ( ( 0x20 + spu_status.i_position_43 ) << 8 )
| 0xbd;
}
p_es = input_AddES( p_input, NULL, i_id, 0 );
p_es->i_stream_id = 0xbd;
p_es->i_type = DVD_SPU_ES;
p_es->i_cat = SPU_ES;
strcpy( p_es->psz_desc, DecodeLanguage( hton16(
vts.manager_inf.p_spu_attr[i-1].i_lang_code ) ) );
}
}
}
#undef spu_status
#undef vts
#undef vmg
/*****************************************************************************
* DVDLaunchDecoders
*****************************************************************************/
void DVDLaunchDecoders( input_thread_t * p_input )
{
thread_dvd_data_t * p_dvd;
int i_audio;
int i_spu;
p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
/* Select Video stream (always 0) */
if( p_main->b_video )
{
input_SelectES( p_input, p_input->stream.pp_es[0] );
}
/* Select audio stream */
if( p_main->b_audio )
{
/* For audio: first one if none or a not existing one specified */
i_audio = config_GetIntVariable( INPUT_CHANNEL_VAR );
if( i_audio < 0 || i_audio > p_dvd->i_audio_nb )
{
config_PutIntVariable( INPUT_CHANNEL_VAR, 1 );
i_audio = 1;
}
if( i_audio > 0 && p_dvd->i_audio_nb > 0 )
{
if( config_GetIntVariable( AOUT_SPDIF_VAR ) ||
( config_GetIntVariable( INPUT_AUDIO_VAR ) ==
REQUESTED_AC3 ) )
{
int i_ac3 = i_audio;
while( ( p_input->stream.pp_es[i_ac3]->i_type !=
AC3_AUDIO_ES ) && ( i_ac3 <=
p_dvd->p_ifo->vts.manager_inf.i_audio_nb ) )
{
i_ac3++;
}
if( p_input->stream.pp_es[i_ac3]->i_type == AC3_AUDIO_ES )
{
input_SelectES( p_input,
p_input->stream.pp_es[i_ac3] );
}
}
else
{
input_SelectES( p_input,
p_input->stream.pp_es[i_audio] );
}
}
}
/* Select subtitle */
if( p_main->b_video )
{
/* for spu, default is none */
i_spu = config_GetIntVariable( INPUT_SUBTITLE_VAR );
if( i_spu < 0 || i_spu > p_dvd->i_spu_nb )
{
config_PutIntVariable( INPUT_SUBTITLE_VAR, 0 );
i_spu = 0;
}
if( i_spu > 0 && p_dvd->i_spu_nb > 0 )
{
i_spu += p_dvd->p_ifo->vts.manager_inf.i_audio_nb;
input_SelectES( p_input, p_input->stream.pp_es[i_spu] );
}
}
}
/* dvd_es.h: functions to find and select ES
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: dvd_es.h,v 1.1 2002/03/06 01:20:56 stef Exp $
*
* Author: Stéphane 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.
*****************************************************************************/
void DVDLaunchDecoders ( input_thread_t * );
void DVDReadVideo ( input_thread_t * );
void DVDReadAudio ( input_thread_t * );
void DVDReadSPU ( input_thread_t * );
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* dvd_ifo.c: Functions for ifo parsing * dvd_ifo.c: Functions for ifo parsing
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: dvd_ifo.c,v 1.43 2001/12/30 07:09:55 sam Exp $ * $Id: dvd_ifo.c,v 1.44 2002/03/06 01:20:56 stef Exp $
* *
* Authors: Stphane Borel <stef@via.ecp.fr> * Authors: Stphane Borel <stef@via.ecp.fr>
* German Tischler <tanis@gaspode.franken.de> * German Tischler <tanis@gaspode.franken.de>
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
# include <videolan/dvdcss.h> # include <videolan/dvdcss.h>
#endif #endif
#include "input_dvd.h" #include "dvd.h"
#include "dvd_ifo.h" #include "dvd_ifo.h"
#include "dvd_udf.h" #include "dvd_udf.h"
......
/* dvd_seek.c: functions to navigate through DVD.
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: dvd_seek.c,v 1.1 2002/03/06 01:20:56 stef Exp $
*
* Author: Stphane 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 <string.h>
#include <videolan/vlc.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
#ifdef STRNCASECMP_IN_STRINGS_H
# include <strings.h>
#endif
#ifdef GOD_DAMN_DMCA
# include "dummy_dvdcss.h"
#else
# include <videolan/dvdcss.h>
#endif
#include "stream_control.h"
#include "input_ext-intf.h"
#include "input_ext-dec.h"
#include "input_ext-plugins.h"
#include "dvd.h"
#include "dvd_seek.h"
#include "dvd_ifo.h"
#include "debug.h"
#define title \
p_dvd->p_ifo->vts.title_unit.p_title[p_dvd->i_title_id-1].title
#define cell p_dvd->p_ifo->vts.cell_inf
/*****************************************************************************
* DVDFindCell: adjust the title cell index with the program cell
*****************************************************************************/
int DVDFindCell( thread_dvd_data_t * p_dvd )
{
int i_cell;
int i_index;
i_cell = p_dvd->i_cell;
i_index = p_dvd->i_prg_cell;
if( i_cell >= cell.i_cell_nb )
{
return -1;
}
while( ( ( title.p_cell_pos[i_index].i_vob_id !=
cell.p_cell_map[i_cell].i_vob_id ) ||
( title.p_cell_pos[i_index].i_cell_id !=
cell.p_cell_map[i_cell].i_cell_id ) ) &&
( i_cell < cell.i_cell_nb - 1 ) )
{
i_cell++;
}
/*
intf_WarnMsg( 12, "FindCell: i_cell %d i_index %d found %d nb %d",
p_dvd->i_cell,
p_dvd->i_prg_cell,
i_cell,
cell.i_cell_nb );
*/
p_dvd->i_cell = i_cell;
return 0;
}
#undef cell
/*****************************************************************************
* DVDFindSector: find cell index in adress map from index in
* information table program map and give corresponding sectors.
*****************************************************************************/
int DVDFindSector( thread_dvd_data_t * p_dvd )
{
if( p_dvd->i_sector > title.p_cell_play[p_dvd->i_prg_cell].i_end_sector )
{
p_dvd->i_prg_cell++;
if( DVDChooseAngle( p_dvd ) < 0 )
{
return -1;
}
}
if( DVDFindCell( p_dvd ) < 0 )
{
intf_ErrMsg( "dvd error: can't find sector" );
return -1;
}
/* Find start and end sectors of new cell */
#if 1
p_dvd->i_sector = __MAX(
p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_start_sector,
title.p_cell_play[p_dvd->i_prg_cell].i_start_sector );
p_dvd->i_end_sector = __MIN(
p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector,
title.p_cell_play[p_dvd->i_prg_cell].i_end_sector );
#else
p_dvd->i_sector = title.p_cell_play[p_dvd->i_prg_cell].i_start_sector;
p_dvd->i_end_sector = title.p_cell_play[p_dvd->i_prg_cell].i_end_sector;
#endif
/*
intf_WarnMsg( 12, "cell: %d sector1: 0x%x end1: 0x%x\n"
"index: %d sector2: 0x%x end2: 0x%x\n"
"category: 0x%x ilvu end: 0x%x vobu start 0x%x",
p_dvd->i_cell,
p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_start_sector,
p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector,
p_dvd->i_prg_cell,
title.p_cell_play[p_dvd->i_prg_cell].i_start_sector,
title.p_cell_play[p_dvd->i_prg_cell].i_end_sector,
title.p_cell_play[p_dvd->i_prg_cell].i_category,
title.p_cell_play[p_dvd->i_prg_cell].i_first_ilvu_vobu_esector,
title.p_cell_play[p_dvd->i_prg_cell].i_last_vobu_start_sector );
*/
return 0;
}
/*****************************************************************************
* DVDChapterSelect: find the cell corresponding to requested chapter
*****************************************************************************/
int DVDChapterSelect( thread_dvd_data_t * p_dvd, int i_chapter )
{
/* Find cell index in Program chain for current chapter */
p_dvd->i_prg_cell = title.chapter_map.pi_start_cell[i_chapter-1] - 1;
p_dvd->i_cell = 0;
p_dvd->i_sector = 0;
DVDChooseAngle( p_dvd );
/* Search for cell_index in cell adress_table and initialize
* start sector */
if( DVDFindSector( p_dvd ) < 0 )
{
intf_ErrMsg( "dvd error: can't select chapter" );
return -1;
}
/* start is : beginning of vts vobs + offset to vob x */
p_dvd->i_start = p_dvd->i_title_start + p_dvd->i_sector;
/* Position the fd pointer on the right address */
if( ( p_dvd->i_start = dvdcss_seek( p_dvd->dvdhandle,
p_dvd->i_start,
DVDCSS_SEEK_MPEG ) ) < 0 )
{
intf_ErrMsg( "dvd error: %s", dvdcss_error( p_dvd->dvdhandle ) );
return -1;
}
p_dvd->i_chapter = i_chapter;
return 0;
}
/*****************************************************************************
* DVDChooseAngle: select the cell corresponding to the selected angle
*****************************************************************************/
int DVDChooseAngle( thread_dvd_data_t * p_dvd )
{
/* basic handling of angles */
switch( ( ( title.p_cell_play[p_dvd->i_prg_cell].i_category & 0xf000 )
>> 12 ) )
{
/* we enter a muli-angle section */
case 0x5:
p_dvd->i_prg_cell += p_dvd->i_angle - 1;
p_dvd->i_angle_cell = 0;
break;
/* we exit a multi-angle section */
case 0x9:
case 0xd:
p_dvd->i_prg_cell += p_dvd->i_angle_nb - p_dvd->i_angle;
break;
}
return 0;
}
#undef title
/* dvd_seek.h: DVD access plugin.
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: dvd_seek.h,v 1.1 2002/03/06 01:20:56 stef Exp $
*
* Author: Stéphane 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.
*****************************************************************************/
int DVDChooseAngle( thread_dvd_data_t * );
int DVDFindCell( thread_dvd_data_t * );
int DVDFindSector( thread_dvd_data_t * );
int DVDChapterSelect( thread_dvd_data_t *, int );
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* found in .ifo. * found in .ifo.
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * Copyright (C) 1998-2001 VideoLAN
* $Id: dvd_summary.c,v 1.13 2002/03/05 17:46:33 stef Exp $ * $Id: dvd_summary.c,v 1.14 2002/03/06 01:20:56 stef Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
# include <videolan/dvdcss.h> # include <videolan/dvdcss.h>
#endif #endif
#include "input_dvd.h" #include "dvd.h"
#include "dvd_ifo.h" #include "dvd_ifo.h"
#include "iso_lang.h" #include "iso_lang.h"
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* contains the basic udf handling functions * contains the basic udf handling functions
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * Copyright (C) 1998-2001 VideoLAN
* $Id: dvd_udf.c,v 1.18 2001/12/30 07:09:55 sam Exp $ * $Id: dvd_udf.c,v 1.19 2002/03/06 01:20:56 stef Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
# include <videolan/dvdcss.h> # include <videolan/dvdcss.h>
#endif #endif
#include "input_dvd.h" #include "dvd.h"
#include "dvd_ifo.h" #include "dvd_ifo.h"
#define UDFADshort 1 #define UDFADshort 1
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* It depends on: libdvdread for ifo files and block reading. * It depends on: libdvdread for ifo files and block reading.
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: input_dvdread.c,v 1.29 2002/03/05 17:46:33 stef Exp $ * $Id: input_dvdread.c,v 1.30 2002/03/06 01:20:56 stef Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -609,14 +609,14 @@ static int DvdReadSetArea( input_thread_t * p_input, input_area_t * p_area ) ...@@ -609,14 +609,14 @@ static int DvdReadSetArea( input_thread_t * p_input, input_area_t * p_area )
/* We don't use input_EndStream here since /* We don't use input_EndStream here since
* we keep area structures */ * we keep area structures */
for( i = 0 ; i < p_input->stream.i_es_number ; i++ ) while( p_input->stream.i_es_number )
{ {
input_DelES( p_input, p_input->stream.pp_es[i] ); input_DelES( p_input, p_input->stream.pp_es[0] );
} }
for( i = 0 ; i < p_input->stream.i_pgrm_number ; i++ ) while( p_input->stream.i_pgrm_number )
{ {
input_DelProgram( p_input, p_input->stream.pp_programs[i] ); input_DelProgram( p_input, p_input->stream.pp_programs[0] );
} }
if( p_input->stream.pp_selected_es ) if( p_input->stream.pp_selected_es )
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* gtk_display.c: Gtk+ tools for main interface * gtk_display.c: Gtk+ tools for main interface
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: gtk_display.c,v 1.17 2002/03/05 17:46:33 stef Exp $ * $Id: gtk_display.c,v 1.18 2002/03/06 01:20:56 stef Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* Stphane Borel <stef@via.ecp.fr> * Stphane Borel <stef@via.ecp.fr>
...@@ -216,13 +216,11 @@ gint GtkModeManage( intf_thread_t * p_intf ) ...@@ -216,13 +216,11 @@ gint GtkModeManage( intf_thread_t * p_intf )
gtk_widget_set_sensitive( GETWIDGET(p_window,"menubar_title"), FALSE ); gtk_widget_set_sensitive( GETWIDGET(p_window,"menubar_title"), FALSE );
gtk_widget_set_sensitive( GETWIDGET(p_window,"menubar_chapter"), gtk_widget_set_sensitive( GETWIDGET(p_window,"menubar_chapter"),
FALSE ); FALSE );
gtk_widget_set_sensitive( GETWIDGET(p_window,"menubar_angle"), FALSE );
gtk_widget_set_sensitive( GETWIDGET(p_window,"menubar_audio"), FALSE ); gtk_widget_set_sensitive( GETWIDGET(p_window,"menubar_audio"), FALSE );
gtk_widget_set_sensitive( GETWIDGET(p_window,"menubar_subpictures"), gtk_widget_set_sensitive( GETWIDGET(p_window,"menubar_subpictures"),
FALSE ); FALSE );
gtk_widget_set_sensitive( GETWIDGET(p_popup,"popup_navigation"), gtk_widget_set_sensitive( GETWIDGET(p_popup,"popup_navigation"),
FALSE ); FALSE );
gtk_widget_set_sensitive( GETWIDGET(p_popup,"popup_angle"), FALSE );
gtk_widget_set_sensitive( GETWIDGET(p_popup,"popup_audio"), FALSE ); gtk_widget_set_sensitive( GETWIDGET(p_popup,"popup_audio"), FALSE );
gtk_widget_set_sensitive( GETWIDGET(p_popup,"popup_subpictures"), gtk_widget_set_sensitive( GETWIDGET(p_popup,"popup_subpictures"),
FALSE ); FALSE );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* gtk_menu.c : functions to handle menu items. * gtk_menu.c : functions to handle menu items.
***************************************************************************** *****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN * Copyright (C) 2000, 2001 VideoLAN
* $Id: gtk_menu.c,v 1.21 2002/03/05 17:46:33 stef Exp $ * $Id: gtk_menu.c,v 1.22 2002/03/06 01:20:56 stef Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* Stphane Borel <stef@via.ecp.fr> * Stphane Borel <stef@via.ecp.fr>
...@@ -70,8 +70,6 @@ static gint GtkTitleMenu( gpointer, GtkWidget *, ...@@ -70,8 +70,6 @@ static gint GtkTitleMenu( gpointer, GtkWidget *,
static gint GtkRadioMenu( intf_thread_t *, GtkWidget *, GSList *, static gint GtkRadioMenu( intf_thread_t *, GtkWidget *, GSList *,
char *, int, int, char *, int, int,
void( *pf_toggle )( GtkCheckMenuItem *, gpointer ) ); void( *pf_toggle )( GtkCheckMenuItem *, gpointer ) );
void GtkMenubarAngleToggle( GtkCheckMenuItem *, gpointer );
void GtkPopupAngleToggle( GtkCheckMenuItem *, gpointer );
gint GtkSetupMenus( intf_thread_t * p_intf ); gint GtkSetupMenus( intf_thread_t * p_intf );
...@@ -279,49 +277,6 @@ void GtkMenubarChapterToggle( GtkCheckMenuItem * menuitem, gpointer user_data ) ...@@ -279,49 +277,6 @@ void GtkMenubarChapterToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
} }
/*
* Angle
*/
#if 0
#define GTKANGLETOGGLE( intf, window, menu, callback ) \
intf_thread_t * p_intf; \
GtkWidget * p_menu; \
input_area_t * p_area; \
\
p_intf = GetIntf( GTK_WIDGET(menuitem), (intf) ); \
\
if( menuitem->active && !p_intf->p_sys->b_angle_update ) \
{ \
p_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( \
p_intf->p_sys->window ), (menu) ) ); \
p_area = p_input_bank->pp_input[0]->stream.p_selected_area; \
p_area->i_angle = (gint)((long)user_data); \
\
input_ChangeArea( p_input_bank->pp_input[0], (input_area_t*)p_area ); \
\
p_intf->p_sys->b_angle_update = 1; \
vlc_mutex_lock( &p_input_bank->pp_input[0]->stream.stream_lock ); \
GtkRadioMenu( p_intf, p_menu, NULL, "Angle", \
p_area->i_angle_nb, p_area->i_angle, (callback) ); \
vlc_mutex_unlock( &p_input_bank->pp_input[0]->stream.stream_lock ); \
p_intf->p_sys->b_angle_update = 0; \
}
void GtkMenubarAngleToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
{
GTKANGLETOGGLE( "intf_window", p_popup, "popup_angle",
GtkPopupAngleToggle );
}
void GtkPopupAngleToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
{
GTKANGLETOGGLE( "intf_popup", p_window, "menubar_angle",
GtkMenubarAngleToggle );
}
#undef GTKANGLETOGGLE
#endif
/**************************************************************************** /****************************************************************************
* Functions to generate menus * Functions to generate menus
****************************************************************************/ ****************************************************************************/
...@@ -539,10 +494,10 @@ static gint GtkProgramMenu( gpointer p_data, ...@@ -539,10 +494,10 @@ static gint GtkProgramMenu( gpointer p_data,
* function, the interface lock has to be taken * function, the interface lock has to be taken
*****************************************************************************/ *****************************************************************************/
static gint GtkLanguageMenus( gpointer p_data, static gint GtkLanguageMenus( gpointer p_data,
GtkWidget * p_root, GtkWidget * p_root,
es_descriptor_t * p_es, es_descriptor_t * p_es,
gint i_cat, gint i_cat,
void(*pf_toggle )( GtkCheckMenuItem *, gpointer ) ) void(*pf_toggle )( GtkCheckMenuItem *, gpointer ) )
{ {
intf_thread_t * p_intf; intf_thread_t * p_intf;
GtkWidget * p_menu; GtkWidget * p_menu;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* vcd.c : VCD input module for vlc * vcd.c : VCD input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2000 VideoLAN * Copyright (C) 2000 VideoLAN
* $Id: vcd.c,v 1.6 2002/03/05 23:29:36 jobi Exp $ * $Id: vcd.c,v 1.7 2002/03/06 01:20:56 stef Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -43,8 +43,8 @@ MODULE_CONFIG_STOP ...@@ -43,8 +43,8 @@ MODULE_CONFIG_STOP
MODULE_INIT_START MODULE_INIT_START
SET_DESCRIPTION( "VCD input module" ) SET_DESCRIPTION( "VCD input module" )
ADD_CAPABILITY( DEMUX, 205 ) ADD_CAPABILITY( DEMUX, 180 )
ADD_CAPABILITY( ACCESS, 105 ) ADD_CAPABILITY( ACCESS, 80 )
ADD_SHORTCUT( "vcd" ) ADD_SHORTCUT( "vcd" )
MODULE_INIT_STOP MODULE_INIT_STOP
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* decoders. * decoders.
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * Copyright (C) 1998-2001 VideoLAN
* $Id: input.c,v 1.186 2002/03/05 06:48:33 gbazin Exp $ * $Id: input.c,v 1.187 2002/03/06 01:20:56 stef Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* Alexis Guillard <alexis.guillard@bt.com> * Alexis Guillard <alexis.guillard@bt.com>
...@@ -188,7 +188,7 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status ) ...@@ -188,7 +188,7 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status )
p_input->stream.control.i_rate = DEFAULT_RATE; p_input->stream.control.i_rate = DEFAULT_RATE;
p_input->stream.control.b_mute = 0; p_input->stream.control.b_mute = 0;
p_input->stream.control.b_grayscale = config_GetIntVariable( p_input->stream.control.b_grayscale = config_GetIntVariable(
VOUT_GRAYSCALE_VAR ); VOUT_GRAYSCALE_VAR );
p_input->stream.control.i_smp = config_GetIntVariable( VDEC_SMP_VAR ); p_input->stream.control.i_smp = config_GetIntVariable( VDEC_SMP_VAR );
intf_WarnMsg( 1, "input: playlist item `%s'", p_input->psz_source ); intf_WarnMsg( 1, "input: playlist item `%s'", p_input->psz_source );
...@@ -444,7 +444,7 @@ static int InitThread( input_thread_t * p_input ) ...@@ -444,7 +444,7 @@ static int InitThread( input_thread_t * p_input )
{ {
intf_WarnMsg( 2, "Drive letter %c: specified in source string", intf_WarnMsg( 2, "Drive letter %c: specified in source string",
p_input->psz_source ) ; p_input->psz_source ) ;
psz_parser = ""; psz_parser = "";
} }
#endif #endif
...@@ -462,7 +462,7 @@ static int InitThread( input_thread_t * p_input ) ...@@ -462,7 +462,7 @@ static int InitThread( input_thread_t * p_input )
/* Come back to parse the access and demux plug-ins */ /* Come back to parse the access and demux plug-ins */
psz_parser = p_input->psz_source; psz_parser = p_input->psz_source;
if( !*psz_parser ) if( !*psz_parser )
{ {
/* No access */ /* No access */
p_input->psz_access = NULL; p_input->psz_access = NULL;
......
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