bytedeco / javacv

Java interface to OpenCV, FFmpeg, and more
Other
7.6k stars 1.59k forks source link

The JVM may crash unexpectedly while merging two audio files #2295

Open CharlieAJing opened 3 weeks ago

CharlieAJing commented 3 weeks ago

here is part of the erro info in hs_error_pid.log

jdk version 11

A fatal error has been detected by the Java Runtime Environment: SIGSEGV (0xb) at pc=0x00007f5a92c1229d, pid=3206, tid=34567


Problematic frame: C [libswresample.so.4+0x1129d]


--------------- T H R E A D ---------------

Current thread (0x00007f5a2bfd9800): JavaThread "Record-IO-5" [_thread_in_native, id=34567, stack(0x00007f59f2ff8000,0x00007f59f30f9000)]

Stack: [0x00007f59f2ff8000,0x00007f59f30f9000], sp=0x00007f59f30f6a78, free space=1018k Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code) C [libswresample.so.4+0x1129d]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code) J 16021 org.bytedeco.ffmpeg.global.swresample.swr_convert(Lorg/bytedeco/ffmpeg/swresample/SwrContext;Lorg/bytedeco/javacpp/PointerPointer;ILorg/bytedeco/javacpp/PointerPointer;I)I (0 bytes) @ 0x00007f5a7df33a71 [0x00007f5a7df339e0+0x0000000000000091] J 44183 c2 org.bytedeco.javacv.FFmpegFrameRecorder.recordSamples(II[Ljava/nio/Buffer;)Z (1878 bytes) @ 0x00007f5a7f2b9ce4 [0x00007f5a7f2b8fc0+0x0000000000000d24] J 16044 c2 org.bytedeco.javacv.FFmpegFrameRecorder.record(Lorg/bytedeco/javacv/Frame;)V (34 bytes) @ 0x00007f5a7df66048 [0x00007f5a7df65f60+0x00000000000000e8] ......


Internal exceptions (20 events): Event: 44605.237 Thread 0x00007f5a33748800 Exception <a 'java/lang/InterruptedException'{0x00000007fb1f2510}> (0x00000007fb1f2510) thrown at [./src/hotspot/share/runtime/objectMonitor.cpp, line 1736] Event: 44605.237 Thread 0x00007f5a4dbbf000 Exception <a 'java/net/SocketException'{0x0000000792e85960}: Socket closed> (0x0000000792e85960) thrown at [./src/hotspot/share/prims/jni.cpp, line 637] Event: 44605.849 Thread 0x00007f5a57b59800 Exception <a 'java/io/IOException'{0x0000000791fd69d8}> (0x0000000791fd69d8) thrown at [./src/hotspot/share/prims/jni.cpp, line 616] Event: 44605.849 Thread 0x00007f5a57b59800 Exception <a 'java/io/IOException'{0x0000000791fdc608}> (0x0000000791fdc608) thrown at [./src/hotspot/share/prims/jni.cpp, line 616] Event: 44605.920 Thread 0x00007f5a0ca91000 Exception <a 'java/net/SocketException'{0x000000079c84d6c8}: Socket closed> (0x000000079c84d6c8) thrown at [./src/hotspot/share/prims/jni.cpp, line 637] Event: 44608.772 Thread 0x00007f5a4d8b4000 Exception <a 'java/net/SocketException'{0x00000007860fb378}: Socket closed> (0x00000007860fb378) thrown at [./src/hotspot/share/prims/jni.cpp, line 637] Event: 44608.772 Thread 0x00007f5a4d8b7800 Exception <a 'java/lang/InterruptedException'{0x0000000787efaae8}> (0x0000000787efaae8) thrown at [./src/hotspot/share/runtime/objectMonitor.cpp, line 1736] Event: 44608.772 Thread 0x00007f5a2b52e800 Exception <a 'java/lang/InterruptedException'{0x00000007c9ccecf0}> (0x00000007c9ccecf0) thrown at [./src/hotspot/share/runtime/objectMonitor.cpp, line 1736] Event: 44608.772 Thread 0x00007f5a4d8b7800 Exception <a 'java/net/SocketException'{0x0000000787efadf0}: Socket closed> (0x0000000787efadf0) thrown at [./src/hotspot/share/prims/jni.cpp, line 637] Event: 44609.755 Thread 0x00007f5a5f0c8000 Exception <a 'java/net/SocketException'{0x000000078df38180}: Socket closed> (0x000000078df38180) thrown at [./src/hotspot/share/prims/jni.cpp, line 637] Event: 44610.850 Thread 0x00007f5a57b59800 Exception <a 'java/io/IOException'{0x000000077e6e5808}> (0x000000077e6e5808) thrown at [./src/hotspot/share/prims/jni.cpp, line 616] Event: 44610.850 Thread 0x00007f5a57b59800 Exception <a 'java/io/IOException'{0x000000077e6f7f38}> (0x000000077e6f7f38) thrown at [./src/hotspot/share/prims/jni.cpp, line 616] Event: 44615.854 Thread 0x00007f5a57b59800 Exception <a 'java/io/IOException'{0x000000076e946238}> (0x000000076e946238) thrown at [./src/hotspot/share/prims/jni.cpp, line 616] Event: 44615.855 Thread 0x00007f5a57b59800 Exception <a 'java/io/IOException'{0x000000076e9543d0}> (0x000000076e9543d0) thrown at [./src/hotspot/share/prims/jni.cpp, line 616] Event: 44618.341 Thread 0x00007f5a4db77000 Exception <a 'java/net/SocketException'{0x00000007ff70e138}: Socket closed> (0x00000007ff70e138) thrown at [./src/hotspot/share/prims/jni.cpp, line 637] Event: 44618.341 Thread 0x00007f5a4db78000 Exception <a 'java/lang/InterruptedException'{0x00000007fd71a510}> (0x00000007fd71a510) thrown at [./src/hotspot/share/runtime/objectMonitor.cpp, line 1736] Event: 44618.341 Thread 0x00007f5a4db78000 Exception <a 'java/net/SocketException'{0x00000007fd71a818}: Socket closed> (0x00000007fd71a818) thrown at [./src/hotspot/share/prims/jni.cpp, line 637] Event: 44619.074 Thread 0x00007f5a602c8000 Exception <a 'java/net/SocketException'{0x00000007fc51b568}: Socket closed> (0x00000007fc51b568) thrown at [./src/hotspot/share/prims/jni.cpp, line 637] Event: 44620.855 Thread 0x00007f5a57b59800 Exception <a 'java/io/IOException'{0x00000007f24d8c78}> (0x00000007f24d8c78) thrown at [./src/hotspot/share/prims/jni.cpp, line 616] Event: 44620.856 Thread 0x00007f5a57b59800 Exception <a 'java/io/IOException'{0x00000007f24e8b28}> (0x00000007f24e8b28) thrown at [./src/hotspot/share/prims/jni.cpp, line 616]


here is my code

try (
    FrameGrabber grabberL = new FrameGrabber(task.getLeftChannelInputFile());
    FrameGrabber grabberR = new FrameGrabber(task.getRightChannelInputFile());
    FFmpegFrameRecorder recorder = createRecorder(task.getOutputFile(), 2)
) {
    grabberL.start();
    grabberR.start();
    recorder.start();

    Frame frameL = getFirstFrame(grabberL);
    Frame frameR = getFirstFrame(grabberR);
    if (ObjectUtils.allNull(frameL, frameR)){
        log.error("^mixRecord^ all frame is null,taskId={}", task.getTaskId());
        return true;
    }

    LocalDateTime expireTime = startTime.plusSeconds(recordConfig.getJniMixTimeoutSeconds());
    while (true) {
        if (expireTime.isBefore(LocalDateTime.now())) {
            log.error("^mixRecord^ timeout, taskId:{}", task.getTaskId());
            break;
        }
        Buffer[] samples = new Buffer[2];
        if (frameL == null && frameR == null) {
            break;
        } else if (frameL != null && frameR != null) {
            samples[0] = frameL.samples[0]; 
            samples[1] = frameR.samples[0];
        } else if (frameL != null) {
            samples[0] = frameL.samples[0];
            samples[1] = createSilenceSampleIfAbsent(null, frameL.samples[0].capacity());
        } else {
            samples[0] = createSilenceSampleIfAbsent(null, frameR.samples[0].capacity());
            samples[1] = frameR.samples[0];
        }

        Frame mixedFrame = new Frame();
        mixedFrame.samples = samples;
        mixedFrame.sampleRate = task.getOutputFile().getSampleRate();
        mixedFrame.audioChannels = 2;
        mixedFrame.opaque = Objects.requireNonNull(ObjectUtils.defaultIfNull(frameL, frameR).opaque);
        recorder.record(mixedFrame);

        frameL = grabberL.grab();
        frameR = grabberR.grab();
    }
    return true;
} catch (Exception e) {
    ...
    return false;
}

@NotNull
private static FFmpegFrameRecorder createRecorder(OutputFile outputFile, int audioChannels) {
    FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputFile.getFile(), audioChannels);
    recorder.setSampleRate(outputFile.getSampleRate());
    recorder.setFormat(outputFile.getFormat());
    return recorder;
}

@Getter
private static class FrameGrabber extends FFmpegFrameGrabber{

    private final InputFile inputFile;

    public FrameGrabber(InputFile inputFile) {
        super(inputFile);
        this.inputFile = inputFile;
        this.setFormat(inputFile.getFormat());
        this.setAudioCodec(inputFile.getAudioCodec());
        this.setSampleRate(inputFile.getSampleRate());
    }

}

private static class InputFile extends File {
    //ignore
}

private Buffer createSilenceSampleIfAbsent(Buffer silenceSample, int capacity) {
    if (silenceSample == null || silenceSample.capacity() != capacity) {
        ShortBuffer silentBuffer = ShortBuffer.allocate(capacity);
        for (int i = 0; i < capacity; i++) {
            silentBuffer.put(i, (short) 0);
        }
        silenceSample = silentBuffer;
    }
    return silenceSample;
}

maven

org.bytedeco javacv 1.5.9 org.bytedeco javacv-platform 1.5.9

saudet commented 3 weeks ago

Please try to set the "org.bytedeco.javacpp.nopointergc" system property to "true".