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

📄 mmsh.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,                "GET %s HTTP/1.0\r\n"                "Accept: */*\r\n"                "User-Agent: NSPlayer/4.1.0.3856\r\n"                "Host: %s:%d\r\n"                "Pragma: no-cache,rate=1.000000,stream-time=0,stream-offset=0:0,request-context=%d,max-duration=0\r\n"                "Pragma: xClientGUID={"GUID_FMT"}\r\n"                "Connection: Close\r\n",                ( p_sys->url.psz_path == NULL || *p_sys->url.psz_path == '\0' ) ? "/" : p_sys->url.psz_path,                p_sys->url.psz_host, p_sys->url.i_port,                p_sys->i_request_context++,                GUID_PRINT( p_sys->guid ) );    if( net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL, "\r\n" ) < 0 )    {        msg_Err( p_access, "failed to send request" );        goto error;    }    /* Receive the http header */    if( ( psz = net_Gets( VLC_OBJECT(p_access), p_sys->fd, NULL ) ) == NULL )    {        msg_Err( p_access, "failed to read answer" );        goto error;    }    if( strncmp( psz, "HTTP/1.", 7 ) )    {        msg_Err( p_access, "invalid HTTP reply '%s'", psz );        free( psz );        goto error;    }    i_code = atoi( &psz[9] );    if( i_code >= 400 )    {        msg_Err( p_access, "error: %s", psz );        free( psz );        goto error;    }    msg_Dbg( p_access, "HTTP reply '%s'", psz );    free( psz );    for( ;; )    {        char *psz = net_Gets( p_access, p_sys->fd, NULL );        char *p;        if( psz == NULL )        {            msg_Err( p_access, "failed to read answer" );            goto error;        }        if( *psz == '\0' )        {            free( psz );            break;        }        if( ( p = strchr( psz, ':' ) ) == NULL )        {            msg_Err( p_access, "malformed header line: %s", psz );            free( psz );            goto error;        }        *p++ = '\0';        while( *p == ' ' ) p++;        /* FIXME FIXME test Content-Type to see if it's a plain stream or an         * asx FIXME */        if( !strcasecmp( psz, "Pragma" ) )        {            if( strstr( p, "features" ) )            {                /* FIXME, it is a bit badly done here ..... */                if( strstr( p, "broadcast" ) )                {                    msg_Dbg( p_access, "stream type = broadcast" );                    p_sys->b_broadcast = VLC_TRUE;                }                else if( strstr( p, "seekable" ) )                {                    msg_Dbg( p_access, "stream type = seekable" );                    p_sys->b_broadcast = VLC_FALSE;                }                else                {                    msg_Warn( p_access, "unknow stream types (%s)", p );                    p_sys->b_broadcast = VLC_FALSE;                }            }        }        else if( !strcasecmp( psz, "Location" ) )        {            psz_location = strdup( p );        }        free( psz );    }    /* Handle the redirection */    if( ( i_code == 301 || i_code == 302 ||          i_code == 303 || i_code == 307 ) &&        psz_location && *psz_location )    {        msg_Dbg( p_access, "redirection to %s", psz_location );        net_Close( p_sys->fd ); p_sys->fd = -1;        *ppsz_location = psz_location;        return VLC_SUCCESS;    }    /* Read the asf header */    p_sys->i_header = 0;    p_sys->p_header = NULL;    for( ;; )    {        chunk_t ck;        if( GetPacket( p_access, &ck ) ||            (ck.i_type != 0x4824) )        {            break;        }        if( ck.i_data > 0 )        {            p_sys->i_header += ck.i_data;            p_sys->p_header = realloc( p_sys->p_header, p_sys->i_header );            memcpy( &p_sys->p_header[p_sys->i_header - ck.i_data],                    ck.p_data, ck.i_data );        }    }    msg_Dbg( p_access, "complete header size=%d", p_sys->i_header );    if( p_sys->i_header <= 0 )    {        msg_Err( p_access, "header size == 0" );        goto error;    }    /* close this connection */    net_Close( p_sys->fd ); p_sys->fd = -1;    /* *** parse header and get stream and their id *** */    /* get all streams properties,     *     * TODO : stream bitrates properties(optional)     *        and bitrate mutual exclusion(optional) */    E_( asf_HeaderParse )( &p_sys->asfh,                           p_sys->p_header, p_sys->i_header );    msg_Dbg( p_access, "packet count="I64Fd" packet size=%d",             p_sys->asfh.i_data_packets_count,             p_sys->asfh.i_min_data_packet_size );    E_( 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" ) );    return VLC_SUCCESS;error:    if( p_sys->fd > 0 )    {        net_Close( p_sys->fd  );        p_sys->fd = -1;    }    return VLC_EGENERIC;}/***************************************************************************** * *****************************************************************************/static int Start( access_t *p_access, off_t i_pos ){    access_sys_t *p_sys = p_access->p_sys;    int  i_streams = 0;    int  i;    char *psz;    msg_Dbg( p_access, "starting stream" );    if( ( p_sys->fd = net_ConnectTCP( p_access, p_sys->url.psz_host,                                      p_sys->url.i_port ) ) < 0 )    {        /* should not occur */        msg_Err( p_access, "cannot connect to the server" );        return VLC_EGENERIC;    }    for( i = 1; i < 128; i++ )    {        if( p_sys->asfh.stream[i].i_selected )        {            i_streams++;        }    }    if( i_streams <= 0 )    {        msg_Err( p_access, "no stream selected" );        return VLC_EGENERIC;    }    net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,                "GET %s HTTP/1.0\r\n"                "Accept: */*\r\n"                "User-Agent: NSPlayer/4.1.0.3856\r\n"                "Host: %s:%d\r\n",                ( p_sys->url.psz_path == NULL || *p_sys->url.psz_path == '\0' ) ? "/" : p_sys->url.psz_path,                p_sys->url.psz_host, p_sys->url.i_port );    if( p_sys->b_broadcast )    {        net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,                    "Pragma: no-cache,rate=1.000000,request-context=%d\r\n",                    p_sys->i_request_context++ );    }    else    {        net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,                    "Pragma: no-cache,rate=1.000000,stream-time=0,stream-offset=%u:%u,request-context=%d,max-duration=0\r\n",                    (uint32_t)((i_pos >> 32)&0xffffffff),                    (uint32_t)(i_pos&0xffffffff),                    p_sys->i_request_context++ );    }    net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,                "Pragma: xPlayStrm=1\r\n"                "Pragma: xClientGUID={"GUID_FMT"}\r\n"                "Pragma: stream-switch-count=%d\r\n"                "Pragma: stream-switch-entry=",                GUID_PRINT( p_sys->guid ),                i_streams);    for( i = 1; i < 128; i++ )    {        if( p_sys->asfh.stream[i].i_cat != ASF_STREAM_UNKNOWN )        {            int i_select = 2;            if( p_sys->asfh.stream[i].i_selected )            {                i_select = 0;            }            net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,                        "ffff:%d:%d ", i, i_select );        }    }    net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL, "\r\n" );    net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,                "Connection: Close\r\n" );    if( net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL, "\r\n" ) < 0 )    {        msg_Err( p_access, "failed to send request" );        return VLC_EGENERIC;    }    if( ( psz = net_Gets( VLC_OBJECT(p_access), p_sys->fd, NULL ) ) == NULL )    {        msg_Err( p_access, "cannot read data" );        return VLC_EGENERIC;    }    if( atoi( &psz[9] ) >= 400 )    {        msg_Err( p_access, "error: %s", psz );        free( psz );        return VLC_EGENERIC;    }    msg_Dbg( p_access, "HTTP reply '%s'", psz );    free( psz );    /* FIXME check HTTP code */    for( ;; )    {        char *psz = net_Gets( p_access, p_sys->fd, NULL );        if( psz == NULL )        {            msg_Err( p_access, "cannot read data" );            return VLC_EGENERIC;        }        if( *psz == '\0' )        {            free( psz );            break;        }        msg_Dbg( p_access, "%s", psz );        free( psz );    }    p_sys->i_packet_used   = 0;    p_sys->i_packet_length = 0;    return VLC_SUCCESS;}/***************************************************************************** * *****************************************************************************/static void Stop( access_t *p_access ){    access_sys_t *p_sys = p_access->p_sys;    msg_Dbg( p_access, "closing stream" );    if( p_sys->fd > 0 )    {        net_Close( p_sys->fd );        p_sys->fd = -1;    }}/***************************************************************************** * *****************************************************************************/static int GetPacket( access_t * p_access, chunk_t *p_ck ){    access_sys_t *p_sys = p_access->p_sys;    int restsize;    /* chunk_t */    memset( p_ck, 0, sizeof( chunk_t ) );    /* Read the chunk header */    /* Some headers are short, like 0x4324. Reading 12 bytes will cause us     * to lose synchronization with the stream. Just read to the length     * (4 bytes), decode and then read up to 8 additional bytes to get the     * entire header.     */    if( net_Read( p_access, p_sys->fd, NULL, p_sys->buffer, 4, VLC_TRUE ) < 4 )    {       msg_Err( p_access, "cannot read data" );       return VLC_EGENERIC;    }    p_ck->i_type = GetWLE( p_sys->buffer);    p_ck->i_size = GetWLE( p_sys->buffer + 2);    restsize = p_ck->i_size;    if( restsize > 8 )        restsize = 8;    if( net_Read( p_access, p_sys->fd, NULL, p_sys->buffer + 4, restsize, VLC_TRUE ) < restsize )    {        msg_Err( p_access, "cannot read data" );        return VLC_EGENERIC;    }    p_ck->i_sequence  = GetDWLE( p_sys->buffer + 4);    p_ck->i_unknown   = GetWLE( p_sys->buffer + 8);    /* Set i_size2 to 8 if this header was short, since a real value won't be     * present in the buffer. Using 8 avoid reading additional data for the     * packet.     */    if( restsize < 8 )        p_ck->i_size2 = 8;    else        p_ck->i_size2 = GetWLE( p_sys->buffer + 10);    p_ck->p_data      = p_sys->buffer + 12;    p_ck->i_data      = p_ck->i_size2 - 8;    if( p_ck->i_type == 0x4524 )   // Transfer complete    {        if( p_ck->i_sequence == 0 )        {            msg_Warn( p_access, "EOF" );            return VLC_EGENERIC;        }        else        {            msg_Warn( p_access, "next stream follow but not supported" );            return VLC_EGENERIC;        }    }    /* 0x4324 is CHUNK_TYPE_RESET. We can safely ignore it: a new stream will     * follow with a sequence of 0 */    else if( (p_ck->i_type != 0x4824) && (p_ck->i_type != 0x4424) &&             (p_ck->i_type != 0x4324) )    {        msg_Err( p_access, "invalid chunk FATAL (0x%x)", p_ck->i_type );        return VLC_EGENERIC;    }    if( (p_ck->i_data > 0) &&        (net_Read( p_access, p_sys->fd, NULL, &p_sys->buffer[12],                   p_ck->i_data, VLC_TRUE ) < p_ck->i_data) )    {        msg_Err( p_access, "cannot read data" );        return VLC_EGENERIC;    }    if( (p_sys->i_packet_sequence != 0) &&        (p_ck->i_sequence != p_sys->i_packet_sequence) )    {        msg_Warn( p_access, "packet lost ? (%d != %d)", p_ck->i_sequence, p_sys->i_packet_sequence );    }    p_sys->i_packet_sequence = p_ck->i_sequence + 1;    p_sys->i_packet_used   = 0;    p_sys->i_packet_length = p_ck->i_data;    p_sys->p_packet        = p_ck->p_data;    return VLC_SUCCESS;}

⌨️ 快捷键说明

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