Commit a4ee4477 authored by Gildas Bazin's avatar Gildas Bazin

* 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.
parent ebc29b88
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* vlc_block.h: Data blocks management functions * vlc_block.h: Data blocks management functions
***************************************************************************** *****************************************************************************
* Copyright (C) 2003 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -38,6 +38,8 @@ struct block_t ...@@ -38,6 +38,8 @@ struct block_t
mtime_t i_pts; mtime_t i_pts;
mtime_t i_dts; mtime_t i_dts;
vlc_bool_t b_discontinuity; /* only temporary */
int i_buffer; int i_buffer;
uint8_t *p_buffer; uint8_t *p_buffer;
......
/*****************************************************************************
* 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 */
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* a52.c: A/52 basic parser * a52.c: A/52 basic parser
***************************************************************************** *****************************************************************************
* Copyright (C) 2001-2002 VideoLAN * 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: Stphane Borel <stef@via.ecp.fr> * Authors: Stphane Borel <stef@via.ecp.fr>
* Christophe Massiot <massiot@via.ecp.fr> * Christophe Massiot <massiot@via.ecp.fr>
...@@ -41,6 +41,8 @@ ...@@ -41,6 +41,8 @@
# include <unistd.h> # include <unistd.h>
#endif #endif
#include "vlc_block_helper.h"
#define A52_HEADER_SIZE 7 #define A52_HEADER_SIZE 7
/***************************************************************************** /*****************************************************************************
...@@ -54,14 +56,11 @@ struct decoder_sys_t ...@@ -54,14 +56,11 @@ struct decoder_sys_t
/* /*
* Input properties * Input properties
*/ */
int i_state; int i_state;
vlc_bool_t b_synchro;
uint8_t p_header[A52_HEADER_SIZE];
int i_header;
mtime_t pts;
int i_frame_size; block_t *p_chain;
block_bytestream_t bytestream;
/* /*
* Decoder output properties * Decoder output properties
...@@ -69,7 +68,6 @@ struct decoder_sys_t ...@@ -69,7 +68,6 @@ struct decoder_sys_t
aout_instance_t * p_aout; /* opaque */ aout_instance_t * p_aout; /* opaque */
aout_input_t * p_aout_input; /* opaque */ aout_input_t * p_aout_input; /* opaque */
audio_sample_format_t aout_format; audio_sample_format_t aout_format;
aout_buffer_t * p_aout_buffer; /* current aout buffer being filled */ aout_buffer_t * p_aout_buffer; /* current aout buffer being filled */
/* /*
...@@ -85,12 +83,16 @@ struct decoder_sys_t ...@@ -85,12 +83,16 @@ struct decoder_sys_t
uint8_t *p_out_buffer; /* output buffer */ uint8_t *p_out_buffer; /* output buffer */
int i_out_buffer; /* position in output buffer */ int i_out_buffer; /* position in output buffer */
audio_date_t end_date; 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 { enum {
STATE_NOSYNC, STATE_NOSYNC,
STATE_PARTIAL_SYNC,
STATE_SYNC, STATE_SYNC,
STATE_HEADER, STATE_HEADER,
STATE_DATA STATE_DATA
...@@ -173,6 +175,7 @@ static int OpenPacketizer( vlc_object_t *p_this ) ...@@ -173,6 +175,7 @@ static int OpenPacketizer( vlc_object_t *p_this )
static int InitDecoder( decoder_t *p_dec ) static int InitDecoder( decoder_t *p_dec )
{ {
p_dec->p_sys->i_state = STATE_NOSYNC; 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->p_out_buffer = NULL;
p_dec->p_sys->i_out_buffer = 0; p_dec->p_sys->i_out_buffer = 0;
...@@ -188,6 +191,8 @@ static int InitDecoder( decoder_t *p_dec ) ...@@ -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_cat = AUDIO_ES;
p_dec->p_sys->sout_format.i_fourcc = VLC_FOURCC( 'a', '5', '2', ' ' ); p_dec->p_sys->sout_format.i_fourcc = VLC_FOURCC( 'a', '5', '2', ' ' );
p_dec->p_sys->p_chain = NULL;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -199,47 +204,47 @@ static int InitDecoder( decoder_t *p_dec ) ...@@ -199,47 +204,47 @@ static int InitDecoder( decoder_t *p_dec )
static int RunDecoder( decoder_t *p_dec, block_t *p_block ) static int RunDecoder( decoder_t *p_dec, block_t *p_block )
{ {
decoder_sys_t *p_sys = p_dec->p_sys; decoder_sys_t *p_sys = p_dec->p_sys;
int i_block_pos = 0; uint8_t p_header[A52_HEADER_SIZE];
mtime_t i_pts = p_block->i_pts;
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 ) switch( p_sys->i_state )
{ {
case STATE_NOSYNC: case STATE_NOSYNC:
/* Look for sync word - should be 0x0b77 */ while( block_PeekBytes( &p_sys->bytestream, p_header, 2 )
while( i_block_pos < p_block->i_buffer && == VLC_SUCCESS )
p_block->p_buffer[i_block_pos] != 0x0b )
{ {
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( p_sys->i_state != STATE_SYNC )
if( i_block_pos < p_block->i_buffer )
{ {
p_sys->i_state = STATE_PARTIAL_SYNC; block_ChainRelease( p_sys->p_chain );
i_block_pos++; p_sys->p_chain = NULL;
p_sys->p_header[0] = 0x0b;
break;
}
break;
case STATE_PARTIAL_SYNC: /* Need more data */
if( p_block->p_buffer[i_block_pos] == 0x77 ) return VLC_SUCCESS;
{
p_sys->i_state = STATE_SYNC;
i_block_pos++;
p_sys->p_header[1] = 0x77;
p_sys->i_header = 2;
} }
else
{
p_sys->i_state = STATE_NOSYNC;
}
break;
case STATE_SYNC: case STATE_SYNC:
/* New frame, set the Presentation Time Stamp */ /* 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 && if( p_sys->pts != 0 &&
p_sys->pts != aout_DateGet( &p_sys->end_date ) ) p_sys->pts != aout_DateGet( &p_sys->end_date ) )
{ {
...@@ -250,62 +255,81 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block ) ...@@ -250,62 +255,81 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
case STATE_HEADER: case STATE_HEADER:
/* Get A/52 frame header (A52_HEADER_SIZE bytes) */ /* 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, /* Need more data */
p_block->i_buffer - i_block_pos ); return VLC_SUCCESS;
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;
} }
if( p_sys->i_header < A52_HEADER_SIZE ) /* Check if frame is valid and get frame info */
break; p_sys->i_frame_size = SyncInfo( p_header,
&p_sys->i_channels,
if( GetOutBuffer( p_dec, &p_sys->p_out_buffer ) &p_sys->i_channels_conf,
!= VLC_SUCCESS ) &p_sys->i_rate,
{ &p_sys->i_bit_rate );
block_Release( p_block ); if( !p_sys->i_frame_size )
return VLC_EGENERIC;
}
if( !p_sys->p_out_buffer )
{ {
msg_Dbg( p_dec, "emulated sync word" );
block_SkipByte( &p_sys->bytestream );
p_sys->i_state = STATE_NOSYNC; p_sys->i_state = STATE_NOSYNC;
p_dec->p_sys->b_synchro = VLC_FALSE;
break; 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; p_sys->i_state = STATE_DATA;
break;
case STATE_DATA: case STATE_DATA:
/* Copy the whole A52 frame into the aout buffer */ /* TODO: If p_block == NULL, flush the buffer without checking the
if( p_sys->i_out_buffer < p_sys->i_frame_size ) * next sync word */
if( !p_dec->p_sys->b_synchro )
{ {
int i_size = __MIN( p_sys->i_frame_size - p_sys->i_out_buffer, /* Check if next expected frame contains the sync word */
p_block->i_buffer - i_block_pos ); 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, if( !p_dec->p_sys->p_out_buffer )
p_block->p_buffer + i_block_pos, i_size ); if( GetOutBuffer( p_dec, &p_sys->p_out_buffer ) != VLC_SUCCESS )
i_block_pos += i_size; {
p_sys->i_out_buffer += i_size; return VLC_EGENERIC;
} }
if( p_sys->i_out_buffer < p_sys->i_frame_size ) /* Copy the whole frame into the buffer */
break; /* Need more data */ 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; 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; return VLC_SUCCESS;
} }
...@@ -337,6 +361,8 @@ static int EndDecoder( decoder_t *p_dec ) ...@@ -337,6 +361,8 @@ static int EndDecoder( decoder_t *p_dec )
sout_InputDelete( p_dec->p_sys->p_sout_input ); 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 ); free( p_dec->p_sys );
return VLC_SUCCESS; return VLC_SUCCESS;
...@@ -345,7 +371,7 @@ static int EndDecoder( decoder_t *p_dec ) ...@@ -345,7 +371,7 @@ static int EndDecoder( decoder_t *p_dec )
/***************************************************************************** /*****************************************************************************
* GetOutBuffer: * 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; decoder_sys_t *p_sys = p_dec->p_sys;
int i_ret; int i_ret;
...@@ -371,25 +397,11 @@ static int GetOutBuffer ( decoder_t *p_dec, uint8_t **pp_out_buffer ) ...@@ -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 ) 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; decoder_sys_t *p_sys = p_dec->p_sys;
/* Check if frame is valid and get frame info */ if( p_sys->p_aout_input != NULL &&
p_sys->i_frame_size = SyncInfo( p_sys->p_header, ( p_sys->aout_format.i_rate != p_sys->i_rate
&i_channels, &i_channels_conf, || p_sys->aout_format.i_original_channels != p_sys->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
|| (int)p_sys->aout_format.i_bytes_per_frame != p_sys->i_frame_size ) ) || (int)p_sys->aout_format.i_bytes_per_frame != p_sys->i_frame_size ) )
{ {
/* Parameters changed - this should not happen. */ /* Parameters changed - this should not happen. */
...@@ -400,13 +412,13 @@ static int GetAoutBuffer( decoder_t *p_dec, aout_buffer_t **pp_buffer ) ...@@ -400,13 +412,13 @@ static int GetAoutBuffer( decoder_t *p_dec, aout_buffer_t **pp_buffer )
/* Creating the audio input if not created yet. */ /* Creating the audio input if not created yet. */
if( p_sys->p_aout_input == NULL ) if( p_sys->p_aout_input == NULL )
{ {
p_sys->aout_format.i_rate = i_rate; p_sys->aout_format.i_rate = p_sys->i_rate;
p_sys->aout_format.i_original_channels = i_channels_conf; p_sys->aout_format.i_original_channels = p_sys->i_channels_conf;
p_sys->aout_format.i_physical_channels 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_bytes_per_frame = p_sys->i_frame_size;
p_sys->aout_format.i_frame_length = A52_FRAME_NB; 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 ); aout_DateSet( &p_sys->end_date, p_sys->pts );
p_sys->p_aout_input = aout_DecNew( p_dec, p_sys->p_aout_input = aout_DecNew( p_dec,
&p_sys->p_aout, &p_sys->p_aout,
...@@ -445,26 +457,11 @@ static int GetAoutBuffer( decoder_t *p_dec, aout_buffer_t **pp_buffer ) ...@@ -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 ) 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; 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 && if( p_sys->p_sout_input != NULL &&
( p_sys->sout_format.i_sample_rate != (int)i_rate ( p_sys->sout_format.i_sample_rate != (int)p_sys->i_rate
|| p_sys->sout_format.i_channels != (int)i_channels ) ) || p_sys->sout_format.i_channels != (int)p_sys->i_channels ) )
{ {
/* Parameters changed - this should not happen. */ /* Parameters changed - this should not happen. */
} }
...@@ -472,19 +469,17 @@ static int GetSoutBuffer( decoder_t *p_dec, sout_buffer_t **pp_buffer ) ...@@ -472,19 +469,17 @@ static int GetSoutBuffer( decoder_t *p_dec, sout_buffer_t **pp_buffer )
/* Creating the sout input if not created yet. */ /* Creating the sout input if not created yet. */
if( p_sys->p_sout_input == NULL ) if( p_sys->p_sout_input == NULL )
{ {
p_sys->sout_format.i_sample_rate = i_rate; p_sys->sout_format.i_sample_rate = p_sys->i_rate;
p_sys->sout_format.i_channels = i_channels; p_sys->sout_format.i_channels = p_sys->i_channels;
p_sys->sout_format.i_block_align = 0; 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.i_extra_data = 0;
p_sys->sout_format.p_extra_data = NULL; 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 ); aout_DateSet( &p_sys->end_date, p_sys->pts );
p_sys->p_sout_input = sout_InputNew( p_dec, p_sys->p_sout_input = sout_InputNew( p_dec, &p_sys->sout_format );
&p_sys->sout_format );
if( p_sys->p_sout_input == NULL ) if( p_sys->p_sout_input == NULL )
{ {
msg_Err( p_dec, "cannot add a new stream" ); 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 ) ...@@ -492,7 +487,7 @@ static int GetSoutBuffer( decoder_t *p_dec, sout_buffer_t **pp_buffer )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
msg_Info( p_dec, "A/52 channels:%d samplerate:%d bitrate:%d", 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 ) ) if( !aout_DateGet( &p_sys->end_date ) )
...@@ -539,6 +534,8 @@ static int SendOutBuffer( decoder_t *p_dec ) ...@@ -539,6 +534,8 @@ static int SendOutBuffer( decoder_t *p_dec )
p_sys->p_aout_buffer = NULL; p_sys->p_aout_buffer = NULL;
} }
p_dec->p_sys->p_out_buffer = NULL;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* libmpeg2.c: mpeg2 video decoder module making use of libmpeg2. * libmpeg2.c: mpeg2 video decoder module making use of libmpeg2.
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * Authors: Gildas Bazin <gbazin@netcourrier.com>
* Christophe Massiot <massiot@via.ecp.fr> * Christophe Massiot <massiot@via.ecp.fr>
...@@ -187,52 +187,50 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block ) ...@@ -187,52 +187,50 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
switch( state ) switch( state )
{ {
case STATE_BUFFER: 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 ); p_sys->b_garbage_pic = 1;
return VLC_SUCCESS; p_pic = p_sys->p_info->current_fbuf->id;
} }
else
#if 0
if( p_pes->b_discontinuity && p_sys->p_synchro
&& p_sys->p_info->sequence->width != (unsigned)-1 )
{ {
vout_SynchroReset( p_sys->p_synchro ); uint8_t *buf[3];
if ( p_sys->p_info->current_fbuf != NULL buf[0] = buf[1] = buf[2] = NULL;
&& p_sys->p_info->current_fbuf->id != NULL ) if( (p_pic = GetNewPicture( p_dec, buf )) == NULL )
{ break;
p_sys->b_garbage_pic = 1; mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
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 );
}
} }
#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 ) if( p_block->i_pts )
{ {
......
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