Android libv4l2-android 摄像头视频捕获
16lz
2021-01-23
1:Android的sdk是Java接口;所以应该可以用Java方法实现摄像头图像捕获;
2:关于C++方法在Android上获取摄像头信息,因为Android系统是Linux的修改,所以网上所说,可以用V4L(V4L2)的方法在Android上获取摄像头;
这里有一个简单示例:
android直接用v4l2采集图片数据
http://songyingjian2009.blog.163.com/blog/static/1318302422013220101931413/
关于V4L,可以百度或Google,可以自己重新学习实现,这里推荐一个类:
Linux上的另一篇文章:
http://blog.csdn.net/wenrenhua08/article/details/39591319
android :
这个类应该在Linux上和Android上应该都可以,需要测试;
libv4l2-android
http://code.openhub.net/project?pid=&ipid=476216&fp=476216&mp&projSelected=true&filterChecked
git://github.com/jollen/libv4l2-android
V4L2Camera.h
/***** Copyright (C) 2010 Moko365 Inc.** Copyright 2008, The Android Open Source Project**** Licensed under the Apache License, Version 2.0 (the "License");** you may not use this file except in compliance with the License.** You may obtain a copy of the License at**** http://www.apache.org/licenses/LICENSE-2.0**** Unless required by applicable law or agreed to in writing, software** distributed under the License is distributed on an "AS IS" BASIS,** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.** See the License for the specific language governing permissions and** limitations under the License.*/#ifndef _CAMIF_H_#define _CAMIF_H_#include namespace android {class V4L2Camera {public: V4L2Camera(); ~V4L2Camera(); int Open(const char *device, unsigned int width, unsigned int height, unsigned int pixelformat); int Init(); void Uninit(); void Close(); void StartStreaming(); void StopStreaming(); void GrabRawFrame(void *raw_base); void Convert(void *raw_base, void *preview_base, unsigned int ppnum);private: int fd; int start; unsigned char *mem; struct v4l2_buffer buf; unsigned int width; unsigned int height; unsigned int pixelformat;};}; // namespace#endif
V4L2Camera.cpp
/***** Copyright (C) 2010 Moko365 Inc** Copyright 2008, The Android Open Source Project**** Licensed under the Apache License, Version 2.0 (the "License");** you may not use this file except in compliance with the License.** You may obtain a copy of the License at**** http://www.apache.org/licenses/LICENSE-2.0**** Unless required by applicable law or agreed to in writing, software** distributed under the License is distributed on an "AS IS" BASIS,** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.** See the License for the specific language governing permissions and** limitations under the License.*/#defineLOG_TAG"V4LCAMERA"#include #include #include #include #include #include #include #include #include #include #include #include #include "V4L2Camera.h"namespace android {V4L2Camera::V4L2Camera(): start(0){}V4L2Camera::~V4L2Camera(){}int V4L2Camera::Open(const char *filename, unsigned int w, unsigned int h, unsigned int p){ int ret; struct v4l2_format format; fd = open(filename, O_RDWR); if (fd < 0) { LOGE("Error opening device: %s", filename); return -1; } width = w; height = h; pixelformat = p; format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; format.fmt.pix.width = width; format.fmt.pix.height = height; format.fmt.pix.pixelformat = pixelformat; // MUST set format.fmt.pix.field = V4L2_FIELD_ANY; ret = ioctl(fd, VIDIOC_S_FMT, &format); if (ret < 0) { LOGE("Unable to set format: %s", strerror(errno)); return -1; } return 0;}void V4L2Camera::Close(){ close(fd);}int V4L2Camera::Init(){ int ret; struct v4l2_requestbuffers rb; start = false; /* V4L2: request buffers, only 1 frame */ rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; rb.memory = V4L2_MEMORY_MMAP; rb.count = 1; ret = ioctl(fd, VIDIOC_REQBUFS, &rb); if (ret < 0) { LOGE("Unable request buffers: %s", strerror(errno)); return -1; } /* V4L2: map buffer */ memset(&buf, 0, sizeof(struct v4l2_buffer)); buf.index = 0; buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; ret = ioctl(fd, VIDIOC_QUERYBUF, &buf); if (ret < 0) { LOGE("Unable query buffer: %s", strerror(errno)); return -1; } /* Only map one */ mem = (unsigned char *)mmap(0, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset); if (mem == MAP_FAILED) { LOGE("Unable map buffer: %s", strerror(errno)); return -1; } /* V4L2: queue buffer */ ret = ioctl(fd, VIDIOC_QBUF, &buf); return 0;}void V4L2Camera::Uninit(){ munmap(mem, buf.length); return ;}void V4L2Camera::StartStreaming(){ enum v4l2_buf_type type; int ret; if (start) return; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ret = ioctl(fd, VIDIOC_STREAMON, &type); if (ret < 0) { LOGE("Unable query buffer: %s", strerror(errno)); return; } start = true;}void V4L2Camera::StopStreaming(){ enum v4l2_buf_type type; int ret; if (!start) return; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ret = ioctl(fd, VIDIOC_STREAMOFF, &type); if (ret < 0) { LOGE("Unable query buffer: %s", strerror(errno)); return; } start = false;}void V4L2Camera::GrabRawFrame(void *raw_base){ int ret; buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; /* V4L2: dequeue buffer */ ret = ioctl(fd, VIDIOC_DQBUF, &buf); if (ret < 0) { LOGE("Unable query buffer: %s", strerror(errno)); return; } /* copy to userspace */ memcpy((unsigned char *)raw_base, mem, buf.bytesused); /* V4l2: queue buffer again after that */ ret = ioctl(fd, VIDIOC_QBUF, &buf); if (ret < 0) { LOGE("Unable query buffer: %s", strerror(errno)); return; }}void V4L2Camera::Convert(void *r, void *p, unsigned int ppm){ unsigned char *raw = (unsigned char *)r; unsigned char *preview = (unsigned char *)p; /* We don't need to really convert that */ if (pixelformat == PIXEL_FORMAT_RGB_888) { /* copy to preview buffer */ memcpy(preview, raw, width*height*ppm); } /* TODO: Convert YUV to RGB. */ return;}}; // namespace
README.md
1
2
3
4
5
6
7
8
libv4l2-android===============v4l2 library for android camera HAL## Reference* V4l2 API Spec, http://www.linuxtv.org/downloads/legacy/video4linux/API/V4L2_API/spec-single/v4l2.html
更多相关文章
- 关于安装Android Studio的一些问题的解决方法
- android 按钮点击的两种方法以及长按事件
- Android 使用Handler的PostDelayed方法实现图片的轮播
- Android 应用启动闪白一下处理方法
- android 调用js中的方法
- Android ScrollView 内部控件 layout_margin失效的解决方法