Chinaunix首页 | 论坛 | 博客
  • 博客访问: 538538
  • 博文数量: 70
  • 博客积分: 3162
  • 博客等级: 中校
  • 技术积分: 850
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-23 13:30
文章分类
文章存档

2013年(1)

2012年(4)

2011年(1)

2010年(7)

2009年(9)

2008年(20)

2007年(3)

2006年(25)

分类: LINUX

2010-05-07 21:15:31

前面写了两篇blog,介绍mfc的hw decoder加入到mplayer和vlc的事情,由于平时懒散惯了,很少总结完整的技术文档,只是收到的邮件太多,我有空都尽量及时回复,只是问的邮件多了,自然很多问题都是重复的,总是回复类似的问题,实在太枯燥,也没那么多时间.现在随机选几个代表性的回复,贴在这里,给需要的朋友参考!
Q:在mplayer那部分代码加入S3C6410的MFC
A:我提供一种方式:
1.在etc/codecs.conf里面添加自己的decoder
2.编写vd_s3c**.c,格式可以参考 vd_rawvideo.c和vd_real.c
3.将vd_s3c**加入到vd.c里面
4.vo部分可以添加 vo_s3c**.c
5.将vo_s3c*加入到video_out.c
具体流程可以阅读mplayer源码DOC/tech目录下的文档

Q:我H264的video stream 同样是baseline的,我封装了一个文件,
不能解出来, 可能是格式上有出入,但我对H264不是很了解。
我真正要用的是,从网络上获取了H264 的video stream后,用S3C 6410 的MFC 来解码。
但我不知道怎么下手做了
A:仔细看下MFC的那几个文档就可以了,文件封装的H264可能需要自己做demuxer,那个文档里面里面有提,ring buf模式支持文件封装的数据,我没测试,linebuf只支持标准的es流,我是用mplayer把文件demuxer出来的h264数据送到 linebuf模式的mfc,这样来测试的。
网络上取H264数据,是rtp/udp还是http?反正都是文件封装的问题,最好用基本的es 流,如果没有文件封装,那需要在本地解析组装NAL

Q:我收到的buffer 根本就没有传给MFC 的 line_buffer. 这个我不明白 ,我也是按MFC 的测试程序做的。 因为给line_buffer 的数据为空,所以一直就没P,P,…… I, P…… 进去,解出来就是花的。我初始化是在一个函数里,解码是在别一个函数里
A:decoder是从pStrmBuf获取H.264的数据,然后把pYUVBuf里面的yuv数据取出来显示,所以你每次都要更新pStrmBuf
更 新pStrmBuf的方法可以自己实现,也可以用mfc实例里面现成的NextFrameH264函数:
使用NextFrameH264函数的时 候,需要设置源数据(H.264)的的起始地址p_start和结束地址p_end,所以在每次调用NextFrameH264函数之前都需要下面这段代 码重新设置p_start和p_end
        pFrameExCtx = FrameExtractorInit(FRAMEX_IN_TYPE_MEM, delimiter_h264, sizeof(delimiter_h264), 1);
        file_strm.p_start = file_strm.p_cur = (unsigned char *)data;
        file_strm.p_end = (unsigned char *)(data + len);
        FrameExtractorFirst(pFrameExCtx, &file_strm);
所以正确的顺序应该这样:
先设置 p_start,p_end,然后调用NextFrameH264更新pStrmBuf,然后再decode,再取yuv
-->set_pos(p_start,end)->update_pStrmBuf(NextFrameH264)-->decode->display->...

你 的代码结构里面会遇到一个问题,就是开始初始化的时候的H.264源数据会没有播放,所以影片开头的一些画面可能会看不到,你可以根据自己的实际程序结构 组织下,比如mfc的测试代码是每次播放完之后就预取下帧数据,所以他的代码是这样的结构:
init->--/|\->decode->display->getNextFrame---|
            |---<----------------------------------|
你也可以自己组织其他模式,比如他还支持decoder和 diaplayer的同步,所以就可以用多线程模式来提高效率

Q:我看了MFC测试程序的代码,他把SPS帧和第一个I帧之间的P帧给丢弃掉了,这个是正确的处理方法吗?
A:mfc初始化的时候必须要按照他那个文档说的,就是config stream(pps,sps,sei,I frame)这样初始化成功后,才可以送入p帧或者I帧正常解码,如果没有完整的config stream,只能在整个数据里面搜索,直到成功搜索到为止,具体可以看mfc的实例代码,他里面也应该是这样的实现。
0001是nal的 startcode,查看实际的h264码流,有时候也可能是001,所以这时候要具体分析下,大致就是如此

Q:是否有S3C.C的原 碼可以供參考 ,謝謝
A:不提供源码.下面是大概的实现思路
s3c.c是按照vlc codec接口标准自己写的代码
也就是用mfc的api实现一个符合vlc codec接口
mfc 的api实现方法可以看mfc demo
vlc codec接口可以参考vlc代码目录下codec/rawvideo.c以及codec/realvideo.c的实现
模仿而已
OpenDecoder
CloseDecoder
DecodeBlock
需要实现类似这样的函数
还可以去看看vlc官方文档
http://wiki.videolan.org/Documentation:Hacker%27s_Guide/Decoder
阅读(18893) | 评论(19) | 转发(2) |
给主人留下些什么吧!~~

huaiyuren2010-06-13 17:20:03

唯一不解的是,我在init方法中还需要按照样例如下调用打开整个文件,否则不可显示:printf("I Am Edward.\n"); // in file open in_fd = sh->ds->demuxer->stream->fd; // get input file size fstat(in_fd, &s); file_size = s.st_size; printf("input file : %d\n",in_fd); // mapping input file to memory in_addr = (char *)mmap(0, file_size, PROT_READ, MAP_SHARED, in_fd, 0); if(in_addr == NULL) { printf("input file memory mapping failed\n"); return -1; } /////////////////////////////////// // FrameExtractor Initializ

huaiyuren2010-06-13 14:07:25

现在有一个问题,无法把自己的vo加入mplayer中。我实现了vo_s3cpp.c并加入了video_out.c。可是在执行./mplayer -vo help后看不见s3cpp。

huaiyuren2010-06-02 09:59:38

问题咨询:请问你编译内核和mplayer使用的交叉编译工具是什么?版本号又是多少?我只能使用cross-4.2.2-eabi编译内核,而使用arm-none-linux-gnueabi-arm-2008q3-72-for-linux编译mplayer.

huaiyuren2010-05-27 15:25:18

前面初始化都成功,运行到下面代码就自动跳出,mplayer提示sigal 11,不知道你有什么建议。 nFrameLeng = ExtractConfigStreamMpeg4(pFrameExCtx, &file_strm, pStrmBuf, INPUT_BUFFER_SIZE, NULL);

huaiyuren2010-05-26 15:32:00

关于第四步:4.vo部分可以添加 vo_s3c**.c。我看远比编写vd_s3c**.c要复杂吧?第四步应该不是必需的啊。但是我省略第四步后,运行时会提示:Requested video codec family [s3cmpeg4] (vfm=mfc) not available Cannot find codec matching selected -vo and format 0x10000004。 为什么呢?