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

📄 v4l.c

📁 VLC媒体播放程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************** * v4l.c : Video4Linux input module for vlc ***************************************************************************** * Copyright (C) 2002-2004 VideoLAN * $Id: v4l.c,v 1.41 2004/02/12 17:52:48 fenrir Exp $ * * Author: Laurent Aimar <fenrir@via.ecp.fr> *         Paul Forgey <paulf at aphrodite dot com> *         Gildas Bazin <gbazin@netcourrier.com> * * 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 <stdio.h>#include <string.h>#include <vlc/vlc.h>#include <vlc/input.h>#include <vlc/vout.h>#include <codecs.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <unistd.h>#include <sys/mman.h>#include <errno.h>#include <fcntl.h>/* From GStreamer's v4l plugin: * Because of some really cool feature in video4linux1, also known as * 'not including sys/types.h and sys/time.h', we had to include it * ourselves. In all their intelligence, these people decided to fix * this in the next version (video4linux2) in such a cool way that it * breaks all compilations of old stuff... * The real problem is actually that linux/time.h doesn't use proper * macro checks before defining types like struct timeval. The proper * fix here is to either fuck the kernel header (which is what we do * by defining _LINUX_TIME_H, an innocent little hack) or by fixing it * upstream, which I'll consider doing later on. If you get compiler * errors here, check your linux/time.h && sys/time.h header setup.*/#define _LINUX_TIME_H#include <linux/videodev.h>#include "videodev_mjpeg.h"#include <sys/soundcard.h>/***************************************************************************** * Module descriptior *****************************************************************************/static int  AccessOpen ( vlc_object_t * );static void AccessClose( vlc_object_t * );static int  DemuxOpen  ( vlc_object_t * );static void DemuxClose ( vlc_object_t * );#define CACHING_TEXT N_("Caching value in ms")#define CACHING_LONGTEXT N_( \    "Allows you to modify the default caching value for v4l streams. This " \    "value should be set in millisecond units." )#define VDEV_TEXT N_("Video device name")#define VDEV_LONGTEXT N_( \    "Specify the name of the video device that will be used. " \    "If you don't specify anything, no video device will be used.")#define ADEV_TEXT N_("Audio device name")#define ADEV_LONGTEXT N_( \    "Specify the name of the audio device that will be used. " \    "If you don't specify anything, no audio device will be used.")#define CHROMA_TEXT N_("Video input chroma format")#define CHROMA_LONGTEXT N_( \    "Force the Video4Linux video device to use a specific chroma format " \    "(eg. I420 (default), RV24, etc.)")vlc_module_begin();    set_description( _("Video4Linux input") );    add_integer( "v4l-caching", DEFAULT_PTS_DELAY / 1000, NULL,                 CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE );    add_string( "v4l-vdev", "/dev/video", 0, VDEV_TEXT, VDEV_LONGTEXT,                VLC_FALSE );    add_string( "v4l-adev", "/dev/dsp", 0, ADEV_TEXT, ADEV_LONGTEXT,                VLC_FALSE );    add_string( "v4l-chroma", NULL, NULL, CHROMA_TEXT, CHROMA_LONGTEXT,                VLC_TRUE );    add_shortcut( "v4l" );    set_capability( "access", 10 );    set_callbacks( AccessOpen, AccessClose );    add_submodule();        set_description( _("Video4Linux demuxer") );        add_shortcut( "v4l" );        set_capability( "demux", 200 );        set_callbacks( DemuxOpen, DemuxClose );vlc_module_end();/***************************************************************************** * Access: local prototypes *****************************************************************************/static int  Read        ( input_thread_t *, byte_t *, size_t );static void ParseMRL    ( input_thread_t * );static int  OpenVideoDev( input_thread_t *, char * );static int  OpenAudioDev( input_thread_t *, char * );#define MJPEG_BUFFER_SIZE (256*1024)struct quicktime_mjpeg_app1{    uint32_t    i_reserved;             /* set to 0 */    uint32_t    i_tag;                  /* 'mjpg' */    uint32_t    i_field_size;           /* offset following EOI */    uint32_t    i_padded_field_size;    /* offset following EOI+pad */    uint32_t    i_next_field;           /* offset to next field */    uint32_t    i_DQT_offset;    uint32_t    i_DHT_offset;    uint32_t    i_SOF_offset;    uint32_t    i_SOS_offset;    uint32_t    i_data_offset;          /* following SOS marker data */};static struct{    int i_v4l;    int i_fourcc;} v4lchroma_to_fourcc[] ={    { VIDEO_PALETTE_GREY, VLC_FOURCC( 'G', 'R', 'E', 'Y' ) },    { VIDEO_PALETTE_HI240, VLC_FOURCC( 'I', '2', '4', '0' ) },    { VIDEO_PALETTE_RGB565, VLC_FOURCC( 'R', 'V', '1', '6' ) },    { VIDEO_PALETTE_RGB555, VLC_FOURCC( 'R', 'V', '1', '5' ) },    { VIDEO_PALETTE_RGB24, VLC_FOURCC( 'R', 'V', '2', '4' ) },    { VIDEO_PALETTE_RGB32, VLC_FOURCC( 'R', 'V', '3', '2' ) },    { VIDEO_PALETTE_YUV422, VLC_FOURCC( 'I', '4', '2', '2' ) },    { VIDEO_PALETTE_YUYV, VLC_FOURCC( 'Y', 'U', 'Y', 'V' ) },    { VIDEO_PALETTE_UYVY, VLC_FOURCC( 'U', 'Y', 'V', 'Y' ) },    { VIDEO_PALETTE_YUV420, VLC_FOURCC( 'I', '4', '2', 'N' ) },    { VIDEO_PALETTE_YUV411, VLC_FOURCC( 'I', '4', '1', 'N' ) },    { VIDEO_PALETTE_RAW, VLC_FOURCC( 'G', 'R', 'A', 'W' ) },    { VIDEO_PALETTE_YUV422P, VLC_FOURCC( 'I', '4', '2', '2' ) },    { VIDEO_PALETTE_YUV420P, VLC_FOURCC( 'I', '4', '2', '0' ) },    { VIDEO_PALETTE_YUV411P, VLC_FOURCC( 'I', '4', '1', '1' ) },    { 0, 0 }};struct access_sys_t{    /* Devices */    char *psz_device;         /* Main device from MRL, can be video or audio */    char *psz_vdev;    int  fd_video;    char *psz_adev;    int  fd_audio;    /* Video properties */    picture_t pic;    int i_fourcc;    int i_channel;    int i_audio;    int i_norm;    int i_tuner;    int i_frequency;    int i_width;    int i_height;    int i_brightness;    int i_hue;    int i_colour;    int i_contrast;    float f_fps;            /* <= 0.0 mean to grab at full rate */    mtime_t i_video_pts;    /* only used when f_fps > 0 */    vlc_bool_t b_mjpeg;    int i_decimation;    int i_quality;    struct video_capability vid_cap;    struct video_mbuf       vid_mbuf;    struct mjpeg_requestbuffers mjpeg_buffers;    uint8_t *p_video_mmap;    int     i_frame_pos;    struct video_mmap   vid_mmap;    struct video_picture vid_picture;    uint8_t *p_video_frame;    int     i_video_frame_size;    int     i_video_frame_size_allocated;    /* Audio properties */    vlc_fourcc_t i_acodec_raw;    int          i_sample_rate;    vlc_bool_t   b_stereo;    uint8_t *p_audio_frame;    int     i_audio_frame_size;    int     i_audio_frame_size_allocated;    /* header */    int     i_streams;    int     i_header_size;    int     i_header_pos;    uint8_t *p_header;      // at lest 8 bytes allocated    /* data */    int     i_data_size;    int     i_data_pos;    uint8_t *p_data;        // never allocated};/* * header: *  fcc  ".v4l" *  u32    stream count *      fcc "auds"|"vids"       0 *      fcc codec               4 *      if vids *          u32 width           8 *          u32 height          12 *          u32 padding         16 *      if auds *          u32 channels        12 *          u32 samplerate      8 *          u32 samplesize      16 * * data: *  u32     stream number *  u32     data size *  u8      data */static void SetDWBE( uint8_t *p, uint32_t dw ){    p[0] = (dw >> 24)&0xff;    p[1] = (dw >> 16)&0xff;    p[2] = (dw >>  8)&0xff;    p[3] = (dw      )&0xff;}static void SetQWBE( uint8_t *p, uint64_t qw ){    SetDWBE( p,     (qw >> 32)&0xffffffff );    SetDWBE( &p[4], qw&0xffffffff);}/***************************************************************************** * AccessOpen: opens v4l device ***************************************************************************** * * url: <video device>:::: * *****************************************************************************/static int AccessOpen( vlc_object_t *p_this ){    input_thread_t *p_input = (input_thread_t *)p_this;    access_sys_t   *p_sys;    vlc_value_t    val;    /* create access private data */    p_input->p_access_data = p_sys = malloc( sizeof( access_sys_t ) );    memset( p_sys, 0, sizeof( access_sys_t ) );    p_sys->i_audio          = -1;    p_sys->i_norm           = VIDEO_MODE_AUTO;    // auto    p_sys->i_tuner          = -1;    p_sys->i_frequency      = -1;    p_sys->f_fps            = -1.0;    p_sys->i_video_pts      = -1;    p_sys->i_brightness     = -1;    p_sys->i_hue            = -1;    p_sys->i_colour         = -1;    p_sys->i_contrast       = -1;    p_sys->b_mjpeg     = VLC_FALSE;    p_sys->i_decimation = 1;    p_sys->i_quality = 100;    p_sys->i_video_frame_size_allocated = 0;    p_sys->i_frame_pos = 0;    p_sys->p_audio_frame  = 0;    p_sys->i_sample_rate  = 44100;    p_sys->b_stereo       = VLC_TRUE;    p_sys->p_header    = NULL;    p_sys->i_data_size = 0;    p_sys->i_data_pos  = 0;    p_sys->p_data      = NULL;    p_sys->psz_device = p_sys->psz_vdev = p_sys->psz_adev = NULL;    p_sys->fd_video = -1;    p_sys->fd_audio = -1;    ParseMRL( p_input );    /* Find main device (video or audio) */    if( p_sys->psz_device && *p_sys->psz_device )    {        msg_Dbg( p_input, "main device=`%s'", p_sys->psz_device );        /* Try to open as video device */        p_sys->fd_video = OpenVideoDev( p_input, p_sys->psz_device );        if( p_sys->fd_video < 0 )        {            /* Try to open as audio device */            p_sys->fd_audio = OpenAudioDev( p_input, p_sys->psz_device );            if( p_sys->fd_audio >= 0 )            {                if( p_sys->psz_adev ) free( p_sys->psz_adev );                p_sys->psz_adev = p_sys->psz_device;                p_sys->psz_device = NULL;            }        }        else        {            if( p_sys->psz_vdev ) 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( !p_input->psz_access ||            strcmp( p_input->psz_access, "v4l" ) )        {            AccessClose( p_this );            return VLC_EGENERIC;        }    }    /* Find video device */    if( p_sys->fd_video < 0 )    {        if( !p_sys->psz_vdev || !*p_sys->psz_vdev )        {            var_Create( p_input, "v4l-vdev",                        VLC_VAR_STRING | VLC_VAR_DOINHERIT );            var_Get( p_input, "v4l-vdev", &val );            if( p_sys->psz_vdev ) free( p_sys->psz_vdev );            p_sys->psz_vdev = val.psz_string;        }        if( p_sys->psz_vdev && *p_sys->psz_vdev )        {            p_sys->fd_video = OpenVideoDev( p_input, p_sys->psz_vdev );        }    }    /* Find audio device */    if( p_sys->fd_audio < 0 )    {        if( !p_sys->psz_adev || !*p_sys->psz_adev )        {            var_Create( p_input, "v4l-adev",                        VLC_VAR_STRING | VLC_VAR_DOINHERIT );            var_Get( p_input, "v4l-adev", &val );            if( p_sys->psz_adev ) free( p_sys->psz_adev );            p_sys->psz_adev = val.psz_string;        }        if( p_sys->psz_adev && *p_sys->psz_adev )        {            p_sys->fd_audio = OpenAudioDev( p_input, p_sys->psz_adev );        }    }    if( p_sys->fd_video < 0 && p_sys->fd_audio < 0 )    {        AccessClose( p_this );        return VLC_EGENERIC;    }    p_input->pf_read        = Read;    p_input->pf_seek        = NULL;    p_input->pf_set_area    = NULL;    p_input->pf_set_program = NULL;    vlc_mutex_lock( &p_input->stream.stream_lock );    p_input->stream.b_pace_control = 0;    p_input->stream.b_seekable = 0;    p_input->stream.p_selected_area->i_size = 0;    p_input->stream.p_selected_area->i_tell = 0;    p_input->stream.i_method = INPUT_METHOD_FILE;    vlc_mutex_unlock( &p_input->stream.stream_lock );    /* Update default_pts to a suitable value for access */    var_Create( p_input, "v4l-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);    var_Get( p_input, "v4l-caching", &val );    p_input->i_pts_delay = val.i_int * 1000;    msg_Info( p_input, "v4l grabbing started" );    /* create header */    p_sys->i_streams     = 0;    p_sys->i_header_size = 8;    p_sys->i_header_pos  = 8;    p_sys->p_header      = malloc( p_sys->i_header_size );

⌨️ 快捷键说明

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