103也疯狂!超频上avi视频解码播放 240*320 10fps 无声音

2019-07-21 03:44发布

上一贴
在mini板上也做Flappybird游戏
http://www.openedv.com/forum.php ... 1&fromuid=71682



先上视频效果吧:
http://player.youku.com/player.php/sid/XMjY4NjUxMzkzMg==/v.swf
视频连接:http://v.youku.com/v_show/id_XMjY4NjUxMzkzMg==.html
代码资料链接:http://pan.baidu.com/s/1jI6yL3C密码:nrs2
播放的过程拍了几张
1.JPG
2.JPG

播放的视频是avi格式的(容器)(和原子哥407开发板的例程用的一样),内部的图像是jpeg,尺寸240*320及以下,帧率10帧每秒(分辨率下降以后,帧率可以有显著增加),没有声音(可以打开音频,设置音频解码器为pcm,但是也不会播放,会自动跳过)
没有声音的原因我后面会解释
转码的时候按截图设置就好。
捕获.JPG

播放的的时候,让一个引脚在单片机解码的时候置高,空闲等待的时候置低,用逻辑分析仪看下引脚
这是比较正常的时候。可以看到,其实解码占用了83%的cpu时间,其实空闲的时候不算太多
108_1795013_4b2e2f2b62e0032.jpg

有时候会遇到有些视频帧比较复杂,比如说这样,解码一帧图像的时间已经超过0.1秒,不过这种情况一般比较少,而且时间超出的也不算拿太多,在可以接受范围内,看起来也不卡
108_1795013_7f85f10817ed2df.jpg


但是在240*320输出分辨率下,10帧已经是差不多算是接近极限了,要提升就得深度优化下了。
我试了176*200的输出分辨率,30帧下单片机仍然有一半以上的时间在睡大觉

使用的时候,要先在单片机后面0x804000地址烧录fatfs所需的UNIGBK文件(用jlink),同时要在flash里面烧中文字库(用 {MOD}中的汉字显示实验烧录),最后再烧录视频解码程序。
编译完的文件不小哈

108_1795013_264ad3003584845.jpg

播放的时候,串口以115200波特率输出调试信息
正常的开机调试信息
108_1795013_8cca67711b8ec0c.jpg
由于内存紧凑,视频读取缓存只能设置了23.5k,大于这个数的帧会被丢掉
出现以下显示,然后会跳过这些帧的播放。受限于总内存量,也是很无奈啊。
当然大部分视频帧基本是在范围内的,不容易发生这种情况
108_1795013_dc9e7b17b4cb1d2.jpg

一直以来,大家都说视频解码应该stm32f103没戏,至少得上407,我也是抱着试一试的心态弄的,结果弄出来的效果还算蛮好的,虽然没啥实用价值。

首先来说我们这次用的主控芯片gd32f103
这些芯片的得来方式,不说了,论坛搞到的一些一元一片的废弃电路板,有单片机还有配送flash芯片

9.JPG

gd32f103呢,是国内兆易创新弄的 和意法的stm32f103 pin_to_pin 对应的芯片,引脚和寄存器都差不多都是一样的,程序基本上是可以直接换过去跑的。
但是呢,也有点不同。按照官方的手册描述gd32f103的主频是可以运行到108mhz的

8.JPG

本着作死的心态,我来测试了下这货的超频体质
测试方法是超了频以后来跑coremark
跑在和stm32f103一样的默认频率72mhz的时候
108_1795013_0a8d78f3e8dabc9.png

跑到104mhz的时候(也就是gd32官方标注频率,8m晶振调不到108mhz的,只能到104)
108_1795013_3caa5bec1280673.png

极限超频到208mhz的时候(不是很稳定,一小会儿就会死),超频体制还是蛮好的说
可见跑分性能相比72mhz,差不多是3倍的样子(当然跑分仅供参考拉,还是实际为准)
108_1795013_8acebba8de898cc.png

