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

📄 v4l.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
                }                else                {                    i_len = strlen( psz_parser );                }                p_sys->psz_adev = strndup( psz_parser, i_len );                psz_parser += i_len;            }            else if( !strncmp( psz_parser, "samplerate=",                               strlen( "samplerate=" ) ) )            {                p_sys->i_sample_rate =                    strtol( psz_parser + strlen( "samplerate=" ),                            &psz_parser, 0 );            }            else if( !strncmp( psz_parser, "stereo", strlen( "stereo" ) ) )            {                psz_parser += strlen( "stereo" );                p_sys->b_stereo = true;            }            else if( !strncmp( psz_parser, "mono", strlen( "mono" ) ) )            {                psz_parser += strlen( "mono" );                p_sys->b_stereo = false;            }            else if( !strncmp( psz_parser, "mjpeg", strlen( "mjpeg" ) ) )            {                psz_parser += strlen( "mjpeg" );                p_sys->b_mjpeg = true;            }            else if( !strncmp( psz_parser, "decimation=",                        strlen( "decimation=" ) ) )            {                p_sys->i_decimation =                    strtol( psz_parser + strlen( "decimation=" ),                            &psz_parser, 0 );            }            else if( !strncmp( psz_parser, "quality=",                        strlen( "quality=" ) ) )            {                p_sys->i_quality =                    strtol( psz_parser + strlen( "quality=" ),                            &psz_parser, 0 );            }            else if( !strncmp( psz_parser, "fps=", strlen( "fps=" ) ) )            {                p_sys->f_fps = strtof( psz_parser + strlen( "fps=" ),                                       &psz_parser );            }            else            {                msg_Warn( p_demux, "unknown option" );            }            while( *psz_parser && *psz_parser != ':' )            {                psz_parser++;            }            if( *psz_parser == '\0' )            {                break;            }        }    }    if( *psz_dup )    {        p_sys->psz_device = strdup( psz_dup );    }    free( psz_dup );}/***************************************************************************** * OpenVideoDev: *****************************************************************************/static int OpenVideoDev( demux_t *p_demux, char *psz_device ){    demux_sys_t *p_sys = p_demux->p_sys;    int i_fd;    struct video_channel vid_channel;    struct mjpeg_params mjpeg;    int i;    if( ( i_fd = open( psz_device, O_RDWR ) ) < 0 )    {        msg_Err( p_demux, "cannot open device (%m)" );        goto vdev_failed;    }    if( ioctl( i_fd, VIDIOCGCAP, &p_sys->vid_cap ) < 0 )    {        msg_Err( p_demux, "cannot get capabilities (%m)" );        goto vdev_failed;    }    msg_Dbg( p_demux,             "V4L device %s %d channels %d audios %d < w < %d %d < h < %d",             p_sys->vid_cap.name,             p_sys->vid_cap.channels,             p_sys->vid_cap.audios,             p_sys->vid_cap.minwidth,  p_sys->vid_cap.maxwidth,             p_sys->vid_cap.minheight, p_sys->vid_cap.maxheight );    if( p_sys->i_channel < 0 || p_sys->i_channel >= p_sys->vid_cap.channels )    {        msg_Dbg( p_demux, "invalid channel, falling back on channel 0" );        p_sys->i_channel = 0;    }    if( p_sys->vid_cap.audios && p_sys->i_audio >= p_sys->vid_cap.audios )    {        msg_Dbg( p_demux, "invalid audio, falling back with no audio" );        p_sys->i_audio = -1;    }    if( p_sys->i_width < p_sys->vid_cap.minwidth ||        p_sys->i_width > p_sys->vid_cap.maxwidth )    {        msg_Dbg( p_demux, "invalid width %i", p_sys->i_width );        p_sys->i_width = 0;    }    if( p_sys->i_height < p_sys->vid_cap.minheight ||        p_sys->i_height > p_sys->vid_cap.maxheight )    {        msg_Dbg( p_demux, "invalid height %i", p_sys->i_height );        p_sys->i_height = 0;    }    if( !( p_sys->vid_cap.type & VID_TYPE_CAPTURE ) )    {        msg_Err( p_demux, "cannot grab" );        goto vdev_failed;    }    vid_channel.channel = p_sys->i_channel;    if( ioctl( i_fd, VIDIOCGCHAN, &vid_channel ) < 0 )    {        msg_Err( p_demux, "cannot get channel infos (%m)" );        goto vdev_failed;    }    msg_Dbg( p_demux,             "setting channel %s(%d) %d tuners flags=0x%x type=0x%x norm=0x%x",             vid_channel.name, vid_channel.channel, vid_channel.tuners,             vid_channel.flags, vid_channel.type, vid_channel.norm );    if( p_sys->i_tuner >= vid_channel.tuners )    {        msg_Dbg( p_demux, "invalid tuner, falling back on tuner 0" );        p_sys->i_tuner = 0;    }    vid_channel.norm = p_sys->i_norm;    if( ioctl( i_fd, VIDIOCSCHAN, &vid_channel ) < 0 )    {        msg_Err( p_demux, "cannot set channel (%m)" );        goto vdev_failed;    }    if( vid_channel.flags & VIDEO_VC_TUNER )    {        /* set tuner */#if 0        struct video_tuner vid_tuner;        if( p_sys->i_tuner >= 0 )        {            vid_tuner.tuner = p_sys->i_tuner;            if( ioctl( i_fd, VIDIOCGTUNER, &vid_tuner ) < 0 )            {                msg_Err( p_demux, "cannot get tuner (%m)" );                goto vdev_failed;            }            msg_Dbg( p_demux, "tuner %s low=%d high=%d, flags=0x%x "                     "mode=0x%x signal=0x%x",                     vid_tuner.name, vid_tuner.rangelow, vid_tuner.rangehigh,                     vid_tuner.flags, vid_tuner.mode, vid_tuner.signal );            msg_Dbg( p_demux, "setting tuner %s (%d)",                     vid_tuner.name, vid_tuner.tuner );            /* FIXME FIXME to be checked FIXME FIXME */            //vid_tuner.mode = p_sys->i_norm;            if( ioctl( i_fd, VIDIOCSTUNER, &vid_tuner ) < 0 )            {                msg_Err( p_demux, "cannot set tuner (%m)" );                goto vdev_failed;            }        }#endif        /* Show a warning if frequency is < than 30000.         * User is certainly usint old syntax. */        /* set frequency */        if( p_sys->i_frequency >= 0 )        {            int driver_frequency = p_sys->i_frequency * 16 /1000;            if( ioctl( i_fd, VIDIOCSFREQ, &driver_frequency ) < 0 )            {                msg_Err( p_demux, "cannot set frequency (%m)" );                goto vdev_failed;            }            msg_Dbg( p_demux, "frequency %d (%d)", p_sys->i_frequency,                                                   driver_frequency );        }    }    /* set audio */    if( vid_channel.flags & VIDEO_VC_AUDIO )    {        struct video_audio      vid_audio;        /* XXX TODO volume, balance, ... */        if( p_sys->i_audio >= 0 )        {            vid_audio.audio = p_sys->i_audio;            if( ioctl( i_fd, VIDIOCGAUDIO, &vid_audio ) < 0 )            {                msg_Err( p_demux, "cannot get audio (%m)" );                goto vdev_failed;            }            /* unmute audio */            vid_audio.flags &= ~VIDEO_AUDIO_MUTE;            if( ioctl( i_fd, VIDIOCSAUDIO, &vid_audio ) < 0 )            {                msg_Err( p_demux, "cannot set audio (%m)" );                goto vdev_failed;            }        }    }    /* establish basic params with input and norm before feeling width     * or height */    if( p_sys->b_mjpeg )    {        struct quicktime_mjpeg_app1 *p_app1;        int32_t i_offset;        if( ioctl( i_fd, MJPIOC_G_PARAMS, &mjpeg ) < 0 )        {            msg_Err( p_demux, "cannot get mjpeg params (%m)" );            goto vdev_failed;        }        mjpeg.input = p_sys->i_channel;        mjpeg.norm  = p_sys->i_norm;        mjpeg.decimation = p_sys->i_decimation;        if( p_sys->i_width )            mjpeg.img_width = p_sys->i_width / p_sys->i_decimation;        if( p_sys->i_height )            mjpeg.img_height = p_sys->i_height / p_sys->i_decimation;        /* establish Quicktime APP1 marker while we are here */        mjpeg.APPn = 1;        mjpeg.APP_len = 40;        /* aligned */        p_app1 = (struct quicktime_mjpeg_app1 *)mjpeg.APP_data;        p_app1->i_reserved = 0;        p_app1->i_tag = VLC_FOURCC( 'm','j','p','g' );        p_app1->i_field_size = 0;        p_app1->i_padded_field_size = 0;        p_app1->i_next_field = 0;        /* XXX WARNING XXX */        /* these's nothing magic about these values.  We are dangerously         * assuming the encoder card is encoding mjpeg-a and is not throwing         * in marker tags we aren't expecting.  It's bad enough we have to         * search through the jpeg output for every frame we grab just to         * find the first field's end marker, so we take this risk to boost         * performance.         * This is really something the driver could do for us because this         * does conform to standards outside of Apple Quicktime.         */        i_offset = 0x2e;        p_app1->i_DQT_offset = hton32( i_offset );        i_offset = 0xb4;        p_app1->i_DHT_offset = hton32( i_offset );        i_offset = 0x258;        p_app1->i_SOF_offset = hton32( i_offset );        i_offset = 0x26b;        p_app1->i_SOS_offset = hton32( i_offset );        i_offset = 0x279;        p_app1->i_data_offset = hton32( i_offset );        /* SOF and SOS aren't specified by the mjpeg API because they aren't         * optional.  They will be present in the output. */        mjpeg.jpeg_markers = JPEG_MARKER_DHT | JPEG_MARKER_DQT;        if( ioctl( i_fd, MJPIOC_S_PARAMS, &mjpeg ) < 0 )        {            msg_Err( p_demux, "cannot set mjpeg params (%m)" );            goto vdev_failed;        }        p_sys->i_width = mjpeg.img_width * mjpeg.HorDcm;        p_sys->i_height = mjpeg.img_height * mjpeg.VerDcm *            mjpeg.field_per_buff;    }    /* fix width/height */    if( !p_sys->b_mjpeg && ( p_sys->i_width == 0 || p_sys->i_height == 0 ) )    {        struct video_window vid_win;        if( ioctl( i_fd, VIDIOCGWIN, &vid_win ) < 0 )        {            msg_Err( p_demux, "cannot get win (%m)" );            goto vdev_failed;        }        p_sys->i_width  = vid_win.width;        p_sys->i_height = vid_win.height;        if( !p_sys->i_width || !p_sys->i_height )        {            p_sys->i_width = p_sys->vid_cap.maxwidth;            p_sys->i_height = p_sys->vid_cap.maxheight;        }        if( !p_sys->i_width || !p_sys->i_height )        {            msg_Err( p_demux, "invalid video size (%ix%i)",                     p_sys->i_width, p_sys->i_height );            goto vdev_failed;        }        msg_Dbg( p_demux, "will use %dx%d", p_sys->i_width, p_sys->i_height );    }    if( !p_sys->b_mjpeg )    {        /* set hue/color/.. */        if( ioctl( i_fd, VIDIOCGPICT, &p_sys->vid_picture ) == 0 )        {            struct video_picture vid_picture = p_sys->vid_picture;            if( p_sys->i_brightness >= 0 && p_sys->i_brightness < 65536 )            {                vid_picture.brightness = p_sys->i_brightness;            }            if( p_sys->i_colour >= 0 && p_sys->i_colour < 65536 )            {                vid_picture.colour = p_sys->i_colour;            }            if( p_sys->i_hue >= 0 && p_sys->i_hue < 65536 )            {                vid_picture.hue = p_sys->i_hue;            }            if( p_sys->i_contrast  >= 0 && p_sys->i_contrast < 65536 )            {                vid_picture.contrast = p_sys->i_contrast;            }            if( ioctl( i_fd, VIDIOCSPICT, &vid_picture ) == 0 )            {                msg_Dbg( p_demux, "v4l device uses brightness: %d",                         vid_picture.brightness );                msg_Dbg( p_demux, "v4l device uses colour: %d",                         vid_picture.colour );                msg_Dbg( p_demux, "v4l device uses hue: %d", vid_picture.hue );                msg_Dbg( p_demux, "v4l device uses contrast: %d",                         vid_picture.contrast );                p_sys->vid_picture = vid_picture;            }        }        /* Find out video format used by device */        if( ioctl( i_fd, VIDIOCGPICT, &p_sys->vid_picture ) == 0 )        {            struct video_picture vid_picture = p_sys->vid_picture;            char *psz;            int i;            p_sys->i_fourcc = 0;            psz = var_CreateGetString( p_demux, "v4l-chroma" );            if( strlen( psz ) >= 4 )            {                vid_picture.palette = 0;                int i_chroma = VLC_FOURCC( psz[0], psz[1], psz[2], psz[3] );                /* Find out v4l chroma code */                for( i = 0; v4lchroma_to_fourcc[i].i_v4l != 0; i++ )                {                    if( v4lchroma_to_fourcc[i].i_fourcc == i_chroma )                    {                        vid_picture.palette = v4lchroma_to_fourcc[i].i_v4l;                        break;                    }                }            }            free( psz );            if( vid_picture.palette &&                !ioctl( i_fd, VIDIOCSPICT, &vid_picture ) )

⌨️ 快捷键说明

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