Commit 0925ed0b authored by Laurent Aimar's avatar Laurent Aimar

* src/video_output/video_output.c : do not use FIND_ANYWHERE to catch

 the playlist.  but use FIND_PARENT. vlc_object_find  with FIND_ANYWHERE
 use p_obj->p_vlc as a starting point  and that doesn't work as playlist
 is  detach from  vlc before  vout is  destroyed by  the decoders  (when
 shutting down)  Perhaps vlc_object_find  should be  fixing to  find the
 root object, but I'm not sure.

 * src/input/*  : move  subtitle handling  from avi  to input.  Now subs
 should works with all file types _BUT_ won't be in synch if the demuxer
 doesn't implement a _precise_ DEMUX_GET_TIME.  So only .avi, .mp4 will
 be ok. Others could works if perfectly cbr.
  Now  Subtitle  track is  only  selected  when specified  by  sub-file
 option.(auto-dectected file is always added but not selected by default)
  Btw, the code could support multiple  subs files, but I don't know how
 to pass multiple filenames, any ideas ?


 * demux/mpeg/mpga.c : play with es_out_t. I'm investigating for now so
 don't use that elsewhere.
parent a903f128
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* control the pace of reading. * control the pace of reading.
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ext-intf.h,v 1.95 2003/09/12 18:34:44 fenrir Exp $ * $Id: input_ext-intf.h,v 1.96 2003/09/13 17:42:15 fenrir Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -346,6 +346,9 @@ struct input_thread_t ...@@ -346,6 +346,9 @@ struct input_thread_t
char * psz_name; char * psz_name;
count_t c_loops; count_t c_loops;
/* private, do not touch it */
input_thread_sys_t *p_sys;
}; };
/* Input methods */ /* Input methods */
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ninput.h * ninput.h
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: ninput.h,v 1.10 2003/09/12 18:34:44 fenrir Exp $ * $Id: ninput.h,v 1.11 2003/09/13 17:42:15 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -36,9 +36,9 @@ typedef struct ...@@ -36,9 +36,9 @@ typedef struct
int i_cat; int i_cat;
vlc_fourcc_t i_codec; vlc_fourcc_t i_codec;
int i_group; /* eg -1. if >= 0 then a "group" (program) is int i_group; /* -1 : standalone
created for each value */ >= 0 then a "group" (program) is created
for each value */
int i_priority; /* -2 : mean not selectable by the users int i_priority; /* -2 : mean not selectable by the users
-1 : mean not selected by default even -1 : mean not selected by default even
when no other stream when no other stream
...@@ -78,7 +78,7 @@ static inline void es_format_Init( es_format_t *fmt, ...@@ -78,7 +78,7 @@ static inline void es_format_Init( es_format_t *fmt,
{ {
fmt->i_cat = i_cat; fmt->i_cat = i_cat;
fmt->i_codec = i_codec; fmt->i_codec = i_codec;
fmt->i_group = -1; fmt->i_group = 0;
fmt->i_priority = 0; fmt->i_priority = 0;
fmt->psz_language = NULL; fmt->psz_language = NULL;
fmt->psz_description = NULL; fmt->psz_description = NULL;
...@@ -213,7 +213,9 @@ enum demux_query_e ...@@ -213,7 +213,9 @@ enum demux_query_e
DEMUX_GET_TIME, /* arg1= int64_t * res= */ DEMUX_GET_TIME, /* arg1= int64_t * res= */
DEMUX_SET_TIME, /* arg1= int64_t res=can fail */ DEMUX_SET_TIME, /* arg1= int64_t res=can fail */
DEMUX_GET_LENGTH /* arg1= int64_t * res=can fail */ DEMUX_GET_LENGTH, /* arg1= int64_t * res=can fail */
DEMUX_GET_FPS /* arg1= float * res=can fail */
}; };
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* Collection of useful common types and macros definitions * Collection of useful common types and macros definitions
***************************************************************************** *****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN * Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: vlc_common.h,v 1.77 2003/09/12 18:34:44 fenrir Exp $ * $Id: vlc_common.h,v 1.78 2003/09/13 17:42:15 fenrir Exp $
* *
* Authors: Samuel Hocevar <sam@via.ecp.fr> * Authors: Samuel Hocevar <sam@via.ecp.fr>
* Vincent Seguin <seguin@via.ecp.fr> * Vincent Seguin <seguin@via.ecp.fr>
...@@ -211,6 +211,7 @@ typedef struct intf_channel_t intf_channel_t; ...@@ -211,6 +211,7 @@ typedef struct intf_channel_t intf_channel_t;
/* Input */ /* Input */
typedef struct input_thread_t input_thread_t; typedef struct input_thread_t input_thread_t;
typedef struct input_thread_sys_t input_thread_sys_t;
typedef struct input_channel_t input_channel_t; typedef struct input_channel_t input_channel_t;
typedef struct input_area_t input_area_t; typedef struct input_area_t input_area_t;
typedef struct input_buffers_t input_buffers_t; typedef struct input_buffers_t input_buffers_t;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* avi.c : AVI file Stream input module for vlc * avi.c : AVI file Stream input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: avi.c,v 1.61 2003/09/12 16:26:40 fenrir Exp $ * $Id: avi.c,v 1.62 2003/09/13 17:42:15 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -29,8 +29,6 @@ ...@@ -29,8 +29,6 @@
#include <vlc/input.h> #include <vlc/input.h>
#include "codecs.h" #include "codecs.h"
#include "../util/sub.h"
#include "libavi.h" #include "libavi.h"
#include "avi.h" #include "avi.h"
...@@ -123,7 +121,6 @@ static int Open( vlc_object_t * p_this ) ...@@ -123,7 +121,6 @@ static int Open( vlc_object_t * p_this )
demux_sys_t *p_avi; demux_sys_t *p_avi;
es_descriptor_t *p_es = NULL; /* avoid warning */ es_descriptor_t *p_es = NULL; /* avoid warning */
unsigned int i; unsigned int i;
mtime_t i_microsecperframe = 0; // for some subtitle format
vlc_bool_t b_stream_audio, b_stream_video; vlc_bool_t b_stream_audio, b_stream_video;
uint8_t *p_peek; uint8_t *p_peek;
...@@ -377,12 +374,6 @@ static int Open( vlc_object_t * p_this ) ...@@ -377,12 +374,6 @@ static int Open( vlc_object_t * p_this )
input_AddInfo( p_cat, _("Bits Per Pixel"), "%d", input_AddInfo( p_cat, _("Bits Per Pixel"), "%d",
p_avi_strf_vids->p_bih->biBitCount ); p_avi_strf_vids->p_bih->biBitCount );
} }
if( i_microsecperframe == 0 )
{
i_microsecperframe = (mtime_t)1000000 *
(mtime_t)p_info->i_scale /
(mtime_t)p_info->i_rate;
}
break; break;
default: default:
msg_Warn( p_input, "stream[%d] unknown type", i ); msg_Warn( p_input, "stream[%d] unknown type", i );
...@@ -424,11 +415,6 @@ static int Open( vlc_object_t * p_this ) ...@@ -424,11 +415,6 @@ static int Open( vlc_object_t * p_this )
#undef p_info #undef p_info
} }
if( ( p_avi->p_sub = subtitle_New( p_input, NULL, i_microsecperframe ) ) )
{
subtitle_Select( p_avi->p_sub );
}
if( config_GetInt( p_input, "avi-index" ) ) if( config_GetInt( p_input, "avi-index" ) )
{ {
if( p_avi->b_seekable ) if( p_avi->b_seekable )
...@@ -572,10 +558,6 @@ static void Close ( vlc_object_t * p_this ) ...@@ -572,10 +558,6 @@ static void Close ( vlc_object_t * p_this )
} }
} }
FREE( p_avi->pp_info ); FREE( p_avi->pp_info );
if( p_avi->p_sub )
{
subtitle_Close( p_avi->p_sub );
}
AVI_ChunkFreeRoot( p_input->s, &p_avi->ck_root ); AVI_ChunkFreeRoot( p_input->s, &p_avi->ck_root );
free( p_avi ); free( p_avi );
...@@ -658,11 +640,6 @@ static int Demux_Seekable( input_thread_t *p_input ) ...@@ -658,11 +640,6 @@ static int Demux_Seekable( input_thread_t *p_input )
p_avi->i_time += 25*1000; /* read 25ms */ p_avi->i_time += 25*1000; /* read 25ms */
if( p_avi->p_sub )
{
subtitle_Demux( p_avi->p_sub, p_avi->i_time );
}
/* Check if we need to send the audio data to decoder */ /* Check if we need to send the audio data to decoder */
b_play_audio = !p_input->stream.control.b_mute; b_play_audio = !p_input->stream.control.b_mute;
...@@ -1227,6 +1204,7 @@ static int Seek( input_thread_t *p_input, mtime_t i_date, int i_percent ) ...@@ -1227,6 +1204,7 @@ static int Seek( input_thread_t *p_input, mtime_t i_date, int i_percent )
static int Control( input_thread_t *p_input, int i_query, va_list args ) static int Control( input_thread_t *p_input, int i_query, va_list args )
{ {
demux_sys_t *p_sys = p_input->p_demux_data; demux_sys_t *p_sys = p_input->p_demux_data;
int i;
double f, *pf; double f, *pf;
int64_t i64, *pi64; int64_t i64, *pi64;
...@@ -1276,10 +1254,6 @@ static int Control( input_thread_t *p_input, int i_query, va_list args ) ...@@ -1276,10 +1254,6 @@ static int Control( input_thread_t *p_input, int i_query, va_list args )
f = (double)va_arg( args, double ); f = (double)va_arg( args, double );
i64 = (mtime_t)(1000000.0 * p_sys->i_length * f ); i64 = (mtime_t)(1000000.0 * p_sys->i_length * f );
i_ret = Seek( p_input, i64, (int)(f * 100) ); i_ret = Seek( p_input, i64, (int)(f * 100) );
if( p_sys->p_sub )
{
subtitle_Seek( p_sys->p_sub, p_sys->i_time );
}
return i_ret; return i_ret;
} }
else else
...@@ -1301,6 +1275,21 @@ static int Control( input_thread_t *p_input, int i_query, va_list args ) ...@@ -1301,6 +1275,21 @@ static int Control( input_thread_t *p_input, int i_query, va_list args )
*pi64 = p_sys->i_length * (mtime_t)1000000; *pi64 = p_sys->i_length * (mtime_t)1000000;
return VLC_SUCCESS; return VLC_SUCCESS;
case DEMUX_GET_FPS:
pf = (double*)va_arg( args, double * );
*pf = 0.0;
for( i = 0; i < (int)p_sys->i_streams; i++ )
{
#define tk p_sys->pp_info[i]
if( tk->i_cat == VIDEO_ES && tk->i_scale > 0)
{
*pf = (float)tk->i_rate / (float)tk->i_scale;
break;
}
#undef tk
}
return VLC_SUCCESS;
default: default:
return demux_vaControlDefault( p_input, i_query, args ); return demux_vaControlDefault( p_input, i_query, args );
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* avi.h : AVI file Stream input module for vlc * avi.h : AVI file Stream input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: avi.h,v 1.14 2003/09/12 16:26:40 fenrir Exp $ * $Id: avi.h,v 1.15 2003/09/13 17:42:15 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -85,7 +85,5 @@ struct demux_sys_t ...@@ -85,7 +85,5 @@ struct demux_sys_t
/* number of streams and information */ /* number of streams and information */
unsigned int i_streams; unsigned int i_streams;
avi_stream_t **pp_info; avi_stream_t **pp_info;
subtitle_demux_t *p_sub;
}; };
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* mp4.c : MP4 file input module for vlc * mp4.c : MP4 file input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: mp4.c,v 1.37 2003/09/12 16:26:40 fenrir Exp $ * $Id: mp4.c,v 1.38 2003/09/13 17:42:16 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -618,7 +618,9 @@ static int Control ( input_thread_t *p_input, int i_query, va_list args ) ...@@ -618,7 +618,9 @@ static int Control ( input_thread_t *p_input, int i_query, va_list args )
(mtime_t)p_sys->i_duration / (mtime_t)p_sys->i_duration /
(mtime_t)p_sys->i_timescale; (mtime_t)p_sys->i_timescale;
return VLC_SUCCESS; return VLC_SUCCESS;
case DEMUX_GET_FPS:
msg_Warn( p_input, "DEMUX_GET_FPS unimplemented !!" );
return VLC_EGENERIC;
default: default:
msg_Err( p_input, "control query unimplemented !!!" ); msg_Err( p_input, "control query unimplemented !!!" );
return demux_vaControlDefault( p_input, i_query, args ); return demux_vaControlDefault( p_input, i_query, args );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* mpga.c : MPEG-I/II Audio input module for vlc * mpga.c : MPEG-I/II Audio input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: mpga.c,v 1.5 2003/09/12 16:26:40 fenrir Exp $ * $Id: mpga.c,v 1.6 2003/09/13 17:42:16 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -57,7 +57,9 @@ struct demux_sys_t ...@@ -57,7 +57,9 @@ struct demux_sys_t
mtime_t i_time; mtime_t i_time;
int i_bitrate_avg; /* extracted from Xing header */ int i_bitrate_avg; /* extracted from Xing header */
es_descriptor_t *p_es; es_out_id_t *p_es;
//es_descriptor_t *p_es;
}; };
static int HeaderCheck( uint32_t h ) static int HeaderCheck( uint32_t h )
...@@ -173,6 +175,8 @@ static int Open( vlc_object_t * p_this ) ...@@ -173,6 +175,8 @@ static int Open( vlc_object_t * p_this )
module_t *p_id3; module_t *p_id3;
es_format_t fmt;
if( p_input->psz_demux && if( p_input->psz_demux &&
( !strncmp( p_input->psz_demux, "mpga", 4 ) || ( !strncmp( p_input->psz_demux, "mpga", 4 ) ||
...@@ -334,28 +338,11 @@ static int Open( vlc_object_t * p_this ) ...@@ -334,28 +338,11 @@ static int Open( vlc_object_t * p_this )
msg_Err( p_input, "cannot init stream" ); msg_Err( p_input, "cannot init stream" );
goto error; goto error;
} }
if( input_AddProgram( p_input, 0, 0) == NULL )
{
vlc_mutex_unlock( &p_input->stream.stream_lock );
msg_Err( p_input, "cannot add program" );
goto error;
}
p_input->stream.pp_programs[0]->b_is_ok = 0;
p_input->stream.p_selected_program = p_input->stream.pp_programs[0];
p_input->stream.i_mux_rate = p_sys->i_bitrate_avg / 8 / 50; p_input->stream.i_mux_rate = p_sys->i_bitrate_avg / 8 / 50;
p_sys->p_es = input_AddES( p_input,
p_input->stream.p_selected_program,
1 , AUDIO_ES, NULL, 0 );
p_sys->p_es->i_stream_id = 1;
p_sys->p_es->i_fourcc = VLC_FOURCC( 'm', 'p', 'g', 'a' );
input_SelectES( p_input, p_sys->p_es );
p_input->stream.p_selected_program->b_is_ok = 1;
vlc_mutex_unlock( &p_input->stream.stream_lock ); vlc_mutex_unlock( &p_input->stream.stream_lock );
es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC( 'm', 'p', 'g', 'a' ) );
p_sys->p_es = es_out_Add( p_input->p_es_out, &fmt );
return VLC_SUCCESS; return VLC_SUCCESS;
error: error:
...@@ -431,14 +418,8 @@ static int Demux( input_thread_t * p_input ) ...@@ -431,14 +418,8 @@ static int Demux( input_thread_t * p_input )
p_input->stream.p_selected_program, p_input->stream.p_selected_program,
p_sys->i_time * 9 / 100 ); p_sys->i_time * 9 / 100 );
if( !p_sys->p_es->p_decoder_fifo ) es_out_Send( p_input->p_es_out, p_sys->p_es, p_pes );
{
msg_Err( p_input, "no audio decoder" );
input_DeletePES( p_input->p_method_data, p_pes );
return( -1 );
}
input_DecodePES( p_sys->p_es->p_decoder_fifo, p_pes );
p_sys->i_time += (mtime_t)1000000 * p_sys->i_time += (mtime_t)1000000 *
(mtime_t)mpga_frame_samples( header ) / (mtime_t)mpga_frame_samples( header ) /
(mtime_t)MPGA_SAMPLE_RATE( header ); (mtime_t)MPGA_SAMPLE_RATE( header );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* demux.c * demux.c
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2003 VideoLAN * Copyright (C) 1999-2003 VideoLAN
* $Id: demux.c,v 1.2 2003/09/07 22:51:11 fenrir Exp $ * $Id: demux.c,v 1.3 2003/09/13 17:42:16 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -133,6 +133,9 @@ int demux_vaControlDefault( input_thread_t *p_input, int i_query, va_list args ...@@ -133,6 +133,9 @@ int demux_vaControlDefault( input_thread_t *p_input, int i_query, va_list args
i_ret = VLC_EGENERIC; i_ret = VLC_EGENERIC;
} }
break; break;
case DEMUX_GET_FPS:
i_ret = VLC_EGENERIC;
break;
default: default:
msg_Err( p_input, "unknown query in demux_vaControlDefault !!!" ); msg_Err( p_input, "unknown query in demux_vaControlDefault !!!" );
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* decoders. * decoders.
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2002 VideoLAN * Copyright (C) 1998-2002 VideoLAN
* $Id: input.c,v 1.239 2003/09/12 18:34:45 fenrir Exp $ * $Id: input.c,v 1.240 2003/09/13 17:42:16 fenrir Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -41,10 +41,19 @@ ...@@ -41,10 +41,19 @@
#include "stream_output.h" #include "stream_output.h"
#include "vlc_interface.h" #include "vlc_interface.h"
#include "codecs.h"
#include "modules/demux/util/sub.h"
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
struct input_thread_sys_t
{
/* subtitles */
int i_sub;
subtitle_demux_t **sub;
};
static int RunThread ( input_thread_t *p_input ); static int RunThread ( input_thread_t *p_input );
static int InitThread ( input_thread_t *p_input ); static int InitThread ( input_thread_t *p_input );
static void ErrorThread ( input_thread_t *p_input ); static void ErrorThread ( input_thread_t *p_input );
...@@ -145,6 +154,7 @@ input_thread_t *__input_CreateThread( vlc_object_t *p_parent, ...@@ -145,6 +154,7 @@ input_thread_t *__input_CreateThread( vlc_object_t *p_parent,
/* Initialize thread properties */ /* Initialize thread properties */
p_input->b_eof = 0; p_input->b_eof = 0;
p_input->p_sys = NULL;
/* Set target */ /* Set target */
p_input->psz_source = strdup( p_item->psz_uri ); p_input->psz_source = strdup( p_item->psz_uri );
...@@ -367,6 +377,7 @@ static int RunThread( input_thread_t *p_input ) ...@@ -367,6 +377,7 @@ static int RunThread( input_thread_t *p_input )
if( p_input->stream.p_selected_area->i_size > 0 ) if( p_input->stream.p_selected_area->i_size > 0 )
{ {
unsigned int i; unsigned int i;
mtime_t i_time;
double f = (double)p_input->stream.p_selected_area->i_seek / double f = (double)p_input->stream.p_selected_area->i_seek /
(double)p_input->stream.p_selected_area->i_size; (double)p_input->stream.p_selected_area->i_size;
...@@ -385,6 +396,22 @@ static int RunThread( input_thread_t *p_input ) ...@@ -385,6 +396,22 @@ static int RunThread( input_thread_t *p_input )
/* Reinitialize synchro. */ /* Reinitialize synchro. */
p_pgrm->i_synchro_state = SYNCHRO_REINIT; p_pgrm->i_synchro_state = SYNCHRO_REINIT;
} }
if( !demux_Control( p_input, DEMUX_GET_TIME, &i_time ) )
{
int i;
vlc_value_t val;
/* Help in bar display */
val.i_time = i_time;
var_Change( p_input, "time", VLC_VAR_SETVALUE, &val, NULL );
/* Seek subs */
for( i = 0; i < p_input->p_sys->i_sub; i++ )
{
subtitle_Seek( p_input->p_sys->sub[i], i_time );
}
}
} }
p_input->stream.p_selected_area->i_seek = NO_SEEK; p_input->stream.p_selected_area->i_seek = NO_SEEK;
} }
...@@ -434,24 +461,35 @@ static int RunThread( input_thread_t *p_input ) ...@@ -434,24 +461,35 @@ static int RunThread( input_thread_t *p_input )
if( !p_input->b_error && !p_input->b_eof && i_update_next < mdate() ) if( !p_input->b_error && !p_input->b_eof && i_update_next < mdate() )
{ {
double d; int i;
mtime_t i_time;
mtime_t i_length;
double d_pos;
/* update input status variables */ /* update input status variables */
if( !demux_Control( p_input, DEMUX_GET_POSITION, &d ) ) if( !demux_Control( p_input, DEMUX_GET_POSITION, &d_pos ) )
{ {
val.f_float = (float)d; val.f_float = (float)d_pos;
var_Change( p_input, "position", VLC_VAR_SETVALUE, &val, NULL ); var_Change( p_input, "position", VLC_VAR_SETVALUE, &val, NULL );
} }
if( !demux_Control( p_input, DEMUX_GET_TIME, &val.i_time ) ) if( !demux_Control( p_input, DEMUX_GET_TIME, &i_time ) )
{ {
val.i_time = i_time;
var_Change( p_input, "time", VLC_VAR_SETVALUE, &val, NULL ); var_Change( p_input, "time", VLC_VAR_SETVALUE, &val, NULL );
} }
if( !demux_Control( p_input, DEMUX_GET_LENGTH, &val.i_time ) ) if( !demux_Control( p_input, DEMUX_GET_LENGTH, &i_length ) )
{ {
val.i_time = i_length;
var_Change( p_input, "length", VLC_VAR_SETVALUE, &val, NULL ); var_Change( p_input, "length", VLC_VAR_SETVALUE, &val, NULL );
} }
i_update_next = mdate() + 200000LL; /* update subs */
for( i = 0; i < p_input->p_sys->i_sub; i++ )
{
subtitle_Demux( p_input->p_sys->sub[i], i_time );
}
i_update_next = mdate() + 150000LL;
} }
} }
...@@ -470,9 +508,12 @@ static int RunThread( input_thread_t *p_input ) ...@@ -470,9 +508,12 @@ static int RunThread( input_thread_t *p_input )
*****************************************************************************/ *****************************************************************************/
static int InitThread( input_thread_t * p_input ) static int InitThread( input_thread_t * p_input )
{ {
float f_fps;
/* Parse source string. Syntax : [[<access>][/<demux>]:][<source>] */ /* Parse source string. Syntax : [[<access>][/<demux>]:][<source>] */
char * psz_parser = p_input->psz_dupsource = strdup(p_input->psz_source); char * psz_parser = p_input->psz_dupsource = strdup(p_input->psz_source);
vlc_value_t val; vlc_value_t val;
subtitle_demux_t *p_sub;
int64_t i_microsecondperframe;
/* Skip the plug-in names */ /* Skip the plug-in names */
while( *psz_parser && *psz_parser != ':' ) while( *psz_parser && *psz_parser != ':' )
...@@ -663,6 +704,34 @@ static int InitThread( input_thread_t * p_input ) ...@@ -663,6 +704,34 @@ static int InitThread( input_thread_t * p_input )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
/* Init input_thread_sys_t */
p_input->p_sys = malloc( sizeof( input_thread_sys_t ) );
p_input->p_sys->i_sub = 0;
p_input->p_sys->sub = NULL;
/* get fps */
if( demux_Control( p_input, DEMUX_GET_FPS, &f_fps ) || f_fps < 0.1 )
{
i_microsecondperframe = 0;
}
else
{
i_microsecondperframe = (int64_t)( (double)1000000.0 / (double)f_fps );
}
/* Now add subtitles (for now only one) */
if( ( p_sub = subtitle_New( p_input, NULL, i_microsecondperframe ) ) )
{
TAB_APPEND( p_input->p_sys->i_sub, p_input->p_sys->sub, p_sub );
/* see if it should be selected */
var_Get( p_sub, "sub-file", &val );
if( val.psz_string && *val.psz_string )
{
subtitle_Select( p_sub );
}
}
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -685,6 +754,7 @@ static void ErrorThread( input_thread_t *p_input ) ...@@ -685,6 +754,7 @@ static void ErrorThread( input_thread_t *p_input )
*****************************************************************************/ *****************************************************************************/
static void EndThread( input_thread_t * p_input ) static void EndThread( input_thread_t * p_input )
{ {
int i;
#ifdef HAVE_SYS_TIMES_H #ifdef HAVE_SYS_TIMES_H
/* Display statistics */ /* Display statistics */
struct tms cpu_usage; struct tms cpu_usage;
...@@ -704,7 +774,8 @@ static void EndThread( input_thread_t * p_input ) ...@@ -704,7 +774,8 @@ static void EndThread( input_thread_t * p_input )
/* Close optional stream output instance */ /* Close optional stream output instance */
if ( p_input->stream.p_sout != NULL ) if ( p_input->stream.p_sout != NULL )
{ {
vlc_object_t *p_pl = vlc_object_find( p_input, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); vlc_object_t *p_pl =
vlc_object_find( p_input, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
vlc_value_t keep; vlc_value_t keep;
if( var_Get( p_input, "sout-keep", &keep ) >= 0 && keep.b_bool && p_pl ) if( var_Get( p_input, "sout-keep", &keep ) >= 0 && keep.b_bool && p_pl )
...@@ -725,6 +796,19 @@ static void EndThread( input_thread_t * p_input ) ...@@ -725,6 +796,19 @@ static void EndThread( input_thread_t * p_input )
} }
} }
/* Destroy subtitles demuxers */
for( i = 0; i < p_input->p_sys->i_sub; i++ )
{
subtitle_Close( p_input->p_sys->sub[i] );
}
if( p_input->p_sys->i_sub > 0 )
{
free( p_input->p_sys->sub );
}
/* Free input_thread_sys_t */
free( p_input->p_sys );
/* Free demultiplexer's data */ /* Free demultiplexer's data */
module_Unneed( p_input, p_input->p_demux ); module_Unneed( p_input, p_input->p_demux );
...@@ -855,6 +939,9 @@ struct es_out_sys_t ...@@ -855,6 +939,9 @@ struct es_out_sys_t
int i_id; int i_id;
es_out_id_t **id; es_out_id_t **id;
vlc_bool_t i_audio;
vlc_bool_t i_video;
}; };
struct es_out_id_t struct es_out_id_t
{ {
...@@ -879,32 +966,218 @@ static es_out_t *EsOutCreate( input_thread_t *p_input ) ...@@ -879,32 +966,218 @@ static es_out_t *EsOutCreate( input_thread_t *p_input )
out->p_sys->p_input = p_input; out->p_sys->p_input = p_input;
out->p_sys->i_id = 0; out->p_sys->i_id = 0;
out->p_sys->id = NULL; out->p_sys->id = NULL;
out->p_sys->i_audio = -1;
out->p_sys->i_video = -1;
return out; return out;
} }
static void EsOutRelease( es_out_t *out ) static void EsOutRelease( es_out_t *out )
{ {
free( out->p_sys ); es_out_sys_t *p_sys = out->p_sys;
int i;
for( i = 0; i < p_sys->i_id; i++ )
{
free( p_sys->id[i] );
}
if( p_sys->id )
{
free( p_sys->id );
}
free( p_sys );
free( out ); free( out );
} }
static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt ) static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
{ {
es_out_id_t *id = malloc( sizeof( es_out_id_t ) ); es_out_sys_t *p_sys = out->p_sys;
input_thread_t *p_input = p_sys->p_input;
es_out_id_t *id = malloc( sizeof( es_out_id_t ) );
pgrm_descriptor_t *p_prgm = NULL;
vlc_mutex_lock( &p_input->stream.stream_lock );
if( fmt->i_group >= 0 )
{
/* search program */
p_prgm = input_FindProgram( p_input, fmt->i_group );
if( p_prgm == NULL )
{
/* create it */
p_prgm = input_AddProgram( p_input, fmt->i_group, 0 );
/* Select the first by default */
if( p_input->stream.p_selected_program == NULL )
{
p_input->stream.p_selected_program = p_prgm;
}
}
}
id->p_es = input_AddES( p_input,
p_prgm,
1 + out->p_sys->i_id,
fmt->i_cat,
fmt->psz_description, 0 );
id->p_es->i_stream_id = 1 + out->p_sys->i_id;
id->p_es->i_fourcc = fmt->i_codec;
switch( fmt->i_cat )
{
case AUDIO_ES:
{
WAVEFORMATEX *p_wf = malloc( sizeof( WAVEFORMATEX ) + fmt->i_extra);
p_wf->wFormatTag = WAVE_FORMAT_UNKNOWN;
p_wf->nChannels = fmt->audio.i_channels;
p_wf->nSamplesPerSec = fmt->audio.i_samplerate;
p_wf->nAvgBytesPerSec = fmt->audio.i_bitrate / 8;
p_wf->nBlockAlign = fmt->audio.i_blockalign;
p_wf->wBitsPerSample = fmt->audio.i_bitspersample;
p_wf->cbSize = fmt->i_extra;
if( fmt->i_extra > 0 )
{
if( fmt->i_extra_type != ES_EXTRA_TYPE_WAVEFORMATEX )
{
msg_Warn( p_input, "extra type != WAVEFORMATEX for audio" );
}
memcpy( &p_wf[1], fmt->p_extra, fmt->i_extra );
}
id->p_es->p_waveformatex = p_wf;
break;
}
case VIDEO_ES:
{
BITMAPINFOHEADER *p_bih = malloc( sizeof( BITMAPINFOHEADER ) +
fmt->i_extra );
p_bih->biSize = sizeof(BITMAPINFOHEADER) + fmt->i_extra;
p_bih->biWidth = fmt->video.i_width;
p_bih->biHeight = fmt->video.i_height;
p_bih->biPlanes = 1;
p_bih->biBitCount = 24;
p_bih->biCompression = fmt->i_codec;
p_bih->biSizeImage = fmt->video.i_width * fmt->video.i_height;
p_bih->biXPelsPerMeter = 0;
p_bih->biYPelsPerMeter = 0;
p_bih->biClrUsed = 0;
p_bih->biClrImportant = 0;
if( fmt->i_extra > 0 )
{
if( fmt->i_extra_type != ES_EXTRA_TYPE_BITMAPINFOHEADER )
{
msg_Warn( p_input,
"extra type != BITMAPINFOHEADER for video" );
}
memcpy( &p_bih[1], fmt->p_extra, fmt->i_extra );
}
id->p_es->p_bitmapinfoheader = p_bih;
break;
}
default:
break;
}
if( fmt->i_cat == AUDIO_ES && fmt->i_priority > out->p_sys->i_audio )
{
if( out->p_sys->i_audio >= 0 )
{
msg_Err( p_input, "FIXME unselect es in es_out_Add" );
}
input_SelectES( p_input, id->p_es );
if( id->p_es->p_decoder_fifo )
{
out->p_sys->i_audio = fmt->i_priority;
}
}
else if( fmt->i_cat == VIDEO_ES && fmt->i_priority > out->p_sys->i_video )
{
if( out->p_sys->i_video >= 0 )
{
msg_Err( p_input, "FIXME unselect es in es_out_Add" );
}
input_SelectES( p_input, id->p_es );
if( id->p_es->p_decoder_fifo )
{
out->p_sys->i_video = fmt->i_priority;
}
}
vlc_mutex_unlock( &p_input->stream.stream_lock );
TAB_APPEND( out->p_sys->i_id, out->p_sys->id, id );
return id; return id;
} }
static int EsOutSend( es_out_t *out, es_out_id_t *id, pes_packet_t *p_pes ) static int EsOutSend( es_out_t *out, es_out_id_t *id, pes_packet_t *p_pes )
{ {
if( id->p_es->p_decoder_fifo )
{
input_DecodePES( id->p_es->p_decoder_fifo, p_pes );
}
else
{
input_DeletePES( out->p_sys->p_input->p_method_data, p_pes );
}
return VLC_SUCCESS; return VLC_SUCCESS;
} }
static void EsOutDel( es_out_t *out, es_out_id_t *id ) static void EsOutDel( es_out_t *out, es_out_id_t *id )
{ {
es_out_sys_t *p_sys = out->p_sys;
TAB_REMOVE( p_sys->i_id, p_sys->id, id );
vlc_mutex_lock( &p_sys->p_input->stream.stream_lock );
if( id->p_es->p_decoder_fifo )
{
input_UnselectES( p_sys->p_input, id->p_es );
}
if( id->p_es->p_waveformatex )
{
free( id->p_es->p_waveformatex );
id->p_es->p_waveformatex = NULL;
}
if( id->p_es->p_bitmapinfoheader )
{
free( id->p_es->p_bitmapinfoheader );
id->p_es->p_bitmapinfoheader = NULL;
}
input_DelES( p_sys->p_input, id->p_es );
vlc_mutex_unlock( &p_sys->p_input->stream.stream_lock );
free( id ); free( id );
} }
static int EsOutControl( es_out_t *out, int i_query, va_list args ) static int EsOutControl( es_out_t *out, int i_query, va_list args )
{ {
return VLC_EGENERIC; es_out_sys_t *p_sys = out->p_sys;
vlc_bool_t b, *pb;
es_out_id_t *id;
switch( i_query )
{
case ES_OUT_SET_SELECT:
id = (es_out_id_t*) va_arg( args, es_out_id_t * );
b = (vlc_bool_t) va_arg( args, vlc_bool_t );
if( b && id->p_es->p_decoder_fifo == NULL )
{
input_SelectES( p_sys->p_input, id->p_es );
return id->p_es->p_decoder_fifo ? VLC_SUCCESS : VLC_EGENERIC;
}
else if( !b && id->p_es->p_decoder_fifo )
{
input_UnselectES( p_sys->p_input, id->p_es );
}
return VLC_SUCCESS;
case ES_OUT_GET_SELECT:
id = (es_out_id_t*) va_arg( args, es_out_id_t * );
pb = (vlc_bool_t*) va_arg( args, vlc_bool_t * );
*pb = id->p_es->p_decoder_fifo ? VLC_TRUE : VLC_FALSE;
return VLC_SUCCESS;
default:
msg_Err( p_sys->p_input, "unknown query in es_out_Control" );
return VLC_EGENERIC;
}
} }
/***************************************************************************** /*****************************************************************************
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* playlist.c : Playlist management functions * playlist.c : Playlist management functions
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: playlist.c,v 1.50 2003/09/10 11:37:53 fenrir Exp $ * $Id: playlist.c,v 1.51 2003/09/13 17:42:16 fenrir Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -692,11 +692,10 @@ static void RunThread ( playlist_t *p_playlist ) ...@@ -692,11 +692,10 @@ static void RunThread ( playlist_t *p_playlist )
} }
else if( p_playlist->i_status == PLAYLIST_STOPPED ) else if( p_playlist->i_status == PLAYLIST_STOPPED )
{ {
ObjectGarbageCollector( p_playlist, VLC_OBJECT_VOUT,
&b_vout_destroyed, &i_vout_destroyed_date );
ObjectGarbageCollector( p_playlist, VLC_OBJECT_SOUT, ObjectGarbageCollector( p_playlist, VLC_OBJECT_SOUT,
&b_sout_destroyed, &i_sout_destroyed_date ); &b_sout_destroyed, &i_sout_destroyed_date );
ObjectGarbageCollector( p_playlist, VLC_OBJECT_VOUT,
&b_vout_destroyed, &i_vout_destroyed_date );
} }
vlc_mutex_unlock( &p_playlist->object_lock ); vlc_mutex_unlock( &p_playlist->object_lock );
...@@ -721,11 +720,15 @@ static void RunThread ( playlist_t *p_playlist ) ...@@ -721,11 +720,15 @@ static void RunThread ( playlist_t *p_playlist )
/* Unlink current input */ /* Unlink current input */
p_input = p_playlist->p_input; p_input = p_playlist->p_input;
p_playlist->p_input = NULL; p_playlist->p_input = NULL;
vlc_object_detach( p_input );
vlc_mutex_unlock( &p_playlist->object_lock ); vlc_mutex_unlock( &p_playlist->object_lock );
/* Destroy input */ /* Destroy input */
input_DestroyThread( p_input ); input_DestroyThread( p_input );
/* Unlink current input (_after_ input_DestroyThread for vout
* garbage collector)*/
vlc_object_detach( p_input );
/* Destroy object */
vlc_object_destroy( p_input ); vlc_object_destroy( p_input );
continue; continue;
} }
...@@ -750,20 +753,21 @@ static void RunThread ( playlist_t *p_playlist ) ...@@ -750,20 +753,21 @@ static void RunThread ( playlist_t *p_playlist )
msleep( INTF_IDLE_SLEEP ); msleep( INTF_IDLE_SLEEP );
} }
/* close all remaining vout */ /* close all remaining sout */
while( ( p_obj = vlc_object_find( p_playlist, while( ( p_obj = vlc_object_find( p_playlist,
VLC_OBJECT_VOUT, FIND_CHILD ) ) ) VLC_OBJECT_SOUT, FIND_CHILD ) ) )
{ {
vlc_object_detach( p_obj );
vlc_object_release( p_obj ); vlc_object_release( p_obj );
vout_Destroy( (vout_thread_t *)p_obj ); sout_DeleteInstance( (sout_instance_t*)p_obj );
} }
/* close all remaining sout */
/* close all remaining vout */
while( ( p_obj = vlc_object_find( p_playlist, while( ( p_obj = vlc_object_find( p_playlist,
VLC_OBJECT_SOUT, FIND_CHILD ) ) ) VLC_OBJECT_VOUT, FIND_CHILD ) ) )
{ {
vlc_object_detach( p_obj );
vlc_object_release( p_obj ); vlc_object_release( p_obj );
sout_DeleteInstance( (sout_instance_t*)p_obj ); vout_Destroy( (vout_thread_t *)p_obj );
} }
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* thread, and destroy a previously oppened video output thread. * thread, and destroy a previously oppened video output thread.
***************************************************************************** *****************************************************************************
* Copyright (C) 2000-2001 VideoLAN * Copyright (C) 2000-2001 VideoLAN
* $Id: video_output.c,v 1.233 2003/09/07 22:43:17 fenrir Exp $ * $Id: video_output.c,v 1.234 2003/09/13 17:42:16 fenrir Exp $
* *
* Authors: Vincent Seguin <seguin@via.ecp.fr> * Authors: Vincent Seguin <seguin@via.ecp.fr>
* *
...@@ -80,7 +80,8 @@ vout_thread_t * __vout_Request ( vlc_object_t *p_this, vout_thread_t *p_vout, ...@@ -80,7 +80,8 @@ vout_thread_t * __vout_Request ( vlc_object_t *p_this, vout_thread_t *p_vout,
{ {
vlc_object_t *p_playlist; vlc_object_t *p_playlist;
p_playlist = vlc_object_find( p_this, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); p_playlist = vlc_object_find( p_this,
VLC_OBJECT_PLAYLIST, FIND_PARENT );
if( p_playlist ) if( p_playlist )
{ {
......
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