mirror of
https://github.com/videolan/vlc.git
synced 2025-01-26 09:36:25 +08:00
* 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.
This commit is contained in:
parent
a903f128da
commit
0925ed0b72
@ -4,7 +4,7 @@
|
||||
* control the pace of reading.
|
||||
*****************************************************************************
|
||||
* 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>
|
||||
*
|
||||
@ -346,6 +346,9 @@ struct input_thread_t
|
||||
char * psz_name;
|
||||
|
||||
count_t c_loops;
|
||||
|
||||
/* private, do not touch it */
|
||||
input_thread_sys_t *p_sys;
|
||||
};
|
||||
|
||||
/* Input methods */
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ninput.h
|
||||
*****************************************************************************
|
||||
* 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>
|
||||
*
|
||||
@ -36,9 +36,9 @@ typedef struct
|
||||
int i_cat;
|
||||
vlc_fourcc_t i_codec;
|
||||
|
||||
int i_group; /* eg -1. if >= 0 then a "group" (program) is
|
||||
created for each value */
|
||||
|
||||
int i_group; /* -1 : standalone
|
||||
>= 0 then a "group" (program) is created
|
||||
for each value */
|
||||
int i_priority; /* -2 : mean not selectable by the users
|
||||
-1 : mean not selected by default even
|
||||
when no other stream
|
||||
@ -78,7 +78,7 @@ static inline void es_format_Init( es_format_t *fmt,
|
||||
{
|
||||
fmt->i_cat = i_cat;
|
||||
fmt->i_codec = i_codec;
|
||||
fmt->i_group = -1;
|
||||
fmt->i_group = 0;
|
||||
fmt->i_priority = 0;
|
||||
fmt->psz_language = NULL;
|
||||
fmt->psz_description = NULL;
|
||||
@ -213,7 +213,9 @@ enum demux_query_e
|
||||
DEMUX_GET_TIME, /* arg1= int64_t * res= */
|
||||
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 @@
|
||||
* Collection of useful common types and macros definitions
|
||||
*****************************************************************************
|
||||
* 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>
|
||||
* Vincent Seguin <seguin@via.ecp.fr>
|
||||
@ -211,6 +211,7 @@ typedef struct intf_channel_t intf_channel_t;
|
||||
|
||||
/* Input */
|
||||
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_area_t input_area_t;
|
||||
typedef struct input_buffers_t input_buffers_t;
|
||||
|
@ -2,7 +2,7 @@
|
||||
* avi.c : AVI file Stream input module for vlc
|
||||
*****************************************************************************
|
||||
* 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>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -29,8 +29,6 @@
|
||||
#include <vlc/input.h>
|
||||
#include "codecs.h"
|
||||
|
||||
#include "../util/sub.h"
|
||||
|
||||
#include "libavi.h"
|
||||
#include "avi.h"
|
||||
|
||||
@ -123,7 +121,6 @@ static int Open( vlc_object_t * p_this )
|
||||
demux_sys_t *p_avi;
|
||||
es_descriptor_t *p_es = NULL; /* avoid warning */
|
||||
unsigned int i;
|
||||
mtime_t i_microsecperframe = 0; // for some subtitle format
|
||||
|
||||
vlc_bool_t b_stream_audio, b_stream_video;
|
||||
uint8_t *p_peek;
|
||||
@ -377,12 +374,6 @@ static int Open( vlc_object_t * p_this )
|
||||
input_AddInfo( p_cat, _("Bits Per Pixel"), "%d",
|
||||
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;
|
||||
default:
|
||||
msg_Warn( p_input, "stream[%d] unknown type", i );
|
||||
@ -424,11 +415,6 @@ static int Open( vlc_object_t * p_this )
|
||||
#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( p_avi->b_seekable )
|
||||
@ -572,10 +558,6 @@ static void Close ( vlc_object_t * p_this )
|
||||
}
|
||||
}
|
||||
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 );
|
||||
|
||||
free( p_avi );
|
||||
@ -658,11 +640,6 @@ static int Demux_Seekable( input_thread_t *p_input )
|
||||
|
||||
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 */
|
||||
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 )
|
||||
static int Control( input_thread_t *p_input, int i_query, va_list args )
|
||||
{
|
||||
demux_sys_t *p_sys = p_input->p_demux_data;
|
||||
int i;
|
||||
double f, *pf;
|
||||
int64_t i64, *pi64;
|
||||
|
||||
@ -1276,10 +1254,6 @@ static int Control( input_thread_t *p_input, int i_query, va_list args )
|
||||
f = (double)va_arg( args, double );
|
||||
i64 = (mtime_t)(1000000.0 * p_sys->i_length * f );
|
||||
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;
|
||||
}
|
||||
else
|
||||
@ -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;
|
||||
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:
|
||||
return demux_vaControlDefault( p_input, i_query, args );
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* avi.h : AVI file Stream input module for vlc
|
||||
*****************************************************************************
|
||||
* 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>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -85,7 +85,5 @@ struct demux_sys_t
|
||||
/* number of streams and information */
|
||||
unsigned int i_streams;
|
||||
avi_stream_t **pp_info;
|
||||
|
||||
subtitle_demux_t *p_sub;
|
||||
};
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
* mp4.c : MP4 file input module for vlc
|
||||
*****************************************************************************
|
||||
* 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>
|
||||
*
|
||||
* 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 )
|
||||
(mtime_t)p_sys->i_duration /
|
||||
(mtime_t)p_sys->i_timescale;
|
||||
return VLC_SUCCESS;
|
||||
|
||||
case DEMUX_GET_FPS:
|
||||
msg_Warn( p_input, "DEMUX_GET_FPS unimplemented !!" );
|
||||
return VLC_EGENERIC;
|
||||
default:
|
||||
msg_Err( p_input, "control query unimplemented !!!" );
|
||||
return demux_vaControlDefault( p_input, i_query, args );
|
||||
|
@ -2,7 +2,7 @@
|
||||
* mpga.c : MPEG-I/II Audio input module for vlc
|
||||
*****************************************************************************
|
||||
* 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>
|
||||
*
|
||||
@ -57,7 +57,9 @@ struct demux_sys_t
|
||||
mtime_t i_time;
|
||||
|
||||
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 )
|
||||
@ -173,6 +175,8 @@ static int Open( vlc_object_t * p_this )
|
||||
|
||||
module_t *p_id3;
|
||||
|
||||
es_format_t fmt;
|
||||
|
||||
|
||||
if( p_input->psz_demux &&
|
||||
( !strncmp( p_input->psz_demux, "mpga", 4 ) ||
|
||||
@ -334,28 +338,11 @@ static int Open( vlc_object_t * p_this )
|
||||
msg_Err( p_input, "cannot init stream" );
|
||||
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_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 );
|
||||
|
||||
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;
|
||||
|
||||
error:
|
||||
@ -431,14 +418,8 @@ static int Demux( input_thread_t * p_input )
|
||||
p_input->stream.p_selected_program,
|
||||
p_sys->i_time * 9 / 100 );
|
||||
|
||||
if( !p_sys->p_es->p_decoder_fifo )
|
||||
{
|
||||
msg_Err( p_input, "no audio decoder" );
|
||||
input_DeletePES( p_input->p_method_data, p_pes );
|
||||
return( -1 );
|
||||
}
|
||||
es_out_Send( p_input->p_es_out, p_sys->p_es, p_pes );
|
||||
|
||||
input_DecodePES( p_sys->p_es->p_decoder_fifo, p_pes );
|
||||
p_sys->i_time += (mtime_t)1000000 *
|
||||
(mtime_t)mpga_frame_samples( header ) /
|
||||
(mtime_t)MPGA_SAMPLE_RATE( header );
|
||||
|
@ -2,7 +2,7 @@
|
||||
* demux.c
|
||||
*****************************************************************************
|
||||
* 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>
|
||||
*
|
||||
@ -133,6 +133,9 @@ int demux_vaControlDefault( input_thread_t *p_input, int i_query, va_list args
|
||||
i_ret = VLC_EGENERIC;
|
||||
}
|
||||
break;
|
||||
case DEMUX_GET_FPS:
|
||||
i_ret = VLC_EGENERIC;
|
||||
break;
|
||||
|
||||
default:
|
||||
msg_Err( p_input, "unknown query in demux_vaControlDefault !!!" );
|
||||
|
@ -4,7 +4,7 @@
|
||||
* decoders.
|
||||
*****************************************************************************
|
||||
* 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>
|
||||
*
|
||||
@ -41,10 +41,19 @@
|
||||
#include "stream_output.h"
|
||||
|
||||
#include "vlc_interface.h"
|
||||
#include "codecs.h"
|
||||
#include "modules/demux/util/sub.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* 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 InitThread ( 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,
|
||||
|
||||
/* Initialize thread properties */
|
||||
p_input->b_eof = 0;
|
||||
p_input->p_sys = NULL;
|
||||
|
||||
/* Set target */
|
||||
p_input->psz_source = strdup( p_item->psz_uri );
|
||||
@ -367,6 +377,7 @@ static int RunThread( input_thread_t *p_input )
|
||||
if( p_input->stream.p_selected_area->i_size > 0 )
|
||||
{
|
||||
unsigned int i;
|
||||
mtime_t i_time;
|
||||
double f = (double)p_input->stream.p_selected_area->i_seek /
|
||||
(double)p_input->stream.p_selected_area->i_size;
|
||||
|
||||
@ -385,6 +396,22 @@ static int RunThread( input_thread_t *p_input )
|
||||
/* Reinitialize synchro. */
|
||||
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;
|
||||
}
|
||||
@ -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() )
|
||||
{
|
||||
double d;
|
||||
int i;
|
||||
mtime_t i_time;
|
||||
mtime_t i_length;
|
||||
double d_pos;
|
||||
|
||||
/* 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 );
|
||||
}
|
||||
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 );
|
||||
}
|
||||
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 );
|
||||
}
|
||||
|
||||
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 )
|
||||
*****************************************************************************/
|
||||
static int InitThread( input_thread_t * p_input )
|
||||
{
|
||||
float f_fps;
|
||||
/* Parse source string. Syntax : [[<access>][/<demux>]:][<source>] */
|
||||
char * psz_parser = p_input->psz_dupsource = strdup(p_input->psz_source);
|
||||
vlc_value_t val;
|
||||
subtitle_demux_t *p_sub;
|
||||
int64_t i_microsecondperframe;
|
||||
|
||||
/* Skip the plug-in names */
|
||||
while( *psz_parser && *psz_parser != ':' )
|
||||
@ -663,6 +704,34 @@ static int InitThread( input_thread_t * p_input )
|
||||
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;
|
||||
}
|
||||
|
||||
@ -685,6 +754,7 @@ static void ErrorThread( input_thread_t *p_input )
|
||||
*****************************************************************************/
|
||||
static void EndThread( input_thread_t * p_input )
|
||||
{
|
||||
int i;
|
||||
#ifdef HAVE_SYS_TIMES_H
|
||||
/* Display statistics */
|
||||
struct tms cpu_usage;
|
||||
@ -704,7 +774,8 @@ static void EndThread( input_thread_t * p_input )
|
||||
/* Close optional stream output instance */
|
||||
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;
|
||||
|
||||
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 )
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
module_Unneed( p_input, p_input->p_demux );
|
||||
|
||||
@ -855,6 +939,9 @@ struct es_out_sys_t
|
||||
|
||||
int i_id;
|
||||
es_out_id_t **id;
|
||||
|
||||
vlc_bool_t i_audio;
|
||||
vlc_bool_t i_video;
|
||||
};
|
||||
struct es_out_id_t
|
||||
{
|
||||
@ -879,32 +966,218 @@ static es_out_t *EsOutCreate( input_thread_t *p_input )
|
||||
out->p_sys->p_input = p_input;
|
||||
out->p_sys->i_id = 0;
|
||||
out->p_sys->id = NULL;
|
||||
|
||||
out->p_sys->i_audio = -1;
|
||||
out->p_sys->i_video = -1;
|
||||
return 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 );
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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 );
|
||||
}
|
||||
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 @@
|
||||
* playlist.c : Playlist management functions
|
||||
*****************************************************************************
|
||||
* 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>
|
||||
*
|
||||
@ -692,11 +692,10 @@ static void RunThread ( playlist_t *p_playlist )
|
||||
}
|
||||
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,
|
||||
&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 );
|
||||
|
||||
@ -721,11 +720,15 @@ static void RunThread ( playlist_t *p_playlist )
|
||||
/* Unlink current input */
|
||||
p_input = p_playlist->p_input;
|
||||
p_playlist->p_input = NULL;
|
||||
vlc_object_detach( p_input );
|
||||
vlc_mutex_unlock( &p_playlist->object_lock );
|
||||
|
||||
/* Destroy 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 );
|
||||
continue;
|
||||
}
|
||||
@ -750,6 +753,14 @@ static void RunThread ( playlist_t *p_playlist )
|
||||
msleep( INTF_IDLE_SLEEP );
|
||||
}
|
||||
|
||||
/* close all remaining sout */
|
||||
while( ( p_obj = vlc_object_find( p_playlist,
|
||||
VLC_OBJECT_SOUT, FIND_CHILD ) ) )
|
||||
{
|
||||
vlc_object_release( p_obj );
|
||||
sout_DeleteInstance( (sout_instance_t*)p_obj );
|
||||
}
|
||||
|
||||
/* close all remaining vout */
|
||||
while( ( p_obj = vlc_object_find( p_playlist,
|
||||
VLC_OBJECT_VOUT, FIND_CHILD ) ) )
|
||||
@ -758,13 +769,6 @@ static void RunThread ( playlist_t *p_playlist )
|
||||
vlc_object_release( p_obj );
|
||||
vout_Destroy( (vout_thread_t *)p_obj );
|
||||
}
|
||||
/* close all remaining sout */
|
||||
while( ( p_obj = vlc_object_find( p_playlist,
|
||||
VLC_OBJECT_SOUT, FIND_CHILD ) ) )
|
||||
{
|
||||
vlc_object_release( p_obj );
|
||||
sout_DeleteInstance( (sout_instance_t*)p_obj );
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -5,7 +5,7 @@
|
||||
* thread, and destroy a previously oppened video output thread.
|
||||
*****************************************************************************
|
||||
* 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>
|
||||
*
|
||||
@ -80,7 +80,8 @@ vout_thread_t * __vout_Request ( vlc_object_t *p_this, vout_thread_t *p_vout,
|
||||
{
|
||||
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 )
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user