* all: begin to introduce access_t (nothing working yet).
authorLaurent Aimar <fenrir@videolan.org>
Sat, 29 May 2004 23:52:49 +0000 (23:52 +0000)
committerLaurent Aimar <fenrir@videolan.org>
Sat, 29 May 2004 23:52:49 +0000 (23:52 +0000)
include/input_ext-intf.h
include/ninput.h
include/vlc_common.h
include/vlc_objects.h
src/input/access.c [new file with mode: 0644]
src/input/es_out.c
src/misc/messages.c
src/misc/objects.c

index 1944abb..5c94f52 100644 (file)
@@ -300,6 +300,7 @@ struct input_thread_t
     int           (* pf_set_program )( input_thread_t *, pgrm_descriptor_t * );
     int           (* pf_set_area )( input_thread_t *, input_area_t * );
     void          (* pf_seek ) ( input_thread_t *, off_t );
+    int           (* pf_access_control )( input_thread_t *, int, va_list );
     access_sys_t *   p_access_data;
     size_t           i_mtu;
     int              i_pts_delay;                        /* internal caching */
index 1f31b0e..bb19c46 100644 (file)
@@ -51,10 +51,15 @@ enum es_out_query_e
     ES_OUT_SET_ES_STATE,/* arg1= es_out_id_t* arg2=vlc_bool_t   */
     ES_OUT_GET_ES_STATE,/* arg1= es_out_id_t* arg2=vlc_bool_t*  */
 
-    /* XXX XXX XXX Don't use them YET !!! */
+    /* PCR handling, by default dts/pts will be automatically computed using thoses PCR */
     ES_OUT_SET_PCR,             /* arg1=int64_t i_pcr(microsecond!) (using default group 0)*/
     ES_OUT_SET_GROUP_PCR,       /* arg1= int i_group, arg2=int64_t i_pcr(microsecond!)*/
-    ES_OUT_RESET_PCR    /* no arg */
+    ES_OUT_RESET_PCR,           /* no arg */
+
+    /* ByBass automatic stream timestamp to absolute timestamp using pcr (and disable the automatic mode XXX:for all groups) */
+    ES_OUT_CONVERT_TIMESTAMP,       /* arg1=int64_t *pi_ts(microsecond!) */
+    ES_OUT_CONVERT_GROUP_TIMESTAMP, /* arg1=int i_group, arg2=int64_t *pi_ts(microsecond!)*/
+
 };
 
 struct es_out_t
@@ -95,6 +100,71 @@ static inline int es_out_Control( es_out_t *out, int i_query, ... )
     va_end( args );
     return i_result;
 }
+/**
+ * \defgroup access Access
+ * @{
+ */
+
+enum access_query_e
+{
+    /* capabilities */
+    ACCESS_CAN_FASTSEEK,    /* arg1= vlc_bool_t*    cannot fail */
+    ACCESS_CAN_PAUSE,       /* arg1= vlc_bool_t*    cannot fail */
+    ACCESS_CAN_CONTROL_PACE,/* arg1= vlc_bool_t*    cannot fail */
+
+    /* */
+    ACCESS_GET_MTU,         /* arg1= int*           cannot fail (0 if no sense) */
+    ACCESS_GET_SIZE,        /* arg1= int64_t*       cannot fail (0 if unknown) */
+    ACCESS_GET_POS,         /* arg1= int64_t*       cannot fail */
+
+    /* */
+    ACCESS_SET_PAUSE_STATE  /* arg1= vlc_bool_t     can fail if unsuported */
+};
+
+struct access_t
+{
+    VLC_COMMON_MEMBERS
+
+    /* Module properties */
+    module_t    *p_module;
+
+    /* Access name (empty if non forced) */
+    char        *psz_access;
+    char        *psz_path;
+    /* Access can fill this entry to force a deluxer */
+    char        *psz_demux;
+
+    /* set by access (only one of pf_read/pf_block may be filled) */
+    int         (*pf_read) ( access_t *, uint8_t *, int );  /* Return -1 if no data yet, 0 if no more data, else real data read */
+    block_t    *(*pf_block)( access_t * );                  /* return a block of data in his 'natural' size */
+    int         (*pf_seek) ( access_t *, int64_t );
+
+    int         (*pf_control)( access_t *, int i_query, va_list args);
+    access_sys_t *p_sys;
+};
+
+#define access2_New( a, b, c, d ) __acess2_New(VLC_OBJECT(a), b, c, d)
+VLC_EXPORT( demux_t *, __access2_New,  ( vlc_object_t *p_obj, char *psz_mrl, stream_t *s, es_out_t *out ) );
+VLC_EXPORT( void,      access2_Delete, ( demux_t * ) );
+
+static inline int access2_vaControl( access_t *p_access, int i_query, va_list args )
+{
+    return p_access->pf_control( p_access, i_query, args );
+}
+static inline int access2_Control( access_t *p_access, int i_query, ... )
+{
+    va_list args;
+    int     i_result;
+
+    va_start( args, i_query );
+    i_result = access2_vaControl( p_access, i_query, args );
+    va_end( args );
+    return i_result;
+}
+
+/**
+ * @}
+ */
 
 /**
  * \defgroup stream Stream
@@ -328,8 +398,12 @@ VLC_EXPORT( int, demux_Control,          ( input_thread_t *, int i_query, ...  )
 
 VLC_EXPORT( int, demux_vaControlDefault, ( input_thread_t *, int i_query, va_list  ) );
 
+/* Access */
+VLC_EXPORT( int, access_vaControl,       ( input_thread_t *, int i_query, va_list  ) );
+VLC_EXPORT( int, access_Control,         ( input_thread_t *, int i_query, ...  ) );
+VLC_EXPORT( int, access_vaControlDefault,( input_thread_t *, int i_query, va_list  ) );
+
 
