]> git.sesse.net Git - vlc/commitdiff
* ALL: Introduction of a new api for decoders.
authorGildas Bazin <gbazin@videolan.org>
Tue, 2 Sep 2003 20:19:26 +0000 (20:19 +0000)
committerGildas Bazin <gbazin@videolan.org>
Tue, 2 Sep 2003 20:19:26 +0000 (20:19 +0000)
   The final aim of this new api is to make it possible to use the decoders from other modules like the transcoder for instance.
   Only a few decoders have been ported to the new api (a52, libmpeg2, dts, vorbis, theora) so the old api is still supported.

   Don't hold your breath, there is still much work to do before we reach this goal.

* modules/codec/a52.c, libmpeg2., dts.c, vorbis.c, theora.c:
   Converted to the new api.
   Merged the a52 and vorbis packetizers in their respective decoders (removes a lot of code duplication).
   New dts and theora packetizers (merged in their respective decoders).

41 files changed:
configure.ac
include/input_ext-dec.h
include/vlc/decoder.h
include/vlc/input.h
include/vlc/sout.h
include/vlc_block.h
include/vlc_common.h
include/vlc_objects.h
modules/codec/a52.c
modules/codec/adpcm.c
modules/codec/araw.c
modules/codec/cinepak/cinepak.c
modules/codec/dts.c
modules/codec/dv.c
modules/codec/faad/decoder.c
modules/codec/ffmpeg/ffmpeg.c
modules/codec/flacdec.c
modules/codec/libmpeg2.c
modules/codec/lpcm.c
modules/codec/mpeg_audio.c
modules/codec/quicktime.c
modules/codec/rawvideo.c
modules/codec/spudec/spudec.c
modules/codec/subsdec/subsdec.c
modules/codec/tarkin.c
modules/codec/theora.c
modules/codec/vorbis.c
modules/codec/xvid.c
modules/demux/ogg.c
modules/misc/dummy/decoder.c
modules/packetizer/Modules.am
modules/packetizer/a52.c [deleted file]
modules/packetizer/copy.c
modules/packetizer/mpeg4audio.c
modules/packetizer/mpeg4video.c
modules/packetizer/mpegaudio.c
modules/packetizer/mpegvideo.c
modules/packetizer/vorbis.c [deleted file]
src/input/input_dec.c
src/misc/block.c
src/misc/objects.c

index 9617bf2976bb3dba7709d3d95b3fd406dad78c7c..604efdeab15ea580c4a3e3cb3c163f7d4d003da7 100644 (file)
@@ -1,5 +1,5 @@
 dnl Autoconf settings for vlc
-dnl $Id: configure.ac,v 1.71 2003/08/31 15:55:56 titer Exp $
+dnl $Id: configure.ac,v 1.72 2003/09/02 20:19:25 gbazin Exp $
 
 AC_INIT(vlc,0.6.3-cvs)
 
@@ -1000,7 +1000,7 @@ if test "${enable_sout}" != "no"
 then
   AX_ADD_PLUGINS([access_output_dummy access_output_udp access_output_file access_output_http])
   AX_ADD_PLUGINS([mux_ts mux_ps mux_avi mux_mp4 mux_asf mux_dummy])
-  AX_ADD_PLUGINS([packetizer_mpegaudio packetizer_mpegvideo packetizer_a52])
+  AX_ADD_PLUGINS([packetizer_mpegaudio packetizer_mpegvideo])
   AX_ADD_PLUGINS([packetizer_mpeg4video packetizer_mpeg4audio])
   AX_ADD_PLUGINS([packetizer_copy])
 
@@ -1934,11 +1934,7 @@ if test "${enable_vorbis}" != "no"
 then
   AC_CHECK_HEADERS(vorbis/codec.h, [
     AX_ADD_PLUGINS([vorbis])
-    AX_ADD_LDFLAGS([vorbis],[-lvorbis -logg])
-    if test "${enable_sout}" != "no"; then
-      AX_ADD_PLUGINS([packetizer_vorbis])
-      AX_ADD_LDFLAGS([packetizer_vorbis],[-lvorbis -logg])
-    fi ],[])
+    AX_ADD_LDFLAGS([vorbis],[-lvorbis -logg]) ],[])
 fi
 
 dnl
index 75e3e06556df851e09df116ac4e21bc301114939..12c8ceadb4e046130f476317c3cfe7a660a7c47d 100644 (file)
@@ -2,7 +2,7 @@
  * input_ext-dec.h: structures exported to the VideoLAN decoders
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: input_ext-dec.h,v 1.79 2003/03/04 13:21:19 massiot Exp $
+ * $Id: input_ext-dec.h,v 1.80 2003/09/02 20:19:25 gbazin Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *          Michel Kaempf <maxx@via.ecp.fr>
@@ -110,8 +110,29 @@ struct decoder_fifo_t
     void *              p_waveformatex;
     void *              p_bitmapinfoheader;
 
+    decoder_t *         p_dec;
+};
+
+/*****************************************************************************
+ * decoder_t
+ *****************************************************************************
+ * The decoder descriptor.
+ *****************************************************************************/
+struct decoder_t
+{
+    VLC_COMMON_MEMBERS
+
     /* Module properties */
-    module_t *              p_module;
+    module_t *          p_module;
+    decoder_sys_t *     p_sys;
+    int                 ( * pf_init )  ( decoder_t * );
+    int                 ( * pf_decode )( decoder_t *, block_t * );
+    int                 ( * pf_end )   ( decoder_t * );
+
+    /* Input properties */
+    decoder_fifo_t *    p_fifo;                /* stores the PES stream data */
+
+    /* Tmp field for old decoder api */
     int                 ( * pf_run ) ( decoder_fifo_t * );
 };
 
index 473d81205d765277b6b49b889032b085730081b3..e6b98a684df62db7854b225755f934f36976f533 100644 (file)
@@ -2,7 +2,7 @@
  * decoder.h: header for vlc decoders
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: decoder.h,v 1.1 2002/06/01 12:31:58 sam Exp $
+ * $Id: decoder.h,v 1.2 2003/09/02 20:19:25 gbazin Exp $
  *
  * 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
@@ -34,6 +34,7 @@ extern "C" {
 /*****************************************************************************
  * Required internal headers
  *****************************************************************************/
+#include "vlc_block.h"
 #include "stream_control.h"
 #include "input_ext-dec.h"
 
index 2f3f7b1c7fb8eae28ff45e0b9bb43d8a48cf2302..cc122968e43461340a9d85e3bb0d15243cee409c 100644 (file)
@@ -2,7 +2,7 @@
  * input.h: input modules header for vlc
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: input.h,v 1.1 2002/06/01 12:31:58 sam Exp $
+ * $Id: input.h,v 1.2 2003/09/02 20:19:25 gbazin Exp $
  *
  * 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
@@ -34,6 +34,7 @@ extern "C" {
 /*****************************************************************************
  * Required internal headers
  *****************************************************************************/
+#include "vlc_block.h"
 #include "stream_control.h"
 #include "input_ext-intf.h" /* input_thread_s */
 #include "input_ext-dec.h" /* data_packet_s */
index a01adb1c96ccc6485870e45f6b4b4007a161fd29..319ffba27aa876212241196fd61e1a180ab2f60b 100644 (file)
@@ -2,7 +2,7 @@
  * sout.h: video output header for vlc
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: sout.h,v 1.2 2003/05/20 16:20:33 zorglub Exp $
+ * $Id: sout.h,v 1.3 2003/09/02 20:19:25 gbazin Exp $
  *
  * 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
@@ -34,6 +34,7 @@ extern "C" {
 /*****************************************************************************
  * Required internal headers
  *****************************************************************************/
+#include "vlc_block.h"
 #include "stream_output.h"
         
 # ifdef __cplusplus
index ea3ccfadfe4803218ccb00087b422368d29b8188..c453a249855b5ff92c7b665e6487b04a25465928 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
- * block.h
+ * vlc_block.h: Data blocks management functions
  *****************************************************************************
  * Copyright (C) 2003 VideoLAN
- * $Id: vlc_block.h,v 1.1 2003/08/23 22:49:50 fenrir Exp $
+ * $Id: vlc_block.h,v 1.2 2003/09/02 20:19:25 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -21,9 +21,8 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
 
-#ifndef _BLOCK_H
-#define _BLOCK_H 1
-
+#ifndef _VLC_BLOCK_H
+#define _VLC_BLOCK_H 1
 
 /*
  * block
@@ -108,4 +107,4 @@ VLC_EXPORT( block_t *,      block_FifoGet,      ( block_fifo_t * ) );
 VLC_EXPORT( block_t *,      block_FifoGetFrame, ( block_fifo_t * ) );
 VLC_EXPORT( block_t *,      block_FifoShow,     ( block_fifo_t * ) );
 
-#endif
+#endif /* VLC_BLOCK_H */
index 8bfceced67ded23b7f30c77401056ef0fcd0e482..f010ce7a0e2097afd604906de3672c119240858e 100644 (file)
@@ -3,7 +3,7 @@
  * Collection of useful common types and macros definitions
  *****************************************************************************
  * Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: vlc_common.h,v 1.75 2003/08/23 22:49:50 fenrir Exp $
+ * $Id: vlc_common.h,v 1.76 2003/09/02 20:19:25 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@via.ecp.fr>
  *          Vincent Seguin <seguin@via.ecp.fr>
@@ -268,6 +268,8 @@ typedef struct slp_session_t    slp_session_t;*/
 
 /* Decoders */
 typedef struct decoder_fifo_t decoder_fifo_t;
+typedef struct decoder_t      decoder_t;
+typedef struct decoder_sys_t  decoder_sys_t;
 
 /* Misc */
 typedef struct data_packet_t data_packet_t;
index f1e4757e9c23b15c5c205da6e7862ad5f5b4a8f8..d2954db549efbc96fc710139405d4dee353c4e5f 100644 (file)
@@ -2,7 +2,7 @@
  * vlc_objects.h: vlc_object_t definition.
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: vlc_objects.h,v 1.16 2003/02/23 19:07:02 fenrir Exp $
+ * $Id: vlc_objects.h,v 1.17 2003/09/02 20:19:25 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -30,6 +30,8 @@
 #define VLC_OBJECT_ITEM       (-6)
 #define VLC_OBJECT_INPUT      (-7)
 #define VLC_OBJECT_DECODER    (-8)
+/* tmp for backward compat */
+#define VLC_OBJECT_DECODER_FIFO (-999)
 #define VLC_OBJECT_VOUT       (-9)
 #define VLC_OBJECT_AOUT      (-10)
 #define VLC_OBJECT_SOUT      (-11)
index e2a8e68eb80463910d7342f52213892b36dfc73e..0a1a424f5f742f3b40302ef343b256867dd9e4af 100644 (file)
@@ -2,12 +2,11 @@
  * a52.c: A/52 basic parser
  *****************************************************************************
  * Copyright (C) 2001-2002 VideoLAN
- * $Id: a52.c,v 1.22 2003/03/31 22:39:27 massiot Exp $
+ * $Id: a52.c,v 1.23 2003/09/02 20:19:25 gbazin Exp $
  *
  * Authors: Stéphane Borel <stef@via.ecp.fr>
  *          Christophe Massiot <massiot@via.ecp.fr>
- *          Michel Lespinasse <walken@zoy.org>
- *          Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *          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
 
 #include <vlc/vlc.h>
 #include <vlc/decoder.h>
+#include <vlc/input.h>
 #include <vlc/aout.h>
+#include <vlc/sout.h>
 
 #ifdef HAVE_UNISTD_H
 #   include <unistd.h>
 #endif
 
+#define A52_HEADER_SIZE 7
+
 /*****************************************************************************
- * dec_thread_t : decoder thread descriptor
+ * decoder_sys_t : decoder descriptor
  *****************************************************************************/
-typedef struct dec_thread_t
+struct decoder_sys_t
 {
+    /* Module mode */
+    vlc_bool_t b_packetizer;
+
     /*
-     * Thread properties
+     * Input properties
      */
-    vlc_thread_t        thread_id;                /* id for thread functions */
+    int     i_state;
+
+    uint8_t p_header[A52_HEADER_SIZE];
+    int     i_header;
+
+    mtime_t pts;
+
+    int     i_frame_size;
 
     /*
-     * Input properties
+     * 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 */
+
+    /*
+     * Packetizer output properties
      */
-    decoder_fifo_t *    p_fifo;                /* stores the PES stream data */
-    bit_stream_t        bit_stream;
+    sout_packetizer_input_t *p_sout_input;
+    sout_format_t           sout_format;
+    sout_buffer_t *         p_sout_buffer;            /* current sout buffer */
 
     /*
-     * Output properties
+     * Common properties
      */
-    aout_instance_t *   p_aout; /* opaque */
-    aout_input_t *      p_aout_input; /* opaque */
-    audio_sample_format_t output_format;
-} dec_thread_t;
+    uint8_t               *p_out_buffer;                    /* output buffer */
+    int                   i_out_buffer;         /* position in output buffer */
+    audio_date_t          end_date;
+};
+
+enum {
+
+    STATE_NOSYNC,
+    STATE_PARTIAL_SYNC,
+    STATE_SYNC,
+    STATE_HEADER,
+    STATE_DATA
+};
 
 /****************************************************************************
  * Local prototypes
  ****************************************************************************/
-static int  OpenDecoder    ( vlc_object_t * );
-static int  RunDecoder     ( decoder_fifo_t * );
+static int  OpenDecoder   ( vlc_object_t * );
+static int  OpenPacketizer( vlc_object_t * );
+
+static int  InitDecoder   ( decoder_t * );
+static int  RunDecoder    ( decoder_t *, block_t * );
+static int  EndDecoder    ( decoder_t * );
 
-static void EndThread      ( dec_thread_t * );
+static int  SyncInfo      ( const byte_t *, int *, int *, int *,int * );
 
-static int  SyncInfo       ( const byte_t *, int *, int *, int * );
+static int GetOutBuffer ( decoder_t *, uint8_t ** );
+static int GetAoutBuffer( decoder_t *, aout_buffer_t ** );
+static int GetSoutBuffer( decoder_t *, sout_buffer_t ** );
+static int SendOutBuffer( decoder_t * );
 
 /*****************************************************************************
  * Module descriptor
@@ -81,6 +120,11 @@ vlc_module_begin();
     set_description( _("A/52 parser") );
     set_capability( "decoder", 100 );
     set_callbacks( OpenDecoder, NULL );
+
+    add_submodule();
+    set_description( _("A/52 audio packetizer") );
+    set_capability( "packetizer", 10 );
+    set_callbacks( OpenPacketizer, NULL );
 vlc_module_end();
 
 /*****************************************************************************
@@ -88,15 +132,62 @@ vlc_module_end();
  *****************************************************************************/
 static int OpenDecoder( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
+
+    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('a','5','2',' ')
+         && p_dec->p_fifo->i_fourcc != VLC_FOURCC('a','5','2','b') )
+    {
+        return VLC_EGENERIC;
+    }
 
-    if( p_fifo->i_fourcc != VLC_FOURCC('a','5','2',' ')
-         && p_fifo->i_fourcc != VLC_FOURCC('a','5','2','b') )
+    p_dec->pf_init = InitDecoder;
+    p_dec->pf_decode = RunDecoder;
+    p_dec->pf_end = EndDecoder;
+
+    /* Allocate the memory needed to store the decoder's structure */
+    if( ( p_dec->p_sys =
+          (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
     {
+        msg_Err( p_dec, "out of memory" );
         return VLC_EGENERIC;
     }
+    p_dec->p_sys->b_packetizer = VLC_FALSE;
+
+    return VLC_SUCCESS;
+}
+
+static int OpenPacketizer( vlc_object_t *p_this )
+{
+    decoder_t *p_dec = (decoder_t*)p_this;
+
+    int i_ret = OpenDecoder( p_this );
+
+    if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE;
+
+    return i_ret;
+}
+
+/*****************************************************************************
+ * InitDecoder: Initalize the decoder
+ *****************************************************************************/
+static int InitDecoder( decoder_t *p_dec )
+{
+    p_dec->p_sys->i_state = STATE_NOSYNC;
+
+    p_dec->p_sys->p_out_buffer = NULL;
+    p_dec->p_sys->i_out_buffer = 0;
+    aout_DateSet( &p_dec->p_sys->end_date, 0 );
+
+    p_dec->p_sys->p_aout = NULL;
+    p_dec->p_sys->p_aout_input = NULL;
+    p_dec->p_sys->p_aout_buffer = NULL;
+    p_dec->p_sys->aout_format.i_format = VLC_FOURCC('a','5','2',' ');
+
+    p_dec->p_sys->p_sout_input = NULL;
+    p_dec->p_sys->p_sout_buffer = NULL;
+    p_dec->p_sys->sout_format.i_cat = AUDIO_ES;
+    p_dec->p_sys->sout_format.i_fourcc = VLC_FOURCC( 'a', '5', '2', ' ' );
 
-    p_fifo->pf_run = RunDecoder;
     return VLC_SUCCESS;
 }
 
@@ -105,167 +196,350 @@ static int OpenDecoder( vlc_object_t *p_this )
  ****************************************************************************
  * This function is called just after the thread is launched.
  ****************************************************************************/
-static int RunDecoder( decoder_fifo_t *p_fifo )
+static int RunDecoder( decoder_t *p_dec, block_t *p_block )
 {
-    dec_thread_t * p_dec;
-    audio_date_t end_date;
+    decoder_sys_t *p_sys = p_dec->p_sys;
+    int i_block_pos = 0;
+    mtime_t i_pts = p_block->i_pts;
 
-    /* Allocate the memory needed to store the thread's structure */
-    p_dec = malloc( sizeof(dec_thread_t) );
-    if( p_dec == NULL )
+    while( i_block_pos < p_block->i_buffer )
     {
-        msg_Err( p_fifo, "out of memory" );
-        DecoderError( p_fifo );
-        return -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 )
+            {
+                i_block_pos++;
+            }
 
-    /* Initialize the thread properties */
-    p_dec->p_aout = NULL;
-    p_dec->p_aout_input = NULL;
-    p_dec->p_fifo = p_fifo;
-    p_dec->output_format.i_format = VLC_FOURCC('a','5','2',' ');
+            if( i_block_pos < p_block->i_buffer )
+            {
+                p_sys->i_state = STATE_PARTIAL_SYNC;
+                i_block_pos++;
+                p_sys->p_header[0] = 0x0b;
+                break;
+            }
+            break;
 
-    aout_DateSet( &end_date, 0 );
+        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;
+            }
+            else
+            {
+                p_sys->i_state = STATE_NOSYNC;
+            }
+            break;
 
-    /* Init the bitstream */
-    if( InitBitstream( &p_dec->bit_stream, p_dec->p_fifo,
-                       NULL, NULL ) != VLC_SUCCESS )
-    {
-        msg_Err( p_fifo, "cannot initialize bitstream" );
-        DecoderError( p_fifo );
-        free( p_dec );
-        return -1;
+        case STATE_SYNC:
+            /* New frame, set the Presentation Time Stamp */
+            p_sys->pts = i_pts; i_pts = 0;
+            if( p_sys->pts != 0 &&
+                p_sys->pts != aout_DateGet( &p_sys->end_date ) )
+            {
+                aout_DateSet( &p_sys->end_date, p_sys->pts );
+            }
+            p_sys->i_state = STATE_HEADER;
+            break;
+
+        case STATE_HEADER:
+            /* Get A/52 frame header (A52_HEADER_SIZE bytes) */
+            if( p_sys->i_header < A52_HEADER_SIZE )
+            {
+                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;
+            }
+
+            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 )
+            {
+                p_sys->i_state = STATE_NOSYNC;
+                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 )
+            {
+                int i_size = __MIN( p_sys->i_frame_size - p_sys->i_out_buffer,
+                                    p_block->i_buffer - i_block_pos );
+
+                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_sys->i_out_buffer < p_sys->i_frame_size )
+                break; /* Need more data */
+
+            SendOutBuffer( p_dec );
+
+            p_sys->i_state = STATE_NOSYNC;
+            break;
+        }
     }
 
-    /* Decoder thread's main loop */
-    while ( !p_dec->p_fifo->b_die && !p_dec->p_fifo->b_error )
+    block_Release( p_block );
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * EndDecoder: clean up the decoder
+ *****************************************************************************/
+static int EndDecoder( decoder_t *p_dec )
+{
+    if( p_dec->p_sys->p_aout_input != NULL )
     {
-        int i_bit_rate;
-        unsigned int i_rate, i_original_channels, i_frame_size;
-        mtime_t pts;
-        byte_t p_header[7];
-        aout_buffer_t * p_buffer;
-
-        /* Look for sync word - should be 0x0b77 */
-        RealignBits( &p_dec->bit_stream );
-        while ( (ShowBits( &p_dec->bit_stream, 16 ) ) != 0x0b77 &&
-                (!p_dec->p_fifo->b_die) && (!p_dec->p_fifo->b_error) )
+        if( p_dec->p_sys->p_aout_buffer )
         {
-            RemoveBits( &p_dec->bit_stream, 8 );
+            aout_DecDeleteBuffer( p_dec->p_sys->p_aout,
+                                  p_dec->p_sys->p_aout_input,
+                                  p_dec->p_sys->p_aout_buffer );
         }
-        if ( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error ) break;
 
-        /* Set the Presentation Time Stamp */
-        NextPTS( &p_dec->bit_stream, &pts, NULL );
-        if ( pts != 0 && pts != aout_DateGet( &end_date ) )
+        aout_DecDelete( p_dec->p_sys->p_aout, p_dec->p_sys->p_aout_input );
+    }
+
+    if( p_dec->p_sys->p_sout_input != NULL )
+    {
+        if( p_dec->p_sys->p_sout_buffer )
         {
-            aout_DateSet( &end_date, pts );
+            sout_BufferDelete( p_dec->p_sys->p_sout_input->p_sout,
+                               p_dec->p_sys->p_sout_buffer );
         }
 
-        /* Get A/52 frame header */
-        GetChunk( &p_dec->bit_stream, p_header, 7 );
-        if ( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error ) break;
+        sout_InputDelete( p_dec->p_sys->p_sout_input );
+    }
 
-        /* Check if frame is valid and get frame info */
-        i_frame_size = SyncInfo( p_header, &i_original_channels, &i_rate,
-                                 &i_bit_rate );
+    free( p_dec->p_sys );
 
-        if( !i_frame_size )
-        {
-            msg_Warn( p_dec->p_fifo, "a52_syncinfo failed" );
-            continue;
-        }
+    return VLC_SUCCESS;
+}
 
-        if( (p_dec->p_aout_input != NULL) &&
-            ( (p_dec->output_format.i_rate != i_rate)
-                || (p_dec->output_format.i_original_channels
-                      != i_original_channels)
-                || (p_dec->output_format.i_bytes_per_frame != i_frame_size) ) )
-        {
-            /* Parameters changed - this should not happen. */
-            aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
-            p_dec->p_aout_input = NULL;
-        }
+/*****************************************************************************
+ * GetOutBuffer:
+ *****************************************************************************/
+static int GetOutBuffer ( decoder_t *p_dec, uint8_t **pp_out_buffer )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+    int i_ret;
 
-        /* Creating the audio input if not created yet. */
-        if( p_dec->p_aout_input == NULL )
-        {
-            p_dec->output_format.i_rate = i_rate;
-            p_dec->output_format.i_original_channels = i_original_channels;
-            p_dec->output_format.i_physical_channels
-                       = i_original_channels & AOUT_CHAN_PHYSMASK;
-            p_dec->output_format.i_bytes_per_frame = i_frame_size;
-            p_dec->output_format.i_frame_length = A52_FRAME_NB;
-            aout_DateInit( &end_date, i_rate );
-            aout_DateSet( &end_date, pts );
-            p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo,
-                                               &p_dec->p_aout,
-                                               &p_dec->output_format );
-
-            if ( p_dec->p_aout_input == NULL )
-            {
-                p_dec->p_fifo->b_error = 1;
-                break;
-            }
-        }
+    if( p_sys->b_packetizer )
+    {
+        i_ret= GetSoutBuffer( p_dec, &p_sys->p_sout_buffer );
+        *pp_out_buffer =
+            p_sys->p_sout_buffer ? p_sys->p_sout_buffer->p_buffer : NULL;
+    }
+    else
+    {
+        i_ret = GetAoutBuffer( p_dec, &p_sys->p_aout_buffer );
+        *pp_out_buffer =
+            p_sys->p_aout_buffer ? p_sys->p_aout_buffer->p_buffer : NULL;
+    }
 
-        if ( !aout_DateGet( &end_date ) )
-        {
-            byte_t p_junk[3840];
+    return i_ret;
+}
 
-            /* We've just started the stream, wait for the first PTS. */
-            GetChunk( &p_dec->bit_stream, p_junk, i_frame_size - 7 );
-            continue;
-        }
+/*****************************************************************************
+ * GetAoutBuffer:
+ *****************************************************************************/
+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;
 
