繁体   English   中英

Android虚拟显示的帧侦听器(NDK内部版本)

[英]Frame Listener for Android Virtual Display (NDK internal build)

我正在为Android平台构建内部共享库。 我有设备制造商提供的签名密钥库。

我的图书馆正在使用Android来源的ScreenRecord.cpp内部文件。 使用MediaCodec编码器可以很好地进行记录; 但是我想访问每个帧,以便在将每个帧传递到编码器之前可以在它们上应用一些图像叠加徽标。 Android源代码中也有一个覆盖示例,但仅适用于更新版本的Android(5.0 / API 21+)。 我想为Android Kitkat(4.4 / API 19)提供覆盖解决方案

这是我从minicap获得的代码示例。

mVirtualDisplay = android::SurfaceComposerClient::createDisplay(
android::String8("minicap"),
true);

LOGI("Creating buffer queue");
mScreenshotClient.getCpuConsumer();
mBufferQueue = mScreenshotClient.mBufferQueue;

LOGI("Creating CPU consumer");
mConsumer = new android::CpuConsumer(mBufferQueue, 3, false);
mConsumer->setName(android::String8("minicap"));
mConsumer->setDefaultBufferSize(targetWidth, targetHeight);
mConsumer->setDefaultBufferFormat(android::PIXEL_FORMAT_RGBA_8888);

mConsumer->setFrameAvailableListener(mFrameProxy); 
//mFrameProxy is from:
//class FrameProxy: public android::ConsumerBase::FrameAvailableListener

LOGI("Publishing virtual display");
android::SurfaceComposerClient::openGlobalTransaction();
android::SurfaceComposerClient::setDisplaySurface(mVirtualDisplay, mBufferQueue);
android::SurfaceComposerClient::setDisplayProjection(mVirtualDisplay,
android::DISPLAY_ORIENTATION_0, layerStackRect, visibleRect);
android::SurfaceComposerClient::setDisplayLayerStack(mVirtualDisplay, 0);// default stack

android::SurfaceComposerClient::closeGlobalTransaction();

我设置了上面的代码,但是FrameAvailableListener的onFrameAvailable()方法仅被调用一次。 即使我在屏幕上放东西,也再也不会调用它。 我在这里想念什么? 在传递给编码器之前,是否没有其他更轻松的方法来访问帧?

Lollipop的屏幕记录源中内置了一个添加覆盖的示例。 据我所知,它不依赖于Lollipop中添加的任何功能,因此您应该能够在4.4上构建和运行它。 bigflake所述,-- --bugreport模式是在4.4的时间范围内添加到AOSP的,但实际上直到5.x才随系统一起提供。 (稍作调整,它甚至应在4.3上运行,但我没有尝试过。)

关键源文件是Overlay.{cpp,h} 它执行与用Java编写的代码相同的操作:创建GLConsumer(SurfaceTexture),使用它将传入的帧转换为GLES纹理,然后将纹理+叠加层渲染到视频编码器。

示例视频在这里 请注意,它从一开始就添加了一块文本,并在左上角添加了运行时间戳/帧计数器。

请其他人注意:此代码使用的是内部私有API,这些API在最新版本中已发生更改,因此任何二进制文件都必须针对特定版本的Android构建,并且即使运行不同制造商的设备也可能无法移植到由不同制造商制造的设备上相同版本的Android(有时OEM会喜欢弄乱东西)。

更新:我先前关于使用KitKat的说法并不准确-在Lollipop版本发布之前,API发生了重大变化。 诀窍是在进行此更改之前先获取源代码,因为那是在BufferQueue API重写到达屏幕记录时。 您可以从更改列表中看到--bugreport选项在此之前大约五个月出现了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM