[讨论] 友善之臂的CMOS摄像头测试程序

wuquan-1230   2010-4-18 10:27 楼主
%:include
%:include
%:include
%:include
%:include
%:include
%:include
%:include
%:include
%:include
%:include
%:include


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;
%>


这是友善之臂的CMOS摄像头的测试程序,是用C++实现的,
测试成功了,不过对于程序的原理还是不明白,比如在读取图像信息的时候需要设置哪些信息,
需要读取的缓冲区在哪等,希望高手指点,帮忙注视一下这个程序也行。谢谢!
我是黑客

回复评论 (6)

回复 楼主 wuquan-1230 的帖子

等等这个驱动我还没看过,共同学习一下!
处处留心皆学问!
点赞  2010-4-18 21:28
引用: 原帖由 daicheng 于 2010-4-18 21:28 发表
等等这个驱动我还没看过,共同学习一下!


这个程序是友善之臂带的测试程序,我看不太懂,
不过我知道大概意思了,
意思就是:读取摄像头的图像信息,然后通过对/dev/fb0操作,直接送往屏幕显示,
好像有个帧缓存,后面就不知道了。
我是黑客
点赞  2010-4-18 22:09
frame buffer  帧缓存
点赞  2010-4-19 09:38
引用: 原帖由 jxb01033016 于 2010-4-19 09:38 发表
frame buffer  帧缓存


呵呵,能不能说一下怎么使用?
我是黑客
点赞  2010-4-19 10:02
见到一个文档,LZ可以参考
基于s3c2440的Linux摄像头驱动开发.pdf (245.56 KB)
(下载次数: 135, 2010-4-21 14:07 上传)
处处留心皆学问!
点赞  2010-4-21 14:07

回复 6楼 daicheng 的帖子

好的,谢谢了!!!
我是黑客
点赞  2010-4-23 13:12
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复