-        p_buffer = aout_DecNewBuffer( p_dec->p_aout, p_dec->p_aout_input,
-                                      A52_FRAME_NB );
-        if ( p_buffer == NULL )
+    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
+        || (int)p_sys->aout_format.i_bytes_per_frame != p_sys->i_frame_size ) )
+    {
+        /* Parameters changed - this should not happen. */
+        aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
+        p_sys->p_aout_input = NULL;
+    }
+
+    /* 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_physical_channels
+            = 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_DateSet( &p_sys->end_date, p_sys->pts );
+        p_sys->p_aout_input = aout_DecNew( p_dec,
+                                           &p_sys->p_aout,
+                                           &p_sys->aout_format );
+
+        if ( p_sys->p_aout_input == NULL )
         {
-            p_dec->p_fifo->b_error = 1;
-            break;
+            *pp_buffer = NULL;
+            return VLC_SUCCESS;
         }
-        p_buffer->start_date = aout_DateGet( &end_date );
-        p_buffer->end_date = aout_DateIncrement( &end_date,
-                                                 A52_FRAME_NB );
-
-        /* Get the whole frame. */
-        memcpy( p_buffer->p_buffer, p_header, 7 );
-        GetChunk( &p_dec->bit_stream, p_buffer->p_buffer + 7,
-                  i_frame_size - 7 );
-        if( p_dec->p_fifo->b_die )
+    }
+
+    if( !aout_DateGet( &p_sys->end_date ) )
+    {
+        /* We've just started the stream, wait for the first PTS. */
+        *pp_buffer = NULL;
+        return VLC_SUCCESS;
+    }
+
+    *pp_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
+                                    A52_FRAME_NB );
+    if( *pp_buffer == NULL )
+    {
+        return VLC_SUCCESS;
+    }
+
+    (*pp_buffer)->start_date = aout_DateGet( &p_sys->end_date );
+    (*pp_buffer)->end_date =
+         aout_DateIncrement( &p_sys->end_date, A52_FRAME_NB );
+
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * GetSoutBuffer:
+ *****************************************************************************/
+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 ) )
+    {
+        /* 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_block_align = 0;
+        p_sys->sout_format.i_bitrate     = 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_DateSet( &p_sys->end_date, p_sys->pts );
+
+        p_sys->p_sout_input = sout_InputNew( p_dec,
+                                             &p_sys->sout_format );
+
+        if( p_sys->p_sout_input == NULL )
         {
-            aout_DecDeleteBuffer( p_dec->p_aout, p_dec->p_aout_input,
-                                  p_buffer );
-            break;
+            msg_Err( p_dec, "cannot add a new stream" );
+            *pp_buffer = NULL;
+            return VLC_EGENERIC;
         }
+        msg_Info( p_dec, "A/52 channels:%d samplerate:%d bitrate:%d",
+                  i_channels, i_rate, i_bit_rate );
+    }
 
-        /* Send the buffer to the aout core. */
-        aout_DecPlay( p_dec->p_aout, p_dec->p_aout_input, p_buffer );
+    if( !aout_DateGet( &p_sys->end_date ) )
+    {
+        /* We've just started the stream, wait for the first PTS. */
+        *pp_buffer = NULL;
+        return VLC_SUCCESS;
     }
 
-    if( p_dec->p_fifo->b_error )
+    *pp_buffer = sout_BufferNew( p_sys->p_sout_input->p_sout,
+                                 p_sys->i_frame_size );
+    if( *pp_buffer == NULL )
     {
-        DecoderError( p_dec->p_fifo );
+        return VLC_SUCCESS;
     }
 
-    EndThread( p_dec );
+    (*pp_buffer)->i_pts =
+        (*pp_buffer)->i_dts = aout_DateGet( &p_sys->end_date );
+
+    (*pp_buffer)->i_length =
+        aout_DateIncrement( &p_sys->end_date, A52_FRAME_NB )
+        - (*pp_buffer)->i_pts;
 
-    return 0;
+    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
- * EndThread : thread destruction
+ * SendOutBuffer:
  *****************************************************************************/
-static void EndThread( dec_thread_t * p_dec )
+static int SendOutBuffer( decoder_t *p_dec )
 {
-    if ( p_dec->p_aout_input != NULL )
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    if( p_sys->b_packetizer )
+    {
+        sout_InputSendBuffer( p_sys->p_sout_input, p_sys->p_sout_buffer );
+        p_sys->p_sout_buffer = NULL;
+    }
+    else
     {
-        aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
+        /* We have all we need, send the buffer to the aout core. */
+        aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input,
+                      p_sys->p_aout_buffer );
+        p_sys->p_aout_buffer = NULL;
     }
 
-    CloseBitstream( &p_dec->bit_stream );
-    free( p_dec );
+    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
@@ -275,7 +549,8 @@ static void EndThread( dec_thread_t * p_dec )
  * since we don't want to oblige S/PDIF people to use liba52 just to get
  * their SyncInfo...
  *****************************************************************************/
-static int SyncInfo( const byte_t * p_buf, int * pi_channels,
+static int SyncInfo( const byte_t * p_buf,
+                     int * pi_channels, int * pi_channels_conf,
                      int * pi_sample_rate, int * pi_bit_rate )
 {
     static const uint8_t halfrate[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3 };
@@ -301,52 +576,67 @@ static int SyncInfo( const byte_t * p_buf, int * pi_channels,
     if ( (p_buf[6] & 0xf8) == 0x50 )
     {
         /* Dolby surround = stereo + Dolby */
-        *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
-                        | AOUT_CHAN_DOLBYSTEREO;
+        *pi_channels = 2;
+        *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
+                            | AOUT_CHAN_DOLBYSTEREO;
     }
     else switch ( acmod )
     {
     case 0x0:
         /* Dual-mono = stereo + dual-mono */
-        *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
-                        | AOUT_CHAN_DUALMONO;
+        *pi_channels = 2;
+        *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
+                            | AOUT_CHAN_DUALMONO;
         break;
     case 0x1:
         /* Mono */
-        *pi_channels = AOUT_CHAN_CENTER;
+        *pi_channels = 1;
+        *pi_channels_conf = AOUT_CHAN_CENTER;
         break;
     case 0x2:
         /* Stereo */
-        *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
+        *pi_channels = 2;
+        *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
         break;
     case 0x3:
         /* 3F */
-        *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER;
+        *pi_channels = 3;
+        *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
+                            | AOUT_CHAN_CENTER;
         break;
     case 0x4:
         /* 2F1R */
-        *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARCENTER;
+        *pi_channels = 3;
+        *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
+                            | AOUT_CHAN_REARCENTER;
         break;
     case 0x5:
         /* 3F1R */
-        *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
-                        | AOUT_CHAN_REARCENTER;
+        *pi_channels = 4;
+        *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
+                            | AOUT_CHAN_REARCENTER;
         break;
     case 0x6:
         /* 2F2R */
-        *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
-                        | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
+        *pi_channels = 4;
+        *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
+                            | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
         break;
     case 0x7:
         /* 3F2R */
-        *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
-                        | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
+        *pi_channels = 5;
+        *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
+                            | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
         break;
     default:
         return 0;
     }
 
-    if ( p_buf[6] & lfeon[acmod] ) *pi_channels |= AOUT_CHAN_LFE;
+    if ( p_buf[6] & lfeon[acmod] )
+    {
+        (*pi_channels)++;
+        *pi_channels_conf |= AOUT_CHAN_LFE;
+    }
 
     frmsizecod = p_buf[4] & 63;
     if (frmsizecod >= 38)
@@ -368,4 +658,3 @@ static int SyncInfo( const byte_t * p_buf, int * pi_channels,
         return 0;
     }
 }
-
index 16e092b089c644eab205842d1464487002d1b06e..b3aed5bdc858320693219711efa20f961976d6ba 100644 (file)
@@ -2,7 +2,7 @@
  * adpcm.c : adpcm variant audio decoder
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: adpcm.c,v 1.12 2003/08/17 23:02:51 fenrir Exp $
+ * $Id: adpcm.c,v 1.13 2003/09/02 20:19:25 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -151,9 +151,9 @@ static int i_adaptation_coeff2[7] =
  *****************************************************************************/
 static int OpenDecoder( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
 
-    switch( p_fifo->i_fourcc )
+    switch( p_dec->p_fifo->i_fourcc )
     {
         case VLC_FOURCC('i','m','a', '4'): /* IMA ADPCM */
         case VLC_FOURCC('m','s',0x00,0x02): /* MS ADPCM */
@@ -161,13 +161,12 @@ static int OpenDecoder( vlc_object_t *p_this )
         case VLC_FOURCC('m','s',0x00,0x61): /* Duck DK4 ADPCM */
         case VLC_FOURCC('m','s',0x00,0x62): /* Duck DK3 ADPCM */
 
-            p_fifo->pf_run = RunDecoder;
+            p_dec->pf_run = RunDecoder;
             return VLC_SUCCESS;
 
         default:
             return VLC_EGENERIC;
     }
-
 }
 
 /*****************************************************************************
@@ -874,5 +873,3 @@ static void DecodeAdpcmDk3( adec_thread_t *p_adec,
     }
 
 }
-
-
index d6a3d7227e05e01543cce4977bd07b1341c7c0ff..4695178629e78561627ed1e2eea5162afc86e306 100644 (file)
@@ -2,7 +2,7 @@
  * araw.c: Pseudo audio decoder; for raw pcm data
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: araw.c,v 1.16 2003/08/17 23:02:51 fenrir Exp $
+ * $Id: araw.c,v 1.17 2003/09/02 20:19:25 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -80,9 +80,9 @@ vlc_module_end();
  *****************************************************************************/
 static int OpenDecoder( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
 
-    switch( p_fifo->i_fourcc )
+    switch( p_dec->p_fifo->i_fourcc )
     {
         case VLC_FOURCC('a','r','a','w'): /* from wav/avi/asf file */
         case VLC_FOURCC('t','w','o','s'): /* _signed_ big endian samples (mov)*/
@@ -90,13 +90,12 @@ static int OpenDecoder( vlc_object_t *p_this )
 
         case VLC_FOURCC('a','l','a','w'):
         case VLC_FOURCC('u','l','a','w'):
-            p_fifo->pf_run = RunDecoder;
+            p_dec->pf_run = RunDecoder;
             return VLC_SUCCESS;
 
         default:
             return VLC_EGENERIC;
     }
-
 }
 
 static int pi_channels_maps[6] =
index 6fb5a8cc4ff8803606ec8acddbe962398e42470b..4ae778102ad8fd443112e584dfc13e19251d9308 100644 (file)
@@ -2,7 +2,7 @@
  * cinepak.c: cinepak video decoder 
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: cinepak.c,v 1.11 2003/08/17 23:02:51 fenrir Exp $
+ * $Id: cinepak.c,v 1.12 2003/09/02 20:19:25 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -70,13 +70,13 @@ vlc_module_end();
  *****************************************************************************/
 static int OpenDecoder( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
     
-    switch( p_fifo->i_fourcc )
+    switch( p_dec->p_fifo->i_fourcc )
     {
         case VLC_FOURCC('c','v','i','d'):
         case VLC_FOURCC('C','V','I','D'):
-            p_fifo->pf_run = RunDecoder;
+            p_dec->pf_run = RunDecoder;
             return VLC_SUCCESS;
     }
 
@@ -834,5 +834,3 @@ static void EndThread( videodec_thread_t *p_vdec )
 
     free( p_vdec );
 }
-
-
index 9c54c32230a570645ddcea8894109b33265ab8dd..84e41ed2e204708e96a5cecece455d86838b1b72 100644 (file)
@@ -2,9 +2,10 @@
  * dts.c: DTS basic parser
  *****************************************************************************
  * Copyright (C) 2003 VideoLAN
- * $Id: dts.c,v 1.3 2003/03/18 00:25:27 jlj Exp $
+ * $Id: dts.c,v 1.4 2003/09/02 20:19:25 gbazin Exp $
  *
  * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
+ *          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
 
 #include <vlc/vlc.h>
 #include <vlc/decoder.h>
+#include <vlc/input.h>
 #include <vlc/aout.h>
+#include <vlc/sout.h>
 
 #ifdef HAVE_UNISTD_H
 #   include <unistd.h>
 #endif
 
+#define DTS_HEADER_SIZE 10
+
 /*****************************************************************************
- * dec_thread_t : decoder thread descriptor
+ * decoder_sys_t : decoder descriptor
  *****************************************************************************/
-typedef struct dec_thread_t
+struct decoder_sys_t
 {
+    /* Module mode */
+    vlc_bool_t b_packetizer;
+
     /*
-     * Thread properties
+     * Input properties
      */
-    vlc_thread_t        thread_id;                /* id for thread functions */
+    int     i_state;
+
+    uint8_t p_header[DTS_HEADER_SIZE];
+    int     i_header;
+
+    mtime_t pts;
+
+    int     i_frame_size;
 
     /*
-     * Input properties
+     * Decoder output properties
      */
-    decoder_fifo_t *    p_fifo;                /* stores the PES stream data */
-    bit_stream_t        bit_stream;
+    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 */
+    /* This is very hacky. For DTS over S/PDIF we apparently need to send
+     * 3 frames at a time. This should likely be moved to the output stage. */
+    int                   i_frames_in_buf;
 
     /*
-     * Output properties
+     * Packetizer output properties
      */
-    aout_instance_t *   p_aout; /* opaque */
-    aout_input_t *      p_aout_input; /* opaque */
-    audio_sample_format_t output_format;
-} dec_thread_t;
+    sout_packetizer_input_t *p_sout_input;
+    sout_format_t           sout_format;
+    sout_buffer_t *         p_sout_buffer;            /* current sout buffer */
+
+    /*
+     * Common properties
+     */
+    uint8_t               *p_out_buffer;                    /* output buffer */
+    int                   i_out_buffer;         /* position in output buffer */
+    audio_date_t          end_date;
+};
+
+enum {
+
+    STATE_NOSYNC,
+    STATE_PARTIAL_SYNC,
+    STATE_SYNC,
+    STATE_HEADER,
+    STATE_DATA
+};
 
 /****************************************************************************
  * Local prototypes
  ****************************************************************************/
-static int  OpenDecoder    ( vlc_object_t * );
-static int  RunDecoder     ( decoder_fifo_t * );
+static int  OpenDecoder   ( vlc_object_t * );
+static int  OpenPacketizer( vlc_object_t * );
+
+static int  InitDecoder   ( decoder_t * );
+static int  RunDecoder    ( decoder_t *, block_t * );
+static int  EndDecoder    ( decoder_t * );
 
-static void EndThread      ( dec_thread_t * );
+static int  SyncInfo      ( const byte_t *, unsigned int *, unsigned int *,
+                            unsigned int *, unsigned int *, unsigned int * );
 
-static int  SyncInfo       ( const byte_t *, unsigned int *,
-                             unsigned int *, unsigned int *,
-                             unsigned int * );
+static int GetOutBuffer ( decoder_t *, uint8_t ** );
+static int GetAoutBuffer( decoder_t *, aout_buffer_t ** );
+static int GetSoutBuffer( decoder_t *, sout_buffer_t ** );
+static int SendOutBuffer( decoder_t * );
 
 /*****************************************************************************
  * Module descriptor
@@ -80,6 +122,11 @@ vlc_module_begin();
     set_description( _("DTS parser") );
     set_capability( "decoder", 100 );
     set_callbacks( OpenDecoder, NULL );
+
+    add_submodule();
+    set_description( _("DTS audio packetizer") );
+    set_capability( "packetizer", 10 );
+    set_callbacks( OpenPacketizer, NULL );
 vlc_module_end();
 
 /*****************************************************************************
@@ -87,214 +134,463 @@ vlc_module_end();
  *****************************************************************************/
 static int OpenDecoder( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
+
+    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('d','t','s',' ')
+         && p_dec->p_fifo->i_fourcc != VLC_FOURCC('d','t','s','b') )
+    {
+        return VLC_EGENERIC;
+    }
+
+    p_dec->pf_init = InitDecoder;
+    p_dec->pf_decode = RunDecoder;
+    p_dec->pf_end = EndDecoder;
 
-    if( p_fifo->i_fourcc != VLC_FOURCC('d','t','s',' ')
-         && p_fifo->i_fourcc != VLC_FOURCC('d','t','s','b') )
+    /* Allocate the memory needed to store the decoder's structure */
+    if( ( p_dec->p_sys =
+          (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
     {
+        msg_Err( p_dec, "out of memory" );
         return VLC_EGENERIC;
     }
+    p_dec->p_sys->b_packetizer = VLC_FALSE;
 
-    p_fifo->pf_run = RunDecoder;
     return VLC_SUCCESS;
 }
 
-/****************************************************************************
- * RunDecoder: the whole thing
- ****************************************************************************
- * This function is called just after the thread is launched.
- ****************************************************************************/
-static int RunDecoder( decoder_fifo_t *p_fifo )
+static int OpenPacketizer( vlc_object_t *p_this )
 {
-    dec_thread_t * p_dec;
-    audio_date_t end_date;
+    decoder_t *p_dec = (decoder_t*)p_this;
 
-    /* Allocate the memory needed to store the thread's structure */
-    p_dec = malloc( sizeof(dec_thread_t) );
-    if( p_dec == NULL )
-    {
-        msg_Err( p_fifo, "out of memory" );
-        DecoderError( p_fifo );
-        return -1;
-    }
+    int i_ret = OpenDecoder( p_this );
 
-    /* Initialize the thread properties */
-    p_dec->p_aout = NULL;
-    p_dec->p_aout_input = NULL;
-    p_dec->p_fifo = p_fifo;
-    p_dec->output_format.i_format = VLC_FOURCC('d','t','s',' ');
+    if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE;
 
-    aout_DateSet( &end_date, 0 );
+    return i_ret;
+}
 
-    /* Init the bitstream */
-    if( InitBitstream( &p_dec->bit_stream, p_dec->p_fifo,
-                       NULL, NULL ) != VLC_SUCCESS )
-    {
-        msg_Err( p_fifo, "cannot initialize bitstream" );
-        DecoderError( p_fifo );
-        free( p_dec );
-        return -1;
-    }
+/*****************************************************************************
+ * InitDecoder: Initalize the decoder
+ *****************************************************************************/
+static int InitDecoder( decoder_t *p_dec )
+{
+    p_dec->p_sys->i_state = STATE_NOSYNC;
 
-    /* Decoder thread's main loop */
-    while( !p_dec->p_fifo->b_die && !p_dec->p_fifo->b_error )
-    {
-        int i;
-        mtime_t pts;
-        byte_t p_header[10];
+    p_dec->p_sys->p_out_buffer = NULL;
+    p_dec->p_sys->i_out_buffer = 0;
+    aout_DateSet( &p_dec->p_sys->end_date, 0 );
+
+    p_dec->p_sys->p_aout = NULL;
+    p_dec->p_sys->p_aout_input = NULL;
+    p_dec->p_sys->p_aout_buffer = NULL;
+    p_dec->p_sys->aout_format.i_format = VLC_FOURCC('d','t','s',' ');
 
-        unsigned int i_rate;
-        unsigned int i_bit_rate;
-        unsigned int i_frame_size;
-        unsigned int i_frame_length;
-        unsigned int i_original_channels;
+    p_dec->p_sys->p_sout_input = NULL;
+    p_dec->p_sys->p_sout_buffer = NULL;
+    p_dec->p_sys->sout_format.i_cat = AUDIO_ES;
+    p_dec->p_sys->sout_format.i_fourcc = VLC_FOURCC('d','t','s',' ');
+
+    return VLC_SUCCESS;
+}
 
-        aout_buffer_t * p_buffer = NULL;
+/****************************************************************************
+ * RunDecoder: the whole thing
+ ****************************************************************************
+ * This function is called just after the thread is launched.
+ ****************************************************************************/
+static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+    int i, i_block_pos = 0;
+    mtime_t i_pts = p_block->i_pts;
 
-        for( i = 0; i < 3; i++ )
+    while( i_block_pos < p_block->i_buffer )
+    {
+        switch( p_sys->i_state )
         {
-            RealignBits( &p_dec->bit_stream );
-            while( (ShowBits( &p_dec->bit_stream, 32 ) ) != 0x7ffe8001 &&
-                   (!p_dec->p_fifo->b_die) && (!p_dec->p_fifo->b_error) )
+        case STATE_NOSYNC:
+            /* Look for sync dword - should be 0x7ffe8001 */
+            while( i_block_pos < p_block->i_buffer &&
+                   p_block->p_buffer[i_block_pos] != 0x7f )
             {
-                RemoveBits( &p_dec->bit_stream, 8 );
+                i_block_pos++;
             }
-            if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error ) break;
 
-            if( i == 0 )
+            if( i_block_pos < p_block->i_buffer )
             {
-                /* Set the Presentation Time Stamp */
-                NextPTS( &p_dec->bit_stream, &pts, NULL );
-                if( pts != 0 && pts != aout_DateGet( &end_date ) )
-                {
-                    aout_DateSet( &end_date, pts );
-                }
+                p_sys->i_state = STATE_PARTIAL_SYNC;
+                i_block_pos++;
+                p_sys->p_header[0] = 0x7f;
+                p_sys->i_header = 1;
+                break;
             }
+            break;
 
-            /* Get DTS frame header */
-            GetChunk( &p_dec->bit_stream, p_header, 10 );
-            if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error ) break;
-
-            i_frame_size = SyncInfo( p_header, &i_original_channels, &i_rate,
-                                               &i_bit_rate, &i_frame_length );
-            if( !i_frame_size )
+        case STATE_PARTIAL_SYNC:
+            /* Get the full 4 sync bytes */
+            if( p_sys->i_header < 4 )
             {
-                msg_Warn( p_dec->p_fifo, "dts_syncinfo failed" );
-                i--; continue;
+                int i_size = __MIN( 4 - 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;
             }
 
-            if( i == 0 )
+            if( p_sys->i_header < 4 )
+                break;
+
+            if( p_sys->p_header[0] == 0x7f && p_sys->p_header[1] == 0xfe &&
+                p_sys->p_header[2] == 0x80 && p_sys->p_header[3] == 0x01 )
             {
-                if( (p_dec->p_aout_input != NULL) &&
-                    ( (p_dec->output_format.i_rate != i_rate)
-                        || (p_dec->output_format.i_original_channels
-                            != i_original_channels)
-                        || (p_dec->output_format.i_bytes_per_frame 
-                            != i_frame_size * 3) ) )
+                p_sys->i_state = STATE_SYNC;
+            }
+            else
+            {
+                for( i = 1; i < 4; i++ )
                 {
-                    /* Parameters changed - this should not happen. */
-                    aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
-                    p_dec->p_aout_input = NULL;
+                    if( p_sys->p_header[i] == 0x7f ) break;
                 }
 
-                /* Creating the audio input if not created yet. */
-                if( p_dec->p_aout_input == NULL )
+                if( p_sys->p_header[i] == 0x7f )
                 {
-                    p_dec->output_format.i_rate = i_rate;
-                    p_dec->output_format.i_original_channels 
-                                = i_original_channels;
-                    p_dec->output_format.i_physical_channels
-                                = i_original_channels & AOUT_CHAN_PHYSMASK;
-                    p_dec->output_format.i_bytes_per_frame = i_frame_size * 3;
-                    p_dec->output_format.i_frame_length = i_frame_length * 3;
-                    aout_DateInit( &end_date, i_rate );
-                    p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo,
-                                                       &p_dec->p_aout,
-                                                       &p_dec->output_format );
-
-                    if( p_dec->p_aout_input == NULL )
-                    {
-                        p_dec->p_fifo->b_error = 1;
-                        break;
-                    }
+                    /* Potential new sync */
+                    p_sys->i_header -= i;
+                    memmove( p_sys->p_header, &p_sys->p_header[i],
+                             p_sys->i_header );
+                    break;
                 }
+
+                /* retry to sync*/
+                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;
+            if( p_sys->pts != 0 &&
+                p_sys->pts != aout_DateGet( &p_sys->end_date ) )
+            {
+                aout_DateSet( &p_sys->end_date, p_sys->pts );
             }
+            p_sys->i_state = STATE_HEADER;
+            break;
 
-            if( !aout_DateGet( &end_date ) )
+        case STATE_HEADER:
+            /* Get DTS frame header (DTS_HEADER_SIZE bytes) */
+            if( p_sys->i_header < DTS_HEADER_SIZE )
             {
-                byte_t p_junk[ i_frame_size ];
+                int i_size = __MIN( DTS_HEADER_SIZE - p_sys->i_header,
+                                    p_block->i_buffer - i_block_pos );
 
-                /* We've just started the stream, wait for the first PTS. */
-                GetChunk( &p_dec->bit_stream, p_junk, i_frame_size - 10 );
-                i--; continue;
+                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( i == 0 )
+            if( p_sys->i_header < DTS_HEADER_SIZE )
+                break;
+
+            if( GetOutBuffer( p_dec, &p_sys->p_out_buffer )
+                != VLC_SUCCESS )
             {
-                p_buffer = aout_DecNewBuffer( p_dec->p_aout, 
-                                              p_dec->p_aout_input,
-                                              i_frame_length * 3 );
-                if( p_buffer == NULL )
-                {
-                    p_dec->p_fifo->b_error = 1;
-                    break;
-                }
-                p_buffer->start_date = aout_DateGet( &end_date );
-                p_buffer->end_date = aout_DateIncrement( &end_date,
-                                                         i_frame_length * 3 );
+                block_Release( p_block );
+                return VLC_EGENERIC;
             }
 
-            /* Get the whole frame. */
-            memcpy( p_buffer->p_buffer + (i * i_frame_size), p_header, 10 );
-            GetChunk( &p_dec->bit_stream, 
-                      p_buffer->p_buffer + (i * i_frame_size) + 10,
-                      i_frame_size - 10 );
-            if( p_dec->p_fifo->b_die ) break;
-        }
+            if( !p_sys->p_out_buffer )
+            {
+                p_sys->i_state = STATE_NOSYNC;
+                break;
+            }
 
-        if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error )
-        {
-            if( p_buffer != NULL )
+            memcpy( p_sys->p_out_buffer, p_sys->p_header, DTS_HEADER_SIZE );
+            p_sys->i_out_buffer = DTS_HEADER_SIZE;
+            p_sys->i_state = STATE_DATA;
+            break;
+
+        case STATE_DATA:
+            /* Copy the whole DTS frame into the aout buffer */
+            if( p_sys->i_out_buffer < p_sys->i_frame_size )
             {
-                aout_DecDeleteBuffer( p_dec->p_aout, p_dec->p_aout_input,
-                                      p_buffer );
+                int i_size = __MIN( p_sys->i_frame_size - p_sys->i_out_buffer,
+                                    p_block->i_buffer - i_block_pos );
+
+                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_sys->i_out_buffer < p_sys->i_frame_size )
+                break; /* Need more data */
+
+            SendOutBuffer( p_dec );
+
+            p_sys->i_state = STATE_NOSYNC;
             break;
         }
+    }
+
+    block_Release( p_block );
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * EndDecoder: clean up the decoder
+ *****************************************************************************/
+static int EndDecoder( decoder_t *p_dec )
+{
+    if( p_dec->p_sys->p_aout_input != NULL )
+    {
+        if( p_dec->p_sys->p_aout_buffer )
+        {
+            aout_DecDeleteBuffer( p_dec->p_sys->p_aout,
+                                  p_dec->p_sys->p_aout_input,
+                                  p_dec->p_sys->p_aout_buffer );
+        }
+
+        aout_DecDelete( p_dec->p_sys->p_aout, p_dec->p_sys->p_aout_input );
+    }
+
+    if( p_dec->p_sys->p_sout_input != NULL )
+    {
+        if( p_dec->p_sys->p_sout_buffer )
+        {
+            sout_BufferDelete( p_dec->p_sys->p_sout_input->p_sout,
+                               p_dec->p_sys->p_sout_buffer );
+        }
+
+        sout_InputDelete( p_dec->p_sys->p_sout_input );
+    }
+
+    free( p_dec->p_sys );
+
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * GetOutBuffer:
+ *****************************************************************************/
+static int GetOutBuffer ( decoder_t *p_dec, uint8_t **pp_out_buffer )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+    int i_ret;
+
+    if( p_sys->b_packetizer )
+    {
+        i_ret= GetSoutBuffer( p_dec, &p_sys->p_sout_buffer );
+        *pp_out_buffer =
+            p_sys->p_sout_buffer ? p_sys->p_sout_buffer->p_buffer : NULL;
+    }
+    else
+    {
+        i_ret = GetAoutBuffer( p_dec, &p_sys->p_aout_buffer );
+        if( p_sys->i_frames_in_buf == 1 )
+            *pp_out_buffer = p_sys->p_aout_buffer ?
+                p_sys->p_aout_buffer->p_buffer : NULL;
+       else
+            *pp_out_buffer = p_sys->p_aout_buffer ?
+                p_sys->p_aout_buffer->p_buffer + p_sys->i_frame_size *
+                (p_sys->i_frames_in_buf - 1) : NULL;
+    }
+
+    return i_ret;
+}
+
+/*****************************************************************************
+ * GetAoutBuffer:
+ *****************************************************************************/
+static int GetAoutBuffer( decoder_t *p_dec, aout_buffer_t **pp_buffer )
+{
+    int i_bit_rate;
+    unsigned int i_frame_length, 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, &i_frame_length );
+
+    if( !p_sys->i_frame_size )
+    {
+        msg_Warn( p_dec, "dts 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 ) )
+    {
+        /* Parameters changed - this should not happen. */
+        aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
+        p_sys->p_aout_input = NULL;
+    }
+
+    /* 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_physical_channels
+            = 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 = i_frame_length;
+        aout_DateInit( &p_sys->end_date, i_rate );
+        aout_DateSet( &p_sys->end_date, p_sys->pts );
+        p_sys->i_frames_in_buf = 3;
+        p_sys->p_aout_input = aout_DecNew( p_dec,
+                                           &p_sys->p_aout,
+                                           &p_sys->aout_format );
+
+        if ( p_sys->p_aout_input == NULL )
+        {
+            *pp_buffer = NULL;
+            return VLC_SUCCESS;
+        }
+    }
 
-        /* Send the buffer to the aout core. */
-        aout_DecPlay( p_dec->p_aout, p_dec->p_aout_input, p_buffer );
+    if( !aout_DateGet( &p_sys->end_date ) )
+    {
+        /* We've just started the stream, wait for the first PTS. */
+        *pp_buffer = NULL;
+        return VLC_SUCCESS;
     }
 
-    if( p_dec->p_fifo->b_error )
+    if( p_sys->i_frames_in_buf == 3 )
     {
-        DecoderError( p_dec->p_fifo );
+        p_sys->i_frames_in_buf = 0;
+        *pp_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
+                                        i_frame_length * 3 );
+        if( *pp_buffer == NULL )
+        {
+            return VLC_SUCCESS;
+        }
+
+        (*pp_buffer)->start_date = aout_DateGet( &p_sys->end_date );
+        (*pp_buffer)->end_date =
+             aout_DateIncrement( &p_sys->end_date, i_frame_length * 3 );
     }
 
-    EndThread( p_dec );
+    p_sys->i_frames_in_buf++;
 
-    return 0;
+    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
- * EndThread : thread destruction
+ * GetSoutBuffer:
  *****************************************************************************/
-static void EndThread( dec_thread_t * p_dec )
+static int GetSoutBuffer( decoder_t *p_dec, sout_buffer_t **pp_buffer )
 {
-    if ( p_dec->p_aout_input != NULL )
+    int i_bit_rate;
+    unsigned int i_frame_length, 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, &i_frame_length );
+
+    if( !p_sys->i_frame_size )
     {
-        aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
+        msg_Warn( p_dec, "dts syncinfo failed" );
+        *pp_buffer = NULL;
+        return VLC_SUCCESS;
     }
 
-    CloseBitstream( &p_dec->bit_stream );
-    free( p_dec );
+    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 ) )
+    {
+        /* 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_block_align = 0;
+        p_sys->sout_format.i_bitrate     = 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_DateSet( &p_sys->end_date, p_sys->pts );
+
+        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" );
+            *pp_buffer = NULL;
+            return VLC_EGENERIC;
+        }
+        msg_Info( p_dec, "DTS channels:%d samplerate:%d bitrate:%d",
+                  i_channels, i_rate, i_bit_rate );
+    }
+
+    if( !aout_DateGet( &p_sys->end_date ) )
+    {
+        /* We've just started the stream, wait for the first PTS. */
+        *pp_buffer = NULL;
+        return VLC_SUCCESS;
+    }
+
+    *pp_buffer = sout_BufferNew( p_sys->p_sout_input->p_sout,
+                                 p_sys->i_frame_size );
+    if( *pp_buffer == NULL )
+    {
+        return VLC_SUCCESS;
+    }
+
+    (*pp_buffer)->i_pts =
+        (*pp_buffer)->i_dts = aout_DateGet( &p_sys->end_date );
+
+    (*pp_buffer)->i_length =
+        aout_DateIncrement( &p_sys->end_date, i_frame_length )
+        - (*pp_buffer)->i_pts;
+
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * SendOutBuffer:
+ *****************************************************************************/
+static int SendOutBuffer( decoder_t *p_dec )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    if( p_sys->b_packetizer )
+    {
+        sout_InputSendBuffer( p_sys->p_sout_input, p_sys->p_sout_buffer );
+        p_sys->p_sout_buffer = NULL;
+    }
+    else if( p_sys->i_frames_in_buf == 3 )
+    {
+        /* We have all we need, send the buffer to the aout core. */
+        aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input,
+                      p_sys->p_aout_buffer );
+        p_sys->p_aout_buffer = NULL;
+    }
+
+    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
  * SyncInfo: parse DTS sync info
  *****************************************************************************/
-static int SyncInfo( const byte_t * p_buf, unsigned int * pi_channels,
+static int SyncInfo( const byte_t * p_buf,
+                     unsigned int * pi_channels,
+                     unsigned int * pi_channels_conf,
                      unsigned int * pi_sample_rate,
                      unsigned int * pi_bit_rate,
                      unsigned int * pi_frame_length )
@@ -340,71 +636,83 @@ static int SyncInfo( const byte_t * p_buf, unsigned int * pi_channels,
     {
         case 0x0:
             /* Mono */
-            *pi_channels = AOUT_CHAN_CENTER;
+            *pi_channels_conf = AOUT_CHAN_CENTER;
             break;
         case 0x1:
             /* Dual-mono = stereo + dual-mono */
-            *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
+            *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
                            AOUT_CHAN_DUALMONO;
             break;
         case 0x2:
         case 0x3:
         case 0x4:
             /* Stereo */
-            *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
+            *pi_channels = 2;
+            *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
             break;
         case 0x5:
             /* 3F */
-            *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER;
+            *pi_channels = 3;
+            *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
+                                AOUT_CHAN_CENTER;
             break;
         case 0x6:
             /* 2F/LFE */
-            *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_LFE;
+            *pi_channels = 3;
+            *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
+                                AOUT_CHAN_LFE;
             break;
         case 0x7:
             /* 3F/LFE */
-            *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
-                           AOUT_CHAN_CENTER | AOUT_CHAN_LFE;
+            *pi_channels = 4;
+            *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
+                                AOUT_CHAN_CENTER | AOUT_CHAN_LFE;
             break;
         case 0x8:
             /* 2F2R */
-            *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
-                           AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
+            *pi_channels = 4;
+            *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
+                                AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
             break;
         case 0x9:
             /* 3F2R */
-            *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
-                           AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |
-                           AOUT_CHAN_REARRIGHT;
+            *pi_channels = 5;
+            *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
+                                AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |
+                                AOUT_CHAN_REARRIGHT;
             break;
         case 0xA:
         case 0xB:
             /* 2F2M2R */
-            *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
-                           AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
-                           AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
+            *pi_channels = 6;
+            *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
+                                AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
+                                AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
             break;
         case 0xC:
             /* 3F2M2R */
-            *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
-                           AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
-                           AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
-                           AOUT_CHAN_REARRIGHT;
+            *pi_channels = 7;
+            *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
+                                AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
+                                AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
+                                AOUT_CHAN_REARRIGHT;
             break;
         case 0xD:
         case 0xE:
             /* 3F2M2R/LFE */
-            *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
-                           AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
-                           AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
-                           AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE;
+            *pi_channels = 8;
+            *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
+                                AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
+                                AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
+                                AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE;
             break;
 
         default:
             if( i_audio_mode <= 63 )
             {
                 /* User defined */
-                *pi_channels = 0; 
+                *pi_channels = 0;
+                *pi_channels_conf = 0; 
             }
             else
             {
index 298dc03909e848d404db4aac7b00422847a5c283..d84b1a7bb99943fb091f39cc20afa6eee7447216 100644 (file)
@@ -2,7 +2,7 @@
  * dv.c: a decoder for DV video
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: dv.c,v 1.4 2003/01/28 16:57:28 sam Exp $
+ * $Id: dv.c,v 1.5 2003/09/02 20:19:25 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -57,14 +57,14 @@ vlc_module_end();
  *****************************************************************************/
 static int OpenDecoder ( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
 
-    if( p_fifo->i_fourcc != VLC_FOURCC('d','v','s','d') )
+    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('d','v','s','d') )
     {
         return VLC_EGENERIC;
     }
 
-    p_fifo->pf_run = RunDecoder;
+    p_dec->pf_run = RunDecoder;
     return VLC_SUCCESS;
 }
 
index d43a833e73f1828bf0f3e498f9897f0615057a7c..1d2e134196425e50efefca2b27b623c0e7e71396 100644 (file)
@@ -2,7 +2,7 @@
  * decoder.c: AAC decoder using libfaad2
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: decoder.c,v 1.29 2003/08/24 23:22:02 gbazin Exp $
+ * $Id: decoder.c,v 1.30 2003/09/02 20:19:25 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -65,14 +65,14 @@ vlc_module_end();
  *****************************************************************************/
 static int OpenDecoder( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
 
-    if( p_fifo->i_fourcc != VLC_FOURCC('m','p','4','a') )
+    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('m','p','4','a') )
     {
         return VLC_EGENERIC;
     }
 
-    p_fifo->pf_run = RunDecoder;
+    p_dec->pf_run = RunDecoder;
     return VLC_SUCCESS;
 }
 
@@ -480,4 +480,3 @@ static void EndThread (adec_thread_t *p_adec)
 
     free( p_adec );
 }
-
index 2e8702d2b2cc15c4af04ec9243fa6ba65493455b..db67bf8199edeba5dd6708221e5454bc04dacf05 100644 (file)
@@ -2,7 +2,7 @@
  * ffmpeg.c: video decoder using ffmpeg library
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: ffmpeg.c,v 1.48 2003/08/15 13:16:38 fenrir Exp $
+ * $Id: ffmpeg.c,v 1.49 2003/09/02 20:19:25 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -189,15 +189,16 @@ vlc_module_end();
  *****************************************************************************/
 static int OpenDecoder( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*) p_this;
 
-    if( ffmpeg_GetFfmpegCodec( p_fifo->i_fourcc, NULL, NULL, NULL ) )
+    if( !ffmpeg_GetFfmpegCodec( p_dec->p_fifo->i_fourcc, NULL, NULL, NULL ) )
     {
-        p_fifo->pf_run = RunDecoder;
-        return VLC_SUCCESS;
+        return VLC_EGENERIC;
     }
 
-    return VLC_EGENERIC;
+    p_dec->pf_run = RunDecoder;
+
+    return VLC_SUCCESS;
 }
 
 typedef union decoder_thread_u
@@ -208,7 +209,6 @@ typedef union decoder_thread_u
 
 } decoder_thread_t;
 
-
 /*****************************************************************************
  * RunDecoder: this function is called just after the thread is created
  *****************************************************************************/
index 942d1832fd77cb61bb10b73c3944408d06d7f6aa..4f3c886280daaf3b394998e393b61a73f26a6881 100644 (file)
@@ -2,7 +2,7 @@
  * flac.c: flac decoder module making use of libflac
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: flacdec.c,v 1.3 2003/08/17 13:56:26 gbazin Exp $
+ * $Id: flacdec.c,v 1.4 2003/09/02 20:19:25 gbazin Exp $
  *
  * Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
  *
@@ -114,14 +114,14 @@ vlc_module_end();
  *****************************************************************************/
 static int OpenDecoder( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
 
-    if( p_fifo->i_fourcc != VLC_FOURCC('f','l','a','c') )
+    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('f','l','a','c') )
     {
         return VLC_EGENERIC;
     }
 
-    p_fifo->pf_run = RunDecoder;
+    p_dec->pf_run = RunDecoder;
     return VLC_SUCCESS;
 }
 
