我正在尝试使用NDK而不是Java制作一个截图应用程序(考虑到它是一个实验,我知道Java代码要简单得多,但是我想通过NDK来实现)。
因此,我已经在Java端实现了以下代码...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
if (mediaProjectionManager != null)
startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(),
420);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
SurfaceTexture surfaceTexture = new SurfaceTexture(420);
Surface mSurface = new Surface(surfaceTexture);
if (requestCode == 420) {
if (resultCode == RESULT_OK) {
MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay("MainActivity", 1080, 1920, 100,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
mSurface,
null, null);
init(mSurface);
}
}
}
private native void init(Surface surface); //native call
static {
System.loadLibrary("native-lib");
}
这是本机代码...
#include <ctime>
#include <filesystem>
#include "media/NdkImageReader.h"
#include "media/NdkImage.h"
#include "android/native_window_jni.h"
#include "log.h"
#include "renderer.h"
#define TAG "JNI"
void onImageAvailableCallback(void *context, AImageReader *reader);
void work(JNIEnv* env, jobject surface){
ANativeWindow *nativeWindow = ANativeWindow_fromSurface(env, surface);
ANativeWindow_acquire(nativeWindow);
AImageReader *imageReader;
media_status_t status = AImageReader_new(1080, 1920, AIMAGE_FORMAT_YUV_420_888, 4,
&imageReader);
if (status == AMEDIA_OK) {
LOGD(TAG, "ImageReader successfully initialized!");
if (nativeWindow != NULL) {
LOGD(TAG, "Surface is not null! Continuing...");
status = AImageReader_getWindow(imageReader, &nativeWindow);
if (status == AMEDIA_OK) {
LOGD(TAG, "ImageReader acquired window!");
AImageReader_ImageListener imageListener{
.context = nullptr,
.onImageAvailable = &onImageAvailableCallback
};
AImageReader_setImageListener(imageReader, &imageListener);
} else return;
} else {
LOGD(TAG, "Surface is null, Aborting...");
return;
}
}
}
extern "C" JNIEXPORT void JNICALL
Java_com_test_fps_MainActivity_init( JNIEnv* env,
jobject thiz,
jobject surface) {
LOGD(TAG, "INIT");
work(env, surface);
}
void onImageAvailableCallback(void *context, AImageReader *reader)
{
LOGD(TAG, "Frame Available");
}
这是logcat ...
2019-06-10 09:54:43.663 8258-8258/com.test.fps W/com.test.fps: JIT profile information will not be recorded: profile file does not exits.
2019-06-10 09:54:43.665 8258-8258/com.test.fps I/chatty: uid=10234(com.test.fps) identical 10 lines
2019-06-10 09:54:43.665 8258-8258/com.test.fps W/com.test.fps: JIT profile information will not be recorded: profile file does not exits.
2019-06-10 09:54:43.688 8258-8258/com.test.fps I/InstantRun: starting instant run server: is main process
2019-06-10 09:54:43.816 8258-8258/com.test.fps W/com.test.fps: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (light greylist, reflection)
2019-06-10 09:54:43.817 8258-8258/com.test.fps W/com.test.fps: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (light greylist, reflection)
2019-06-10 09:54:43.828 8258-8258/com.test.fps D/OpenGLRenderer: Skia GL Pipeline
2019-06-10 09:54:43.953 8258-8280/com.test.fps I/Adreno: QUALCOMM build : 791494e, Id7006ec082
Build Date : 12/09/18
OpenGL ES Shader Compiler Version: EV031.24.02.00
Local Branch :
Remote Branch : refs/tags/AU_LINUX_ANDROID_LA.UM.7.3.R1.09.00.00.423.045
Remote Branch : NONE
Reconstruct Branch : NOTHING
2019-06-10 09:54:43.953 8258-8280/com.test.fps I/Adreno: Build Config : S P 6.0.7 AArch64
2019-06-10 09:54:43.957 8258-8280/com.test.fps I/Adreno: PFP: 0x016ee180, ME: 0x00000000
2019-06-10 09:54:43.964 8258-8280/com.test.fps I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
2019-06-10 09:54:43.964 8258-8280/com.test.fps I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasHDRDisplay retrieved: 0
2019-06-10 09:54:43.964 8258-8280/com.test.fps I/OpenGLRenderer: Initialized EGL, version 1.4
2019-06-10 09:54:43.964 8258-8280/com.test.fps D/OpenGLRenderer: Swap behavior 2
2019-06-10 09:54:44.064 8258-8258/com.test.fps D/JNI: INIT
2019-06-10 09:54:44.065 8258-8258/com.test.fps D/JNI: ImageReader successfully initialized!
2019-06-10 09:54:44.065 8258-8258/com.test.fps D/JNI: Surface is not null! Continuing...
2019-06-10 09:54:44.065 8258-8258/com.test.fps D/JNI: ImageReader acquired window!
2019-06-10 09:54:46.592 8258-8272/com.test.fps I/Gralloc2: Adding additional valid usage bits: 0x8200000
我曾尝试在Java中使用图像读取器,但它在NDK中无法正常工作。
我想念什么吗?
答案 0 :(得分:0)
我认为您的代码有误:
ANativeWindow *nativeWindow = ANativeWindow_fromSurface(env, surface);
...
status = AImageReader_getWindow(imageReader, &nativeWindow);
在函数“ AImageReader_getWindow”中
media_status_t AImageReader_getWindow(AImageReader* reader, /*out*/ANativeWindow** window) __INTRODUCED_IN(24);
window参数不在,不在。 并且您的AImageReader未连接到Java表面。
注意
也许您可以将ANativeWindow(从AImageReader)转换为Surface并在Java中使用它,那么它将起作用。