]> git.sesse.net Git - vlc/commitdiff
* include/vlc_block.h, modules/codec/libmpeg2.c: re-added the discontinuity flag...
authorGildas Bazin <gbazin@videolan.org>
Tue, 30 Sep 2003 20:23:03 +0000 (20:23 +0000)
committerGildas Bazin <gbazin@videolan.org>
Tue, 30 Sep 2003 20:23:03 +0000 (20:23 +0000)
* 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.

include/vlc_block.h
include/vlc_block_helper.h [new file with mode: 0644]
modules/codec/a52.c
modules/codec/libmpeg2.c

index c453a249855b5ff92c7b665e6487b04a25465928..e4282d606f9582254e3828a66e6168697f63f5a1 100644 (file)
@@ -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 <fenrir@via.ecp.fr>
  *
@@ -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 (file)
index 0000000..8eaa4cc
--- /dev/null
@@ -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 <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 */
index 0a1a424f5f742f3b40302ef343b256867dd9e4af..3f0713b2a1a68d5410f05e1201a009966b98a17b 100644 (file)
@@ -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 <stef@via.ecp.fr>
  *          Christophe Massiot <massiot@via.ecp.fr>
@@ -41,6 +41,8 @@
 #   include <unistd.h>
 #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;
 }
 
index 49eaac265f87b6ac4f987c7dbd384a4f7687fa0c..75939b0c1f127de61022a9c5faaff1f743a0ac4b 100755 (executable)
@@ -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 <gbazin@netcourrier.com>
  *          Christophe Massiot <massiot@via.ecp.fr>
@@ -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 )
             {