如何在视频渲染案例中使用 ImageView 进行高效处理?

How to process efficiently with ImageView in a video render case?

我正在开发一个视频流应用程序。这是一个特殊情况,我需要手动处理每一帧(从网络访问到解码和其他处理)。在我所有过程的最后,对于每一帧,我都有一个包含 ARGB_8888 编码图像的 byte[]

现在,我以这种方式绘制每一帧(假设 width = 1280 和 height = 720,并且 data 是我的 byte[] 包含框架,imageView 是我的 ImageView 容器)

// Step 1: reception and treatments
// After that, data contains the frame bytes;

// Step 2: bitmap creation
Bitmap toDraw = Bitmap.createBitmap(1280, 720, Bitmap.Config.ARGB_8888);
toDraw.copyPixelsFromBuffer(ByteBuffer.wrap(data));

// Step 3: draw the bitmap
imageView.post(new Runnable() {

    @Override
    public void run()
    {
        imageView.setImageBitmap(toDraw);
    }
});

一切正常,没问题。但是我有很多 GC,我真的不喜欢每次都为每个相同大小的框架创建一个新的 Bitmap!所以我需要知道如何优化我的帧渲染?我知道我只能第一次调用 createBitmap 然后只使用 copyPixelsFromBuffer 来填充它(即使它制作了一个副本并且我不喜欢它但它更好)。我想到了一个直观的解决方案,但我不知道是否可行:

如果我只在第一次创建和绘制 Bitmap,然后我从 imageView 检索对像素的引用并修改它或直接修改它,或者将我的 data 作为参考,会怎样?我搜索了 DrawingCache 但没有找到解决方案。

否则,有没有比这段代码做得更好的想法(更好的意思是内存友好且速度更快)?问题是:什么是快速更新我的 imageView 提供我已经解码的 byte[] 数据(对于每一帧)的最佳方法。


编辑:我刚看到 that。我会测试并继续调查。

您可以仅在需要时创建位图,如果它为空或大小不合适

Bitmap mBitmap;

private void someMethod(){

    if(mBitmap == null || !isBitmapSizeOk(mBitmap)){
        if(mBitmap != null) mBitmap.recycle();

        mBitmap = Bitmap.createBitmap(1280, 720, Bitmap.Config.ARGB_8888);
        // call it only when the Bitmap instance changes
        imageView.setImageBitmap(mBitmap); 
    }

    mBitmap.copyPixelsFromBuffer(ByteBuffer.wrap(data));

    // Step 3: draw the bitmap
    imageView.post(new Runnable() {

        @Override
        public void run(){    
            imageView.invalidate();       
        }
    });
}

可以只在创建Bitmap时调用setImageBitmap(mBitmap),避免每次都调用它,但是ImageView需要知道它必须自己重绘,你可以调用invalidate()