X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faccess%2Frtmp%2Faccess.c;h=c7f5ed7bacefe949ef67ed37c178351b676b1be4;hb=bc09c365ab435fda0185e60a423f69d6dfa348c8;hp=1df9f62b531436349e1f27dedc201e055c3912a1;hpb=13ae40b0efc4f1b1ce205d9a057537047fcab3f4;p=vlc diff --git a/modules/access/rtmp/access.c b/modules/access/rtmp/access.c index 1df9f62b53..c7f5ed7bac 100644 --- a/modules/access/rtmp/access.c +++ b/modules/access/rtmp/access.c @@ -27,7 +27,7 @@ # include "config.h" #endif -#include +#include #include #include @@ -45,32 +45,46 @@ "Caching value for RTMP streams. This " \ "value should be set in milliseconds." ) +#define SWFURL_TEXT N_("Default SWF Referrer URL") +#define SWFURL_LONGTEXT N_("The SFW URL to use as referrer when connecting to "\ + "the server. This is the SWF file that contained " \ + "the stream.") + +#define PAGEURL_TEXT N_("Default Page Referrer URL") +#define PAGEURL_LONGTEXT N_("The Page URL to use as referrer when connecting to " \ + "the server. This is the page housing the SWF " \ + "file.") + static int Open ( vlc_object_t * ); static void Close( vlc_object_t * ); -vlc_module_begin(); - set_description( N_("RTMP input") ); - set_shortname( N_("RTMP") ); - set_category( CAT_INPUT ); - set_subcategory( SUBCAT_INPUT_ACCESS ); +vlc_module_begin () + set_description( N_("RTMP input") ) + set_shortname( N_("RTMP") ) + set_category( CAT_INPUT ) + set_subcategory( SUBCAT_INPUT_ACCESS ) add_integer( "rtmp-caching", DEFAULT_PTS_DELAY / 1000, NULL, CACHING_TEXT, - CACHING_LONGTEXT, true ); + CACHING_LONGTEXT, true ) + add_string( "rtmp-swfurl", "file:///player.swf", NULL, SWFURL_TEXT, + SWFURL_LONGTEXT, true ) + add_string( "rtmp-pageurl", "file:///player.htm", NULL, PAGEURL_TEXT, + PAGEURL_LONGTEXT, true ) - set_capability( "access", 10 ); - set_callbacks( Open, Close ); - add_shortcut( "rtmp" ); -vlc_module_end(); + set_capability( "access", 0 ) + set_callbacks( Open, Close ) + add_shortcut( "rtmp" ) +vlc_module_end () /***************************************************************************** * Local prototypes *****************************************************************************/ -static int Read( access_t *, uint8_t *, size_t ); /*DOWN: last parameter int */ -static int Seek( access_t *, int64_t ); +static ssize_t Read( access_t *, uint8_t *, size_t ); +static int Seek( access_t *, uint64_t ); static int Control( access_t *, int, va_list ); -static void ThreadControl( vlc_object_t * ); +static void* ThreadControl( void * ); /***************************************************************************** * Open: open the rtmp connection @@ -88,14 +102,11 @@ static int Open( vlc_object_t *p_this ) p_sys->p_thread = vlc_object_create( p_access, sizeof( rtmp_control_thread_t ) ); if( !p_sys->p_thread ) - { - msg_Err( p_access, "out of memory" ); return VLC_ENOMEM; - } vlc_object_attach( p_sys->p_thread, p_access ); /* Parse URI - remove spaces */ - p = psz = strdup( p_access->psz_path ); + p = psz = strdup( p_access->psz_location ); while( (p = strchr( p, ' ' )) != NULL ) *p = '+'; vlc_UrlParse( &p_sys->p_thread->url, psz, 0 ); @@ -118,22 +129,26 @@ static int Open( vlc_object_t *p_this ) } length_path = strlen( p_sys->p_thread->url.psz_path ); - length_media_name = strlen( strrchr( p_sys->p_thread->url.psz_path, '/' ) ) - 1; + char* psz_tmp = strrchr( p_sys->p_thread->url.psz_path, '/' ); + if( !psz_tmp ) + goto error; + length_media_name = strlen( psz_tmp ) - 1; p_sys->p_thread->psz_application = strndup( p_sys->p_thread->url.psz_path + 1, length_path - length_media_name - 2 ); p_sys->p_thread->psz_media = strdup( p_sys->p_thread->url.psz_path + ( length_path - length_media_name ) ); + p_sys->p_thread->psz_swf_url = var_CreateGetString( p_access, "rtmp-swfurl" ); + p_sys->p_thread->psz_page_url = var_CreateGetString( p_access, "rtmp-pageurl" ); + msg_Dbg( p_access, "rtmp: host='%s' port=%d path='%s'", p_sys->p_thread->url.psz_host, p_sys->p_thread->url.i_port, p_sys->p_thread->url.psz_path ); if( p_sys->p_thread->url.psz_username && *p_sys->p_thread->url.psz_username ) { - msg_Dbg( p_access, " user='%s', pwd='%s'", - p_sys->p_thread->url.psz_username, p_sys->p_thread->url.psz_password ); + msg_Dbg( p_access, " user='%s'", p_sys->p_thread->url.psz_username ); } /* Initialize thread variables */ - p_sys->p_thread->b_die = 0; p_sys->p_thread->b_error= 0; p_sys->p_thread->p_fifo_input = block_FifoNew(); p_sys->p_thread->p_empty_blocks = block_FifoNew(); @@ -160,7 +175,7 @@ static int Open( vlc_object_t *p_this ) p_sys->p_thread->p_base_object = p_this; - vlc_cond_init( p_sys->p_thread, &p_sys->p_thread->wait ); + vlc_cond_init( &p_sys->p_thread->wait ); vlc_mutex_init( &p_sys->p_thread->lock ); @@ -186,7 +201,7 @@ static int Open( vlc_object_t *p_this ) goto error2; } - p_sys->p_thread->fd = net_Accept( p_access, p_fd_listen, -1 ); + p_sys->p_thread->fd = net_Accept( p_access, p_fd_listen ); net_ListenClose( p_fd_listen ); @@ -211,8 +226,8 @@ static int Open( vlc_object_t *p_this ) p_sys->p_thread->result_publish = 0; } - if( vlc_thread_create( p_sys->p_thread, "rtmp control thread", ThreadControl, - VLC_THREAD_PRIORITY_INPUT, false ) ) + if( vlc_clone( &p_sys->p_thread->thread, ThreadControl, p_sys->p_thread, + VLC_THREAD_PRIORITY_INPUT ) ) { msg_Err( p_access, "cannot spawn rtmp control thread" ); goto error2; @@ -223,6 +238,9 @@ static int Open( vlc_object_t *p_this ) if( rtmp_connect_active( p_sys->p_thread ) < 0 ) { msg_Err( p_access, "connect active failed"); + /* Kill the running thread */ + vlc_cancel( p_sys->p_thread->thread ); + vlc_join( p_sys->p_thread->thread, NULL ); goto error2; } } @@ -240,15 +258,20 @@ error2: vlc_cond_destroy( &p_sys->p_thread->wait ); vlc_mutex_destroy( &p_sys->p_thread->lock ); + block_FifoRelease( p_sys->p_thread->p_fifo_input ); + block_FifoRelease( p_sys->p_thread->p_empty_blocks ); + free( p_sys->p_thread->psz_application ); free( p_sys->p_thread->psz_media ); + free( p_sys->p_thread->psz_swf_url ); + free( p_sys->p_thread->psz_page_url ); net_Close( p_sys->p_thread->fd ); error: - vlc_object_detach( p_sys->p_thread ); + vlc_UrlClean( &p_sys->p_thread->url ); + vlc_object_release( p_sys->p_thread ); - vlc_UrlClean( &p_sys->p_thread->url ); free( p_sys ); return VLC_EGENERIC; @@ -263,12 +286,8 @@ static void Close( vlc_object_t * p_this ) access_sys_t *p_sys = p_access->p_sys; int i; -/* p_sys->p_thread->b_die = true;*/ - vlc_object_kill( p_sys->p_thread ); - block_FifoWake( p_sys->p_thread->p_fifo_input ); - block_FifoWake( p_sys->p_thread->p_empty_blocks ); - - vlc_thread_join( p_sys->p_thread ); + vlc_cancel( p_sys->p_thread->thread ); + vlc_join( p_sys->p_thread->thread, NULL ); vlc_cond_destroy( &p_sys->p_thread->wait ); vlc_mutex_destroy( &p_sys->p_thread->lock ); @@ -289,19 +308,20 @@ static void Close( vlc_object_t * p_this ) var_Destroy( p_access, "rtmp-caching" ); - vlc_object_detach( p_sys->p_thread ); - vlc_object_release( p_sys->p_thread ); - vlc_UrlClean( &p_sys->p_thread->url ); free( p_sys->p_thread->psz_application ); free( p_sys->p_thread->psz_media ); + free( p_sys->p_thread->psz_swf_url ); + free( p_sys->p_thread->psz_page_url ); + + vlc_object_release( p_sys->p_thread ); free( p_sys ); } /***************************************************************************** * Read: standard read on a file descriptor. *****************************************************************************/ -static int Read( access_t *p_access, uint8_t *p_buffer, size_t 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; rtmp_packet_t *rtmp_packet; @@ -313,7 +333,7 @@ static int Read( access_t *p_access, uint8_t *p_buffer, size_t i_len ) while( i_len_tmp < i_len ) { - if( p_sys->p_thread->result_stop || p_access->info.b_eof || p_access->b_die ) + if( p_sys->p_thread->result_stop || p_access->info.b_eof || !vlc_object_alive (p_access) ) { p_access->info.b_eof = true; return 0; @@ -324,8 +344,10 @@ static int Read( access_t *p_access, uint8_t *p_buffer, size_t i_len ) if( !p_sys->p_thread->metadata_received ) { /* Wait until enough data is received for extracting metadata */ +#warning This is not thread-safe (because block_FifoCount() is not)! if( block_FifoCount( p_sys->p_thread->p_fifo_input ) < 10 ) { +#warning This is wrong! msleep(100000); continue; } @@ -382,12 +404,8 @@ static int Read( access_t *p_access, uint8_t *p_buffer, size_t i_len ) i_ret = net_Write( p_sys->p_thread, p_sys->p_thread->fd, NULL, tmp_buffer, rtmp_packet->length_encoded ); if( i_ret != rtmp_packet->length_encoded ) { - free( rtmp_packet->body->body ); - free( rtmp_packet->body ); - free( rtmp_packet ); - free( tmp_buffer ); msg_Err( p_access, "failed send publish start" ); - return -1; + goto error; } free( rtmp_packet->body->body ); free( rtmp_packet->body ); @@ -404,12 +422,8 @@ static int Read( access_t *p_access, uint8_t *p_buffer, size_t i_len ) i_ret = net_Write( p_sys->p_thread, p_sys->p_thread->fd, NULL, tmp_buffer, rtmp_packet->length_encoded ); if( i_ret != rtmp_packet->length_encoded ) { - free( rtmp_packet->body->body ); - free( rtmp_packet->body ); - free( rtmp_packet ); - free( tmp_buffer ); msg_Err( p_access, "failed send bytes read" ); - return -1; + goto error; } free( rtmp_packet->body->body ); free( rtmp_packet->body ); @@ -418,12 +432,19 @@ static int Read( access_t *p_access, uint8_t *p_buffer, size_t i_len ) } return i_len_tmp; + +error: + free( rtmp_packet->body->body ); + free( rtmp_packet->body ); + free( rtmp_packet ); + free( tmp_buffer ); + return -1; } /***************************************************************************** * Seek: seek to a specific location in a file *****************************************************************************/ -static int Seek( access_t *p_access, int64_t i_pos ) +static int Seek( access_t *p_access, uint64_t i_pos ) { VLC_UNUSED( p_access ); VLC_UNUSED( i_pos ); @@ -448,7 +469,6 @@ static int Seek( access_t *p_access, int64_t i_pos ) static int Control( access_t *p_access, int i_query, va_list args ) { bool *pb_bool; - int *pi_int; int64_t *pi_64; switch( i_query ) @@ -471,11 +491,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 = 0; - break; - case ACCESS_GET_PTS_DELAY: pi_64 = (int64_t*) va_arg( args, int64_t * ); *pi_64 = var_GetInteger( p_access, "rtmp-caching" ) * INT64_C(1000); @@ -505,16 +520,19 @@ static int Control( access_t *p_access, int i_query, va_list args ) /***************************************************************************** * ThreadControl: manage control messages and pipe media to Read *****************************************************************************/ -static void ThreadControl( vlc_object_t *p_this ) +static void* ThreadControl( void *p_this ) { - rtmp_control_thread_t *p_thread = (rtmp_control_thread_t *) p_this; + rtmp_control_thread_t *p_thread = p_this; rtmp_packet_t *rtmp_packet; + int canc = vlc_savecancel (); rtmp_init_handler( p_thread->rtmp_handler ); - while( !p_thread->b_die ) + for( ;; ) { + vlc_restorecancel( canc ); rtmp_packet = rtmp_read_net_packet( p_thread ); + canc = vlc_savecancel( ); if( rtmp_packet != NULL ) { if( rtmp_packet->content_type < 0x01 /* RTMP_CONTENT_TYPE_CHUNK_SIZE */ @@ -534,15 +552,18 @@ static void ThreadControl( vlc_object_t *p_this ) /* Sometimes server close connection too soon */ if( p_thread->result_connect ) { +#warning There must be a bug here! vlc_mutex_lock( &p_thread->lock ); vlc_cond_signal( &p_thread->wait ); vlc_mutex_unlock( &p_thread->lock ); } - p_thread->b_die = 1; +#warning info cannot be accessed outside input thread! ((access_t *) p_thread->p_base_object)->info.b_eof = true; - block_FifoWake( p_thread->p_fifo_input ); + break; } } + vlc_restorecancel (canc); + return NULL; }