]> git.sesse.net Git - vlc/blobdiff - src/input/input_ext-plugins.c
* ALL: libvlc now compiles and run under WinCE. I haven't ported any modules
[vlc] / src / input / input_ext-plugins.c
index 4e7d20560094b109658b6a477709b1458d57e097..c26270427435f255b027f67365bc46718c1f12fb 100644 (file)
@@ -2,7 +2,7 @@
  * input_ext-plugins.c: useful functions for access and demux plug-ins
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: input_ext-plugins.c,v 1.3 2002/03/26 23:08:40 gbazin Exp $
+ * $Id: input_ext-plugins.c,v 1.21 2002/11/10 23:41:53 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
  * Preamble
  *****************************************************************************/
 #include <stdlib.h>
+#include <string.h>
 
-#ifdef HAVE_SYS_TIME_H
-#    include <sys/time.h>
+#include <vlc/vlc.h>
+
+#ifdef HAVE_SYS_STAT_H
+#   include <sys/stat.h>
 #endif
 
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
+#ifdef HAVE_ERRNO_H
+#   include <errno.h>
+#endif
 
-#include <videolan/vlc.h>
+#ifdef HAVE_FCNTL_H
+#   include <fcntl.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#    include <sys/time.h>
+#endif
 
 #ifdef HAVE_UNISTD_H
 #   include <unistd.h>
-#elif defined( _MSC_VER ) && defined( _WIN32 )
+#elif defined( _MSC_VER ) && defined( _WIN32 ) && !defined( UNDER_CE )
 #   include <io.h>
 #endif
 
-#ifdef WIN32
-#   include <winsock2.h>
-#   include <ws2tcpip.h>
-#elif !defined( SYS_BEOS ) && !defined( SYS_NTO )
-#   include <netdb.h>                                         /* hostent ... */
-#   include <sys/socket.h>
-#   include <netinet/in.h>
-#   ifdef HAVE_ARPA_INET_H
-#       include <arpa/inet.h>                    /* inet_ntoa(), inet_aton() */
-#   endif
-#endif
-
-#ifdef WIN32
+#ifdef UNDER_CE
+    /* No network support */
+#elif defined( WIN32 )
 #   include <winsock2.h>
 #   include <ws2tcpip.h>
 #elif !defined( SYS_BEOS ) && !defined( SYS_NTO )
-#   include <netdb.h>                                         /* hostent ... */
-#   include <sys/socket.h>
-#   include <netinet/in.h>
-#   ifdef HAVE_ARPA_INET_H
-#       include <arpa/inet.h>                    /* inet_ntoa(), inet_aton() */
-#   endif
+#   include <sys/types.h>
+#   include <sys/socket.h>                                         /* recv() */
 #endif
 
-
-
 #include "stream_control.h"
 #include "input_ext-intf.h"
 #include "input_ext-dec.h"
@@ -91,9 +82,9 @@
 /*****************************************************************************
  * data_buffer_t: shared data type
  *****************************************************************************/
-typedef struct data_buffer_s
+struct data_buffer_t
 {
-    struct data_buffer_s * p_next;
+    data_buffer_t * p_next;
 
     /* number of data packets this buffer is referenced from - when it falls
      * down to 0, the buffer is freed */
@@ -101,7 +92,7 @@ typedef struct data_buffer_s
 
     /* size of the current buffer (starting right after this byte) */
     size_t i_size;
-} data_buffer_t;
+};
 
 /*****************************************************************************
  * input_buffers_t: defines a LIFO per data type to keep
@@ -113,32 +104,32 @@ struct                                                                      \
     unsigned int i_depth;                                                   \
 } NAME;
 
-typedef struct input_buffers_s
+struct input_buffers_t
 {
     vlc_mutex_t lock;
     PACKETS_LIFO( pes_packet_t, pes )
     PACKETS_LIFO( data_packet_t, data )
     PACKETS_LIFO( data_buffer_t, buffers )
     size_t i_allocated;
-} input_buffers_t;
+};
 
 
 /*****************************************************************************
  * input_BuffersInit: initialize the cache structures, return a pointer to it
  *****************************************************************************/
