1:Android的sdk是Java接口;所以应该可以用Java方法实现摄像头图像捕获;
2:关于C++方法在Android上获取摄像头信息,因为Android系统是Linux的修改,所以网上所说,可以用V4L(V4L2)的方法在Android上获取摄像头;
这里有一个简单示例:
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.
*/
#define LOG_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