Commit 68e099d6 authored by Laurent Aimar's avatar Laurent Aimar

* mms: enable seek :) It works for me with both udp and tcp. Somebody

could check if it compiles on other OS than linux ? (I don't known what
headers should be included)
 * asf: fix to support seeking with mms
 Note: You cannot seek and use demuxdump demuxer...
parent 0f0ecaa9
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* mms.c: MMS access plug-in * mms.c: MMS access plug-in
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * Copyright (C) 2001, 2002 VideoLAN
* $Id: mms.c,v 1.7 2002/11/25 00:22:04 fenrir Exp $ * $Id: mms.c,v 1.8 2002/11/25 15:08:34 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -56,6 +56,8 @@ ...@@ -56,6 +56,8 @@
# endif # endif
#else #else
# include <sys/socket.h> # include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
#endif #endif
#include "network.h" #include "network.h"
...@@ -231,8 +233,14 @@ static int Open( vlc_object_t *p_this ) ...@@ -231,8 +233,14 @@ static int Open( vlc_object_t *p_this )
/* *** finished to set some variable *** */ /* *** finished to set some variable *** */
vlc_mutex_lock( &p_input->stream.stream_lock ); vlc_mutex_lock( &p_input->stream.stream_lock );
/* those data could be different for UDP/TCP */ if( p_access->i_proto == MMS_PROTO_UDP )
p_input->stream.b_pace_control = 1; {
p_input->stream.b_pace_control = 0;
}
else
{
p_input->stream.b_pace_control = 1;
}
p_input->stream.p_selected_area->i_tell = 0; p_input->stream.p_selected_area->i_tell = 0;
if( p_access->i_packet_count <= 0 ) if( p_access->i_packet_count <= 0 )
{ {
...@@ -241,7 +249,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -241,7 +249,7 @@ static int Open( vlc_object_t *p_this )
} }
else else
{ {
p_input->stream.b_seekable = 0; p_input->stream.b_seekable = 1;
p_input->stream.p_selected_area->i_size = p_input->stream.p_selected_area->i_size =
p_access->i_header + p_access->i_header +
p_access->i_packet_count * p_access->i_packet_length; p_access->i_packet_count * p_access->i_packet_length;
...@@ -298,17 +306,20 @@ static void Seek( input_thread_t * p_input, off_t i_pos ) ...@@ -298,17 +306,20 @@ static void Seek( input_thread_t * p_input, off_t i_pos )
* *
* *
*/ */
#if 0 #if 1
access_t *p_access = (access_t*)p_input->p_access_data; access_t *p_access = (access_t*)p_input->p_access_data;
uint32_t i_packet; uint32_t i_packet;
uint32_t i_offset; uint32_t i_offset;
var_buffer_t buffer;
if( i_pos < 0 ) if( i_pos < 0 )
{ {
return; return;
} }
msg_Dbg( p_input, "seeking to %lld, header size:%d", i_pos, p_access->i_header );
vlc_mutex_lock( &p_input->stream.stream_lock );
if( i_pos < p_access->i_header) if( i_pos < p_access->i_header)
{ {
...@@ -330,11 +341,57 @@ static void Seek( input_thread_t * p_input, off_t i_pos ) ...@@ -330,11 +341,57 @@ static void Seek( input_thread_t * p_input, off_t i_pos )
i_packet = ( i_pos - p_access->i_header ) / p_access->i_packet_length; i_packet = ( i_pos - p_access->i_header ) / p_access->i_packet_length;
i_offset = ( i_pos - p_access->i_header ) % p_access->i_packet_length; i_offset = ( i_pos - p_access->i_header ) % p_access->i_packet_length;
} }
msg_Dbg( p_input, "seeking to "I64Fd " (packet:%d)", i_pos, i_packet );
MMSStop( p_input ); MMSStop( p_input );
MMSStart( p_input, i_packet ); msg_Dbg( p_input, "stream stopped (seek)" );
/* *** restart stream *** */
var_buffer_initwrite( &buffer, 0 );
var_buffer_add64( &buffer, 0 ); /* seek point in second */
var_buffer_add32( &buffer, 0xffffffff );
var_buffer_add32( &buffer, i_packet ); // begin from start
var_buffer_add8( &buffer, 0xff ); // stream time limit
var_buffer_add8( &buffer, 0xff ); // on 3bytes ...
var_buffer_add8( &buffer, 0xff ); //
var_buffer_add8( &buffer, 0x00 ); // don't use limit
var_buffer_add32( &buffer, p_access->i_media_packet_id_type );
mms_CommandSend( p_input, 0x07, p_access->i_command_level, 0x0001ffff,
buffer.p_data, buffer.i_data );
var_buffer_free( &buffer );
for( ;; )
{
mms_HeaderMediaRead( p_input, MMS_PACKET_CMD );
if( p_access->i_command == 0x1e )
{
msg_Dbg( p_input, "received 0x1e (seek)" );
break;
}
}
for( ;; )
{
mms_HeaderMediaRead( p_input, MMS_PACKET_CMD );
if( p_access->i_command == 0x05 )
{
msg_Dbg( p_input, "received 0x05 (seek)" );
break;
}
}
/* get a packet */
mms_HeaderMediaRead( p_input, MMS_PACKET_MEDIA );
msg_Dbg( p_input, "Streaming restarted" );
p_access->i_media_used += i_offset; p_access->i_media_used += i_offset;
p_access->i_pos = i_pos; p_access->i_pos = i_pos;
p_input->stream.p_selected_area->i_tell = i_pos;
vlc_mutex_unlock( &p_input->stream.stream_lock );
#endif #endif
} }
...@@ -385,7 +442,7 @@ static int Read ( input_thread_t * p_input, byte_t * p_buffer, ...@@ -385,7 +442,7 @@ static int Read ( input_thread_t * p_input, byte_t * p_buffer,
} }
else else
{ {
if( mms_HeaderMediaRead( p_input, MMS_PACKET_MEDIA ) < 0 ); if( p_access->i_eos || mms_HeaderMediaRead( p_input, MMS_PACKET_MEDIA ) < 0 );
{ {
p_access->i_pos += i_data; p_access->i_pos += i_data;
return( i_data ); return( i_data );
...@@ -691,24 +748,35 @@ static int MMSOpen( input_thread_t *p_input, ...@@ -691,24 +748,35 @@ static int MMSOpen( input_thread_t *p_input,
/* *** Bind port if UDP protocol is selected *** */ /* *** Bind port if UDP protocol is selected *** */
if( b_udp ) if( b_udp )
{ {
msg_Err( p_input,
"MMS/UDP not yet functionnal, anyway trying..." );
if( !p_url->psz_bind_addr || !*p_url->psz_bind_addr ) if( !p_url->psz_bind_addr || !*p_url->psz_bind_addr )
{ {
msg_Err( p_input, "for udp you have to provide bind address (mms://<server_addr>@<bind_addr/<path> (FIXME)" ); struct sockaddr_in name;
socklen_t i_namelen = sizeof( struct sockaddr_in );
if( getsockname( p_access->socket_tcp.i_handle,
(struct sockaddr_in*)&name, &i_namelen ) < 0 )
{
msg_Err( p_input, "for udp you have to provide bind address (mms://<server_addr>@<bind_addr/<path> (FIXME)" );
#if defined( UNDER_CE ) #if defined( UNDER_CE )
CloseHandle( (HANDLE)p_access->socket_tcp.i_handle ); CloseHandle( (HANDLE)p_access->socket_tcp.i_handle );
#elif defined( WIN32 ) #elif defined( WIN32 )
closesocket( p_access->socket_tcp.i_handle ); closesocket( p_access->socket_tcp.i_handle );
#else #else
close( p_access->socket_tcp.i_handle ); close( p_access->socket_tcp.i_handle );
#endif #endif
return( -1 ); return( -1 );
}
p_access->psz_bind_addr = inet_ntoa( name.sin_addr );
}
else
{
p_access->psz_bind_addr = strdup( p_url->psz_bind_addr );
} }
socket_desc.i_type = NETWORK_UDP; socket_desc.i_type = NETWORK_UDP;
socket_desc.psz_server_addr = ""; socket_desc.psz_server_addr = "";
socket_desc.i_server_port = 0; socket_desc.i_server_port = 0;
socket_desc.psz_bind_addr = p_url->psz_bind_addr; socket_desc.psz_bind_addr = p_access->psz_bind_addr;
socket_desc.i_bind_port = p_url->i_bind_port; socket_desc.i_bind_port = p_url->i_bind_port;
p_input->p_private = (void*)&socket_desc; p_input->p_private = (void*)&socket_desc;
if( !( p_network = module_Need( p_input, "network", psz_network ) ) ) if( !( p_network = module_Need( p_input, "network", psz_network ) ) )
...@@ -728,6 +796,10 @@ static int MMSOpen( input_thread_t *p_input, ...@@ -728,6 +796,10 @@ static int MMSOpen( input_thread_t *p_input,
p_input->i_mtu = 0;/*socket_desc.i_mtu; FIXME */ p_input->i_mtu = 0;/*socket_desc.i_mtu; FIXME */
} }
else
{
p_access->psz_bind_addr = NULL;
}
/* *** Init context for mms prototcol *** */ /* *** Init context for mms prototcol *** */
GenerateGuid( &p_access->guid ); /* used to identify client by server */ GenerateGuid( &p_access->guid ); /* used to identify client by server */
...@@ -751,6 +823,7 @@ static int MMSOpen( input_thread_t *p_input, ...@@ -751,6 +823,7 @@ static int MMSOpen( input_thread_t *p_input,
p_access->i_buffer_udp = 0; p_access->i_buffer_udp = 0;
p_access->p_cmd = NULL; p_access->p_cmd = NULL;
p_access->i_cmd = 0; p_access->i_cmd = 0;
p_access->i_eos = 0;
/* *** send command 1 : connection request *** */ /* *** send command 1 : connection request *** */
var_buffer_initwrite( &buffer, 0 ); var_buffer_initwrite( &buffer, 0 );
...@@ -809,7 +882,7 @@ static int MMSOpen( input_thread_t *p_input, ...@@ -809,7 +882,7 @@ static int MMSOpen( input_thread_t *p_input,
{ {
sprintf( tmp, sprintf( tmp,
"\\\\%s\\UDP\\%d", "\\\\%s\\UDP\\%d",
p_url->psz_bind_addr, p_access->psz_bind_addr,
p_url->i_bind_port ); p_url->i_bind_port );
} }
else else
...@@ -1344,7 +1417,7 @@ static int NetFillBuffer( input_thread_t *p_input ) ...@@ -1344,7 +1417,7 @@ static int NetFillBuffer( input_thread_t *p_input )
} }
else else
{ {
msg_Warn( p_input, "ask for tcp:%d udp:%d", i_tcp, i_udp ); // msg_Warn( p_input, "ask for tcp:%d udp:%d", i_tcp, i_udp );
} }
/* We'll wait 0.5 second if nothing happens */ /* We'll wait 0.5 second if nothing happens */
...@@ -1385,21 +1458,26 @@ static int NetFillBuffer( input_thread_t *p_input ) ...@@ -1385,21 +1458,26 @@ static int NetFillBuffer( input_thread_t *p_input )
i_udp_read = 0; i_udp_read = 0;
} }
#if 0
p_access->i_buffer_tcp += i_tcp_read;
p_access->i_buffer_udp += i_udp_read;
msg_Dbg( p_input,
"filling TCP buffer with %d bytes (buffer:%d)",
i_tcp_read,
p_access->i_buffer_tcp );
if( p_access->i_proto == MMS_PROTO_UDP ) if( p_access->i_proto == MMS_PROTO_UDP )
{ {
msg_Dbg( p_input, msg_Dbg( p_input,
"filling UDP buffer with %d bytes (buffer:%d)", "filling buffer TCP:%d+%d UDP:%d+%d",
i_udp_read, p_access->i_buffer_tcp,
p_access->i_buffer_udp ); i_tcp_read,
p_access->i_buffer_udp,
i_udp_read );
} }
else
{
msg_Dbg( p_input,
"filling buffer TCP:%d+%d",
p_access->i_buffer_tcp,
i_tcp_read );
}
#endif
p_access->i_buffer_tcp += i_tcp_read;
p_access->i_buffer_udp += i_udp_read;
return( i_tcp_read + i_udp_read); return( i_tcp_read + i_udp_read);
#endif #endif
...@@ -1546,9 +1624,9 @@ static int mms_ParsePacket( input_thread_t *p_input, ...@@ -1546,9 +1624,9 @@ static int mms_ParsePacket( input_thread_t *p_input,
FREE( p_access->p_header ); FREE( p_access->p_header );
p_access->p_header = p_packet; p_access->p_header = p_packet;
p_access->i_header = i_packet_length - 8; p_access->i_header = i_packet_length - 8;
msg_Dbg( p_input, /* msg_Dbg( p_input,
"receive header packet (%d bytes)", "receive header packet (%d bytes)",
i_packet_length - 8 ); i_packet_length - 8 ); */
return( MMS_PACKET_HEADER ); return( MMS_PACKET_HEADER );
} }
...@@ -1558,9 +1636,9 @@ static int mms_ParsePacket( input_thread_t *p_input, ...@@ -1558,9 +1636,9 @@ static int mms_ParsePacket( input_thread_t *p_input,
p_access->p_media = p_packet; p_access->p_media = p_packet;
p_access->i_media = i_packet_length - 8; p_access->i_media = i_packet_length - 8;
p_access->i_media_used = 0; p_access->i_media_used = 0;
msg_Dbg( p_input, /* msg_Dbg( p_input,
"receive media packet (%d bytes)", "receive media packet (%d bytes)",
i_packet_length - 8 ); i_packet_length - 8 ); */
return( MMS_PACKET_MEDIA ); return( MMS_PACKET_MEDIA );
} }
...@@ -1739,9 +1817,11 @@ static int mms_CommandRead( input_thread_t *p_input, int i_command1, int i_comma ...@@ -1739,9 +1817,11 @@ static int mms_CommandRead( input_thread_t *p_input, int i_command1, int i_comma
{ {
case 0x03: case 0x03:
msg_Warn( p_input, "socket closed by server" ); msg_Warn( p_input, "socket closed by server" );
p_access->i_eos = 1;
return( -1 ); return( -1 );
case 0x1e: case 0x1e:
msg_Warn( p_input, "end of media stream" ); msg_Warn( p_input, "end of media stream" );
p_access->i_eos = 1;
return( -1 ); return( -1 );
default: default:
break; break;
...@@ -1773,7 +1853,7 @@ static int mms_HeaderMediaRead( input_thread_t *p_input, int i_type ) ...@@ -1773,7 +1853,7 @@ static int mms_HeaderMediaRead( input_thread_t *p_input, int i_type )
} }
else if( i_status == i_type || i_type == MMS_PACKET_ANY ) else if( i_status == i_type || i_type == MMS_PACKET_ANY )
{ {
return( 0 ); return( i_type );
} }
else if( i_status == MMS_PACKET_CMD ) else if( i_status == MMS_PACKET_CMD )
{ {
...@@ -1781,9 +1861,11 @@ static int mms_HeaderMediaRead( input_thread_t *p_input, int i_type ) ...@@ -1781,9 +1861,11 @@ static int mms_HeaderMediaRead( input_thread_t *p_input, int i_type )
{ {
case 0x03: case 0x03:
msg_Warn( p_input, "socket closed by server" ); msg_Warn( p_input, "socket closed by server" );
p_access->i_eos = 1;
return( -1 ); return( -1 );
case 0x1e: case 0x1e:
msg_Warn( p_input, "end of media stream" ); msg_Warn( p_input, "end of media stream" );
p_access->i_eos = 1;
return( -1 ); return( -1 );
case 0x20: case 0x20:
/* XXX not too dificult to be done EXCEPT that we /* XXX not too dificult to be done EXCEPT that we
...@@ -1791,6 +1873,7 @@ static int mms_HeaderMediaRead( input_thread_t *p_input, int i_type ) ...@@ -1791,6 +1873,7 @@ static int mms_HeaderMediaRead( input_thread_t *p_input, int i_type )
* could do that :p */ * could do that :p */
msg_Err( p_input, msg_Err( p_input,
"reinitialization needed --> unsupported" ); "reinitialization needed --> unsupported" );
p_access->i_eos = 1;
return( -1 ); return( -1 );
default: default:
break; break;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* mms.h: MMS access plug-in * mms.h: MMS access plug-in
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * Copyright (C) 2001, 2002 VideoLAN
* $Id: mms.h,v 1.4 2002/11/25 00:22:04 fenrir Exp $ * $Id: mms.h,v 1.5 2002/11/25 15:08:34 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -73,6 +73,7 @@ typedef struct access_s ...@@ -73,6 +73,7 @@ typedef struct access_s
input_socket_t socket_tcp; /* TCP socket for communication with server */ input_socket_t socket_tcp; /* TCP socket for communication with server */
input_socket_t socket_udp; /* Optional UDP socket for data(media/header packet) */ input_socket_t socket_udp; /* Optional UDP socket for data(media/header packet) */
/* send by server */ /* send by server */
char *psz_bind_addr; /* used by udp */
url_t url; /* connect to this server */ url_t url; /* connect to this server */
...@@ -108,6 +109,7 @@ typedef struct access_s ...@@ -108,6 +109,7 @@ typedef struct access_s
/* extracted informations */ /* extracted informations */
int i_command; int i_command;
int i_eos;
/* from 0x01 answer (not yet set) */ /* from 0x01 answer (not yet set) */
char *psz_server_version; char *psz_server_version;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* asf.c : ASFv01 file input module for vlc * asf.c : ASFv01 file input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: asf.c,v 1.7 2002/11/19 17:23:21 fenrir Exp $ * $Id: asf.c,v 1.8 2002/11/25 15:08:34 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -77,7 +77,7 @@ static int Activate( vlc_object_t * p_this ) ...@@ -77,7 +77,7 @@ static int Activate( vlc_object_t * p_this )
if( p_input->i_mtu == 0 ) if( p_input->i_mtu == 0 )
{ {
/* Improve speed. */ /* Improve speed. */
p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE ; p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE;
} }
p_input->pf_demux = Demux; p_input->pf_demux = Demux;
...@@ -403,7 +403,8 @@ static int Demux( input_thread_t *p_input ) ...@@ -403,7 +403,8 @@ static int Demux( input_thread_t *p_input )
i_offset = 0; i_offset = 0;
} }
/* XXX work only when i_min_data_packet_size == i_max_data_packet_size */ /* XXX work only when i_min_data_packet_size == i_max_data_packet_size */
i_offset -= i_offset % p_demux->p_fp->i_min_data_packet_size; i_offset += p_demux->p_fp->i_min_data_packet_size -
i_offset % p_demux->p_fp->i_min_data_packet_size;
ASF_SeekAbsolute( p_input, p_demux->i_data_begin + i_offset ); ASF_SeekAbsolute( p_input, p_demux->i_data_begin + i_offset );
p_demux->i_time = 0; p_demux->i_time = 0;
...@@ -416,6 +417,7 @@ static int Demux( input_thread_t *p_input ) ...@@ -416,6 +417,7 @@ static int Demux( input_thread_t *p_input )
} }
#undef p_stream #undef p_stream
} }
p_demux->i_first_pts = -1;
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* libasf.c : * libasf.c :
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: libasf.c,v 1.6 2002/11/14 16:17:47 fenrir Exp $ * $Id: libasf.c,v 1.7 2002/11/25 15:08:34 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -117,8 +117,16 @@ int ASF_SeekAbsolute( input_thread_t *p_input, ...@@ -117,8 +117,16 @@ int ASF_SeekAbsolute( input_thread_t *p_input,
return( 1 ); return( 1 );
} }
if( !p_input->stream.b_seekable && i_pos < i_filepos )
{
msg_Err( p_input, "cannot seek" );
return( 0 );
}
if( p_input->stream.b_seekable && if( p_input->stream.b_seekable &&
p_input->stream.i_method != INPUT_METHOD_NETWORK ) ( p_input->stream.i_method == INPUT_METHOD_FILE ||
i_pos < i_filepos ||
i_pos - i_filepos > 10000 ) )
{ {
p_input->pf_seek( p_input, i_pos ); p_input->pf_seek( p_input, i_pos );
input_AccessReinit( p_input ); input_AccessReinit( p_input );
...@@ -142,14 +150,8 @@ int ASF_SeekAbsolute( input_thread_t *p_input, ...@@ -142,14 +150,8 @@ int ASF_SeekAbsolute( input_thread_t *p_input,
i_size -= i_read; i_size -= i_read;
} while( i_size > 0 ); } while( i_size > 0 );
return( 1 );
} }
else return( 1 );
{
msg_Err( p_input, "cannot seek" );
return( 0 );
}
} }
/* return 1 if success, 0 if fail */ /* return 1 if success, 0 if fail */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment