X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Finput%2Finput_programs.c;h=0404a95012a7223ef8efaab6bab1a675ea10b073;hb=eb1ec4a42c24cdf9a2b916feeac47324b6edcbc5;hp=4ac64d14bb4772b3ae0a175f03dc939a4ff8ce65;hpb=b3d7d241c512324a517d08a165cbba69e6e5f008;p=vlc diff --git a/src/input/input_programs.c b/src/input/input_programs.c index 4ac64d14bb..0404a95012 100644 --- a/src/input/input_programs.c +++ b/src/input/input_programs.c @@ -1,8 +1,8 @@ /***************************************************************************** * input_programs.c: es_descriptor_t, pgrm_descriptor_t management ***************************************************************************** - * Copyright (C) 1999, 2000 VideoLAN - * $Id: input_programs.c,v 1.46 2001/04/10 17:47:05 stef Exp $ + * Copyright (C) 1999-2001 VideoLAN + * $Id: input_programs.c,v 1.83 2002/04/25 21:52:42 sam Exp $ * * Authors: Christophe Massiot * @@ -24,25 +24,16 @@ /***************************************************************************** * Preamble *****************************************************************************/ -#include "defs.h" - #include #include /* memcpy(), memset() */ +#include /* off_t */ -#include "config.h" -#include "common.h" -#include "threads.h" -#include "mtime.h" -#include "debug.h" - -#include "intf_msg.h" +#include #include "stream_control.h" #include "input_ext-intf.h" #include "input_ext-dec.h" -#include "input.h" - -#include "main.h" /* --noaudio --novideo */ +#include "input_ext-plugins.h" /* * NOTICE : all of these functions expect you to have taken the lock on @@ -54,13 +45,20 @@ *****************************************************************************/ int input_InitStream( input_thread_t * p_input, size_t i_data_len ) { + p_input->stream.i_stream_id = 0; + + /* initialized to 0 since we don't give the signal to the interface + * before the end of input initialization */ + p_input->stream.b_changed = 0; p_input->stream.pp_es = NULL; p_input->stream.pp_selected_es = NULL; + p_input->stream.p_removed_es = NULL; + p_input->stream.p_newly_selected_es = NULL; p_input->stream.pp_programs = NULL; - p_input->stream.pp_areas = NULL; - p_input->stream.p_selected_area = NULL; - + p_input->stream.p_selected_program = NULL; + p_input->stream.p_new_program = NULL; + if( i_data_len ) { if ( (p_input->stream.p_demux_data = malloc( i_data_len )) == NULL ) @@ -70,6 +68,10 @@ int input_InitStream( input_thread_t * p_input, size_t i_data_len ) } memset( p_input->stream.p_demux_data, 0, i_data_len ); } + else + { + p_input->stream.p_demux_data = NULL; + } return 0; } @@ -91,6 +93,18 @@ void input_EndStream( input_thread_t * p_input ) input_DelES( p_input, p_input->stream.pp_es[0] ); } + /* Free all areas */ + while( p_input->stream.i_area_nb ) + { + input_DelArea( p_input, p_input->stream.pp_areas[0] ); + } + + /* Free selected ES */ + if( p_input->stream.pp_selected_es != NULL ) + { + free( p_input->stream.pp_selected_es ); + } + if( p_input->stream.p_demux_data != NULL ) { free( p_input->stream.p_demux_data ); @@ -126,8 +140,6 @@ pgrm_descriptor_t * input_AddProgram( input_thread_t * p_input, /* Where to add the pgrm */ int i_pgrm_index = p_input->stream.i_pgrm_number; - intf_DbgMsg("Adding description for pgrm %d", i_pgrm_id); - /* Add an entry to the list of program associated with the stream */ p_input->stream.i_pgrm_number++; p_input->stream.pp_programs = realloc( p_input->stream.pp_programs, @@ -161,11 +173,6 @@ pgrm_descriptor_t * input_AddProgram( input_thread_t * p_input, p_input->stream.pp_programs[i_pgrm_index]->i_synchro_state = SYNCHRO_START; - p_input->stream.pp_programs[i_pgrm_index]->p_vout - = p_input->p_default_vout; - p_input->stream.pp_programs[i_pgrm_index]->p_aout - = p_input->p_default_aout; - if( i_data_len ) { p_input->stream.pp_programs[i_pgrm_index]->p_demux_data = @@ -178,6 +185,10 @@ pgrm_descriptor_t * input_AddProgram( input_thread_t * p_input, memset( p_input->stream.pp_programs[i_pgrm_index]->p_demux_data, 0, i_data_len ); } + else + { + p_input->stream.pp_programs[i_pgrm_index]->p_demux_data = NULL; + } return p_input->stream.pp_programs[i_pgrm_index]; } @@ -193,8 +204,6 @@ void input_DelProgram( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm ) ASSERT( p_pgrm ); - intf_DbgMsg("Deleting description for pgrm %d", p_pgrm->i_number); - /* Free the structures that describe the es that belongs to that program */ while( p_pgrm->i_es_number ) { @@ -244,8 +253,6 @@ input_area_t * input_AddArea( input_thread_t * p_input ) /* Where to add the pgrm */ int i_area_index = p_input->stream.i_area_nb; - intf_DbgMsg("Adding description for area %d", i_area_index ); - /* Add an entry to the list of program associated with the stream */ p_input->stream.i_area_nb++; p_input->stream.pp_areas = realloc( p_input->stream.pp_areas, @@ -278,6 +285,105 @@ input_area_t * input_AddArea( input_thread_t * p_input ) return p_input->stream.pp_areas[i_area_index]; } +/***************************************************************************** + * input_SetProgram: changes the current program + *****************************************************************************/ +int input_SetProgram( input_thread_t * p_input, pgrm_descriptor_t * p_new_prg ) +{ + int i_es_index; + int i_required_audio_es; + int i_required_spu_es; + int i_audio_es = 0; + int i_spu_es = 0; + + if ( p_input->stream.p_selected_program ) + { + for ( i_es_index = 1 ; /* 0 should be the PMT */ + i_es_index < p_input->stream.p_selected_program-> + i_es_number ; + i_es_index ++ ) + { +#define p_es p_input->stream.p_selected_program->pp_es[i_es_index] + if ( p_es->p_decoder_fifo ) /* if the ES was selected */ + { + input_UnselectES( p_input , p_es ); + } +#undef p_es + } + } + /* Get the number of the required audio stream */ + if( p_main->b_audio ) + { + /* Default is the first one */ + i_required_audio_es = config_GetIntVariable( "audio-channel" ); + if( i_required_audio_es < 0 ) + { + i_required_audio_es = 1; + } + } + else + { + i_required_audio_es = 0; + } + + /* Same thing for subtitles */ + if( p_main->b_video ) + { + /* for spu, default is none */ + i_required_spu_es = config_GetIntVariable( "spu-channel" ); + if( i_required_spu_es < 0 ) + { + i_required_spu_es = 0; + } + } + else + { + i_required_spu_es = 0; + } + + for (i_es_index = 0 ; i_es_index < p_new_prg->i_es_number ; i_es_index ++ ) + { + switch( p_new_prg->pp_es[i_es_index]->i_cat ) + { + case VIDEO_ES: + intf_WarnMsg( 4, "Selecting ES %x", + p_new_prg->pp_es[i_es_index]->i_id ); + input_SelectES( p_input, p_new_prg->pp_es[i_es_index] ); + break; + case AUDIO_ES: + i_audio_es += 1; + if( i_audio_es <= i_required_audio_es ) + { + intf_WarnMsg( 4, "Selecting ES %x", + p_new_prg->pp_es[i_es_index]->i_id ); + input_SelectES( p_input, p_new_prg->pp_es[i_es_index]); + } + break; + /* Not sure this one is fully specification-compliant */ + case SPU_ES : + i_spu_es += 1; + if( i_spu_es <= i_required_spu_es ) + { + intf_WarnMsg( 4, "Selecting ES %x", + p_new_prg->pp_es[i_es_index]->i_id ); + input_SelectES( p_input, p_new_prg->pp_es[i_es_index] ); + } + break; + default : + intf_WarnMsg( 2, "ES %x has unknown type", + p_new_prg->pp_es[i_es_index]->i_id ); + break; + } + + } + + + p_input->stream.p_selected_program = p_new_prg; + + return( 0 ); +} + + /***************************************************************************** * input_DelArea: destroy a area descriptor ***************************************************************************** @@ -289,8 +395,6 @@ void input_DelArea( input_thread_t * p_input, input_area_t * p_area ) ASSERT( p_area ); - intf_DbgMsg("Deleting description for area %d", p_area->i_id ); - /* Find the area in the areas table */ for( i_area_index = 0; i_area_index < p_input->stream.i_area_nb; i_area_index++ ) @@ -350,8 +454,6 @@ es_descriptor_t * input_AddES( input_thread_t * p_input, { es_descriptor_t * p_es; - intf_DbgMsg("Adding description for ES 0x%x", i_es_id); - p_es = (es_descriptor_t *)malloc( sizeof(es_descriptor_t) ); if( p_es == NULL ) { @@ -376,6 +478,7 @@ es_descriptor_t * input_AddES( input_thread_t * p_input, p_es->p_decoder_fifo = NULL; p_es->b_audio = 0; p_es->i_cat = UNKNOWN_ES; + p_es->i_demux_fd = 0; if( i_data_len ) { @@ -483,127 +586,21 @@ void input_DelES( input_thread_t * p_input, es_descriptor_t * p_es ) } -/***************************************************************************** - * InitDecConfig: initializes a decoder_config_t - *****************************************************************************/ -static int InitDecConfig( input_thread_t * p_input, es_descriptor_t * p_es, - decoder_config_t * p_config ) -{ - p_config->i_id = p_es->i_id; - p_config->i_type = p_es->i_type; - p_config->p_stream_ctrl = - &p_input->stream.control; - - /* Decoder FIFO */ - if( (p_config->p_decoder_fifo = - (decoder_fifo_t *)malloc( sizeof(decoder_fifo_t) )) == NULL ) - { - intf_ErrMsg( "Out of memory" ); - return( -1 ); - } - - vlc_mutex_init(&p_config->p_decoder_fifo->data_lock); - vlc_cond_init(&p_config->p_decoder_fifo->data_wait); - p_config->p_decoder_fifo->i_start = p_config->p_decoder_fifo->i_end = 0; - p_config->p_decoder_fifo->b_die = p_config->p_decoder_fifo->b_error = 0; - p_config->p_decoder_fifo->p_packets_mgt = p_input->p_method_data; - p_config->p_decoder_fifo->pf_delete_pes = p_input->pf_delete_pes; - p_es->p_decoder_fifo = p_config->p_decoder_fifo; - - p_config->pf_init_bit_stream = InitBitstream; - - p_input->stream.i_selected_es_number++; - - p_input->stream.pp_selected_es = realloc( - p_input->stream.pp_selected_es, - p_input->stream.i_selected_es_number - * sizeof(es_descriptor_t *) ); - if( p_input->stream.pp_selected_es == NULL ) - { - intf_ErrMsg( "Unable to realloc memory in input_SelectES" ); - return(-1); - } - p_input->stream.pp_selected_es[p_input->stream.i_selected_es_number - 1] - = p_es; - - return( 0 ); -} - -/***************************************************************************** - * GetVdecConfig: returns a valid vdec_config_t - *****************************************************************************/ -static vdec_config_t * GetVdecConfig( input_thread_t * p_input, - es_descriptor_t * p_es ) -{ - vdec_config_t * p_config; - - p_config = (vdec_config_t *)malloc( sizeof(vdec_config_t) ); - if( p_config == NULL ) - { - intf_ErrMsg( "Unable to allocate memory in GetVdecConfig" ); - return( NULL ); - } - p_config->p_vout = p_input->p_default_vout; - if( InitDecConfig( p_input, p_es, &p_config->decoder_config ) == -1 ) - { - free( p_config ); - return( NULL ); - } - - return( p_config ); -} - -/***************************************************************************** - * GetAdecConfig: returns a valid adec_config_t - *****************************************************************************/ -static adec_config_t * GetAdecConfig( input_thread_t * p_input, - es_descriptor_t * p_es ) -{ - adec_config_t * p_config; - - p_config = (adec_config_t *)malloc( sizeof(adec_config_t)); - if( p_config == NULL ) - { - intf_ErrMsg( "Unable to allocate memory in GetAdecConfig" ); - return( NULL ); - } - p_config->p_aout = p_input->p_default_aout; - if( InitDecConfig( p_input, p_es, &p_config->decoder_config ) == -1 ) - { - free( p_config ); - return( NULL ); - } - - return( p_config ); -} - /***************************************************************************** * input_SelectES: selects an ES and spawns the associated decoder ***************************************************************************** * Remember we are still supposed to have stream_lock when entering this * function ? *****************************************************************************/ -/* FIXME */ -vlc_thread_t adec_CreateThread( void * ); -vlc_thread_t ac3dec_CreateThread( void * ); -vlc_thread_t vpar_CreateThread( void * ); -vlc_thread_t spudec_CreateThread( void * ); - int input_SelectES( input_thread_t * p_input, es_descriptor_t * p_es ) { - /* FIXME ! */ - decoder_capabilities_t decoder; - void * p_config; - if( p_es == NULL ) { - intf_ErrMsg( "Nothing to do in input_SelectES" ); + intf_ErrMsg( "input error: nothing to do in input_SelectES" ); return -1; } -#ifdef DEBUG_INPUT - intf_DbgMsg( "Selecting ES 0x%x", p_es->i_id ); -#endif + intf_WarnMsg( 4, "input: selecting ES 0x%x", p_es->i_id ); if( p_es->p_decoder_fifo != NULL ) { @@ -611,62 +608,35 @@ int input_SelectES( input_thread_t * p_input, es_descriptor_t * p_es ) return( -1 ); } + p_es->thread_id = 0; + switch( p_es->i_type ) { + case AC3_AUDIO_ES: case MPEG1_AUDIO_ES: case MPEG2_AUDIO_ES: + case MPEG4_VIDEO_ES: + case MSMPEG4_VIDEO_ES: + case LPCM_AUDIO_ES: if( p_main->b_audio ) { - decoder.pf_create_thread = adec_CreateThread; - p_config = (void *)GetAdecConfig( p_input, p_es ); - /* Release the lock, not to block the input thread during * the creation of the thread. */ vlc_mutex_unlock( &p_input->stream.stream_lock ); - p_es->thread_id = input_RunDecoder( &decoder, p_config ); + p_es->thread_id = input_RunDecoder( p_input, p_es ); vlc_mutex_lock( &p_input->stream.stream_lock ); } break; case MPEG1_VIDEO_ES: case MPEG2_VIDEO_ES: - if( p_main->b_video ) - { - decoder.pf_create_thread = vpar_CreateThread; - p_config = (void *)GetVdecConfig( p_input, p_es ); - - /* Release the lock, not to block the input thread during - * the creation of the thread. */ - vlc_mutex_unlock( &p_input->stream.stream_lock ); - p_es->thread_id = input_RunDecoder( &decoder, p_config ); - vlc_mutex_lock( &p_input->stream.stream_lock ); - } - break; - - case AC3_AUDIO_ES: - if( p_main->b_audio ) - { - decoder.pf_create_thread = ac3dec_CreateThread; - p_config = (void *)GetAdecConfig( p_input, p_es ); - - /* Release the lock, not to block the input thread during - * the creation of the thread. */ - vlc_mutex_unlock( &p_input->stream.stream_lock ); - p_es->thread_id = input_RunDecoder( &decoder, p_config ); - vlc_mutex_lock( &p_input->stream.stream_lock ); - } - break; - case DVD_SPU_ES: if( p_main->b_video ) { - decoder.pf_create_thread = spudec_CreateThread; - p_config = (void *)GetVdecConfig( p_input, p_es ); - /* Release the lock, not to block the input thread during * the creation of the thread. */ vlc_mutex_unlock( &p_input->stream.stream_lock ); - p_es->thread_id = input_RunDecoder( &decoder, p_config ); + p_es->thread_id = input_RunDecoder( p_input, p_es ); vlc_mutex_lock( &p_input->stream.stream_lock ); } break; @@ -699,9 +669,7 @@ int input_UnselectES( input_thread_t * p_input, es_descriptor_t * p_es ) return -1; } -#ifdef DEBUG_INPUT - intf_DbgMsg( "Unselecting ES 0x%x", p_es->i_id ); -#endif + intf_WarnMsg( 4, "input: unselecting ES 0x%x", p_es->i_id ); if( p_es->p_decoder_fifo == NULL ) { @@ -710,6 +678,7 @@ int input_UnselectES( input_thread_t * p_input, es_descriptor_t * p_es ) } input_EndDecoder( p_input, p_es ); + p_es->p_pes = NULL; if( ( p_es->p_decoder_fifo == NULL ) && ( p_input->stream.i_selected_es_number > 0 ) ) @@ -732,9 +701,7 @@ int input_UnselectES( input_thread_t * p_input, es_descriptor_t * p_es ) if( p_input->stream.pp_selected_es == NULL ) { -#ifdef DEBUG_INPUT - intf_DbgMsg( "No more selected ES in input_UnselectES" ); -#endif + intf_WarnMsg( 4, "input: no more selected ES in input_UnselectES" ); return( 1 ); } }