相比较与stm32只能超到140-150mhz左右的样子,还是有不少提升的嘛
和跑在167mhz的stm32f4系列来比,差距不是很大了哈(当然,cm4核的fpu和dsp也是一大杀器啊,搞软解虐cm3几条街)
(成绩来源于coremark官网www.eembc.org/coremark/index.php
108_1795013_35af6d3d704fd28.jpg

顺便说明下:超频使用不具有实用价值,仅为爱好者学习娱乐,请勿在产品中使用,否则后果不堪设想
板子上的gd32f103re,配置如图 512kflash 64ksram

108_1795013_7ab2245c70c0caf.jpg

专门
做了个板子方便玩耍
原理图
10.JPG

和其他板子一起拼板的,切板技术不佳,吧固定孔干费了,不过还好只是外观上的问题,不影响功能
板子正面,兼容好几款我手上的屏幕,可以做转接板也可以背面焊mcu玩耍
3.JPG

背面先吧gd32撸上去
4.JPG

晶振,外围电容
5.JPG

正面屏幕焊上,一次点亮没问题
以为原子
mini开发板的LCD驱动引脚和SDIO有冲突,所以做了些移动,屏幕程序需要做点小修改
6.JPG

用得上的元件全部怼上去,完工
7.JPG

讲下软件部分
总体来说,最难的是103的内存不够,才64k,非常捉襟见肘
第二难的还是运算速度不够,不超频真的没戏

关于没做声音播放的原因,两层,1是stm32的iis接口的引脚pb3 5或者pb13 15 ,而屏幕的16位数据接口吧整个gpiob都占用了,引脚冲突,所以也就没设置相关的音频播放硬件
2是,内存连接视频都捉襟见肘,实在腾不出更多的空间来给音频播放使用了。(音频播放至少得有个10k左右的内存,在方便弄pcm输出,而且才仅仅是pcm,还不是mp3或者aac)
3是处理器基本没有多少空余时间,加音频必拖慢视频播放

为了保障稳定性,这次我超到了192mhz,跑了好久,不会死,200和208就很容易死


首先,整个工程 lcd驱动部分移植与mini板程序,sdio和fatfs移植于战舰的程序,libjpeg和视频相关部分移植于探索者F4资料(再次感谢原子哥)
超频部分,超频到192mhz使用,用的12mhz晶振

108_1795013_1acee16f634405c.jpg
倍频16倍
108_1795013_7d5cda2ad0513e7.jpg

108_1795013_5cf9befaefa8b44.jpg

其实用8mhz晶振也是可以的。需要倍频24倍(stm32只能倍频到16倍,gd32可以到32倍)
这是st的手册
12.JPG
13.JPG
看gd参考手册可以得知多了一个寄存器的位 27位
11.JPG
14.JPG

改下stm32f10x.h文件里面增加这些内容
[mw_shl_code=c,true]    #define  RCC_CFGR_PLLMULL2                  ((uint32_t)0x00000000)        /*!< PLL input clock*2 */
    #define  RCC_CFGR_PLLMULL3                  ((uint32_t)0x00040000)        /*!< PLL input clock*3 */
    #define  RCC_CFGR_PLLMULL4                  ((uint32_t)0x00080000)        /*!< PLL input clock*4 */
    #define  RCC_CFGR_PLLMULL5                  ((uint32_t)0x000C0000)        /*!< PLL input clock*5 */
    #define  RCC_CFGR_PLLMULL6                  ((uint32_t)0x00100000)        /*!< PLL input clock*6 */
    #define  RCC_CFGR_PLLMULL7                  ((uint32_t)0x00140000)        /*!< PLL input clock*7 */
    #define  RCC_CFGR_PLLMULL8                  ((uint32_t)0x00180000)        /*!< PLL input clock*8 */
    #define  RCC_CFGR_PLLMULL9                  ((uint32_t)0x001C0000)        /*!< PLL input clock*9 */
    #define  RCC_CFGR_PLLMULL10                 ((uint32_t)0x00200000)        /*!< PLL input clock10 */
    #define  RCC_CFGR_PLLMULL11                 ((uint32_t)0x00240000)        /*!< PLL input clock*11 */
    #define  RCC_CFGR_PLLMULL12                 ((uint32_t)0x00280000)        /*!< PLL input clock*12 */
    #define  RCC_CFGR_PLLMULL13                 ((uint32_t)0x002C0000)        /*!< PLL input clock*13 */
    #define  RCC_CFGR_PLLMULL14                 ((uint32_t)0x00300000)        /*!< PLL input clock*14 */
    #define  RCC_CFGR_PLLMULL15                 ((uint32_t)0x00340000)        /*!< PLL input clock*15 */
    #define  RCC_CFGR_PLLMULL16                 ((uint32_t)0x00380000)        /*!< PLL input clock*16 */
            #define  RCC_CFGR_PLLMULL17                          ((uint32_t)0x08000000)        /*!< PLL input clock*17 */
            #define  RCC_CFGR_PLLMULL18                          ((uint32_t)0x08040000)        /*!< PLL input clock*18 */
            #define  RCC_CFGR_PLLMULL19                          ((uint32_t)0x08080000)        /*!< PLL input clock*19 */
            #define  RCC_CFGR_PLLMULL20                          ((uint32_t)0x080C0000)        /*!< PLL input clock*20 */
            #define  RCC_CFGR_PLLMULL21                          ((uint32_t)0x08100000)        /*!< PLL input clock*21 */
            #define  RCC_CFGR_PLLMULL22                          ((uint32_t)0x08140000)        /*!< PLL input clock*22 */
            #define  RCC_CFGR_PLLMULL23                          ((uint32_t)0x08180000)        /*!< PLL input clock*23 */
            #define  RCC_CFGR_PLLMULL24                          ((uint32_t)0x081C0000)        /*!< PLL input clock*24 */
            #define  RCC_CFGR_PLLMULL25                          ((uint32_t)0x08200000)        /*!< PLL input clock*25 */
            #define  RCC_CFGR_PLLMULL26                          ((uint32_t)0x08240000)        /*!< PLL input clock*26 */
            #define  RCC_CFGR_PLLMULL27                          ((uint32_t)0x08280000)        /*!< PLL input clock*27 */
            #define  RCC_CFGR_PLLMULL28                          ((uint32_t)0x082C0000)        /*!< PLL input clock*28 */
            #define  RCC_CFGR_PLLMULL29                          ((uint32_t)0x08300000)        /*!< PLL input clock*29 */
            #define  RCC_CFGR_PLLMULL30                          ((uint32_t)0x08340000)        /*!< PLL input clock*30 */
            #define  RCC_CFGR_PLLMULL31                          ((uint32_t)0x08380000)        /*!< PLL input clock*31 */
            #define  RCC_CFGR_PLLMULL32                          ((uint32_t)0x083C0000)        /*!< PLL input clock*32 */[/mw_shl_code]

再次提醒:超频使用不具有实用价值,仅为爱好者学习娱乐,请勿在产品中使用,否则后果不堪设想
因为频率太高,串口计算波特率部分需要改下库函数,否则会溢出
108_1795013_b6ec4ad5232177b.jpg

屏幕显示方面,因为mini板的屏幕引脚和sdio有冲突,影响高速读卡,所以屏幕驱动引脚移动到了别处
108_1795013_d7753f9cb2e9916.jpg

视频解码部分
读写缓冲区改成23.5k,再大就要爆内存了,但是有些复杂的帧到了30k以上,只能忍痛跳过
108_1795013_7f40fa2266590fc.png

解码缓冲区,实测解240*320需要25252字节内存,也就是24.66k,所以分配给25k内存正好合适
108_1795013_4bb5f33a6184f05.jpg


播放部分,检测是视频帧且帧大小小于缓存,则加载解码,大于或者是音频,则跳过

其他具体的移植细节,还是看源码吧

现在还有个bug是播放完一曲的时候,在malloc程序在free内存的时候,会概率性进硬件中断,应该是越界了
,后面有空我再找找看原因
快进快退,之类功能也还没做
代码资料链接:http://pan.baidu.com/s/1jI6yL3C密码:nrs2
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
43条回答
posystorage
2019-07-22 07:36
正点原子 发表于 2017-5-3 21:00
真是犀利

感谢原子哥支持。
我找到最后视频退出时会概率性进硬件中断的原因了。
花了两天终于检测出来了,是栈溢出,影响了其他运行参数。栈被编译在内存的最末尾,然后向下一走溢出就到变量区了。然后靠近栈很近的mem1mapbase是malloc里面存放申请内存的地址的,这个参数被溢出的栈修改了,导致在释放内存的时候,地址不对,硬件中断错误。
同样的ftinfo,和avix早就被覆盖了,只是没造成特别严重的问题
    mem1base                                 0x20001480   Data       55008  malloc.o(.bss)
    mem1mapbase                              0x2000eb60   Data        3438  malloc.o(.bss)
    ftinfo                                   0x2000f8ce   Data          33  fontupd.o(.bss)
    avix                                     0x2000f8ef   Data          40  avi.o(.bss)
    __initial_sp                             0x2000ffd8   Data           0  startup_stm32f10x_hd.o(STACK)

0x2000f918   0x000006c0   Zero   RW      STACK               startup_stm32f10x_hd.o
后来吧栈改大了,问题解决。原来是0x400,现在改到0x6c0,毕竟内存还是太捉襟见肘了。
检查的方法用的这位大量的小工具,http://www.openedv.com/posts/list/19693.htm,很是感谢

一周热门 更多>