"Android + FFMpeg"友谊真的可用吗?

vol*_*_by 32 video android 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的gelded ffmpeg源代码,具有构建脚本([web]:http://www.rockplayer.com/download/rockplayer_ffmpeg_git_20100418.zip)的巨大Android.mk .经过一些修正后,它由NDK3和NDK5构建.Rockplayer可能是Android上最酷的媒体播放器,我认为我会使用它的构建有一些额外的好处.

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

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

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

  1. Bambuser(armv5te的NDK5 buld,RGBA8888):33 ms /帧平均值.
  2. Rockplayer(用于霓虹灯的NDK3版本,RGB565):27 ms /帧平均值.

对于第一眼看起来并不坏,但只是认为这些只是解码帧的结果.如果有人在解码时有更好的结果,请告诉我.

视频最难的是渲染.如果我们有位图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.

就这样.我知道有一些方法可以使用片段着色器来使用GPU转换YUV像素,但是我们将使用相同的glTexImage2D和200毫秒的纹理加载.

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

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

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

有任何想法吗?为你祈祷 ;)

Ult*_*ior 1

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