-void * input_BuffersInit( void )
+void * __input_BuffersInit( vlc_object_t *p_this )
 {
     input_buffers_t * p_buffers = malloc( sizeof( input_buffers_t ) );
 
     if( p_buffers == NULL )
     {
-        return( NULL );
+        return NULL;
     }
 
     memset( p_buffers, 0, sizeof( input_buffers_t ) );
-    vlc_mutex_init( &p_buffers->lock );
+    vlc_mutex_init( p_this, &p_buffers->lock );
 
-    return( p_buffers );
+    return p_buffers;
 }
 
 /*****************************************************************************
@@ -152,19 +143,13 @@ void * input_BuffersInit( void )
         p_packet = p_next;                                                  \
     }
 
-void input_BuffersEnd( input_buffers_t * p_buffers )
+void input_BuffersEnd( input_thread_t * p_input, input_buffers_t * p_buffers )
 {
     if( p_buffers != NULL )
     {
-        if( p_main->b_stats )
-        {
-            intf_StatMsg( "input buffers stats: pes: %d packets",
-                          p_buffers->pes.i_depth );
-            intf_StatMsg( "input buffers stats: data: %d packets",
-                          p_buffers->data.i_depth );
-            intf_StatMsg( "input buffers stats: buffers: %d packets",
-                          p_buffers->buffers.i_depth );
-        }
+        msg_Dbg( p_input, "pes: %d packets", p_buffers->pes.i_depth );
+        msg_Dbg( p_input, "data: %d packets", p_buffers->data.i_depth );
+        msg_Dbg( p_input, "buffers: %d packets", p_buffers->buffers.i_depth );
 
         {
             /* Free PES */
@@ -192,9 +177,8 @@ void input_BuffersEnd( input_buffers_t * p_buffers )
 
         if( p_buffers->i_allocated )
         {
-            intf_ErrMsg( "input buffers error: %d bytes have not been"
-                         " freed, expect memory leak",
-                         p_buffers->i_allocated );
+            msg_Err( p_input, "%d bytes have not been freed, "
+                              "expect memory leak", p_buffers->i_allocated );
         }
 
         vlc_mutex_destroy( &p_buffers->lock );
@@ -205,16 +189,14 @@ void input_BuffersEnd( input_buffers_t * p_buffers )
 /*****************************************************************************
  * input_NewBuffer: return a pointer to a data buffer of the appropriate size
  *****************************************************************************/
