0

I'm trying to get render video streamed by ffmpeg on to a surfaceview on Android. My code is passing the compilation but it is crashing during runtime. By using the nm tool (part of NDK), I was checking the compiler generated symbols and found that it added some special prefixes (like _Z6) and suffixes (e.g: _JNIEnvP8_jobjectP8_jstring). This could be valid if it does only for JNI methods. But it is doing the same for functions included from shared object files like libavcodec.so . Am I missing some thing here?

NDK version: 15.2.**** (Latest)

ndk {
        abiFilters 'armeabi'
    }
    externalNativeBuild {
        cmake {
            arguments '-DANDROID_PLATFORM=android-16',
                    '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=gnustl_static', '-DANDROID_DEPRECATED_HEADERS=ON', "-DANDROID_CPP_FEATURES=rtti exceptions"
        }
        ndkBuild {
            arguments "APP_DEPRECATED_HEADERS=true"
        }
    }

Below is the output of the nm tool.

arm-linux-androideabi-nm -a ../.externalNativeBuild/cmake/release/armeabi/CMakeFiles/ffmpeg-jni.dir/ffmpeg-jni.cpp.o
00000000 n .ARM.attributes
00000000 r .ARM.exidx.text.JNI_OnLoad
00000000 r .ARM.exidx.text._Z12createBitmapP7_JNIEnvii
00000000 r .ARM.exidx.text._Z12naSetSurfaceP7_JNIEnvP8_jobjectS2_
00000000 r .ARM.exidx.text._Z13naGetVideoResP7_JNIEnvP8_jobject
00000000 r .ARM.exidx.text._Z15decodeAndRenderPv
00000000 r .ARM.exidx.text._Z6finishP7_JNIEnv
00000000 r .ARM.exidx.text._Z6naInitP7_JNIEnvP8_jobjectP8_jstring
00000000 r .ARM.exidx.text._Z6naPlayP7_JNIEnvP8_jobject
00000000 r .ARM.exidx.text._Z6naStopP7_JNIEnvP8_jobject
00000000 r .ARM.exidx.text._Z6wcslenPKw
00000000 r .ARM.exidx.text._Z7naSetupP7_JNIEnvP8_jobjectii
00000000 r .ARM.exidx.text._ZN7_JNIEnv22CallStaticObjectMethodEP7_jclassP10_jmethodIDz
00000000 r .ARM.extab.text.JNI_OnLoad
00000000 r .ARM.extab.text._Z12createBitmapP7_JNIEnvii
00000000 r .ARM.extab.text._Z12naSetSurfaceP7_JNIEnvP8_jobjectS2_
00000000 r .ARM.extab.text._Z13naGetVideoResP7_JNIEnvP8_jobject
00000000 r .ARM.extab.text._Z15decodeAndRenderPv
00000000 r .ARM.extab.text._Z6finishP7_JNIEnv
00000000 r .ARM.extab.text._Z6naInitP7_JNIEnvP8_jobjectP8_jstring
00000000 r .ARM.extab.text._Z6naPlayP7_JNIEnvP8_jobject
00000000 r .ARM.extab.text._Z6naStopP7_JNIEnvP8_jobject
00000000 r .ARM.extab.text._Z6wcslenPKw
00000000 r .ARM.extab.text._Z7naSetupP7_JNIEnvP8_jobjectii
00000000 r .ARM.extab.text._ZN7_JNIEnv22CallStaticObjectMethodEP7_jclassP10_jmethodIDz
00000000 r .L.str
00000042 r .L.str.17
00000000 r .L.str.6
0000000d r .L.str.9
00000000 b .bss
00000000 n .comment
00000000 d .data
00000000 N .debug_abbrev
00000000 N .debug_frame
00000000 N .debug_info
00000000 N .debug_line
00000000 N .debug_loc
00000000 N .debug_macinfo
00000000 N .debug_pubnames
00000000 N .debug_pubtypes
00000000 N .debug_ranges
00000000 N .debug_str
00000000 n .group
00000000 n .note.GNU-stack
00000000 r .rodata.str1.1
00000000 r .rodata.str4.4
00000000 t .text
00000000 t .text.JNI_OnLoad
00000000 t .text._**Z12**createBitmapP7_JNIEnvii
00000000 t .text._**Z12**naSetSurfaceP7_JNIEnvP8_jobjectS2_
00000000 t .text._**Z13**naGetVideoResP7_JNIEnvP8_jobject
00000000 t .text._Z15decodeAndRenderPv
00000000 t .text._Z6finishP7_JNIEnv
00000000 t .text._Z6naInitP7_JNIEnvP8_jobjectP8_jstring
00000000 t .text._Z6naPlayP7_JNIEnvP8_jobject
00000000 t .text._Z6naStopP7_JNIEnvP8_jobject
00000000 t .text._Z6wcslenPKw
00000000 t .text._Z7naSetupP7_JNIEnvP8_jobjectii
00000000 t .text._ZN7_JNIEnv22CallStaticObjectMethodEP7_jclassP10_jmethodIDz
00000000 a /Users/gopinath/repos/app_android/productionapp/app/src/main/cpp/ffmpeg-jni.cpp
         U ANativeWindow_fromSurface
         U ANativeWindow_lock
         U ANativeWindow_release
         U ANativeWindow_setBuffersGeometry
         U ANativeWindow_unlockAndPost
         U AndroidBitmap_lockPixels
         U AndroidBitmap_unlockPixels
