您的位置:首页 > 其它

让s60 3rd支持flash播放吧

2009-10-20 09:32 169 查看
让s60 3rd支持flash播放吧-(1)

北京理工大学 20981 陈罡
adobe的flash播放器到现在可谓是家喻户晓了,网上无数的网站页面上为了
给用户很绚丽的视觉体验,都不约而同的使用了flash动画。有了adobe公司
的强大的flash动画制作工具,任何效果的界面和特效都是可以做出来的,
甚至基于flv格式的视频也没有任何问题。可以说flash技术给互联网网站带
来了一次影响深远的变革。
在手机平台上发展如何呢?手机上目前对动画的支持仅仅是限于对gif和svg
动画的支持,gif我就不多说了,是一个老标准了,而svg则是比较新兴的
基于xml的矢量动画标准,该标准目前还在处于一个不断变化和发展的状态中。
每次我去检索和查找svg标准的相关文献,总能找到新的特性。
至少对于symbian 3rd来说已经开始支持svg图片的缩放、显示等操作了(虽然
还十分有限,只能用于应用程序图标以及mbm编译好的资源文件里面),但毕竟
在手机上从api支持还是从制作工具而言都是十分有限的,而且对于交互操作来
说,虽然svg支持event事件,以及内嵌java script,但是这些对于手机,尤其
是手机应用程序来说,还是很奢侈的一件事情。个人感觉svg号称是全部内容都
是xml格式的,可视化的,但是想想看,一个很复杂的图形,xml会增长到很多
很多行,即使能够看懂又能如何?!太多了,没那么多精力去看啊。不如把它
当成是“黑盒子”处理好了。
反观adobe公司的flash文件格式,经过互联网的“酒精”考验,已经发展得十分
成熟了。目前adobe公司推出了flash lite以及面向运营商的ODP(On-Device
Portal) flash cast。其中flash lite就专门定义了对手机和嵌入式设备的交互,
而且本身flash文件格式就支持action script,尤其是action script中的
fs_command()函数,可以从flash文件中向flash播放器传递参数和数据。这就
使得用flash制作特效界面,而采用c/c++编写后台服务成为了可能。而且从制作
工具的角度来看,adobe公司的flash编辑器无疑是目前功能最强大、最完善的
工具了。
adobe公司推出了自己的flash lite标准以后,就自行开发了手机上的flash lite
播放器,首先这是很不错的做法。可以为程序员做后续开发节约很多时间。就跟
在pc上开发应用程序一样,只需要调用一下flash插件,就可以在你的程序中实现
绚丽的flash效果,以及播放flash动画了。但是有一利就必有一弊,adobe公司自己
开发的flash lite播放器就相当于垄断了action script的话语权,例如,adobe公司
在flash lite中创造了fs_command2()函数,专门用于将参数传给flash播放器,然后
执行动作,并返回结果的。我不知道adobe的flash lite是否支持第三方开发者扩展对
action script函数的响应,不过貌似flash lite的播放器已经可以对开发者通过
fs_command和fs_command2函数传入的参数进行响应了,但是能否允许开发者自己定义
新的功能和fs_command的参数,就不得而知了。
综上所述,如果能够在手机上实现flash播放、交互还是很不错的选择。而且最好能够
自己控制flash的播放器,那样的话就可以任意加入对action script的支持了,甚至
可以自己创造出自己的script格式。
处于这一点考虑,偶决定开始研究一下,实验一下,看看能实现手机上的flash播放器。
看了两天adobe发布的flash文件格式,感觉还是很有希望的。当然,具体的操作起来,
自然需要借助于open source的力量了。于是乎,简单搜索了一下,有以下几个项目可
供参考:
(1)gnash
这个目前还在积极的开发过程中,可以用日新月异来形容。它目前是支持flash版本最高
的一个开源项目。其中用到了很多的库,例如jpeglib,zlib,libpng以及一些音视频的
解码程序,例如ffmpeg或者gstreamer(二者可选其一),绘图方面可以支持libagg或者
libsdl,内部进行trans matrix变换的时候使用了open gl的api,在linux下面对应的
库是mesalib,全部采用c++开发,大量使用了boost模板库。总体来说它的功能与复杂程度
是成正比的,毕竟gnash支持flash文件标准到了7.0嘛。
(2)gameswf
这个很早就停止开发了,其实它就是gnash的前身。gnash开始了,它自然就停止了。
不过要想完全看明白gnash,先看看这个也是很有启发的。它支持open gl以及direct 3d
两种渲染引擎,好像还支持sdl不过我拿到的版本已经被改的面目全非了。目前,gameswf
对于flash的支持最多到flash 6.0。如果移植到symbian上,目前,
symbian上的open c的最新插件已经可以支持boost和open gl es了;移植到win mobile
上,当然了direct 3d肯定是没有问题的了。这个库是最合适的了(这也只是从理论上来说,
真正的移植工作还有很长的路要走)。
(3)flirt
这个项目很早就非常有名了,早在2004年以前就开始了基本的开发,可惜到2006年年底
就停止开发了。它完全不借助于boost以及stl之类的库,也没有使用open gl以及direct
3d,完全是c/c++开发,其中使用到了jpeglib以及zlib和libmad,这些都不是问题了。
大量使用了标准c的posix库。自己重新实现一下,或者使用symbian open c都是没有问题的。从
依赖库的角度来看,这个flirt的手机移植难度是最低的。

