00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <stdlib.h>
00028
00029 #include <vlc/vlc.h>
00030 #include <vlc/input.h>
00031
00032 #include "vlc_playlist.h"
00033
00034 #include "network.h"
00035 #include "asf.h"
00036 #include "buffer.h"
00037
00038 #include "mms.h"
00039 #include "mmsh.h"
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 int E_(MMSHOpen) ( access_t * );
00050 void E_(MMSHClose) ( access_t * );
00051
00052 static int Read( access_t *, uint8_t *, int );
00053 static int ReadRedirect( access_t *, uint8_t *, int );
00054 static int Seek( access_t *, int64_t );
00055 static int Control( access_t *, int, va_list );
00056
00057 static int Describe( access_t *, char **ppsz_location );
00058 static int Start( access_t *, int64_t );
00059 static void Stop( access_t * );
00060 static int GetPacket( access_t *, chunk_t * );
00061
00062
00063
00064
00065 int E_(MMSHOpen)( access_t *p_access )
00066 {
00067 access_sys_t *p_sys;
00068 char *psz_location = NULL;
00069
00070
00071
00072
00073 p_access->pf_read = Read;
00074 p_access->pf_block = NULL;
00075 p_access->pf_control = Control;
00076 p_access->pf_seek = Seek;
00077 p_access->info.i_update = 0;
00078 p_access->info.i_size = 0;
00079 p_access->info.i_pos = 0;
00080 p_access->info.b_eof = VLC_FALSE;
00081 p_access->info.i_title = 0;
00082 p_access->info.i_seekpoint = 0;
00083 p_access->p_sys = p_sys = malloc( sizeof( access_sys_t ) );
00084 memset( p_sys, 0, sizeof( access_sys_t ) );
00085 p_sys->i_proto= MMS_PROTO_HTTP;
00086 p_sys->fd = -1;
00087 p_sys->i_start= 0;
00088
00089
00090 vlc_UrlParse( &p_sys->url, p_access->psz_path, 0 );
00091 if( p_sys->url.psz_host == NULL || *p_sys->url.psz_host == '\0' )
00092 {
00093 msg_Err( p_access, "invalid host" );
00094 vlc_UrlClean( &p_sys->url );
00095 free( p_sys );
00096 return VLC_EGENERIC;
00097 }
00098 if( p_sys->url.i_port <= 0 )
00099 p_sys->url.i_port = 80;
00100
00101 if( Describe( p_access, &psz_location ) )
00102 {
00103 vlc_UrlClean( &p_sys->url );
00104 free( p_sys );
00105 return VLC_EGENERIC;
00106 }
00107
00108 if( psz_location && *psz_location )
00109 {
00110 playlist_t * p_playlist = vlc_object_find( p_access, VLC_OBJECT_PLAYLIST, FIND_PARENT );
00111
00112 msg_Dbg( p_access, "redirection to %s", psz_location );
00113
00114 if( !p_playlist )
00115 {
00116 msg_Err( p_access, "redirection failed: can't find playlist" );
00117 free( psz_location );
00118 return VLC_EGENERIC;
00119 }
00120 p_playlist->pp_items[p_playlist->i_index]->b_autodeletion = VLC_TRUE;
00121 playlist_Add( p_playlist, psz_location, psz_location,
00122 PLAYLIST_INSERT | PLAYLIST_GO,
00123 p_playlist->i_index + 1 );
00124 vlc_object_release( p_playlist );
00125
00126 free( psz_location );
00127
00128 p_access->pf_read = ReadRedirect;
00129 return VLC_SUCCESS;
00130 }
00131
00132
00133 if( Start( p_access, 0 ) )
00134 {
00135 msg_Err( p_access, "cannot start stream" );
00136 free( p_sys->p_header );
00137 vlc_UrlClean( &p_sys->url );
00138 free( p_sys );
00139 return VLC_EGENERIC;
00140 }
00141
00142 if( !p_sys->b_broadcast )
00143 {
00144 p_access->info.i_size = p_sys->asfh.i_file_size;
00145 }
00146
00147 return VLC_SUCCESS;
00148 }
00149
00150
00151
00152
00153 void E_( MMSHClose )( access_t *p_access )
00154 {
00155 access_sys_t *p_sys = p_access->p_sys;
00156
00157 Stop( p_access );
00158 free( p_sys );
00159 }
00160
00161
00162
00163
00164 static int Control( access_t *p_access, int i_query, va_list args )
00165 {
00166 access_sys_t *p_sys = p_access->p_sys;
00167 vlc_bool_t *pb_bool;
00168 int *pi_int;
00169 int64_t *pi_64;
00170 int i_int;
00171
00172 switch( i_query )
00173 {
00174
00175 case ACCESS_CAN_SEEK:
00176 pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );
00177 *pb_bool = !p_sys->b_broadcast;
00178 break;
00179
00180 case ACCESS_CAN_FASTSEEK:
00181 case ACCESS_CAN_PAUSE:
00182 pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );
00183 *pb_bool = VLC_FALSE;
00184 break;
00185
00186 case ACCESS_CAN_CONTROL_PACE:
00187 pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );
00188
00189 #if 0
00190
00191 *pb_bool = VLC_FALSE;
00192 #endif
00193 *pb_bool = VLC_TRUE;
00194 break;
00195
00196
00197 case ACCESS_GET_MTU:
00198 pi_int = (int*)va_arg( args, int * );
00199 *pi_int = 3 * p_sys->asfh.i_min_data_packet_size;
00200 break;
00201
00202 case ACCESS_GET_PTS_DELAY:
00203 pi_64 = (int64_t*)va_arg( args, int64_t * );
00204 *pi_64 = (int64_t)var_GetInteger( p_access, "mms-caching" ) * I64C(1000);
00205 break;
00206
00207 case ACCESS_GET_PRIVATE_ID_STATE:
00208 i_int = (int)va_arg( args, int );
00209 pb_bool = (vlc_bool_t *)va_arg( args, vlc_bool_t * );
00210
00211 if( i_int < 0 || i_int > 127 )
00212 return VLC_EGENERIC;
00213 *pb_bool = p_sys->asfh.stream[i_int].i_selected ? VLC_TRUE : VLC_FALSE;
00214 break;
00215
00216
00217 case ACCESS_SET_PAUSE_STATE:
00218 case ACCESS_GET_TITLE_INFO:
00219 case ACCESS_SET_TITLE:
00220 case ACCESS_SET_SEEKPOINT:
00221 case ACCESS_SET_PRIVATE_ID_STATE:
00222 return VLC_EGENERIC;
00223
00224 default:
00225 msg_Warn( p_access, "unimplemented query in control" );
00226 return VLC_EGENERIC;
00227
00228 }
00229 return VLC_SUCCESS;
00230 }
00231
00232
00233
00234
00235 static int Seek( access_t *p_access, int64_t i_pos )
00236 {
00237 access_sys_t *p_sys = p_access->p_sys;
00238 chunk_t ck;
00239 off_t i_offset;
00240 off_t i_packet;
00241
00242 msg_Dbg( p_access, "seeking to "I64Fd, i_pos );
00243
00244 i_packet = ( i_pos - p_sys->i_header ) / p_sys->asfh.i_min_data_packet_size;
00245 i_offset = ( i_pos - p_sys->i_header ) % p_sys->asfh.i_min_data_packet_size;
00246
00247 Stop( p_access );
00248 Start( p_access, i_packet * p_sys->asfh.i_min_data_packet_size );
00249
00250 while( !p_access->b_die )
00251 {
00252 if( GetPacket( p_access, &ck ) )
00253 break;
00254
00255
00256 if( ck.i_type != 0x4824 )
00257 break;
00258
00259 msg_Warn( p_access, "skipping header" );
00260 }
00261
00262 p_access->info.i_pos = i_pos;
00263 p_access->info.b_eof = VLC_FALSE;
00264 p_sys->i_packet_used += i_offset;
00265
00266 return VLC_SUCCESS;
00267 }
00268
00269
00270
00271
00272 static int ReadRedirect( access_t *p_access, uint8_t *p, int i_len )
00273 {
00274 return 0;
00275 }
00276
00277
00278
00279
00280 static int Read( access_t *p_access, uint8_t *p_buffer, int i_len )
00281 {
00282 access_sys_t *p_sys = p_access->p_sys;
00283 size_t i_copy;
00284 size_t i_data = 0;
00285
00286 if( p_access->info.b_eof )
00287 return 0;
00288
00289 while( i_data < (size_t) i_len )
00290 {
00291 if( p_access->info.i_pos < p_sys->i_start + p_sys->i_header )
00292 {
00293 int i_offset = p_access->info.i_pos - p_sys->i_start;
00294 i_copy = __MIN( p_sys->i_header - i_offset, (int)((size_t)i_len - i_data) );
00295 memcpy( &p_buffer[i_data], &p_sys->p_header[i_offset], i_copy );
00296
00297 i_data += i_copy;
00298 p_access->info.i_pos += i_copy;
00299 }
00300 else if( p_sys->i_packet_used < p_sys->i_packet_length )
00301 {
00302 i_copy = __MIN( p_sys->i_packet_length - p_sys->i_packet_used,
00303 i_len - i_data );
00304
00305 memcpy( &p_buffer[i_data],
00306 &p_sys->p_packet[p_sys->i_packet_used],
00307 i_copy );
00308
00309 i_data += i_copy;
00310 p_sys->i_packet_used += i_copy;
00311 p_access->info.i_pos += i_copy;
00312 }
00313 else if( p_sys->i_packet_length > 0 &&
00314 (int)p_sys->i_packet_used < p_sys->asfh.i_min_data_packet_size )
00315 {
00316 i_copy = __MIN( p_sys->asfh.i_min_data_packet_size - p_sys->i_packet_used,
00317 i_len - i_data );
00318
00319 memset( &p_buffer[i_data], 0, i_copy );
00320
00321 i_data += i_copy;
00322 p_sys->i_packet_used += i_copy;
00323 p_access->info.i_pos += i_copy;
00324 }
00325 else
00326 {
00327 chunk_t ck;
00328 if( GetPacket( p_access, &ck ) )
00329 {
00330 if( ck.i_type == 0x4524 && ck.i_sequence != 0 && p_sys->b_broadcast )
00331 {
00332 char *psz_location = NULL;
00333
00334 p_sys->i_start = p_access->info.i_pos;
00335
00336 msg_Dbg( p_access, "stoping the stream" );
00337 Stop( p_access );
00338
00339 msg_Dbg( p_access, "describe the stream" );
00340 if( Describe( p_access, &psz_location ) )
00341 {
00342 msg_Err( p_access, "describe failed" );
00343 p_access->info.b_eof = VLC_TRUE;
00344 return 0;
00345 }
00346 if( Start( p_access, 0 ) )
00347 {
00348 msg_Err( p_access, "Start failed" );
00349 p_access->info.b_eof = VLC_TRUE;
00350 return 0;
00351 }
00352 }
00353 else
00354 {
00355 p_access->info.b_eof = VLC_TRUE;
00356 return 0;
00357 }
00358 }
00359 if( ck.i_type != 0x4424 )
00360 {
00361 p_sys->i_packet_used = 0;
00362 p_sys->i_packet_length = 0;
00363 }
00364 }
00365 }
00366
00367 return( i_data );
00368 }
00369
00370
00371
00372
00373 static int Describe( access_t *p_access, char **ppsz_location )
00374 {
00375 access_sys_t *p_sys = p_access->p_sys;
00376 char *psz_location = NULL;
00377 char *psz;
00378 int i_code;
00379
00380
00381 p_sys->b_broadcast = VLC_TRUE;
00382 p_sys->i_request_context = 1;
00383 p_sys->i_packet_sequence = 0;
00384 p_sys->i_packet_used = 0;
00385 p_sys->i_packet_length = 0;
00386 p_sys->p_packet = NULL;
00387 E_( GenerateGuid )( &p_sys->guid );
00388
00389 if( ( p_sys->fd = net_OpenTCP( p_access, p_sys->url.psz_host,
00390 p_sys->url.i_port ) ) < 0 )
00391 {
00392 msg_Err( p_access, "cannot connect to %s:%d", p_sys->url.psz_host, p_sys->url.i_port );
00393 goto error;
00394 }
00395
00396
00397 net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,
00398 "GET %s HTTP/1.0\r\n"
00399 "Accept: */*\r\n"
00400 "User-Agent: NSPlayer/4.1.0.3856\r\n"
00401 "Host: %s:%d\r\n"
00402 "Pragma: no-cache,rate=1.000000,stream-time=0,stream-offset=0:0,request-context=%d,max-duration=0\r\n"
00403 "Pragma: xClientGUID={"GUID_FMT"}\r\n"
00404 "Connection: Close\r\n",
00405 ( p_sys->url.psz_path == NULL || *p_sys->url.psz_path == '\0' ) ? "/" : p_sys->url.psz_path,
00406 p_sys->url.psz_host, p_sys->url.i_port,
00407 p_sys->i_request_context++,
00408 GUID_PRINT( p_sys->guid ) );
00409
00410 if( net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL, "\r\n" ) < 0 )
00411 {
00412 msg_Err( p_access, "failed to send request" );
00413 goto error;
00414 }
00415
00416
00417 if( ( psz = net_Gets( VLC_OBJECT(p_access), p_sys->fd, NULL ) ) == NULL )
00418 {
00419 msg_Err( p_access, "failed to read answer" );
00420 goto error;
00421 }
00422 if( strncmp( psz, "HTTP/1.", 7 ) )
00423 {
00424 msg_Err( p_access, "invalid HTTP reply '%s'", psz );
00425 free( psz );
00426 goto error;
00427 }
00428 i_code = atoi( &psz[9] );
00429 if( i_code >= 400 )
00430 {
00431 msg_Err( p_access, "error: %s", psz );
00432 free( psz );
00433 goto error;
00434 }
00435
00436 msg_Dbg( p_access, "HTTP reply '%s'", psz );
00437 free( psz );
00438 for( ;; )
00439 {
00440 char *psz = net_Gets( p_access, p_sys->fd, NULL );
00441 char *p;
00442
00443 if( psz == NULL )
00444 {
00445 msg_Err( p_access, "failed to read answer" );
00446 goto error;
00447 }
00448
00449 if( *psz == '\0' )
00450 {
00451 free( psz );
00452 break;
00453 }
00454
00455 if( ( p = strchr( psz, ':' ) ) == NULL )
00456 {
00457 msg_Err( p_access, "malformed header line: %s", psz );
00458 free( psz );
00459 goto error;
00460 }
00461 *p++ = '\0';
00462 while( *p == ' ' ) p++;
00463
00464
00465
00466 if( !strcasecmp( psz, "Pragma" ) )
00467 {
00468 if( strstr( p, "features" ) )
00469 {
00470
00471 if( strstr( p, "broadcast" ) )
00472 {
00473 msg_Dbg( p_access, "stream type = broadcast" );
00474 p_sys->b_broadcast = VLC_TRUE;
00475 }
00476 else if( strstr( p, "seekable" ) )
00477 {
00478 msg_Dbg( p_access, "stream type = seekable" );
00479 p_sys->b_broadcast = VLC_FALSE;
00480 }
00481 else
00482 {
00483 msg_Warn( p_access, "unknow stream types (%s)", p );
00484 p_sys->b_broadcast = VLC_FALSE;
00485 }
00486 }
00487 }
00488 else if( !strcasecmp( psz, "Location" ) )
00489 {
00490 psz_location = strdup( p );
00491 }
00492
00493 free( psz );
00494 }
00495
00496
00497 if( ( i_code == 301 || i_code == 302 ||
00498 i_code == 303 || i_code == 307 ) &&
00499 psz_location && *psz_location )
00500 {
00501 msg_Dbg( p_access, "redirection to %s", psz_location );
00502 net_Close( p_sys->fd ); p_sys->fd = -1;
00503
00504 *ppsz_location = psz_location;
00505 return VLC_SUCCESS;
00506 }
00507
00508
00509 p_sys->i_header = 0;
00510 p_sys->p_header = NULL;
00511 for( ;; )
00512 {
00513 chunk_t ck;
00514 if( GetPacket( p_access, &ck ) ||
00515 ck.i_type != 0x4824 )
00516 {
00517 break;
00518 }
00519
00520 if( ck.i_data > 0 )
00521 {
00522 p_sys->i_header += ck.i_data;
00523 p_sys->p_header = realloc( p_sys->p_header, p_sys->i_header );
00524 memcpy( &p_sys->p_header[p_sys->i_header - ck.i_data],
00525 ck.p_data, ck.i_data );
00526 }
00527 }
00528 msg_Dbg( p_access, "complete header size=%d", p_sys->i_header );
00529 if( p_sys->i_header <= 0 )
00530 {
00531 msg_Err( p_access, "header size == 0" );
00532 goto error;
00533 }
00534
00535 net_Close( p_sys->fd ); p_sys->fd = -1;
00536
00537
00538
00539
00540
00541
00542 E_( asf_HeaderParse )( &p_sys->asfh,
00543 p_sys->p_header, p_sys->i_header );
00544 msg_Dbg( p_access, "packet count="I64Fd" packet size=%d",
00545 p_sys->asfh.i_data_packets_count,
00546 p_sys->asfh.i_min_data_packet_size );
00547
00548 E_( asf_StreamSelect)( &p_sys->asfh,
00549 var_CreateGetInteger( p_access, "mms-maxbitrate" ),
00550 var_CreateGetInteger( p_access, "mms-all" ),
00551 var_CreateGetInteger( p_access, "audio" ),
00552 var_CreateGetInteger( p_access, "video" ) );
00553
00554 return VLC_SUCCESS;
00555
00556 error:
00557 if( p_sys->fd > 0 )
00558 {
00559 net_Close( p_sys->fd );
00560 p_sys->fd = -1;
00561 }
00562 return VLC_EGENERIC;
00563 }
00564
00565
00566
00567
00568 static int Start( access_t *p_access, off_t i_pos )
00569 {
00570 access_sys_t *p_sys = p_access->p_sys;
00571 int i_streams = 0;
00572 int i;
00573 char *psz;
00574
00575 msg_Dbg( p_access, "starting stream" );
00576
00577 if( ( p_sys->fd = net_OpenTCP( p_access, p_sys->url.psz_host,
00578 p_sys->url.i_port ) ) < 0 )
00579 {
00580
00581 msg_Err( p_access, "cannot connect to the server" );
00582 return VLC_EGENERIC;
00583 }
00584
00585 for( i = 1; i < 128; i++ )
00586 {
00587 if( p_sys->asfh.stream[i].i_selected )
00588 {
00589 i_streams++;
00590 }
00591 }
00592
00593 if( i_streams <= 0 )
00594 {
00595 msg_Err( p_access, "no stream selected" );
00596 return VLC_EGENERIC;
00597 }
00598 net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,
00599 "GET %s HTTP/1.0\r\n"
00600 "Accept: */*\r\n"
00601 "User-Agent: NSPlayer/4.1.0.3856\r\n"
00602 "Host: %s:%d\r\n",
00603 ( p_sys->url.psz_path == NULL || *p_sys->url.psz_path == '\0' ) ? "/" : p_sys->url.psz_path,
00604 p_sys->url.psz_host, p_sys->url.i_port );
00605 if( p_sys->b_broadcast )
00606 {
00607 net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,
00608 "Pragma: no-cache,rate=1.000000,request-context=%d\r\n",
00609 p_sys->i_request_context++ );
00610 }
00611 else
00612 {
00613 net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,
00614 "Pragma: no-cache,rate=1.000000,stream-time=0,stream-offset=%u:%u,request-context=%d,max-duration=0\r\n",
00615 (uint32_t)((i_pos >> 32)&0xffffffff),
00616 (uint32_t)(i_pos&0xffffffff),
00617 p_sys->i_request_context++ );
00618 }
00619 net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,
00620 "Pragma: xPlayStrm=1\r\n"
00621 "Pragma: xClientGUID={"GUID_FMT"}\r\n"
00622 "Pragma: stream-switch-count=%d\r\n"
00623 "Pragma: stream-switch-entry=",
00624 GUID_PRINT( p_sys->guid ),
00625 i_streams);
00626
00627 for( i = 1; i < 128; i++ )
00628 {
00629 if( p_sys->asfh.stream[i].i_cat != ASF_STREAM_UNKNOWN )
00630 {
00631 int i_select = 2;
00632 if( p_sys->asfh.stream[i].i_selected )
00633 {
00634 i_select = 0;
00635 }
00636
00637 net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,
00638 "ffff:%d:%d ", i, i_select );
00639 }
00640 }
00641 net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL, "\r\n" );
00642 net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,
00643 "Connection: Close\r\n" );
00644
00645 if( net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL, "\r\n" ) < 0 )
00646 {
00647 msg_Err( p_access, "failed to send request" );
00648 return VLC_EGENERIC;
00649 }
00650
00651 if( ( psz = net_Gets( VLC_OBJECT(p_access), p_sys->fd, NULL ) ) == NULL )
00652 {
00653 msg_Err( p_access, "cannot read data" );
00654 return VLC_EGENERIC;
00655 }
00656 if( atoi( &psz[9] ) >= 400 )
00657 {
00658 msg_Err( p_access, "error: %s", psz );
00659 free( psz );
00660 return VLC_EGENERIC;
00661 }
00662 msg_Dbg( p_access, "HTTP reply '%s'", psz );
00663 free( psz );
00664
00665
00666 for( ;; )
00667 {
00668 char *psz = net_Gets( p_access, p_sys->fd, NULL );
00669 if( psz == NULL )
00670 {
00671 msg_Err( p_access, "cannot read data" );
00672 return VLC_EGENERIC;
00673 }
00674 if( *psz == '\0' )
00675 {
00676 free( psz );
00677 break;
00678 }
00679 msg_Dbg( p_access, "%s", psz );
00680 free( psz );
00681 }
00682
00683 p_sys->i_packet_used = 0;
00684 p_sys->i_packet_length = 0;
00685
00686 return VLC_SUCCESS;
00687 }
00688
00689
00690
00691
00692 static void Stop( access_t *p_access )
00693 {
00694 access_sys_t *p_sys = p_access->p_sys;
00695
00696 msg_Dbg( p_access, "closing stream" );
00697 if( p_sys->fd > 0 )
00698 {
00699 net_Close( p_sys->fd );
00700 p_sys->fd = -1;
00701 }
00702 }
00703
00704
00705
00706
00707 static int GetPacket( access_t * p_access, chunk_t *p_ck )
00708 {
00709 access_sys_t *p_sys = p_access->p_sys;
00710
00711
00712 memset( p_ck, 0, sizeof( chunk_t ) );
00713
00714
00715 if( net_Read( p_access, p_sys->fd, NULL, p_sys->buffer, 12, VLC_TRUE ) < 12 )
00716 {
00717
00718 return VLC_EGENERIC;
00719 }
00720
00721 p_ck->i_type = GetWLE( p_sys->buffer);
00722 p_ck->i_size = GetWLE( p_sys->buffer + 2);
00723 p_ck->i_sequence = GetDWLE( p_sys->buffer + 4);
00724 p_ck->i_unknown = GetWLE( p_sys->buffer + 8);
00725 p_ck->i_size2 = GetWLE( p_sys->buffer + 10);
00726 p_ck->p_data = p_sys->buffer + 12;
00727 p_ck->i_data = p_ck->i_size2 - 8;
00728
00729 if( p_ck->i_type == 0x4524 )
00730 {
00731 if( p_ck->i_sequence == 0 )
00732 {
00733 msg_Warn( p_access, "EOF" );
00734 return VLC_EGENERIC;
00735 }
00736 else
00737 {
00738 msg_Warn( p_access, "Next stream follow but not supported" );
00739 return VLC_EGENERIC;
00740 }
00741 }
00742 else if( p_ck->i_type != 0x4824 && p_ck->i_type != 0x4424 )
00743 {
00744 msg_Err( p_access, "invalid chunk FATAL (0x%x)", p_ck->i_type );
00745 return VLC_EGENERIC;
00746 }
00747
00748 if( p_ck->i_data > 0 &&
00749 net_Read( p_access, p_sys->fd, NULL, &p_sys->buffer[12], p_ck->i_data, VLC_TRUE ) < p_ck->i_data )
00750 {
00751 msg_Err( p_access, "cannot read data" );
00752 return VLC_EGENERIC;
00753 }
00754
00755 if( p_sys->i_packet_sequence != 0 &&
00756 p_ck->i_sequence != p_sys->i_packet_sequence )
00757 {
00758 msg_Warn( p_access, "packet lost ? (%d != %d)", p_ck->i_sequence, p_sys->i_packet_sequence );
00759 }
00760
00761 p_sys->i_packet_sequence = p_ck->i_sequence + 1;
00762 p_sys->i_packet_used = 0;
00763 p_sys->i_packet_length = p_ck->i_data;
00764 p_sys->p_packet = p_ck->p_data;
00765
00766 return VLC_SUCCESS;
00767 }