Commit 46e872e4 authored by Laurent Aimar's avatar Laurent Aimar

* all: implement more es_out_* control, audio-channel and spu-channel are

 implemented.
parent fc1221c1
...@@ -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.18 2003/11/21 00:38:01 gbazin Exp $ * $Id: ninput.h,v 1.19 2003/11/27 04:11:40 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -26,17 +26,36 @@ ...@@ -26,17 +26,36 @@
#include "vlc_es.h" #include "vlc_es.h"
enum es_out_mode_e
{
ES_OUT_MODE_NONE, /* don't select anything */
ES_OUT_MODE_ALL, /* eg for stream output */
ES_OUT_MODE_AUTO /* best audio/video or for input follow audio-channel, spu-channel */
};
enum es_out_query_e enum es_out_query_e
{ {
ES_OUT_SET_SELECT, /* arg1= es_out_id_t* arg2=vlc_bool_t */ /* activate apply of mode */
ES_OUT_GET_SELECT /* arg1= es_out_id_t* arg2=vlc_bool_t* */ ES_OUT_SET_ACTIVE, /* arg1= vlc_bool_t */
/* see if mode is currently aplied or not */
ES_OUT_GET_ACTIVE, /* arg1= vlc_bool_t* */
/* set/get mode */
ES_OUT_SET_MODE, /* arg1= int */
ES_OUT_GET_MODE, /* arg2= int* */
/* set es selected for the es category(audio/video/spu) */
ES_OUT_SET_ES, /* arg1= es_out_id_t* */
/* force selection/unselection of the ES (bypass current mode)*/
ES_OUT_SET_ES_STATE,/* arg1= es_out_id_t* arg2=vlc_bool_t */
ES_OUT_GET_ES_STATE,/* arg1= es_out_id_t* arg2=vlc_bool_t* */
}; };
struct es_out_t struct es_out_t
{ {
es_out_id_t *(*pf_add) ( es_out_t *, es_format_t * ); es_out_id_t *(*pf_add) ( es_out_t *, es_format_t * );
int (*pf_send) ( es_out_t *, es_out_id_t *, block_t * ); int (*pf_send) ( es_out_t *, es_out_id_t *, block_t * );
int (*pf_send_pes)( es_out_t *, es_out_id_t *, pes_packet_t * );
void (*pf_del) ( es_out_t *, es_out_id_t * ); void (*pf_del) ( es_out_t *, es_out_id_t * );
int (*pf_control)( es_out_t *, int i_query, va_list ); int (*pf_control)( es_out_t *, int i_query, va_list );
...@@ -52,15 +71,11 @@ static inline void es_out_Del( es_out_t *out, es_out_id_t *id ) ...@@ -52,15 +71,11 @@ static inline void es_out_Del( es_out_t *out, es_out_id_t *id )
out->pf_del( out, id ); out->pf_del( out, id );
} }
static inline int es_out_Send( es_out_t *out, es_out_id_t *id, static inline int es_out_Send( es_out_t *out, es_out_id_t *id,
block_t *p_block ) block_t *p_block )
{ {
return out->pf_send( out, id, p_block ); return out->pf_send( out, id, p_block );
} }
static inline int es_out_SendPES( es_out_t *out, es_out_id_t *id,
pes_packet_t *p_pes )
{
return out->pf_send_pes( out, id, p_pes );
}
static inline int es_out_vaControl( es_out_t *out, int i_query, va_list args ) static inline int es_out_vaControl( es_out_t *out, int i_query, va_list args )
{ {
return out->pf_control( out, i_query, args ); return out->pf_control( out, i_query, args );
......
...@@ -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.77 2003/11/26 08:18:09 gbazin Exp $ * $Id: avi.c,v 1.78 2003/11/27 04:11:40 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
...@@ -469,7 +469,7 @@ static int Demux_Seekable( input_thread_t *p_input ) ...@@ -469,7 +469,7 @@ static int Demux_Seekable( input_thread_t *p_input )
avi_track_t *tk = p_sys->track[i_track]; avi_track_t *tk = p_sys->track[i_track];
vlc_bool_t b; vlc_bool_t b;
es_out_Control( p_input->p_es_out, ES_OUT_GET_SELECT, tk->p_es, &b ); es_out_Control( p_input->p_es_out, ES_OUT_GET_ES_STATE, tk->p_es, &b );
if( b && !tk->b_activated ) if( b && !tk->b_activated )
{ {
if( p_sys->b_seekable) if( p_sys->b_seekable)
...@@ -794,7 +794,7 @@ static int Demux_UnSeekable( input_thread_t *p_input ) ...@@ -794,7 +794,7 @@ static int Demux_UnSeekable( input_thread_t *p_input )
avi_track_t *tk = p_sys->track[i_stream]; avi_track_t *tk = p_sys->track[i_stream];
vlc_bool_t b; vlc_bool_t b;
es_out_Control( p_input->p_es_out, ES_OUT_GET_SELECT, tk->p_es, &b ); es_out_Control( p_input->p_es_out, ES_OUT_GET_ES_STATE, tk->p_es, &b );
if( b && tk->i_cat == VIDEO_ES ) if( b && tk->i_cat == VIDEO_ES )
{ {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* mkv.cpp : matroska demuxer * mkv.cpp : matroska demuxer
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: mkv.cpp,v 1.44 2003/11/23 13:15:27 gbazin Exp $ * $Id: mkv.cpp,v 1.45 2003/11/27 04:11:40 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -1401,7 +1401,7 @@ static void BlockDecode( input_thread_t *p_input, KaxBlock *block, mtime_t i_pts ...@@ -1401,7 +1401,7 @@ static void BlockDecode( input_thread_t *p_input, KaxBlock *block, mtime_t i_pts
return; return;
} }
es_out_Control( p_input->p_es_out, ES_OUT_GET_SELECT, tk.p_es, &b ); es_out_Control( p_input->p_es_out, ES_OUT_GET_ES_STATE, tk.p_es, &b );
if( !b ) if( !b )
{ {
tk.b_inited = VLC_FALSE; tk.b_inited = VLC_FALSE;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ogg.c : ogg stream input module for vlc * ogg.c : ogg stream input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001-2003 VideoLAN * Copyright (C) 2001-2003 VideoLAN
* $Id: ogg.c,v 1.47 2003/11/26 08:18:09 gbazin Exp $ * $Id: ogg.c,v 1.48 2003/11/27 04:11:40 fenrir Exp $
* *
* Authors: Gildas Bazin <gbazin@netcourrier.com> * Authors: Gildas Bazin <gbazin@netcourrier.com>
* *
...@@ -359,7 +359,7 @@ static void Ogg_DecodePacket( input_thread_t *p_input, ...@@ -359,7 +359,7 @@ static void Ogg_DecodePacket( input_thread_t *p_input,
} }
/* Check the ES is selected */ /* Check the ES is selected */
es_out_Control( p_input->p_es_out, ES_OUT_GET_SELECT, es_out_Control( p_input->p_es_out, ES_OUT_GET_ES_STATE,
p_stream->p_es, &b_selected ); p_stream->p_es, &b_selected );
if( b_selected && !p_stream->b_activated ) if( b_selected && !p_stream->b_activated )
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* rawdv.c : raw dv input module for vlc * rawdv.c : raw dv input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: rawdv.c,v 1.12 2003/11/24 19:19:02 fenrir Exp $ * $Id: rawdv.c,v 1.13 2003/11/27 04:11:40 fenrir Exp $
* *
* Authors: Gildas Bazin <gbazin@netcourrier.com> * Authors: Gildas Bazin <gbazin@netcourrier.com>
* *
...@@ -297,9 +297,9 @@ static int Demux( input_thread_t * p_input ) ...@@ -297,9 +297,9 @@ static int Demux( input_thread_t * p_input )
return 0; return 0;
} }
es_out_Control( p_input->p_es_out, ES_OUT_GET_SELECT, es_out_Control( p_input->p_es_out, ES_OUT_GET_ES_STATE,
p_sys->p_es_audio, &b_audio ); p_sys->p_es_audio, &b_audio );
es_out_Control( p_input->p_es_out, ES_OUT_GET_SELECT, es_out_Control( p_input->p_es_out, ES_OUT_GET_ES_STATE,
p_sys->p_es_video, &b_video ); p_sys->p_es_video, &b_video );
p_block->i_dts = p_block->i_dts =
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* sub.c * sub.c
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2003 VideoLAN * Copyright (C) 1999-2003 VideoLAN
* $Id: sub.c,v 1.38 2003/11/21 00:38:01 gbazin Exp $ * $Id: sub.c,v 1.39 2003/11/27 04:11:40 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -502,7 +502,7 @@ static int sub_demux( subtitle_demux_t *p_sub, mtime_t i_maxdate ) ...@@ -502,7 +502,7 @@ static int sub_demux( subtitle_demux_t *p_sub, mtime_t i_maxdate )
input_thread_t *p_input = p_sub->p_input; input_thread_t *p_input = p_sub->p_input;
vlc_bool_t b; vlc_bool_t b;
es_out_Control( p_input->p_es_out, ES_OUT_GET_SELECT, p_sub->p_es, &b ); es_out_Control( p_input->p_es_out, ES_OUT_GET_ES_STATE, p_sub->p_es, &b );
if( b && !p_sub->i_previously_selected ) if( b && !p_sub->i_previously_selected )
{ {
p_sub->i_previously_selected = 1; p_sub->i_previously_selected = 1;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* es_out.c: Es Out handler for input. * es_out.c: Es Out handler for input.
***************************************************************************** *****************************************************************************
* Copyright (C) 2003 VideoLAN * Copyright (C) 2003 VideoLAN
* $Id: es_out.c,v 1.1 2003/11/24 20:50:45 fenrir Exp $ * $Id: es_out.c,v 1.2 2003/11/27 04:11:40 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -35,25 +35,43 @@ ...@@ -35,25 +35,43 @@
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
struct es_out_id_t
{
int i_channel;
es_descriptor_t *p_es;
};
struct es_out_sys_t struct es_out_sys_t
{ {
input_thread_t *p_input; input_thread_t *p_input;
/* all es */
int i_id; int i_id;
es_out_id_t **id;
vlc_bool_t i_audio; int i_es;
vlc_bool_t i_video; es_out_id_t **es;
};
struct es_out_id_t /* mode gestion */
{ vlc_bool_t b_active;
es_descriptor_t *p_es; int i_mode;
/* es count */
int i_audio;
int i_video;
int i_sub;
/* es to select */
int i_audio_last;
int i_sub_last;
/* current main es */
es_out_id_t *p_es_audio;
es_out_id_t *p_es_video;
es_out_id_t *p_es_sub;
}; };
static es_out_id_t *EsOutAdd ( es_out_t *, es_format_t * ); static es_out_id_t *EsOutAdd ( es_out_t *, es_format_t * );
static int EsOutSend ( es_out_t *, es_out_id_t *, block_t * ); static int EsOutSend ( es_out_t *, es_out_id_t *, block_t * );
static int EsOutSendPES( es_out_t *, es_out_id_t *, pes_packet_t * );
static void EsOutDel ( es_out_t *, es_out_id_t * ); static void EsOutDel ( es_out_t *, es_out_id_t * );
static int EsOutControl( es_out_t *, int i_query, va_list ); static int EsOutControl( es_out_t *, int i_query, va_list );
...@@ -63,20 +81,40 @@ static int EsOutControl( es_out_t *, int i_query, va_list ); ...@@ -63,20 +81,40 @@ static int EsOutControl( es_out_t *, int i_query, va_list );
*****************************************************************************/ *****************************************************************************/
es_out_t *input_EsOutNew( input_thread_t *p_input ) es_out_t *input_EsOutNew( input_thread_t *p_input )
{ {
es_out_t *out = malloc( sizeof( es_out_t ) ); es_out_t *out = malloc( sizeof( es_out_t ) );
es_out_sys_t *p_sys = malloc( sizeof( es_out_sys_t ) );
vlc_value_t val;
out->pf_add = EsOutAdd; out->pf_add = EsOutAdd;
out->pf_send = EsOutSend; out->pf_send = EsOutSend;
out->pf_send_pes= EsOutSendPES;
out->pf_del = EsOutDel; out->pf_del = EsOutDel;
out->pf_control = EsOutControl; out->pf_control = EsOutControl;
out->p_sys = p_sys;
p_sys->p_input = p_input;
p_sys->b_active = VLC_FALSE;
p_sys->i_mode = ES_OUT_MODE_AUTO;
p_sys->i_id = 1;
p_sys->i_es = 0;
p_sys->es = NULL;
p_sys->i_audio = 0;
p_sys->i_video = 0;
p_sys->i_sub = 0;
var_Get( p_input, "audio-channel", &val );
p_sys->i_audio_last = val.i_int;
var_Get( p_input, "spu-channel", &val );
p_sys->i_sub_last = val.i_int;
p_sys->p_es_audio = NULL;
p_sys->p_es_video = NULL;
p_sys->p_es_sub = NULL;
out->p_sys = malloc( sizeof( es_out_sys_t ) );
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; return out;
} }
...@@ -88,18 +126,97 @@ void input_EsOutDelete( es_out_t *out ) ...@@ -88,18 +126,97 @@ void input_EsOutDelete( es_out_t *out )
es_out_sys_t *p_sys = out->p_sys; es_out_sys_t *p_sys = out->p_sys;
int i; int i;
for( i = 0; i < p_sys->i_id; i++ ) for( i = 0; i < p_sys->i_es; i++ )
{ {
free( p_sys->id[i] ); free( p_sys->es[i] );
} }
if( p_sys->id ) if( p_sys->es )
{ {
free( p_sys->id ); free( p_sys->es );
} }
free( p_sys ); free( p_sys );
free( out ); free( out );
} }
/*****************************************************************************
* EsOutSelect: Select an ES given the current mode
* XXX: you need to take a the lock before (stream.stream_lock)
*****************************************************************************/
static void EsOutSelect( es_out_t *out, es_out_id_t *es, vlc_bool_t b_force )
{
es_out_sys_t *p_sys = out->p_sys;
input_thread_t *p_input = p_sys->p_input;
int i_cat = es->p_es->i_cat;
if( !p_sys->b_active || ( !b_force && es->p_es->fmt.i_priority < 0 ) )
{
return;
}
if( p_sys->i_mode == ES_OUT_MODE_ALL || b_force )
{
input_SelectES( p_input, es->p_es );
}
else if( p_sys->i_mode == ES_OUT_MODE_AUTO )
{
int i_wanted = -1;
if( i_cat == AUDIO_ES )
{
if( p_sys->p_es_audio && p_sys->p_es_audio->p_es->fmt.i_priority >= es->p_es->fmt.i_priority )
{
return;
}
i_wanted = p_sys->i_audio_last >= 0 ? p_sys->i_audio_last : es->i_channel;
}
else if( i_cat == SPU_ES )
{
if( p_sys->p_es_sub && p_sys->p_es_sub->p_es->fmt.i_priority >= es->p_es->fmt.i_priority )
{
return;
}
i_wanted = p_sys->i_sub_last;
}
else if( i_cat == VIDEO_ES )
{
i_wanted = es->i_channel;
}
if( i_wanted == es->i_channel )
{
input_SelectES( p_input, es->p_es );
}
}
/* FIXME TODO handle priority here */
if( es->p_es->p_dec )
{
if( i_cat == AUDIO_ES )
{
if( p_sys->i_mode == ES_OUT_MODE_AUTO &&
p_sys->p_es_audio && p_sys->p_es_audio->p_es->p_dec )
{
input_UnselectES( p_input, p_sys->p_es_audio->p_es );
}
p_sys->p_es_audio = es;
}
else if( i_cat == SPU_ES )
{
if( p_sys->i_mode == ES_OUT_MODE_AUTO &&
p_sys->p_es_sub && p_sys->p_es_sub->p_es->p_dec )
{
input_UnselectES( p_input, p_sys->p_es_sub->p_es );
}
p_sys->p_es_sub = es;
}
else if( i_cat == VIDEO_ES )
{
p_sys->p_es_video = es;
}
}
}
/***************************************************************************** /*****************************************************************************
* EsOutAdd: * EsOutAdd:
*****************************************************************************/ *****************************************************************************/
...@@ -107,7 +224,7 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt ) ...@@ -107,7 +224,7 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
{ {
es_out_sys_t *p_sys = out->p_sys; es_out_sys_t *p_sys = out->p_sys;
input_thread_t *p_input = p_sys->p_input; input_thread_t *p_input = p_sys->p_input;
es_out_id_t *id = malloc( sizeof( es_out_id_t ) ); es_out_id_t *es = malloc( sizeof( es_out_id_t ) );
pgrm_descriptor_t *p_prgm = NULL; pgrm_descriptor_t *p_prgm = NULL;
char psz_cat[strlen( "Stream " ) + 10]; char psz_cat[strlen( "Stream " ) + 10];
input_info_category_t *p_cat; input_info_category_t *p_cat;
...@@ -131,13 +248,13 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt ) ...@@ -131,13 +248,13 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
} }
} }
id->p_es = input_AddES( p_input, es->p_es = input_AddES( p_input,
p_prgm, p_prgm,
1 + out->p_sys->i_id, out->p_sys->i_id,
fmt->i_cat, fmt->i_cat,
fmt->psz_description, 0 ); fmt->psz_description, 0 );
id->p_es->i_stream_id = 1 + out->p_sys->i_id; es->p_es->i_stream_id = out->p_sys->i_id;
id->p_es->i_fourcc = fmt->i_codec; es->p_es->i_fourcc = fmt->i_codec;
switch( fmt->i_cat ) switch( fmt->i_cat )
{ {
...@@ -157,7 +274,9 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt ) ...@@ -157,7 +274,9 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
{ {
memcpy( &p_wf[1], fmt->p_extra, fmt->i_extra ); memcpy( &p_wf[1], fmt->p_extra, fmt->i_extra );
} }
id->p_es->p_waveformatex = p_wf; es->p_es->p_waveformatex = p_wf;
es->i_channel = p_sys->i_audio;
break; break;
} }
case VIDEO_ES: case VIDEO_ES:
...@@ -181,7 +300,9 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt ) ...@@ -181,7 +300,9 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
{ {
memcpy( &p_bih[1], fmt->p_extra, fmt->i_extra ); memcpy( &p_bih[1], fmt->p_extra, fmt->i_extra );
} }
id->p_es->p_bitmapinfoheader = p_bih; es->p_es->p_bitmapinfoheader = p_bih;
es->i_channel = p_sys->i_video;
break; break;
} }
case SPU_ES: case SPU_ES:
...@@ -190,43 +311,24 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt ) ...@@ -190,43 +311,24 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
memset( p_sub, 0, sizeof( subtitle_data_t ) ); memset( p_sub, 0, sizeof( subtitle_data_t ) );
if( fmt->i_extra > 0 ) if( fmt->i_extra > 0 )
{ {
p_sub->psz_header = malloc( fmt->i_extra ); p_sub->psz_header = malloc( fmt->i_extra + 1 );
memcpy( p_sub->psz_header, fmt->p_extra , fmt->i_extra ); memcpy( p_sub->psz_header, fmt->p_extra , fmt->i_extra );
/* just to be sure */
((uint8_t*)fmt->p_extra)[fmt->i_extra] = '\0';
} }
/* FIXME beuuuuuurk */ /* FIXME beuuuuuurk */
id->p_es->p_demux_data = p_sub; es->p_es->p_demux_data = p_sub;
es->i_channel = p_sys->i_sub;
break; break;
} }
default: default:
es->i_channel = 0;
break; break;
} }
if( fmt->i_cat == AUDIO_ES && fmt->i_priority > out->p_sys->i_audio ) sprintf( psz_cat, _("Stream %d"), out->p_sys->i_id - 1 );
{
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_dec )
{
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_dec )
{
out->p_sys->i_video = fmt->i_priority;
}
}
sprintf( psz_cat, _("Stream %d"), out->p_sys->i_id );
if( ( p_cat = input_InfoCategory( p_input, psz_cat ) ) ) if( ( p_cat = input_InfoCategory( p_input, psz_cat ) ) )
{ {
/* Add information */ /* Add information */
...@@ -284,74 +386,99 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt ) ...@@ -284,74 +386,99 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
break; break;
} }
} }
vlc_mutex_unlock( &p_input->stream.stream_lock );
id->p_es->fmt = *fmt;
TAB_APPEND( out->p_sys->i_id, out->p_sys->id, id ); /* Apply mode
return id; * XXX change that when we do group too */
} if( 1 )
/*****************************************************************************
* EsOutSend:
*****************************************************************************/
static int EsOutSend( es_out_t *out, es_out_id_t *id, block_t *p_block )
{
if( id->p_es->p_dec )
{ {
input_DecodeBlock( id->p_es->p_dec, p_block ); EsOutSelect( out, es, VLC_FALSE );
} }
else
vlc_mutex_unlock( &p_input->stream.stream_lock );
es->p_es->fmt = *fmt;
TAB_APPEND( out->p_sys->i_es, out->p_sys->es, es );
p_sys->i_id++; /* always incremented */
switch( fmt->i_cat )
{ {
block_Release( p_block ); case AUDIO_ES:
p_sys->i_audio++;
break;
case SPU_ES:
p_sys->i_sub++;
break;
case VIDEO_ES:
p_sys->i_video++;
break;
} }
return VLC_SUCCESS;
return es;
} }
/***************************************************************************** /*****************************************************************************
* EsOutSendPES: * EsOutSend:
*****************************************************************************/ *****************************************************************************/
static int EsOutSendPES( 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 *es, block_t *p_block )
{ {
if( id->p_es->p_dec ) vlc_mutex_lock( &out->p_sys->p_input->stream.stream_lock );
if( es->p_es->p_dec )
{ {
input_DecodePES( id->p_es->p_dec, p_pes ); input_DecodeBlock( es->p_es->p_dec, p_block );
} }
else else
{ {
input_DeletePES( out->p_sys->p_input->p_method_data, p_pes ); block_Release( p_block );
} }
vlc_mutex_unlock( &out->p_sys->p_input->stream.stream_lock );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
/***************************************************************************** /*****************************************************************************
* EsOutDel: * EsOutDel:
*****************************************************************************/ *****************************************************************************/
static void EsOutDel( es_out_t *out, es_out_id_t *id ) static void EsOutDel( es_out_t *out, es_out_id_t *es )
{ {
es_out_sys_t *p_sys = out->p_sys; es_out_sys_t *p_sys = out->p_sys;
TAB_REMOVE( p_sys->i_id, p_sys->id, id ); TAB_REMOVE( p_sys->i_es, p_sys->es, es );
switch( es->p_es->i_cat )
{
case AUDIO_ES:
p_sys->i_audio--;
break;
case SPU_ES:
p_sys->i_sub--;
break;
case VIDEO_ES:
p_sys->i_video--;
break;
}
/* We don't try to reselect */
vlc_mutex_lock( &p_sys->p_input->stream.stream_lock ); vlc_mutex_lock( &p_sys->p_input->stream.stream_lock );
if( id->p_es->p_dec ) if( es->p_es->p_dec )
{ {
input_UnselectES( p_sys->p_input, id->p_es ); input_UnselectES( p_sys->p_input, es->p_es );
} }
if( id->p_es->p_waveformatex )
if( es->p_es->p_waveformatex )
{ {
free( id->p_es->p_waveformatex ); free( es->p_es->p_waveformatex );
id->p_es->p_waveformatex = NULL; es->p_es->p_waveformatex = NULL;
} }
if( id->p_es->p_bitmapinfoheader ) if( es->p_es->p_bitmapinfoheader )
{ {
free( id->p_es->p_bitmapinfoheader ); free( es->p_es->p_bitmapinfoheader );
id->p_es->p_bitmapinfoheader = NULL; es->p_es->p_bitmapinfoheader = NULL;
} }
input_DelES( p_sys->p_input, id->p_es ); input_DelES( p_sys->p_input, es->p_es );
vlc_mutex_unlock( &p_sys->p_input->stream.stream_lock ); vlc_mutex_unlock( &p_sys->p_input->stream.stream_lock );
free( id ); free( es );
} }
/***************************************************************************** /*****************************************************************************
...@@ -361,30 +488,94 @@ static int EsOutControl( es_out_t *out, int i_query, va_list args ) ...@@ -361,30 +488,94 @@ static int EsOutControl( es_out_t *out, int i_query, va_list args )
{ {
es_out_sys_t *p_sys = out->p_sys; es_out_sys_t *p_sys = out->p_sys;
vlc_bool_t b, *pb; vlc_bool_t b, *pb;
es_out_id_t *id; int i, *pi;
es_out_id_t *es;
switch( i_query ) switch( i_query )
{ {
case ES_OUT_SET_SELECT: case ES_OUT_SET_ES_STATE:
vlc_mutex_lock( &p_sys->p_input->stream.stream_lock ); vlc_mutex_lock( &p_sys->p_input->stream.stream_lock );
id = (es_out_id_t*) va_arg( args, es_out_id_t * ); es = (es_out_id_t*) va_arg( args, es_out_id_t * );
b = (vlc_bool_t) va_arg( args, vlc_bool_t ); b = (vlc_bool_t) va_arg( args, vlc_bool_t );
if( b && id->p_es->p_dec == NULL ) if( b && es->p_es->p_dec == NULL )
{ {
input_SelectES( p_sys->p_input, id->p_es ); input_SelectES( p_sys->p_input, es->p_es );
vlc_mutex_unlock( &p_sys->p_input->stream.stream_lock ); vlc_mutex_unlock( &p_sys->p_input->stream.stream_lock );
return id->p_es->p_dec ? VLC_SUCCESS : VLC_EGENERIC; return es->p_es->p_dec ? VLC_SUCCESS : VLC_EGENERIC;
} }
else if( !b && id->p_es->p_dec ) else if( !b && es->p_es->p_dec )
{ {
input_UnselectES( p_sys->p_input, id->p_es ); input_UnselectES( p_sys->p_input, es->p_es );
vlc_mutex_unlock( &p_sys->p_input->stream.stream_lock ); vlc_mutex_unlock( &p_sys->p_input->stream.stream_lock );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
case ES_OUT_GET_SELECT: case ES_OUT_GET_ES_STATE:
id = (es_out_id_t*) va_arg( args, es_out_id_t * ); es = (es_out_id_t*) va_arg( args, es_out_id_t * );
pb = (vlc_bool_t*) va_arg( args, vlc_bool_t * ); pb = (vlc_bool_t*) va_arg( args, vlc_bool_t * );
*pb = id->p_es->p_dec ? VLC_TRUE : VLC_FALSE; *pb = es->p_es->p_dec ? VLC_TRUE : VLC_FALSE;
return VLC_SUCCESS;
case ES_OUT_SET_ACTIVE:
b = (vlc_bool_t) va_arg( args, vlc_bool_t );
p_sys->b_active = b;
return VLC_SUCCESS;
case ES_OUT_GET_ACTIVE:
pb = (vlc_bool_t*) va_arg( args, vlc_bool_t * );
*pb = p_sys->b_active;
return VLC_SUCCESS;
case ES_OUT_SET_MODE:
i = (int) va_arg( args, int );
if( i == ES_OUT_MODE_NONE || i == ES_OUT_MODE_ALL || i == ES_OUT_MODE_AUTO )
{
p_sys->i_mode = i;
/* Reapply policy mode */
vlc_mutex_lock( &p_sys->p_input->stream.stream_lock );
for( i = 0; i < p_sys->i_es; i++ )
{
if( p_sys->es[i]->p_es->p_dec )
{
input_UnselectES( p_sys->p_input, p_sys->es[i]->p_es );
}
}
for( i = 0; i < p_sys->i_es; i++ )
{
EsOutSelect( out, p_sys->es[i], VLC_FALSE );
}
vlc_mutex_unlock( &p_sys->p_input->stream.stream_lock );
return VLC_SUCCESS;
}
return VLC_EGENERIC;
case ES_OUT_GET_MODE:
pi = (int*) va_arg( args, int* );
*pi = p_sys->i_mode;
return VLC_SUCCESS;
case ES_OUT_SET_ES:
es = (es_out_id_t*) va_arg( args, es_out_id_t * );
if( es == NULL )
{
for( i = 0; i < p_sys->i_es; i++ )
{
vlc_mutex_lock( &p_sys->p_input->stream.stream_lock );
if( p_sys->es[i]->p_es->p_dec )
{
input_UnselectES( p_sys->p_input, p_sys->es[i]->p_es );
}
vlc_mutex_unlock( &p_sys->p_input->stream.stream_lock );
}
}
else
{
vlc_mutex_lock( &p_sys->p_input->stream.stream_lock );
EsOutSelect( out, es, VLC_TRUE );
vlc_mutex_unlock( &p_sys->p_input->stream.stream_lock );
}
return VLC_SUCCESS; return VLC_SUCCESS;
default: default:
...@@ -393,3 +584,6 @@ static int EsOutControl( es_out_t *out, int i_query, va_list args ) ...@@ -393,3 +584,6 @@ static int EsOutControl( es_out_t *out, int i_query, va_list args )
} }
} }
...@@ -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.264 2003/11/26 18:48:24 gbazin Exp $ * $Id: input.c,v 1.265 2003/11/27 04:11:40 fenrir Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -622,6 +622,8 @@ static int InitThread( input_thread_t * p_input ) ...@@ -622,6 +622,8 @@ static int InitThread( input_thread_t * p_input )
} }
p_input->p_es_out = input_EsOutNew( p_input ); p_input->p_es_out = input_EsOutNew( p_input );
es_out_Control( p_input->p_es_out, ES_OUT_SET_ACTIVE, VLC_FALSE );
es_out_Control( p_input->p_es_out, ES_OUT_SET_MODE, ES_OUT_MODE_NONE );
/* Find and open appropriate access module */ /* Find and open appropriate access module */
p_input->p_access = module_Need( p_input, "access", p_input->p_access = module_Need( p_input, "access",
...@@ -744,7 +746,7 @@ static int InitThread( input_thread_t * p_input ) ...@@ -744,7 +746,7 @@ static int InitThread( input_thread_t * p_input )
if( ( p_sub = subtitle_New( p_input, strdup(val.psz_string), i_microsecondperframe, 0 ) ) ) if( ( p_sub = subtitle_New( p_input, strdup(val.psz_string), i_microsecondperframe, 0 ) ) )
{ {
/* Select this ES by default */ /* Select this ES by default */
es_out_Control( p_input->p_es_out, ES_OUT_SET_SELECT, p_sub->p_es, VLC_TRUE ); es_out_Control( p_input->p_es_out, ES_OUT_SET_ES_STATE, p_sub->p_es, VLC_TRUE );
TAB_APPEND( p_input->p_sys->i_sub, p_input->p_sys->sub, p_sub ); TAB_APPEND( p_input->p_sys->i_sub, p_input->p_sys->sub, p_sub );
} }
...@@ -767,6 +769,9 @@ static int InitThread( input_thread_t * p_input ) ...@@ -767,6 +769,9 @@ static int InitThread( input_thread_t * p_input )
free(tmp); free(tmp);
} }
es_out_Control( p_input->p_es_out, ES_OUT_SET_ACTIVE, VLC_TRUE );
es_out_Control( p_input->p_es_out, ES_OUT_SET_MODE, ES_OUT_MODE_AUTO );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
......
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