From: Gildas Bazin Date: Tue, 30 Sep 2003 20:23:03 +0000 (+0000) Subject: * include/vlc_block.h, modules/codec/libmpeg2.c: re-added the discontinuity flag... X-Git-Tag: 0.7.0~874 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=a4ee447788e85ead0d1ce0e0f7f345af3829ddc9;p=vlc * include/vlc_block.h, modules/codec/libmpeg2.c: re-added the discontinuity flag in block_t and re-enabled the discontinuity gestion in the libmpeg2 codec. * include/vlc_block_helper.h: implemented bytestream reading helper functions for chained blocks. * modules/codec/a52.c: modified to use the bytestream reading functions. The flexibility added by these functions makes the code simpler and better at detecting synchro code emulations. --- diff --git a/include/vlc_block.h b/include/vlc_block.h index c453a24985..e4282d606f 100644 --- a/include/vlc_block.h +++ b/include/vlc_block.h @@ -2,7 +2,7 @@ * vlc_block.h: Data blocks management functions ***************************************************************************** * Copyright (C) 2003 VideoLAN - * $Id: vlc_block.h,v 1.2 2003/09/02 20:19:25 gbazin Exp $ + * $Id: vlc_block.h,v 1.3 2003/09/30 20:23:03 gbazin Exp $ * * Authors: Laurent Aimar * @@ -38,6 +38,8 @@ struct block_t mtime_t i_pts; mtime_t i_dts; + vlc_bool_t b_discontinuity; /* only temporary */ + int i_buffer; uint8_t *p_buffer; diff --git a/include/vlc_block_helper.h b/include/vlc_block_helper.h new file mode 100644 index 0000000000..8eaa4cc2d9 --- /dev/null +++ b/include/vlc_block_helper.h @@ -0,0 +1,364 @@ +/***************************************************************************** + * vlc_block_helper.h: Helper functions for data blocks management. + ***************************************************************************** + * Copyright (C) 2003 VideoLAN + * $Id: vlc_block_helper.h,v 1.1 2003/09/30 20:23:03 gbazin Exp $ + * + * Authors: Gildas Bazin + * + * 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. + *****************************************************************************/ + +#ifndef _VLC_BLOCK_HELPER_H +#define _VLC_BLOCK_HELPER_H 1 + +typedef struct block_bytestream_t +{ + block_t *p_chain; + block_t *p_block; + int i_offset; +} block_bytestream_t; + +#define block_BytestreamInit( a, b, c ) __block_BytestreamInit( VLC_OBJECT(a), b, c ) + +/***************************************************************************** + * block_bytestream_t management + *****************************************************************************/ +static inline block_bytestream_t __block_BytestreamInit( vlc_object_t *p_obj, + block_t *p_block, int i_offset ) +{ + block_bytestream_t bytestream; + + bytestream.i_offset = i_offset; + bytestream.p_block = p_block; + bytestream.p_chain = p_block; + + return bytestream; +} + +static inline block_t *block_BytestreamFlush( block_bytestream_t *p_bytestream) +{ + while( p_bytestream->p_chain != p_bytestream->p_block ) + { + block_t *p_next; + p_next = p_bytestream->p_chain->p_next; + p_bytestream->p_chain->pf_release( p_bytestream->p_chain ); + p_bytestream->p_chain = p_next; + } + + return p_bytestream->p_chain; +} + +static inline mtime_t block_BytestreamPTS( block_bytestream_t *p_bytestream ) +{ + while( p_bytestream->p_chain != p_bytestream->p_block ) + { + block_t *p_next; + p_next = p_bytestream->p_chain->p_next; + p_bytestream->p_chain->pf_release( p_bytestream->p_chain ); + p_bytestream->p_chain = p_next; + } + + return p_bytestream->p_chain; +} + +static inline int block_SkipByte( block_bytestream_t *p_bytestream ) +{ + /* Most common case first */ + if( p_bytestream->p_block->i_buffer - p_bytestream->i_offset ) + { + p_bytestream->i_offset++; + return VLC_SUCCESS; + } + else + { + block_t *p_block; + + /* Less common case which is also slower */ + for( p_block = p_bytestream->p_block->p_next; + p_block != NULL; p_block = p_block->p_next ) + { + if( p_block->i_buffer ) + { + p_bytestream->i_offset = 1; + p_bytestream->p_block = p_block; + return VLC_SUCCESS; + } + } + } + + /* Not enough data, bail out */ + return VLC_EGENERIC; +} + +static inline int block_PeekByte( block_bytestream_t *p_bytestream, + uint8_t *p_data ) +{ + /* Most common case first */ + if( p_bytestream->p_block->i_buffer - p_bytestream->i_offset ) + { + *p_data = p_bytestream->p_block->p_buffer[p_bytestream->i_offset]; + return VLC_SUCCESS; + } + else + { + block_t *p_block; + + /* Less common case which is also slower */ + for( p_block = p_bytestream->p_block->p_next; + p_block != NULL; p_block = p_block->p_next ) + { + if( p_block->i_buffer ) + { + *p_data = p_block->p_buffer[0]; + return VLC_SUCCESS; + } + } + } + + /* Not enough data, bail out */ + return VLC_EGENERIC; +} + +static inline int block_GetByte( block_bytestream_t *p_bytestream, + uint8_t *p_data ) +{ + /* Most common case first */ + if( p_bytestream->p_block->i_buffer - p_bytestream->i_offset ) + { + *p_data = p_bytestream->p_block->p_buffer[p_bytestream->i_offset]; + p_bytestream->i_offset++; + return VLC_SUCCESS; + } + else + { + block_t *p_block; + + /* Less common case which is also slower */ + for( p_block = p_bytestream->p_block->p_next; + p_block != NULL; p_block = p_block->p_next ) + { + if( p_block->i_buffer ) + { + *p_data = p_block->p_buffer[0]; + p_bytestream->i_offset = 1; + p_bytestream->p_block = p_block; + return VLC_SUCCESS; + } + } + } + + /* Not enough data, bail out */ + return VLC_EGENERIC; +} + +static inline int block_SkipBytes( block_bytestream_t *p_bytestream, + int i_data ) +{ + block_t *p_block; + int i_offset, i_copy; + + /* Check we have that much data */ + i_offset = p_bytestream->i_offset; + i_copy = 0; + for( p_block = p_bytestream->p_block; + p_block != NULL; p_block = p_block->p_next ) + { + i_copy = __MIN( i_data, p_block->i_buffer - i_offset ); + i_data -= i_copy; + i_offset = 0; + + if( !i_data ) break; + } + + if( i_data ) + { + /* Not enough data, bail out */ + return VLC_EGENERIC; + } + + p_bytestream->p_block = p_block; + p_bytestream->i_offset = i_copy; + return VLC_SUCCESS; +} + +static inline int block_PeekBytes( block_bytestream_t *p_bytestream, + uint8_t *p_data, int i_data ) +{ + block_t *p_block; + int i_offset, i_copy, i_size; + + /* Check we have that much data */ + i_offset = p_bytestream->i_offset; + i_size = i_data; + i_copy = 0; + for( p_block = p_bytestream->p_block; + p_block != NULL; p_block = p_block->p_next ) + { + i_copy = __MIN( i_size, p_block->i_buffer - i_offset ); + i_size -= i_copy; + i_offset = 0; + + if( !i_size ) break; + } + + if( i_size ) + { + /* Not enough data, bail out */ + return VLC_EGENERIC; + } + + /* Copy the data */ + i_offset = p_bytestream->i_offset; + i_size = i_data; + i_copy = 0; + for( p_block = p_bytestream->p_block; + p_block != NULL; p_block = p_block->p_next ) + { + i_copy = __MIN( i_size, p_block->i_buffer - i_offset ); + i_size -= i_copy; + + if( i_copy ) + { + memcpy( p_data, p_block->p_buffer + i_offset, i_copy ); + p_data += i_copy; + } + + i_offset = 0; + + if( !i_size ) break; + } + + return VLC_SUCCESS; +} + +static inline int block_GetBytes( block_bytestream_t *p_bytestream, + uint8_t *p_data, int i_data ) +{ + block_t *p_block; + int i_offset, i_copy, i_size; + + /* Check we have that much data */ + i_offset = p_bytestream->i_offset; + i_size = i_data; + i_copy = 0; + for( p_block = p_bytestream->p_block; + p_block != NULL; p_block = p_block->p_next ) + { + i_copy = __MIN( i_size, p_block->i_buffer - i_offset ); + i_size -= i_copy; + i_offset = 0; + + if( !i_size ) break; + } + + if( i_size ) + { + /* Not enough data, bail out */ + return VLC_EGENERIC; + } + + /* Copy the data */ + i_offset = p_bytestream->i_offset; + i_size = i_data; + i_copy = 0; + for( p_block = p_bytestream->p_block; + p_block != NULL; p_block = p_block->p_next ) + { + i_copy = __MIN( i_size, p_block->i_buffer - i_offset ); + i_size -= i_copy; + + if( i_copy ) + { + memcpy( p_data, p_block->p_buffer + i_offset, i_copy ); + p_data += i_copy; + } + + i_offset = 0; + + if( !i_size ) break; + } + + /* No buffer given, just skip the data */ + p_bytestream->p_block = p_block; + p_bytestream->i_offset = i_copy; + + return VLC_SUCCESS; +} + +static inline int block_PeekOffsetBytes( block_bytestream_t *p_bytestream, + int i_peek_offset, uint8_t *p_data, int i_data ) +{ + block_t *p_block; + int i_offset, i_copy, i_size; + + /* Check we have that much data */ + i_offset = p_bytestream->i_offset; + i_size = i_data + i_peek_offset; + i_copy = 0; + for( p_block = p_bytestream->p_block; + p_block != NULL; p_block = p_block->p_next ) + { + i_copy = __MIN( i_size, p_block->i_buffer - i_offset ); + i_size -= i_copy; + i_offset = 0; + + if( !i_size ) break; + } + + if( i_size ) + { + /* Not enough data, bail out */ + return VLC_EGENERIC; + } + + /* Find the right place */ + i_offset = p_bytestream->i_offset; + i_size = i_peek_offset; + i_copy = 0; + for( p_block = p_bytestream->p_block; + p_block != NULL; p_block = p_block->p_next ) + { + i_copy = __MIN( i_size, p_block->i_buffer - i_offset ); + i_size -= i_copy; + i_offset = 0; + + if( !i_size ) break; + } + + /* Copy the data */ + i_offset = i_copy; + i_size = i_data; + i_copy = 0; + for( ; p_block != NULL; p_block = p_block->p_next ) + { + i_copy = __MIN( i_size, p_block->i_buffer - i_offset ); + i_size -= i_copy; + + if( i_copy ) + { + memcpy( p_data, p_block->p_buffer + i_offset, i_copy ); + p_data += i_copy; + } + + i_offset = 0; + + if( !i_size ) break; + } + + return VLC_SUCCESS; +} + +#endif /* VLC_BLOCK_HELPER_H */ diff --git a/modules/codec/a52.c b/modules/codec/a52.c index 0a1a424f5f..3f0713b2a1 100644 --- a/modules/codec/a52.c +++ b/modules/codec/a52.c @@ -2,7 +2,7 @@ * a52.c: A/52 basic parser ***************************************************************************** * Copyright (C) 2001-2002 VideoLAN - * $Id: a52.c,v 1.23 2003/09/02 20:19:25 gbazin Exp $ + * $Id: a52.c,v 1.24 2003/09/30 20:23:03 gbazin Exp $ * * Authors: Stéphane Borel * Christophe Massiot @@ -41,6 +41,8 @@ # include #endif +#include "vlc_block_helper.h" + #define A52_HEADER_SIZE 7 /***************************************************************************** @@ -54,14 +56,11 @@ struct decoder_sys_t /* * Input properties */ - int i_state; - - uint8_t p_header[A52_HEADER_SIZE]; - int i_header; - - mtime_t pts; + int i_state; + vlc_bool_t b_synchro; - int i_frame_size; + block_t *p_chain; + block_bytestream_t bytestream; /* * Decoder output properties @@ -69,7 +68,6 @@ struct decoder_sys_t aout_instance_t * p_aout; /* opaque */ aout_input_t * p_aout_input; /* opaque */ audio_sample_format_t aout_format; - aout_buffer_t * p_aout_buffer; /* current aout buffer being filled */ /* @@ -85,12 +83,16 @@ struct decoder_sys_t uint8_t *p_out_buffer; /* output buffer */ int i_out_buffer; /* position in output buffer */ audio_date_t end_date; + + mtime_t pts; + int i_frame_size, i_bit_rate; + unsigned int i_rate, i_channels, i_channels_conf; + }; enum { STATE_NOSYNC, - STATE_PARTIAL_SYNC, STATE_SYNC, STATE_HEADER, STATE_DATA @@ -173,6 +175,7 @@ static int OpenPacketizer( vlc_object_t *p_this ) static int InitDecoder( decoder_t *p_dec ) { p_dec->p_sys->i_state = STATE_NOSYNC; + p_dec->p_sys->b_synchro = VLC_FALSE; p_dec->p_sys->p_out_buffer = NULL; p_dec->p_sys->i_out_buffer = 0; @@ -188,6 +191,8 @@ static int InitDecoder( decoder_t *p_dec ) p_dec->p_sys->sout_format.i_cat = AUDIO_ES; p_dec->p_sys->sout_format.i_fourcc = VLC_FOURCC( 'a', '5', '2', ' ' ); + p_dec->p_sys->p_chain = NULL; + return VLC_SUCCESS; } @@ -199,47 +204,47 @@ static int InitDecoder( decoder_t *p_dec ) static int RunDecoder( decoder_t *p_dec, block_t *p_block ) { decoder_sys_t *p_sys = p_dec->p_sys; - int i_block_pos = 0; - mtime_t i_pts = p_block->i_pts; + uint8_t p_header[A52_HEADER_SIZE]; + + if( p_sys->p_chain ) + { + block_ChainAppend( &p_sys->p_chain, p_block ); + } + else + { + block_ChainAppend( &p_sys->p_chain, p_block ); + p_sys->bytestream = block_BytestreamInit( p_dec, p_sys->p_chain, 0 ); + } - while( i_block_pos < p_block->i_buffer ) + while( 1 ) { switch( p_sys->i_state ) { + case STATE_NOSYNC: - /* Look for sync word - should be 0x0b77 */ - while( i_block_pos < p_block->i_buffer && - p_block->p_buffer[i_block_pos] != 0x0b ) + while( block_PeekBytes( &p_sys->bytestream, p_header, 2 ) + == VLC_SUCCESS ) { - i_block_pos++; + if( p_header[0] == 0x0b && p_header[1] == 0x77 ) + { + p_sys->i_state = STATE_SYNC; + break; + } + block_SkipByte( &p_sys->bytestream ); + p_dec->p_sys->b_synchro = VLC_FALSE; } - - if( i_block_pos < p_block->i_buffer ) + if( p_sys->i_state != STATE_SYNC ) { - p_sys->i_state = STATE_PARTIAL_SYNC; - i_block_pos++; - p_sys->p_header[0] = 0x0b; - break; - } - break; + block_ChainRelease( p_sys->p_chain ); + p_sys->p_chain = NULL; - case STATE_PARTIAL_SYNC: - if( p_block->p_buffer[i_block_pos] == 0x77 ) - { - p_sys->i_state = STATE_SYNC; - i_block_pos++; - p_sys->p_header[1] = 0x77; - p_sys->i_header = 2; + /* Need more data */ + return VLC_SUCCESS; } - else - { - p_sys->i_state = STATE_NOSYNC; - } - break; case STATE_SYNC: /* New frame, set the Presentation Time Stamp */ - p_sys->pts = i_pts; i_pts = 0; + p_sys->pts = p_sys->bytestream.p_block->i_pts; if( p_sys->pts != 0 && p_sys->pts != aout_DateGet( &p_sys->end_date ) ) { @@ -250,62 +255,81 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block ) case STATE_HEADER: /* Get A/52 frame header (A52_HEADER_SIZE bytes) */ - if( p_sys->i_header < A52_HEADER_SIZE ) + if( block_PeekBytes( &p_sys->bytestream, p_header, + A52_HEADER_SIZE ) != VLC_SUCCESS ) { - int i_size = __MIN( A52_HEADER_SIZE - p_sys->i_header, - p_block->i_buffer - i_block_pos ); - - memcpy( p_sys->p_header + p_sys->i_header, - p_block->p_buffer + i_block_pos, i_size ); - i_block_pos += i_size; - p_sys->i_header += i_size; + /* Need more data */ + return VLC_SUCCESS; } - if( p_sys->i_header < A52_HEADER_SIZE ) - break; - - if( GetOutBuffer( p_dec, &p_sys->p_out_buffer ) - != VLC_SUCCESS ) - { - block_Release( p_block ); - return VLC_EGENERIC; - } - - if( !p_sys->p_out_buffer ) + /* Check if frame is valid and get frame info */ + p_sys->i_frame_size = SyncInfo( p_header, + &p_sys->i_channels, + &p_sys->i_channels_conf, + &p_sys->i_rate, + &p_sys->i_bit_rate ); + if( !p_sys->i_frame_size ) { + msg_Dbg( p_dec, "emulated sync word" ); + block_SkipByte( &p_sys->bytestream ); p_sys->i_state = STATE_NOSYNC; + p_dec->p_sys->b_synchro = VLC_FALSE; break; } - - memcpy( p_sys->p_out_buffer, p_sys->p_header, A52_HEADER_SIZE ); - p_sys->i_out_buffer = A52_HEADER_SIZE; p_sys->i_state = STATE_DATA; - break; case STATE_DATA: - /* Copy the whole A52 frame into the aout buffer */ - if( p_sys->i_out_buffer < p_sys->i_frame_size ) + /* TODO: If p_block == NULL, flush the buffer without checking the + * next sync word */ + + if( !p_dec->p_sys->b_synchro ) { - int i_size = __MIN( p_sys->i_frame_size - p_sys->i_out_buffer, - p_block->i_buffer - i_block_pos ); + /* Check if next expected frame contains the sync word */ + if( block_PeekOffsetBytes( &p_sys->bytestream, + p_sys->i_frame_size, p_header, 2 ) + != VLC_SUCCESS ) + { + /* Need more data */ + return VLC_SUCCESS; + } + + if( p_header[0] != 0x0b || p_header[1] != 0x77 ) + { + msg_Dbg( p_dec, "emulated sync word " + "(no sync on following frame)" ); + p_sys->i_state = STATE_NOSYNC; + block_SkipByte( &p_sys->bytestream ); + p_dec->p_sys->b_synchro = VLC_FALSE; + break; + } + } - memcpy( p_sys->p_out_buffer + p_sys->i_out_buffer, - p_block->p_buffer + i_block_pos, i_size ); - i_block_pos += i_size; - p_sys->i_out_buffer += i_size; + if( !p_dec->p_sys->p_out_buffer ) + if( GetOutBuffer( p_dec, &p_sys->p_out_buffer ) != VLC_SUCCESS ) + { + return VLC_EGENERIC; } - if( p_sys->i_out_buffer < p_sys->i_frame_size ) - break; /* Need more data */ + /* Copy the whole frame into the buffer */ + if( block_GetBytes( &p_sys->bytestream, p_sys->p_out_buffer, + p_sys->i_frame_size ) != VLC_SUCCESS ) + { + /* Need more data */ + return VLC_SUCCESS; + } - SendOutBuffer( p_dec ); + p_sys->p_chain = block_BytestreamFlush( &p_sys->bytestream ); + SendOutBuffer( p_dec ); p_sys->i_state = STATE_NOSYNC; - break; + p_dec->p_sys->b_synchro = VLC_TRUE; + + /* Make sure we don't reuse the same pts twice */ + if( p_sys->pts == p_sys->bytestream.p_block->i_pts ) + p_sys->pts = p_sys->bytestream.p_block->i_pts = 0; } } - block_Release( p_block ); return VLC_SUCCESS; } @@ -337,6 +361,8 @@ static int EndDecoder( decoder_t *p_dec ) sout_InputDelete( p_dec->p_sys->p_sout_input ); } + if( p_dec->p_sys->p_chain ) block_ChainRelease( p_sys->p_chain ); + free( p_dec->p_sys ); return VLC_SUCCESS; @@ -345,7 +371,7 @@ static int EndDecoder( decoder_t *p_dec ) /***************************************************************************** * GetOutBuffer: *****************************************************************************/ -static int GetOutBuffer ( decoder_t *p_dec, uint8_t **pp_out_buffer ) +static int GetOutBuffer( decoder_t *p_dec, uint8_t **pp_out_buffer ) { decoder_sys_t *p_sys = p_dec->p_sys; int i_ret; @@ -371,25 +397,11 @@ static int GetOutBuffer ( decoder_t *p_dec, uint8_t **pp_out_buffer ) *****************************************************************************/ static int GetAoutBuffer( decoder_t *p_dec, aout_buffer_t **pp_buffer ) { - int i_bit_rate; - unsigned int i_rate, i_channels, i_channels_conf; - decoder_sys_t *p_sys = p_dec->p_sys; - /* Check if frame is valid and get frame info */ - p_sys->i_frame_size = SyncInfo( p_sys->p_header, - &i_channels, &i_channels_conf, - &i_rate, &i_bit_rate ); - - if( !p_sys->i_frame_size ) - { - msg_Warn( p_dec, "a52 syncinfo failed" ); - *pp_buffer = NULL; - return VLC_SUCCESS; - } - - if( p_sys->p_aout_input != NULL && ( p_sys->aout_format.i_rate != i_rate - || p_sys->aout_format.i_original_channels != i_channels_conf + if( p_sys->p_aout_input != NULL && + ( p_sys->aout_format.i_rate != p_sys->i_rate + || p_sys->aout_format.i_original_channels != p_sys->i_channels_conf || (int)p_sys->aout_format.i_bytes_per_frame != p_sys->i_frame_size ) ) { /* Parameters changed - this should not happen. */ @@ -400,13 +412,13 @@ static int GetAoutBuffer( decoder_t *p_dec, aout_buffer_t **pp_buffer ) /* Creating the audio input if not created yet. */ if( p_sys->p_aout_input == NULL ) { - p_sys->aout_format.i_rate = i_rate; - p_sys->aout_format.i_original_channels = i_channels_conf; + p_sys->aout_format.i_rate = p_sys->i_rate; + p_sys->aout_format.i_original_channels = p_sys->i_channels_conf; p_sys->aout_format.i_physical_channels - = i_channels_conf & AOUT_CHAN_PHYSMASK; + = p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK; p_sys->aout_format.i_bytes_per_frame = p_sys->i_frame_size; p_sys->aout_format.i_frame_length = A52_FRAME_NB; - aout_DateInit( &p_sys->end_date, i_rate ); + aout_DateInit( &p_sys->end_date, p_sys->i_rate ); aout_DateSet( &p_sys->end_date, p_sys->pts ); p_sys->p_aout_input = aout_DecNew( p_dec, &p_sys->p_aout, @@ -445,26 +457,11 @@ static int GetAoutBuffer( decoder_t *p_dec, aout_buffer_t **pp_buffer ) *****************************************************************************/ static int GetSoutBuffer( decoder_t *p_dec, sout_buffer_t **pp_buffer ) { - int i_bit_rate; - unsigned int i_rate, i_channels, i_channels_conf; - decoder_sys_t *p_sys = p_dec->p_sys; - /* Check if frame is valid and get frame info */ - p_sys->i_frame_size = SyncInfo( p_sys->p_header, - &i_channels, &i_channels_conf, - &i_rate, &i_bit_rate ); - - if( !p_sys->i_frame_size ) - { - msg_Warn( p_dec, "a52 syncinfo failed" ); - *pp_buffer = NULL; - return VLC_SUCCESS; - } - if( p_sys->p_sout_input != NULL && - ( p_sys->sout_format.i_sample_rate != (int)i_rate - || p_sys->sout_format.i_channels != (int)i_channels ) ) + ( p_sys->sout_format.i_sample_rate != (int)p_sys->i_rate + || p_sys->sout_format.i_channels != (int)p_sys->i_channels ) ) { /* Parameters changed - this should not happen. */ } @@ -472,19 +469,17 @@ static int GetSoutBuffer( decoder_t *p_dec, sout_buffer_t **pp_buffer ) /* Creating the sout input if not created yet. */ if( p_sys->p_sout_input == NULL ) { - p_sys->sout_format.i_sample_rate = i_rate; - p_sys->sout_format.i_channels = i_channels; + p_sys->sout_format.i_sample_rate = p_sys->i_rate; + p_sys->sout_format.i_channels = p_sys->i_channels; p_sys->sout_format.i_block_align = 0; - p_sys->sout_format.i_bitrate = i_bit_rate; + p_sys->sout_format.i_bitrate = p_sys->i_bit_rate; p_sys->sout_format.i_extra_data = 0; p_sys->sout_format.p_extra_data = NULL; - aout_DateInit( &p_sys->end_date, i_rate ); + aout_DateInit( &p_sys->end_date, p_sys->i_rate ); aout_DateSet( &p_sys->end_date, p_sys->pts ); - p_sys->p_sout_input = sout_InputNew( p_dec, - &p_sys->sout_format ); - + p_sys->p_sout_input = sout_InputNew( p_dec, &p_sys->sout_format ); if( p_sys->p_sout_input == NULL ) { msg_Err( p_dec, "cannot add a new stream" ); @@ -492,7 +487,7 @@ static int GetSoutBuffer( decoder_t *p_dec, sout_buffer_t **pp_buffer ) return VLC_EGENERIC; } msg_Info( p_dec, "A/52 channels:%d samplerate:%d bitrate:%d", - i_channels, i_rate, i_bit_rate ); + p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate ); } if( !aout_DateGet( &p_sys->end_date ) ) @@ -539,6 +534,8 @@ static int SendOutBuffer( decoder_t *p_dec ) p_sys->p_aout_buffer = NULL; } + p_dec->p_sys->p_out_buffer = NULL; + return VLC_SUCCESS; } diff --git a/modules/codec/libmpeg2.c b/modules/codec/libmpeg2.c index 49eaac265f..75939b0c1f 100755 --- a/modules/codec/libmpeg2.c +++ b/modules/codec/libmpeg2.c @@ -2,7 +2,7 @@ * libmpeg2.c: mpeg2 video decoder module making use of libmpeg2. ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: libmpeg2.c,v 1.27 2003/09/03 10:23:17 gbazin Exp $ + * $Id: libmpeg2.c,v 1.28 2003/09/30 20:23:03 gbazin Exp $ * * Authors: Gildas Bazin * Christophe Massiot @@ -187,52 +187,50 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block ) switch( state ) { case STATE_BUFFER: - if( !p_block->i_buffer || b_need_more_data ) + if( !p_block->i_buffer || b_need_more_data ) + { + block_Release( p_block ); + return VLC_SUCCESS; + } + + if( p_block->b_discontinuity && p_sys->p_synchro + && p_sys->p_info->sequence->width != (unsigned)-1 ) + { + vout_SynchroReset( p_sys->p_synchro ); + if( p_sys->p_info->current_fbuf != NULL + && p_sys->p_info->current_fbuf->id != NULL ) { - block_Release( p_block ); - return VLC_SUCCESS; + p_sys->b_garbage_pic = 1; + p_pic = p_sys->p_info->current_fbuf->id; } - -#if 0 - if( p_pes->b_discontinuity && p_sys->p_synchro - && p_sys->p_info->sequence->width != (unsigned)-1 ) + else { - vout_SynchroReset( p_sys->p_synchro ); - if ( p_sys->p_info->current_fbuf != NULL - && p_sys->p_info->current_fbuf->id != NULL ) - { - p_sys->b_garbage_pic = 1; - p_pic = p_sys->p_info->current_fbuf->id; - } - else - { - uint8_t *buf[3]; - buf[0] = buf[1] = buf[2] = NULL; - if( (p_pic = GetNewPicture( p_dec, buf )) == NULL ) - break; - mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic ); - } - p_sys->p_picture_to_destroy = p_pic; - - memset( p_pic->p[0].p_pixels, 0, - p_sys->p_info->sequence->width - * p_sys->p_info->sequence->height ); - memset( p_pic->p[1].p_pixels, 0x80, - p_sys->p_info->sequence->width - * p_sys->p_info->sequence->height / 4 ); - memset( p_pic->p[2].p_pixels, 0x80, - p_sys->p_info->sequence->width - * p_sys->p_info->sequence->height / 4 ); - - if ( p_sys->b_slice_i ) - { - vout_SynchroNewPicture( p_sys->p_synchro, - I_CODING_TYPE, 2, 0, 0, p_sys->i_current_rate ); - vout_SynchroDecode( p_sys->p_synchro ); - vout_SynchroEnd( p_sys->p_synchro, I_CODING_TYPE, 0 ); - } + uint8_t *buf[3]; + buf[0] = buf[1] = buf[2] = NULL; + if( (p_pic = GetNewPicture( p_dec, buf )) == NULL ) + break; + mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic ); } -#endif + p_sys->p_picture_to_destroy = p_pic; + + memset( p_pic->p[0].p_pixels, 0, + p_sys->p_info->sequence->width + * p_sys->p_info->sequence->height ); + memset( p_pic->p[1].p_pixels, 0x80, + p_sys->p_info->sequence->width + * p_sys->p_info->sequence->height / 4 ); + memset( p_pic->p[2].p_pixels, 0x80, + p_sys->p_info->sequence->width + * p_sys->p_info->sequence->height / 4 ); + + if ( p_sys->b_slice_i ) + { + vout_SynchroNewPicture( p_sys->p_synchro, + I_CODING_TYPE, 2, 0, 0, p_sys->i_current_rate ); + vout_SynchroDecode( p_sys->p_synchro ); + vout_SynchroEnd( p_sys->p_synchro, I_CODING_TYPE, 0 ); + } + } if( p_block->i_pts ) {