7

I created a movie player based on FFmpeg. It works fine. The decoding is quite fast, on LG P970 (Cortex A8 with Neon) I have an average 70 fps with 640 x 424 resolution video stream including YUV2RGB conversion. However, there is one bottleneck. It is drawing on Canvas.

I use jnigraphics native library to fill picture data into the bitmap in the native side and then I draw this bitmap on Canvas in SurfaceView. It is quite simple and common approach, but the drawing takes 44 ms for bitmap with 640 x 424 resolution which reduces fps to 23 and makes this technique unusable... It takes a lot more then the whole A/V frame decoding!

Is there any method how to draw bitmaps significantly faster? I would prefer to render completely in the native code using OpenGLES 2, but I have read it also could be slow. So what now?...

How can I render bitmaps as fast as possible?

Community
  • 1
  • 1
vitakot
  • 3,786
  • 4
  • 27
  • 59
  • isn't there a way to access the buffer of SurfaceView directly from native code? Camera Preview does this afaik. – zapl Apr 20 '12 at 10:40
  • AFAIK no, at least no standard way using NDK. Of course, it is possible to link with Android sources, but it would cause troubles with compatibility... – vitakot Apr 20 '12 at 10:52

2 Answers2

3

Draw them in GLES1.x. You do not need to use GLES2 as you will have no use, or at least not in the context of your question, for shaders which would be the general primary reason of using GLES2.x. So for simplicity sake, GLES1.x would be ideal. All you need to do is draw the bytebuffer to the screen. On my Galaxy S (Vibrant) this takes about 3ms. The size of the byte[] in my wallpaper is 800x480x3 or 1152000 which is significantly larger than what you are working with.

I believe this guide should point you in the correct direction.

http://qdevarena.blogspot.com/2009/02/how-to-load-texture-in-android-opengl.html

As for the notion of accessing canvas from native code, I would just avoid that altogether and follow an OpenGL implementation by offloading everything to GPU as much as possible.

ian.shaun.thomas
  • 3,468
  • 25
  • 40
  • Thanks, you are right; I will switch back to OpenGLES1.x. I have no experience with Open GL so my assumption was the newer is better. I have already read the article in the link you provided. Actually, I think I must have read all related articles which Google was able to find for me, even for iOS platform... After a whole day of researching I am still lost a bit. – vitakot Apr 20 '12 at 19:22
  • Both version access the same hardware. The power in 2.0 comes from the additional hardware you get access to (the shader processors). So in that light I think its hard to say one is better or worse, it is typically as simple as deciding what you need to accomplish. – ian.shaun.thomas Apr 20 '12 at 19:40
3

I recall during the Replica Island presentation during GoogleIO the designer said that using the OpenGL 'draw_texture' extension glDrawTexfOES was the fastest way to blit to the screen, and significantly faster than drawing just regular quads with textures attached (I'm assuming you're using OpenGL).

You can't rotate the texture, but it doesn't sound like you need that.

Tim
  • 35,413
  • 11
  • 95
  • 121
  • You are right, I don't care about rotation. I found some nice example using OpenGLES1.x (https://github.com/richq/glbuffer) which uses the function you mentioned. – vitakot Apr 20 '12 at 19:10