index 6711989d63ebf03b665d37566066c394b62fb482..ac72e02bab736116b9ce8b9114b49c28b275412b 100755 (executable)
@@ -2,9 +2,10 @@
  * libmpeg2.c: mpeg2 video decoder module making use of libmpeg2.
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: libmpeg2.c,v 1.25 2003/08/18 13:16:43 zorglub Exp $
+ * $Id: libmpeg2.c,v 1.26 2003/09/02 20:19:25 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
+ *          Christophe Massiot <massiot@via.ecp.fr>
  *
  * 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
@@ -43,9 +44,9 @@
 #define AR_221_1_PICTURE        4                  /* 2.21:1 picture (movie) */
 
 /*****************************************************************************
- * dec_thread_t : libmpeg2 decoder thread descriptor
+ * decoder_sys_t : libmpeg2 decoder descriptor
  *****************************************************************************/
-typedef struct dec_thread_t
+struct decoder_sys_t
 {
     /*
      * libmpeg2 properties
@@ -57,7 +58,6 @@ typedef struct dec_thread_t
     /*
      * Input properties
      */
-    decoder_fifo_t   *p_fifo;                  /* stores the PES stream data */
     pes_packet_t     *p_pes;                  /* current PES we are decoding */
     mtime_t          i_pts;
     mtime_t          i_previous_pts;
@@ -76,16 +76,17 @@ typedef struct dec_thread_t
     vout_thread_t *p_vout;
     vout_synchro_t *p_synchro;
 
-} dec_thread_t;
+};
 
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
 static int  OpenDecoder  ( vlc_object_t * );
-static int  RunDecoder   ( decoder_fifo_t * );
-static void CloseDecoder ( dec_thread_t * );
+static int  InitDecoder  ( decoder_t * );
+static int  RunDecoder   ( decoder_t *, block_t * );
+static int  EndDecoder   ( decoder_t * );
 
-static picture_t *GetNewPicture( dec_thread_t *, uint8_t ** );
+static picture_t *GetNewPicture( decoder_t *, uint8_t ** );
 
 /*****************************************************************************
  * Module descriptor
@@ -102,93 +103,100 @@ vlc_module_end();
  *****************************************************************************/
 static int OpenDecoder( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
 
-    if( p_fifo->i_fourcc != VLC_FOURCC('m','p','g','v') )
+    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('m','p','g','v') &&
+        p_dec->p_fifo->i_fourcc != VLC_FOURCC('m','p','g','1') &&
+        p_dec->p_fifo->i_fourcc != VLC_FOURCC('m','p','g','2') )
     {
         return VLC_EGENERIC;
     }
 
-    p_fifo->pf_run = RunDecoder;
+    p_dec->pf_init = InitDecoder;
+    p_dec->pf_decode = RunDecoder;
+    p_dec->pf_end = EndDecoder;
+
     return VLC_SUCCESS;
 }
 
 /*****************************************************************************
- * RunDecoder: the libmpeg2 decoder
+ * InitDecoder: Initalize the decoder
  *****************************************************************************/
