- /* Close input method */
- p_input->p_Close( p_input );
-
- /* Destroy all decoder threads */
- for( i_es_loop = 0;
- (i_es_loop < INPUT_MAX_ES) && (p_input->pp_selected_es[i_es_loop] != NULL) ;
- i_es_loop++ )
- {
- switch( p_input->pp_selected_es[i_es_loop]->i_type )
- {
- case MPEG1_VIDEO_ES:
- case MPEG2_VIDEO_ES:
-#ifdef OLD_DECODER
- vdec_DestroyThread( (vdec_thread_t*)(p_input->pp_selected_es[i_es_loop]->p_dec) /*, NULL */ );
-#else
- vpar_DestroyThread( (vpar_thread_t*)(p_input->pp_selected_es[i_es_loop]->p_dec) /*, NULL */ );
-#endif
- break;
- case MPEG1_AUDIO_ES:
- case MPEG2_AUDIO_ES:
- adec_DestroyThread( (adec_thread_t*)(p_input->pp_selected_es[i_es_loop]->p_dec) );
- break;
- case AC3_AUDIO_ES:
- ac3dec_DestroyThread( (ac3dec_thread_t *)(p_input->pp_selected_es[i_es_loop]->p_dec) );
- break;
- case LPCM_AUDIO_ES:
- lpcmdec_DestroyThread((lpcmdec_thread_t *)(p_input->pp_selected_es[i_es_loop]->p_dec) );
- break;
- case DVD_SPU_ES:
- spudec_DestroyThread( (spudec_thread_t *)(p_input->pp_selected_es[i_es_loop]->p_dec) );
- break;
- case 0:
- /* Special streams for the PSI decoder, PID 0 and 1 */
- break;
-#ifdef DEBUG
- default:
- intf_DbgMsg("error: unknown decoder type %d\n", p_input->pp_selected_es[i_es_loop]->i_type );
- break;
-#endif
- }
- }
-
- input_NetlistEnd( p_input ); /* clean netlist */
- input_PsiEnd( p_input ); /* clean PSI information */
- input_PcrEnd( p_input ); /* clean PCR information */
- free( p_input ); /* free input_thread structure */
-
- /* Update status */
- *pi_status = THREAD_OVER;
-}
-
-/*****************************************************************************
- * input_ReadPacket: reads a packet from the network or the file
- *****************************************************************************/
-static __inline__ int input_ReadPacket( input_thread_t *p_input )
-{
- int i_base_index; /* index of the first free iovec */
- int i_current_index;
- int i_packet_size;
-#ifdef INPUT_LIFO_TS_NETLIST
- int i_meanwhile_released;
- int i_currently_removed;
-#endif
- ts_packet_t * p_ts_packet;
-
- /* In this function, we only care about the TS netlist. PES netlist
- * is for the demultiplexer. */
-#ifdef INPUT_LIFO_TS_NETLIST
- i_base_index = p_input->netlist.i_ts_index;
-
- /* Verify that we still have packets in the TS netlist */
- if( (INPUT_MAX_TS + INPUT_TS_READ_ONCE - 1 - p_input->netlist.i_ts_index) <= INPUT_TS_READ_ONCE )
- {
- intf_ErrMsg("input error: TS netlist is empty !\n");
- return( -1 );
- }
-
-#else /* FIFO netlist */
- i_base_index = p_input->netlist.i_ts_start;
- if( p_input->netlist.i_ts_start + INPUT_TS_READ_ONCE -1 > INPUT_MAX_TS )
- {
- /* The netlist is splitted in 2 parts. We must gather them to consolidate
- the FIFO (we make the loop easily in having the same iovec at the far
- end and in the beginning of netlist_free).
- That's why the netlist is (INPUT_MAX_TS +1) + (INPUT_TS_READ_ONCE -1)
- large. */
- memcpy( p_input->netlist.p_ts_free + INPUT_MAX_TS + 1,
- p_input->netlist.p_ts_free,
- (p_input->netlist.i_ts_start + INPUT_TS_READ_ONCE - 1 - INPUT_MAX_TS)
- * sizeof(struct iovec) );
- }
-
- /* Verify that we still have packets in the TS netlist */
- if( ((p_input->netlist.i_ts_end -1 - p_input->netlist.i_ts_start) & INPUT_MAX_TS) <= INPUT_TS_READ_ONCE )
- {
- intf_ErrMsg("input error: TS netlist is empty !\n");
- return( -1 );
- }
-#endif /* FIFO netlist */
-
- /* Scatter read the buffer. */
- i_packet_size = (*p_input->p_Read)( p_input,
- &p_input->netlist.p_ts_free[i_base_index],
- INPUT_TS_READ_ONCE );
- if( i_packet_size == (-1) )
- {
-#if 0
- intf_DbgMsg("Read packet %d %p %d %d\n", i_base_index,
- &p_input->netlist.p_ts_free[i_base_index],
- p_input->netlist.i_ts_start,
- p_input->netlist.i_ts_end);
-#endif
- intf_ErrMsg("input error: readv() failed (%s)\n", strerror(errno));
- return( -1 );
- }
-
- if( i_packet_size == 0 )
- {
- /* No packet has been received, so stop here. */
- return( 0 );
- }
-
- /* Demultiplex the TS packets (1..INPUT_TS_READ_ONCE) received. */
- for( i_current_index = i_base_index;
- (i_packet_size -= TS_PACKET_SIZE) >= 0;
- i_current_index++ )
- {
- /* BTW, something REALLY bad could happen if we receive packets with
- a wrong size. */
- p_ts_packet = (ts_packet_t*)(p_input->netlist.p_ts_free[i_current_index].iov_base);
- /* Don't cry :-), we are allowed to do that cast, because initially,
- our buffer was malloc'ed with sizeof(ts_packet_t) */
-
- /* Find out if we need this packet and demultiplex. */
- input_SortPacket( p_input /* for current PIDs and netlist */,
- p_ts_packet);
- }
-
- if( i_packet_size > 0 )
- {
- intf_ErrMsg("input error: wrong size\n");
- return( -1 );
- }
-
- /* Remove the TS packets we have just filled from the netlist */
-#ifdef INPUT_LIFO_TS_NETLIST
- /* We need to take a lock here while we're calculating index positions. */
- vlc_mutex_lock( &p_input->netlist.lock );
-
- i_meanwhile_released = i_base_index - p_input->netlist.i_ts_index;
- if( i_meanwhile_released )