From ecff1e713f6962d45ff9a397e11410066eaa0ebe Mon Sep 17 00:00:00 2001 From: Christophe Massiot Date: Wed, 10 Jan 2001 19:22:11 +0000 Subject: [PATCH] * Changed code for handling b_die in bitstream ; * Move input_ext-dec.h to input.h ; * New input_NullPacket function ; * Fixed init bugs in input and vpar ; --- include/input_ext-dec.h | 5 +-- src/input/input.h | 57 +++++++++++++++++++++++++++++++- src/input/input_dec.c | 33 ++++++++++-------- src/input/input_dec.h | 31 ----------------- src/input/input_ext-dec.c | 46 ++++++-------------------- src/input/input_programs.c | 5 ++- src/input/input_ps.c | 6 +++- src/input/mpeg_system.c | 41 ++--------------------- src/input/mpeg_system.h | 4 +-- src/video_decoder/video_parser.h | 5 +-- src/video_parser/video_parser.c | 13 ++++++-- src/video_parser/vpar_synchro.c | 4 ++- 12 files changed, 116 insertions(+), 134 deletions(-) delete mode 100644 src/input/input_dec.h diff --git a/include/input_ext-dec.h b/include/input_ext-dec.h index 7593fe3087..3f6efdb076 100644 --- a/include/input_ext-dec.h +++ b/include/input_ext-dec.h @@ -2,7 +2,7 @@ * input_ext-dec.h: structures exported to the VideoLAN decoders ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: input_ext-dec.h,v 1.9 2001/01/10 16:24:11 massiot Exp $ + * $Id: input_ext-dec.h,v 1.10 2001/01/10 19:22:10 massiot Exp $ * * Authors: * @@ -146,7 +146,8 @@ typedef struct bit_stream_s /* Callback to the decoder used when changing data packets ; set * to NULL if your decoder doesn't need it. */ - void (* pf_bitstream_callback)( struct bit_stream_s * ); + void (* pf_bitstream_callback)( struct bit_stream_s *, + boolean_t b_new_pes ); /* Optional argument to the callback */ void * p_callback_arg; diff --git a/src/input/input.h b/src/input/input.h index a718fd7304..32edd5d432 100644 --- a/src/input/input.h +++ b/src/input/input.h @@ -2,7 +2,7 @@ * input.h: structures of the input not exported to other modules ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: input.h,v 1.6 2000/12/21 19:24:27 massiot Exp $ + * $Id: input.h,v 1.7 2001/01/10 19:22:11 massiot Exp $ * * Authors: * @@ -30,6 +30,8 @@ * Ethernet MTU is 1500 bytes, so in a UDP * * packet we can put : 1500/188 = 7 TS * * packets. Have a nice day and merry Xmas. */ +#define PADDING_PACKET_SIZE 100 /* Size of the NULL packet inserted in case + * of data loss (this should be < 188). */ /***************************************************************************** * input_capabilities_t @@ -90,3 +92,56 @@ struct es_descriptor_s * input_AddES( struct input_thread_s *, void input_DelES( struct input_thread_s *, struct es_descriptor_s * ); int input_SelectES( struct input_thread_s *, struct es_descriptor_s * ); +/***************************************************************************** + * Prototypes from input_dec.c + *****************************************************************************/ +//decoder_capabilities_s * input_ProbeDecoder( void ); +vlc_thread_t input_RunDecoder( struct decoder_capabilities_s *, void * ); +void input_EndDecoder( struct input_thread_s *, struct es_descriptor_s * ); +void input_DecodePES( struct decoder_fifo_s *, struct pes_packet_s * ); + +/***************************************************************************** + * Create a NULL packet for padding in case of a data loss + *****************************************************************************/ +static __inline__ void input_NullPacket( input_thread_t * p_input, + es_descriptor_t * p_es ) +{ + data_packet_t * p_pad_data; + pes_packet_t * p_pes; + + if( (p_pad_data = p_input->p_plugin->pf_new_packet( + p_input->p_method_data, + PADDING_PACKET_SIZE )) == NULL ) + { + intf_ErrMsg("Out of memory"); + p_input->b_error = 1; + return; + } + memset( p_pad_data->p_buffer, 0, PADDING_PACKET_SIZE ); + p_pad_data->b_discard_payload = 1; + p_pes = p_es->p_pes; + + if( p_pes != NULL ) + { + p_pes->b_messed_up = 1; + p_es->p_last->p_next = p_pad_data; + p_es->p_last = p_pad_data; + } + else + { + if( (p_pes = p_input->p_plugin->pf_new_pes( + p_input->p_method_data )) == NULL ) + { + intf_ErrMsg("Out of memory"); + p_input->b_error = 1; + return; + } + + p_pes->p_first = p_pad_data; + p_pes->b_messed_up = p_pes->b_discontinuity = 1; + input_DecodePES( p_es->p_decoder_fifo, p_pes ); + } + + p_es->b_discontinuity = 0; +} + diff --git a/src/input/input_dec.c b/src/input/input_dec.c index e829cb526f..2d92835806 100644 --- a/src/input/input_dec.c +++ b/src/input/input_dec.c @@ -2,7 +2,7 @@ * input_dec.c: Functions for the management of decoders ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: input_dec.c,v 1.3 2001/01/07 03:56:40 henri Exp $ + * $Id: input_dec.c,v 1.4 2001/01/10 19:22:11 massiot Exp $ * * Authors: Christophe Massiot * @@ -24,7 +24,6 @@ /***************************************************************************** * Preamble *****************************************************************************/ -/* FIXME: we shouldn't be obliged to include these */ #include "defs.h" #include "config.h" @@ -35,6 +34,9 @@ #include "stream_control.h" #include "input_ext-dec.h" +#include "input_ext-intf.h" + +#include "input.h" /***************************************************************************** * input_RunDecoder: spawns a new decoder thread @@ -48,28 +50,31 @@ vlc_thread_t input_RunDecoder( decoder_capabilities_t * p_decoder, /***************************************************************************** * 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 ) +void input_EndDecoder( input_thread_t * p_input, es_descriptor_t * p_es ) { - p_decoder_fifo->b_die = 1; + p_es->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 ); + input_NullPacket( p_input, p_es ); + if( p_es->p_pes != NULL ) + { + input_DecodePES( p_es->p_decoder_fifo, p_es->p_pes ); + } /* Destroy the lock and cond */ - vlc_cond_destroy( &p_decoder_fifo->data_wait ); - vlc_mutex_destroy( &p_decoder_fifo->data_lock ); + vlc_cond_destroy( &p_es->p_decoder_fifo->data_wait ); + vlc_mutex_destroy( &p_es->p_decoder_fifo->data_lock ); /* Waiting for the thread to exit */ - vlc_thread_join( thread_id ); + vlc_thread_join( p_es->thread_id ); /* Freeing all packets still in the decoder fifo. */ - while( !DECODER_FIFO_ISEMPTY( *p_decoder_fifo ) ) + while( !DECODER_FIFO_ISEMPTY( *p_es->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 ); + p_es->p_decoder_fifo->pf_delete_pes( + p_es->p_decoder_fifo->p_packets_mgt, + DECODER_FIFO_START( *p_es->p_decoder_fifo ) ); + DECODER_FIFO_INCSTART( *p_es->p_decoder_fifo ); } } diff --git a/src/input/input_dec.h b/src/input/input_dec.h deleted file mode 100644 index 87002ccbd7..0000000000 --- a/src/input/input_dec.h +++ /dev/null @@ -1,31 +0,0 @@ -/***************************************************************************** - * input_dec.h: prototypes needed by an application to use a VideoLAN - * decoder - ***************************************************************************** - * Copyright (C) 1999, 2000 VideoLAN - * $Id: input_dec.h,v 1.2 2000/12/22 10:58:27 massiot Exp $ - * - * 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 - * 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 ); -void input_DecodePES( struct decoder_fifo_s *, struct pes_packet_s * ); diff --git a/src/input/input_ext-dec.c b/src/input/input_ext-dec.c index 9f404214eb..adbc9f58aa 100644 --- a/src/input/input_ext-dec.c +++ b/src/input/input_ext-dec.c @@ -34,6 +34,8 @@ #include "stream_control.h" #include "input_ext-dec.h" +#include "input_ext-intf.h" + #include "input.h" /***************************************************************************** @@ -73,17 +75,7 @@ void NextDataPacket( bit_stream_t * p_bit_stream ) WORD_TYPE buffer_left; ptrdiff_t i_bytes_left; decoder_fifo_t * p_fifo = p_bit_stream->p_decoder_fifo; - - /* Buffer used at the end of a decoder thread, to give it zero - * values if needed. */ - static byte_t p_zero[64] = { 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 }; + boolean_t b_new_pes; /* Put the remaining bytes (not aligned on a word boundary) in a * temporary buffer. */ @@ -103,47 +95,31 @@ void NextDataPacket( bit_stream_t * p_bit_stream ) * that's why we need to take the lock before. */ vlc_mutex_lock( &p_fifo->data_lock ); - /* Is the input thread dying ? */ - if( p_fifo->b_die ) - { - vlc_mutex_unlock( &p_fifo->data_lock ); - p_bit_stream->p_byte = p_zero; - p_bit_stream->p_end = &p_zero[sizeof(p_zero) - 1]; - return; - } - - /* We should increase the start index of the decoder fifo, but - * if we do this now, the input thread could overwrite the - * pointer to the current PES packet, and we weren't able to - * give it back to the netlist. That's why we free the PES - * packet first. */ + /* Free the previous PES packet. */ p_fifo->pf_delete_pes( p_fifo->p_packets_mgt, DECODER_FIFO_START( *p_fifo ) ); DECODER_FIFO_INCSTART( *p_fifo ); - while( DECODER_FIFO_ISEMPTY( *p_fifo ) ) + if( DECODER_FIFO_ISEMPTY( *p_fifo ) ) { + /* Wait for the input to tell us when we receive a packet. */ vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock ); - if( p_fifo->b_die ) - { - vlc_mutex_unlock( &p_fifo->data_lock ); - p_bit_stream->p_byte = p_zero; - p_bit_stream->p_end = &p_zero[sizeof(p_zero) - 1]; - return; - } } /* The next byte could be found in the next PES packet */ p_bit_stream->p_data = DECODER_FIFO_START( *p_fifo )->p_first; - /* We can release the fifo's data lock */ vlc_mutex_unlock( &p_fifo->data_lock ); + + b_new_pes = 1; } else { /* Perhaps the next data packet of the current PES packet contains * real data (ie its payload's size is greater than 0). */ p_bit_stream->p_data = p_bit_stream->p_data->p_next; + + b_new_pes = 0; } } while ( p_bit_stream->p_data->p_payload_start == p_bit_stream->p_data->p_payload_end ); @@ -155,7 +131,7 @@ void NextDataPacket( bit_stream_t * p_bit_stream ) /* Call back the decoder. */ if( p_bit_stream->pf_bitstream_callback != NULL ) { - p_bit_stream->pf_bitstream_callback( p_bit_stream ); + p_bit_stream->pf_bitstream_callback( p_bit_stream, b_new_pes ); } /* Copy remaining bits of the previous packet */ diff --git a/src/input/input_programs.c b/src/input/input_programs.c index 7a477aab39..10d85b9794 100644 --- a/src/input/input_programs.c +++ b/src/input/input_programs.c @@ -2,7 +2,7 @@ * input_programs.c: es_descriptor_t, pgrm_descriptor_t management ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: input_programs.c,v 1.22 2001/01/08 18:16:33 sam Exp $ + * $Id: input_programs.c,v 1.23 2001/01/10 19:22:11 massiot Exp $ * * Authors: * @@ -40,7 +40,6 @@ #include "input_ext-intf.h" #include "input_ext-dec.h" #include "input.h" -#include "input_dec.h" #include "main.h" /* --noaudio --novideo */ @@ -342,7 +341,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 ); + input_EndDecoder( p_input, p_es ); free( p_es->p_decoder_fifo ); } diff --git a/src/input/input_ps.c b/src/input/input_ps.c index ea4693830a..1f90a1654e 100644 --- a/src/input/input_ps.c +++ b/src/input/input_ps.c @@ -2,7 +2,7 @@ * input_ps.c: PS demux and packet management ***************************************************************************** * Copyright (C) 1998, 1999, 2000 VideoLAN - * $Id: input_ps.c,v 1.19 2001/01/10 16:24:11 massiot Exp $ + * $Id: input_ps.c,v 1.20 2001/01/10 19:22:11 massiot Exp $ * * Authors: * @@ -424,6 +424,10 @@ static struct data_packet_s * NewPacket( void * p_garbage, return NULL; } + /* Initialize data */ + p_data->p_next = NULL; + p_data->b_discard_payload = 0; + p_data->p_payload_start = p_data->p_buffer; p_data->p_payload_end = p_data->p_buffer + i_size; diff --git a/src/input/mpeg_system.c b/src/input/mpeg_system.c index 4b280201e1..a4158dad38 100644 --- a/src/input/mpeg_system.c +++ b/src/input/mpeg_system.c @@ -2,7 +2,7 @@ * mpeg_system.c: TS, PS and PES management ***************************************************************************** * Copyright (C) 1998, 1999, 2000 VideoLAN - * $Id: mpeg_system.c,v 1.25 2001/01/08 18:16:33 sam Exp $ + * $Id: mpeg_system.c,v 1.26 2001/01/10 19:22:11 massiot Exp $ * * Authors: * @@ -41,7 +41,6 @@ #include "input.h" #include "mpeg_system.h" -#include "input_dec.h" #include "main.h" /* AC3/MPEG channel, SPU channel */ @@ -449,45 +448,12 @@ void input_GatherPES( input_thread_t * p_input, data_packet_t * p_data, * for the next start code). */ if( b_packet_lost || p_es->b_discontinuity ) { - data_packet_t * p_pad_data; - - if( (p_pad_data = p_input->p_plugin->pf_new_packet( - p_input->p_method_data, - PADDING_PACKET_SIZE )) == NULL ) - { - intf_ErrMsg("Out of memory"); - p_input->b_error = 1; - return; - } - memset( p_data->p_buffer, 0, PADDING_PACKET_SIZE ); - p_pad_data->b_discard_payload = 1; - - if( p_pes != NULL ) - { - p_pes->b_messed_up = p_pes->b_discontinuity = 1; - input_GatherPES( p_input, p_pad_data, p_es, 0, 0 ); - } - else - { - if( (p_pes = p_input->p_plugin->pf_new_pes( - p_input->p_method_data )) == NULL ) - { - intf_ErrMsg("Out of memory"); - p_input->b_error = 1; - return; - } - - p_pes->p_first = p_pad_data; - p_pes->b_messed_up = p_pes->b_discontinuity = 1; - input_DecodePES( p_es->p_decoder_fifo, p_pes ); - } - - p_es->b_discontinuity = 0; + input_NullPacket( p_input, p_es ); } if( b_unit_start && p_pes != NULL ) { - /* If the TS packet contains the begining of a new PES packet, and + /* If the data packet contains the begining of a new PES packet, and * if we were reassembling a PES packet, then the PES should be * complete now, so parse its header and give it to the decoders. */ input_ParsePES( p_input, p_es ); @@ -535,7 +501,6 @@ void input_GatherPES( input_thread_t * p_input, data_packet_t * p_data, p_es->p_last->p_next = p_data; } - p_data->p_next = NULL; p_es->p_last = p_data; /* Size of the payload carried in the data packet */ diff --git a/src/input/mpeg_system.h b/src/input/mpeg_system.h index c405ccec95..b653635856 100644 --- a/src/input/mpeg_system.h +++ b/src/input/mpeg_system.h @@ -3,7 +3,7 @@ * and TS system layers ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: mpeg_system.h,v 1.4 2000/12/26 19:14:47 massiot Exp $ + * $Id: mpeg_system.h,v 1.5 2001/01/10 19:22:11 massiot Exp $ * * Authors: * @@ -27,8 +27,6 @@ *****************************************************************************/ #define TS_PACKET_SIZE 188 /* Size of a TS packet */ #define PSI_SECTION_SIZE 4096 /* Maximum size of a PSI section */ -#define PADDING_PACKET_SIZE 100 /* Size of the NULL packet inserted in case - * of data loss (this should be < 188). */ /***************************************************************************** diff --git a/src/video_decoder/video_parser.h b/src/video_decoder/video_parser.h index 691d134e4d..1556390b3a 100644 --- a/src/video_decoder/video_parser.h +++ b/src/video_decoder/video_parser.h @@ -2,7 +2,7 @@ * video_parser.h : video parser thread ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: video_parser.h,v 1.1 2000/12/21 17:19:52 massiot Exp $ + * $Id: video_parser.h,v 1.2 2001/01/10 19:22:11 massiot Exp $ * * Authors: Christophe Massiot * @@ -95,7 +95,8 @@ typedef struct vpar_thread_s decoder_fifo_t * p_fifo; /* PES input fifo */ bit_stream_t bit_stream; vdec_config_t * p_config; - + /* Bitstream context */ + mtime_t next_pts, next_dts; /* Output properties */ vout_thread_t * p_vout; /* video output thread */ diff --git a/src/video_parser/video_parser.c b/src/video_parser/video_parser.c index bb2a58e420..30dcbfb51d 100644 --- a/src/video_parser/video_parser.c +++ b/src/video_parser/video_parser.c @@ -2,7 +2,7 @@ * video_parser.c : video parser thread ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: video_parser.c,v 1.63 2001/01/07 04:31:18 henri Exp $ + * $Id: video_parser.c,v 1.64 2001/01/10 19:22:11 massiot Exp $ * * Authors: Christophe Massiot * Samuel Hocevar @@ -67,14 +67,13 @@ static int InitThread ( vpar_thread_t *p_vpar ); static void RunThread ( vpar_thread_t *p_vpar ); static void ErrorThread ( vpar_thread_t *p_vpar ); static void EndThread ( vpar_thread_t *p_vpar ); +static void BitstreamCallback ( bit_stream_t *p_bit_stream ); /***************************************************************************** * vpar_CreateThread: create a generic parser thread ***************************************************************************** * This function creates a new video parser thread, and returns a pointer * to its description. On error, it returns NULL. - * Following configuration properties are used: - * XXX?? *****************************************************************************/ vlc_thread_t vpar_CreateThread( vdec_config_t * p_config ) { @@ -398,3 +397,11 @@ static void EndThread( vpar_thread_t *p_vpar ) intf_DbgMsg("vpar debug: EndThread(%p)", p_vpar); } + +/***************************************************************************** + * BitstreamCallback: Import parameters from the new data/PES packet + ***************************************************************************** + * This function is called when the thread ends after a sucessful + * initialization. + *****************************************************************************/ +static void BitstreamCallback ( bit_stream_t *p_bit_stream ); diff --git a/src/video_parser/vpar_synchro.c b/src/video_parser/vpar_synchro.c index 0072eb3c14..07959f66b1 100644 --- a/src/video_parser/vpar_synchro.c +++ b/src/video_parser/vpar_synchro.c @@ -2,7 +2,7 @@ * vpar_synchro.c : frame dropping routines ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: vpar_synchro.c,v 1.68 2000/12/29 12:49:30 massiot Exp $ + * $Id: vpar_synchro.c,v 1.69 2001/01/10 19:22:11 massiot Exp $ * * Authors: Christophe Massiot * Samuel Hocevar @@ -152,6 +152,8 @@ void vpar_SynchroInit( vpar_thread_t * p_vpar ) p_vpar->synchro.b_dropped_last = 0; p_vpar->synchro.current_pts = mdate() + DEFAULT_PTS_DELAY; p_vpar->synchro.backward_pts = 0; + p_vpar->synchro.i_trashed_pic = p_vpar->synchro.i_not_chosen_pic = + p_vpar->synchro.i_pic = 0; } /*****************************************************************************