如何使ffmpeg像Android的内置视频查看器一样高效?
How can ffmpeg be made as efficient as Android's built-in video viewer?
我有一个基于https://ikaruga2.wordpress.com/2011/06/15/video-live-wallpaper-part-1/,使用中的ffmpeg库的旧副本http://bambuser.com/opensource.在这个项目的C++代码中,我们有以下几行代码:
unsigned long long current = GetCurrentTimeInNanoseconds();
avcodec_decode_video(pCodecCtx, pFrame, &frameFinished, packet.data, packet.size);
__android_log_print(ANDROID_LOG_DEBUG, "getFrame>>>>", "decode video time: %llu", (GetCurrentTimeInNanoseconds() - current)/1000000);
该代码使用1280x720 h264源视频文件,在Xperia Ion上连续报告60到90毫秒的每帧解码时间。其他将帧输出到屏幕的处理平均需要30毫秒以上,变化很小。这导致了10-11fps的帧速率。
忽略其他处理,平均花费75ms的解码将产生13fps。然而,当我浏览我的SD卡并点击mp4文件在本地查看器中打开它时,它会以每秒30帧的速度显示。此外,当我在本机查看器中打开同一mp4的1920x1080版本时,它也以全30fps的速度运行,没有停顿或滞后。这意味着(对我的新手来说)有些事情非常非常错误,因为硬件显然能够更快地解码。
可以将哪些标志或选项传递给avcode_decode_video,以优化解码速度以匹配本地查看器的解码速度?是否可以在其他地方进行优化以进一步优化速度?有没有理由让原生查看器可以更快地解码一个数量级(考虑到1920x1080的源结果)?
编辑
下面的答案很有帮助,但目前对我来说并不实用。与此同时,我已经设法将解码时间减少了70%,并通过数小时的试错找到了一些最佳编码标志。以下是我用于编码的ffmpeg参数,以防它对其他偶然发现这篇文章的人有所帮助:
ffmpeg.exe -i "#inputFilePath#" -c:v libx264 -preset veryslow -g 2 -y -s 910x512 -b 5000k -minrate 2000k -maxrate 8000k -pix_fmt yuv420p -tune fastdecode -coder 0 -flags -loop -profile:v main -x264-params subme=5:ref=4 "#ouputFilePath#"
有了这些设置,ffmpeg可以在20-25秒内解码帧,尽管使用sws_scale,然后写入纹理,我仍然在Xperia Ion上以低于我想要的分辨率徘徊在约22 FPS。
本机查看器使用硬件h264解码器,而ffmpeg通常只编译软件 您必须使用libstagefright构建ffmpeg
libstagefright选项已被提取
- C++中高效的大型稀疏块压缩线性方程
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- 如何在C++中高效地构造随机骰子
- 如何将不同的可执行文件合并到一个窗口框架中进行编码?像浏览器一样
- 为什么在C++中对链表这样做?(像堆叠一样处理它们)
- 如何实现高效的算法来计算大型数据集的多个不同值?
- 堆栈和队列是否像C++中的数组一样传递?
- 是否有技术原因阻止 Java 中的 final C++ 像 const 一样严格?
- 访问数据成员(本身是对象)的数据成员,就好像它们是类成员一样
- 我们可以将集合的值存储在变量中吗?就像我们可以将数组的值存储在变量中一样
- 更高效地在微控制器上对C++进行基准测试
- 我如何在C++像在 Python 中一样实现 f 字符串?
- 从C++无序集合中高效提取元素
- 自制的上衣:看起来一样,但不完全相同
- 如何使用 redis-plus-plus 存储二进制数据,就像我想存储结构一样?@for_stack?
- 如何像在 C++ 中处理数组一样对 .txt 文件中的字符进行寻址?
- 如何将两个字符串加在一起,就好像它们是变量一样?
- 像C++一样编写高效的实体系统
- 如何使ffmpeg像Android的内置视频查看器一样高效?
- 如何在Python中像指针一样高效地迭代数组