-/* New demux arch: don't touch that */
 /* stream_t *s could be null and then it mean a access+demux in one */
 #define demux2_New( a, b, c, d ) __demux2_New(VLC_OBJECT(a), b, c, d)
 VLC_EXPORT( demux_t *, __demux2_New,  ( vlc_object_t *p_obj, char *psz_mrl, stream_t *s, es_out_t *out ) );
index e5cd07d..652c9c6 100644 (file)
@@ -240,6 +240,7 @@ typedef struct es_out_t     es_out_t;
 typedef struct es_out_id_t  es_out_id_t;
 typedef struct es_out_sys_t es_out_sys_t;
 typedef struct demux_t  demux_t;
+typedef struct access_t access_t;
 
 /* Audio */
 typedef struct aout_instance_t aout_instance_t;
index bc48112..ea9c1d0 100644 (file)
@@ -50,6 +50,7 @@
 #define VLC_OBJECT_VLM        (-16)
 #define VLC_OBJECT_ANNOUNCE   (-17)
 #define VLC_OBJECT_DEMUX      (-18)
+#define VLC_OBJECT_ACCESS     (-19)
 
 #define VLC_OBJECT_GENERIC  (-666)
 
diff --git a/src/input/access.c b/src/input/access.c
new file mode 100644 (file)
index 0000000..749aa08
--- /dev/null
@@ -0,0 +1,204 @@
+/*****************************************************************************
+ * access.c
+ *****************************************************************************
+ * Copyright (C) 1999-2004 VideoLAN
+ * $Id: demux.c 7546 2004-04-29 13:53:29Z gbazin $
+ *
+ * Author: Laurent Aimar <fenrir@via.ecp.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <vlc/vlc.h>
+#include <vlc/input.h>
+
+#include "ninput.h"
+
+int access_vaControl( input_thread_t *p_input, int i_query, va_list args )
+{
+    if( p_input->pf_access_control )
+    {
+        return p_input->pf_access_control( p_input, i_query, args );
+    }
+    return VLC_EGENERIC;
+}
+
+int access_Control( input_thread_t *p_input, int i_query, ...  )
+{
+    va_list args;
+    int     i_result;
+
+    va_start( args, i_query );
+    i_result = access_vaControl( p_input, i_query, args );
+    va_end( args );
+
+    return i_result;
+}
+
+int access_vaControlDefault( input_thread_t *p_input, int i_query, va_list args )
+{
+    return VLC_EGENERIC;
+}
+
+/*****************************************************************************
+ * access2_New:
+ *****************************************************************************/
+access_t *__access2_New( vlc_object_t *p_obj,
+                       char *psz_mrl, stream_t *s, es_out_t *out )
+{
+    msg_Err( p_obj, "access2_New not yet implemented" );
+    return NULL;
+#if 0
+    access_t *p_access = vlc_object_create( p_obj, VLC_OBJECT_ACCESS );
+
+    char    *psz_dup = strdup( psz_mrl ? psz_mrl : "" );
+    char    *psz = strchr( psz_dup, ':' );
+    char    *psz_module;
+
+    if( p_demux == NULL )
+    {
+        free( psz_dup );
+        return NULL;
+    }
+
+    /* Parse URL */
+    p_demux->psz_access = NULL;
+    p_demux->psz_demux  = NULL;
+    p_demux->psz_path   = NULL;
+
+    if( psz )
+    {
+        *psz++ = '\0';
+
+        if( psz[0] == '/' && psz[1] == '/' )
+        {
+            psz += 2;
+        }
+        p_demux->psz_path = strdup( psz );
+
+        psz = strchr( psz_dup, '/' );
+        if( psz )
+        {
+            *psz++ = '\0';
+            p_demux->psz_access = strdup( psz_dup );
+            p_demux->psz_demux  = strdup( psz );
+        }
+    }
+    else
+    {
+        p_demux->psz_path = strdup( psz_mrl );
+    }
+    free( psz_dup );
+
+
+    if( p_demux->psz_access == NULL )
+    {
+        p_demux->psz_access = strdup( "" );
+    }
+    if( p_demux->psz_demux == NULL )
+    {
+        p_demux->psz_demux = strdup( "" );
+    }
+    if( p_demux->psz_path == NULL )
+    {
+        p_demux->psz_path = strdup( "" );
+    }
+    msg_Dbg( p_obj, "demux2_New: '%s' -> access='%s' demux='%s' path='%s'",
+             psz_mrl,
+             p_demux->psz_access, p_demux->psz_demux, p_demux->psz_path );
+
+    p_demux->s          = s;
+    p_demux->out        = out;
+
+    p_demux->pf_demux   = NULL;
+    p_demux->pf_control = NULL;
+    p_demux->p_sys      = NULL;
+
+    psz_module = p_demux->psz_demux;
+    if( *psz_module == '\0' && strrchr( p_demux->psz_path, '.' ) )
+    {
+        /* XXX: add only file without any problem here and with strong detection.
+         *  - no .mp3, .a52, ... (aac is added as it works only by file ext anyway
+         *  - wav can't be added 'cause of a52 and dts in them as raw audio
+         */
+        static struct { char *ext; char *demux; } exttodemux[] =
+        {
+            { "aac",  "aac" },
+            { "aiff", "aiff" },
+            { "asf",  "asf" }, { "wmv",  "asf" }, { "wma",  "asf" },
+            { "avi",  "avi" },
+            { "au",   "au" },
+            { "flac", "flac" },
+            { "dv",   "dv" },
+            { "m3u",  "m3u" },
+            { "mkv",  "mkv" }, { "mka",  "mkv" }, { "mks",  "mkv" },
+            { "mp4",  "mp4" }, { "m4a",  "mp4" }, { "mov",  "mp4" }, { "moov", "mp4" },
+            { "mod",  "mod" }, { "xm",   "mod" },
+            { "nsv",  "nsv" },
+            { "ogg",  "ogg" }, { "ogm",  "ogg" },
+            { "pva",  "pva" },
+            { "rm",   "rm" },
+            { "",  "" },
+        };
+
+        char *psz_ext = strrchr( p_demux->psz_path, '.' ) + 1;
+        int  i;
+
+        for( i = 0; exttodemux[i].ext != NULL; i++ )
+        {
+            if( !strcasecmp( psz_ext, exttodemux[i].ext ) )
+            {
+                psz_module = exttodemux[i].demux;
+                break;
+            }
+        }
+    }
+
+    /* Before module_Need (for var_Create...) */
+    vlc_object_attach( p_demux, p_obj );
+
+    p_demux->p_module =
+        module_Need( p_demux, "demux2", psz_module,
+                     !strcmp( psz_module, p_demux->psz_demux ) ? VLC_TRUE : VLC_FALSE );
+
+    if( p_demux->p_module == NULL )
+    {
+        vlc_object_detach( p_demux );
+        free( p_demux->psz_path );
+        free( p_demux->psz_demux );
+        free( p_demux->psz_access );
+        vlc_object_destroy( p_demux );
+        return NULL;
+    }
+
+    return p_demux;
+#endif
+}
+
+/*****************************************************************************
+ * demux2_Delete:
+ *****************************************************************************/
+void access2_Delete( access_t *p_access )
+{
+    module_Unneed( p_access, p_access->p_module );
+    vlc_object_detach( p_access );
+
+    free( p_access->psz_access );
+    free( p_access->psz_path );
+    free( p_access->psz_demux );
+
+    vlc_object_destroy( p_access );
+}
index a129944..a863e9b 100644 (file)
@@ -46,7 +46,7 @@ struct es_out_id_t
 struct es_out_sys_t
 {
     input_thread_t *p_input;
-    vlc_bool_t      b_pcr_set;
+    vlc_bool_t      b_convert_ts_auto;  /* automatically convert TimeStamp */
 
     /* all es */
     int         i_id;
@@ -99,7 +99,7 @@ es_out_t *input_EsOutNew( input_thread_t *p_input )
     out->p_sys      = p_sys;
 
     p_sys->p_input = p_input;
-    p_sys->b_pcr_set = VLC_FALSE;
+    p_sys->b_convert_ts_auto = VLC_TRUE;
 
     p_sys->b_active = VLC_FALSE;
     p_sys->i_mode   = ES_OUT_MODE_AUTO;
@@ -159,7 +159,7 @@ void input_EsOutDelete( es_out_t *out )
 static pgrm_descriptor_t *EsOutAddProgram( es_out_t *out, int i_group )
 {
     input_thread_t    *p_input = out->p_sys->p_input;
-    pgrm_descriptor_t *p_prgm;
+    pgrm_descriptor_t *p_pgrm;
     es_descriptor_t   *p_pmt;
 
     /* FIXME we should use a object variable but a lot of place in src/input
@@ -167,23 +167,23 @@ static pgrm_descriptor_t *EsOutAddProgram( es_out_t *out, int i_group )
     int               i_select = config_GetInt( p_input, "program" );
 
     /* create it */
-    p_prgm = input_AddProgram( p_input, i_group, 0 );
+    p_pgrm = input_AddProgram( p_input, i_group, 0 );
 
     /* XXX welcome to kludge, add a dummy es, if you want to understand
      * why have a look at input_SetProgram. Basicaly, it assume the first
      * es to be the PMT, how that is stupid, nevertheless it is needed for
      * the old ts demuxer */
-    p_pmt = input_AddES( p_input, p_prgm, 0, UNKNOWN_ES, NULL, 0 );
+    p_pmt = input_AddES( p_input, p_pgrm, 0, UNKNOWN_ES, NULL, 0 );
     p_pmt->i_fourcc = VLC_FOURCC( 'n', 'u', 'l', 'l' );
 
     /* Select i_select or the first by default */
     if( p_input->stream.p_selected_program == NULL &&
         ( i_select <= 0 || i_select == i_group ) )
     {
-        p_input->stream.p_selected_program = p_prgm;
+        p_input->stream.p_selected_program = p_pgrm;
     }
 
-    return p_prgm;
+    return p_pgrm;
 }
 
 /**
@@ -297,7 +297,7 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
     es_out_sys_t      *p_sys = out->p_sys;
     input_thread_t    *p_input = p_sys->p_input;
     es_out_id_t       *es = malloc( sizeof( es_out_id_t ) );
-    pgrm_descriptor_t *p_prgm = NULL;
+    pgrm_descriptor_t *p_pgrm = NULL;
     char              psz_cat[sizeof( _("Stream ") ) + 10];
     char              *psz_description;
 
@@ -305,12 +305,12 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
     if( fmt->i_group >= 0 )
     {
         /* search program */
-        p_prgm = input_FindProgram( p_input, fmt->i_group );
+        p_pgrm = input_FindProgram( p_input, fmt->i_group );
 
-        if( p_prgm == NULL )
+        if( p_pgrm == NULL )
         {
             /* Create it */
-            p_prgm = EsOutAddProgram( out, fmt->i_group );
+            p_pgrm = EsOutAddProgram( out, fmt->i_group );
         }
     }
     if( fmt->i_id < 0 )
