]> git.sesse.net Git - vlc/blobdiff - plugins/mpeg/input_ps.c
* Fixed the BeOS compile typo.
[vlc] / plugins / mpeg / input_ps.c
index 6f80ffaee0cd75df5d8af2a48b2cceefe66c4b33..856856c723f61ca56ab35a7e85f1ffb8ebb383d5 100644 (file)
@@ -2,7 +2,7 @@
  * input_ps.c: PS demux and packet management
  *****************************************************************************
  * Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: input_ps.c,v 1.12 2001/04/05 14:00:28 asmax Exp $
+ * $Id: input_ps.c,v 1.25 2001/05/30 17:03:12 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *          Cyril Deguet <asmax@via.ecp.fr>
@@ -32,6 +32,9 @@
 
 #include <stdlib.h>
 #include <string.h>
+#ifdef STRNCASECMP_IN_STRINGS_H
+#   include <strings.h>
+#endif
 #include <errno.h>
 
 #include <sys/types.h>
@@ -85,8 +88,8 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
 #define input p_function_list->functions.input
     p_function_list->pf_probe = PSProbe;
     input.pf_init             = PSInit;
-    input.pf_open             = input_FileOpen;
-    input.pf_close            = input_FileClose;
+    input.pf_open             = NULL; /* Set in PSInit */
+    input.pf_close            = NULL;
     input.pf_end              = PSEnd;
     input.pf_set_area         = NULL;
     input.pf_read             = PSRead;
@@ -143,7 +146,7 @@ static int PSProbe( probedata_t *p_data )
 static void PSInit( input_thread_t * p_input )
 {
     thread_ps_data_t *  p_method;
-    packet_cache_t *   p_packet_cache;
+    packet_cache_t *    p_packet_cache;
 
     if( (p_method =
          (thread_ps_data_t *)malloc( sizeof(thread_ps_data_t) )) == NULL )
@@ -163,6 +166,13 @@ static void PSInit( input_thread_t * p_input )
         return;
     }
     p_input->p_method_data = (void *)p_packet_cache;
+
+    /* Set callback */
+    p_input->pf_open  = p_input->pf_file_open;
+    p_input->pf_close = p_input->pf_file_close;
+
+    /* Initialize packet cache mutex */
+    vlc_mutex_init( &p_packet_cache->lock );
     
     /* allocates the data cache */
     p_packet_cache->data.p_stack = malloc( DATA_CACHE_SIZE * 
@@ -170,8 +180,8 @@ static void PSInit( input_thread_t * p_input )
     if ( p_packet_cache->data.p_stack == NULL )
     {
         intf_ErrMsg( "Out of memory" );
-       p_input->b_error = 1;
-       return;
+        p_input->b_error = 1;
+        return;
     }
     p_packet_cache->data.l_index = 0;
     
@@ -267,7 +277,10 @@ static void PSInit( input_thread_t * p_input )
         }
         rewind( p_method->stream );
         vlc_mutex_lock( &p_input->stream.stream_lock );
+
+        p_input->stream.i_method = INPUT_METHOD_FILE;
         p_input->stream.p_selected_area->i_tell = 0;
+
         if( p_demux_data->b_has_PSM )
         {
             /* (The PSM decoder will care about spawning the decoders) */
@@ -329,7 +342,16 @@ static void PSInit( input_thread_t * p_input )
                         break;
 
                     case LPCM_AUDIO_ES:
-                        /* FIXME ! */
+                        if( main_GetIntVariable( INPUT_CHANNEL_VAR, 0 )
+                                == ((p_es->i_id & 0x1F00) >> 8) )
+                        switch( main_GetIntVariable( INPUT_AUDIO_VAR, 0 ) )
+                        {
+                        case 0:
+                            main_PutIntVariable( INPUT_AUDIO_VAR,
+                                                 REQUESTED_LPCM );
+                        case REQUESTED_LPCM:
+                            input_SelectES( p_input, p_es );
+                        }
                         break;
                 }
             }
@@ -345,6 +367,7 @@ static void PSInit( input_thread_t * p_input )
     {
         /* The programs will be added when we read them. */
         vlc_mutex_lock( &p_input->stream.stream_lock );
+        p_input->stream.i_method = INPUT_METHOD_FILE;
         p_input->stream.pp_programs[0]->b_is_ok = 0;
         vlc_mutex_unlock( &p_input->stream.stream_lock );
     }
