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

📄 mmstu.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
    while( vlc_object_alive (p_access) )    {        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)" );            break;        }    }    /* get a packet */    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 = false;    return VLC_SUCCESS;}/***************************************************************************** * Read: *****************************************************************************/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 < i_len )    {        if( p_access->info.i_pos < p_sys->i_header )        {            i_copy = __MIN( i_len, p_sys->i_header - p_access->info.i_pos );            memcpy( &p_buffer[i_data], &p_sys->p_header[p_access->info.i_pos], i_copy );            i_data += i_copy;            p_access->info.i_pos += i_copy;        }        else if( p_sys->i_media_used < p_sys->i_media )        {            i_copy = __MIN( i_len - i_data ,                            p_sys->i_media - p_sys->i_media_used );            memcpy( &p_buffer[i_data], &p_sys->p_media[p_sys->i_media_used], i_copy );            i_data += i_copy;            p_sys->i_media_used += i_copy;            p_access->info.i_pos += i_copy;        }        else if( p_sys->p_media != NULL &&                 p_sys->i_media_used < p_sys->i_packet_length )        {            i_copy = __MIN( i_len - i_data,                            p_sys->i_packet_length - p_sys->i_media_used);            memset( &p_buffer[i_data], 0, i_copy );            i_data += i_copy;            p_sys->i_media_used += i_copy;            p_access->info.i_pos += i_copy;        }        else if( p_access->info.b_eof ||                 mms_HeaderMediaRead( p_access, MMS_PACKET_MEDIA ) < 0 )        {            break;        }    }    return i_data;}/**************************************************************************** * MMSOpen : Open a connection with the server over mmst or mmsu ****************************************************************************/static int MMSOpen( access_t  *p_access, vlc_url_t *p_url, int  i_proto ){    access_sys_t *p_sys = p_access->p_sys;    int           b_udp = ( i_proto == MMS_PROTO_UDP ) ? 1 : 0;    var_buffer_t buffer;    char         tmp[4096];    uint16_t     *p;    int          i_server_version;    int          i_tool_version;    int          i_update_player_url;    int          i_encryption_type;    int          i;    int          i_streams;    int          i_first;    char         *mediapath;    /* *** Open a TCP connection with server *** */    msg_Dbg( p_access, "waiting for connection..." );    p_sys->i_handle_tcp = net_ConnectTCP( p_access, p_url->psz_host, p_url->i_port );    if( p_sys->i_handle_tcp < 0 )    {        msg_Err( p_access, "failed to open a connection (tcp)" );        return VLC_EGENERIC;    }    msg_Dbg( p_access,             "connection(tcp) with \"%s:%d\" successful",             p_url->psz_host,             p_url->i_port );    /* *** Bind port if UDP protocol is selected *** */    if( b_udp )    {        if( net_GetSockAddress( p_sys->i_handle_tcp, p_sys->sz_bind_addr,                                NULL ) )        {            net_Close( p_sys->i_handle_tcp );            return VLC_EGENERIC;        }        p_sys->i_handle_udp = net_ListenUDP1( (vlc_object_t *)p_access, p_sys->sz_bind_addr,                                              7000 );        if( p_sys->i_handle_udp < 0 )        {            msg_Err( p_access, "failed to open a connection (udp)" );            net_Close( p_sys->i_handle_tcp );            return VLC_EGENERIC;        }        msg_Dbg( p_access,                 "connection(udp) at \"%s:%d\" successful",                 p_sys->sz_bind_addr, 7000 );    }    /* *** Init context for mms prototcol *** */     GenerateGuid ( &p_sys->guid );    /* used to identify client by server */    msg_Dbg( p_access,             "generated guid: "GUID_FMT,             GUID_PRINT( p_sys->guid ) );    p_sys->i_command_level = 1;          /* updated after 0x1A command */    p_sys->i_seq_num = 0;    p_sys->i_media_packet_id_type  = 0x04;    p_sys->i_header_packet_id_type = 0x02;    p_sys->i_proto = i_proto;    p_sys->i_packet_seq_num = 0;    p_sys->p_header = NULL;    p_sys->i_header = 0;    p_sys->p_media = NULL;    p_sys->i_media = 0;    p_sys->i_media_used = 0;    p_access->info.i_pos = 0;    p_sys->i_buffer_tcp = 0;    p_sys->i_buffer_udp = 0;    p_sys->p_cmd = NULL;    p_sys->i_cmd = 0;    p_access->info.b_eof = false;    /* *** send command 1 : connection request *** */    var_buffer_initwrite( &buffer, 0 );    var_buffer_add16( &buffer, 0x001c );    var_buffer_add16( &buffer, 0x0003 );    sprintf( tmp,             "NSPlayer/7.0.0.1956; {"GUID_FMT"}; Host: %s",             GUID_PRINT( p_sys->guid ),             p_url->psz_host );    var_buffer_addUTF16( &buffer, tmp );    mms_CommandSend( p_access,                     0x01,          /* connexion request */                     0x00000000,    /* flags, FIXME */                     0x0004000b,    /* ???? */                     buffer.p_data,                     buffer.i_data );    if( mms_CommandRead( p_access, 0x01, 0 ) < 0 )    {        var_buffer_free( &buffer );        MMSClose( p_access );        return VLC_EGENERIC;    }    i_server_version = GetDWLE( p_sys->p_cmd + MMS_CMD_HEADERSIZE + 32 );    i_tool_version = GetDWLE( p_sys->p_cmd + MMS_CMD_HEADERSIZE + 36 );    i_update_player_url = GetDWLE( p_sys->p_cmd + MMS_CMD_HEADERSIZE + 40 );    i_encryption_type = GetDWLE( p_sys->p_cmd + MMS_CMD_HEADERSIZE + 44 );    p = (uint16_t*)( p_sys->p_cmd + MMS_CMD_HEADERSIZE + 48 );#define GETUTF16( psz, size ) \    { \        int i; \        psz = malloc( size + 1); \        for( i = 0; i < size; i++ ) \        { \            psz[i] = p[i]; \        } \        psz[size] = '\0'; \        p += ( size ); \    }    GETUTF16( p_sys->psz_server_version, i_server_version );    GETUTF16( p_sys->psz_tool_version, i_tool_version );    GETUTF16( p_sys->psz_update_player_url, i_update_player_url );    GETUTF16( p_sys->psz_encryption_type, i_encryption_type );#undef GETUTF16    msg_Dbg( p_access,             "0x01 --> server_version:\"%s\" tool_version:\"%s\" update_player_url:\"%s\" encryption_type:\"%s\"",             p_sys->psz_server_version,             p_sys->psz_tool_version,             p_sys->psz_update_player_url,             p_sys->psz_encryption_type );    /* *** should make an 18 command to make data timing *** */    /* *** send command 2 : transport protocol selection *** */    var_buffer_reinitwrite( &buffer, 0 );    var_buffer_add32( &buffer, 0x00000000 );    var_buffer_add32( &buffer, 0x000a0000 );    var_buffer_add32( &buffer, 0x00000002 );    if( b_udp )    {        sprintf( tmp,                 "\\\\%s\\UDP\\%d",                 p_sys->sz_bind_addr,                 7000 ); // FIXME    }    else    {        sprintf( tmp, "\\\\192.168.0.1\\TCP\\1242"  );    }    var_buffer_addUTF16( &buffer, tmp );    var_buffer_add16( &buffer, '0' );    mms_CommandSend( p_access,                     0x02,          /* connexion request */                     0x00000000,    /* flags, FIXME */                     0xffffffff,    /* ???? */                     buffer.p_data,                     buffer.i_data );    /* *** response from server, should be 0x02 or 0x03 *** */    mms_CommandRead( p_access, 0x02, 0x03 );    if( p_sys->i_command == 0x03 )    {        msg_Err( p_access,                 "%s protocol selection failed", b_udp ? "UDP" : "TCP" );        var_buffer_free( &buffer );        MMSClose( p_access );        return VLC_EGENERIC;    }    else if( p_sys->i_command != 0x02 )    {        msg_Warn( p_access, "received command isn't 0x02 in reponse to 0x02" );    }    /* *** send command 5 : media file name/path requested *** */    var_buffer_reinitwrite( &buffer, 0 );    var_buffer_add64( &buffer, 0 );    /* 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,                     p_sys->i_command_level,                     0xffffffff,                     buffer.p_data,                     buffer.i_data );    /* *** wait for reponse *** */    mms_CommandRead( p_access, 0x1a, 0x06 );    /* test if server send 0x1A answer */    if( p_sys->i_command == 0x1A )    {        msg_Err( p_access, "id/password requested (not yet supported)" );        /*  FIXME */        var_buffer_free( &buffer );        MMSClose( p_access );        return VLC_EGENERIC;    }    if( p_sys->i_command != 0x06 )    {        msg_Err( p_access,                 "unknown answer (0x%x instead of 0x06)",                 p_sys->i_command );        var_buffer_free( &buffer );        MMSClose( p_access );        return( -1 );    }    /*  1 for file ok, 2 for authen ok */    switch( GetDWLE( p_sys->p_cmd + MMS_CMD_HEADERSIZE ) )    {        case 0x0001:            msg_Dbg( p_access, "media file name/path accepted" );            break;        case 0x0002:            msg_Dbg( p_access, "authentication accepted" );            break;        case -1:        default:        msg_Err( p_access, "error while asking for file %d",                 GetDWLE( p_sys->p_cmd + MMS_CMD_HEADERSIZE ) );        var_buffer_free( &buffer );        MMSClose( p_access );        return VLC_EGENERIC;    }    p_sys->i_flags_broadcast =        GetDWLE( p_sys->p_cmd + MMS_CMD_HEADERSIZE + 12 );    p_sys->i_media_length =        GetDWLE( p_sys->p_cmd + MMS_CMD_HEADERSIZE + 24 );    p_sys->i_packet_length =        GetDWLE( p_sys->p_cmd + MMS_CMD_HEADERSIZE + 44 );    p_sys->i_packet_count =        GetDWLE( p_sys->p_cmd + MMS_CMD_HEADERSIZE + 48 );    p_sys->i_max_bit_rate =        GetDWLE( p_sys->p_cmd + MMS_CMD_HEADERSIZE + 56 );    p_sys->i_header_size =        GetDWLE( p_sys->p_cmd + MMS_CMD_HEADERSIZE + 60 );    msg_Dbg( p_access,             "answer 0x06 flags:0x%8.8"PRIx32" media_length:%"PRIu32"s "             "packet_length:%zul packet_count:%"PRId32" max_bit_rate:%d "             "header_size:%zu",             p_sys->i_flags_broadcast,             p_sys->i_media_length,             (unsigned)p_sys->i_packet_length,             p_sys->i_packet_count,             p_sys->i_max_bit_rate,             p_sys->i_header_size );    /* *** send command 15 *** */    var_buffer_reinitwrite( &buffer, 0 );    var_buffer_add32( &buffer, 0 );    var_buffer_add32( &buffer, 0x8000 );    var_buffer_add32( &buffer, 0xffffffff );    var_buffer_add32( &buffer, 0x00 );    var_buffer_add32( &buffer, 0x00 );    var_buffer_add32( &buffer, 0x00 );    var_buffer_add64( &buffer, (((uint64_t)0x40ac2000)<<32) );    var_buffer_add32( &buffer, p_sys->i_header_packet_id_type );    var_buffer_add32( &buffer, 0x00 );    mms_CommandSend( p_access, 0x15, p_sys->i_command_level, 0x00,                     buffer.p_data, buffer.i_data );    /* *** wait for reponse *** */    /* Commented out because it fails on some stream (no 0x11 answer) */#if 0    mms_CommandRead( p_access, 0x11, 0 );    if( p_sys->i_command != 0x11 )    {        msg_Err( p_access,                 "unknown answer (0x%x instead of 0x11)",                 p_sys->i_command );        var_buffer_free( &buffer );        MMSClose( p_access );        return( -1 );    }#endif    /* *** now read header packet *** */    /* XXX could be split over multiples packets */    msg_Dbg( p_access, "reading header" );    for( ;; )    {        if( mms_HeaderMediaRead( p_access, MMS_PACKET_HEADER ) < 0 )        {            msg_Err( p_access, "cannot receive header" );            var_buffer_free( &buffer );            MMSClose( p_access );            return VLC_EGENERIC;        }        if( p_sys->i_header >= p_sys->i_header_size )        {            msg_Dbg( p_access,                     "header complete(%zu)",                     p_sys->i_header );            break;        }        msg_Dbg( p_access,                 "header incomplete (%zu/%zu), reading more",                 p_sys->i_header,                 p_sys->i_header_size );    }    /* *** parse header and get stream and their id *** */    /* get all streams properties,     *     * TODO : stream bitrates properties(optional)     *        and bitrate mutual exclusion(optional) */

⌨️ 快捷键说明

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