Commit 830641e4 authored by Laurent Aimar's avatar Laurent Aimar

Fixed #1102 ("Bad request" error)

Completed RESET command support.
Updated user agent to "NSPlayer/7.10.0.3059"
parent d4b31bea
...@@ -57,7 +57,15 @@ static int Control( access_t *, int, va_list ); ...@@ -57,7 +57,15 @@ static int Control( access_t *, int, va_list );
static int Describe( access_t *, char **ppsz_location ); static int Describe( access_t *, char **ppsz_location );
static int Start( access_t *, int64_t ); static int Start( access_t *, int64_t );
static void Stop( access_t * ); static void Stop( access_t * );
static int GetPacket( access_t *, chunk_t * ); static int GetPacket( access_t *, chunk_t * );
static void GetHeader( access_t *p_access );
static int Restart( access_t * );
static int Reset( access_t * );
//#define MMSH_USER_AGENT "NSPlayer/4.1.0.3856"
#define MMSH_USER_AGENT "NSPlayer/7.10.0.3059"
/**************************************************************************** /****************************************************************************
* Open: connect to ftp server and ask for file * Open: connect to ftp server and ask for file
...@@ -320,47 +328,111 @@ static int Read( access_t *p_access, uint8_t *p_buffer, int i_len ) ...@@ -320,47 +328,111 @@ static int Read( access_t *p_access, uint8_t *p_buffer, int i_len )
chunk_t ck; chunk_t ck;
if( GetPacket( p_access, &ck ) ) if( GetPacket( p_access, &ck ) )
{ {
if( (ck.i_type == 0x4524) && (ck.i_sequence != 0) && int i_ret = -1;
(p_sys->b_broadcast) ) if( p_sys->b_broadcast )
{
if( ck.i_type == 0x4524 && ck.i_sequence != 0 )
i_ret = Restart( p_access );
else if( ck.i_type == 0x4324 )
i_ret = Reset( p_access );
}
if( i_ret )
{
p_access->info.b_eof = VLC_TRUE;
return 0;
}
}
if( ck.i_type != 0x4424 )
{ {
p_sys->i_packet_used = 0;
p_sys->i_packet_length = 0;
}
}
}
return( i_data );
}
/* */
static int Restart( access_t *p_access )
{
access_sys_t *p_sys = p_access->p_sys;
char *psz_location = NULL; char *psz_location = NULL;
msg_Dbg( p_access, "Restart the stream" );
p_sys->i_start = p_access->info.i_pos; p_sys->i_start = p_access->info.i_pos;
/* */
msg_Dbg( p_access, "stoping the stream" ); msg_Dbg( p_access, "stoping the stream" );
Stop( p_access ); Stop( p_access );
/* */
msg_Dbg( p_access, "describe the stream" ); msg_Dbg( p_access, "describe the stream" );
if( Describe( p_access, &psz_location ) ) if( Describe( p_access, &psz_location ) )
{ {
msg_Err( p_access, "describe failed" ); msg_Err( p_access, "describe failed" );
p_access->info.b_eof = VLC_TRUE; return -1;
return 0;
} }
/* */
if( Start( p_access, 0 ) ) if( Start( p_access, 0 ) )
{ {
msg_Err( p_access, "Start failed" ); msg_Err( p_access, "Start failed" );
p_access->info.b_eof = VLC_TRUE; return -1;
return 0;
} }
}
else
{
p_access->info.b_eof = VLC_TRUE;
return 0; return 0;
} }
} static int Reset( access_t *p_access )
if( ck.i_type != 0x4424 ) {
{ access_sys_t *p_sys = p_access->p_sys;
asf_header_t old_asfh = p_sys->asfh;
int i;
msg_Dbg( p_access, "Reset the stream" );
p_sys->i_start = p_access->info.i_pos;
/* */
p_sys->i_packet_sequence = 0;
p_sys->i_packet_used = 0; p_sys->i_packet_used = 0;
p_sys->i_packet_length = 0; p_sys->i_packet_length = 0;
p_sys->p_packet = NULL;
/* Get the next header FIXME memory loss ? */
GetHeader( p_access );
if( p_sys->i_header <= 0 )
return -1;
E_( asf_HeaderParse )( &p_sys->asfh,
p_sys->p_header, p_sys->i_header );
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 );
E_( asf_StreamSelect)( &p_sys->asfh,
var_CreateGetInteger( p_access, "mms-maxbitrate" ),
var_CreateGetInteger( p_access, "mms-all" ),
var_CreateGetInteger( p_access, "audio" ),
var_CreateGetInteger( p_access, "video" ) );
/* Check we have comptible asfh */
for( i = 1; i < 128; i++ )
{
asf_stream_t *p_old = &old_asfh.stream[i];
asf_stream_t *p_new = &p_sys->asfh.stream[i];
if( p_old->i_cat != p_new->i_cat || p_old->i_selected != p_new->i_selected )
break;
} }
} if( i < 128 )
{
msg_Warn( p_access, "incompatible asf header, restart" );
return Restart( p_access );
} }
return( i_data ); /* */
p_sys->i_packet_used = 0;
p_sys->i_packet_length = 0;
return 0;
} }
/***************************************************************************** /*****************************************************************************
* Describe: * Describe:
*****************************************************************************/ *****************************************************************************/
...@@ -392,7 +464,7 @@ static int Describe( access_t *p_access, char **ppsz_location ) ...@@ -392,7 +464,7 @@ static int Describe( access_t *p_access, char **ppsz_location )
net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL, net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,
"GET %s HTTP/1.0\r\n" "GET %s HTTP/1.0\r\n"
"Accept: */*\r\n" "Accept: */*\r\n"
"User-Agent: NSPlayer/4.1.0.3856\r\n" "User-Agent: "MMSH_USER_AGENT"\r\n"
"Host: %s:%d\r\n" "Host: %s:%d\r\n"
"Pragma: no-cache,rate=1.000000,stream-time=0,stream-offset=0:0,request-context=%d,max-duration=0\r\n" "Pragma: no-cache,rate=1.000000,stream-time=0,stream-offset=0:0,request-context=%d,max-duration=0\r\n"
"Pragma: xClientGUID={"GUID_FMT"}\r\n" "Pragma: xClientGUID={"GUID_FMT"}\r\n"
...@@ -501,26 +573,7 @@ static int Describe( access_t *p_access, char **ppsz_location ) ...@@ -501,26 +573,7 @@ static int Describe( access_t *p_access, char **ppsz_location )
} }
/* Read the asf header */ /* Read the asf header */
p_sys->i_header = 0; GetHeader( p_access );
p_sys->p_header = NULL;
for( ;; )
{
chunk_t ck;
if( GetPacket( p_access, &ck ) ||
(ck.i_type != 0x4824) )
{
break;
}
if( ck.i_data > 0 )
{
p_sys->i_header += ck.i_data;
p_sys->p_header = realloc( p_sys->p_header, p_sys->i_header );
memcpy( &p_sys->p_header[p_sys->i_header - ck.i_data],
ck.p_data, ck.i_data );
}
}
msg_Dbg( p_access, "complete header size=%d", p_sys->i_header );
if( p_sys->i_header <= 0 ) if( p_sys->i_header <= 0 )
{ {
msg_Err( p_access, "header size == 0" ); msg_Err( p_access, "header size == 0" );
...@@ -555,6 +608,30 @@ error: ...@@ -555,6 +608,30 @@ error:
} }
return VLC_EGENERIC; return VLC_EGENERIC;
} }
static void GetHeader( access_t *p_access )
{
access_sys_t *p_sys = p_access->p_sys;
/* Read the asf header */
p_sys->i_header = 0;
p_sys->p_header = NULL;
for( ;; )
{
chunk_t ck;
if( GetPacket( p_access, &ck ) || ck.i_type != 0x4824 )
break;
if( ck.i_data > 0 )
{
p_sys->i_header += ck.i_data;
p_sys->p_header = realloc( p_sys->p_header, p_sys->i_header );
memcpy( &p_sys->p_header[p_sys->i_header - ck.i_data],
ck.p_data, ck.i_data );
}
}
msg_Dbg( p_access, "complete header size=%d", p_sys->i_header );
}
/***************************************************************************** /*****************************************************************************
* *
...@@ -563,6 +640,7 @@ static int Start( access_t *p_access, off_t i_pos ) ...@@ -563,6 +640,7 @@ static int Start( access_t *p_access, off_t i_pos )
{ {
access_sys_t *p_sys = p_access->p_sys; access_sys_t *p_sys = p_access->p_sys;
int i_streams = 0; int i_streams = 0;
int i_streams_selected = 0;
int i; int i;
char *psz; char *psz;
...@@ -578,13 +656,14 @@ static int Start( access_t *p_access, off_t i_pos ) ...@@ -578,13 +656,14 @@ static int Start( access_t *p_access, off_t i_pos )
for( i = 1; i < 128; i++ ) for( i = 1; i < 128; i++ )
{ {
if( p_sys->asfh.stream[i].i_selected ) if( p_sys->asfh.stream[i].i_cat == ASF_STREAM_UNKNOWN )
{ continue;
i_streams++; i_streams++;
} if( p_sys->asfh.stream[i].i_selected )
i_streams_selected++;
} }
if( i_streams <= 0 ) if( i_streams_selected <= 0 )
{ {
msg_Err( p_access, "no stream selected" ); msg_Err( p_access, "no stream selected" );
return VLC_EGENERIC; return VLC_EGENERIC;
...@@ -592,7 +671,7 @@ static int Start( access_t *p_access, off_t i_pos ) ...@@ -592,7 +671,7 @@ static int Start( access_t *p_access, off_t i_pos )
net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL, net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,
"GET %s HTTP/1.0\r\n" "GET %s HTTP/1.0\r\n"
"Accept: */*\r\n" "Accept: */*\r\n"
"User-Agent: NSPlayer/4.1.0.3856\r\n" "User-Agent: "MMSH_USER_AGENT"\r\n"
"Host: %s:%d\r\n", "Host: %s:%d\r\n",
( p_sys->url.psz_path == NULL || *p_sys->url.psz_path == '\0' ) ? "/" : p_sys->url.psz_path, ( p_sys->url.psz_path == NULL || *p_sys->url.psz_path == '\0' ) ? "/" : p_sys->url.psz_path,
p_sys->url.psz_host, p_sys->url.i_port ); p_sys->url.psz_host, p_sys->url.i_port );
...@@ -713,10 +792,8 @@ static int GetPacket( access_t * p_access, chunk_t *p_ck ) ...@@ -713,10 +792,8 @@ static int GetPacket( access_t * p_access, chunk_t *p_ck )
* entire header. * entire header.
*/ */
if( net_Read( p_access, p_sys->fd, NULL, p_sys->buffer, 4, VLC_TRUE ) < 4 ) 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; return VLC_EGENERIC;
}
p_ck->i_type = GetWLE( p_sys->buffer); p_ck->i_type = GetWLE( p_sys->buffer);
p_ck->i_size = GetWLE( p_sys->buffer + 2); p_ck->i_size = GetWLE( p_sys->buffer + 2);
...@@ -753,14 +830,17 @@ static int GetPacket( access_t * p_access, chunk_t *p_ck ) ...@@ -753,14 +830,17 @@ static int GetPacket( access_t * p_access, chunk_t *p_ck )
} }
else else
{ {
msg_Warn( p_access, "next stream follow but not supported" ); msg_Warn( p_access, "next stream following" );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
} }
/* 0x4324 is CHUNK_TYPE_RESET. We can safely ignore it: a new stream will else if( p_ck->i_type == 0x4324 )
* follow with a sequence of 0 */ {
else if( (p_ck->i_type != 0x4824) && (p_ck->i_type != 0x4424) && /* 0x4324 is CHUNK_TYPE_RESET: a new stream will follow with a sequence of 0 */
(p_ck->i_type != 0x4324) ) msg_Warn( p_access, "next stream following (reset) seq=%d", p_ck->i_sequence );
return VLC_EGENERIC;
}
else if( (p_ck->i_type != 0x4824) && (p_ck->i_type != 0x4424) )
{ {
msg_Err( p_access, "invalid chunk FATAL (0x%x)", p_ck->i_type ); msg_Err( p_access, "invalid chunk FATAL (0x%x)", p_ck->i_type );
return VLC_EGENERIC; return VLC_EGENERIC;
...@@ -774,11 +854,13 @@ static int GetPacket( access_t * p_access, chunk_t *p_ck ) ...@@ -774,11 +854,13 @@ static int GetPacket( access_t * p_access, chunk_t *p_ck )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
#if 0
if( (p_sys->i_packet_sequence != 0) && if( (p_sys->i_packet_sequence != 0) &&
(p_ck->i_sequence != p_sys->i_packet_sequence) ) (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 ); msg_Warn( p_access, "packet lost ? (%d != %d)", p_ck->i_sequence, p_sys->i_packet_sequence );
} }
#endif
p_sys->i_packet_sequence = p_ck->i_sequence + 1; p_sys->i_packet_sequence = p_ck->i_sequence + 1;
p_sys->i_packet_used = 0; p_sys->i_packet_used = 0;
......
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