NDK无法解析的函数:media_status_t AMediaCodec_createInputSurface(AMediaCodec * mData,ANativeWindow ** surface)

时间:2018-11-18 22:44:08

标签: android c++ android-ndk

NDK文档说此功能可用(https://developer.android.com/ndk/reference/group/media#group___media_1ga8eb3e60bb5c76e90d7652dff636dd17b),确实可以从Java代码中调用它,但是它会从C ++代码中产生一个“无法解析的函数” [在Android Studio中]错误。

我正在尝试将 MJPEG 流提供给MediaCodec,并让MediaMuxer从其中记录MP4视频。我发现了在Java代码中如何做类似事情的有限示例,但在本地代码中如何做类似事情的零示例。因此,我尝试在本机代码中复制Java示例。这个特定的函数调用对于实现我的目标似乎相对重要,我可以从Java代码成功调用:MediaCodec.createInputSurface()。我查看了media/NdkMediaCodec.h,但{strong>未列出了createInputSurface()

我是用错误的方式走的,有我不理解的东西吗?这是本机代码:

jboolean Java_com_business_rky_tht_1app_MjpegView_StartMP4Record(JNIEnv *env, jclass clazz, jobject surface, jstring filename) {

AMediaCodec *Native_codec = AMediaCodec_createEncoderByType("video/avc");
if (Native_codec != NULL)
{
    AMediaFormat *Media_Format = AMediaFormat_new();
    if (Media_Format != NULL) 
    {
        AMediaCrypto *Media_Crypto = NULL;
        uint32_t Config_Flags = AMEDIACODEC_CONFIGURE_FLAG_ENCODE;
        ANativeWindow *Native_Window  = ANativeWindow_fromSurface(env, surface);

        if(Native_Window == NULL)
            return JNI_FALSE;

        int32_t Frame_Height = ANativeWindow_getHeight(Native_Window);
        int32_t Frame_Width  = ANativeWindow_getWidth(Native_Window);

        // Make the work area of the frame a multiple of 64
        int32_t Image_Height = (Frame_Height & (0xFFFFFFC0) );
        int32_t Image_Width = (Frame_Width & (0xFFFFFFC0) );
        int32_t Color_Format = ANativeWindow_getFormat(Native_Window);

        // No limits for input size
        // AMediaFormat_setInt32(format, "max-input-size", 0);
        AMediaFormat_setInt32(Media_Format, AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, 0);
        AMediaFormat_setInt32(Media_Format, AMEDIAFORMAT_KEY_MAX_HEIGHT, Frame_Height);
        AMediaFormat_setInt32(Media_Format, AMEDIAFORMAT_KEY_MAX_WIDTH, Frame_Width);
        AMediaFormat_setString(Media_Format, AMEDIAFORMAT_KEY_MIME, "video/avc");
        AMediaFormat_setInt32(Media_Format, AMEDIAFORMAT_KEY_HEIGHT, Frame_Height);
        AMediaFormat_setInt32(Media_Format, AMEDIAFORMAT_KEY_WIDTH, Frame_Width);

        // ** For simplicity we just crop from right and bottom,
        // ** to center the image 1/2 the differences should be
        // ** cropped from all four sides
        AMediaFormat_setInt32(Media_Format, "crop-left" , 0);
        AMediaFormat_setInt32(Media_Format, "crop-top" , 0);
        AMediaFormat_setInt32(Media_Format, "crop-right" , (Image_Width - 1));
        AMediaFormat_setInt32(Media_Format, "crop-bottom" , (Image_Height - 1));
        AMediaFormat_setInt32(Media_Format,AMEDIAFORMAT_KEY_STRIDE,Frame_Width);

        AMediaFormat_setInt32(Media_Format, AMEDIAFORMAT_KEY_COLOR_FORMAT, Color_Format);

        media_status_t rc = AMediaCodec_configure(Native_codec, Media_Format, NULL, NULL, Config_Flags);

        if (AMEDIA_OK == rc) {

            AMediaCodec_createInputSurface(Native_codec, &Native_Window);
                            //  ^^^ UNRESOLVED - UNRESOLVED - UNRESOLVED ^^^


            // Would start codec and create muxer
            // .
            // .
            // .
            return JNI_TRUE;
        }else{
            AMediaCodec_delete(Native_codec);
            ANativeWindow_release(Native_Window);
            return JNI_FALSE;
        }
    } // End - if (Media_Format != NULL)
} // End - if (Native_codec != NULL)

} //结束-StartMP4Rec


构建错误:

  

构建命令失败。执行过程时出错   C:\ Users \ rky \ AppData \ Local \ Android \ Sdk \ ndk-bundle \ ndk-build.cmd与   参数{NDK_PROJECT_PATH = null   APP_BUILD_SCRIPT = C:\ Users \ rky \ AndroidStudioProjects \ THT_App \ app \ src \ main \ jni \ Android.mk   NDK_APPLICATION_MK = C:\ Users \ rky \ AndroidStudioProjects \ THT_App \ app \ src \ main \ jni \ Application.mk   APP_ABI = arm64-v8a NDK_ALL_ABIS = arm64-v8a NDK_DEBUG = 1   APP_PLATFORM = android-18   NDK_OUT = C:/用户/ rky / AndroidStudioProjects / THT_App / app / build / intermediates / ndkBuild / debug / obj   NDK_LIBS_OUT = C:\ Users \ rky \ AndroidStudioProjects \ THT_App \ app \ build \ intermediates \ ndkBuild \ debug \ lib   C:/Users/rky/AndroidStudioProjects/THT_App/app/build/intermediates/ndkBuild/debug/obj/local/arm64-v8a/libMjpgToMP4.so}   [arm64-v8a]编译++:MjpgToMP4 <= MjpgToMP4.cpp   C:/用户/rky/AndroidStudioProjects/THT_App/app/src/main/jni/MjpgToMP4/MjpgToMP4.cpp:320:17:   错误:使用未声明的标识符“ AMediaCodec_createInputSurface”;   您是说'AMediaCodec_setOutputSurface'吗?                   AMediaCodec_createInputSurface(Native_codec,&Native_Window);                   ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~                   AMediaCodec_setOutputSurface C:/ Users / rky / AppData / Local / Android / Sdk / ndk-bundle / build //../ sysroot / usr / include \ media / NdkMediaCodec.h:266:16:   注意:此处声明为“ AMediaCodec_setOutputSurface” media_status_t   AMediaCodec_setOutputSurface(AMediaCodec *,ANativeWindow *曲面)   __INTRODUCED_IN(21);                  ^ C:/Users/rky/AndroidStudioProjects/THT_App/app/src/main/jni/MjpgToMP4/MjpgToMP4.cpp:320:62:   错误:无法使用以下命令初始化类型为'ANativeWindow '的参数   类型“ ANativeWindow ”的右值                   AMediaCodec_createInputSurface(Native_codec,&Native_Window);                                                                ^ ~~~~~~~~~~~~~   C:/ Users / rky / AppData / Local / Android / Sdk / ndk-bundle / build //../ sysroot / usr / include \ media / NdkMediaCodec.h:266:74:   注意:在此处将参数传递给参数“ surface” media_status_t   AMediaCodec_setOutputSurface(AMediaCodec ,ANativeWindow *曲面)   __INTRODUCED_IN(21);                                                                            ^产生2个错误。制作:*   [C:/Users/rky/AndroidStudioProjects/THT_App/app/build/intermediates/ndkBuild/debug/obj/local/arm64-v8a/objs-debug/MjpgToMP4/MjpgToMP4.o]   错误1

2 个答案:

答案 0 :(得分:2)

这些函数是在API级别 21 26中引入的,但是您的版本指定APP_PLATFORM = android-18。确保在build.gradle中不要将minSdkVersion设置得太低。

答案 1 :(得分:-1)

[已解决]正如Alex Cohn修改过的答案所表明的那样。尽管文档中说了什么,但API 26 NOT 21中还是引入了AMediaCodec_createInputSurface(...)。如果我将应用gradle.build编辑为:“ minSdkVersion 26”,则解决了AMediaCodec_createInputSurface(...)。如果将其更改为:“ minSdkVersion 25”,则不会解析AMediaCodec_createInputSurface(...)。简而言之,文档是错误的。