@@ -355,6 +378,7 @@ static void PSInit( input_thread_t * p_input )
  *****************************************************************************/
 static void PSEnd( input_thread_t * p_input )
 {
+    vlc_mutex_destroy( &((packet_cache_t *)p_input->p_plugin_data)->lock );
     free( p_input->p_plugin_data );
 }
 
@@ -425,7 +449,7 @@ static int PSRead( input_thread_t * p_input,
                 /* It is common for MPEG-1 streams to pad with zeros
                  * (although it is forbidden by the recommendation), so
                  * don't bother everybody in this case. */
-                intf_WarnMsg( 1, "Garbage at input (%.8x)", i_startcode );
+                intf_WarnMsg( 3, "Garbage at input (%.8x)", i_startcode );
             }
 
             while( (i_startcode & 0xFFFFFF00) != 0x100L )
@@ -508,7 +532,6 @@ static int PSRead( input_thread_t * p_input,
 
         /* Give the packet to the other input stages. */
         pp_packets[i_packet] = p_data;
-//fprintf(stderr, "read2 %li %li\n", p_data, p_data->l_size);
     }
 
     return( 0 );
@@ -524,7 +547,11 @@ static void PSSeek( input_thread_t * p_input, off_t i_position )
     p_method = (thread_ps_data_t *)p_input->p_plugin_data;
 
     /* A little bourrin but should work for a while --Meuuh */
+#ifndef WIN32
     fseeko( p_method->stream, i_position, SEEK_SET );
+#else
+    fseek( p_method->stream, (long)i_position, SEEK_SET );
+#endif
 
     p_input->stream.p_selected_area->i_tell = i_position;
 }
