• «
  • 1
  • 2
  • »
  • Pages: 1/2     Go
主题 : 友善之臂提供的CMOS摄像头测试代码赏析(完整) 复制链接 | 浏览器收藏 | 打印
这个阶段正是我事业的上升期,我怎么能走得开呢?
级别: 精灵王
UID: 3197
精华: 3
发帖: 770
金钱: 6995 两
威望: 5398 点
综合积分: 1600 分
注册时间: 2008-12-30
最后登录: 2010-12-31
楼主  发表于: 2009-04-29 21:53

 友善之臂提供的CMOS摄像头测试代码赏析(完整)

图片:
camtest是一个命令行程序,运行它可以实现CMOS摄像头的动态预览

CMOS摄像头对应的内核驱动源代码    :Linux-2.6.29/drivers/media/video/s3c2440camif.c
当然这一个还不够,还有同样目录下的其他源代码文件搭配使用。

解压光盘中的linux\examples.tgz可以得到camtest源代码。
camtest源代码清单:
%:include <iostream>
%:include <fcntl.h>
%:include <sys/ioctl.h>
%:include <sys/types.h>
%:include <sys/stat.h>
%:include <sys/mman.h>
%:include <unistd.h>
%:include <string.h>
%:include <stdlib.h>
%:include <string.h>
%:include <linux/types.h>
%:include <linux/fb.h>


class TError <%
public:
    TError(const char *msg) <%
        this->msg = msg;
    %>
    TError(const TError bitand e) <%
        msg = e.msg;
    %>
    void Output() <%
        std::cerr << msg << std::endl;
    %>
    virtual ~TError() <%%>
protected:
    TError bitand operator=(const TError bitand);
private:
    const char *msg;
%>;

// Linear memory based image
class TRect <%
public:
    TRect():  Addr(0), Size(0), Width(0), Height(0), LineLen(0), BPP(16) <%
    %>
    virtual ~TRect() <%
    %>
    bool DrawRect(const TRect bitand SrcRect, int x, int y) const <%
        if (BPP not_eq 16 or SrcRect.BPP not_eq 16) <%
            // don't support that yet
            throw TError("does not support other than 16 BPP yet");
        %>

        // clip
        int x0, y0, x1, y1;
        x0 = x;
        y0 = y;
        x1 = x0 + SrcRect.Width - 1;
        y1 = y0 + SrcRect.Height - 1;
        if (x0 < 0) <%
            x0 = 0;
        %>
        if (x0 > Width - 1) <%
            return true;
        %>
        if( x1 < 0) <%
            return true;
        %>
        if (x1 > Width - 1) <%
            x1 = Width - 1;
        %>
        if (y0 < 0) <%
            y0 = 0;
        %>
        if (y0 > Height - 1) <%
            return true;
        %>
        if (y1 < 0) <%
            return true;
        %>
        if (y1 > Height - 1) <%
            y1 = Height -1;
        %>

        //copy
        int copyLineLen = (x1 + 1 - x0) * BPP / 8;
        unsigned char *DstPtr = Addr + LineLen * y0 + x0 * BPP / 8;
        const unsigned char *SrcPtr = SrcRect.Addr + SrcRect.LineLen *(y0 - y) + (x0 - x) * SrcRect.BPP / 8;

        for (int i = y0; i <= y1; i++) <%
            memcpy(DstPtr, SrcPtr, copyLineLen);
            DstPtr += LineLen;
            SrcPtr += SrcRect.LineLen;
        %>
        
        
        return true;
    %>

    bool DrawRect(const TRect bitand rect) const <% // default is Center
        return DrawRect(rect, (Width - rect.Width) / 2, (Height - rect.Height) / 2);
    %>

    bool Clear() const <%
        int i;
        unsigned char *ptr;
        for (i = 0, ptr = Addr; i < Height; i++, ptr += LineLen) <%
            memset(ptr, 0, Width * BPP / 8);
        %>
        return true;
    %>

protected:
    TRect(const TRect bitand);
    TRect bitand operator=( const TRect bitand);

protected:
    unsigned char *Addr;
    int Size;
    int Width, Height, LineLen;
    unsigned BPP;
%>;



class TFrameBuffer: public TRect <%
public:
    TFrameBuffer(const char *DeviceName = "/dev/fb0"): TRect(), fd(-1) <%
        Addr = (unsigned char *)MAP_FAILED;

            fd = open(DeviceName, O_RDWR);
        if (fd < 0) <%
            throw TError("cannot open frame buffer");
        %>

            struct fb_fix_screeninfo Fix;
            struct fb_var_screeninfo Var;
        if (ioctl(fd, FBIOGET_FSCREENINFO, bitand Fix) < 0 or ioctl(fd, FBIOGET_VSCREENINFO, bitand Var) < 0) <%
            throw TError("cannot get frame buffer information");
        %>

        BPP = Var.bits_per_pixel;
            if (BPP not_eq 16) <%
            throw TError("support 16BPP frame buffer only");
        %>

            Width  = Var.xres;
            Height = Var.yres;
            LineLen = Fix.line_length;
              Size = LineLen * Height;

        int PageSize = getpagesize();
        Size = (Size + PageSize - 1) / PageSize * PageSize ;
            Addr = (unsigned char *)mmap(NULL, Size, PROT_READ|PROT_WRITE,MAP_SHARED, fd, 0);
        if (Addr == (unsigned char *)MAP_FAILED) <%
            throw TError("map frame buffer failed");
            return;
        %>
        ::close(fd);
        fd = -1;

        Clear();
    %>

    virtual ~TFrameBuffer() <%
        ::munmap(Addr, Size);
        Addr = (unsigned char *)MAP_FAILED;

        ::close(fd);
        fd = -1;
    %>

