⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtmp_amf_flv.c

📁 vlc源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* TODOintrtmp_seek( access_t *p_access, int64_t i_pos ){    access_sys_t *p_sys = p_access->p_sys;    rtmp_packet_t *rtmp_packet;    rtmp_body_t *rtmp_body;    uint8_t *tmp_buffer;    uint64_t tmp_number;    ssize_t i_ret;msg_Warn(p_access, "i_pos %lld", i_pos);    // Build NetStream.seek call //    rtmp_body = rtmp_body_new();    tmp_buffer = amf_encode_element( AMF_DATATYPE_STRING, "seek" );    rtmp_body_append( rtmp_body, tmp_buffer,        AMF_DATATYPE_SIZE_STRING + strlen( "seek" ) );    free( tmp_buffer );    tmp_number = 0;    tmp_buffer = amf_encode_element( AMF_DATATYPE_NUMBER,        &tmp_number );    rtmp_body_append( rtmp_body, tmp_buffer, AMF_DATATYPE_SIZE_NUMBER );    free( tmp_buffer );    tmp_buffer = amf_encode_element( AMF_DATATYPE_NULL, NULL );    rtmp_body_append( rtmp_body, tmp_buffer, AMF_DATATYPE_SIZE_NULL );    free( tmp_buffer );//TODO: convert i_pos to double and see if they are milliseconds    tmp_buffer = amf_encode_element( AMF_DATATYPE_NUMBER,        &i_pos );    rtmp_body_append( rtmp_body, tmp_buffer, AMF_DATATYPE_SIZE_NUMBER );    free( tmp_buffer );    rtmp_packet = rtmp_new_packet( p_sys->p_thread, RTMP_DEFAULT_STREAM_INDEX_INVOKE,        0, RTMP_DATATYPE_INVOKE, RTMP_SRC_DST_DEFAULT, rtmp_body );    free( rtmp_body->body );    free( rtmp_body );    tmp_buffer = rtmp_encode_packet( p_access, rtmp_packet );     // Call NetStream.seek //    i_ret = net_Write( p_access, p_sys->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 call NetStream.seek" );        return -1;    }    free( rtmp_packet->body->body );    free( rtmp_packet->body );    free( rtmp_packet );    free( tmp_buffer );    // Receive TODO: see what //    rtmp_packet = rtmp_read_net_packet( p_access, p_sys->fd );    free( rtmp_packet->body->body );    free( rtmp_packet->body );    free( rtmp_packet );    return 0;}*/rtmp_packet_t *rtmp_build_bytes_read( rtmp_control_thread_t *p_thread, uint32_t reply ){    rtmp_packet_t *rtmp_packet;    rtmp_body_t *rtmp_body;    uint8_t *tmp_buffer;    /* Build bytes read packet */    rtmp_body = rtmp_body_new( -1 );    tmp_buffer = (uint8_t *) malloc( sizeof( uint32_t ) * sizeof( uint8_t ) );    if( !tmp_buffer ) return NULL;    reply = hton32( reply );    memcpy( tmp_buffer, &reply, sizeof( uint32_t ) );    rtmp_body_append( rtmp_body, tmp_buffer, sizeof( uint32_t ) );    free( tmp_buffer );    rtmp_packet = rtmp_new_packet( p_thread, RTMP_DEFAULT_STREAM_INDEX_CONTROL,        0, RTMP_CONTENT_TYPE_BYTES_READ, 0, rtmp_body );    free( rtmp_body->body );    free( rtmp_body );    return rtmp_packet;}rtmp_packet_t *rtmp_build_publish_start( rtmp_control_thread_t *p_thread ){    rtmp_packet_t *rtmp_packet;    rtmp_body_t *rtmp_body;    uint8_t *tmp_buffer;    /* Build publish start event */    rtmp_body = rtmp_body_new( -1 );    tmp_buffer = amf_encode_element( AMF_DATATYPE_STRING, "onStatus" );    rtmp_body_append( rtmp_body, tmp_buffer,        AMF_DATATYPE_SIZE_STRING + strlen( "onStatus" ) );    free( tmp_buffer );    tmp_buffer = amf_encode_element( AMF_DATATYPE_NUMBER,        &p_thread->stream_server_id );    rtmp_body_append( rtmp_body, tmp_buffer, AMF_DATATYPE_SIZE_NUMBER );    free( tmp_buffer );    tmp_buffer = amf_encode_element( AMF_DATATYPE_NULL, NULL );    rtmp_body_append( rtmp_body, tmp_buffer, AMF_DATATYPE_SIZE_NULL );    free( tmp_buffer );    tmp_buffer = amf_encode_element( AMF_DATATYPE_OBJECT, NULL );    rtmp_body_append( rtmp_body, tmp_buffer, AMF_DATATYPE_SIZE_OBJECT );    free( tmp_buffer );    tmp_buffer = amf_encode_object_variable( "level",        AMF_DATATYPE_STRING, "status" );    rtmp_body_append( rtmp_body, tmp_buffer,        AMF_DATATYPE_SIZE_OBJECT_VARIABLE + strlen( "level" ) +        AMF_DATATYPE_SIZE_STRING + strlen( "status" ) );    free ( tmp_buffer );    tmp_buffer = amf_encode_object_variable( "code",        AMF_DATATYPE_STRING, "NetStream.Publish.Start" );    rtmp_body_append( rtmp_body, tmp_buffer,        AMF_DATATYPE_SIZE_OBJECT_VARIABLE + strlen( "code" ) +        AMF_DATATYPE_SIZE_STRING + strlen( "NetStream.Publish.Start" ) );    free ( tmp_buffer );    tmp_buffer = amf_encode_object_variable( "description",        AMF_DATATYPE_STRING, "" );    rtmp_body_append( rtmp_body, tmp_buffer,        AMF_DATATYPE_SIZE_OBJECT_VARIABLE + strlen( "description" ) +        AMF_DATATYPE_SIZE_STRING + strlen( "" ) );    free ( tmp_buffer );    tmp_buffer = amf_encode_object_variable( "details",        AMF_DATATYPE_STRING, p_thread->psz_publish );    rtmp_body_append( rtmp_body, tmp_buffer,        AMF_DATATYPE_SIZE_OBJECT_VARIABLE + strlen( "details" ) +        AMF_DATATYPE_SIZE_STRING + strlen( p_thread->psz_publish ) );    free ( tmp_buffer );    tmp_buffer = amf_encode_object_variable( "clientid",        AMF_DATATYPE_NUMBER, &p_thread->stream_client_id );    rtmp_body_append( rtmp_body, tmp_buffer,        AMF_DATATYPE_SIZE_OBJECT_VARIABLE + strlen( "clientid" ) +        AMF_DATATYPE_SIZE_NUMBER );    free( tmp_buffer );    tmp_buffer = amf_encode_element ( AMF_DATATYPE_END_OF_OBJECT, NULL );    rtmp_body_append( rtmp_body, tmp_buffer, AMF_DATATYPE_SIZE_END_OF_OBJECT );    free( tmp_buffer );    rtmp_packet = rtmp_new_packet( p_thread, RTMP_DEFAULT_STREAM_INDEX_INVOKE,        0, RTMP_CONTENT_TYPE_INVOKE, 0, rtmp_body );    free( rtmp_body->body );    free( rtmp_body );    return rtmp_packet;}rtmp_packet_t *rtmp_build_flv_over_rtmp( rtmp_control_thread_t *p_thread, block_t *p_buffer ){    rtmp_packet_t *rtmp_packet;    if( p_thread->flv_length_body > 0 )    {        p_thread->flv_length_body -= p_buffer->i_buffer;        rtmp_body_append( p_thread->flv_body, p_buffer->p_buffer, p_buffer->i_buffer );        if( p_thread->flv_length_body > 0 )            return NULL;    }    else    {        p_thread->flv_content_type = *p_buffer->p_buffer;        p_buffer->p_buffer[0] = 0;        p_thread->flv_length_body = ntoh32( *(uint32_t *) (p_buffer->p_buffer) );        p_buffer->p_buffer[3] = 0;        p_thread->flv_timestamp = ntoh32( *(uint32_t *) (p_buffer->p_buffer + 3) );    }    if( p_thread->flv_length_body > p_buffer->i_buffer - FLV_TAG_SIZE - FLV_TAG_PREVIOUS_TAG_SIZE )    {        p_thread->flv_length_body -= p_buffer->i_buffer - FLV_TAG_SIZE - FLV_TAG_PREVIOUS_TAG_SIZE;        rtmp_body_append( p_thread->flv_body, p_buffer->p_buffer + FLV_TAG_SIZE, p_buffer->i_buffer - FLV_TAG_SIZE );        return NULL;    }    else    {        rtmp_body_append( p_thread->flv_body, p_buffer->p_buffer + FLV_TAG_SIZE, p_thread->flv_length_body );    }    rtmp_packet = rtmp_new_packet( p_thread, rtmp_get_stream_index( p_thread->flv_content_type ),        p_thread->flv_timestamp, p_thread->flv_content_type, RTMP_SRC_DST_DEFAULT, p_thread->flv_body );    p_thread->flv_length_body = 0;    rtmp_body_reset( p_thread->flv_body );    return rtmp_packet;}rtmp_packet_t *rtmp_read_net_packet( rtmp_control_thread_t *p_thread ){    int length_header;    int stream_index;    int bytes_left;    uint8_t p_read[12];    rtmp_packet_t *rtmp_packet;    ssize_t i_ret;    for(;;)    {        i_ret = net_Read( p_thread, p_thread->fd, NULL, p_read, 1, true );        if( i_ret != 1 )            goto error;        length_header = rtmp_decode_header_size( (vlc_object_t *) p_thread, p_read[0] & RTMP_HEADER_SIZE_MASK );        stream_index = p_read[0] & RTMP_HEADER_STREAM_INDEX_MASK;        i_ret = net_Read( p_thread, p_thread->fd, NULL, p_read + 1, length_header - 1, true );        if( i_ret != length_header - 1 )            goto error;        /* Update timestamp if not is an interchunk packet */        if( length_header == 1 && p_thread->rtmp_headers_recv[stream_index].body == NULL )        {            p_thread->rtmp_headers_recv[stream_index].timestamp +=                p_thread->rtmp_headers_recv[stream_index].timestamp_relative;        }        /* Length 4 and 8 headers have relative timestamp */        if( length_header == 4 || length_header == 8 )        {            p_read[0] = 0;            p_thread->rtmp_headers_recv[stream_index].timestamp_relative = ntoh32( *(uint32_t *) p_read );            p_thread->rtmp_headers_recv[stream_index].timestamp +=                p_thread->rtmp_headers_recv[stream_index].timestamp_relative;        }        if( length_header >= 8 )        {            p_read[3] = 0;            p_thread->rtmp_headers_recv[stream_index].length_body = ntoh32( *(uint32_t *) (p_read + 3) );            p_thread->rtmp_headers_recv[stream_index].content_type = p_read[7];        }        /* Length 12 headers have absolute timestamp */        if( length_header >= 12 )        {            p_read[0] = 0;            p_thread->rtmp_headers_recv[stream_index].timestamp = ntoh32( *(uint32_t *) p_read );            p_thread->rtmp_headers_recv[stream_index].src_dst = ntoh32( *(uint32_t *) (p_read + 8) );        }        if( p_thread->rtmp_headers_recv[stream_index].body == NULL )        {            p_thread->rtmp_headers_recv[stream_index].body =                rtmp_body_new( p_thread->rtmp_headers_recv[stream_index].length_body );        }        bytes_left = p_thread->rtmp_headers_recv[stream_index].body->length_buffer -            p_thread->rtmp_headers_recv[stream_index].body->length_body;        if( bytes_left > p_thread->chunk_size_recv )            bytes_left = p_thread->chunk_size_recv;        i_ret = net_Read( p_thread, p_thread->fd, NULL,            p_thread->rtmp_headers_recv[stream_index].body->body +            p_thread->rtmp_headers_recv[stream_index].body->length_body,            bytes_left, true );        if( i_ret != bytes_left )            goto error;        p_thread->rtmp_headers_recv[stream_index].body->length_body += bytes_left;        if( p_thread->rtmp_headers_recv[stream_index].length_body == p_thread->rtmp_headers_recv[stream_index].body->length_body )        {            rtmp_packet = (rtmp_packet_t *) malloc( sizeof( rtmp_packet_t ) );            if( !rtmp_packet ) goto error;            rtmp_packet->stream_index = stream_index;            rtmp_packet->timestamp = p_thread->rtmp_headers_recv[stream_index].timestamp;            rtmp_packet->timestamp_relative = p_thread->rtmp_headers_recv[stream_index].timestamp_relative;            rtmp_packet->content_type = p_thread->rtmp_headers_recv[stream_index].content_type;            rtmp_packet->src_dst = p_thread->rtmp_headers_recv[stream_index].src_dst;            rtmp_packet->length_body = p_thread->rtmp_headers_recv[stream_index].length_body;            rtmp_packet->body = p_thread->rtmp_headers_recv[stream_index].body;            p_thread->rtmp_headers_recv[stream_index].body = NULL;            return rtmp_packet;        }    }error:    msg_Err( p_thread, "rtmp_read_net_packet: net_Read error");    return NULL;}voidrtmp_init_handler( rtmp_handler_t *rtmp_handler ){    rtmp_handler[RTMP_CONTENT_TYPE_CHUNK_SIZE] = rtmp_handler_chunk_size;    rtmp_handler[RTMP_CONTENT_TYPE_UNKNOWN_02] = rtmp_handler_null;    rtmp_handler[RTMP_CONTENT_TYPE_BYTES_READ] = rtmp_handler_null;    rtmp_handler[RTMP_CONTENT_TYPE_PING] = rtmp_handler_null;    rtmp_handler[RTMP_CONTENT_TYPE_SERVER_BW] = rtmp_handler_null;    rtmp_handler[RTMP_CONTENT_TYPE_CLIENT_BW] = rtmp_handler_null;    rtmp_handler[RTMP_CONTENT_TYPE_UNKNOWN_07] = rtmp_handler_null;    rtmp_handler[RTMP_CONTENT_TYPE_AUDIO_DATA] = rtmp_handler_audio_data;    rtmp_handler[RTMP_CONTENT_TYPE_VIDEO_DATA] = rtmp_handler_video_data;    rtmp_handler[RTMP_CONTENT_TYPE_UNKNOWN_0A_0E] = rtmp_handler_null;    rtmp_handler[RTMP_CONTENT_TYPE_FLEX_STREAM] = rtmp_handler_null;    rtmp_handler[RTMP_CONTENT_TYPE_FLEX_SHARED_OBJECT] = rtmp_handler_null;    rtmp_handler[RTMP_CONTENT_TYPE_MESSAGE] = rtmp_handler_null;    rtmp_handler[RTMP_CONTENT_TYPE_NOTIFY] = rtmp_handler_notify;    rtmp_handler[RTMP_CONTENT_TYPE_SHARED_OBJECT] = rtmp_handler_null;    rtmp_handler[RTMP_CONTENT_TYPE_INVOKE] = rtmp_handler_invoke;}static voidrtmp_handler_null( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet ){    VLC_UNUSED(p_thread);    free( rtmp_packet->body->body );    free( rtmp_packet->body );    free( rtmp_packet );}static voidrtmp_handler_chunk_size( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet ){    p_thread->chunk_size_recv = ntoh32( *(uint32_t *) (rtmp_packet->body->body) );    free( rtmp_packet->body->body );    free( rtmp_packet->body );    free( rtmp_packet );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -