X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Finput%2Finput_programs.c;h=e0f63273bcdf871fff66d8a6afcfdf79ce211ce0;hb=440f9992ee947ea5fd0debbf35fdd1011c6404b3;hp=a6f8dc3793342f78da85b30fd1de2c19c818bc10;hpb=10dda32d99399292d79edaf98b83ee75f0cd5726;p=vlc diff --git a/src/input/input_programs.c b/src/input/input_programs.c index a6f8dc3793..e0f63273bc 100644 --- a/src/input/input_programs.c +++ b/src/input/input_programs.c @@ -1,11 +1,10 @@ /***************************************************************************** * input_programs.c: es_descriptor_t, pgrm_descriptor_t management - * FIXME : check the return value of realloc() and malloc() ! ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: input_programs.c,v 1.16 2000/12/22 15:34:24 massiot Exp $ + * $Id: input_programs.c,v 1.57 2001/05/23 17:47:34 stef 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 @@ -28,6 +27,8 @@ #include "defs.h" #include +#include /* memcpy(), memset() */ +#include /* off_t */ #include "config.h" #include "common.h" @@ -41,7 +42,6 @@ #include "input_ext-intf.h" #include "input_ext-dec.h" #include "input.h" -#include "input_dec.h" #include "main.h" /* --noaudio --novideo */ @@ -53,18 +53,32 @@ /***************************************************************************** * 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_method = INPUT_METHOD_NONE; 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; if( i_data_len ) { - p_input->stream.p_demux_data = malloc( i_data_len ); + if ( (p_input->stream.p_demux_data = malloc( i_data_len )) == NULL ) + { + intf_ErrMsg( "Unable to allocate memory in input_InitStream"); + return 1; + } memset( p_input->stream.p_demux_data, 0, i_data_len ); } + + return 0; } /***************************************************************************** @@ -72,23 +86,28 @@ void input_InitStream( input_thread_t * p_input, size_t i_data_len ) *****************************************************************************/ void input_EndStream( input_thread_t * p_input ) { - int i; - /* Free all programs and associated ES, and associated decoders. */ - for( i = 0; i < p_input->stream.i_pgrm_number; i++ ) + while( p_input->stream.i_pgrm_number ) { - /* Don't put i instead of 0 !! */ input_DelProgram( p_input, p_input->stream.pp_programs[0] ); } - free( p_input->stream.pp_programs ); /* Free standalone ES */ - for( i = 0; i < p_input->stream.i_es_number; i++ ) + while( p_input->stream.i_es_number ) { input_DelES( p_input, p_input->stream.pp_es[0] ); } - free( p_input->stream.pp_es ); - free( p_input->stream.pp_selected_es ); + + /* Free all areas */ + while( p_input->stream.i_area_nb ) + { + input_DelArea( p_input, p_input->stream.pp_areas[0] ); + } + + if( p_input->stream.p_demux_data != NULL ) + { + free( p_input->stream.p_demux_data ); + } } /***************************************************************************** @@ -127,11 +146,21 @@ pgrm_descriptor_t * input_AddProgram( input_thread_t * p_input, 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 ) + { + intf_ErrMsg( "Unable to allocate memory in input_AddProgram" ); + 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; @@ -140,23 +169,20 @@ pgrm_descriptor_t * input_AddProgram( input_thread_t * p_input, 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; + input_ClockInit( p_input->stream.pp_programs[i_pgrm_index] ); - 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_input->stream.pp_programs[i_pgrm_index]->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 ) + { + intf_ErrMsg( "Unable to allocate memory in input_AddProgram" ); + return( NULL ); + } memset( p_input->stream.pp_programs[i_pgrm_index]->p_demux_data, 0, i_data_len ); } @@ -171,21 +197,18 @@ pgrm_descriptor_t * input_AddProgram( input_thread_t * p_input, *****************************************************************************/ void input_DelProgram( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm ) { - int i_index, i_pgrm_index; + int i_pgrm_index; 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 */ - for( i_index = 0; i_index < p_pgrm->i_es_number; i_index++ ) + while( p_pgrm->i_es_number ) { - input_DelES( p_input, p_pgrm->pp_es[i_index] ); + input_DelES( p_input, p_pgrm->pp_es[0] ); } - /* Free the table of es descriptors */ - free( p_pgrm->pp_es ); - /* Free the demux data */ if( p_pgrm->p_demux_data != NULL ) { @@ -202,16 +225,110 @@ void input_DelProgram( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm ) /* 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 *) ); + if( p_input->stream.i_pgrm_number && p_input->stream.pp_programs == NULL) + { + intf_ErrMsg( "input error: unable to realloc program list" + " in input_DelProgram" ); + } + /* 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 */ + 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, + p_input->stream.i_area_nb + * sizeof(input_area_t *) ); + if( p_input->stream.pp_areas == NULL ) + { + intf_ErrMsg( "Unable to realloc memory in input_AddArea" ); + return( NULL ); + } + + /* Allocate the structure to store this description */ + p_input->stream.pp_areas[i_area_index] = + malloc( sizeof(input_area_t) ); + if( p_input->stream.pp_areas[i_area_index] == NULL ) + { + intf_ErrMsg( "Unable to allocate memory in input_AddArea" ); + return( NULL ); + } + + /* Init this entry */ + p_input->stream.pp_areas[i_area_index]->i_id = 0; + p_input->stream.pp_areas[i_area_index]->i_start = 0; + p_input->stream.pp_areas[i_area_index]->i_size = 0; + p_input->stream.pp_areas[i_area_index]->i_tell = 0; + p_input->stream.pp_areas[i_area_index]->i_seek = NO_SEEK; + p_input->stream.pp_areas[i_area_index]->i_part_nb = 1; + p_input->stream.pp_areas[i_area_index]->i_part= 0; + p_input->stream.pp_areas[i_area_index]->i_angle_nb = 1; + p_input->stream.pp_areas[i_area_index]->i_angle = 0; + + return p_input->stream.pp_areas[i_area_index]; +} + +/***************************************************************************** + * 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; + + 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++ ) + { + if( p_input->stream.pp_areas[i_area_index] == p_area ) + break; + } + + /* Remove this area from the stream's list of areas */ + p_input->stream.i_area_nb--; + + p_input->stream.pp_areas[i_area_index] = + p_input->stream.pp_areas[p_input->stream.i_area_nb]; + p_input->stream.pp_areas = realloc( p_input->stream.pp_areas, + p_input->stream.i_area_nb + * sizeof(input_area_t *) ); + + if( p_input->stream.i_area_nb && p_input->stream.pp_areas == NULL) + { + intf_ErrMsg( "input error: unable to realloc area list" + " in input_DelArea" ); + } + + /* Free the description of this area */ + free( p_area ); +} + + /***************************************************************************** * input_FindES: returns a pointer to an ES described by its ID *****************************************************************************/ @@ -243,24 +360,41 @@ es_descriptor_t * input_AddES( input_thread_t * p_input, { es_descriptor_t * p_es; - intf_DbgMsg("Adding description for ES %d", i_es_id); + 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" ); + 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; /* 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->b_audio = 0; + p_es->i_cat = UNKNOWN_ES; 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" ); + return( NULL ); + } memset( p_es->p_demux_data, 0, i_data_len ); } else @@ -275,6 +409,11 @@ es_descriptor_t * input_AddES( input_thread_t * p_input, 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; p_es->p_pgrm = p_pgrm; } @@ -300,8 +439,7 @@ void input_DelES( input_thread_t * p_input, es_descriptor_t * p_es ) /* Kill associated decoder, if any. */ if( p_es->p_decoder_fifo != NULL ) { - input_EndDecoder( p_es->p_decoder_fifo, p_es->thread_id ); - free( p_es->p_decoder_fifo ); + input_EndDecoder( p_input, p_es ); } /* Remove this ES from the description of the program if it is associated to @@ -317,6 +455,10 @@ void input_DelES( input_thread_t * p_input, es_descriptor_t * p_es ) 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" ); + } break; } } @@ -344,45 +486,12 @@ void input_DelES( input_thread_t * p_input, es_descriptor_t * p_es ) p_input->stream.pp_es = realloc( p_input->stream.pp_es, p_input->stream.i_es_number * sizeof(es_descriptor_t *)); -} - -#ifdef STATS -/***************************************************************************** - * input_DumpStream: dumps the contents of a stream descriptor - *****************************************************************************/ -void input_DumpStream( input_thread_t * p_input ) -{ - 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_input->stream.i_es_number && p_input->stream.pp_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 - } + intf_ErrMsg( "Unable to realloc memory in input_DelES" ); } + } -#endif /***************************************************************************** * InitDecConfig: initializes a decoder_config_t @@ -390,7 +499,7 @@ void input_DumpStream( input_thread_t * p_input ) static int InitDecConfig( input_thread_t * p_input, es_descriptor_t * p_es, decoder_config_t * p_config ) { - p_config->i_stream_id = p_es->i_stream_id; + 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; @@ -408,12 +517,25 @@ static int InitDecConfig( input_thread_t * p_input, es_descriptor_t * p_es, 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_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 ); } @@ -426,11 +548,15 @@ static vdec_config_t * GetVdecConfig( input_thread_t * p_input, vdec_config_t * p_config; p_config = (vdec_config_t *)malloc( sizeof(vdec_config_t) ); - p_config->p_vout = p_input->p_default_vout; + if( p_config == NULL ) + { + intf_ErrMsg( "Unable to allocate memory in GetVdecConfig" ); + return( NULL ); + } if( InitDecConfig( p_input, p_es, &p_config->decoder_config ) == -1 ) { free( p_config ); - return NULL; + return( NULL ); } return( p_config ); @@ -444,12 +570,17 @@ static adec_config_t * GetAdecConfig( input_thread_t * p_input, { adec_config_t * p_config; - p_config = (adec_config_t *)malloc( sizeof(adec_config_t) ); - p_config->p_aout = p_input->p_default_aout; + p_config = (adec_config_t *)malloc( sizeof(adec_config_t)); + if( p_config == NULL ) + { + intf_ErrMsg( "Unable to allocate memory in GetAdecConfig" ); + return( NULL ); + } + if( InitDecConfig( p_input, p_es, &p_config->decoder_config ) == -1 ) { free( p_config ); - return NULL; + return( NULL ); } return( p_config ); @@ -457,25 +588,38 @@ static adec_config_t * GetAdecConfig( input_thread_t * p_input, /***************************************************************************** * 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 ac3spdif_CreateThread( void * ); +vlc_thread_t spdif_CreateThread( void * ); vlc_thread_t vpar_CreateThread( void * ); vlc_thread_t spudec_CreateThread( void * ); +vlc_thread_t lpcmdec_CreateThread( void * ); int input_SelectES( input_thread_t * p_input, es_descriptor_t * p_es ) { /* FIXME ! */ decoder_capabilities_t decoder; + void * p_config; -#ifdef DEBUG_INPUT - intf_DbgMsg( "Selecting ES %d", p_es->i_id ); + if( p_es == NULL ) + { + intf_ErrMsg( "Nothing to do in input_SelectES" ); + return -1; + } + +#ifdef TRACE_INPUT + intf_DbgMsg( "Selecting ES 0x%x", p_es->i_id ); #endif if( p_es->p_decoder_fifo != NULL ) { - intf_ErrMsg( "ES %d is already selected", p_es->i_id ); + intf_ErrMsg( "ES 0x%x is already selected", p_es->i_id ); return( -1 ); } @@ -486,8 +630,13 @@ int input_SelectES( input_thread_t * p_input, es_descriptor_t * p_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 ) ); + 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; @@ -496,44 +645,131 @@ int input_SelectES( input_thread_t * p_input, es_descriptor_t * p_es ) if( p_main->b_video ) { decoder.pf_create_thread = vpar_CreateThread; - p_es->thread_id = input_RunDecoder( &decoder, - (void *)GetVdecConfig( p_input, p_es ) ); + 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_es->thread_id = input_RunDecoder( &decoder, - (void *)GetAdecConfig( p_input, p_es ) ); + if( main_GetIntVariable( AOUT_SPDIF_VAR, 0 ) ) + { + decoder.pf_create_thread = spdif_CreateThread; + } + else + { + 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 LPCM_AUDIO_ES: + if( p_main->b_audio ) + { + decoder.pf_create_thread = lpcmdec_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_es->thread_id = input_RunDecoder( &decoder, - (void *)GetVdecConfig( p_input, p_es ) ); + 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; default: - intf_ErrMsg( "Unknown stream type %d", p_es->i_type ); + intf_ErrMsg( "Unknown stream type 0x%x", p_es->i_type ); return( -1 ); break; } - if( p_es->p_decoder_fifo != NULL ) + if( p_es->thread_id == 0 ) + { + return( -1 ); + } + + return( 0 ); +} + +/***************************************************************************** + * input_UnselectES: removes an ES from the list of selected ES + *****************************************************************************/ +int input_UnselectES( input_thread_t * p_input, es_descriptor_t * p_es ) +{ + + int i_index = 0; + + if( p_es == NULL ) + { + intf_ErrMsg( "Nothing to do in input_UnselectES" ); + return -1; + } + +#ifdef TRACE_INPUT + intf_DbgMsg( "Unselecting ES 0x%x", p_es->i_id ); +#endif + + if( p_es->p_decoder_fifo == NULL ) { - p_input->stream.i_selected_es_number++; + intf_ErrMsg( "ES 0x%x is not selected", p_es->i_id ); + return( -1 ); + } + + input_EndDecoder( p_input, p_es ); + + if( ( p_es->p_decoder_fifo == NULL ) && + ( p_input->stream.i_selected_es_number > 0 ) ) + { + p_input->stream.i_selected_es_number--; + + while( ( i_index < p_input->stream.i_selected_es_number ) && + ( p_input->stream.pp_selected_es[i_index] != p_es ) ) + { + i_index++; + } + + p_input->stream.pp_selected_es[i_index] = + p_input->stream.pp_selected_es[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 *) ); - p_input->stream.pp_selected_es[p_input->stream.i_selected_es_number - 1] - = p_es; + + if( p_input->stream.pp_selected_es == NULL ) + { +#ifdef TRACE_INPUT + intf_DbgMsg( "No more selected ES in input_UnselectES" ); +#endif + return( 1 ); + } } + return( 0 ); }