Android libv4l2-android 摄像头视频捕获

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.
*/

#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

 

 

 

你可能感兴趣的:(Linux(Ubuntu),Android)