-static int RunDecoder( decoder_fifo_t *p_fifo )
+static int InitDecoder( decoder_t *p_dec )
 {
-    dec_thread_t    *p_dec;
-    data_packet_t   *p_data = NULL;
-    mpeg2_state_t   state;
-    picture_t       *p_pic;
-    int             i_aspect;
-    int             i_pic;
-
-    /* Allocate the memory needed to store the thread's structure */
-    if( (p_dec = (dec_thread_t *)malloc (sizeof(dec_thread_t)) )
-        == NULL)
+    /* Allocate the memory needed to store the decoder's structure */
+    if( ( p_dec->p_sys =
+          (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
     {
-        msg_Err( p_fifo, "out of memory" );
-        goto error;
+        msg_Err( p_dec, "out of memory" );
+        return VLC_EGENERIC;
     }
 
     /* Initialize the thread properties */
-    memset( p_dec, 0, sizeof(dec_thread_t) );
-    p_dec->p_fifo     = p_fifo;
-    p_dec->p_pes      = NULL;
-    p_dec->p_vout     = NULL;
-    p_dec->p_mpeg2dec = NULL;
-    p_dec->p_synchro  = NULL;
-    p_dec->p_info     = NULL;
-    p_dec->i_pts      = mdate() + DEFAULT_PTS_DELAY;
-    p_dec->i_current_pts  = 0;
-    p_dec->i_previous_pts = 0;
-    p_dec->i_period_remainder = 0;
-    p_dec->p_picture_to_destroy = NULL;
-    p_dec->b_garbage_pic = 0;
-    p_dec->b_slice_i  = 0;
-    p_dec->b_skip     = 0;
+    memset( p_dec->p_sys, 0, sizeof(decoder_sys_t) );
+    p_dec->p_sys->p_pes      = NULL;
+    p_dec->p_sys->p_vout     = NULL;
+    p_dec->p_sys->p_mpeg2dec = NULL;
+    p_dec->p_sys->p_synchro  = NULL;
+    p_dec->p_sys->p_info     = NULL;
+    p_dec->p_sys->i_pts      = mdate() + DEFAULT_PTS_DELAY;
+    p_dec->p_sys->i_current_pts  = 0;
+    p_dec->p_sys->i_previous_pts = 0;
+    p_dec->p_sys->i_period_remainder = 0;
+    p_dec->p_sys->p_picture_to_destroy = NULL;
+    p_dec->p_sys->b_garbage_pic = 0;
+    p_dec->p_sys->b_slice_i  = 0;
+    p_dec->p_sys->b_skip     = 0;
 
     /* Initialize decoder */
-    p_dec->p_mpeg2dec = mpeg2_init();
-    if( p_dec->p_mpeg2dec == NULL)
-        goto error;
+    p_dec->p_sys->p_mpeg2dec = mpeg2_init();
+    if( p_dec->p_sys->p_mpeg2dec == NULL)
+    {
+        msg_Err( p_dec, "mpeg2_init() failed" );
+        free( p_dec->p_sys );
+        return VLC_EGENERIC;
+    }
 
-    p_dec->p_info = mpeg2_info( p_dec->p_mpeg2dec );
+    p_dec->p_sys->p_info = mpeg2_info( p_dec->p_sys->p_mpeg2dec );
+
+    return VLC_SUCCESS;
+}
 
-    /* libmpeg2 decoder thread's main loop */
-    while( (!p_dec->p_fifo->b_die) && (!p_dec->p_fifo->b_error) )
+/*****************************************************************************
+ * RunDecoder: the libmpeg2 decoder
+ *****************************************************************************/
+static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+{
+    decoder_sys_t   *p_sys = p_dec->p_sys;
+    mpeg2_state_t   state;
+    picture_t       *p_pic;
+    int             i_aspect;
+
+    vlc_bool_t      b_need_more_data = VLC_FALSE;
+
+    while( 1 )
     {
-        state = mpeg2_parse( p_dec->p_mpeg2dec );
+        state = mpeg2_parse( p_sys->p_mpeg2dec );
 
         switch( state )
         {
         case STATE_BUFFER:
-            /* Feed libmpeg2 a data packet at a time */
-            if( p_data == NULL )
-            {
-                /* Get the next PES */
-                if( p_dec->p_pes )
-                    input_DeletePES( p_dec->p_fifo->p_packets_mgt,
-                                     p_dec->p_pes );
-
-                input_ExtractPES( p_dec->p_fifo, &p_dec->p_pes );
-                if( !p_dec->p_pes )
+                if( !p_block->i_buffer || b_need_more_data )
                 {
-                    p_dec->p_fifo->b_error = 1;
-                    break;
+                    block_Release( p_block );
+                    return VLC_SUCCESS;
                 }
 
-                if( p_dec->p_pes->b_discontinuity && p_dec->p_synchro 
-                     && p_dec->p_info->sequence->width != (unsigned)-1 )
+#if 0
+                if( p_pes->b_discontinuity && p_sys->p_synchro 
+                     && p_sys->p_info->sequence->width != (unsigned)-1 )
                 {
-                    vout_SynchroReset( p_dec->p_synchro );
-                    if ( p_dec->p_info->current_fbuf != NULL
-                          && p_dec->p_info->current_fbuf->id != NULL )
+                    vout_SynchroReset( p_sys->p_synchro );
+                    if ( p_sys->p_info->current_fbuf != NULL
+                          && p_sys->p_info->current_fbuf->id != NULL )
                     {
-                        p_dec->b_garbage_pic = 1;
-                        p_pic = p_dec->p_info->current_fbuf->id;
+                        p_sys->b_garbage_pic = 1;
+                        p_pic = p_sys->p_info->current_fbuf->id;
                     }
                     else
                     {
@@ -196,49 +204,43 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
                         buf[0] = buf[1] = buf[2] = NULL;
                         if( (p_pic = GetNewPicture( p_dec, buf )) == NULL )
                             break;
-                        mpeg2_set_buf( p_dec->p_mpeg2dec, buf, p_pic );
+                        mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
                     }
-                    p_dec->p_picture_to_destroy = p_pic;
+                    p_sys->p_picture_to_destroy = p_pic;
 
                     memset( p_pic->p[0].p_pixels, 0,
-                            p_dec->p_info->sequence->width
-                             * p_dec->p_info->sequence->height );
+                            p_sys->p_info->sequence->width
+                             * p_sys->p_info->sequence->height );
                     memset( p_pic->p[1].p_pixels, 0x80,
-                            p_dec->p_info->sequence->width
-                             * p_dec->p_info->sequence->height / 4 );
+                            p_sys->p_info->sequence->width
+                             * p_sys->p_info->sequence->height / 4 );
                     memset( p_pic->p[2].p_pixels, 0x80,
-                            p_dec->p_info->sequence->width
-                             * p_dec->p_info->sequence->height / 4 );
+                            p_sys->p_info->sequence->width
+                             * p_sys->p_info->sequence->height / 4 );
 
-                    if ( p_dec->b_slice_i )
+                    if ( p_sys->b_slice_i )
                     {
-                        vout_SynchroNewPicture( p_dec->p_synchro,
-                            I_CODING_TYPE, 2, 0, 0, p_dec->i_current_rate );
-                        vout_SynchroDecode( p_dec->p_synchro );
-                        vout_SynchroEnd( p_dec->p_synchro, I_CODING_TYPE, 0 );
+                        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
 
-                if( p_dec->p_pes->i_pts )
-                {
-                    mpeg2_pts( p_dec->p_mpeg2dec,
-                               (uint32_t)p_dec->p_pes->i_pts );
-                    p_dec->i_previous_pts = p_dec->i_current_pts;
-                    p_dec->i_current_pts = p_dec->p_pes->i_pts;
-                }
-
-                p_dec->i_current_rate = p_dec->p_pes->i_rate;
-                p_data = p_dec->p_pes->p_first;
+            if( p_block->i_pts )
+            {
+                mpeg2_pts( p_sys->p_mpeg2dec, (uint32_t)p_block->i_pts );
+                p_sys->i_previous_pts = p_sys->i_current_pts;
+                p_sys->i_current_pts = p_block->i_pts;
             }
 
-            if( p_data != NULL )
-            {
-                mpeg2_buffer( p_dec->p_mpeg2dec,
-                              p_data->p_payload_start,
-                              p_data->p_payload_end );
+            p_sys->i_current_rate = DEFAULT_RATE;//p_pes->i_rate;
 
-                p_data = p_data->p_next;
-            }
+            mpeg2_buffer( p_sys->p_mpeg2dec, p_block->p_buffer,
+                          p_block->p_buffer + p_block->i_buffer );
+
+            b_need_more_data = VLC_TRUE;
             break;
 
         case STATE_SEQUENCE:
@@ -266,99 +268,105 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
                 case AR_SQUARE_PICTURE:
                 default:
                     i_aspect = VOUT_ASPECT_FACTOR *
-                                   p_dec->p_info->sequence->width /
-                                   p_dec->p_info->sequence->height;
+                                   p_sys->p_info->sequence->width /
+                                   p_sys->p_info->sequence->height;
                     break;
                 }
             }
             else
             {
                 /* Use the value provided in the MPEG sequence header */
-                i_aspect = ((uint64_t)p_dec->p_info->sequence->display_width) *
-                    p_dec->p_info->sequence->pixel_width * VOUT_ASPECT_FACTOR /
-                    p_dec->p_info->sequence->display_height /
-                    p_dec->p_info->sequence->pixel_height;
+                i_aspect = ((uint64_t)p_sys->p_info->sequence->display_width) *
+                    p_sys->p_info->sequence->pixel_width * VOUT_ASPECT_FACTOR /
+                    p_sys->p_info->sequence->display_height /
+                    p_sys->p_info->sequence->pixel_height;
             }
 
-            if ( p_dec->p_vout != NULL )
-            { 
+            if ( p_dec->p_sys->p_vout != NULL )
+            {
+              int i_pic;
                 /* Temporary hack to free the pictures in use by libmpeg2 */
-                for ( i_pic = 0; i_pic < p_dec->p_vout->render.i_pictures; i_pic++ )
+                for ( i_pic = 0; i_pic < p_dec->p_sys->p_vout->render.i_pictures; i_pic++ )
                 {
-                    if( p_dec->p_vout->render.pp_picture[i_pic]->i_status ==
+                    if( p_dec->p_sys->p_vout->render.pp_picture[i_pic]->i_status ==
                           RESERVED_PICTURE )
-                        vout_DestroyPicture( p_dec->p_vout,
-                                         p_dec->p_vout->render.pp_picture[i_pic] );
-                    if( p_dec->p_vout->render.pp_picture[i_pic]->i_refcount > 0 )
-                        vout_UnlinkPicture( p_dec->p_vout,
-                                         p_dec->p_vout->render.pp_picture[i_pic] );
+                        vout_DestroyPicture( p_dec->p_sys->p_vout,
+                                         p_dec->p_sys->p_vout->render.pp_picture[i_pic] );
+                    if( p_dec->p_sys->p_vout->render.pp_picture[i_pic]->i_refcount > 0 )
+                        vout_UnlinkPicture( p_dec->p_sys->p_vout,
+                                         p_dec->p_sys->p_vout->render.pp_picture[i_pic] );
                 }
             }
 
-            p_dec->p_vout = vout_Request( p_dec->p_fifo, p_dec->p_vout,
-                                          p_dec->p_info->sequence->width,
-                                          p_dec->p_info->sequence->height,
-                                          VLC_FOURCC('Y','V','1','2'), i_aspect );
-           
-            if(p_dec->p_vout == NULL )
+            p_sys->p_vout = vout_Request( p_dec, p_sys->p_vout,
+                                          p_sys->p_info->sequence->width,
+                                          p_sys->p_info->sequence->height,
+                                          VLC_FOURCC('Y','V','1','2'),
+                                          i_aspect );
+
+            if(p_sys->p_vout == NULL )
             {
-                msg_Err( p_dec->p_fifo , "cannot create vout" );
+                msg_Err( p_dec, "cannot create vout" );
+                block_Release( p_block );
                 return -1;
             } 
-             
-            msg_Dbg( p_dec->p_fifo, "%dx%d, aspect %d, %u.%03u fps",
-                     p_dec->p_info->sequence->width,
-                     p_dec->p_info->sequence->height, i_aspect,
-                     (u32)((u64)1001000000 * 27 / p_dec->p_info->sequence->frame_period / 1001),
-                     (u32)((u64)1001000000 * 27 / p_dec->p_info->sequence->frame_period % 1001) );
 
-            mpeg2_custom_fbuf( p_dec->p_mpeg2dec, 1 );
+            msg_Dbg( p_dec, "%dx%d, aspect %d, %u.%03u fps",
+                     p_sys->p_info->sequence->width,
+                     p_sys->p_info->sequence->height, i_aspect,
+                     (uint32_t)((u64)1001000000 * 27 /
+                     p_sys->p_info->sequence->frame_period / 1001),
+                     (uint32_t)((u64)1001000000 * 27 /
+                     p_sys->p_info->sequence->frame_period % 1001) );
+
+            mpeg2_custom_fbuf( p_sys->p_mpeg2dec, 1 );
 
             /* Set the first 2 reference frames */
-            mpeg2_set_buf( p_dec->p_mpeg2dec, buf, NULL );
+            mpeg2_set_buf( p_sys->p_mpeg2dec, buf, NULL );
 
             if( (p_pic = GetNewPicture( p_dec, buf )) == NULL ) break;
             memset( p_pic->p[0].p_pixels, 0,
-                    p_dec->p_info->sequence->width
-                     * p_dec->p_info->sequence->height );
+                    p_sys->p_info->sequence->width
+                     * p_sys->p_info->sequence->height );
             memset( p_pic->p[1].p_pixels, 0x80,
-                    p_dec->p_info->sequence->width
-                     * p_dec->p_info->sequence->height / 4 );
+                    p_sys->p_info->sequence->width
+                     * p_sys->p_info->sequence->height / 4 );
             memset( p_pic->p[2].p_pixels, 0x80,
-                    p_dec->p_info->sequence->width
-                     * p_dec->p_info->sequence->height / 4 );
-            mpeg2_set_buf( p_dec->p_mpeg2dec, buf, p_pic );
+                    p_sys->p_info->sequence->width
+                     * p_sys->p_info->sequence->height / 4 );
+            mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
             /* This picture will never go through display_picture. */
-            vout_DatePicture( p_dec->p_vout, p_pic, 0 );
-            vout_DisplayPicture( p_dec->p_vout, p_pic );
+            vout_DatePicture( p_sys->p_vout, p_pic, 0 );
+            vout_DisplayPicture( p_sys->p_vout, p_pic );
             /* For some reason, libmpeg2 will put this pic twice in
              * discard_picture. This can be considered a bug in libmpeg2. */
-            vout_LinkPicture( p_dec->p_vout, p_pic );
+            vout_LinkPicture( p_sys->p_vout, p_pic );
 
-            if ( p_dec->p_synchro )
+            if ( p_sys->p_synchro )
             {
-                vout_SynchroRelease( p_dec->p_synchro );
+                vout_SynchroRelease( p_sys->p_synchro );
             }
-            p_dec->p_synchro = vout_SynchroInit( p_dec->p_fifo, p_dec->p_vout,
-                (u32)((u64)1001000000 * 27 / p_dec->p_info->sequence->frame_period) );
-            p_dec->b_after_sequence_header = 1;
+            p_sys->p_synchro = vout_SynchroInit( p_dec, p_sys->p_vout,
+                (uint32_t)((uint64_t)1001000000 * 27 /
+                p_sys->p_info->sequence->frame_period) );
+            p_sys->b_after_sequence_header = 1;
         }
         break;
 
         case STATE_PICTURE_2ND:
-            vout_SynchroNewPicture( p_dec->p_synchro,
-                p_dec->p_info->current_picture->flags & PIC_MASK_CODING_TYPE,
-                p_dec->p_info->current_picture->nb_fields,
+            vout_SynchroNewPicture( p_sys->p_synchro,
+                p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE,
+                p_sys->p_info->current_picture->nb_fields,
                 0, 0,
-                p_dec->i_current_rate );
+                p_sys->i_current_rate );
 
-            if ( p_dec->b_skip )
+            if ( p_sys->b_skip )
             {
-                vout_SynchroTrash( p_dec->p_synchro );
+                vout_SynchroTrash( p_sys->p_synchro );
             }
             else
             {
-                vout_SynchroDecode( p_dec->p_synchro );
+                vout_SynchroDecode( p_sys->p_synchro );
             }
             break;
 
@@ -367,85 +375,84 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
             uint8_t *buf[3];
             buf[0] = buf[1] = buf[2] = NULL;
 
-            if ( p_dec->b_after_sequence_header
-                  && ((p_dec->p_info->current_picture->flags
+            if ( p_sys->b_after_sequence_header
+                  && ((p_sys->p_info->current_picture->flags
                         & PIC_MASK_CODING_TYPE)
                        == PIC_FLAG_CODING_TYPE_P) )
             {
                 /* Intra-slice refresh. Simulate a blank I picture. */
-                msg_Dbg( p_dec->p_fifo, "intra-slice refresh stream" );
-                vout_SynchroNewPicture( p_dec->p_synchro,
-                    I_CODING_TYPE, 2, 0, 0, p_dec->i_current_rate );
-                vout_SynchroDecode( p_dec->p_synchro );
-                vout_SynchroEnd( p_dec->p_synchro, I_CODING_TYPE, 0 );
-                p_dec->b_slice_i = 1;
+                msg_Dbg( p_dec, "intra-slice refresh stream" );
+                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 );
+                p_sys->b_slice_i = 1;
             }
-            p_dec->b_after_sequence_header = 0;
-
-            vout_SynchroNewPicture( p_dec->p_synchro,
-                p_dec->p_info->current_picture->flags & PIC_MASK_CODING_TYPE,
-                p_dec->p_info->current_picture->nb_fields,
-                (p_dec->p_info->current_picture->flags & PIC_FLAG_PTS) ?
-                    ( (p_dec->p_info->current_picture->pts ==
-                                (uint32_t)p_dec->i_current_pts) ?
-                              p_dec->i_current_pts : p_dec->i_previous_pts ) : 0,
-                0,
-                p_dec->i_current_rate );
-
-            if ( !(p_dec->b_slice_i
-                   && ((p_dec->p_info->current_picture->flags
+            p_sys->b_after_sequence_header = 0;
+
+            vout_SynchroNewPicture( p_sys->p_synchro,
+                p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE,
+                p_sys->p_info->current_picture->nb_fields,
+                (p_sys->p_info->current_picture->flags & PIC_FLAG_PTS) ?
+                    ( ( p_sys->p_info->current_picture->pts ==
+                        (uint32_t)p_sys->i_current_pts ) ?
+                      p_sys->i_current_pts : p_sys->i_previous_pts ) : 0,
+                0, p_sys->i_current_rate );
+
+            if ( !(p_sys->b_slice_i
+                   && ((p_sys->p_info->current_picture->flags
                          & PIC_MASK_CODING_TYPE) == P_CODING_TYPE))
-                   && !vout_SynchroChoose( p_dec->p_synchro,
-                              p_dec->p_info->current_picture->flags
+                   && !vout_SynchroChoose( p_sys->p_synchro,
+                              p_sys->p_info->current_picture->flags
                                 & PIC_MASK_CODING_TYPE ) )
             {
-                mpeg2_skip( p_dec->p_mpeg2dec, 1 );
-                p_dec->b_skip = 1;
-                vout_SynchroTrash( p_dec->p_synchro );
-                mpeg2_set_buf( p_dec->p_mpeg2dec, buf, NULL );
+                mpeg2_skip( p_sys->p_mpeg2dec, 1 );
+                p_sys->b_skip = 1;
+                vout_SynchroTrash( p_sys->p_synchro );
+                mpeg2_set_buf( p_sys->p_mpeg2dec, buf, NULL );
             }
             else
             {
-                mpeg2_skip( p_dec->p_mpeg2dec, 0 );
-                p_dec->b_skip = 0;
-                vout_SynchroDecode( p_dec->p_synchro );
+                mpeg2_skip( p_sys->p_mpeg2dec, 0 );
+                p_sys->b_skip = 0;
+                vout_SynchroDecode( p_sys->p_synchro );
                 if( (p_pic = GetNewPicture( p_dec, buf )) == NULL ) break;
-                mpeg2_set_buf( p_dec->p_mpeg2dec, buf, p_pic );
+                mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
             }
         }
         break;
 
         case STATE_END:
         case STATE_SLICE:
-            if( p_dec->p_info->display_fbuf
-                && p_dec->p_info->display_fbuf->id )
+            if( p_sys->p_info->display_fbuf
+                && p_sys->p_info->display_fbuf->id )
             {
-                p_pic = (picture_t *)p_dec->p_info->display_fbuf->id;
+                p_pic = (picture_t *)p_sys->p_info->display_fbuf->id;
 
-                vout_SynchroEnd( p_dec->p_synchro,
-                            p_dec->p_info->display_picture->flags
+                vout_SynchroEnd( p_sys->p_synchro,
+                            p_sys->p_info->display_picture->flags
                              & PIC_MASK_CODING_TYPE,
-                            p_dec->b_garbage_pic );
-                p_dec->b_garbage_pic = 0;
-                vout_DisplayPicture( p_dec->p_vout, p_pic );
+                            p_sys->b_garbage_pic );
+                p_sys->b_garbage_pic = 0;
+                vout_DisplayPicture( p_sys->p_vout, p_pic );
 
-                if ( p_dec->p_picture_to_destroy != p_pic )
+                if ( p_sys->p_picture_to_destroy != p_pic )
                 {
-                    vout_DatePicture( p_dec->p_vout, p_pic,
-                        vout_SynchroDate( p_dec->p_synchro ) );
+                    vout_DatePicture( p_sys->p_vout, p_pic,
+                        vout_SynchroDate( p_sys->p_synchro ) );
                 }
                 else
                 {
-                    p_dec->p_picture_to_destroy = NULL;
-                    vout_DatePicture( p_dec->p_vout, p_pic, 0 );
+                    p_sys->p_picture_to_destroy = NULL;
+                    vout_DatePicture( p_sys->p_vout, p_pic, 0 );
                 }
             }
 
-            if( p_dec->p_info->discard_fbuf &&
-                p_dec->p_info->discard_fbuf->id )
+            if( p_sys->p_info->discard_fbuf &&
+                p_sys->p_info->discard_fbuf->id )
             {
-                p_pic = (picture_t *)p_dec->p_info->discard_fbuf->id;
-                vout_UnlinkPicture( p_dec->p_vout, p_pic );
+                p_pic = (picture_t *)p_sys->p_info->discard_fbuf->id;
+                vout_UnlinkPicture( p_sys->p_vout, p_pic );
             }
             break;
 
@@ -454,46 +461,46 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
             uint8_t *buf[3];
             buf[0] = buf[1] = buf[2] = NULL;
 
-            msg_Warn( p_dec->p_fifo, "invalid picture encountered" );
-            if ( ( p_dec->p_info->current_picture == NULL ) || 
-               ( ( p_dec->p_info->current_picture->flags & PIC_MASK_CODING_TYPE)
+            msg_Warn( p_dec, "invalid picture encountered" );
+            if ( ( p_sys->p_info->current_picture == NULL ) || 
+               ( ( p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE)
                   != B_CODING_TYPE ) )
             {
-                vout_SynchroReset( p_dec->p_synchro );
+                vout_SynchroReset( p_sys->p_synchro );
             }
-            mpeg2_skip( p_dec->p_mpeg2dec, 1 );
-            p_dec->b_skip = 1;
+            mpeg2_skip( p_sys->p_mpeg2dec, 1 );
+            p_sys->b_skip = 1;
 
-            if( p_dec->p_info->current_fbuf &&
-                p_dec->p_info->current_fbuf->id )
+            if( p_sys->p_info->current_fbuf &&
+                p_sys->p_info->current_fbuf->id )
             {
-                p_dec->b_garbage_pic = 1;
-                p_pic = p_dec->p_info->current_fbuf->id;
+                p_sys->b_garbage_pic = 1;
+                p_pic = p_sys->p_info->current_fbuf->id;
             }
             else
             {
                 if( (p_pic = GetNewPicture( p_dec, buf )) == NULL )
                     break;
-                mpeg2_set_buf( p_dec->p_mpeg2dec, buf, p_pic );
+                mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
             }
-            p_dec->p_picture_to_destroy = p_pic;
+            p_sys->p_picture_to_destroy = p_pic;
 
             memset( p_pic->p[0].p_pixels, 0,
-                    p_dec->p_info->sequence->width
-                     * p_dec->p_info->sequence->height );
+                    p_sys->p_info->sequence->width
+                     * p_sys->p_info->sequence->height );
             memset( p_pic->p[1].p_pixels, 0x80,
-                    p_dec->p_info->sequence->width
-                     * p_dec->p_info->sequence->height / 4 );
+                    p_sys->p_info->sequence->width
+                     * p_sys->p_info->sequence->height / 4 );
             memset( p_pic->p[2].p_pixels, 0x80,
-                    p_dec->p_info->sequence->width
-                     * p_dec->p_info->sequence->height / 4 );
+                    p_sys->p_info->sequence->width
+                     * p_sys->p_info->sequence->height / 4 );
 
-            if ( p_dec->b_slice_i )
+            if ( p_sys->b_slice_i )
             {
-                vout_SynchroNewPicture( p_dec->p_synchro,
-                            I_CODING_TYPE, 2, 0, 0, p_dec->i_current_rate );
-                vout_SynchroDecode( p_dec->p_synchro );
-                vout_SynchroEnd( p_dec->p_synchro, I_CODING_TYPE, 0 );
+                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 );
             }
             break;
         }
@@ -503,86 +510,68 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
         }
     }
 
-    /* If b_error is set, the libmpeg2 decoder thread enters the error loop */
-    if( p_dec->p_fifo->b_error )
-    {
-        DecoderError( p_dec->p_fifo );
-    }
-
-    /* End of the libmpeg2 decoder thread */
-    CloseDecoder( p_dec );
-
-    return 0;
-
- error:
-    DecoderError( p_fifo );
-    if( p_dec )
-    {
-        if( p_dec->p_fifo )
-            p_dec->p_fifo->b_error = 1;
-
-        /* End of the libmpeg2 decoder thread */
-        CloseDecoder( p_dec );
-    }
-
-    return -1;
+    block_Release( p_block );
+    return VLC_EGENERIC;
 }
 
 /*****************************************************************************
- * CloseDecoder: libmpeg2 decoder destruction
+ * EndDecoder: libmpeg2 decoder destruction
  *****************************************************************************/
-static void CloseDecoder( dec_thread_t * p_dec )
+static int EndDecoder( decoder_t * p_dec )
 {
-    if( p_dec )
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    if( p_sys )
     {
         int i_pic;
 
-        if( p_dec->p_pes )
-            input_DeletePES( p_dec->p_fifo->p_packets_mgt, p_dec->p_pes );
-
-        if( p_dec->p_synchro )
-            vout_SynchroRelease( p_dec->p_synchro );
+        if( p_sys->p_synchro )
+            vout_SynchroRelease( p_sys->p_synchro );
 
-        if( p_dec->p_vout )
+        if( p_sys->p_vout )
         {
             /* Temporary hack to free the pictures in use by libmpeg2 */
-            for( i_pic = 0; i_pic < p_dec->p_vout->render.i_pictures; i_pic++ )
+            for( i_pic = 0; i_pic < p_sys->p_vout->render.i_pictures; i_pic++ )
             {
-                if( p_dec->p_vout->render.pp_picture[i_pic]->i_status ==
+                if( p_sys->p_vout->render.pp_picture[i_pic]->i_status ==
                       RESERVED_PICTURE )
-                    vout_DestroyPicture( p_dec->p_vout,
-                                     p_dec->p_vout->render.pp_picture[i_pic] );
-                if( p_dec->p_vout->render.pp_picture[i_pic]->i_refcount > 0 )
-                    vout_UnlinkPicture( p_dec->p_vout,
-                                     p_dec->p_vout->render.pp_picture[i_pic] );
+                    vout_DestroyPicture( p_sys->p_vout,
+                                     p_sys->p_vout->render.pp_picture[i_pic] );
+                if( p_sys->p_vout->render.pp_picture[i_pic]->i_refcount > 0 )
+                    vout_UnlinkPicture( p_sys->p_vout,
+                                     p_sys->p_vout->render.pp_picture[i_pic] );
             }
 
-            vout_Request( p_dec->p_fifo, p_dec->p_vout, 0, 0, 0, 0 );
+            vout_Request( p_dec, p_sys->p_vout, 0, 0, 0, 0 );
         }
 
-        if( p_dec->p_mpeg2dec ) mpeg2_close( p_dec->p_mpeg2dec );
+        if( p_sys->p_mpeg2dec ) mpeg2_close( p_sys->p_mpeg2dec );
 
-        free( p_dec );
+        free( p_sys );
     }
+
+    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
  * GetNewPicture: Get a new picture from the vout and set the buf struct
  *****************************************************************************/
-static picture_t *GetNewPicture( dec_thread_t *p_dec, uint8_t **pp_buf )
+static picture_t *GetNewPicture( decoder_t *p_dec, uint8_t **pp_buf )
 {
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
     picture_t *p_pic;
-    vlc_bool_t b_progressive = p_dec->p_info->current_picture != NULL ?
-        p_dec->p_info->current_picture->flags & PIC_FLAG_PROGRESSIVE_FRAME :
+    vlc_bool_t b_progressive = p_sys->p_info->current_picture != NULL ?
+        p_sys->p_info->current_picture->flags & PIC_FLAG_PROGRESSIVE_FRAME :
         1;
-    vlc_bool_t b_top_field_first = p_dec->p_info->current_picture != NULL ?
-        p_dec->p_info->current_picture->flags & PIC_FLAG_TOP_FIELD_FIRST :
+    vlc_bool_t b_top_field_first = p_sys->p_info->current_picture != NULL ?
+        p_sys->p_info->current_picture->flags & PIC_FLAG_TOP_FIELD_FIRST :
         1;
-    unsigned int i_nb_fields = p_dec->p_info->current_picture != NULL ?
-        p_dec->p_info->current_picture->nb_fields : 2;
+    unsigned int i_nb_fields = p_sys->p_info->current_picture != NULL ?
+        p_sys->p_info->current_picture->nb_fields : 2;
 
     /* Get a new picture */
-    while( !(p_pic = vout_CreatePicture( p_dec->p_vout,
+    while( !(p_pic = vout_CreatePicture( p_sys->p_vout,
         b_progressive, b_top_field_first, i_nb_fields )) )
     {
         if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error )
@@ -592,7 +581,7 @@ static picture_t *GetNewPicture( dec_thread_t *p_dec, uint8_t **pp_buf )
     }
     if( p_pic == NULL )
         return NULL;
-    vout_LinkPicture( p_dec->p_vout, p_pic );
+    vout_LinkPicture( p_sys->p_vout, p_pic );
 
     pp_buf[0] = p_pic->p[0].p_pixels;
     pp_buf[1] = p_pic->p[1].p_pixels;
index 055f7e39bde319154c6e0c5ed1a56b0a24e98a49..fc73cc36be381b9f688676a9be2616fb970278ff 100644 (file)
@@ -2,7 +2,7 @@
  * lpcm.c: lpcm decoder module
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: lpcm.c,v 1.16 2003/06/10 23:01:40 massiot Exp $
+ * $Id: lpcm.c,v 1.17 2003/09/02 20:19:25 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *          Henri Fallon <henri@videolan.org>
@@ -102,15 +102,15 @@ vlc_module_end();
  *****************************************************************************/
 static int OpenDecoder( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
 
-    if( p_fifo->i_fourcc != VLC_FOURCC('l','p','c','m')
-         && p_fifo->i_fourcc != VLC_FOURCC('l','p','c','b') )
+    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('l','p','c','m')
+         && p_dec->p_fifo->i_fourcc != VLC_FOURCC('l','p','c','b') )
     {   
         return VLC_EGENERIC;
     }
     
-    p_fifo->pf_run = RunDecoder;
+    p_dec->pf_run = RunDecoder;
     return VLC_SUCCESS;
 }
 
index 972f82dc24b1a528cadc657573b531071087f802..0a72022918dcc20135d76408eb2374c28ab0d0ef 100644 (file)
@@ -2,7 +2,7 @@
  * mpeg_audio.c: parse MPEG audio sync info and packetize the stream
  *****************************************************************************
  * Copyright (C) 2001-2003 VideoLAN
- * $Id: mpeg_audio.c,v 1.16 2003/06/25 00:40:41 fenrir Exp $
+ * $Id: mpeg_audio.c,v 1.17 2003/09/02 20:19:25 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Eric Petit <titer@videolan.org>
@@ -94,14 +94,14 @@ vlc_module_end();
  *****************************************************************************/
 static int Open( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
 
-    if( p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', 'a') )
+    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', 'a') )
     {
         return VLC_EGENERIC;
     }
 
-    p_fifo->pf_run = RunDecoder;
+    p_dec->pf_run = RunDecoder;
     return VLC_SUCCESS;
 }
 
index d1d6d52e4b7278848661117225ccaed58c9b43e9..968e8b5154febd54e5e082a68baf25331fdbd575 100644 (file)
@@ -2,7 +2,7 @@
  * quicktime.c: a quicktime decoder that uses the QT library/dll
  *****************************************************************************
  * Copyright (C) 2003 VideoLAN
- * $Id: quicktime.c,v 1.11 2003/08/17 23:02:51 fenrir Exp $
+ * $Id: quicktime.c,v 1.12 2003/09/02 20:19:25 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir at via.ecp.fr>
  *          Derk-Jan Hartman <thedj at users.sf.net>
@@ -273,9 +273,9 @@ static int GetPESData( uint8_t *p_buf, int i_max, pes_packet_t *p_pes )
  *****************************************************************************/
 static int OpenDecoder( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
 
-    switch( p_fifo->i_fourcc )
+    switch( p_dec->p_fifo->i_fourcc )
     {
         case VLC_FOURCC('S','V','Q','3'): /* Sorenson v3 */
     /*    case VLC_FOURCC('S','V','Q','1'):  Sorenson v1 
@@ -285,7 +285,7 @@ static int OpenDecoder( vlc_object_t *p_this )
         case VLC_FOURCC('r','l','e',' '): /* QuickTime animation (RLE) */
         case VLC_FOURCC('r','p','z','a'): /* QuickTime Apple Video */
         case VLC_FOURCC('a','z','p','r'): /* QuickTime animation (RLE) */
-            p_fifo->pf_run = RunDecoderVideo;
+            p_dec->pf_run = RunDecoderVideo;
             return VLC_SUCCESS;
 
         case VLC_FOURCC('m','p','4','a'): /* MPEG-4 audio */
@@ -309,7 +309,7 @@ static int OpenDecoder( vlc_object_t *p_this )
         case 0x6D730002:                        /* Microsoft ADPCM-ACM */
         case 0x6D730011:                        /* DVI Intel IMAADPCM-ACM */
 
-            p_fifo->pf_run = RunDecoderAudio;
+            p_dec->pf_run = RunDecoderAudio;
             return VLC_SUCCESS;
         default:
             return VLC_EGENERIC;
index bb2817f71f75088bfdb66d85d8dd31df29a8a64f..eb8a1d14ac3bca290bdf740e5a6ec6cefd15aba3 100644 (file)
@@ -2,7 +2,7 @@
  * rawvideo.c: Pseudo audio decoder; for raw video data
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: rawvideo.c,v 1.5 2003/05/02 03:40:01 fenrir Exp $
+ * $Id: rawvideo.c,v 1.6 2003/09/02 20:19:25 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -76,9 +76,9 @@ vlc_module_end();
  *****************************************************************************/
 static int OpenDecoder( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
 
-    switch( p_fifo->i_fourcc )
+    switch( p_dec->p_fifo->i_fourcc )
     {
         /* Planar YUV */
         case VLC_FOURCC('I','4','4','4'):
@@ -99,13 +99,12 @@ static int OpenDecoder( vlc_object_t *p_this )
         case VLC_FOURCC('R','V','1','6'):
         case VLC_FOURCC('R','V','1','5'):
 
-            p_fifo->pf_run = RunDecoder;
+            p_dec->pf_run = RunDecoder;
             return VLC_SUCCESS;
 
         default:
             return VLC_EGENERIC;
     }
-
 }
 
 /*****************************************************************************
index a31aaf6c4203be115d4902664caac8bbb6243660..cd7c7f072ca8dad493eb3ca93b67694bcb93653c 100644 (file)
@@ -2,7 +2,7 @@
  * spudec.c : SPU decoder thread
  *****************************************************************************
  * Copyright (C) 2000-2001 VideoLAN
- * $Id: spudec.c,v 1.24 2003/07/22 20:49:10 hartman Exp $
+ * $Id: spudec.c,v 1.25 2003/09/02 20:19:26 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -59,15 +59,15 @@ vlc_module_end();
  *****************************************************************************/
 static int OpenDecoder( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
 
-    if( p_fifo->i_fourcc != VLC_FOURCC('s','p','u',' ')
-         && p_fifo->i_fourcc != VLC_FOURCC('s','p','u','b') )
+    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('s','p','u',' ')
+         && p_dec->p_fifo->i_fourcc != VLC_FOURCC('s','p','u','b') )
     {   
         return VLC_EGENERIC;
     }
     
-    p_fifo->pf_run = RunDecoder;
+    p_dec->pf_run = RunDecoder;
 
     return VLC_SUCCESS;
 }
@@ -230,4 +230,3 @@ static void EndThread( spudec_thread_t *p_spudec )
     CloseBitstream( &p_spudec->bit_stream );
     free( p_spudec );
 }
-
index 2285784bb91b799ef2845afccd419c80deefb921..bbaa6bccbf357c342db38405421cc8c8801dc780 100644 (file)
@@ -2,7 +2,7 @@
  * subsdec.c : SPU decoder thread
  *****************************************************************************
  * Copyright (C) 2000-2001 VideoLAN
- * $Id: subsdec.c,v 1.8 2003/08/27 12:24:52 sigmunau Exp $
+ * $Id: subsdec.c,v 1.9 2003/09/02 20:19:26 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *          Samuel Hocevar <sam@zoy.org>
@@ -95,14 +95,14 @@ vlc_module_end();
  *****************************************************************************/
 static int OpenDecoder( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
 
-    if( p_fifo->i_fourcc != VLC_FOURCC('s','u','b','t') )
+    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('s','u','b','t') )
     {
         return VLC_EGENERIC;
     }
 
-    p_fifo->pf_run = RunDecoder;
+    p_dec->pf_run = RunDecoder;
 
     var_Create( p_this, "subsdec-align", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
 #if defined(HAVE_ICONV)
index ea27d159782265484c5a975b6c00a1996663354b..f2b81c217c9762ac4b975863f898ec61b858609f 100644 (file)
@@ -2,7 +2,7 @@
  * tarkin.c: tarkin decoder module making use of libtarkin.
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: tarkin.c,v 1.4 2002/11/28 21:00:48 gbazin Exp $
+ * $Id: tarkin.c,v 1.5 2003/09/02 20:19:25 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
@@ -103,14 +103,14 @@ vlc_module_end();
  *****************************************************************************/
 static int OpenDecoder( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
 
-    if( p_fifo->i_fourcc != VLC_FOURCC('t','a','r','k') )
+    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('t','a','r','k') )
     {
         return VLC_EGENERIC;
     }
 
-    p_fifo->pf_run = RunDecoder;
+    p_dec->pf_run = RunDecoder;
     return VLC_SUCCESS;
 }
 
index 41b607716d0029fdf37080628aa7770e8c050f96..bbc6917ce6e6a3d4722b84c2ec654fd0393f7c54 100644 (file)
@@ -2,7 +2,7 @@
  * theora.c: theora decoder module making use of libtheora.
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: theora.c,v 1.5 2003/06/11 15:53:50 gbazin Exp $
+ * $Id: theora.c,v 1.6 2003/09/02 20:19:25 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
+#include <stdlib.h>                                      /* malloc(), free() */
+#include <string.h>                                    /* memcpy(), memset() */
+
 #include <vlc/vlc.h>
 #include <vlc/vout.h>
-#include <vlc/input.h>
 #include <vlc/decoder.h>
-
-#include <stdlib.h>                                      /* malloc(), free() */
-#include <string.h>                                    /* memcpy(), memset() */
+#include <vlc/input.h>
+#include <vlc/sout.h>
+#include <input_ext-dec.h>
 
 #include <ogg/ogg.h>
 
 #include <theora/theora.h>
 
 /*****************************************************************************
- * dec_thread_t : theora decoder thread descriptor
+ * decoder_sys_t : theora decoder descriptor
  *****************************************************************************/
-typedef struct dec_thread_t
+struct decoder_sys_t
 {
+    /* Module mode */
+    vlc_bool_t b_packetizer;
+
     /*
-     * Thread properties
+     * Input properties
      */
-    vlc_thread_t        thread_id;                /* id for thread functions */
+    int i_headers;
 
     /*
      * Theora properties
@@ -54,29 +59,39 @@ typedef struct dec_thread_t
     theora_state     td;                   /* theora bitstream user comments */
 
     /*
-     * Input properties
+     * Output properties
      */
-    decoder_fifo_t         *p_fifo;            /* stores the PES stream data */
-    pes_packet_t           *p_pes;            /* current PES we are decoding */
+    vout_thread_t *p_vout;
 
     /*
-     * Output properties
+     * Packetizer output properties
      */
-    vout_thread_t *p_vout;
+    sout_packetizer_input_t *p_sout_input;
+    sout_format_t           sout_format;
 
-} dec_thread_t;
+    /*
+     * Common properties
+     */
+    mtime_t i_pts;
+};
 
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
-static int  OpenDecoder  ( vlc_object_t * );
-static int  RunDecoder   ( decoder_fifo_t * );
-static void CloseDecoder ( dec_thread_t * );
+static int OpenDecoder   ( vlc_object_t * );
+static int OpenPacketizer( vlc_object_t * );
+
+static int InitDecoder   ( decoder_t * );
+static int RunDecoder    ( decoder_t *, block_t * );
+static int EndDecoder    ( decoder_t * );
 
-static void DecodePacket ( dec_thread_t * );
-static int  GetOggPacket ( dec_thread_t *, ogg_packet *, mtime_t * );
+static int ProcessPacket ( decoder_t *, ogg_packet *, mtime_t );
+static int DecodePacket  ( decoder_t *, ogg_packet * );
+static int SendPacket    ( decoder_t *, ogg_packet * );
 
-static void theora_CopyPicture( dec_thread_t *, picture_t *, yuv_buffer * );
+static void ParseTheoraComments( decoder_t * );
+
+static void theora_CopyPicture( decoder_t *, picture_t *, yuv_buffer * );
 
 /*****************************************************************************
  * Module descriptor
@@ -86,6 +101,12 @@ vlc_module_begin();
     set_capability( "decoder", 100 );
     set_callbacks( OpenDecoder, NULL );
     add_shortcut( "theora" );
+
+    add_submodule();
+    set_description( _("Theora video packetizer") );
+    set_capability( "packetizer", 100 );
+    set_callbacks( OpenPacketizer, NULL );
+    add_shortcut( "theora" );
 vlc_module_end();
 
 /*****************************************************************************
@@ -93,224 +114,375 @@ vlc_module_end();
  *****************************************************************************/
 static int OpenDecoder( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
 
-    if( p_fifo->i_fourcc != VLC_FOURCC('t','h','e','o') )
+    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('t','h','e','o') )
     {
         return VLC_EGENERIC;
     }
 
-    p_fifo->pf_run = RunDecoder;
+    p_dec->pf_init = InitDecoder;
+    p_dec->pf_decode = RunDecoder;
+    p_dec->pf_end = EndDecoder;
+
+    /* Allocate the memory needed to store the decoder's structure */
+    if( ( p_dec->p_sys =
+          (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
+    {
+        msg_Err( p_dec, "out of memory" );
+        return VLC_EGENERIC;
+    }
+    p_dec->p_sys->b_packetizer = VLC_FALSE;
+
     return VLC_SUCCESS;
 }
+
+static int OpenPacketizer( vlc_object_t *p_this )
+{
+    decoder_t *p_dec = (decoder_t*)p_this;
+
+    int i_ret = OpenDecoder( p_this );
+
+    if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE;
+
+    return i_ret;
+}
+
 /*****************************************************************************
- * RunDecoder: the theora decoder
+ * InitDecoder: Initalize the decoder
  *****************************************************************************/
-static int RunDecoder( decoder_fifo_t *p_fifo )
+static int InitDecoder( decoder_t *p_dec )
 {
-    dec_thread_t *p_dec;
-    ogg_packet oggpacket;
-    int i_chroma, i_aspect;
-    mtime_t i_pts;
+    decoder_sys_t *p_sys = p_dec->p_sys;
 
-    /* Allocate the memory needed to store the thread's structure */
-    if( (p_dec = (dec_thread_t *)malloc (sizeof(dec_thread_t)) )
-            == NULL)
-    {
-        msg_Err( p_fifo, "out of memory" );
-        goto error;
-    }
+    p_sys->i_pts = 0;
 
-    /* Initialize the thread properties */
-    memset( p_dec, 0, sizeof(dec_thread_t) );
-    p_dec->p_fifo = p_fifo;
-    p_dec->p_pes  = NULL;
-    p_dec->p_vout = NULL;
+    p_sys->p_sout_input = NULL;
+    p_sys->sout_format.i_cat = VIDEO_ES;
+    p_sys->sout_format.i_fourcc = VLC_FOURCC( 't', 'h', 'e', 'o' );
+    p_sys->sout_format.i_width  = 0;
+    p_sys->sout_format.i_height = 0;
+    p_sys->sout_format.i_bitrate     = 0;
+    p_sys->sout_format.i_extra_data  = 0;
+    p_sys->sout_format.p_extra_data  = NULL;
 
     /* Init supporting Theora structures needed in header parsing */
-    theora_comment_init( &p_dec->tc );
-    theora_info_init( &p_dec->ti );
-
-    /* Take care of the initial Theora header */
-    if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS )
-        goto error;
+    theora_comment_init( &p_sys->tc );
+    theora_info_init( &p_sys->ti );
 
-    oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */
-    if( theora_decode_header( &p_dec->ti, &p_dec->tc, &oggpacket ) < 0 )
-    {
-        msg_Err( p_dec->p_fifo, "This bitstream does not contain Theora "
-                 "video data" );
-        goto error;
-    }
+    p_sys->i_headers = 0;
 
-    /* The next two packets in order are the comment and codebook headers.
-       We need to watch out that these packets are not missing as a
-       missing or corrupted header is fatal. */
-    if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS )
-        goto error;
+    return VLC_SUCCESS;
+}
 
-    if( theora_decode_header( &p_dec->ti, &p_dec->tc, &oggpacket ) < 0 )
-    {
-        msg_Err( p_dec->p_fifo, "2nd Theora header is corrupted" );
-        goto error;
-    }
+/****************************************************************************
+ * RunDecoder: the whole thing
+ ****************************************************************************
+ * This function must be fed with ogg packets.
+ ****************************************************************************/
+static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+    ogg_packet oggpacket;
+    int i_ret;
 
-    if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS )
-        goto error;
+    /* Block to Ogg packet */
+    oggpacket.packet = p_block->p_buffer;
+    oggpacket.bytes = p_block->i_buffer;
+    oggpacket.granulepos = p_block->i_dts;
+    oggpacket.b_o_s = 0;
+    oggpacket.e_o_s = 0;
+    oggpacket.packetno = 0;
 
-    if( theora_decode_header( &p_dec->ti, &p_dec->tc, &oggpacket ) < 0 )
+    if( p_sys->i_headers == 0 )
     {
-        msg_Err( p_dec->p_fifo, "3rd Theora header is corrupted" );
-        goto error;
-    }
+        /* Take care of the initial Theora header */
 
-    /* We have all the headers, initialize decoder */
-    theora_decode_init( &p_dec->td, &p_dec->ti );
-    msg_Dbg( p_dec->p_fifo, "%dx%d %.02f fps video, frame content is %dx%d "
-             "with offset (%d,%d)",
-             p_dec->ti.width, p_dec->ti.height,
-             (double)p_dec->ti.fps_numerator/p_dec->ti.fps_denominator,
-             p_dec->ti.frame_width, p_dec->ti.frame_height,
-             p_dec->ti.offset_x, p_dec->ti.offset_y );
-
-    /* Initialize video output */
-    if( p_dec->ti.aspect_denominator )
-        i_aspect = VOUT_ASPECT_FACTOR * p_dec->ti.aspect_numerator /
-                    p_dec->ti.aspect_denominator;
-    else
-        i_aspect = VOUT_ASPECT_FACTOR * p_dec->ti.width / p_dec->ti.height;
+        oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */
+        if( theora_decode_header( &p_sys->ti, &p_sys->tc, &oggpacket ) < 0 )
+        {
+            msg_Err( p_dec->p_fifo, "This bitstream does not contain Theora "
+                     "video data" );
+            block_Release( p_block );
+            return VLC_EGENERIC;
+        }
+        p_sys->i_headers++;
 
-    i_chroma = VLC_FOURCC('Y','V','1','2');
+        if( p_sys->b_packetizer )
+        {
+            /* add a input for the stream ouput */
+            p_sys->sout_format.i_width  = p_sys->ti.width;
+            p_sys->sout_format.i_height = p_sys->ti.height;
+
+            p_sys->p_sout_input =
+                sout_InputNew( p_dec, &p_sys->sout_format );
+
+            if( !p_sys->p_sout_input )
+            {
+                msg_Err( p_dec, "cannot add a new stream" );
+                block_Release( p_block );
+                return VLC_EGENERIC;
+            }
+        }
+        else
+        {
+            /* Initialize video output */
+            int i_chroma, i_aspect;
+
+            if( p_sys->ti.aspect_denominator )
+                i_aspect = VOUT_ASPECT_FACTOR * p_sys->ti.aspect_numerator /
+                    p_sys->ti.aspect_denominator;
+            else
+                i_aspect = VOUT_ASPECT_FACTOR *
+                    p_sys->ti.frame_width / p_sys->ti.frame_height;
+
+            i_chroma = VLC_FOURCC('Y','V','1','2');
+
+            p_sys->p_vout =
+                vout_Request( p_dec, NULL,
+                              p_sys->ti.frame_width, p_sys->ti.frame_height,
+                              i_chroma, i_aspect );
+            if( p_sys->p_vout == NULL )
+            {
+                msg_Err( p_dec, "failed to create video output" );
+                block_Release( p_block );
+                return VLC_EGENERIC;
+            }
+        }
 
-    p_dec->p_vout = vout_Request( p_dec->p_fifo, p_dec->p_vout,
-                                  p_dec->ti.width, p_dec->ti.height,
-                                  i_chroma, i_aspect );
+        msg_Dbg( p_dec, "%dx%d %.02f fps video, frame content "
+                 "is %dx%d with offset (%d,%d)",
+                 p_sys->ti.width, p_sys->ti.height,
+                 (double)p_sys->ti.fps_numerator/p_sys->ti.fps_denominator,
+                 p_sys->ti.frame_width, p_sys->ti.frame_height,
+                 p_sys->ti.offset_x, p_sys->ti.offset_y );
 
-    /* theora decoder thread's main loop */
-    while( (!p_dec->p_fifo->b_die) && (!p_dec->p_fifo->b_error) )
+        if( p_sys->b_packetizer )
+        {
+            i_ret = SendPacket( p_dec, &oggpacket );
+            block_Release( p_block );
+            return i_ret;
+        }
+        else
+        {
+            block_Release( p_block );
+            return VLC_SUCCESS;
+        }
+    }
+
+    if( p_sys->i_headers == 1 )
     {
-        DecodePacket( p_dec );
+        /* The next packet in order is the comments header */
+        if( theora_decode_header( &p_sys->ti, &p_sys->tc, &oggpacket ) < 0 )
+        {
+            msg_Err( p_dec, "2nd Theora header is corrupted" );
+            return VLC_EGENERIC;
+        }
+        p_sys->i_headers++;
+    
+        ParseTheoraComments( p_dec );
+
+        if( p_sys->b_packetizer )
+        {
+            i_ret = SendPacket( p_dec, &oggpacket );
+            block_Release( p_block );
+            return i_ret;
+        }
+        else
+        {
+            block_Release( p_block );
+            return VLC_SUCCESS;
+        }
     }
 
-    /* If b_error is set, the theora decoder thread enters the error loop */
-    if( p_dec->p_fifo->b_error )
+    if( p_sys->i_headers == 2 )
     {
-        DecoderError( p_dec->p_fifo );
+        /* The next packet in order is the codebooks header
+           We need to watch out that this packet is not missing as a
+           missing or corrupted header is fatal. */
+        if( theora_decode_header( &p_sys->ti, &p_sys->tc, &oggpacket ) < 0 )
+        {
+            msg_Err( p_dec, "3rd Theora header is corrupted" );
+            return VLC_EGENERIC;
+        }
+        p_sys->i_headers++;
+    
+        if( !p_sys->b_packetizer )
+        {
+            /* We have all the headers, initialize decoder */
+            theora_decode_init( &p_sys->td, &p_sys->ti );
+        }
+
+        if( p_sys->b_packetizer )
+        {
+            i_ret = SendPacket( p_dec, &oggpacket );
+            block_Release( p_block );
+            return i_ret;
+        }
+        else
+        {
+            block_Release( p_block );
+            return VLC_SUCCESS;
+        }
     }
 
-    /* End of the theora decoder thread */
-    CloseDecoder( p_dec );
+    i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts );
+    block_Release( p_block );
+    return i_ret;
+}
 
-    return 0;
+/*****************************************************************************
+ * ProcessPacket: processes a Vorbis packet.
+ *****************************************************************************/
+static int ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
+                          mtime_t i_pts )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
 
- error:
-    DecoderError( p_fifo );
-    if( p_dec )
+    /* Date management */
+    if( i_pts > 0 && i_pts != p_sys->i_pts )
     {
-        if( p_dec->p_fifo )
-            p_dec->p_fifo->b_error = 1;
-
-        /* End of the theora decoder thread */
-        CloseDecoder( p_dec );
+        p_sys->i_pts = i_pts;
     }
 
-    return -1;
+    if( p_sys->b_packetizer )
+    {
+        return SendPacket( p_dec, p_oggpacket );
+    }
+    else
+    {
+        return DecodePacket( p_dec, p_oggpacket );
+    }
 }
 
 /*****************************************************************************
  * DecodePacket: decodes a Theora packet.
  *****************************************************************************/
