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

📄 mmstu.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
     asf_HeaderParse ( &p_sys->asfh,                           p_sys->p_header, p_sys->i_header );     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" ) );    /* *** now select stream we want to receive *** */    /* TODO take care of stream bitrate TODO */    i_streams = 0;    i_first = -1;    var_buffer_reinitwrite( &buffer, 0 );    /* for now, select first audio and video stream */    for( i = 1; i < 128; i++ )    {        if( p_sys->asfh.stream[i].i_cat != ASF_STREAM_UNKNOWN )        {            i_streams++;            if( i_first != -1 )            {                var_buffer_add16( &buffer, 0xffff );                var_buffer_add16( &buffer, i );            }            else            {                i_first = i;            }            if( p_sys->asfh.stream[i].i_selected )            {                var_buffer_add16( &buffer, 0x0000 );                msg_Info( p_access,                          "selecting stream[0x%x] %s (%d kb/s)",                          i,                          ( p_sys->asfh.stream[i].i_cat == ASF_STREAM_AUDIO  ) ?                                                  "audio" : "video" ,                          p_sys->asfh.stream[i].i_bitrate / 1024);            }            else            {                var_buffer_add16( &buffer, 0x0002 );                msg_Info( p_access,                          "ignoring stream[0x%x] %s (%d kb/s)",                          i,                          ( p_sys->asfh.stream[i].i_cat == ASF_STREAM_AUDIO  ) ?                                    "audio" : "video" ,                          p_sys->asfh.stream[i].i_bitrate / 1024);            }        }    }    if( i_streams == 0 )    {        msg_Err( p_access, "cannot find any stream" );        var_buffer_free( &buffer );        MMSClose( p_access );        return VLC_EGENERIC;    }    mms_CommandSend( p_access, 0x33,                     i_streams,                     0xffff | ( i_first << 16 ),                     buffer.p_data, buffer.i_data );    mms_CommandRead( p_access, 0x21, 0 );    if( p_sys->i_command != 0x21 )    {        msg_Err( p_access,                 "unknown answer (0x%x instead of 0x21)",                 p_sys->i_command );        var_buffer_free( &buffer );        MMSClose( p_access );        return VLC_EGENERIC;    }    var_buffer_free( &buffer );    msg_Info( p_access, "connection successful" );    return VLC_SUCCESS;}/**************************************************************************** * MMSStart : Start streaming ****************************************************************************/static int MMSStart( access_t  *p_access, uint32_t i_packet ){    access_sys_t        *p_sys = p_access->p_sys;    var_buffer_t    buffer;    /* *** start stream from packet 0 *** */    var_buffer_initwrite( &buffer, 0 );    var_buffer_add64( &buffer, 0 ); /* seek point in second */    var_buffer_add32( &buffer, 0xffffffff );    var_buffer_add32( &buffer, i_packet ); // begin from start    var_buffer_add8( &buffer, 0xff ); // stream time limit    var_buffer_add8( &buffer, 0xff ); //  on 3bytes ...    var_buffer_add8( &buffer, 0xff ); //    var_buffer_add8( &buffer, 0x00 ); // don't use limit    var_buffer_add32( &buffer, p_sys->i_media_packet_id_type );    mms_CommandSend( p_access, 0x07, p_sys->i_command_level, 0x0001ffff,                     buffer.p_data, buffer.i_data );    var_buffer_free( &buffer );    mms_CommandRead( p_access, 0x05, 0 );    if( p_sys->i_command != 0x05 )    {        msg_Err( p_access,                 "unknown answer (0x%x instead of 0x05)",                 p_sys->i_command );        return -1;    }    else    {        /* get a packet */        if( mms_HeaderMediaRead( p_access, MMS_PACKET_MEDIA ) < 0 )            return -1;        msg_Dbg( p_access, "streaming started" );        return 0;    }}/**************************************************************************** * MMSStop : Stop streaming ****************************************************************************/static int MMSStop( access_t  *p_access ){    access_sys_t *p_sys = p_access->p_sys;    /* *** stop stream but keep connection alive *** */    mms_CommandSend( p_access,                     0x09,                     p_sys->i_command_level,                     0x001fffff,                     NULL, 0 );    return( 0 );}/**************************************************************************** * MMSClose : Close streaming and connection ****************************************************************************/static void MMSClose( access_t  *p_access ){    access_sys_t        *p_sys = p_access->p_sys;    msg_Dbg( p_access, "Connection closed" );    /* *** tell server that we will disconnect *** */    mms_CommandSend( p_access,                     0x0d,                     p_sys->i_command_level,                     0x00000001,                     NULL, 0 );    /* *** close sockets *** */    net_Close( p_sys->i_handle_tcp );    if( p_sys->i_proto == MMS_PROTO_UDP )    {        net_Close( p_sys->i_handle_udp );    }    FREENULL( p_sys->p_cmd );    FREENULL( p_sys->p_media );    FREENULL( p_sys->p_header );    FREENULL( p_sys->psz_server_version );    FREENULL( p_sys->psz_tool_version );    FREENULL( p_sys->psz_update_player_url );    FREENULL( p_sys->psz_encryption_type );}/**************************************************************************** * * MMS specific functions * ****************************************************************************/static int mms_CommandSend( access_t *p_access, int i_command,                            uint32_t i_prefix1, uint32_t i_prefix2,                            uint8_t *p_data, int i_data_old ){    var_buffer_t buffer;    access_sys_t *p_sys = p_access->p_sys;    int i_data_by8, i_ret;    int i_data = i_data_old;    while( i_data & 0x7 ) i_data++;    i_data_by8 = i_data >> 3;    /* first init buffer */    var_buffer_initwrite( &buffer, 0 );    var_buffer_add32( &buffer, 0x00000001 );    /* start sequence */    var_buffer_add32( &buffer, 0xB00BFACE );    /* size after protocol type */    var_buffer_add32( &buffer, i_data + MMS_CMD_HEADERSIZE - 16 );    var_buffer_add32( &buffer, 0x20534d4d );    /* protocol "MMS " */    var_buffer_add32( &buffer, i_data_by8 + 4 );    var_buffer_add32( &buffer, p_sys->i_seq_num ); p_sys->i_seq_num++;    var_buffer_add64( &buffer, 0 );    var_buffer_add32( &buffer, i_data_by8 + 2 );    var_buffer_add32( &buffer, 0x00030000 | i_command ); /* dir | command */    var_buffer_add32( &buffer, i_prefix1 );    /* command specific */    var_buffer_add32( &buffer, i_prefix2 );    /* command specific */    /* specific command data */    if( p_data && i_data > 0 )    {        var_buffer_addmemory( &buffer, p_data, i_data_old );    }    /* Append padding to the command data */    var_buffer_add64( &buffer, 0 );    /* send it */    vlc_mutex_lock( &p_sys->lock_netwrite );    i_ret = net_Write( p_access, p_sys->i_handle_tcp, NULL, buffer.p_data,                       buffer.i_data - ( 8 - ( i_data - i_data_old ) ) );    vlc_mutex_unlock( &p_sys->lock_netwrite );    if( i_ret != buffer.i_data - ( 8 - ( i_data - i_data_old ) ) )    {        msg_Err( p_access, "failed to send command" );        return VLC_EGENERIC;    }    var_buffer_free( &buffer );    return VLC_SUCCESS;}static int NetFillBuffer( access_t *p_access ){#ifdef UNDER_CE    return -1;#else    access_sys_t    *p_sys = p_access->p_sys;    int             i_ret;    struct pollfd   ufd[2];    unsigned        timeout, nfd;    /* FIXME when using udp */    ssize_t i_tcp, i_udp;    ssize_t i_tcp_read, i_udp_read;    int i_try = 0;    i_tcp = MMS_BUFFER_SIZE/2 - p_sys->i_buffer_tcp;    if( p_sys->i_proto == MMS_PROTO_UDP )    {        i_udp = MMS_BUFFER_SIZE/2 - p_sys->i_buffer_udp;    }    else    {        i_udp = 0;  /* there isn't udp socket */    }    if( ( i_udp <= 0 ) && ( i_tcp <= 0 ) )    {        msg_Warn( p_access, "nothing to read %d:%d", (int)i_tcp, (int)i_udp );        return 0;    }    else    {        /* msg_Warn( p_access, "ask for tcp:%d udp:%d", i_tcp, i_udp ); */    }    /* Find if some data is available */    do    {        i_try++;        /* Initialize file descriptor set */        memset (ufd, 0, sizeof (ufd));        nfd = 0;        if( i_tcp > 0 )        {            ufd[nfd].fd = p_sys->i_handle_tcp;            ufd[nfd].events = POLLIN;            nfd++;        }        if( i_udp > 0 )        {            ufd[nfd].fd = p_sys->i_handle_tcp;            ufd[nfd].events = POLLIN;            nfd++;        }        /* We'll wait 0.5 second if nothing happens */        timeout = 500;        if( i_try * timeout > p_sys->i_timeout )        {            msg_Err(p_access, "no data received");            return -1;        }        if( i_try > 3 && (p_sys->i_buffer_tcp > 0 || p_sys->i_buffer_udp > 0) )        {            return -1;        }        if( !vlc_object_alive (p_access) || p_access->b_error ) return -1;        //msg_Dbg( p_access, "NetFillBuffer: trying again (select)" );    } while( !(i_ret = poll( ufd, nfd, timeout)) ||             (i_ret < 0 && errno == EINTR) );    if( i_ret < 0 )    {        msg_Err( p_access, "network poll error (%m)" );        return -1;    }    i_tcp_read = i_udp_read = 0;    if( ( i_tcp > 0 ) && ufd[0].revents )    {        i_tcp_read =            recv( p_sys->i_handle_tcp,                  p_sys->buffer_tcp + p_sys->i_buffer_tcp,                  i_tcp + MMS_BUFFER_SIZE/2, 0 );    }    if( i_udp > 0 && ufd[i_tcp > 0].revents )    {        i_udp_read = recv( p_sys->i_handle_udp,                           p_sys->buffer_udp + p_sys->i_buffer_udp,                           i_udp + MMS_BUFFER_SIZE/2, 0 );    }#ifdef MMS_DEBUG    if( p_sys->i_proto == MMS_PROTO_UDP )    {        msg_Dbg( p_access, "filling buffer TCP:%d+%d UDP:%d+%d",                 p_sys->i_buffer_tcp, i_tcp_read,                 p_sys->i_buffer_udp, i_udp_read );    }    else    {        msg_Dbg( p_access, "filling buffer TCP:%d+%d",                 p_sys->i_buffer_tcp, i_tcp_read );    }#endif    if( i_tcp_read > 0 ) p_sys->i_buffer_tcp += i_tcp_read;    if( i_udp_read > 0 ) p_sys->i_buffer_udp += i_udp_read;    return i_tcp_read + i_udp_read;#endif}static int  mms_ParseCommand( access_t *p_access,                              uint8_t *p_data,                              size_t i_data,                              int *pi_used ){ #define GET32( i_pos ) \    ( p_sys->p_cmd[i_pos] + ( p_sys->p_cmd[i_pos +1] << 8 ) + \      ( p_sys->p_cmd[i_pos + 2] << 16 ) + \      ( p_sys->p_cmd[i_pos + 3] << 24 ) )    access_sys_t        *p_sys = p_access->p_sys;    uint32_t    i_length;    uint32_t    i_id;    free( p_sys->p_cmd );    p_sys->i_cmd = i_data;    p_sys->p_cmd = malloc( i_data );    memcpy( p_sys->p_cmd, p_data, i_data );    *pi_used = i_data; /* by default */    if( i_data < MMS_CMD_HEADERSIZE )    {        msg_Warn( p_access, "truncated command (header incomplete)" );        p_sys->i_command = 0;        return -1;    }    i_id =  GetDWLE( p_data + 4 );    i_length = GetDWLE( p_data + 8 ) + 16;    if( i_id != 0xb00bface || i_length < 16 )    {        msg_Err( p_access,                 "incorrect command header (0x%"PRIx32")", i_id );        p_sys->i_command = 0;        return -1;    }    if( i_length > p_sys->i_cmd )    {        msg_Warn( p_access,                  "truncated command (missing %zu bytes)",                   (size_t)i_length - i_data  );        p_sys->i_command = 0;        return -1;    }    else if( i_length < p_sys->i_cmd )    {        p_sys->i_cmd = i_length;

⌨️ 快捷键说明

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