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

📄 tvi_v4l.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 5 页
字号:
        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->height*priv->bytesperline);    if (cnt < 2) cnt = 2;    return cnt;}#ifdef HAVE_TV_TELETEXTstatic int vbi_init(priv_t* priv,char* device){    int vbi_fd=0;    struct video_capability cap;    if(!device)        return TVI_CONTROL_FALSE;    priv->vbi_dev=strdup(device);    vbi_fd=open(priv->vbi_dev,O_RDWR);    if(vbi_fd<0){        mp_msg(MSGT_TV,MSGL_ERR,"vbi: could not open device %s\n",priv->vbi_dev);        return  TVI_CONTROL_FALSE;    }        if(ioctl(vbi_fd,VIDIOCGCAP,&cap)<0){        mp_msg(MSGT_TV,MSGL_ERR,"vbi: Query capatibilities failed for %s\n",priv->vbi_dev);        close(vbi_fd);        return  TVI_CONTROL_FALSE;    }    if(!cap.type & VID_TYPE_CAPTURE){        mp_msg(MSGT_TV,MSGL_ERR,"vbi: %s is not capture device\n",priv->vbi_dev);        close(vbi_fd);        return  TVI_CONTROL_FALSE;    }    priv->vbi_fd=vbi_fd;    mp_msg(MSGT_TV,MSGL_DBG3,"vbi: init ok\n");    return TVI_CONTROL_TRUE;}static int vbi_get_props(priv_t* priv,tt_stream_props* ptsp){    struct vbi_format fmt;    int res;    if(!priv || !ptsp)        return TVI_CONTROL_FALSE;    memset(&fmt,0,sizeof(struct vbi_format));    if((res=ioctl(priv->vbi_fd,VIDIOCGVBIFMT,&fmt))<0){        mp_msg(MSGT_TV,MSGL_ERR,"vbi_get_props: Query format failed: %x\n",res);        return  TVI_CONTROL_FALSE;    }    ptsp->interlaced=(fmt.flags& VBI_INTERLACED?1:0);    if(fmt.start[1]>0 && fmt.count[1]){        if(fmt.start[1]>=286)            //625            ptsp->offset=10.2e-6*fmt.sampling_rate;        else            //525            ptsp->offset=9.2e-6*fmt.sampling_rate;    }else        ptsp->offset=9.7e-6*fmt.sampling_rate;    ptsp->sampling_rate=fmt.sampling_rate;    ptsp->samples_per_line=fmt.samples_per_line,    ptsp->count[0]=fmt.count[0];    ptsp->count[1]=fmt.count[1];    ptsp->bufsize = ptsp->samples_per_line * (ptsp->count[0] + ptsp->count[1]);    mp_msg(MSGT_TV,MSGL_V,"vbi_get_props: sampling_rate=%d,offset:%d,samples_per_line: %d\n interlaced:%s, count=[%d,%d]\n",            ptsp->sampling_rate,        ptsp->offset,        ptsp->samples_per_line,        ptsp->interlaced?"Yes":"No",        ptsp->count[0],        ptsp->count[1]);    return TVI_CONTROL_TRUE;}static void *vbi_grabber(void *data){    priv_t *priv = (priv_t *) data;    int bytes,seq,prev_seq;    unsigned char* buf;    tt_stream_props tsp;    if(!priv->priv_vbi){        mp_msg(MSGT_TV,MSGL_WARN,"vbi: vbi not initialized. stopping thread.\n");        return NULL;    }    if(vbi_get_props(priv,&tsp)!=TVI_CONTROL_TRUE)        return NULL;    buf=malloc(tsp.bufsize);    seq=0;    prev_seq=0;    mp_msg(MSGT_TV,MSGL_V,"vbi: vbi capture thread started.\n");    while (!priv->vbi_shutdown){        bytes=read(priv->vbi_fd,buf,tsp.bufsize);        if (bytes!=tsp.bufsize){            mp_msg(MSGT_TV,MSGL_WARN,"vbi: expecting bytes: %d, got: %d",tsp.bufsize,bytes);            break;        }        seq=*(int*)(buf+bytes-4);        if(seq<=1) continue;        if (prev_seq && seq!=prev_seq+1){            prev_seq=0;            seq=0;        }        prev_seq=seq;        teletext_control(priv->priv_vbi,TV_VBI_CONTROL_DECODE_PAGE,&buf);        mp_msg(MSGT_TV,MSGL_DBG3,"grabber: seq:%d\n",seq);    }    free(buf);    return NULL;}#endif //HAVE_TV_TELETEXTstatic int start(priv_t *priv){    int i;    int bytes_per_sample;    struct video_window win;    if (ioctl(priv->video_fd, VIDIOCGPICT, &priv->picture) == -1)    {        mp_msg(MSGT_TV, MSGL_ERR, "ioctl get picture failed: %s\n", strerror(errno));        return(0);    }    priv->picture.palette = format2palette(priv->format);    priv->picture.depth = palette2depth(priv->picture.palette);    if (priv->format != IMGFMT_BGR15) {        priv->bytesperline = priv->width * priv->picture.depth / 8;    } else {        priv->bytesperline = priv->width * 2;    }    mp_msg(MSGT_TV, MSGL_V, "Picture values:\n");    mp_msg(MSGT_TV, MSGL_V, " Depth: %d, Palette: %s (Format: %s)\n", priv->picture.depth,        PALETTE(priv->picture.palette), vo_format_name(priv->format));    mp_msg(MSGT_TV, MSGL_V, " Brightness: %d, Hue: %d, Colour: %d, Contrast: %d\n",        priv->picture.brightness, priv->picture.hue,        priv->picture.colour, priv->picture.contrast);    if (ioctl(priv->video_fd, VIDIOCSPICT, &priv->picture) == -1)    {        mp_msg(MSGT_TV, MSGL_ERR, "ioctl set picture failed: %s\n", strerror(errno));        mp_msg(MSGT_TV, MSGL_ERR, "The 'outfmt' of '%s' is likely not supported by your card\n",               vo_format_name(priv->format));        return 0;    }    /* Set capture size */    win.x = 0;    win.y = 0;    win.width = priv->width;    win.height = priv->height;    win.chromakey = -1;    win.flags = 0;    win.clipcount = 0;    if (ioctl(priv->video_fd, VIDIOCSWIN, &win) == -1)        mp_msg(MSGT_TV, MSGL_ERR, "ioctl set window failed: %s\n", strerror(errno));    if ( !priv->tv_param->mjpeg )    {        /* map grab buffer */        if (ioctl(priv->video_fd, VIDIOCGMBUF, &priv->mbuf) == -1)        {            mp_msg(MSGT_TV, MSGL_ERR, "ioctl get mbuf failed: %s\n", strerror(errno));            return 0;        }        mp_msg(MSGT_TV, MSGL_V, "mbuf: size=%d, frames=%d\n",            priv->mbuf.size, priv->mbuf.frames);        priv->mmap = mmap(0, priv->mbuf.size, PROT_READ|PROT_WRITE,                          MAP_SHARED, priv->video_fd, 0);        if (priv->mmap == (unsigned char *)-1)        {            mp_msg(MSGT_TV, MSGL_ERR, "Unable to map memory for buffers: %s\n", strerror(errno));            return 0;        }        mp_msg(MSGT_TV, MSGL_DBG2, "our buffer: %p\n", priv->mmap);        /* num of buffers */        priv->nbuf = priv->mbuf.frames;        /* video buffers */        priv->buf = calloc(priv->nbuf, sizeof(struct video_mmap));        if (!priv->buf)            return 0;        memset(priv->buf, 0, priv->nbuf * sizeof(struct video_mmap));    }    if ( !priv->tv_param->mjpeg )    {        priv->nbuf = priv->mbuf.frames;        for (i=0; i < priv->nbuf; i++)        {            priv->buf[i].format = priv->picture.palette;            priv->buf[i].frame = i;            priv->buf[i].width = priv->width;            priv->buf[i].height = priv->height;            mp_msg(MSGT_TV, MSGL_DBG2, "buffer: %d => %p\n", i, &priv->buf[i]);        }    }#if 0    {        struct video_play_mode pmode;        pmode.mode = VID_PLAY_NORMAL;        pmode.p1 = 1;        pmode.p2 = 0;        if (ioctl(priv->video_fd, VIDIOCSPLAYMODE, &pmode) == -1)        {            mp_msg(MSGT_TV, MSGL_ERR, "ioctl set play mode failed: %s\n", strerror(errno));//          return(0);        }    }#endif#if 0    // initialize video capture    if (ioctl(priv->video_fd, VIDIOCCAPTURE, &one) == -1)    {        mp_msg(MSGT_TV, MSGL_ERR, "FATAL: ioctl ccapture failed: %s\n", strerror(errno));        return(0);    }#endif    /* setup audio parameters */    if (!priv->tv_param->noaudio) {        setup_audio_buffer_sizes(priv);        bytes_per_sample = priv->audio_in.bytes_per_sample;        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_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                                                                    *bytes_per_sample);        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_recv_blocks_total = 0;        priv->audio_sent_blocks_total = 0;    }    /* setup video parameters */    if (priv->immediate_mode) {        priv->video_buffer_size_max = VID_BUF_SIZE_IMMEDIATE;    } else {        priv->video_buffer_size_max = get_capture_buffer_size(priv);    }    priv->video_buffer_size_current = 0;    if (!priv->tv_param->noaudio) {        if (priv->video_buffer_size_max < 3.0*priv->fps*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");        }    }    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->height*priv->bytesperline/(1024*1024));    priv->video_ringbuffer = calloc(priv->video_buffer_size_max, sizeof(unsigned char*));    if (!priv->video_ringbuffer) {        mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate video buffer: %s\n", strerror(errno));        return 0;    }    for (i = 0; i < priv->video_buffer_size_max; i++)        priv->video_ringbuffer[i] = NULL;    priv->video_timebuffer = calloc(priv->video_buffer_size_max, sizeof(long long));    if (!priv->video_timebuffer) {        mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate time buffer: %s\n", strerror(errno));        return 0;    }    priv->video_avg_buffer = malloc(sizeof(long long) * VIDEO_AVG_BUFFER_SIZE);    if (!priv->video_avg_buffer) {        mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate period buffer: %s\n", strerror(errno));        return 0;    }    priv->video_interval_sum = (1e6/priv->fps)*VIDEO_AVG_BUFFER_SIZE;    for (i = 0; i < VIDEO_AVG_BUFFER_SIZE; i++) {        priv->video_avg_buffer[i] = 1e6/priv->fps;    }    priv->video_avg_ptr = 0;    priv->video_head = 0;    priv->video_tail = 0;    priv->video_cnt = 0;    priv->first = 1;    if (priv->capability.audios) {        /* enable audio */        if (priv->tv_param->volume >= 0)            priv->audio[priv->audio_id].volume = priv->tv_param->volume;        if (priv->tv_param->bass >= 0)            priv->audio[priv->audio_id].bass = priv->tv_param->bass;        if (priv->tv_param->treble >= 0)            priv->audio[priv->audio_id].treble = priv->tv_param->treble;        if (priv->tv_param->balance >= 0)            priv->audio[priv->audio_id].balance = priv->tv_param->balance;        priv->audio[priv->audio_id].flags &= ~VIDEO_AUDIO_MUTE;        mp_msg(MSGT_TV, MSGL_V, "Enabling tv audio. Requested setup is:\n");        mp_msg(MSGT_TV, MSGL_V, "id=%d vol=%d bass=%d treble=%d balance=%d mode=%s",               priv->audio_id,               priv->audio[priv->audio_id].volume, priv->audio[priv->audio_id].bass, priv->audio[priv->audio_id].treble,               priv->audio[priv->audio_id].balance, audio_mode2name(priv->audio[priv->audio_id].mode));        mp_msg(MSGT_TV, MSGL_V, " chan=%d\n", priv->audio_channels[priv->audio_id]);        ioctl(priv->video_fd, VIDIOCSAUDIO, &priv->audio[priv->audio_id]);    }#ifdef HAVE_TV_TELETEXT    /* start vbi thread */    if(priv->priv_vbi){        priv->vbi_shutdown = 0;        pthread_create(&priv->vbi_grabber_thread, NULL, vbi_grabber, priv);    }#endif    /* launch capture threads */    priv->shutdown = 0;    if (!priv->tv_param->noaudio) {        pthread_mutex_init(&priv->audio_starter, NULL);        pthread_mutex_init(&priv->skew_mutex, NULL);        pthread_mutex_lock(&priv->audio_starter);        pthread_create(&priv->audio_grabber_thread, NULL, audio_grabber, priv);    }    pthread_mutex_init(&priv->video_buffer_mutex, NULL);    /* we'll launch the video capture later, when a first request for a frame arrives */    return(1);}static int control(priv_t *priv, int cmd, void *arg)

⌨️ 快捷键说明

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