如何使ffmpeg像Android的内置视频查看器一样高效?

How can ffmpeg be made as efficient as Android's built-in video viewer?

本文关键字:高效 一样 ffmpeg 何使 Android 视频 内置      更新时间:2023-10-16

我有一个基于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选项已被提取