]> git.sesse.net Git - vlc/blobdiff - plugins/mpeg_adec/mpeg_adec.c
All decoders (audio, video, subtitles) are now modules.
[vlc] / plugins / mpeg_adec / mpeg_adec.c
similarity index 54%
rename from src/audio_decoder/audio_decoder.c
rename to plugins/mpeg_adec/mpeg_adec.c
index e06f6c2d211d1d9838c73cea9b38f5ae0f8d416d..a2cc0c509b919187e80f45bf9d19fe06d6d07401 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
- * audio_decoder.c: MPEG audio decoder thread
+ * mpeg_adec.c: MPEG audio decoder thread
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: audio_decoder.c,v 1.52 2001/08/22 17:21:45 massiot Exp $
+ * $Id: mpeg_adec.c,v 1.1 2001/11/13 12:09:18 henri Exp $
  *
  * Authors: Michel Kaempf <maxx@via.ecp.fr>
  *          Michel Lespinasse <walken@via.ecp.fr>
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
 
-/*
- * TODO :
- *
- * - optimiser les NeedBits() et les GetBits() du code là où c'est possible ;
- * - vlc_cond_signal() / vlc_cond_wait() ;
- *
- */
+#define MODULE_NAME mpeg_adec
+#include "modules_inner.h"
 
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
 #include "defs.h"
 
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>                                              /* getpid() */
-#endif
-
-#include <stdio.h>                                           /* "intf_msg.h" */
-#include <string.h>                                    /* memcpy(), memset() */
 #include <stdlib.h>                                      /* malloc(), free() */
 
 #include "config.h"
-#include "common.h"
+#include "common.h"                                     /* boolean_t, byte_t */
 #include "threads.h"
 #include "mtime.h"
+#include "intf_msg.h"
+
+#include "audio_output.h"               /* aout_fifo_t (for audio_decoder.h) */
+
+#include "modules.h"
+#include "modules_export.h"
 
-#include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
 #include "stream_control.h"
 #include "input_ext-dec.h"
 
-#include "audio_output.h"               /* aout_fifo_t (for audio_decoder.h) */
-
-#include "adec_generic.h"
-#include "audio_decoder.h"
-#include "adec_math.h"                                     /* DCT32(), PCM() */
+#include "mpeg_adec_generic.h"
+#include "mpeg_adec.h"
 
 #define ADEC_FRAME_SIZE (2*1152)
 
 /*****************************************************************************
- * Local prototypes
+ * Local Prototypes
  *****************************************************************************/
-static int      InitThread             (adec_thread_t * p_adec);
-static void     RunThread              (adec_thread_t * p_adec);
-static void     ErrorThread            (adec_thread_t * p_adec);
-static void     EndThread              (adec_thread_t * p_adec);
+static int          adec_Probe( probedata_t * );
+static int          adec_RunThread   ( decoder_config_t * );
+static void         adec_EndThread ( adec_thread_t * );
+static void         adec_ErrorThread ( adec_thread_t * );
+static void         adec_Decode( adec_thread_t * );
+
 
 /*****************************************************************************
- * adec_CreateThread: creates an audio decoder thread
- *****************************************************************************
- * This function creates a new audio decoder thread, and returns a pointer to
- * its description. On error, it returns NULL.
+ * Capabilities
  *****************************************************************************/
-vlc_thread_t adec_CreateThread ( adec_config_t * p_config )
+void _M( adec_getfunctions )( function_list_t * p_function_list )
 {
-    adec_thread_t *     p_adec;
+    p_function_list->pf_probe = adec_Probe;
+    p_function_list->functions.dec.pf_RunThread = adec_RunThread;
+}
+
+/*****************************************************************************
+ * Build configuration tree.
+ *****************************************************************************/
+MODULE_CONFIG_START
+ADD_WINDOW( "Configuration for mpeg audio decoder module" )
+    ADD_COMMENT( "Nothing to configure" )
+MODULE_CONFIG_STOP
+
+MODULE_INIT_START
+    p_module->i_capabilities = MODULE_CAPABILITY_DEC;
+    p_module->psz_longname = "Mpeg I layer 1/2 audio decoder";
+MODULE_INIT_STOP
+
+MODULE_ACTIVATE_START
+    _M( adec_getfunctions )( &p_module->p_functions->dec );
+MODULE_ACTIVATE_STOP
 
-    intf_DbgMsg ( "adec debug: creating audio decoder thread" );
+MODULE_DEACTIVATE_START
+MODULE_DEACTIVATE_STOP
 
