【问题标题】:Reliable screen capturing using Android Media Projection API使用 Android Media Projection API 进行可靠的屏幕捕获
【发布时间】:2016-03-03 16:05:54
【问题描述】:

我们使用 Media Projection API 的实现工作正常。但是我们在尝试将捕获的图像写入文件时经常会丢失帧。即使所有 io 代码都在单独的线程中执行。

我们想对捕获的帧进行一些在线图像分析,因此我们不能使用screenrecord或类似的工具。

有没有办法从原生代码调用 Android Media Projection 方法?为了获得更好的性能?

我们甚至尝试在捕获过程中不调用任何 io 操作。直到最后,我们都在记忆中。但是在 30fps 时我们仍然存在丢失帧的问题。我们怎样才能避免这种情况?

        try {
            image = mImageReader.acquireLatestImage();
            if (image != null) {
                Image.Plane[] planes = image.getPlanes();
                ByteBuffer buffer = planes[0].getBuffer();
                int pixelStride = planes[0].getPixelStride();
                int rowStride = planes[0].getRowStride();
                int rowPadding = rowStride - pixelStride * mWidth;
                String.valueOf(pixelStride) + " -- rowStride: " + String.valueOf(rowStride) + " rowPadding: " + String.valueOf(rowPadding));
                // create bitmap
                if(mBitmap==null || rowPadding != mRowPadding || pixelStride != mPixelStride) {
                    mRowPadding = rowPadding; mPixelStride = pixelStride;
                    mBitmap = Bitmap.createBitmap(mWidth + rowPadding / pixelStride, mHeight, Bitmap.Config.ARGB_8888);
                }
                mBitmap.copyPixelsFromBuffer(buffer);
                Bitmap myBitmap = Bitmap.createScaledBitmap(mBitmap, (mWidth + rowPadding / pixelStride) / 16, mHeight / 16, false);

                ramStorage.add(myBitmap);

【问题讨论】:

  • 尽量重复使用位图,而不是重新创建它们。此外,您可以为 ImageReader 提供更多帧(构造方法中的最后一个参数)

标签: android performance android-ndk screen-capture android-mediaprojection


【解决方案1】:

所有与 Bitmap 相关的代码都是本地实现的,因此将现有代码转换为使用 JNI 不会产生任何影响。我猜你遇到了内存带宽或 CPU 限制(来自复制和缩放每一帧的数据),或者只是因为调度程序让其他线程运行而错过了实时截止日期。

最佳方法取决于您所需的质量水平以及应用的功能。如果您录制为视频流,而不是捕获一系列独立的帧,您将使用更少的内存和非常少的 CPU。当您仅以 30fps 的速度刻录几 MB/秒时,将数据保存在 RAM 中更为实用。如果您的应用程序经常更改屏幕上的每个像素,这可能无法正常工作。您的分析代码必须能够容忍宏块和矢量量化错误。

您可以通过在保存位图之前不缩放位图来权衡 CPU 与 RAM。您也可以完全避免 Bitmap,并执行您自己的复制 + 缩放操作以将 ImageReader 内容传输到 RAM 存储,一次完成这两个操作(您希望在本机代码中编写复制缩放功能)。

【讨论】:

    猜你喜欢
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 1970-01-01
    • 2014-05-31
    • 1970-01-01
    相关资源
    最近更新 更多