没有调用AImageReader的onImageAvailableCallback

时间:2019-06-10 04:59:27

标签: android c++ android-ndk ndk-build

我正在尝试使用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中无法正常工作。

我想念什么吗?

1 个答案:

答案 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中使用它,那么它将起作用。