-static void DecodePacket( dec_thread_t *p_dec )
+static int DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
 {
-    ogg_packet oggpacket;
     picture_t *p_pic;
-    mtime_t i_pts;
     yuv_buffer yuv;
 
-    if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS )
-    {
-        /* This should mean an eos */
-        return;
-    }
+    decoder_sys_t *p_sys = p_dec->p_sys;
 
-    theora_decode_packetin( &p_dec->td, &oggpacket );
+    theora_decode_packetin( &p_sys->td, p_oggpacket );
 
     /* Decode */
-    theora_decode_YUVout( &p_dec->td, &yuv );
+    theora_decode_YUVout( &p_sys->td, &yuv );
 
     /* Get a new picture */
-    while( !(p_pic = vout_CreatePicture( p_dec->p_vout, 0, 0, 0 ) ) )
+    while( !(p_pic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 ) ) )
     {
         if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error )
         {
-            return;
+            return VLC_EGENERIC;
         }
         msleep( VOUT_OUTMEM_SLEEP );
     }
-    if( !p_pic )
-        return;
+    if( !p_pic ) return VLC_EGENERIC;
 
     theora_CopyPicture( p_dec, p_pic, &yuv );
 
-    vout_DatePicture( p_dec->p_vout, p_pic, i_pts );
-    vout_DisplayPicture( p_dec->p_vout, p_pic );
+    vout_DatePicture( p_sys->p_vout, p_pic, p_sys->i_pts );
+    vout_DisplayPicture( p_sys->p_vout, p_pic );
+
+    /* Date management */
+    p_sys->i_pts += ( 1000000 * p_sys->ti.fps_numerator /
+                      p_sys->ti.fps_denominator ); /* 1 frame per packet */
+
+    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
- * GetOggPacket: get the following theora packet from the stream and send back
- *               the result in an ogg packet (for easy decoding by libtheora).
- *****************************************************************************
- * Returns VLC_EGENERIC in case of eof.
+ * SendPacket: send an ogg packet to the stream output.
  *****************************************************************************/
-static int GetOggPacket( dec_thread_t *p_dec, ogg_packet *p_oggpacket,
-                         mtime_t *p_pts )
+static int SendPacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
 {
-    if( p_dec->p_pes ) input_DeletePES( p_dec->p_fifo->p_packets_mgt,
-                                        p_dec->p_pes );
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    sout_buffer_t *p_sout_buffer =
+        sout_BufferNew( p_sys->p_sout_input->p_sout, p_oggpacket->bytes );
 
-    input_ExtractPES( p_dec->p_fifo, &p_dec->p_pes );
-    if( !p_dec->p_pes ) return VLC_EGENERIC;
+    if( !p_sout_buffer ) return VLC_EGENERIC;
 
-    p_oggpacket->packet = p_dec->p_pes->p_first->p_payload_start;
-    p_oggpacket->bytes = p_dec->p_pes->i_pes_size;
-    p_oggpacket->granulepos = p_dec->p_pes->i_dts;
-    p_oggpacket->b_o_s = 0;
-    p_oggpacket->e_o_s = 0;
-    p_oggpacket->packetno = 0;
+    p_dec->p_vlc->pf_memcpy( p_sout_buffer->p_buffer,
+                             p_oggpacket->packet,
+                             p_oggpacket->bytes );
 
-    *p_pts = p_dec->p_pes->i_pts;
+    /* Date management */
+    p_sout_buffer->i_dts = p_sout_buffer->i_pts = p_sys->i_pts;
+    p_sys->i_pts += ( 1000000 * p_sys->ti.fps_numerator /
+                      p_sys->ti.fps_denominator ); /* 1 frame per packet */
+
+    if( p_sys->i_headers >= 3 )
+        p_sout_buffer->i_length = p_sys->i_pts - p_sout_buffer->i_pts;
+    else
+        p_sout_buffer->i_length = 0;
+
+    sout_InputSendBuffer( p_sys->p_sout_input, p_sout_buffer );
 
     return VLC_SUCCESS;
 }
 
 /*****************************************************************************
- * CloseDecoder: theora decoder destruction
+ * ParseTheoraComments: FIXME should be done in demuxer
  *****************************************************************************/
-static void CloseDecoder( dec_thread_t * p_dec )
+static void ParseTheoraComments( decoder_t *p_dec )
 {
-
-    if( p_dec )
+    input_thread_t *p_input = (input_thread_t *)p_dec->p_parent;
+    input_info_category_t *p_cat =
+        input_InfoCategory( p_input, _("Theora Comment") );
+    int i = 0;
+    char *psz_name, *psz_value, *psz_comment;
+    while ( i < p_dec->p_sys->tc.comments )
     {
-        if( p_dec->p_pes )
-            input_DeletePES( p_dec->p_fifo->p_packets_mgt, p_dec->p_pes );
+        psz_comment = strdup( p_dec->p_sys->tc.user_comments[i] );
+        if( !psz_comment )
+        {
+            msg_Warn( p_dec, "Out of memory" );
+            break;
+        }
+        psz_name = psz_comment;
+        psz_value = strchr( psz_comment, '=' );
+        if( psz_value )
+        {
+            *psz_value = '\0';
+            psz_value++;
+            input_AddInfo( p_cat, psz_name, psz_value );
+        }
+        free( psz_comment );
+        i++;
+    }
+}
+
+/*****************************************************************************
+ * EndDecoder: theora decoder destruction
+ *****************************************************************************/
+static int EndDecoder( decoder_t *p_dec )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
 
-        vout_Request( p_dec->p_fifo, p_dec->p_vout, 0, 0, 0, 0 );
+    if( !p_sys->b_packetizer )
+        vout_Request( p_dec, p_sys->p_vout, 0, 0, 0, 0 );
 
-        theora_info_clear( &p_dec->ti );
-        theora_comment_clear( &p_dec->tc );
+    theora_info_clear( &p_sys->ti );
+    theora_comment_clear( &p_sys->tc );
 
-        free( p_dec );
-    }
+    free( p_sys );
+
+    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
  * theora_CopyPicture: copy a picture from theora internal buffers to a
  *                     picture_t structure.
  *****************************************************************************/
