X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Finput%2Finput_programs.c;h=90f855a27db96f3b5a4464bbfcb66075dbb781f2;hb=bc061e8455fa11eec3167681d53f9df3974b13a5;hp=50f8c6bbf88c1cbf9e765ce3a25a873a06115ab3;hpb=a558a9bb47f6212da40eb8798243d08107865f7d;p=vlc diff --git a/src/input/input_programs.c b/src/input/input_programs.c index 50f8c6bbf8..90f855a27d 100644 --- a/src/input/input_programs.c +++ b/src/input/input_programs.c @@ -1,10 +1,10 @@ /***************************************************************************** * input_programs.c: es_descriptor_t, pgrm_descriptor_t management ***************************************************************************** - * Copyright (C) 1999, 2000 VideoLAN - * $Id: input_programs.c,v 1.25 2001/01/12 17:33:18 massiot Exp $ + * Copyright (C) 1999-2002 VideoLAN + * $Id: input_programs.c,v 1.98 2002/11/11 14:39:12 sam Exp $ * - * Authors: + * Authors: Christophe Massiot * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,24 +24,15 @@ /***************************************************************************** * Preamble *****************************************************************************/ -#include "defs.h" - #include +#include /* memcpy(), memset() */ -#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 @@ -51,23 +42,37 @@ /***************************************************************************** * input_InitStream: init the stream descriptor of the given input *****************************************************************************/ -void input_InitStream( input_thread_t * p_input, size_t i_data_len ) +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.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 ) { - intf_ErrMsg( "Unable to allocate memory in input_InitStream"); - /* FIXME : find a way to tell if failed */ - return; + msg_Err( p_input, "out of memory" ); + return 1; } memset( p_input->stream.p_demux_data, 0, i_data_len ); } + else + { + p_input->stream.p_demux_data = NULL; + } + + return 0; } /***************************************************************************** @@ -86,6 +91,23 @@ 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 ); + } } /***************************************************************************** @@ -103,7 +125,7 @@ pgrm_descriptor_t * input_FindProgram( input_thread_t * p_input, u16 i_pgrm_id ) } } - return( NULL ); + return NULL; } /***************************************************************************** @@ -115,65 +137,48 @@ pgrm_descriptor_t * input_AddProgram( input_thread_t * p_input, u16 i_pgrm_id, size_t i_data_len ) { /* Where to add the pgrm */ - int i_pgrm_index = p_input->stream.i_pgrm_number; + pgrm_descriptor_t * p_pgrm = malloc( sizeof(pgrm_descriptor_t) ); - 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, - p_input->stream.i_pgrm_number - * sizeof(pgrm_descriptor_t *) ); - if( p_input->stream.pp_programs == NULL ) - { - intf_ErrMsg( "Unable to realloc memory in input_AddProgram" ); - return( NULL ); - } - - /* Allocate the structure to store this description */ - p_input->stream.pp_programs[i_pgrm_index] = - malloc( sizeof(pgrm_descriptor_t) ); - if( p_input->stream.pp_programs[i_pgrm_index] == NULL ) + if( p_pgrm == NULL ) { - intf_ErrMsg( "Unable to allocate memory in input_AddProgram" ); - return( NULL ); + msg_Err( p_input, "out of memory" ); + return NULL; } - + /* Init this entry */ - p_input->stream.pp_programs[i_pgrm_index]->i_number = i_pgrm_id; - p_input->stream.pp_programs[i_pgrm_index]->b_is_ok = 0; - p_input->stream.pp_programs[i_pgrm_index]->i_version = 0; - - p_input->stream.pp_programs[i_pgrm_index]->i_es_number = 0; - p_input->stream.pp_programs[i_pgrm_index]->pp_es = NULL; - - p_input->stream.pp_programs[i_pgrm_index]->delta_cr = 0; - p_input->stream.pp_programs[i_pgrm_index]->delta_absolute = 0; - p_input->stream.pp_programs[i_pgrm_index]->last_cr = 0; - p_input->stream.pp_programs[i_pgrm_index]->c_average_count = 0; - p_input->stream.pp_programs[i_pgrm_index]->i_synchro_state - = SYNCHRO_NOT_STARTED; - p_input->stream.pp_programs[i_pgrm_index]->b_discontinuity = 0; - - 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; + p_pgrm->i_number = i_pgrm_id; + p_pgrm->b_is_ok = 0; + p_pgrm->i_version = 0; + + p_pgrm->i_es_number = 0; + p_pgrm->pp_es = NULL; + + input_ClockInit( p_pgrm ); + + p_pgrm->i_synchro_state = SYNCHRO_START; if( i_data_len ) { - p_input->stream.pp_programs[i_pgrm_index]->p_demux_data = - malloc( i_data_len ); - if( p_input->stream.pp_programs[i_pgrm_index]->p_demux_data == NULL ) + p_pgrm->p_demux_data = malloc( i_data_len ); + if( p_pgrm->p_demux_data == NULL ) { - intf_ErrMsg( "Unable to allocate memory in input_AddProgram" ); - return( NULL ); + msg_Err( p_input, "out of memory" ); + return NULL; } - memset( p_input->stream.pp_programs[i_pgrm_index]->p_demux_data, 0, - i_data_len ); + memset( p_pgrm->p_demux_data, 0, i_data_len ); } + else + { + p_pgrm->p_demux_data = NULL; + } + + /* Add an entry to the list of program associated with the stream */ + INSERT_ELEM( p_input->stream.pp_programs, + p_input->stream.i_pgrm_number, + p_input->stream.i_pgrm_number, + p_pgrm ); - return p_input->stream.pp_programs[i_pgrm_index]; + return p_pgrm; } /***************************************************************************** @@ -185,9 +190,20 @@ void input_DelProgram( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm ) { int i_pgrm_index; - ASSERT( p_pgrm ); + /* Find the program in the programs table */ + for( i_pgrm_index = 0; i_pgrm_index < p_input->stream.i_pgrm_number; + i_pgrm_index++ ) + { + if( p_input->stream.pp_programs[i_pgrm_index] == p_pgrm ) + break; + } - intf_DbgMsg("Deleting description for pgrm %d", p_pgrm->i_number); + /* If the program wasn't found, do nothing */ + if( i_pgrm_index == p_input->stream.i_pgrm_number ) + { + msg_Err( p_input, "program does not belong to this input" ); + return; + } /* Free the structures that describe the es that belongs to that program */ while( p_pgrm->i_es_number ) @@ -201,33 +217,182 @@ void input_DelProgram( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm ) free( p_pgrm->p_demux_data ); } - /* Find the program in the programs table */ - for( i_pgrm_index = 0; i_pgrm_index < p_input->stream.i_pgrm_number; - i_pgrm_index++ ) + /* Remove this program from the stream's list of programs */ + REMOVE_ELEM( p_input->stream.pp_programs, + p_input->stream.i_pgrm_number, + i_pgrm_index ); + + /* Free the description of this program */ + free( p_pgrm ); +} + +/***************************************************************************** + * input_AddArea: add and init an area descriptor + ***************************************************************************** + * This area descriptor will be referenced in the given stream descriptor + *****************************************************************************/ +input_area_t * input_AddArea( input_thread_t * p_input ) +{ + /* Where to add the pgrm */ + input_area_t * p_area = malloc( sizeof(input_area_t) ); + + if( p_area == NULL ) { - if( p_input->stream.pp_programs[i_pgrm_index] == p_pgrm ) + msg_Err( p_input, "out of memory" ); + return NULL; + } + + /* Init this entry */ + p_area->i_id = 0; + p_area->i_start = 0; + p_area->i_size = 0; + p_area->i_tell = 0; + p_area->i_seek = NO_SEEK; + p_area->i_part_nb = 1; + p_area->i_part= 0; + + /* Add an entry to the list of program associated with the stream */ + INSERT_ELEM( p_input->stream.pp_areas, + p_input->stream.i_area_nb, + p_input->stream.i_area_nb, + p_area ); + + return p_area; +} + +/***************************************************************************** + * 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( config_GetInt( p_input, "audio" ) ) + { + /* Default is the first one */ + i_required_audio_es = config_GetInt( p_input, "audio-channel" ); + if( i_required_audio_es < 0 ) + { + i_required_audio_es = 1; + } + } + else + { + i_required_audio_es = 0; + } + + /* Same thing for subtitles */ + if( config_GetInt( p_input, "video" ) ) + { + /* for spu, default is none */ + i_required_spu_es = config_GetInt( p_input, "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: + msg_Dbg( p_input, "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 ) + { + msg_Dbg( p_input, "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 ) + { + msg_Dbg( p_input, "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 : + msg_Dbg( p_input, "ES %x has unknown type", + p_new_prg->pp_es[i_es_index]->i_id ); + break; + } + } - /* Remove this program from the stream's list of programs */ - p_input->stream.i_pgrm_number--; - p_input->stream.pp_programs[i_pgrm_index] = - p_input->stream.pp_programs[p_input->stream.i_pgrm_number]; - p_input->stream.pp_programs = realloc( p_input->stream.pp_programs, - p_input->stream.i_pgrm_number - * sizeof(pgrm_descriptor_t *) ); + p_input->stream.p_selected_program = p_new_prg; + + return( 0 ); +} + + +/***************************************************************************** + * input_DelArea: destroy a area descriptor + ***************************************************************************** + * All ES descriptions referenced in the descriptor will be deleted. + *****************************************************************************/ +void input_DelArea( input_thread_t * p_input, input_area_t * p_area ) +{ + int i_area_index; + + /* Find the area in the areas table */ + for( i_area_index = 0; i_area_index < p_input->stream.i_area_nb; + i_area_index++ ) + { + if( p_input->stream.pp_areas[i_area_index] == p_area ) + break; + } - if( p_input->stream.i_pgrm_number && p_input->stream.pp_programs == NULL) + /* If the area wasn't found, do nothing */ + if( i_area_index == p_input->stream.i_area_nb ) { - intf_ErrMsg( "input error: unable to realloc program list" - " in input_DelProgram" ); + msg_Err( p_input, "area does not belong to this input" ); + return; } - /* Free the description of this program */ - free( p_pgrm ); + /* Remove this area from the stream's list of areas */ + REMOVE_ELEM( p_input->stream.pp_areas, + p_input->stream.i_area_nb, + i_area_index ); + + /* Free the description of this area */ + free( p_area ); } + /***************************************************************************** * input_FindES: returns a pointer to an ES described by its ID *****************************************************************************/ @@ -243,7 +408,7 @@ es_descriptor_t * input_FindES( input_thread_t * p_input, u16 i_es_id ) } } - return( NULL ); + return NULL; } /***************************************************************************** @@ -259,37 +424,34 @@ 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 ) { - intf_ErrMsg( "Unable to allocate memory in input_AddES" ); + msg_Err( p_input, "out of memory" ); return( NULL); } - p_input->stream.i_es_number++; - p_input->stream.pp_es = realloc( p_input->stream.pp_es, - p_input->stream.i_es_number - * sizeof(es_descriptor_t *) ); - if( p_input->stream.pp_es == NULL ) - { - intf_ErrMsg( "Unable to realloc memory in input_AddES" ); - return( NULL ); - } - p_input->stream.pp_es[p_input->stream.i_es_number - 1] = p_es; - p_es->i_id = i_es_id; + + INSERT_ELEM( p_input->stream.pp_es, + p_input->stream.i_es_number, + p_input->stream.i_es_number, + p_es ); /* Init its values */ - p_es->b_discontinuity = 0; + p_es->i_id = i_es_id; + p_es->psz_desc[0] = '\0'; p_es->p_pes = NULL; p_es->p_decoder_fifo = NULL; + p_es->i_cat = UNKNOWN_ES; + p_es->i_demux_fd = 0; + p_es->c_packets = 0; + p_es->c_invalid_packets = 0; if( i_data_len ) { p_es->p_demux_data = malloc( i_data_len ); if( p_es->p_demux_data == NULL ) { - intf_ErrMsg( "Unable to allocate memory in input_AddES" ); + msg_Err( p_input, "out of memory" ); return( NULL ); } memset( p_es->p_demux_data, 0, i_data_len ); @@ -302,16 +464,10 @@ es_descriptor_t * input_AddES( input_thread_t * p_input, /* Add this ES to the program definition if one is given */ if( p_pgrm ) { - p_pgrm->i_es_number++; - p_pgrm->pp_es = realloc( p_pgrm->pp_es, - p_pgrm->i_es_number - * sizeof(es_descriptor_t *) ); - if( p_pgrm->pp_es == NULL ) - { - intf_ErrMsg( "Unable to realloc memory in input_AddES" ); - return( NULL ); - } - p_pgrm->pp_es[p_pgrm->i_es_number - 1] = p_es; + INSERT_ELEM( p_pgrm->pp_es, + p_pgrm->i_es_number, + p_pgrm->i_es_number, + p_es ); p_es->p_pgrm = p_pgrm; } else @@ -330,7 +486,21 @@ void input_DelES( input_thread_t * p_input, es_descriptor_t * p_es ) int i_index, i_es_index; pgrm_descriptor_t * p_pgrm; - ASSERT( p_es ); + /* Find the ES in the ES table */ + for( i_es_index = 0; i_es_index < p_input->stream.i_es_number; + i_es_index++ ) + { + if( p_input->stream.pp_es[i_es_index] == p_es ) + break; + } + + /* If the ES wasn't found, do nothing */ + if( i_es_index == p_input->stream.i_es_number ) + { + msg_Err( p_input, "ES does not belong to this input" ); + return; + } + p_pgrm = p_es->p_pgrm; /* Kill associated decoder, if any. */ @@ -347,15 +517,9 @@ void input_DelES( input_thread_t * p_input, es_descriptor_t * p_es ) { if( p_pgrm->pp_es[i_index] == p_es ) { - p_pgrm->i_es_number--; - p_pgrm->pp_es[i_index] = p_pgrm->pp_es[p_pgrm->i_es_number]; - p_pgrm->pp_es = realloc( p_pgrm->pp_es, - p_pgrm->i_es_number - * sizeof(es_descriptor_t *)); - if( p_pgrm->i_es_number && p_pgrm->pp_es == NULL ) - { - intf_ErrMsg( "Unable to realloc memory in input_DelES" ); - } + REMOVE_ELEM( p_pgrm->pp_es, + p_pgrm->i_es_number, + i_index ); break; } } @@ -375,224 +539,111 @@ void input_DelES( input_thread_t * p_input, es_descriptor_t * p_es ) break; } + /* Remove this ES from the stream's list of ES */ + REMOVE_ELEM( p_input->stream.pp_es, + p_input->stream.i_es_number, + i_es_index ); + /* Free the ES */ free( p_es ); - p_input->stream.i_es_number--; - p_input->stream.pp_es[i_es_index] = - p_input->stream.pp_es[p_input->stream.i_es_number]; - p_input->stream.pp_es = realloc( p_input->stream.pp_es, - p_input->stream.i_es_number - * sizeof(es_descriptor_t *)); - if( p_input->stream.i_es_number && p_input->stream.pp_es == NULL ) - { - intf_ErrMsg( "Unable to realloc memory in input_DelES" ); - } - } -#ifdef STATS /***************************************************************************** - * input_DumpStream: dumps the contents of a stream descriptor + * input_SelectES: selects an ES and spawns the associated decoder + ***************************************************************************** + * Remember we are still supposed to have stream_lock when entering this + * function ? *****************************************************************************/ -void input_DumpStream( input_thread_t * p_input ) +int input_SelectES( input_thread_t * p_input, es_descriptor_t * p_es ) { - int i, j; -#define S p_input->stream - intf_Msg( "input info: Dumping stream ID 0x%x", S.i_stream_id ); - if( S.b_seekable ) - intf_Msg( "input info: seekable stream, position: %d/%d", - S.i_tell, S.i_size ); - else - intf_Msg( "input info: %s", S.b_pace_control ? "pace controlled" : - "pace un-controlled" ); -#undef S - for( i = 0; i < p_input->stream.i_pgrm_number; i++ ) + if( p_es == NULL ) { -#define P p_input->stream.pp_programs[i] - intf_Msg( "input info: Dumping program 0x%x, version %d (%s)", - P->i_number, P->i_version, - P->b_is_ok ? "complete" : "partial" ); - if( P->i_synchro_state == SYNCHRO_OK ) - intf_Msg( "input info: synchro absolute delta : %lld (jitter : %lld)", - P->delta_absolute, P->delta_cr ); -#undef P - for( j = 0; j < p_input->stream.pp_programs[i]->i_es_number; j++ ) - { -#define ES p_input->stream.pp_programs[i]->pp_es[j] - intf_Msg( "input info: ES 0x%x, stream 0x%x, type 0x%x, %s", - ES->i_id, ES->i_stream_id, ES->i_type, - ES->p_decoder_fifo != NULL ? "selected" : "not selected"); -#undef ES - } + msg_Err( p_input, "nothing to do in input_SelectES" ); + return -1; } -} -#endif -/***************************************************************************** - * 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 ) + if( ((p_es->i_cat == VIDEO_ES) || (p_es->i_cat == SPU_ES)) + && !config_GetInt( p_input, "video" ) ) { - intf_ErrMsg( "Out of memory" ); - return( -1 ); + msg_Dbg( p_input, + "video is disabled, not selecting ES 0x%x", p_es->i_id ); + 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->p_plugin->pf_delete_pes; - p_es->p_decoder_fifo = p_config->p_decoder_fifo; - - p_config->pf_init_bit_stream = InitBitstream; - - return( 0 ); -} + if( (p_es->i_cat == AUDIO_ES) && !config_GetInt( p_input, "audio" ) ) + { + msg_Dbg( p_input, + "audio is disabled, not selecting ES 0x%x", p_es->i_id ); + return -1; + } -/***************************************************************************** - * 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; + msg_Dbg( p_input, "selecting ES 0x%x", p_es->i_id ); - p_config = (vdec_config_t *)malloc( sizeof(vdec_config_t) ); - if( p_config == NULL ) + if( p_es->p_decoder_fifo != NULL ) { - intf_ErrMsg( "Unable to allocate memory in GetVdecConfig" ); - return( NULL ); + msg_Err( p_input, "ES 0x%x is already selected", p_es->i_id ); + return -1; } - p_config->p_vout = p_input->p_default_vout; - if( InitDecConfig( p_input, p_es, &p_config->decoder_config ) == -1 ) + + /* 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->p_decoder_fifo = input_RunDecoder( p_input, p_es ); + vlc_mutex_lock( &p_input->stream.stream_lock ); + + if( p_es->p_decoder_fifo == NULL ) { - free( p_config ); - return( NULL ); + return -1; } - return( p_config ); + return 0; } /***************************************************************************** - * GetAdecConfig: returns a valid adec_config_t + * input_UnselectES: removes an ES from the list of selected ES *****************************************************************************/ -static adec_config_t * GetAdecConfig( input_thread_t * p_input, - es_descriptor_t * p_es ) +int input_UnselectES( 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 ) + int i_index = 0; + + if( p_es == NULL ) { - free( p_config ); - return( NULL ); + msg_Err( p_input, "nothing to do in input_UnselectES" ); + return -1; } - return( p_config ); -} + msg_Dbg( p_input, "unselecting ES 0x%x", p_es->i_id ); -/***************************************************************************** - * input_SelectES: selects an ES and spawns the associated decoder - *****************************************************************************/ -/* 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; - -#ifdef DEBUG_INPUT - intf_DbgMsg( "Selecting ES 0x%x", p_es->i_id ); -#endif - - if( p_es->p_decoder_fifo != NULL ) + if( p_es->p_decoder_fifo == NULL ) { - intf_ErrMsg( "ES %d is already selected", p_es->i_id ); + msg_Err( p_input, "ES 0x%x is not selected", p_es->i_id ); return( -1 ); } - switch( p_es->i_type ) - { - case MPEG1_AUDIO_ES: - case MPEG2_AUDIO_ES: - if( p_main->b_audio ) - { - decoder.pf_create_thread = adec_CreateThread; - p_es->thread_id = input_RunDecoder( &decoder, - (void *)GetAdecConfig( p_input, p_es ) ); - } - break; + input_EndDecoder( p_input, p_es ); + p_es->p_pes = NULL; - case MPEG1_VIDEO_ES: - case MPEG2_VIDEO_ES: - if( p_main->b_video ) + if( ( p_es->p_decoder_fifo == NULL ) && + ( p_input->stream.i_selected_es_number > 0 ) ) + { + while( ( i_index < p_input->stream.i_selected_es_number - 1 ) && + ( p_input->stream.pp_selected_es[i_index] != p_es ) ) { - decoder.pf_create_thread = vpar_CreateThread; - p_es->thread_id = input_RunDecoder( &decoder, - (void *)GetVdecConfig( p_input, p_es ) ); + i_index++; } - break; - case AC3_AUDIO_ES: - if( p_main->b_audio ) - { - decoder.pf_create_thread = ac3dec_CreateThread; - p_es->thread_id = input_RunDecoder( &decoder, - (void *)GetAdecConfig( p_input, p_es ) ); - } - break; + /* XXX: no need to memmove, we have unsorted data */ + REMOVE_ELEM( p_input->stream.pp_selected_es, + p_input->stream.i_selected_es_number, + i_index ); - case DVD_SPU_ES: - if( p_main->b_video ) + if( p_input->stream.i_selected_es_number == 0 ) { - decoder.pf_create_thread = spudec_CreateThread; - p_es->thread_id = input_RunDecoder( &decoder, - (void *)GetVdecConfig( p_input, p_es ) ); + msg_Dbg( p_input, "no more selected ES" ); + return 1; } - break; - - default: - intf_ErrMsg( "Unknown stream type %d", p_es->i_type ); - return( -1 ); - break; } - if( p_es->p_decoder_fifo != NULL ) - { - 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 ); + return 0; }