20回答

2收藏

Badapple——树莓派+12864液晶视频播放实验

 

Raspberry Pi Raspberry Pi 25145 人阅读 | 20 人回复 | 2012-11-27

本帖最后由 小菜儿 于 2015-1-12 10:48 编辑

网上有很多用各种显示屏、字符界面、甚至是激光、示波器等去播放动画的视频。而在视频的选择上,很多视频播放的是Bad Apple影绘。这个视频全程黑白,所以在各种设备上播放效果都特别良好,经常被用来做各种实验,所以也有句名言“有屏幕的地方就有Bad Apple”。
我买到树莓派之后一直在想树莓派+GPIO这个组合能做些什么有意思的事情。正好最近找到了一个一直都没有玩的3.3V小尺寸12864液晶模块,就决定用这个也放一放Bad Apple,见证一下树莓派远超过单片机的实力。



视频:
http://player.youku.com/player.php/sid/XNDU4MzQwMTUy/v.swf



概要
设备与材料:
树莓派
MzL05-12864液晶模块 (控制器: ST7565)
“Bad Apple影绘”等视频资源
功能:12864液晶模块的单色视频播放
开发周期:几个小时


程序发布
程序的下载及用法,请见项目首页:
树莓派12864视频播放器 http://shamiao.com/project/raspi12864
—————————————————————————————-
注:本日志为开发过程记录。对编程不感兴趣就请读到这里为止
—————————————————————————————-


视频数据的准备
视频是以前从niconico上下载下来的原画质视频。(512×384, 3’39″=6566帧@30fps/容器mp4/视频AVC/音频AAC)
128×64单色无压缩视频的数据量是128*64*6566/8 = 6.41MiB,不大。所以为了最高效率起见,还是把视频的每一帧先处理成符合液晶屏幕的,可以直接写入液晶模块的格式。
格式是由液晶模块主控ST7565所规定的:


这个格式是纵向的,和更常见的大12864里用的ST7920(横向)不一样。个人感觉纵向的有点烦人。
处理步骤:视频 → 每一帧截图为BMP文件 → 目标文件。
中间需要在某个位置,将图片尺寸从512×384缩小为128×64。
我选择的是在“视频→BMP”这一步直接缩小。不过先转出BMP来,再把所有的BMP批处理了也可以。


视频→BMP

一处理视频就比较麻烦,工具繁多、方法复杂。
将视频转换成图片序列(当然不能一帧一帧去截图了@_@),使用VirtualDub。但是VirtualDub不能读***容器的文件,并且支持的解码器极其有限(AVC和H264都不行)……。
我是不希望用视频转换工具重新压一遍(损画质)。所以找了个解决办法:AviSynth。这个软件可以通过写脚本,将任何视频“伪装”成AVI文件,供其他软件无障碍读取。并且可以做一些简单的视频处理。
但是AviSynth也不能直接读*** AVC的文件,还需要给它加插件FFmpegSource
步骤:(1)安装AviSynth和FFmpegSource。
下载FFmpegSource时选择32位稳定发布版ffms-2.17.7z;
(2)写伪装用的.avs脚本,和badapple***放在同一目录下:
A = FFAudioSource(“badapple***″)
V = FFVideoSource(“badapple***″).BicubicResize(128,64)
AudioDub(V, A)
# 注意:这个脚本里直接顺手把视频尺寸缩小到了128×64。
(3)开VirtualDub,把.avs脚本当做视频打开。然后File→Export→Image Sequence输出图像序列,输出格式选BMP。
由于这么麻烦,所以我把我转换出来的BMP文件序列,放出来提供下载 不用管这么多步骤,用就好了:
http://dl.vmall.com/c00sg8rfgk
(Bad.Apple.开发大礼包.[逐帧BMP截图+原画质视频].z01
& Bad.Apple.开发大礼包.[逐帧BMP截图+原画质视频].zip)
注:网盘早晚是会失效的。如果不能下载,请留言告诉我。


BMP→液晶屏数据

虽然点阵液晶取模软件不少,但想做批量的,现成的程序肯定没有,自己写是跑不了的。
程序流程:读BMP文件→判断每个像素(黑或白)→转换成液晶屏规定的数据字节→写二进制文件。
读BMP我拉了一个BMP识别库EasyBMP来用——BMP格式再简单也不值得做重复发明轮子的事情 这个库可以方便的读取每个像素的RGB颜色值,功能够用了。
尽管BadApple是黑白视频,但灰度部分也是存在的——比如1’29″妹红的火焰,和1’54″幽灵乐团的影子。所以使用RGB→YUV公式中亮度分量Y的部分,先将每个像素点转换成灰度值:Y = 0.299R + 0.587G + 0.114B
我的判断方法,是简单的50%阈值:亮度过一半为白,不到一半为黑。保险,但不完美。至少因为图片太小,在0’55″就丢失掉了二小姐的“奸笑”这个细节。
总之写出的取模程序,最后输出output.bin即为动画数据。尺寸应该是一字节不差的:1024B/帧 × 6566帧 = 6566KiB。