-static void theora_CopyPicture( dec_thread_t *p_dec, picture_t *p_pic,
+static void theora_CopyPicture( decoder_t *p_dec, picture_t *p_pic,
                                 yuv_buffer *yuv )
 {
     int i_plane, i_line, i_width, i_dst_stride, i_src_stride;
+    int i_src_xoffset, i_src_yoffset;
     u8  *p_dst, *p_src;
 
     for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
@@ -318,12 +490,21 @@ static void theora_CopyPicture( dec_thread_t *p_dec, picture_t *p_pic,
         p_dst = p_pic->p[i_plane].p_pixels;
         p_src = i_plane ? (i_plane - 1 ? yuv->v : yuv->u ) : yuv->y;
         i_width = p_pic->p[i_plane].i_visible_pitch;
-        i_dst_stride = p_pic->p[i_plane].i_pitch;
-        i_src_stride = i_plane ? yuv->uv_stride : yuv->y_stride;
+        i_dst_stride  = p_pic->p[i_plane].i_pitch;
+        i_src_stride  = i_plane ? yuv->uv_stride : yuv->y_stride;
+        i_src_xoffset = p_dec->p_sys->ti.offset_x;
+        i_src_yoffset = p_dec->p_sys->ti.offset_y;
+        if( i_plane )
+        {
+            i_src_xoffset /= 2;
+            i_src_yoffset /= 2;
+        } 
+
+        p_src += (i_src_yoffset * i_src_stride + i_src_yoffset);
 
         for( i_line = 0; i_line < p_pic->p[i_plane].i_lines; i_line++ )
         {
-            p_dec->p_fifo->p_vlc->pf_memcpy( p_dst, p_src, i_width );
+            p_dec->p_vlc->pf_memcpy( p_dst, p_src, i_width );
             p_src += i_src_stride;
             p_dst += i_dst_stride;
         }
index 84e4ea9d18a8168c8bf5a7b9032e1ba443735084..05ee7eceb485e39d5cf680be2e46884af6a8eb4b 100644 (file)
@@ -2,7 +2,7 @@
  * vorbis.c: vorbis decoder module making use of libvorbis.
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: vorbis.c,v 1.16 2003/03/30 18:14:36 gbazin Exp $
+ * $Id: vorbis.c,v 1.17 2003/09/02 20:19:25 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
@@ -30,6 +30,8 @@
 #include <vlc/vlc.h>
 #include <vlc/aout.h>
 #include <vlc/decoder.h>
+#include <vlc/input.h>
+#include <vlc/sout.h>
 #include <input_ext-dec.h>
 
 #include <vlc/input.h>
 #endif
 
 /*****************************************************************************
- * dec_thread_t : vorbis decoder thread descriptor
+ * decoder_sys_t : vorbis decoder descriptor
  *****************************************************************************/
-typedef struct dec_thread_t
+struct decoder_sys_t
 {
+    /* Module mode */
+    vlc_bool_t b_packetizer;
+
     /*
-     * Thread properties
+     * Input properties
      */
-    vlc_thread_t        thread_id;                /* id for thread functions */
+    int i_headers;
 
     /*
      * Vorbis properties
@@ -62,21 +67,26 @@ typedef struct dec_thread_t
                           * decoder */
     vorbis_block     vb; /* local working space for packet->PCM decode */
 
-    /*
-     * Input properties
-     */
-    decoder_fifo_t         *p_fifo;            /* stores the PES stream data */
-    pes_packet_t           *p_pes;            /* current PES we are decoding */
-
     /*
      * Output properties
      */
     aout_instance_t        *p_aout;
     aout_input_t           *p_aout_input;
-    audio_sample_format_t   output_format;
-    audio_date_t            end_date;
+    audio_sample_format_t   aout_format;
 
-} dec_thread_t;
+    /*
+     * Packetizer output properties
+     */
+    sout_packetizer_input_t *p_sout_input;
+    sout_format_t           sout_format;
+
+    /*
+     * Common properties
+     */
+    audio_date_t          end_date;
+    int                   i_last_block_size;
+
+};
 
 static int pi_channels_maps[6] =
 {
@@ -89,15 +99,21 @@ static int pi_channels_maps[6] =
      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
 };
 
-/*****************************************************************************
+/****************************************************************************
  * Local prototypes
- *****************************************************************************/
-static int  OpenDecoder  ( vlc_object_t * );
-static int  RunDecoder   ( decoder_fifo_t * );
-static void CloseDecoder ( dec_thread_t * );
+ ****************************************************************************/
+static int OpenDecoder   ( vlc_object_t * );
+static int OpenPacketizer( vlc_object_t * );
+
+static int InitDecoder   ( decoder_t * );
+static int RunDecoder    ( decoder_t *, block_t * );
+static int EndDecoder    ( decoder_t * );
 
-static void DecodePacket ( dec_thread_t * );
-static int  GetOggPacket ( dec_thread_t *, ogg_packet *, mtime_t * );
+static int ProcessPacket ( decoder_t *, ogg_packet *, mtime_t );
+static int DecodePacket  ( decoder_t *, ogg_packet * );
+static int SendPacket    ( decoder_t *, ogg_packet * );
+
+static void ParseVorbisComments( decoder_t * );
 
 #ifdef MODULE_NAME_IS_tremor
 static void Interleave   ( int32_t *, const int32_t **, int, int );
@@ -116,6 +132,11 @@ vlc_module_begin();
     set_capability( "decoder", 100 );
 #endif
     set_callbacks( OpenDecoder, NULL );
+
+    add_submodule();
+    set_description( _("Vorbis audio packetizer") );
+    set_capability( "packetizer", 100 );
+    set_callbacks( OpenPacketizer, NULL );
 vlc_module_end();
 
 /*****************************************************************************
@@ -123,256 +144,381 @@ vlc_module_end();
  *****************************************************************************/
 static int OpenDecoder( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
 
-    if( p_fifo->i_fourcc != VLC_FOURCC('v','o','r','b') )
+    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('v','o','r','b') )
     {
         return VLC_EGENERIC;
     }
 
-    p_fifo->pf_run = RunDecoder;
+    p_dec->pf_init = InitDecoder;
+    p_dec->pf_decode = RunDecoder;
+    p_dec->pf_end = EndDecoder;
+
+    /* Allocate the memory needed to store the decoder's structure */
+    if( ( p_dec->p_sys =
+          (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
+    {
+        msg_Err( p_dec, "out of memory" );
+        return VLC_EGENERIC;
+    }
+    p_dec->p_sys->b_packetizer = VLC_FALSE;
+
     return VLC_SUCCESS;
 }
 
+static int OpenPacketizer( vlc_object_t *p_this )
+{
+    decoder_t *p_dec = (decoder_t*)p_this;
+
+    int i_ret = OpenDecoder( p_this );
+
+    if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE;
+
+    return i_ret;
+}
+
 /*****************************************************************************
- * RunDecoder: the vorbis decoder
+ * InitDecoder: Initalize the decoder
  *****************************************************************************/
-static int RunDecoder( decoder_fifo_t * p_fifo )
+static int InitDecoder( decoder_t *p_dec )
 {
-    dec_thread_t *p_dec;
-    ogg_packet oggpacket;
-    mtime_t i_pts;
+    decoder_sys_t *p_sys = p_dec->p_sys;
 
-    /* Allocate the memory needed to store the thread's structure */
-    if( (p_dec = (dec_thread_t *)malloc (sizeof(dec_thread_t)) )
-            == NULL)
-    {
-        msg_Err( p_fifo, "out of memory" );
-        goto error;
-    }
+    aout_DateSet( &p_sys->end_date, 0 );
 
-    /* Initialize the thread properties */
-    memset( p_dec, 0, sizeof(dec_thread_t) );
-    p_dec->p_fifo = p_fifo;
-    p_dec->p_pes  = NULL;
+    p_sys->p_aout = NULL;
+    p_sys->p_aout_input = NULL;
+    p_sys->aout_format.i_format = VLC_FOURCC('v','o','r','b');
 
-    /* Take care of the initial Vorbis header */
-    vorbis_info_init( &p_dec->vi );
-    vorbis_comment_init( &p_dec->vc );
+    p_sys->p_sout_input = NULL;
+    p_sys->sout_format.i_cat = AUDIO_ES;
+    p_sys->sout_format.i_fourcc = VLC_FOURCC( 'v', 'o', 'r', 'b' );
+    p_sys->sout_format.i_block_align = 0;
+    p_sys->sout_format.i_bitrate     = 0;
+    p_sys->sout_format.i_extra_data  = 0;
+    p_sys->sout_format.p_extra_data  = NULL;
 
-    if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS )
-        goto error;
+    /* Take care of vorbis init */
+    vorbis_info_init( &p_sys->vi );
+    vorbis_comment_init( &p_sys->vc );
 
-    oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */
-    if( vorbis_synthesis_headerin( &p_dec->vi, &p_dec->vc, &oggpacket ) < 0 )
-    {
-        msg_Err( p_dec->p_fifo, "This bitstream does not contain Vorbis "
-                 "audio data");
-        goto error;
-    }
+    p_sys->i_headers = 0;
 
-    /* The next two packets in order are the comment and codebook headers.
-       We need to watch out that these packets are not missing as a
-       missing or corrupted header is fatal. */
-    if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS )
-        goto error;
+    return VLC_SUCCESS;
+}
 
-    if( vorbis_synthesis_headerin( &p_dec->vi, &p_dec->vc, &oggpacket ) < 0 )
-    {
-        msg_Err( p_dec->p_fifo, "2nd Vorbis header is corrupted" );
-        goto error;
-    }
-    /* parse the vorbis comment. FIXME should be done in demuxer*/
+/****************************************************************************
+ * RunDecoder: the whole thing
+ ****************************************************************************
+ * This function must be fed with ogg packets.
+ ****************************************************************************/
+static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+    ogg_packet oggpacket;
+    int i_ret;
+
+    /* Block to Ogg packet */
+    oggpacket.packet = p_block->p_buffer;
+    oggpacket.bytes = p_block->i_buffer;
+    oggpacket.granulepos = p_block->i_dts;
+    oggpacket.b_o_s = 0;
+    oggpacket.e_o_s = 0;
+    oggpacket.packetno = 0;
+
+    if( p_sys->i_headers == 0 )
     {
-        input_thread_t *p_input = (input_thread_t *)p_fifo->p_parent;
-        input_info_category_t *p_cat = input_InfoCategory( p_input,
-                                                           _("Vorbis Comment") );
-        int i = 0;
-        char *psz_name, *psz_value, *psz_comment;
-        while ( i < p_dec->vc.comments )
+        /* Take care of the initial Vorbis header */
+
+        oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */
+        if( vorbis_synthesis_headerin( &p_sys->vi, &p_sys->vc,
+                                       &oggpacket ) < 0 )
+        {
+            msg_Err( p_dec->p_fifo, "This bitstream does not contain Vorbis "
+                     "audio data");
+            block_Release( p_block );
+            return VLC_EGENERIC;
+        }
+        p_sys->i_headers++;
+
+        if( p_sys->b_packetizer )
         {
-            psz_comment = strdup( p_dec->vc.user_comments[i] );
-            if ( !psz_comment )
+            /* add a input for the stream ouput */
+            p_sys->sout_format.i_sample_rate = p_sys->vi.rate;
+            p_sys->sout_format.i_channels    = p_sys->vi.channels;
+            p_sys->sout_format.i_block_align = 1;
+            p_sys->sout_format.i_bitrate     = p_sys->vi.bitrate_nominal;
+
+            p_sys->p_sout_input =
+                sout_InputNew( p_dec, &p_sys->sout_format );
+
+            if( !p_sys->p_sout_input )
             {
-                msg_Warn( p_dec->p_fifo, "Out of memory" );
-                break;
+                msg_Err( p_dec, "cannot add a new stream" );
+                block_Release( p_block );
+                return VLC_EGENERIC;
             }
-            psz_name = psz_comment;
-            psz_value = strchr( psz_comment, '=' );
-            if( psz_value )
+        }
+        else
+        {
+#ifdef MODULE_NAME_IS_tremor
+            p_sys->aout_format.i_format = VLC_FOURCC('f','i','3','2');
+#else
+            p_sys->aout_format.i_format = VLC_FOURCC('f','l','3','2');
+#endif
+            p_sys->aout_format.i_physical_channels =
+                p_sys->aout_format.i_original_channels =
+                    pi_channels_maps[p_sys->vi.channels];
+            p_sys->aout_format.i_rate = p_sys->vi.rate;
+
+            p_sys->p_aout = NULL;
+            p_sys->p_aout_input = aout_DecNew( p_dec, &p_sys->p_aout,
+                                               &p_sys->aout_format );
+
+            if( p_sys->p_aout_input == NULL )
             {
-                *psz_value = '\0';
-                psz_value++;
-                input_AddInfo( p_cat, psz_name, psz_value );
+                msg_Err( p_dec, "failed to create aout fifo" );
+                block_Release( p_block );
+                return VLC_EGENERIC;
             }
-            free( psz_comment );
-            i++;
         }
-    }
-    
-    if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS )
-        goto error;
 
-    if( vorbis_synthesis_headerin( &p_dec->vi, &p_dec->vc, &oggpacket ) < 0 )
-    {
-        msg_Err( p_dec->p_fifo, "3rd Vorbis header is corrupted" );
-        goto error;
-    }
+        aout_DateInit( &p_sys->end_date, p_sys->vi.rate );
 
-    /* Initialize the Vorbis packet->PCM decoder */
-    vorbis_synthesis_init( &p_dec->vd, &p_dec->vi );
-    vorbis_block_init( &p_dec->vd, &p_dec->vb );
+        msg_Dbg( p_dec, "channels:%d samplerate:%ld bitrate:%ld",
+                 p_sys->vi.channels, p_sys->vi.rate,
+                 p_sys->vi.bitrate_nominal );
 
-#ifdef MODULE_NAME_IS_tremor
-    p_dec->output_format.i_format = VLC_FOURCC('f','i','3','2');
-#else
-    p_dec->output_format.i_format = VLC_FOURCC('f','l','3','2');
-#endif
-    p_dec->output_format.i_physical_channels =
-        p_dec->output_format.i_original_channels =
-            pi_channels_maps[p_dec->vi.channels];
-    p_dec->output_format.i_rate = p_dec->vi.rate;
-
-    aout_DateInit( &p_dec->end_date, p_dec->vi.rate );
-    p_dec->p_aout = NULL;
-    p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo,
-                                       &p_dec->p_aout,
-                                       &p_dec->output_format );
-
-    if( p_dec->p_aout_input == NULL )
-    {
-        msg_Err( p_dec->p_fifo, "failed to create aout fifo" );
-        goto error;
+        if( p_sys->b_packetizer )
+        {
+            i_ret = SendPacket( p_dec, &oggpacket );
+            block_Release( p_block );
+            return i_ret;
+        }
+        else
+        {
+            block_Release( p_block );
+            return VLC_SUCCESS;
+        }
     }
 
-    /* vorbis decoder thread's main loop */
-    while( (!p_dec->p_fifo->b_die) && (!p_dec->p_fifo->b_error) )
+    if( p_sys->i_headers == 1 )
     {
-        DecodePacket( p_dec );
+        /* The next packet in order is the comments header */
+        if( vorbis_synthesis_headerin( &p_sys->vi, &p_sys->vc, &oggpacket )
+            < 0 )
+        {
+            msg_Err( p_dec, "2nd Vorbis header is corrupted" );
+            return VLC_EGENERIC;
+        }
+        p_sys->i_headers++;
+    
+        ParseVorbisComments( p_dec );
+
+        if( p_sys->b_packetizer )
+        {
+            i_ret = SendPacket( p_dec, &oggpacket );
+            block_Release( p_block );
+            return i_ret;
+        }
+        else
+        {
+            block_Release( p_block );
+            return VLC_SUCCESS;
+        }
     }
 
-    /* If b_error is set, the vorbis decoder thread enters the error loop */
-    if( p_dec->p_fifo->b_error )
+    if( p_sys->i_headers == 2 )
     {
-        DecoderError( p_dec->p_fifo );
+        /* The next packet in order is the codebooks header
+           We need to watch out that this packet is not missing as a
+           missing or corrupted header is fatal. */
+        if( vorbis_synthesis_headerin( &p_sys->vi, &p_sys->vc, &oggpacket )
+            < 0 )
+        {
+            msg_Err( p_dec, "3rd Vorbis header is corrupted" );
+            return VLC_EGENERIC;
+        }
+        p_sys->i_headers++;
+    
+        if( !p_sys->b_packetizer )
+        {
+            /* Initialize the Vorbis packet->PCM decoder */
+            vorbis_synthesis_init( &p_sys->vd, &p_sys->vi );
+            vorbis_block_init( &p_sys->vd, &p_sys->vb );
+        }
+
+        if( p_sys->b_packetizer )
+        {
+            i_ret = SendPacket( p_dec, &oggpacket );
+            block_Release( p_block );
+            return i_ret;
+        }
+        else
+        {
+            block_Release( p_block );
+            return VLC_SUCCESS;
+        }
     }
 
-    /* End of the vorbis decoder thread */
-    CloseDecoder( p_dec );
+    i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts );
+    block_Release( p_block );
+    return i_ret;
+}
 
-    return 0;
+/*****************************************************************************
+ * ProcessPacket: processes a Vorbis packet.
+ *****************************************************************************/
+static int ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
+                          mtime_t i_pts )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
 
- error:
-    DecoderError( p_fifo );
-    if( p_dec )
+    /* Date management */
+    if( i_pts > 0 && i_pts != aout_DateGet( &p_sys->end_date ) )
     {
-        if( p_dec->p_fifo )
-            p_dec->p_fifo->b_error = 1;
-
-        /* End of the vorbis decoder thread */
-        CloseDecoder( p_dec );
+        aout_DateSet( &p_sys->end_date, i_pts );
     }
 
-    return -1;
-
+    if( p_sys->b_packetizer )
+    {
+        return SendPacket( p_dec, p_oggpacket );
+    }
+    else
+    {
+        return DecodePacket( p_dec, p_oggpacket );
+    }
 }
 
 /*****************************************************************************
  * DecodePacket: decodes a Vorbis packet.
  *****************************************************************************/
-static void DecodePacket( dec_thread_t *p_dec )
+static int DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
 {
-    aout_buffer_t *p_aout_buffer;
-    ogg_packet    oggpacket;
+    decoder_sys_t *p_sys = p_dec->p_sys;
+    int           i_samples;
+
 #ifdef MODULE_NAME_IS_tremor
     int32_t       **pp_pcm;
 #else
     float         **pp_pcm;
 #endif
-    int           i_samples;
-    mtime_t       i_pts;
 
-    if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS )
-    {
-        /* This should mean an eos */
-        return;
-    }
-
-    /* Date management */
-    if( i_pts > 0 && i_pts != aout_DateGet( &p_dec->end_date ) )
-    {
-        aout_DateSet( &p_dec->end_date, i_pts );
-    }
-
-    if( vorbis_synthesis( &p_dec->vb, &oggpacket ) == 0 )
-        vorbis_synthesis_blockin( &p_dec->vd, &p_dec->vb );
+    if( vorbis_synthesis( &p_sys->vb, p_oggpacket ) == 0 )
+        vorbis_synthesis_blockin( &p_sys->vd, &p_sys->vb );
 
     /* **pp_pcm is a multichannel float vector. In stereo, for
      * example, pp_pcm[0] is left, and pp_pcm[1] is right. i_samples is
      * the size of each channel. Convert the float values
      * (-1.<=range<=1.) to whatever PCM format and write it out */
 
-    while( ( i_samples = vorbis_synthesis_pcmout( &p_dec->vd, &pp_pcm ) ) > 0 )
+    while( ( i_samples = vorbis_synthesis_pcmout( &p_sys->vd, &pp_pcm ) ) > 0 )
     {
 
-        p_aout_buffer = aout_DecNewBuffer( p_dec->p_aout, p_dec->p_aout_input,
+        aout_buffer_t *p_aout_buffer;
+        p_aout_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
                                            i_samples );
         if( !p_aout_buffer )
         {
-            msg_Err( p_dec->p_fifo, "cannot get aout buffer" );
-            p_dec->p_fifo->b_error = 1;
-            return;
+            msg_Err( p_dec, "cannot get aout buffer" );
+            return VLC_SUCCESS;
         }
 
         /* Interleave the samples */
 #ifdef MODULE_NAME_IS_tremor
         Interleave( (int32_t *)p_aout_buffer->p_buffer,
-                    (const int32_t **)pp_pcm, p_dec->vi.channels, i_samples );
+                    (const int32_t **)pp_pcm, p_sys->vi.channels, i_samples );
 #else
         Interleave( (float *)p_aout_buffer->p_buffer,
-                    (const float **)pp_pcm, p_dec->vi.channels, i_samples );
+                    (const float **)pp_pcm, p_sys->vi.channels, i_samples );
 #endif
 
         /* Tell libvorbis how many samples we actually consumed */
-        vorbis_synthesis_read( &p_dec->vd, i_samples );
+        vorbis_synthesis_read( &p_sys->vd, i_samples );
 
         /* Date management */
-        p_aout_buffer->start_date = aout_DateGet( &p_dec->end_date );
-        p_aout_buffer->end_date = aout_DateIncrement( &p_dec->end_date,
+        p_aout_buffer->start_date = aout_DateGet( &p_sys->end_date );
+        p_aout_buffer->end_date = aout_DateIncrement( &p_sys->end_date,
                                                       i_samples );
 
-        aout_DecPlay( p_dec->p_aout, p_dec->p_aout_input, p_aout_buffer );
+        aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input, p_aout_buffer );
     }
 
 }
 
 /*****************************************************************************
- * GetOggPacket: get the following vorbis packet from the stream and send back
- *               the result in an ogg packet (for easy decoding by libvorbis).
- *****************************************************************************
- * Returns VLC_EGENERIC in case of eof.
+ * SendPacket: send an ogg packet to the stream output.
  *****************************************************************************/
-static int GetOggPacket( dec_thread_t *p_dec, ogg_packet *p_oggpacket,
-                         mtime_t *p_pts )
+static int SendPacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
 {
-    if( p_dec->p_pes ) input_DeletePES( p_dec->p_fifo->p_packets_mgt,
-                                        p_dec->p_pes );
+    decoder_sys_t *p_sys = p_dec->p_sys;
+    int           i_block_size, i_samples;
+
+    sout_buffer_t *p_sout_buffer =
+        sout_BufferNew( p_sys->p_sout_input->p_sout, p_oggpacket->bytes );
 
-    input_ExtractPES( p_dec->p_fifo, &p_dec->p_pes );
-    if( !p_dec->p_pes ) return VLC_EGENERIC;
+    if( !p_sout_buffer ) return VLC_EGENERIC;
 
-    p_oggpacket->packet = p_dec->p_pes->p_first->p_payload_start;
-    p_oggpacket->bytes = p_dec->p_pes->i_pes_size;
-    p_oggpacket->granulepos = p_dec->p_pes->i_dts;
-    p_oggpacket->b_o_s = 0;
-    p_oggpacket->e_o_s = 0;
-    p_oggpacket->packetno = 0;
+    i_block_size = vorbis_packet_blocksize( &p_sys->vi, p_oggpacket );
+    if( i_block_size < 0 ) i_block_size = 0; /* non audio packet */
+    i_samples = ( p_sys->i_last_block_size + i_block_size ) >> 2;
+    p_sys->i_last_block_size = i_block_size;
 
-    *p_pts = p_dec->p_pes->i_pts;
+    p_dec->p_vlc->pf_memcpy( p_sout_buffer->p_buffer,
+                             p_oggpacket->packet,
+                             p_oggpacket->bytes );
+
+    p_sout_buffer->i_bitrate = p_sys->vi.bitrate_nominal;
+
+    /* Date management */
+    p_sout_buffer->i_dts = p_sout_buffer->i_pts =
+        aout_DateGet( &p_sys->end_date );
+
+    if( p_sys->i_headers >= 3 )
+        p_sout_buffer->i_length =
+            aout_DateIncrement( &p_sys->end_date, i_samples ) -
+            p_sout_buffer->i_pts;
+    else
+        p_sout_buffer->i_length = 0;
+
+    sout_InputSendBuffer( p_sys->p_sout_input, p_sout_buffer );
 
     return VLC_SUCCESS;
 }
 
+/*****************************************************************************
+ * ParseVorbisComments: FIXME should be done in demuxer
+ *****************************************************************************/
+static void ParseVorbisComments( decoder_t *p_dec )
+{
+    input_thread_t *p_input = (input_thread_t *)p_dec->p_parent;
+    input_info_category_t *p_cat =
+        input_InfoCategory( p_input, _("Vorbis Comment") );
+    int i = 0;
+    char *psz_name, *psz_value, *psz_comment;
+    while ( i < p_dec->p_sys->vc.comments )
+    {
+        psz_comment = strdup( p_dec->p_sys->vc.user_comments[i] );
+        if( !psz_comment )
+        {
+            msg_Warn( p_dec, "Out of memory" );
+            break;
+        }
+        psz_name = psz_comment;
+        psz_value = strchr( psz_comment, '=' );
+        if( psz_value )
+        {
+            *psz_value = '\0';
+            psz_value++;
+            input_AddInfo( p_cat, psz_name, psz_value );
+        }
+        free( psz_comment );
+        i++;
+    }
+}
+
 /*****************************************************************************
  * Interleave: helper function to interleave channels
  *****************************************************************************/
@@ -395,23 +541,32 @@ static void Interleave( float *p_out, const float **pp_in,
 }
 
 /*****************************************************************************
- * CloseDecoder: vorbis decoder destruction
+ * EndDecoder: vorbis decoder destruction
  *****************************************************************************/
-static void CloseDecoder( dec_thread_t * p_dec )
+static int EndDecoder( decoder_t * p_dec )
 {
-    if( p_dec->p_aout_input != NULL )
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    if( p_sys->p_aout_input != NULL )
+    {
+        aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
+    }
+
+    if( p_sys->p_sout_input != NULL )
     {
-        aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
+        sout_InputDelete( p_sys->p_sout_input );
     }
 
-    if( p_dec )
+    if( !p_sys->b_packetizer && p_sys->i_headers >= 3 )
     {
-        if( p_dec->p_pes )
-            input_DeletePES( p_dec->p_fifo->p_packets_mgt, p_dec->p_pes );
-        vorbis_block_clear( &p_dec->vb );
-        vorbis_dsp_clear( &p_dec->vd );
-        vorbis_comment_clear( &p_dec->vc );
-        vorbis_info_clear( &p_dec->vi );  /* must be called last */
-        free( p_dec );
+        vorbis_block_clear( &p_sys->vb );
+        vorbis_dsp_clear( &p_sys->vd );
     }
+
+    vorbis_comment_clear( &p_sys->vc );
+    vorbis_info_clear( &p_sys->vi );  /* must be called last */
+
+    free( p_sys );
+
+    return VLC_SUCCESS;
 }
index ff2fda6daa715eb9ef980104e9e1bd92ae8d78a0..acf8a98f79b263e088f685fc0a49e6418b68f125 100644 (file)
@@ -2,7 +2,7 @@
  * xvid.c: a decoder for libxvidcore, the Xvid video codec
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: xvid.c,v 1.5 2003/02/20 01:52:45 sigmunau Exp $
+ * $Id: xvid.c,v 1.6 2003/09/02 20:19:25 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -59,16 +59,16 @@ vlc_module_end();
  *****************************************************************************/
 static int OpenDecoder ( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
 
-    if( p_fifo->i_fourcc != VLC_FOURCC('x','v','i','d')
-         && p_fifo->i_fourcc != VLC_FOURCC('X','V','I','D')
-         && p_fifo->i_fourcc != VLC_FOURCC('D','I','V','X') )
+    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('x','v','i','d')
+         && p_dec->p_fifo->i_fourcc != VLC_FOURCC('X','V','I','D')
+         && p_dec->p_fifo->i_fourcc != VLC_FOURCC('D','I','V','X') )
     {
         return VLC_EGENERIC;
     }
 
-    p_fifo->pf_run = RunDecoder;
+    p_dec->pf_run = RunDecoder;
     return VLC_SUCCESS;
 }
 
@@ -271,4 +271,3 @@ static int RunDecoder ( decoder_fifo_t *p_fifo )
 
     return VLC_SUCCESS;
 }
-
index dcfbf662f2fd0061c893d191f14c5df61b47da7f..17aa3cbbe8e27273f31b01a86052d1316cebdfb0 100644 (file)
@@ -2,7 +2,7 @@
  * ogg.c : ogg stream input module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: ogg.c,v 1.31 2003/08/17 23:02:52 fenrir Exp $
+ * $Id: ogg.c,v 1.32 2003/09/02 20:19:26 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  * 
@@ -601,7 +601,7 @@ static int Ogg_FindLogicalStreams( input_thread_t *p_input, demux_sys_t *p_ogg)
                         i_keyframe_frequency_force >>= 1;
                     }
 
