Optimized libmad_output() for smoother sound. It is still not optimal.
[vlc.git] / plugins / mad / mad_adec.c
index 8cbf0ae..d84fad2 100644 (file)
  *                                                                         *
  ***************************************************************************/
 
  *                                                                         *
  ***************************************************************************/
 
-#define MODULE_NAME mad
-#include "modules_inner.h"
-
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
-#include "defs.h"
-
 #include <stdlib.h>                                      /* malloc(), free() */
 #include <string.h>                                              /* strdup() */
 
 #include <stdlib.h>                                      /* malloc(), free() */
 #include <string.h>                                              /* strdup() */
 
-#include "common.h"                                     /* boolean_t, byte_t */
-#include "intf_msg.h"
-#include "threads.h"
-#include "mtime.h"
-#include "tests.h"
+#include <videolan/vlc.h>
 
 #include "audio_output.h"
 
 
 #include "audio_output.h"
 
-#include "modules.h"
-#include "modules_export.h"
-
 #include "stream_control.h"
 #include "input_ext-dec.h"
 
 #include "stream_control.h"
 #include "input_ext-dec.h"
 
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
-static int      mad_adec_Probe       ( probedata_t * );
-static int      mad_adec_Run         ( decoder_config_t * );
-static int      mad_adec_Init        (mad_adec_thread_t * p_mad_adec);
-static void     mad_adec_ErrorThread (mad_adec_thread_t * p_mad_adec);
-static void     mad_adec_EndThread   (mad_adec_thread_t * p_mad_adec);
+static int  decoder_Probe  ( probedata_t * );
+static int  decoder_Run    ( decoder_config_t * );
+static int  InitThread     ( mad_adec_thread_t * p_mad_adec );
+static void EndThread      ( mad_adec_thread_t * p_mad_adec );
 
 /*****************************************************************************
  * Capabilities
  *****************************************************************************/
 void _M( adec_getfunctions )( function_list_t * p_function_list )
 {
 
 /*****************************************************************************
  * Capabilities
  *****************************************************************************/
 void _M( adec_getfunctions )( function_list_t * p_function_list )
 {
-    p_function_list->pf_probe = mad_adec_Probe;
-    p_function_list->functions.dec.pf_run = mad_adec_Run;
+    p_function_list->pf_probe = decoder_Probe;
+    p_function_list->functions.dec.pf_run = decoder_Run;
 }
 
 /*****************************************************************************
  * Build configuration tree.
  *****************************************************************************/
 MODULE_CONFIG_START
 }
 
 /*****************************************************************************
  * Build configuration tree.
  *****************************************************************************/
 MODULE_CONFIG_START
-ADD_WINDOW( "Configuration for mad_adec module" )
-    ADD_COMMENT( "No device to configure." )
+    ADD_WINDOW( "Configuration for mad_adec module" )
+        ADD_COMMENT( "No device to configure." )
 MODULE_CONFIG_STOP
 
 MODULE_INIT_START
 MODULE_CONFIG_STOP
 
 MODULE_INIT_START
-    p_module->i_capabilities = MODULE_CAPABILITY_DEC;
-    p_module->psz_longname = "Libmad MPEG 1/2/3 audio decoder library";
+    SET_DESCRIPTION( "Libmad MPEG 1/2/3 audio decoder library" )
+    ADD_CAPABILITY( DECODER, 950 )
 MODULE_INIT_STOP
 
 MODULE_ACTIVATE_START
 MODULE_INIT_STOP
 
 MODULE_ACTIVATE_START
@@ -93,19 +80,15 @@ MODULE_DEACTIVATE_START
 MODULE_DEACTIVATE_STOP
 
 /*****************************************************************************
 MODULE_DEACTIVATE_STOP
 
 /*****************************************************************************
- * mad_adec_Probe: probe the decoder and return score
+ * decoder_Probe: probe the decoder and return score
  *****************************************************************************
  * Tries to launch a decoder and return score so that the interface is able
  * to chose.
  *****************************************************************************/
  *****************************************************************************
  * Tries to launch a decoder and return score so that the interface is able
  * to chose.
  *****************************************************************************/
