X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faccess%2Fmms%2Fmmsh.c;h=98784b21b9c461b94a6068a27ada351793557925;hb=15643af1;hp=44a98edd645852f8dfcc7ff7055e816f7443e7eb;hpb=50083d4a143a10582e56343d2d78d5bda4cb013f;p=vlc diff --git a/modules/access/mms/mmsh.c b/modules/access/mms/mmsh.c index 44a98edd64..98784b21b9 100644 --- a/modules/access/mms/mmsh.c +++ b/modules/access/mms/mmsh.c @@ -29,13 +29,16 @@ # include "config.h" #endif +#include + #include #include -#include "vlc_strings.h" -#include "vlc_input.h" +#include +#include +#include #include -#include "vlc_url.h" +#include #include "asf.h" #include "buffer.h" @@ -52,7 +55,7 @@ int MMSHOpen ( access_t * ); void MMSHClose ( access_t * ); -static ssize_t Read( access_t *, uint8_t *, size_t ); +static block_t *Block( access_t *p_access ); static ssize_t ReadRedirect( access_t *, uint8_t *, size_t ); static int Seek( access_t *, int64_t ); static int Control( access_t *, int, va_list ); @@ -79,28 +82,10 @@ int MMSHOpen( access_t *p_access ) char *psz_location = NULL; char *psz_proxy; - /* init p_sys */ - - /* Set up p_access */ - p_access->pf_read = Read; - p_access->pf_block = NULL; - p_access->pf_control = Control; - p_access->pf_seek = Seek; - p_access->info.i_update = 0; - p_access->info.i_size = 0; - p_access->info.i_pos = 0; - 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; + STANDARD_BLOCK_ACCESS_INIT - memset( p_sys, 0, sizeof( access_sys_t ) ); p_sys->i_proto= MMS_PROTO_HTTP; p_sys->fd = -1; - p_sys->i_start= 0; /* Handle proxy */ p_sys->b_proxy = false; @@ -165,48 +150,47 @@ int MMSHOpen( access_t *p_access ) ( *p_sys->url.psz_host == '\0' ) ) { msg_Err( p_access, "invalid host" ); - vlc_UrlClean( &p_sys->proxy ); - vlc_UrlClean( &p_sys->url ); - free( p_sys ); - return VLC_EGENERIC; + goto error; } if( p_sys->url.i_port <= 0 ) p_sys->url.i_port = 80; if( Describe( p_access, &psz_location ) ) - { - vlc_UrlClean( &p_sys->proxy ); - vlc_UrlClean( &p_sys->url ); - free( p_sys ); - return VLC_EGENERIC; - } + goto error; + /* Handle redirection */ if( psz_location && *psz_location ) { msg_Dbg( p_access, "redirection to %s", psz_location ); - input_thread_t * p_input = vlc_object_find( p_access, VLC_OBJECT_INPUT, FIND_PARENT ); + input_thread_t * p_input = access_GetParentInput( p_access ); input_item_t * p_new_loc; + + if( !p_input ) + { + free( psz_location ); + goto error; + } /** \bug we do not autodelete here */ - p_new_loc = input_ItemNew( p_access, psz_location, psz_location ); - input_ItemAddSubItem( input_GetItem( p_input ), p_new_loc ); + p_new_loc = input_item_New( p_access, psz_location, psz_location ); + input_item_AddSubItem( input_GetItem( p_input ), p_new_loc ); + vlc_gc_decref( p_new_loc ); vlc_object_release( p_input ); free( psz_location ); + p_access->pf_block = NULL; p_access->pf_read = ReadRedirect; return VLC_SUCCESS; } + free( psz_location ); /* Start playing */ if( Start( p_access, 0 ) ) { msg_Err( p_access, "cannot start stream" ); free( p_sys->p_header ); - vlc_UrlClean( &p_sys->proxy ); - vlc_UrlClean( &p_sys->url ); - free( p_sys ); - return VLC_EGENERIC; + goto error; } if( !p_sys->b_broadcast ) @@ -215,6 +199,12 @@ int MMSHOpen( access_t *p_access ) } return VLC_SUCCESS; + +error: + vlc_UrlClean( &p_sys->proxy ); + vlc_UrlClean( &p_sys->url ); + free( p_sys ); + return VLC_EGENERIC; } /***************************************************************************** @@ -226,7 +216,7 @@ void MMSHClose ( access_t *p_access ) Stop( p_access ); - free( p_sys->p_header ); + free( p_sys->p_header ); vlc_UrlClean( &p_sys->proxy ); vlc_UrlClean( &p_sys->url ); @@ -241,7 +231,6 @@ static int Control( access_t *p_access, int i_query, va_list args ) access_sys_t *p_sys = p_access->p_sys; bool *pb_bool; bool b_bool; - int *pi_int; int64_t *pi_64; int i_int; @@ -265,11 +254,6 @@ static int Control( access_t *p_access, int i_query, va_list args ) break; /* */ - case ACCESS_GET_MTU: - pi_int = (int*)va_arg( args, int * ); - *pi_int = 3 * p_sys->asfh.i_min_data_packet_size; - break; - case ACCESS_GET_PTS_DELAY: pi_64 = (int64_t*)va_arg( args, int64_t * ); *pi_64 = (int64_t)var_GetInteger( p_access, "mms-caching" ) * INT64_C(1000); @@ -326,9 +310,8 @@ static int Seek( access_t *p_access, int64_t i_pos ) Stop( p_access ); Start( p_access, i_packet * p_sys->asfh.i_min_data_packet_size ); - while( !p_access->b_die ) + while( vlc_object_alive (p_access) ) { - msg_Warn( p_access, "GetPacket 1" ); if( GetPacket( p_access, &ck ) ) break; @@ -347,89 +330,85 @@ static int Seek( access_t *p_access, int64_t i_pos ) } /***************************************************************************** - * Read: + * ReadRedirect: *****************************************************************************/ static ssize_t ReadRedirect( access_t *p_access, uint8_t *p, size_t i_len ) { + VLC_UNUSED(p_access); VLC_UNUSED(p); VLC_UNUSED(i_len); return 0; } /***************************************************************************** - * Read: + * Block: *****************************************************************************/ -static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len ) +static block_t *Block( access_t *p_access ) { access_sys_t *p_sys = p_access->p_sys; - size_t i_copy; - size_t i_data = 0; + const unsigned i_packet_min = p_sys->asfh.i_min_data_packet_size; + + if( p_access->info.i_pos < p_sys->i_start + p_sys->i_header ) + { + const size_t i_offset = p_access->info.i_pos - p_sys->i_start; + const size_t i_copy = p_sys->i_header - i_offset; - if( p_access->info.b_eof ) - return 0; + block_t *p_block = block_New( p_access, i_copy ); + if( !p_block ) + return NULL; - while( i_data < (size_t) i_len ) + memcpy( p_block->p_buffer, &p_sys->p_header[i_offset], i_copy ); + p_access->info.i_pos += i_copy; + return p_block; + } + else if( p_sys->i_packet_length > 0 && + p_sys->i_packet_used < __MAX( p_sys->i_packet_length, i_packet_min ) ) { - 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, - (int)((size_t)i_len - i_data) ); - memcpy( &p_buffer[i_data], &p_sys->p_header[i_offset], i_copy ); + size_t i_copy = 0; + size_t i_padding = 0; - i_data += i_copy; - p_access->info.i_pos += i_copy; - } - else if( p_sys->i_packet_used < p_sys->i_packet_length ) - { - i_copy = __MIN( p_sys->i_packet_length - p_sys->i_packet_used, - i_len - i_data ); - memcpy( &p_buffer[i_data], - &p_sys->p_packet[p_sys->i_packet_used], - 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) ) - { - i_copy = __MIN( p_sys->asfh.i_min_data_packet_size - p_sys->i_packet_used, - i_len - i_data ); - memset( &p_buffer[i_data], 0, i_copy ); + if( p_sys->i_packet_used < p_sys->i_packet_length ) + i_copy = p_sys->i_packet_length - p_sys->i_packet_used; + if( __MAX( p_sys->i_packet_used, p_sys->i_packet_length ) < i_packet_min ) + i_padding = i_packet_min - __MAX( p_sys->i_packet_used, p_sys->i_packet_length ); + + block_t *p_block = block_New( p_access, i_copy + i_padding ); + if( !p_block ) + return NULL; - i_data += i_copy; - p_sys->i_packet_used += i_copy; - p_access->info.i_pos += i_copy; + if( i_copy > 0 ) + memcpy( &p_block->p_buffer[0], &p_sys->p_packet[p_sys->i_packet_used], i_copy ); + if( i_padding > 0 ) + memset( &p_block->p_buffer[i_copy], 0, i_padding ); + + p_sys->i_packet_used += i_copy + i_padding; + p_access->info.i_pos += i_copy + i_padding; + return p_block; + + } + + chunk_t ck; + if( GetPacket( p_access, &ck ) ) + { + int i_ret = -1; + 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 ); } - else + if( i_ret ) { - chunk_t ck; - msg_Warn( p_access, "GetPacket 2" ); - if( GetPacket( p_access, &ck ) ) - { - int i_ret = -1; - 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 = true; - return 0; - } - } - if( ck.i_type != 0x4424 ) - { - p_sys->i_packet_used = 0; - p_sys->i_packet_length = 0; - } + p_access->info.b_eof = true; + return 0; } } + if( ck.i_type != 0x4424 ) + { + p_sys->i_packet_used = 0; + p_sys->i_packet_length = 0; + } - return( i_data ); + return NULL; } /* */ @@ -452,6 +431,8 @@ static int Restart( access_t *p_access ) msg_Err( p_access, "describe failed" ); return VLC_EGENERIC; } + free( psz_location ); + /* */ if( Start( p_access, 0 ) ) { @@ -480,17 +461,17 @@ static int Reset( access_t *p_access ) if( p_sys->i_header <= 0 ) return VLC_EGENERIC; - asf_HeaderParse ( &p_sys->asfh, - p_sys->p_header, p_sys->i_header ); + asf_HeaderParse ( &p_sys->asfh, + p_sys->p_header, p_sys->i_header ); msg_Dbg( p_access, "packet count=%"PRId64" packet size=%d", p_sys->asfh.i_data_packets_count, p_sys->asfh.i_min_data_packet_size ); - 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" ) ); + 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++ ) @@ -541,8 +522,9 @@ static int OpenConnection( access_t *p_access ) char *buf; char *b64; - asprintf( &buf, "%s:%s", p_sys->proxy.psz_username, - p_sys->proxy.psz_password ? p_sys->proxy.psz_password : "" ); + if( asprintf( &buf, "%s:%s", p_sys->proxy.psz_username, + p_sys->proxy.psz_password ? p_sys->proxy.psz_password : "" ) == -1 ) + return VLC_ENOMEM; b64 = vlc_b64_encode( buf ); free( buf ); @@ -582,7 +564,8 @@ static int Describe( access_t *p_access, char **ppsz_location ) p_sys->i_packet_used = 0; p_sys->i_packet_length = 0; p_sys->p_packet = NULL; - GenerateGuid ( &p_sys->guid ); + + GenerateGuid ( &p_sys->guid ); if( OpenConnection( p_access ) ) return VLC_EGENERIC; @@ -603,7 +586,7 @@ static int Describe( access_t *p_access, char **ppsz_location ) } /* Receive the http header */ - if( ( psz = net_Gets( VLC_OBJECT(p_access), p_sys->fd, NULL ) ) == NULL ) + if( ( psz = net_Gets( p_access, p_sys->fd, NULL ) ) == NULL ) { msg_Err( p_access, "failed to read answer" ); goto error; @@ -694,6 +677,7 @@ static int Describe( access_t *p_access, char **ppsz_location ) *ppsz_location = psz_location; return VLC_SUCCESS; } + free( psz_location ); /* Read the asf header */ GetHeader( p_access ); @@ -711,17 +695,20 @@ static int Describe( access_t *p_access, char **ppsz_location ) * * TODO : stream bitrates properties(optional) * and bitrate mutual exclusion(optional) */ - asf_HeaderParse ( &p_sys->asfh, - p_sys->p_header, p_sys->i_header ); + asf_HeaderParse ( &p_sys->asfh, + p_sys->p_header, p_sys->i_header ); msg_Dbg( p_access, "packet count=%"PRId64" packet size=%d", p_sys->asfh.i_data_packets_count, p_sys->asfh.i_min_data_packet_size ); - 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" ) ); + if( p_sys->asfh.i_min_data_packet_size <= 0 ) + goto error; + + 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" ) ); return VLC_SUCCESS; error: @@ -750,7 +737,8 @@ static void GetHeader( access_t *p_access ) 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 ); + p_sys->p_header = realloc_or_free( p_sys->p_header, p_sys->i_header ); + assert( p_sys->p_header ); memcpy( &p_sys->p_header[p_sys->i_header - ck.i_data], ck.p_data, ck.i_data ); } @@ -837,7 +825,7 @@ static int Start( access_t *p_access, int64_t i_pos ) return VLC_EGENERIC; } - psz = net_Gets( VLC_OBJECT(p_access), p_sys->fd, NULL ); + psz = net_Gets( p_access, p_sys->fd, NULL ); if( psz == NULL ) { msg_Err( p_access, "cannot read data 0" );