S3C6410 MFC H264 编码流程分析

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

转自:http://blog.sina.com.cn/s/blog_65f6a0520100rgg7.html

在代码分析开始前需要对一个概念进行解释,就是MFC

Multi Format Codec的缩写,是ARM微处理器内部一种支持多种硬件编码方式的硬件电路,能够编码/解码MPEG-4/H.263/H.26430fps)等多种格式的多媒体影像。

TOP6410开发板使用的是ARM11的核,我们现在要利用这个ARM内部的硬件编解码电路来直接对摄像头采集到的图像进行基于硬件的编解码。首先在项目开始前需要对TOP6410的性能做大体的测试,现在我们使用的是三星提供的测试程序,通过对这个测试程序的分析可以很好地让我们了解基于系统级的图像编解码函数的调用机制,有利于我们顺利的提取图像并且进行进一步的处理。

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

 

static void      *handle;

 

 

static void *mfc_encoder_init(int width, intheight, 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, intframe_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", "SsbSipH264EncodeInitFailed\n");

                  return NULL;

        }

 

        ret = SsbSipH264EncodeExe(handle);

 

        return handle;

}

首先要注意的是传入的参数,它们分别定义了每一帧图像的长宽,帧的速度,比特率,GOPGroup of Pictures)策略影响编码质量(设置编码的质量系数)。

函数的作用是对整个MFC的参数进行设置

这里有一个frame_size,有人问为什么要定义成那么大,我们需要的图像每一帧的大小是我们可以自己定义的,我们在代码执行前一般都会开一个缓冲区来存放每一帧的数据,由于我们开的缓冲区给每帧的大小就是那么大,所以这里也好配合我们之前开辟的缓冲区大小进行编码。

SsbSipH264EncodeInit()这个函数可以说是真正的开始进入编码的初始化过程,现在让我们进去看看。

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

hOpen = open(MFC_DEV_NAME,O_RDWR|O_NDELAY);//打开设备节点

 

// mapping shared in/out buffer betweenapplication 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)

其实这就是一个解除映射的过程。


Samsung MFC(Multi Format Codec) Fireware 三星MFC固件,版本从V5-V8支持exynos4412 等高端处理器 立即下载

相关推荐

H264MFC播放器

这段代码花了我很长时间,也参考了不少大神的代码。用live555接收H264数据流,用方法ffmpeg解码,然后在MFC上面显示出来。当然,其中还存在一些Bug,希望大家相互交流一下,给我提一些建议。现在我主要是用live555的服务器或者android手机上运行spydroid来测试,均是可以播放的。

h264 按帧解析源码h264 按帧解析源码h264 按帧解析源码h264 按帧解析源码h264 按帧解析源码h264 按帧

h264 按帧解析源码h264 按帧解析源码

h264码流分析器(MFC源码)

仿elecard stream analyzer 写的MFC代码,有很多不足,对了解h264码流有帮助,供大家学习之用

基于使用VC2010和MFC开发的H.264码流分析器程序源代码.zip

基于使用VC2010和MFC开发的H.264码流分析器程序源代码,可供学习及设计参考。

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

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

niuniumenghua的专栏 2372

Linux3.X下的Samsung MFC(Multi Format Codec) Firmware

作者:咕唧咕唧liukun321来自:http://blog.csdn.net/liukun321三星系列处理器,从S3c6410开始SOC上就集成了一个MFC(Multi Format Codec)多格式媒体编解码器硬件模块。并且三星的linux BSP开源了对它的驱动。看过MFC驱动的朋友,肯定发现了,在驱动初始化过程中,内核需要加载一个Samsung MFC 固件。没有它MFC是用不了的。下

咕唧咕唧shubo.lk的专栏 6601

MFC h264分析源码

MFC h264分析源码 仿elecard stream analyzer 写的MFC代码,对了解h264码流有帮助,供大家学习之用

只有MFC编码没有解码 基于H_264的嵌入式实时监控系统设计

基于H264编解码的视频监控在实际中的应用

ffmpeg解码h264视频文件,并且实时显示(mfc

用ffmpeg解码h264视频文件,并且将解码出来的每帧图像用opencv封装进行显示,ffmpeg采用的是最新的3-2版本。另外,程序预留了将每帧图像保存成bmp的接口,注释详细。使用时须配置好ffmpeg和opencv,然后将自己的h264文件名称修改为1.h264 并将其置于当前目录即可运行(可作为2次开发的参考)

S3C2440和S3C6410性能比较

 比较项目 S3C2440 S3C6410 内核 ARM920T ARM1176JZF-S 主频 400MHZ 533MHZ/667MHZ 处理器类型 16/32-bit RISC 16/32-bit RISC 设计目标 高性能、低功耗 高性能、低功耗、高性价比 主要应用 手持设备 2.5G和3G通信服务 内部总线结构 32/16-bit 64/32-bit 多媒体硬件编码器/解码器 无 有(支持...

无语僧 7503

s3c6410硬件mfc解码分析-H264

H264的解码流程: @函数Test_Display_H264: 1 打开源文件,返回文件描述符in_fd,函数open() 2 将文件的相关信息存放的结构体stat中,函数fstat(),比如文件的大小 3 将文件映射到内存中,函数mmap()返回首地址,in_addr 4 打开post processor,返回文件描述符,pp_fd 5 打开frame buffer,返回文件描述符fb_fd; 6 函数FrameExtractorInit,初始化帧提取器 FrameExtractorIn

ccskyer的专栏 3522
上一篇: S3C6410 MFC H264 解码分析
下一篇: 基于JRTPLIB库的RTP数据传输设计文档
eten
博客等级 码龄16年 483粉丝 104原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值