-static int mad_adec_Probe( probedata_t *p_data )
+static int decoder_Probe( probedata_t *p_data )
 {
     if( p_data->i_type == MPEG1_AUDIO_ES || p_data->i_type == MPEG2_AUDIO_ES )
     {
 {
     if( p_data->i_type == MPEG1_AUDIO_ES || p_data->i_type == MPEG2_AUDIO_ES )
     {
-        if( TestMethod( ADEC_MPEG_VAR, "mad" ) )
-        {
-            return( 999 );
-        }
         return( 50 );
     }
     else
         return( 50 );
     }
     else
@@ -115,9 +98,9 @@ static int mad_adec_Probe( probedata_t *p_data )
 }
 
 /*****************************************************************************
 }
 
 /*****************************************************************************
- * mad_adec_Run: this function is called just after the thread is created
+ * decoder_Run: this function is called just after the thread is created
  *****************************************************************************/
  *****************************************************************************/
-static int mad_adec_Run ( decoder_config_t * p_config )
+static int decoder_Run ( decoder_config_t * p_config )
 {
     mad_adec_thread_t *   p_mad_adec;
 
 {
     mad_adec_thread_t *   p_mad_adec;
 
@@ -129,7 +112,8 @@ static int mad_adec_Run ( decoder_config_t * p_config )
     if (p_mad_adec == NULL)
     {
         intf_ErrMsg ( "mad_adec error: not enough memory "
     if (p_mad_adec == NULL)
     {
         intf_ErrMsg ( "mad_adec error: not enough memory "
-                      "for mad_adec_Run() to allocate p_mad_adec" );
+                      "for decoder_Run() to allocate p_mad_adec" );
+        DecoderError( p_config->p_decoder_fifo );
         return( -1 );
     }
 
         return( -1 );
     }
 
@@ -138,9 +122,11 @@ static int mad_adec_Run ( decoder_config_t * p_config )
      */
     p_mad_adec->p_config = p_config;
     p_mad_adec->p_fifo = p_mad_adec->p_config->p_decoder_fifo;
      */
     p_mad_adec->p_config = p_config;
     p_mad_adec->p_fifo = p_mad_adec->p_config->p_decoder_fifo;
-    if( mad_adec_Init( p_mad_adec ) )
+    if( InitThread( p_mad_adec ) )
     {
         intf_ErrMsg( "mad_adec error: could not initialize thread" );
     {
         intf_ErrMsg( "mad_adec error: could not initialize thread" );
+        DecoderError( p_config->p_decoder_fifo );
+        free( p_mad_adec );
         return( -1 );
     }
 
         return( -1 );
     }
 
@@ -151,7 +137,8 @@ static int mad_adec_Run ( decoder_config_t * p_config )
        if (mad_decoder_run(p_mad_adec->libmad_decoder, MAD_DECODER_MODE_SYNC)==-1)
        {
          intf_ErrMsg( "mad_adec error: libmad decoder returns abnormally");
        if (mad_decoder_run(p_mad_adec->libmad_decoder, MAD_DECODER_MODE_SYNC)==-1)
        {
          intf_ErrMsg( "mad_adec error: libmad decoder returns abnormally");
-         mad_adec_EndThread(p_mad_adec);
+          DecoderError( p_mad_adec->p_fifo );
+         EndThread(p_mad_adec);
          return( -1 );
        }
     }
          return( -1 );
        }
     }
@@ -159,19 +146,19 @@ static int mad_adec_Run ( decoder_config_t * p_config )
     /* If b_error is set, the mad decoder thread enters the error loop */
     if (p_mad_adec->p_fifo->b_error)
     {
     /* If b_error is set, the mad decoder thread enters the error loop */
     if (p_mad_adec->p_fifo->b_error)
     {
-        mad_adec_ErrorThread (p_mad_adec);
+        DecoderError( p_mad_adec->p_fifo );
     }
 
     /* End of the ac3 decoder thread */
     }
 
     /* End of the ac3 decoder thread */
-    mad_adec_EndThread (p_mad_adec);
+    EndThread (p_mad_adec);
 
     return( 0 );
 }
 
 /*****************************************************************************
 
     return( 0 );
 }
 
 /*****************************************************************************
- * mad_adec_Init: initialize data before entering main loop
+ * InitThread: initialize data before entering main loop
  *****************************************************************************/
  *****************************************************************************/
-static int mad_adec_Init( mad_adec_thread_t * p_mad_adec )
+static int InitThread( mad_adec_thread_t * p_mad_adec )
 {
     /*
      * Properties of audio for libmad
 {
     /*
      * Properties of audio for libmad
@@ -193,10 +180,10 @@ static int mad_adec_Init( mad_adec_thread_t * p_mad_adec )
     mad_decoder_init( p_mad_adec->libmad_decoder,
                      p_mad_adec,       /* vlc's thread structure and p_fifo playbuffer */
                      libmad_input,     /* input_func */
     mad_decoder_init( p_mad_adec->libmad_decoder,
                      p_mad_adec,       /* vlc's thread structure and p_fifo playbuffer */
                      libmad_input,     /* input_func */
-                     libmad_header,    /* header_func */
+                     0,                /* header_func */
                      0,                /* filter */
                      libmad_output,    /* output_func */
                      0,                /* filter */
                      libmad_output,    /* output_func */
-                     0,        /* error */
+                     0,                /* error */
                      0);               /* message */
 
     mad_decoder_options(p_mad_adec->libmad_decoder, MAD_OPTION_IGNORECRC);
                      0);               /* message */
 
     mad_decoder_options(p_mad_adec->libmad_decoder, MAD_OPTION_IGNORECRC);
@@ -223,37 +210,10 @@ static int mad_adec_Init( mad_adec_thread_t * p_mad_adec )
     return( 0 );
 }
 
     return( 0 );
 }
 
-
-/*****************************************************************************
- * mad_adec_ErrorThread : mad decoder's RunThread() error loop
- *****************************************************************************/
-static void mad_adec_ErrorThread (mad_adec_thread_t * p_mad_adec)
-{
-    /* We take the lock, because we are going to read/write the start/end
-     * indexes of the decoder fifo */
-    vlc_mutex_lock (&p_mad_adec->p_fifo->data_lock);
-
-    /* Wait until a `die' order is sent */
-    while (!p_mad_adec->p_fifo->b_die)
-    {
-        /* Trash all received PES packets */
-        p_mad_adec->p_fifo->pf_delete_pes(
-                        p_mad_adec->p_fifo->p_packets_mgt,
-                        p_mad_adec->p_fifo->p_first );
-
-        /* Waiting for the input thread to put new PES packets in the fifo */
-        vlc_cond_wait (&p_mad_adec->p_fifo->data_wait,
-                       &p_mad_adec->p_fifo->data_lock);
-    }
-
-    /* We can release the lock before leaving */
-    vlc_mutex_unlock (&p_mad_adec->p_fifo->data_lock);
-}
-
 /*****************************************************************************
 /*****************************************************************************
- * mad_adec_EndThread : libmad decoder thread destruction
+ * EndThread : libmad decoder thread destruction
  *****************************************************************************/
  *****************************************************************************/
-static void mad_adec_EndThread (mad_adec_thread_t * p_mad_adec)
+static void EndThread (mad_adec_thread_t * p_mad_adec)
 {
     intf_ErrMsg ("mad_adec debug: destroying mad decoder thread %p", p_mad_adec);
 
 {
     intf_ErrMsg ("mad_adec debug: destroying mad decoder thread %p", p_mad_adec);
 
@@ -271,9 +231,8 @@ static void mad_adec_EndThread (mad_adec_thread_t * p_mad_adec)
     /* mad_decoder_finish releases the memory allocated inside the struct */
     mad_decoder_finish( p_mad_adec->libmad_decoder );
 
     /* mad_decoder_finish releases the memory allocated inside the struct */
     mad_decoder_finish( p_mad_adec->libmad_decoder );
 
-    /* Unlock the modules */
+    /* Unlock the modules, p_mad_adec->p_config is released by the decoder subsystem  */
     free( p_mad_adec->libmad_decoder );
     free( p_mad_adec->libmad_decoder );
-//    free( p_mad_adec->p_config ); /* for now a reminder until integration with cvs */
     free( p_mad_adec );
 
     intf_ErrMsg ("mad_adec debug: mad decoder thread %p destroyed", p_mad_adec);
     free( p_mad_adec );
 
     intf_ErrMsg ("mad_adec debug: mad decoder thread %p destroyed", p_mad_adec);