-                    p_stream->f_rate = (float)i_fps_numerator /
+                    p_stream->f_rate = ((float)i_fps_numerator) /
                                                 i_fps_denominator;
                     msg_Dbg( p_input,
                              "found theora header, bitrate: %i, rate: %f",
index 86f770f32ad22987201b2a69139f045ea07577b2..8c2c0aeee64e1bc457461c2c188c813c0f079731 100644 (file)
@@ -2,7 +2,7 @@
  * dec_dummy.c: dummy decoder plugin for vlc.
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: decoder.c,v 1.5 2003/03/03 16:49:14 gbazin Exp $
+ * $Id: decoder.c,v 1.6 2003/09/02 20:19:26 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *      
@@ -56,7 +56,7 @@ static int Run ( decoder_fifo_t * );
  *****************************************************************************/
 int E_(OpenDecoder) ( vlc_object_t *p_this )
 {
-    ((decoder_fifo_t*)p_this)->pf_run = Run;
+    ((decoder_t*)p_this)->pf_run = Run;
 
     return VLC_SUCCESS;
 }
index 0f4275c55c3385726526274722c681175e7b40a1..9d3b660f847d8824f51c609910a03bb3e7ea2c99 100644 (file)
@@ -1,7 +1,5 @@
 SOURCES_packetizer_copy = copy.c
-SOURCES_packetizer_a52 = a52.c
 SOURCES_packetizer_mpegaudio = mpegaudio.c
 SOURCES_packetizer_mpegvideo = mpegvideo.c
 SOURCES_packetizer_mpeg4video = mpeg4video.c
 SOURCES_packetizer_mpeg4audio = mpeg4audio.c
-SOURCES_packetizer_vorbis = vorbis.c
diff --git a/modules/packetizer/a52.c b/modules/packetizer/a52.c
deleted file mode 100644 (file)
index 0f768fc..0000000
+++ /dev/null
@@ -1,377 +0,0 @@
-/*****************************************************************************
- * a52.c
- *****************************************************************************
- * Copyright (C) 2001, 2002 VideoLAN
- * $Id: a52.c,v 1.5 2003/05/03 02:09:41 fenrir Exp $
- *
- * Authors: Laurent Aimar <fenrir@via.ecp.fr>
- *          Eric Petit <titer@videolan.org>
- *
- * 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.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#include <vlc/vlc.h>
-#include <vlc/aout.h>
-#include <vlc/decoder.h>
-#include <vlc/input.h>
-#include <vlc/sout.h>
-
-#include <stdlib.h>                                      /* malloc(), free() */
-#include <string.h>                                              /* strdup() */
-#include "codecs.h"                         /* WAVEFORMATEX BITMAPINFOHEADER */
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-typedef struct packetizer_s
-{
-    /* Input properties */
-    decoder_fifo_t          *p_fifo;
-    bit_stream_t            bit_stream;
-
-    /* Output properties */
-    sout_packetizer_input_t *p_sout_input;
-    sout_format_t           output_format;
-
-    uint64_t                i_samplescount;
-
-    mtime_t                 i_last_pts;
-} packetizer_t;
-
-static int  Open    ( vlc_object_t * );
-static int  Run     ( decoder_fifo_t * );
-
-static int  InitThread     ( packetizer_t * );
-static void PacketizeThread   ( packetizer_t * );
-static void EndThread      ( packetizer_t * );
-
-static int SyncInfo( const byte_t *, int *, int *, int * );
-
-#define FREE( p ) if( p ) free( p ); p = NULL
-
-/*****************************************************************************
- * Module descriptor
- *****************************************************************************/
-
-vlc_module_begin();
-    set_description( _("A/52 audio packetizer") );
-    set_capability( "packetizer", 10 );
-    set_callbacks( Open, NULL );
-vlc_module_end();
-
-
-
-/*****************************************************************************
- * OpenDecoder: probe the packetizer and return score
- *****************************************************************************
- * Tries to launch a decoder and return score so that the interface is able
- * to choose.
- *****************************************************************************/
-static int Open( vlc_object_t *p_this )
-{
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
-
-    if( p_fifo->i_fourcc != VLC_FOURCC( 'a', '5', '2', ' ') &&
-        p_fifo->i_fourcc != VLC_FOURCC( 'a', '5', '2', 'b') )
-    {
-        return VLC_EGENERIC;
-    }
-
-    p_fifo->pf_run = Run;
-    return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * RunDecoder: this function is called just after the thread is created
- *****************************************************************************/
-static int Run( decoder_fifo_t *p_fifo )
-{
-    packetizer_t *p_pack;
-    int b_error;
-
-    msg_Info( p_fifo, "Running A/52 packetizer" );
-    if( !( p_pack = malloc( sizeof( packetizer_t ) ) ) )
-    {
-        msg_Err( p_fifo, "out of memory" );
-        DecoderError( p_fifo );
-        return( -1 );
-    }
-    memset( p_pack, 0, sizeof( packetizer_t ) );
-
-    p_pack->p_fifo = p_fifo;
-
-    if( InitThread( p_pack ) != 0 )
-    {
-        DecoderError( p_fifo );
-        return( -1 );
-    }
-
-    while( ( !p_pack->p_fifo->b_die )&&( !p_pack->p_fifo->b_error ) )
-    {
-        PacketizeThread( p_pack );
-    }
-
-
-    if( ( b_error = p_pack->p_fifo->b_error ) )
-    {
-        DecoderError( p_pack->p_fifo );
-    }
-
-    EndThread( p_pack );
-
-    if( b_error )
-    {
-        return( -1 );
-    }
-
-    return( 0 );
-}
-
-
-
-/*****************************************************************************
- * InitThread: initialize data before entering main loop
- *****************************************************************************/
-
-static int InitThread( packetizer_t *p_pack )
-{
-
-    p_pack->output_format.i_cat = AUDIO_ES;
-    p_pack->output_format.i_fourcc = VLC_FOURCC( 'a', '5', '2', ' ' );
-
-    p_pack->p_sout_input   = NULL;
-
-    p_pack->i_samplescount = 0;
-    p_pack->i_last_pts     = 0;
-
-    if( InitBitstream( &p_pack->bit_stream, p_pack->p_fifo,
-                       NULL, NULL ) != VLC_SUCCESS )
-    {
-        msg_Err( p_pack->p_fifo, "cannot initialize bitstream" );
-        return -1;
-    }
-
-    return( 0 );
-}
-
-/*****************************************************************************
- * PacketizeThread: packetize an unit (here copy a complete pes)
- *****************************************************************************/
-static void PacketizeThread( packetizer_t *p_pack )
-{
-    sout_buffer_t   *p_sout_buffer;
-
-
-    uint8_t p_header[7];
-    int     i_channels, i_samplerate, i_bitrate;
-    int     i_framelength;
-    mtime_t i_pts;
-
-    /* search a valid start code */
-    for( ;; )
-    {
-        int i_skip = 0;
-
-        RealignBits( &p_pack->bit_stream );
-        while( ShowBits( &p_pack->bit_stream, 16 ) != 0x0b77 &&
-               !p_pack->p_fifo->b_die && !p_pack->p_fifo->b_error )
-        {
-            RemoveBits( &p_pack->bit_stream, 8 );
-            i_skip++;
-        }
-        if( i_skip )
-        {
-            msg_Warn( p_pack->p_fifo, "trashing %d bytes", i_skip );
-        }
-        if( p_pack->p_fifo->b_die || p_pack->p_fifo->b_error )
-        {
-            return;
-        }
-
-        /* Set the Presentation Time Stamp */
-        NextPTS( &p_pack->bit_stream, &i_pts, NULL );
-
-        GetChunk( &p_pack->bit_stream, p_header, 7 );
-        if( p_pack->p_fifo->b_die ) return;
-
-        /* Check if frame is valid and get frame info */
-        i_framelength = SyncInfo( p_header, &i_channels, &i_samplerate,
-                                  &i_bitrate );
-
-        if( !i_framelength )
-        {
-            msg_Warn( p_pack->p_fifo, "invalid header found" );
-            continue;
-        }
-        else
-        {
-//            msg_Dbg( p_pack->p_fifo, "frame length %d b", i_framelength );
-            break;
-        }
-    }
-
-    if( !p_pack->p_sout_input )
-    {
-        p_pack->output_format.i_sample_rate = i_samplerate;
-        p_pack->output_format.i_channels    = i_channels;
-        p_pack->output_format.i_block_align = 0;
-        p_pack->output_format.i_bitrate     = 0;
-        p_pack->output_format.i_extra_data  = 0;
-        p_pack->output_format.p_extra_data  = NULL;
-
-        p_pack->p_sout_input =
-            sout_InputNew( p_pack->p_fifo,
-                           &p_pack->output_format );
-
-        if( !p_pack->p_sout_input )
-        {
-            msg_Err( p_pack->p_fifo,
-                     "cannot add a new stream" );
-            p_pack->p_fifo->b_error = 1;
-            return;
-        }
-        msg_Info( p_pack->p_fifo,
-                 "A/52 channels:%d samplerate:%d bitrate:%d",
-                 i_channels, i_samplerate, i_bitrate );
-    }
-
-    if( i_pts <= 0 && p_pack->i_last_pts <= 0 )
-    {
-        msg_Dbg( p_pack->p_fifo, "need a starting pts" );
-        return;
-    }
-
-    /* fix pts */
-    if( i_pts <= 0 )
-    {
-        i_pts = p_pack->i_last_pts +
-                    (uint64_t)1000000 *
-                    (uint64_t)A52_FRAME_NB /
-                    (uint64_t)i_samplerate;
-    }
-    p_pack->i_last_pts = i_pts;
-
-    p_sout_buffer =
-        sout_BufferNew( p_pack->p_sout_input->p_sout, i_framelength );
-    if( !p_sout_buffer )
-    {
-        p_pack->p_fifo->b_error = 1;
-        return;
-    }
-    memcpy( p_sout_buffer->p_buffer, p_header, 7 );
-    p_sout_buffer->i_bitrate = i_bitrate;
-
-    p_sout_buffer->i_pts =
-        p_sout_buffer->i_dts = i_pts;
-
-    p_sout_buffer->i_length =
-            (uint64_t)1000000 *
-            (uint64_t)A52_FRAME_NB /
-            (uint64_t)i_samplerate;
-
-    p_pack->i_samplescount += A52_FRAME_NB;
-
-    /* we are already aligned */
-    GetChunk( &p_pack->bit_stream,
-              p_sout_buffer->p_buffer + 7,
-              i_framelength - 7 );
-
-    sout_InputSendBuffer( p_pack->p_sout_input,
-                          p_sout_buffer );
-}
-
-
-/*****************************************************************************
- * EndThread : packetizer thread destruction
- *****************************************************************************/
-static void EndThread ( packetizer_t *p_pack)
-{
-    if( p_pack->p_sout_input )
-    {
-        sout_InputDelete( p_pack->p_sout_input );
-    }
-    free( p_pack );
-}
-
-/*****************************************************************************
- * SyncInfo: parse A52 sync info
- *****************************************************************************
- * This code is borrowed from liba52 by Aaron Holtzman & Michel Lespinasse,
- * since we don't want to oblige S/PDIF people to use liba52 just to get
- * their SyncInfo...
- * fenrir: I've change it to report channels count
- *****************************************************************************/
-static int SyncInfo( const byte_t * p_buf, int * pi_channels,
-                     int * pi_sample_rate, int * pi_bit_rate )
-{
-    static const uint8_t halfrate[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3 };
-    static const int rate[] = { 32,  40,  48,  56,  64,  80,  96, 112,
-                                128, 160, 192, 224, 256, 320, 384, 448,
-                                512, 576, 640 };
-    static const uint8_t lfeon[8] = { 0x10, 0x10, 0x04, 0x04,
-                                      0x04, 0x01, 0x04, 0x01 };
-    static const int acmod_to_channels[8] = { 2, 1, 2, 3, 3, 4, 4, 5 };
-    int frmsizecod;
-    int bitrate;
-    int half;
-    int acmod;
-
-    if ((p_buf[0] != 0x0b) || (p_buf[1] != 0x77))        /* syncword */
-        return 0;
-
-    if (p_buf[5] >= 0x60)                /* bsid >= 12 */
-        return 0;
-    half = halfrate[p_buf[5] >> 3];
-
-    /* acmod, dsurmod and lfeon */
-    acmod = p_buf[6] >> 5;
-    if ( (p_buf[6] & 0xf8) == 0x50 )
-    {
-        /* Dolby surround = stereo + Dolby */
-/*        *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
-                        | AOUT_CHAN_DOLBYSTEREO;*/
-        *pi_channels = 2; /* FIXME ???  */
-    }
-    else
-    {
-        *pi_channels = acmod_to_channels[acmod&0x07];
-    }
-
-    if ( p_buf[6] & lfeon[acmod] ) *pi_channels += 1;//|= AOUT_CHAN_LFEA;
-
-    frmsizecod = p_buf[4] & 63;
-    if (frmsizecod >= 38)
-        return 0;
-    bitrate = rate [frmsizecod >> 1];
-    *pi_bit_rate = (bitrate * 1000) >> half;
-
-    switch (p_buf[4] & 0xc0) {
-    case 0:
-        *pi_sample_rate = 48000 >> half;
-        return 4 * bitrate;
-    case 0x40:
-        *pi_sample_rate = 44100 >> half;
-        return 2 * (320 * bitrate / 147 + (frmsizecod & 1));
-    case 0x80:
-        *pi_sample_rate = 32000 >> half;
-        return 6 * bitrate;
-    default:
-        return 0;
-    }
-}
-
-
index 0664f963c071c299e04340ebb55017aeb8eb6518..a90c03febd58c60f0748cc8f464e3ea2225891f2 100644 (file)
@@ -2,7 +2,7 @@
  * copy.c
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: copy.c,v 1.15 2003/08/11 20:19:45 fenrir Exp $
+ * $Id: copy.c,v 1.16 2003/09/02 20:19:26 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Eric Petit <titer@videolan.org>
@@ -80,9 +80,9 @@ static void input_ShowPES( decoder_fifo_t *p_fifo, pes_packet_t **pp_pes );
  *****************************************************************************/
 static int Open( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
 
-    p_fifo->pf_run = Run;
+    p_dec->pf_run = Run;
 
     return VLC_SUCCESS;
 }
@@ -672,4 +672,3 @@ static void input_ShowPES( decoder_fifo_t *p_fifo, pes_packet_t **pp_pes )
     *pp_pes = p_fifo->p_first;
     vlc_mutex_unlock( &p_fifo->data_lock );
 }
-
index 8b5e0f0105d046be334adb735626f7df69383121..f7427ae7a046b2b6f90865ce0d0153695c57b1ff 100644 (file)
@@ -2,7 +2,7 @@
  * mpeg4audio.c
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: mpeg4audio.c,v 1.6 2003/05/03 02:09:41 fenrir Exp $
+ * $Id: mpeg4audio.c,v 1.7 2003/09/02 20:19:26 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -100,11 +100,11 @@ vlc_module_end();
  *****************************************************************************/
 static int Open( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
 
-    p_fifo->pf_run = Run;
+    p_dec->pf_run = Run;
 
-    if( p_fifo->i_fourcc == VLC_FOURCC( 'm', 'p', '4', 'a') )
+    if( p_dec->p_fifo->i_fourcc == VLC_FOURCC( 'm', 'p', '4', 'a') )
     {
         return( VLC_SUCCESS );
     }
@@ -363,4 +363,3 @@ static void EndThread ( packetizer_thread_t *p_pack)
     }
     free( p_pack );
 }
-
index b521a4b21b183d5cd1c22a3309123bdcb65151b4..a29583fdd99033a6d3081554bbb4594a838eec4c 100644 (file)
@@ -2,7 +2,7 @@
  * mpeg4video.c
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: mpeg4video.c,v 1.12 2003/05/03 02:09:41 fenrir Exp $
+ * $Id: mpeg4video.c,v 1.13 2003/09/02 20:19:26 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Eric Petit <titer@videolan.org>
@@ -104,11 +104,11 @@ vlc_module_end();
  *****************************************************************************/
 static int Open( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
 
-    p_fifo->pf_run = Run;
+    p_dec->pf_run = Run;
 
-    switch(  p_fifo->i_fourcc )
+    switch( p_dec->p_fifo->i_fourcc )
     {
         case VLC_FOURCC( 'm', '4', 's', '2'):
         case VLC_FOURCC( 'M', '4', 'S', '2'):
@@ -485,4 +485,3 @@ static void input_ShowPES( decoder_fifo_t *p_fifo, pes_packet_t **pp_pes )
         *pp_pes = p_pes;
     }
 }