protected:
    TFrameBuffer(const TFrameBuffer bitand);
    TFrameBuffer bitand operator=( const TFrameBuffer bitand);
private:
    int fd;
%>;

class TVideo : public TRect <%
public:
    TVideo(const char *DeviceName = "/dev/camera"): TRect(), fd(-1) <%
        Addr = 0;
        fd = ::open(DeviceName, O_RDONLY);
        if (fd < 0) <%
            throw TError("cannot open video device");
        %>
        Width = 640;
        Height = 512;
        BPP = 16;
        LineLen = Width * BPP / 8;
        Size = LineLen * Height;
        Addr = new unsigned char<:Size:>;

        Clear();
    %>

    bool FetchPicture() const <%
        int count = ::read(fd, Addr, Size);
        if (count not_eq Size) <%
            throw TError("error in fetching picture from video");
        %>
        return true;
    %>

    virtual ~TVideo() <%
        ::close(fd);
        fd = -1;
        delete<::> Addr;
        Addr = 0;
    %>

protected:
    TVideo(const TVideo bitand);
    TVideo bitand operator=(const TVideo bitand);

private:
    int fd;
%>;

int main(int argc, char **argv)
<%
    try <%
        TFrameBuffer FrameBuffer;
        TVideo Video;
        for (;;) <%
            Video.FetchPicture();
            FrameBuffer.DrawRect(Video);
        %>
    %> catch (TError bitand e) <%
        e.Output();
        return 1;
    %>

    return 0;
%>


编译脚本Makefile:


camtest: camtest.cpp
    arm-linux-g++ camtest.cpp -Wall -O2 -o camtest
    arm-linux-strip -s camtest

clean:
    rm camtest
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
1楼  发表于: 2009-04-29 22:25
去掉那些多余的%>再发一次吧, 另外源代码代码记得用[code][/code] tag标记。
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
I want ! I do !
级别: 侠客
UID: 5509
精华: 0
发帖: 61
金钱: 565 两
威望: 491 点
综合积分: 122 分
注册时间: 2009-04-25
最后登录: 2018-02-08
2楼  发表于: 2009-05-06 11:54
级别: 新手上路
UID: 5367
精华: 0
发帖: 7
金钱: 70 两
威望: 70 点
综合积分: 14 分
注册时间: 2009-04-20
最后登录: 2009-05-29
3楼  发表于: 2009-05-06 14:15
能否麻烦楼主把那example打个包发给我,从arm9.net上下到的没有camtest,只有comtest谢谢.
562652830@qq.com
哈哈
级别: 新手上路
UID: 8755
精华: 0
发帖: 11
金钱: 110 两
威望: 55 点
综合积分: 22 分
注册时间: 2009-09-05
最后登录: 2009-10-13
4楼  发表于: 2009-09-05 00:11
我觉得用V4L就行了
级别: 新手上路
UID: 6173
精华: 0
发帖: 32
金钱: 260 两
威望: 151 点
综合积分: 64 分
注册时间: 2009-05-22
最后登录: 2011-07-29
5楼  发表于: 2009-10-18 11:14
你的赏识在哪里?一句注释都没有。晕死
级别: 新手上路
UID: 9216
精华: 0
发帖: 1
金钱: 10 两
威望: 5 点
综合积分: 2 分
注册时间: 2009-09-21
最后登录: 2009-10-22
6楼  发表于: 2009-10-20 16:37
...... 哥  我的哥  复制 粘贴 累 不
这个阶段正是我事业的上升期,我怎么能走得开呢?
级别: 精灵王
UID: 3197
精华: 3
发帖: 770
金钱: 6995 两
威望: 5398 点
综合积分: 1600 分
注册时间: 2008-12-30
最后登录: 2010-12-31
7楼  发表于: 2009-10-20 21:41
对于真正的程序员而言,代码本身就是一种艺术。
拷贝蒙娜丽莎和品味蒙娜丽莎,是两种不同层次的行为,当然,也有人对她为她写写评论,也有人看为她写的评论。我属于第一种,楼上呢?
级别: 新手上路
UID: 64
精华: 0
发帖: 41
金钱: 395 两
威望: 143 点
综合积分: 82 分
注册时间: 2008-02-02
最后登录: 2015-12-31
8楼  发表于: 2009-10-21 11:09
引用第7楼26672624于2009-10-20 21:41发表的  :
对于真正的程序员而言,代码本身就是一种艺术。
拷贝蒙娜丽莎和品味蒙娜丽莎,是两种不同层次的行为,当然,也有人对她为她写写评论,也有人看为她写的评论。我属于第一种,楼上呢?


主要楼主的标题有点大,“赏析”就是欣赏加分析的意思,建议改为“欣赏”或者“围观”比较合适。
不要砸我。
级别: 新手上路
UID: 6013
精华: 0
发帖: 18
金钱: 180 两
威望: 140 点
综合积分: 36 分
注册时间: 2009-05-16
最后登录: 2009-10-22
9楼  发表于: 2009-10-21 14:26
请教一下楼主,
基于这个CMOS驱动。。。是不是不可以用V4L来写应用层程序呀。。。。IOCTL都没呀。。
  • «
  • 1
  • 2
  • »
  • Pages: 1/2     Go