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

📄 tvi_v4l2.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 5 页
字号:
        }        priv->streamon = 0;        /* unqueue all remaining buffers */        memset(&buf,0,sizeof(buf));        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;        buf.memory = V4L2_MEMORY_MMAP;        while (!ioctl(priv->video_fd, VIDIOC_DQBUF, &buf));    }    /* unmap all buffers */    for (i = 0; i < priv->mapcount; i++) {        if (munmap(priv->map[i].addr, priv->map[i].len) < 0) {            mp_msg(MSGT_TV, MSGL_ERR, "%s: munmap capture buffer failed: %s\n",                   info.short_name, strerror(errno));        }    }    /* stop audio thread */    if (!priv->tv_param->noaudio && priv->audio_grabber_thread) {        pthread_join(priv->audio_grabber_thread, NULL);        pthread_mutex_destroy(&priv->skew_mutex);        pthread_mutex_destroy(&priv->audio_mutex);    }    set_mute(priv, 1);    /* free memory and close device */    free(priv->map);                priv->map = NULL;    priv->mapcount = 0;    if(priv->video_fd!=-1)close(priv->video_fd);        priv->video_fd  = -1;    free(priv->video_dev);        priv->video_dev = NULL;    if (priv->video_ringbuffer) {        int i;        for (i = 0; i < priv->video_buffer_size_current; i++) {            free(priv->video_ringbuffer[i].data);        }        free(priv->video_ringbuffer);    }    if (!priv->tv_param->noaudio) {        if (priv->audio_ringbuffer)            free(priv->audio_ringbuffer);        if (priv->audio_skew_buffer)            free(priv->audio_skew_buffer);        if (priv->audio_skew_delta_buffer)            free(priv->audio_skew_delta_buffer);    }    /* show some nice statistics ;-) */    mp_msg(MSGT_TV, MSGL_INFO,           "%s: %d frames successfully processed, %d frames dropped.\n",           info.short_name, priv->frames, dropped);    mp_msg(MSGT_TV, MSGL_V, "%s: up to %u video frames buffered.\n",           info.short_name, priv->video_buffer_size_current);    return 1;}/* initialisation */static int init(priv_t *priv){    int i;    priv->audio_ringbuffer = NULL;    priv->audio_skew_buffer = NULL;    priv->audio_skew_delta_buffer = NULL;    priv->audio_inited = 0;    /* Open the video device. */    priv->video_fd = open(priv->video_dev, O_RDWR);    if (priv->video_fd < 0) {        mp_msg(MSGT_TV, MSGL_ERR, "%s: unable to open '%s': %s\n",               info.short_name, priv->video_dev, strerror(errno));        uninit(priv);        return 0;    }    mp_msg(MSGT_TV, MSGL_DBG2, "%s: video fd: %s: %d\n",           info.short_name, priv->video_dev, priv->video_fd);    /*    ** Query the video capabilities and current settings    ** for further control calls.    */    if (ioctl(priv->video_fd, VIDIOC_QUERYCAP, &priv->capability) < 0) {        mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query capabilities failed: %s\n",               info.short_name, strerror(errno));        uninit(priv);        return 0;    }    if (!(priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE))    {        mp_msg(MSGT_TV, MSGL_ERR, "Device %s is not a video capture device.\n",               priv->video_dev);        return 0;    }    if (getfmt(priv) < 0) {        uninit(priv);        return 0;    }    getstd(priv);    /*    ** if this device has got a tuner query it's settings    ** otherwise set some nice defaults    */    if (priv->capability.capabilities & V4L2_CAP_TUNER) {        if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {            mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",                   info.short_name, strerror(errno));            uninit(priv);            return 0;        }    }    mp_msg(MSGT_TV, MSGL_INFO, "Selected device: %s\n", priv->capability.card);    if (priv->capability.capabilities & V4L2_CAP_TUNER) {        mp_msg(MSGT_TV, MSGL_INFO, " Tuner cap:%s%s%s\n",                (priv->tuner.capability & V4L2_TUNER_CAP_STEREO) ? " STEREO" : "",                (priv->tuner.capability & V4L2_TUNER_CAP_LANG1)  ? " LANG1"  : "",                (priv->tuner.capability & V4L2_TUNER_CAP_LANG2)  ? " LANG2"  : "");        mp_msg(MSGT_TV, MSGL_INFO, " Tuner rxs:%s%s%s%s\n",                (priv->tuner.rxsubchans & V4L2_TUNER_SUB_MONO)   ? " MONO"   : "",                (priv->tuner.rxsubchans & V4L2_TUNER_SUB_STEREO) ? " STEREO" : "",                (priv->tuner.rxsubchans & V4L2_TUNER_SUB_LANG1)  ? " LANG1"  : "",                (priv->tuner.rxsubchans & V4L2_TUNER_SUB_LANG2)  ? " LANG2"  : "");    }    mp_msg(MSGT_TV, MSGL_INFO, " Capabilites:%s%s%s%s%s%s%s%s%s%s%s\n",           priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE?           "  video capture": "",           priv->capability.capabilities & V4L2_CAP_VIDEO_OUTPUT?           "  video output": "",           priv->capability.capabilities & V4L2_CAP_VIDEO_OVERLAY?           "  video overlay": "",           priv->capability.capabilities & V4L2_CAP_VBI_CAPTURE?           "  VBI capture device": "",           priv->capability.capabilities & V4L2_CAP_VBI_OUTPUT?           "  VBI output": "",           priv->capability.capabilities & V4L2_CAP_RDS_CAPTURE?           "  RDS data capture": "",           priv->capability.capabilities & V4L2_CAP_TUNER?           "  tuner": "",           priv->capability.capabilities & V4L2_CAP_AUDIO?           "  audio": "",           priv->capability.capabilities & V4L2_CAP_READWRITE?           "  read/write": "",           priv->capability.capabilities & V4L2_CAP_ASYNCIO?           "  async i/o": "",           priv->capability.capabilities & V4L2_CAP_STREAMING?           "  streaming": "");    mp_msg(MSGT_TV, MSGL_INFO, " supported norms:");    for (i = 0;; i++) {        struct v4l2_standard standard;        memset(&standard, 0, sizeof(standard));        standard.index = i;        if (-1 == ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))            break;        mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, standard.name);    }    mp_msg(MSGT_TV, MSGL_INFO, "\n inputs:");    for (i = 0; 1; i++) {        struct v4l2_input input;        input.index = i;        if (ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &input) < 0) {            break;        }        mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, input.name);    }    if (ioctl(priv->video_fd, VIDIOC_G_INPUT, &i) < 0) {        mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get input failed: %s\n",               info.short_name, strerror(errno));    }    mp_msg(MSGT_TV, MSGL_INFO, "\n Current input: %d\n", i);    for (i = 0; ; i++) {        struct v4l2_fmtdesc fmtdesc;        fmtdesc.index = i;        fmtdesc.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;        if (ioctl(priv->video_fd, VIDIOC_ENUM_FMT, &fmtdesc) < 0) {            break;        }        mp_msg(MSGT_TV, MSGL_V, " Format %-6s (%2d bits, %s): %s\n",               pixfmt2name(fmtdesc.pixelformat), pixfmt2depth(fmtdesc.pixelformat),               fmtdesc.description, vo_format_name(fcc_vl2mp(fmtdesc.pixelformat)));    }    mp_msg(MSGT_TV, MSGL_INFO, " Current format: %s\n",           pixfmt2name(priv->format.fmt.pix.pixelformat));    /* set some nice defaults */    if (getfmt(priv) < 0) return 0;    priv->format.fmt.pix.width  = 640;    priv->format.fmt.pix.height = 480;    if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {        mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set format failed: %s\n",               info.short_name, strerror(errno));        uninit(priv);        return 0;    }//    if (!(priv->capability.capabilities & V4L2_CAP_AUDIO) && !priv->tv_param->force_audio) priv->tv_param->noaudio = 1;    if (priv->capability.capabilities & V4L2_CAP_TUNER) {        struct v4l2_control control;        if (priv->tv_param->amode >= 0) {            mp_msg(MSGT_TV, MSGL_V, "%s: setting audio mode\n", info.short_name);            priv->tuner.audmode = amode2v4l(priv->tv_param->amode);            if (ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {                mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set tuner failed: %s\n",                       info.short_name, strerror(errno));                return TVI_CONTROL_FALSE;            }        }        mp_msg(MSGT_TV, MSGL_INFO, "%s: current audio mode is :%s%s%s%s\n", info.short_name,                (priv->tuner.audmode == V4L2_TUNER_MODE_MONO)   ? " MONO"   : "",                (priv->tuner.audmode == V4L2_TUNER_MODE_STEREO) ? " STEREO" : "",                (priv->tuner.audmode == V4L2_TUNER_MODE_LANG1)  ? " LANG1"  : "",                (priv->tuner.audmode == V4L2_TUNER_MODE_LANG2)  ? " LANG2"  : "");        if (priv->tv_param->volume >= 0) {            control.id = V4L2_CID_AUDIO_VOLUME;            control.value = priv->tv_param->volume;            set_control(priv, &control, 0);        }        if (priv->tv_param->bass >= 0) {            control.id = V4L2_CID_AUDIO_BASS;            control.value = priv->tv_param->bass;            set_control(priv, &control, 0);        }        if (priv->tv_param->treble >= 0) {            control.id = V4L2_CID_AUDIO_TREBLE;            control.value = priv->tv_param->treble;            set_control(priv, &control, 0);        }        if (priv->tv_param->balance >= 0) {            control.id = V4L2_CID_AUDIO_BALANCE;            control.value = priv->tv_param->balance;            set_control(priv, &control, 0);        }    }    return 1;}static int get_capture_buffer_size(priv_t *priv){    int bufsize, cnt;    if (priv->tv_param->buffer_size >= 0) {        bufsize = priv->tv_param->buffer_size*1024*1024;    } else {#ifdef HAVE_SYS_SYSINFO_H        struct sysinfo si;                sysinfo(&si);        if (si.totalram<2*1024*1024) {            bufsize = 1024*1024;        } else {            bufsize = si.totalram/2;        }#else        bufsize = 16*1024*1024;#endif    }        cnt = bufsize/priv->format.fmt.pix.sizeimage;    if (cnt < 2) cnt = 2;        return cnt;}/* that's the real start, we'got the format parameters (checked with control) */static int start(priv_t *priv){    struct v4l2_requestbuffers request;    unsigned int i;    /* setup audio parameters */    init_audio(priv);    if (!priv->tv_param->noaudio && !priv->audio_inited) return 0;    /* we need this to size the audio buffer properly */    if (priv->immediate_mode) {        priv->video_buffer_size_max = 2;    } else {        priv->video_buffer_size_max = get_capture_buffer_size(priv);    }        if (!priv->tv_param->noaudio) {        setup_audio_buffer_sizes(priv);        priv->audio_skew_buffer = calloc(priv->aud_skew_cnt, sizeof(long long));        if (!priv->audio_skew_buffer) {            mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));            return 0;        }        priv->audio_skew_delta_buffer = calloc(priv->aud_skew_cnt, sizeof(long long));        if (!priv->audio_skew_delta_buffer) {            mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));            return 0;        }        priv->audio_ringbuffer = calloc(priv->audio_in.blocksize, priv->audio_buffer_size);        if (!priv->audio_ringbuffer) {            mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate audio buffer: %s\n", strerror(errno));            return 0;        }        priv->audio_secs_per_block = (double)priv->audio_in.blocksize/(priv->audio_in.samplerate                                                                    *priv->audio_in.channels                                                                    *priv->audio_in.bytes_per_sample);        priv->audio_usecs_per_block = 1e6*priv->audio_secs_per_block;        priv->audio_head = 0;        priv->audio_tail = 0;        priv->audio_cnt = 0;        priv->audio_drop = 0;        priv->audio_skew = 0;        priv->audio_skew_total = 0;        priv->audio_skew_delta_total = 0;        priv->audio_recv_blocks_total = 0;        priv->audio_sent_blocks_total = 0;        priv->audio_null_blocks_inserted = 0;        priv->audio_insert_null_samples = 0;        priv->dropped_frames_timeshift = 0;        priv->dropped_frames_compensated = 0;        pthread_mutex_init(&priv->skew_mutex, NULL);        pthread_mutex_init(&priv->audio_mutex, NULL);    }    /* setup video parameters */    if (!priv->tv_param->noaudio) {        if (priv->video_buffer_size_max < (3*priv->standard.frameperiod.denominator) /                                               priv->standard.frameperiod.numerator            *priv->audio_secs_per_block) {            mp_msg(MSGT_TV, MSGL_ERR, "Video buffer shorter than 3 times audio frame duration.\n"                   "You will probably experience heavy framedrops.\n");        }    }        {        int bytesperline = priv->format.fmt.pix.width*pixfmt2depth(priv->format.fmt.pix.pixelformat)/8;                mp_msg(MSGT_TV, MSGL_V, "Using a ring buffer for maximum %d frames, %d MB total size.\n",               priv->video_buffer_size_max,               priv->video_buffer_size_max*priv->format.fmt.pix.height*bytesperline/(1024*1024));    }    priv->video_ringbuffer = calloc(priv->video_buffer_size_max, sizeof(video_buffer_entry));    if (!priv->video_ringbuffer) {        mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate video buffer: %s\n", strerror(errno));        return 0;    }    memset(priv->video_ringbuffer,0,priv->video_buffer_size_max * sizeof(video_buffer_entry));    pthread_mutex_init(&priv->video_buffer_mutex, NULL);    priv->video_head = 0;    priv->video_tail = 0;    priv->video_cnt = 0;        /* request buffers */    if (priv->immediate_mode) {        request.count = 2;    } else {        request.count = BUFFER_COUNT;

⌨️ 快捷键说明

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