S3C6410摄像头测试程序流程mfc分析

限时加码!20+主流AI编程工具免费用 购周边加赠Coding Plan Lite,Claude Code、Cursor等即刻畅享,学习进阶更高效! 阅读详情
作者:
嵌入式领域著名讲师  O(∩_∩)O  牛牛猛  华清远见金牌讲师
                                     
在代码分析开始前需要对一个概念进行解释,就是MFC。
Multi Format Codec的缩写,是ARM微处理器内部一种支持多种硬件编码方式的硬件电路,能够编码/解码MPEG-4/H.263/H.264(30fps)等多种格式的多媒体影像。
TOP6410开发板使用的是ARM11的核,我们现在要利用这个ARM内部的硬件编解码电路来直接对摄像头采集到的图像进行基于硬件的编解码。首先在项目开始前需要对TOP6410的性能做大体的测试,现在我们使用的是三星提供的测试程序,通过对这个测试程序的分析可以很好地让我们了解基于系统级的图像编解码函数的调用机制,有利于我们顺利的提取图像并且进行进一步的处理。

要使用MFC,首先要了解如何使用这种机制,在我们的代码中首先要定义一个MFC的句柄(handle),所有的MFC操作都是需要通过传递这个handle作为参数来执行的,它的重要性就跟main 函数差不多,是整个编解码过程的掌舵者。在源码中是这样定义的:


static void       *handle;
static void *mfc_encoder_init(int width, int height, int frame_rate, int bitrate, int gop_num);
static void *mfc_encoder_exe(void *handle, unsigned char *yuv_buf, int frame_size, int first_frame, long *size);
static void mfc_encoder_free(void *handle);

看到我们这里定义了三个函数分别是初始化函数,执行函数,还有句柄释放函数。我们就是要利用这三个函数进行我们的编解码操作,我们再来看看init函数的实现:
void *mfc_encoder_init(int width, int height, int frame_rate, int bitrate, int gop_num)
{
         int                                frame_size;
         void                    *handle;
         int                                ret;
 
 
         frame_size       = (width * height * 3) >> 1;//这里的意思是把width*height*3的值除以2
 
         handle = SsbSipH264EncodeInit(width, height, frame_rate, bitrate, gop_num);
         if (handle == NULL) {
                   LOG_MSG(LOG_ERROR, "Test_Encoder", "SsbSipH264EncodeInit Failed/n");
                   return NULL;
         }
 
         ret = SsbSipH264EncodeExe(handle);
 
         return handle;
}


首先要注意的是传入的参数,它们分别定义了每一帧图像的长宽,帧的速度,比特率,GOP(Group of Pictures)策略影响编码质量(设置编码的质量系数)。
函数的作用是对整个MFC的参数进行设置
这里有一个frame_size,有人问为什么要定义成那么大,我们需要的图像每一帧的大小是我们可以自己定义的,我们在代码执行前一般都会开一个缓冲区来存放每一帧的数据,由于我们开的缓冲区给每帧的大小就是那么大,所以这里也好配合我们之前开辟的缓冲区大小进行编码。
SsbSipH264EncodeInit()这个函数可以说是真正的开始进入编码的初始化过程,现在让我们进去看看。

现在我们来看看代码里的关键的几个地方:

hOpen = open(MFC_DEV_NAME, O_RDWR|O_NDELAY);//打开设备节点
 
// mapping shared in/out buffer between application and MFC device driver
addr = (unsigned char *) mmap(0, BUF_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, hOpen, 0);

这里是进行内存映射,我想做过摄像头项目的人对这个肯定特别有体会,这个函数的作用其实就是把MFC设备工作后写入的那部分内存映射到我的应用程序开的缓冲区中,也就是说我只要对应用程序中的buffer进行读写其实就是对部分内存的读写。内存映射是linux内核当中一个非常重要的机制,希望能够引起大家足够多的重视。


pCTX = (_MFCLIB_H264_ENC *) malloc(sizeof(_MFCLIB_H264_ENC));

看到这里我想有必要展示一下这个_MFCLIB_H264_ENC的结构体:


typedef struct
{
         int          magic;
         int           hOpen;
         int     fInit;
         int     enc_strm_size;
         int              enc_hdr_size;
        
         unsigned int            width, height;
         unsigned int            framerate, bitrate;
         unsigned int            gop_num;
         unsigned char  *mapped_addr;
} _MFCLIB_H264_ENC;

这个是为MFC设备定义的结构体,至于这样定义主要是为了能够和内核中的定义进行匹配,相关代码可以参看内核。这里主要是定义了编码需要的参数。 之后的工作就是要把这个结构体填满(定义好各项初始化参数),主要的作用就是完成初始化的工作。到这里SsbSipH264EncodeInit()结束,但是初始化工作并没有完成。
其实这里你会发现handle是什么?handle其实在这里被定义为了指向_MFCLIB_H264_ENC这个结构体的指针。其实仔细的朋友你会发现handle这个指针在每一次函数调用过程当中都会指向不同的结构体或者是内存地址,读者可以把它理解成贯穿于整个MFC硬件解码的过程当中的中间变量,就相当于指向贯穿于我们程序主干部分的指针,通过它可以得到整个硬解码过程的清晰函数结构。
要执行SsbSipH264EncodeExe()函数。要做的是对MFC内部的一些结构体进行初始化,然后就到了很关键的一步:
r = ioctl(pCTX->hOpen, IOCTL_MFC_H264_ENC_INIT, &mfc_args);
这一步其实就是把我们刚才设置好的关于MFC的初始化参数传递到我们内核的驱动程序中,使得驱动程序能够根据我们提供的这些参数对设备进行相应的初始化工作。
在这里IOCTL_MFC_H264_ENC_INIT是制定设备的编码格式,pCTX->hOpen是设备的描述符,mfc_args里转载了MFC所有的参数。完成了这些才算是真正的完成了初始化的工作。
总结一下我们刚才经过的步骤:
1.       打开设备节点
2.       进行内存到应用的内存映射
3.       初始化关于MFC设备的机构体,并且提供相应的参数
4.       把_MFCLIB_H264_ENC参数传入MFC跟深层次的结构体当中
5.       通过ioctl函数把这些参数传入到内核当中
       

初始化完成以后我们就要正式开始编码了,现在看一下mfc_encoder_exe()函数的实现大致过程。其实运行的过程非常的简单:


SsbSipH264EncodeGetInBuf(handle, 0);
SsbSipH264EncodeExe(handle);
SsbSipH264EncodeGetConfig(handle, H264_ENC_GETCONF_HEADER_SIZE, &hdr_size);
SsbSipH264EncodeGetOutBuf(handle, size);
 

看以上这几个函数,其作用通过读函数名字我想就已经非常清楚了,步骤如下:
1.       首先得到输入图像的地址buffer
2.       然后进行编码
3.       第一次的编码需要传入配置参数
4.       得到输出的经过编码的图像的地址(通过内部结构体传递)和大小

 
分析完以上过程之后,最后就是完成编码后的处理函数


static void mfc_encoder_free(void *handle);


其实它当中就是调用了一个SsbSipH264EncodeDeInit(handle);函数
里面其实只是做了一件事:munmap(pCTX->mapped_addr, BUF_SIZE);
其实这就是一个解除映射的过程。
s3c6410开发板 linux下 摄像头测试代码 s3c6410 开发板 摄像头 测试代码 s3c6410 开发板 摄像头 测试代码 linux下的测试代码。内核版本2.6以上。 注:这只是测试代码,linux内核要有摄像头驱动才行! 立即下载

相关推荐

ok6410和210的qt打开摄像头程序

usb的摄像头采集视频程序,直接用qt编译,就能在6410上运行。

vlc加入s3c6410 MFC硬件解码器,PP视频输出

最近在开发基于LINUX 的MX27视频可视电话,VGA硬件编解码,硬件YUV2RGB比较流畅。但UI一直没有比较好的方案,在没有窗口管理系统时,管理QT程序同非QT视频窗口非常麻烦。想用Andriod, 但由于Freescale没有提供MX27比较新的内核,挪到Andriod上工作太多,准备看看Samsung 6410视频硬件解码如何。 599元买了一块FriendlyARM的Tin

创造晴天 3689

usb摄像头在ARM上的测试程序

luvcview是一个开源项目,专注于UVC摄像头的测试,只要您的摄像头支持UVC驱动,即可使用luvcview测试程序,如何知道自己的摄像头是不是支持UVC驱动呢?在这个网站上查一下,看看自己摄像头的ID是不是在支持的列表中,http://www.ideasonboard.org/uvc/

S3C6410 MFC视频硬件解码

<br />做了一个星期的s3c6410,有很多弄懂得,也有很多没清楚的,感觉比较混乱,还是理一下思路。<br />0. 知识点<br /><br /> <br />1. 视频解码的整个流程大致如下:<br /> <br /><br /> <br /> <br />说明了视频文件解码的整个过程,而在做s3c6410硬件解码中,我们需要关注的是怎样把一个视频文件(avi/mkv/mp4)拿来,然后做demuxer变成raw video stream,接着就能输入到硬件中:<br /><br />得到raw v

暂时为空 5145

三星6410摄像头测试程序流程分析

 作者:嵌入式领域著名讲师  O(∩_∩)O  牛牛猛  华清远见金牌讲师                                       点击链接加我好友!http://student.csdn.net/invite.php?u=111047&c=758a60d66d3a92d1欢迎大家去我CSDN博客上踩踩我的个人主页 <span sty

niuniumenghua的专栏 2372

S3C6410 MFC decode H.264流程

     自己的MID平台播放视频支持的格式有限,按照应用要求需要扩展更多的格式。6410自己是带MFC(multi format codec),支持MPEG4,H263,H264的硬解码。通过ls -l /dev可以得知s3c-mfc的驱动模块已经加载了,在android中操纵MFC的编解码部分是在external/opencore/codecs_v2/video/s3c_mfc目录下,发出IO

zhandoushi的专栏 5830

s3c6410使用MFC-API进行MPEG-4格式解码及LCD播放代码注释

/*将MPEG-4格式的视频显示到LCD上*/#include #include #include #include #include #include #include #include #include #include #include #include

hxgqh的专栏 2943

S3C6410 MFC H264 编码流程分析

转自:http://blog.sina.com.cn/s/blog_65f6a0520100rgg7.html 在代码分析开始前需要对一个概念进行解释,就是MFC。 Multi Format Codec的缩写,是ARM微处理器内部一种支持多种硬件编码方式的硬件电路,能够编码/解码MPEG-4/H.263/H.264(30fps)等多种格式的多媒体影像。 TOP6410开发板使用的是ARM

leo115的专栏 7064

s3c6410MFC编解码实例

对三星提供的实例进行修改,让其代码更加简洁,实现利用MFC将YUV编码成H264,和将H264解码成YUV。

基于S3C6410+CMOS摄像头的H264图像压缩 摄像头输出YUV420格式图像

本程序在S3C6410开发板上测试都是可以用的,CMOS摄像头用的是OV9650,视频采集使用V4L2视屏设备驱动接口,设置采样格式为YUV420,然后进行MFC硬件的H264编码,得到H264格式的视频图像.

s3c6410 jpeg编码 linux,立宇泰ARMSYS6410开发板推出Linux2.6.28、android、ubuntu三个linux系统版本,提供最...

ARMSYS6410开发板采用了Linux-2.6.28作为标准版的linux内核,其中集成了丰富的驱动资源,充分展现S3C6410的各项特性,包括硬件编解码、2D/3D加速、显示协处理、TVOUT输出、视频采集和编码、4路串口、2路SD/MMC接口、1路10/100M以太网接口、1路USB host接口等等,使立宇泰6410开发板成为目前linux配置最为强劲和最完整的开发板之一。ARMSYS6...

weixin_30537231的博客 202

UT-S3C6410开发板环境下的多种嵌入式操作软件资源之Win CE6.0【友坚科技】

WinCE6.0软件资源软件特性:  ·CPU主频稳定工作于667MHz<br /> ·视频硬件编码、解码支持MPEG-4/H263/H264/VC-1<br /> ·2D、3D图形硬件加速、D3D Mobile,支持OpenGL ES1.1 & 2.0<br /> ·支持SD卡+USB2.0升级系统 <br /> ·支持TCPMP播放器完美硬件解码,MPE

smiletaolin的专栏 2080
上一篇: Video4Linux简介
下一篇: DMA简介
ckangle
博客等级 码龄14年 45粉丝 15原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值