I have an app that streams video using Kickflip and ButterflyTV libRTMP
Now for 99% percent of the time the app is working ok, but from time to time I get a native s
"You can store the data in a
byte[]. This allows very fast access from managed code. On the native side, however, you're not guaranteed to be able to access the data without having to copy it."
See https://developer.android.com/training/articles/perf-jni.html
Some musings and things to try:
frame data has been removed/damaged/locked/movedframe variable info (using ByteBuffer) to mRTMPMuxer.writeVideobyte buffers,in ByteBuffer the storage is not allocated on the managed heap, and can always be accessed directly from native code.//allocates memory from the native heap ByteBuffer data = ByteBuffer.allocateDirect(frame.getData().length); data.clear(); //System.gc(); //copy data data.get(frame.getData(), 0, frame.getData().length); //data = (frame.getData() == null) ? null : frame.getData().clone(); int offset = frame.getOffset(); int size = frame.getSize(); int time = frame.getTime(); writeResult = mRTMPMuxer.writeVideo(data , offset, size, time); JNIEXPORT jint JNICALL Java_net_butterflytv_rtmp_1client_RTMPMuxer_writeVideo( JNIEnv *env, jobject instance, jobject data_, //NOT jbyteArray data_, jint offset, jint length, jint timestamp) { jbyte *data = env->GetDirectBufferAddress(env, data);//GetDirectBufferAddress NOT GetByteArrayElements jint result = rtmp_sender_write_video_frame(data, length, timestamp, 0, 0); //(*env)->ReleaseByteArrayElements(env, data_, data, 0);//???? return result; }Debugging
Some code from SO Catching exceptions thrown from native code:
    static uint32_t find_start_code(uint8_t *buf, uint32_t zeros_in_startcode){
    //...
    try {
        if ((info = (buf[zeros_in_startcode] != 1)? 0: 1) == 0) return 0;//your code
    }
    // You can catch std::exception for more generic error handling
    catch (std::exception e){
        throwJavaException (env, e.what());//see method below
    }
    //...
Then a new method:
    void throwJavaException(JNIEnv *env, const char *msg)
    {
     // You can put your own exception here
     jclass c = env->FindClass("java/lang/RuntimeException");
     if (NULL == c)
     {
         //B plan: null pointer ...
         c = env->FindClass("java/lang/NullPointerException");
     }
     env->ThrowNew(c, msg);
    }
}
Don't get too hung up on SEGV_ACCERR, you have a segmentation fault,SIGSEGV (caused by a program trying to read or write an illegal memory location, read in your case).
From siginfo.h:
SEGV_MAPERR means you tried to access an address that doesn't map to anything. SEGV_ACCERR means you tried to access an address that you don't have permission to access.
This may be of interest:
Q: I noticed that there was RTMP support. But a patch which remove RTMP had been merged.
Q: Could you tell me why ?
A: We don't think RTMP serves the mobile broadcasting use case as well as HLS,
A: and so we don't want to dedicate our limited resources towards supporting it.
see: https://github.com/Kickflip/kickflip-android-sdk/issues/33
I suggest you register an issue with:
https://github.com/Kickflip/kickflip-android-sdk/issues
https://github.com/ButterflyTV/LibRtmp-Client-for-Android/issues
By symptom/description of the problem, your program is most likely experiencing some sort of invalid memory access/corruption which is somehow related with multi-thread race condition scenario. From my past experience, debugging memory corruption itself is very difficult and if it is linked to multi-thread environment it becomes very very difficult. Some of my previous post might be helpful and provide some general guidelines on these topics. Please note that these posts are related to Windows/Linux and not for Android platform.
cpp - valgrind - Invalid read of size 8
A segmentation fault sometimes occurs when the function cvCreateFileCapture is invoked on network URL
While reading further about similar issue and your code sinppet, I came across one post which is mentioned below:
What does SEGV_ACCERR mean?
Client code snippet of your application
synchronized (mWriteFence) {
                if (!mConnected) {
                    continue;
                }
                if (frame.getFrameType() == Frame.VIDEO_FRAME) {
                    writeResult = mRTMPMuxer.writeVideo(frame.getData(), frame.getOffset(), frame.getSize(), frame.getTime());
                    calcVideoFpsAndBitrate(frame.getSize());
                } else if (frame.getFrameType() == Frame.AUDIO_FRAME) {
                    writeResult = mRTMPMuxer.writeAudio(frame.getData(), frame.getOffset(), frame.getSize(), frame.getTime());
                    calcAudioBitrate(frame.getSize());
                }
}
From above code, it appears to me that if your application receives  Frame.VIDEO_FRAME &  Frame.AUDIO_FRAME in certain order it might be leading to some sort of race condition(may be async model implementation) while using the frame variable within RtmpMuxerMix.writeThread module. 
To conclude such issues:
.