]> git.sesse.net Git - vlc/blobdiff - plugins/ac3_spdif/ac3_spdif.c
All decoders (audio, video, subtitles) are now modules.
[vlc] / plugins / ac3_spdif / ac3_spdif.c
similarity index 76%
rename from src/ac3_spdif/ac3_spdif.c
rename to plugins/ac3_spdif/ac3_spdif.c
index fa531afd1a96c52c44da9336c04b44ca704c33b2..72a81daa723385ae9f2deb43749205fd597fba26 100644 (file)
@@ -2,7 +2,7 @@
  * ac3_spdif.c: ac3 pass-through to external decoder with enabled soundcard
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: ac3_spdif.c,v 1.12 2001/09/30 20:25:13 bozo Exp $
+ * $Id: ac3_spdif.c,v 1.1 2001/11/13 12:09:17 henri Exp $
  *
  * Authors: Stéphane Borel <stef@via.ecp.fr>
  *          Juha Yrjola <jyrjola@cc.hut.fi>
@@ -23,6 +23,9 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
 
+#define MODULE_NAME ac3_spdif
+#include "modules_inner.h"
+
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
 #include "common.h"
 #include "threads.h"
 #include "mtime.h"
-
 #include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
 
+#include "audio_output.h"
+
+#include "modules.h"
+#include "modules_export.h"
+
 #include "stream_control.h"
 #include "input_ext-dec.h"
 
-#include "audio_output.h"
-
 #include "ac3_spdif.h"
 #include "ac3_iec958.h"
 
 /****************************************************************************
  * Local Prototypes
  ****************************************************************************/
-static int  InitThread       ( ac3_spdif_thread_t * );
-static void RunThread        ( ac3_spdif_thread_t * );
-static void ErrorThread      ( ac3_spdif_thread_t * );
-static void EndThread        ( ac3_spdif_thread_t * );
+static int  ac3_spdif_Probe       ( probedata_t * );
+static int  ac3_spdif_Run         ( decoder_config_t * );
+static int  ac3_spdif_Init        ( ac3_spdif_thread_t * );
+static void ac3_spdif_ErrorThread ( ac3_spdif_thread_t * );
+static void ac3_spdif_EndThread   ( ac3_spdif_thread_t * );
 static void BitstreamCallback( bit_stream_t *, boolean_t );
 
-/****************************************************************************
- * spdif_CreateThread: initialize the spdif thread
- ****************************************************************************/
-vlc_thread_t spdif_CreateThread( adec_config_t * p_config )
+/*****************************************************************************
+ * Capabilities
+ *****************************************************************************/
+void _M( adec_getfunctions )( function_list_t * p_function_list )
 {
-    ac3_spdif_thread_t *   p_spdif;
-
-    intf_DbgMsg( "spdif debug: creating ac3 pass-through thread" );
-
-    /* Allocate the memory needed to store the thread's structure */
-    p_spdif = malloc( sizeof(ac3_spdif_thread_t) );
-
-    if( p_spdif == NULL )
-    {
-        intf_ErrMsg ( "spdif error: not enough memory "
-                      "for spdif_CreateThread() to create the new thread");
-        return 0;
-    }
-    
-    /* Temporary buffer to store ac3 frames to be transformed */
-    p_spdif->p_ac3 = malloc( SPDIF_FRAME_SIZE );
-
-    if( p_spdif->p_ac3 == NULL )
-    {
-        free( p_spdif->p_ac3 );
-        return 0;
-    }
-
-    /*
-     * Initialize the thread properties
-     */
-    p_spdif->p_config = p_config;
-    p_spdif->p_fifo = p_config->decoder_config.p_decoder_fifo;
-
-    p_spdif->p_aout_fifo = NULL;
-
-    /* Spawn the ac3 to spdif thread */
-    if (vlc_thread_create(&p_spdif->thread_id, "spdif", 
-                (vlc_thread_func_t)RunThread, (void *)p_spdif))
-    {
-        intf_ErrMsg( "spdif error: can't spawn spdif thread" );
-        free( p_spdif->p_ac3 );
-        free( p_spdif );
-        return 0;
-    }
-
-    intf_DbgMsg( "spdif debug: spdif thread (%p) created", p_spdif );
-
-    return p_spdif->thread_id;
+    p_function_list->pf_probe = ac3_spdif_Probe;
+    p_function_list->functions.dec.pf_RunThread = ac3_spdif_Run;
 }
 
