AImageReader's onImageAvailableCallback 未被调用

AImageReader's onImageAvailableCallback is not being called

本文关键字:调用 onImageAvailableCallback AImageReader      更新时间:2023-10-16

我正在尝试使用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");
}

这是日志猫...

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 中无法正常工作。

我错过了什么吗?

我认为你的代码有错误:

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);

窗口参数不在,已出。 并且您的 AImageReader 未连接到 Java 表面。

注意

也许如果你能将你的ANativeWindow(从AImageReader(转换为surface并在java中使用它,它就会起作用。