static int v4l_do_mmap(V4lState *s){ struct video_mbuf vmbuf; int err,i; memset(&vmbuf,0,sizeof(vmbuf)); /* try to get mmap properties */ err=ioctl(s->fd,VIDIOCGMBUF,&vmbuf); if (err<0){ ms_error("Could not get mmap properties: %s",strerror(errno)); return -1; }else { if (vmbuf.size>0){ /* do the mmap */ s->msize=vmbuf.size; s->frame_max=vmbuf.frames; } else { ms_error("This device cannot support mmap."); return -1; } } s->mmapdbuf=mmap(NULL,s->msize,PROT_READ,MAP_SHARED,s->fd,0); if (s->mmapdbuf==(void*)-1) { /* for non-mmu arch */ s->mmapdbuf=mmap(NULL,s->msize,PROT_READ,MAP_PRIVATE,s->fd,0); if (s->mmapdbuf==(void*)-1) { ms_error("Could not mmap: %s",strerror(errno)); s->mmapdbuf=NULL; return -1; } } /* initialize the mediastreamer buffers */ ms_message("Using %i-frames mmap'd buffer at %p, len %i", s->frame_max, s->mmapdbuf,s->msize); for(i=0;i<s->frame_max;i++){ mblk_t *buf=esballoc((uint8_t*)s->mmapdbuf+vmbuf.offsets[i],vmbuf.offsets[1],0,NULL); /* adjust to real size of picture*/ if (s->pix_fmt==MS_RGB24) buf->b_wptr+=s->vsize.width*s->vsize.height*3; else buf->b_wptr+=(s->vsize.width*s->vsize.height*3)/2; s->frames[i]=ms_yuv_buf_alloc_from_buffer(s->vsize.width, s->vsize.height, buf); } s->frame_ind=0; return 0; }
static int msv4l2_do_mmap(V4l2State *s){ struct v4l2_requestbuffers req; int i; enum v4l2_buf_type type; memset(&req,0,sizeof(req)); req.count = 4; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; if (v4l2_ioctl (s->fd, VIDIOC_REQBUFS, &req)<0) { ms_error("Error requesting info on mmap'd buffers: %s",strerror(errno)); return -1; } for (i=0; i<req.count; ++i) { struct v4l2_buffer buf; mblk_t *msg; void *start; memset(&buf,0,sizeof(buf)); buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory=V4L2_MEMORY_MMAP; buf.index=i; if (v4l2_ioctl (s->fd, VIDIOC_QUERYBUF, &buf)<0){ ms_error("Could not VIDIOC_QUERYBUF : %s",strerror(errno)); return -1; } start=v4l2_mmap (NULL /* start anywhere */, buf.length, PROT_READ | PROT_WRITE /* required */, MAP_SHARED /* recommended */, s->fd, buf.m.offset); if (start==NULL){ ms_error("Could not v4l2_mmap: %s",strerror(errno)); } msg=esballoc(start,buf.length,0,NULL); msg->b_wptr+=buf.length; s->frames[i]=ms_yuv_buf_alloc_from_buffer(s->vsize.width, s->vsize.height, msg); } s->frame_max=req.count; for (i = 0; i < s->frame_max; ++i) { struct v4l2_buffer buf; memset(&buf,0,sizeof(buf)); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if (-1==v4l2_ioctl (s->fd, VIDIOC_QBUF, &buf)){ ms_error("VIDIOC_QBUF failed: %s",strerror(errno)); }else { inc_ref(s->frames[i]); s->queued++; } } /*start capture immediately*/ type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 ==v4l2_ioctl (s->fd, VIDIOC_STREAMON, &type)){ ms_error("VIDIOC_STREAMON failed: %s",strerror(errno)); return -1; } return 0; }