-/*
- * Local functions
- */
-
-/****************************************************************************
- * InitThread: initialize thread data and create output fifo
- ****************************************************************************/
-static int InitThread( ac3_spdif_thread_t * p_spdif )
-{
-    boolean_t b_sync = 0;
-
-    p_spdif->p_config->decoder_config.pf_init_bit_stream(
-            &p_spdif->bit_stream,
-            p_spdif->p_config->decoder_config.p_decoder_fifo,
-            BitstreamCallback, (void*)p_spdif );
-
-    /* Creating the audio output fifo */
-    p_spdif->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_SPDIF_FIFO, 1, 48000, 0,
-                                            SPDIF_FRAME_SIZE, NULL );
-
-    if( p_spdif->p_aout_fifo == NULL )
-    {
-        return -1;
-    }
-
-    intf_WarnMsg( 3, "spdif: aout fifo #%d created",
-                     p_spdif->p_aout_fifo->i_fifo );
-
-    /* Sync word */
-    p_spdif->p_ac3[0] = 0x0b;
-    p_spdif->p_ac3[1] = 0x77;
-
-    /* Find syncword */
-    while( !b_sync )
-    {
-        while( GetBits( &p_spdif->bit_stream, 8 ) != 0x0b );
-        p_spdif->i_real_pts = p_spdif->i_pts;
-        p_spdif->i_pts = 0;
-        b_sync = ( ShowBits( &p_spdif->bit_stream, 8 ) == 0x77 );
-    }
-    RemoveBits( &p_spdif->bit_stream, 8 );
-
-    /* Check stream properties */
-    if( ac3_iec958_parse_syncinfo( p_spdif ) < 0 )
-    {
-        intf_ErrMsg( "spdif error: stream not valid");
-
-        aout_DestroyFifo( p_spdif->p_aout_fifo );
-        return -1;
-    }
+/*****************************************************************************
+ * Build configuration tree.
+ *****************************************************************************/
+MODULE_CONFIG_START
+ADD_WINDOW( "Configuration for ac3 spdif decoder module" )
+    ADD_COMMENT( "Nothing to configure" )
+MODULE_CONFIG_STOP
 
-    /* Check that we can handle the rate 
-     * FIXME: we should check that we have the same rate for all fifos 
-     * but all rates should be supported by the decoder (32, 44.1, 48) */
-    if( p_spdif->ac3_info.i_sample_rate != 48000 )
-    {
-        intf_ErrMsg( "spdif error: Only 48000 Hz streams supported");
+MODULE_INIT_START
+    p_module->i_capabilities = MODULE_CAPABILITY_DEC;
+    p_module->psz_longname = "Ac3 SPDIF decoder for AC3 pass-through";
+MODULE_INIT_STOP
 
-        aout_DestroyFifo( p_spdif->p_aout_fifo );
-        return -1;
-    }
-    p_spdif->p_aout_fifo->l_rate = p_spdif->ac3_info.i_sample_rate;
+MODULE_ACTIVATE_START
+    _M( adec_getfunctions )( &p_module->p_functions->dec );
+MODULE_ACTIVATE_STOP
 
-    GetChunk( &p_spdif->bit_stream, p_spdif->p_ac3 + sizeof(sync_frame_t),
-        p_spdif->ac3_info.i_frame_size - sizeof(sync_frame_t) );
+MODULE_DEACTIVATE_START
+MODULE_DEACTIVATE_STOP
 
-    return 0;
+/*****************************************************************************
+ * ac3_spdif_Probe: probe the decoder and return score
+ *****************************************************************************
+ * Tries to launch a decoder and return score so that the interface is able 
+ * to chose.
+ *****************************************************************************/
+static int ac3_spdif_Probe( probedata_t *p_data )
+{
+    if( main_GetIntVariable( AOUT_SPDIF_VAR, 0 ) && 
+        p_data->i_type == AC3_AUDIO_ES )
+        return( 100 );
+    else
+        return( 0 );
 }
 
+
 /****************************************************************************
- * RunThread: loop that reads ac3 ES and transform it to
- * an spdif compliant stream.
+ * ac3_spdif_Run: the whole thing
+ ****************************************************************************
+ * This function is called just after the thread is launched.
  ****************************************************************************/
