X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faccess%2Fmms%2Fmmstu.c;h=a3867bf64d3db89929d3e4a74e0c8652126823d9;hb=37708112ca12f0bacbed99fc5a1a7e774b7a8511;hp=71c256047c1ab67902f57b566dc7301908049a87;hpb=552e595131c5f1d66eba8e3c22c2b1c509be5153;p=vlc diff --git a/modules/access/mms/mmstu.c b/modules/access/mms/mmstu.c index 71c256047c..a3867bf64d 100644 --- a/modules/access/mms/mmstu.c +++ b/modules/access/mms/mmstu.c @@ -25,7 +25,11 @@ /***************************************************************************** * Preamble *****************************************************************************/ -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include #include #include @@ -45,6 +49,9 @@ #ifdef HAVE_SYS_STAT_H # include #endif +#ifdef HAVE_POLL +# include +#endif #include #include "vlc_url.h" @@ -64,11 +71,11 @@ /***************************************************************************** * Local prototypes *****************************************************************************/ -int E_( MMSTUOpen ) ( access_t * ); -void E_( MMSTUClose ) ( access_t * ); +int MMSTUOpen ( access_t * ); +void MMSTUClose ( access_t * ); -static int Read( access_t *, uint8_t *, int ); +static ssize_t Read( access_t *, uint8_t *, size_t ); static int Seek( access_t *, int64_t ); static int Control( access_t *, int, va_list ); @@ -86,7 +93,7 @@ static int mms_HeaderMediaRead( access_t *, int ); static int mms_ReceivePacket( access_t * ); -int E_(MMSTUOpen)( access_t *p_access ) +int MMSTUOpen( access_t *p_access ) { access_sys_t *p_sys; int i_proto; @@ -100,12 +107,15 @@ int E_(MMSTUOpen)( access_t *p_access ) p_access->info.i_update = 0; p_access->info.i_size = 0; p_access->info.i_pos = 0; - p_access->info.b_eof = VLC_FALSE; + p_access->info.b_eof = false; p_access->info.i_title = 0; p_access->info.i_seekpoint = 0; p_access->p_sys = p_sys = malloc( sizeof( access_sys_t ) ); + if( !p_sys ) return VLC_ENOMEM; memset( p_sys, 0, sizeof( access_sys_t ) ); + p_sys->i_timeout = var_CreateGetInteger( p_access, "mms-timeout" ); + /* *** Parse URL and get server addr/port and path *** */ vlc_UrlParse( &p_sys->url, p_access->psz_path, 0 ); if( p_sys->url.psz_host == NULL || *p_sys->url.psz_host == '\0' ) @@ -169,11 +179,11 @@ int E_(MMSTUOpen)( access_t *p_access ) } if( p_sys->i_packet_count <= 0 || ( p_sys->i_flags_broadcast >> 24 ) == 0x02 ) { - p_sys->b_seekable = VLC_FALSE; + p_sys->b_seekable = false; } else { - p_sys->b_seekable = VLC_TRUE; + p_sys->b_seekable = true; p_access->info.i_size = (uint64_t)p_sys->i_header + (uint64_t)p_sys->i_packet_count * (uint64_t)p_sys->i_packet_length; @@ -183,7 +193,7 @@ int E_(MMSTUOpen)( access_t *p_access ) if( MMSStart( p_access, 0xffffffff ) < 0 ) { msg_Err( p_access, "cannot start stream" ); - E_(MMSTUClose) ( p_access ); + MMSTUClose ( p_access ); return VLC_EGENERIC; } return VLC_SUCCESS; @@ -192,7 +202,7 @@ int E_(MMSTUOpen)( access_t *p_access ) /***************************************************************************** * Close: free unused data structures *****************************************************************************/ -void E_(MMSTUClose)( access_t *p_access ) +void MMSTUClose( access_t *p_access ) { access_sys_t *p_sys = p_access->p_sys; @@ -211,7 +221,7 @@ void E_(MMSTUClose)( access_t *p_access ) static int Control( access_t *p_access, int i_query, va_list args ) { access_sys_t *p_sys = p_access->p_sys; - vlc_bool_t *pb_bool; + bool *pb_bool; int *pi_int; int64_t *pi_64; int i_int; @@ -221,24 +231,24 @@ static int Control( access_t *p_access, int i_query, va_list args ) { /* */ case ACCESS_CAN_SEEK: - pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* ); + pb_bool = (bool*)va_arg( args, bool* ); *pb_bool = p_sys->b_seekable; break; case ACCESS_CAN_FASTSEEK: case ACCESS_CAN_PAUSE: - pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* ); - *pb_bool = VLC_FALSE; + pb_bool = (bool*)va_arg( args, bool* ); + *pb_bool = false; break; case ACCESS_CAN_CONTROL_PACE: - pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* ); + pb_bool = (bool*)va_arg( args, bool* ); #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; + *pb_bool = false; #endif - *pb_bool = VLC_TRUE; + *pb_bool = true; break; /* */ @@ -250,16 +260,16 @@ static int Control( access_t *p_access, int i_query, va_list args ) case ACCESS_GET_PTS_DELAY: pi_64 = (int64_t*)va_arg( args, int64_t * ); var_Get( p_access, "mms-caching", &val ); - *pi_64 = (int64_t)var_GetInteger( p_access, "mms-caching" ) * I64C(1000); + *pi_64 = (int64_t)var_GetInteger( p_access, "mms-caching" ) * INT64_C(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 * ); + pb_bool = (bool *)va_arg( args, bool * ); if( i_int < 0 || i_int > 127 ) return VLC_EGENERIC; - *pb_bool = p_sys->asfh.stream[i_int].i_selected ? VLC_TRUE : VLC_FALSE; + *pb_bool = p_sys->asfh.stream[i_int].i_selected ? true : false; break; /* */ @@ -268,6 +278,7 @@ static int Control( access_t *p_access, int i_query, va_list args ) case ACCESS_SET_TITLE: case ACCESS_SET_SEEKPOINT: case ACCESS_SET_PRIVATE_ID_STATE: + case ACCESS_GET_CONTENT_TYPE: return VLC_EGENERIC; @@ -313,7 +324,7 @@ static int Seek( access_t * p_access, int64_t i_pos ) i_packet = ( i_pos - p_sys->i_header ) / p_sys->i_packet_length; i_offset = ( i_pos - p_sys->i_header ) % p_sys->i_packet_length; } - msg_Dbg( p_access, "seeking to "I64Fd " (packet:%d)", i_pos, i_packet ); + msg_Dbg( p_access, "seeking to %"PRId64 " (packet:%d)", i_pos, i_packet ); MMSStop( p_access ); msg_Dbg( p_access, "stream stopped (seek)" ); @@ -337,7 +348,12 @@ static int Seek( access_t * p_access, int64_t i_pos ) while( !p_access->b_die ) { - mms_HeaderMediaRead( p_access, MMS_PACKET_CMD ); + if( mms_HeaderMediaRead( p_access, MMS_PACKET_CMD ) < 0 ) + { + p_access->info.b_eof = true; + return VLC_EGENERIC; + } + if( p_sys->i_command == 0x1e ) { msg_Dbg( p_access, "received 0x1e (seek)" ); @@ -347,7 +363,11 @@ static int Seek( access_t * p_access, int64_t i_pos ) while( !p_access->b_die ) { - mms_HeaderMediaRead( p_access, MMS_PACKET_CMD ); + if( mms_HeaderMediaRead( p_access, MMS_PACKET_CMD ) < 0 ) + { + p_access->info.b_eof = true; + return VLC_EGENERIC; + } if( p_sys->i_command == 0x05 ) { msg_Dbg( p_access, "received 0x05 (seek)" ); @@ -356,12 +376,17 @@ static int Seek( access_t * p_access, int64_t i_pos ) } /* get a packet */ - mms_HeaderMediaRead( p_access, MMS_PACKET_MEDIA ); + if( mms_HeaderMediaRead( p_access, MMS_PACKET_MEDIA ) < 0 ) + { + p_access->info.b_eof = true; + return VLC_EGENERIC; + } + msg_Dbg( p_access, "Streaming restarted" ); p_sys->i_media_used += i_offset; p_access->info.i_pos = i_pos; - p_access->info.b_eof = VLC_FALSE; + p_access->info.b_eof = false; return VLC_SUCCESS; } @@ -369,16 +394,21 @@ static int Seek( access_t * p_access, int64_t i_pos ) /***************************************************************************** * Read: *****************************************************************************/ -static int Read( access_t *p_access, uint8_t *p_buffer, int i_len ) +static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len ) { access_sys_t *p_sys = p_access->p_sys; size_t i_data; size_t i_copy; + if( p_access->info.b_eof ) + { + return 0; + } + i_data = 0; /* *** now send data if needed *** */ - while( i_data < (size_t)i_len ) + while( i_data < i_len ) { if( p_access->info.i_pos < p_sys->i_header ) { @@ -435,6 +465,7 @@ static int MMSOpen( access_t *p_access, vlc_url_t *p_url, int i_proto ) int i; int i_streams; int i_first; + char *mediapath; /* *** Open a TCP connection with server *** */ @@ -474,7 +505,7 @@ static int MMSOpen( access_t *p_access, vlc_url_t *p_url, int i_proto ) } /* *** Init context for mms prototcol *** */ - E_( GenerateGuid )( &p_sys->guid ); /* used to identify client by server */ + GenerateGuid ( &p_sys->guid ); /* used to identify client by server */ msg_Dbg( p_access, "generated guid: "GUID_FMT, GUID_PRINT( p_sys->guid ) ); @@ -495,7 +526,7 @@ static int MMSOpen( access_t *p_access, vlc_url_t *p_url, int i_proto ) p_sys->i_buffer_udp = 0; p_sys->p_cmd = NULL; p_sys->i_cmd = 0; - p_access->info.b_eof = 0; + p_access->info.b_eof = false; /* *** send command 1 : connection request *** */ var_buffer_initwrite( &buffer, 0 ); @@ -595,7 +626,14 @@ static int MMSOpen( access_t *p_access, vlc_url_t *p_url, int i_proto ) /* *** send command 5 : media file name/path requested *** */ var_buffer_reinitwrite( &buffer, 0 ); var_buffer_add64( &buffer, 0 ); - var_buffer_addUTF16( &buffer, p_url->psz_path ); + + /* media file path shouldn't start with / character */ + mediapath = p_url->psz_path; + if ( *mediapath == '/' ) + { + mediapath++; + } + var_buffer_addUTF16( &buffer, mediapath ); mms_CommandSend( p_access, 0x05, @@ -729,9 +767,9 @@ static int MMSOpen( access_t *p_access, vlc_url_t *p_url, int i_proto ) * * TODO : stream bitrates properties(optional) * and bitrate mutual exclusion(optional) */ - E_( asf_HeaderParse )( &p_sys->asfh, + asf_HeaderParse ( &p_sys->asfh, p_sys->p_header, p_sys->i_header ); - E_( asf_StreamSelect)( &p_sys->asfh, + asf_StreamSelect( &p_sys->asfh, var_CreateGetInteger( p_access, "mms-maxbitrate" ), var_CreateGetInteger( p_access, "mms-all" ), var_CreateGetInteger( p_access, "audio" ), @@ -844,14 +882,15 @@ static int MMSStart( access_t *p_access, uint32_t i_packet ) msg_Err( p_access, "unknown answer (0x%x instead of 0x05)", p_sys->i_command ); - return( -1 ); + return -1; } else { /* get a packet */ - mms_HeaderMediaRead( p_access, MMS_PACKET_MEDIA ); + if( mms_HeaderMediaRead( p_access, MMS_PACKET_MEDIA ) < 0 ) + return -1; msg_Dbg( p_access, "streaming started" ); - return( 0 ); + return 0; } } @@ -966,14 +1005,13 @@ static int NetFillBuffer( access_t *p_access ) #else access_sys_t *p_sys = p_access->p_sys; - struct timeval timeout; - fd_set fds_r, fds_e; int i_ret; + struct pollfd ufd[2]; + unsigned timeout, nfd; /* FIXME when using udp */ ssize_t i_tcp, i_udp; ssize_t i_tcp_read, i_udp_read; - int i_handle_max; int i_try = 0; i_tcp = MMS_BUFFER_SIZE/2 - p_sys->i_buffer_tcp; @@ -987,14 +1025,7 @@ static int NetFillBuffer( access_t *p_access ) i_udp = 0; /* there isn't udp socket */ } - i_handle_max = 0; - - if( i_tcp > 0 ) - i_handle_max = __MAX( i_handle_max, p_sys->i_handle_tcp ); - if( i_udp > 0 ) - i_handle_max = __MAX( i_handle_max, p_sys->i_handle_udp ); - - if( i_handle_max == 0 ) + if( ( i_udp <= 0 ) && ( i_tcp <= 0 ) ) { msg_Warn( p_access, "nothing to read %d:%d", (int)i_tcp, (int)i_udp ); return 0; @@ -1010,23 +1041,30 @@ static int NetFillBuffer( access_t *p_access ) i_try++; /* Initialize file descriptor set */ - FD_ZERO( &fds_r ); - FD_ZERO( &fds_e ); + memset (ufd, 0, sizeof (ufd)); + nfd = 0; if( i_tcp > 0 ) { - FD_SET( p_sys->i_handle_tcp, &fds_r ); - FD_SET( p_sys->i_handle_tcp, &fds_e ); + ufd[nfd].fd = p_sys->i_handle_tcp; + ufd[nfd].events = POLLIN; + nfd++; } if( i_udp > 0 ) { - FD_SET( p_sys->i_handle_udp, &fds_r ); - FD_SET( p_sys->i_handle_udp, &fds_e ); + ufd[nfd].fd = p_sys->i_handle_tcp; + ufd[nfd].events = POLLIN; + nfd++; } /* We'll wait 0.5 second if nothing happens */ - timeout.tv_sec = 0; - timeout.tv_usec = 500000; + timeout = 500; + + if( i_try * timeout > p_sys->i_timeout ) + { + msg_Err(p_access, "no data received"); + return -1; + } if( i_try > 3 && (p_sys->i_buffer_tcp > 0 || p_sys->i_buffer_udp > 0) ) { @@ -1037,18 +1075,18 @@ static int NetFillBuffer( access_t *p_access ) //msg_Dbg( p_access, "NetFillBuffer: trying again (select)" ); - } while( !(i_ret = select(i_handle_max +1, &fds_r, 0, &fds_e, &timeout)) || + } while( !(i_ret = poll( ufd, nfd, timeout)) || (i_ret < 0 && errno == EINTR) ); if( i_ret < 0 ) { - msg_Err( p_access, "network select error (%m)" ); + msg_Err( p_access, "network poll error (%m)" ); return -1; } i_tcp_read = i_udp_read = 0; - if( i_tcp > 0 && FD_ISSET( p_sys->i_handle_tcp, &fds_r ) ) + if( ( i_tcp > 0 ) && ufd[0].revents ) { i_tcp_read = recv( p_sys->i_handle_tcp, @@ -1056,7 +1094,7 @@ static int NetFillBuffer( access_t *p_access ) i_tcp + MMS_BUFFER_SIZE/2, 0 ); } - if( i_udp > 0 && FD_ISSET( p_sys->i_handle_udp, &fds_r ) ) + if( i_udp > 0 && ufd[i_tcp > 0].revents ) { i_udp_read = recv( p_sys->i_handle_udp, p_sys->buffer_udp + p_sys->i_buffer_udp, @@ -1098,10 +1136,7 @@ static int mms_ParseCommand( access_t *p_access, int i_length; uint32_t i_id; - if( p_sys->p_cmd ) - { - free( p_sys->p_cmd ); - } + free( p_sys->p_cmd ); p_sys->i_cmd = i_data; p_sys->p_cmd = malloc( i_data ); memcpy( p_sys->p_cmd, p_data, i_data ); @@ -1274,7 +1309,7 @@ static int mms_ReceivePacket( access_t *p_access ) for( ;; ) { - vlc_bool_t b_refill = VLC_TRUE; + bool b_refill = true; /* first if we need to refill buffer */ if( p_sys->i_buffer_tcp >= MMS_CMD_HEADERSIZE ) @@ -1284,18 +1319,18 @@ static int mms_ReceivePacket( access_t *p_access ) if( GetDWLE( p_sys->buffer_tcp + 8 ) + 16 <= (uint32_t)p_sys->i_buffer_tcp ) { - b_refill = VLC_FALSE; + b_refill = false; } } else if( GetWLE( p_sys->buffer_tcp + 6 ) <= p_sys->i_buffer_tcp ) { - b_refill = VLC_FALSE; + b_refill = false; } } if( p_sys->i_proto == MMS_PROTO_UDP && p_sys->i_buffer_udp >= 8 && GetWLE( p_sys->buffer_udp + 6 ) <= p_sys->i_buffer_udp ) { - b_refill = VLC_FALSE; + b_refill = false; } if( b_refill && NetFillBuffer( p_access ) < 0 ) @@ -1445,17 +1480,18 @@ static int mms_CommandRead( access_t *p_access, int i_command1, { case 0x03: msg_Warn( p_access, "socket closed by server" ); - p_access->info.b_eof = 1; + p_access->info.b_eof = true; return VLC_EGENERIC; case 0x1e: msg_Warn( p_access, "end of media stream" ); - p_access->info.b_eof = 1; + p_access->info.b_eof = true; return VLC_EGENERIC; default: break; } } } + p_access->info.b_eof = true; msg_Warn( p_access, "failed to receive command (aborting)" ); return VLC_EGENERIC; @@ -1492,11 +1528,11 @@ static int mms_HeaderMediaRead( access_t *p_access, int i_type ) { case 0x03: msg_Warn( p_access, "socket closed by server" ); - p_access->info.b_eof = 1; + p_access->info.b_eof = true; return -1; case 0x1e: msg_Warn( p_access, "end of media stream" ); - p_access->info.b_eof = 1; + p_access->info.b_eof = true; return -1; case 0x20: /* XXX not too dificult to be done EXCEPT that we @@ -1504,7 +1540,7 @@ static int mms_HeaderMediaRead( access_t *p_access, int i_type ) * could do that :p */ msg_Err( p_access, "reinitialization needed --> unsupported" ); - p_access->info.b_eof = VLC_TRUE; + p_access->info.b_eof = true; return -1; default: break; @@ -1514,6 +1550,7 @@ static int mms_HeaderMediaRead( access_t *p_access, int i_type ) msg_Err( p_access, "cannot receive %s (aborting)", ( i_type == MMS_PACKET_HEADER ) ? "header" : "media data" ); + p_access->info.b_eof = true; return -1; }