00000000 T JNI_OnLoad
00000000 T _Z12createBitmapP7_JNIEnvii
00000000 T _Z12naSetSurfaceP7_JNIEnvP8_jobjectS2_
         U _Z13av_read_frameP15AVFormatContextP8AVPacket
         U _Z13avcodec_closeP14AVCodecContext
         U _Z13avcodec_open2P14AVCodecContextPK7AVCodecPP12AVDictionary
00000000 T _Z13naGetVideoResP7_JNIEnvP8_jobject
         U _Z14av_dump_formatP15AVFormatContextiPKci
         U _Z14av_frame_allocv
         U _Z14av_free_packetP8AVPacket
         U _Z14sws_getContextii13AVPixelFormatiiS_iP9SwsFilterS1_PKd
         U _Z15av_register_allv
00000000 T _Z15decodeAndRenderPv
         U _Z19avformat_open_inputPP15AVFormatContextPKcP13AVInputFormatPP12AVDictionary
         U _Z20av_image_fill_arraysPPhPiPKh13AVPixelFormatiii
         U _Z20avcodec_find_decoder9AVCodecID
         U _Z20avformat_close_inputPP15AVFormatContext
         U _Z21avcodec_decode_video2P14AVCodecContextP7AVFramePiPK8AVPacket
         U _Z25avformat_find_stream_infoP15AVFormatContextPP12AVDictionary
00000000 T _Z6finishP7_JNIEnv
00000000 T _Z6naInitP7_JNIEnvP8_jobjectP8_jstring
00000000 T _Z6naPlayP7_JNIEnvP8_jobject
00000000 T _Z6naStopP7_JNIEnvP8_jobject
00000000 T _Z6wcslenPKw
         U _Z7av_freePv
00000000 T _Z7naSetupP7_JNIEnvP8_jobjectii
         U _Z9sws_scaleP10SwsContextPKPKhPKiiiPKPhS6_
00000000 W _ZN7_JNIEnv22CallStaticObjectMethodEP7_jclassP10_jmethodIDz
         U __aeabi_memcpy
         U __aeabi_unwind_cpp_pr0
         U __aeabi_unwind_cpp_pr1
         U __android_log_print
         U __sF
         U __stack_chk_fail
         U __stack_chk_guard
0000001c B bitmap
00000020 B buffer
00000010 B codecCtx
00000014 B decodedFrame
00000008 B formatCtx
00000018 B frameRGBA
         U fwrite
0000002c B height
         U malloc
         U pthread_create
00000030 B stop
00000024 B sws_ctx
00000004 B videoFileName
0000000c B videoStream
00000028 B width
00000000 B window

It adds prefixes and suffixes for library defined functions like _Z14av_frame_allocv. (Here _Z14 & v are prepended and appended by the compiler) Did anyone face a similar problem as this is? Can somebody point me to what is happening here and how can I make it omit the extra prefixes and suffixes?

Gopinath
  • 12,981
  • 6
  • 36
  • 50

2 Answers2

2

It took a while for me to figure out since I am a newbie w.r.to native development. The problem was that I was combining both C & C++ code and compiling using g++ compiler. In order for c++ to support method overloading, the compiler was appending unique prefixes and suffixes.

The solution is to import the C header files under extern C block. Or Make the whole file as .c file and compile with gcc wherever possible. The later solution worked for me.

Gopinath
  • 12,981
  • 6
  • 36
  • 50
1

Wrap your C code inside an extern C block.

extern "C"
{
   void foo(char);
   int bar;
}

This is to tell the C++ compiler not to do any name mangling on the specific code. More details on name mangling here.