Документация NDK гласит, что эта функция доступна (https://developer.android.com/ndk/reference/group/media#group___media_1ga8eb3e60bb5c76e90d7652dff636dd17b), и действительно ее можно вызывать из кода Java, но она выдает ошибку "неразрешенная функция" [в Android Studio] из кода C ++.
Я пытаюсь передать поток MJPEG в MediaCodec
и сделать так, чтобы MediaMuxer
записал видео MP4 с него. Я нашел ограниченные примеры того, как делать подобные вещи в коде Java, но примеры ZERO, как делать что-то подобное в родном коде. Поэтому я попытался дублировать примеры Java в нативном коде. Этот конкретный вызов функции представляется относительно важным для достижения моей цели, и я могу успешно вызвать: MediaCodec.createInputSurface()
из Java-кода. Я посмотрел на media/NdkMediaCodec.h
и 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 = ноль
APP_BUILD_SCRIPT = C: \ Users \ скалистый \ AndroidStudioProjects \ THT_App \ приложение \ SRC \ главная \ JNI \ Android.mk
NDK_APPLICATION_MK = C: \ Users \ скалистый \ AndroidStudioProjects \ THT_App \ приложение \ SRC \ главная \ JNI \ Application.mk
APP_ABI = arm64-v8a NDK_ALL_ABIS = arm64-v8a NDK_DEBUG = 1
APP_PLATFORM = андроид-18
NDK_OUT = C: / Users / скалистый / AndroidStudioProjects / THT_App / приложение / сборки / промежуточные / ndkBuild / отлаживать / объект
NDK_LIBS_OUT = C: \ Users \ скалистый \ AndroidStudioProjects \ THT_App \ приложение \ сборка \ полупродуктов \ ndkBuild \ Debug \ Lib
С: /Users/rky/AndroidStudioProjects/THT_App/app/build/intermediates/ndkBuild/debug/obj/local/arm64-v8a/libMjpgToMP4.so}
[arm64-v8a] Компиляция ++: MjpgToMP4 <= MjpgToMP4.cpp
С: /Users/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 * surface)
__INTRODUCED_IN (21);
^ C: /Users/rky/AndroidStudioProjects/THT_App/app/src/main/jni/MjpgToMP4/MjpgToMP4.cpp: 320: 62:
ошибка: невозможно инициализировать параметр типа «ANativeWindow <em>» с
Значение типа 'ANativeWindow '
AMediaCodec_createInputSurface (Native_codec, & Native_Window);
^ ~~~~~~~~~~~~~
C: / Users / скалистый / AppData / Local / Android / Sdk / NDK-расслоение / построить //../ SYSROOT / USR / включать \ Media / NdkMediaCodec.h: 266: 74:
примечание: передача аргумента параметру 'surface' здесь media_status_t
AMediaCodec_setOutputSurface (AMediaCodec , ANativeWindow * surface)
__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