/*****************************************************************************
* mmsh.c:
*****************************************************************************
- * Copyright (C) 2001, 2002 VideoLAN
+ * Copyright (C) 2001, 2002 the VideoLAN team
* $Id$
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* 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.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
#include "vlc_playlist.h"
#include "network.h"
+#include "vlc_url.h"
#include "asf.h"
#include "buffer.h"
vlc_bool_t *pb_bool;
int *pi_int;
int64_t *pi_64;
+ int i_int;
switch( i_query )
{
pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );
*pb_bool = !p_sys->b_broadcast;
break;
+
case ACCESS_CAN_FASTSEEK:
case ACCESS_CAN_PAUSE:
+ pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );
+ *pb_bool = VLC_FALSE;
+ break;
+
case ACCESS_CAN_CONTROL_PACE:
pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );
+
+#if 0 /* Disable for now until we have a clock synchro algo
+ * which works with something else than MPEG over UDP */
*pb_bool = VLC_FALSE;
+#endif
+ *pb_bool = VLC_TRUE;
break;
/* */
*pi_64 = (int64_t)var_GetInteger( p_access, "mms-caching" ) * I64C(1000);
break;
+ case ACCESS_GET_PRIVATE_ID_STATE:
+ i_int = (int)va_arg( args, int );
+ pb_bool = (vlc_bool_t *)va_arg( args, vlc_bool_t * );
+
+ if( i_int < 0 || i_int > 127 )
+ return VLC_EGENERIC;
+ *pb_bool = p_sys->asfh.stream[i_int].i_selected ? VLC_TRUE : VLC_FALSE;
+ break;
+
/* */
case ACCESS_SET_PAUSE_STATE:
case ACCESS_GET_TITLE_INFO:
if( p_access->info.b_eof )
return 0;
- while( i_data < i_len )
+ while( i_data < (size_t) i_len )
{
if( p_access->info.i_pos < p_sys->i_start + p_sys->i_header )
{
int i_offset = p_access->info.i_pos - p_sys->i_start;
- i_copy = __MIN( p_sys->i_header - i_offset, i_len - i_data );
+ i_copy = __MIN( p_sys->i_header - i_offset, (int)((size_t)i_len - i_data) );
memcpy( &p_buffer[i_data], &p_sys->p_header[i_offset], i_copy );
i_data += i_copy;
p_sys->i_packet_used += i_copy;
p_access->info.i_pos += i_copy;
}
- else if( p_sys->i_packet_length > 0 &&
- (int)p_sys->i_packet_used < p_sys->asfh.i_min_data_packet_size )
+ else if( (p_sys->i_packet_length > 0) &&
+ ((int)p_sys->i_packet_used < p_sys->asfh.i_min_data_packet_size) )
{
i_copy = __MIN( p_sys->asfh.i_min_data_packet_size - p_sys->i_packet_used,
i_len - i_data );
chunk_t ck;
if( GetPacket( p_access, &ck ) )
{
- if( ck.i_type == 0x4524 && ck.i_sequence != 0 && p_sys->b_broadcast )
+ if( (ck.i_type == 0x4524) && (ck.i_sequence != 0) &&
+ (p_sys->b_broadcast) )
{
char *psz_location = NULL;
p_sys->p_packet = NULL;
E_( GenerateGuid )( &p_sys->guid );
- if( ( p_sys->fd = net_OpenTCP( p_access, p_sys->url.psz_host,
+ if( ( p_sys->fd = net_ConnectTCP( p_access, p_sys->url.psz_host,
p_sys->url.i_port ) ) < 0 )
{
- msg_Err( p_access, "cannot connect to %s:%d", p_sys->url.psz_host, p_sys->url.i_port );
+ msg_Err( p_access, "cannot connect to %s:%d", p_sys->url.psz_host,
+ p_sys->url.i_port );
goto error;
}
{
chunk_t ck;
if( GetPacket( p_access, &ck ) ||
- ck.i_type != 0x4824 )
+ (ck.i_type != 0x4824) )
{
break;
}
* and bitrate mutual exclusion(optional) */
E_( asf_HeaderParse )( &p_sys->asfh,
p_sys->p_header, p_sys->i_header );
- msg_Dbg( p_access, "packet count=%lld packet size=%d",
+ msg_Dbg( p_access, "packet count="I64Fd" packet size=%d",
p_sys->asfh.i_data_packets_count,
p_sys->asfh.i_min_data_packet_size );
var_CreateGetInteger( p_access, "mms-all" ),
var_CreateGetInteger( p_access, "audio" ),
var_CreateGetInteger( p_access, "video" ) );
-
return VLC_SUCCESS;
error:
msg_Dbg( p_access, "starting stream" );
- if( ( p_sys->fd = net_OpenTCP( p_access, p_sys->url.psz_host,
- p_sys->url.i_port ) ) < 0 )
+ if( ( p_sys->fd = net_ConnectTCP( p_access, p_sys->url.psz_host,
+ p_sys->url.i_port ) ) < 0 )
{
/* should not occur */
msg_Err( p_access, "cannot connect to the server" );
static int GetPacket( access_t * p_access, chunk_t *p_ck )
{
access_sys_t *p_sys = p_access->p_sys;
+ int restsize;
/* chunk_t */
memset( p_ck, 0, sizeof( chunk_t ) );
/* Read the chunk header */
- if( net_Read( p_access, p_sys->fd, NULL, p_sys->buffer, 12, VLC_TRUE ) < 12 )
+ /* Some headers are short, like 0x4324. Reading 12 bytes will cause us
+ * to lose synchronization with the stream. Just read to the length
+ * (4 bytes), decode and then read up to 8 additional bytes to get the
+ * entire header.
+ */
+ if( net_Read( p_access, p_sys->fd, NULL, p_sys->buffer, 4, VLC_TRUE ) < 4 )
{
- /* msg_Err( p_access, "cannot read data" ); */
- return VLC_EGENERIC;
+ msg_Err( p_access, "cannot read data" );
+ return VLC_EGENERIC;
}
+ p_ck->i_type = GetWLE( p_sys->buffer);
+ p_ck->i_size = GetWLE( p_sys->buffer + 2);
+
+ restsize = p_ck->i_size;
+ if( restsize > 8 )
+ restsize = 8;
- p_ck->i_type = GetWLE( p_sys->buffer);
- p_ck->i_size = GetWLE( p_sys->buffer + 2);
+ if( net_Read( p_access, p_sys->fd, NULL, p_sys->buffer + 4, restsize, VLC_TRUE ) < restsize )
+ {
+ msg_Err( p_access, "cannot read data" );
+ return VLC_EGENERIC;
+ }
p_ck->i_sequence = GetDWLE( p_sys->buffer + 4);
p_ck->i_unknown = GetWLE( p_sys->buffer + 8);
- p_ck->i_size2 = GetWLE( p_sys->buffer + 10);
+
+ /* Set i_size2 to 8 if this header was short, since a real value won't be
+ * present in the buffer. Using 8 avoid reading additional data for the
+ * packet.
+ */
+ if( restsize < 8 )
+ p_ck->i_size2 = 8;
+ else
+ p_ck->i_size2 = GetWLE( p_sys->buffer + 10);
+
p_ck->p_data = p_sys->buffer + 12;
p_ck->i_data = p_ck->i_size2 - 8;
return VLC_EGENERIC;
}
}
- else if( p_ck->i_type != 0x4824 && p_ck->i_type != 0x4424 )
+ /* 0x4324 is CHUNK_TYPE_RESET. We can safely ignore it: a new stream will
+ * follow with a sequence of 0 */
+ else if( (p_ck->i_type != 0x4824) && (p_ck->i_type != 0x4424) &&
+ (p_ck->i_type != 0x4324) )
{
msg_Err( p_access, "invalid chunk FATAL (0x%x)", p_ck->i_type );
return VLC_EGENERIC;
}
- if( p_ck->i_data > 0 &&
- net_Read( p_access, p_sys->fd, NULL, &p_sys->buffer[12], p_ck->i_data, VLC_TRUE ) < p_ck->i_data )
+ if( (p_ck->i_data > 0) &&
+ (net_Read( p_access, p_sys->fd, NULL, &p_sys->buffer[12],
+ p_ck->i_data, VLC_TRUE ) < p_ck->i_data) )
{
msg_Err( p_access, "cannot read data" );
return VLC_EGENERIC;
}
- if( p_sys->i_packet_sequence != 0 &&
- p_ck->i_sequence != p_sys->i_packet_sequence )
+ if( (p_sys->i_packet_sequence != 0) &&
+ (p_ck->i_sequence != p_sys->i_packet_sequence) )
{
msg_Warn( p_access, "packet lost ? (%d != %d)", p_ck->i_sequence, p_sys->i_packet_sequence );
}