-static void RunThread( ac3_spdif_thread_t * p_spdif )
+static int ac3_spdif_Run( decoder_config_t * p_config )
 {
+    ac3_spdif_thread_t *   p_spdif;
     mtime_t     i_frame_time;
     boolean_t   b_sync;
     /* PTS of the current frame */
     mtime_t     i_current_pts = 0;
 
-    /* Initializing the spdif decoder thread */
-    if( InitThread( p_spdif ) )
+    intf_DbgMsg( "spdif debug: ac3_spdif thread created, initializing." );
+
+    /* Allocate the memory needed to store the thread's structure */
+    p_spdif = malloc( sizeof(ac3_spdif_thread_t) );
+
+    if( p_spdif == NULL )
+    {
+        intf_ErrMsg ( "spdif error: not enough memory "
+                      "for spdif_CreateThread() to create the new thread");
+        return( -1 );
+    }
+  
+    p_spdif->p_config = p_config; 
+    
+    if (ac3_spdif_Init( p_spdif ) )
     {
-         p_spdif->p_fifo->b_error = 1;
+        intf_ErrMsg( "spdif error: could not initialize thread" );
+        return( -1 );
     }
 
     /* Compute the theorical duration of an ac3 frame */
     i_frame_time = 1000000 * AC3_FRAME_SIZE /
                              p_spdif->ac3_info.i_sample_rate;
+    
+    intf_DbgMsg( "spdif debug: ac3_spdif thread (%p) initialized", p_spdif );
 
     while( !p_spdif->p_fifo->b_die && !p_spdif->p_fifo->b_error )
     {
@@ -264,19 +213,99 @@ static void RunThread( ac3_spdif_thread_t * p_spdif )
     /* If b_error is set, the ac3 spdif thread enters the error loop */
     if( p_spdif->p_fifo->b_error )
     {
-        ErrorThread( p_spdif );
+        ac3_spdif_ErrorThread( p_spdif );
     }
 
     /* End of the ac3 decoder thread */
-    EndThread( p_spdif );
+    ac3_spdif_EndThread( p_spdif );
+    
+    return( 0 );
+}
+
+/****************************************************************************
+ * ac3_spdif_Init: initialize thread data and create output fifo
+ ****************************************************************************/
+static int ac3_spdif_Init( ac3_spdif_thread_t * p_spdif )
+{
+    boolean_t b_sync = 0;
+
+    /* Temporary buffer to store ac3 frames to be transformed */
+    p_spdif->p_ac3 = malloc( SPDIF_FRAME_SIZE );
+
+    if( p_spdif->p_ac3 == NULL )
+    {
+        free( p_spdif->p_ac3 );
+        return( -1 );
+    }
+
+    /*
+     * Initialize the thread properties
+     */
+    p_spdif->p_fifo = p_spdif->p_config->p_decoder_fifo;
+
+    p_spdif->p_config->pf_init_bit_stream(
+            &p_spdif->bit_stream,
+            p_spdif->p_config->p_decoder_fifo,
+            BitstreamCallback, (void*)p_spdif );
+
+    /* Creating the audio output fifo */
+    p_spdif->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_SPDIF_FIFO, 1, 48000, 0,
+                                            SPDIF_FRAME_SIZE, NULL );
 
-    return;
+    if( p_spdif->p_aout_fifo == NULL )
+    {
+        return( -1 );
+    }
+
+    intf_WarnMsg( 3, "spdif: aout fifo #%d created",
+                     p_spdif->p_aout_fifo->i_fifo );
+
+    /* Sync word */
+    p_spdif->p_ac3[0] = 0x0b;
+    p_spdif->p_ac3[1] = 0x77;
+
+    /* Find syncword */
+    while( !b_sync )
+    {
+        while( GetBits( &p_spdif->bit_stream, 8 ) != 0x0b );
+        p_spdif->i_real_pts = p_spdif->i_pts;
+        p_spdif->i_pts = 0;
+        b_sync = ( ShowBits( &p_spdif->bit_stream, 8 ) == 0x77 );
+    }
+    RemoveBits( &p_spdif->bit_stream, 8 );
+
+    /* Check stream properties */
+    if( ac3_iec958_parse_syncinfo( p_spdif ) < 0 )
+    {
+        intf_ErrMsg( "spdif error: stream not valid");
+
+        aout_DestroyFifo( p_spdif->p_aout_fifo );
+        return( -1 );
+    }
+
+    /* Check that we can handle the rate 
+     * FIXME: we should check that we have the same rate for all fifos 
+     * but all rates should be supported by the decoder (32, 44.1, 48) */
+    if( p_spdif->ac3_info.i_sample_rate != 48000 )
+    {
+        intf_ErrMsg( "spdif error: Only 48000 Hz streams supported");
+
+        aout_DestroyFifo( p_spdif->p_aout_fifo );
+        return -1;
+    }
+    p_spdif->p_aout_fifo->l_rate = p_spdif->ac3_info.i_sample_rate;
+
+    GetChunk( &p_spdif->bit_stream, p_spdif->p_ac3 + sizeof(sync_frame_t),
+        p_spdif->ac3_info.i_frame_size - sizeof(sync_frame_t) );
+
+    return( 0 );
 }
 
+
 /*****************************************************************************
- * ErrorThread : ac3 spdif's RunThread() error loop
+ * ac3_spdif_ErrorThread : ac3 spdif's RunThread() error loop
  *****************************************************************************/
-static void ErrorThread( ac3_spdif_thread_t * p_spdif )
+static void ac3_spdif_ErrorThread( ac3_spdif_thread_t * p_spdif )
 {
     /* We take the lock, because we are going to read/write the start/end
      * indexes of the decoder fifo */
@@ -303,9 +332,9 @@ static void ErrorThread( ac3_spdif_thread_t * p_spdif )
 }
 
 /*****************************************************************************
- * EndThread : ac3 spdif thread destruction
+ * ac3_spdif_EndThread : ac3 spdif thread destruction
  *****************************************************************************/
-static void EndThread( ac3_spdif_thread_t * p_spdif )
+static void ac3_spdif_EndThread( ac3_spdif_thread_t * p_spdif )
 {
     intf_DbgMsg( "spdif debug: destroying thread %p", p_spdif );
 
@@ -325,7 +354,7 @@ static void EndThread( ac3_spdif_thread_t * p_spdif )
     free( p_spdif->p_config );
     free( p_spdif->p_ac3 );
     free( p_spdif );
-
+    
     intf_DbgMsg ("spdif debug: thread %p destroyed", p_spdif );
 }