分类:
2010-03-02 15:39:16
TCPMP作为一个强大的开源播放器,支持ARM,MIPS,SH3,X86等硬件平台。我分别在WINCE ARMV4与WINCE MIPSII平台对TCPMP进行了测试,个人感觉TCPMP对ARM平台的支持比MIPSII平台要好的多。(具体型号分别为 ARM926EJ-S 与 AMD/Alchemy,MIPS-AU/200)。
一个分辨率为320X240,用MP43压缩的视频文件在ARM平台下可以流畅播放,而在MIPSII平台下要卡的多。而640X480,MP43压缩的 视频在MIPS平台下甚至无法显示。更为蹊跷的是用TSCC压缩编码的屏幕流文件在ARM平台下可以流畅播放,而在MIPS平台下也无法显示。
本文带着这样的疑问,来窥探下TCPMP的源码。
在Common项目中的codec.c文件里有一个Process(codec* p, const packet* Packet, const flowstate* State)函数,(被player.c中的ProcessThread函数调用),这个函数的功能应该就是对每一帧视频数据解码,并显示。此函数中有两 句很重要的语句。1 p->Process(p,Packet,State); 2 p->Out.Process(p->Out.Pin.Node,&p->Packet,State); 语句1调用解码器进行解码(实际调用的应该是ffmpeg.c中的Process函数),语句2调用视频渲染函数对解码的视频进行渲染,显示。(实际调用 的应该是overlay.c中的Blit函数)。在overlay.c中的Blit函数实际调用的是overlay_gdi.c中的Blit函数来进行视 频渲染的。而只有在满足一定条件(if (p->Soft && p->Inited && p->Show && Packet->Data[0]))下,才会调用overlay_gdi.c中的Blit函数。跟踪表明,在MIPS平台下,正是因为 p->Soft == 0,导致条件不成立,无法执行overlay_gdi.c中的Blit函数,所以视频无法显示。 那p->Soft在MIPS平台下为什么为0呢?
在播放一个视频之前,TCPMP会进行初始化工作,其中会调用blit_soft.c中的BlitCreate函数,这个函数应该是针对不同的平台与视频 格式,对视频渲染代码进行优化。在BlitCreate函数中,会调用BlitCompile函数,针对不同视频格式(YUV,RGB)与平台 (ARM,MIPS,SH3)生成不同的视频渲染动态代码。当为(RGB ARM)时,会调用Any_RGB_RGB()函数生成代码,当(YUV ARM)时,会调用Fix_Any_YUV()函数生成代码,当(YUV MIPS)时,会调用Fix_RGB_UV()函数生成代码,唯独为(RGB MIPS)时,没有调用任何的代码。从而导致在执行CodeBuild()函数后,p->Code.Size = 0, 从而 p->Entry为NULL.自然也就有了p->Soft == NULL.
解决这个问题,可以再MIPS平台下实现类似ARM4的Any_RGB_RGB功能,但此难度不小,需要了解MIPS与ARM平台的指令系统,还要读懂Any_RGB_RGB代码。另一种思路可以先将RGB转换为YUV,再进行视频的渲染。
另外,将Common项目中的BLITTEST宏打开,不在调用针对不同视频格式与平台进行优化的代码,而是统一调用了BlitUniversal函数生 成代码,此时在MIPS平台下可以正常显示320x240之下的TSCC编码文件。但还是很卡。作者提示此方法很慢,仅为兼容性与测试所用。
本应画一个示意图说明上面函数调用过程。