Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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;
}