“Android + FFMpeg”友谊真的可用吗?

时间:2011-05-20 13:28:48

标签: android video ffmpeg

这个问题并不意味着我很感兴趣,如果ffmpeg代码可以在Andoid上使用。我知道它可以。我只是问一个人是否有真正的表现进展。 经过几周的实验,我已经创造了这个问题,我已经够了...... 我不想写分支,人们甚至不会说他们解码什么样的视频(分辨率,编解码器),只谈一些神秘的FPS。我只是不明白他们想做什么。此外,我不打算仅为我的手机或具有一些扩展OpenGL功能的Android 2.2 ++手机开发应用程序。我有非常受欢迎的手机HTC Desire,所以如果应用程序不起作用,那么下一步是什么?

嗯,我有什么?

  1. 来自最新HEAD分支的FFMpeg源代码。实际上我不能用NDK5来填充它所以我决定使用偷来的。

  2. Bambuser的构建脚本(bash),带有适当的ffmpeg源([web]:http://bambuser.com/r/opensource/ffmpeg-4f7d2fe-android-2011-03-07.tar.gz)。 通过使用NDK5进行一些修正后,它可以很好地构建。

  3. Rockplayer's gelded ffmpeg源代码,包含构建脚本([web]:http://www.rockplayer.com/download/rockplayer_ffmpeg_git_20100418.zip)的巨大Android.mk。 经过一些修正后,它由NDK3和NDK5构建。 Rockplayer可能是Android上最酷的媒体播放器,我认为我会使用它的构建有一些额外的好处。

  4. 我有适合项目的视频(不大且不小):600x360 H.264。

    我们从第2和第3条得到的两个库为我们提供了从视频中获取帧的可能性(逐帧,搜索等)。我没有尝试获得音轨,因为我不需要一个项目。我不是在这里发布我的来源,因为我认为这是传统的,而且很容易找到。

    嗯,视频的结果是什么? HTC Desire,Android 2.2 600x360,H.264 解码和渲染在不同的线程中

    1. Bambuser(armv5te的NDK5 buld,RGBA8888):33 ms /帧平均值。
    2. Rockplayer(NDK3 build for neon,RGB565):27 ms /帧平均值。
    3. 第一眼看上去并不坏,但只是认为这些只是解码帧的结果。 如果有人在解码时有更好的结果,请告诉我。

      视频最难的是渲染。如果我们有位图600x360,我们应该在绘画前以某种方式缩放,因为不同的手机有不同的屏幕尺寸,我们不能指望我们的视频与屏幕尺寸相同。

      我们有什么选项来重新缩放帧以使其适合屏幕? 我能够检查(同一部手机和视频源)这些情况:

      1. sws_scale()Bambuser构建中的C函数:70 ms /帧。不可接受的。
      2. Android中的傻瓜位图重新缩放(Bitmap.createScaledBitmap):65毫秒/帧。不可接受的。
      3. 纹理四边形中的正投影中的OpenGL渲染。在这种情况下,我不需要缩放框架。我只需要准备纹理1024x512(在我的情况下是RGBA8888)包含帧像素,然后将其加载到GPU(gl.glTexImage2D)中。结果:~220 ms /帧渲染。不能接受的。我没想到glTexImage2D只是吮吸了Snapdragon CPU。
      4. 这就是全部。 我知道有一些方法可以使用片段着色器来使用GPU转换YUV像素,但是我们将使用相同的glTexImage2D和200毫秒的纹理加载。

        但这不是结束。 ...我唯一的朋友结束...... :) 这不是没有希望的条件。

        尝试使用RockPlayer你肯定会想知道他们如何快速地进行该死的帧缩放。我想他们在ARM架构方面有很好的经验。他们最有可能使用avcodec_decode_video2而不是img_convert(就像我在RP版本中所做的那样),但他们使用一些技巧(取决于ARM版本)进行缩放。 也许他们也有一些“神奇”的buld配置,因为ffmpeg减少了解码时间,但他们发布的Android.mk并不是他们使用的Android.mk。说不上...

        所以,现在看起来你不仅可以为ffmpeg推出一些简单的JNI桥接器,而且还拥有适用于Android平台的真正媒体播放器。只有当您拥有不需要缩放的合适视频时,才能执行此操作。

        有什么想法吗?我希望你;)

3 个答案:

答案 0 :(得分:1)

我在android上编译了ffmpeg。从这一点来说 - 播放视频完全取决于实现,所以没有必要测量可以在需要的地方高度优化的事物的延迟,而不是使用标准的swscale。是的 - 您可以构建一些简单的JNI桥并在NDK中使用它来执行ffmpeg调用,但这已经是一个播放器代码。

答案 1 :(得分:1)

根据我的经验,YUV到RGB的转换一直是瓶颈。因此,using an OpenGL shader证明了这一点可以带来显着的推动。

答案 2 :(得分:0)

我将http://writingminds.github.io/ffmpeg-android-java/用于我的项目。有一些复杂命令的解决方法,但对于简单的命令,包装器对我来说非常好。