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
答案 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(...)。简而言之,文档是错误的。