@@ -319,7 +319,7 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
     }
 
     psz_description = LanguageGetName( fmt->psz_language );
-    es->p_es = input_AddES( p_input, p_prgm, fmt->i_id + 1,
+    es->p_es = input_AddES( p_input, p_pgrm, fmt->i_id + 1,
                             fmt->i_cat, psz_description, 0 );
     es->p_es->i_stream_id = fmt->i_id;
     es->p_es->i_fourcc = fmt->i_codec;
@@ -451,7 +451,7 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
 {
     es_out_sys_t *p_sys = out->p_sys;
 
-    if( p_sys->b_pcr_set )
+    if( p_sys->b_convert_ts_auto )
     {
         pgrm_descriptor_t *p_pgrm = es->p_es->p_pgrm;
         input_thread_t    *p_input = p_sys->p_input;
@@ -665,31 +665,30 @@ static int EsOutControl( es_out_t *out, int i_query, va_list args )
         case ES_OUT_SET_PCR:
         case ES_OUT_SET_GROUP_PCR:
         {
-            pgrm_descriptor_t *p_prgm = NULL;
+            pgrm_descriptor_t *p_pgrm = NULL;
             int64_t           i_pcr;
 
             if( i_query == ES_OUT_SET_PCR )
             {
-                p_prgm = p_sys->p_input->stream.p_selected_program;
+                p_pgrm = p_sys->p_input->stream.p_selected_program;
             }
             else
             {
                 int i_group = (int)va_arg( args, int );
-                p_prgm = input_FindProgram( p_sys->p_input, i_group );
-                if( p_prgm == NULL )
+                p_pgrm = input_FindProgram( p_sys->p_input, i_group );
+                if( p_pgrm == NULL )
                 {
                     /* we create the requested program */
-                    p_prgm = EsOutAddProgram( out, i_group );
+                    p_pgrm = EsOutAddProgram( out, i_group );
                 }
             }
             i_pcr = (int64_t)va_arg( args, int64_t );
             /* search program */
-            if( p_prgm )
+            if( p_pgrm )
             {
                 /* 11 is a vodoo trick to avoid non_pcr*9/100 to be null */
-                input_ClockManageRef( p_sys->p_input, p_prgm, (i_pcr + 11 ) * 9 / 100);
+                input_ClockManageRef( p_sys->p_input, p_pgrm, (i_pcr + 11 ) * 9 / 100);
             }
-            p_sys->b_pcr_set = VLC_TRUE;
             return VLC_SUCCESS;
         }
 
@@ -700,9 +699,32 @@ static int EsOutControl( es_out_t *out, int i_query, va_list args )
                     SYNCHRO_REINIT;
                 p_sys->p_input->stream.pp_programs[i]->last_pts = 0;
             }
-            p_sys->b_pcr_set = VLC_TRUE;
             return VLC_SUCCESS;
 
+        case ES_OUT_CONVERT_TIMESTAMP:
+        case ES_OUT_CONVERT_GROUP_TIMESTAMP:
+        {
+            pgrm_descriptor_t *p_pgrm = NULL;
+
+            if( i_query == ES_OUT_CONVERT_TIMESTAMP )
+            {
+                p_pgrm = p_sys->p_input->stream.p_selected_program;
+            }
+            else
+            {
+                int i_group = (int)va_arg( args, int );
+                p_pgrm = input_FindProgram( p_sys->p_input, i_group );
+            }
+            if( p_pgrm )
+            {
+                int64_t *pi_ts = (int64_t*)va_arg( args, int64_t* );
+
+                *pi_ts = input_ClockGetTS( p_sys->p_input, p_pgrm, ( *pi_ts + 11 ) * 9 / 100 );
+            }
+            p_sys->b_convert_ts_auto = VLC_FALSE;
+            return VLC_SUCCESS;
+        }
+
         default:
             msg_Err( p_sys->p_input, "unknown query in es_out_Control" );
             return VLC_EGENERIC;
index 3e32998..589eb66 100644 (file)
@@ -496,6 +496,7 @@ static void PrintMsg ( vlc_object_t * p_this, msg_item_t * p_item )
         case VLC_OBJECT_VLM: psz_object = "vlm"; break;
         case VLC_OBJECT_ANNOUNCE: psz_object = "announce handler"; break;
         case VLC_OBJECT_DEMUX: psz_object = "demuxer"; break;
+        case VLC_OBJECT_ACCESS: psz_object = "access"; break;
     }
 
 #ifdef UNDER_CE
index 4413a7d..025eab5 100644 (file)
@@ -132,6 +132,10 @@ void * __vlc_object_create( vlc_object_t *p_this, int i_type )
             i_size = sizeof(demux_t);
             psz_type = "demux";
             break;
+        case VLC_OBJECT_ACCESS:
+            i_size = sizeof(access_t);
+            psz_type = "access";
+            break;
         case VLC_OBJECT_DECODER:
             i_size = sizeof(decoder_t);
             psz_type = "decoder";