使用GPIO/SPI驱动12864
我手里这个12864是串行驱动的,时序符合SPI——尽管只能单向写入,MISO没有用到。
树莓派的GPIO里直接有SPI。树莓派需要设置的SPI参数检查一下:
字节顺序(MSB First)
时钟极性(CPOL=1, CPHA=1)
时钟分频(即SPI总线频率,64分频=4MHz。检查液晶的时序图,确保总线频率不超过液晶模块支持的最高频率)
片选信号(随意,我用的CS0)
片选极性(低有效)
操作树莓派的GPIO和SPI,我用了BCM2835函数库。用法很简单,看Example就够了。
12864的上电初始化时序,我偷懒参考了北京集粹的资料
st7565驱动程序.pdf (326.17 KB, 下载次数: 48)
——这家公司的资料很准确。注:对于液晶模块,只要控制器一致,资料一般可以通用。


动画播放
动画的流程:读取一帧的数据→写入液晶模块→等待1/30s→下一帧。
但是“等待1/30s”,肯定不是字面意思的“延时1/30s”。因为写SPI总线这个操作本身就使用时间,并且这个时间无法确定、不可忽略。忽略就会造成明显的时间不准。
其实这个“等待1/30s”,准确来说,应该表达为“等待下一个1/30s时刻的到来”。也就是说,在程序中要维持一个ms级的时标,每显示一帧就标注一下当前的时刻,然后等待到时标相比上一个标记点超过了33ms,就该显示下一帧了。
Linux环境下ms级的时标,这个问题正经找了一阵……。有不少人认为该使用gettimeofday()函数,但是用这个,在跨越两天的时间不就出问题了……
最后找到<sys/timeb.h>提供的ftime()函数可以解决。ftime()函数可以得到当前的毫秒级的UNIX时间戳。不过也不是没有隐患:程序运行中,不能更改系统时间。这个问题暂时放着了。

总结
其实这个项目相比单片机播放视频,是相当轻松的:
性能够用,海量内存和存储随便使,无需自己操心SD卡操作、FAT32等等
开发资源丰富,甚至无需交叉编译和烧录下载
SPI使用很方便。
果然用树莓派做点短开发周期的玩具再合适不过了。

作者:沙渺,原文http://shamiao.com/raspi/5
分享到:
回复

使用道具 举报

回答|共 20 个

倒序浏览

沙发

小菜儿

发表于 2012-11-27 09:12:07 | 只看该作者

本帖最后由 xinxincaijq 于 2012-11-27 09:15 编辑

树莓派12864动画播放程序更新+发布

树莓派12864动画播放程序更新完善。处理掉了程序中不谨慎的大量细节,完善了取模程序。播放程序增加了两项功能:音频同步播放、帧率自定义。
本次更新,将程序做到了可以发布的水平。放出供爱好者下载赏玩。

视频更新:树莓派12864液晶模块视频播放器(正式视频)
http://player.youku.com/player.php/sid/XNDYwNjY4NzQ0/v.swf

程序发布
程序的下载、用法等,详见项目主页:
树莓派12864视频播放器 http://shamiao.com/project/raspi12864

声音播放
其实相当的简单:在开始播放视频时,直接调用外部的音频播放器播放MP3文件即可。
音频播放器,就从debian提供的软件包里随便抓了一个:mpg123

帧率自定义
实现帧率自定义,应该是只需要算一下,每一帧持续的时间为(1000/fps)ms即可。但是有点小问题。程序中使用的时标均为整数,这样除法所产生的小数部分(舍去)就会产生误差。
例如30fps,1000/30=33.3ms,反过来33*30=990ms,则每24帧就会比1秒种不足10ms。
实际现象就是:一开始音画是同步的,越到后面画面就快的越多。
我考虑的解决办法是,将不足的毫秒数平均分配到各帧中补偿回来。还以30fps为例,不足10ms,则每3帧多播放1ms,就将30帧的时间补回了准确的1000ms。
帧率通过参数输入。程序中将帧率限制在最高60fps——虽然这个液晶模块可以达到的更高,但是由于严重的拖影,其实高了也没用处。甚至60都有点多,30的效果就很好了。

作者:沙渺  原文:http://shamiao.com/raspi/12
板凳

dzcn

发表于 2012-11-27 09:14:23 | 只看该作者

为啥都喜欢bad apple
地板

小菜儿

发表于 2012-11-27 09:52:12 | 只看该作者

ht868788 发表于 2012-11-27 09:47
真心不错,这个不知道TFT彩显效果怎么样?

拿到板子,自己尝试就知道效果啦!
5#

zndz410

发表于 2012-11-27 10:06:17 | 只看该作者

这个板真心想佣有啊。
6#

小菜儿

发表于 2012-11-27 10:10:53 | 只看该作者

louyj 发表于 2012-11-27 10:06
这个板真心想佣有啊。

哈哈~心动不如行动,爱板现在做活动,价格优惠哦!https://www.cirmall.com/bbs/thread-4157-1-1.html
7#

zndz410

发表于 2012-11-27 10:12:38 | 只看该作者

还有抢楼活动就好了。
8#

mawenran

发表于 2012-11-27 11:35:50 | 只看该作者

这个要顶!!非常赞啊!
9#

QQ哥

发表于 2012-11-27 15:48:38 | 只看该作者

羡慕啊~
我就是QQ哥,QQ哥就是我!
https://www.cirmall.com/bbs/?fromuser=QQ%E5%93%A5
10#

Altarage

发表于 2012-11-28 00:48:37 | 只看该作者

有屏幕的地方就有烂苹果啊
您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条