嵌入式Linux下基于FFmpeg的视频硬件编解码 (3)

X264_frame函数执行编码过程。需要注意的是data参数保存了需要编码的数据,是一个四维的数组,要把它转换成一维数组用于S3C6410编码器输入。另外,编码数据存在空的情况,也就是空帧。这是需要处理的,方法是返回“0”,表示没有输出数据,否则程序运行时会出现段错误。

static int X264_frame(AVCodecContext *ctx,uint8_t *buf,int bufsize,void *data){

……

//空间转换

if(frame){

memcpy(x4>in_buf,frame>data[0],ctx>width*ctx>height);

memcpy(x4>in_buf+ctx>width*ctx>height,frame>data[1],ctx>width*ctx>height/4);

memcpy(x4>in_buf+ctx>width*ctx>height+ctx>width*ctx>height/4,frame>data[2],

ctx>width*ctx>height/4);

}

else

return 0;//空帧,返回

//执行编码过程

ioctl(x4>dev_fd,S3C_MFC_IOCTL_MFC_H264_ENC_EXE,&x4>enc_exe);

//编码数据输出

bufsize = x4>enc_exe.out_encoded_size;

memcpy(buf,x4>out_buf,bufsize);

……

return bufsize;

}

X264_close关闭函数用于编码结束后的资源释放,包括取消空间映射和关闭设备文件。

static av_cold int X264_close(AVCodecContext *avctx){

//取消空间映射

munmap(x4>addr,BUF_SIZE);

//关闭设备文件

close(x4>dev_fd);

return 0;

}

解码函数的实现过程类似于编码函数,包括空间转换、执行解码和解码数据输出。初始化时使用S3C_MFC_IOCTL_MFC_H264_DEC_INIT参数,执行时使用S3C_MFC_IOCTL_MFC_H264_ENC_EXE参数。

4 运行测试

s3cx264编解码器添加到FFmpeg后,可以通过以下方式测试:

① 用如下命令编译FFmpeg。

./configure enablecrosscompile

arch=armv6 cpu=armv6

targetos=linux crossprefix

=http://www.likecs.com/usr/local/arm/4.3.2/bin/

armlinux

② 运行 ./ffmpeg codecs查看可以找到s3cx264编解码器,如图2所示。

嵌入式Linux下基于FFmpeg的视频硬件编解码

图2 FFmpeg显示s3cx264编解码器信息

③ 结合USB摄像头测试s3cx264编码。运行 ./ffmpeg s 320x240 r 50 f video4linux2 i /dev/video2 vcodec s3cx264 test.mp4 可以看到FFmpegg正使用s3cx264编码器将USB摄像头采集的数据编码压缩成test.mp4文件。test.mp4能够正常播放显示。

以上测试说明已经成功地将s3cx264硬件视频编码器添加到了FFmpeg中,能够编码视频数据,可以运用到其他使用FFmpeg库的多媒体程序中。

结语

对于多媒体开发来说,编解码时使用FFmpeg多媒体库是一个不错的选择,支持较多的音视频编解码,编程接口简单易用。了解FFmpeg编解码过程,熟悉FFmpeg硬件编解码器添加方法,对多媒体开发,尤其是资源有限的嵌入式多媒体开发有很大帮助。本文通过分析FFmpeg视频编解码过程和三星S3C6410处理器视频硬件编解码方法,在FFmpeg库中成功添加S3C6410硬件编解码器,使FFmpeg库具有H.264视频格式的硬件编解码能力,可运用于游戏设备、监控设备、视频会议设备和数字网络电视等嵌入式系统中,同时也为其他嵌入式设备添加别的视频格式的编解码器到FFmpeg多媒体库提供了参考。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwzzgx.html