@@ -544,11 +571,16 @@ static struct data_packet_s * NewPacket( void * p_packet_cache,
     data_packet_t *    p_data;
     long               l_index;
 
-    if ( (p_cache = (packet_cache_t *)p_packet_cache) == NULL )
+    p_cache = (packet_cache_t *)p_packet_cache;
+
+#ifdef DEBUG
+    if ( p_cache == NULL )
     {
         intf_ErrMsg( "PPacket cache not initialized" );
         return NULL;
     }
+#endif
+
     /* Safety check */
     if( l_size > INPUT_MAX_PACKET_SIZE )
     {
@@ -556,15 +588,21 @@ static struct data_packet_s * NewPacket( void * p_packet_cache,
         return NULL;
     }
 
+    vlc_mutex_lock( &p_cache->lock );
+
     /* Checks whether the data cache is empty */
     if( p_cache->data.l_index == 0 )
     {
         /* Allocates a new packet */
         if ( (p_data = malloc( sizeof(data_packet_t) )) == NULL )
         {
-            intf_DbgMsg( "Out of memory" );
+            intf_ErrMsg( "Out of memory" );
+            vlc_mutex_unlock( &p_cache->lock );
             return NULL;
         }
+#ifdef TRACE_INPUT
+        intf_DbgMsg( "PS input: data packet allocated" );
+#endif
     }
     else
     {
@@ -572,7 +610,8 @@ static struct data_packet_s * NewPacket( void * p_packet_cache,
         if( (p_data = p_cache->data.p_stack[ -- p_cache->data.l_index ]) 
             == NULL )
         {
-            intf_DbgMsg( "NULL packet in the data cache" );
+            intf_ErrMsg( "NULL packet in the data cache" );
+            vlc_mutex_unlock( &p_cache->lock );
             return NULL;
         }
     }
@@ -584,13 +623,17 @@ static struct data_packet_s * NewPacket( void * p_packet_cache,
         /* Checks whether the buffer cache is empty */
         if( p_cache->small.l_index == 0 )
         {
-           /* Allocates a new packet */
+            /* Allocates a new packet */
             if ( (p_data->p_buffer = malloc( l_size )) == NULL )
             {
                 intf_DbgMsg( "Out of memory" );
                 free( p_data );
+                vlc_mutex_unlock( &p_cache->lock );
                 return NULL;
             }
+#ifdef TRACE_INPUT
+            intf_DbgMsg( "PS input: small buffer allocated" );
+#endif
             p_data->l_size = l_size;
         }
         else
@@ -600,11 +643,12 @@ static struct data_packet_s * NewPacket( void * p_packet_cache,
             if( (p_data->p_buffer = p_cache->small.p_stack[l_index].p_data)
                 == NULL )
             {
-                intf_DbgMsg( "NULL packet in the small buffer cache" );
+                intf_ErrMsg( "NULL packet in the small buffer cache" );
                 free( p_data );
+                vlc_mutex_unlock( &p_cache->lock );
                 return NULL;
             }
-               /* Reallocates the packet if it is too small or too large */
+            /* Reallocates the packet if it is too small or too large */
             if( p_cache->small.p_stack[l_index].l_size < l_size ||
                 p_cache->small.p_stack[l_index].l_size > 2*l_size )
             {
@@ -624,13 +668,17 @@ static struct data_packet_s * NewPacket( void * p_packet_cache,
         /* Checks whether the buffer cache is empty */
         if( p_cache->large.l_index == 0 )
         {
-           /* Allocates a new packet */
+            /* Allocates a new packet */
             if ( (p_data->p_buffer = malloc( l_size )) == NULL )
             {
-                intf_DbgMsg( "Out of memory" );
+                intf_ErrMsg( "Out of memory" );
                 free( p_data );
+                vlc_mutex_unlock( &p_cache->lock );
                 return NULL;
             }
+#ifdef TRACE_INPUT
+            intf_DbgMsg( "PS input: large buffer allocated" );
+#endif
             p_data->l_size = l_size;
         }
         else
@@ -640,11 +688,12 @@ static struct data_packet_s * NewPacket( void * p_packet_cache,
             if( (p_data->p_buffer = p_cache->large.p_stack[l_index].p_data)
                 == NULL )
             {
-                intf_DbgMsg( "NULL packet in the small buffer cache" );
+                intf_ErrMsg( "NULL packet in the small buffer cache" );
                 free( p_data );
+                vlc_mutex_unlock( &p_cache->lock );
                 return NULL;
             }
-               /* Reallocates the packet if it is too small or too large */
+            /* Reallocates the packet if it is too small or too large */
             if( p_cache->large.p_stack[l_index].l_size < l_size ||
                 p_cache->large.p_stack[l_index].l_size > 2*l_size )
             {
@@ -655,18 +704,19 @@ static struct data_packet_s * NewPacket( void * p_packet_cache,
             {
                 p_data->l_size = p_cache->large.p_stack[l_index].l_size;
             }
-           }
+        }
     }
 
+    vlc_mutex_unlock( &p_cache->lock );
+
     /* Initialize data */
     p_data->p_next = NULL;
     p_data->b_discard_payload = 0;
     p_data->p_payload_start = p_data->p_buffer;
     p_data->p_payload_end = p_data->p_buffer + l_size;
 
-//fprintf(stderr, "addr: %li %li buf %li\n", p_data, p_data->l_size, p_data->p_buffer);
     return( p_data );
-       
+
 }
 
 
@@ -678,11 +728,18 @@ static pes_packet_t * NewPES( void * p_packet_cache )
     packet_cache_t *   p_cache;
     pes_packet_t *     p_pes;
 
-    if ( (p_cache = (packet_cache_t *)p_packet_cache) == NULL )
+    p_cache = (packet_cache_t *)p_packet_cache;
+
+#ifdef DEBUG
+    if ( p_cache == NULL )
     {
         intf_ErrMsg( "Packet cache not initialized" );
         return NULL;
     }
+#endif
+
+    vlc_mutex_lock( &p_cache->lock );  
+
     /* Checks whether the PES cache is empty */
     if( p_cache->pes.l_index == 0 )
     {
@@ -690,8 +747,12 @@ static pes_packet_t * NewPES( void * p_packet_cache )
         if ( (p_pes = malloc( sizeof(pes_packet_t) )) == NULL )
         {
             intf_DbgMsg( "Out of memory" );
+            vlc_mutex_unlock( &p_cache->lock );        
             return NULL;
         }
+#ifdef TRACE_INPUT
+        intf_DbgMsg( "PS input: PES packet allocated" );
+#endif
     }
     else
     {
@@ -699,11 +760,14 @@ static pes_packet_t * NewPES( void * p_packet_cache )
         if( (p_pes = p_cache->pes.p_stack[ -- p_cache->pes.l_index ]) 
             == NULL )
         {
-            intf_DbgMsg( "NULL packet in the data cache" );
+            intf_ErrMsg( "NULL packet in the data cache" );
+            vlc_mutex_unlock( &p_cache->lock );
             return NULL;
         }
     }
-       
+
+    vlc_mutex_unlock( &p_cache->lock );
+
     p_pes->b_data_alignment = p_pes->b_discontinuity =
         p_pes->i_pts = p_pes->i_dts = 0;
     p_pes->i_pes_size = 0;
@@ -720,14 +784,20 @@ static void DeletePacket( void * p_packet_cache,
                           data_packet_t * p_data )
 {
     packet_cache_t *   p_cache;
-       
-    if ( (p_cache = (packet_cache_t *)p_packet_cache) == NULL )
+
+    p_cache = (packet_cache_t *)p_packet_cache;
+
+#ifdef DEBUG
+    if ( p_cache == NULL )
     {
         intf_ErrMsg( "Packet cache not initialized" );
         return;
     }
+#endif
+
+    ASSERT( p_data );
 
-       ASSERT( p_data );
+    vlc_mutex_lock( &p_cache->lock );
 
     /* Checks whether the data cache is full */
     if ( p_cache->data.l_index < DATA_CACHE_SIZE )
@@ -749,9 +819,12 @@ static void DeletePacket( void * p_packet_cache,
             {
                 ASSERT( p_data->p_buffer );
                 free( p_data->p_buffer );
+#ifdef TRACE_INPUT
+                intf_DbgMsg( "PS input: small buffer freed" );
+#endif
             }
         }
-       else
+        else
         {
             /* Checks whether the large buffer cache is full */
             if ( p_cache->large.l_index < LARGE_CACHE_SIZE )
@@ -765,6 +838,9 @@ static void DeletePacket( void * p_packet_cache,
             {
                 ASSERT( p_data->p_buffer );
                 free( p_data->p_buffer );
+#ifdef TRACE_INPUT
+                intf_DbgMsg( "PS input: large buffer freed" );
+#endif
             }
         }
     }
@@ -772,9 +848,13 @@ static void DeletePacket( void * p_packet_cache,
     {
         /* Cache full: the packet must be freed */
         free( p_data->p_buffer );
-       free( p_data );
+        free( p_data );
+#ifdef TRACE_INPUT
+        intf_DbgMsg( "PS input: data packet freed" );
+#endif
     }
 
+    vlc_mutex_unlock( &p_cache->lock );
 }
 
 /*****************************************************************************
@@ -786,11 +866,15 @@ static void DeletePES( void * p_packet_cache, pes_packet_t * p_pes )
     data_packet_t *     p_data;
     data_packet_t *     p_next;
 
-    if ( (p_cache = (packet_cache_t *)p_packet_cache) == NULL )
+    p_cache = (packet_cache_t *)p_packet_cache;
+
+#ifdef DEBUG
+    if ( p_cache == NULL )
     {
         intf_ErrMsg( "Packet cache not initialized" );
         return;
     }
+#endif
 
     ASSERT( p_pes);
 
@@ -803,16 +887,23 @@ static void DeletePES( void * p_packet_cache, pes_packet_t * p_pes )
         p_data = p_next;
     }
 
+    vlc_mutex_lock( &p_cache->lock );
+
     /* Checks whether the PES cache is full */
     if ( p_cache->pes.l_index < PES_CACHE_SIZE )
     {
-       /* Cache not full: store the packet in it */
+        /* Cache not full: store the packet in it */
         p_cache->pes.p_stack[ p_cache->pes.l_index ++ ] = p_pes;
     }
     else
     {
         /* Cache full: the packet must be freed */
         free( p_pes );
+#ifdef TRACE_INPUT
+        intf_DbgMsg( "PS input: PES packet freed" );
+#endif
     }
+
+    vlc_mutex_unlock( &p_cache->lock );
 }