在Android 4.x上以60fps平滑显示位图流

时间:2013-07-18 21:53:50

标签: android bitmap android-canvas surfaceview frame-rate

(这是由于我将使用的服务器软件的限制,如果我可以改变它,我会)。

我通过套接字接收一系列720x480 JPEG文件(大小约为6kb)。我对网络进行了基准测试,发现我能够以60FPS顺利接收这些JPEG。

我当前的绘图操作是在2560x1600的Nexus 10显示器上,这是我的解码方法,一旦我从套接字接收到字节数组:

public static void decode(byte[] tmp, Long time) {
    try {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferQualityOverSpeed = false;
        options.inDither = false;
        Bitmap bitmap = BitmapFactory.decodeByteArray(tmp, 0, tmp.length, options);
        Bitmap background = Bitmap.createScaledBitmap
                (bitmap, MainActivity.screenwidth, MainActivity.screenheight, false);
        background.setHasAlpha(false);
            Canvas canvas = MainActivity.surface.getHolder().lockCanvas();
            canvas.drawColor(Color.BLACK);
            canvas.drawBitmap(background, 0, 0, new Paint());
            MainActivity.surface.getHolder().unlockCanvasAndPost(canvas);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

如您所见,我正在从SurfaceView清除画布,然后将Bitmap绘制到SurfaceView。我的问题是它非常非常缓慢。

基于在锁定操作之前和之后添加System.currentTimeMillis()的一些测试导致获取画布,绘制位图,然后再推回画布之间的差异大约为30ms。显示的SurfaceView 非常滞后,有时会来回跳跃,帧速率很差。

是否有这样的参考方法?同样,我无法修改我从服务器获得的内容,但我希望在可能的情况下以60FPS显示位图。

(我已尝试设置ImageView的内容,并收到类似的结果)。我在SurfaceView中没有其他可能影响它的代码。我已将持有者设置为RGBA_8888格式:

    getHolder().setFormat(PixelFormat.RGBA_8888);

是否可以将此位图流转换为VideoView?会更快吗?

感谢。

1 个答案:

答案 0 :(得分:3)

每当遇到性能问题时,请使用Traceview确定问题的确切位置。使用System.currentTimeMillis()就像试图用锤子修剪牛排一样。

她的第一件事是从主应用程序线程中解码位图。在后台线程中执行此操作。您的主应用程序线程应只是绘制位图,将它们从该后台线程填充的队列中拉出。 Android的主应用程序线程设置为在Android 4.1(又称“Project Butter”)的基础上以60fps为基础进行渲染,因此只要您可以在几毫秒内绘制Bitmap,并假设您的网络并且解码可以使你的队列保持最新状态,你应该得到60fps的结果。

此外,当您拥有一致大小的图片时,始终在Android 3.0+上使用inBitmap BitmapFactory.Options,因为问题的一部分将是GC窃取CPU时间。处理您旋转的Bitmap个对象池,这样可以减少垃圾堆积,并且不会过多地碎片堆。

我怀疑让你更好地让Android在ImageView(或仅通过绘制到View画布)缩放图像,而不是让BitmapFactory缩放图像,因为Android可以利用硬件图形加速进行渲染,BitmapFactory不能。 Traceview再次成为你的朋友。

关于:

  

并且发现我能够以60FPS顺利接收这些JPEG。

有时只会是真的。移动设备往往是移动的。假设“6kb”表示6KB(6千字节),那么假设连接速度为~3Mbps(每秒3兆比特),这远非确定。

关于:

  

是否可以将此位图流转换为VideoView?

VideoView是一个播放视频的小部件,但您没有视频。

推送来推,你可能需要下载到NDK并在本机代码中执行此操作,但我希望不会。