+/*****************************************************************************
+ * adec_Probe: probe the decoder and return score
+ *****************************************************************************/
+static int adec_Probe( probedata_t *p_data )
+{
+    if( p_data->i_type == MPEG1_AUDIO_ES || p_data->i_type == MPEG2_AUDIO_ES )
+        return( 100 );
+    else
+        return( 0 );
+}
+
+/*****************************************************************************
+ * adec_RunThread: initialize, go inside main loop, detroy
+ *****************************************************************************/
+static int adec_RunThread ( decoder_config_t * p_config )
+{
+    adec_thread_t   * p_adec;
+    
+    intf_DbgMsg("mpeg_adec debug: thread launched, initializing.");
+    
     /* Allocate the memory needed to store the thread's structure */
     if ( (p_adec = (adec_thread_t *)malloc (sizeof(adec_thread_t))) == NULL ) 
     {
@@ -89,143 +118,116 @@ vlc_thread_t adec_CreateThread ( adec_config_t * p_config )
                       " adec_CreateThread() to create the new thread" );
         return 0;
     }
-
+    
     /*
      * Initialize the thread properties
      */
     p_adec->p_config = p_config;
-    p_adec->p_fifo = p_config->decoder_config.p_decoder_fifo;
+    p_adec->p_fifo = p_config->p_decoder_fifo;
 
-    /*
-     * Initialize the decoder properties
+    /* 
+     * Initilize the banks
      */
-    adec_Init ( p_adec );
-
+    p_adec->bank_0.actual = p_adec->bank_0.v1;
+    p_adec->bank_0.pos = 0;
+    p_adec->bank_1.actual = p_adec->bank_1.v1;
+    p_adec->bank_1.pos = 0;
+    
     /*
-     * Initialize the output properties
+     * Initialize bit stream 
      */
-    p_adec->p_aout_fifo = NULL;
+    p_adec->p_config->pf_init_bit_stream( &p_adec->bit_stream,
+        p_adec->p_config->p_decoder_fifo, NULL, NULL );
 
-    /* Spawn the audio decoder thread */
-    if ( vlc_thread_create(&p_adec->thread_id, "audio decoder",
-         (vlc_thread_func_t)RunThread, (void *)p_adec) ) 
+    /* Create the audio output fifo */
+    p_adec->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_STEREO_FIFO, 2, 0, 0,
+                                           ADEC_FRAME_SIZE, NULL );
+    if ( p_adec->p_aout_fifo == NULL )
     {
-        intf_ErrMsg ("adec error: can't spawn audio decoder thread");
-        free (p_adec);
-        return 0;
+        intf_ErrMsg("mpeg_adec error: cannot create audio output fifo");
+        return -1;
     }
 
-    intf_DbgMsg ("adec debug: audio decoder thread (%p) created", p_adec);
-    return p_adec->thread_id;
-}
-
-/* following functions are local */
+    intf_DbgMsg("mpeg_adec debug: thread initialized, decoding begins.");
 
-/*****************************************************************************
- * InitThread : initialize an audio decoder thread
- *****************************************************************************
- * This function is called from RunThread and performs the second step of the
- * initialization. It returns 0 on success.
- *****************************************************************************/
-static int InitThread (adec_thread_t * p_adec)
-{
-    intf_DbgMsg ("adec debug: initializing audio decoder thread %p", p_adec);
-
-    p_adec->p_config->decoder_config.pf_init_bit_stream( &p_adec->bit_stream,
-        p_adec->p_config->decoder_config.p_decoder_fifo, NULL, NULL );
+    p_adec->i_sync = 0;
 
-    /* Creating the audio output fifo */
-    p_adec->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_STEREO_FIFO, 2, 0, 0,
-                                           ADEC_FRAME_SIZE, NULL );
-    if ( p_adec->p_aout_fifo == NULL ) 
+    /* Audio decoder thread's main loop */
+    while( (!p_adec->p_fifo->b_die) && (!p_adec->p_fifo->b_error) )
     {
-        return -1;
+        adec_Decode( p_adec );
+    }
+    
+    /* If b_error is set, the audio decoder thread enters the error loop */
+    if( p_adec->p_fifo->b_error ) 
+    {
+        adec_ErrorThread( p_adec );
     }
 
-    intf_DbgMsg ( "adec debug: audio decoder thread %p initialized", p_adec );
-    return 0;
+    /* End of the audio decoder thread */
+    adec_EndThread( p_adec );
+
+    return( 0 );
 }
 
+/*
+ * Following finctions are local to this module
+ */
+
 /*****************************************************************************
- * RunThread : audio decoder thread
- *****************************************************************************
- * Audio decoder thread. This function does only returns when the thread is
- * terminated.
+ * adec_Decode: decodes a mpeg frame
  *****************************************************************************/
