mirror of
https://code.videolan.org/videolan/vlc
synced 2024-10-07 03:56:28 +02:00
RTMP bugfix and reusability enhacenment
Signed-off-by: Ilkka Ollakka <ileoo@videolan.org>
This commit is contained in:
parent
fb19b264f8
commit
aa5fe86aed
@ -82,77 +82,87 @@ static int Open( vlc_object_t *p_this )
|
||||
int length_path, length_media_name;
|
||||
int i;
|
||||
|
||||
/*DOWN:
|
||||
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->pf_read = Read;
|
||||
p_access->pf_block = Block;
|
||||
p_access->pf_control = Control;
|
||||
p_access->pf_seek = Seek;
|
||||
do
|
||||
{
|
||||
p_access->p_sys = (access_sys_t *) malloc( sizeof( access_sys_t ) );
|
||||
if( !p_access->p_sys )
|
||||
return VLC_ENOMEM;
|
||||
} while(0);
|
||||
p_sys = p_access->p_sys;
|
||||
memset( p_sys, 0, sizeof( access_sys_t ) );
|
||||
*/
|
||||
STANDARD_READ_ACCESS_INIT
|
||||
|
||||
/* Parse URI - remove spaces */
|
||||
p = psz = strdup( p_access->psz_path );
|
||||
while( (p = strchr( p, ' ' )) != NULL )
|
||||
*p = '+';
|
||||
vlc_UrlParse( &p_sys->url, psz, 0 );
|
||||
free( psz );
|
||||
|
||||
if( !p_access->psz_access ||
|
||||
strncmp( p_access->psz_access, "rtmp", 4 ))
|
||||
{
|
||||
msg_Warn( p_access, "invalid protocol" );
|
||||
vlc_UrlClean( &p_sys->url );
|
||||
free( p_sys );
|
||||
return VLC_EGENERIC;
|
||||
}
|
||||
|
||||
if( p_sys->url.psz_host == NULL || *p_sys->url.psz_host == '\0' )
|
||||
{
|
||||
msg_Warn( p_access, "invalid host" );
|
||||
vlc_UrlClean( &p_sys->url );
|
||||
free( p_sys );
|
||||
return VLC_EGENERIC;
|
||||
}
|
||||
|
||||
if( p_sys->url.i_port <= 0 )
|
||||
p_sys->url.i_port = 1935;
|
||||
|
||||
if ( p_sys->url.psz_path == NULL ) {
|
||||
msg_Warn( p_access, "invalid path" );
|
||||
vlc_UrlClean( &p_sys->url );
|
||||
free( p_sys );
|
||||
return VLC_EGENERIC;
|
||||
}
|
||||
|
||||
length_path = strlen( p_sys->url.psz_path );
|
||||
length_media_name = strlen( strrchr( p_sys->url.psz_path, '/' ) ) - 1;
|
||||
|
||||
p_sys->psz_application = strndup( p_sys->url.psz_path + 1, length_path - length_media_name - 2 );
|
||||
p_sys->psz_media = strdup( p_sys->url.psz_path + ( length_path - length_media_name ) );
|
||||
|
||||
msg_Dbg( p_access, "rtmp: host='%s' port=%d path='%s'",
|
||||
p_sys->url.psz_host, p_sys->url.i_port, p_sys->url.psz_path );
|
||||
|
||||
if( p_sys->url.psz_username && *p_sys->url.psz_username )
|
||||
{
|
||||
msg_Dbg( p_access, " user='%s', pwd='%s'",
|
||||
p_sys->url.psz_username, p_sys->url.psz_password );
|
||||
}
|
||||
|
||||
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" );
|
||||
vlc_UrlClean( &p_sys->url );
|
||||
free( p_sys );
|
||||
return VLC_EGENERIC;
|
||||
return VLC_ENOMEM;
|
||||
}
|
||||
vlc_object_attach( p_sys->p_thread, p_access );
|
||||
|
||||
/* Parse URI - remove spaces */
|
||||
p = psz = strdup( p_access->psz_path );
|
||||
while( (p = strchr( p, ' ' )) != NULL )
|
||||
*p = '+';
|
||||
vlc_UrlParse( &p_sys->p_thread->url, psz, 0 );
|
||||
free( psz );
|
||||
|
||||
if( p_sys->p_thread->url.psz_host == NULL
|
||||
|| *p_sys->p_thread->url.psz_host == '\0' )
|
||||
{
|
||||
msg_Warn( p_access, "invalid host" );
|
||||
goto error;
|
||||
}
|
||||
|
||||
vlc_object_attach( p_sys->p_thread, p_access );
|
||||
if( p_sys->p_thread->url.i_port <= 0 )
|
||||
p_sys->p_thread->url.i_port = 1935;
|
||||
|
||||
if( p_sys->p_thread->url.psz_path == NULL )
|
||||
{
|
||||
msg_Warn( p_access, "invalid path" );
|
||||
goto error;
|
||||
}
|
||||
|
||||
length_path = strlen( p_sys->p_thread->url.psz_path );
|
||||
length_media_name = strlen( strrchr( p_sys->p_thread->url.psz_path, '/' ) ) - 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 ) );
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
/* Initialize thread variables */
|
||||
p_sys->p_thread->b_die = 0;
|
||||
p_sys->p_thread->b_error= 0;
|
||||
p_sys->p_thread->p_fifo_media = block_FifoNew();
|
||||
p_sys->p_thread->p_fifo_input = block_FifoNew();
|
||||
p_sys->p_thread->p_empty_blocks = block_FifoNew();
|
||||
p_sys->p_thread->has_audio = 0;
|
||||
p_sys->p_thread->has_video = 0;
|
||||
p_sys->p_thread->metadata_received = 0;
|
||||
p_sys->p_thread->first_media_packet = 1;
|
||||
p_sys->p_thread->flv_tag_previous_tag_size = 0x00000000; /* FLV_TAG_FIRST_PREVIOUS_TAG_SIZE */
|
||||
p_sys->p_thread->chunk_size_recv = 128; /* RTMP_DEFAULT_CHUNK_SIZE */
|
||||
p_sys->p_thread->chunk_size_send = 128; /* RTMP_DEFAULT_CHUNK_SIZE */
|
||||
for(i = 0; i < 64; i++)
|
||||
{
|
||||
memset( &p_sys->p_thread->rtmp_headers_recv[i], 0, sizeof( rtmp_packet_t ) );
|
||||
@ -167,62 +177,54 @@ static int Open( vlc_object_t *p_this )
|
||||
p_sys->p_thread->rtmp_headers_send[i].body = NULL;
|
||||
}
|
||||
|
||||
p_sys->p_thread->p_base_object = p_this;
|
||||
|
||||
vlc_cond_init( p_sys->p_thread, &p_sys->p_thread->wait );
|
||||
|
||||
vlc_mutex_init( &p_sys->p_thread->lock );
|
||||
|
||||
p_sys->p_thread->result_connect = 1;
|
||||
p_sys->p_thread->result_play = 1;
|
||||
p_sys->p_thread->result_stop = 0;
|
||||
|
||||
/* Open connection */
|
||||
p_sys->fd = net_ConnectTCP( p_access, p_sys->url.psz_host, p_sys->url.i_port );
|
||||
p_sys->p_thread->fd = p_sys->fd;
|
||||
if( p_sys->fd == -1 )
|
||||
p_sys->p_thread->fd = net_ConnectTCP( p_access, p_sys->p_thread->url.psz_host, p_sys->p_thread->url.i_port );
|
||||
if( p_sys->p_thread->fd == -1 )
|
||||
{
|
||||
int *p_fd_listen;
|
||||
|
||||
msg_Warn( p_access, "cannot connect to %s:%d", p_sys->url.psz_host, p_sys->url.i_port );
|
||||
msg_Warn( p_access, "cannot connect to %s:%d", p_sys->p_thread->url.psz_host, p_sys->p_thread->url.i_port );
|
||||
msg_Dbg( p_access, "switching to passive mode" );
|
||||
|
||||
p_sys->active = 0;
|
||||
|
||||
p_fd_listen = net_ListenTCP( p_access, p_sys->url.psz_host, p_sys->url.i_port );
|
||||
p_fd_listen = net_ListenTCP( p_access, p_sys->p_thread->url.psz_host, p_sys->p_thread->url.i_port );
|
||||
if( p_fd_listen == NULL )
|
||||
{
|
||||
msg_Warn( p_access, "cannot listen to %s port %i", p_sys->url.psz_host, p_sys->url.i_port );
|
||||
vlc_UrlClean( &p_sys->url );
|
||||
net_Close( p_sys-> fd );
|
||||
free( p_sys );
|
||||
return VLC_EGENERIC;
|
||||
msg_Err( p_access, "cannot listen to %s port %i", p_sys->p_thread->url.psz_host, p_sys->p_thread->url.i_port );
|
||||
goto error2;
|
||||
}
|
||||
|
||||
p_sys->fd = net_Accept( p_access, p_fd_listen, -1 );
|
||||
p_sys->p_thread->fd = net_Accept( p_access, p_fd_listen, -1 );
|
||||
|
||||
net_ListenClose( p_fd_listen );
|
||||
|
||||
if( rtmp_handshake_passive( p_this ) < 0 )
|
||||
if( rtmp_handshake_passive( p_this, p_sys->p_thread->fd ) < 0 )
|
||||
{
|
||||
msg_Err( p_access, "Passive handshake failed");
|
||||
vlc_UrlClean( &p_sys->url );
|
||||
net_Close( p_sys-> fd );
|
||||
free( p_sys );
|
||||
return VLC_EGENERIC;
|
||||
msg_Err( p_access, "handshake passive failed");
|
||||
goto error2;
|
||||
}
|
||||
|
||||
p_sys->p_thread->result_publish = 1;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
msg_Dbg( p_access, "using active connection");
|
||||
p_sys->active = 1;
|
||||
|
||||
if( rtmp_handshake_active( p_this ) < 0 )
|
||||
if( rtmp_handshake_active( p_this, p_sys->p_thread->fd ) < 0 )
|
||||
{
|
||||
msg_Err( p_access, "Active handshake failed");
|
||||
vlc_UrlClean( &p_sys->url );
|
||||
net_Close( p_sys-> fd );
|
||||
free( p_sys );
|
||||
return VLC_EGENERIC;
|
||||
msg_Err( p_access, "handshake active failed");
|
||||
goto error2;
|
||||
}
|
||||
|
||||
p_sys->p_thread->result_publish = 0;
|
||||
@ -232,22 +234,15 @@ static int Open( vlc_object_t *p_this )
|
||||
VLC_THREAD_PRIORITY_INPUT, false ) )
|
||||
{
|
||||
msg_Err( p_access, "cannot spawn rtmp control thread" );
|
||||
vlc_UrlClean( &p_sys->url );
|
||||
net_Close( p_sys-> fd );
|
||||
free( p_sys );
|
||||
return VLC_EGENERIC;
|
||||
goto error2;
|
||||
}
|
||||
|
||||
if( p_sys->active )
|
||||
if( p_sys->active )
|
||||
{
|
||||
msg_Dbg( p_access, "Activation active connection");
|
||||
if( rtmp_connect_active( p_this ) < 0)
|
||||
if( rtmp_connect_active( p_sys->p_thread ) < 0 )
|
||||
{
|
||||
msg_Err( p_access, "Active connection failed");
|
||||
vlc_UrlClean( &p_sys->url );
|
||||
net_Close( p_sys-> fd );
|
||||
free( p_sys );
|
||||
return VLC_EGENERIC;
|
||||
msg_Err( p_access, "connect active failed");
|
||||
goto error2;
|
||||
}
|
||||
}
|
||||
|
||||
@ -255,19 +250,27 @@ static int Open( vlc_object_t *p_this )
|
||||
p_access->p_sys->flv_packet = NULL;
|
||||
p_access->p_sys->read_packet = 1;
|
||||
|
||||
msg_Dbg( p_access, "waiting for buffer to fill");
|
||||
/* Wait until enough data is received for extracting metadata */
|
||||
while( block_FifoCount( p_access->p_sys->p_thread->p_fifo_media ) < 10 )
|
||||
{
|
||||
msg_Dbg( p_access, "waiting for buffer to fill");
|
||||
msleep(1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Update default_pts to a suitable value for rtmp access */
|
||||
var_Create( p_access, "rtmp-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
|
||||
|
||||
return VLC_SUCCESS;
|
||||
|
||||
error2:
|
||||
vlc_cond_destroy( &p_sys->p_thread->wait );
|
||||
vlc_mutex_destroy( &p_sys->p_thread->lock );
|
||||
|
||||
free( p_sys->p_thread->psz_application );
|
||||
free( p_sys->p_thread->psz_media );
|
||||
|
||||
net_Close( p_sys->p_thread->fd );
|
||||
error:
|
||||
vlc_object_detach( p_sys->p_thread );
|
||||
vlc_object_release( p_sys->p_thread );
|
||||
|
||||
vlc_UrlClean( &p_sys->p_thread->url );
|
||||
free( p_sys );
|
||||
|
||||
return VLC_EGENERIC;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
@ -277,47 +280,40 @@ static void Close( vlc_object_t * p_this )
|
||||
{
|
||||
access_t *p_access = (access_t *) p_this;
|
||||
access_sys_t *p_sys = p_access->p_sys;
|
||||
int i;
|
||||
|
||||
msg_Warn(p_access, "Close");
|
||||
|
||||
/* p_sys->p_thread->b_die = true;*/
|
||||
vlc_object_kill( p_sys->p_thread );
|
||||
block_FifoWake( p_sys->p_thread->p_fifo_media );
|
||||
block_FifoWake( p_sys->p_thread->p_fifo_input );
|
||||
block_FifoWake( p_sys->p_thread->p_empty_blocks );
|
||||
/*
|
||||
for( i = 0; i < 5; i++ )
|
||||
{
|
||||
block_t *p_dummy = block_New( p_access, 256 );
|
||||
p_dummy->i_dts = 0;
|
||||
p_dummy->i_pts = 0;
|
||||
p_dummy->i_length = 0;
|
||||
memset( p_dummy->p_buffer, 0, p_dummy->i_buffer );
|
||||
block_FifoPut( p_sys->p_thread->p_fifo_media, p_dummy );
|
||||
}
|
||||
for( i = 0; i < 5; i++ )
|
||||
{
|
||||
block_t *p_dummy = block_New( p_access, 256 );
|
||||
p_dummy->i_dts = 0;
|
||||
p_dummy->i_pts = 0;
|
||||
p_dummy->i_length = 0;
|
||||
memset( p_dummy->p_buffer, 0, p_dummy->i_buffer );
|
||||
block_FifoPut( p_sys->p_thread->p_empty_blocks, p_dummy );
|
||||
}*/
|
||||
|
||||
vlc_thread_join( p_sys->p_thread );
|
||||
|
||||
vlc_cond_destroy( &p_sys->p_thread->wait );
|
||||
vlc_mutex_destroy( &p_sys->p_thread->lock );
|
||||
|
||||
block_FifoRelease( p_sys->p_thread->p_fifo_media );
|
||||
block_FifoRelease( p_sys->p_thread->p_fifo_input );
|
||||
block_FifoRelease( p_sys->p_thread->p_empty_blocks );
|
||||
|
||||
net_Close( p_sys->fd );
|
||||
for( i = 0; i < 64; i++ ) /* RTMP_HEADER_STREAM_INDEX_MASK */
|
||||
{
|
||||
if( p_sys->p_thread->rtmp_headers_recv[i].body != NULL )
|
||||
{
|
||||
free( p_sys->p_thread->rtmp_headers_recv[i].body->body );
|
||||
free( p_sys->p_thread->rtmp_headers_recv[i].body );
|
||||
}
|
||||
}
|
||||
|
||||
net_Close( p_sys->p_thread->fd );
|
||||
|
||||
var_Destroy( p_access, "rtmp-caching" );
|
||||
|
||||
vlc_object_detach( p_sys->p_thread );
|
||||
vlc_object_release( p_sys->p_thread );
|
||||
|
||||
vlc_UrlClean( &p_sys->url );
|
||||
free( p_sys->psz_application );
|
||||
free( p_sys->psz_media );
|
||||
vlc_UrlClean( &p_sys->p_thread->url );
|
||||
free( p_sys->p_thread->psz_application );
|
||||
free( p_sys->p_thread->psz_media );
|
||||
free( p_sys );
|
||||
}
|
||||
|
||||
@ -327,35 +323,39 @@ static void Close( vlc_object_t * p_this )
|
||||
static int 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;
|
||||
uint8_t *tmp_buffer;
|
||||
ssize_t i_ret;
|
||||
int i_len_tmp;
|
||||
|
||||
if( p_sys->fd < 0 )
|
||||
{
|
||||
p_access->info.b_eof = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
i_len_tmp = 0;
|
||||
|
||||
while( i_len_tmp < i_len )
|
||||
{
|
||||
if( p_sys->p_thread->result_stop || p_access->info.b_eof || p_access->b_die )
|
||||
{
|
||||
p_access->info.b_eof = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( p_sys->read_packet )
|
||||
{
|
||||
if( !p_sys->p_thread->metadata_received )
|
||||
{
|
||||
/* Wait until enough data is received for extracting metadata */
|
||||
if( block_FifoCount( p_sys->p_thread->p_fifo_input ) < 10 )
|
||||
{
|
||||
msleep(100000);
|
||||
continue;
|
||||
}
|
||||
|
||||
p_sys->flv_packet = flv_get_metadata( p_access );
|
||||
|
||||
p_sys->p_thread->metadata_received = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( p_sys->active && block_FifoCount( p_sys->p_thread->p_fifo_media ) == 0 )
|
||||
{
|
||||
p_access->info.b_eof = true;
|
||||
break;
|
||||
}
|
||||
|
||||
p_sys->flv_packet = block_FifoGet( p_sys->p_thread->p_fifo_media );
|
||||
p_sys->flv_packet = block_FifoGet( p_sys->p_thread->p_fifo_input );
|
||||
if( p_sys->flv_packet == NULL )
|
||||
continue; /* Forced wake-up */
|
||||
}
|
||||
@ -400,12 +400,44 @@ p_buffer[i+8], p_buffer[i+9], p_buffer[i+10], p_buffer[i+11], p_buffer[i+12], p_
|
||||
/* Send publish onStatus event only once */
|
||||
p_sys->p_thread->result_publish = 0;
|
||||
|
||||
rtmp_send_publish_start( p_access );
|
||||
rtmp_packet = rtmp_build_publish_start( p_sys->p_thread );
|
||||
|
||||
tmp_buffer = rtmp_encode_packet( p_sys->p_thread, rtmp_packet );
|
||||
|
||||
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" );
|
||||
}
|
||||
free( rtmp_packet->body->body );
|
||||
free( rtmp_packet->body );
|
||||
free( rtmp_packet );
|
||||
free( tmp_buffer );
|
||||
}
|
||||
|
||||
p_access->info.i_pos += i_len_tmp;
|
||||
|
||||
rtmp_send_bytes_read( p_access, p_access->info.i_pos );
|
||||
rtmp_packet = rtmp_build_bytes_read( p_sys->p_thread, p_access->info.i_pos );
|
||||
|
||||
tmp_buffer = rtmp_encode_packet( p_sys->p_thread, rtmp_packet );
|
||||
|
||||
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" );
|
||||
}
|
||||
free( rtmp_packet->body->body );
|
||||
free( rtmp_packet->body );
|
||||
free( rtmp_packet );
|
||||
free( tmp_buffer );
|
||||
}
|
||||
|
||||
return i_len_tmp;
|
||||
@ -436,37 +468,37 @@ 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;
|
||||
bool *pb_bool;
|
||||
int *pi_int;
|
||||
int64_t *pi_64;
|
||||
|
||||
switch( i_query )
|
||||
{
|
||||
/* */
|
||||
case ACCESS_CAN_SEEK:
|
||||
case ACCESS_CAN_FASTSEEK:
|
||||
pb_bool = (bool*)va_arg( args, bool* );
|
||||
pb_bool = (bool*) va_arg( args, bool* );
|
||||
*pb_bool = false; /* TODO */
|
||||
break;
|
||||
|
||||
case ACCESS_CAN_PAUSE:
|
||||
pb_bool = (bool*)va_arg( args, bool* );
|
||||
pb_bool = (bool*) va_arg( args, bool* );
|
||||
*pb_bool = false; /* TODO */
|
||||
break;
|
||||
|
||||
case ACCESS_CAN_CONTROL_PACE:
|
||||
pb_bool = (bool*)va_arg( args, bool* );
|
||||
pb_bool = (bool*) va_arg( args, bool* );
|
||||
*pb_bool = true;
|
||||
break;
|
||||
|
||||
/* */
|
||||
case ACCESS_GET_MTU:
|
||||
pi_int = (int*)va_arg( args, int * );
|
||||
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 = (int64_t*) va_arg( args, int64_t * );
|
||||
*pi_64 = var_GetInteger( p_access, "rtmp-caching" ) * INT64_C(1000);
|
||||
break;
|
||||
|
||||
@ -503,13 +535,18 @@ static void ThreadControl( vlc_object_t *p_this )
|
||||
|
||||
while( !p_thread->b_die )
|
||||
{
|
||||
|
||||
rtmp_packet = rtmp_read_net_packet( p_thread );
|
||||
if( rtmp_packet != NULL )
|
||||
{
|
||||
if( rtmp_packet->content_type < 0x01 /* RTMP_CONTENT_TYPE_CHUNK_SIZE */
|
||||
|| rtmp_packet->content_type > 0x14 ) /* RTMP_CONTENT_TYPE_INVOKE */
|
||||
{
|
||||
free( rtmp_packet->body->body );
|
||||
free( rtmp_packet->body );
|
||||
free( rtmp_packet );
|
||||
|
||||
msg_Warn( p_thread, "unknown content type received" );
|
||||
}
|
||||
else
|
||||
p_thread->rtmp_handler[rtmp_packet->content_type]( p_thread, rtmp_packet );
|
||||
}
|
||||
@ -524,6 +561,9 @@ static void ThreadControl( vlc_object_t *p_this )
|
||||
}
|
||||
|
||||
p_thread->b_die = 1;
|
||||
((access_t *) p_thread->p_base_object)->info.b_eof = true;
|
||||
|
||||
block_FifoWake( p_thread->p_fifo_input );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -26,7 +26,7 @@
|
||||
typedef struct rtmp_packet_t rtmp_packet_t;
|
||||
typedef struct rtmp_body_t rtmp_body_t;
|
||||
typedef struct rtmp_control_thread_t rtmp_control_thread_t;
|
||||
typedef void (*rtmp_handler_t)( rtmp_control_thread_t *rtmp_control_thread, rtmp_packet_t *rtmp_packet );
|
||||
typedef void (*rtmp_handler_t)( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet );
|
||||
|
||||
struct rtmp_packet_t
|
||||
{
|
||||
@ -54,51 +54,61 @@ struct rtmp_control_thread_t
|
||||
|
||||
int fd;
|
||||
|
||||
block_fifo_t *p_fifo_media;
|
||||
vlc_url_t url;
|
||||
char *psz_application;
|
||||
char *psz_media;
|
||||
|
||||
block_fifo_t *p_fifo_input;
|
||||
block_fifo_t *p_empty_blocks;
|
||||
|
||||
vlc_mutex_t lock;
|
||||
vlc_cond_t wait;
|
||||
|
||||
int result_connect;
|
||||
int result_publish;
|
||||
int result_play;
|
||||
int result_publish;
|
||||
int result_stop;
|
||||
|
||||
double stream_client;
|
||||
double stream_server;
|
||||
double stream_client_id;
|
||||
double stream_server_id;
|
||||
|
||||
char *psz_publish;
|
||||
|
||||
/* Rebuild FLV variables */
|
||||
/* Rebuild FLV variables (access) */
|
||||
int has_audio;
|
||||
int has_video;
|
||||
int metadata_received;
|
||||
uint8_t metadata_stereo;
|
||||
uint8_t metadata_samplesize;
|
||||
uint8_t metadata_samplerate;
|
||||
uint32_t metadata_samplerate;
|
||||
uint8_t metadata_audiocodecid;
|
||||
uint8_t metadata_videocodecid;
|
||||
uint8_t metadata_frametype;
|
||||
int first_media_packet;
|
||||
uint32_t flv_tag_previous_tag_size;
|
||||
|
||||
/* Vars for rebuilding FLV (access_output) */
|
||||
rtmp_body_t *flv_body;
|
||||
uint8_t flv_content_type;
|
||||
uint32_t flv_length_body;
|
||||
uint32_t flv_timestamp;
|
||||
|
||||
/* vars for channel state */
|
||||
uint32_t chunk_size_recv;
|
||||
uint32_t chunk_size_send;
|
||||
rtmp_packet_t rtmp_headers_recv[64]; /* RTMP_HEADER_STREAM_MAX */
|
||||
rtmp_packet_t rtmp_headers_send[64];
|
||||
|
||||
rtmp_handler_t rtmp_handler[21]; /* index by RTMP_CONTENT_TYPE */
|
||||
|
||||
/* Pointer to base module object (later needs to casted) */
|
||||
void *p_base_object;
|
||||
};
|
||||
|
||||
struct access_sys_t
|
||||
{
|
||||
int active;
|
||||
|
||||
int fd;
|
||||
|
||||
vlc_url_t url;
|
||||
char *psz_application;
|
||||
char *psz_media;
|
||||
|
||||
/* vars for reading from fifo */
|
||||
block_t *flv_packet;
|
||||
int read_packet;
|
||||
@ -110,17 +120,27 @@ struct access_sys_t
|
||||
/*****************************************************************************
|
||||
* RTMP header:
|
||||
******************************************************************************/
|
||||
int rtmp_handshake_passive( vlc_object_t *p_this );
|
||||
int rtmp_handshake_active( vlc_object_t *p_this );
|
||||
int rtmp_connect_active( vlc_object_t *p_this );
|
||||
int rtmp_handshake_active( vlc_object_t *p_this, int fd );
|
||||
int rtmp_handshake_passive( vlc_object_t *p_this, int fd );
|
||||
int rtmp_connect_active( rtmp_control_thread_t *p_thread );
|
||||
int rtmp_connect_passive( rtmp_control_thread_t *p_thread );
|
||||
//int rtmp_seek( access_t *p_access, int64_t i_pos ); TODO
|
||||
int rtmp_send_bytes_read( access_t *p_access, uint32_t reply );
|
||||
int rtmp_send_publish_start( access_t *p_access );
|
||||
//
|
||||
rtmp_packet_t *rtmp_build_bytes_read( rtmp_control_thread_t *p_thread, uint32_t reply );
|
||||
rtmp_packet_t *rtmp_build_publish_start( rtmp_control_thread_t *p_thread );
|
||||
rtmp_packet_t *rtmp_build_flv_over_rtmp( rtmp_control_thread_t *p_thread, block_t *p_buffer );
|
||||
|
||||
rtmp_packet_t *rtmp_read_net_packet( rtmp_control_thread_t *p_thread );
|
||||
uint8_t *rtmp_encode_packet( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet );
|
||||
void rtmp_init_handler( rtmp_handler_t *rtmp_handler );
|
||||
/*****************************************************************************
|
||||
* FLV header:
|
||||
******************************************************************************/
|
||||
block_t *flv_get_metadata( access_t *p_access );
|
||||
block_t *flv_insert_header( access_t *p_access, block_t *first_packet );
|
||||
|
||||
/*****************************************************************************
|
||||
* RTMP body header:
|
||||
******************************************************************************/
|
||||
rtmp_body_t *rtmp_body_new( int length_buffer );
|
||||
void rtmp_body_reset( rtmp_body_t * );
|
||||
|
Loading…
Reference in New Issue
Block a user