-static __inline__ data_buffer_t * NewBuffer( input_buffers_t * p_buffers,
-                                             size_t i_size )
+static inline data_buffer_t * NewBuffer( input_buffers_t * p_buffers,
+                                         size_t i_size )
 {
     data_buffer_t * p_buf;
 
     /* Safety check */
     if( p_buffers->i_allocated > INPUT_MAX_ALLOCATION )
     {
-        intf_ErrMsg( "INPUT_MAX_ALLOCATION reached (%d)",
-                     p_buffers->i_allocated );
         return NULL;
     } 
 
@@ -233,7 +215,6 @@ static __inline__ data_buffer_t * NewBuffer( input_buffers_t * p_buffers,
             p_buf = malloc( sizeof(input_buffers_t) + i_size );
             if( p_buf == NULL )
             {
-                intf_ErrMsg( "Out of memory" );
                 return NULL;
             }
             p_buf->i_size = i_size;
@@ -246,7 +227,6 @@ static __inline__ data_buffer_t * NewBuffer( input_buffers_t * p_buffers,
         p_buf = malloc( sizeof(input_buffers_t) + i_size );
         if( p_buf == NULL )
         {
-            intf_ErrMsg( "Out of memory" );
             return NULL;
         }
         p_buf->i_size = i_size;
@@ -257,7 +237,7 @@ static __inline__ data_buffer_t * NewBuffer( input_buffers_t * p_buffers,
     p_buf->p_next = NULL;
     p_buf->i_refcount = 0;
 
-    return( p_buf );
+    return p_buf;
 }
 
 data_buffer_t * input_NewBuffer( input_buffers_t * p_buffers, size_t i_size )
@@ -268,14 +248,14 @@ data_buffer_t * input_NewBuffer( input_buffers_t * p_buffers, size_t i_size )
     p_buf = NewBuffer( p_buffers, i_size );
     vlc_mutex_unlock( &p_buffers->lock );
 
-    return( p_buf );
+    return p_buf;
 }
 
 /*****************************************************************************
  * input_ReleaseBuffer: put a buffer back into the cache
  *****************************************************************************/
-static __inline__ void ReleaseBuffer( input_buffers_t * p_buffers,
-                                      data_buffer_t * p_buf )
+static inline void ReleaseBuffer( input_buffers_t * p_buffers,
+                                  data_buffer_t * p_buf )
 {
     /* Decrement refcount */
     if( --p_buf->i_refcount > 0 )
@@ -307,8 +287,8 @@ void input_ReleaseBuffer( input_buffers_t * p_buffers, data_buffer_t * p_buf )
 /*****************************************************************************
  * input_ShareBuffer: allocate a data_packet_t pointing to a given buffer
  *****************************************************************************/
-static __inline__ data_packet_t * ShareBuffer( input_buffers_t * p_buffers,
-                                               data_buffer_t * p_buf )
+static inline data_packet_t * ShareBuffer( input_buffers_t * p_buffers,
+                                           data_buffer_t * p_buf )
 {
     data_packet_t * p_data;
 
@@ -325,7 +305,6 @@ static __inline__ data_packet_t * ShareBuffer( input_buffers_t * p_buffers,
         p_data = malloc( sizeof(data_packet_t) );
         if( p_data == NULL )
         {
-            intf_ErrMsg( "Out of memory" );
             return NULL;
         }
     }
@@ -338,7 +317,7 @@ static __inline__ data_packet_t * ShareBuffer( input_buffers_t * p_buffers,
     p_data->p_payload_end = p_data->p_demux_start + p_buf->i_size;
     p_buf->i_refcount++;
 
-    return( p_data );
+    return p_data;
 }
 
 data_packet_t * input_ShareBuffer( input_buffers_t * p_buffers,
@@ -350,21 +329,23 @@ data_packet_t * input_ShareBuffer( input_buffers_t * p_buffers,
     p_data = ShareBuffer( p_buffers, p_buf );
     vlc_mutex_unlock( &p_buffers->lock );
 
-    return( p_data );
+    return p_data;
 }
 
 /*****************************************************************************
  * input_NewPacket: allocate a packet along with a buffer
  *****************************************************************************/
-static __inline__ data_packet_t * NewPacket( input_buffers_t * p_buffers,
-                                             size_t i_size )
+static inline data_packet_t * NewPacket( input_buffers_t * p_buffers,
+                                         size_t i_size )
 {
-    data_buffer_t * p_buf = NewBuffer( p_buffers, i_size );
+    data_buffer_t * p_buf;
     data_packet_t * p_data;
 
+    p_buf = NewBuffer( p_buffers, i_size );
+
     if( p_buf == NULL )
     {
-        return( NULL );
+        return NULL;
     }
 
     p_data = ShareBuffer( p_buffers, p_buf );
@@ -372,7 +353,7 @@ static __inline__ data_packet_t * NewPacket( input_buffers_t * p_buffers,
     {
         ReleaseBuffer( p_buffers, p_buf );
     }
-    return( p_data );
+    return p_data;
 }
 
 data_packet_t * input_NewPacket( input_buffers_t * p_buffers, size_t i_size )
@@ -383,14 +364,14 @@ data_packet_t * input_NewPacket( input_buffers_t * p_buffers, size_t i_size )
     p_data = NewPacket( p_buffers, i_size );
     vlc_mutex_unlock( &p_buffers->lock );
 
-    return( p_data );
+    return p_data;
 }
 
 /*****************************************************************************
  * input_DeletePacket: deallocate a packet and its buffers
  *****************************************************************************/
-static __inline__ void DeletePacket( input_buffers_t * p_buffers,
-                                     data_packet_t * p_data )
+static inline void DeletePacket( input_buffers_t * p_buffers,
+                                 data_packet_t * p_data )
 {
     while( p_data != NULL )
     {
@@ -424,7 +405,7 @@ void input_DeletePacket( input_buffers_t * p_buffers, data_packet_t * p_data )
 /*****************************************************************************
  * input_NewPES: return a pointer to a new PES packet
  *****************************************************************************/
-static __inline__ pes_packet_t * NewPES( input_buffers_t * p_buffers )
+static inline pes_packet_t * NewPES( input_buffers_t * p_buffers )
 {
     pes_packet_t * p_pes;
 
@@ -441,7 +422,6 @@ static __inline__ pes_packet_t * NewPES( input_buffers_t * p_buffers )
         p_pes = malloc( sizeof(pes_packet_t) );
         if( p_pes == NULL )
         {
-            intf_ErrMsg( "Out of memory" );
             return NULL;
         }
     }
@@ -453,7 +433,7 @@ static __inline__ pes_packet_t * NewPES( input_buffers_t * p_buffers )
     p_pes->i_pes_size = 0;
     p_pes->i_nb_data = 0;
 
-    return( p_pes );
+    return p_pes;
 }
 
 pes_packet_t * input_NewPES( input_buffers_t * p_buffers )
@@ -464,15 +444,15 @@ pes_packet_t * input_NewPES( input_buffers_t * p_buffers )
     p_pes = NewPES( p_buffers );
     vlc_mutex_unlock( &p_buffers->lock );
 
-    return( p_pes );
+    return p_pes;
 }
 
 /*****************************************************************************
  * input_DeletePES: put a pes and all data packets and all buffers back into
  *                  the cache
  *****************************************************************************/
-static __inline__ void DeletePES( input_buffers_t * p_buffers,
-                                  pes_packet_t * p_pes )
+static inline void DeletePES( input_buffers_t * p_buffers,
+                              pes_packet_t * p_pes )
 {
     while( p_pes != NULL )
     {
@@ -531,14 +511,19 @@ ssize_t input_FillBuffer( input_thread_t * p_input )
                        i_remains + p_input->i_bufsize );
     if( p_buf == NULL )
     {
-        return( -1 );
+        msg_Err( p_input, "failed allocating a new buffer (decoder stuck?)" );
+        return -1;
     }
     p_buf->i_refcount = 1;
 
     if( p_input->p_data_buffer != NULL )
     {
-        FAST_MEMCPY( (byte_t *)p_buf + sizeof(data_buffer_t),
-                     p_input->p_current_data, (size_t)i_remains );
+        if( i_remains )
+        {
+            p_input->p_vlc->pf_memcpy( (byte_t *)p_buf + sizeof(data_buffer_t),
+                                       p_input->p_current_data,
+                                       (size_t)i_remains );
+        }
         ReleaseBuffer( p_input->p_method_data, p_input->p_data_buffer );
     }
 
@@ -546,16 +531,16 @@ ssize_t input_FillBuffer( input_thread_t * p_input )
     vlc_mutex_unlock( &p_input->p_method_data->lock );
 
     i_ret = p_input->pf_read( p_input,
-                             (byte_t *)p_buf + sizeof(data_buffer_t)
-                              + i_remains,
-                             p_input->i_bufsize );
-
+                              (byte_t *)p_buf + sizeof(data_buffer_t)
+                               + i_remains,
+                              p_input->i_bufsize );
     if( i_ret < 0 ) i_ret = 0;
+
     p_input->p_data_buffer = p_buf;
     p_input->p_current_data = (byte_t *)p_buf + sizeof(data_buffer_t);
     p_input->p_last_data = p_input->p_current_data + i_remains + i_ret;
 
-    return( (ssize_t)i_remains + i_ret );
+    return (ssize_t)i_remains + i_ret;
 }
 
 /*****************************************************************************
@@ -572,7 +557,7 @@ ssize_t input_Peek( input_thread_t * p_input, byte_t ** pp_byte, size_t i_size )
 
         if( i_size == -1 )
         {
-            return( -1 );
+            return -1;
         }
         else if( i_ret < i_size )
         {
@@ -580,7 +565,7 @@ ssize_t input_Peek( input_thread_t * p_input, byte_t ** pp_byte, size_t i_size )
         }
     }
     *pp_byte = p_input->p_current_data;
-    return( i_size );
+    return i_size;
 }
 
 /*****************************************************************************
@@ -597,7 +582,7 @@ ssize_t input_SplitBuffer( input_thread_t * p_input,
 
         if( i_ret == -1 )
         {
-            return( -1 );
+            return -1;
         }
         else if( i_ret < i_size )
         {
@@ -605,6 +590,11 @@ ssize_t input_SplitBuffer( input_thread_t * p_input,
         }
     }
 
+    if ( !i_size )
+    {
+        return 0;
+    }
+
     *pp_data = input_ShareBuffer( p_input->p_method_data,
                                   p_input->p_data_buffer );
 
@@ -614,7 +604,12 @@ ssize_t input_SplitBuffer( input_thread_t * p_input,
 
     p_input->p_current_data += i_size;
 
-    return( i_size );
+    /* Update stream position */
+    vlc_mutex_lock( &p_input->stream.stream_lock );
+    p_input->stream.p_selected_area->i_tell += i_size;
+    vlc_mutex_unlock( &p_input->stream.stream_lock );
+    return i_size;
 }
 
 /*****************************************************************************
@@ -622,12 +617,12 @@ ssize_t input_SplitBuffer( input_thread_t * p_input,
  *****************************************************************************/
 int input_AccessInit( input_thread_t * p_input )
 {
-    p_input->p_method_data = input_BuffersInit();
-    if( p_input->p_method_data == NULL ) return( -1 );
+    p_input->p_method_data = input_BuffersInit( p_input );
+    if( p_input->p_method_data == NULL ) return -1;
     p_input->p_data_buffer = NULL;
     p_input->p_current_data = NULL;
     p_input->p_last_data = NULL;
-    return( 0 );
+    return 0;
 }
 
 /*****************************************************************************
@@ -654,7 +649,7 @@ void input_AccessEnd( input_thread_t * p_input )
         ReleaseBuffer( p_input->p_method_data, p_input->p_data_buffer );
     }
 
-    input_BuffersEnd( p_input->p_method_data );
+    input_BuffersEnd( p_input, p_input->p_method_data );
 }
 
 
@@ -666,14 +661,42 @@ void input_AccessEnd( input_thread_t * p_input )
 /*****************************************************************************
  * input_FDClose: close the target
  *****************************************************************************/
-void input_FDClose( input_thread_t * p_input )
+void __input_FDClose( vlc_object_t * p_this )
 {
+    input_thread_t * p_input = (input_thread_t *)p_this;
     input_socket_t * p_access_data = (input_socket_t *)p_input->p_access_data;
 
-    intf_WarnMsg( 2, "input: closing `%s/%s:%s'", 
-                  p_input->psz_access, p_input->psz_demux, p_input->psz_name );
+    msg_Info( p_input, "closing `%s/%s://%s'", 
+              p_input->psz_access, p_input->psz_demux, p_input->psz_name );
  
+#ifdef UNDER_CE
+    CloseHandle( (HANDLE)p_access_data->i_handle );
+#else
     close( p_access_data->i_handle );
+#endif
+
+    free( p_access_data );
+}
+
+/*****************************************************************************
+ * input_FDNetworkClose: close a network target
+ *****************************************************************************/
+void __input_FDNetworkClose( vlc_object_t * p_this )
+{
+    input_thread_t * p_input = (input_thread_t *)p_this;
+    input_socket_t * p_access_data = (input_socket_t *)p_input->p_access_data;
+
+    msg_Info( p_input, "closing network `%s/%s://%s'", 
+              p_input->psz_access, p_input->psz_demux, p_input->psz_name );
+#ifdef UNDER_CE
+    CloseHandle( (HANDLE)p_access_data->i_handle );
+#elif defined( WIN32 )
+    closesocket( p_access_data->i_handle );
+#else
+    close( p_access_data->i_handle );
+#endif
+
     free( p_access_data );
 }
 
@@ -683,29 +706,39 @@ void input_FDClose( input_thread_t * p_input )
 ssize_t input_FDRead( input_thread_t * p_input, byte_t * p_buffer, size_t i_len )
 {
     input_socket_t * p_access_data = (input_socket_t *)p_input->p_access_data;
+    ssize_t i_ret;
  
-    ssize_t i_ret = read( p_access_data->i_handle, p_buffer, i_len );
-    if( i_ret > 0 )
+#ifdef UNDER_CE
+    if( !ReadFile( (HANDLE)p_access_data->i_handle, p_buffer, i_len,
+                   (LPWORD)&i_ret, NULL ) )
     {
-        vlc_mutex_lock( &p_input->stream.stream_lock );
-        p_input->stream.p_selected_area->i_tell += i_ret;
-        vlc_mutex_unlock( &p_input->stream.stream_lock );
+        i_ret = -1;
     }
+#else
+    i_ret = read( p_access_data->i_handle, p_buffer, i_len );
+#endif
  
     if( i_ret < 0 )
     {
-        intf_ErrMsg( "input error: read() failed (%s)", strerror(errno) );
+#   ifdef HAVE_ERRNO_H
+        msg_Err( p_input, "read failed (%s)", strerror(errno) );
+#   else
+        msg_Err( p_input, "read failed" );
+#   endif
     }
  
-    return( i_ret );
+    return i_ret;
 }
 
 /*****************************************************************************
  * NetworkSelect: Checks whether data is available on a file descriptor
  *****************************************************************************/
-static __inline__ int NetworkSelect( input_thread_t * p_input )
+static inline int NetworkSelect( input_thread_t * p_input )
 {
+#ifdef UNDER_CE
+    return -1;
+
+#else
     input_socket_t * p_access_data = (input_socket_t *)p_input->p_access_data;
     struct timeval  timeout;
     fd_set          fds;
@@ -723,12 +756,14 @@ static __inline__ int NetworkSelect( input_thread_t * p_input )
     i_ret = select( p_access_data->i_handle + 1, &fds,
                      NULL, NULL, &timeout );
  
-    if( i_ret == -1 )
+    if( i_ret == -1 && errno != EINTR )
     {
-        intf_ErrMsg( "input error: network select error (%s)", strerror(errno) );
+        msg_Err( p_input, "network select error (%s)", strerror(errno) );
     }
 
-    return( i_ret );
+    return i_ret;
+
+#endif
 }
 
 /*****************************************************************************
@@ -738,6 +773,10 @@ static __inline__ int NetworkSelect( input_thread_t * p_input )
 ssize_t input_FDNetworkRead( input_thread_t * p_input, byte_t * p_buffer,
                              size_t i_len )
 {
+#ifdef UNDER_CE
+    return -1;
+
+#else
     if( NetworkSelect( p_input ) > 0 )
     {
         input_socket_t * p_access_data
@@ -754,13 +793,15 @@ ssize_t input_FDNetworkRead( input_thread_t * p_input, byte_t * p_buffer,
 
         if( i_ret < 0 )
         {
-            intf_ErrMsg( "input error: recv() failed (%s)", strerror(errno) );
+            msg_Err( p_input, "recv failed (%s)", strerror(errno) );
         }
 
-        return( i_ret );
+        return i_ret;
     }
     
-    return( 0 );
+    return 0;
+
+#endif
 }
 
 /*****************************************************************************
@@ -768,13 +809,25 @@ ssize_t input_FDNetworkRead( input_thread_t * p_input, byte_t * p_buffer,
  *****************************************************************************/
 void input_FDSeek( input_thread_t * p_input, off_t i_pos )
 {
+#define S p_input->stream
     input_socket_t * p_access_data = (input_socket_t *)p_input->p_access_data;
 
     lseek( p_access_data->i_handle, i_pos, SEEK_SET );
 
-    vlc_mutex_lock( &p_input->stream.stream_lock );
-    p_input->stream.p_selected_area->i_tell = i_pos;
-    vlc_mutex_unlock( &p_input->stream.stream_lock );
+    vlc_mutex_lock( &S.stream_lock );
+    S.p_selected_area->i_tell = i_pos;
+    if( S.p_selected_area->i_tell > S.p_selected_area->i_size )
+    {
+        msg_Err( p_input, "seeking too far" );
+        S.p_selected_area->i_tell = S.p_selected_area->i_size;
+    }
+    else if( S.p_selected_area->i_tell < 0 )
+    {
+        msg_Err( p_input, "seeking too early" );
+        S.p_selected_area->i_tell = 0;
+    }
+    vlc_mutex_unlock( &S.stream_lock );
+#undef S
 }