1

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

我正在通过套接字接收一系列 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 中清除画布,然后将位图绘制到 SurfaceView。我的问题是它非常非常慢。

一些基于在锁定操作之前和之后添加 System.currentTimeMillis() 的测试导致获取画布、绘制位图和推回画布之间大约有 30 毫秒的差异。显示出来的SurfaceView卡顿,有时会来回跳动,帧率很可怕。

有这样的绘图方法吗?同样,我无法修改从服务器获取的内容,但我希望尽可能以 60FPS 显示位图。

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

    getHolder().setFormat(PixelFormat.RGBA_8888);

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

谢谢。

4

1 回答 1

3

每当您遇到性能问题时,请使用Traceview准确找出问题所在。使用System.currentTimeMillis()就像试图用锤子修剪牛排。

她的第一件事是从主应用程序线程中获取位图解码。在后台线程中执行此操作。您的主应用程序线程应该只是绘制位图,将它们从由该后台线程填充的队列中拉出。从 Android 4.1(又名“Project Butter”)开始,Android 的主应用程序线程设置为以 60fps 的速度呈现,因此只要您可以Bitmap在几毫秒内绘制出来,并假设您的网络和解码可以保持您的当前队列,您应该得到 60fps 的结果。

此外,当您拥有大小一致的图像时,请始终在 Android 3.0+ 上使用inBitmapwith BitmapFactory.Options,因为您的问题的一部分将是 GC 窃取 CPU 时间。处理您循环的对象池Bitmap,这样您就可以减少垃圾的产生,并且不会对堆造成太多碎片。

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

关于:

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

有时只会如此。移动设备往往是移动的。假设“6kb”的意思是 6KB(6 KB),那么您假设的连接约为 3Mbps(每秒 3 兆位),这远非确定。

关于:

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

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

迫在眉睫,您可能需要下拉到 NDK 并在本机代码中执行此操作,但我不希望这样做。

于 2013-07-18T22:11:10.140 回答