我们使用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);
答案 0 :(得分:2)
使用Bitmap执行任何后果的所有代码都是本机实现的,因此将现有代码转换为使用JNI并不会产生任何影响。我猜测你正在运行内存带宽或CPU限制(来自复制和扩展每帧的数据)或只是缺少实时截止日期,因为调度程序让其他线程运行。
最佳方法取决于您需要的质量级别以及应用程序正在执行的操作。如果您录制为视频流,而不是捕获一系列独立帧,您将使用更少的内存和非常少的CPU。当你以30fps的速度刻录几MB /秒时,将数据保存在RAM中更实用。如果您的应用经常更改屏幕上的每个像素,这可能无法正常工作。您的分析代码必须能够容忍宏块和矢量量化错误。
您可以在保存之前不通过缩放位图来换取CPU的RAM。您还可以完全避免使用Bitmap,并执行您自己的复制+缩放操作以将ImageReader内容传输到RAM存储,一次完成两个操作(您希望在本机代码中编写复制缩放功能)。