]> git.sesse.net Git - vlc/commitdiff
* ALL: final improvements to the decoders/packetizers api.
authorGildas Bazin <gbazin@videolan.org>
Sun, 16 Nov 2003 21:07:31 +0000 (21:07 +0000)
committerGildas Bazin <gbazin@videolan.org>
Sun, 16 Nov 2003 21:07:31 +0000 (21:07 +0000)
   (There are still a few decoders/packetizers left to be converted but this shouldn't take too long).
* ALL: small improvements to the encoders api.

55 files changed:
include/aout_internal.h
include/audio_output.h
include/input_ext-intf.h
include/ninput.h
include/vlc_block_helper.h
include/vlc_codec.h
include/vlc_common.h
include/vlc_video.h
modules/codec/a52.c
modules/codec/adpcm.c
modules/codec/araw.c
modules/codec/cinepak.c
modules/codec/dts.c
modules/codec/dv.c
modules/codec/dvbsub.c
modules/codec/faad.c
modules/codec/ffmpeg/audio.c
modules/codec/ffmpeg/encoder.c
modules/codec/ffmpeg/ffmpeg.c
modules/codec/ffmpeg/ffmpeg.h
modules/codec/ffmpeg/video.c
modules/codec/flacdec.c
modules/codec/libmpeg2.c
modules/codec/lpcm.c
modules/codec/mpeg_audio.c
modules/codec/rawvideo.c
modules/codec/speex.c
modules/codec/spudec/spudec.c
modules/codec/subsdec.c
modules/codec/tarkin.c
modules/codec/theora.c
modules/codec/vorbis.c
modules/codec/xvid.c
modules/demux/a52sys.c
modules/demux/aac.c
modules/demux/asf/asf.c
modules/demux/au.c
modules/demux/avi/avi.c
modules/demux/livedotcom.cpp
modules/demux/mkv.cpp
modules/demux/mpeg/mpga.c
modules/demux/wav.c
modules/misc/dummy/Modules.am
modules/misc/dummy/decoder.c
modules/misc/dummy/dummy.c
modules/misc/dummy/dummy.h
modules/packetizer/copy.c
modules/packetizer/mpeg4audio.c
modules/stream_out/transcode.c
src/audio_output/common.c
src/audio_output/dec.c
src/input/input.c
src/input/input_dec.c
src/input/input_programs.c
src/libvlc.h

index 9f38dcb16e8b0b0d002383f84f16845aa092ec20..81e53885e0c09c468b81ebcc0a6977dabe7d2a22 100644 (file)
@@ -2,7 +2,7 @@
  * aout_internal.h : internal defines for audio output
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: aout_internal.h,v 1.41 2003/10/27 21:54:10 gbazin Exp $
+ * $Id: aout_internal.h,v 1.42 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -97,7 +97,7 @@ struct aout_fifo_t
 /*****************************************************************************
  * aout_filter_t : audio output filter
  *****************************************************************************/
-typedef struct aout_filter_t
+struct aout_filter_t
 {
     VLC_COMMON_MEMBERS
 
@@ -113,7 +113,7 @@ typedef struct aout_filter_t
                                          struct aout_buffer_t * );
     vlc_bool_t              b_in_place;
     vlc_bool_t              b_continuity;
-} aout_filter_t;
+};
 
 /*****************************************************************************
  * aout_mixer_t : audio output mixer
@@ -255,20 +255,10 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
                     aout_buffer_t * p_buffer );
 
 /* From filters.c : */
-int aout_FiltersCreatePipeline( aout_instance_t * p_aout,
-                                aout_filter_t ** pp_filters,
-                                int * pi_nb_filters,
-                                const audio_sample_format_t * p_input_format,
-                                const audio_sample_format_t * p_output_format );
-void aout_FiltersDestroyPipeline( aout_instance_t * p_aout,
-                                  aout_filter_t ** pp_filters,
-                                  int i_nb_filters );
-void aout_FiltersHintBuffers( aout_instance_t * p_aout,
-                              aout_filter_t ** pp_filters,
-                              int i_nb_filters, aout_alloc_t * p_first_alloc );
-void aout_FiltersPlay( aout_instance_t * p_aout,
-                       aout_filter_t ** pp_filters,
-                       int i_nb_filters, aout_buffer_t ** pp_input_buffer );
+VLC_EXPORT( int, aout_FiltersCreatePipeline, ( aout_instance_t * p_aout, aout_filter_t ** pp_filters, int * pi_nb_filters, const audio_sample_format_t * p_input_format, const audio_sample_format_t * p_output_format ) );
+VLC_EXPORT( void, aout_FiltersDestroyPipeline, ( aout_instance_t * p_aout, aout_filter_t ** pp_filters, int i_nb_filters ) );
+VLC_EXPORT( void, aout_FiltersPlay, ( aout_instance_t * p_aout, aout_filter_t ** pp_filters, int i_nb_filters, aout_buffer_t ** pp_input_buffer ) );
+void aout_FiltersHintBuffers( aout_instance_t * p_aout, aout_filter_t ** pp_filters, int i_nb_filters, aout_alloc_t * p_first_alloc );
 
 /* From mixer.c : */
 int aout_MixerNew( aout_instance_t * p_aout );
index 2971b76cb2bd311d46090689b12f33d9cf1af420..98820eadac78511791ea54e9982e9ee00ee3b086 100644 (file)
@@ -2,7 +2,7 @@
  * audio_output.h : audio output interface
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: audio_output.h,v 1.83 2003/10/08 21:01:07 gbazin Exp $
+ * $Id: audio_output.h,v 1.84 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
  *****************************************************************************
  * This structure defines a format for audio samples.
  *****************************************************************************/
-struct audio_sample_format_t
+struct audio_format_t
 {
     vlc_fourcc_t        i_format;
+
     unsigned int        i_rate;
+
     /* Describes the channels configuration of the samples (ie. number of
      * channels which are available in the buffer, and positions). */
     uint32_t            i_physical_channels;
+
     /* Describes from which original channels, before downmixing, the
      * buffer is derived. */
     uint32_t            i_original_channels;
+
     /* Optional - for A/52, SPDIF and DTS types : */
     /* Bytes used by one compressed frame, depends on bitrate. */
     unsigned int        i_bytes_per_frame;
+
     /* Number of sampleframes contained in one compressed frame. */
     unsigned int        i_frame_length;
     /* Please note that it may be completely arbitrary - buffers are not
@@ -48,6 +53,12 @@ struct audio_sample_format_t
      * just here for the division :
      * buffer_size = i_nb_samples * i_bytes_per_frame / i_frame_length
      */
+
+    /* FIXME ? (used by the codecs) */
+    int i_bitrate;
+    int i_channels;
+    int i_blockalign;
+    int i_bitspersample;
 };
 
 #define AOUT_FMTS_IDENTICAL( p_first, p_second ) (                          \
index 20e39fddf39dbba32fc9f696ebc9c6e0f0e6cde6..d07de40c59c234618a5e7276a64d50c10f5272c7 100644 (file)
@@ -4,7 +4,7 @@
  * control the pace of reading.
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_ext-intf.h,v 1.97 2003/11/06 16:36:41 nitrox Exp $
+ * $Id: input_ext-intf.h,v 1.98 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -26,6 +26,8 @@
 #ifndef _VLC_INPUT_EXT_INTF_H
 #define _VLC_INPUT_EXT_INTF_H 1
 
+#include "ninput.h"
+
 /*
  * Communication input -> interface
  */
@@ -65,6 +67,7 @@ struct es_descriptor_t
     unsigned int            i_pes_real_size;   /* as indicated by the header */
 
     /* Decoder information */
+    es_format_t             fmt;
     decoder_fifo_t *        p_decoder_fifo;
     void *                  p_waveformatex;
     void *                  p_bitmapinfoheader;
index c9a13caf84f67aadd64434bf7b2c8803d47ca28c..e2b5b827e090ccbe28c1bc3d88ac73aadc6adcb9 100644 (file)
@@ -2,7 +2,7 @@
  * ninput.h
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: ninput.h,v 1.14 2003/11/13 17:59:34 gbazin Exp $
+ * $Id: ninput.h,v 1.15 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -24,6 +24,9 @@
 #ifndef _NINPUT_H
 #define _NINPUT_H 1
 
+#include "audio_output.h"
+#include "vlc_video.h"
+
 enum es_extra_type_e
 {
     ES_EXTRA_TYPE_UNKNOWN,
@@ -32,6 +35,12 @@ enum es_extra_type_e
     ES_EXTRA_TYPE_SUBHEADER
 };
 
+typedef struct subs_format_t
+{
+    char *psz_encoding;
+
+} subs_format_t;
+
 typedef struct
 {
     int             i_cat;
@@ -47,31 +56,16 @@ typedef struct
     char            *psz_language;
     char            *psz_description;
 
-    struct
-    {
-        int i_samplerate;
-        int i_channels;
-        int i_bitrate;
-        int i_blockalign;
-        int i_bitspersample;
-    } audio;
-
-    struct
-    {
-        int i_width;
-        int i_height;
-        int i_display_width;
-        int i_display_height;
-    } video;
-
-    struct
-    {
-        char *psz_encoding;
-    } subs;
+    audio_format_t audio;
+    video_format_t video;
+    subs_format_t  subs;
+
+    int     i_bitrate;
 
     int     i_extra_type;
     int     i_extra;
     void    *p_extra;
+
 } es_format_t;
 
 static inline void es_format_Init( es_format_t *fmt,
@@ -84,18 +78,9 @@ static inline void es_format_Init( es_format_t *fmt,
     fmt->psz_language           = NULL;
     fmt->psz_description        = NULL;
 
-    fmt->audio.i_samplerate     = 0;
-    fmt->audio.i_channels       = 0;
-    fmt->audio.i_bitrate        = 0;
-    fmt->audio.i_blockalign     = 0;
-    fmt->audio.i_bitspersample  = 0;
-
-    fmt->video.i_width          = 0;
-    fmt->video.i_height         = 0;
-    fmt->video.i_display_width  = 0;
-    fmt->video.i_display_height = 0;
-
-    fmt->subs.psz_encoding      = NULL;
+    memset( &fmt->audio, 0, sizeof(audio_format_t) );
+    memset( &fmt->video, 0, sizeof(video_format_t) );
+    memset( &fmt->subs, 0, sizeof(subs_format_t) );
 
     fmt->i_extra_type           = ES_EXTRA_TYPE_UNKNOWN;
     fmt->i_extra                = 0;
index 1e8676b536157331b731e2ad04664989230c35de..bb155023be58eda299e89e169b2deffb352220d4 100644 (file)
@@ -2,7 +2,7 @@
  * vlc_block_helper.h: Helper functions for data blocks management.
  *****************************************************************************
  * Copyright (C) 2003 VideoLAN
- * $Id: vlc_block_helper.h,v 1.4 2003/10/23 20:51:20 gbazin Exp $
+ * $Id: vlc_block_helper.h,v 1.5 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
@@ -29,26 +29,38 @@ typedef struct block_bytestream_t
     block_t             *p_chain;
     block_t             *p_block;
     int                 i_offset;
+
 } block_bytestream_t;
 
-#define block_BytestreamInit( a, b, c ) __block_BytestreamInit( VLC_OBJECT(a), b, c )
+#define block_BytestreamInit( a ) __block_BytestreamInit( VLC_OBJECT(a) )
 
 /*****************************************************************************
  * block_bytestream_t management
  *****************************************************************************/
-static inline block_bytestream_t __block_BytestreamInit( vlc_object_t *p_obj,
-                                           block_t *p_block, int i_offset )
+static inline block_bytestream_t __block_BytestreamInit( vlc_object_t *p_obj )
 {
     block_bytestream_t bytestream;
 
-    bytestream.i_offset = i_offset;
-    bytestream.p_block = p_block;
-    bytestream.p_chain = p_block;
+    bytestream.i_offset = 0;
+    bytestream.p_chain = bytestream.p_block = NULL;
 
     return bytestream;
 }
 
-static inline block_t *block_BytestreamFlush( block_bytestream_t *p_bytestream)
+static inline void block_BytestreamRelease( block_bytestream_t *p_bytestream )
+{
+    while( p_bytestream->p_chain )
+    {
+        block_t *p_next;
+        p_next = p_bytestream->p_chain->p_next;
+        p_bytestream->p_chain->pf_release( p_bytestream->p_chain );
+        p_bytestream->p_chain = p_next;
+    }
+    p_bytestream->i_offset = 0;
+    p_bytestream->p_chain = p_bytestream->p_block = NULL;
+}
+
+static inline void block_BytestreamFlush( block_bytestream_t *p_bytestream )
 {
     while( p_bytestream->p_chain != p_bytestream->p_block )
     {
@@ -57,8 +69,54 @@ static inline block_t *block_BytestreamFlush( block_bytestream_t *p_bytestream)
         p_bytestream->p_chain->pf_release( p_bytestream->p_chain );
         p_bytestream->p_chain = p_next;
     }
+    while( p_bytestream->p_block &&
+           (p_bytestream->p_block->i_buffer - p_bytestream->i_offset) == 0 )
+    {
+        block_t *p_next;
+        p_next = p_bytestream->p_chain->p_next;
+        p_bytestream->p_chain->pf_release( p_bytestream->p_chain );
+        p_bytestream->p_chain = p_bytestream->p_block = p_next;
+        p_bytestream->i_offset = 0;
+    }
+}
 
-    return p_bytestream->p_chain;
+static inline void block_BytestreamPush( block_bytestream_t *p_bytestream,
+                                         block_t *p_block )
+{
+    block_ChainAppend( &p_bytestream->p_chain, p_block );
+    if( !p_bytestream->p_block ) p_bytestream->p_block = p_block;
+}
+
+static inline block_t *block_BytestreamPop( block_bytestream_t *p_bytestream )
+{
+    block_t *p_block;
+
+    block_BytestreamFlush( p_bytestream );
+
+    p_block = p_bytestream->p_block;
+    if( p_block == NULL )
+    {
+        return NULL;
+    }
+    else if( !p_block->p_next )
+    {
+        p_block->p_buffer += p_bytestream->i_offset;
+        p_block->i_buffer -= p_bytestream->i_offset;
+        p_bytestream->i_offset = 0;
+        p_bytestream->p_chain = p_bytestream->p_block = NULL;
+        return p_block;
+    }
+
+    while( p_block->p_next && p_block->p_next->p_next )
+        p_block = p_block->p_next;
+
+    {
+        block_t *p_block_old = p_block;
+        p_block = p_block->p_next;
+        p_block_old->p_next = NULL;
+    }
+
+    return p_block;
 }
 
 static inline int block_SkipByte( block_bytestream_t *p_bytestream )
@@ -151,6 +209,34 @@ static inline int block_GetByte( block_bytestream_t *p_bytestream,
     return VLC_EGENERIC;
 }
 
+static inline int block_WaitBytes( block_bytestream_t *p_bytestream,
+                                   int i_data )
+{
+    block_t *p_block;
+    int i_offset, i_copy, i_size;
+
+    /* Check we have that much data */
+    i_offset = p_bytestream->i_offset;
+    i_size = i_data;
+    i_copy = 0;
+    for( p_block = p_bytestream->p_block;
+         p_block != NULL; p_block = p_block->p_next )
+    {
+        i_copy = __MIN( i_size, p_block->i_buffer - i_offset );
+        i_size -= i_copy;
+        i_offset = 0;
+
+        if( !i_size ) break;
+    }
+
+    if( i_size )
+    {
+        /* Not enough data, bail out */
+        return VLC_EGENERIC;
+    }
+    return VLC_SUCCESS;
+}
+
 static inline int block_SkipBytes( block_bytestream_t *p_bytestream,
                                    int i_data )
 {
index 5acb0746ee8c1a979e7cfcb3481e9efc0a0b6b13..180538a09b9094c56e0a59993c1d17da7f030e26 100644 (file)
@@ -2,7 +2,7 @@
  * vlc_codec.h: codec related structures
  *****************************************************************************
  * Copyright (C) 1999-2003 VideoLAN
- * $Id: vlc_codec.h,v 1.3 2003/11/05 18:59:01 gbazin Exp $
+ * $Id: vlc_codec.h,v 1.4 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
 #ifndef _VLC_CODEC_H
 #define _VLC_CODEC_H 1
 
+#include "ninput.h"
+
 /**
  * \file
  * This file defines the structure and types used by decoders and encoders
  */
 
+typedef struct decoder_owner_sys_t decoder_owner_sys_t;
+
 /**
  * \defgroup decoder Decoder
  *
@@ -43,15 +47,39 @@ struct decoder_t
     /* Module properties */
     module_t *          p_module;
     decoder_sys_t *     p_sys;
-    int                 ( * pf_init )  ( decoder_t * );
+
+    /* Deprecated */
     int                 ( * pf_decode )( decoder_t *, block_t * );
-    int                 ( * pf_end )   ( decoder_t * );
+    decoder_fifo_t *    p_fifo;
+    int                 ( * pf_run ) ( decoder_fifo_t * );
+    /* End deprecated */
 
-    /* Input properties */
-    decoder_fifo_t *    p_fifo;                /* stores the PES stream data */
+    picture_t *         ( * pf_decode_video )( decoder_t *, block_t ** );
+    aout_buffer_t *     ( * pf_decode_audio )( decoder_t *, block_t ** );
+    void                ( * pf_decode_sub)   ( decoder_t *, block_t ** );
+    block_t *           ( * pf_packetize )   ( decoder_t *, block_t ** );
 
-    /* Tmp field for old decoder api */
-    int                 ( * pf_run ) ( decoder_fifo_t * );
+    /* Input format ie from demuxer (XXX: a lot of field could be invalid) */
+    es_format_t         fmt_in;
+
+    /* Output format of decoder/packetizer */
+    es_format_t         fmt_out;
+
+    /*
+     * Buffers allocation
+     */
+
+    /* Audio output callbacks */
+    aout_buffer_t * ( * pf_aout_buffer_new) ( decoder_t *, int );
+    void            ( * pf_aout_buffer_del) ( decoder_t *, aout_buffer_t * );
+
+    /* Video output callbacks */
+    picture_t     * ( * pf_vout_buffer_new) ( decoder_t * );
+    void            ( * pf_vout_buffer_del) ( decoder_t *, picture_t * );
+
+
+    /* Private structure for the owner of the decoder */
+    decoder_owner_sys_t *p_owner;
 };
 
 /**
@@ -79,22 +107,12 @@ struct encoder_t
     block_t *           ( * pf_encode_audio )( encoder_t *, aout_buffer_t * );
 
     /* Properties of the input data fed to the encoder */
-    union {
-        audio_sample_format_t audio;
-        video_frame_format_t  video;
-    } format;
+    es_format_t         fmt_in;
 
     /* Properties of the output of the encoder */
-    vlc_fourcc_t i_fourcc;
-    int          i_bitrate;
-
-    int          i_extra_data;
-    uint8_t      *p_extra_data;
+    es_format_t         fmt_out;
 
     /* FIXME: move these to the ffmpeg encoder */
-    int i_frame_rate;
-    int i_frame_rate_base;
-    int i_aspect;
     int i_key_int;
     int i_b_frames;
     int i_vtolerance;
index 20398d00a7d9fc3c8702ae3697acbafeaa962c3f..1aed2663484923ca131990c3d254fab009ff26a8 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.85 2003/10/29 17:32:54 zorglub Exp $
+ * $Id: vlc_common.h,v 1.86 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@via.ecp.fr>
  *          Vincent Seguin <seguin@via.ecp.fr>
@@ -229,14 +229,17 @@ typedef struct aout_sys_t aout_sys_t;
 typedef struct aout_fifo_t aout_fifo_t;
 typedef struct aout_input_t aout_input_t;
 typedef struct aout_buffer_t aout_buffer_t;
-typedef struct audio_sample_format_t audio_sample_format_t;
+typedef struct audio_format_t audio_format_t;
+typedef audio_format_t audio_sample_format_t;
 typedef struct audio_date_t audio_date_t;
+typedef struct aout_filter_t aout_filter_t;
 
 /* Video */
 typedef struct vout_thread_t vout_thread_t;
 typedef struct vout_sys_t vout_sys_t;
 typedef struct chroma_sys_t chroma_sys_t;
-typedef struct video_frame_format_t video_frame_format_t;
+typedef struct video_format_t video_format_t;
+typedef video_format_t video_frame_format_t;
 typedef struct picture_t picture_t;
 typedef struct picture_sys_t picture_sys_t;
 typedef struct picture_heap_t picture_heap_t;
index 66b3564f1c20aff3b5bf7a3005756cb12154f8a2..70aedd27e57783df331b2ef3dfbdf840ddcc6d21 100644 (file)
@@ -4,7 +4,7 @@
  * includes all common video types and constants.
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: vlc_video.h,v 1.5 2003/10/24 21:27:06 gbazin Exp $
+ * $Id: vlc_video.h,v 1.6 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *
@@ -28,7 +28,7 @@
 /**
  * Description of a video frame
  */
-struct video_frame_format_t
+struct video_format_t
 {
     vlc_fourcc_t i_chroma;                               /**< picture chroma */
     unsigned int i_aspect;                                 /**< aspect ratio */
@@ -42,6 +42,8 @@ struct video_frame_format_t
 
     unsigned int i_bits_per_pixel;             /**< number of bits per pixel */
 
+    unsigned int i_frame_rate;                     /**< frame rate numerator */
+    unsigned int i_frame_rate_base;              /**< frame rate denominator */
 };
 
 /**
index 8ea4310939e67c9613f94aa3d5c21e9601bd78fb..7f6b1f1446d017b676113431e684c833ea467967 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
- * a52.c: A/52 basic parser
+ * a52.c: parse A/52 audio sync info and packetize the stream
  *****************************************************************************
  * Copyright (C) 2001-2002 VideoLAN
- * $Id: a52.c,v 1.28 2003/10/23 20:51:20 gbazin Exp $
+ * $Id: a52.c,v 1.29 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Stéphane Borel <stef@via.ecp.fr>
  *          Christophe Massiot <massiot@via.ecp.fr>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>                                              /* memcpy() */
-#include <fcntl.h>
 
 #include <vlc/vlc.h>
 #include <vlc/decoder.h>
 #include <vlc/input.h>
-#include <vlc/aout.h>
-#include <vlc/sout.h>
 
 #include "vlc_block_helper.h"
 
@@ -52,33 +49,16 @@ struct decoder_sys_t
     /*
      * Input properties
      */
-    int        i_state;
+    int i_state;
 
-    block_t *p_chain;
     block_bytestream_t bytestream;
 
-    /*
-     * Decoder output properties
-     */
-    aout_instance_t *     p_aout;                                  /* opaque */
-    aout_input_t *        p_aout_input;                            /* opaque */
-    audio_sample_format_t aout_format;
-    aout_buffer_t *       p_aout_buffer; /* current aout buffer being filled */
-
-    /*
-     * Packetizer output properties
-     */
-    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 */
-    audio_date_t          end_date;
+    audio_date_t   end_date;
 
-    mtime_t pts;
+    mtime_t i_pts;
     int i_frame_size, i_bit_rate;
     unsigned int i_rate, i_channels, i_channels_conf;
 
@@ -89,7 +69,9 @@ enum {
     STATE_NOSYNC,
     STATE_SYNC,
     STATE_HEADER,
-    STATE_DATA
+    STATE_NEXT_SYNC,
+    STATE_GET_DATA,
+    STATE_SEND_DATA
 };
 
 /****************************************************************************
@@ -97,17 +79,14 @@ enum {
  ****************************************************************************/
 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 CloseDecoder  ( vlc_object_t * );
+static void *DecodeBlock  ( decoder_t *, block_t ** );
 
 static int  SyncInfo      ( const byte_t *, int *, 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 * );
+static uint8_t       *GetOutBuffer ( decoder_t *, void ** );
+static aout_buffer_t *GetAoutBuffer( decoder_t * );
+static block_t       *GetSoutBuffer( decoder_t * );
 
 /*****************************************************************************
  * Module descriptor
@@ -115,12 +94,12 @@ static int SendOutBuffer( decoder_t * );
 vlc_module_begin();
     set_description( _("A/52 parser") );
     set_capability( "decoder", 100 );
-    set_callbacks( OpenDecoder, NULL );
+    set_callbacks( OpenDecoder, CloseDecoder );
 
     add_submodule();
     set_description( _("A/52 audio packetizer") );
     set_capability( "packetizer", 10 );
-    set_callbacks( OpenPacketizer, NULL );
+    set_callbacks( OpenPacketizer, CloseDecoder );
 vlc_module_end();
 
 /*****************************************************************************
@@ -129,25 +108,38 @@ vlc_module_end();
 static int OpenDecoder( vlc_object_t *p_this )
 {
     decoder_t *p_dec = (decoder_t*)p_this;
+    decoder_sys_t *p_sys;
 
-    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('a','5','2',' ')
-         && p_dec->p_fifo->i_fourcc != VLC_FOURCC('a','5','2','b') )
+    if( p_dec->fmt_in.i_codec != VLC_FOURCC('a','5','2',' ')
+          && p_dec->fmt_in.i_codec != VLC_FOURCC('a','5','2','b') )
     {
         return VLC_EGENERIC;
     }
 
-    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 =
+    if( ( p_dec->p_sys = 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;
+
+    /* Misc init */
+    p_sys->b_packetizer = VLC_FALSE;
+    p_sys->i_state = STATE_NOSYNC;
+    aout_DateSet( &p_sys->end_date, 0 );
+
+    p_sys->bytestream = block_BytestreamInit( p_dec );
+
+    /* Set output properties */
+    p_dec->fmt_out.i_cat = AUDIO_ES;
+    p_dec->fmt_out.i_codec = VLC_FOURCC('a','5','2',' ');
+
+    /* Set callback */
+    p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
+        DecodeBlock;
+    p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
+        DecodeBlock;
 
     return VLC_SUCCESS;
 }
@@ -163,68 +155,38 @@ static int OpenPacketizer( vlc_object_t *p_this )
     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;
-    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_dec->p_sys->p_chain = NULL;
-
-    return VLC_SUCCESS;
-}
-
 /****************************************************************************
- * RunDecoder: the whole thing
+ * DecodeBlock: the whole thing
  ****************************************************************************
  * This function is called just after the thread is launched.
  ****************************************************************************/
-static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
     uint8_t p_header[A52_HEADER_SIZE];
+    uint8_t *p_buf;
+    void *p_out_buffer;
 
-    if( !aout_DateGet( &p_sys->end_date ) && !p_block->i_pts )
+    if( !pp_block || !*pp_block ) return NULL;
+
+    if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )
     {
         /* We've just started the stream, wait for the first PTS. */
-        block_Release( p_block );
-        return VLC_SUCCESS;
+        block_Release( *pp_block );
+        return NULL;
     }
 
-    if( p_block->b_discontinuity )
+    if( (*pp_block)->b_discontinuity )
     {
-        p_sys->i_state = STATE_SYNC;
+        p_sys->i_state = STATE_NOSYNC;
     }
 
-    if( p_sys->p_chain )
-    {
-        block_ChainAppend( &p_sys->p_chain, p_block );
-    }
-    else
-    {
-        block_ChainAppend( &p_sys->p_chain, p_block );
-        p_sys->bytestream = block_BytestreamInit( p_dec, p_sys->p_chain, 0 );
-    }
+    block_BytestreamPush( &p_sys->bytestream, *pp_block );
 
     while( 1 )
     {
         switch( p_sys->i_state )
         {
-
         case STATE_NOSYNC:
             while( block_PeekBytes( &p_sys->bytestream, p_header, 2 )
                    == VLC_SUCCESS )
@@ -238,30 +200,21 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
             }
             if( p_sys->i_state != STATE_SYNC )
             {
-                if( block_PeekByte( &p_sys->bytestream, p_header )
-                    == VLC_SUCCESS && p_header[0] == 0x0b )
-                {
-                    /* Start of a sync word, need more data */
-                    return VLC_SUCCESS;
-                }
-
-                block_ChainRelease( p_sys->p_chain );
-                p_sys->p_chain = NULL;
+               block_BytestreamFlush( &p_sys->bytestream );
 
                 /* Need more data */
-                return VLC_SUCCESS;
+                return NULL;
             }
 
         case STATE_SYNC:
             /* New frame, set the Presentation Time Stamp */
-            p_sys->pts = p_sys->bytestream.p_block->i_pts;
-            if( p_sys->pts != 0 &&
-                p_sys->pts != aout_DateGet( &p_sys->end_date ) )
+            p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
+            if( p_sys->i_pts != 0 &&
+                p_sys->i_pts != aout_DateGet( &p_sys->end_date ) )
             {
-                aout_DateSet( &p_sys->end_date, p_sys->pts );
+                aout_DateSet( &p_sys->end_date, p_sys->i_pts );
             }
             p_sys->i_state = STATE_HEADER;
-            break;
 
         case STATE_HEADER:
             /* Get A/52 frame header (A52_HEADER_SIZE bytes) */
@@ -269,7 +222,7 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
                                  A52_HEADER_SIZE ) != VLC_SUCCESS )
             {
                 /* Need more data */
-                return VLC_SUCCESS;
+                return NULL;
             }
 
             /* Check if frame is valid and get frame info */
@@ -285,247 +238,160 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
                 p_sys->i_state = STATE_NOSYNC;
                 break;
             }
-            p_sys->i_state = STATE_DATA;
+            p_sys->i_state = STATE_NEXT_SYNC;
 
-        case STATE_DATA:
-            /* TODO: If p_block == NULL, flush the buffer without checking the
+        case STATE_NEXT_SYNC:
+            /* TODO: If pp_block == NULL, flush the buffer without checking the
              * next sync word */
 
-           /* Check if next expected frame contains the sync word */
-           if( block_PeekOffsetBytes( &p_sys->bytestream,
-                                      p_sys->i_frame_size, p_header, 2 )
-               != VLC_SUCCESS )
-           {
-               /* Need more data */
-               return VLC_SUCCESS;
-           }
-
-           if( p_header[0] != 0x0b || p_header[1] != 0x77 )
-           {
-               msg_Dbg( p_dec, "emulated sync word "
-                        "(no sync on following frame)" );
-               p_sys->i_state = STATE_NOSYNC;
-               block_SkipByte( &p_sys->bytestream );
-               break;
+            /* Check if next expected frame contains the sync word */
+            if( block_PeekOffsetBytes( &p_sys->bytestream,
+                                       p_sys->i_frame_size, p_header, 2 )
+                != VLC_SUCCESS )
+            {
+                /* Need more data */
+                return NULL;
             }
 
-            if( !p_sys->p_out_buffer )
-            if( GetOutBuffer( p_dec, &p_sys->p_out_buffer ) != VLC_SUCCESS )
+            if( p_header[0] != 0x0b || p_header[1] != 0x77 )
             {
-                return VLC_EGENERIC;
+                msg_Dbg( p_dec, "emulated sync word "
+                         "(no sync on following frame)" );
+                p_sys->i_state = STATE_NOSYNC;
+                block_SkipByte( &p_sys->bytestream );
+                break;
             }
+            p_sys->i_state = STATE_SEND_DATA;
+            break;
 
-            /* Copy the whole frame into the buffer */
-            if( block_GetBytes( &p_sys->bytestream, p_sys->p_out_buffer,
-                                p_sys->i_frame_size ) != VLC_SUCCESS )
+        case STATE_GET_DATA:
+            /* Make sure we have enough data.
+             * (Not useful if we went through NEXT_SYNC) */
+            if( block_WaitBytes( &p_sys->bytestream,
+                                 p_sys->i_frame_size ) != VLC_SUCCESS )
             {
                 /* Need more data */
-                return VLC_SUCCESS;
+                return NULL;
             }
+            p_sys->i_state = STATE_SEND_DATA;
 
-            p_sys->p_chain = block_BytestreamFlush( &p_sys->bytestream );
+        case STATE_SEND_DATA:
+            if( !(p_buf = GetOutBuffer( p_dec, &p_out_buffer )) )
+            {
+                //p_dec->b_error = VLC_TRUE;
+                return NULL;
+            }
 
-            SendOutBuffer( p_dec );
-            p_sys->i_state = STATE_NOSYNC;
+            /* Copy the whole frame into the buffer. When we reach this point
+             * we already know we have enough data available. */
+            block_GetBytes( &p_sys->bytestream, p_buf, p_sys->i_frame_size );
 
             /* Make sure we don't reuse the same pts twice */
-            if( p_sys->pts == p_sys->bytestream.p_block->i_pts )
-                p_sys->pts = p_sys->bytestream.p_block->i_pts = 0;
-        }
-    }
+            if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
+                p_sys->i_pts = p_sys->bytestream.p_block->i_pts = 0;
 
-    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 );
-        }
+            /* So p_block doesn't get re-added several times */
+            *pp_block = block_BytestreamPop( &p_sys->bytestream );
 
-        aout_DecDelete( p_dec->p_sys->p_aout, p_dec->p_sys->p_aout_input );
-    }
+            p_sys->i_state = STATE_NOSYNC;
 
-    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 );
+            return p_out_buffer;
         }
-
-        sout_InputDelete( p_dec->p_sys->p_sout_input );
     }
 
-    if( p_dec->p_sys->p_chain ) block_ChainRelease( p_dec->p_sys->p_chain );
-
-    free( p_dec->p_sys );
-
-    return VLC_SUCCESS;
+    return NULL;
 }
 
 /*****************************************************************************
- * GetOutBuffer:
+ * CloseDecoder: clean up the decoder
  *****************************************************************************/
-static int GetOutBuffer( decoder_t *p_dec, uint8_t **pp_out_buffer )
+static void CloseDecoder( vlc_object_t *p_this )
 {
+    decoder_t *p_dec = (decoder_t*)p_this;
     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 );
-        *pp_out_buffer =
-            p_sys->p_aout_buffer ? p_sys->p_aout_buffer->p_buffer : NULL;
-    }
+    block_BytestreamRelease( &p_sys->bytestream );
 
-    return i_ret;
+    free( p_sys );
 }
 
 /*****************************************************************************
- * GetAoutBuffer:
+ * GetOutBuffer:
  *****************************************************************************/
-static int GetAoutBuffer( decoder_t *p_dec, aout_buffer_t **pp_buffer )
+static uint8_t *GetOutBuffer( decoder_t *p_dec, void **pp_out_buffer )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
+    uint8_t *p_buf;
 
-    if( p_sys->p_aout_input != NULL &&
-        ( p_sys->aout_format.i_rate != p_sys->i_rate
-        || p_sys->aout_format.i_original_channels != p_sys->i_channels_conf
-        || (int)p_sys->aout_format.i_bytes_per_frame != p_sys->i_frame_size ) )
+    if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
     {
-        /* Parameters changed - this should not happen. */
-        aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
-        p_sys->p_aout_input = NULL;
-    }
+        msg_Info( p_dec, "A/52 channels:%d samplerate:%d bitrate:%d",
+                  p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate );
 
-    /* Creating the audio input if not created yet. */
-    if( p_sys->p_aout_input == NULL )
-    {
-        p_sys->aout_format.i_rate = p_sys->i_rate;
-        p_sys->aout_format.i_original_channels = p_sys->i_channels_conf;
-        p_sys->aout_format.i_physical_channels
-            = p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
-        p_sys->aout_format.i_bytes_per_frame = p_sys->i_frame_size;
-        p_sys->aout_format.i_frame_length = A52_FRAME_NB;
         aout_DateInit( &p_sys->end_date, p_sys->i_rate );
-        aout_DateSet( &p_sys->end_date, p_sys->pts );
-        p_sys->p_aout_input = aout_DecNew( p_dec,
-                                           &p_sys->p_aout,
-                                           &p_sys->aout_format );
-        if( p_sys->p_aout_input == NULL )
-        {
-            *pp_buffer = NULL;
-            return VLC_EGENERIC;
-        }
+        aout_DateSet( &p_sys->end_date, p_sys->i_pts );
     }
 
-    *pp_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
-                                    A52_FRAME_NB );
-    if( *pp_buffer == NULL )
+    p_dec->fmt_out.audio.i_rate     = p_sys->i_rate;
+    p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
+    p_dec->fmt_out.audio.i_bitrate  = p_sys->i_bit_rate;
+    p_dec->fmt_out.audio.i_bytes_per_frame = p_sys->i_frame_size;
+    p_dec->fmt_out.audio.i_frame_length = A52_FRAME_NB;
+
+    p_dec->fmt_out.audio.i_original_channels = p_sys->i_channels_conf;
+    p_dec->fmt_out.audio.i_physical_channels =
+        p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
+
+    if( p_sys->b_packetizer )
     {
-        return VLC_EGENERIC;
+        block_t *p_sout_buffer = GetSoutBuffer( p_dec );
+        p_buf = p_sout_buffer ? p_sout_buffer->p_buffer : NULL;
+        *pp_out_buffer = p_sout_buffer;
+    }
+    else
+    {
+        aout_buffer_t *p_aout_buffer = GetAoutBuffer( p_dec );
+        p_buf = p_aout_buffer ? p_aout_buffer->p_buffer : NULL;
+        *pp_out_buffer = p_aout_buffer;
     }
 
-    (*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;
+    return p_buf;
 }
 
 /*****************************************************************************
- * GetSoutBuffer:
+ * GetAoutBuffer:
  *****************************************************************************/
-static int GetSoutBuffer( decoder_t *p_dec, sout_buffer_t **pp_buffer )
+static aout_buffer_t *GetAoutBuffer( decoder_t *p_dec )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
+    aout_buffer_t *p_buf;
 
-    if( p_sys->p_sout_input != NULL &&
-        ( p_sys->sout_format.i_sample_rate != (int)p_sys->i_rate
-          || p_sys->sout_format.i_channels != (int)p_sys->i_channels ) )
-    {
-        /* Parameters changed - this should not happen. */
-    }
-
-    /* Creating the sout input if not created yet. */
-    if( p_sys->p_sout_input == NULL )
-    {
-        p_sys->sout_format.i_sample_rate = p_sys->i_rate;
-        p_sys->sout_format.i_channels    = p_sys->i_channels;
-        p_sys->sout_format.i_block_align = 0;
-        p_sys->sout_format.i_bitrate     = p_sys->i_bit_rate;
-        p_sys->sout_format.i_extra_data  = 0;
-        p_sys->sout_format.p_extra_data  = NULL;
+    p_buf = p_dec->pf_aout_buffer_new( p_dec, A52_FRAME_NB  );
+    if( p_buf == NULL ) return NULL;
 
-        aout_DateInit( &p_sys->end_date, p_sys->i_rate );
-        aout_DateSet( &p_sys->end_date, p_sys->pts );
+    p_buf->start_date = aout_DateGet( &p_sys->end_date );
+    p_buf->end_date = aout_DateIncrement( &p_sys->end_date, A52_FRAME_NB );
 
-        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, "A/52 channels:%d samplerate:%d bitrate:%d",
-                  p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate );
-    }
-
-    *pp_buffer = sout_BufferNew( p_sys->p_sout_input->p_sout,
-                                 p_sys->i_frame_size );
-    if( *pp_buffer == NULL )
-    {
-        return VLC_EGENERIC;
-    }
-
-    (*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 VLC_SUCCESS;
+    return p_buf;
 }
 
 /*****************************************************************************
- * SendOutBuffer:
+ * GetSoutBuffer:
  *****************************************************************************/
-static int SendOutBuffer( decoder_t *p_dec )
+static block_t *GetSoutBuffer( decoder_t *p_dec )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
+    block_t *p_block;
 
-    if( p_sys->b_packetizer )
-    {
-        sout_InputSendBuffer( p_sys->p_sout_input, p_sys->p_sout_buffer );
-        p_sys->p_sout_buffer = NULL;
-    }
-    else
-    {
-        /* 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;
-    }
+    p_block = block_New( p_dec, p_sys->i_frame_size );
+    if( p_block == NULL ) return NULL;
 
-    p_sys->p_out_buffer = NULL;
+    p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
 
-    return VLC_SUCCESS;
+    p_block->i_length = aout_DateIncrement( &p_sys->end_date, A52_FRAME_NB ) -
+        p_block->i_pts;
+
+    return p_block;
 }
 
 /*****************************************************************************
index 5afd36255b2c95ebd714d331573725a2d8d91ad5..555f08ffe1e13d2fca4d1906148a34e9e05872ce 100644 (file)
@@ -2,7 +2,7 @@
  * adpcm.c : adpcm variant audio decoder
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: adpcm.c,v 1.15 2003/11/05 01:47:40 fenrir Exp $
+ * $Id: adpcm.c,v 1.16 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -29,7 +29,6 @@
 #include <stdlib.h>                                      /* malloc(), free() */
 
 #include <vlc/vlc.h>
-#include <vlc/aout.h>
 #include <vlc/decoder.h>
 #include <vlc/input.h>
 
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
-static int  Open    ( vlc_object_t * );
+static int  OpenDecoder( vlc_object_t * );
+static void CloseDecoder( vlc_object_t * );
+
+static aout_buffer_t *DecodeBlock( decoder_t *, block_t ** );
 
 vlc_module_begin();
     set_description( _("ADPCM audio decoder") );
     set_capability( "decoder", 50 );
-    set_callbacks( Open, NULL );
+    set_callbacks( OpenDecoder, CloseDecoder );
 vlc_module_end();
 
-
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
@@ -61,31 +62,19 @@ enum adpcm_codec_e
 
 struct decoder_sys_t
 {
-    WAVEFORMATEX       *p_wf;
     enum adpcm_codec_e codec;
 
     int                 i_block;
     int                 i_samplesperblock;
 
-    /* audio output */
-    aout_instance_t *   p_aout;       /* opaque */
-    aout_input_t *      p_aout_input; /* opaque */
-    audio_sample_format_t output_format;
-
-    audio_date_t        date;
+    audio_date_t        end_date;
 };
 
-static int Init  ( decoder_t * );
-static int Decode( decoder_t *, block_t * );
-static int End   ( decoder_t * );
-
-
-
-static void DecodeAdpcmMs       ( decoder_sys_t *, int16_t *, uint8_t * );
-static void DecodeAdpcmImaWav   ( decoder_sys_t *, int16_t *, uint8_t * );
-static void DecodeAdpcmImaQT    ( decoder_sys_t *, int16_t *, uint8_t * );
-static void DecodeAdpcmDk4      ( decoder_sys_t *, int16_t *, uint8_t * );
-static void DecodeAdpcmDk3      ( decoder_sys_t *, int16_t *, uint8_t * );
+static void DecodeAdpcmMs    ( decoder_t *, int16_t *, uint8_t * );
+static void DecodeAdpcmImaWav( decoder_t *, int16_t *, uint8_t * );
+static void DecodeAdpcmImaQT ( decoder_t *, int16_t *, uint8_t * );
+static void DecodeAdpcmDk4   ( decoder_t *, int16_t *, uint8_t * );
+static void DecodeAdpcmDk3   ( decoder_t *, int16_t *, uint8_t * );
 
 static int pi_channels_maps[6] =
 {
@@ -134,64 +123,48 @@ static int i_adaptation_coeff2[7] =
     0, -256, 0, 64, 0, -208, -232
 };
 
-
 /*****************************************************************************
  * OpenDecoder: probe the decoder 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 )
+static int OpenDecoder( vlc_object_t *p_this )
 {
     decoder_t *p_dec = (decoder_t*)p_this;
+    decoder_sys_t *p_sys;
 
-    switch( p_dec->p_fifo->i_fourcc )
+    switch( p_dec->fmt_in.i_codec )
     {
         case VLC_FOURCC('i','m','a', '4'): /* IMA ADPCM */
         case VLC_FOURCC('m','s',0x00,0x02): /* MS ADPCM */
         case VLC_FOURCC('m','s',0x00,0x11): /* IMA ADPCM */
         case VLC_FOURCC('m','s',0x00,0x61): /* Duck DK4 ADPCM */
         case VLC_FOURCC('m','s',0x00,0x62): /* Duck DK3 ADPCM */
-
-            p_dec->pf_init   = Init;
-            p_dec->pf_decode = Decode;
-            p_dec->pf_end    = End;
-
-            p_dec->p_sys     = malloc( sizeof( decoder_sys_t ) );
-            return VLC_SUCCESS;
-
+            break;
         default:
             return VLC_EGENERIC;
     }
-}
-
-/*****************************************************************************
- * Init:
- *****************************************************************************/
-static int Init  ( decoder_t *p_dec )
-{
-    decoder_sys_t *p_sys = p_dec->p_sys;
 
-    WAVEFORMATEX *p_wf;
-    if( ( p_wf = (WAVEFORMATEX*)p_dec->p_fifo->p_waveformatex ) == NULL )
+    /* Allocate the memory needed to store the decoder's structure */
+    if( ( p_dec->p_sys = p_sys =
+          (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
     {
-        msg_Err( p_dec, "unknown raw format" );
+        msg_Err( p_dec, "out of memory" );
         return VLC_EGENERIC;
     }
 
-    if( p_wf->nChannels < 1 || p_wf->nChannels > 2 )
+    if( p_dec->fmt_in.audio.i_channels <= 0 ||
+        p_dec->fmt_in.audio.i_channels > 5 )
     {
-        msg_Err( p_dec, "bad channels count(1-2)" );
+        msg_Err( p_dec, "bad channels count(1-5)" );
         return VLC_EGENERIC;
     }
-    if( p_wf->nSamplesPerSec <= 0 )
+
+    if( p_dec->fmt_in.audio.i_rate <= 0 )
     {
         msg_Err( p_dec, "bad samplerate" );
         return VLC_EGENERIC;
     }
 
-    p_sys->p_wf = p_wf;
-    switch( p_dec->p_fifo->i_fourcc )
+    switch( p_dec->fmt_in.i_codec )
     {
         case VLC_FOURCC('i','m','a', '4'): /* IMA ADPCM */
             p_sys->codec = ADPCM_IMA_QT;
@@ -210,146 +183,152 @@ static int Init  ( decoder_t *p_dec )
             break;
     }
 
-    if( ( p_sys->i_block = p_wf->nBlockAlign ) <= 0 )
+    if( 1 )//( p_sys->i_block = p_wf->nBlockAlign ) <= 0 )
     {
-        p_sys->i_block = p_sys->codec==ADPCM_IMA_QT ? 34*p_wf->nChannels:1024;
+        p_sys->i_block = (p_sys->codec == ADPCM_IMA_QT) ?
+            34 * p_dec->fmt_in.audio.i_channels : 1024;
         msg_Warn( p_dec, "block size undefined, -> using %d", p_sys->i_block );
     }
 
     /* calculate samples per block */
     switch( p_sys->codec )
     {
-        case ADPCM_IMA_QT:
-            p_sys->i_samplesperblock = 64;
-            break;
-        case ADPCM_IMA_WAV:
-            p_sys->i_samplesperblock =
-                 2 * ( p_sys->i_block - 4 * p_wf->nChannels )/ p_wf->nChannels;
-                 break;
-        case ADPCM_MS:
-            p_sys->i_samplesperblock =
-                2 * (p_sys->i_block - 7 * p_wf->nChannels)/p_wf->nChannels + 2;
-            break;
-        case ADPCM_DK4:
-            p_sys->i_samplesperblock =
-               2 * (p_sys->i_block - 4 * p_wf->nChannels)/p_wf->nChannels + 1;
-            break;
-        case ADPCM_DK3:
-            p_wf->nChannels = 2;
-            p_sys->i_samplesperblock = ( 4 * ( p_sys->i_block - 16 ) + 2 )/ 3;
-            break;
+    case ADPCM_IMA_QT:
+        p_sys->i_samplesperblock = 64;
+        break;
+    case ADPCM_IMA_WAV:
+        p_sys->i_samplesperblock =
+            2 * ( p_sys->i_block - 4 * p_dec->fmt_in.audio.i_channels ) /
+            p_dec->fmt_in.audio.i_channels;
+        break;
+    case ADPCM_MS:
+        p_sys->i_samplesperblock =
+            2 * (p_sys->i_block - 7 * p_dec->fmt_in.audio.i_channels) /
+            p_dec->fmt_in.audio.i_channels + 2;
+        break;
+    case ADPCM_DK4:
+        p_sys->i_samplesperblock =
+            2 * (p_sys->i_block - 4 * p_dec->fmt_in.audio.i_channels) /
+            p_dec->fmt_in.audio.i_channels + 1;
+        break;
+    case ADPCM_DK3:
+        p_dec->fmt_in.audio.i_channels = 2;
+        p_sys->i_samplesperblock = ( 4 * ( p_sys->i_block - 16 ) + 2 )/ 3;
+        break;
     }
-    msg_Dbg( p_dec,
-             "format: samplerate:%dHz channels:%d bits/sample:%d blockalign:%d samplesperblock %d",
-             p_wf->nSamplesPerSec, p_wf->nChannels,
-             p_wf->wBitsPerSample, p_wf->nBlockAlign,
+
+    msg_Dbg( p_dec, "format: samplerate:%dHz channels:%d bits/sample:%d "
+             "blockalign:%d samplesperblock %d",
+             p_dec->fmt_in.audio.i_rate, p_dec->fmt_in.audio.i_channels,
+             p_dec->fmt_in.audio.i_bitspersample, p_sys->i_block,
              p_sys->i_samplesperblock );
 
-    p_sys->output_format.i_format = AOUT_FMT_S16_NE;
-    p_sys->output_format.i_rate = p_wf->nSamplesPerSec;
-    p_sys->output_format.i_physical_channels =
-    p_sys->output_format.i_original_channels =
-            pi_channels_maps[p_wf->nChannels];
+    p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
+    p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
+    p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
+    p_dec->fmt_out.audio.i_physical_channels =
+        p_dec->fmt_out.audio.i_original_channels =
+            pi_channels_maps[p_dec->fmt_in.audio.i_channels];
 
-    p_sys->p_aout = NULL;
-    p_sys->p_aout_input = aout_DecNew( p_dec,
-                                       &p_sys->p_aout, &p_sys->output_format);
-    if( p_sys->p_aout_input == NULL )
-    {
-        msg_Err( p_dec, "cannot create aout" );
-        return VLC_EGENERIC;
-    }
+    aout_DateInit( &p_sys->end_date, p_dec->fmt_out.audio.i_rate );
+    aout_DateSet( &p_sys->end_date, 0 );
 
-    aout_DateInit( &p_sys->date, p_sys->output_format.i_rate );
-    aout_DateSet( &p_sys->date, 0 );
+    p_dec->pf_decode_audio = DecodeBlock;
 
     return VLC_SUCCESS;
 }
 
 /*****************************************************************************
- * Decode:
+ * DecodeBlock:
  *****************************************************************************/
-static int Decode( decoder_t *p_dec, block_t *p_block )
+static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
 {
     decoder_sys_t *p_sys  = p_dec->p_sys;
-    mtime_t        i_pts  = p_block->i_pts;
-    uint8_t       *p_data = p_block->p_buffer;
-    int            i_data = p_block->i_buffer;
+    block_t *p_block;
 
-    while( i_data >= p_sys->i_block )
+    if( !pp_block || !*pp_block ) return NULL;
+
+    p_block = *pp_block;
+
+    if( p_block->i_pts != 0 &&
+        p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
+    {
+        aout_DateSet( &p_sys->end_date, p_block->i_pts );
+    }
+    else if( !aout_DateGet( &p_sys->end_date ) )
     {
-        aout_buffer_t *out;
+        /* We've just started the stream, wait for the first PTS. */
+        block_Release( p_block );
+        return NULL;
+    }
 
-        if( i_pts != 0 && i_pts != aout_DateGet( &p_sys->date ) )
-        {
-            aout_DateSet( &p_sys->date, i_pts );
-        }
-        else if( !aout_DateGet( &p_sys->date ) )
-        {
-            block_Release( p_block );
-            return VLC_SUCCESS;
-        }
-        i_pts = 0;
+    /* Don't re-use the same pts twice */
+    p_block->i_pts = 0;
+
+    if( p_block->i_buffer >= p_sys->i_block )
+    {
+        aout_buffer_t *p_out;
 
-        out = aout_DecNewBuffer( p_sys->p_aout,
-                                 p_sys->p_aout_input,
-                                 p_sys->i_samplesperblock );
-        if( out == NULL )
+        p_out = p_dec->pf_aout_buffer_new( p_dec, p_sys->i_samplesperblock );
+        if( p_out == NULL )
         {
-            msg_Err( p_dec, "cannot get aout buffer" );
             block_Release( p_block );
-            return VLC_EGENERIC;
+            return NULL;
         }
-        out->start_date = aout_DateGet( &p_sys->date );
-        out->end_date   = aout_DateIncrement( &p_sys->date,
-                                              p_sys->i_samplesperblock );
+
+        p_out->start_date = aout_DateGet( &p_sys->end_date );
+        p_out->end_date =
+            aout_DateIncrement( &p_sys->end_date, p_sys->i_samplesperblock );
 
         switch( p_sys->codec )
         {
-            case ADPCM_IMA_QT:
-                DecodeAdpcmImaQT( p_sys, (int16_t*)out->p_buffer, p_data );
-                break;
-            case ADPCM_IMA_WAV:
-                DecodeAdpcmImaWav( p_sys, (int16_t*)out->p_buffer, p_data );
-                break;
-            case ADPCM_MS:
-                DecodeAdpcmMs( p_sys, (int16_t*)out->p_buffer, p_data );
-                break;
-            case ADPCM_DK4:
-                DecodeAdpcmDk4( p_sys, (int16_t*)out->p_buffer, p_data );
-                break;
-            case ADPCM_DK3:
-                DecodeAdpcmDk3( p_sys, (int16_t*)out->p_buffer, p_data );
-                break;
-            default:
-                break;
+        case ADPCM_IMA_QT:
+            DecodeAdpcmImaQT( p_dec, (int16_t*)p_out->p_buffer,
+                              p_block->p_buffer );
+            break;
+        case ADPCM_IMA_WAV:
+            DecodeAdpcmImaWav( p_dec, (int16_t*)p_out->p_buffer,
+                               p_block->p_buffer );
+            break;
+        case ADPCM_MS:
+            DecodeAdpcmMs( p_dec, (int16_t*)p_out->p_buffer,
+                           p_block->p_buffer );
+            break;
+        case ADPCM_DK4:
+            DecodeAdpcmDk4( p_dec, (int16_t*)p_out->p_buffer,
+                            p_block->p_buffer );
+            break;
+        case ADPCM_DK3:
+            DecodeAdpcmDk3( p_dec, (int16_t*)p_out->p_buffer,
+                            p_block->p_buffer );
+            break;
+        default:
+            break;
         }
-        aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input, out );
 
-        p_data += p_sys->i_block;
-        i_data -= p_sys->i_block;
+        p_block->p_buffer += p_out->i_nb_bytes;
+        p_block->i_buffer -= p_out->i_nb_bytes;
+        return p_out;
     }
 
     block_Release( p_block );
-    return VLC_SUCCESS;
+    return NULL;
 }
 
 /*****************************************************************************
- * End:
+ * CloseDecoder:
  *****************************************************************************/
-static int End   ( decoder_t *p_dec )
+static void CloseDecoder( vlc_object_t *p_this )
 {
+    decoder_t *p_dec = (decoder_t *)p_this;
     decoder_sys_t *p_sys = p_dec->p_sys;
 
-    if( p_sys->p_aout_input )
-    {
-        aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
-    }
     free( p_sys );
-
-    return VLC_SUCCESS;
 }
 
+/*****************************************************************************
+ * Local functions
+ *****************************************************************************/
 #define CLAMP( v, min, max ) \
     if( (v) < (min) ) (v) = (min); \
     if( (v) > (max) ) (v) = (max)
@@ -401,14 +380,16 @@ static int AdpcmMsExpandNibble(adpcm_ms_channel_t *p_channel,
     return( i_predictor );
 }
 
-static void DecodeAdpcmMs( decoder_sys_t *p_sys, int16_t *p_sample, uint8_t *p_buffer )
+static void DecodeAdpcmMs( decoder_t *p_dec, int16_t *p_sample,
+                           uint8_t *p_buffer )
 {
+    decoder_sys_t *p_sys  = p_dec->p_sys;
     adpcm_ms_channel_t channel[2];
     int i_nibbles;
     int b_stereo;
     int i_block_predictor;
 
-    b_stereo = p_sys->p_wf->nChannels == 2 ? 1 : 0;
+    b_stereo = p_dec->fmt_in.audio.i_channels == 2 ? 1 : 0;
 
     GetByte( i_block_predictor );
     CLAMP( i_block_predictor, 0, 6 );
@@ -453,8 +434,8 @@ static void DecodeAdpcmMs( decoder_sys_t *p_sys, int16_t *p_sample, uint8_t *p_b
         *p_sample++ = channel[0].i_sample1;
     }
 
-    for( i_nibbles =  2 *( p_sys->i_block - 7 * p_sys->p_wf->nChannels );
-         i_nibbles > 0; i_nibbles -= 2,p_buffer++ )
+    for( i_nibbles = 2 * (p_sys->i_block - 7 * p_dec->fmt_in.audio.i_channels);
+         i_nibbles > 0; i_nibbles -= 2, p_buffer++ )
     {
         *p_sample++ = AdpcmMsExpandNibble( &channel[0], (*p_buffer) >> 4);
         *p_sample++ = AdpcmMsExpandNibble( &channel[b_stereo ? 1 : 0],
@@ -495,13 +476,15 @@ static int AdpcmImaWavExpandNibble(adpcm_ima_wav_channel_t *p_channel,
     return( p_channel->i_predictor );
 }
 
-static void DecodeAdpcmImaWav( decoder_sys_t *p_sys, int16_t *p_sample, uint8_t *p_buffer )
+static void DecodeAdpcmImaWav( decoder_t *p_dec, int16_t *p_sample,
+                               uint8_t *p_buffer )
 {
+    decoder_sys_t *p_sys  = p_dec->p_sys;
     adpcm_ima_wav_channel_t channel[2];
     int                     i_nibbles;
     int                     b_stereo;
 
-    b_stereo = p_sys->p_wf->nChannels == 2 ? 1 : 0;
+    b_stereo = p_dec->fmt_in.audio.i_channels == 2 ? 1 : 0;
 
     GetWord( channel[0].i_predictor );
     GetByte( channel[0].i_step_index );
@@ -562,16 +545,17 @@ static void DecodeAdpcmImaWav( decoder_sys_t *p_sys, int16_t *p_sample, uint8_t
 /*
  * Ima4 in QT file
  */
-static void DecodeAdpcmImaQT( decoder_sys_t *p_sys, int16_t *p_sample, uint8_t *p_buffer )
+static void DecodeAdpcmImaQT( decoder_t *p_dec, int16_t *p_sample,
+                              uint8_t *p_buffer )
 {
     adpcm_ima_wav_channel_t channel[2];
     int                     i_nibbles;
     int                     i_ch;
     int                     i_step;
 
-    i_step   = p_sys->p_wf->nChannels;
+    i_step = p_dec->fmt_in.audio.i_channels;
 
-    for( i_ch = 0; i_ch < p_sys->p_wf->nChannels; i_ch++ )
+    for( i_ch = 0; i_ch < p_dec->fmt_in.audio.i_channels; i_ch++ )
     {
         /* load preambule */
         channel[i_ch].i_predictor  = (int16_t)((( ( p_buffer[0] << 1 )|(  p_buffer[1] >> 7 ) ))<<7);
@@ -599,14 +583,15 @@ static void DecodeAdpcmImaQT( decoder_sys_t *p_sys, int16_t *p_sample, uint8_t *
 /*
  * Dk4
  */
-
-static void DecodeAdpcmDk4( decoder_sys_t *p_sys, int16_t *p_sample, uint8_t *p_buffer )
+static void DecodeAdpcmDk4( decoder_t *p_dec, int16_t *p_sample,
+                            uint8_t *p_buffer )
 {
+    decoder_sys_t *p_sys  = p_dec->p_sys;
     adpcm_ima_wav_channel_t channel[2];
     int                     i_nibbles;
     int                     b_stereo;
 
-    b_stereo = p_sys->p_wf->nChannels == 2 ? 1 : 0;
+    b_stereo = p_dec->fmt_in.audio.i_channels == 2 ? 1 : 0;
 
     GetWord( channel[0].i_predictor );
     GetByte( channel[0].i_step_index );
@@ -644,8 +629,10 @@ static void DecodeAdpcmDk4( decoder_sys_t *p_sys, int16_t *p_sample, uint8_t *p_
 /*
  * Dk3
  */
-static void DecodeAdpcmDk3( decoder_sys_t *p_sys, int16_t *p_sample, uint8_t *p_buffer )
+static void DecodeAdpcmDk3( decoder_t *p_dec, int16_t *p_sample,
+                            uint8_t *p_buffer )
 {
+    decoder_sys_t *p_sys  = p_dec->p_sys;
     uint8_t                 *p_end = &p_buffer[p_sys->i_block];
     adpcm_ima_wav_channel_t sum;
     adpcm_ima_wav_channel_t diff;
@@ -705,4 +692,3 @@ static void DecodeAdpcmDk3( decoder_sys_t *p_sys, int16_t *p_sample, uint8_t *p_
         }
     }
 }
-
index 7e0b85e7e4a07d918f5ab0fdfd17388873f9d0c0..ae7dd17d75d79494eb389b4c820ccd488ab20e0a 100644 (file)
@@ -2,7 +2,7 @@
  * araw.c: Pseudo audio decoder; for raw pcm data
  *****************************************************************************
  * Copyright (C) 2001, 2003 VideoLAN
- * $Id: araw.c,v 1.23 2003/11/08 04:57:56 fenrir Exp $
+ * $Id: araw.c,v 1.24 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
  * Preamble
  *****************************************************************************/
 #include <stdlib.h>                                      /* malloc(), free() */
-#include <vlc/vlc.h>
 
-#include <vlc/aout.h>
+#include <vlc/vlc.h>
 #include <vlc/decoder.h>
 #include <vlc/input.h>
 
-#include <vlc/sout.h>
-
 #include "codecs.h"
 
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
-static int  DecoderOpen    ( vlc_object_t * );
+static int  DecoderOpen ( vlc_object_t * );
+static void DecoderClose( vlc_object_t * );
 
-static int  EncoderOpen  ( vlc_object_t *p_this );
-static void EncoderClose ( vlc_object_t *p_this );
+static int  EncoderOpen ( vlc_object_t * );
+static void EncoderClose( vlc_object_t * );
 
 vlc_module_begin();
     /* audio decoder module */
     set_description( _("Raw/Log Audio decoder") );
     set_capability( "decoder", 50 );
-    set_callbacks( DecoderOpen, NULL );
+    set_callbacks( DecoderOpen, DecoderClose );
 
     /* audio encoder submodule */
     add_submodule();
     set_description( _("Raw audio encoder") );
-    set_capability( "audio encoder", 10 );
+    set_capability( "encoder", 10 );
     set_callbacks( EncoderOpen, EncoderClose );
 vlc_module_end();
 
-
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
-static int DecoderInit  ( decoder_t * );
-static int DecoderDecode( decoder_t *, block_t * );
-static int DecoderEnd   ( decoder_t * );
+static aout_buffer_t *DecodeBlock( decoder_t *, block_t ** );
+static block_t *EncoderEncode( encoder_t *, aout_buffer_t * );
 
 struct decoder_sys_t
 {
-    WAVEFORMATEX    *p_wf;
-
-    int16_t        *p_logtos16;  // used with m/alaw to int16_t
-
-    /* Output properties */
-    aout_instance_t *   p_aout;       /* opaque */
-    aout_input_t *      p_aout_input; /* opaque */
-    audio_sample_format_t output_format;
+    int16_t *p_logtos16;  /* used with m/alaw to int16_t */
 
-    audio_date_t        date;
+    audio_date_t end_date;
 };
 
-
-static block_t *EncoderEncode( encoder_t *, aout_buffer_t *p_aout_buf );
-
-/*****************************************************************************
- * DecoderOpen: probe the decoder and return score
- *****************************************************************************
- * Tries to launch a decoder and return score so that the interface is able
- * to choose.
- *****************************************************************************/
-static int DecoderOpen( vlc_object_t *p_this )
-{
-    decoder_t *p_dec = (decoder_t*)p_this;
-
-    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)*/
-        case VLC_FOURCC('s','o','w','t'): /* _signed_ little endian samples (mov)*/
-
-        case VLC_FOURCC('a','l','a','w'):
-        case VLC_FOURCC('u','l','a','w'):
-            p_dec->pf_init   = DecoderInit;
-            p_dec->pf_decode = DecoderDecode;
-            p_dec->pf_end    = DecoderEnd;
-
-            p_dec->p_sys     = malloc( sizeof( decoder_sys_t ) );
-            return VLC_SUCCESS;
-
-        default:
-            return VLC_EGENERIC;
-    }
-}
-
 static int pi_channels_maps[6] =
 {
     0,
@@ -195,264 +151,267 @@ static int16_t alawtos16[256] =
 };
 
 /*****************************************************************************
- * DecoderInit: initialize data before entering main loop
+ * DecoderOpen: probe the decoder and return score
  *****************************************************************************/
-static int DecoderInit( decoder_t *p_dec )
+static int DecoderOpen( vlc_object_t *p_this )
 {
-    decoder_sys_t *p_sys = p_dec->p_sys;
+    decoder_t *p_dec = (decoder_t*)p_this;
+    decoder_sys_t *p_sys;
+
+    switch( p_dec->fmt_in.i_codec )
+    {
+    /* from wav/avi/asf file */
+    case VLC_FOURCC('a','r','a','w'):
+    /* _signed_ big endian samples (mov)*/
+    case VLC_FOURCC('t','w','o','s'):
+    /* _signed_ little endian samples (mov)*/
+    case VLC_FOURCC('s','o','w','t'):
+
+    case VLC_FOURCC('a','l','a','w'):
+    case VLC_FOURCC('u','l','a','w'):
+        break;
+
+    default:
+        return VLC_EGENERIC;
+    }
 
-    WAVEFORMATEX *p_wf;
-    if( ( p_wf = (WAVEFORMATEX*)p_dec->p_fifo->p_waveformatex ) == NULL )
+    /* Allocate the memory needed to store the decoder's structure */
+    if( ( p_dec->p_sys = p_sys =
+          (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
     {
-        msg_Err( p_dec, "unknown raw format" );
+        msg_Err( p_dec, "out of memory" );
         return VLC_EGENERIC;
     }
 
-    if( p_wf->nChannels <= 0 || p_wf->nChannels > 5 )
+    if( p_dec->fmt_in.audio.i_channels <= 0 ||
+        p_dec->fmt_in.audio.i_channels > 5 )
     {
         msg_Err( p_dec, "bad channels count(1-5)" );
         return VLC_EGENERIC;
     }
-    if( p_wf->nSamplesPerSec <= 0 )
+
+    if( p_dec->fmt_in.audio.i_rate <= 0 )
     {
         msg_Err( p_dec, "bad samplerate" );
         return VLC_EGENERIC;
     }
 
-    p_sys->p_wf = p_wf;
     p_sys->p_logtos16 = NULL;
 
-    /* fixing some values */
-    if( p_wf->nBlockAlign == 0 &&
-        ( p_wf->wFormatTag == WAVE_FORMAT_PCM ||
-          p_wf->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ) )
-    {
-        p_wf->nBlockAlign = ( p_wf->wBitsPerSample + 7 ) / 8 * p_wf->nChannels;
-    }
+    msg_Dbg( p_dec, "samplerate:%dHz channels:%d bits/sample:%d",
+             p_dec->fmt_in.audio.i_rate, p_dec->fmt_in.audio.i_channels,
+             p_dec->fmt_in.audio.i_bitspersample );
 
-    msg_Dbg( p_dec,
-             "samplerate:%dHz channels:%d bits/sample:%d blockalign:%d",
-             p_wf->nSamplesPerSec,  p_wf->nChannels,
-             p_wf->wBitsPerSample,  p_wf->nBlockAlign );
-
-    if( p_wf->wFormatTag  == WAVE_FORMAT_IEEE_FLOAT )
+    if( 0 /* p_wf->wFormatTag == WAVE_FORMAT_IEEE_FLOAT */ )
     {
-        switch( ( p_wf->wBitsPerSample + 7 ) / 8 )
+        switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
         {
-            case( 4 ):
-                p_sys->output_format.i_format = VLC_FOURCC('f','l','3','2');
-                break;
-            case( 8 ):
-                p_sys->output_format.i_format = VLC_FOURCC('f','l','6','4');
-                break;
-            default:
-                msg_Err( p_dec, "bad parameters(bits/sample)" );
-                return VLC_EGENERIC;
+        case 4:
+            p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','3','2');
+            break;
+        case 8:
+            p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','6','4');
+            break;
+        default:
+            msg_Err( p_dec, "bad parameters(bits/sample)" );
+            return VLC_EGENERIC;
         }
     }
     else
     {
-        if( p_dec->p_fifo->i_fourcc == VLC_FOURCC( 't', 'w', 'o', 's' ) )
+        if( p_dec->fmt_in.i_codec == VLC_FOURCC( 't', 'w', 'o', 's' ) )
         {
-            switch( ( p_wf->wBitsPerSample + 7 ) / 8 )
+            switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
             {
-                case( 1 ):
-                    p_sys->output_format.i_format = VLC_FOURCC('s','8',' ',' ');
-                    break;
-                case( 2 ):
-                    p_sys->output_format.i_format = VLC_FOURCC('s','1','6','b');
-                    break;
-                case( 3 ):
-                    p_sys->output_format.i_format = VLC_FOURCC('s','2','4','b');
-                    break;
-                case( 4 ):
-                    p_sys->output_format.i_format = VLC_FOURCC('s','3','2','b');
-                    break;
-                default:
-                    msg_Err( p_dec, "bad parameters(bits/sample)" );
-                    return VLC_EGENERIC;
+            case 1:
+                p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
+                break;
+            case 2:
+                p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','b');
+                break;
+            case 3:
+                p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','b');
+                break;
+            case 4:
+                p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','b');
+                break;
+            default:
+                msg_Err( p_dec, "bad parameters(bits/sample)" );
+                return VLC_EGENERIC;
             }
         }
-        else if( p_dec->p_fifo->i_fourcc == VLC_FOURCC( 's', 'o', 'w', 't' ) )
+        else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', 'o', 'w', 't' ) )
         {
-            switch( ( p_wf->wBitsPerSample + 7 ) / 8 )
+            switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
             {
-                case( 1 ):
-                    p_sys->output_format.i_format = VLC_FOURCC('s','8',' ',' ');
-                    break;
-                case( 2 ):
-                    p_sys->output_format.i_format = VLC_FOURCC('s','1','6','l');
-                    break;
-                case( 3 ):
-                    p_sys->output_format.i_format = VLC_FOURCC('s','2','4','l');
-                    break;
-                case( 4 ):
-                    p_sys->output_format.i_format = VLC_FOURCC('s','3','2','l');
-                    break;
-                default:
-                    msg_Err( p_dec, "bad parameters(bits/sample)" );
-                    return VLC_EGENERIC;
+            case 1:
+                p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
+                break;
+            case 2:
+                p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
+                break;
+            case 3:
+                p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
+                break;
+            case 4:
+                p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
+                break;
+            default:
+                msg_Err( p_dec, "bad parameters(bits/sample)" );
+                return VLC_EGENERIC;
             }
         }
-        else if( p_dec->p_fifo->i_fourcc == VLC_FOURCC( 'a', 'r', 'a', 'w' ) )
+        else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'r', 'a', 'w' ) )
         {
-            switch( ( p_wf->wBitsPerSample + 7 ) / 8 )
+            switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
             {
-                case( 1 ):
-                    p_sys->output_format.i_format = VLC_FOURCC('u','8',' ',' ');
-                    break;
-                case( 2 ):
-                    p_sys->output_format.i_format = VLC_FOURCC('s','1','6','l');
-                    break;
-                case( 3 ):
-                    p_sys->output_format.i_format = VLC_FOURCC('s','2','4','l');
-                    break;
-                case( 4 ):
-                    p_sys->output_format.i_format = VLC_FOURCC('s','3','2','l');
-                    break;
-                default:
-                    msg_Err( p_dec, "bad parameters(bits/sample)" );
-                    return VLC_EGENERIC;
+            case 1:
+                p_dec->fmt_out.i_codec = VLC_FOURCC('u','8',' ',' ');
+                break;
+            case 2:
+                p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
+                break;
+            case 3:
+                p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
+                break;
+            case 4:
+                p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
+                break;
+            default:
+                msg_Err( p_dec, "bad parameters(bits/sample)" );
+                return VLC_EGENERIC;
             }
         }
-        else if( p_dec->p_fifo->i_fourcc == VLC_FOURCC( 'a', 'l', 'a', 'w' ) )
+        else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'l', 'a', 'w' ) )
         {
-            p_sys->output_format.i_format = AOUT_FMT_S16_NE;
+            p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
             p_sys->p_logtos16  = alawtos16;
-            p_wf->wBitsPerSample = 8;
+            p_dec->fmt_in.audio.i_bitspersample = 8;
         }
-        else if( p_dec->p_fifo->i_fourcc == VLC_FOURCC( 'u', 'l', 'a', 'w' ) )
+        else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'u', 'l', 'a', 'w' ) )
         {
-            p_sys->output_format.i_format = AOUT_FMT_S16_NE;
+            p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
             p_sys->p_logtos16  = ulawtos16;
-            p_wf->wBitsPerSample = 8;
+            p_dec->fmt_in.audio.i_bitspersample = 8;
         }
     }
-    p_sys->output_format.i_rate = p_wf->nSamplesPerSec;
 
-    p_sys->output_format.i_physical_channels =
-    p_sys->output_format.i_original_channels = pi_channels_maps[p_wf->nChannels];
+    /* Set output properties */
+    p_dec->fmt_out.i_cat = AUDIO_ES;
+    p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
+    p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
+    p_dec->fmt_out.audio.i_physical_channels =
+        p_dec->fmt_out.audio.i_original_channels =
+            pi_channels_maps[p_dec->fmt_in.audio.i_channels];
 
-    p_sys->p_aout       = NULL;
-    p_sys->p_aout_input = aout_DecNew( p_dec, &p_sys->p_aout,
-                                       &p_sys->output_format );
-    if( p_sys->p_aout_input == NULL )
-    {
-        msg_Err( p_dec, "cannot create aout" );
-        return VLC_EGENERIC;
-    }
+    aout_DateInit( &p_sys->end_date, p_dec->fmt_out.audio.i_rate );
+    aout_DateSet( &p_sys->end_date, 0 );
 
-    aout_DateInit( &p_sys->date, p_sys->output_format.i_rate );
-    aout_DateSet( &p_sys->date, 0 );
+    p_dec->pf_decode_audio = DecodeBlock;
 
     return VLC_SUCCESS;
 }
 
-/*****************************************************************************
- * DecoderDecode: decodes a frame
- *****************************************************************************/
-static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
+/****************************************************************************
+ * DecodeBlock: the whole thing
+ ****************************************************************************
+ * This function must be fed with whole samples (see nBlockAlign).
+ ****************************************************************************/
+static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
-    int            i_size = p_block->i_buffer;
-    uint8_t        *p = p_block->p_buffer;
-    int            i_samples; // per channels
+    block_t *p_block;
+    int i_samples;
 
-    if( p_sys->p_wf->nBlockAlign > 0 )
-    {
-        /* Align it (it should already be aligned by demuxer) */
-        i_size -= i_size % p_sys->p_wf->nBlockAlign;
-    }
-    if( i_size < p_sys->p_wf->nBlockAlign )
-    {
-        block_Release( p_block );
-        return VLC_SUCCESS;
-    }
-    i_samples = i_size / ( ( p_sys->p_wf->wBitsPerSample + 7 ) / 8 ) /
-                p_sys->p_wf->nChannels;
+    if( !pp_block || !*pp_block ) return NULL;
+
+    p_block = *pp_block;
 
-    if( p_block->i_pts != 0 && p_block->i_pts != aout_DateGet( &p_sys->date ) )
+    if( p_block->i_pts != 0 &&
+        p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
     {
-        aout_DateSet( &p_sys->date, p_block->i_pts );
+        aout_DateSet( &p_sys->end_date, p_block->i_pts );
     }
-    else if( !aout_DateGet( &p_sys->date ) )
+    else if( !aout_DateGet( &p_sys->end_date ) )
     {
+        /* We've just started the stream, wait for the first PTS. */
         block_Release( p_block );
-        return VLC_SUCCESS;
+        return NULL;
     }
 
-    while( i_samples > 0 )
+    /* Don't re-use the same pts twice */
+    p_block->i_pts = 0;
+
+    i_samples = p_block->i_buffer * 8 / p_dec->fmt_in.audio.i_bitspersample /
+        p_dec->fmt_in.audio.i_channels;
+
+
+    /* Create chunks of max 1024 samples */
+    if( i_samples > 0 )
     {
-        int           i_copy = __MIN( i_samples, 1024 );
-        aout_buffer_t *out;
+        aout_buffer_t *p_out;
+        i_samples = __MIN( i_samples, 1024 );
 
-        out = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input, i_copy );
-        if( out == NULL )
+        p_out = p_dec->pf_aout_buffer_new( p_dec, i_samples );
+        if( p_out == NULL )
         {
-            msg_Err( p_dec, "cannot get aout buffer" );
             block_Release( p_block );
-            return VLC_EGENERIC;
+            return NULL;
         }
 
-        out->start_date = aout_DateGet( &p_sys->date );
-        out->end_date   = aout_DateIncrement( &p_sys->date, i_copy );
+        p_out->start_date = aout_DateGet( &p_sys->end_date );
+        p_out->end_date   = aout_DateIncrement( &p_sys->end_date, i_samples );
 
         if( p_sys->p_logtos16 )
         {
-            int16_t      *s = (int16_t*)out->p_buffer;
+            int16_t *s = (int16_t*)p_out->p_buffer;
             unsigned int i;
 
-            for( i = 0; i < out->i_nb_bytes / 2; i++ )
+            for( i = 0; i < p_out->i_nb_bytes / 2; i++ )
             {
-                *s++ = p_sys->p_logtos16[*p++];
+                *s++ = p_sys->p_logtos16[*p_block->p_buffer++];
+                p_block->i_buffer++;
             }
         }
         else
         {
-            memcpy( out->p_buffer, p, out->i_nb_bytes );
-
-            p += out->i_nb_bytes;
+            memcpy( p_out->p_buffer, p_block->p_buffer, p_out->i_nb_bytes );
+            p_block->p_buffer += p_out->i_nb_bytes;
+            p_block->i_buffer -= p_out->i_nb_bytes;
         }
 
-        aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input, out );
-
-        i_samples -= i_copy;
+        return p_out;
     }
+
     block_Release( p_block );
-    return VLC_SUCCESS;
+    return NULL;
 }
 
 /*****************************************************************************
- * DecoderEnd : faad decoder thread destruction
+ * DecoderClose: decoder destruction
  *****************************************************************************/
-static int DecoderEnd( decoder_t *p_dec )
+static void DecoderClose( vlc_object_t *p_this )
 {
-    decoder_sys_t *p_sys = p_dec->p_sys;
+    decoder_t *p_dec = (decoder_t *)p_this;
 
-    if( p_sys->p_aout_input )
-    {
-        aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
-    }
-    free( p_sys );
-
-    return VLC_SUCCESS;
+    free( p_dec->p_sys );
 }
 
 /*****************************************************************************
  * EncoderOpen:
  *****************************************************************************/
-static int  EncoderOpen  ( vlc_object_t *p_this )
+static int EncoderOpen( vlc_object_t *p_this )
 {
     encoder_t *p_enc = (encoder_t *)p_this;
 
-    if( p_enc->format.audio.i_format != VLC_FOURCC( 's', '1', '6', 'b' ) &&
-        p_enc->format.audio.i_format != VLC_FOURCC( 's', '1', '6', 'l' ) )
+    if( p_enc->fmt_in.i_codec != VLC_FOURCC( 's', '1', '6', 'b' ) &&
+        p_enc->fmt_in.i_codec != VLC_FOURCC( 's', '1', '6', 'l' ) )
     {
         msg_Warn( p_enc, "unhandled input format" );
         return VLC_EGENERIC;
     }
 
-    switch( p_enc->i_fourcc )
+    switch( p_enc->fmt_out.i_codec )
     {
         case VLC_FOURCC( 's', '1', '6', 'b' ):
         case VLC_FOURCC( 's', '1', '6', 'l' ):
@@ -469,11 +428,7 @@ static int  EncoderOpen  ( vlc_object_t *p_this )
     }
 
     p_enc->p_sys = NULL;
-    p_enc->pf_header = NULL;
     p_enc->pf_encode_audio = EncoderEncode;
-    p_enc->pf_encode_video = NULL;
-    p_enc->i_extra_data = 0;
-    p_enc->p_extra_data = NULL;
 
     return VLC_SUCCESS;
 }
@@ -494,21 +449,22 @@ static block_t *EncoderEncode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
     block_t *p_block = NULL;
     unsigned int i;
 
-    if( p_enc->i_fourcc == p_enc->format.audio.i_format )
+    if( p_enc->fmt_in.i_codec == p_enc->fmt_out.i_codec )
     {
         if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
         {
-            memcpy( p_block->p_buffer, p_aout_buf->p_buffer, p_aout_buf->i_nb_bytes );
+            memcpy( p_block->p_buffer, p_aout_buf->p_buffer,
+                    p_aout_buf->i_nb_bytes );
         }
     }
-    else if( p_enc->i_fourcc == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
+    else if( p_enc->fmt_out.i_codec == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
     {
         if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
         {
             uint8_t *p_dst = (uint8_t*)p_block->p_buffer;
             int8_t  *p_src = (int8_t*) p_aout_buf->p_buffer;
 
-            if( p_enc->format.audio.i_format == VLC_FOURCC( 's', '1', '6', 'l' ) )
+            if( p_enc->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) )
             {
                 p_src++;
             }
@@ -519,14 +475,14 @@ static block_t *EncoderEncode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
             }
         }
     }
-    else if( p_enc->i_fourcc == VLC_FOURCC( 's', '8', ' ', ' ' ) )
+    else if( p_enc->fmt_out.i_codec == VLC_FOURCC( 's', '8', ' ', ' ' ) )
     {
         if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
         {
             int8_t *p_dst = (int8_t*)p_block->p_buffer;
             int8_t *p_src = (int8_t*)p_aout_buf->p_buffer;
 
-            if( p_enc->format.audio.i_format == VLC_FOURCC( 's', '1', '6', 'l' ) )
+            if( p_enc->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) )
             {
                 p_src++;
             }
@@ -559,11 +515,9 @@ static block_t *EncoderEncode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
     if( p_block )
     {
         p_block->i_dts = p_block->i_pts = p_aout_buf->start_date;
-        p_block->i_length = (int64_t)p_aout_buf->i_nb_samples * (int64_t)1000000 /
-                            p_enc->format.audio.i_rate;
+        p_block->i_length = (int64_t)p_aout_buf->i_nb_samples *
+            (int64_t)1000000 / p_enc->fmt_in.audio.i_rate;
     }
 
     return p_block;
 }
-
-
index a9ef93bcf187c006fd6ab96f56da514b1d43af25..4a3b8eed1c41e111fb1642f9266c15dca0bf2e93 100644 (file)
@@ -2,7 +2,7 @@
  * cinepak.c: cinepak video decoder
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: cinepak.c,v 1.2 2003/10/25 00:49:13 sam Exp $
+ * $Id: cinepak.c,v 1.3 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -71,20 +71,14 @@ struct decoder_sys_t
      * Cinepak properties
      */
     cinepak_context_t *p_context;
-
-    /*
-     * Output properties
-     */
-    vout_thread_t *p_vout;
 };
 
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
-static int OpenDecoder( vlc_object_t * );
-static int InitDecoder( decoder_t * );
-static int RunDecoder ( decoder_t *, block_t * );
-static int EndDecoder ( decoder_t * );
+static int  OpenDecoder( vlc_object_t * );
+static void CloseDecoder( vlc_object_t * );
+static picture_t *DecodeBlock ( decoder_t *, block_t ** );
 
 static int cinepak_decode_frame( cinepak_context_t *, int, uint8_t * );
 
@@ -94,7 +88,7 @@ static int cinepak_decode_frame( cinepak_context_t *, int, uint8_t * );
 vlc_module_begin();
     set_description( _("Cinepak video decoder") );
     set_capability( "decoder", 70 );
-    set_callbacks( OpenDecoder, NULL );
+    set_callbacks( OpenDecoder, CloseDecoder );
 vlc_module_end();
 
 /*****************************************************************************
@@ -106,8 +100,10 @@ vlc_module_end();
 static int OpenDecoder( vlc_object_t *p_this )
 {
     decoder_t *p_dec = (decoder_t*)p_this;
+    decoder_sys_t *p_sys;
+    vlc_value_t val;
 
-    switch( p_dec->p_fifo->i_fourcc )
+    switch( p_dec->fmt_in.i_codec )
     {
         case VLC_FOURCC('c','v','i','d'):
         case VLC_FOURCC('C','V','I','D'):
@@ -118,30 +114,13 @@ static int OpenDecoder( vlc_object_t *p_this )
     }
 
     /* Allocate the memory needed to store the decoder's structure */
-    if( ( p_dec->p_sys =
+    if( ( p_dec->p_sys = p_sys =
           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
     {
         msg_Err( p_dec, "out of memory" );
         return VLC_EGENERIC;
     }
 
-    p_dec->pf_init = InitDecoder;
-    p_dec->pf_decode = RunDecoder;
-    p_dec->pf_end = EndDecoder;
-
-    return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * InitDecoder: Initalize the decoder
- *****************************************************************************/
-static int InitDecoder( decoder_t *p_dec )
-{
-    decoder_sys_t *p_sys = p_dec->p_sys;
-    vlc_value_t val;
-
-    p_sys->p_vout = NULL;
-
     if( !(p_sys->p_context = malloc( sizeof( cinepak_context_t ) ) ) )
     {
         msg_Err( p_dec, "out of memory" );
@@ -152,57 +131,53 @@ static int InitDecoder( decoder_t *p_dec )
     var_Get( p_dec, "grayscale", &val );
     p_sys->p_context->b_grayscale = val.b_bool;
 
+    p_dec->pf_decode_video = DecodeBlock;
+
     msg_Dbg( p_dec, "cinepak decoder started" );
 
     return VLC_SUCCESS;
 }
 
 /****************************************************************************
- * RunDecoder: the whole thing
+ * DecodeBlock: the whole thing
  ****************************************************************************
  * This function must be fed with whole frames.
  ****************************************************************************/
-static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
     int i_status, i_plane;
     uint8_t *p_dst, *p_src;
     picture_t *p_pic;
+    block_t *p_block;
+
+    if( !pp_block || !*pp_block ) return NULL;
 
-    i_status = cinepak_decode_frame( p_sys->p_context,
-                                     p_block->i_buffer, p_block->p_buffer );
+    p_block = *pp_block;
+
+    i_status = cinepak_decode_frame( p_sys->p_context, p_block->i_buffer,
+                                     p_block->p_buffer );
     if( i_status < 0 )
     {
         msg_Warn( p_dec, "cannot decode one frame (%d bytes)",
                   p_block->i_buffer );
         block_Release( p_block );
-        return VLC_SUCCESS;
+        return NULL;
     }
 
-    /* Check our vout */
-    p_sys->p_vout = vout_Request( p_dec, p_sys->p_vout,
-                                  p_sys->p_context->i_width,
-                                  p_sys->p_context->i_height,
-                                  VLC_FOURCC('I','4','2','0'),
-                                  p_sys->p_context->i_width
-                                    * VOUT_ASPECT_FACTOR
-                                    / p_sys->p_context->i_height );
-    if( !p_sys->p_vout )
-    {
-        msg_Err( p_dec, "cannot create vout" );
-        block_Release( p_block );
-        return VLC_EGENERIC;
-    }
+    p_dec->fmt_out.video.i_width = p_sys->p_context->i_width;
+    p_dec->fmt_out.video.i_height = p_sys->p_context->i_height;
+    p_dec->fmt_out.video.i_aspect = p_sys->p_context->i_width
+        * VOUT_ASPECT_FACTOR / p_sys->p_context->i_height;
+    p_dec->fmt_out.i_codec = VLC_FOURCC('I','4','2','0');
+
+    /* Get a new picture */
+    p_pic = p_dec->pf_vout_buffer_new( p_dec );
 
-    /* Send decoded frame to vout */
-    while( !(p_pic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 ) ) )
+    if( p_pic == NULL )
     {
-        if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error )
-        {
-            block_Release( p_block );
-            return VLC_EGENERIC;
-        }
-        msleep( VOUT_OUTMEM_SLEEP );
+        block_Release( p_block );
+        return NULL;
     }
 
     for( i_plane = 0; i_plane < 3; i_plane++ )
@@ -224,25 +199,23 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
         }
     }
 
-    vout_DatePicture( p_sys->p_vout, p_pic, p_block->i_pts);
-    vout_DisplayPicture( p_sys->p_vout, p_pic );
-
+    p_pic->date = p_block->i_pts;
     block_Release( p_block );
-    return VLC_SUCCESS;
+
+    return p_pic;
 }
 
 /*****************************************************************************
- * EndDecoder: theora decoder destruction
+ * CloseDecoder: decoder destruction
  *****************************************************************************/
-static int EndDecoder( decoder_t *p_dec )
+static void CloseDecoder( vlc_object_t *p_this )
 {
+    decoder_t *p_dec = (decoder_t *)p_this;
     decoder_sys_t *p_sys = p_dec->p_sys;
     int i;
 
     msg_Dbg( p_dec, "cinepak decoder stopped" );
 
-    vout_Request( p_dec, p_sys->p_vout, 0, 0, 0, 0 );
-
     for( i = 0; i < 3; i++ )
     {
         if( p_sys->p_context->p_pix[i] ) free( p_sys->p_context->p_pix[i] );
@@ -251,8 +224,6 @@ static int EndDecoder( decoder_t *p_dec )
     free( p_sys->p_context );
 
     free( p_sys );
-
-    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
index 84e41ed2e204708e96a5cecece455d86838b1b72..45e72f606edc6e3d523d1d7ef018e2aef471a6c9 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
- * dts.c: DTS basic parser
+ * dts.c: parse DTS audio sync info and packetize the stream
  *****************************************************************************
  * Copyright (C) 2003 VideoLAN
- * $Id: dts.c,v 1.4 2003/09/02 20:19:25 gbazin Exp $
+ * $Id: dts.c,v 1.5 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
  *          Gildas Bazin <gbazin@netcourrier.com>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>                                              /* memcpy() */
-#include <fcntl.h>
 
 #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
+#include "vlc_block_helper.h"
 
 #define DTS_HEADER_SIZE 10
 
@@ -53,48 +48,35 @@ struct decoder_sys_t
     /*
      * Input properties
      */
-    int     i_state;
+    int i_state;
 
-    uint8_t p_header[DTS_HEADER_SIZE];
-    int     i_header;
-
-    mtime_t pts;
-
-    int     i_frame_size;
+    block_bytestream_t bytestream;
 
     /*
-     * Decoder output properties
+     * Common 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 */
+    audio_date_t   end_date;
+
+    mtime_t i_pts;
+
+    int i_frame_size, i_bit_rate;
+    unsigned int i_frame_length, i_rate, i_channels, i_channels_conf;
+
     /* 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;
-
-    /*
-     * Packetizer output properties
-     */
-    sout_packetizer_input_t *p_sout_input;
-    sout_format_t           sout_format;
-    sout_buffer_t *         p_sout_buffer;            /* current sout buffer */
+    int i_frames_in_buf;
+    aout_buffer_t *p_aout_buffer;        /* current aout buffer being filled */
 
-    /*
-     * 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
+    STATE_NEXT_SYNC,
+    STATE_GET_DATA,
+    STATE_SEND_DATA
 };
 
 /****************************************************************************
@@ -102,18 +84,15 @@ enum {
  ****************************************************************************/
 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 CloseDecoder  ( vlc_object_t * );
+static void *DecodeBlock  ( decoder_t *, block_t ** );
 
 static int  SyncInfo      ( const byte_t *, unsigned int *, 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 * );
+static uint8_t       *GetOutBuffer ( decoder_t *, void ** );
+static aout_buffer_t *GetAoutBuffer( decoder_t * );
+static block_t       *GetSoutBuffer( decoder_t * );
 
 /*****************************************************************************
  * Module descriptor
@@ -121,7 +100,7 @@ static int SendOutBuffer( decoder_t * );
 vlc_module_begin();
     set_description( _("DTS parser") );
     set_capability( "decoder", 100 );
-    set_callbacks( OpenDecoder, NULL );
+    set_callbacks( OpenDecoder, CloseDecoder );
 
     add_submodule();
     set_description( _("DTS audio packetizer") );
@@ -135,25 +114,39 @@ vlc_module_end();
 static int OpenDecoder( vlc_object_t *p_this )
 {
     decoder_t *p_dec = (decoder_t*)p_this;
+    decoder_sys_t *p_sys;
 
-    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('d','t','s',' ')
-         && p_dec->p_fifo->i_fourcc != VLC_FOURCC('d','t','s','b') )
+    if( p_dec->fmt_in.i_codec != VLC_FOURCC('d','t','s',' ')
+         && p_dec->fmt_in.i_codec != VLC_FOURCC('d','t','s','b') )
     {
         return VLC_EGENERIC;
     }
 
-    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 =
+    if( ( p_dec->p_sys = 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;
+
+    /* Misc init */
+    p_sys->b_packetizer = VLC_FALSE;
+    p_sys->i_state = STATE_NOSYNC;
+    aout_DateSet( &p_sys->end_date, 0 );
+    p_sys->i_frames_in_buf = 0;
+
+    p_sys->bytestream = block_BytestreamInit( p_dec );
+
+    /* Set output properties */
+    p_dec->fmt_out.i_cat = AUDIO_ES;
+    p_dec->fmt_out.i_codec = VLC_FOURCC('d','t','s',' ');
+
+    /* Set callback */
+    p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
+        DecodeBlock;
+    p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
+        DecodeBlock;
 
     return VLC_SUCCESS;
 }
@@ -169,420 +162,264 @@ static int OpenPacketizer( vlc_object_t *p_this )
     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('d','t','s',' ');
-
-    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;
-}
-
 /****************************************************************************
- * RunDecoder: the whole thing
+ * DecodeBlock: the whole thing
  ****************************************************************************
  * This function is called just after the thread is launched.
  ****************************************************************************/
-static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
-    int i, i_block_pos = 0;
-    mtime_t i_pts = p_block->i_pts;
+    uint8_t p_header[DTS_HEADER_SIZE];
+    uint8_t *p_buf;
+    void *p_out_buffer;
 
-    while( i_block_pos < p_block->i_buffer )
+    if( !pp_block || !*pp_block ) return NULL;
+
+    if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )
+    {
+        /* We've just started the stream, wait for the first PTS. */
+        block_Release( *pp_block );
+        return NULL;
+    }
+
+    if( (*pp_block)->b_discontinuity )
+    {
+        p_sys->i_state = STATE_NOSYNC;
+    }
+
+    block_BytestreamPush( &p_sys->bytestream, *pp_block );
+
+    while( 1 )
     {
         switch( p_sys->i_state )
         {
         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 )
+            while( block_PeekBytes( &p_sys->bytestream, p_header, 4 )
+                   == VLC_SUCCESS )
             {
-                i_block_pos++;
-            }
-
-            if( i_block_pos < p_block->i_buffer )
-            {
-                p_sys->i_state = STATE_PARTIAL_SYNC;
-                i_block_pos++;
-                p_sys->p_header[0] = 0x7f;
-                p_sys->i_header = 1;
-                break;
-            }
-            break;
-
-        case STATE_PARTIAL_SYNC:
-            /* Get the full 4 sync bytes */
-            if( p_sys->i_header < 4 )
-            {
-                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( 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 )
-            {
-                p_sys->i_state = STATE_SYNC;
-            }
-            else
-            {
-                for( i = 1; i < 4; i++ )
+                if( p_header[0] == 0x7f && p_header[1] == 0xfe &&
+                    p_header[2] == 0x80 && p_header[3] == 0x01 )
                 {
-                    if( p_sys->p_header[i] == 0x7f ) break;
-                }
-
-                if( p_sys->p_header[i] == 0x7f )
-                {
-                    /* Potential new sync */
-                    p_sys->i_header -= i;
-                    memmove( p_sys->p_header, &p_sys->p_header[i],
-                             p_sys->i_header );
+                    p_sys->i_state = STATE_SYNC;
                     break;
                 }
+                block_SkipByte( &p_sys->bytestream );
+            }
+            if( p_sys->i_state != STATE_SYNC )
+            {
+                block_BytestreamFlush( &p_sys->bytestream );
 
-                /* retry to sync*/
-                p_sys->i_state = STATE_NOSYNC;
+                /* Need more data */
+                return NULL;
             }
-            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 ) )
+            p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
+            if( p_sys->i_pts != 0 &&
+                p_sys->i_pts != aout_DateGet( &p_sys->end_date ) )
             {
-                aout_DateSet( &p_sys->end_date, p_sys->pts );
+                aout_DateSet( &p_sys->end_date, p_sys->i_pts );
             }
             p_sys->i_state = STATE_HEADER;
-            break;
 
         case STATE_HEADER:
             /* Get DTS frame header (DTS_HEADER_SIZE bytes) */
-            if( p_sys->i_header < DTS_HEADER_SIZE )
+            if( block_PeekBytes( &p_sys->bytestream, p_header,
+                                 DTS_HEADER_SIZE ) != VLC_SUCCESS )
             {
-                int i_size = __MIN( DTS_HEADER_SIZE - p_sys->i_header,
-                                    p_block->i_buffer - i_block_pos );
-
-                memcpy( p_sys->p_header + p_sys->i_header,
-                        p_block->p_buffer + i_block_pos, i_size );
-                i_block_pos += i_size;
-                p_sys->i_header += i_size;
+                /* Need more data */
+                return NULL;
             }
 
-            if( p_sys->i_header < DTS_HEADER_SIZE )
+            /* Check if frame is valid and get frame info */
+            p_sys->i_frame_size = SyncInfo( p_header,
+                                            &p_sys->i_channels,
+                                            &p_sys->i_channels_conf,
+                                            &p_sys->i_rate,
+                                            &p_sys->i_bit_rate,
+                                            &p_sys->i_frame_length );
+            if( !p_sys->i_frame_size )
+            {
+                msg_Dbg( p_dec, "emulated sync word" );
+                block_SkipByte( &p_sys->bytestream );
+                p_sys->i_state = STATE_NOSYNC;
                 break;
+            }
+            p_sys->i_state = STATE_NEXT_SYNC;
 
-            if( GetOutBuffer( p_dec, &p_sys->p_out_buffer )
+        case STATE_NEXT_SYNC:
+            /* TODO: If pp_block == NULL, flush the buffer without checking the
+             * next sync word */
+
+            /* Check if next expected frame contains the sync word */
+            if( block_PeekOffsetBytes( &p_sys->bytestream,
+                                       p_sys->i_frame_size, p_header, 4 )
                 != VLC_SUCCESS )
             {
-                block_Release( p_block );
-                return VLC_EGENERIC;
+                /* Need more data */
+                return NULL;
             }
 
-            if( !p_sys->p_out_buffer )
+            if( p_header[0] == 0x7f && p_header[1] == 0xfe &&
+                p_header[2] == 0x80 && p_header[3] == 0x01 )
             {
+                msg_Dbg( p_dec, "emulated sync word "
+                         "(no sync on following frame)" );
                 p_sys->i_state = STATE_NOSYNC;
+                block_SkipByte( &p_sys->bytestream );
                 break;
             }
-
-            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;
+            p_sys->i_state = STATE_SEND_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 )
+        case STATE_GET_DATA:
+            /* Make sure we have enough data.
+             * (Not useful if we went through NEXT_SYNC) */
+            if( block_WaitBytes( &p_sys->bytestream,
+                                 p_sys->i_frame_size ) != VLC_SUCCESS )
             {
-                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;
+                /* Need more data */
+                return NULL;
             }
+            p_sys->i_state = STATE_SEND_DATA;
 
-            if( p_sys->i_out_buffer < p_sys->i_frame_size )
-                break; /* Need more data */
+        case STATE_SEND_DATA:
+            if( !(p_buf = GetOutBuffer( p_dec, &p_out_buffer )) )
+            {
+                //p_dec->b_error = VLC_TRUE;
+                return NULL;
+            }
 
-            SendOutBuffer( p_dec );
+            /* Copy the whole frame into the buffer. When we reach this point
+             * we already know we have enough data available. */
+            block_GetBytes( &p_sys->bytestream, p_buf, p_sys->i_frame_size );
 
-            p_sys->i_state = STATE_NOSYNC;
-            break;
-        }
-    }
+            /* Make sure we don't reuse the same pts twice */
+            if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
+                p_sys->i_pts = p_sys->bytestream.p_block->i_pts = 0;
 
-    block_Release( p_block );
-    return VLC_SUCCESS;
-}
+            /* So p_block doesn't get re-added several times */
+            *pp_block = block_BytestreamPop( &p_sys->bytestream );
 
-/*****************************************************************************
- * 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 );
-        }
+            p_sys->i_state = STATE_NOSYNC;
 
-        aout_DecDelete( p_dec->p_sys->p_aout, p_dec->p_sys->p_aout_input );
-    }
+            if( !p_sys->b_packetizer )
+            {
+                if( p_sys->i_frames_in_buf != 3 ) return NULL;
+                else
+                {
+                    p_sys->i_frames_in_buf = 0;
+                    p_sys->p_aout_buffer = 0;
+                }
+            }
 
-    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 );
+            return p_out_buffer;
         }
-
-        sout_InputDelete( p_dec->p_sys->p_sout_input );
     }
 
-    free( p_dec->p_sys );
-
-    return VLC_SUCCESS;
+    return NULL;
 }
 
 /*****************************************************************************
- * GetOutBuffer:
+ * CloseDecoder: clean up the decoder
  *****************************************************************************/
-static int GetOutBuffer ( decoder_t *p_dec, uint8_t **pp_out_buffer )
+static void CloseDecoder( vlc_object_t *p_this )
 {
+    decoder_t *p_dec = (decoder_t*)p_this;
     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;
-    }
+    block_BytestreamRelease( &p_sys->bytestream );
 
-    return i_ret;
+    free( p_sys );
 }
 
 /*****************************************************************************
- * GetAoutBuffer:
+ * GetOutBuffer:
  *****************************************************************************/
-static int GetAoutBuffer( decoder_t *p_dec, aout_buffer_t **pp_buffer )
+static uint8_t *GetOutBuffer( decoder_t *p_dec, void **pp_out_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;
+    uint8_t *p_buf;
 
-    /* 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 )
+    if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
     {
-        msg_Warn( p_dec, "dts syncinfo failed" );
-        *pp_buffer = NULL;
-        return VLC_SUCCESS;
-    }
+        msg_Info( p_dec, "DTS channels:%d samplerate:%d bitrate:%d",
+                  p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate );
 
-    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;
+        aout_DateInit( &p_sys->end_date, p_sys->i_rate );
+        aout_DateSet( &p_sys->end_date, p_sys->i_pts );
     }
 
-    /* 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;
-        }
-    }
+    p_dec->fmt_out.audio.i_rate     = p_sys->i_rate;
+    p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
+    p_dec->fmt_out.audio.i_bitrate  = p_sys->i_bit_rate;
+    p_dec->fmt_out.audio.i_bytes_per_frame = p_sys->i_frame_size;
+    p_dec->fmt_out.audio.i_frame_length = p_sys->i_frame_length;
+
+    p_dec->fmt_out.audio.i_original_channels = p_sys->i_channels_conf;
+    p_dec->fmt_out.audio.i_physical_channels =
+        p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
 
-    if( !aout_DateGet( &p_sys->end_date ) )
+    if( p_sys->b_packetizer )
     {
-        /* We've just started the stream, wait for the first PTS. */
-        *pp_buffer = NULL;
-        return VLC_SUCCESS;
+        block_t *p_sout_buffer = GetSoutBuffer( p_dec );
+        p_buf = p_sout_buffer ? p_sout_buffer->p_buffer : NULL;
+        *pp_out_buffer = p_sout_buffer;
     }
-
-    if( p_sys->i_frames_in_buf == 3 )
+    else
     {
-        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 )
+        if( !p_sys->i_frames_in_buf )
         {
-            return VLC_SUCCESS;
+            p_sys->p_aout_buffer = GetAoutBuffer( p_dec );
         }
-
-        (*pp_buffer)->start_date = aout_DateGet( &p_sys->end_date );
-        (*pp_buffer)->end_date =
-             aout_DateIncrement( &p_sys->end_date, i_frame_length * 3 );
+        p_buf = p_sys->p_aout_buffer ? p_sys->p_aout_buffer->p_buffer +
+            p_sys->i_frames_in_buf * p_sys->i_frame_size : NULL;
+        *pp_out_buffer = p_sys->p_aout_buffer;
     }
 
     p_sys->i_frames_in_buf++;
 
-    return VLC_SUCCESS;
+    return p_buf;
 }
 
 /*****************************************************************************
- * GetSoutBuffer:
+ * GetAoutBuffer:
  *****************************************************************************/
-static int GetSoutBuffer( decoder_t *p_dec, sout_buffer_t **pp_buffer )
+static aout_buffer_t *GetAoutBuffer( decoder_t *p_dec )
 {
-    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;
+    aout_buffer_t *p_buf;
 
-    /* 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_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 );
+    p_buf = p_dec->pf_aout_buffer_new( p_dec, p_sys->i_frame_length * 3 );
+    if( p_buf == NULL ) return NULL;
 
-    (*pp_buffer)->i_length =
-        aout_DateIncrement( &p_sys->end_date, i_frame_length )
-        - (*pp_buffer)->i_pts;
+    p_buf->start_date = aout_DateGet( &p_sys->end_date );
+    p_buf->end_date =
+        aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length * 3 );
 
-    return VLC_SUCCESS;
+    return p_buf;
 }
 
 /*****************************************************************************
- * SendOutBuffer:
+ * GetSoutBuffer:
  *****************************************************************************/
-static int SendOutBuffer( decoder_t *p_dec )
+static block_t *GetSoutBuffer( decoder_t *p_dec )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
+    block_t *p_block;
 
-    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;
-    }
+    p_block = block_New( p_dec, p_sys->i_frame_size );
+    if( p_block == NULL ) return NULL;
 
-    return VLC_SUCCESS;
+    p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
+
+    p_block->i_length = aout_DateIncrement( &p_sys->end_date,
+        p_sys->i_frame_length ) - p_block->i_pts;
+
+    return p_block;
 }
 
 /*****************************************************************************
index d84b1a7bb99943fb091f39cc20afa6eee7447216..5f9acf9f30987040727ae2ba7ebadb7c4a860bac 100644 (file)
@@ -2,7 +2,7 @@
  * dv.c: a decoder for DV video
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: dv.c,v 1.5 2003/09/02 20:19:25 gbazin Exp $
+ * $Id: dv.c,v 1.6 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -59,7 +59,7 @@ static int OpenDecoder ( vlc_object_t *p_this )
 {
     decoder_t *p_dec = (decoder_t*)p_this;
 
-    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('d','v','s','d') )
+    if( p_dec->fmt_in.i_codec != VLC_FOURCC('d','v','s','d') )
     {
         return VLC_EGENERIC;
     }
index f561f96b0eff1575f59ac979b155ee46d12af3ad..2a3f2d252b463fb7c3f2d75936c158692979f52c 100644 (file)
@@ -2,7 +2,7 @@
  * dvbsub.c : DVB subtitles decoder thread
  *****************************************************************************
  * Copyright (C) 2003 ANEVIA
- * $Id: dvbsub.c,v 1.2 2003/11/06 19:35:05 nitrox Exp $
+ * $Id: dvbsub.c,v 1.3 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Damien LUCAS <damien.lucas@anevia.com>
  *
@@ -275,7 +275,7 @@ vlc_module_end();
 static int OpenDecoder( vlc_object_t *p_this )
 {
     decoder_t *p_dec = (decoder_t*) p_this;
-    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('d','v','b','s') )
+    if( p_dec->fmt_in.i_codec != VLC_FOURCC('d','v','b','s') )
     {
         return VLC_EGENERIC;
     }
index ae96b4b1d5d10f1a50f2c9b20edbcbfbe8ed2b9b..a6000b406f78cff33264fced5efd88637e1f046c 100644 (file)
@@ -2,7 +2,7 @@
  * decoder.c: AAC decoder using libfaad2
  *****************************************************************************
  * Copyright (C) 2001, 2003 VideoLAN
- * $Id: faad.c,v 1.3 2003/11/05 01:47:40 fenrir Exp $
+ * $Id: faad.c,v 1.4 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
  * Module descriptor
  *****************************************************************************/
 static int  Open( vlc_object_t * );
+static void CloseDecoder( vlc_object_t * );
 
 vlc_module_begin();
     set_description( _("AAC audio decoder (using libfaad2)") );
     set_capability( "decoder", 60 );
-    set_callbacks( Open, NULL );
+    set_callbacks( Open, CloseDecoder );
 vlc_module_end();
 
 
 /****************************************************************************
  * Local prototypes
  ****************************************************************************/
-static int  InitDecoder   ( decoder_t * );
-static int  RunDecoder    ( decoder_t *, block_t * );
-static int  EndDecoder    ( decoder_t * );
+static aout_buffer_t *DecodeBlock( decoder_t *, block_t ** );
 
 struct decoder_sys_t
 {
     /* faad handler */
     faacDecHandle *hfaad;
 
-    /* audio output */
-    audio_sample_format_t output_format;
-    aout_instance_t *     p_aout;                                  /* opaque */
-    aout_input_t *        p_aout_input;                            /* opaque */
-
     /* samples */
-    audio_date_t          date;
+    audio_date_t date;
 
     /* temporary buffer */
-    uint8_t               *p_buffer;
-    int                   i_buffer;
-    int                   i_buffer_size;
+    uint8_t *p_buffer;
+    int     i_buffer;
+    int     i_buffer_size;
 };
 
-/*****************************************************************************
- * OpenDecoder: probe the decoder and return score
- *****************************************************************************/
-static int  Open( vlc_object_t *p_this )
-{
-    decoder_t *p_dec = (decoder_t*)p_this;
-
-    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('m','p','4','a') )
-    {
-        return VLC_EGENERIC;
-    }
-
-    p_dec->pf_init = InitDecoder;
-    p_dec->pf_decode = RunDecoder;
-    p_dec->pf_end = EndDecoder;
-
-    p_dec->p_sys  = malloc( sizeof( decoder_sys_t ) );
-
-    return VLC_SUCCESS;
-}
-
 static unsigned int pi_channels_maps[7] =
 {
     0,
     AOUT_CHAN_CENTER,
     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
     AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
-    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
-    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
+    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT |
+        AOUT_CHAN_REARRIGHT,
+    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |
+        AOUT_CHAN_REARRIGHT,
      /* FIXME */
-    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_REARCENTER
+    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |
+        AOUT_CHAN_REARRIGHT | AOUT_CHAN_REARCENTER
 };
 
 /*****************************************************************************
- * InitDecoder:
+ * OpenDecoder: probe the decoder and return score
  *****************************************************************************/
-static int  InitDecoder   ( decoder_t *p_dec )
+static int Open( vlc_object_t *p_this )
 {
+    decoder_t *p_dec = (decoder_t*)p_this;
     decoder_sys_t *p_sys = p_dec->p_sys;
-    WAVEFORMATEX    wf, *p_wf;
     faacDecConfiguration *cfg;
 
-    if( ( p_wf = (WAVEFORMATEX*)p_dec->p_fifo->p_waveformatex ) == NULL )
+    if( p_dec->fmt_in.i_codec != VLC_FOURCC('m','p','4','a') )
     {
-        p_wf = &wf;
-        memset( p_wf, 0, sizeof( WAVEFORMATEX ) );
+        return VLC_EGENERIC;
+    }
+
+    /* Allocate the memory needed to store the decoder's structure */
+    if( ( p_dec->p_sys = p_sys =
+          (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
+    {
+        msg_Err( p_dec, "out of memory" );
+        return VLC_EGENERIC;
     }
 
     /* Open a faad context */
@@ -123,37 +106,43 @@ static int  InitDecoder   ( decoder_t *p_dec )
         return VLC_EGENERIC;
     }
 
-    if( p_wf->cbSize > 0 )
+    /* Misc init */
+    aout_DateSet( &p_sys->date, 0 );
+    p_dec->fmt_out.i_cat = AUDIO_ES;
+    p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','3','2');
+    p_dec->pf_decode_audio = DecodeBlock;
+
+    if( p_dec->fmt_in.i_extra > 0 )
     {
         /* We have a decoder config so init the handle */
-        unsigned long   i_rate;
-        unsigned char   i_channels;
+        unsigned long i_rate;
+        unsigned char i_channels;
 
-        if( faacDecInit2( p_sys->hfaad,
-                          (uint8_t*)&p_wf[1], p_wf->cbSize,
+        if( faacDecInit2( p_sys->hfaad, p_dec->fmt_in.p_extra,
+                          p_dec->fmt_in.i_extra,
                           &i_rate, &i_channels ) < 0 )
         {
             return VLC_EGENERIC;
         }
 
-        p_sys->output_format.i_rate = i_rate;
-        p_sys->output_format.i_physical_channels =
-        p_sys->output_format.i_original_channels =
-            pi_channels_maps[i_channels];
+        p_dec->fmt_out.audio.i_rate = i_rate;
+        p_dec->fmt_out.audio.i_channels = i_channels;
+        p_dec->fmt_out.audio.i_physical_channels =
+            p_dec->fmt_out.audio.i_original_channels =
+                pi_channels_maps[i_channels];
+
+        aout_DateInit( &p_sys->date, i_rate );
     }
     else
     {
         /* Will be initalised from first frame */
-        p_sys->output_format.i_rate = 0;
-        p_sys->output_format.i_physical_channels =
-        p_sys->output_format.i_original_channels = 0;
+        p_dec->fmt_out.audio.i_rate = 0;
+        p_dec->fmt_out.audio.i_channels = 0;
+        p_dec->fmt_out.audio.i_physical_channels =
+            p_dec->fmt_out.audio.i_original_channels = 0;
     }
-    p_sys->output_format.i_format = VLC_FOURCC('f','l','3','2');
-
-    p_sys->p_aout = NULL;
-    p_sys->p_aout_input = NULL;
 
-    /* set the faad config */
+    /* Set the faad config */
     cfg = faacDecGetCurrentConfiguration( p_sys->hfaad );
     cfg->outputFormat = FAAD_FMT_FLOAT;
     faacDecSetConfiguration( p_sys->hfaad, cfg );
@@ -167,28 +156,36 @@ static int  InitDecoder   ( decoder_t *p_dec )
 }
 
 /*****************************************************************************
- * InitDecoder:
+ * DecodeBlock:
  *****************************************************************************/
-static int  RunDecoder    ( decoder_t *p_dec, block_t *p_block )
+static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
+    block_t *p_block;
 
-    int          i_used = 0;
-    mtime_t      i_pts = p_block->i_pts;
+    if( !pp_block || !*pp_block ) return NULL;
+
+    p_block = *pp_block;
 
     /* Append the block to the temporary buffer */
     if( p_sys->i_buffer_size < p_sys->i_buffer + p_block->i_buffer )
     {
-        p_sys->i_buffer_size += p_block->i_buffer;
+        p_sys->i_buffer_size = p_sys->i_buffer + p_block->i_buffer;
         p_sys->p_buffer = realloc( p_sys->p_buffer, p_sys->i_buffer_size );
     }
-    memcpy( &p_sys->p_buffer[p_sys->i_buffer], p_block->p_buffer, p_block->i_buffer );
-    p_sys->i_buffer += p_block->i_buffer;
 
-    if( p_sys->output_format.i_rate == 0 )
+    if( p_block->i_buffer )
+    {
+        memcpy( &p_sys->p_buffer[p_sys->i_buffer],
+                p_block->p_buffer, p_block->i_buffer );
+        p_sys->i_buffer += p_block->i_buffer;
+        p_block->i_buffer = 0;
+    }
+
+    if( p_dec->fmt_out.audio.i_rate == 0 && p_sys->i_buffer )
     {
-        unsigned long   i_rate;
-        unsigned char   i_channels;
+        unsigned long i_rate;
+        unsigned char i_channels;
 
         /* Init faad with the first frame */
         if( faacDecInit( p_sys->hfaad,
@@ -196,137 +193,121 @@ static int  RunDecoder    ( decoder_t *p_dec, block_t *p_block )
                          &i_rate, &i_channels ) < 0 )
         {
             block_Release( p_block );
-            return VLC_EGENERIC;
+            return NULL;
         }
-        p_sys->output_format.i_rate = i_rate;
-        p_sys->output_format.i_physical_channels =
-        p_sys->output_format.i_original_channels =
-            pi_channels_maps[i_channels];
+
+        p_dec->fmt_out.audio.i_rate = i_rate;
+        p_dec->fmt_out.audio.i_channels = i_channels;
+        p_dec->fmt_out.audio.i_physical_channels =
+            p_dec->fmt_out.audio.i_original_channels =
+                pi_channels_maps[i_channels];
+
+        aout_DateInit( &p_sys->date, i_rate );
+    }
+
+    if( p_block->i_pts != 0 && p_block->i_pts != aout_DateGet( &p_sys->date ) )
+    {
+        aout_DateSet( &p_sys->date, p_block->i_pts );
+    }
+    else if( !aout_DateGet( &p_sys->date ) )
+    {
+        /* We've just started the stream, wait for the first PTS. */
+        block_Release( p_block );
+        p_sys->i_buffer = 0;
+        return NULL;
     }
 
     /* Decode all data */
-    while( i_used < p_sys->i_buffer )
+    if( p_sys->i_buffer )
     {
         void *samples;
         faacDecFrameInfo frame;
-        aout_buffer_t   *out;
+        aout_buffer_t *p_out;
 
         samples = faacDecDecode( p_sys->hfaad, &frame,
-                                 &p_sys->p_buffer[i_used], p_sys->i_buffer - i_used );
+                                 p_sys->p_buffer, p_sys->i_buffer );
 
         if( frame.error > 0 )
         {
             msg_Warn( p_dec, "%s", faacDecGetErrorMessage( frame.error ) );
-            /* flush the buffer */
+
+            /* Flush the buffer */
             p_sys->i_buffer = 0;
             block_Release( p_block );
-            return VLC_SUCCESS;
+            return NULL;
         }
+
         if( frame.channels <= 0 || frame.channels > 6 )
         {
             msg_Warn( p_dec, "invalid channels count" );
-            /* flush the buffer */
+
+            /* Flush the buffer */
             p_sys->i_buffer = 0;
             block_Release( p_block );
-            return VLC_SUCCESS;
+            return NULL;
         }
+
         if( frame.samples <= 0 )
         {
             msg_Warn( p_dec, "decoded zero samples" );
-            /* flush the buffer */
+
+            /* Flush the buffer */
             p_sys->i_buffer = 0;
             block_Release( p_block );
-            return VLC_SUCCESS;
+            return NULL;
         }
 
-        /* we have decoded a valid frame */
-        /* msg_Dbg( p_dec, "consumed %d for %dHz %dc %lld", frame.bytesconsumed, frame.samplerate, frame.channels, i_pts ); */
-        i_used += frame.bytesconsumed;
-
-
-        /* create/recreate the output */
-        if( p_sys->p_aout_input &&
-            ( p_sys->output_format.i_original_channels != pi_channels_maps[frame.channels] ||
-              p_sys->output_format.i_rate != frame.samplerate ) )
+        /* We decoded a valid frame */
+        if( p_dec->fmt_out.audio.i_rate != frame.samplerate )
         {
-            aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
-            p_sys->p_aout_input = NULL;
+            aout_DateInit( &p_sys->date, frame.samplerate );
+            aout_DateSet( &p_sys->date, p_block->i_pts );
         }
+        p_block->i_pts = 0;  /* PTS is valid only once */
 
-        if( p_sys->p_aout_input == NULL )
-        {
-            p_sys->output_format.i_physical_channels =
-            p_sys->output_format.i_original_channels = pi_channels_maps[frame.channels];
-            p_sys->output_format.i_rate = frame.samplerate;
-
-            aout_DateInit( &p_sys->date, p_sys->output_format.i_rate );
-            aout_DateSet( &p_sys->date, 0 );
-
-            p_sys->p_aout_input = aout_DecNew( p_dec, &p_sys->p_aout, &p_sys->output_format );
-        }
+        p_dec->fmt_out.audio.i_rate = frame.samplerate;
+        p_dec->fmt_out.audio.i_channels = frame.channels;
+        p_dec->fmt_out.audio.i_physical_channels =
+            p_dec->fmt_out.audio.i_original_channels =
+                pi_channels_maps[frame.channels];
 
-        if( p_sys->p_aout_input == NULL )
+        p_out = p_dec->pf_aout_buffer_new( p_dec,
+                                           frame.samples / frame.channels );
+        if( p_out == NULL )
         {
-            msg_Err( p_dec, "cannot create aout" );
+            p_sys->i_buffer = 0;
             block_Release( p_block );
-            return VLC_EGENERIC;
+            return NULL;
         }
 
-        if( i_pts != 0 && i_pts != aout_DateGet( &p_sys->date ) )
-        {
-            aout_DateSet( &p_sys->date, i_pts );
-        }
-        else if( !aout_DateGet( &p_sys->date ) )
-        {
-            /* Wait for a dated packet */
-            msg_Dbg( p_dec, "no date" );
-            p_sys->i_buffer = 0;
-            return VLC_SUCCESS;
-        }
-        i_pts = 0;  /* PTS is valid only once */
+        p_out->start_date = aout_DateGet( &p_sys->date );
+        p_out->end_date = aout_DateIncrement( &p_sys->date,
+                                              frame.samples / frame.channels );
+
+        memcpy( p_out->p_buffer, samples, p_out->i_nb_bytes );
 
-        if( ( out = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
-                                       frame.samples / frame.channels ) ) == NULL )
+        p_sys->i_buffer -= frame.bytesconsumed;
+        if( p_sys->i_buffer > 0 )
         {
-            msg_Err( p_dec, "cannot get a new buffer" );
-            block_Release( p_block );
-            return VLC_EGENERIC;
+            memmove( p_sys->p_buffer, &p_sys->p_buffer[frame.bytesconsumed],
+                     p_sys->i_buffer );
         }
-        out->start_date = aout_DateGet( &p_sys->date );
-        out->end_date   = aout_DateIncrement( &p_sys->date,
-                                              frame.samples / frame.channels );
-        memcpy( out->p_buffer, samples, out->i_nb_bytes );
-
-        aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input, out );
-    }
 
-    p_sys->i_buffer -= i_used;
-    if( p_sys->i_buffer > 0 )
-    {
-        memmove( &p_sys->p_buffer[0], &p_sys->p_buffer[i_used], p_sys->i_buffer );
+        return p_out;
     }
 
     block_Release( p_block );
-    return VLC_SUCCESS;
+    return NULL;
 }
 
 /*****************************************************************************
- * InitDecoder:
+ * CloseDecoder:
  *****************************************************************************/
-static int  EndDecoder    ( decoder_t *p_dec )
+static void CloseDecoder( vlc_object_t *p_this )
 {
+    decoder_t *p_dec = (decoder_t *)p_this;
     decoder_sys_t *p_sys = p_dec->p_sys;
 
-    if( p_sys->p_aout_input )
-    {
-        aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
-    }
-
     faacDecClose( p_sys->hfaad );
     free( p_sys );
-
-    return VLC_SUCCESS;
 }
-
-
-
index df9191fb24d6d73f9258c5690de67c6aa5240ccb..b50f0c13f189021556990c0376ba4a1dac4ecde1 100644 (file)
@@ -2,7 +2,7 @@
  * audio.c: audio decoder using ffmpeg library
  *****************************************************************************
  * Copyright (C) 1999-2003 VideoLAN
- * $Id: audio.c,v 1.21 2003/10/27 10:00:40 gbazin Exp $
+ * $Id: audio.c,v 1.22 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Gildas Bazin <gbazin@netcourrier.com>
 #include <string.h>
 
 #include <vlc/vlc.h>
-#include <vlc/vout.h>
-#include <vlc/aout.h>
 #include <vlc/decoder.h>
 #include <vlc/input.h>
 
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>                                              /* getpid() */
-#endif
-
-#ifdef HAVE_SYS_TIMES_H
-#   include <sys/times.h>
-#endif
-
 #include "codecs.h"
 #include "aout_internal.h"
 
@@ -83,8 +73,6 @@ struct decoder_sys_t
     /*
      * Output properties
      */
-    aout_instance_t       *p_aout;
-    aout_input_t          *p_aout_input;
     audio_sample_format_t aout_format;
     audio_date_t          end_date;
 };
@@ -98,7 +86,6 @@ int E_(InitAudioDec)( decoder_t *p_dec, AVCodecContext *p_context,
                       AVCodec *p_codec, int i_codec_id, char *psz_namecodec )
 {
     decoder_sys_t *p_sys;
-    WAVEFORMATEX wf, *p_wf;
 
     /* Allocate the memory needed to store the decoder's structure */
     if( ( p_dec->p_sys = p_sys =
@@ -113,25 +100,19 @@ int E_(InitAudioDec)( decoder_t *p_dec, AVCodecContext *p_context,
     p_dec->p_sys->i_codec_id = i_codec_id;
     p_dec->p_sys->psz_namecodec = psz_namecodec;
 
-    if( ( p_wf = p_dec->p_fifo->p_waveformatex ) == NULL )
-    {
-        msg_Warn( p_dec, "audio informations missing" );
-        p_wf = &wf;
-        memset( p_wf, 0, sizeof( WAVEFORMATEX ) );
-    }
-
     /* ***** Fill p_context with init values ***** */
-    p_sys->p_context->sample_rate = p_wf->nSamplesPerSec;
-    p_sys->p_context->channels = p_wf->nChannels;
-    p_sys->p_context->block_align = p_wf->nBlockAlign;
-    p_sys->p_context->bit_rate = p_wf->nAvgBytesPerSec * 8;
+    p_sys->p_context->sample_rate = p_dec->fmt_in.audio.i_rate;
+    p_sys->p_context->channels = p_dec->fmt_in.audio.i_channels;
+    p_sys->p_context->block_align = p_dec->fmt_in.audio.i_blockalign;
+    p_sys->p_context->bit_rate = p_dec->fmt_in.i_bitrate;
 
-    if( ( p_sys->p_context->extradata_size = p_wf->cbSize ) > 0 )
+    if( ( p_sys->p_context->extradata_size = p_dec->fmt_in.i_extra ) > 0 )
     {
         p_sys->p_context->extradata =
-            malloc( p_wf->cbSize + FF_INPUT_BUFFER_PADDING_SIZE );
-        memcpy( p_sys->p_context->extradata, &p_wf[1], p_wf->cbSize);
-        memset( &((uint8_t*)p_sys->p_context->extradata)[p_wf->cbSize], 0,
+            malloc( p_dec->fmt_in.i_extra + FF_INPUT_BUFFER_PADDING_SIZE );
+        memcpy( p_sys->p_context->extradata,
+                p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra );
+        memset( p_sys->p_context->extradata + p_dec->fmt_in.i_extra, 0,
                 FF_INPUT_BUFFER_PADDING_SIZE );
     }
 
@@ -148,131 +129,106 @@ int E_(InitAudioDec)( decoder_t *p_dec, AVCodecContext *p_context,
 
     p_sys->p_output = malloc( 3 * AVCODEC_MAX_AUDIO_FRAME_SIZE );
 
-    p_sys->p_aout = NULL;
-    p_sys->p_aout_input = NULL;
-
     aout_DateSet( &p_sys->end_date, 0 );
 
+    /* Set output properties */
+    p_dec->fmt_out.i_cat = AUDIO_ES;
+    p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
+
     return VLC_SUCCESS;
 }
 
 /*****************************************************************************
  * DecodeAudio: Called to decode one frame
  *****************************************************************************/
-int E_( DecodeAudio )( decoder_t *p_dec, block_t *p_block )
+aout_buffer_t *E_( DecodeAudio )( decoder_t *p_dec, block_t **pp_block )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
-    aout_buffer_t *p_aout_buffer;
-    mtime_t i_pts;
+    int i_used, i_output, i_samples;
+    uint8_t *p_samples;
+    aout_buffer_t *p_buffer;
+    block_t *p_block;
+
+    if( !pp_block || !*pp_block ) return NULL;
 
-    uint8_t *p_buffer, *p_samples;
-    int i_buffer, i_samples;
+    p_block = *pp_block;
 
     if( !aout_DateGet( &p_sys->end_date ) && !p_block->i_pts )
     {
         /* We've just started the stream, wait for the first PTS. */
         block_Release( p_block );
-        return VLC_SUCCESS;
+        return NULL;
     }
 
-    i_pts = p_block->i_pts;
-    i_buffer = p_block->i_buffer;
-    p_buffer = p_block->p_buffer;
-
-    while( i_buffer )
+    if( !p_block->i_buffer )
     {
-        int i_used, i_output;
+        block_Release( p_block );
+        return NULL;
+    }
 
-        i_used = avcodec_decode_audio( p_sys->p_context,
-                                       (int16_t*)p_sys->p_output, &i_output,
-                                       p_buffer, i_buffer );
+    i_used = avcodec_decode_audio( p_sys->p_context,
+                                   (int16_t*)p_sys->p_output, &i_output,
+                                   p_block->p_buffer, p_block->i_buffer );
+
+    if( i_used < 0 )//|| i_output == 0 )
+    {
         if( i_used < 0 )
-        {
-            msg_Warn( p_dec, "cannot decode one frame (%d bytes)", i_buffer );
-            break;
-        }
-
-        i_buffer -= i_used;
-        p_buffer += i_used;
-
-        if( p_sys->p_context->channels <= 0 || p_sys->p_context->channels > 6 )
-        {
-            msg_Warn( p_dec, "invalid channels count %d",
-                      p_sys->p_context->channels );
-            break;
-        }
-
-        /* **** First check if we have a valid output **** */
-        if( p_sys->p_aout_input == NULL ||
-            p_sys->aout_format.i_original_channels !=
-            pi_channels_maps[p_sys->p_context->channels] )
-        {
-            if( p_sys->p_aout_input != NULL )
-            {
-                /* **** Delete the old **** */
-                aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
-            }
-
-            /* **** Create a new audio output **** */
-            p_sys->aout_format.i_format = AOUT_FMT_S16_NE;
-            p_sys->aout_format.i_rate = p_sys->p_context->sample_rate;
-            p_sys->aout_format.i_physical_channels =
-                p_sys->aout_format.i_original_channels =
-                    pi_channels_maps[p_sys->p_context->channels];
-
-            aout_DateInit( &p_sys->end_date, p_sys->aout_format.i_rate );
-            p_sys->p_aout_input = aout_DecNew( p_dec, &p_sys->p_aout,
-                                               &p_sys->aout_format );
-        }
-
-        if( !p_sys->p_aout_input )
-        {
-            msg_Err( p_dec, "cannot create audio output" );
-            block_Release( p_block );
-            return VLC_EGENERIC;
-        }
-
-        if( i_pts != 0 && i_pts != aout_DateGet( &p_sys->end_date ) )
-        {
-            aout_DateSet( &p_sys->end_date, i_pts );
-            i_pts = 0;
-        }
-
-        /* **** Now we can output these samples **** */
-        i_samples = i_output / 2 / p_sys->p_context->channels;
-
-        p_samples = p_sys->p_output;
-        while( i_samples > 0 )
-        {
-            int i_smaller_samples;
-
-            i_smaller_samples = __MIN( 8000, i_samples );
-
-            p_aout_buffer = aout_DecNewBuffer( p_sys->p_aout,
-                                               p_sys->p_aout_input,
-                                               i_smaller_samples );
-            if( !p_aout_buffer )
-            {
-                msg_Err( p_dec, "cannot get aout buffer" );
-                block_Release( p_block );
-                return VLC_EGENERIC;
-            }
-
-            p_aout_buffer->start_date = aout_DateGet( &p_sys->end_date );
-            p_aout_buffer->end_date = aout_DateIncrement( &p_sys->end_date,
-                                                          i_smaller_samples );
-            memcpy( p_aout_buffer->p_buffer, p_samples,
-                    p_aout_buffer->i_nb_bytes );
-
-            aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input, p_aout_buffer );
-
-            p_samples += i_smaller_samples * 2 * p_sys->p_context->channels;
-            i_samples -= i_smaller_samples;
-        }
+            msg_Warn( p_dec, "cannot decode one frame (%d bytes)",
+                      p_block->i_buffer );
+
+        block_Release( p_block );
+        return NULL;
     }
 
-    block_Release( p_block );
-    return VLC_SUCCESS;
+    p_block->i_buffer -= i_used;
+    p_block->p_buffer += i_used;
+
+    if( p_sys->p_context->channels <= 0 || p_sys->p_context->channels > 6 )
+    {
+        msg_Warn( p_dec, "invalid channels count %d",
+                  p_sys->p_context->channels );
+        block_Release( p_block );
+        return NULL;
+    }
+
+    if( p_dec->fmt_out.audio.i_rate != p_sys->p_context->sample_rate )
+    {
+        aout_DateInit( &p_sys->end_date, p_sys->p_context->sample_rate );
+        aout_DateSet( &p_sys->end_date, p_block->i_pts );
+    }
+
+    /* **** Set audio output parameters **** */
+    p_dec->fmt_out.audio.i_rate     = p_sys->p_context->sample_rate;
+    p_dec->fmt_out.audio.i_channels = p_sys->p_context->channels;
+    p_dec->fmt_out.audio.i_original_channels =
+        p_dec->fmt_out.audio.i_physical_channels =
+            pi_channels_maps[p_sys->p_context->channels];
+
+    if( p_block->i_pts != 0 &&
+        p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
+    {
+        aout_DateSet( &p_sys->end_date, p_block->i_pts );
+        p_block->i_pts = 0;
+    }
+
+    /* **** Now we can output these samples **** */
+    i_samples = i_output / 2 / p_sys->p_context->channels;
+    p_samples = p_sys->p_output;
+
+    p_buffer = p_dec->pf_aout_buffer_new( p_dec, i_samples );
+    if( !p_buffer )
+    {
+        msg_Err( p_dec, "cannot get aout buffer" );
+        block_Release( p_block );
+        return NULL;
+    }
+
+    p_buffer->start_date = aout_DateGet( &p_sys->end_date );
+    p_buffer->end_date = aout_DateIncrement( &p_sys->end_date, i_samples );
+
+    memcpy( p_buffer->p_buffer, p_samples, p_buffer->i_nb_bytes );
+
+    return p_buffer;
 }
 
 /*****************************************************************************
@@ -283,9 +239,4 @@ void E_(EndAudioDec)( decoder_t *p_dec )
     decoder_sys_t *p_sys = p_dec->p_sys;
 
     if( p_sys->p_output ) free( p_sys->p_output );
-
-    if( p_sys->p_aout_input )
-    {
-        aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
-    }
 }
index 72da93307785ca294139857a102d06bace945b4b..fa3c307849fc433be4f2745cfa4c4196369701dd 100644 (file)
@@ -2,7 +2,7 @@
  * encoder.c: video and audio encoder using the ffmpeg library
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: encoder.c,v 1.6 2003/11/05 23:32:31 hartman Exp $
+ * $Id: encoder.c,v 1.7 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Gildas Bazin <gbazin@netcourrier.com>
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
-int  E_(OpenVideoEncoder) ( vlc_object_t * );
-void E_(CloseVideoEncoder)( vlc_object_t * );
-
-int  E_(OpenAudioEncoder) ( vlc_object_t * );
-void E_(CloseAudioEncoder)( vlc_object_t * );
+int  E_(OpenEncoder) ( vlc_object_t * );
+void E_(CloseEncoder)( vlc_object_t * );
 
 static block_t *EncodeVideo( encoder_t *, picture_t * );
 static block_t *EncodeAudio( encoder_t *, aout_buffer_t * );
@@ -92,29 +89,35 @@ struct encoder_sys_t
 };
 
 /*****************************************************************************
- * OpenVideoEncoder: probe the encoder
+ * OpenEncoder: probe the encoder
  *****************************************************************************/
-int E_(OpenVideoEncoder)( vlc_object_t *p_this )
+int E_(OpenEncoder)( vlc_object_t *p_this )
 {
     encoder_t *p_enc = (encoder_t *)p_this;
     encoder_sys_t *p_sys = p_enc->p_sys;
-    AVCodecContext  *p_context;
+    AVCodecContext *p_context;
     AVCodec *p_codec;
     int i_codec_id, i_cat;
     char *psz_namecodec;
 
-    if( !E_(GetFfmpegCodec)( p_enc->i_fourcc, &i_cat, &i_codec_id,
+    if( !E_(GetFfmpegCodec)( p_enc->fmt_out.i_codec, &i_cat, &i_codec_id,
                              &psz_namecodec ) )
     {
         return VLC_EGENERIC;
     }
 
-    if( i_cat != VIDEO_ES )
+    if( p_enc->fmt_out.i_cat == VIDEO_ES && i_cat != VIDEO_ES )
     {
         msg_Err( p_enc, "\"%s\" is not a video encoder", psz_namecodec );
         return VLC_EGENERIC;
     }
 
+    if( p_enc->fmt_out.i_cat == AUDIO_ES && i_cat != AUDIO_ES )
+    {
+        msg_Err( p_enc, "\"%s\" is not an audio encoder", psz_namecodec );
+        return VLC_EGENERIC;
+    }
+
     /* Initialization must be done before avcodec_find_decoder() */
     E_(InitLibavcodec)(p_this);
 
@@ -134,41 +137,86 @@ int E_(OpenVideoEncoder)( vlc_object_t *p_this )
     p_enc->p_sys = p_sys;
     p_sys->p_codec = p_codec;
 
-    p_enc->pf_header = NULL;
     p_enc->pf_encode_video = EncodeVideo;
-    p_enc->format.video.i_chroma = VLC_FOURCC('I','4','2','0');
+    p_enc->pf_encode_audio = EncodeAudio;
 
-    if( p_enc->i_fourcc == VLC_FOURCC( 'm','p','1','v' ) ||
-        p_enc->i_fourcc == VLC_FOURCC( 'm','p','2','v' ) )
+    p_sys->p_buffer_out = NULL;
+    p_sys->p_buffer = NULL;
+
+    p_sys->p_context = p_context = avcodec_alloc_context();
+
+    /* Set CPU capabilities */
+#ifdef HAVE_MMX
+    p_context->dsp_mask = 0;
+    if( p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_MMX )
+    {
+        p_context->dsp_mask &= FF_MM_MMX;
+    }
+    if( p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_MMXEXT )
+    {
+        p_context->dsp_mask &= FF_MM_MMXEXT;
+    }
+    if( p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_3DNOW )
+    {
+        p_context->dsp_mask &= FF_MM_3DNOW;
+    }
+    if( p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_SSE )
     {
-        p_enc->i_fourcc = VLC_FOURCC( 'm','p','g','v' );
+        p_context->dsp_mask &= FF_MM_SSE;
+        p_context->dsp_mask &= FF_MM_SSE2; /* FIXME */
     }
+    /* Hack to make sure everything can be disabled **/
+    p_context->dsp_mask &= (FF_MM_FORCE >> 1);
+#endif
 
-    p_sys->p_context = p_context = avcodec_alloc_context();
-    p_context->width = p_enc->format.video.i_width;
-    p_context->height = p_enc->format.video.i_height;
-    p_context->bit_rate = p_enc->i_bitrate;
+    /* Make sure we get extradata filled by the encoder */
+    p_context->extradata_size = 0;
+    p_context->extradata = NULL;
+    p_context->flags |= CODEC_FLAG_GLOBAL_HEADER;
+
+    if( p_enc->fmt_in.i_cat == VIDEO_ES )
+    {
+        p_context->width = p_enc->fmt_in.video.i_width;
+        p_context->height = p_enc->fmt_in.video.i_height;
 
-    p_context->frame_rate = p_enc->i_frame_rate;
+        p_context->frame_rate = p_enc->fmt_in.video.i_frame_rate;
 #if LIBAVCODEC_BUILD >= 4662
-    p_context->frame_rate_base= p_enc->i_frame_rate_base;
+        p_context->frame_rate_base= p_enc->fmt_in.video.i_frame_rate_base;
 #endif
 
 #if LIBAVCODEC_BUILD >= 4687
-    p_context->sample_aspect_ratio =
-        av_d2q( p_enc->i_aspect * p_context->height / p_context->width /
-                VOUT_ASPECT_FACTOR, 255 );
+        p_context->sample_aspect_ratio =
+            av_d2q( p_enc->fmt_in.video.i_aspect * p_context->height /
+                    p_context->width / VOUT_ASPECT_FACTOR, 255 );
 #else
-    p_context->aspect_ratio = ((float)p_enc->i_aspect) / VOUT_ASPECT_FACTOR;
+        p_context->aspect_ratio = ((float)p_enc->fmt_in.video.i_aspect) /
+            VOUT_ASPECT_FACTOR;
 #endif
 
-    p_context->gop_size = p_enc->i_key_int >= 0 ? p_enc->i_key_int : 50;
+        p_sys->p_buffer_out = malloc( AVCODEC_MAX_VIDEO_FRAME_SIZE );
+
+        /* Ffmpeg does handle the conversion itself */
+        //p_enc->fmt_in.i_codec = VLC_FOURCC('I','4','2','0');
+    }
+    else if( p_enc->fmt_in.i_cat == AUDIO_ES )
+    {
+        p_enc->fmt_in.i_codec  = AOUT_FMT_S16_NE;
+        p_context->bit_rate    = p_enc->fmt_out.i_bitrate;
+        p_context->sample_rate = p_enc->fmt_in.audio.i_rate;
+        p_context->channels    = p_enc->fmt_in.audio.i_channels;
+        p_sys->i_frame_size = p_context->frame_size * 2 * p_context->channels;
+        p_sys->p_buffer = malloc( p_sys->i_frame_size );
+        p_sys->p_buffer_out = malloc( 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE );
+    }
+
+    /* Misc parameters */
+    p_context->gop_size = p_enc->i_key_int > 0 ? p_enc->i_key_int : 50;
     p_context->max_b_frames =
         __MIN( p_enc->i_b_frames, FF_MAX_B_FRAMES );
     p_context->b_frame_strategy = 0;
     p_context->b_quant_factor = 2.0;
 
-    if( p_enc->i_vtolerance >= 0 )
+    if( p_enc->i_vtolerance > 0 )
     {
         p_context->bit_rate_tolerance = p_enc->i_vtolerance;
     }
@@ -186,7 +234,7 @@ int E_(OpenVideoEncoder)( vlc_object_t *p_this )
 
     if( i_codec_id == CODEC_ID_RAWVIDEO )
     {
-        p_context->pix_fmt = E_(GetFfmpegChroma)( p_enc->i_fourcc );
+        p_context->pix_fmt = E_(GetFfmpegChroma)( p_enc->fmt_in.i_codec );
     }
 
     /* Make sure we get extradata filled by the encoder */
@@ -194,19 +242,40 @@ int E_(OpenVideoEncoder)( vlc_object_t *p_this )
     p_context->extradata = NULL;
     p_context->flags |= CODEC_FLAG_GLOBAL_HEADER;
 
-    if( avcodec_open( p_context, p_sys->p_codec ) )
+    if( avcodec_open( p_context, p_codec ) )
     {
-        msg_Err( p_enc, "cannot open encoder" );
-        return VLC_EGENERIC;
+        if( p_enc->fmt_in.i_cat == AUDIO_ES && p_context->channels > 2 )
+        {
+            p_context->channels = 2;
+            p_enc->fmt_in.audio.i_channels = 2; // FIXME
+            if( avcodec_open( p_context, p_codec ) )
+            {
+                msg_Err( p_enc, "cannot open encoder" );
+                return VLC_EGENERIC;
+            }
+            msg_Warn( p_enc, "stereo mode selected (codec limitation)" );
+        }
+        else
+        {
+            msg_Err( p_enc, "cannot open encoder" );
+            return VLC_EGENERIC;
+        }
     }
 
-    p_enc->i_extra_data = p_context->extradata_size;
-    p_enc->p_extra_data = p_context->extradata;
+    p_enc->fmt_out.i_extra = p_context->extradata_size;
+    p_enc->fmt_out.p_extra = p_context->extradata;
     p_context->flags &= ~CODEC_FLAG_GLOBAL_HEADER;
 
-    p_sys->p_buffer_out = malloc( AVCODEC_MAX_VIDEO_FRAME_SIZE );
+    if( p_enc->fmt_in.i_cat == AUDIO_ES )
+    {
+        p_sys->i_frame_size = p_context->frame_size * 2 * p_context->channels;
+        p_sys->p_buffer = malloc( p_sys->i_frame_size );
+    }
+
     p_sys->i_last_ref_pts = 0;
     p_sys->i_buggy_pts_detect = 0;
+    p_sys->i_samples_delay = 0;
+    p_sys->i_pts = 0;
 
     msg_Dbg( p_enc, "found encoder %s", psz_namecodec );
 
@@ -229,7 +298,7 @@ static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict )
     }
 
     /* Set the pts of the frame being encoded (segfaults with mpeg4!)*/
-    if( p_enc->i_fourcc == VLC_FOURCC( 'm', 'p', 'g', 'v' ) )
+    if( p_enc->fmt_out.i_codec == VLC_FOURCC( 'm', 'p', 'g', 'v' ) )
         frame.pts = p_pict->date;
     else
         frame.pts = 0;
@@ -250,8 +319,9 @@ static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict )
             p_sys->i_buggy_pts_detect = p_sys->p_context->coded_frame->pts;
 
             /* FIXME, 3-2 pulldown is not handled correctly */
-            p_block->i_length = I64C(1000000) * p_enc->i_frame_rate_base /
-                                  p_enc->i_frame_rate;
+            p_block->i_length = I64C(1000000) *
+                p_enc->fmt_in.video.i_frame_rate_base /
+                p_enc->fmt_in.video.i_frame_rate;
             p_block->i_pts    = p_sys->p_context->coded_frame->pts;
 
             if( !p_sys->p_context->delay ||
@@ -279,8 +349,9 @@ static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict )
         {
             /* Buggy libavcodec which doesn't update coded_frame->pts
              * correctly */
-            p_block->i_length = I64C(1000000) * p_enc->i_frame_rate_base /
-                                  p_enc->i_frame_rate;
+            p_block->i_length = I64C(1000000) *
+                p_enc->fmt_in.video.i_frame_rate_base /
+                p_enc->fmt_in.video.i_frame_rate;
             p_block->i_dts = p_block->i_pts = p_pict->date;
         }
 
@@ -290,118 +361,6 @@ static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict )
     return NULL;
 }
 
-/*****************************************************************************
- * CloseVideoEncoder: ffmpeg video encoder destruction
- *****************************************************************************/
-void E_(CloseVideoEncoder)( vlc_object_t *p_this )
-{
-    encoder_t *p_enc = (encoder_t *)p_this;
-    encoder_sys_t *p_sys = p_enc->p_sys;
-
-    avcodec_close( p_sys->p_context );
-    free( p_sys->p_context );
-    free( p_sys->p_buffer_out );
-    free( p_sys );
-}
-
-/*****************************************************************************
- * OpenAudioEncoder: probe the encoder
- *****************************************************************************/
-int E_(OpenAudioEncoder)( vlc_object_t *p_this )
-{
-    encoder_t *p_enc = (encoder_t *)p_this;
-    encoder_sys_t *p_sys;
-    AVCodecContext *p_context;
-    AVCodec *p_codec;
-    int i_codec_id, i_cat;
-    char *psz_namecodec;
-
-    if( !E_(GetFfmpegCodec)( p_enc->i_fourcc, &i_cat, &i_codec_id,
-                             &psz_namecodec ) )
-    {
-        return VLC_EGENERIC;
-    }
-
-    if( i_cat != AUDIO_ES )
-    {
-        msg_Err( p_enc, "\"%s\" is not an audio encoder", psz_namecodec );
-        return VLC_EGENERIC;
-    }
-
-    /* Initialization must be done before avcodec_find_decoder() */
-    E_(InitLibavcodec)(p_this);
-
-    p_codec = avcodec_find_encoder( i_codec_id );
-    if( !p_codec )
-    {
-        msg_Err( p_enc, "cannot find encoder %s", psz_namecodec );
-        return VLC_EGENERIC;
-    }
-
-    /* Allocate the memory needed to store the decoder's structure */
-    if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
-    {
-        msg_Err( p_enc, "out of memory" );
-        return VLC_EGENERIC;
-    }
-    p_enc->p_sys = p_sys;
-    p_sys->p_codec = p_codec;
-
-    p_enc->pf_header = NULL;
-    p_enc->pf_encode_audio = EncodeAudio;
-    p_enc->format.audio.i_format = VLC_FOURCC('s','1','6','n');
-
-    p_sys->p_context = p_context = avcodec_alloc_context();
-    p_context->bit_rate    = p_enc->i_bitrate;
-    p_context->sample_rate = p_enc->format.audio.i_rate;
-    p_context->channels    =
-        aout_FormatNbChannels( &p_enc->format.audio );
-
-    /* Make sure we get extradata filled by the encoder */
-    p_context->extradata_size = 0;
-    p_context->extradata = NULL;
-    p_context->flags |= CODEC_FLAG_GLOBAL_HEADER;
-
-    if( avcodec_open( p_context, p_codec ) < 0 )
-    {
-        if( p_context->channels > 2 )
-        {
-            p_context->channels = 2;
-            //id->f_dst.i_channels   = 2;
-            if( avcodec_open( p_context, p_codec ) < 0 )
-            {
-                msg_Err( p_enc, "cannot open encoder" );
-                return VLC_EGENERIC;
-            }
-            msg_Warn( p_enc, "stereo mode selected (codec limitation)" );
-        }
-        else
-        {
-            msg_Err( p_enc, "cannot open encoder" );
-            return VLC_EGENERIC;
-        }
-    }
-
-    p_enc->i_extra_data = p_context->extradata_size;
-    p_enc->p_extra_data = p_context->extradata;
-    p_context->flags &= ~CODEC_FLAG_GLOBAL_HEADER;
-
-    p_sys->i_frame_size = p_context->frame_size * 2 * p_context->channels;
-    p_sys->p_buffer = malloc( p_sys->i_frame_size );
-    p_sys->p_buffer_out = malloc( 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE );
-
-    msg_Warn( p_enc, "avcodec_setup_audio: %d %d %d %d",
-              p_context->frame_size, p_context->bit_rate, p_context->channels,
-              p_context->sample_rate );
-
-    p_sys->i_samples_delay = 0;
-    p_sys->i_pts = 0;
-
-    msg_Dbg( p_enc, "found encoder %s", psz_namecodec );
-
-    return VLC_SUCCESS;
-}
-
 /****************************************************************************
  * EncodeAudio: the whole thing
  ****************************************************************************/
@@ -416,7 +375,7 @@ static block_t *EncodeAudio( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
 
     p_sys->i_pts = p_aout_buf->start_date -
                 (mtime_t)1000000 * (mtime_t)p_sys->i_samples_delay /
-                (mtime_t)p_enc->format.audio.i_rate;
+                (mtime_t)p_enc->fmt_in.audio.i_rate;
 
     p_sys->i_samples_delay += i_samples;
 
@@ -484,16 +443,18 @@ static block_t *EncodeAudio( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
 }
 
 /*****************************************************************************
- * CloseAudioEncoder: ffmpeg audio encoder destruction
+ * CloseEncoder: ffmpeg encoder destruction
  *****************************************************************************/
-void E_(CloseAudioEncoder)( vlc_object_t *p_this )
+void E_(CloseEncoder)( vlc_object_t *p_this )
 {
     encoder_t *p_enc = (encoder_t *)p_this;
     encoder_sys_t *p_sys = p_enc->p_sys;
 
     avcodec_close( p_sys->p_context );
     free( p_sys->p_context );
-    free( p_sys->p_buffer );
-    free( p_sys->p_buffer_out );
+
+    if( p_sys->p_buffer ) free( p_sys->p_buffer );
+    if( p_sys->p_buffer_out ) free( p_sys->p_buffer_out );
+
     free( p_sys );
 }
index c6a9268488a1d04268e84a06d8009f5fec0a6040..b90f2d8e312f03764d72bd6bfe726b476e109e52 100644 (file)
@@ -2,7 +2,7 @@
  * ffmpeg.c: video decoder using ffmpeg library
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: ffmpeg.c,v 1.58 2003/10/29 20:53:41 gbazin Exp $
+ * $Id: ffmpeg.c,v 1.59 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Gildas Bazin <gbazin@netcourrier.com>
 #include <string.h>
 
 #include <vlc/vlc.h>
-#include <vlc/vout.h>
-#include <vlc/aout.h>
 #include <vlc/decoder.h>
 #include <vlc/input.h>
 
-#ifdef HAVE_SYS_TIMES_H
-#   include <sys/times.h>
-#endif
-
 /* ffmpeg header */
 #ifdef HAVE_FFMPEG_AVCODEC_H
 #   include <ffmpeg/avcodec.h>
@@ -77,10 +71,7 @@ struct decoder_sys_t
  * Local prototypes
  ****************************************************************************/
 static int OpenDecoder( vlc_object_t * );
-static int InitDecoder( decoder_t * );
-static int EndDecoder( decoder_t * );
-
-static int b_ffmpeginit = 0;
+static void CloseDecoder( vlc_object_t * );
 
 /*****************************************************************************
  * Module descriptor
@@ -90,7 +81,7 @@ vlc_module_begin();
     /* decoder main module */
     add_category_hint( N_("ffmpeg"), NULL, VLC_FALSE );
     set_capability( "decoder", 70 );
-    set_callbacks( OpenDecoder, NULL );
+    set_callbacks( OpenDecoder, CloseDecoder );
     set_description( _("ffmpeg audio/video decoder((MS)MPEG4,SVQ1,H263,WMV,WMA)") );
 
     add_bool( "ffmpeg-dr", 1, NULL, DR_TEXT, DR_TEXT, VLC_TRUE );
@@ -115,18 +106,12 @@ vlc_module_begin();
     set_callbacks( E_(OpenChroma), NULL );
     set_description( _("ffmpeg chroma conversion") );
 
-     /* video encoder submodule */
-     add_submodule();
-     set_description( _("ffmpeg video encoder") );
-     set_capability( "video encoder", 100 );
-     set_callbacks( E_(OpenVideoEncoder), E_(CloseVideoEncoder) );
-     /* audio encoder submodule */
-     add_submodule();
-     set_description( _("ffmpeg audio encoder") );
-     set_capability( "audio encoder", 10 );
-     set_callbacks( E_(OpenAudioEncoder), E_(CloseAudioEncoder) );
+    /* encoder submodule */
+    add_submodule();
+    set_description( _("ffmpeg audio/video encoder") );
+    set_capability( "encoder", 100 );
+    set_callbacks( E_(OpenEncoder), E_(CloseEncoder) );
+
     var_Create( p_module->p_libvlc, "avcodec", VLC_VAR_MUTEX );
 vlc_module_end();
 
@@ -136,10 +121,14 @@ vlc_module_end();
 static int OpenDecoder( vlc_object_t *p_this )
 {
     decoder_t *p_dec = (decoder_t*) p_this;
-    int i_cat, i_codec_id;
+    int i_cat, i_codec_id, i_result;
     char *psz_namecodec;
 
-    if( !E_(GetFfmpegCodec)( p_dec->p_fifo->i_fourcc, &i_cat, &i_codec_id,
+    AVCodecContext *p_context;
+    AVCodec        *p_codec;
+
+    /* *** determine codec type *** */
+    if( !E_(GetFfmpegCodec)( p_dec->fmt_in.i_codec, &i_cat, &i_codec_id,
                              &psz_namecodec ) )
     {
         return VLC_EGENERIC;
@@ -148,54 +137,51 @@ static int OpenDecoder( vlc_object_t *p_this )
     /* Initialization must be done before avcodec_find_decoder() */
     E_(InitLibavcodec)(p_this);
 
-    if( !avcodec_find_decoder( i_codec_id ) )
-    {
-        msg_Dbg( p_dec, "codec not found (%s)", psz_namecodec );
-        return VLC_EGENERIC;
-    }
-
-    p_dec->pf_init = InitDecoder;
-    p_dec->pf_decode = (i_cat == VIDEO_ES) ? E_(DecodeVideo) : E_(DecodeAudio);
-    p_dec->pf_end = EndDecoder;
-
-    return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * InitDecoder: Initalize the decoder
- *****************************************************************************/
-static int InitDecoder( decoder_t *p_dec )
-{
-    int i_cat, i_codec_id, i_result;
-    char *psz_namecodec;
-    AVCodecContext *p_context;
-    AVCodec        *p_codec;
-
-    /* *** determine codec type *** */
-    E_(GetFfmpegCodec)( p_dec->p_fifo->i_fourcc,
-                        &i_cat, &i_codec_id, &psz_namecodec );
-
     /* *** ask ffmpeg for a decoder *** */
     if( !( p_codec = avcodec_find_decoder( i_codec_id ) ) )
     {
-        msg_Err( p_dec, "codec not found (%s)", psz_namecodec );
+        msg_Dbg( p_dec, "codec not found (%s)", psz_namecodec );
         return VLC_EGENERIC;
     }
 
     /* *** get a p_context *** */
     p_context = avcodec_alloc_context();
 
+    /* Set CPU capabilities */
+#ifdef HAVE_MMX
+    p_context->dsp_mask = 0;
+    if( p_dec->p_libvlc->i_cpu & CPU_CAPABILITY_MMX )
+    {
+        p_context->dsp_mask &= FF_MM_MMX;
+    }
+    if( p_dec->p_libvlc->i_cpu & CPU_CAPABILITY_MMXEXT )
+    {
+        p_context->dsp_mask &= FF_MM_MMXEXT;
+    }
+    if( p_dec->p_libvlc->i_cpu & CPU_CAPABILITY_3DNOW )
+    {
+        p_context->dsp_mask &= FF_MM_3DNOW;
+    }
+    if( p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_SSE )
+    {
+        p_context->dsp_mask &= FF_MM_SSE;
+        p_context->dsp_mask &= FF_MM_SSE2; /* FIXME */
+    }
+    /* Hack to make sure everything can be disabled **/
+    p_context->dsp_mask &= (FF_MM_FORCE >> 1);
+#endif
+
     switch( i_cat )
     {
     case VIDEO_ES:
+        p_dec->pf_decode_video = E_(DecodeVideo);
         i_result = E_( InitVideoDec )( p_dec, p_context, p_codec,
                                        i_codec_id, psz_namecodec );
-        p_dec->pf_decode = E_(DecodeVideo);
         break;
     case AUDIO_ES:
+        p_dec->pf_decode_audio = E_(DecodeAudio);
         i_result = E_( InitAudioDec )( p_dec, p_context, p_codec,
                                        i_codec_id, psz_namecodec );
-        p_dec->pf_decode = E_(DecodeAudio);
         break;
     default:
         i_result = VLC_EGENERIC;
@@ -205,12 +191,13 @@ static int InitDecoder( decoder_t *p_dec )
 
     return i_result;
 }
-  
+
 /*****************************************************************************
- * EndDecoder: decoder destruction
+ * CloseDecoder: decoder destruction
  *****************************************************************************/
-static int EndDecoder( decoder_t *p_dec )
+static void CloseDecoder( vlc_object_t *p_this )
 {
+    decoder_t *p_dec = (decoder_t *)p_this;
     decoder_sys_t *p_sys = p_dec->p_sys;
 
     if( !p_sys->p_context )
@@ -234,7 +221,6 @@ static int EndDecoder( decoder_t *p_dec )
     }
 
     free( p_sys );
-    return VLC_SUCCESS;
 }
   
 /*****************************************************************************
@@ -692,12 +678,13 @@ int E_(GetFfmpegChroma)( vlc_fourcc_t i_chroma )
 
 void E_(InitLibavcodec)( vlc_object_t *p_object )
 {
+    static int b_ffmpeginit = 0;
     vlc_value_t lockval;
 
     var_Get( p_object->p_libvlc, "avcodec", &lockval );
     vlc_mutex_lock( lockval.p_address );
 
-     /* *** init ffmpeg library (libavcodec) *** */
+    /* *** init ffmpeg library (libavcodec) *** */
     if( !b_ffmpeginit )
     {
         avcodec_init();
index 2393c21948f8cd251c6a32f2ebca8edc2b97c065..d4a57941b6c120bcf122d095bd8a82e444f3890f 100644 (file)
@@ -2,7 +2,7 @@
  * ffmpeg.h: decoder using the ffmpeg library
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: ffmpeg.h,v 1.27 2003/10/27 01:04:38 gbazin Exp $
+ * $Id: ffmpeg.h,v 1.28 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -42,20 +42,20 @@ int E_(GetFfmpegChroma)( vlc_fourcc_t );
 int  E_( InitVideoDec )( decoder_t *, AVCodecContext *, AVCodec *,
                          int, char * );
 void E_( EndVideoDec ) ( decoder_t * );
-int  E_( DecodeVideo ) ( decoder_t *, block_t * );
+picture_t *E_( DecodeVideo ) ( decoder_t *, block_t ** );
 
 /* Audio decoder module */
 int  E_( InitAudioDec )( decoder_t *, AVCodecContext *, AVCodec *,
                          int, char * );
 void E_( EndAudioDec ) ( decoder_t * );
-int  E_( DecodeAudio ) ( decoder_t *, block_t * );
+aout_buffer_t *E_( DecodeAudio ) ( decoder_t *, block_t ** );
 
 /* Chroma conversion module */
 int  E_(OpenChroma)( vlc_object_t * );
 
 /* Video encoder module */
-int  E_(OpenVideoEncoder) ( vlc_object_t * );
-void E_(CloseVideoEncoder)( vlc_object_t * );
+int  E_(OpenEncoder) ( vlc_object_t * );
+void E_(CloseEncoder)( vlc_object_t * );
 
 /* Audio encoder module */
 int  E_(OpenAudioEncoder) ( vlc_object_t * );
index 1349a26c4cd0749030d3f3cfe09043e52cfafb69..74ed35ab2a8d42ecd4f63f68238f8e8773e2a6da 100644 (file)
@@ -2,7 +2,7 @@
  * video.c: video decoder using the ffmpeg library
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: video.c,v 1.43 2003/10/28 14:17:52 gbazin Exp $
+ * $Id: video.c,v 1.44 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Gildas Bazin <gbazin@netcourrier.com>
 #include <string.h>
 
 #include <vlc/vlc.h>
-#include <vlc/vout.h>
 #include <vlc/decoder.h>
 #include <vlc/input.h>
 
-#ifdef HAVE_SYS_TIMES_H
-#   include <sys/times.h>
-#endif
-
 /* ffmpeg header */
 #ifdef HAVE_FFMPEG_AVCODEC_H
 #   include <ffmpeg/avcodec.h>
@@ -66,11 +61,8 @@ struct decoder_sys_t
     AVFrame          *p_ff_pic;
     BITMAPINFOHEADER *p_format;
 
-    vout_thread_t    *p_vout;
-
     /* for frame skipping algo */
     int b_hurry_up;
-    int i_frame_error;
     int i_frame_skip;
 
     /* how many decoded frames are late */
@@ -82,11 +74,12 @@ struct decoder_sys_t
 
     vlc_bool_t b_has_b_frames;
 
-    int i_buffer;
-    char *p_buffer;
+    int i_buffer_orig, i_buffer;
+    char *p_buffer_orig, *p_buffer;
 
     /* Postprocessing handle */
     void *p_pp;
+    vlc_bool_t b_pp_init;
 };
 
 /*****************************************************************************
@@ -99,20 +92,31 @@ static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *, AVFrame * );
 /*****************************************************************************
  * Local Functions
  *****************************************************************************/
-static inline uint32_t ffmpeg_PixFmtToChroma( int i_ff_chroma )
+static uint32_t ffmpeg_PixFmtToChroma( int i_ff_chroma )
 {
-    /* FIXME FIXME some of them are wrong */
     switch( i_ff_chroma )
     {
     case PIX_FMT_YUV420P:
-    case PIX_FMT_YUV422:
-        return( VLC_FOURCC('I','4','2','0') );
-    case PIX_FMT_RGB24:
-        return( VLC_FOURCC('R','V','2','4') );
+        return VLC_FOURCC('I','4','2','0');
     case PIX_FMT_YUV422P:
-        return( VLC_FOURCC('I','4','2','2') );
+        return VLC_FOURCC('I','4','2','2');
     case PIX_FMT_YUV444P:
-        return( VLC_FOURCC('I','4','4','4') );
+        return VLC_FOURCC('I','4','4','4');
+
+    case PIX_FMT_YUV422:
+        return VLC_FOURCC('Y','U','Y','2');
+
+    case PIX_FMT_RGB555:
+        return VLC_FOURCC('R','V','1','5');
+    case PIX_FMT_RGB565:
+        return VLC_FOURCC('R','V','1','6');
+    case PIX_FMT_RGB24:
+        return VLC_FOURCC('R','V','2','4');
+    case PIX_FMT_RGBA32:
+        return VLC_FOURCC('R','V','3','2');
+    case PIX_FMT_GRAY8:
+        return VLC_FOURCC('G','R','E','Y');
+
     case PIX_FMT_YUV410P:
     case PIX_FMT_YUV411P:
     case PIX_FMT_BGR24:
@@ -121,50 +125,54 @@ static inline uint32_t ffmpeg_PixFmtToChroma( int i_ff_chroma )
     }
 }
 
-/* Return a Vout */
-static vout_thread_t *ffmpeg_CreateVout( decoder_t  *p_dec,
-                                         AVCodecContext *p_context )
+/* Returns a new picture buffer */
+static inline picture_t *ffmpeg_NewPictBuf( decoder_t *p_dec,
+                                            AVCodecContext *p_context )
 {
-    vout_thread_t *p_vout;
-    unsigned int   i_width = p_context->width;
-    unsigned int   i_height = p_context->height;
-    uint32_t       i_chroma = ffmpeg_PixFmtToChroma( p_context->pix_fmt );
-    unsigned int   i_aspect;
+    decoder_sys_t *p_sys = p_dec->p_sys;
+    picture_t *p_pic;
 
-    if( !i_width || !i_height )
+    p_dec->fmt_out.video.i_width = p_context->width;
+    p_dec->fmt_out.video.i_height = p_context->height;
+    p_dec->fmt_out.i_codec = ffmpeg_PixFmtToChroma( p_context->pix_fmt );
+
+    if( !p_context->width || !p_context->height )
     {
-        return( NULL ); /* Can't create a new vout without display size */
+        return NULL; /* invalid display size */
     }
 
-    if( !i_chroma )
+    if( !p_dec->fmt_out.i_codec )
     {
         /* we make conversion if possible*/
-        i_chroma = VLC_FOURCC('I','4','2','0');
+        p_dec->fmt_out.i_codec = VLC_FOURCC('I','4','2','0');
     }
 
 #if LIBAVCODEC_BUILD >= 4687
-    i_aspect = VOUT_ASPECT_FACTOR * ( av_q2d(p_context->sample_aspect_ratio) *
-        p_context->width / p_context->height );
+    p_dec->fmt_out.video.i_aspect =
+        VOUT_ASPECT_FACTOR * ( av_q2d(p_context->sample_aspect_ratio) *
+            p_context->width / p_context->height );
 #else
-    i_aspect = VOUT_ASPECT_FACTOR * p_context->aspect_ratio;
+    p_dec->fmt_out.video.i_aspect =
+        VOUT_ASPECT_FACTOR * p_context->aspect_ratio;
 #endif
-    if( i_aspect == 0 )
+    if( p_dec->fmt_out.video.i_aspect == 0 )
     {
-        i_aspect = VOUT_ASPECT_FACTOR * i_width / i_height;
+        p_dec->fmt_out.video.i_aspect =
+            VOUT_ASPECT_FACTOR * p_context->width / p_context->height;
     }
 
-    /* Spawn a video output if there is none. First we look for our children,
-     * then we look for any other vout that might be available. */
-    p_vout = vout_Request( p_dec, p_dec->p_sys->p_vout,
-                           i_width, i_height, i_chroma, i_aspect );
+    p_pic = p_dec->pf_vout_buffer_new( p_dec );
 
 #ifdef LIBAVCODEC_PP
-    if( p_dec->p_sys->p_pp )
-        E_(InitPostproc)( p_dec, p_dec->p_sys->p_pp, i_width, i_height,
-                          p_context->pix_fmt );
+    if( p_sys->p_pp && !p_sys->b_pp_init )
+    {
+        E_(InitPostproc)( p_dec, p_sys->p_pp, p_context->width,
+                          p_context->height, p_context->pix_fmt );
+        p_sys->b_pp_init = VLC_TRUE;
+    }
 #endif
 
-    return p_vout;
+    return p_pic;
 }
 
 /*****************************************************************************
@@ -194,18 +202,9 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context,
     p_dec->p_sys->psz_namecodec = psz_namecodec;
     p_sys->p_ff_pic = avcodec_alloc_frame();
 
-    if( ( p_sys->p_format =
-          (BITMAPINFOHEADER *)p_dec->p_fifo->p_bitmapinfoheader ) != NULL )
-    {
-        /* ***** Fill p_context with init values ***** */
-        p_sys->p_context->width  = p_sys->p_format->biWidth;
-        p_sys->p_context->height = p_sys->p_format->biHeight;
-    }
-    else
-    {
-        msg_Warn( p_dec, "display informations missing" );
-        p_sys->p_format = NULL;
-    }
+    /* ***** Fill p_context with init values ***** */
+    p_sys->p_context->width  = p_dec->fmt_in.video.i_width;
+    p_sys->p_context->height = p_dec->fmt_in.video.i_height;
 
     /*  ***** Get configuration of ffmpeg plugin ***** */
     i_tmp = config_GetInt( p_dec, "ffmpeg-workaround-bugs" );
@@ -258,6 +257,7 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context,
 
 #ifdef LIBAVCODEC_PP
     p_sys->p_pp = NULL;
+    p_dec->p_sys->b_pp_init = VLC_FALSE;
     if( E_(OpenPostproc)( p_dec, &p_sys->p_pp ) == VLC_SUCCESS )
     {
         /* for now we cannot do postproc and dr */
@@ -280,16 +280,15 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context,
     p_sys->p_context->opaque = p_dec;
 
     /* ***** init this codec with special data ***** */
-    if( p_sys->p_format && p_sys->p_format->biSize > sizeof(BITMAPINFOHEADER) )
+    if( p_dec->fmt_in.i_extra )
     {
         int b_gotpicture;
-        int i_size = p_sys->p_format->biSize - sizeof(BITMAPINFOHEADER);
+        int i_size = p_dec->fmt_in.i_extra;
 
         if( p_sys->i_codec_id == CODEC_ID_MPEG4 )
         {
             uint8_t *p_vol = malloc( i_size + FF_INPUT_BUFFER_PADDING_SIZE );
-
-            memcpy( p_vol, &p_sys->p_format[1], i_size );
+            memcpy( p_vol, p_dec->fmt_in.p_extra, i_size );
             memset( &p_vol[i_size], 0, FF_INPUT_BUFFER_PADDING_SIZE );
 
             avcodec_decode_video( p_sys->p_context, p_sys->p_ff_pic,
@@ -307,7 +306,7 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context,
 
             memcpy( &p[0],  "SVQ3", 4 );
             memset( &p[4], 0, 8 );
-            memcpy( &p[12], &p_sys->p_format[1], i_size );
+            memcpy( &p[12], p_dec->fmt_in.p_extra, i_size );
         }
 #endif
         else
@@ -316,20 +315,24 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context,
             p_sys->p_context->extradata =
                 malloc( i_size + FF_INPUT_BUFFER_PADDING_SIZE );
             memcpy( p_sys->p_context->extradata,
-                    &p_sys->p_format[1], i_size );
+                    p_dec->fmt_in.p_extra, i_size );
             memset( &((uint8_t*)p_sys->p_context->extradata)[i_size],
                     0, FF_INPUT_BUFFER_PADDING_SIZE );
         }
     }
 
     /* ***** misc init ***** */
-    p_sys->p_vout = NULL;
     p_sys->input_pts = 0;
     p_sys->i_pts = 0;
     p_sys->b_has_b_frames = VLC_FALSE;
     p_sys->i_late_frames = 0;
-    p_sys->i_buffer = 1;
-    p_sys->p_buffer = malloc( p_sys->i_buffer );
+    p_sys->i_buffer = 0;
+    p_sys->i_buffer_orig = 1;
+    p_sys->p_buffer_orig = p_sys->p_buffer = malloc( p_sys->i_buffer );
+
+    /* Set output properties */
+    p_dec->fmt_out.i_cat = VIDEO_ES;
+    p_dec->fmt_out.i_codec = ffmpeg_PixFmtToChroma( p_context->pix_fmt );
 
     return VLC_SUCCESS;
 }
@@ -337,17 +340,22 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context,
 /*****************************************************************************
  * DecodeVideo: Called to decode one or more frames
  *****************************************************************************/
-int E_(DecodeVideo)( decoder_t *p_dec, block_t *p_block )
+picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
-    int i_buffer, b_drawpicture;
-    char *p_buffer;
+    int b_drawpicture;
+    block_t *p_block;
+
+    if( !pp_block || !*pp_block ) return NULL;
+
+    p_block = *pp_block;
 
     if( p_block->i_pts > 0 )
     {
         p_sys->input_pts = p_block->i_pts;
     }
 
+#if 0
     /* TODO implement it in a better way */
     /* A good idea could be to decode all I pictures and see for the other */
     if( p_sys->b_hurry_up && p_sys->i_late_frames > 4 )
@@ -364,7 +372,8 @@ int E_(DecodeVideo)( decoder_t *p_dec, block_t *p_block )
 
             p_sys->i_late_frames--; /* needed else it will never be decrease */
             block_Release( p_block );
-            return VLC_SUCCESS;
+            p_sys->i_buffer = 0;
+            return NULL;
         }
     }
     else
@@ -383,6 +392,7 @@ int E_(DecodeVideo)( decoder_t *p_dec, block_t *p_block )
         p_sys->i_late_frames--;
         return VLC_SUCCESS;
     }
+#endif
 
     if( !p_sys->p_context->width || !p_sys->p_context->height )
     {
@@ -395,36 +405,46 @@ int E_(DecodeVideo)( decoder_t *p_dec, block_t *p_block )
 
     /* Don't forget that ffmpeg requires a little more bytes
      * that the real frame size */
-    i_buffer = p_block->i_buffer;
-    if( i_buffer + FF_INPUT_BUFFER_PADDING_SIZE > p_sys->i_buffer )
+    if( p_block->i_buffer )
     {
-        free( p_sys->p_buffer );
-        p_sys->i_buffer = i_buffer + FF_INPUT_BUFFER_PADDING_SIZE;
-        p_sys->p_buffer = malloc( p_sys->i_buffer );
+        p_sys->i_buffer = p_block->i_buffer;
+        if( p_sys->i_buffer + FF_INPUT_BUFFER_PADDING_SIZE >
+            p_sys->i_buffer_orig )
+        {
+            free( p_sys->p_buffer_orig );
+            p_sys->i_buffer_orig =
+                p_block->i_buffer + FF_INPUT_BUFFER_PADDING_SIZE;
+            p_sys->p_buffer_orig = malloc( p_sys->i_buffer_orig );
+        }
+        p_sys->p_buffer = p_sys->p_buffer_orig;
+        p_sys->i_buffer = p_block->i_buffer;
+        p_dec->p_vlc->pf_memcpy( p_sys->p_buffer, p_block->p_buffer,
+                                 p_block->i_buffer );
+        memset( p_sys->p_buffer + p_block->i_buffer, 0,
+                FF_INPUT_BUFFER_PADDING_SIZE );
+
+        p_block->i_buffer = 0;
     }
-    p_buffer = p_sys->p_buffer;
-    p_dec->p_vlc->pf_memcpy( p_buffer, p_block->p_buffer, p_block->i_buffer );
-    memset( p_buffer + i_buffer, 0, FF_INPUT_BUFFER_PADDING_SIZE );
 
-    while( i_buffer )
+    while( p_sys->i_buffer )
     {
         int i_used, b_gotpicture;
         picture_t *p_pic;
 
         i_used = avcodec_decode_video( p_sys->p_context, p_sys->p_ff_pic,
                                        &b_gotpicture,
-                                       p_buffer, i_buffer );
+                                       p_sys->p_buffer, p_sys->i_buffer );
         if( i_used < 0 )
         {
-            msg_Warn( p_dec, "cannot decode one frame (%d bytes)", i_buffer );
-            p_sys->i_frame_error++;
+            msg_Warn( p_dec, "cannot decode one frame (%d bytes)",
+                      p_sys->i_buffer );
             block_Release( p_block );
-            return VLC_SUCCESS;
+            return NULL;
         }
 
         /* Consumed bytes */
-        i_buffer -= i_used;
-        p_buffer += i_used;
+        p_sys->i_buffer -= i_used;
+        p_sys->p_buffer += i_used;
 
         /* Nothing to display */
         if( !b_gotpicture ) continue;
@@ -449,23 +469,12 @@ int E_(DecodeVideo)( decoder_t *p_dec, block_t *p_block )
 
         if( !p_sys->b_direct_rendering )
         {
-            p_sys->p_vout = ffmpeg_CreateVout( p_dec, p_sys->p_context );
-            if( !p_sys->p_vout )
-            {
-                msg_Err( p_dec, "cannot create vout" );
-                block_Release( p_block );
-                return VLC_EGENERIC;
-            }
-
             /* Get a new picture */
-            while( !(p_pic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 ) ) )
+            p_pic = ffmpeg_NewPictBuf( p_dec, p_sys->p_context );
+            if( !p_pic )
             {
-                if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error )
-                {
-                    block_Release( p_block );
-                    return VLC_EGENERIC;
-                }
-                msleep( VOUT_OUTMEM_SLEEP );
+                block_Release( p_block );
+                return NULL;
             }
 
             /* Fill p_picture_t from AVVideoFrame and do chroma conversion
@@ -493,8 +502,7 @@ int E_(DecodeVideo)( decoder_t *p_dec, block_t *p_block )
         /* Send decoded frame to vout */
         if( p_sys->i_pts )
         {
-            vout_DatePicture( p_sys->p_vout, p_pic, p_sys->i_pts );
-            vout_DisplayPicture( p_sys->p_vout, p_pic );
+            p_pic->date = p_sys->i_pts;
 
             /* interpolate the next PTS */
             if( p_sys->p_context->frame_rate > 0 )
@@ -504,11 +512,16 @@ int E_(DecodeVideo)( decoder_t *p_dec, block_t *p_block )
                     p_sys->p_context->frame_rate_base /
                     (2 * p_sys->p_context->frame_rate);
             }
+            return p_pic;
+        }
+        else
+        {
+            p_dec->pf_vout_buffer_del( p_dec, p_pic );
         }
     }
 
     block_Release( p_block );
-    return VLC_SUCCESS;
+    return NULL;
 }
 
 /*****************************************************************************
@@ -527,10 +540,7 @@ void E_(EndVideoDec)( decoder_t *p_dec )
     E_(ClosePostproc)( p_dec, p_sys->p_pp );
 #endif
 
-    free( p_sys->p_buffer );
-
-    /* We are about to die. Reattach video output to p_vlc. */
-    vout_Request( p_dec, p_sys->p_vout, 0, 0, 0, 0 );
+    free( p_sys->p_buffer_orig );
 }
 
 /*****************************************************************************
@@ -632,28 +642,14 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context,
         return avcodec_default_get_buffer( p_context, p_ff_pic );
     }
 
-    /* Check and (re)create our vout if needed */
-    p_sys->p_vout = ffmpeg_CreateVout( p_dec, p_sys->p_context );
-    if( !p_sys->p_vout )
+    /* Get a new picture */
+    //p_sys->p_vout->render.b_allow_modify_pics = 0;
+    p_pic = ffmpeg_NewPictBuf( p_dec, p_sys->p_context );
+    if( !p_pic )
     {
-        msg_Err( p_dec, "cannot create vout" );
-        p_dec->p_fifo->b_error = 1; /* abort */
         p_sys->b_direct_rendering = 0;
         return avcodec_default_get_buffer( p_context, p_ff_pic );
     }
-
-    p_sys->p_vout->render.b_allow_modify_pics = 0;
-
-    /* Get a new picture */
-    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 )
-        {
-            p_sys->b_direct_rendering = 0;
-            return avcodec_default_get_buffer( p_context, p_ff_pic );
-        }
-        msleep( VOUT_OUTMEM_SLEEP );
-    }
     p_sys->p_context->draw_horiz_band = NULL;
 
     p_ff_pic->opaque = (void*)p_pic;
@@ -670,20 +666,19 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context,
 
     if( p_ff_pic->reference != 0 )
     {
-        vout_LinkPicture( p_sys->p_vout, p_pic );
+      //vout_LinkPicture( p_sys->p_vout, p_pic );
     }
 
     /* FIXME what is that, should give good value */
     p_ff_pic->age = 256*256*256*64; // FIXME FIXME from ffmpeg
 
-    return( 0 );
+    return 0;
 }
 
-static void  ffmpeg_ReleaseFrameBuf( struct AVCodecContext *p_context,
-                                     AVFrame *p_ff_pic )
+static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *p_context,
+                                    AVFrame *p_ff_pic )
 {
     decoder_t *p_dec = (decoder_t *)p_context->opaque;
-    decoder_sys_t *p_sys = p_dec->p_sys;
     picture_t *p_pic;
 
     if( p_ff_pic->type != FF_BUFFER_TYPE_USER )
@@ -701,6 +696,6 @@ static void  ffmpeg_ReleaseFrameBuf( struct AVCodecContext *p_context,
 
     if( p_ff_pic->reference != 0 )
     {
-        vout_UnlinkPicture( p_sys->p_vout, p_pic );
+      //vout_UnlinkPicture( p_sys->p_vout, p_pic );
     }
 }
index 4f3c886280daaf3b394998e393b61a73f26a6881..3b0cd72da7b8dad8d5f51f690f18bc593d9ac7ce 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.4 2003/09/02 20:19:25 gbazin Exp $
+ * $Id: flacdec.c,v 1.5 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
  *
@@ -116,7 +116,7 @@ static int OpenDecoder( vlc_object_t *p_this )
 {
     decoder_t *p_dec = (decoder_t*)p_this;
 
-    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('f','l','a','c') )
+    if( p_dec->fmt_in.i_codec != VLC_FOURCC('f','l','a','c') )
     {
         return VLC_EGENERIC;
     }
index bef10b689bf9d3773da8c6b2a071c4276489ebdc..d80b1829adaa41bc0d9aeabda4fd7d4b5156d84b 100755 (executable)
@@ -2,7 +2,7 @@
  * libmpeg2.c: mpeg2 video decoder module making use of libmpeg2.
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: libmpeg2.c,v 1.32 2003/11/04 17:46:17 gbazin Exp $
+ * $Id: libmpeg2.c,v 1.33 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *          Christophe Massiot <massiot@via.ecp.fr>
@@ -72,18 +72,18 @@ struct decoder_sys_t
     /*
      * Output properties
      */
-    vout_thread_t *p_vout;
     vout_synchro_t *p_synchro;
+    int i_aspect;
 
 };
 
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
-static int OpenDecoder( vlc_object_t * );
-static int InitDecoder( decoder_t * );
-static int RunDecoder ( decoder_t *, block_t * );
-static int EndDecoder ( decoder_t * );
+static int  OpenDecoder( vlc_object_t * );
+static void CloseDecoder( vlc_object_t * );
+
+static picture_t *DecodeBlock( decoder_t *, block_t ** );
 
 static picture_t *GetNewPicture( decoder_t *, uint8_t ** );
 
@@ -93,7 +93,7 @@ static picture_t *GetNewPicture( decoder_t *, uint8_t ** );
 vlc_module_begin();
     set_description( _("MPEG I/II video decoder (using libmpeg2)") );
     set_capability( "decoder", 150 );
-    set_callbacks( OpenDecoder, NULL );
+    set_callbacks( OpenDecoder, CloseDecoder );
     add_shortcut( "libmpeg2" );
 vlc_module_end();
 
@@ -103,32 +103,21 @@ vlc_module_end();
 static int OpenDecoder( vlc_object_t *p_this )
 {
     decoder_t *p_dec = (decoder_t*)p_this;
+    decoder_sys_t *p_sys;
 
-    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') &&
+    if( p_dec->fmt_in.i_codec != VLC_FOURCC('m','p','g','v') &&
+        p_dec->fmt_in.i_codec != VLC_FOURCC('m','p','g','1') &&
         /* Pinnacle hardware-mpeg1 */
-        p_dec->p_fifo->i_fourcc != VLC_FOURCC('P','I','M','1') &&
+        p_dec->fmt_in.i_codec != VLC_FOURCC('P','I','M','1') &&
         /* ATI Video */
-        p_dec->p_fifo->i_fourcc != VLC_FOURCC('V','C','R','2') &&
-        p_dec->p_fifo->i_fourcc != VLC_FOURCC('m','p','g','2') )
+        p_dec->fmt_in.i_codec != VLC_FOURCC('V','C','R','2') &&
+        p_dec->fmt_in.i_codec != VLC_FOURCC('m','p','g','2') )
     {
         return VLC_EGENERIC;
     }
 
-    p_dec->pf_init = InitDecoder;
-    p_dec->pf_decode = RunDecoder;
-    p_dec->pf_end = EndDecoder;
-
-    return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * InitDecoder: Initalize the decoder
- *****************************************************************************/
-static int InitDecoder( decoder_t *p_dec )
-{
     /* Allocate the memory needed to store the decoder's structure */
-    if( ( p_dec->p_sys =
+    if( ( p_dec->p_sys = p_sys =
           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
     {
         msg_Err( p_dec, "out of memory" );
@@ -136,30 +125,31 @@ static int InitDecoder( decoder_t *p_dec )
     }
 
     /* Initialize the thread properties */
-    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->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;
+    memset( p_sys, 0, sizeof(decoder_sys_t) );
+    p_sys->p_pes      = NULL;
+    p_sys->p_mpeg2dec = NULL;
+    p_sys->p_synchro  = NULL;
+    p_sys->p_info     = NULL;
+    p_sys->i_pts      = mdate() + DEFAULT_PTS_DELAY;
+    p_sys->i_current_pts  = 0;
+    p_sys->i_previous_pts = 0;
+    p_sys->p_picture_to_destroy = NULL;
+    p_sys->b_garbage_pic = 0;
+    p_sys->b_slice_i  = 0;
+    p_sys->b_skip     = 0;
 
     /* Initialize decoder */
-    p_dec->p_sys->p_mpeg2dec = mpeg2_init();
-    if( p_dec->p_sys->p_mpeg2dec == NULL)
+    p_sys->p_mpeg2dec = mpeg2_init();
+    if( p_sys->p_mpeg2dec == NULL)
     {
         msg_Err( p_dec, "mpeg2_init() failed" );
-        free( p_dec->p_sys );
+        free( p_sys );
         return VLC_EGENERIC;
     }
 
-    p_dec->p_sys->p_info = mpeg2_info( p_dec->p_sys->p_mpeg2dec );
+    p_sys->p_info = mpeg2_info( p_sys->p_mpeg2dec );
+
+    p_dec->pf_decode_video = DecodeBlock;
 
     return VLC_SUCCESS;
 }
@@ -167,32 +157,29 @@ static int InitDecoder( decoder_t *p_dec )
 /*****************************************************************************
  * RunDecoder: the libmpeg2 decoder
  *****************************************************************************/
-static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_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;
+    block_t *p_block;
+
+    if( !pp_block || !*pp_block ) return NULL;
+
+    p_block = *pp_block;
 
     while( 1 )
     {
-        if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error )
-        {
-            block_Release( p_block );
-            return VLC_EGENERIC;
-        }
-
         state = mpeg2_parse( p_sys->p_mpeg2dec );
 
         switch( state )
         {
         case STATE_BUFFER:
-            if( !p_block->i_buffer || b_need_more_data )
+            if( !p_block->i_buffer )
             {
                 block_Release( p_block );
-                return VLC_SUCCESS;
+                return NULL;
             }
 
             if( p_block->b_discontinuity && p_sys->p_synchro
@@ -215,16 +202,6 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
                 }
                 p_sys->p_picture_to_destroy = p_pic;
 
-                memset( p_pic->p[0].p_pixels, 0,
-                        p_sys->p_info->sequence->width
-                         * p_sys->p_info->sequence->height );
-                memset( p_pic->p[1].p_pixels, 0x80,
-                        p_sys->p_info->sequence->width
-                         * p_sys->p_info->sequence->height / 4 );
-                memset( p_pic->p[2].p_pixels, 0x80,
-                        p_sys->p_info->sequence->width
-                         * p_sys->p_info->sequence->height / 4 );
-
                 if ( p_sys->b_slice_i )
                 {
                     vout_SynchroNewPicture( p_sys->p_synchro,
@@ -246,7 +223,7 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
             mpeg2_buffer( p_sys->p_mpeg2dec, p_block->p_buffer,
                           p_block->p_buffer + p_block->i_buffer );
 
-            b_need_more_data = VLC_TRUE;
+           p_block->i_buffer = 0;
             break;
 
         case STATE_SEQUENCE:
@@ -255,25 +232,24 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
             uint8_t *buf[3];
             buf[0] = buf[1] = buf[2] = NULL;
 
-            /* Check whether the input gives a particular aspect ratio */
-            if( p_dec->p_fifo->p_demux_data
-                && ( *(int*)(p_dec->p_fifo->p_demux_data) & 0x7 ) )
+            /* Check whether the input gave a particular aspect ratio */
+            if( p_dec->fmt_in.video.i_aspect )
             {
-                i_aspect = *(int*)(p_dec->p_fifo->p_demux_data);
-                switch( i_aspect )
+                p_sys->i_aspect = p_dec->fmt_in.video.i_aspect;
+                switch( p_sys->i_aspect )
                 {
                 case AR_3_4_PICTURE:
-                    i_aspect = VOUT_ASPECT_FACTOR * 4 / 3;
+                    p_sys->i_aspect = VOUT_ASPECT_FACTOR * 4 / 3;
                     break;
                 case AR_16_9_PICTURE:
-                    i_aspect = VOUT_ASPECT_FACTOR * 16 / 9;
+                    p_sys->i_aspect = VOUT_ASPECT_FACTOR * 16 / 9;
                     break;
                 case AR_221_1_PICTURE:
-                    i_aspect = VOUT_ASPECT_FACTOR * 221 / 100;
+                    p_sys->i_aspect = VOUT_ASPECT_FACTOR * 221 / 100;
                     break;
                 case AR_SQUARE_PICTURE:
                 default:
-                    i_aspect = VOUT_ASPECT_FACTOR *
+                    p_sys->i_aspect = VOUT_ASPECT_FACTOR *
                                    p_sys->p_info->sequence->width /
                                    p_sys->p_info->sequence->height;
                     break;
@@ -282,73 +258,42 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
             else
             {
                 /* Use the value provided in the MPEG sequence header */
-                i_aspect = ((uint64_t)p_sys->p_info->sequence->display_width) *
+                p_sys->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_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_sys->p_vout->render.i_pictures; i_pic++ )
-                {
-                    if( p_dec->p_sys->p_vout->render.pp_picture[i_pic]->i_status ==
-                          RESERVED_PICTURE )
-                        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_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, "cannot create vout" );
-                block_Release( p_block );
-                return -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,
+                     p_sys->p_info->sequence->height, p_sys->i_aspect,
                      (uint32_t)((uint64_t)1001000000 * 27 /
-                                 p_sys->p_info->sequence->frame_period / 1001),
+                         p_sys->p_info->sequence->frame_period / 1001),
                      (uint32_t)((uint64_t)1001000000 * 27 /
-                                 p_sys->p_info->sequence->frame_period % 1001) );
+                         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_sys->p_mpeg2dec, buf, NULL );
 
-            if( (p_pic = GetNewPicture( p_dec, buf )) == NULL ) break;
-            memset( p_pic->p[0].p_pixels, 0,
-                    p_sys->p_info->sequence->width
-                     * p_sys->p_info->sequence->height );
-            memset( p_pic->p[1].p_pixels, 0x80,
-                    p_sys->p_info->sequence->width
-                     * p_sys->p_info->sequence->height / 4 );
-            memset( p_pic->p[2].p_pixels, 0x80,
-                    p_sys->p_info->sequence->width
-                     * p_sys->p_info->sequence->height / 4 );
+            if( (p_pic = GetNewPicture( p_dec, buf )) == NULL )
+           {
+               block_Release( p_block );
+               return NULL;
+           }
+
             mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
+
             /* This picture will never go through display_picture. */
-            vout_DatePicture( p_sys->p_vout, p_pic, 0 );
-            vout_DisplayPicture( p_sys->p_vout, p_pic );
+            p_pic->date = 0;
+
             /* For some reason, libmpeg2 will put this pic twice in
              * discard_picture. This can be considered a bug in libmpeg2. */
-            vout_LinkPicture( p_sys->p_vout, p_pic );
+            //vout_LinkPicture( p_sys->p_vout, p_pic );
 
-            if ( p_sys->p_synchro )
+            if( p_sys->p_synchro )
             {
                 vout_SynchroRelease( p_sys->p_synchro );
             }
@@ -363,10 +308,9 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
             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_sys->i_current_rate );
+                0, 0, p_sys->i_current_rate );
 
-            if ( p_sys->b_skip )
+            if( p_sys->b_skip )
             {
                 vout_SynchroTrash( p_sys->p_synchro );
             }
@@ -381,10 +325,9 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
             uint8_t *buf[3];
             buf[0] = buf[1] = buf[2] = NULL;
 
-            if ( p_sys->b_after_sequence_header
-                  && ((p_sys->p_info->current_picture->flags
-                        & PIC_MASK_CODING_TYPE)
-                       == PIC_FLAG_CODING_TYPE_P) )
+            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, "intra-slice refresh stream" );
@@ -411,7 +354,7 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
                    && !vout_SynchroChoose( p_sys->p_synchro,
                               p_sys->p_info->current_picture->flags
                                 & PIC_MASK_CODING_TYPE,
-                              p_sys->p_vout->render_time ) )
+                             /*p_sys->p_vout->render_time*/ 0 /*FIXME*/ ) )
             {
                 mpeg2_skip( p_sys->p_mpeg2dec, 1 );
                 p_sys->b_skip = 1;
@@ -423,7 +366,13 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
                 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;
+
+                if( (p_pic = GetNewPicture( p_dec, buf )) == NULL )
+               {
+                   block_Release( p_block );
+                   return NULL;
+               }
+
                 mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
             }
         }
@@ -441,26 +390,28 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
                              & PIC_MASK_CODING_TYPE,
                             p_sys->b_garbage_pic );
                 p_sys->b_garbage_pic = 0;
-                vout_DisplayPicture( p_sys->p_vout, p_pic );
 
                 if ( p_sys->p_picture_to_destroy != p_pic )
                 {
-                    vout_DatePicture( p_sys->p_vout, p_pic,
-                        vout_SynchroDate( p_sys->p_synchro ) );
+                    p_pic->date = vout_SynchroDate( p_sys->p_synchro );
                 }
                 else
                 {
                     p_sys->p_picture_to_destroy = NULL;
-                    vout_DatePicture( p_sys->p_vout, p_pic, 0 );
+                    p_pic->date = 0;
                 }
+           return p_pic; /* FIXME */
             }
 
             if( p_sys->p_info->discard_fbuf &&
                 p_sys->p_info->discard_fbuf->id )
             {
-                p_pic = (picture_t *)p_sys->p_info->discard_fbuf->id;
-                vout_UnlinkPicture( p_sys->p_vout, p_pic );
+               //p_pic = (picture_t *)p_sys->p_info->discard_fbuf->id;
+                //vout_UnlinkPicture( p_sys->p_vout, p_pic );
             }
+
+           //return p_pic; /* FIXME */
+
             break;
 
         case STATE_INVALID:
@@ -470,8 +421,8 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
 
             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 ) )
+               ( ( p_sys->p_info->current_picture->flags &
+                  PIC_MASK_CODING_TYPE) != B_CODING_TYPE ) )
             {
                 vout_SynchroReset( p_sys->p_synchro );
             }
@@ -502,7 +453,7 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
                     p_sys->p_info->sequence->width
                      * p_sys->p_info->sequence->height / 4 );
 
-            if ( p_sys->b_slice_i )
+            if( p_sys->b_slice_i )
             {
                 vout_SynchroNewPicture( p_sys->p_synchro,
                             I_CODING_TYPE, 2, 0, 0, p_sys->i_current_rate );
@@ -517,47 +468,23 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
         }
     }
 
-    block_Release( p_block );
-    return VLC_EGENERIC;
+    /* Never reached */
+    return NULL;
 }
 
 /*****************************************************************************
- * EndDecoder: libmpeg2 decoder destruction
+ * CloseDecoder: libmpeg2 decoder destruction
  *****************************************************************************/
-static int EndDecoder( decoder_t * p_dec )
+static void CloseDecoder( vlc_object_t *p_this )
 {
+    decoder_t *p_dec = (decoder_t *)p_this;
     decoder_sys_t *p_sys = p_dec->p_sys;
 
-    if( p_sys )
-    {
-        int i_pic;
-
-        if( p_sys->p_synchro )
-            vout_SynchroRelease( p_sys->p_synchro );
-
-        if( p_sys->p_vout )
-        {
-            /* Temporary hack to free the pictures in use by libmpeg2 */
-            for( i_pic = 0; i_pic < p_sys->p_vout->render.i_pictures; i_pic++ )
-            {
-                if( p_sys->p_vout->render.pp_picture[i_pic]->i_status ==
-                      RESERVED_PICTURE )
-                    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_sys->p_vout, 0, 0, 0, 0 );
-        }
+    if( p_sys->p_synchro ) vout_SynchroRelease( p_sys->p_synchro );
 
-        if( p_sys->p_mpeg2dec ) mpeg2_close( p_sys->p_mpeg2dec );
+    if( p_sys->p_mpeg2dec ) mpeg2_close( p_sys->p_mpeg2dec );
 
-        free( p_sys );
-    }
-
-    return VLC_SUCCESS;
+    free( p_sys );
 }
 
 /*****************************************************************************
@@ -568,26 +495,28 @@ 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_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_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_sys->p_info->current_picture != NULL ?
-        p_sys->p_info->current_picture->nb_fields : 2;
+    p_dec->fmt_out.video.i_width = p_sys->p_info->sequence->width;
+    p_dec->fmt_out.video.i_height = p_sys->p_info->sequence->height;
+    p_dec->fmt_out.video.i_aspect = p_sys->i_aspect;
 
-    /* Get a new picture */
-    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 )
-            break;
+    p_dec->fmt_out.i_codec =
+        ( p_sys->p_info->sequence->chroma_height <
+          p_sys->p_info->sequence->height ) ?
+        VLC_FOURCC('I','4','2','0') : VLC_FOURCC('I','4','2','2');
 
-        msleep( VOUT_OUTMEM_SLEEP );
-    }
+    /* Get a new picture */
+    p_pic = p_dec->pf_vout_buffer_new( p_dec );
 
     if( p_pic == NULL ) return NULL;
 
-    vout_LinkPicture( p_sys->p_vout, p_pic );
+    p_pic->b_progressive = p_sys->p_info->current_picture != NULL ?
+        p_sys->p_info->current_picture->flags & PIC_FLAG_PROGRESSIVE_FRAME : 1;
+    p_pic->b_top_field_first = p_sys->p_info->current_picture != NULL ?
+        p_sys->p_info->current_picture->flags & PIC_FLAG_TOP_FIELD_FIRST : 1;
+    p_pic->i_nb_fields = p_sys->p_info->current_picture != NULL ?
+        p_sys->p_info->current_picture->nb_fields : 2;
+
+    //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 fc73cc36be381b9f688676a9be2616fb970278ff..ccfc99b631cae09c37655fa3d376b2471d14573f 100644 (file)
@@ -2,7 +2,7 @@
  * lpcm.c: lpcm decoder module
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: lpcm.c,v 1.17 2003/09/02 20:19:25 gbazin Exp $
+ * $Id: lpcm.c,v 1.18 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *          Henri Fallon <henri@videolan.org>
@@ -104,8 +104,8 @@ static int OpenDecoder( vlc_object_t *p_this )
 {
     decoder_t *p_dec = (decoder_t*)p_this;
 
-    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') )
+    if( p_dec->fmt_in.i_codec != VLC_FOURCC('l','p','c','m')
+         && p_dec->fmt_in.i_codec != VLC_FOURCC('l','p','c','b') )
     {   
         return VLC_EGENERIC;
     }
index dccabe7ec9240372ddd0bf73efe1dd3f0e1437b2..8918ff68a1a2edaabdd3dc96b5f415f9ec4ca3de 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.21 2003/10/23 21:28:11 gbazin Exp $
+ * $Id: mpeg_audio.c,v 1.22 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Eric Petit <titer@videolan.org>
@@ -51,32 +51,15 @@ struct decoder_sys_t
      */
     int        i_state;
 
-    block_t *p_chain;
     block_bytestream_t bytestream;
 
-    /*
-     * Decoder output properties
-     */
-    aout_instance_t *     p_aout;                                  /* opaque */
-    aout_input_t *        p_aout_input;                            /* opaque */
-    audio_sample_format_t aout_format;
-    aout_buffer_t *       p_aout_buffer; /* current aout buffer being filled */
-
-    /*
-     * Packetizer output properties
-     */
-    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 */
     audio_date_t          end_date;
     unsigned int          i_current_layer;
 
-    mtime_t pts;
+    mtime_t i_pts;
 
     int i_frame_size, i_free_frame_size;
     unsigned int i_channels_conf, i_channels;
@@ -90,7 +73,8 @@ enum {
     STATE_SYNC,
     STATE_HEADER,
     STATE_NEXT_SYNC,
-    STATE_DATA
+    STATE_GET_DATA,
+    STATE_SEND_DATA
 };
 
 /* This isn't the place to put mad-specific stuff. However, it makes the
@@ -104,17 +88,14 @@ enum {
 /****************************************************************************
  * Local prototypes
  ****************************************************************************/
-static int OpenDecoder   ( vlc_object_t * );
-static int OpenPacketizer( vlc_object_t * );
+static int  OpenDecoder   ( vlc_object_t * );
+static int  OpenPacketizer( vlc_object_t * );
+static void CloseDecoder  ( vlc_object_t * );
+static void *DecodeBlock  ( decoder_t *, block_t ** );
 
-static int InitDecoder   ( decoder_t * );
-static int RunDecoder    ( decoder_t *, block_t * );
-static int EndDecoder    ( decoder_t * );
-
-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 * );
+static uint8_t       *GetOutBuffer ( decoder_t *, void ** );
+static aout_buffer_t *GetAoutBuffer( decoder_t * );
+static block_t       *GetSoutBuffer( decoder_t * );
 
 static int SyncInfo( uint32_t i_header, unsigned int * pi_channels,
                      unsigned int * pi_channels_conf,
@@ -129,12 +110,12 @@ static int SyncInfo( uint32_t i_header, unsigned int * pi_channels,
 vlc_module_begin();
     set_description( _("MPEG audio layer I/II/III parser") );
     set_capability( "decoder", 100 );
-    set_callbacks( OpenDecoder, NULL );
+    set_callbacks( OpenDecoder, CloseDecoder );
 
     add_submodule();
     set_description( _("MPEG audio layer I/II/III packetizer") );
     set_capability( "packetizer", 10 );
-    set_callbacks( OpenPacketizer, NULL );
+    set_callbacks( OpenPacketizer, CloseDecoder );
 vlc_module_end();
 
 /*****************************************************************************
@@ -143,24 +124,39 @@ vlc_module_end();
 static int OpenDecoder( vlc_object_t *p_this )
 {
     decoder_t *p_dec = (decoder_t*)p_this;
+    decoder_sys_t *p_sys;
 
-    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', 'a') )
+    if( p_dec->fmt_in.i_codec != VLC_FOURCC('m','p','g','a') )
     {
         return VLC_EGENERIC;
     }
 
-    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 =
+    if( ( p_dec->p_sys = 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;
+
+    /* Misc init */
+    p_sys->b_packetizer = VLC_FALSE;
+    p_sys->i_state = STATE_NOSYNC;
+    aout_DateSet( &p_sys->end_date, 0 );
+    p_sys->bytestream = block_BytestreamInit( p_dec );
+
+    /* Set output properties */
+    p_dec->fmt_out.i_cat = AUDIO_ES;
+    p_dec->fmt_out.i_codec = VLC_FOURCC('m','p','g','a');
+
+    /* Set callback */
+    p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
+        DecodeBlock;
+    p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
+        DecodeBlock;
+
+    /* Start with the minimum size for a free bitrate frame */
+    p_sys->i_free_frame_size = MPGA_HEADER_SIZE;
 
     return VLC_SUCCESS;
 }
@@ -176,66 +172,34 @@ static int OpenPacketizer( vlc_object_t *p_this )
     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;
-    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('m','p','g','a');
-
-    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('m','p','g','a');
-
-    /* Start with the minimum size for a free bitrate frame */
-    p_dec->p_sys->i_free_frame_size = MPGA_HEADER_SIZE;
-
-    p_dec->p_sys->p_chain = NULL;
-
-    return VLC_SUCCESS;
-}
-
 /****************************************************************************
- * RunDecoder: the whole thing
+ * DecodeBlock: the whole thing
  ****************************************************************************
  * This function is called just after the thread is launched.
  ****************************************************************************/
-static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
     uint8_t p_header[MAD_BUFFER_GUARD];
     uint32_t i_header;
+    uint8_t *p_buf;
+    void *p_out_buffer;
+
+    if( !pp_block || !*pp_block ) return NULL;
 
-    if( !aout_DateGet( &p_sys->end_date ) && !p_block->i_pts )
+    if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )
     {
         /* We've just started the stream, wait for the first PTS. */
-        block_Release( p_block );
-        return VLC_SUCCESS;
+        block_Release( *pp_block );
+        return NULL;
     }
 
-    if( p_block->b_discontinuity )
+    if( (*pp_block)->b_discontinuity )
     {
-        p_sys->i_state = STATE_SYNC;
+        p_sys->i_state = STATE_NOSYNC;
     }
 
-    if( p_sys->p_chain )
-    {
-        block_ChainAppend( &p_sys->p_chain, p_block );
-    }
-    else
-    {
-        block_ChainAppend( &p_sys->p_chain, p_block );
-        p_sys->bytestream = block_BytestreamInit( p_dec, p_sys->p_chain, 0 );
-    }
+    block_BytestreamPush( &p_sys->bytestream, *pp_block );
 
     while( 1 )
     {
@@ -256,30 +220,21 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
             }
             if( p_sys->i_state != STATE_SYNC )
             {
-                if( block_PeekByte( &p_sys->bytestream, p_header )
-                    == VLC_SUCCESS && p_header[0] == 0xff )
-                {
-                    /* Start of a sync word, need more data */
-                    return VLC_SUCCESS;
-                }
-
-                block_ChainRelease( p_sys->p_chain );
-                p_sys->p_chain = NULL;
+                block_BytestreamFlush( &p_sys->bytestream );
 
                 /* Need more data */
-                return VLC_SUCCESS;
+                return NULL;
             }
 
         case STATE_SYNC:
             /* New frame, set the Presentation Time Stamp */
-            p_sys->pts = p_sys->bytestream.p_block->i_pts;
-            if( p_sys->pts != 0 &&
-                p_sys->pts != aout_DateGet( &p_sys->end_date ) )
+            p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
+            if( p_sys->i_pts != 0 &&
+                p_sys->i_pts != aout_DateGet( &p_sys->end_date ) )
             {
-                aout_DateSet( &p_sys->end_date, p_sys->pts );
+                aout_DateSet( &p_sys->end_date, p_sys->i_pts );
             }
             p_sys->i_state = STATE_HEADER;
-            break;
 
         case STATE_HEADER:
             /* Get MPGA frame header (MPGA_HEADER_SIZE bytes) */
@@ -287,7 +242,7 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
                                  MPGA_HEADER_SIZE ) != VLC_SUCCESS )
             {
                 /* Need more data */
-                return VLC_SUCCESS;
+                return NULL;
             }
 
             /* Build frame header */
@@ -334,7 +289,7 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
                                        MAD_BUFFER_GUARD ) != VLC_SUCCESS )
             {
                 /* Need more data */
-                return VLC_SUCCESS;
+                return NULL;
             }
 
             if( p_header[0] == 0xff && (p_header[1] & 0xe0) == 0xe0 )
@@ -359,23 +314,9 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
                                               &i_next_max_frame_size,
                                               &i_next_layer );
 
-                if( i_next_frame_size == -1 )
-                {
-                    msg_Dbg( p_dec, "emulated start code on next frame" );
-                    block_SkipByte( &p_sys->bytestream );
-                    p_sys->i_state = STATE_NOSYNC;
-                    break;
-                }
-
                 /* Free bitrate only */
-                if( p_sys->i_bit_rate == 0 )
+                if( p_sys->i_bit_rate == 0 && i_next_frame_size == -1 )
                 {
-                    if( i_next_bit_rate != 0 )
-                    {
-                        p_sys->i_frame_size++;
-                        break;
-                    }
-
                     if( (unsigned int)p_sys->i_frame_size >
                         p_sys->i_max_frame_size )
                     {
@@ -387,6 +328,17 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
                         p_sys->i_free_frame_size = MPGA_HEADER_SIZE;
                         break;
                     }
+
+                    p_sys->i_frame_size++;
+                    break;
+                }
+
+                if( i_next_frame_size == -1 )
+                {
+                    msg_Dbg( p_dec, "emulated start code on next frame" );
+                    block_SkipByte( &p_sys->bytestream );
+                    p_sys->i_state = STATE_NOSYNC;
+                    break;
                 }
 
                 /* Check info is in sync with previous one */
@@ -408,12 +360,35 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
                     p_sys->i_state = STATE_NOSYNC;
                     break;
                 }
+
+                /* Free bitrate only */
+                if( p_sys->i_bit_rate == 0 )
+                {
+                    if( i_next_bit_rate != 0 )
+                    {
+                        p_sys->i_frame_size++;
+                        break;
+                    }
+                }
+
             }
             else
             {
                 /* Free bitrate only */
                 if( p_sys->i_bit_rate == 0 )
                 {
+                    if( (unsigned int)p_sys->i_frame_size >
+                        p_sys->i_max_frame_size )
+                    {
+                        msg_Dbg( p_dec, "frame too big %d > %d "
+                                 "(emulated startcode ?)", p_sys->i_frame_size,
+                                 p_sys->i_max_frame_size );
+                        block_SkipByte( &p_sys->bytestream );
+                        p_sys->i_state = STATE_NOSYNC;
+                        p_sys->i_free_frame_size = MPGA_HEADER_SIZE;
+                        break;
+                    }
+
                     p_sys->i_frame_size++;
                     break;
                 }
@@ -425,254 +400,156 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
                 break;
             }
 
-            if( GetOutBuffer( p_dec, &p_sys->p_out_buffer ) != VLC_SUCCESS )
+            p_sys->i_state = STATE_SEND_DATA;
+            break;
+
+        case STATE_GET_DATA:
+            /* Make sure we have enough data.
+             * (Not useful if we went through NEXT_SYNC) */
+            if( block_WaitBytes( &p_sys->bytestream,
+                                 p_sys->i_frame_size ) != VLC_SUCCESS )
             {
-                return VLC_EGENERIC;
+                /* Need more data */
+                return NULL;
             }
+            p_sys->i_state = STATE_SEND_DATA;
 
-            /* Free bitrate only */
-            if( p_sys->i_bit_rate == 0 )
+        case STATE_SEND_DATA:
+            if( !(p_buf = GetOutBuffer( p_dec, &p_out_buffer )) )
             {
-                p_sys->i_free_frame_size = p_sys->i_frame_size;
+                //p_dec->b_error = VLC_TRUE;
+                return NULL;
             }
 
-            p_sys->i_state = STATE_DATA;
-
-        case STATE_DATA:
-            /* Copy the whole frame into the buffer */
-            if( block_GetBytes( &p_sys->bytestream, p_sys->p_out_buffer,
-                                p_sys->i_frame_size ) != VLC_SUCCESS )
+            /* Free bitrate only */
+            if( p_sys->i_bit_rate == 0 )
             {
-                /* Need more data */
-                return VLC_SUCCESS;
+                p_sys->i_free_frame_size = p_sys->i_frame_size;
             }
 
-            p_sys->p_chain = block_BytestreamFlush( &p_sys->bytestream );
+            /* Copy the whole frame into the buffer. When we reach this point
+             * we already know we have enough data available. */
+            block_GetBytes( &p_sys->bytestream, p_buf, p_sys->i_frame_size );
 
             /* Get beginning of next frame for libmad */
             if( !p_sys->b_packetizer )
             {
-                memcpy( p_sys->p_out_buffer + p_sys->i_frame_size,
+                memcpy( p_buf + p_sys->i_frame_size,
                         p_header, MAD_BUFFER_GUARD );
             }
 
-            SendOutBuffer( p_dec );
             p_sys->i_state = STATE_NOSYNC;
 
             /* Make sure we don't reuse the same pts twice */
-            if( p_sys->pts == p_sys->bytestream.p_block->i_pts )
-                p_sys->pts = p_sys->bytestream.p_block->i_pts = 0;
+            if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
+                p_sys->i_pts = p_sys->bytestream.p_block->i_pts = 0;
+
+            /* So p_block doesn't get re-added several times */
+            *pp_block = block_BytestreamPop( &p_sys->bytestream );
+
+            return p_out_buffer;
         }
     }
 
-    return VLC_SUCCESS;
+    return NULL;
 }
 
 /*****************************************************************************
  * GetOutBuffer:
  *****************************************************************************/
-static int GetOutBuffer( decoder_t *p_dec, uint8_t **pp_out_buffer )
+static uint8_t *GetOutBuffer( decoder_t *p_dec, void **pp_out_buffer )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
-    int i_ret;
+    uint8_t *p_buf;
+
+    if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
+    {
+        msg_Info( p_dec, "MPGA channels:%d samplerate:%d bitrate:%d",
+                  p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate );
+
+        aout_DateInit( &p_sys->end_date, p_sys->i_rate );
+        aout_DateSet( &p_sys->end_date, p_sys->i_pts );
+    }
+
+    p_dec->fmt_out.audio.i_rate     = p_sys->i_rate;
+    p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
+    p_dec->fmt_out.audio.i_bitrate  = p_sys->i_bit_rate;
+    p_dec->fmt_out.audio.i_frame_length = p_sys->i_frame_length;
+    p_dec->fmt_out.audio.i_bytes_per_frame =
+        p_sys->i_max_frame_size + MAD_BUFFER_GUARD;
+
+    p_dec->fmt_out.audio.i_original_channels = p_sys->i_channels_conf;
+    p_dec->fmt_out.audio.i_physical_channels =
+        p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
 
     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;
+        block_t *p_sout_buffer = GetSoutBuffer( p_dec );
+        p_buf = p_sout_buffer ? p_sout_buffer->p_buffer : NULL;
+        *pp_out_buffer = p_sout_buffer;
     }
     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;
+        aout_buffer_t *p_aout_buffer = GetAoutBuffer( p_dec );
+        p_buf = p_aout_buffer ? p_aout_buffer->p_buffer : NULL;
+        *pp_out_buffer = p_aout_buffer;
     }
 
-    return i_ret;
+    return p_buf;
 }
 
 /*****************************************************************************
  * GetAoutBuffer:
  *****************************************************************************/
-static int GetAoutBuffer( decoder_t *p_dec, aout_buffer_t **pp_buffer )
+static aout_buffer_t *GetAoutBuffer( decoder_t *p_dec )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
+    aout_buffer_t *p_buf;
 
-    if( p_sys->p_aout_input != NULL &&
-        ( p_sys->aout_format.i_rate != p_sys->i_rate
-        || p_sys->aout_format.i_original_channels != p_sys->i_channels_conf
-        || p_sys->aout_format.i_bytes_per_frame !=
-           p_sys->i_max_frame_size + MAD_BUFFER_GUARD
-        || p_sys->aout_format.i_frame_length != p_sys->i_frame_length
-        || p_sys->i_current_layer != p_sys->i_layer ) )
-    {
-        /* Parameters changed - this should not happen. */
-        aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
-        p_sys->p_aout_input = NULL;
-    }
+    p_buf = p_dec->pf_aout_buffer_new( p_dec, p_sys->i_frame_length );
+    if( p_buf == NULL ) return NULL;
 
-    /* Creating the audio input if not created yet. */
-    if( p_sys->p_aout_input == NULL )
-    {
-        p_sys->i_current_layer = p_sys->i_layer;
-        if( p_sys->i_layer == 3 )
-        {
-            p_sys->aout_format.i_format = VLC_FOURCC('m','p','g','3');
-        }
-        else
-        {
-            p_sys->aout_format.i_format = VLC_FOURCC('m','p','g','a');
-        }
+    p_buf->start_date = aout_DateGet( &p_sys->end_date );
+    p_buf->end_date =
+        aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length );
 
-        p_sys->aout_format.i_rate = p_sys->i_rate;
-        p_sys->aout_format.i_original_channels = p_sys->i_channels_conf;
-        p_sys->aout_format.i_physical_channels
-            = p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
-        p_sys->aout_format.i_bytes_per_frame = p_sys->i_max_frame_size
-            + MAD_BUFFER_GUARD;
-        p_sys->aout_format.i_frame_length = p_sys->i_frame_length;
-        aout_DateInit( &p_sys->end_date, p_sys->i_rate );
-        aout_DateSet( &p_sys->end_date, p_sys->pts );
-        p_sys->p_aout_input = aout_DecNew( p_dec,
-                                           &p_sys->p_aout,
-                                           &p_sys->aout_format );
-        if( p_sys->p_aout_input == NULL )
-        {
-            *pp_buffer = NULL;
-            return VLC_EGENERIC;
-        }
-    }
-
-    *pp_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
-                                    p_sys->i_frame_length );
-    if( *pp_buffer == NULL )
-    {
-        return VLC_EGENERIC;
-    }
+    /* Hack for libmad filter */
+    p_buf->i_nb_bytes = p_sys->i_frame_size + MAD_BUFFER_GUARD;
 
-    (*pp_buffer)->start_date = aout_DateGet( &p_sys->end_date );
-    (*pp_buffer)->end_date =
-         aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length );
-
-    return VLC_SUCCESS;
+    return p_buf;
 }
 
 /*****************************************************************************
  * GetSoutBuffer:
  *****************************************************************************/
-static int GetSoutBuffer( decoder_t *p_dec, sout_buffer_t **pp_buffer )
+static block_t *GetSoutBuffer( decoder_t *p_dec )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
+    block_t *p_block;
 
-    if( p_sys->p_sout_input != NULL &&
-        ( p_sys->sout_format.i_sample_rate != (int)p_sys->i_rate
-          || p_sys->sout_format.i_channels != (int)p_sys->i_channels ) )
-    {
-        /* Parameters changed - this should not happen. */
-    }
+    p_block = block_New( p_dec, p_sys->i_frame_size );
+    if( p_block == NULL ) return NULL;
 
-    /* Creating the sout input if not created yet. */
-    if( p_sys->p_sout_input == NULL )
-    {
-        p_sys->sout_format.i_sample_rate = p_sys->i_rate;
-        p_sys->sout_format.i_channels    = p_sys->i_channels;
-        p_sys->sout_format.i_block_align = 0;
-        p_sys->sout_format.i_bitrate     = p_sys->i_bit_rate;
-        p_sys->sout_format.i_extra_data  = 0;
-        p_sys->sout_format.p_extra_data  = NULL;
+    p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
 
-        aout_DateInit( &p_sys->end_date, p_sys->i_rate );
-        aout_DateSet( &p_sys->end_date, p_sys->pts );
-
-        p_sys->p_sout_input = sout_InputNew( p_dec, &p_sys->sout_format );
-        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, "MPGA channels:%d samplerate:%d bitrate:%d",
-                  p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate );
-    }
-
-    *pp_buffer = sout_BufferNew( p_sys->p_sout_input->p_sout,
-                                 p_sys->i_frame_size );
-    if( *pp_buffer == NULL )
-    {
-        return VLC_EGENERIC;
-    }
+    p_block->i_length =
+        aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length ) -
+            p_block->i_pts;
 
-    (*pp_buffer)->i_pts =
-        (*pp_buffer)->i_dts = aout_DateGet( &p_sys->end_date );
-
-    (*pp_buffer)->i_length =
-        aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length )
-        - (*pp_buffer)->i_pts;
-
-    return VLC_SUCCESS;
+    return p_block;
 }
 
 /*****************************************************************************
- * SendOutBuffer:
+ * CloseDecoder: clean up the decoder
  *****************************************************************************/
-static int SendOutBuffer( decoder_t *p_dec )
+static void CloseDecoder( vlc_object_t *p_this )
 {
+    decoder_t *p_dec = (decoder_t *)p_this;
     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
-    {
-        /* We have all we need, send the buffer to the aout core. */
-        p_sys->p_aout_buffer->i_nb_bytes =
-            p_sys->i_frame_size + MAD_BUFFER_GUARD;
-        aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input,
-                      p_sys->p_aout_buffer );
-        p_sys->p_aout_buffer = NULL;
-    }
-
-    p_sys->p_out_buffer = NULL;
+    block_BytestreamRelease( &p_sys->bytestream );
 
-    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 );
-    }
-
-    if( p_dec->p_sys->p_chain ) block_ChainRelease( p_dec->p_sys->p_chain );
-
-    free( p_dec->p_sys );
-
-    return VLC_SUCCESS;
+    free( p_sys );
 }
 
 /*****************************************************************************
index 83fc9bf69a8ed77bfc3b195b46cc56f86b6c2ef5..390d22dd8be5151c4921f7aca780e0c7587bc578 100644 (file)
@@ -2,7 +2,7 @@
  * rawvideo.c: Pseudo video decoder/packetizer for raw video data
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: rawvideo.c,v 1.7 2003/10/24 21:27:06 gbazin Exp $
+ * $Id: rawvideo.c,v 1.8 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
 #include <string.h>                                              /* strdup() */
 
 #include <vlc/vlc.h>
-#include <vlc/vout.h>
 #include <vlc/decoder.h>
 #include <vlc/input.h>
-#include <vlc/sout.h>
 
 #include "codecs.h"
 
@@ -48,17 +46,6 @@ struct decoder_sys_t
      */
     int i_raw_size;
 
-    /*
-     * Output properties
-     */
-    vout_thread_t *p_vout;
-
-    /*
-     * Packetizer output properties
-     */
-    sout_packetizer_input_t *p_sout_input;
-    sout_format_t           sout_format;
-
     /*
      * Common properties
      */
@@ -69,15 +56,14 @@ struct decoder_sys_t
 /****************************************************************************
  * Local prototypes
  ****************************************************************************/
-static int OpenDecoder   ( vlc_object_t * );
-static int OpenPacketizer( vlc_object_t * );
+static int  OpenDecoder   ( vlc_object_t * );
+static int  OpenPacketizer( vlc_object_t * );
+static void CloseDecoder  ( vlc_object_t * );
 
-static int InitDecoder   ( decoder_t * );
-static int RunDecoder    ( decoder_t *, block_t * );
-static int EndDecoder    ( decoder_t * );
+static void *DecodeBlock  ( decoder_t *, block_t ** );
 
-static int DecodeFrame   ( decoder_t *, block_t * );
-static int SendFrame     ( decoder_t *, block_t * );
+static picture_t *DecodeFrame( decoder_t *, block_t * );
+static block_t   *SendFrame  ( decoder_t *, block_t * );
 
 /*****************************************************************************
  * Module descriptor
@@ -85,25 +71,23 @@ static int SendFrame     ( decoder_t *, block_t * );
 vlc_module_begin();
     set_description( _("Pseudo Raw Video decoder") );
     set_capability( "decoder", 50 );
-    set_callbacks( OpenDecoder, NULL );
+    set_callbacks( OpenDecoder, CloseDecoder );
 
     add_submodule();
     set_description( _("Pseudo Raw Video packetizer") );
     set_capability( "packetizer", 100 );
-    set_callbacks( OpenPacketizer, NULL );
+    set_callbacks( OpenPacketizer, CloseDecoder );
 vlc_module_end();
 
 /*****************************************************************************
  * OpenDecoder: probe the decoder and return score
- *****************************************************************************
- * Tries to launch a decoder and return score so that the interface is able
- * to choose.
  *****************************************************************************/
 static int OpenDecoder( vlc_object_t *p_this )
 {
     decoder_t *p_dec = (decoder_t*)p_this;
+    decoder_sys_t *p_sys;
 
-    switch( p_dec->p_fifo->i_fourcc )
+    switch( p_dec->fmt_in.i_codec )
     {
         /* Planar YUV */
         case VLC_FOURCC('I','4','4','4'):
@@ -129,18 +113,47 @@ static int OpenDecoder( vlc_object_t *p_this )
             return VLC_EGENERIC;
     }
 
-    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 =
+    if( ( p_dec->p_sys = p_sys =
           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
     {
         msg_Err( p_dec, "out of memory" );
         return VLC_EGENERIC;
     }
+    /* Misc init */
     p_dec->p_sys->b_packetizer = VLC_FALSE;
+    p_sys->i_pts = 0;
+
+    if( p_dec->fmt_in.video.i_width <= 0 ||
+        p_dec->fmt_in.video.i_height <= 0 )
+    {
+        msg_Err( p_dec, "invalid display size %dx%d",
+                 p_dec->fmt_in.video.i_width, p_dec->fmt_in.video.i_height );
+        return VLC_EGENERIC;
+    }
+
+    /* Find out p_vdec->i_raw_size */
+    vout_InitFormat( &p_dec->fmt_out.video, p_dec->fmt_in.i_codec,
+                     p_dec->fmt_in.video.i_width,
+                     p_dec->fmt_in.video.i_height,
+                     p_dec->fmt_in.video.i_aspect );
+    p_sys->i_raw_size = p_dec->fmt_out.video.i_bits_per_pixel *
+        p_dec->fmt_out.video.i_width * p_dec->fmt_out.video.i_height / 8;
+
+    /* Set output properties */
+    p_dec->fmt_out.i_cat = VIDEO_ES;
+    p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
+    //if( !p_dec->fmt_in.video.i_aspect )
+    {
+        p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR *
+            p_dec->fmt_out.video.i_width / p_dec->fmt_out.video.i_height;
+    }
+
+    /* Set callbacks */
+    p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
+        DecodeBlock;
+    p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
+        DecodeBlock;
 
     return VLC_SUCCESS;
 }
@@ -156,96 +169,27 @@ static int OpenPacketizer( vlc_object_t *p_this )
     return i_ret;
 }
 
-/*****************************************************************************
- * InitDecoder: Initalize the decoder
- *****************************************************************************/
-static int InitDecoder( decoder_t *p_dec )
-{
-    decoder_sys_t *p_sys = p_dec->p_sys;
-    video_frame_format_t format;
-
-    p_sys->i_pts = 0;
-
-    p_sys->p_sout_input = NULL;
-    p_sys->sout_format.i_cat = VIDEO_ES;
-    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;
-
-#define bih ((BITMAPINFOHEADER*)p_dec->p_fifo->p_bitmapinfoheader)
-    if( bih == NULL )
-    {
-        msg_Err( p_dec, "info missing, fatal" );
-        return VLC_EGENERIC;
-    }
-    if( bih->biWidth <= 0 || bih->biHeight <= 0 )
-    {
-        msg_Err( p_dec, "invalid display size %dx%d",
-                 bih->biWidth, bih->biHeight );
-        return VLC_EGENERIC;
-    }
-
-    if( p_sys->b_packetizer )
-    {
-        /* add an input for the stream ouput */
-        p_sys->sout_format.i_width  = bih->biWidth;
-        p_sys->sout_format.i_height = bih->biHeight;
-        p_sys->sout_format.i_fourcc = p_dec->p_fifo->i_fourcc;
-
-        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" );
-            return VLC_EGENERIC;
-        }
-    }
-    else
-    {
-        /* Initialize video output */
-        p_sys->p_vout = vout_Request( p_dec, NULL,
-                                      bih->biWidth, bih->biHeight,
-                                      p_dec->p_fifo->i_fourcc,
-                                      VOUT_ASPECT_FACTOR * bih->biWidth /
-                                      bih->biHeight );
-        if( p_sys->p_vout == NULL )
-        {
-            msg_Err( p_dec, "failed to create vout" );
-            return VLC_EGENERIC;
-        }
-    }
-
-    /* Find out p_vdec->i_raw_size */
-    vout_InitFormat( &format, p_dec->p_fifo->i_fourcc,
-                     bih->biWidth, bih->biHeight,
-                     bih->biWidth * VOUT_ASPECT_FACTOR / bih->biHeight );
-    p_sys->i_raw_size = format.i_bits_per_pixel *
-        format.i_width * format.i_height / 8;
-#undef bih
-
-    return VLC_SUCCESS;
-}
-
 /****************************************************************************
- * RunDecoder: the whole thing
+ * DecodeBlock: the whole thing
  ****************************************************************************
- * This function must be fed with ogg packets.
+ * This function must be fed with complete frames.
  ****************************************************************************/
-static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
-    int i_ret;
+    block_t *p_block;
+    void *p_buf;
+
+    if( !pp_block || !*pp_block ) return NULL;
+
+    p_block = *pp_block;
 
-#if 0
-    if( !aout_DateGet( &p_sys->end_date ) && !p_block->i_pts )
+    if( !p_sys->i_pts && !p_block->i_pts )
     {
         /* We've just started the stream, wait for the first PTS. */
         block_Release( p_block );
-        return VLC_SUCCESS;
+        return NULL;
     }
-#endif
 
     /* Date management */
     if( p_block->i_pts > 0 && p_block->i_pts != p_sys->i_pts )
@@ -259,23 +203,23 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
                   p_block->i_buffer, p_sys->i_raw_size );
 
         block_Release( p_block );
-        return VLC_EGENERIC;
+        return NULL;
     }
 
     if( p_sys->b_packetizer )
     {
-        i_ret = SendFrame( p_dec, p_block );
+        p_buf = SendFrame( p_dec, p_block );
     }
     else
     {
-        i_ret = DecodeFrame( p_dec, p_block );
+        p_buf = DecodeFrame( p_dec, p_block );
     }
 
     /* Date management: 1 frame per packet */
     p_sys->i_pts += ( I64C(1000000) * 1.0 / 25 /*FIXME*/ );
+    *pp_block = NULL;
 
-    block_Release( p_block );
-    return i_ret;
+    return p_buf;
 }
 
 /*****************************************************************************
@@ -306,70 +250,44 @@ static void FillPicture( decoder_t *p_dec, block_t *p_block, picture_t *p_pic )
 /*****************************************************************************
  * DecodeFrame: decodes a video frame.
  *****************************************************************************/
-static int DecodeFrame( decoder_t *p_dec, block_t *p_block )
+static picture_t *DecodeFrame( decoder_t *p_dec, block_t *p_block )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
     picture_t *p_pic;
 
     /* Get a new picture */
-    while( !(p_pic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 ) ) )
+    p_pic = p_dec->pf_vout_buffer_new( p_dec );
+    if( !p_pic )
     {
-        if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error )
-        {
-            return VLC_EGENERIC;
-        }
-        msleep( VOUT_OUTMEM_SLEEP );
+        block_Release( p_block );
+        return NULL;
     }
-    if( !p_pic ) return VLC_EGENERIC;
 
     FillPicture( p_dec, p_block, p_pic );
 
-    vout_DatePicture( p_sys->p_vout, p_pic, p_sys->i_pts );
-    vout_DisplayPicture( p_sys->p_vout, p_pic );
+    p_pic->date = p_sys->i_pts;
 
-    return VLC_SUCCESS;
+    block_Release( p_block );
+    return p_pic;
 }
 
 /*****************************************************************************
  * SendFrame: send a video frame to the stream output.
  *****************************************************************************/
-static int SendFrame( decoder_t *p_dec, block_t *p_block )
+static block_t *SendFrame( decoder_t *p_dec, block_t *p_block )
 {
     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_block->i_buffer );
-
-    if( !p_sout_buffer ) return VLC_EGENERIC;
+    p_block->i_dts = p_block->i_pts = p_sys->i_pts;
 
-    p_dec->p_vlc->pf_memcpy( p_sout_buffer->p_buffer,
-                             p_block->p_buffer, p_block->i_buffer );
-
-    p_sout_buffer->i_dts = p_sout_buffer->i_pts = p_sys->i_pts;
-
-    sout_InputSendBuffer( p_sys->p_sout_input, p_sout_buffer );
-
-    return VLC_SUCCESS;
+    return p_block;
 }
 
 /*****************************************************************************
- * EndDecoder: decoder destruction
+ * CloseDecoder: decoder destruction
  *****************************************************************************/
-static int EndDecoder( decoder_t *p_dec )
+static void CloseDecoder( vlc_object_t *p_this )
 {
-    decoder_sys_t *p_sys = p_dec->p_sys;
-
-    if( !p_sys->b_packetizer )
-    {
-        vout_Request( p_dec, p_sys->p_vout, 0, 0, 0, 0 );
-    }
-
-    if( p_sys->p_sout_input != NULL )
-    {
-        sout_InputDelete( p_sys->p_sout_input );
-    }
-
-    free( p_sys );
-
-    return VLC_SUCCESS;
+    decoder_t *p_dec = (decoder_t*)p_this;
+    free( p_dec->p_sys );
 }
index ec1c733076a9e88bfa85318851420ea809f7c932..e3578302d550c28bb47df251b2fd07b943ebc713 100755 (executable)
@@ -2,7 +2,7 @@
  * speex.c: speex decoder/packetizer module making use of libspeex.
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: speex.c,v 1.2 2003/10/22 18:24:08 gbazin Exp $
+ * $Id: speex.c,v 1.3 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
 #include <string.h>                                    /* memcpy(), memset() */
 
 #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>
 
 #include <ogg/ogg.h>
@@ -54,6 +49,7 @@ struct decoder_sys_t
      * Input properties
      */
     int i_headers;
+    int i_frame_in_packet;
 
     /*
      * Speex properties
@@ -63,23 +59,10 @@ struct decoder_sys_t
     SpeexStereoState stereo;
     void *p_state;
 
-    /*
-     * Output properties
-     */
-    aout_instance_t        *p_aout;
-    aout_input_t           *p_aout_input;
-    audio_sample_format_t   aout_format;
-
-    /*
-     * Packetizer output properties
-     */
-    sout_packetizer_input_t *p_sout_input;
-    sout_format_t           sout_format;
-
     /*
      * Common properties
      */
-    audio_date_t          end_date;
+    audio_date_t end_date;
 
 };
 
@@ -97,17 +80,16 @@ static int pi_channels_maps[6] =
 /****************************************************************************
  * Local prototypes
  ****************************************************************************/
-static int OpenDecoder   ( vlc_object_t * );
-static int OpenPacketizer( vlc_object_t * );
+static int  OpenDecoder   ( vlc_object_t * );
+static int  OpenPacketizer( vlc_object_t * );
+static void CloseDecoder  ( vlc_object_t * );
 
-static int InitDecoder   ( decoder_t * );
-static int RunDecoder    ( decoder_t *, block_t * );
-static int EndDecoder    ( decoder_t * );
+static void *DecodeBlock  ( decoder_t *, block_t ** );
+static int  ProcessHeader ( decoder_t *, ogg_packet * );
+static void *ProcessPacket( decoder_t *, ogg_packet *, block_t ** );
 
-static int ProcessHeader ( decoder_t *, ogg_packet * );
-static int ProcessPacket ( decoder_t *, ogg_packet *, mtime_t );
-static int DecodePacket  ( decoder_t *, ogg_packet * );
-static int SendPacket    ( decoder_t *, ogg_packet * );
+static aout_buffer_t *DecodePacket( decoder_t *, ogg_packet * );
+static block_t *SendPacket( decoder_t *, ogg_packet *, block_t * );
 
 static void ParseSpeexComments( decoder_t *, ogg_packet * );
 
@@ -117,12 +99,12 @@ static void ParseSpeexComments( decoder_t *, ogg_packet * );
 vlc_module_begin();
     set_description( _("Speex audio decoder") );
     set_capability( "decoder", 100 );
-    set_callbacks( OpenDecoder, NULL );
+    set_callbacks( OpenDecoder, CloseDecoder );
 
     add_submodule();
     set_description( _("Speex audio packetizer") );
     set_capability( "packetizer", 100 );
-    set_callbacks( OpenPacketizer, NULL );
+    set_callbacks( OpenPacketizer, CloseDecoder );
 vlc_module_end();
 
 /*****************************************************************************
@@ -131,18 +113,15 @@ vlc_module_end();
 static int OpenDecoder( vlc_object_t *p_this )
 {
     decoder_t *p_dec = (decoder_t*)p_this;
+    decoder_sys_t *p_sys = p_dec->p_sys;
 
-    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('s','p','x',' ') )
+    if( p_dec->fmt_in.i_codec != VLC_FOURCC('s','p','x',' ') )
     {
         return VLC_EGENERIC;
     }
 
-    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 =
+    if( ( p_dec->p_sys = p_sys =
           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
     {
         msg_Err( p_dec, "out of memory" );
@@ -150,6 +129,23 @@ static int OpenDecoder( vlc_object_t *p_this )
     }
     p_dec->p_sys->b_packetizer = VLC_FALSE;
 
+    aout_DateSet( &p_sys->end_date, 0 );
+
+    /* Set output properties */
+    p_dec->fmt_out.i_cat = AUDIO_ES;
+    p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
+
+    /* Set callbacks */
+    p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
+        DecodeBlock;
+    p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
+        DecodeBlock;
+
+    p_sys->i_headers = 0;
+    p_sys->p_state = NULL;
+    p_sys->p_header = NULL;
+    p_sys->i_frame_in_packet = 0;
+
     return VLC_SUCCESS;
 }
 
@@ -159,53 +155,42 @@ static int OpenPacketizer( vlc_object_t *p_this )
 
     int i_ret = OpenDecoder( p_this );
 
-    if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE;
+    if( i_ret == VLC_SUCCESS )
+    {
+        p_dec->p_sys->b_packetizer = VLC_TRUE;
+        p_dec->fmt_out.i_codec = VLC_FOURCC('s','p','x',' ');
+    }
 
     return i_ret;
 }
 
-/*****************************************************************************
- * InitDecoder: Initalize the decoder
- *****************************************************************************/
-static int InitDecoder( decoder_t *p_dec )
-{
-    decoder_sys_t *p_sys = p_dec->p_sys;
-
-    aout_DateSet( &p_sys->end_date, 0 );
-
-    p_sys->p_aout = NULL;
-    p_sys->p_aout_input = NULL;
-    p_sys->aout_format.i_format = VLC_FOURCC('s','p','x',' ');
-
-    p_sys->p_sout_input = NULL;
-    p_sys->sout_format.i_cat = AUDIO_ES;
-    p_sys->sout_format.i_fourcc = VLC_FOURCC( 's', 'p', 'x', ' ' );
-    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;
-
-    p_sys->i_headers = 0;
-    p_sys->p_state = NULL;
-    p_sys->p_header = NULL;
-
-    return VLC_SUCCESS;
-}
-
 /****************************************************************************
- * RunDecoder: the whole thing
+ * DecodeBlock: the whole thing
  ****************************************************************************
  * This function must be fed with ogg packets.
  ****************************************************************************/
-static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+static void *DecodeBlock( decoder_t *p_dec, block_t **pp_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;
+    if( !pp_block ) return NULL;
+
+    if( *pp_block )
+    {
+        /* Block to Ogg packet */
+        oggpacket.packet = (*pp_block)->p_buffer;
+        oggpacket.bytes = (*pp_block)->i_buffer;
+    }
+    else
+    {
+        if( p_sys->b_packetizer ) return NULL;
+
+        /* Block to Ogg packet */
+        oggpacket.packet = NULL;
+        oggpacket.bytes = 0;
+    }
+
     oggpacket.granulepos = -1;
     oggpacket.b_o_s = 0;
     oggpacket.e_o_s = 0;
@@ -217,23 +202,13 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
         if( ProcessHeader( p_dec, &oggpacket ) != VLC_SUCCESS )
         {
             msg_Err( p_dec, "Initial Speex header is corrupted" );
-            block_Release( p_block );
-            return VLC_EGENERIC;
+            block_Release( *pp_block );
+            return NULL;
         }
 
         p_sys->i_headers++;
 
-        if( p_sys->b_packetizer )
-        {
-            i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts );
-            block_Release( p_block );
-            return i_ret;
-        }
-        else
-        {
-            block_Release( p_block );
-            return VLC_SUCCESS;
-        }
+        return ProcessPacket( p_dec, &oggpacket, pp_block );
     }
 
     if( p_sys->i_headers == 1 )
@@ -242,40 +217,10 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
         ParseSpeexComments( p_dec, &oggpacket );
         p_sys->i_headers++;
 
-        if( p_sys->b_packetizer )
-        {
-            i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts );
-            block_Release( p_block );
-            return i_ret;
-        }
-        else
-        {
-            block_Release( p_block );
-            return VLC_SUCCESS;
-        }
-    }
-
-    if( p_sys->i_headers < p_sys->p_header->extra_headers + 2 )
-    {
-        /* Skip them for now */
-        p_sys->i_headers++;
-    
-        if( p_sys->b_packetizer )
-        {
-            i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts );
-            block_Release( p_block );
-            return i_ret;
-        }
-        else
-        {
-            block_Release( p_block );
-            return VLC_SUCCESS;
-        }
+        return ProcessPacket( p_dec, &oggpacket, pp_block );
     }
 
-    i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts );
-    block_Release( p_block );
-    return i_ret;
+    return ProcessPacket( p_dec, &oggpacket, pp_block );
 }
 
 /*****************************************************************************
@@ -330,27 +275,6 @@ static int ProcessHeader( decoder_t *p_dec, ogg_packet *p_oggpacket )
              ( p_header->nb_channels == 1 ) ? " (mono" : " (stereo",
              p_header->vbr ? ", VBR)" : ")" );
 
-    aout_DateInit( &p_sys->end_date, p_header->rate );
-
-    if( p_sys->b_packetizer )
-    {
-        /* add an input for the stream ouput */
-        p_sys->sout_format.i_sample_rate = p_header->rate;
-        p_sys->sout_format.i_channels    = p_header->nb_channels;
-        p_sys->sout_format.i_block_align = 1;
-        p_sys->sout_format.i_bitrate     = 0;
-
-        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" );
-            return VLC_EGENERIC;
-        }
-
-        /* We're done */
-        return VLC_SUCCESS;
-    }
-
     /* Take care of speex decoder init */
     speex_bits_init( &p_sys->bits );
     p_sys->p_state = p_state = speex_decoder_init( p_mode );
@@ -370,20 +294,14 @@ static int ProcessHeader( decoder_t *p_dec, ogg_packet *p_oggpacket )
         speex_decoder_ctl( p_state, SPEEX_SET_HANDLER, &callback );
     }
 
-    p_sys->aout_format.i_format = AOUT_FMT_S16_NE;
-    p_sys->aout_format.i_physical_channels =
-        p_sys->aout_format.i_original_channels =
+    /* Setup the format */
+    p_dec->fmt_out.audio.i_physical_channels =
+        p_dec->fmt_out.audio.i_original_channels =
             pi_channels_maps[p_header->nb_channels];
-    p_sys->aout_format.i_rate = p_header->rate;
+    p_dec->fmt_out.audio.i_channels = p_header->nb_channels;
+    p_dec->fmt_out.audio.i_rate = p_header->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 )
-    {
-        msg_Err( p_dec, "failed to create aout fifo" );
-        return VLC_EGENERIC;
-    }
+    aout_DateInit( &p_sys->end_date, p_header->rate );
 
     return VLC_SUCCESS;
 }
@@ -391,72 +309,89 @@ static int ProcessHeader( decoder_t *p_dec, ogg_packet *p_oggpacket )
 /*****************************************************************************
  * ProcessPacket: processes a Speex packet.
  *****************************************************************************/
-static int ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
-                          mtime_t i_pts )
+static void *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
+                            block_t **pp_block )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
+    block_t *p_block = *pp_block;
 
     /* Date management */
-    if( i_pts > 0 && i_pts != aout_DateGet( &p_sys->end_date ) )
+    if( p_block && p_block->i_pts > 0 &&
+        p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
     {
-        aout_DateSet( &p_sys->end_date, i_pts );
+        aout_DateSet( &p_sys->end_date, p_block->i_pts );
     }
 
     if( !aout_DateGet( &p_sys->end_date ) )
     {
         /* We've just started the stream, wait for the first PTS. */
-        return VLC_SUCCESS;
+        if( p_block ) block_Release( p_block );
+        return NULL;
     }
 
+    *pp_block = NULL; /* To avoid being fed the same packet again */
+
     if( p_sys->b_packetizer )
     {
-        return SendPacket( p_dec, p_oggpacket );
+         return SendPacket( p_dec, p_oggpacket, p_block );
     }
     else
     {
-        return DecodePacket( p_dec, p_oggpacket );
+        aout_buffer_t *p_aout_buffer;
+
+        if( p_sys->i_headers >= p_sys->p_header->extra_headers + 2 )
+            p_aout_buffer = DecodePacket( p_dec, p_oggpacket );
+        else
+            p_aout_buffer = NULL; /* Skip headers */
+
+        if( p_block )
+        {
+            block_Release( p_block );
+        }
+        return p_aout_buffer;
     }
 }
 
 /*****************************************************************************
  * DecodePacket: decodes a Speex packet.
  *****************************************************************************/
-static int DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
+static aout_buffer_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
-    int j;
 
-    /* Copy Ogg packet to Speex bitstream */
-    speex_bits_read_from( &p_sys->bits, p_oggpacket->packet,
-                          p_oggpacket->bytes );
+    if( p_oggpacket->bytes )
+    {
+        /* Copy Ogg packet to Speex bitstream */
+        speex_bits_read_from( &p_sys->bits, p_oggpacket->packet,
+                              p_oggpacket->bytes );
+        p_sys->i_frame_in_packet = 0;
+    }
 
-    /* Decode each frame of the packet */
-    for( j = 0; j != p_sys->p_header->frames_per_packet; j++ )
+    /* Decode one frame at a time */
+    if( p_sys->i_frame_in_packet < p_sys->p_header->frames_per_packet )
     {
         aout_buffer_t *p_aout_buffer;
         int i_ret;
 
-        p_aout_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
-                                           p_sys->p_header->frame_size );
+        p_aout_buffer =
+            p_dec->pf_aout_buffer_new( p_dec, p_sys->p_header->frame_size );
         if( !p_aout_buffer )
         {
-            msg_Err( p_dec, "cannot get aout buffer" );
-            return VLC_SUCCESS;
+            return NULL;
         }
 
         i_ret = speex_decode( p_sys->p_state, &p_sys->bits,
                               (int16_t *)p_aout_buffer->p_buffer );
-        if( i_ret == -1 ) break; /* End of stream */
+        if( i_ret == -1 ) return NULL; /* End of stream */
         if( i_ret== -2 )
         {
             msg_Warn( p_dec, "Decoding error: corrupted stream?" );
-            break;
+            return NULL;
         }
 
         if( speex_bits_remaining( &p_sys->bits ) < 0 )
         {
             msg_Warn( p_dec, "Decoding overflow: corrupted stream?" );
-            break;
         }
 
         if( p_sys->p_header->nb_channels == 2 )
@@ -468,45 +403,36 @@ static int DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
         p_aout_buffer->end_date =
             aout_DateIncrement( &p_sys->end_date, p_sys->p_header->frame_size);
 
-        aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input, p_aout_buffer );
-    }
+        p_sys->i_frame_in_packet++;
 
-    return VLC_SUCCESS;
+        return p_aout_buffer;
+    }
+    else
+    {
+        return NULL;
+    }
 }
 
 /*****************************************************************************
  * SendPacket: send an ogg packet to the stream output.
  *****************************************************************************/
-static int SendPacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
+static block_t *SendPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
+                            block_t *p_block )
 {
     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 );
-
-    if( !p_sout_buffer ) return VLC_EGENERIC;
-
-    p_dec->p_vlc->pf_memcpy( p_sout_buffer->p_buffer,
-                             p_oggpacket->packet,
-                             p_oggpacket->bytes );
-
-    p_sout_buffer->i_bitrate = 0;
-
     /* Date management */
-    p_sout_buffer->i_dts = p_sout_buffer->i_pts =
-        aout_DateGet( &p_sys->end_date );
+    p_block->i_dts = p_block->i_pts = aout_DateGet( &p_sys->end_date );
 
     if( p_sys->i_headers >= p_sys->p_header->extra_headers + 2 )
-        p_sout_buffer->i_length =
+        p_block->i_length =
             aout_DateIncrement( &p_sys->end_date,
                                 p_sys->p_header->frame_size ) -
-            p_sout_buffer->i_pts;
+            p_block->i_pts;
     else
-        p_sout_buffer->i_length = 0;
+        p_block->i_length = 0;
 
-    sout_InputSendBuffer( p_sys->p_sout_input, p_sout_buffer );
-
-    return VLC_SUCCESS;
+    return p_block;
 }
 
 /*****************************************************************************
@@ -552,22 +478,13 @@ static void ParseSpeexComments( decoder_t *p_dec, ogg_packet *p_oggpacket )
 }
 
 /*****************************************************************************
- * EndDecoder: speex decoder destruction
+ * CloseDecoder: speex decoder destruction
  *****************************************************************************/
-static int EndDecoder( decoder_t * p_dec )
+static void CloseDecoder( vlc_object_t *p_this )
 {
+    decoder_t * p_dec = (decoder_t *)p_this;
     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 )
-    {
-        sout_InputDelete( p_sys->p_sout_input );
-    }
-
     if( p_sys->p_state )
     {
         speex_decoder_destroy( p_sys->p_state );
@@ -576,6 +493,4 @@ static int EndDecoder( decoder_t * p_dec )
 
     if( p_sys->p_header ) free( p_sys->p_header );
     free( p_sys );
-
-    return VLC_SUCCESS;
 }
index 162c3c8898196dfb003104ee1908ce167db9068d..ee91f93c505ca626b7966597e6bd1af8f0e0b247 100644 (file)
@@ -2,7 +2,7 @@
  * spudec.c : SPU decoder thread
  *****************************************************************************
  * Copyright (C) 2000-2001 VideoLAN
- * $Id: spudec.c,v 1.26 2003/11/06 16:36:41 nitrox Exp $
+ * $Id: spudec.c,v 1.27 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -61,8 +61,8 @@ static int OpenDecoder( vlc_object_t *p_this )
 {
     decoder_t *p_dec = (decoder_t*)p_this;
 
-    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('s','p','u',' ')
-         && p_dec->p_fifo->i_fourcc != VLC_FOURCC('s','p','u','b') )
+    if( p_dec->fmt_in.i_codec != VLC_FOURCC('s','p','u',' ')
+         && p_dec->fmt_in.i_codec != VLC_FOURCC('s','p','u','b') )
     {
         return VLC_EGENERIC;
     }
index bc56ea22bcbe2b23203b99c2cf91b40132ee97ae..566a31d7ae375f28579d5e9bce96cd5abc32ae07 100644 (file)
@@ -2,7 +2,7 @@
  * subsdec.c : text subtitles decoder
  *****************************************************************************
  * Copyright (C) 2000-2001 VideoLAN
- * $Id: subsdec.c,v 1.6 2003/11/15 15:40:19 hartman Exp $
+ * $Id: subsdec.c,v 1.7 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *          Samuel Hocevar <sam@zoy.org>
@@ -56,10 +56,9 @@ struct decoder_sys_t
  * Local prototypes
  *****************************************************************************/
 static int  OpenDecoder   ( vlc_object_t * );
+static void CloseDecoder  ( vlc_object_t * );
 
-static int  InitDecoder   ( decoder_t * );
-static int  RunDecoder    ( decoder_t *, block_t * );
-static int  EndDecoder    ( decoder_t * );
+static void DecodeBlock   ( decoder_t *, block_t ** );
 
 static void ParseText     ( decoder_t *, block_t *, vout_thread_t * );
 
@@ -103,7 +102,7 @@ static char *ppsz_justification_text[] = {N_("Center"),N_("Left"),N_("Right")};
 vlc_module_begin();
     set_description( _("text subtitles decoder") );
     set_capability( "decoder", 50 );
-    set_callbacks( OpenDecoder, NULL );
+    set_callbacks( OpenDecoder, CloseDecoder );
 
     add_category_hint( N_("Subtitles"), NULL, VLC_FALSE );
     add_integer( "subsdec-align", 0, NULL, ALIGN_TEXT, ALIGN_LONGTEXT,
@@ -125,37 +124,25 @@ vlc_module_end();
 static int OpenDecoder( vlc_object_t *p_this )
 {
     decoder_t *p_dec = (decoder_t*)p_this;
+    decoder_sys_t *p_sys;
+    vlc_value_t val;
 
-    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('s','u','b','t') && 
-        p_dec->p_fifo->i_fourcc != VLC_FOURCC('s','s','a',' ') )
+    if( p_dec->fmt_in.i_codec != VLC_FOURCC('s','u','b','t') && 
+        p_dec->fmt_in.i_codec != VLC_FOURCC('s','s','a',' ') )
     {
         return VLC_EGENERIC;
     }
 
-    p_dec->pf_init = InitDecoder;
-    p_dec->pf_decode = RunDecoder;
-    p_dec->pf_end = EndDecoder;
+    p_dec->pf_decode_sub = DecodeBlock;
 
     /* Allocate the memory needed to store the decoder's structure */
-    if( ( p_dec->p_sys =
+    if( ( p_dec->p_sys = p_sys =
           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
     {
         msg_Err( p_dec, "out of memory" );
         return VLC_EGENERIC;
     }
 
-    return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * InitDecoder: Initalize the decoder
- *****************************************************************************/
-static int InitDecoder( decoder_t *p_dec )
-{
-    decoder_sys_t *p_sys = p_dec->p_sys;
-    subtitle_data_t *p_demux_data = (subtitle_data_t *)p_dec->p_fifo->p_demux_data;
-    vlc_value_t val;
-
     var_Create( p_dec, "subsdec-align", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
     var_Get( p_dec, "subsdec-align", &val );
     p_sys->i_align = val.i_int;
@@ -183,6 +170,7 @@ static int InitDecoder( decoder_t *p_dec )
 
     if( val.psz_string ) free( val.psz_string );
 #else
+
     msg_Dbg( p_dec, "No iconv support available" );
 #endif
 
@@ -195,11 +183,11 @@ static int InitDecoder( decoder_t *p_dec )
 }
 
 /****************************************************************************
- * RunDecoder: the whole thing
+ * DecodeBlock: the whole thing
  ****************************************************************************
  * This function must be fed with complete subtitles units.
  ****************************************************************************/
-static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+static void DecodeBlock( decoder_t *p_dec, block_t **pp_block )
 {
     vout_thread_t *p_vout;
 
@@ -208,20 +196,18 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
     if( !p_vout )
     {
         msg_Warn( p_dec, "couldn't find a video output, trashing subtitle" );
-        return VLC_SUCCESS;
     }
 
-    ParseText( p_dec, p_block, p_vout );
+    ParseText( p_dec, *pp_block, p_vout );
     vlc_object_release( p_vout );
-
-    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
- * EndDecoder: clean up the decoder
+ * CloseDecoder: clean up the decoder
  *****************************************************************************/
-static int EndDecoder( decoder_t *p_dec )
+static void CloseDecoder( vlc_object_t *p_this )
 {
+    decoder_t *p_dec = (decoder_t *)p_this;
     decoder_sys_t *p_sys = p_dec->p_sys;
     vout_thread_t *p_vout;
 
@@ -253,8 +239,6 @@ static int EndDecoder( decoder_t *p_dec )
 #endif
 
     free( p_sys );
-
-    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
index 1c6b82c1e64837404ec6af25137ac52cbb10bce8..9ed2a34f870680fad65f982b2320475f423051fb 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.6 2003/10/25 00:49:13 sam Exp $
+ * $Id: tarkin.c,v 1.7 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
@@ -105,7 +105,7 @@ static int OpenDecoder( vlc_object_t *p_this )
 {
     decoder_t *p_dec = (decoder_t*)p_this;
 
-    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('t','a','r','k') )
+    if( p_dec->fmt_in.i_codec != VLC_FOURCC('t','a','r','k') )
     {
         return VLC_EGENERIC;
     }
index 2f81c7140d8f0703205ed737d3e17763c3a180ab..48ffd2cccd36a440e5c5ed208db83d8f8f595947 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.13 2003/10/25 00:49:13 sam Exp $
+ * $Id: theora.c,v 1.14 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
 #include <string.h>                                    /* memcpy(), memset() */
 
 #include <vlc/vlc.h>
-#include <vlc/vout.h>
 #include <vlc/decoder.h>
 #include <vlc/input.h>
-#include <vlc/sout.h>
-#include <input_ext-dec.h>
 
 #include <ogg/ogg.h>
 
@@ -58,17 +55,6 @@ struct decoder_sys_t
     theora_comment   tc;                            /* theora comment header */
     theora_state     td;                   /* theora bitstream user comments */
 
-    /*
-     * Output properties
-     */
-    vout_thread_t *p_vout;
-
-    /*
-     * Packetizer output properties
-     */
-    sout_packetizer_input_t *p_sout_input;
-    sout_format_t           sout_format;
-
     /*
      * Common properties
      */
@@ -78,16 +64,14 @@ struct decoder_sys_t
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
-static int OpenDecoder   ( vlc_object_t * );
-static int OpenPacketizer( vlc_object_t * );
+static int  OpenDecoder   ( vlc_object_t * );
+static int  OpenPacketizer( vlc_object_t * );
+static void CloseDecoder  ( vlc_object_t * );
 
-static int InitDecoder   ( decoder_t * );
-static int RunDecoder    ( decoder_t *, block_t * );
-static int EndDecoder    ( decoder_t * );
+static void *DecodeBlock  ( decoder_t *, block_t ** );
+static void *ProcessPacket ( decoder_t *, ogg_packet *, block_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 picture_t *DecodePacket( decoder_t *, ogg_packet * );
 
 static void ParseTheoraComments( decoder_t * );
 static void theora_CopyPicture( decoder_t *, picture_t *, yuv_buffer * );
@@ -103,18 +87,18 @@ static block_t *Encode( encoder_t *p_enc, picture_t *p_pict );
 vlc_module_begin();
     set_description( _("Theora video decoder") );
     set_capability( "decoder", 100 );
-    set_callbacks( OpenDecoder, NULL );
+    set_callbacks( OpenDecoder, CloseDecoder );
     add_shortcut( "theora" );
 
     add_submodule();
     set_description( _("Theora video packetizer") );
     set_capability( "packetizer", 100 );
-    set_callbacks( OpenPacketizer, NULL );
+    set_callbacks( OpenPacketizer, CloseDecoder );
     add_shortcut( "theora" );
 
     add_submodule();
     set_description( _("Theora video encoder") );
-    set_capability( "video encoder", 100 );
+    set_capability( "encoder", 100 );
     set_callbacks( OpenEncoder, CloseEncoder );
     add_shortcut( "theora" );
 vlc_module_end();
@@ -125,18 +109,15 @@ vlc_module_end();
 static int OpenDecoder( vlc_object_t *p_this )
 {
     decoder_t *p_dec = (decoder_t*)p_this;
+    decoder_sys_t *p_sys;
 
-    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('t','h','e','o') )
+    if( p_dec->fmt_in.i_codec != VLC_FOURCC('t','h','e','o') )
     {
         return VLC_EGENERIC;
     }
 
-    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 =
+    if( ( p_dec->p_sys = p_sys =
           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
     {
         msg_Err( p_dec, "out of memory" );
@@ -144,6 +125,24 @@ static int OpenDecoder( vlc_object_t *p_this )
     }
     p_dec->p_sys->b_packetizer = VLC_FALSE;
 
+    p_sys->i_pts = 0;
+
+    /* Set output properties */
+    p_dec->fmt_out.i_cat = VIDEO_ES;
+    p_dec->fmt_out.i_codec = VLC_FOURCC('I','4','2','0');
+
+    /* Set callbacks */
+    p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
+        DecodeBlock;
+    p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
+        DecodeBlock;
+
+    /* Init supporting Theora structures needed in header parsing */
+    theora_comment_init( &p_sys->tc );
+    theora_info_init( &p_sys->ti );
+
+    p_sys->i_headers = 0;
+
     return VLC_SUCCESS;
 }
 
@@ -153,48 +152,29 @@ static int OpenPacketizer( vlc_object_t *p_this )
 
     int i_ret = OpenDecoder( p_this );
 
-    if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE;
+    if( i_ret == VLC_SUCCESS )
+    {
+        p_dec->p_sys->b_packetizer = VLC_TRUE;
+        p_dec->fmt_out.i_codec = VLC_FOURCC( 't', 'h', 'e', 'o' );
+    }
 
     return i_ret;
 }
 
-/*****************************************************************************
- * InitDecoder: Initalize the decoder
- *****************************************************************************/
-static int InitDecoder( decoder_t *p_dec )
-{
-    decoder_sys_t *p_sys = p_dec->p_sys;
-
-    p_sys->i_pts = 0;
-
-    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_sys->tc );
-    theora_info_init( &p_sys->ti );
-
-    p_sys->i_headers = 0;
-
-    return VLC_SUCCESS;
-}
-
 /****************************************************************************
- * RunDecoder: the whole thing
+ * DecodeBlock: the whole thing
  ****************************************************************************
  * This function must be fed with ogg packets.
  ****************************************************************************/
-static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
+    block_t *p_block;
     ogg_packet oggpacket;
-    int i_ret;
+
+    if( !pp_block || !*pp_block ) return NULL;
+
+    p_block = *pp_block;
 
     /* Block to Ogg packet */
     oggpacket.packet = p_block->p_buffer;
@@ -211,55 +191,23 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
         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 "
+            msg_Err( p_dec, "This bitstream does not contain Theora "
                      "video data" );
             block_Release( p_block );
-            return VLC_EGENERIC;
+            return NULL;
         }
         p_sys->i_headers++;
 
+        /* Set output properties */
+        p_dec->fmt_out.video.i_width = p_sys->ti.width;
+        p_dec->fmt_out.video.i_height = p_sys->ti.height;
 
-        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;
-            }
-        }
+        if( p_sys->ti.aspect_denominator )
+            p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR *
+                p_sys->ti.aspect_numerator / p_sys->ti.aspect_denominator;
         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->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR *
+                p_sys->ti.frame_width / p_sys->ti.frame_height;
 
         msg_Dbg( p_dec, "%dx%d %.02f fps video, frame content "
                  "is %dx%d with offset (%d,%d)",
@@ -268,17 +216,7 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
                  p_sys->ti.frame_width, p_sys->ti.frame_height,
                  p_sys->ti.offset_x, p_sys->ti.offset_y );
 
-        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;
-        }
+        return ProcessPacket( p_dec, &oggpacket, pp_block );
     }
 
     if( p_sys->i_headers == 1 )
@@ -287,23 +225,13 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
         if( theora_decode_header( &p_sys->ti, &p_sys->tc, &oggpacket ) < 0 )
         {
             msg_Err( p_dec, "2nd Theora header is corrupted" );
-            return VLC_EGENERIC;
+            return NULL;
         }
         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;
-        }
+        return ProcessPacket( p_dec, &oggpacket, pp_block );
     }
 
     if( p_sys->i_headers == 2 )
@@ -314,7 +242,7 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
         if( theora_decode_header( &p_sys->ti, &p_sys->tc, &oggpacket ) < 0 )
         {
             msg_Err( p_dec, "3rd Theora header is corrupted" );
-            return VLC_EGENERIC;
+            return NULL;
         }
         p_sys->i_headers++;
 
@@ -324,115 +252,84 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
             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;
-        }
+        return ProcessPacket( p_dec, &oggpacket, pp_block );
     }
 
-    i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts );
-    block_Release( p_block );
-    return i_ret;
+    return ProcessPacket( p_dec, &oggpacket, pp_block );
 }
 
 /*****************************************************************************
- * ProcessPacket: processes a Vorbis packet.
+ * ProcessPacket: processes a theora packet.
  *****************************************************************************/
-static int ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
-                          mtime_t i_pts )
+static void *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
+                            block_t **pp_block )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
+    block_t *p_block = *pp_block;
+    void *p_buf;
 
     /* Date management */
-    if( i_pts > 0 && i_pts != p_sys->i_pts )
+    if( p_block->i_pts > 0 && p_block->i_pts != p_sys->i_pts )
     {
-        p_sys->i_pts = i_pts;
+        p_sys->i_pts = p_block->i_pts;
     }
 
     if( p_sys->b_packetizer )
     {
-        return SendPacket( p_dec, p_oggpacket );
+        /* Date management */
+        p_block->i_dts = p_block->i_pts = p_sys->i_pts;
+
+        if( p_sys->i_headers >= 3 )
+            p_block->i_length = p_sys->i_pts - p_block->i_pts;
+        else
+            p_block->i_length = 0;
+
+        p_buf = p_block;
     }
     else
     {
-        return DecodePacket( p_dec, p_oggpacket );
-    }
-}
-
-/*****************************************************************************
- * DecodePacket: decodes a Theora packet.
- *****************************************************************************/
-static int DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
-{
-    picture_t *p_pic;
-    yuv_buffer yuv;
-
-    decoder_sys_t *p_sys = p_dec->p_sys;
-
-    theora_decode_packetin( &p_sys->td, p_oggpacket );
-
-    /* Decode */
-    theora_decode_YUVout( &p_sys->td, &yuv );
+        if( p_sys->i_headers >= 3 )
+            p_buf = DecodePacket( p_dec, p_oggpacket );
+        else
+            p_buf = NULL;
 
-    /* Get a new picture */
-    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 )
+        if( p_block )
         {
-            return VLC_EGENERIC;
+            block_Release( p_block );
+            *pp_block = NULL;
         }
-        msleep( VOUT_OUTMEM_SLEEP );
     }
-    if( !p_pic ) return VLC_EGENERIC;
-
-    theora_CopyPicture( p_dec, p_pic, &yuv );
-
-    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 += ( I64C(1000000) * p_sys->ti.fps_denominator /
                       p_sys->ti.fps_numerator ); /* 1 frame per packet */
 
-    return VLC_SUCCESS;
+    return p_buf;
 }
 
 /*****************************************************************************
- * SendPacket: send an ogg packet to the stream output.
+ * DecodePacket: decodes a Theora packet.
  *****************************************************************************/
-static int SendPacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
+static picture_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
+    picture_t *p_pic;
+    yuv_buffer yuv;
 
-    sout_buffer_t *p_sout_buffer =
-        sout_BufferNew( p_sys->p_sout_input->p_sout, p_oggpacket->bytes );
-
-    if( !p_sout_buffer ) return VLC_EGENERIC;
+    theora_decode_packetin( &p_sys->td, p_oggpacket );
 
-    p_dec->p_vlc->pf_memcpy( p_sout_buffer->p_buffer,
-                             p_oggpacket->packet,
-                             p_oggpacket->bytes );
+    /* Decode */
+    theora_decode_YUVout( &p_sys->td, &yuv );
 
-    /* Date management */
-    p_sout_buffer->i_dts = p_sout_buffer->i_pts = p_sys->i_pts;
-    p_sys->i_pts += ( I64C(1000000) * p_sys->ti.fps_denominator /
-                      p_sys->ti.fps_numerator ); /* 1 frame per packet */
+    /* Get a new picture */
+    p_pic = p_dec->pf_vout_buffer_new( p_dec );
+    if( !p_pic ) return NULL;
 
-    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;
+    theora_CopyPicture( p_dec, p_pic, &yuv );
 
-    sout_InputSendBuffer( p_sys->p_sout_input, p_sout_buffer );
+    p_pic->date = p_sys->i_pts;
 
-    return VLC_SUCCESS;
+    return p_pic;
 }
 
 /*****************************************************************************
@@ -467,26 +364,17 @@ static void ParseTheoraComments( decoder_t *p_dec )
 }
 
 /*****************************************************************************
- * EndDecoder: theora decoder destruction
+ * CloseDecoder: theora decoder destruction
  *****************************************************************************/
-static int EndDecoder( decoder_t *p_dec )
+static void CloseDecoder( vlc_object_t *p_this )
 {
+    decoder_t *p_dec = (decoder_t *)p_this;
     decoder_sys_t *p_sys = p_dec->p_sys;
 
-    if( !p_sys->b_packetizer )
-        vout_Request( p_dec, p_sys->p_vout, 0, 0, 0, 0 );
-
-    if( p_sys->p_sout_input != NULL )
-    {
-        sout_InputDelete( p_sys->p_sout_input );
-    }
-
     theora_info_clear( &p_sys->ti );
     theora_comment_clear( &p_sys->tc );
 
     free( p_sys );
-
-    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
@@ -534,7 +422,7 @@ struct encoder_sys_t
     /*
      * Input properties
      */
-    int i_headers;
+    vlc_bool_t b_headers;
 
     /*
      * Theora properties
@@ -543,12 +431,6 @@ struct encoder_sys_t
     theora_comment   tc;                            /* theora comment header */
     theora_state     td;                   /* theora bitstream user comments */
 
-    /*
-     * Packetizer output properties
-     */
-    sout_packetizer_input_t *p_sout_input;
-    sout_format_t           sout_format;
-
     /*
      * Common properties
      */
@@ -563,7 +445,7 @@ static int OpenEncoder( vlc_object_t *p_this )
     encoder_t *p_enc = (encoder_t *)p_this;
     encoder_sys_t *p_sys = p_enc->p_sys;
 
-    if( p_enc->i_fourcc != VLC_FOURCC('t','h','e','o') )
+    if( p_enc->fmt_out.i_codec != VLC_FOURCC('t','h','e','o') )
     {
         return VLC_EGENERIC;
     }
@@ -578,7 +460,7 @@ static int OpenEncoder( vlc_object_t *p_this )
 
     p_enc->pf_header = Headers;
     p_enc->pf_encode_video = Encode;
-    p_enc->format.video.i_chroma = VLC_FOURCC('I','4','2','0');
+    p_enc->fmt_in.i_codec = VLC_FOURCC('I','4','2','0');
 
 #define frame_x_offset 0
 #define frame_y_offset 0
@@ -590,10 +472,10 @@ static int OpenEncoder( vlc_object_t *p_this )
 
     theora_info_init( &p_sys->ti );
 
-    p_sys->ti.width = p_enc->format.video.i_width;
-    p_sys->ti.height = p_enc->format.video.i_height;
-    p_sys->ti.frame_width = p_enc->format.video.i_width;
-    p_sys->ti.frame_height = p_enc->format.video.i_height;
+    p_sys->ti.width = p_enc->fmt_in.video.i_width;
+    p_sys->ti.height = p_enc->fmt_in.video.i_height;
+    p_sys->ti.frame_width = p_enc->fmt_in.video.i_width;
+    p_sys->ti.frame_height = p_enc->fmt_in.video.i_height;
     p_sys->ti.offset_x = frame_x_offset;
     p_sys->ti.offset_y = frame_y_offset;
     p_sys->ti.fps_numerator = video_hzn;
@@ -601,7 +483,7 @@ static int OpenEncoder( vlc_object_t *p_this )
     p_sys->ti.aspect_numerator = video_an;
     p_sys->ti.aspect_denominator = video_ad;
     p_sys->ti.colorspace = not_specified;
-    p_sys->ti.target_bitrate = p_enc->i_bitrate;
+    p_sys->ti.target_bitrate = p_enc->fmt_out.i_bitrate;
     p_sys->ti.quality = video_q;
 
     p_sys->ti.dropframes_p = 0;
@@ -609,7 +491,7 @@ static int OpenEncoder( vlc_object_t *p_this )
     p_sys->ti.keyframe_auto_p = 1;
     p_sys->ti.keyframe_frequency = 64;
     p_sys->ti.keyframe_frequency_force = 64;
-    p_sys->ti.keyframe_data_target_bitrate = p_enc->i_bitrate * 1.5;
+    p_sys->ti.keyframe_data_target_bitrate = p_enc->fmt_out.i_bitrate * 1.5;
     p_sys->ti.keyframe_auto_threshold = 80;
     p_sys->ti.keyframe_mindistance = 8;
     p_sys->ti.noise_sensitivity = 1;
@@ -618,7 +500,7 @@ static int OpenEncoder( vlc_object_t *p_this )
     theora_info_clear( &p_sys->ti );
     theora_comment_init( &p_sys->tc );
 
-    p_sys->i_headers = 0;
+    p_sys->b_headers = VLC_FALSE;
 
     return VLC_SUCCESS;
 }
@@ -631,35 +513,32 @@ static int OpenEncoder( vlc_object_t *p_this )
 static block_t *Headers( encoder_t *p_enc )
 {
     encoder_sys_t *p_sys = p_enc->p_sys;
-    ogg_packet oggpacket;
-    block_t *p_block;
+    block_t *p_chain = NULL;
 
     /* Create theora headers */
-    switch( p_sys->i_headers )
+    if( !p_sys->b_headers )
     {
-    case 0:
-        theora_encode_header( &p_sys->td, &oggpacket );
-        break;
-    case 1:
-        theora_encode_comment( &p_sys->tc, &oggpacket );
-        break;
-    case 2:
-        theora_encode_tables( &p_sys->td, &oggpacket );
-        break;
-    default:
-        break;
-    }
+        ogg_packet oggpackets[3];
+        int i;
 
-    p_sys->i_headers++;
-    if( p_sys->i_headers > 3 ) return NULL;
+        theora_encode_header( &p_sys->td, &oggpackets[0] );
+        theora_encode_comment( &p_sys->tc, &oggpackets[1] );
+        theora_encode_tables( &p_sys->td, &oggpackets[2] );
 
-    /* Ogg packet to block */
-    p_block = block_New( p_enc, oggpacket.bytes );
-    p_block->p_buffer = oggpacket.packet;
-    p_block->i_buffer = oggpacket.bytes;
-    p_block->i_dts = oggpacket.granulepos;
+        /* Ogg packet to block */
+        for( i = 0; i < 3; i++ )
+        {
+            block_t *p_block = block_New( p_enc, oggpackets[i].bytes );
+            memcpy( p_block->p_buffer, oggpackets[i].packet,
+                    oggpackets[i].bytes );
+            p_block->i_dts = p_block->i_pts = p_block->i_length = 0;
+            block_ChainAppend( &p_chain, p_block );
+        }
 
-    return p_block;
+        p_sys->b_headers = VLC_TRUE;
+    }
+
+    return p_chain;
 }
 
 /****************************************************************************
@@ -689,7 +568,11 @@ static block_t *Encode( encoder_t *p_enc, picture_t *p_pict )
     yuv.u = p_pict->p[1].p_pixels;
     yuv.v = p_pict->p[2].p_pixels;
 
-    theora_encode_YUVin( &p_sys->td, &yuv );
+    if( theora_encode_YUVin( &p_sys->td, &yuv ) < 0 )
+    {
+        msg_Warn( p_enc, "failed encoding a frame" );
+        return NULL;
+    }
 
     theora_encode_packetout( &p_sys->td, 0, &oggpacket );
 
index 417694817bda6074fdd668af02f2c84acfe3f16a..a998aba5947bdd28fe48575e555a06f8c3b6e3a8 100644 (file)
@@ -2,7 +2,7 @@
  * vorbis.c: vorbis decoder/encoder/packetizer module making use of libvorbis.
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: vorbis.c,v 1.21 2003/10/27 17:50:54 gbazin Exp $
+ * $Id: vorbis.c,v 1.22 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
 #include <string.h>                                    /* memcpy(), memset() */
 
 #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>
 
 #include <ogg/ogg.h>
@@ -78,24 +73,11 @@ struct decoder_sys_t
                           * decoder */
     vorbis_block     vb; /* local working space for packet->PCM decode */
 
-    /*
-     * Output properties
-     */
-    aout_instance_t        *p_aout;
-    aout_input_t           *p_aout_input;
-    audio_sample_format_t   aout_format;
-
-    /*
-     * 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;
+    audio_date_t end_date;
+    int          i_last_block_size;
 
 };
 
@@ -113,16 +95,15 @@ static int pi_channels_maps[6] =
 /****************************************************************************
  * Local prototypes
  ****************************************************************************/
-static int OpenDecoder   ( vlc_object_t * );
-static int OpenPacketizer( vlc_object_t * );
+static int  OpenDecoder   ( vlc_object_t * );
+static int  OpenPacketizer( vlc_object_t * );
+static void CloseDecoder  ( vlc_object_t * );
+static void *DecodeBlock  ( decoder_t *, block_t ** );
 
-static int InitDecoder   ( decoder_t * );
-static int RunDecoder    ( decoder_t *, block_t * );
-static int EndDecoder    ( decoder_t * );
+static void *ProcessPacket ( decoder_t *, ogg_packet *, block_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 aout_buffer_t *DecodePacket  ( decoder_t *, ogg_packet * );
+static block_t *SendPacket( decoder_t *, ogg_packet *, block_t * );
 
 static void ParseVorbisComments( decoder_t * );
 
@@ -150,17 +131,17 @@ vlc_module_begin();
 #else
     set_capability( "decoder", 100 );
 #endif
-    set_callbacks( OpenDecoder, NULL );
+    set_callbacks( OpenDecoder, CloseDecoder );
 
     add_submodule();
     set_description( _("Vorbis audio packetizer") );
     set_capability( "packetizer", 100 );
-    set_callbacks( OpenPacketizer, NULL );
+    set_callbacks( OpenPacketizer, CloseDecoder );
 
 #ifndef MODULE_NAME_IS_tremor
     add_submodule();
     set_description( _("Vorbis audio encoder") );
-    set_capability( "audio encoder", 100 );
+    set_capability( "encoder", 100 );
     set_callbacks( OpenEncoder, CloseEncoder );
 #endif
 
@@ -172,24 +153,43 @@ vlc_module_end();
 static int OpenDecoder( vlc_object_t *p_this )
 {
     decoder_t *p_dec = (decoder_t*)p_this;
+    decoder_sys_t *p_sys;
 
-    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('v','o','r','b') )
+    if( p_dec->fmt_in.i_codec != VLC_FOURCC('v','o','r','b') )
     {
         return VLC_EGENERIC;
     }
 
-    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 =
+    if( ( p_dec->p_sys = 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;
+
+    /* Misc init */
+    aout_DateSet( &p_sys->end_date, 0 );
+    p_sys->b_packetizer = VLC_FALSE;
+    p_sys->i_headers = 0;
+
+    /* Take care of vorbis init */
+    vorbis_info_init( &p_sys->vi );
+    vorbis_comment_init( &p_sys->vc );
+
+    /* Set output properties */
+    p_dec->fmt_out.i_cat = AUDIO_ES;
+#ifdef MODULE_NAME_IS_tremor
+    p_dec->fmt_out.i_codec = VLC_FOURCC('f','i','3','2');
+#else
+    p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','3','2');
+#endif
+
+    /* Set callbacks */
+    p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
+        DecodeBlock;
+    p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
+        DecodeBlock;
 
     return VLC_SUCCESS;
 }
@@ -200,55 +200,42 @@ static int OpenPacketizer( vlc_object_t *p_this )
 
     int i_ret = OpenDecoder( p_this );
 
-    if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE;
+    if( i_ret == VLC_SUCCESS )
+    {
+        p_dec->p_sys->b_packetizer = VLC_TRUE;
+        p_dec->fmt_out.i_codec = VLC_FOURCC('v','o','r','b');
+    }
 
     return i_ret;
 }
 
-/*****************************************************************************
- * InitDecoder: Initalize the decoder
- *****************************************************************************/
-static int InitDecoder( decoder_t *p_dec )
-{
-    decoder_sys_t *p_sys = p_dec->p_sys;
-
-    aout_DateSet( &p_sys->end_date, 0 );
-
-    p_sys->p_aout = NULL;
-    p_sys->p_aout_input = NULL;
-    p_sys->aout_format.i_format = VLC_FOURCC('v','o','r','b');
-
-    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;
-
-    /* Take care of vorbis init */
-    vorbis_info_init( &p_sys->vi );
-    vorbis_comment_init( &p_sys->vc );
-
-    p_sys->i_headers = 0;
-
-    return VLC_SUCCESS;
-}
-
 /****************************************************************************
- * RunDecoder: the whole thing
+ * DecodeBlock: the whole thing
  ****************************************************************************
  * This function must be fed with ogg packets.
  ****************************************************************************/
-static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+static void *DecodeBlock( decoder_t *p_dec, block_t **pp_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;
+    if( !pp_block ) return NULL;
+
+    if( *pp_block )
+    {
+        /* Block to Ogg packet */
+        oggpacket.packet = (*pp_block)->p_buffer;
+        oggpacket.bytes = (*pp_block)->i_buffer;
+    }
+    else
+    {
+        if( p_sys->b_packetizer ) return NULL;
+
+        /* Block to Ogg packet */
+        oggpacket.packet = NULL;
+        oggpacket.bytes = 0;
+    }
+
     oggpacket.granulepos = -1;
     oggpacket.b_o_s = 0;
     oggpacket.e_o_s = 0;
@@ -262,55 +249,20 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
         if( vorbis_synthesis_headerin( &p_sys->vi, &p_sys->vc,
                                        &oggpacket ) < 0 )
         {
-            msg_Err( p_dec->p_fifo, "This bitstream does not contain Vorbis "
+            msg_Err( p_dec, "This bitstream does not contain Vorbis "
                      "audio data");
-            block_Release( p_block );
-            return VLC_EGENERIC;
+            block_Release( *pp_block );
+            return NULL;
         }
         p_sys->i_headers++;
 
-        if( p_sys->b_packetizer )
-        {
-            /* 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_Err( p_dec, "cannot add a new stream" );
-                block_Release( p_block );
-                return VLC_EGENERIC;
-            }
-        }
-        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 )
-            {
-                msg_Err( p_dec, "failed to create aout fifo" );
-                block_Release( p_block );
-                return VLC_EGENERIC;
-            }
-        }
+        /* Setup the format */
+        p_dec->fmt_out.audio.i_rate     = p_sys->vi.rate;
+        p_dec->fmt_out.audio.i_channels = p_sys->vi.channels;
+        p_dec->fmt_out.audio.i_bitrate  = p_sys->vi.bitrate_nominal;
+        p_dec->fmt_out.audio.i_physical_channels =
+            p_dec->fmt_out.audio.i_original_channels =
+                pi_channels_maps[p_sys->vi.channels];
 
         aout_DateInit( &p_sys->end_date, p_sys->vi.rate );
 
@@ -318,17 +270,7 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
                  p_sys->vi.channels, p_sys->vi.rate,
                  p_sys->vi.bitrate_nominal );
 
-        if( p_sys->b_packetizer )
-        {
-            i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts );
-            block_Release( p_block );
-            return i_ret;
-        }
-        else
-        {
-            block_Release( p_block );
-            return VLC_SUCCESS;
-        }
+        return ProcessPacket( p_dec, &oggpacket, pp_block );
     }
 
     if( p_sys->i_headers == 1 )
@@ -338,23 +280,14 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
             < 0 )
         {
             msg_Err( p_dec, "2nd Vorbis header is corrupted" );
-            return VLC_EGENERIC;
+            block_Release( *pp_block );
+            return NULL;
         }
         p_sys->i_headers++;
     
         ParseVorbisComments( p_dec );
 
-        if( p_sys->b_packetizer )
-        {
-            i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts );
-            block_Release( p_block );
-            return i_ret;
-        }
-        else
-        {
-            block_Release( p_block );
-            return VLC_SUCCESS;
-        }
+        return ProcessPacket( p_dec, &oggpacket, pp_block );
     }
 
     if( p_sys->i_headers == 2 )
@@ -366,7 +299,8 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
             < 0 )
         {
             msg_Err( p_dec, "3rd Vorbis header is corrupted" );
-            return VLC_EGENERIC;
+            block_Release( *pp_block );
+            return NULL;
         }
         p_sys->i_headers++;
     
@@ -377,58 +311,62 @@ static int RunDecoder( decoder_t *p_dec, block_t *p_block )
             vorbis_block_init( &p_sys->vd, &p_sys->vb );
         }
 
-        if( p_sys->b_packetizer )
-        {
-            i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts );
-            block_Release( p_block );
-            return i_ret;
-        }
-        else
-        {
-            block_Release( p_block );
-            return VLC_SUCCESS;
-        }
+        return ProcessPacket( p_dec, &oggpacket, pp_block );
     }
 
-    i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts );
-    block_Release( p_block );
-    return i_ret;
+    return ProcessPacket( p_dec, &oggpacket, pp_block );
 }
 
 /*****************************************************************************
  * ProcessPacket: processes a Vorbis packet.
  *****************************************************************************/
-static int ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
-                          mtime_t i_pts )
+static void *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
+                            block_t **pp_block )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
+    block_t *p_block = *pp_block;
 
     /* Date management */
-    if( i_pts > 0 && i_pts != aout_DateGet( &p_sys->end_date ) )
+    if( p_block && p_block->i_pts > 0 &&
+        p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
     {
-        aout_DateSet( &p_sys->end_date, i_pts );
+        aout_DateSet( &p_sys->end_date, p_block->i_pts );
     }
 
     if( !aout_DateGet( &p_sys->end_date ) )
     {
         /* We've just started the stream, wait for the first PTS. */
-        return VLC_SUCCESS;
+        if( p_block ) block_Release( p_block );
+        return NULL;
     }
 
+    *pp_block = NULL; /* To avoid being fed the same packet again */
+
     if( p_sys->b_packetizer )
     {
-        return SendPacket( p_dec, p_oggpacket );
+        return SendPacket( p_dec, p_oggpacket, p_block );
     }
     else
     {
-        return DecodePacket( p_dec, p_oggpacket );
+        aout_buffer_t *p_aout_buffer;
+
+        if( p_sys->i_headers >= 3 )
+            p_aout_buffer = DecodePacket( p_dec, p_oggpacket );
+        else
+            p_aout_buffer = NULL;
+
+        if( p_block )
+        {
+            block_Release( p_block );
+        }
+        return p_aout_buffer;
     }
 }
 
 /*****************************************************************************
  * DecodePacket: decodes a Vorbis packet.
  *****************************************************************************/
-static int DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
+static aout_buffer_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
     int           i_samples;
@@ -439,7 +377,8 @@ static int DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
     float         **pp_pcm;
 #endif
 
-    if( vorbis_synthesis( &p_sys->vb, p_oggpacket ) == 0 )
+    if( p_oggpacket->bytes &&
+        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
@@ -447,17 +386,15 @@ static int DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
      * 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_sys->vd, &pp_pcm ) ) > 0 )
+    if( ( i_samples = vorbis_synthesis_pcmout( &p_sys->vd, &pp_pcm ) ) > 0 )
     {
 
         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, "cannot get aout buffer" );
-            return VLC_SUCCESS;
-        }
+
+        p_aout_buffer =
+            p_dec->pf_aout_buffer_new( p_dec, i_samples );
+
+        if( p_aout_buffer == NULL ) return NULL;
 
         /* Interleave the samples */
 #ifdef MODULE_NAME_IS_tremor
@@ -475,50 +412,38 @@ static int DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
         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_sys->p_aout, p_sys->p_aout_input, p_aout_buffer );
+        return p_aout_buffer;
+    }
+    else
+    {
+        return NULL;
     }
-
 }
 
 /*****************************************************************************
- * SendPacket: send an ogg packet to the stream output.
+ * SendPacket: send an ogg dated packet to the stream output.
  *****************************************************************************/
-static int SendPacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
+static block_t *SendPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
+                            block_t *p_block )
 {
     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 );
-
-    if( !p_sout_buffer ) return VLC_EGENERIC;
+    int i_block_size, i_samples;
 
     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_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 );
+    p_block->i_dts = p_block->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;
+        p_block->i_length = aout_DateIncrement( &p_sys->end_date, i_samples ) -
+            p_block->i_pts;
     else
-        p_sout_buffer->i_length = 0;
-
-    sout_InputSendBuffer( p_sys->p_sout_input, p_sout_buffer );
+        p_block->i_length = 0;
 
-    return VLC_SUCCESS;
+    return p_block;
 }
 
 /*****************************************************************************
@@ -574,22 +499,13 @@ static void Interleave( float *p_out, const float **pp_in,
 }
 
 /*****************************************************************************
- * EndDecoder: vorbis decoder destruction
+ * CloseDecoder: vorbis decoder destruction
  *****************************************************************************/
-static int EndDecoder( decoder_t * p_dec )
+static void CloseDecoder( vlc_object_t *p_this )
 {
+    decoder_t *p_dec = (decoder_t *)p_this;
     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 )
-    {
-        sout_InputDelete( p_sys->p_sout_input );
-    }
-
     if( !p_sys->b_packetizer && p_sys->i_headers >= 3 )
     {
         vorbis_block_clear( &p_sys->vb );
@@ -600,11 +516,8 @@ static int EndDecoder( decoder_t * p_dec )
     vorbis_info_clear( &p_sys->vi );  /* must be called last */
 
     free( p_sys );
-
-    return VLC_SUCCESS;
 }
 
-
 #if defined(HAVE_VORBIS_VORBISENC_H) && !defined(MODULE_NAME_IS_tremor)
 
 /*****************************************************************************
@@ -632,12 +545,6 @@ struct encoder_sys_t
     int i_samples_delay;
     int i_channels;
 
-    /*
-     * Packetizer output properties
-     */
-    sout_packetizer_input_t *p_sout_input;
-    sout_format_t           sout_format;
-
     /*
      * Common properties
      */
@@ -652,7 +559,7 @@ static int OpenEncoder( vlc_object_t *p_this )
     encoder_t *p_enc = (encoder_t *)p_this;
     encoder_sys_t *p_sys;
 
-    if( p_enc->i_fourcc != VLC_FOURCC('v','o','r','b') )
+    if( p_enc->fmt_out.i_codec != VLC_FOURCC('v','o','r','b') )
     {
         return VLC_EGENERIC;
     }
@@ -667,14 +574,14 @@ static int OpenEncoder( vlc_object_t *p_this )
 
     p_enc->pf_header = Headers;
     p_enc->pf_encode_audio = Encode;
-    p_enc->format.audio.i_format = VLC_FOURCC('f','l','3','2');
+    p_enc->fmt_in.i_codec = VLC_FOURCC('f','l','3','2');
 
     /* Initialize vorbis encoder */
     vorbis_info_init( &p_sys->vi );
 
     if( vorbis_encode_setup_managed( &p_sys->vi,
-            aout_FormatNbChannels( &p_enc->format.audio ),
-            p_enc->format.audio.i_rate, -1, p_enc->i_bitrate, -1 ) ||
+           p_enc->fmt_in.audio.i_channels, p_enc->fmt_in.audio.i_rate,
+            -1, p_enc->fmt_out.i_bitrate, -1 ) ||
         vorbis_encode_ctl( &p_sys->vi, OV_ECTL_RATEMANAGE_AVG, NULL ) ||
         vorbis_encode_setup_init( &p_sys->vi ) ){}
 
@@ -686,7 +593,7 @@ static int OpenEncoder( vlc_object_t *p_this )
     vorbis_analysis_init( &p_sys->vd, &p_sys->vi );
     vorbis_block_init( &p_sys->vd, &p_sys->vb );
 
-    p_sys->i_channels = aout_FormatNbChannels( &p_enc->format.audio );
+    p_sys->i_channels = p_enc->fmt_in.audio.i_channels;
     p_sys->i_last_block_size = 0;
     p_sys->i_samples_delay = 0;
     p_sys->i_headers = 0;
@@ -743,7 +650,7 @@ static block_t *Encode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
 
     p_sys->i_pts = p_aout_buf->start_date -
                 (mtime_t)1000000 * (mtime_t)p_sys->i_samples_delay /
-                (mtime_t)p_enc->format.audio.i_rate;
+                (mtime_t)p_enc->fmt_in.audio.i_rate;
 
     p_sys->i_samples_delay += p_aout_buf->i_nb_samples;
 
@@ -798,7 +705,7 @@ static block_t *Encode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
             p_sys->i_last_block_size = i_block_size;
 
             p_block->i_length = (mtime_t)1000000 *
-                (mtime_t)i_samples / (mtime_t)p_enc->format.audio.i_rate;
+                (mtime_t)i_samples / (mtime_t)p_enc->fmt_in.audio.i_rate;
 
             p_block->i_dts = p_block->i_pts = p_sys->i_pts;
 
index acf8a98f79b263e088f685fc0a49e6418b68f125..666b225e5e02cfd615851461acb12a3bd05635d0 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.6 2003/09/02 20:19:25 gbazin Exp $
+ * $Id: xvid.c,v 1.7 2003/11/16 21:07:30 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -61,9 +61,9 @@ static int OpenDecoder ( vlc_object_t *p_this )
 {
     decoder_t *p_dec = (decoder_t*)p_this;
 
-    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') )
+    if( p_dec->fmt_in.i_codec != VLC_FOURCC('x','v','i','d')
+         && p_dec->fmt_in.i_codec != VLC_FOURCC('X','V','I','D')
+         && p_dec->fmt_in.i_codec != VLC_FOURCC('D','I','V','X') )
     {
         return VLC_EGENERIC;
     }
index 3a26238d8b90cd1522816801abb30e154297dfde..fb15b537b931ac3c62ba1e6c9cb05830d077d4b8 100644 (file)
@@ -2,7 +2,7 @@
  * a52.c : Raw a52 Stream input module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: a52sys.c,v 1.8 2003/11/13 12:28:34 fenrir Exp $
+ * $Id: a52sys.c,v 1.9 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -144,10 +144,10 @@ static int Open( vlc_object_t * p_this )
     {
         int i_frame_size;
 
-        HeaderInfo( p_peek, &fmt.audio.i_channels, &fmt.audio.i_samplerate, &i_frame_size );
+        HeaderInfo( p_peek, &fmt.audio.i_channels, &fmt.audio.i_rate, &i_frame_size );
 
         msg_Dbg( p_input, "a52 channels=%d sample_rate=%d",
-                 fmt.audio.i_channels, fmt.audio.i_samplerate );
+                 fmt.audio.i_channels, fmt.audio.i_rate );
     }
 
     vlc_mutex_lock( &p_input->stream.stream_lock );
index 916632f209ca394eab42f2df43de4e96673823ce..69d5b852a315bd00df6613537427265e47b75c4e 100644 (file)
@@ -2,7 +2,7 @@
  * aac.c : Raw aac Stream input module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: aac.c,v 1.6 2003/11/13 12:28:34 fenrir Exp $
+ * $Id: aac.c,v 1.7 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -157,7 +157,7 @@ static int Open( vlc_object_t * p_this )
     if( HeaderCheck( p_peek ) )
     {
         fmt.audio.i_channels = AAC_CHANNELS( p_peek );
-        fmt.audio.i_samplerate = AAC_SAMPLE_RATE( p_peek );
+        fmt.audio.i_rate = AAC_SAMPLE_RATE( p_peek );
 
         msg_Dbg( p_input,
                  "adts header: id=%d channels=%d sample_rate=%d",
index 1873b11bdc618c03cbfc90ef9f663c0280563b03..3cdd6a458e7f6bed27881ed81512b3a5cc5a34e4 100644 (file)
@@ -2,7 +2,7 @@
  * asf.c : ASFv01 file input module for vlc
  *****************************************************************************
  * Copyright (C) 2002-2003 VideoLAN
- * $Id: asf.c,v 1.40 2003/11/13 12:28:34 fenrir Exp $
+ * $Id: asf.c,v 1.41 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -186,7 +186,7 @@ static int Open( vlc_object_t * p_this )
             es_format_Init( &fmt, AUDIO_ES, 0 );
             wf_tag_to_fourcc( GetWLE( &p_data[0] ), &fmt.i_codec, NULL );
             fmt.audio.i_channels        = GetWLE(  &p_data[2] );
-            fmt.audio.i_samplerate      = GetDWLE( &p_data[4] );
+            fmt.audio.i_rate      = GetDWLE( &p_data[4] );
             fmt.audio.i_bitrate         = GetDWLE( &p_data[8] ) * 8;
             fmt.audio.i_blockalign      = GetWLE(  &p_data[12] );
             fmt.audio.i_bitspersample   = GetWLE(  &p_data[14] );
index fb280515699fbe70c093f7726649354b58a156f5..ee1a7182c0c29ddcaaf1261d50cf0ac391c480fe 100644 (file)
@@ -2,7 +2,7 @@
  * au.c : au file input module for vlc
  *****************************************************************************
  * Copyright (C) 2001-2003 VideoLAN
- * $Id: au.c,v 1.8 2003/11/11 00:37:59 fenrir Exp $
+ * $Id: au.c,v 1.9 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -170,7 +170,7 @@ static int Open( vlc_object_t * p_this )
     /* Create WAVEFORMATEX structure */
     es_format_Init( &p_sys->fmt, AUDIO_ES, 0 );
     p_sys->fmt.audio.i_channels   = p_sys->au.i_channels;
-    p_sys->fmt.audio.i_samplerate = p_sys->au.i_sample_rate;
+    p_sys->fmt.audio.i_rate = p_sys->au.i_sample_rate;
     switch( p_sys->au.i_encoding )
     {
         case AU_ALAW_8:        /* 8-bit ISDN A-law */
@@ -262,7 +262,7 @@ static int Open( vlc_object_t * p_this )
             i_cat                    = AU_CAT_UNKNOWN;
             goto error;
     }
-    p_sys->fmt.audio.i_bitrate = p_sys->fmt.audio.i_samplerate *
+    p_sys->fmt.audio.i_bitrate = p_sys->fmt.audio.i_rate *
                                  p_sys->fmt.audio.i_channels *
                                  p_sys->fmt.audio.i_bitspersample;
 
@@ -279,7 +279,7 @@ static int Open( vlc_object_t * p_this )
         int i_samples, i_modulo;
 
         /* read samples for 50ms of */
-        i_samples = __MAX( p_sys->fmt.audio.i_samplerate / 20, 1 );
+        i_samples = __MAX( p_sys->fmt.audio.i_rate / 20, 1 );
 
         p_sys->i_frame_size = i_samples * p_sys->fmt.audio.i_channels * ( (p_sys->fmt.audio.i_bitspersample + 7) / 8 );
 
@@ -293,7 +293,7 @@ static int Open( vlc_object_t * p_this )
 
         p_sys->i_frame_length = (mtime_t)1000000 *
                                 (mtime_t)i_samples /
-                                (mtime_t)p_sys->fmt.audio.i_samplerate;
+                                (mtime_t)p_sys->fmt.audio.i_rate;
 
         p_input->pf_demux = DemuxPCM;
         p_input->pf_demux_control = demux_vaControlDefault;
index 81ca721f18dfc2c1922eb1d861792ad2dc074906..2d686c6405422a9a1f52381ea24049962371d2ce 100644 (file)
@@ -2,7 +2,7 @@
  * avi.c : AVI file Stream input module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: avi.c,v 1.68 2003/11/16 15:51:59 titer Exp $
+ * $Id: avi.c,v 1.69 2003/11/16 21:07:31 gbazin Exp $
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -274,7 +274,7 @@ static int Open( vlc_object_t * p_this )
                 es_format_Init( &fmt, AUDIO_ES, tk->i_codec );
 
                 fmt.audio.i_channels        = p_auds->p_wf->nChannels;
-                fmt.audio.i_samplerate      = p_auds->p_wf->nSamplesPerSec;
+                fmt.audio.i_rate            = p_auds->p_wf->nSamplesPerSec;
                 fmt.audio.i_bitrate         = p_auds->p_wf->nAvgBytesPerSec * 8;
                 fmt.audio.i_blockalign      = p_auds->p_wf->nBlockAlign;
                 fmt.audio.i_bitspersample   = p_auds->p_wf->wBitsPerSample;
index ab0e75df23c4be1c66dd8199fe784df7e70b4e2a..c9ddbab42f313fd83a8da7f6b09caa5ce71fe831 100644 (file)
@@ -2,7 +2,7 @@
  * live.cpp : live.com support.
  *****************************************************************************
  * Copyright (C) 2003 VideoLAN
- * $Id: livedotcom.cpp,v 1.6 2003/11/08 06:47:34 fenrir Exp $
+ * $Id: livedotcom.cpp,v 1.7 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -453,19 +453,19 @@ static int  DemuxOpen ( vlc_object_t *p_this )
         {
             es_format_Init( &tk->fmt, AUDIO_ES, VLC_FOURCC( 'u', 'n', 'd', 'f' ) );
             tk->fmt.audio.i_channels = sub->numChannels();
-            tk->fmt.audio.i_samplerate = sub->rtpSource()->timestampFrequency();
+            tk->fmt.audio.i_rate = sub->rtpSource()->timestampFrequency();
 
             if( !strcmp( sub->codecName(), "MPA" ) ||
                 !strcmp( sub->codecName(), "MPA-ROBUST" ) ||
                 !strcmp( sub->codecName(), "X-MP3-DRAFT-00" ) )
             {
                 tk->fmt.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'a' );
-                tk->fmt.audio.i_samplerate = 0;
+                tk->fmt.audio.i_rate = 0;
             }
             else if( !strcmp( sub->codecName(), "AC3" ) )
             {
                 tk->fmt.i_codec = VLC_FOURCC( 'a', '5', '2', ' ' );
-                tk->fmt.audio.i_samplerate = 0;
+                tk->fmt.audio.i_rate = 0;
             }
             else if( !strcmp( sub->codecName(), "L16" ) )
             {
index f59a0012cfe72d361dc000cc6f4ffea17e25f327..a11c5b926863222c84d9e01841502f667cc95042 100644 (file)
@@ -2,7 +2,7 @@
  * mkv.cpp : matroska demuxer
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: mkv.cpp,v 1.39 2003/11/13 12:28:34 fenrir Exp $
+ * $Id: mkv.cpp,v 1.40 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -734,7 +734,7 @@ static int Open( vlc_object_t * p_this )
                                     KaxVideoDisplayWidth &vwidth = *(KaxVideoDisplayWidth*)el4;
                                     vwidth.ReadData( p_sys->es->I_O() );
 
-                                    tk.fmt.video.i_display_width = uint16( vwidth );
+                                    tk.fmt.video.i_visible_width = uint16( vwidth );
                                     msg_Dbg( p_input, "|   |   |   |   + display width=%d", uint16( vwidth ) );
                                 }
                                 else if( EbmlId( *el4 ) == KaxVideoDisplayHeight::ClassInfos.GlobalId )
@@ -742,7 +742,7 @@ static int Open( vlc_object_t * p_this )
                                     KaxVideoDisplayWidth &vheight = *(KaxVideoDisplayWidth*)el4;
                                     vheight.ReadData( p_sys->es->I_O() );
 
-                                    tk.fmt.video.i_display_height = uint16( vheight );
+                                    tk.fmt.video.i_visible_height = uint16( vheight );
                                     msg_Dbg( p_input, "|   |   |   |   + display height=%d", uint16( vheight ) );
                                 }
                                 else if( EbmlId( *el4 ) == KaxVideoFrameRate::ClassInfos.GlobalId )
@@ -795,8 +795,8 @@ static int Open( vlc_object_t * p_this )
                                     KaxAudioSamplingFreq &afreq = *(KaxAudioSamplingFreq*)el4;
                                     afreq.ReadData( p_sys->es->I_O() );
 
-                                    tk.fmt.audio.i_samplerate = (int)float( afreq );
-                                    msg_Dbg( p_input, "|   |   |   |   + afreq=%d", tk.fmt.audio.i_samplerate );
+                                    tk.fmt.audio.i_rate = (int)float( afreq );
+                                    msg_Dbg( p_input, "|   |   |   |   + afreq=%d", tk.fmt.audio.i_rate );
                                 }
                                 else if( EbmlId( *el4 ) == KaxAudioChannels::ClassInfos.GlobalId )
                                 {
@@ -1068,7 +1068,7 @@ static int Open( vlc_object_t * p_this )
                 wf_tag_to_fourcc( GetWLE( &p_wf->wFormatTag ), &tk.fmt.i_codec, NULL );
 
                 tk.fmt.audio.i_channels   = GetWLE( &p_wf->nChannels );
-                tk.fmt.audio.i_samplerate = GetDWLE( &p_wf->nSamplesPerSec );
+                tk.fmt.audio.i_rate = GetDWLE( &p_wf->nSamplesPerSec );
                 tk.fmt.audio.i_bitrate    = GetDWLE( &p_wf->nAvgBytesPerSec ) * 8;
                 tk.fmt.audio.i_blockalign = GetWLE( &p_wf->nBlockAlign );;
                 tk.fmt.audio.i_bitspersample = GetWLE( &p_wf->wBitsPerSample );
@@ -1133,7 +1133,7 @@ static int Open( vlc_object_t * p_this )
 
             for( i_srate = 0; i_srate < 13; i_srate++ )
             {
-                if( i_sample_rates[i_srate] == tk.fmt.audio.i_samplerate )
+                if( i_sample_rates[i_srate] == tk.fmt.audio.i_rate )
                 {
                     break;
                 }
index ba84043b1d2b5a8a30944a2079905d77030e0cc4..3b603bd90d5cd0ec5db34808fd5c07a412010b7c 100644 (file)
@@ -2,7 +2,7 @@
  * mpga.c : MPEG-I/II Audio input module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: mpga.c,v 1.7 2003/11/13 12:28:34 fenrir Exp $
+ * $Id: mpga.c,v 1.8 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -311,7 +311,7 @@ static int Open( vlc_object_t * p_this )
                  MPGA_SAMPLE_RATE( header ) );
 
         fmt.audio.i_channels = MPGA_CHANNELS( header );
-        fmt.audio.i_samplerate = MPGA_SAMPLE_RATE( header );
+        fmt.audio.i_rate = MPGA_SAMPLE_RATE( header );
         fmt.audio.i_bitrate = p_sys->i_bitrate_avg;
     }
 
index c585f6efe2133556781cb9ab6e553ce107348b7d..c9a65d5ca4e6a3b851d165011e831930dec5a247 100644 (file)
@@ -2,7 +2,7 @@
  * wav.c : wav file input module for vlc
  *****************************************************************************
  * Copyright (C) 2001-2003 VideoLAN
- * $Id: wav.c,v 1.8 2003/11/11 02:49:26 fenrir Exp $
+ * $Id: wav.c,v 1.9 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -135,7 +135,7 @@ static int Open( vlc_object_t * p_this )
     es_format_Init( &p_sys->fmt, AUDIO_ES, 0 );
     wf_tag_to_fourcc( GetWLE( &p_wf->wFormatTag ), &p_sys->fmt.i_codec, &psz_name );
     p_sys->fmt.audio.i_channels = GetWLE ( &p_wf->nChannels );
-    p_sys->fmt.audio.i_samplerate = GetDWLE( &p_wf->nSamplesPerSec );
+    p_sys->fmt.audio.i_rate = GetDWLE( &p_wf->nSamplesPerSec );
     p_sys->fmt.audio.i_blockalign = GetWLE ( &p_wf->nBlockAlign );
     p_sys->fmt.audio.i_bitrate    = GetDWLE( &p_wf->nAvgBytesPerSec ) * 8;
     p_sys->fmt.audio.i_bitspersample = GetWLE ( &p_wf->wBitsPerSample );;
@@ -150,7 +150,7 @@ static int Open( vlc_object_t * p_this )
     msg_Dbg( p_input, "format:0x%4.4x channels:%d %dHz %dKo/s blockalign:%d bits/samples:%d extra size:%d",
             GetWLE( &p_wf->wFormatTag ),
             p_sys->fmt.audio.i_channels,
-            p_sys->fmt.audio.i_samplerate,
+            p_sys->fmt.audio.i_rate,
             p_sys->fmt.audio.i_bitrate / 8 / 1024,
             p_sys->fmt.audio.i_blockalign,
             p_sys->fmt.audio.i_bitspersample,
@@ -338,12 +338,12 @@ static void FrameInfo_PCM( input_thread_t *p_input,
     int i_modulo;
 
     /* read samples for 50ms of */
-    i_samples = __MAX( p_sys->fmt.audio.i_samplerate / 20, 1 );
+    i_samples = __MAX( p_sys->fmt.audio.i_rate / 20, 1 );
 
 
     *pi_length = (mtime_t)1000000 *
                  (mtime_t)i_samples /
-                 (mtime_t)p_sys->fmt.audio.i_samplerate;
+                 (mtime_t)p_sys->fmt.audio.i_rate;
 
     i_bytes = i_samples * p_sys->fmt.audio.i_channels * ( (p_sys->fmt.audio.i_bitspersample + 7) / 8 );
 
@@ -370,7 +370,7 @@ static void FrameInfo_MS_ADPCM( input_thread_t *p_input,
 
     *pi_length = (mtime_t)1000000 *
                  (mtime_t)i_samples /
-                 (mtime_t)p_sys->fmt.audio.i_samplerate;
+                 (mtime_t)p_sys->fmt.audio.i_rate;
 
     *pi_size = p_sys->fmt.audio.i_blockalign;
 }
@@ -388,7 +388,7 @@ static void FrameInfo_IMA_ADPCM( input_thread_t *p_input,
 
     *pi_length = (mtime_t)1000000 *
                  (mtime_t)i_samples /
-                 (mtime_t)p_sys->fmt.audio.i_samplerate;
+                 (mtime_t)p_sys->fmt.audio.i_rate;
 
     *pi_size = p_sys->fmt.audio.i_blockalign;
 }
index b9f3531fcbd473593e4c546802cbaf22af3817e6..21773febf66aa2094c1d46a2556b3bb166118d6e 100644 (file)
@@ -6,6 +6,7 @@ SOURCES_dummy = \
        interface.c \
        input.c \
        decoder.c \
+       encoder.c \
        renderer.c \
        $(NULL)
 
index cbd400a890fad3770f9601ae2da3c63d5a2384a5..317e4acf251786acd370b84f9dae5b7e752413f6 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
- * dec_dummy.c: dummy decoder plugin for vlc.
+ * decoder.c: dummy decoder plugin for vlc.
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: decoder.c,v 1.7 2003/10/25 00:49:14 sam Exp $
+ * $Id: decoder.c,v 1.8 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
 #include <stdio.h> /* sprintf() */
 
 /*****************************************************************************
- * Local prototypes
+ * decoder_sys_t : theora decoder descriptor
  *****************************************************************************/
-static int Run ( decoder_fifo_t * );
+struct decoder_sys_t
+{
+    int i_fd;
+};
 
 /*****************************************************************************
- * OpenDecoder: probe the decoder and return score
- *****************************************************************************
- * Always returns 0 because we are the dummy decoder!
+ * Local prototypes
  *****************************************************************************/
-int E_(OpenDecoder) ( vlc_object_t *p_this )
-{
-    ((decoder_t*)p_this)->pf_run = Run;
-
-    return VLC_SUCCESS;
-}
+static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block );
 
 /*****************************************************************************
- * Run: this function is called just after the thread is created
+ * OpenDecoder: Open the decoder
  *****************************************************************************/
-static int Run ( decoder_fifo_t *p_fifo )
+int E_(OpenDecoder) ( vlc_object_t *p_this )
 {
-    uint8_t p_buffer[1024];
+    decoder_t *p_dec = (decoder_t*)p_this;
+    decoder_sys_t *p_sys;
+    char psz_file[ PATH_MAX ];
 
-    bit_stream_t bit_stream;
-    mtime_t      last_date = mdate();
-    size_t       i_bytes = 0;
+    /* Allocate the memory needed to store the decoder's structure */
+    if( ( p_dec->p_sys = p_sys =
+          (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
+    {
+        msg_Err( p_dec, "out of memory" );
+        return VLC_EGENERIC;
+    }
 
-    char         psz_file[100];
-#ifndef UNDER_CE
-    int          i_fd;
-#endif
+    sprintf( psz_file, "stream.%i", p_dec->i_object_id );
 
-    sprintf( psz_file, "stream.%i", p_fifo->i_object_id );
 #ifndef UNDER_CE
-    i_fd = open( psz_file, O_WRONLY | O_CREAT | O_TRUNC, 00644 );
+    p_sys->i_fd = open( psz_file, O_WRONLY | O_CREAT | O_TRUNC, 00644 );
 
-    if( i_fd == -1 )
+    if( p_sys->i_fd == -1 )
     {
-        msg_Err( p_fifo, "cannot create `%s'", psz_file );
-        p_fifo->b_error = 1;
-        DecoderError( p_fifo );
-        return -1;
+        msg_Err( p_dec, "cannot create `%s'", psz_file );
+        return VLC_EGENERIC;
     }
 #endif
 
-    msg_Dbg( p_fifo, "dumping stream to file `%s'", psz_file );
+    msg_Dbg( p_dec, "dumping stream to file `%s'", psz_file );
 
-    if( InitBitstream( &bit_stream, p_fifo, NULL, NULL ) != VLC_SUCCESS )
-    {
-        msg_Err( p_fifo, "cannot initialize bitstream" );
-        p_fifo->b_error = 1;
-        DecoderError( p_fifo );
-#ifndef UNDER_CE
-        close( i_fd );
-#endif
-        return -1;
-    }
+    /* Set callbacks */
+    p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
+        DecodeBlock;
+    p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
+        DecodeBlock;
 
-    while( !p_fifo->b_die && !p_fifo->b_error )
-    {
-        GetChunk( &bit_stream, p_buffer, 1024 );
-#ifndef UNDER_CE
-        write( i_fd, p_buffer, 1024 );
+    return VLC_SUCCESS;
+}
 
-        i_bytes += 1024;
-#endif
+/****************************************************************************
+ * RunDecoder: the whole thing
+ ****************************************************************************
+ * This function must be fed with ogg packets.
+ ****************************************************************************/
+static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+    block_t *p_block;
 
-        if( mdate() < last_date + 2000000 )
-        {
-            continue;
-        }
+    if( !pp_block || !*pp_block ) return NULL;
+    p_block = *pp_block;
 
-        msg_Dbg( p_fifo, "dumped %i bytes", i_bytes );
+    if( p_block->i_buffer )
+    {
+#ifndef UNDER_CE
+        write( p_sys->i_fd, p_block->p_buffer, p_block->i_buffer );
+#endif
 
-        i_bytes = 0;
-        last_date = mdate();
+        msg_Dbg( p_dec, "dumped %i bytes", p_block->i_buffer );
     }
 
-    if( i_bytes )
-    {
-        msg_Dbg( p_fifo, "dumped %i bytes", i_bytes );
-    }
+    block_Release( p_block );
+    return NULL;
+}
+
+/*****************************************************************************
+ * CloseDecoder: decoder destruction
+ *****************************************************************************/
+void E_(CloseDecoder) ( vlc_object_t *p_this )
+{
+    decoder_t *p_dec = (decoder_t *)p_this;
+    decoder_sys_t *p_sys = p_dec->p_sys;
 
 #ifndef UNDER_CE
-    close( i_fd );
+    close( p_sys->i_fd );
 #endif
-    CloseBitstream( &bit_stream );
-
-    if( p_fifo->b_error )
-    {
-        DecoderError( p_fifo );
-        return -1;
-    }
 
-    return 0;
+    free( p_sys );
 }
index a568c80ffc0331a84859b2150c75357f06e6a53c..3fcca128089a72b88df5d2a6f81004f610c210a1 100644 (file)
@@ -2,7 +2,7 @@
  * dummy.c : dummy plugin for vlc
  *****************************************************************************
  * Copyright (C) 2000, 2001 VideoLAN
- * $Id: dummy.c,v 1.9 2003/07/14 21:32:59 sigmunau Exp $
+ * $Id: dummy.c,v 1.10 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -69,7 +69,11 @@ vlc_module_begin();
     add_submodule();
         set_description( _("dummy decoder function") );
         set_capability( "decoder", 0 );
-        set_callbacks( E_(OpenDecoder), NULL );
+        set_callbacks( E_(OpenDecoder), E_(CloseDecoder) );
+    add_submodule();
+        set_description( _("dummy encoder function") );
+        set_capability( "encoder", 0 );
+        set_callbacks( E_(OpenEncoder), E_(CloseEncoder) );
     add_submodule();
         set_description( _("dummy audio output function") );
         set_capability( "audio output", 1 );
index bd90954cdcc6a2ebababdfe4863156e4f1430b9b..82224ebc5257a7f84a6bbd06d97a67e828defb6b 100644 (file)
@@ -2,7 +2,7 @@
  * dummy.h : dummy plugin for vlc
  *****************************************************************************
  * Copyright (C) 2000, 2001, 2002 VideoLAN
- * $Id: dummy.h,v 1.2 2003/07/14 21:32:59 sigmunau Exp $
+ * $Id: dummy.h,v 1.3 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -32,9 +32,13 @@ int  E_(OpenDemux)    ( vlc_object_t * );
 void E_(CloseDemux)   ( vlc_object_t * );
 
 int  E_(OpenDecoder)  ( vlc_object_t * );
+void E_(CloseDecoder) ( vlc_object_t * );
+
+int  E_(OpenEncoder)  ( vlc_object_t * );
+void E_(CloseEncoder) ( vlc_object_t * );
 
 int  E_(OpenAudio)    ( vlc_object_t * );
 
 int  E_(OpenVideo)    ( vlc_object_t * );
 
-int E_(OpenRenderer)  ( vlc_object_t * );
+int  E_(OpenRenderer) ( vlc_object_t * );
index 9b74eebd408942405e6a4ba29c52c5c3d3729fce..f5ee5bb1cdf426f34538a0f2b0a91b71586e6d4e 100644 (file)
@@ -2,7 +2,7 @@
  * copy.c
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: copy.c,v 1.17 2003/09/29 22:37:36 gbazin Exp $
+ * $Id: copy.c,v 1.18 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Eric Petit <titer@videolan.org>
@@ -240,35 +240,6 @@ static int Init( packetizer_thread_t *p_pack )
             p_pack->output_format.i_cat = VIDEO_ES;
             break;
 
-        case VLC_FOURCC( 'I', '4', '2', '0' ):
-            p_pack->output_format.i_fourcc = VLC_FOURCC( 'I', '4', '2', '0' );
-            p_pack->output_format.i_cat = VIDEO_ES;
-            break;
-        case VLC_FOURCC( 'I', '4', '2', '2' ):
-            p_pack->output_format.i_fourcc = VLC_FOURCC( 'I', '4', '2', '2' );
-            p_pack->output_format.i_cat = VIDEO_ES;
-            break;
-        case VLC_FOURCC( 'R', 'V', '1', '5' ):
-            p_pack->output_format.i_fourcc = VLC_FOURCC( 'R', 'V', '1', '5' );
-            p_pack->output_format.i_cat = VIDEO_ES;
-            break;
-        case VLC_FOURCC( 'R', 'V', '1', '6' ):
-            p_pack->output_format.i_fourcc = VLC_FOURCC( 'R', 'V', '1', '6' );
-            p_pack->output_format.i_cat = VIDEO_ES;
-            break;
-        case VLC_FOURCC( 'R', 'V', '2', '4' ):
-            p_pack->output_format.i_fourcc = VLC_FOURCC( 'R', 'V', '2', '4' );
-            p_pack->output_format.i_cat = VIDEO_ES;
-            break;
-        case VLC_FOURCC( 'R', 'V', '3', '2' ):
-            p_pack->output_format.i_fourcc = VLC_FOURCC( 'R', 'V', '3', '2' );
-            p_pack->output_format.i_cat = VIDEO_ES;
-            break;
-        case VLC_FOURCC( 'G', 'R', 'E', 'Y' ):
-            p_pack->output_format.i_fourcc = VLC_FOURCC( 'G', 'R', 'E', 'Y' );
-            p_pack->output_format.i_cat = VIDEO_ES;
-            break;
-
         /* audio */
         case VLC_FOURCC( 'm', 'p', 'g', 'a' ):
             p_pack->output_format.i_fourcc = VLC_FOURCC( 'm', 'p', 'g', 'a' );
index dfc319c8eebcbd5da91dfb8e25c7c5d7e4bc64a8..6a1b5e694d2c26ed9704c8c7b808d7b0ef920658 100644 (file)
@@ -2,7 +2,7 @@
  * mpeg4audio.c: parse and packetize an MPEG 4 audio stream
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: mpeg4audio.c,v 1.11 2003/10/24 17:55:14 gbazin Exp $
+ * $Id: mpeg4audio.c,v 1.12 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Gildas Bazin <gbazin@netcourrier.com>
@@ -58,23 +58,15 @@ struct decoder_sys_t
     /*
      * Input properties
      */
-    int        i_state;
+    int i_state;
 
-    block_t *p_chain;
     block_bytestream_t bytestream;
 
-    /*
-     * Packetizer output properties
-     */
-    sout_packetizer_input_t *p_sout_input;
-    sout_format_t           sout_format;
-    sout_buffer_t *         p_sout_buffer;            /* current sout buffer */
-
     /*
      * Common properties
      */
-    audio_date_t          end_date;
-    mtime_t pts;
+    audio_date_t end_date;
+    mtime_t i_pts;
 
     int i_frame_size, i_raw_blocks;
     unsigned int i_channels;
@@ -87,7 +79,8 @@ enum {
     STATE_SYNC,
     STATE_HEADER,
     STATE_NEXT_SYNC,
-    STATE_DATA
+    STATE_GET_DATA,
+    STATE_SEND_DATA
 };
 
 static int i_sample_rates[] = 
@@ -101,12 +94,13 @@ static int i_sample_rates[] =
 /****************************************************************************
  * Local prototypes
  ****************************************************************************/
-static int OpenPacketizer( vlc_object_t * );
-static int InitPacketizer( decoder_t * );
-static int RunFramePacketizer ( decoder_t *, block_t * );
-static int RunADTSPacketizer ( decoder_t *, block_t * );
-static int EndPacketizer ( decoder_t * );
-static int GetSoutBuffer( decoder_t *, sout_buffer_t ** );
+static int  OpenPacketizer( vlc_object_t * );
+static void ClosePacketizer( vlc_object_t * );
+
+static block_t *PacketizeBlock    ( decoder_t *, block_t ** );
+static block_t *ADTSPacketizeBlock( decoder_t *, block_t ** );
+
+static uint8_t *GetOutBuffer ( decoder_t *, void ** );
 
 static int ADTSSyncInfo( decoder_t *, const byte_t * p_buf,
                          unsigned int * pi_channels,
@@ -121,7 +115,7 @@ static int ADTSSyncInfo( decoder_t *, const byte_t * p_buf,
 vlc_module_begin();
     set_description( _("MPEG4 Audio packetizer") );
     set_capability( "packetizer", 50 );
-    set_callbacks( OpenPacketizer, NULL );
+    set_callbacks( OpenPacketizer, ClosePacketizer );
 vlc_module_end();
 
 /*****************************************************************************
@@ -130,151 +124,140 @@ vlc_module_end();
 static int OpenPacketizer( vlc_object_t *p_this )
 {
     decoder_t *p_dec = (decoder_t*)p_this;
+    decoder_sys_t *p_sys;
 
-    if( p_dec->p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', '4', 'a' ) )
+    if( p_dec->fmt_in.i_codec != VLC_FOURCC( 'm', 'p', '4', 'a' ) )
     {
         return VLC_EGENERIC;
     }
 
     /* Allocate the memory needed to store the decoder's structure */
-    if( ( p_dec->p_sys =
+    if( ( p_dec->p_sys = p_sys =
           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
     {
         msg_Err( p_dec, "out of memory" );
         return VLC_EGENERIC;
     }
 
-    p_dec->pf_init = InitPacketizer;
-    p_dec->pf_decode = RunFramePacketizer;
-    p_dec->pf_end = EndPacketizer;
-
-    return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * InitPacketizer: Initalize the packetizer
- *****************************************************************************/
-static int InitPacketizer( decoder_t *p_dec )
-{
-    decoder_sys_t *p_sys = p_dec->p_sys;
-    WAVEFORMATEX *p_wf;
-
+    /* Misc init */
     p_sys->i_state = STATE_NOSYNC;
-
     aout_DateSet( &p_sys->end_date, 0 );
+    p_sys->bytestream = block_BytestreamInit( p_dec );
 
-    p_sys->p_sout_input = NULL;
-    p_sys->p_sout_buffer = NULL;
-    p_sys->p_chain = NULL;
+    /* Set output properties */
+    p_dec->fmt_out.i_cat = AUDIO_ES;
+    p_dec->fmt_out.i_codec = VLC_FOURCC('m','p','4','a');
 
-    msg_Info( p_dec, "Running MPEG4 audio packetizer" );
+    /* Set callback */
+    p_dec->pf_packetize = PacketizeBlock;
 
-    p_wf = (WAVEFORMATEX*)p_dec->p_fifo->p_waveformatex;
+    msg_Info( p_dec, "Running MPEG4 audio packetizer" );
 
-    if( p_wf && p_wf->cbSize > 0)
+    if( p_dec->fmt_in.i_extra > 0 )
     {
-        uint8_t *p_config = (uint8_t*)&p_wf[1];
+        uint8_t *p_config = (uint8_t*)p_dec->fmt_in.p_extra;
         int     i_index;
 
         i_index = ( ( p_config[0] << 1 ) | ( p_config[1] >> 7 ) ) & 0x0f;
         if( i_index != 0x0f )
         {
-            p_sys->i_rate = i_sample_rates[i_index];
-            p_sys->i_frame_length = (( p_config[1] >> 2 ) & 0x01) ? 960 : 1024;
+            p_dec->fmt_out.audio.i_rate = i_sample_rates[i_index];
+            p_dec->fmt_out.audio.i_frame_length =
+                (( p_config[1] >> 2 ) & 0x01) ? 960 : 1024;
         }
         else
         {
-            p_sys->i_rate = ( ( p_config[1] & 0x7f ) << 17 ) |
+            p_dec->fmt_out.audio.i_rate = ( ( p_config[1] & 0x7f ) << 17 ) |
                 ( p_config[2] << 9 ) | ( p_config[3] << 1 ) |
                 ( p_config[4] >> 7 );
-            p_sys->i_frame_length = (( p_config[4] >> 2 ) & 0x01) ? 960 : 1024;
+            p_dec->fmt_out.audio.i_frame_length =
+                (( p_config[4] >> 2 ) & 0x01) ? 960 : 1024;
         }
 
         msg_Dbg( p_dec, "AAC %dHz %d samples/frame",
-                 p_sys->i_rate, p_sys->i_frame_length );
+                 p_dec->fmt_out.audio.i_rate,
+                 p_dec->fmt_out.audio.i_frame_length );
 
-        p_sys->i_channels = p_wf->nChannels;
-        p_sys->sout_format.i_extra_data = p_wf->cbSize;
-        p_sys->sout_format.p_extra_data = malloc( p_wf->cbSize );
-        memcpy( p_sys->sout_format.p_extra_data, &p_wf[1], p_wf->cbSize );
+        aout_DateInit( &p_sys->end_date, p_dec->fmt_out.audio.i_rate );
+
+        p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
+        p_dec->fmt_out.i_extra = p_dec->fmt_in.i_extra;
+        p_dec->fmt_out.p_extra = malloc( p_dec->fmt_in.i_extra );
+        memcpy( p_dec->fmt_out.p_extra, p_dec->fmt_in.p_extra,
+                p_dec->fmt_in.i_extra );
     }
     else
     {
         msg_Dbg( p_dec, "No decoder specific info, must be an ADTS stream" );
 
         /* We will try to create a AAC Config from adts */
-        p_sys->sout_format.i_extra_data = 0;
-        p_sys->sout_format.p_extra_data = NULL;
-        p_dec->pf_decode = RunADTSPacketizer;
+        p_dec->fmt_out.i_extra = 0;
+        p_dec->fmt_out.p_extra = NULL;
+        p_dec->pf_packetize = ADTSPacketizeBlock;
     }
 
     return VLC_SUCCESS;
 }
 
 /****************************************************************************
- * RunFramePacketizer: the whole thing
+ * PacketizeBlock: the whole thing
  ****************************************************************************
  * This function must be fed with complete frames.
  ****************************************************************************/
-static int RunFramePacketizer( decoder_t *p_dec, block_t *p_block )
+static block_t *PacketizeBlock( decoder_t *p_dec, block_t **pp_block )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
+    block_t *p_block;
+
+    if( !pp_block || !*pp_block ) return NULL;
+
+    p_block = *pp_block;
 
     if( !aout_DateGet( &p_sys->end_date ) && !p_block->i_pts )
     {
         /* We've just started the stream, wait for the first PTS. */
         block_Release( p_block );
-        return VLC_SUCCESS;
+        return NULL;
     }
-
-    p_sys->pts = p_block->i_pts;
-    p_sys->i_frame_size = p_block->i_buffer;
-
-    if( GetSoutBuffer( p_dec, &p_sys->p_sout_buffer ) != VLC_SUCCESS )
+    else if( p_block->i_pts != 0 &&
+             p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
     {
-        return VLC_EGENERIC;
+        aout_DateSet( &p_sys->end_date, p_block->i_pts );
     }
 
-    /* Copy the whole frame into the buffer */
-    p_dec->p_vlc->pf_memcpy( p_sys->p_sout_buffer->p_buffer,
-                             p_block->p_buffer, p_block->i_buffer );
+    p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
 
-    sout_InputSendBuffer( p_sys->p_sout_input, p_sys->p_sout_buffer );
-    p_sys->p_sout_buffer = NULL;
+    p_block->i_length = aout_DateIncrement( &p_sys->end_date,
+        p_dec->fmt_out.audio.i_frame_length ) - p_block->i_pts;
 
-    block_Release( p_block );
-    return VLC_SUCCESS;
+    return *pp_block;
 }
 
 /****************************************************************************
- * RunADTSPacketizer: the whole thing
+ * DTSPacketizeBlock: the whole thing
  ****************************************************************************/
-static int RunADTSPacketizer( decoder_t *p_dec, block_t *p_block )
+static block_t *ADTSPacketizeBlock( decoder_t *p_dec, block_t **pp_block )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
     uint8_t p_header[ADTS_HEADER_SIZE];
+    void *p_out_buffer;
+    uint8_t *p_buf;
 
-    if( !aout_DateGet( &p_sys->end_date ) && !p_block->i_pts )
+    if( !pp_block || !*pp_block ) return NULL;
+
+    if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )
     {
         /* We've just started the stream, wait for the first PTS. */
-        block_Release( p_block );
-        return VLC_SUCCESS;
+        block_Release( *pp_block );
+        return NULL;
     }
 
-    if( p_block->b_discontinuity )
+    if( (*pp_block)->b_discontinuity )
     {
-        p_sys->i_state = STATE_SYNC;
+        p_sys->i_state = STATE_NOSYNC;
     }
 
-    if( p_sys->p_chain )
-    {
-        block_ChainAppend( &p_sys->p_chain, p_block );
-    }
-    else
-    {
-        block_ChainAppend( &p_sys->p_chain, p_block );
-        p_sys->bytestream = block_BytestreamInit( p_dec, p_sys->p_chain, 0 );
-    }
+    block_BytestreamPush( &p_sys->bytestream, *pp_block );
 
     while( 1 )
     {
@@ -295,27 +278,19 @@ static int RunADTSPacketizer( decoder_t *p_dec, block_t *p_block )
             }
             if( p_sys->i_state != STATE_SYNC )
             {
-                if( block_PeekByte( &p_sys->bytestream, p_header )
-                    == VLC_SUCCESS && p_header[0] == 0xff )
-                {
-                    /* Start of a sync word, need more data */
-                    return VLC_SUCCESS;
-                }
-
-                block_ChainRelease( p_sys->p_chain );
-                p_sys->p_chain = NULL;
+                block_BytestreamFlush( &p_sys->bytestream );
 
                 /* Need more data */
-                return VLC_SUCCESS;
+                return NULL;
             }
 
         case STATE_SYNC:
             /* New frame, set the Presentation Time Stamp */
-            p_sys->pts = p_sys->bytestream.p_block->i_pts;
-            if( p_sys->pts != 0 &&
-                p_sys->pts != aout_DateGet( &p_sys->end_date ) )
+            p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
+            if( p_sys->i_pts != 0 &&
+                p_sys->i_pts != aout_DateGet( &p_sys->end_date ) )
             {
-                aout_DateSet( &p_sys->end_date, p_sys->pts );
+                aout_DateSet( &p_sys->end_date, p_sys->i_pts );
             }
             p_sys->i_state = STATE_HEADER;
             break;
@@ -326,7 +301,7 @@ static int RunADTSPacketizer( decoder_t *p_dec, block_t *p_block )
                                  ADTS_HEADER_SIZE ) != VLC_SUCCESS )
             {
                 /* Need more data */
-                return VLC_SUCCESS;
+                return NULL;
             }
 
             /* Check if frame is valid and get frame info */
@@ -344,9 +319,9 @@ static int RunADTSPacketizer( decoder_t *p_dec, block_t *p_block )
                 break;
             }
 
-            p_sys->i_state = STATE_DATA;
+            p_sys->i_state = STATE_NEXT_SYNC;
 
-        case STATE_DATA:
+        case STATE_NEXT_SYNC:
             /* TODO: If p_block == NULL, flush the buffer without checking the
              * next sync word */
 
@@ -356,7 +331,7 @@ static int RunADTSPacketizer( decoder_t *p_dec, block_t *p_block )
                 != VLC_SUCCESS )
             {
                 /* Need more data */
-                return VLC_SUCCESS;
+                return NULL;
             }
 
             if( p_header[0] != 0xff || (p_header[1] & 0xf6) != 0xf0 )
@@ -368,125 +343,103 @@ static int RunADTSPacketizer( decoder_t *p_dec, block_t *p_block )
                 break;
             }
 
-            if( !p_sys->p_sout_buffer )
-            if( GetSoutBuffer( p_dec, &p_sys->p_sout_buffer ) != VLC_SUCCESS )
+            p_sys->i_state = STATE_SEND_DATA;
+            break;
+
+        case STATE_GET_DATA:
+            /* Make sure we have enough data.
+             * (Not useful if we went through NEXT_SYNC) */
+            if( block_WaitBytes( &p_sys->bytestream, p_sys->i_frame_size +
+                                 p_sys->i_header_size) != VLC_SUCCESS )
             {
-                return VLC_EGENERIC;
+                /* Need more data */
+                return NULL;
             }
+            p_sys->i_state = STATE_SEND_DATA;
 
-            /* Skip the ADTS header */
-            if( p_sys->i_header_size )
+        case STATE_SEND_DATA:
+            if( !(p_buf = GetOutBuffer( p_dec, &p_out_buffer )) )
             {
-                if( block_SkipBytes( &p_sys->bytestream,
-                                     p_sys->i_header_size ) != VLC_SUCCESS )
-                {
-                    /* Need more data */
-                    return VLC_SUCCESS;
-                }
-                p_sys->i_header_size = 0;
+                //p_dec->b_error = VLC_TRUE;
+                return NULL;
             }
 
+            /* When we reach this point we already know we have enough
+             * data available. */
+
+            /* Skip the ADTS header */
+            block_SkipBytes( &p_sys->bytestream, p_sys->i_header_size );
+
             /* Copy the whole frame into the buffer */
-            if( block_GetBytes( &p_sys->bytestream,
-                                p_sys->p_sout_buffer->p_buffer,
-                                p_sys->i_frame_size ) != VLC_SUCCESS )
-            {
-                /* Need more data */
-                return VLC_SUCCESS;
-            }
+            block_GetBytes( &p_sys->bytestream, p_buf, p_sys->i_frame_size );
 
-            p_sys->p_chain = block_BytestreamFlush( &p_sys->bytestream );
+            /* Make sure we don't reuse the same pts twice */
+            if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
+                p_sys->i_pts = p_sys->bytestream.p_block->i_pts = 0;
 
-            sout_InputSendBuffer( p_sys->p_sout_input, p_sys->p_sout_buffer );
+            /* So p_block doesn't get re-added several times */
+            *pp_block = block_BytestreamPop( &p_sys->bytestream );
 
             p_sys->i_state = STATE_NOSYNC;
-            p_sys->p_sout_buffer = NULL;
 
-            /* Make sure we don't reuse the same pts twice */
-            if( p_sys->pts == p_sys->bytestream.p_block->i_pts )
-                p_sys->pts = p_sys->bytestream.p_block->i_pts = 0;
+            return p_out_buffer;
         }
     }
 
-    return VLC_SUCCESS;
+    return NULL;
 }
 
 /*****************************************************************************
- * GetSoutBuffer:
+ * GetOutBuffer:
  *****************************************************************************/
-static int GetSoutBuffer( decoder_t *p_dec, sout_buffer_t **pp_buffer )
+static uint8_t *GetOutBuffer( decoder_t *p_dec, void **pp_out_buffer )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
+    block_t *p_block;
 
-    if( p_sys->p_sout_input != NULL &&
-        ( p_sys->sout_format.i_sample_rate != (int)p_sys->i_rate
-          || p_sys->sout_format.i_channels != (int)p_sys->i_channels ) )
-    {
-        /* Parameters changed - this should not happen. */
-    }
-
-    /* Creating the sout input if not created yet. */
-    if( p_sys->p_sout_input == NULL )
+    if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
     {
-        p_sys->sout_format.i_cat = AUDIO_ES;
-        p_sys->sout_format.i_fourcc = VLC_FOURCC( 'm', 'p', '4', 'a' );
-        p_sys->sout_format.i_sample_rate = p_sys->i_rate;
-        p_sys->sout_format.i_channels    = p_sys->i_channels;
-        p_sys->sout_format.i_block_align = 0;
-        p_sys->sout_format.i_bitrate     = 0;
-
-        aout_DateInit( &p_sys->end_date, p_sys->i_rate );
-        aout_DateSet( &p_sys->end_date, p_sys->pts );
-
-        p_sys->p_sout_input = sout_InputNew( p_dec, &p_sys->sout_format );
-        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, "AAC channels: %d samplerate: %d",
                   p_sys->i_channels, p_sys->i_rate );
-    }
 
-    *pp_buffer = sout_BufferNew( p_sys->p_sout_input->p_sout,
-                                 p_sys->i_frame_size );
-    if( *pp_buffer == NULL )
-    {
-        return VLC_EGENERIC;
+        aout_DateInit( &p_sys->end_date, p_sys->i_rate );
+        aout_DateSet( &p_sys->end_date, p_sys->i_pts );
     }
 
-    (*pp_buffer)->i_pts =
-        (*pp_buffer)->i_dts = aout_DateGet( &p_sys->end_date );
+    p_dec->fmt_out.audio.i_rate     = p_sys->i_rate;
+    p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
+    p_dec->fmt_out.audio.i_bytes_per_frame = p_sys->i_frame_size;
+    p_dec->fmt_out.audio.i_frame_length = p_sys->i_frame_length;
 
-    (*pp_buffer)->i_length =
-        aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length )
-        - (*pp_buffer)->i_pts;
+#if 0
+    p_dec->fmt_out.audio.i_original_channels = p_sys->i_channels_conf;
+    p_dec->fmt_out.audio.i_physical_channels =
+        p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
+#endif
 
-    return VLC_SUCCESS;
+    p_block = block_New( p_dec, p_sys->i_frame_size );
+    if( p_block == NULL ) return NULL;
+
+    p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
+
+    p_block->i_length = aout_DateIncrement( &p_sys->end_date,
+                            p_sys->i_frame_length ) - p_block->i_pts;
+
+    *pp_out_buffer = p_block;
+    return p_block->p_buffer;
 }
 
 /*****************************************************************************
- * EndPacketizer: clean up the packetizer
+ * ClosePacketizer: clean up the packetizer
  *****************************************************************************/
-static int EndPacketizer( decoder_t *p_dec )
+static void ClosePacketizer( vlc_object_t *p_this )
 {
-    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 );
-    }
+    decoder_t *p_dec = (decoder_t *)p_this;
+    decoder_sys_t *p_sys = p_dec->p_sys;
 
-    if( p_dec->p_sys->p_chain ) block_ChainRelease( p_dec->p_sys->p_chain );
+    block_BytestreamRelease( &p_sys->bytestream );
 
     free( p_dec->p_sys );
-
-    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
@@ -499,7 +452,6 @@ static int ADTSSyncInfo( decoder_t * p_dec, const byte_t * p_buf,
                          unsigned int * pi_header_size,
                          unsigned int * pi_raw_blocks_in_frame )
 {
-    decoder_sys_t *p_sys = p_dec->p_sys;
     int i_id, i_profile, i_sample_rate_idx, i_frame_size;
     vlc_bool_t b_crc;
 
@@ -525,13 +477,13 @@ static int ADTSSyncInfo( decoder_t * p_dec, const byte_t * p_buf,
     *pi_frame_length = 1024;
 
     /* Build the decoder specific info header */
-    if( !p_dec->p_sys->sout_format.i_extra_data )
+    if( !p_dec->fmt_out.i_extra )
     {
-        p_sys->sout_format.i_extra_data = 2;
-        p_sys->sout_format.p_extra_data = malloc( 2 );
-        p_sys->sout_format.p_extra_data[0] =
+        p_dec->fmt_out.i_extra = 2;
+        p_dec->fmt_out.p_extra = malloc( 2 );
+        ((uint8_t *)p_dec->fmt_out.p_extra)[0] =
             (i_profile + 1) << 3 | (i_sample_rate_idx >> 1);
-        p_sys->sout_format.p_extra_data[1] =
+        ((uint8_t *)p_dec->fmt_out.p_extra)[1] =
             ((i_sample_rate_idx & 0x01) << 7) | (*pi_channels <<3);
     }
 
index a693e403478bd15cabb9a19f3ba2c342a4c0f4bf..745433a0e988de931cd69e0d68b1cce4519f6496 100644 (file)
@@ -2,7 +2,7 @@
  * transcode.c
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: transcode.c,v 1.49 2003/11/05 18:59:01 gbazin Exp $
+ * $Id: transcode.c,v 1.50 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Gildas Bazin <gbazin@netcourrier.com>
@@ -598,6 +598,39 @@ static inline int get_ff_chroma( vlc_fourcc_t i_chroma )
     }
 }
 
+static inline vlc_fourcc_t get_vlc_chroma( int i_pix_fmt )
+{
+    switch( i_pix_fmt )
+    {
+    case PIX_FMT_YUV420P:
+        return VLC_FOURCC('I','4','2','0');
+    case PIX_FMT_YUV422P:
+        return VLC_FOURCC('I','4','2','2');
+    case PIX_FMT_YUV444P:
+        return VLC_FOURCC('I','4','4','4');
+
+    case PIX_FMT_YUV422:
+        return VLC_FOURCC('Y','U','Y','2');
+
+    case PIX_FMT_RGB555:
+        return VLC_FOURCC('R','V','1','5');
+    case PIX_FMT_RGB565:
+        return VLC_FOURCC('R','V','1','6');
+    case PIX_FMT_RGB24:
+        return VLC_FOURCC('R','V','2','4');
+    case PIX_FMT_RGBA32:
+        return VLC_FOURCC('R','V','3','2');
+    case PIX_FMT_GRAY8:
+        return VLC_FOURCC('G','R','E','Y');
+
+    case PIX_FMT_YUV410P:
+    case PIX_FMT_YUV411P:
+    case PIX_FMT_BGR24:
+    default:
+        return 0;
+    }
+}
+
 static int transcode_audio_ffmpeg_new( sout_stream_t *p_stream,
                                        sout_stream_id_t *id )
 {
@@ -657,18 +690,22 @@ static int transcode_audio_ffmpeg_new( sout_stream_t *p_stream,
 
     /* find encoder */
     id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
-    id->p_encoder->i_fourcc = id->f_dst.i_fourcc;
-    id->p_encoder->format.audio.i_format = AOUT_FMT_S16_NE;
-    id->p_encoder->format.audio.i_rate = id->f_dst.i_sample_rate;
-    id->p_encoder->format.audio.i_physical_channels =
-        id->p_encoder->format.audio.i_original_channels =
+
+    /* Initialization of encoder format structures */
+    es_format_Init( &id->p_encoder->fmt_in, AUDIO_ES, AOUT_FMT_S16_NE );
+    id->p_encoder->fmt_in.audio.i_format = AOUT_FMT_S16_NE;
+    id->p_encoder->fmt_in.audio.i_rate = id->f_dst.i_sample_rate;
+    id->p_encoder->fmt_in.audio.i_physical_channels =
+        id->p_encoder->fmt_in.audio.i_original_channels =
             pi_channels_maps[id->f_dst.i_channels];
-    id->p_encoder->i_bitrate = id->f_dst.i_bitrate;
-    id->p_encoder->i_extra_data = 0;
-    id->p_encoder->p_extra_data = NULL;
+    id->p_encoder->fmt_in.audio.i_channels = id->f_dst.i_channels;
+
+    id->p_encoder->fmt_out = id->p_encoder->fmt_in;
+    id->p_encoder->fmt_out.i_codec = id->f_dst.i_fourcc;
+    id->p_encoder->fmt_out.i_bitrate = id->f_dst.i_bitrate;
 
     id->p_encoder->p_module =
-        module_Need( id->p_encoder, "audio encoder", NULL );
+        module_Need( id->p_encoder, "encoder", NULL );
     if( !id->p_encoder->p_module )
     {
         vlc_object_destroy( id->p_encoder );
@@ -678,8 +715,8 @@ static int transcode_audio_ffmpeg_new( sout_stream_t *p_stream,
 
     id->b_enc_inited = VLC_FALSE;
 
-    id->f_dst.i_extra_data = id->p_encoder->i_extra_data;
-    id->f_dst.p_extra_data = id->p_encoder->p_extra_data;
+    id->f_dst.i_extra_data = id->p_encoder->fmt_out.i_extra;
+    id->f_dst.p_extra_data = id->p_encoder->fmt_out.p_extra;
 
     /* Hack for mp3 transcoding support */
     if( id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','3',' ' ) )
@@ -953,64 +990,65 @@ static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
 
     /* Open encoder */
     id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
-    id->p_encoder->i_fourcc = id->f_dst.i_fourcc;
-    id->p_encoder->format.video.i_width = p_sys->i_width;
-    id->p_encoder->format.video.i_height = p_sys->i_height;
-    id->p_encoder->i_bitrate = p_sys->i_vbitrate;
 
-    id->p_encoder->i_vtolerance = p_sys->i_vtolerance;
-    id->p_encoder->i_key_int = p_sys->i_key_int;
-    id->p_encoder->i_b_frames = p_sys->i_b_frames;
-    id->p_encoder->i_qmin = p_sys->i_qmin;
-    id->p_encoder->i_qmax = p_sys->i_qmax;
-    id->p_encoder->i_hq = p_sys->i_hq;
+    /* Initialization of encoder format structures */
+    es_format_Init( &id->p_encoder->fmt_in,
+                   id->f_src.i_cat, get_vlc_chroma(id->ff_dec_c->pix_fmt) );
+
+    id->p_encoder->fmt_in.video.i_width = id->f_dst.i_width;
+    id->p_encoder->fmt_in.video.i_height = id->f_dst.i_height;
 
-    if( id->p_encoder->format.video.i_width <= 0 )
+    if( id->p_encoder->fmt_in.video.i_width <= 0 )
     {
-        id->p_encoder->format.video.i_width = id->f_dst.i_width =
+        id->p_encoder->fmt_in.video.i_width = id->f_dst.i_width =
             id->ff_dec_c->width - p_sys->i_crop_left - p_sys->i_crop_right;
     }
-    if( id->p_encoder->format.video.i_height <= 0 )
+    if( id->p_encoder->fmt_in.video.i_height <= 0 )
     {
-        id->p_encoder->format.video.i_height = id->f_dst.i_height =
+        id->p_encoder->fmt_in.video.i_height = id->f_dst.i_height =
             id->ff_dec_c->height - p_sys->i_crop_top - p_sys->i_crop_bottom;
     }
 
-    id->p_ff_pic         = avcodec_alloc_frame();
-    id->p_ff_pic_tmp0    = NULL;
-    id->p_ff_pic_tmp1    = NULL;
-    id->p_ff_pic_tmp2    = NULL;
-    id->p_vresample      = NULL;
-
+    id->p_encoder->fmt_in.video.i_frame_rate = 25; /* FIXME as it break mpeg */
+    id->p_encoder->fmt_in.video.i_frame_rate_base= 1;
     if( id->ff_dec )
     {
-        id->p_encoder->i_frame_rate = id->ff_dec_c->frame_rate;
+        id->p_encoder->fmt_in.video.i_frame_rate = id->ff_dec_c->frame_rate;
 #if LIBAVCODEC_BUILD >= 4662
-        id->p_encoder->i_frame_rate_base= id->ff_dec_c->frame_rate_base;
+        id->p_encoder->fmt_in.video.i_frame_rate_base =
+            id->ff_dec_c->frame_rate_base;
 #endif
 
 #if LIBAVCODEC_BUILD >= 4687
-        id->p_encoder->i_aspect = VOUT_ASPECT_FACTOR *
+        id->p_encoder->fmt_in.video.i_aspect = VOUT_ASPECT_FACTOR *
             ( av_q2d(id->ff_dec_c->sample_aspect_ratio) *
               id->ff_dec_c->width / id->ff_dec_c->height );
 #else
-        id->p_encoder->i_aspect = VOUT_ASPECT_FACTOR *
+        id->p_encoder->video.fmt_in.i_aspect = VOUT_ASPECT_FACTOR *
             id->ff_dec_c->aspect_ratio;
 #endif
 
     }
-    else
-    {
-#if LIBAVCODEC_BUILD >= 4662
-        id->p_encoder->i_frame_rate     = 25 ; /* FIXME as it break mpeg */
-        id->p_encoder->i_frame_rate_base= 1;
-#else
-        id->p_encoder->i_frame_rate     = 25 * FRAME_RATE_BASE;
-#endif
-    }
+
+    id->p_encoder->fmt_out = id->p_encoder->fmt_in;
+    id->p_encoder->fmt_out.i_codec = id->f_dst.i_fourcc;
+    id->p_encoder->fmt_out.i_bitrate = id->f_dst.i_bitrate;
+
+    id->p_encoder->i_vtolerance = p_sys->i_vtolerance;
+    id->p_encoder->i_key_int = p_sys->i_key_int;
+    id->p_encoder->i_b_frames = p_sys->i_b_frames;
+    id->p_encoder->i_qmin = p_sys->i_qmin;
+    id->p_encoder->i_qmax = p_sys->i_qmax;
+    id->p_encoder->i_hq = p_sys->i_hq;
+
+    id->p_ff_pic         = avcodec_alloc_frame();
+    id->p_ff_pic_tmp0    = NULL;
+    id->p_ff_pic_tmp1    = NULL;
+    id->p_ff_pic_tmp2    = NULL;
+    id->p_vresample      = NULL;
 
     id->p_encoder->p_module =
-        module_Need( id->p_encoder, "video encoder", NULL );
+        module_Need( id->p_encoder, "encoder", NULL );
 
     if( !id->p_encoder->p_module )
     {
@@ -1138,26 +1176,26 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
         {
             /* XXX hack because of copy packetizer and mpeg4video that can fail
              * detecting size */
-            if( id->p_encoder->format.video.i_width <= 0 )
+            if( id->p_encoder->fmt_in.video.i_width <= 0 )
             {
-                id->p_encoder->format.video.i_width = id->f_dst.i_width =
+                id->p_encoder->fmt_in.video.i_width =
+                  id->p_encoder->fmt_out.video.i_width = id->f_dst.i_width =
                     id->ff_dec_c->width - p_sys->i_crop_left -
-                    p_sys->i_crop_right;
+                      p_sys->i_crop_right;
             }
-            if( id->p_encoder->format.video.i_height <= 0 )
+            if( id->p_encoder->fmt_in.video.i_height <= 0 )
             {
-                id->p_encoder->format.video.i_height = id->f_dst.i_height =
+                id->p_encoder->fmt_in.video.i_height =
+                  id->p_encoder->fmt_out.video.i_height = id->f_dst.i_height =
                     id->ff_dec_c->height - p_sys->i_crop_top -
-                    p_sys->i_crop_bottom;
+                      p_sys->i_crop_bottom;
             }
 
-            id->p_encoder->i_bitrate = p_sys->i_vbitrate;
-
-            id->p_encoder->i_extra_data = 0;
-            id->p_encoder->p_extra_data = NULL;
+            id->p_encoder->fmt_out.i_extra = 0;
+            id->p_encoder->fmt_out.p_extra = NULL;
 
             id->p_encoder->p_module =
-                module_Need( id->p_encoder, "video encoder", NULL );
+                module_Need( id->p_encoder, "encoder", NULL );
             if( !id->p_encoder->p_module )
             {
                 vlc_object_destroy( id->p_encoder );
@@ -1165,8 +1203,8 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
                 return VLC_EGENERIC;
             }
 
-            id->f_dst.i_extra_data = id->p_encoder->i_extra_data;
-            id->f_dst.p_extra_data = id->p_encoder->p_extra_data;
+            id->f_dst.i_extra_data = id->p_encoder->fmt_out.i_extra;
+            id->f_dst.p_extra_data = id->p_encoder->fmt_out.p_extra;
 
             /* Hack for mp2v/mp1v transcoding support */
             if( id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','1','v' ) ||
@@ -1198,7 +1236,7 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
             }
 
             id->i_inter_pixfmt =
-                get_ff_chroma( id->p_encoder->format.video.i_chroma );
+                get_ff_chroma( id->p_encoder->fmt_in.i_codec );
 
             id->b_enc_inited = VLC_TRUE;
         }
@@ -1293,7 +1331,7 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
 
         /* Encoding */
         vout_InitPicture( VLC_OBJECT(p_stream), &pic,
-                          id->p_encoder->format.video.i_chroma,
+                          id->p_encoder->fmt_in.i_codec,
                           id->f_dst.i_width, id->f_dst.i_height,
                           id->f_dst.i_width * VOUT_ASPECT_FACTOR /
                           id->f_dst.i_height );
index c86b8158d7b12b6234773abd5fa6866985411385..edae9e99d9fc33720254fcf99fc8c2a0dfa9f302 100644 (file)
@@ -2,7 +2,7 @@
  * common.c : audio output management of common data structures
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: common.c,v 1.17 2003/02/11 11:16:04 massiot Exp $
+ * $Id: common.c,v 1.18 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -66,8 +66,6 @@ aout_instance_t * __aout_New( vlc_object_t * p_parent )
     val.b_bool = VLC_TRUE;
     var_Set( p_aout, "intf-change", val );
 
-    vlc_object_attach( p_aout, p_parent->p_vlc );
-
     return p_aout;
 }
 
index 0480c6b69a519a981faa8fac6316369aed748080..377d2b9fd362b5756e36aca35ea37094f3173b37 100644 (file)
@@ -2,7 +2,7 @@
  * dec.c : audio output API towards decoders
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: dec.c,v 1.12 2003/10/27 21:54:10 gbazin Exp $
+ * $Id: dec.c,v 1.13 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -164,6 +164,7 @@ aout_input_t * __aout_DecNew( vlc_object_t * p_this,
             {
                 return NULL;
             }
+            vlc_object_attach( *pp_aout, p_this->p_vlc );
         }
         else
         {
index 2690647b16455a7e17fd7d16429105005404d79c..7fa827c8a6be2fe6be59cbe06382ffe76cddf87c 100644 (file)
@@ -4,7 +4,7 @@
  * decoders.
  *****************************************************************************
  * Copyright (C) 1998-2002 VideoLAN
- * $Id: input.c,v 1.254 2003/11/13 13:31:12 fenrir Exp $
+ * $Id: input.c,v 1.255 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -981,6 +981,7 @@ struct es_out_sys_t
     vlc_bool_t  i_audio;
     vlc_bool_t  i_video;
 };
+
 struct es_out_id_t
 {
     es_descriptor_t *p_es;
@@ -1008,6 +1009,7 @@ static es_out_t *EsOutCreate( input_thread_t *p_input )
     out->p_sys->i_video = -1;
     return out;
 }
+
 static void      EsOutRelease( es_out_t *out )
 {
     es_out_sys_t *p_sys = out->p_sys;
@@ -1065,11 +1067,12 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
     {
         case AUDIO_ES:
         {
-            WAVEFORMATEX *p_wf = malloc( sizeof( WAVEFORMATEX ) + fmt->i_extra);
+            WAVEFORMATEX *p_wf =
+                malloc( sizeof( WAVEFORMATEX ) + fmt->i_extra);
 
             p_wf->wFormatTag        = WAVE_FORMAT_UNKNOWN;
             p_wf->nChannels         = fmt->audio.i_channels;
-            p_wf->nSamplesPerSec    = fmt->audio.i_samplerate;
+            p_wf->nSamplesPerSec    = fmt->audio.i_rate;
             p_wf->nAvgBytesPerSec   = fmt->audio.i_bitrate / 8;
             p_wf->nBlockAlign       = fmt->audio.i_blockalign;
             p_wf->wBitsPerSample    = fmt->audio.i_bitspersample;
@@ -1078,7 +1081,7 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
             {
                 if( fmt->i_extra_type != ES_EXTRA_TYPE_WAVEFORMATEX )
                 {
-                    msg_Warn( p_input, "extra type != WAVEFORMATEX for audio" );
+                    msg_Warn( p_input, "extra type != WAVEFORMATEX for audio");
                 }
                 memcpy( &p_wf[1], fmt->p_extra, fmt->i_extra );
             }
@@ -1095,7 +1098,8 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
             p_bih->biPlanes         = 1;
             p_bih->biBitCount       = 24;
             p_bih->biCompression    = fmt->i_codec;
-            p_bih->biSizeImage      = fmt->video.i_width * fmt->video.i_height;
+            p_bih->biSizeImage      = fmt->video.i_width *
+                                          fmt->video.i_height;
             p_bih->biXPelsPerMeter  = 0;
             p_bih->biYPelsPerMeter  = 0;
             p_bih->biClrUsed        = 0;
@@ -1166,39 +1170,50 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
         {
             case AUDIO_ES:
                 input_AddInfo( p_cat, _("Type"), _("Audio") );
-                input_AddInfo( p_cat, _("Codec"), "%.4s", (char*)&fmt->i_codec );
+                input_AddInfo( p_cat, _("Codec"), "%.4s",
+                               (char*)&fmt->i_codec );
                 if( fmt->audio.i_channels > 0 )
                 {
-                    input_AddInfo( p_cat, _("Channels"), "%d", fmt->audio.i_channels );
+                    input_AddInfo( p_cat, _("Channels"), "%d",
+                                   fmt->audio.i_channels );
                 }
-                if( fmt->audio.i_samplerate > 0 )
+                if( fmt->audio.i_rate > 0 )
                 {
-                    input_AddInfo( p_cat, _("Sample Rate"), "%d", fmt->audio.i_samplerate );
+                    input_AddInfo( p_cat, _("Sample Rate"), "%d",
+                                   fmt->audio.i_rate );
                 }
                 if( fmt->audio.i_bitrate > 0 )
                 {
-                    input_AddInfo( p_cat, _("Bitrate"), "%d", fmt->audio.i_bitrate );
+                    input_AddInfo( p_cat, _("Bitrate"), "%d",
+                                   fmt->audio.i_bitrate );
                 }
                 if( fmt->audio.i_bitspersample )
                 {
-                    input_AddInfo( p_cat, _("Bits Per Sample"), "%d", fmt->audio.i_bitspersample );
+                    input_AddInfo( p_cat, _("Bits Per Sample"), "%d",
+                                   fmt->audio.i_bitspersample );
                 }
                 break;
             case VIDEO_ES:
                 input_AddInfo( p_cat, _("Type"), _("Video") );
-                input_AddInfo( p_cat, _("Codec"), "%.4s", (char*)&fmt->i_codec );
+                input_AddInfo( p_cat, _("Codec"), "%.4s",
+                               (char*)&fmt->i_codec );
                 if( fmt->video.i_width > 0 && fmt->video.i_height > 0 )
                 {
-                    input_AddInfo( p_cat, _("Resolution"), "%dx%d", fmt->video.i_width, fmt->video.i_height );
+                    input_AddInfo( p_cat, _("Resolution"), "%dx%d",
+                                   fmt->video.i_width, fmt->video.i_height );
                 }
-                if( fmt->video.i_display_width > 0 && fmt->video.i_display_height > 0 )
+                if( fmt->video.i_visible_width > 0 &&
+                    fmt->video.i_visible_height > 0 )
                 {
-                    input_AddInfo( p_cat, _("Display Resolution"), "%dx%d", fmt->video.i_display_width, fmt->video.i_display_height);
+                    input_AddInfo( p_cat, _("Display Resolution"), "%dx%d",
+                                   fmt->video.i_visible_width,
+                                   fmt->video.i_visible_height);
                 }
                 break;
             case SPU_ES:
                 input_AddInfo( p_cat, _("Type"), _("Subtitle") );
-                input_AddInfo( p_cat, _("Codec"), "%.4s", (char*)&fmt->i_codec );
+                input_AddInfo( p_cat, _("Codec"), "%.4s",
+                               (char*)&fmt->i_codec );
                 break;
             default:
 
@@ -1207,9 +1222,12 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
     }
     vlc_mutex_unlock( &p_input->stream.stream_lock );
 
+    id->p_es->fmt = *fmt;
+
     TAB_APPEND( out->p_sys->i_id, out->p_sys->id, id );
     return id;
 }
+
 static int EsOutSend( es_out_t *out, es_out_id_t *id, pes_packet_t *p_pes )
 {
     if( id->p_es->p_decoder_fifo )
@@ -1222,6 +1240,7 @@ static int EsOutSend( es_out_t *out, es_out_id_t *id, pes_packet_t *p_pes )
     }
     return VLC_SUCCESS;
 }
+
 static void EsOutDel( es_out_t *out, es_out_id_t *id )
 {
     es_out_sys_t *p_sys = out->p_sys;
@@ -1248,6 +1267,7 @@ static void EsOutDel( es_out_t *out, es_out_id_t *id )
 
     free( id );
 }
+
 static int EsOutControl( es_out_t *out, int i_query, va_list args )
 {
     es_out_sys_t *p_sys = out->p_sys;
@@ -1306,8 +1326,8 @@ static int PositionCallback( vlc_object_t *p_this, char const *psz_cmd,
 
     vlc_mutex_lock( &p_input->stream.stream_lock );
     p_input->stream.p_selected_area->i_seek =
-                    (int64_t)( newval.f_float *
-                               (double)p_input->stream.p_selected_area->i_size );
+        (int64_t)( newval.f_float *
+                   (double)p_input->stream.p_selected_area->i_size );
 
     if( p_input->stream.p_selected_area->i_seek < 0 )
     {
index 83000f429dcda57c3c54d7498df228e6bf1a39ef..1cc012c2e643853fa2154209249dbd05941d6db6 100644 (file)
@@ -2,9 +2,10 @@
  * input_dec.c: Functions for the management of decoders
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: input_dec.c,v 1.66 2003/11/06 16:36:41 nitrox Exp $
+ * $Id: input_dec.c,v 1.67 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
+ *          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/vout.h>
+
+#include "stream_output.h"
 
 #include "input_ext-intf.h"
 #include "input_ext-plugins.h"
 
+#include "codecs.h"
+
 static decoder_t * CreateDecoder( input_thread_t *, es_descriptor_t *, int );
 static int         DecoderThread( decoder_t * );
 static void        DeleteDecoder( decoder_t * );
 
+/* Buffers allocation callbacks for the decoders */
+static aout_buffer_t *aout_new_buffer( decoder_t *, int );
+static void aout_del_buffer( decoder_t *, aout_buffer_t * );
+
+static picture_t *vout_new_buffer( decoder_t * );
+static void vout_del_buffer( decoder_t *, picture_t * );
+
+static es_format_t null_es_format = {0};
+
 /*****************************************************************************
  * input_RunDecoder: spawns a new decoder thread
  *****************************************************************************/
@@ -280,13 +295,27 @@ void input_EscapeAudioDiscontinuity( input_thread_t * p_input )
     }
 }
 
+struct decoder_owner_sys_t
+{
+    aout_instance_t *p_aout;
+    aout_input_t    *p_aout_input;
+
+    vout_thread_t   *p_vout;
+
+    sout_packetizer_input_t *p_sout;
+
+    /* Current format in use by the output */
+    video_format_t video;
+    audio_format_t audio; 
+};
+
 /*****************************************************************************
- * CreateDecoderFifo: create a decoder_fifo_t
+ * CreateDecoder: create a decoder object
  *****************************************************************************/
 static decoder_t * CreateDecoder( input_thread_t * p_input,
                                   es_descriptor_t * p_es, int i_object_type )
 {
-    decoder_t * p_dec;
+    decoder_t *p_dec;
 
     p_dec = vlc_object_create( p_input, i_object_type );
     if( p_dec == NULL )
@@ -295,9 +324,11 @@ static decoder_t * CreateDecoder( input_thread_t * p_input,
         return NULL;
     }
 
-    p_dec->pf_init = 0;
     p_dec->pf_decode = 0;
-    p_dec->pf_end = 0;
+    p_dec->pf_decode_audio = 0;
+    p_dec->pf_decode_video = 0;
+    p_dec->pf_decode_sub = 0;
+    p_dec->pf_packetize = 0;
     p_dec->pf_run = 0;
 
     /* Select a new ES */
@@ -307,7 +338,6 @@ static decoder_t * CreateDecoder( input_thread_t * p_input,
                  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 )
     {
@@ -316,14 +346,69 @@ static decoder_t * CreateDecoder( input_thread_t * p_input,
     }
 
     /* Initialize the decoder fifo */
-    //memset( p_dec->p_fifo, 0, sizeof(decoder_fifo_t) );
     p_dec->p_module = NULL;
 
-    /* Initialize the p_fifo structure */
+    p_dec->fmt_in = p_es->fmt;
+
+    if( p_es->p_waveformatex )
+    {
+#define p_wf ((WAVEFORMATEX *)p_es->p_waveformatex)
+        p_dec->fmt_in.audio.i_channels = p_wf->nChannels;
+        p_dec->fmt_in.audio.i_rate = p_wf->nSamplesPerSec;
+        p_dec->fmt_in.i_bitrate = p_wf->nAvgBytesPerSec * 8;
+        p_dec->fmt_in.audio.i_blockalign = p_wf->nBlockAlign;
+        p_dec->fmt_in.audio.i_bitspersample = p_wf->wBitsPerSample;
+        p_dec->fmt_in.i_extra = p_wf->cbSize;
+        p_dec->fmt_in.p_extra = NULL;
+        if( p_wf->cbSize )
+        {
+            p_dec->fmt_in.p_extra = malloc( p_wf->cbSize );
+            memcpy( p_dec->fmt_in.p_extra, &p_wf[1], p_wf->cbSize );
+        }
+    }
+
+    if( p_es->p_bitmapinfoheader )
+    {
+#define p_bih ((BITMAPINFOHEADER *) p_es->p_bitmapinfoheader)
+        p_dec->fmt_in.i_extra = p_bih->biSize - sizeof(BITMAPINFOHEADER);
+        p_dec->fmt_in.p_extra = NULL;
+        if( p_dec->fmt_in.i_extra )
+        {
+            p_dec->fmt_in.p_extra = malloc( p_dec->fmt_in.i_extra );
+            memcpy( p_dec->fmt_in.p_extra, &p_bih[1], p_dec->fmt_in.i_extra );
+        }
+
+        p_dec->fmt_in.video.i_width = p_bih->biWidth;
+        p_dec->fmt_in.video.i_height = p_bih->biHeight;
+    }
+
+    p_dec->fmt_in.i_cat = p_es->i_cat;
+    p_dec->fmt_in.i_codec = p_es->i_fourcc;
+
+    p_dec->fmt_out = null_es_format;
+
+    /* Allocate our private structure for the decoder */
+    p_dec->p_owner = (decoder_owner_sys_t*)malloc(sizeof(decoder_owner_sys_t));
+    if( p_dec->p_owner == NULL )
+    {
+        msg_Err( p_dec, "out of memory" );
+        return NULL;
+    }
+    p_dec->p_owner->p_aout = NULL;
+    p_dec->p_owner->p_aout_input = NULL;
+    p_dec->p_owner->p_vout = NULL;
+    p_dec->p_owner->p_sout = NULL;
+
+    /* Set buffers allocation callbacks for the decoders */
+    p_dec->pf_aout_buffer_new = aout_new_buffer;
+    p_dec->pf_aout_buffer_del = aout_del_buffer;
+    p_dec->pf_vout_buffer_new = vout_new_buffer;
+    p_dec->pf_vout_buffer_del = vout_del_buffer;
+
+    /* For old decoders only */
     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;
@@ -332,16 +417,14 @@ static decoder_t * CreateDecoder( input_thread_t * p_input,
     p_dec->p_fifo->p_spuinfo = p_es->p_spuinfo;
     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;
@@ -363,10 +446,6 @@ static int DecoderThread( decoder_t * p_dec )
         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 )
     {
@@ -398,30 +477,93 @@ static int DecoderThread( decoder_t * p_dec )
         p_block->i_pts = p_pes->i_pts;
         p_block->i_dts = p_pes->i_dts;
         p_block->b_discontinuity = p_pes->b_discontinuity;
-        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( p_dec->i_object_type == VLC_OBJECT_PACKETIZER )
+        {
+            sout_buffer_t *p_sout_buffer;
+            block_t *p_sout_block;
 
-    /* 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 )
+            while( (p_sout_block = p_dec->pf_packetize( p_dec, &p_block )) )
+            {
+                if( !p_dec->p_owner->p_sout )
+                {
+                    sout_format_t sout_format;
+
+                    sout_format.i_cat = p_dec->fmt_out.i_cat;
+                    sout_format.i_fourcc = p_dec->fmt_out.i_codec;
+                    sout_format.i_sample_rate =
+                        p_dec->fmt_out.audio.i_rate;
+                    sout_format.i_channels =
+                        p_dec->fmt_out.audio.i_channels;
+                    sout_format.i_width  =
+                        p_dec->fmt_out.video.i_width;
+                    sout_format.i_height =
+                        p_dec->fmt_out.video.i_height;
+                    sout_format.i_block_align = 0;
+                    //sout_format.i_bitrate     = p_dec->fmt_out.i_bit_rate;
+                    sout_format.i_extra_data  = p_dec->fmt_out.i_extra;
+                    sout_format.p_extra_data  = p_dec->fmt_out.p_extra;
+
+                    p_dec->p_owner->p_sout =
+                        sout_InputNew( p_dec, &sout_format );
+
+                    if( p_dec->p_owner->p_sout == NULL )
+                    {
+                        msg_Err( p_dec, "cannot create packetizer output" );
+                        break;
+                    }
+                }
+
+                p_sout_buffer =
+                    sout_BufferNew( p_dec->p_owner->p_sout->p_sout,
+                                    p_sout_block->i_buffer );
+                if( p_sout_buffer == NULL )
+                {
+                    msg_Err( p_dec, "cannot get sout buffer" );
+                    break;
+                }
+
+                memcpy( p_sout_buffer->p_buffer, p_sout_block->p_buffer,
+                        p_sout_block->i_buffer );
+
+                p_sout_buffer->i_pts = p_sout_block->i_pts;
+                p_sout_buffer->i_dts = p_sout_block->i_dts;
+                p_sout_buffer->i_length = p_sout_block->i_length;
+
+                block_Release( p_sout_block );
+
+                sout_InputSendBuffer( p_dec->p_owner->p_sout, p_sout_buffer );
+            }
+        }
+        else if( p_dec->fmt_in.i_cat == AUDIO_ES )
         {
-            /* Trash all received PES packets */
-            input_ExtractPES( p_dec->p_fifo, NULL );
+            aout_buffer_t *p_aout_buf;
+
+            while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, &p_block )) )
+            {
+                aout_DecPlay( p_dec->p_owner->p_aout,
+                              p_dec->p_owner->p_aout_input, p_aout_buf );
+            }
         }
-    }
+        else
+        {
+            picture_t *p_pic;
 
-    /* End of the decoder */
-    p_dec->pf_end( p_dec );
+            while( (p_pic = p_dec->pf_decode_video( p_dec, &p_block )) )
+            {
+                vout_DatePicture( p_dec->p_owner->p_vout, p_pic, p_pic->date );
+                vout_DisplayPicture( p_dec->p_owner->p_vout, p_pic );
+            }
+        }
+
+        input_DeletePES( p_dec->p_fifo->p_packets_mgt, p_pes );
+    }
 
     return 0;
 }
 
 /*****************************************************************************
- * DeleteDecoderFifo: destroy a decoder_fifo_t
+ * DeleteDecoder: destroys a decoder object
  *****************************************************************************/
 static void DeleteDecoder( decoder_t * p_dec )
 {
@@ -443,5 +585,135 @@ static void DeleteDecoder( decoder_t * p_dec )
 
     /* Free fifo */
     vlc_object_destroy( p_dec->p_fifo );
-    //free( p_dec->p_fifo );
+
+    /* Cleanup */
+    if( p_dec->p_owner->p_aout_input )
+        aout_DecDelete( p_dec->p_owner->p_aout, p_dec->p_owner->p_aout_input );
+
+    if( p_dec->p_owner->p_vout )
+    {
+        int i_pic;
+
+        /* Hack to make sure all the the pictures are freed by the decoder */
+        for( i_pic = 0; i_pic < p_dec->p_owner->p_vout->render.i_pictures;
+             i_pic++ )
+        {
+            if( p_dec->p_owner->p_vout->render.pp_picture[i_pic]->i_status ==
+                RESERVED_PICTURE )
+                vout_DestroyPicture( p_dec->p_owner->p_vout,
+                    p_dec->p_owner->p_vout->render.pp_picture[i_pic] );
+            if( p_dec->p_owner->p_vout->render.pp_picture[i_pic]->i_refcount
+                > 0 )
+                vout_UnlinkPicture( p_dec->p_owner->p_vout,
+                    p_dec->p_owner->p_vout->render.pp_picture[i_pic] );
+        }
+
+        /* We are about to die. Reattach video output to p_vlc. */
+        vout_Request( p_dec, p_dec->p_owner->p_vout, 0, 0, 0, 0 );
+    }
+
+    if( p_dec->p_owner->p_sout )
+        sout_InputDelete( p_dec->p_owner->p_sout );
+
+    free( p_dec->p_owner );
+
+}
+
+/*****************************************************************************
+ * Buffers allocation callbacks for the decoders
+ *****************************************************************************/
+static aout_buffer_t *aout_new_buffer( decoder_t *p_dec, int i_samples )
+{
+    decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;
+    aout_buffer_t *p_buffer;
+
+    if( p_sys->p_aout_input != NULL &&
+        ( p_dec->fmt_out.audio.i_rate != p_sys->audio.i_rate ||
+          p_dec->fmt_out.audio.i_original_channels !=
+              p_sys->audio.i_original_channels ||
+          p_dec->fmt_out.audio.i_bytes_per_frame !=
+              p_sys->audio.i_bytes_per_frame ) )
+    {
+        /* Parameters changed, restart the aout */
+        aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
+        p_sys->p_aout_input = NULL;
+    }
+
+    if( p_sys->p_aout_input == NULL )
+    {
+        p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;
+        p_sys->audio = p_dec->fmt_out.audio;
+        p_sys->p_aout_input =
+            aout_DecNew( p_dec, &p_sys->p_aout, &p_sys->audio );
+        if( p_sys->p_aout_input == NULL )
+        {
+            msg_Err( p_dec, "failed to create audio output" );
+            return NULL;
+        }
+        p_dec->fmt_out.audio.i_bytes_per_frame =
+            p_sys->audio.i_bytes_per_frame;
+    }
+
+    p_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
+                                  i_samples );
+
+    return p_buffer;
+}
+
+static void aout_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
+{
+    aout_DecDeleteBuffer( p_dec->p_owner->p_aout,
+                          p_dec->p_owner->p_aout_input, p_buffer );
+}
+
+static picture_t *vout_new_buffer( decoder_t *p_dec )
+{
+    decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;
+    picture_t *p_pic;
+
+    if( p_sys->p_vout == NULL ||
+        p_dec->fmt_out.video.i_width != p_sys->video.i_width ||
+        p_dec->fmt_out.video.i_height != p_sys->video.i_height ||
+        p_dec->fmt_out.video.i_chroma != p_sys->video.i_chroma ||
+        p_dec->fmt_out.video.i_aspect != p_sys->video.i_aspect )
+    {
+        if( !p_dec->fmt_out.video.i_width ||
+            !p_dec->fmt_out.video.i_height )
+        {
+            /* Can't create a new vout without display size */
+            return NULL;
+        }
+
+        p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
+        p_sys->video = p_dec->fmt_out.video;
+
+        p_sys->p_vout = vout_Request( p_dec, p_sys->p_vout,
+                                      p_sys->video.i_width,
+                                      p_sys->video.i_height,
+                                      p_sys->video.i_chroma,
+                                      p_sys->video.i_aspect );
+
+        if( p_sys->p_vout == NULL )
+        {
+            msg_Err( p_dec, "failed to create video output" );
+            return NULL;
+        }
+    }
+
+    /* Get a new picture */
+    while( !(p_pic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 ) ) )
+    {
+        if( p_dec->b_die || p_dec->b_error )
+        {
+            return NULL;
+        }
+        msleep( VOUT_OUTMEM_SLEEP );
+    }
+
+    return p_pic;
+}
+
+static void vout_del_buffer( decoder_t *p_dec, picture_t *p_pic )
+{
+    vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic );
 }
index c6e4a579a65ee00e0fc7a9a86399207353a7ec04..bb260f454687abbf54c97988be54efa4d367e01b 100644 (file)
@@ -2,7 +2,7 @@
  * input_programs.c: es_descriptor_t, pgrm_descriptor_t management
  *****************************************************************************
  * Copyright (C) 1999-2002 VideoLAN
- * $Id: input_programs.c,v 1.120 2003/11/06 16:36:41 nitrox Exp $
+ * $Id: input_programs.c,v 1.121 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -51,6 +51,8 @@ static int NavigationCallback( vlc_object_t *, char const *,
 static int ESCallback( vlc_object_t *, char const *,
                        vlc_value_t, vlc_value_t, void * );
 
+static es_format_t null_es_format = {0};
+
 /*****************************************************************************
  * input_InitStream: init the stream descriptor of the given input
  *****************************************************************************/
@@ -618,6 +620,7 @@ es_descriptor_t * input_AddES( input_thread_t * p_input,
     p_es->c_packets = 0;
     p_es->c_invalid_packets = 0;
     p_es->b_force_decoder = VLC_FALSE;
+    p_es->fmt = null_es_format;
 
     if( i_data_len )
     {
index d450110ad1f30d89d243f8184170586bf7635675..ab6d64eed9fe7641a478ee2dab6b92f6bbafab13 100644 (file)
@@ -2,7 +2,7 @@
  * libvlc.h: main libvlc header
  *****************************************************************************
  * Copyright (C) 1998-2002 VideoLAN
- * $Id: libvlc.h,v 1.106 2003/11/15 00:26:15 hartman Exp $
+ * $Id: libvlc.h,v 1.107 2003/11/16 21:07:31 gbazin Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -345,24 +345,16 @@ static char *ppsz_language_text[] =
     "its codecs (decompression methods). Only advanced users should " \
     "alter this option as it can break playback of all your streams." )
 
-#define CODEC_TEXT N_("Choose preferred codec list")
+#define CODEC_TEXT N_("Choose preferred codecs list")
 #define CODEC_LONGTEXT N_( \
-    "This allows you to select the order in which VLC will choose its " \
-    "codecs. For instance, 'a52old,a52,any' will try the old a52 codec " \
-    "before the new one. Please be aware that VLC does not make any " \
-    "difference between audio or video codecs, so you should always specify " \
-    "'any' at the end of the list to make sure there is a fallback for the " \
-    "types you didn't specify.")
-
+    "This allows you to select a list of codecs that VLC will use in " \
+    "priority. For instance, 'dummy,a52' will try the dummy and a52 codecs " \
+    "before trying the other ones.")
 
-#define ENCODER_VIDEO_TEXT N_("Choose preferred video encoder list")
-#define ENCODER_VIDEO_LONGTEXT N_( \
-    "This allows you to select the order in which VLC will choose its " \
-    "codecs. " )
-#define ENCODER_AUDIO_TEXT N_("Choose preferred audio encoder list")
-#define ENCODER_AUDIO_LONGTEXT N_( \
-    "This allows you to select the order in which VLC will choose its " \
-    "codecs. " )
+#define ENCODER_TEXT N_("Choose preferred encoders list")
+#define ENCODER_LONGTEXT N_( \
+    "This allows you to select a list of encoders that VLC will use in " \
+    "priority")
 
 #define SOUT_CAT_LONGTEXT N_( \
     "These options allow you to set default global options for the " \
@@ -705,6 +697,7 @@ vlc_module_begin();
     /* Decoder options */
     add_category_hint( N_("Decoders"), CODEC_CAT_LONGTEXT , VLC_TRUE );
     add_module( "codec", "decoder", NULL, NULL, CODEC_TEXT, CODEC_LONGTEXT, VLC_TRUE );
+    add_module( "encoder", "encoder", NULL, NULL, ENCODER_TEXT, ENCODER_LONGTEXT, VLC_TRUE );
 
 
     /* Stream output options */