Hi,<br><br>Thanks for your kindly code review. I indeed had debugged and tested this small access module. It can be compiled and work fine for me. But I trim some trailing whitespace before commit and make patch, I think that operation make the source code uncompilable. I am sorry. <br>

By the way, I wrote this module by using http access module as template, the source code is not clean enough :) So I resubmit my patch base on Rémi Denis-Courmont's comments.<br><br><div class="gmail_quote">2009/4/2 Rémi Denis-Courmont <span dir="ltr"><<a href="mailto:rem@videolan.org" target="_blank">rem@videolan.org</a>></span><br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
        Hello,<br>
<br>
Le mercredi 1 avril 2009 17:31:00 zhigang wang, vous avez écrit :<br>
<div><div></div><div>> The module I write is for the GSoC qualification task. This task is not<br>
> list on " VLC selection tasks".<br>
> Truran VoD system is used by our school VoD system. There is only a windows<br>
> client support this VoD system. I wrote this small access module of VLC<br>
> these days so that I can play videos of this VoD system on linux.<br>
><br>
> Please give me some commit. If it's not enough for qualifuction task, I<br>
> will choose another selection task.<br>
<br>
</div></div>As JB said, this is enough as far as GSoC qualification is concerned.<br>
<br>
Nevertheless, some comments inline:<br>
<br>
diff --git a/modules/access/truran_vod.c b/modules/access/truran_vod.c<br>
new file mode 100644<br>
index 0000000..4ae21cc<br>
--- /dev/null<br>
+++ b/modules/access/truran_vod.c<br>
@@ -0,0 +1,599 @@<br>
+/*****************************************************************************<br>
+ * truran_vod.c: Truran VOD input module<br>
+<br>
*****************************************************************************<br>
+ * Copyright (C) 2009 the VideoLAN team<br>
<br>
You need the license boilerplate here.<br>
<br>
+ * $Id$\movie\test.avi<br>
        ^^^^^^^^^^^^^^^<br>
What's this?<br>
<br>
+#define VOD_DEBUG<br>
+*/<br>
+#define MTU (32*1024)<br>
<br>
Is there a specific reason for 32kb read segmentation?<br>
<br>
+#ifdef VOD_DEBUG<br>
+#include <stdio.h><br>
+#endif<br>
+<br>
+#undef ATTRIBUTE_PACKED<br>
+<br>
+#if defined(__GNUC__)<br>
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)<br>
+#define ATTRIBUTE_PACKED __attribute__ ((packed))<br>
+#define PRAGMA_PACK 0<br>
+#endif<br>
+#endif<br>
<br>
We have HAVE_ATTRIBUTE_PACKED in <config.h> for this.<br>
<br>
+#if !defined(ATTRIBUTE_PACKED)<br>
+#define ATTRIBUTE_PACKED<br>
+#define PRAGMA_PACK 1<br>
+#endif<br>
+<br>
+#if PRAGMA_PACK<br>
+#pragma pack(1)<br>
+#endif<br>
+<br>
+/*****************************************************************************<br>
+ * Module descriptor<br>
+<br>
*****************************************************************************/<br>
+#define CACHING_TEXT N_("Caching value in ms")<br>
+#define CACHING_LONGTEXT N_( \<br>
+    "Caching value for Truran VOD streams. This " \<br>
+    "value should be set in milliseconds." )<br>
+<br>
+#define RECONNECT_TEXT N_("Auto re-connect")<br>
+#define RECONNECT_LONGTEXT N_( \<br>
+    "Automatically try to reconnect to the stream in case of a sudden " \<br>
+    "disconnect." )<br>
+<br>
+static int  Open ( vlc_object_t * );<br>
+static void Close( vlc_object_t * );<br>
<br>
Where are the #include lines? Where did you define vlc_object_t? Can you even<br>
even compile this?<br>
<br>
+vlc_module_begin();<br>
+    set_shortname( N_("VOD" ) );<br>
+    set_description( N_("Truran VOD input") );<br>
+    set_category( CAT_INPUT );<br>
+    set_subcategory( SUBCAT_INPUT_ACCESS );<br>
+<br>
+    add_integer( "vod-caching", DEFAULT_PTS_DELAY / 1000, NULL, CACHING_TEXT,<br>
+                 CACHING_LONGTEXT, true );<br>
+<br>
+     add_bool( "vod-reconnect", 0, NULL, RECONNECT_TEXT,<br>
+              RECONNECT_LONGTEXT, true );<br>
+<br>
+    set_capability( "access", 0 );<br>
+    add_shortcut( "vod" );<br>
+<br>
+    set_callbacks( Open, Close );<br>
+vlc_module_end();<br>
+<br>
+/*****************************************************************************<br>
+ * Local prototypes<br>
+<br>
*****************************************************************************/<br>
+#if PRAGMA_PACK<br>
+#pragma pack(1)<br>
+#endif<br>
+<br>
+typedef struct {<br>
+    char magic[4];<br>
+    unsigned int ver;          /* always 00 02 00 00 */<br>
+    unsigned int type;         /* ok = 00 00 00 00, err = 0c 00 00 00 */<br>
+    unsigned int unknown1;     /* always 00 00 00 00 */<br>
+    unsigned int len_lo;               /* lower 32 bits of length */<br>
+    unsigned int len_hi;               /* higher 32 bits of length */<br>
+    unsigned int pos_lo;               /* lower 32 bits of position */<br>
+    unsigned int pos_hi;               /* higher 32 bits of position */<br>
+    unsigned int unknown2;     /* always 00 00 01 00 */<br>
+    unsigned int unknown3;     /* always 00 00 00 00 */<br>
+    unsigned int unknown4;     /* ok = 64 00 00 00, err = 00 00 00 00 */<br>
+    char errmsg[100];<br>
+    char name[260];<br>
+    char date[108];<br>
+} ATTRIBUTE_PACKED response_t;<br>
<br>
I guess you are assuming that unsigned int is 32-bits. You should really use<br>
uint32_t instead.<br>
<br>
+<br>
+#if PRAGMA_PACK<br>
+#pragma pack()<br>
+#endif<br>
+<br>
+struct access_sys_t {<br>
+    int fd;<br>
+<br>
+    /* From uri */<br>
+    vlc_url_t url;<br>
+<br>
+    int i_code; /*must be 200*/<br>
+    char       *psz_mime;<br>
+    response_t resp;<br>
<br>
Do you really need to keep the response buffer in the plugin state?<br>
<br>
+    bool b_seekable;<br>
<br>
This seems to be always true. Then you should remove it.<br>
<br>
+    bool b_reconnect;<br>
+#ifdef VOD_DEBUG<br>
+    FILE* out_fd;<br>
+#endif<br>
+};<br>
+<br>
+/* */<br>
+static ssize_t Read( access_t *, uint8_t *, size_t );<br>
+static block_t *Block( access_t *p_access );<br>
+static int Seek( access_t *, int64_t );<br>
+static int Control( access_t *, int, va_list );<br>
+<br>
+/* */<br>
+static int Connect( access_t *, int64_t );<br>
+static int Request( access_t *p_access, int64_t i_tell );<br>
+static void Disconnect( access_t * );<br>
+<br>
+/*****************************************************************************<br>
+ * Open:<br>
+<br>
*****************************************************************************/<br>
+static int Open( vlc_object_t *p_this )<br>
+{<br>
+    access_t     *p_access = (access_t*)p_this;<br>
+    access_sys_t *p_sys;<br>
+    char         *psz, *p;<br>
+<br>
+    /* Set up p_access */<br>
+#if 1<br>
+    STANDARD_READ_ACCESS_INIT;<br>
+#else<br>
+    STANDARD_BLOCK_ACCESS_INIT;<br>
+#endif<br>
<br>
If block mode is not needed, then you should remove it completely.<br>
<br>
+<br>
+    p_sys->fd = -1;<br>
+    p_sys->b_seekable = true;<br>
+    p_sys->psz_mime = NULL;<br>
+<br>
+    p_access->info.i_size = -1;<br>
+    p_access->info.i_pos  = 0;<br>
+    p_access->info.b_eof  = false;<br>
+<br>
+    /* Parse URI - remove spaces */<br>
+    p = psz = strdup( p_access->psz_path );<br>
+<br>
+    vlc_UrlParse( &p_sys->url, psz, 0 );<br>
+    free( psz );<br>
<br>
There is no point in strdup+free here, is there?<br>
And p does not seem to be ever used (GCC should warn you about that).<br>
<br>
+    if( p_sys->url.psz_host == NULL || *p_sys->url.psz_host == '\0' )<br>
+    {<br>
+        msg_Warn( p_access, "invalid host" );<br>
+        goto error;<br>
+    }<br>
+<br>
+    if( p_sys->url.i_port <= 0 )  p_sys->url.i_port = 1680;<br>
+<br>
+    p_sys->b_reconnect = var_CreateGetBool( p_access, "vod-reconnect" );<br>
+<br>
+    if (Connect( p_access, 0 ) != VLC_SUCCESS) goto error;<br>
+<br>
+#ifdef VOD_DEBUG<br>
+    p_sys->out_fd = fopen("dump", "wb");<br>
+#endif<br>
<br>
You probably don't need this. You can run VLC with<br>
`--demux dump --demuxdump-file dump` if you want to dump content.<br>
<br>
+    return VLC_SUCCESS;<br>
+<br>
+error:<br>
+    vlc_UrlClean( &p_sys->url );<br>
+    free( p_sys->psz_mime );<br>
+<br>
+    Disconnect( p_access );<br>
+    free( p_sys );<br>
+<br>
+    return VLC_EGENERIC;<br>
+}<br>
+<br>
+/*****************************************************************************<br>
+ * Close:<br>
+<br>
*****************************************************************************/<br>
+static void Close( vlc_object_t *p_this )<br>
+{<br>
+    access_t     *p_access = (access_t*)p_this;<br>
+    access_sys_t *p_sys = p_access->p_sys;<br>
+<br>
+    vlc_UrlClean( &p_sys->url );<br>
+    free( p_sys->psz_mime );<br>
+<br>
+    Disconnect( p_access );<br>
+<br>
+#ifdef VOD_DEBUG<br>
+   fclose( p_sys->out_fd);<br>
+#endif<br>
+<br>
+    free( p_sys );<br>
+}<br>
+<br>
+/*****************************************************************************<br>
+ * Read: Read up to i_len bytes from the vod sockect connection and place in<br>
+ * p_buffer. Return the actual number of bytes read<br>
+<br>
*****************************************************************************/<br>
+static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )<br>
+{<br>
+    access_sys_t *p_sys = p_access->p_sys;<br>
+    int i_read;<br>
+<br>
+    if( p_sys->fd < 0 )<br>
+    {<br>
+        p_access->info.b_eof = true;<br>
+        return 0;<br>
+    }<br>
+<br>
+    if( p_access->info.i_size >= 0 &&<br>
+        i_len + p_access->info.i_pos > p_access->info.i_size )<br>
+    {<br>
+        if( ( i_len = p_access->info.i_size - p_access->info.i_pos ) == 0 )<br>
+        {<br>
+            p_access->info.b_eof = true;<br>
+            return 0;<br>
+        }<br>
+    }<br>
+<br>
+    i_read = net_Read( p_access, p_sys->fd, NULL, p_buffer, i_len, false );<br>
+<br>
+#ifdef VOD_DEBUG<br>
+    msg_Dbg(p_access, ">%d--->%d", i_read, i_len - i_read);<br>
+#endif<br>
+<br>
+    if( i_read > 0 )<br>
+    {<br>
+        p_access->info.i_pos += i_read;<br>
+    }<br>
+    else if( i_read == 0 )<br>
+    {<br>
+        /*<br>
+         * I very much doubt that this will work.<br>
+         * If i_read == 0, the connection *IS* dead, so the only<br>
+         * sensible thing to do is Disconnect() and then retry.<br>
+         * Otherwise, I got recv() completely wrong. -- Courmisch<br>
+         */<br>
<br>
This comment (that I wrote a long time ago) does not belong here.<br>
<br>
+        Disconnect( p_access );<br>
+        if( p_sys->b_reconnect )<br>
+        {<br>
+            msg_Dbg( p_access, "got disconnected, trying to reconnect" );<br>
+            if( Connect( p_access, p_access->info.i_pos ) )<br>
+            {<br>
+                msg_Dbg( p_access, "reconnection failed" );<br>
+            }<br>
+            else<br>
+            {<br>
+                p_sys->b_reconnect = false;<br>
+                i_read = Read( p_access, p_buffer, i_len );<br>
+                p_sys->b_reconnect = true;<br>
+            }<br>
+        }<br>
+<br>
+        if( i_read == 0 ) p_access->info.b_eof = true;<br>
+    }<br>
+#ifdef VOD_DEBUG<br>
+    fwrite( p_buffer, 1, i_read, p_sys->out_fd);<br>
+#endif<br>
+<br>
+    return i_read;<br>
+}<br>
+<br>
+/*****************************************************************************<br>
+ * Block<br>
+<br>
*****************************************************************************/<br>
+static block_t *Block( access_t *p_access )<br>
<br>
This function seems to be unused, and should be removed. GCC should have<br>
warned about this issue.<br>
<br>
+{<br>
+    access_sys_t *p_sys = p_access->p_sys;<br>
+    block_t      *p_block;<br>
+    ssize_t i_read;<br>
+<br>
+    if( p_access->info.b_eof )<br>
+        return NULL;<br>
+<br>
+    /* Read data */<br>
+    p_block = block_New( p_access, MTU );<br>
+    i_read = net_Read( p_access, p_sys->fd, NULL, p_block->p_buffer, MTU,<br>
false );<br>
+<br>
+#ifdef VOD_DEBUG<br>
+     msg_Dbg(p_access, "<%d--->%d", i_read, MTU - i_read);<br>
+#endif<br>
+<br>
+    if( i_read < 0 )<br>
+    {<br>
+        block_Release( p_block );<br>
+        return NULL;<br>
+    }<br>
+<br>
+#ifdef VOD_DEBUG<br>
+    fwrite( p_block->p_buffer, 1, i_read, p_sys->out_fd);<br>
+#endif<br>
+<br>
+    return block_Realloc( p_block, 0, p_block->i_buffer = i_read );<br>
+}<br>
+#if 0<br>
+static char* get_comment(char* fn)<br>
+{<br>
+    char* pos;<br>
+<br>
+    pos = strrchr(fn,'\\');<br>
+    if (pos) fn = pos+1;<br>
+    pos = strrchr(fn,'/');<br>
+    if (pos) fn = pos+1;<br>
+    return fn;<br>
+    //  return "<a href="http://comic.sjtu.edu.cn" target="_blank">comic.sjtu.edu.cn</a>";<br>
+}<br>
+#endif<br>
+static unsigned int get_ip_from_fd(int fd)<br>
<br>
Return uint32_t here.<br>
<br>
+{<br>
+    struct sockaddr_in saddr;<br>
+    socklen_t len = sizeof(saddr);<br>
+<br>
+    getsockname(fd,(struct sockaddr*)(&saddr), &len);<br>
+    return saddr.sin_addr.s_addr;<br>
+}<br>
+<br>
+static int Connect( access_t *p_access, int64_t i_tell )<br>
+{<br>
+    access_sys_t   *p_sys = p_access->p_sys;<br>
+<br>
+    /* Open connection */<br>
+    p_sys->fd = net_ConnectTCP( p_access,  p_sys->url.psz_host,<br>
p_sys->url.i_port );<br>
+    if( p_sys->fd == -1 )<br>
+    {<br>
+        msg_Err( p_access, "cannot connect to %s:%d",  p_sys->url.psz_host,<br>
p_sys->url.i_port );<br>
+        return VLC_EGENERIC;<br>
+    }<br>
+    return Request( p_access, i_tell );<br>
+}<br>
+<br>
+static int Request( access_t *p_access, int64_t i_tell )<br>
+{<br>
+    access_sys_t   *p_sys = p_access->p_sys;<br>
+    char buffer[4096];<br>
+    int pos = 0;<br>
+    int size = sizeof(buffer);<br>
+    response_t *resp = &p_sys->resp;<br>
+    char           *psz;<br>
+    char hostname[256];<br>
+<br>
+    gethostname (hostname, sizeof (hostname));<br>
+    #define myprintf(fmt, args...) do { int len = snprintf(buffer+pos, size,<br>
fmt, ## args); pos+=len; size-=len; } while (0)<br>
<br>
size may suffer an integer underflow here, as snprintf() expects an unsigned.<br>
<br>
+<br>
+    myprintf("POST /XMMS/%s%ld.xms HTTP/1.0\r\n", hostname, time(NULL) %<br>
10000 + 10000);<br>
+    myprintf("Host: %s\r\n",   hostname);<br>
<br>
Normally, the HTTP Host field conveys the remote host name from the URL, not<br>
the local host name. I don't know what's correct here, because your protocol<br>
seems to not Unless there is a weird deviation from standard HTTP.<br>
<br>
+    myprintf("Accept: %s\r\n", "*/*");<br>
+    myprintf("User-Agent: %s\r\n", "XMPLAYER");<br>
+    myprintf("UGT:%s\r\n",     "XMPLAYER");<br>
+    myprintf("UIP:%u\r\n",     get_ip_from_fd(p_sys->fd));<br>
<br>
Should be "PRIu32" instead of u, I guess. You should also check that the<br>
socket address is in the AF_INET family first.<br>
<br>
+    myprintf("USN:%d\r\n",     12345678);<br>
+    myprintf("PRI:%d\r\n",     0);<br>
+    myprintf("UPR:%d\r\n",     0);<br>
+    myprintf("SPL:%"PRId64"\r\n",     i_tell);<br>
+    myprintf("SPH:%d\r\n",     0);<br>
+    myprintf("URN:%s\r\n",     "sjtu");<br>
+    myprintf("PWD:%s\r\n",     "sjtu");<br>
<br>
Is this used anywhere except in SJTU university?<br>
<br>
+    myprintf("FPT:%d\r\n",     (i_tell==0)?1:0);<br>
+    myprintf("FIL:%s\r\n",     (p_sys->url.psz_path[0] == '/')?<br>
p_sys->url.psz_path+1:p_sys->url.psz_path);<br>
+    myprintf("ULG:%s\r\n",     "CN");<br>
<br>
I assume this is only used by Chinese users.<br>
<br>
+    myprintf("STT:%s\r\n",     "YYYY/MM/DD HH:MM:SS");<br>
<br>
Is this the date, or the date format?<br>
<br>
+    myprintf("HST:%s\r\n",     hostname);<br>
+    myprintf("PNM:%s\r\n",     "<a href="http://comic.sjtu.edu.cn" target="_blank">comic.sjtu.edu.cn</a>");<br>
<br>
Same question as above.<br>
<br>
+    myprintf("PID:%d\r\n",     0);<br>
+    myprintf("IDX:%d\r\n",     0);<br>
+    myprintf("\r\n");<br>
+<br>
+    msg_Dbg( p_access, "sending request: \n%s", buffer);<br>
+<br>
+    if ( net_Write( p_access, p_sys->fd, NULL, buffer, strlen(buffer) ) <= 0)<br>
+    {<br>
+        msg_Err( p_access, "failed to send request" );<br>
+        Disconnect( p_access );<br>
+        return VLC_EGENERIC;<br>
+    }<br>
+<br>
+    /* Read Answer */<br>
+    if( ( psz = net_Gets( VLC_OBJECT(p_access), p_sys->fd, NULL ) ) == NULL )<br>
+    {<br>
+        msg_Err( p_access, "failed to read answer" );<br>
+        goto error;<br>
+    }<br>
+    if( !strncmp( psz, "HTTP/1.", 7 ) )<br>
+    {<br>
+          p_sys->i_code = atoi( &psz[9] );<br>
+    }<br>
+    else {<br>
+        msg_Err( p_access, "invalid HTTP reply '%s'", psz );<br>
+        free( psz );<br>
+        goto error;<br>
+    }<br>
+<br>
+    msg_Dbg( p_access, "answer code %d",  p_sys->i_code );<br>
+<br>
+    for( ;; )<br>
+    {<br>
+        char *psz = net_Gets( VLC_OBJECT(p_access), p_sys->fd, NULL );<br>
+        char *p;<br>
+<br>
+        if( psz == NULL )<br>
+        {<br>
+            msg_Err( p_access, "failed to read answer" );<br>
+            goto error;<br>
+        }<br>
+<br>
+        if( !vlc_object_alive (p_access) || p_access->b_error )<br>
+        {<br>
+            free( psz );<br>
+            goto error;<br>
+        }<br>
+<br>
+        msg_Dbg( p_access, "Line=%s", psz );<br>
+        if( *psz == '\0' )<br>
+        {<br>
+            free( psz );<br>
+            break;<br>
+        }<br>
+<br>
+        if( ( p = strchr( psz, ':' ) ) == NULL )<br>
+        {<br>
+            msg_Err( p_access, "malformed header line: %s", psz );<br>
+            free( psz );<br>
+            goto error;<br>
+        }<br>
+        *p++ = '\0';<br>
+        while( *p == ' ' ) p++;<br>
+<br>
+        if( !strcasecmp( psz, "Content-Type" ) )<br>
+        {<br>
+            free( p_sys->psz_mime );<br>
+            p_sys->psz_mime = strdup( p );<br>
+            msg_Dbg( p_access, "Content-Type: %s", p_sys->psz_mime );<br>
+            if (!strcmp(p_sys->psz_mime, "errmsg/*"))<br>
+            {<br>
+                msg_Err( p_access, "Error: %s", p );<br>
+                free( psz );<br>
+                goto error;<br>
+            }<br>
+        }<br>
+<br>
+        free( psz );<br>
+    }<br>
+<br>
+    if (net_Read( p_access, p_sys->fd, NULL, resp, sizeof(response_t), true )<br>
< (int)sizeof(response_t))<br>
+    {<br>
+        msg_Err( p_access, "failed to read Response" );<br>
+        goto error;<br>
+    }<br>
+<br>
+    if (strncmp( resp->magic, "XMMS", 4 ) != 0)<br>
+    {     // CHECK MAGIC<br>
+        msg_Err(p_access, " magic mismatch");<br>
+        goto error;<br>
+    }<br>
+<br>
+    if ((resp->type != 0) && (resp->unknown4 == 0))<br>
+    { // maybe error<br>
+        msg_Err(p_access, "Server error %s", resp->errmsg);<br>
+        goto error;<br>
+    }<br>
+<br>
+    msg_Dbg(p_access, "Opening %s\n", resp->name);<br>
+    msg_Dbg(p_access, "Date %s\n", resp->date);<br>
+    msg_Dbg(p_access, "Position %u/%u\n", resp->pos_lo, resp->len_lo);<br>
<br>
Assuming you are using a little-endian system, that will fail on big-endian<br>
systems.<br>
<br>
+<br>
+    if (resp->len_lo == 0) {<br>
+        Disconnect(p_access);<br>
+        msg_Err( p_access, "Open failed, may be too many users." );<br>
+        return VLC_EGENERIC;<br>
+    }<br>
+<br>
+    p_access->info.i_size = resp->len_lo;<br>
+    p_access->info.i_pos  = resp->pos_lo;<br>
<br>
Same (worse) problem here.<br>
<br>
+    p_access->info.b_eof  = false;<br>
+<br>
+    if (resp->pos_lo >= resp->len_lo)<br>
<br>
And here.<br>
<br>
+        p_access->info.b_eof  = true;<br>
+<br>
+    return VLC_SUCCESS;<br>
+<br>
+error:<br>
+    Disconnect( p_access );<br>
+    return VLC_EGENERIC;<br>
+}<br>
+<br>
+/*****************************************************************************<br>
+ * Disconnect:<br>
+<br>
*****************************************************************************/<br>
+static void Disconnect( access_t *p_access )<br>
+{<br>
+    access_sys_t *p_sys = p_access->p_sys;<br>
+<br>
+    if( p_sys->fd != -1)<br>
+    {<br>
+        net_Close(p_sys->fd);<br>
+        p_sys->fd = -1;<br>
+    }<br>
+}<br>
+<br>
+/*****************************************************************************<br>
+ * Seek: close and re-open a connection at the right place<br>
+<br>
*****************************************************************************/<br>
+static int Seek( access_t *p_access, int64_t i_pos )<br>
+{<br>
+    msg_Dbg( p_access, "trying to seek to %"PRId64, i_pos );<br>
+<br>
+    Disconnect( p_access );<br>
+<br>
+    if( p_access->info.i_size<br>
+     && (uint64_t)i_pos >= (uint64_t)p_access->info.i_size ) {<br>
+        msg_Err( p_access, "seek to far" );<br>
+        int retval = Seek( p_access, p_access->info.i_size - 1 );<br>
+        if( retval == VLC_SUCCESS ) {<br>
+            uint8_t p_buffer[2];<br>
+            Read( p_access, p_buffer, 1);<br>
+            p_access->info.b_eof  = false;<br>
+        }<br>
+        return retval;<br>
+    }<br>
+    if( Connect( p_access, i_pos ) != VLC_SUCCESS)<br>
+    {<br>
+        msg_Err( p_access, "seek failed" );<br>
+        p_access->info.b_eof = true;<br>
+        return VLC_EGENERIC;<br>
+    }<br>
+    return VLC_SUCCESS;<br>
+}<br>
+<br>
+/*****************************************************************************<br>
+ * Control:<br>
+<br>
*****************************************************************************/<br>
+static int Control( access_t *p_access, int i_query, va_list args )<br>
+{<br>
+    access_sys_t *p_sys = p_access->p_sys;<br>
+    bool   *pb_bool;<br>
+    int64_t      *pi_64;<br>
+<br>
+    switch( i_query )<br>
+    {<br>
+        /* */<br>
+        case ACCESS_CAN_SEEK:<br>
+            pb_bool = (bool*)va_arg( args, bool* );<br>
+            *pb_bool = p_sys->b_seekable;<br>
+            break;<br>
+        case ACCESS_CAN_FASTSEEK:<br>
+            pb_bool = (bool*)va_arg( args, bool* );<br>
+            *pb_bool = false;<br>
+            break;<br>
+        case ACCESS_CAN_PAUSE:<br>
+        case ACCESS_CAN_CONTROL_PACE:<br>
+            pb_bool = (bool*)va_arg( args, bool* );<br>
+<br>
+            *pb_bool = true;<br>
+            break;<br>
+<br>
+        case ACCESS_GET_PTS_DELAY:<br>
+            pi_64 = (int64_t*)va_arg( args, int64_t * );<br>
+            *pi_64 = (int64_t)var_GetInteger( p_access, "vod-caching" ) *<br>
INT64_C(1000);<br>
+            break;<br>
+<br>
+        /* */<br>
+        case ACCESS_SET_PAUSE_STATE:<br>
+            break;<br>
+<br>
+        case ACCESS_GET_META:<br>
+/*<br>
+            p_meta = (vlc_meta_t*)va_arg( args, vlc_meta_t* );<br>
+<br>
+            if( p_sys->psz_icy_name )<br>
+                vlc_meta_Set( p_meta, vlc_meta_Title, p_sys->psz_icy_name );<br>
+            if( p_sys->psz_icy_genre )<br>
+                vlc_meta_Set( p_meta, vlc_meta_Genre, p_sys->psz_icy_genre );<br>
+            if( p_sys->psz_icy_title )<br>
+                vlc_meta_Set( p_meta, vlc_meta_NowPlaying,<br>
p_sys->psz_icy_title );<br>
+*/<br>
<br>
<br>
Remove this.<br>
<br>
+            break;<br>
+<br>
+        case ACCESS_GET_CONTENT_TYPE:<br>
+            *va_arg( args, char ** ) =<br>
+                p_sys->psz_mime ? strdup( p_sys->psz_mime ) : NULL;<br>
+            break;<br>
+<br>
+        case ACCESS_GET_TITLE_INFO:<br>
+        case ACCESS_SET_TITLE:<br>
+        case ACCESS_SET_SEEKPOINT:<br>
+        case ACCESS_SET_PRIVATE_ID_STATE:<br>
+            return VLC_EGENERIC;<br>
+<br>
+        default:<br>
+            msg_Warn( p_access, "unimplemented query in control" );<br>
+            return VLC_EGENERIC;<br>
+<br>
+    }<br>
+    return VLC_SUCCESS;<br>
+}<br>
+<br>
--<br>
1.5.4.3<br>
<font color="#888888"><br>
--<br>
Rémi Denis-Courmont<br>
<a href="http://git.remlab.net/cgi-bin/gitweb.cgi?p=vlc-courmisch.git;a=summary" target="_blank">http://git.remlab.net/cgi-bin/gitweb.cgi?p=vlc-courmisch.git;a=summary</a><br>
</font></blockquote></div><br>