* 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.
* 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 <fenrir@via.ecp.fr>
*
mtime_t i_pts;
mtime_t i_dts;
+ vlc_bool_t b_discontinuity; /* only temporary */
+
int i_buffer;
uint8_t *p_buffer;
--- /dev/null
+/*****************************************************************************
+ * 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 <gbazin@netcourrier.com>
+ *
+ * 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 */
* 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 <stef@via.ecp.fr>
* Christophe Massiot <massiot@via.ecp.fr>
# include <unistd.h>
#endif
+#include "vlc_block_helper.h"
+
#define A52_HEADER_SIZE 7
/*****************************************************************************
/*
* 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
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 */
/*
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
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;
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;
}
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 ) )
{
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;
}
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;
/*****************************************************************************
* 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;
*****************************************************************************/
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. */
/* 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,
*****************************************************************************/
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. */
}
/* 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" );
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 ) )
p_sys->p_aout_buffer = NULL;
}
+ p_dec->p_sys->p_out_buffer = NULL;
+
return VLC_SUCCESS;
}
* 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 <gbazin@netcourrier.com>
* Christophe Massiot <massiot@via.ecp.fr>
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 )
{