Commit 91bc3eb7 authored by Christophe Massiot's avatar Christophe Massiot

* New decoder spawning API input_dec.c ;

* Moved p_input->pp_es -> p_input->stream.pp_es and clean up of
  input_programs.c & co ;
* Fixed memory leaks.
parent 423a3bcf
...@@ -189,6 +189,7 @@ INPUT = src/input/input_ps.o \ ...@@ -189,6 +189,7 @@ INPUT = src/input/input_ps.o \
src/input/input_ts.o \ src/input/input_ts.o \
src/input/mpeg_system.o \ src/input/mpeg_system.o \
src/input/input_ext-dec.o \ src/input/input_ext-dec.o \
src/input/input_dec.o \
src/input/input_programs.o \ src/input/input_programs.o \
src/input/input_netlist.o \ src/input/input_netlist.o \
src/input/input.o src/input/input.o
......
/*****************************************************************************
* input_ext-dec.h: structures exported to the VideoLAN decoders
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ext-dec.h,v 1.4 2000/12/21 19:24:26 massiot Exp $
*
* Authors:
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/* Structures exported to the decoders */ /* Structures exported to the decoders */
/***************************************************************************** /*****************************************************************************
...@@ -496,7 +519,7 @@ typedef struct decoder_capabilities_s ...@@ -496,7 +519,7 @@ typedef struct decoder_capabilities_s
int i_weight; /* for a given stream type, the decoder int i_weight; /* for a given stream type, the decoder
* with higher weight will be spawned */ * with higher weight will be spawned */
vlc_thread_t (* pf_create_thread)( struct decoder_config_s * ); vlc_thread_t (* pf_create_thread)( void * );
} decoder_capabilities_t; } decoder_capabilities_t;
/* Decoder types */ /* Decoder types */
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* control the pace of reading. * control the pace of reading.
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ext-intf.h,v 1.7 2000/12/21 15:01:08 massiot Exp $ * $Id: input_ext-intf.h,v 1.8 2000/12/21 19:24:26 massiot Exp $
* *
* Authors: * Authors:
* *
...@@ -153,10 +153,16 @@ typedef struct stream_descriptor_s ...@@ -153,10 +153,16 @@ typedef struct stream_descriptor_s
/* Demultiplexer data */ /* Demultiplexer data */
void * p_demux_data; void * p_demux_data;
/* Programs description */ /* Programs descriptions */
int i_pgrm_number; /* size of the following array */ int i_pgrm_number; /* size of the following array */
pgrm_descriptor_t ** pp_programs; /* array of pointers to pgrm */ pgrm_descriptor_t ** pp_programs; /* array of pointers to pgrm */
/* ES descriptions */
int i_es_number;
es_descriptor_t ** pp_es; /* carried elementary streams */
int i_selected_es_number;
es_descriptor_t ** pp_selected_es; /* ES with a decoder */
/* Stream control */ /* Stream control */
stream_ctrl_t control; stream_ctrl_t control;
} stream_descriptor_t; } stream_descriptor_t;
...@@ -211,12 +217,6 @@ typedef struct input_thread_s ...@@ -211,12 +217,6 @@ typedef struct input_thread_s
/* General stream description */ /* General stream description */
stream_descriptor_t stream; /* PAT tables */ stream_descriptor_t stream; /* PAT tables */
es_descriptor_t ** pp_es; /* carried elementary streams */
int i_es_number;
/* List of streams to demux */
es_descriptor_t ** pp_selected_es;
int i_selected_es_number;
/* For auto-launch of decoders */ /* For auto-launch of decoders */
struct aout_thread_s * p_default_aout; struct aout_thread_s * p_default_aout;
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* decoders. * decoders.
***************************************************************************** *****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN * Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: input.c,v 1.62 2000/12/21 14:18:15 massiot Exp $ * $Id: input.c,v 1.63 2000/12/21 19:24:26 massiot Exp $
* *
* Authors: * Authors:
* *
...@@ -95,10 +95,8 @@ input_thread_t *input_CreateThread ( input_config_t * p_config, int *pi_status ) ...@@ -95,10 +95,8 @@ input_thread_t *input_CreateThread ( input_config_t * p_config, int *pi_status )
p_input->p_config = p_config; p_input->p_config = p_config;
/* Initialize stream description */ /* Initialize stream description */
p_input->pp_es = NULL; p_input->stream.i_es_number = 0;
p_input->pp_selected_es = NULL; p_input->stream.i_selected_es_number = 0;
p_input->i_es_number = 0;
p_input->i_selected_es_number = 0;
p_input->stream.i_pgrm_number = 0; p_input->stream.i_pgrm_number = 0;
/* Initialize stream control properties. */ /* Initialize stream control properties. */
...@@ -296,7 +294,6 @@ static void ErrorThread( input_thread_t *p_input ) ...@@ -296,7 +294,6 @@ static void ErrorThread( input_thread_t *p_input )
static void EndThread( input_thread_t * p_input ) static void EndThread( input_thread_t * p_input )
{ {
int * pi_status; /* thread status */ int * pi_status; /* thread status */
int i_es_loop; /* es index */
/* Store status */ /* Store status */
pi_status = p_input->pi_status; pi_status = p_input->pi_status;
...@@ -312,41 +309,14 @@ static void EndThread( input_thread_t * p_input ) ...@@ -312,41 +309,14 @@ static void EndThread( input_thread_t * p_input )
} }
#endif #endif
/* Destroy all decoder threads */ /* Free all ES and destroy all decoder threads */
for( i_es_loop = 0; i_es_loop < p_input->i_selected_es_number; input_EndStream( p_input );
i_es_loop++ )
{
decoder_fifo_t * p_decoder_fifo;
p_decoder_fifo = p_input->pp_selected_es[i_es_loop]->p_decoder_fifo;
p_decoder_fifo->b_die = 1;
/* Make sure the thread leaves the NextDataPacket() function */
vlc_mutex_lock( &p_decoder_fifo->data_lock);
vlc_cond_signal( &p_decoder_fifo->data_wait );
vlc_mutex_unlock( &p_decoder_fifo->data_lock );
/* Waiting for the thread to exit */
vlc_thread_join( p_input->pp_selected_es[i_es_loop]->thread_id );
/* Freeing all packets still in the decoder fifo. */
while( !DECODER_FIFO_ISEMPTY( *p_decoder_fifo ) )
{
p_decoder_fifo->pf_delete_pes( p_decoder_fifo->p_packets_mgt,
DECODER_FIFO_START( *p_decoder_fifo ) );
DECODER_FIFO_INCSTART( *p_decoder_fifo );
}
free( p_input->pp_selected_es[i_es_loop]->p_decoder_fifo );
}
/* Free demultiplexer's data */ /* Free demultiplexer's data */
p_input->p_plugin->pf_end( p_input ); p_input->p_plugin->pf_end( p_input );
free( p_input->p_plugin ); free( p_input->p_plugin );
/* Free input structures */ /* Free input structure */
input_EndStream( p_input );
free( p_input->pp_es );
free( p_input->pp_selected_es );
free( p_input ); free( p_input );
/* Update status */ /* Update status */
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input.h: structures of the input not exported to other modules * input.h: structures of the input not exported to other modules
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: input.h,v 1.5 2000/12/21 14:18:15 massiot Exp $ * $Id: input.h,v 1.6 2000/12/21 19:24:27 massiot Exp $
* *
* Authors: * Authors:
* *
...@@ -78,13 +78,15 @@ void NextDataPacket ( struct bit_stream_s * ); ...@@ -78,13 +78,15 @@ void NextDataPacket ( struct bit_stream_s * );
*****************************************************************************/ *****************************************************************************/
void input_InitStream( struct input_thread_s *, size_t ); void input_InitStream( struct input_thread_s *, size_t );
void input_EndStream( struct input_thread_s * ); void input_EndStream( struct input_thread_s * );
struct pgrm_descriptor_s * input_FindProgram( struct input_thread_s *, u16 );
struct pgrm_descriptor_s * input_AddProgram( struct input_thread_s *, struct pgrm_descriptor_s * input_AddProgram( struct input_thread_s *,
u16, size_t ); u16, size_t );
void input_DelProgram( struct input_thread_s *, u16 ); void input_DelProgram( struct input_thread_s *, struct pgrm_descriptor_s * );
void input_DumpStream( struct input_thread_s * ); void input_DumpStream( struct input_thread_s * );
struct es_descriptor_s * input_FindES( struct input_thread_s *, u16 );
struct es_descriptor_s * input_AddES( struct input_thread_s *, struct es_descriptor_s * input_AddES( struct input_thread_s *,
struct pgrm_descriptor_s *, u16, struct pgrm_descriptor_s *, u16,
size_t ); size_t );
void input_DelES( struct input_thread_s *, u16 ); void input_DelES( struct input_thread_s *, struct es_descriptor_s * );
int input_SelectES( struct input_thread_s *, struct es_descriptor_s * ); int input_SelectES( struct input_thread_s *, struct es_descriptor_s * );
/*****************************************************************************
* input_dec.c: Functions for the management of decoders
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_dec.c,v 1.1 2000/12/21 19:24:27 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
/* FIXME: we shouldn't be obliged to include these */
#include "defs.h"
#include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
#include "stream_control.h"
#include "input_ext-dec.h"
/*****************************************************************************
* input_RunDecoder: spawns a new decoder thread
*****************************************************************************/
vlc_thread_t input_RunDecoder( decoder_capabilities_t * p_decoder,
void * p_data )
{
return( p_decoder->pf_create_thread( p_data ) );
}
/*****************************************************************************
* input_EndDecoder: kills a decoder thread and waits until it's finished
*****************************************************************************/
void input_EndDecoder( decoder_fifo_t * p_decoder_fifo, vlc_thread_t thread_id )
{
p_decoder_fifo->b_die = 1;
/* Make sure the thread leaves the NextDataPacket() function */
vlc_mutex_lock( &p_decoder_fifo->data_lock);
vlc_cond_signal( &p_decoder_fifo->data_wait );
vlc_mutex_unlock( &p_decoder_fifo->data_lock );
/* Waiting for the thread to exit */
vlc_thread_join( thread_id );
/* Freeing all packets still in the decoder fifo. */
while( !DECODER_FIFO_ISEMPTY( *p_decoder_fifo ) )
{
p_decoder_fifo->pf_delete_pes( p_decoder_fifo->p_packets_mgt,
DECODER_FIFO_START( *p_decoder_fifo ) );
DECODER_FIFO_INCSTART( *p_decoder_fifo );
}
}
/*****************************************************************************
* input_dec.h: prototypes needed by an application to use a VideoLAN
* decoder
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_dec.h,v 1.1 2000/12/21 19:24:27 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Prototypes
*****************************************************************************/
//decoder_capabilities_s * input_ProbeDecoder( void );
vlc_thread_t input_RunDecoder( struct decoder_capabilities_s *, void * );
void input_EndDecoder( struct decoder_fifo_s *, vlc_thread_t );
This diff is collapsed.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* mpeg_system.c: TS, PS and PES management * mpeg_system.c: TS, PS and PES management
***************************************************************************** *****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN * Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: mpeg_system.c,v 1.13 2000/12/21 13:54:15 massiot Exp $ * $Id: mpeg_system.c,v 1.14 2000/12/21 19:24:27 massiot Exp $
* *
* Authors: * Authors:
* *
...@@ -673,11 +673,14 @@ static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data ) ...@@ -673,11 +673,14 @@ static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data )
stream_ps_data_t * p_demux = stream_ps_data_t * p_demux =
(stream_ps_data_t *)p_input->stream.p_demux_data; (stream_ps_data_t *)p_input->stream.p_demux_data;
intf_Msg("input info: Your stream contains Program Stream Map information");
intf_Msg("input info: Please send a mail to <massiot@via.ecp.fr>");
#if 0
if( !p_demux->b_is_PSM_complete ) if( !p_demux->b_is_PSM_complete )
{ {
byte_t * p_byte; byte_t * p_byte;
byte_t * p_end; byte_t * p_end;
int i_es = 0;
intf_DbgMsg( "Building PSM" ); intf_DbgMsg( "Building PSM" );
if( p_data->p_payload_start + 10 > p_data->p_payload_end ) if( p_data->p_payload_start + 10 > p_data->p_payload_end )
...@@ -710,34 +713,12 @@ static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data ) ...@@ -710,34 +713,12 @@ static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data )
/* 4 == minimum useful size of a section */ /* 4 == minimum useful size of a section */
while( p_byte + 4 <= p_end ) while( p_byte + 4 <= p_end )
{ {
#if 0 es_descriptor_t * p_es;
p_input->p_es[i_es].i_id
= p_input->p_es[i_es].i_stream_id
= p_byte[1];
p_input->p_es[i_es].i_type = p_byte[0];
p_input->p_es[i_es].p_pgrm = p_input->stream.pp_programs[0];
p_input->p_es[i_es].p_pes = NULL;
p_byte += 4 + U16_AT(&p_byte[2]);
#ifdef AUTO_SPAWN
switch( p_input->p_es[i_es].i_type )
{
case MPEG1_AUDIO_ES:
case MPEG2_AUDIO_ES:
/* Spawn audio thread. */
intf_DbgMsg( "Starting an MPEG-audio decoder" );
break;
case MPEG1_VIDEO_ES:
case MPEG2_VIDEO_ES:
/* Spawn video thread. */
intf_DbgMsg( "Starting an MPEG-video decoder" );
break;
}
#endif
i_es++; p_es = input_AddES( p_input, p_input->stream.pp_programs[0],
#endif p_byte[1], 0 );
p_es->i_type = p_byte[0];
p_byte += 4 + U16_AT(&p_byte[2]);
} }
vlc_mutex_unlock( &p_input->stream.stream_lock ); vlc_mutex_unlock( &p_input->stream.stream_lock );
...@@ -750,6 +731,7 @@ static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data ) ...@@ -750,6 +731,7 @@ static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data )
intf_ErrMsg( "PSM changed, this is not supported yet !" ); intf_ErrMsg( "PSM changed, this is not supported yet !" );
p_demux->i_PSM_version = p_data->p_buffer[6] & 0x1F; p_demux->i_PSM_version = p_data->p_buffer[6] & 0x1F;
} }
#endif
} }
/***************************************************************************** /*****************************************************************************
...@@ -774,13 +756,13 @@ es_descriptor_t * input_ParsePS( input_thread_t * p_input, ...@@ -774,13 +756,13 @@ es_descriptor_t * input_ParsePS( input_thread_t * p_input,
if( p_input->stream.pp_programs[0]->b_is_ok ) if( p_input->stream.pp_programs[0]->b_is_ok )
{ {
/* Look only at the selected ES. */ /* Look only at the selected ES. */
for( i_dummy = 0; i_dummy < p_input->i_selected_es_number; for( i_dummy = 0; i_dummy < p_input->stream.i_selected_es_number;
i_dummy++ ) i_dummy++ )
{ {
if( p_input->pp_selected_es[i_dummy] != NULL if( p_input->stream.pp_selected_es[i_dummy] != NULL
&& p_input->pp_selected_es[i_dummy]->i_id == i_id ) && p_input->stream.pp_selected_es[i_dummy]->i_id == i_id )
{ {
p_es = p_input->pp_selected_es[i_dummy]; p_es = p_input->stream.pp_selected_es[i_dummy];
break; break;
} }
} }
...@@ -788,15 +770,7 @@ es_descriptor_t * input_ParsePS( input_thread_t * p_input, ...@@ -788,15 +770,7 @@ es_descriptor_t * input_ParsePS( input_thread_t * p_input,
else else
{ {
/* Search all ES ; if not found -> AddES */ /* Search all ES ; if not found -> AddES */
for( i_dummy = 0; i_dummy < p_input->i_es_number; i_dummy++ ) p_es = input_FindES( p_input, i_id );
{
if( p_input->pp_es[i_dummy] != NULL
&& p_input->pp_es[i_dummy]->i_id == i_id )
{
p_es = p_input->pp_es[i_dummy];
break;
}
}
if( p_es == NULL ) if( p_es == NULL )
{ {
...@@ -927,7 +901,6 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data ) ...@@ -927,7 +901,6 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
break; break;
case 0x1BC: /* PROGRAM_STREAM_MAP_CODE */ case 0x1BC: /* PROGRAM_STREAM_MAP_CODE */
intf_ErrMsg("meuuuuh\n");
DecodePSM( p_input, p_data ); DecodePSM( p_input, p_data );
b_trash = 1; b_trash = 1;
break; break;
...@@ -947,13 +920,17 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data ) ...@@ -947,13 +920,17 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
{ {
p_es = input_ParsePS( p_input, p_data ); p_es = input_ParsePS( p_input, p_data );
if( p_es != NULL && p_es->p_decoder_fifo != NULL && !b_trash ) if( p_es != NULL && p_es->p_decoder_fifo != NULL )
{ {
#ifdef STATS #ifdef STATS
p_es->c_packets++; p_es->c_packets++;
#endif #endif
input_GatherPES( p_input, p_data, p_es, 1, 0 ); input_GatherPES( p_input, p_data, p_es, 1, 0 );
} }
else
{
b_trash = 1;
}
} }
/* Trash the packet if it has no payload or if it isn't selected */ /* Trash the packet if it has no payload or if it isn't selected */
...@@ -999,26 +976,10 @@ void input_DemuxTS( input_thread_t * p_input, data_packet_t * p_data ) ...@@ -999,26 +976,10 @@ void input_DemuxTS( input_thread_t * p_input, data_packet_t * p_data )
/* Find out the elementary stream. */ /* Find out the elementary stream. */
vlc_mutex_lock( &p_input->stream.stream_lock ); vlc_mutex_lock( &p_input->stream.stream_lock );
for( i_dummy = 0; i_dummy < p_input->i_es_number; i_dummy++ ) p_es = input_FindES( p_input, i_pid );
{
if( p_input->pp_es[i_dummy] != NULL )
{
if( p_input->pp_es[i_dummy]->i_id == i_pid )
{
p_es = p_input->pp_es[i_dummy];
p_es_demux = (es_ts_data_t *)p_es->p_demux_data;
p_pgrm_demux = (pgrm_ts_data_t *)p_es->p_pgrm->p_demux_data;
break;
}
}
}
vlc_mutex_unlock( &p_input->stream.stream_lock ); vlc_mutex_unlock( &p_input->stream.stream_lock );
#ifdef STATS if( p_es == NULL || p_es->p_decoder_fifo == NULL )
p_es->c_packets++;
#endif
if( p_es->p_decoder_fifo == NULL )
{ {
/* Not selected. Just read the adaptation field for a PCR. */ /* Not selected. Just read the adaptation field for a PCR. */
b_trash = 1; b_trash = 1;
...@@ -1026,6 +987,10 @@ void input_DemuxTS( input_thread_t * p_input, data_packet_t * p_data ) ...@@ -1026,6 +987,10 @@ void input_DemuxTS( input_thread_t * p_input, data_packet_t * p_data )
if( (p_es->p_decoder_fifo != NULL) || (p_pgrm_demux->i_pcr_pid == i_pid) ) if( (p_es->p_decoder_fifo != NULL) || (p_pgrm_demux->i_pcr_pid == i_pid) )
{ {
#ifdef STATS
p_es->c_packets++;
#endif
/* Extract adaptation field information if any */ /* Extract adaptation field information if any */
if( !b_adaptation ) if( !b_adaptation )
{ {
......
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