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

📄 mmsh.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * mmsh.c: ***************************************************************************** * Copyright (C) 2001, 2002 VideoLAN * $Id: mmsh.c 10101 2005-03-02 16:47:31Z robux4 $ * * Authors: Laurent Aimar <fenrir@via.ecp.fr> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include <stdlib.h>#include <vlc/vlc.h>#include <vlc/input.h>#include "vlc_playlist.h"#include "network.h"#include "asf.h"#include "buffer.h"#include "mms.h"#include "mmsh.h"/* TODO: *  - http_proxy *  - authentication *//***************************************************************************** * Local prototypes *****************************************************************************/int  E_(MMSHOpen)  ( access_t * );void E_(MMSHClose) ( access_t * );static int  Read( access_t *, uint8_t *, int );static int  ReadRedirect( access_t *, uint8_t *, int );static int  Seek( access_t *, int64_t );static int  Control( access_t *, int, va_list );static int  Describe( access_t  *, char **ppsz_location );static int  Start( access_t *, int64_t );static void Stop( access_t * );static int  GetPacket( access_t *, chunk_t * );/**************************************************************************** * Open: connect to ftp server and ask for file ****************************************************************************/int E_(MMSHOpen)( access_t *p_access ){    access_sys_t    *p_sys;    char            *psz_location = NULL;    /* init p_sys */    /* Set up p_access */    p_access->pf_read = Read;    p_access->pf_block = NULL;    p_access->pf_control = Control;    p_access->pf_seek = Seek;    p_access->info.i_update = 0;    p_access->info.i_size = 0;    p_access->info.i_pos = 0;    p_access->info.b_eof = VLC_FALSE;    p_access->info.i_title = 0;    p_access->info.i_seekpoint = 0;    p_access->p_sys = p_sys = malloc( sizeof( access_sys_t ) );    memset( p_sys, 0, sizeof( access_sys_t ) );    p_sys->i_proto= MMS_PROTO_HTTP;    p_sys->fd     = -1;    p_sys->i_start= 0;    /* open a tcp connection */    vlc_UrlParse( &p_sys->url, p_access->psz_path, 0 );    if( p_sys->url.psz_host == NULL || *p_sys->url.psz_host == '\0' )    {        msg_Err( 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 = 80;    if( Describe( p_access, &psz_location ) )    {        vlc_UrlClean( &p_sys->url );        free( p_sys );        return VLC_EGENERIC;    }    /* Handle redirection */    if( psz_location && *psz_location )    {        playlist_t * p_playlist = vlc_object_find( p_access, VLC_OBJECT_PLAYLIST, FIND_PARENT );        msg_Dbg( p_access, "redirection to %s", psz_location );        if( !p_playlist )        {            msg_Err( p_access, "redirection failed: can't find playlist" );            free( psz_location );            return VLC_EGENERIC;        }        p_playlist->pp_items[p_playlist->i_index]->b_autodeletion = VLC_TRUE;        playlist_Add( p_playlist, psz_location, psz_location,                      PLAYLIST_INSERT | PLAYLIST_GO,                      p_playlist->i_index + 1 );        vlc_object_release( p_playlist );        free( psz_location );        p_access->pf_read = ReadRedirect;        return VLC_SUCCESS;    }    /* Start playing */    if( Start( p_access, 0 ) )    {        msg_Err( p_access, "cannot start stream" );        free( p_sys->p_header );        vlc_UrlClean( &p_sys->url );        free( p_sys );        return VLC_EGENERIC;    }    if( !p_sys->b_broadcast )    {        p_access->info.i_size = p_sys->asfh.i_file_size;    }    return VLC_SUCCESS;}/***************************************************************************** * Close: free unused data structures *****************************************************************************/void E_( MMSHClose )( access_t *p_access ){    access_sys_t *p_sys = p_access->p_sys;    Stop( p_access );    free( p_sys );}/***************************************************************************** * Control: *****************************************************************************/static int Control( access_t *p_access, int i_query, va_list args ){    access_sys_t *p_sys = p_access->p_sys;    vlc_bool_t   *pb_bool;    int          *pi_int;    int64_t      *pi_64;    int          i_int;    switch( i_query )    {        /* */        case ACCESS_CAN_SEEK:            pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );            *pb_bool = !p_sys->b_broadcast;            break;        case ACCESS_CAN_FASTSEEK:        case ACCESS_CAN_PAUSE:            pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );            *pb_bool = VLC_FALSE;            break;        case ACCESS_CAN_CONTROL_PACE:            pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );#if 0       /* Disable for now until we have a clock synchro algo             * which works with something else than MPEG over UDP */            *pb_bool = VLC_FALSE;#endif            *pb_bool = VLC_TRUE;            break;        /* */        case ACCESS_GET_MTU:            pi_int = (int*)va_arg( args, int * );            *pi_int = 3 * p_sys->asfh.i_min_data_packet_size;            break;        case ACCESS_GET_PTS_DELAY:            pi_64 = (int64_t*)va_arg( args, int64_t * );            *pi_64 = (int64_t)var_GetInteger( p_access, "mms-caching" ) * I64C(1000);            break;        case ACCESS_GET_PRIVATE_ID_STATE:            i_int = (int)va_arg( args, int );            pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t );            if( i_int < 0 || i_int > 127 )                return VLC_EGENERIC;            *pb_bool =  p_sys->asfh.stream[i_int].i_selected ? VLC_TRUE : VLC_FALSE;            break;        /* */        case ACCESS_SET_PAUSE_STATE:        case ACCESS_GET_TITLE_INFO:        case ACCESS_SET_TITLE:        case ACCESS_SET_SEEKPOINT:        case ACCESS_SET_PRIVATE_ID_STATE:            return VLC_EGENERIC;        default:            msg_Warn( p_access, "unimplemented query in control" );            return VLC_EGENERIC;    }    return VLC_SUCCESS;}/***************************************************************************** * Seek: try to go at the right place *****************************************************************************/static int Seek( access_t *p_access, int64_t i_pos ){    access_sys_t *p_sys = p_access->p_sys;    chunk_t      ck;    off_t        i_offset;    off_t        i_packet;    msg_Dbg( p_access, "seeking to "I64Fd, i_pos );    i_packet = ( i_pos - p_sys->i_header ) / p_sys->asfh.i_min_data_packet_size;    i_offset = ( i_pos - p_sys->i_header ) % p_sys->asfh.i_min_data_packet_size;    Stop( p_access );    Start( p_access, i_packet * p_sys->asfh.i_min_data_packet_size );    while( !p_access->b_die )    {        if( GetPacket( p_access, &ck ) )            break;        /* skip headers */        if( ck.i_type != 0x4824 )            break;        msg_Warn( p_access, "skipping header" );    }    p_access->info.i_pos = i_pos;    p_access->info.b_eof = VLC_FALSE;    p_sys->i_packet_used += i_offset;    return VLC_SUCCESS;}/***************************************************************************** * Read: *****************************************************************************/static int ReadRedirect( access_t *p_access, uint8_t *p, int i_len ){    return 0;}/***************************************************************************** * Read: *****************************************************************************/static int Read( access_t *p_access, uint8_t *p_buffer, int i_len ){    access_sys_t *p_sys = p_access->p_sys;    size_t       i_copy;    size_t       i_data = 0;    if( p_access->info.b_eof )        return 0;    while( i_data < i_len )    {        if( p_access->info.i_pos < p_sys->i_start + p_sys->i_header )        {            int i_offset = p_access->info.i_pos - p_sys->i_start;            i_copy = __MIN( p_sys->i_header - i_offset, i_len - i_data );            memcpy( &p_buffer[i_data], &p_sys->p_header[i_offset], i_copy );            i_data += i_copy;            p_access->info.i_pos += i_copy;        }        else if( p_sys->i_packet_used < p_sys->i_packet_length )        {            i_copy = __MIN( p_sys->i_packet_length - p_sys->i_packet_used,                            i_len - i_data );            memcpy( &p_buffer[i_data],                    &p_sys->p_packet[p_sys->i_packet_used],                    i_copy );            i_data += i_copy;            p_sys->i_packet_used += i_copy;            p_access->info.i_pos += i_copy;        }        else if( p_sys->i_packet_length > 0 &&                 (int)p_sys->i_packet_used < p_sys->asfh.i_min_data_packet_size )        {            i_copy = __MIN( p_sys->asfh.i_min_data_packet_size - p_sys->i_packet_used,                            i_len - i_data );            memset( &p_buffer[i_data], 0, i_copy );            i_data += i_copy;            p_sys->i_packet_used += i_copy;            p_access->info.i_pos += i_copy;        }        else        {            chunk_t ck;            if( GetPacket( p_access, &ck ) )            {                if( ck.i_type == 0x4524 && ck.i_sequence != 0 && p_sys->b_broadcast )                {                    char *psz_location = NULL;                    p_sys->i_start = p_access->info.i_pos;                    msg_Dbg( p_access, "stoping the stream" );                    Stop( p_access );                    msg_Dbg( p_access, "describe the stream" );                    if( Describe( p_access, &psz_location ) )                    {                        msg_Err( p_access, "describe failed" );                        p_access->info.b_eof = VLC_TRUE;                        return 0;                    }                    if( Start( p_access, 0 ) )                    {                        msg_Err( p_access, "Start failed" );                        p_access->info.b_eof = VLC_TRUE;                        return 0;                    }                }                else                {                    p_access->info.b_eof = VLC_TRUE;                    return 0;                }            }            if( ck.i_type != 0x4424 )            {                p_sys->i_packet_used = 0;                p_sys->i_packet_length = 0;            }        }    }    return( i_data );}/***************************************************************************** * Describe: *****************************************************************************/static int Describe( access_t  *p_access, char **ppsz_location ){    access_sys_t *p_sys = p_access->p_sys;    char         *psz_location = NULL;    char         *psz;    int          i_code;    /* Reinit context */    p_sys->b_broadcast = VLC_TRUE;    p_sys->i_request_context = 1;    p_sys->i_packet_sequence = 0;    p_sys->i_packet_used = 0;

⌨️ 快捷键说明

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