-static void RunThread (adec_thread_t * p_adec)
+static void adec_Decode( adec_thread_t * p_adec )
 {
-    int sync;
+    s16 * buffer;
+    adec_sync_info_t sync_info;
 
-    intf_DbgMsg ( "adec debug: running audio decoder thread (%p) (pid == %i)",
-                  p_adec, getpid() );
+    if( ! adec_SyncFrame (p_adec, &sync_info) )
+    {
+        p_adec->i_sync = 1;
 
-    /* Initializing the audio decoder thread */
-    p_adec->p_fifo->b_error = InitThread (p_adec);
+        p_adec->p_aout_fifo->l_rate = sync_info.sample_rate;
 
-    sync = 0;
+        buffer = ((s16 *)p_adec->p_aout_fifo->buffer)
+                    + (p_adec->p_aout_fifo->l_end_frame * ADEC_FRAME_SIZE);
 
-    /* Audio decoder thread's main loop */
-    while( (!p_adec->p_fifo->b_die) && (!p_adec->p_fifo->b_error) )
-    {
-        s16 * buffer;
-        adec_sync_info_t sync_info;
+        if( DECODER_FIFO_START( *p_adec->p_fifo)->i_pts )
+        {
+            p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] =
+                DECODER_FIFO_START( *p_adec->p_fifo )->i_pts;
+            DECODER_FIFO_START(*p_adec->p_fifo)->i_pts = 0;
+        }
+        else
+        {
+            p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] =
+                LAST_MDATE;
+        }
 
-        if( ! adec_SyncFrame (p_adec, &sync_info) )
+        if( adec_DecodeFrame (p_adec, buffer) )
         {
-            sync = 1;
-
-            p_adec->p_aout_fifo->l_rate = sync_info.sample_rate;
-
-            buffer = ((s16 *)p_adec->p_aout_fifo->buffer)
-                        + (p_adec->p_aout_fifo->l_end_frame * ADEC_FRAME_SIZE);
-
-            if( DECODER_FIFO_START( *p_adec->p_fifo)->i_pts )
-            {
-                p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] =
-                    DECODER_FIFO_START( *p_adec->p_fifo )->i_pts;
-                DECODER_FIFO_START(*p_adec->p_fifo)->i_pts = 0;
-            }
-            else
-            {
-                p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] =
-                    LAST_MDATE;
-            }
-
-            if( adec_DecodeFrame (p_adec, buffer) )
-            {
-                /* Ouch, failed decoding... We'll have to resync */
-                sync = 0;
-            }
-            else
-            {
-                vlc_mutex_lock (&p_adec->p_aout_fifo->data_lock);
-    
-                p_adec->p_aout_fifo->l_end_frame =
-                    (p_adec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
-                vlc_cond_signal (&p_adec->p_aout_fifo->data_wait);
-                vlc_mutex_unlock (&p_adec->p_aout_fifo->data_lock);
-            }
+            /* Ouch, failed decoding... We'll have to resync */
+            p_adec->i_sync = 0;
         }
-    }
+        else
+        {
+            vlc_mutex_lock (&p_adec->p_aout_fifo->data_lock);
 
-    /* If b_error is set, the audio decoder thread enters the error loop */
-    if( p_adec->p_fifo->b_error ) 
-    {
-        ErrorThread( p_adec );
+            p_adec->p_aout_fifo->l_end_frame =
+                (p_adec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
+            vlc_cond_signal (&p_adec->p_aout_fifo->data_wait);
+            vlc_mutex_unlock (&p_adec->p_aout_fifo->data_lock);
+        }
     }
-
-    /* End of the audio decoder thread */
-    EndThread( p_adec );
 }
 
 /*****************************************************************************
- * ErrorThread : audio decoder's RunThread() error loop
+ * adec_ErrorThread : audio decoder's RunThread() error loop
  *****************************************************************************
  * This function is called when an error occured during thread main's loop. The
  * thread can still receive feed, but must be ready to terminate as soon as
  * possible.
  *****************************************************************************/
-static void ErrorThread ( adec_thread_t *p_adec )
+static void adec_ErrorThread ( adec_thread_t *p_adec )
 {
     /* We take the lock, because we are going to read/write the start/end
      * indexes of the decoder fifo */
@@ -250,13 +252,14 @@ static void ErrorThread ( adec_thread_t *p_adec )
     vlc_mutex_unlock ( &p_adec->p_fifo->data_lock );
 }
 
+
 /*****************************************************************************
- * EndThread : audio decoder thread destruction
+ * adec_EndThread : audio decoder thread destruction
  *****************************************************************************
  * This function is called when the thread ends after a sucessful
  * initialization.
  *****************************************************************************/
-static void EndThread ( adec_thread_t *p_adec )
+static void adec_EndThread ( adec_thread_t *p_adec )
 {
     intf_DbgMsg ( "adec debug: destroying audio decoder thread %p", p_adec );