-
index dabe01ddd6e27112408dfa84ff4446369333117d..71a0fd884de509f1f974aba5b56f87294d36d9ec 100644 (file)
@@ -2,7 +2,7 @@
  * mpegaudio.c
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: mpegaudio.c,v 1.7 2003/08/26 23:12:37 fenrir Exp $
+ * $Id: mpegaudio.c,v 1.8 2003/09/02 20:19:26 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Eric Petit <titer@videolan.org>
@@ -110,14 +110,14 @@ static int mpegaudio_samplerate[2][4] = /* version 1 then 2 */
  *****************************************************************************/
 static int Open( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
 
-    if( p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', 'a') )
+    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', 'a') )
     {
         return VLC_EGENERIC;
     }
 
-    p_fifo->pf_run = Run;
+    p_dec->pf_run = Run;
     return VLC_SUCCESS;
 }
 
index ca5bf49bf7d8cf2bd75071fd36bb085adaf4d3b0..659e73d64e384c8741692d01683ead58c337c752 100644 (file)
@@ -2,7 +2,7 @@
  * mpegvideo.c
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: mpegvideo.c,v 1.18 2003/08/11 18:52:41 gbazin Exp $
+ * $Id: mpegvideo.c,v 1.19 2003/09/02 20:19:26 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Eric Petit <titer@videolan.org>
@@ -98,16 +98,16 @@ vlc_module_end();
  *****************************************************************************/
 static int Open( vlc_object_t *p_this )
 {
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+    decoder_t *p_dec = (decoder_t*)p_this;
 
-    if( p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', 'v') &&
-        p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', '1') &&
-        p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', '2') )
+    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', 'v') &&
+        p_dec->p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', '1') &&
+        p_dec->p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', '2') )
     {
         return VLC_EGENERIC;
     }
 
-    p_fifo->pf_run = Run;
+    p_dec->pf_run = Run;
     return VLC_SUCCESS;
 }
 
diff --git a/modules/packetizer/vorbis.c b/modules/packetizer/vorbis.c
deleted file mode 100644 (file)
index efca225..0000000
+++ /dev/null
@@ -1,376 +0,0 @@
-/*****************************************************************************
- * vorbis.c Vorbis audio packetizer
- *****************************************************************************
- * Copyright (C) 2001, 2002 VideoLAN
- * $Id: vorbis.c,v 1.1 2003/06/23 23:51:31 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.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#include <vlc/vlc.h>
-#include <vlc/aout.h>
-#include <vlc/decoder.h>
-#include <vlc/input.h>
-#include <vlc/sout.h>
-
-#include <stdlib.h>                                      /* malloc(), free() */
-#include <string.h>                                              /* strdup() */
-#include "codecs.h"                         /* WAVEFORMATEX BITMAPINFOHEADER */
-
-#include <ogg/ogg.h>
-#include <vorbis/codec.h>
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-typedef struct packetizer_s
-{
-    /*
-     * Input properties
-     */
-    decoder_fifo_t         *p_fifo;            /* stores the PES stream data */
-    pes_packet_t           *p_pes;            /* current PES we are decoding */
-
-    /* Output properties */
-    sout_packetizer_input_t *p_sout_input;
-    sout_format_t           output_format;
-
-    /*
-     * Vorbis properties
-     */
-    vorbis_info      vi; /* struct that stores all the static vorbis bitstream
-                            settings */
-    vorbis_comment   vc; /* struct that stores all the bitstream user
-                          * comments */
-    vorbis_dsp_state vd; /* central working state for the packet->PCM
-                          * decoder */
-    vorbis_block     vb; /* local working space for packet->PCM decode */
-
-    uint64_t                i_samplescount;
-
-    mtime_t                 i_interpolated_pts;
-    int                     i_last_block_size;
-
-} packetizer_t;
-
-static int  Open    ( vlc_object_t * );
-static int  Run     ( decoder_fifo_t * );
-
-static int  InitThread     ( packetizer_t * );
-static void PacketizeThread   ( packetizer_t * );
-static void EndThread      ( packetizer_t * );
-
-static int GetOggPacket( packetizer_t *, ogg_packet *, mtime_t * );
-static int SendOggPacket( packetizer_t *, ogg_packet *, mtime_t, int );
-
-#define FREE( p ) if( p ) free( p ); p = NULL
-
-/*****************************************************************************
- * Module descriptor
- *****************************************************************************/
-vlc_module_begin();
-    set_description( _("Vorbis audio packetizer") );
-    set_capability( "packetizer", 50 );
-    set_callbacks( Open, NULL );
-vlc_module_end();
-
-/*****************************************************************************
- * OpenDecoder: probe the packetizer and return score
- *****************************************************************************/
-static int Open( vlc_object_t *p_this )
-{
-    decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
-
-    if( p_fifo->i_fourcc != VLC_FOURCC( 'v', 'o', 'r', 'b') )
-    {
-        return VLC_EGENERIC;
-    }
-
-    p_fifo->pf_run = Run;
-    return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * RunDecoder: this function is called just after the thread is created
- *****************************************************************************/
-static int Run( decoder_fifo_t *p_fifo )
-{
-    packetizer_t *p_pack;
-    int b_error;
-
-    msg_Info( p_fifo, "Running vorbis packetizer" );
-    if( !( p_pack = malloc( sizeof( packetizer_t ) ) ) )
-    {
-        msg_Err( p_fifo, "out of memory" );
-        DecoderError( p_fifo );
-        return -1;
-    }
-    memset( p_pack, 0, sizeof( packetizer_t ) );
-
-    p_pack->p_fifo = p_fifo;
-
-    if( InitThread( p_pack ) != 0 )
-    {
-        DecoderError( p_fifo );
-        return -1;
-    }
-
-    while( ( !p_pack->p_fifo->b_die )&&( !p_pack->p_fifo->b_error ) )
-    {
-        PacketizeThread( p_pack );
-    }
-
-
-    if( ( b_error = p_pack->p_fifo->b_error ) )
-    {
-        DecoderError( p_pack->p_fifo );
-    }
-
-    EndThread( p_pack );
-
-    FREE( p_pack );
-
-    if( b_error )
-    {
-        return -1;
-    }
-
-    return 0;
-}
-
-/*****************************************************************************
- * InitThread: initialize data before entering main loop
- *****************************************************************************/
-static int InitThread( packetizer_t *p_pack )
-{ 
-    mtime_t    i_pts;
-    ogg_packet oggpacket;
-
-    p_pack->output_format.i_cat = AUDIO_ES;
-    p_pack->output_format.i_fourcc = p_pack->p_fifo->i_fourcc;
-    p_pack->output_format.i_sample_rate = 0;
-    p_pack->output_format.i_channels    = 0;
-    p_pack->output_format.i_block_align = 0;
-    p_pack->output_format.i_bitrate     = 0;
-    p_pack->output_format.i_extra_data  = 0;
-    p_pack->output_format.p_extra_data  = NULL;
-
-
-    p_pack->p_sout_input = NULL;
-
-    p_pack->i_samplescount = 0;
-    p_pack->i_interpolated_pts = 0;
-
-    p_pack->p_pes  = NULL;
-
-    /* Take care of vorbis init */
-    vorbis_info_init( &p_pack->vi );
-    vorbis_comment_init( &p_pack->vc );
-
-    /* Take care of the initial Vorbis headers */
-    if( GetOggPacket( p_pack, &oggpacket, &i_pts ) != VLC_SUCCESS )
-        goto error;
-
-    oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */
-    if( vorbis_synthesis_headerin( &p_pack->vi, &p_pack->vc, &oggpacket ) < 0 )
-    {
-        msg_Err( p_pack->p_fifo, "This bitstream does not contain Vorbis "
-                 "audio data");
-        goto error;
-    }
-
-    /* add a input for the stream ouput */
-    p_pack->output_format.i_sample_rate = p_pack->vi.rate;
-    p_pack->output_format.i_channels    = p_pack->vi.channels;
-    p_pack->output_format.i_block_align = 1;
-    p_pack->output_format.i_bitrate     = p_pack->vi.bitrate_nominal;
-
-    p_pack->p_sout_input =
-        sout_InputNew( p_pack->p_fifo, &p_pack->output_format );
-
-    if( !p_pack->p_sout_input )
-    {
-        msg_Err( p_pack->p_fifo, "cannot add a new stream" );
-        p_pack->p_fifo->b_error = 1;
-        goto error;
-    }
-    msg_Dbg( p_pack->p_fifo, "channels:%d samplerate:%d bitrate:%d",
-             p_pack->vi.channels, p_pack->vi.rate, p_pack->vi.bitrate_nominal);
-
-    if( SendOggPacket( p_pack, &oggpacket, 0, 0 ) != VLC_SUCCESS )
-        goto error;
-
-    /* The next two packets in order are the comment and codebook headers.
-       We need to watch out that these packets are not missing as a
-       missing or corrupted header is fatal. */
-    if( GetOggPacket( p_pack, &oggpacket, &i_pts ) != VLC_SUCCESS )
-        goto error;
-
-    if( vorbis_synthesis_headerin( &p_pack->vi, &p_pack->vc, &oggpacket ) < 0 )
-    {
-        msg_Err( p_pack->p_fifo, "2nd Vorbis header is corrupted" );
-        goto error;
-    }
-    
-    if( SendOggPacket( p_pack, &oggpacket, 0, 0 ) != VLC_SUCCESS )
-        goto error;
-
-    if( GetOggPacket( p_pack, &oggpacket, &i_pts ) != VLC_SUCCESS )
-        goto error;
-
-    if( vorbis_synthesis_headerin( &p_pack->vi, &p_pack->vc, &oggpacket ) < 0 )
-    {
-        msg_Err( p_pack->p_fifo, "3rd Vorbis header is corrupted" );
-        goto error;
-    }
-
-    if( SendOggPacket( p_pack, &oggpacket, 0, 0 ) != VLC_SUCCESS )
-        goto error;
-
-    /* Initialize the Vorbis packet->PCM decoder */
-    vorbis_synthesis_init( &p_pack->vd, &p_pack->vi );
-    vorbis_block_init( &p_pack->vd, &p_pack->vb );
-
-    return 0;
-
- error:
-    EndThread( p_pack );
-    return -1;
-}
-
-/*****************************************************************************
- * PacketizeThread: packetize an unit (here copy a complete ogg packet)
- *****************************************************************************/
-static void PacketizeThread( packetizer_t *p_pack )
-{
-    mtime_t    i_pts;
-    int        i_samples, i_block_size;
-    ogg_packet oggpacket;
-
-    /* Timestamp all the packets */
-    if( GetOggPacket( p_pack, &oggpacket, &i_pts ) != VLC_SUCCESS )
-        goto error;
-
-    if( i_pts <= 0 && p_pack->i_interpolated_pts <= 0 )
-    {
-        msg_Dbg( p_pack->p_fifo, "need a starting pts" );
-        return;
-    }
-
-    if( i_pts > 0 ) p_pack->i_interpolated_pts = i_pts;
-
-    i_block_size = vorbis_packet_blocksize( &p_pack->vi, &oggpacket );
-    if( i_block_size < 0 ) i_block_size = 0; /* non audio packet */
-    i_samples = ( p_pack->i_last_block_size + i_block_size ) >> 2;
-    p_pack->i_last_block_size = i_block_size;
-
-    if( SendOggPacket( p_pack, &oggpacket, p_pack->i_interpolated_pts,
-                       i_samples ) != VLC_SUCCESS )
-        goto error;
-
-    p_pack->i_interpolated_pts += 1000000 * (uint64_t)i_samples
-        / p_pack->vi.rate;
-
-    return;
-
- error:
-    p_pack->p_fifo->b_error = 1;
-}
-
-/*****************************************************************************
- * EndThread : packetizer thread destruction
- *****************************************************************************/
-static void EndThread ( packetizer_t *p_pack)
-{
-    if( p_pack->p_pes )
-        input_DeletePES( p_pack->p_fifo->p_packets_mgt, p_pack->p_pes );
-
-    vorbis_block_clear( &p_pack->vb );
-    vorbis_dsp_clear( &p_pack->vd );
-    vorbis_comment_clear( &p_pack->vc );
-    vorbis_info_clear( &p_pack->vi );  /* must be called last */
-
-    if( p_pack->p_sout_input )
-    {
-        sout_InputDelete( p_pack->p_sout_input );
-    }
-}
-
-/*****************************************************************************
- * GetOggPacket: get the following vorbis packet from the stream and send back
- *               the result in an ogg packet (for easy decoding by libvorbis).
- *****************************************************************************
- * Returns VLC_EGENERIC in case of eof.
- *****************************************************************************/
-static int GetOggPacket( packetizer_t *p_pack, ogg_packet *p_oggpacket,
-                         mtime_t *p_pts )
-{
-    if( p_pack->p_pes ) input_DeletePES( p_pack->p_fifo->p_packets_mgt,
-                                         p_pack->p_pes );
-
-    input_ExtractPES( p_pack->p_fifo, &p_pack->p_pes );
-    if( !p_pack->p_pes ) return VLC_EGENERIC;
-
-    p_oggpacket->packet = p_pack->p_pes->p_first->p_payload_start;
-    p_oggpacket->bytes = p_pack->p_pes->i_pes_size;
-    p_oggpacket->granulepos = p_pack->p_pes->i_dts;
-    p_oggpacket->b_o_s = 0;
-    p_oggpacket->e_o_s = 0;
-    p_oggpacket->packetno = 0;
-
-    *p_pts = p_pack->p_pes->i_pts;
-
-    return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * SendOggPacket: send an ogg packet to the stream output.
- *****************************************************************************
- * Returns VLC_EGENERIC in case of error.
- *****************************************************************************/
-static int SendOggPacket( packetizer_t *p_pack, ogg_packet *p_oggpacket,
-                          mtime_t i_pts, int i_samples )
-{
-    sout_buffer_t *p_sout_buffer =
-        sout_BufferNew( p_pack->p_sout_input->p_sout, p_oggpacket->bytes );
-
-    if( !p_sout_buffer )
-    {
-        p_pack->p_fifo->b_error = 1;
-        return VLC_EGENERIC;
-    }
-
-    p_pack->p_fifo->p_vlc->pf_memcpy( p_sout_buffer->p_buffer,
-                                      p_oggpacket->packet,
-                                      p_oggpacket->bytes );
-
-    p_sout_buffer->i_bitrate = p_pack->vi.bitrate_nominal;
-
-    p_sout_buffer->i_dts = i_pts;
-    p_sout_buffer->i_pts = i_pts;
-
-    p_sout_buffer->i_length = 1000000 * (uint64_t)i_samples / p_pack->vi.rate;
-
-    p_pack->i_samplescount += i_samples;
-
-    sout_InputSendBuffer( p_pack->p_sout_input, p_sout_buffer );
-
-    return VLC_SUCCESS;
-}
index 8c65f5f35e9df5767bc099b0f1a75fa8b0c137ec..29ad1e2f076df9f7d55346a8c23eb9e13c77d624 100644 (file)
@@ -2,7 +2,7 @@
  * input_dec.c: Functions for the management of decoders
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: input_dec.c,v 1.61 2003/07/23 01:13:48 gbazin Exp $
+ * $Id: input_dec.c,v 1.62 2003/09/02 20:19:26 gbazin Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
 
 #include <vlc/vlc.h>
 
+#include "vlc_block.h"
 #include "stream_control.h"
 #include "input_ext-dec.h"
 #include "input_ext-intf.h"
 #include "input_ext-plugins.h"
 
-static decoder_fifo_t * CreateDecoderFifo( input_thread_t *,
-                                           es_descriptor_t * );
-static void             DeleteDecoderFifo( decoder_fifo_t * );
+static decoder_t * CreateDecoder( input_thread_t *, es_descriptor_t * );
+static int         DecoderThread( decoder_t * );
+static void        DeleteDecoder( decoder_t * );
 
 /*****************************************************************************
  * input_RunDecoder: spawns a new decoder thread
@@ -45,19 +46,18 @@ decoder_fifo_t * input_RunDecoder( input_thread_t * p_input,
                                    es_descriptor_t * p_es )
 {
     vlc_value_t    val;
-    decoder_fifo_t *p_fifo;
-    int i_priority;
+    decoder_t      *p_dec;
+    int            i_priority;
 
     /* Create the decoder configuration structure */
-    p_fifo = CreateDecoderFifo( p_input, p_es );
-
-    if( p_fifo == NULL )
+    p_dec = CreateDecoder( p_input, p_es );
+    if( p_dec == NULL )
     {
-        msg_Err( p_input, "could not create decoder fifo" );
+        msg_Err( p_input, "could not create decoder" );
         return NULL;
     }
 
-    p_fifo->p_module = NULL;
+    p_dec->p_module = NULL;
 
     /* If we are in sout mode, search for packetizer module */
     var_Get( p_input, "sout", &val );
@@ -77,24 +77,26 @@ decoder_fifo_t * input_RunDecoder( input_thread_t * p_input,
 
         if( val.b_bool )
         {
-            p_fifo->p_module =
-                module_Need( p_fifo, "packetizer", "$packetizer" );
+            p_dec->p_module =
+                module_Need( p_dec, "packetizer", "$packetizer" );
         }
     }
     else
     {
         /* default Get a suitable decoder module */
-        p_fifo->p_module = module_Need( p_fifo, "decoder", "$codec" );
+        p_dec->p_module = module_Need( p_dec, "decoder", "$codec" );
 
         if( val.psz_string ) free( val.psz_string );
     }
 
-    if( p_fifo->p_module == NULL )
+    if( p_dec->p_module == NULL )
     {
-        msg_Err( p_fifo, "no suitable decoder module for fourcc `%4.4s'.\nVLC probably does not support this sound or video format.",
-                       (char*)&p_fifo->i_fourcc );
-        DeleteDecoderFifo( p_fifo );
-        vlc_object_destroy( p_fifo );
+        msg_Err( p_dec, "no suitable decoder module for fourcc `%4.4s'.\n"
+                 "VLC probably does not support this sound or video format.",
+                 (char*)&p_dec->p_fifo->i_fourcc );
+
+        DeleteDecoder( p_dec );
+        vlc_object_destroy( p_dec );
         return NULL;
     }
 
@@ -108,27 +110,29 @@ decoder_fifo_t * input_RunDecoder( input_thread_t * p_input,
     }
 
     /* Spawn the decoder thread */
-    if( vlc_thread_create( p_fifo, "decoder", p_fifo->pf_run,
+    if( vlc_thread_create( p_dec, "decoder", DecoderThread,
                            i_priority, VLC_FALSE ) )
     {
-        msg_Err( p_fifo, "cannot spawn decoder thread \"%s\"",
-                         p_fifo->p_module->psz_object_name );
-        module_Unneed( p_fifo, p_fifo->p_module );
+        msg_Err( p_dec, "cannot spawn decoder thread \"%s\"",
+                         p_dec->p_module->psz_object_name );
+        module_Unneed( p_dec, p_dec->p_module );
+        DeleteDecoder( p_dec );
+        vlc_object_destroy( p_dec );
         return NULL;
     }
 
     p_input->stream.b_changed = 1;
 
-    return p_fifo;
+    return p_dec->p_fifo;
 }
 
-
 /*****************************************************************************
  * input_EndDecoder: kills a decoder thread and waits until it's finished
  *****************************************************************************/
 void input_EndDecoder( input_thread_t * p_input, es_descriptor_t * p_es )
 {
     int i_dummy;
+    decoder_t *p_dec = p_es->p_decoder_fifo->p_dec;
 
     p_es->p_decoder_fifo->b_die = 1;
 
@@ -148,17 +152,17 @@ void input_EndDecoder( input_thread_t * p_input, es_descriptor_t * p_es )
     /* I thought that unlocking was better since thread join can be long
      * but it actually creates late pictures and freezes --stef */
     /* vlc_mutex_unlock( &p_input->stream.stream_lock ); */
-    vlc_thread_join( p_es->p_decoder_fifo );
+    vlc_thread_join( p_dec );
     /* vlc_mutex_lock( &p_input->stream.stream_lock ); */
 
-    /* Delete decoder configuration */
-    DeleteDecoderFifo( p_es->p_decoder_fifo );
-
     /* Unneed module */
-    module_Unneed( p_es->p_decoder_fifo, p_es->p_decoder_fifo->p_module );
+    module_Unneed( p_dec, p_dec->p_module );
 
-    /* Delete the fifo */
-    vlc_object_destroy( p_es->p_decoder_fifo );
+    /* Delete decoder configuration */
+    DeleteDecoder( p_dec );
+
+    /* Delete the decoder */
+    vlc_object_destroy( p_dec );
 
     /* Tell the input there is no more decoder */
     p_es->p_decoder_fifo = NULL;
@@ -275,65 +279,161 @@ void input_EscapeAudioDiscontinuity( input_thread_t * p_input )
 /*****************************************************************************
  * CreateDecoderFifo: create a decoder_fifo_t
  *****************************************************************************/
-static decoder_fifo_t * CreateDecoderFifo( input_thread_t * p_input,
-                                           es_descriptor_t * p_es )
+static decoder_t * CreateDecoder( input_thread_t * p_input,
+                                  es_descriptor_t * p_es )
 {
-    decoder_fifo_t * p_fifo;
+    decoder_t * p_dec;
 
-    /* Decoder FIFO */
-    p_fifo = vlc_object_create( p_input, VLC_OBJECT_DECODER );
-    if( p_fifo == NULL )
+    p_dec = vlc_object_create( p_input, VLC_OBJECT_DECODER );
+    if( p_dec == NULL )
     {
         msg_Err( p_input, "out of memory" );
         return NULL;
     }
 
+    p_dec->pf_init = 0;
+    p_dec->pf_decode = 0;
+    p_dec->pf_end = 0;
+    p_dec->pf_run = 0;
+
     /* Select a new ES */
     INSERT_ELEM( p_input->stream.pp_selected_es,
                  p_input->stream.i_selected_es_number,
                  p_input->stream.i_selected_es_number,
                  p_es );
 
+    /* Allocate the memory needed to store the decoder's fifo */
+    //p_dec->p_fifo = (decoder_fifo_t *)malloc(sizeof(decoder_fifo_t));
+    p_dec->p_fifo = vlc_object_create( p_input, VLC_OBJECT_DECODER_FIFO );
+    if( p_dec->p_fifo == NULL )
+    {
+        msg_Err( p_input, "out of memory" );
+        return NULL;
+    }
+
+    /* Initialize the decoder fifo */
+    //memset( p_dec->p_fifo, 0, sizeof(decoder_fifo_t) );
+    p_dec->p_module = NULL;
+
     /* Initialize the p_fifo structure */
-    vlc_mutex_init( p_input, &p_fifo->data_lock );
-    vlc_cond_init( p_input, &p_fifo->data_wait );
-    p_es->p_decoder_fifo = p_fifo;
-
-    p_fifo->i_id = p_es->i_id;
-    p_fifo->i_fourcc = p_es->i_fourcc;
-    p_fifo->p_demux_data   = p_es->p_demux_data;
-    p_fifo->p_waveformatex = p_es->p_waveformatex;
-    p_fifo->p_bitmapinfoheader = p_es->p_bitmapinfoheader;
-    p_fifo->p_stream_ctrl = &p_input->stream.control;
-    p_fifo->p_sout = p_input->stream.p_sout;
-
-    p_fifo->p_first = NULL;
-    p_fifo->pp_last = &p_fifo->p_first;
-    p_fifo->i_depth = 0;
-    p_fifo->b_die = p_fifo->b_error = 0;
-    p_fifo->p_packets_mgt = p_input->p_method_data;
-
-    vlc_object_attach( p_fifo, p_input );
-
-    return p_fifo;
+    vlc_mutex_init( p_input, &p_dec->p_fifo->data_lock );
+    vlc_cond_init( p_input, &p_dec->p_fifo->data_wait );
+    p_es->p_decoder_fifo = p_dec->p_fifo;
+
+    p_dec->p_fifo->i_id = p_es->i_id;
+    p_dec->p_fifo->i_fourcc = p_es->i_fourcc;
+    p_dec->p_fifo->p_demux_data   = p_es->p_demux_data;
+    p_dec->p_fifo->p_waveformatex = p_es->p_waveformatex;
+    p_dec->p_fifo->p_bitmapinfoheader = p_es->p_bitmapinfoheader;
+    p_dec->p_fifo->p_stream_ctrl = &p_input->stream.control;
+    p_dec->p_fifo->p_sout = p_input->stream.p_sout;
+
+    p_dec->p_fifo->p_first = NULL;
+    p_dec->p_fifo->pp_last = &p_dec->p_fifo->p_first;
+    p_dec->p_fifo->i_depth = 0;
+    p_dec->p_fifo->b_die = p_dec->p_fifo->b_error = 0;
+    p_dec->p_fifo->p_packets_mgt = p_input->p_method_data;
+
+    p_dec->p_fifo->p_dec = p_dec;
+
+    vlc_object_attach( p_dec->p_fifo, p_input );
+    vlc_object_attach( p_dec, p_input );
+
+    return p_dec;
+}
+
+/*****************************************************************************
+ * DecoderThread: the decoding main loop
+ *****************************************************************************/
+static int DecoderThread( decoder_t * p_dec )
+{
+    pes_packet_t  *p_pes;
+    data_packet_t *p_data;
+    block_t       *p_block;
+
+    /* Temporary wrapper to keep old decoder api functional */
+    if( p_dec->pf_run )
+    {
+        p_dec->pf_run( p_dec->p_fifo );
+        return 0;
+    }
+
+
+    /* Initialize the decoder */
+    p_dec->p_fifo->b_error = p_dec->pf_init( p_dec );
+
+    /* The decoder's main loop */
+    while( !p_dec->p_fifo->b_die && !p_dec->p_fifo->b_error )
+    {
+        int i_size;
+
+        input_ExtractPES( p_dec->p_fifo, &p_pes );
+        if( !p_pes )
+        {
+            p_dec->p_fifo->b_error = 1;
+            break;
+        }
+
+       for( i_size = 0, p_data = p_pes->p_first;
+            p_data != NULL; p_data = p_data->p_next )
+       {
+           i_size += p_data->p_payload_end - p_data->p_payload_start;
+       }
+       p_block = block_New( p_dec, i_size );
+       for( i_size = 0, p_data = p_pes->p_first;
+            p_data != NULL; p_data = p_data->p_next )
+       {
+            memcpy( p_block->p_buffer + i_size, p_data->p_payload_start,
+                   p_data->p_payload_end - p_data->p_payload_start );
+            i_size += p_data->p_payload_end - p_data->p_payload_start;
+       }
+
+        p_block->i_pts = p_pes->i_pts;
+        p_block->i_dts = p_pes->i_dts;
+        p_dec->p_fifo->b_error = p_dec->pf_decode( p_dec, p_block );
+
+        input_DeletePES( p_dec->p_fifo->p_packets_mgt, p_pes );
+    }
+
+    /* If b_error is set, the decoder thread enters the error loop */
+    if( p_dec->p_fifo->b_error )
+    {
+        /* Wait until a `die' order is sent */
+        while( !p_dec->p_fifo->b_die )
+        {
+            /* Trash all received PES packets */
+            input_ExtractPES( p_dec->p_fifo, NULL );
+        }
+    }
+
+    /* End of the decoder */
+    p_dec->pf_end( p_dec );
+
+    return 0;
 }
 
 /*****************************************************************************
  * DeleteDecoderFifo: destroy a decoder_fifo_t
  *****************************************************************************/
-static void DeleteDecoderFifo( decoder_fifo_t * p_fifo )
+static void DeleteDecoder( decoder_t * p_dec )
 {
-    vlc_object_detach( p_fifo );
+    vlc_object_detach( p_dec );
+    vlc_object_detach( p_dec->p_fifo );
 
-    msg_Dbg( p_fifo, "killing decoder for 0x%x, fourcc `%4.4s', %d PES in FIFO",
-                     p_fifo->i_id, (char*)&p_fifo->i_fourcc, p_fifo->i_depth );
+    msg_Dbg( p_dec,
+             "killing decoder for 0x%x, fourcc `%4.4s', %d PES in FIFO",
+             p_dec->p_fifo->i_id, (char*)&p_dec->p_fifo->i_fourcc,
+             p_dec->p_fifo->i_depth );
 
     /* Free all packets still in the decoder fifo. */
-    input_DeletePES( p_fifo->p_packets_mgt,
-                     p_fifo->p_first );
+    input_DeletePES( p_dec->p_fifo->p_packets_mgt,
+                     p_dec->p_fifo->p_first );
 
     /* Destroy the lock and cond */
-    vlc_cond_destroy( &p_fifo->data_wait );
-    vlc_mutex_destroy( &p_fifo->data_lock );
-}
+    vlc_cond_destroy( &p_dec->p_fifo->data_wait );
+    vlc_mutex_destroy( &p_dec->p_fifo->data_lock );
 
+    /* Free fifo */
+    vlc_object_destroy( p_dec->p_fifo );
+    //free( p_dec->p_fifo );
+}
index 2e7db1dce3fdc94761bd023cbc80d557dac4605e..cd686c49a68f2d2c2dcc20b45232a79dfeb9553d 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
- * block.c
+ * block.c: Data blocks management functions
  *****************************************************************************
  * Copyright (C) 2003 VideoLAN
- * $Id: block.c,v 1.1 2003/08/23 22:49:50 fenrir Exp $
+ * $Id: block.c,v 1.2 2003/09/02 20:19:26 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@videolan.org>
  *
@@ -38,8 +38,9 @@ struct block_sys_t
     uint8_t     *p_allocated_buffer;
     int         i_allocated_buffer;
 
-    vlc_bool_t  b_modify;       /* has it be put in modify state */
-    int         i_duplicated;   /* how many times it has been duplicated (only content) */
+    vlc_bool_t  b_modify;       /* has it been put in modified state */
+    int         i_duplicated;   /* how many times has the content been
+                                 * duplicated */
 
 };
 
@@ -104,6 +105,7 @@ static block_t *BlockModify( block_t *p_block, vlc_bool_t b_will_modify )
 
     return p_mod;
 }
+
 static block_t *BlockDuplicate( block_t *p_block )
 {
     block_t *p_dup;
@@ -128,15 +130,16 @@ static block_t *BlockRealloc( block_t *p_block, int i_prebody, int i_body )
 {
 
     vlc_mutex_lock( &p_block->p_sys->lock );
-    if( i_prebody < 0 ||
-        ( p_block->p_buffer - i_prebody > p_block->p_sys->p_allocated_buffer ) )
+    if( i_prebody < 0 || p_block->p_buffer - i_prebody >
+        p_block->p_sys->p_allocated_buffer )
     {
         p_block->p_buffer -= i_prebody;
         p_block->i_buffer += i_prebody;
         i_prebody = 0;
     }
     if( i_body < 0 ||
-        ( p_block->p_buffer + i_body < p_block->p_sys->p_allocated_buffer + p_block->p_sys->i_allocated_buffer ) )
+        p_block->p_buffer + i_body < p_block->p_sys->p_allocated_buffer +
+        p_block->p_sys->i_allocated_buffer )
     {
         p_block->i_buffer = i_body;
         i_body = 0;
@@ -147,7 +150,8 @@ static block_t *BlockRealloc( block_t *p_block, int i_prebody, int i_body )
     {
         block_t *p_rea = block_New( p_block->p_manager, i_prebody + i_body );
 
-        memcpy( &p_rea->p_buffer[i_prebody], p_block->p_buffer, p_block->i_buffer );
+        memcpy( &p_rea->p_buffer[i_prebody], p_block->p_buffer,
+                p_block->i_buffer );
 
         return p_rea;
     }
@@ -160,7 +164,9 @@ static block_t *BlockRealloc( block_t *p_block, int i_prebody, int i_body )
         i_start = p_rea->p_buffer - p_rea->p_sys->p_allocated_buffer;
 
         p_rea->p_sys->i_allocated_buffer += i_body - p_rea->i_buffer;
-        p_rea->p_sys->p_allocated_buffer = realloc( p_rea->p_sys->p_allocated_buffer, p_rea->p_sys->i_allocated_buffer );
+        p_rea->p_sys->p_allocated_buffer =
+            realloc( p_rea->p_sys->p_allocated_buffer,
+                     p_rea->p_sys->i_allocated_buffer );
 
         p_rea->p_buffer = &p_rea->p_sys->p_allocated_buffer[i_start];
         p_rea->i_buffer = i_body;
@@ -170,6 +176,7 @@ static block_t *BlockRealloc( block_t *p_block, int i_prebody, int i_body )
 
     return p_block;
 }
+
 /*****************************************************************************
  * Standard block management
  *
@@ -203,7 +210,6 @@ block_t *__block_New( vlc_object_t *p_obj, int i_size )
     block_t     *p_block;
     block_sys_t *p_sys;
 
-
     p_block = block_NewEmpty();
 
     p_block->i_buffer       = i_size;
@@ -218,7 +224,7 @@ block_t *__block_New( vlc_object_t *p_obj, int i_size )
     p_block->pf_realloc     = BlockRealloc;
 
     /* that should be ok (no comunication between multiple p_vlc) */
-    p_block->p_manager      = p_obj->p_vlc;
+    p_block->p_manager      = VLC_OBJECT( p_obj->p_vlc );
 
     p_block->p_sys = p_sys = malloc( sizeof( block_sys_t ) );
     vlc_mutex_init( p_obj, &p_sys->lock );
@@ -230,7 +236,7 @@ block_t *__block_New( vlc_object_t *p_obj, int i_size )
     return p_block;
 }
 
-void    block_ChainAppend( block_t **pp_list, block_t *p_block )
+void block_ChainAppend( block_t **pp_list, block_t *p_block )
 {
 
     if( *pp_list == NULL )
@@ -249,7 +255,7 @@ void    block_ChainAppend( block_t **pp_list, block_t *p_block )
     }
 }
 
-void    block_ChainRelease( block_t *p_block )
+void block_ChainRelease( block_t *p_block )
 {
     while( p_block )
     {
@@ -320,7 +326,7 @@ block_t *block_ChainGather( block_t *p_list )
 /*****************************************************************************
  * block_fifo_t managment
  *****************************************************************************/
-block_fifo_t * __block_FifoNew  ( vlc_object_t *p_obj )
+block_fifo_t *__block_FifoNew( vlc_object_t *p_obj )
 {
     block_fifo_t *p_fifo;
 
@@ -334,7 +340,7 @@ block_fifo_t * __block_FifoNew  ( vlc_object_t *p_obj )
     return p_fifo;
 }
 
-void           block_FifoRelease( block_fifo_t *p_fifo )
+void block_FifoRelease( block_fifo_t *p_fifo )
 {
     block_FifoEmpty( p_fifo );
     vlc_cond_destroy( &p_fifo->wait );
@@ -342,7 +348,7 @@ void           block_FifoRelease( block_fifo_t *p_fifo )
     free( p_fifo );
 }
 
-void            block_FifoEmpty( block_fifo_t *p_fifo )
+void block_FifoEmpty( block_fifo_t *p_fifo )
 {
     block_t *b;
 
@@ -362,7 +368,7 @@ void            block_FifoEmpty( block_fifo_t *p_fifo )
     vlc_mutex_unlock( &p_fifo->lock );
 }
 
-int           block_FifoPut    ( block_fifo_t *p_fifo, block_t *p_block )
+int block_FifoPut( block_fifo_t *p_fifo, block_t *p_block )
 {
     int i_size = 0;
     vlc_mutex_lock( &p_fifo->lock );
@@ -379,14 +385,14 @@ int           block_FifoPut    ( block_fifo_t *p_fifo, block_t *p_block )
 
     } while( p_block );
 
-    /* warm there is data in this fifo */
+    /* warn there is data in this fifo */
     vlc_cond_signal( &p_fifo->wait );
     vlc_mutex_unlock( &p_fifo->lock );
 
     return i_size;
 }
 
-block_t *      block_FifoGet    ( block_fifo_t *p_fifo )
+block_t *block_FifoGet( block_fifo_t *p_fifo )
 {
     block_t *b;
 
@@ -413,7 +419,7 @@ block_t *      block_FifoGet    ( block_fifo_t *p_fifo )
     return( b );
 }
 
-block_t *      block_FifoShow   ( block_fifo_t *p_fifo )
+block_t *block_FifoShow( block_fifo_t *p_fifo )
 {
     block_t *b;
 
@@ -432,7 +438,7 @@ block_t *      block_FifoShow   ( block_fifo_t *p_fifo )
 
 }
 
-block_t *      block_FifoGetFrame( block_fifo_t *p_fifo )
+block_t *block_FifoGetFrame( block_fifo_t *p_fifo )
 {
     block_t *b = NULL;
 
@@ -449,5 +455,3 @@ block_t *      block_FifoGetFrame( block_fifo_t *p_fifo )
 
     return b;
 }
-
-
index 333fbe147b26a2ef4a8b1f7bfd6d18e7212dac3f..6ff807675935c1728c3c639d89222e0dedfb622b 100644 (file)
@@ -2,7 +2,7 @@
  * objects.c: vlc_object_t handling
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: objects.c,v 1.37 2003/06/26 12:19:59 sam Exp $
+ * $Id: objects.c,v 1.38 2003/09/02 20:19:26 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -109,6 +109,10 @@ void * __vlc_object_create( vlc_object_t *p_this, int i_type )
             psz_type = "input";
             break;
         case VLC_OBJECT_DECODER:
+            i_size = sizeof(decoder_t);
+            psz_type = "decoder";
+            break;
+        case VLC_OBJECT_DECODER_FIFO: /* tmp for backward compat */
             i_size = sizeof(decoder_fifo_t);
             psz_type = "decoder";
             break;