经过几天的hack,总算可以在symbian 3rd上面成功播放flash文件了。
贴个图下次接着写(要开会了。。。):



让s60 3rd支持flash播放吧-(2)

北京理工大学 20981 陈罡

上一篇,大致分析了一下目前比较有名的开源的flash播放器的构成以及大致需要的技术和
移植到symbian、win mobile平台的可行性。最后,我们还是选择flirt做为入手的起点,
毕竟它是不借助外部的库,自己自成体系进行swf文件的解码、计算的。(当然,这里的
自成体系是指不借助direct 3d和open gl之类的库,以及boost之类的库;其实本质上,flirt
仍然要依赖三个主要的库,jpeglib,zlib和libmad)。

尽管有了nokia symbian的open c的强力支持,移植起来也并非一件很容易的事情。偶就
把移植的过程以及遇到的难点整理一下,一来为了备忘,二来为后来者铺平一些道路。
下面的全部移植过程均采用flirt20060121的最新版本来做的,到source forge上面下载源代码
自然是必不可少的预先准备工作,以及symbian 3rd sdk,open c安装这些就不赘述了。

(1)将代码放入symbian项目中
这一步主要是把代码拷贝到新建的symbian工程目录,然后修改mmp文件,将所有的.c文件的后缀
改为.cpp,然后添加open c所需要的lib和include路径,例如:

systeminclude /epoc32/include/stdapis
library libc.lib // 这个是open c的library
library libm.lib // 这个是math.h需要的一些数学库函数

(有用过偶的测试代码的朋友反映还需要加入estlib.lib,才能编译过去。这一点很奇怪,
偶采用vs2005+carbide.vs 3.0.1+s60 3rd sdk fp1是没有加这个lib也可以运行的)

(2)尝试编译一次

呵呵,这一次必然是编译不过去的。偶第一次编译竟然出了980多处错误,已经足以让偶处于
半昏迷状态。不过这次编译,可以让偶从宏观上了解一下,整个项目目前都在哪些地方存在问题。
例如某些linux相关的头文件找不到,某些linux专用的函数,某些跟硬件接口有关的,例如mixer
某些库有关的jpeglib, zlib, libmad之类的接口和头文件等等。这样会把问题暴露得比较彻底一些
为了下一步开始动手做port有一个整体的overview。

(3)从全局的定义开始入手

主要就是types.h和dd.h这两个文件了。从功能上来看,dd.h主要负责debug log输出的,这些是
采用stdio库的文件操作函数来完成的,在这个地方可以考虑采用RFileLogger类来完成log日志操作
替换。然后就是关于一些数学库函数的处理了,例如有下面这一段:

#ifdef WIN32
#include <float.h>
#define rint(a) floor((a)+0.5)
#define isnan(a) _isnan(a)
#define finite(a) _finite(a)
#endif

这是对ieee浮点数支持的函数,这里的nan的意思是not a number,不是一个数字,代表当前的浮点数
按照ieee的浮点数标准来说不是一个数字,还有finite之类对无穷大/小之类的定义。这些数学函数主要
是用来保证double类型的浮点数在解码和运算过程中是合法的。必需要有喔,否则symbian的模拟器就会
出现kernel exec 3的那种不知所云的错误退出。(这是偶的惨痛教训)
再有就是数据类型的定义了,这里需要说一下的就是SInt64,用的是long long。但是这个数据类型在
symbian中是没有的,arm的core通常最大只有32位,因此需要把它改为32位的即可。所幸在程序中没有
怎么用到这个变量。然后就是boolean的定义了,这些基本数据类型的定义相信有些经验的开发者都可以
很优雅地处理掉。

