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

📄 v4l.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
                                    VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );    var_Get( p_demux, "v4l-samplerate", &val );    p_sys->i_sample_rate  = val.i_int;    var_Create( p_demux, "v4l-stereo", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );    var_Get( p_demux, "v4l-stereo", &val );    p_sys->b_stereo       = val.b_bool;    p_sys->psz_device = p_sys->psz_vdev = p_sys->psz_adev = NULL;    p_sys->fd_video = -1;    p_sys->fd_audio = -1;    p_sys->p_es_video = p_sys->p_es_audio = 0;    p_sys->p_block_audio = 0;    ParseMRL( p_demux );    /* Find main device (video or audio) */    if( p_sys->psz_device && *p_sys->psz_device )    {        msg_Dbg( p_demux, "main device=`%s'", p_sys->psz_device );        /* Try to open as video device */        p_sys->fd_video = OpenVideoDev( p_demux, p_sys->psz_device );        if( p_sys->fd_video < 0 )        {            /* Try to open as audio device */            p_sys->fd_audio = OpenAudioDev( p_demux, p_sys->psz_device );            if( p_sys->fd_audio >= 0 )            {                free( p_sys->psz_adev );                p_sys->psz_adev = p_sys->psz_device;                p_sys->psz_device = NULL;            }        }        else        {            free( p_sys->psz_vdev );            p_sys->psz_vdev = p_sys->psz_device;            p_sys->psz_device = NULL;        }    }    /* If no device opened, only continue if the access was forced */    if( p_sys->fd_video < 0 && p_sys->fd_audio < 0 )    {        if( strcmp( p_demux->psz_access, "v4l" ) )        {            Close( p_this );            return VLC_EGENERIC;        }    }    /* Find video device */    if( p_sys->fd_video < 0 )    {        if( !p_sys->psz_vdev || !*p_sys->psz_vdev )        {            free( p_sys->psz_vdev );            p_sys->psz_vdev = var_CreateGetString( p_demux, "v4l-vdev" );;        }        if( p_sys->psz_vdev && *p_sys->psz_vdev )        {            p_sys->fd_video = OpenVideoDev( p_demux, p_sys->psz_vdev );        }    }    /* Find audio device */    if( p_sys->fd_audio < 0 )    {        if( !p_sys->psz_adev || !*p_sys->psz_adev )        {            free( p_sys->psz_adev );            p_sys->psz_adev = var_CreateGetString( p_demux, "v4l-adev" );;        }        if( p_sys->psz_adev && *p_sys->psz_adev )        {            p_sys->fd_audio = OpenAudioDev( p_demux, p_sys->psz_adev );        }    }    if( p_sys->fd_video < 0 && p_sys->fd_audio < 0 )    {        Close( p_this );        return VLC_EGENERIC;    }    msg_Dbg( p_demux, "v4l grabbing started" );    /* Declare elementary streams */    if( p_sys->fd_video >= 0 )    {        es_format_t fmt;        es_format_Init( &fmt, VIDEO_ES, p_sys->i_fourcc );        fmt.video.i_width  = p_sys->i_width;        fmt.video.i_height = p_sys->i_height;        fmt.video.i_aspect = 4 * VOUT_ASPECT_FACTOR / 3;        /* Setup rgb mask for RGB formats */        switch( p_sys->i_fourcc )        {            case VLC_FOURCC('R','V','1','5'):                fmt.video.i_rmask = 0x001f;                fmt.video.i_gmask = 0x03e0;                fmt.video.i_bmask = 0x7c00;                break;            case VLC_FOURCC('R','V','1','6'):                fmt.video.i_rmask = 0x001f;                fmt.video.i_gmask = 0x07e0;                fmt.video.i_bmask = 0xf800;                break;            case VLC_FOURCC('R','V','2','4'):            case VLC_FOURCC('R','V','3','2'):                fmt.video.i_rmask = 0x00ff0000;                fmt.video.i_gmask = 0x0000ff00;                fmt.video.i_bmask = 0x000000ff;                break;        }        msg_Dbg( p_demux, "added new video es %4.4s %dx%d",                 (char*)&fmt.i_codec, fmt.video.i_width, fmt.video.i_height );        p_sys->p_es_video = es_out_Add( p_demux->out, &fmt );    }    if( p_sys->fd_audio >= 0 )    {        es_format_t fmt;        es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC('a','r','a','w') );        fmt.audio.i_channels = p_sys->b_stereo ? 2 : 1;        fmt.audio.i_rate = p_sys->i_sample_rate;        fmt.audio.i_bitspersample = 16; // FIXME ?        fmt.audio.i_blockalign = fmt.audio.i_channels *            fmt.audio.i_bitspersample / 8;        fmt.i_bitrate = fmt.audio.i_channels * fmt.audio.i_rate *            fmt.audio.i_bitspersample;        msg_Dbg( p_demux, "new audio es %d channels %dHz",                 fmt.audio.i_channels, fmt.audio.i_rate );        p_sys->p_es_audio = es_out_Add( p_demux->out, &fmt );    }    /* Update default_pts to a suitable value for access */    var_Create( p_demux, "v4l-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );    return VLC_SUCCESS;}/***************************************************************************** * Close: close device, free resources *****************************************************************************/static void Close( vlc_object_t *p_this ){    demux_t     *p_demux = (demux_t *)p_this;    demux_sys_t *p_sys   = p_demux->p_sys;    free( p_sys->psz_device );    free( p_sys->psz_vdev );    free( p_sys->psz_adev );    if( p_sys->fd_video >= 0 ) close( p_sys->fd_video );    if( p_sys->fd_audio >= 0 ) close( p_sys->fd_audio );    if( p_sys->p_block_audio ) block_Release( p_sys->p_block_audio );    if( p_sys->b_mjpeg )    {        int i_noframe = -1;        ioctl( p_sys->fd_video, MJPIOC_QBUF_CAPT, &i_noframe );    }    if( p_sys->p_video_mmap && p_sys->p_video_mmap != MAP_FAILED )    {        if( p_sys->b_mjpeg )            munmap( p_sys->p_video_mmap, p_sys->mjpeg_buffers.size *                    p_sys->mjpeg_buffers.count );        else            munmap( p_sys->p_video_mmap, p_sys->vid_mbuf.size );    }    free( p_sys );}/***************************************************************************** * Control: *****************************************************************************/static int Control( demux_t *p_demux, int i_query, va_list args ){    bool *pb;    int64_t    *pi64;    switch( i_query )    {        /* Special for access_demux */        case DEMUX_CAN_PAUSE:        case DEMUX_CAN_SEEK:        case DEMUX_SET_PAUSE_STATE:        case DEMUX_CAN_CONTROL_PACE:            pb = (bool*)va_arg( args, bool * );            *pb = false;            return VLC_SUCCESS;        case DEMUX_GET_PTS_DELAY:            pi64 = (int64_t*)va_arg( args, int64_t * );            *pi64 = (int64_t)var_GetInteger( p_demux, "v4l-caching" ) * 1000;            return VLC_SUCCESS;        case DEMUX_GET_TIME:            pi64 = (int64_t*)va_arg( args, int64_t * );            *pi64 = mdate();            return VLC_SUCCESS;        /* TODO implement others */        default:            return VLC_EGENERIC;    }    return VLC_EGENERIC;}/***************************************************************************** * Demux: *****************************************************************************/static int Demux( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    es_out_id_t  *p_es = p_sys->p_es_audio;    block_t *p_block = NULL;    /* Try grabbing audio frames first */    if( p_sys->fd_audio < 0 || !( p_block = GrabAudio( p_demux ) ) )    {        /* Try grabbing video frame */        p_es = p_sys->p_es_video;        if( p_sys->fd_video > 0 ) p_block = GrabVideo( p_demux );    }    if( !p_block )    {        /* Sleep so we do not consume all the cpu, 10ms seems         * like a good value (100fps) */        msleep( 10000 );        return 1;    }    es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts );    es_out_Send( p_demux->out, p_es, p_block );    return 1;}/***************************************************************************** * ParseMRL: parse the options contained in the MRL *****************************************************************************/static void ParseMRL( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    char *psz_dup = strdup( p_demux->psz_path );    char *psz_parser = psz_dup;    while( *psz_parser && *psz_parser != ':' )    {        psz_parser++;    }    if( *psz_parser == ':' )    {        /* read options */        for( ;; )        {            *psz_parser++ = '\0';            if( !strncmp( psz_parser, "channel=", strlen( "channel=" ) ) )            {                p_sys->i_channel = strtol( psz_parser + strlen( "channel=" ),                                           &psz_parser, 0 );            }            else if( !strncmp( psz_parser, "norm=", strlen( "norm=" ) ) )            {                psz_parser += strlen( "norm=" );                if( !strncmp( psz_parser, "pal", strlen( "pal" ) ) )                {                    p_sys->i_norm = VIDEO_MODE_PAL;                    psz_parser += strlen( "pal" );                }                else if( !strncmp( psz_parser, "ntsc", strlen( "ntsc" ) ) )                {                    p_sys->i_norm = VIDEO_MODE_NTSC;                    psz_parser += strlen( "ntsc" );                }                else if( !strncmp( psz_parser, "secam", strlen( "secam" ) ) )                {                    p_sys->i_norm = VIDEO_MODE_SECAM;                    psz_parser += strlen( "secam" );                }                else if( !strncmp( psz_parser, "auto", strlen( "auto" ) ) )                {                    p_sys->i_norm = VIDEO_MODE_AUTO;                    psz_parser += strlen( "auto" );                }                else                {                    p_sys->i_norm = strtol( psz_parser, &psz_parser, 0 );                }            }            else if( !strncmp( psz_parser, "frequency=",                               strlen( "frequency=" ) ) )            {                p_sys->i_frequency =                    strtol( psz_parser + strlen( "frequency=" ),                            &psz_parser, 0 );                if( p_sys->i_frequency < 30000 )                {                    msg_Warn( p_demux, "v4l syntax has changed : "                              "'frequency' is now channel frequency in kHz");                }            }            else if( !strncmp( psz_parser, "audio=", strlen( "audio=" ) ) )            {                p_sys->i_audio = strtol( psz_parser + strlen( "audio=" ),                                         &psz_parser, 0 );            }            else if( !strncmp( psz_parser, "size=", strlen( "size=" ) ) )            {                psz_parser += strlen( "size=" );                if( !strncmp( psz_parser, "subqcif", strlen( "subqcif" ) ) )                {                    p_sys->i_width  = 128;                    p_sys->i_height = 96;                }                else if( !strncmp( psz_parser, "qsif", strlen( "qsif" ) ) )                {                    p_sys->i_width  = 160;                    p_sys->i_height = 120;                }                else if( !strncmp( psz_parser, "qcif", strlen( "qcif" ) ) )                {                    p_sys->i_width  = 176;                    p_sys->i_height = 144;                }                else if( !strncmp( psz_parser, "sif", strlen( "sif" ) ) )                {                    p_sys->i_width  = 320;                    p_sys->i_height = 244;                }                else if( !strncmp( psz_parser, "cif", strlen( "cif" ) ) )                {                    p_sys->i_width  = 352;                    p_sys->i_height = 288;                }                else if( !strncmp( psz_parser, "vga", strlen( "vga" ) ) )                {                    p_sys->i_width  = 640;                    p_sys->i_height = 480;                }                else                {                    /* widthxheight */                    p_sys->i_width = strtol( psz_parser, &psz_parser, 0 );                    if( *psz_parser == 'x' || *psz_parser == 'X')                    {                        p_sys->i_height = strtol( psz_parser + 1,                                                  &psz_parser, 0 );                    }                    msg_Dbg( p_demux, "WxH %dx%d", p_sys->i_width,                             p_sys->i_height );                }            }            else if( !strncmp( psz_parser, "brightness=", strlen( "brightness=" ) ) )            {                p_sys->i_brightness = strtol( psz_parser + strlen( "brightness=" ),                                              &psz_parser, 0 );            }            else if( !strncmp( psz_parser, "colour=", strlen( "colour=" ) ) )            {                p_sys->i_colour = strtol( psz_parser + strlen( "colour=" ),                                          &psz_parser, 0 );            }            else if( !strncmp( psz_parser, "hue=", strlen( "hue=" ) ) )            {                p_sys->i_hue = strtol( psz_parser + strlen( "hue=" ),                                       &psz_parser, 0 );            }            else if( !strncmp( psz_parser, "contrast=", strlen( "contrast=" ) ) )            {                p_sys->i_contrast = strtol( psz_parser + strlen( "contrast=" ),                                            &psz_parser, 0 );            }            else if( !strncmp( psz_parser, "tuner=", strlen( "tuner=" ) ) )            {                p_sys->i_tuner = strtol( psz_parser + strlen( "tuner=" ),                                         &psz_parser, 0 );            }            else if( !strncmp( psz_parser, "adev=", strlen( "adev=" ) ) )            {                int  i_len;                psz_parser += strlen( "adev=" );                if( strchr( psz_parser, ':' ) )                {                    i_len = strchr( psz_parser, ':' ) - psz_parser;

⌨️ 快捷键说明

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