(4)修改变量命名以及强制类型转换

这个纯粹是浪费时间了,这个flirt是采用纯c预言编写的,因此通篇采用经过封装过的dd_malloc(),
dd_realloc(),dd_free(),这些都是void *类型的内存分配函数,在原始的代码中都是直接赋值的方式:

struct ABC * pabc = dd_malloc(sizeof(struct ABC)) ;

类似这样的代码,这在c99编译器上编译是没有任何问题的,但是对于c++的编译起来说,就严重成为一个
error,因此,需要一个个老老实实地修改为:

struct ABC * pabc = (struct ABC *)(dd_malloc(sizeof(struct ABC))) ;

这样的代码才可以,整个过程很冗长,让人乏味,把这些改完偶已经口吐白沫,又一次半昏死状态。。。
或许可以通过某些编译选项解决这个问题,不过为了防止链接的时候.c的obj与.cpp的obj发生欲哭无泪的
问题,只好忍了。再有,就是代码里面有不少地方、变量命名都是采用new, class, list之类c++保留字
做为变量名(list不是,它是stl模板保留字了,请不要嘲笑偶,这里只是举个例子)命名,因此编译的时候
肯定是过不去的。

解决方法很简单,在原有的保留字命名的后面加上个_v, _p即可。

例如:
int new ;
可以改为
int new_v ;
诸如此类,不再一一讲述。

(5)对于字节存储和表达式顺序的修改

这里就是关键了,需要非常重视。打开swfcore/format/read.cpp就会看到关于表达式的处理顺序问题
这里只举一个例子,说明一下原理:

return (long)readUInt8(r) + (readUInt8(r) << 8) + (readUInt8(r) << 16) + (readUInt8(r) << 24);

这是read.cpp文件中,long readSInt32(ddReader* r)函数的函数体。
这里采用了一个一个字节读取出来,然后拼接成32位有符号数字的方法,但是从symbian 3rd模拟器的效果
来看,这种拼接是错误的。我想可能是由于编译器对表达式各元素处理的先后顺序导致的。举个例子来说,
我希望读取的数字为:18 38,而通过上述表达式计算的结果却是38 18 00 00。这个时候就可以灵活地考虑
采用c预言里面的union(共用体)来解决这个问题,
示例代码如下:
register union {
int val ;
unsigned char a[4] ;
} data ;
data.val = 0 ;
data.a[0] = readUInt8(r) ;
data.a[1] = readUInt8(r) ;
data.a[2] = readUInt8(r) ;
data.a[3] = readSInt8(r) ;
return (long)(data.val) ;
代码看上去罗嗦了许多,肯定还有更好的解决方法,目前偶只是要确保数据正确和代码可以工作。
修改完毕read.cpp中几个文件读取函数上述问题以后,基本上剩下的工作就是小打小闹了。

(6)最后说一下解码结果格式

利用flirt在手机上解码出来的数据的存放格式是RGBA,四个字节表示一个像素。这一点在显示图像的时候
要额外注意了。可以用最简单的方式,采用flirt提供的宏COLOR_BLUE(), COLOR_RED(), COLOR_GREEN()来
获取三原色,还有一个字节就是alpha透明度通道了。在偶的测试代码中没有理会这个alpha透明通道,结果
导致有些效果显示不全。以后有时间再做调整吧。
另外,偶已经把jpeglib和zlib都移植上去了,播放flash动画应该问题不大,但是libmad还没有腾出时间来

加上去希望有兴趣的朋友可以沿着偶的思路继续做下去把libmad解码器移植到这个flash播放器上去。这样
依赖symbian 3rd就不必非要依靠adobe的flash lite也可以播放flash动画了。
还有,在这个port实验中,DestroyActionEngine()这个函数有内存泄露问题还没有解决,同样希望有兴趣的
朋友来解决这个问题。

希望这篇文章对各位后来者有用,谢谢大家。
附上模拟器上运行的效果图片:



附上源代码:
文件: FlashTest.rar
大小: 610KB
下载: 下载

PS:
(1)程序编译后请把a.swf放到模拟器的c盘根目录下面
(2)选择菜单play
(3)按向下方向键,即可一帧一帧播放flash
(这里偶懒得查键值,直接写了个数字上去,如果按向下方向键不能播放的朋友清酌情修改)
(4)按stop释放资源

文章出处:http://blog.chinaunix.net/u/26691/showart_1011738.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: