Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash of jvm on grabbing devices from ffmpeg response #1445

Open
stserakhau opened this issue Dec 8, 2023 · 4 comments
Open

Crash of jvm on grabbing devices from ffmpeg response #1445

stserakhau opened this issue Dec 8, 2023 · 4 comments

Comments

@stserakhau
Copy link

stserakhau commented Dec 8, 2023

Hi All,

        <bytedeco.version>1.5.10-SNAPSHOT</bytedeco.version>
        <bytedeco.ffmpeg.version>6.1</bytedeco.ffmpeg.version>
        <bytedeco.opencv.version>4.8.1</bytedeco.opencv.version>

&

        <bytedeco.version>1.5.9</bytedeco.version>
        <bytedeco.ffmpeg.version>6.0</bytedeco.ffmpeg.version>
        <bytedeco.opencv.version>4.7.0</bytedeco.opencv.version>

sometimes I catch crash of JVM on the line

log.info("4: {}, {}, {}, {}", context, device, inputFormat, options);
            if (res == 0) {
                res = avformat_open_input(context, device, inputFormat, options); <<<<<< crash probably here

1st case of the output before crash log.txt

# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000000000000, pid=12876, tid=4168
#
# JRE version: Java(TM) SE Runtime Environment (20.0.2+9) (build 20.0.2+9-78)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (20.0.2+9-78, mixed mode, emulated-client, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, windows-amd64)
# Problematic frame:
# C  0x00007ff8f1f11a5d

hs_err_pid12876.log

2nd case of the output before crash log2.txt

2023-12-08T11:45:42,570 INFO  [ForkJoinPool-1-worker-1] c.b.b.s.w.LocalMediaDeviceDiscoveryService: 4: org.bytedeco.ffmpeg.avformat.AVFormatContext[address=0x1e722c100c0,position=0,limit=0,capacity=0,deallocator=null], audio=@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{EB1F26F3-AAA6-4A20-AAB1-F0AA36AF8F4D}, org.bytedeco.ffmpeg.avformat.AVInputFormat[address=0x7ff8f2316c80,position=0,limit=0,capacity=0,deallocator=null], org.bytedeco.ffmpeg.avutil.AVDictionary[address=0x1e721fa09c0,position=0,limit=0,capacity=0,deallocator=null]
terminate called after throwing an instance of 'JavaCPP_exception'
  what():  java.lang.NullPointerException
terminate called recursively

Source code:

import com.banalytics.box.module.model.discovery.AudioDevice;
import com.banalytics.box.module.model.discovery.AudioProperties;
import com.banalytics.box.module.model.discovery.VideoDevice;
import com.banalytics.box.module.model.discovery.VideoProperties;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.ffmpeg.avcodec.AVCodec;
import org.bytedeco.ffmpeg.avcodec.AVCodecHWConfig;
import org.bytedeco.ffmpeg.avformat.AVOutputFormat;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avformat;
import org.bytedeco.javacpp.Pointer;

import java.util.*;
import java.util.stream.Collectors;

import static org.bytedeco.ffmpeg.global.avcodec.*;
import static org.bytedeco.ffmpeg.global.avutil.AVMEDIA_TYPE_VIDEO;

@Slf4j
public abstract class AbstractLocalMediaDeviceDiscovery {
    protected Map<String, AudioDevice> audioDevices = new HashMap<>();
    protected Map<String, VideoDevice> videoDevices = new HashMap<>();

    protected abstract void scanLocalDevices();

    public List<String> microphones() {
        scanLocalDevices();
        return audioDevices.values().stream()
                .sorted(Comparator.comparing(a -> a.name))
                .map(d -> d.alternativeName + "~" + d.name)
                .collect(Collectors.toList());
    }

    public List<String> cameras() {
        scanLocalDevices();
        return videoDevices.values().stream()
                .sorted(Comparator.comparing(a -> a.name))
                .map(d -> d.alternativeName + "~" + d.name)
                .collect(Collectors.toList());
    }

    public List<String> cameraResolutionsFps(String camera) {
        for (VideoDevice vd : videoDevices.values()) {
            if (vd.alternativeName.equals(camera)) {
                TreeSet<VideoProperties.ResolutionFpsCase> cases = vd.videoProperties.resolutionFpsCases;
                List<String> result = new ArrayList<>();
                for (VideoProperties.ResolutionFpsCase rfc : cases) {
                    String key = rfc.getWidth() + "x" + rfc.getHeight() + "/" + rfc.getMinFps() + "-" + rfc.getMaxFps();
                    String value = key;
                    if (rfc.getMinFps() != rfc.getMinRecommendedFps() || rfc.getMaxFps() != rfc.getMaxRecommendedFps()) {
                        value += " (" + rfc.getMinRecommendedFps() + "-" + rfc.getMaxRecommendedFps() + ")";
                    }
                    result.add(key + "~" + value);
                }
                return result;
            }
        }
        return Collections.emptyList();
    }

    public Set<String> audioSupportedSampleRates(String audio) {
        AudioDevice audioDevice = audioDevices.get(audio);
        if (audioDevice == null) {
            return Collections.emptySet();
        }
        Set<String> result = new LinkedHashSet<>();
        AudioProperties ap = audioDevice.audioProperties;

        for (AudioProperties.AudioCase ac : ap.audioCases) {
            result.add("" + ac.getRate());
        }

        return result;
    }

    /*todo below experiments */
    private final Map<String, String> videoEncoders = new TreeMap<>();
    private final Map<String, String> videoDecoders = new TreeMap<>();

    private void loadCodecs() {
        Pointer i = new Pointer((Pointer) null);

        AVOutputFormat format = avformat.av_guess_format("mp4", null, null);
        int counter = 0;
        AVCodec codec = null;
        AVCodec testCodec;
        while ((testCodec = av_codec_iterate(i)) != null) {
            log.info("Iterate {}", i);
            if (testCodec.type() == AVMEDIA_TYPE_VIDEO) {
                if (avformat.avformat_query_codec(format, testCodec.id(), FF_COMPLIANCE_STRICT) > 0) {
                    log.info("\tFormat {}", i);
                    AVCodecHWConfig hwConfig = avcodec.avcodec_get_hw_config(testCodec, 0);
                    log.info("\tConfig {}", i);
                    if (hwConfig == null) {
                        continue;
                    }
                    for (int j = 0; ; j++) {
                        hwConfig = avcodec.avcodec_get_hw_config(testCodec, j);
                        log.info("\t\tConfig {}-{}", i, j);
                        if (hwConfig == null) {
                            break;
                        }
                        if ((hwConfig.methods() & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) > 0) {
                            log.info("\t\t" + testCodec.name().getString() + " supports device: " + hwConfig.device_type());
                            System.out.println();
                        }
                        //AV_HWDEVICE_TYPE_DXVA2
                    }

                    if (av_codec_is_encoder(testCodec) > 0)
                        log.info("\tis encoder {}", i);{
                        videoEncoders.put(testCodec.name().getString(), testCodec.long_name().getString());
                    }
                    if (av_codec_is_decoder(testCodec) > 0) {
                        log.info("\tis decoder {}", i);
                        videoDecoders.put(testCodec.name().getString(), testCodec.long_name().getString());
                    }
                }
            }
        }
    }

    public Set<String> accelerators() {
        return Set.of(
                "cuvid", "d3d11va", "dxva2", "libmfx", "qsv", "vaapi", "vdpau"
        );
    }

    public Map<String, String> accelerationDecoders() {
        if (videoEncoders.isEmpty()) {
            loadCodecs();
        }

        return videoDecoders;
    }
}
import com.banalytics.box.module.model.discovery.AudioDevice;
import com.banalytics.box.module.model.discovery.VideoDevice;
import com.banalytics.box.service.AbstractLocalMediaDeviceDiscovery;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.ffmpeg.avformat.AVFormatContext;
import org.bytedeco.ffmpeg.avformat.AVInputFormat;
import org.bytedeco.ffmpeg.avutil.AVDictionary;
import org.bytedeco.ffmpeg.avutil.LogCallback;
import org.bytedeco.ffmpeg.global.avformat;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacpp.BytePointer;
import org.bytedeco.javacv.FFmpegLogCallback;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

import java.util.*;

import static org.bytedeco.ffmpeg.global.avdevice.avdevice_register_all;
import static org.bytedeco.ffmpeg.global.avformat.*;
import static org.bytedeco.ffmpeg.global.avutil.av_dict_set;

@Slf4j
@Profile({"windows"})
@Service
public class LocalMediaDeviceDiscoveryService extends AbstractLocalMediaDeviceDiscovery implements InitializingBean {

    @Override
    public void afterPropertiesSet() throws Exception {
        try {
            avdevice_register_all();
            avutil.av_log_set_level(avutil.AV_LOG_FATAL);
        } catch (Throwable e) {
            log.error(e.getMessage(), e);
        }
    }

    private volatile long expirationTimeout;

    public synchronized void scanLocalDevices() {
        log.info("============Scan started");
        synchronized (org.bytedeco.ffmpeg.global.avcodec.class) {
            long now = System.currentTimeMillis();
//            if (now < expirationTimeout) {
//                log.info("============Scan results from cache");
//                return;
//            }
            expirationTimeout = now + 120 * 1000;
            List<String> result = Collections.synchronizedList(new ArrayList<>());
            avutil.av_log_set_level(avutil.AV_LOG_INFO);
            avutil.setLogCallback(new LogCallback() {
                StringBuilder line = new StringBuilder();

                @Override
                public void call(int i, BytePointer bytePointer) {
                    try {
                        String message = bytePointer.getString("UTF-8");
                        if (message.isEmpty()) {
                            return;
                        }
                        line.append(message);
                        boolean newLine = message.indexOf('\n') > -1;
                        if (newLine) {
                            result.add(line.toString().trim());
                            line = new StringBuilder();
                        }
                    } catch (Throwable e) {
                        log.error(e.getMessage(), e);
                    }
                }
            });

            DeviceInfoAccumulator deviceInfoAccumulator = new DeviceInfoAccumulator();
            try {
                result.clear();
                execute("dshow", "list_devices", "dummy");
                Thread.sleep(50);
                deviceInfoAccumulator.process(result);

                Set<String> removedAudioDevices = new HashSet<>(audioDevices.keySet());
                for (Map.Entry<String, AudioDevice> entry : deviceInfoAccumulator.audioDevices.entrySet()) {
                    String key = entry.getKey();
                    removedAudioDevices.remove(key);
                    AudioDevice value = entry.getValue();
                    if (audioDevices.containsKey(key)) {
                        continue;
                    }
                    audioDevices.put(key, value);
                }
                removedAudioDevices.forEach(key -> audioDevices.remove(key));

                Set<String> removedVideoDevices = new HashSet<>(videoDevices.keySet());
                for (Map.Entry<String, VideoDevice> entry : deviceInfoAccumulator.videoDevices.entrySet()) {
                    String key = entry.getKey();
                    removedVideoDevices.remove(key);
                    VideoDevice val = entry.getValue();
                    if (videoDevices.containsKey(key)) {
                        continue;
                    }
                    videoDevices.put(key, val);
                }
                removedVideoDevices.forEach(key -> videoDevices.remove(key));

            } catch (Throwable e) {
                log.info(e.getMessage());
            }
            for (VideoDevice videoDevice : videoDevices.values()) {
                if (!videoDevice.videoProperties.resolutionFpsCases.isEmpty()) {
                    continue;
                }
                VideoDevicePropertyAccumulator vda = new VideoDevicePropertyAccumulator();
                try {
                    result.clear();
                    execute("dshow", "list_options", "video=" + videoDevice.alternativeName);
                    Thread.sleep(50);
                    log.info("Executed 2");
                    vda.process(result);
                } catch (Throwable e) {
                    log.info(e.getMessage());
                } finally {
                    videoDevice.videoProperties = vda.videoProperties;
                }
            }
            for (AudioDevice audioDevice : audioDevices.values()) {
                if (!audioDevice.audioProperties.audioCases.isEmpty()) {
                    continue;
                }
                AudioDevicePropertyAccumulator ada = new AudioDevicePropertyAccumulator();
                try {
                    result.clear();
                    execute("dshow", "list_options", "audio=" + audioDevice.alternativeName);
                    ada.process(result);
                } catch (Throwable e) {
                    log.info(e.getMessage());
                } finally {
                    audioDevice.audioProperties = ada.audioProperties;
                }
            }
            log.info("============Scan done");
            try {
                Thread.sleep(50);
                avutil.av_log_set_level(avutil.AV_LOG_FATAL);
                Thread.sleep(50);
                FFmpegLogCallback.set();
                Thread.sleep(50);
                log.info("============Revert to default logger");
            } catch (InterruptedException e) {
                log.error(e.getMessage(), e);
            }
        }
    }

    private static void execute(String format, String option, String device) {
        log.info("Execute: {}, {}, {}", format, option, device);
        AVFormatContext context = avformat_alloc_context();
        AVDictionary options = new AVDictionary(null);
        AVInputFormat inputFormat = avformat.av_find_input_format(format);
        log.info("1");
        try {
            log.info("2");
            context.iformat(inputFormat);
            log.info("3");
            Thread.sleep(50);
            int res = av_dict_set(options, option, "true", 0);//list_options or list_formats
            //4: org.bytedeco.ffmpeg.avformat.AVFormatContext[address=0x1e5a1490840,position=0,limit=0,capacity=0,deallocator=null], dummy, org.bytedeco.ffmpeg.avformat.AVInputFormat[address=0x7ff8f5de6c60,position=0,limit=0,capacity=0,deallocator=null], org.bytedeco.ffmpeg.avutil.AVDictionary[address=0x1e5154fcb40,position=0,limit=0,capacity=0,deallocator=null]
            //4: org.bytedeco.ffmpeg.avformat.AVFormatContext[address=0x1e5a1490840,position=0,limit=0,capacity=0,deallocator=null], video=@device_pnp_\\?\\usb#vid_0c45&pid_636b&mi_00#6&1d140336&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global, org.bytedeco.ffmpeg.avformat.AVInputFormat[address=0x7ff8f5de6c60,position=0,limit=0,capacity=0,deallocator=null], org.bytedeco.ffmpeg.avutil.AVDictionary[address=0x1e4bccfedc0,position=0,limit=0,capacity=0,deallocator=null]

            //4: org.bytedeco.ffmpeg.avformat.AVFormatContext[address=0x1e5a1490840,position=0,limit=0,capacity=0,deallocator=null], audio=@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{EB1F26F3-AAA6-4A20-AAB1-F0AA36AF8F4D}, org.bytedeco.ffmpeg.avformat.AVInputFormat[address=0x7ff8f5de6c60,position=0,limit=0,capacity=0,deallocator=null], org.bytedeco.ffmpeg.avutil.AVDictionary[address=0x1e5154fd000,position=0,limit=0,capacity=0,deallocator=null]

            Thread.sleep(50);

            log.info("4: {}, {}, {}, {}", context, device, inputFormat, options);
            if (res == 0) {
//                System.out.println("=============== " + context + " / " + device + " / " + inputFormat + " / " + options);
                res = avformat_open_input(context, device, inputFormat, options);
                log.info("5");
                if (!context.isNull()) {
                    log.info("6");
                    avformat_close_input(context);
                    log.info("7");
                }
            }
        } catch (InterruptedException e) {
            log.error(e.getMessage(), e);
        } finally {
            log.info("8");
            avformat_free_context(context);
            log.info("9");
            context.close();
            log.info("10");
            options.close();
            log.info("11");
            inputFormat.close();
            log.info("Executed");
        }
    }
}
import com.banalytics.box.module.model.discovery.AudioDevice;
import com.banalytics.box.module.model.discovery.LocalDevice;
import com.banalytics.box.module.model.discovery.VideoDevice;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DeviceInfoAccumulator {
    public Map<String, AudioDevice> audioDevices = new HashMap<>();
    public Map<String, VideoDevice> videoDevices = new HashMap<>();

    LocalDevice currentDevice;

    public void process(List<String> lines) {
        for (String details : lines) {
            //todo windows case
            if (!details.contains("[dshow")) {
                continue;
            }

            if (details.contains("Alternative name")) {
                int camNameStart = details.indexOf("\"");
                int camNameEnd = details.lastIndexOf("\"");
                currentDevice.alternativeName = details.substring(camNameStart + 1, camNameEnd);
            } else {
                int camNameStart = details.indexOf("\"");
                int camNameEnd = details.lastIndexOf("\"");
                if (camNameStart == -1 || camNameEnd == -1) {
                    continue;
                }
                String name = details.substring(camNameStart + 1, camNameEnd);

                int typeStart = details.indexOf("(", camNameEnd + 1);
                int typeEnd = details.lastIndexOf(")");

                String type = details.substring(typeStart + 1, typeEnd);

                currentDevice = "audio".equals(type) ? new AudioDevice() : new VideoDevice();
                currentDevice.name = name;
            }

            if (currentDevice.isCompleted()) {
                if (currentDevice instanceof AudioDevice ad) {
                    audioDevices.put(currentDevice.alternativeName, ad);
                } else if (currentDevice instanceof VideoDevice vd) {
                    videoDevices.put(currentDevice.alternativeName, vd);
                }
            }
        }
    }
}
@saudet
Copy link
Member

saudet commented Dec 10, 2023

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

@stserakhau
Copy link
Author

I uses this java.exe -Xmx512m -Xms512m -Dorg.bytedeco.javacpp.nopointergc=true

Log in the 1st case shows that the JVM crash appears on the line
avformat_open_input(context, device, inputFormat, options);

Log in 2nd case shows the crash appears on the same line but with another output.

@stserakhau
Copy link
Author

The code above

  1. sets the logger to capture the FFmpeg output with device details
  2. Executes FFmpeg commands, which prints devices & details via custom logger
  3. Parses the captured log and extracts device details -> here DeviceInfoAccumulator

Entry point - method scanLocalDevices

Crash always appears inside private static void execute(String format, String option, String device)

sometimes on execute("dshow", "list_devices", "dummy");

sometimes on execute("dshow", "list_options", "video=" + videoDevice.alternativeName);

sometime on execute("dshow", "list_options", "audio=" + audioDevice.alternativeName);

but in all 3 cases on the line

res = avformat_open_input(context, device, inputFormat, options);

and most of the crashes appears on Execute: dshow, list_options, audio=@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{736173BF-B41F-48A4-9ED3-D161B6D3FF4F}

Hardware details extracted via ffmpeg comand line

>>>>>> ffmpeg -list_devices true -f dshow -i dummy
ffmpeg version 5.1.2-essentials_build-www.gyan.dev Copyright (c) 2000-2022 the FFmpeg developers
  built with gcc 12.1.0 (Rev2, Built by MSYS2 project)
  configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-lzma --enable-zlib --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-sdl2 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --enable-libass --enable-libfreetype --enable-libfribidi --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-libgme --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libtheora --enable-libvo-amrwbenc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-librubberband
  libavutil      57. 28.100 / 57. 28.100
  libavcodec     59. 37.100 / 59. 37.100
  libavformat    59. 27.100 / 59. 27.100
  libavdevice    59.  7.100 / 59.  7.100
  libavfilter     8. 44.100 /  8. 44.100
  libswscale      6.  7.100 /  6.  7.100
  libswresample   4.  7.100 /  4.  7.100
  libpostproc    56.  6.100 / 56.  6.100
[dshow @ 0000020ab314ec40] "USB Camera" (video)
[dshow @ 0000020ab314ec40]   Alternative name "@device_pnp_\\?\usb#vid_0c45&pid_636b&mi_00#6&1d140336&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"
[dshow @ 0000020ab314ec40] "Microfon

 (USB Camera)" (audio)
[dshow @ 0000020ab314ec40]   Alternative name "**@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{736173BF-B41F-48A4-9ED3-D161B6D3FF4F}**"
[dshow @ 0000020ab314ec40] "Microfon (3- Plantronics .Audio 655 DSP)" (audio)
[dshow @ 0000020ab314ec40]   Alternative name "**@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{EB1F26F3-AAA6-4A20-AAB1-F0AA36AF8F4D}**"
dummy: Immediate exit requested

FFmpeg command to extract the device details

>>>>>>ffmpeg -f dshow -list_options true -i "audio=**@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{736173BF-B41F-48A4-9ED3-D161B6D3FF4F}**"
ffmpeg version 5.1.2-essentials_build-www.gyan.dev Copyright (c) 2000-2022 the FFmpeg developers
  built with gcc 12.1.0 (Rev2, Built by MSYS2 project)
  configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-lzma --enable-zlib --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-sdl2 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --enable-libass --enable-libfreetype --enable-libfribidi --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-libgme --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libtheora --enable-libvo-amrwbenc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-librubberband
  libavutil      57. 28.100 / 57. 28.100
  libavcodec     59. 37.100 / 59. 37.100
  libavformat    59. 27.100 / 59. 27.100
  libavdevice    59.  7.100 / 59.  7.100
  libavfilter     8. 44.100 /  8. 44.100
  libswscale      6.  7.100 /  6.  7.100
  libswresample   4.  7.100 /  4.  7.100
  libpostproc    56.  6.100 / 56.  6.100
[dshow @ 000001b6bfcfecc0] DirectShow audio only device options (from audio devices)
[dshow @ 000001b6bfcfecc0]  Pin "Capture" (alternative pin name "Capture")
[dshow @ 000001b6bfcfecc0]   ch= 2, bits=16, rate= 44100
    Last message repeated 1 times
[dshow @ 000001b6bfcfecc0]   ch= 1, bits=16, rate= 44100
[dshow @ 000001b6bfcfecc0]   ch= 2, bits=16, rate= 32000
[dshow @ 000001b6bfcfecc0]   ch= 1, bits=16, rate= 32000
[dshow @ 000001b6bfcfecc0]   ch= 2, bits=16, rate= 22050
[dshow @ 000001b6bfcfecc0]   ch= 1, bits=16, rate= 22050
[dshow @ 000001b6bfcfecc0]   ch= 2, bits=16, rate= 11025
[dshow @ 000001b6bfcfecc0]   ch= 1, bits=16, rate= 11025
[dshow @ 000001b6bfcfecc0]   ch= 2, bits=16, rate=  8000
[dshow @ 000001b6bfcfecc0]   ch= 1, bits=16, rate=  8000
[dshow @ 000001b6bfcfecc0]   ch= 2, bits= 8, rate= 44100
[dshow @ 000001b6bfcfecc0]   ch= 1, bits= 8, rate= 44100
[dshow @ 000001b6bfcfecc0]   ch= 2, bits= 8, rate= 22050
[dshow @ 000001b6bfcfecc0]   ch= 1, bits= 8, rate= 22050
[dshow @ 000001b6bfcfecc0]   ch= 2, bits= 8, rate= 11025
[dshow @ 000001b6bfcfecc0]   ch= 1, bits= 8, rate= 11025
[dshow @ 000001b6bfcfecc0]   ch= 2, bits= 8, rate=  8000
[dshow @ 000001b6bfcfecc0]   ch= 1, bits= 8, rate=  8000
[dshow @ 000001b6bfcfecc0]   ch= 2, bits=16, rate= 48000
[dshow @ 000001b6bfcfecc0]   ch= 1, bits=16, rate= 48000
[dshow @ 000001b6bfcfecc0]   ch= 2, bits=16, rate= 96000
[dshow @ 000001b6bfcfecc0]   ch= 1, bits=16, rate= 96000
audio=**@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{736173BF-B41F-48A4-9ED3-D161B6D3FF4F}**: Immediate exit requested

@stserakhau
Copy link
Author

The current crash appears with the next case:

  1. I started grabbing from USB device - success
  2. Executed scanLocalDevices() - produced JVM crash in org.bytedeco.ffmpeg.global.swscale.sws_getCachedContext

hs_err_pid12432.log

The code, which works with grabber is stable, work 24x7. Crash appears only when I try to capture the ffmpeg log with devices

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
J 9837  org.bytedeco.ffmpeg.global.swscale.sws_getCachedContext(Lorg/bytedeco/ffmpeg/swscale/SwsContext;IIIIIIILorg/bytedeco/ffmpeg/swscale/SwsFilter;Lorg/bytedeco/ffmpeg/swscale/SwsFilter;Lorg/bytedeco/javacpp/DoublePointer;)Lorg/bytedeco/ffmpeg/swscale/SwsContext; (0 bytes) @ 0x0000019db9d0bcf6 [0x0000019db9d0bc20+0x00000000000000d6]
J 9831 c1 org.bytedeco.javacv.FFmpegFrameGrabber.processImage()V (520 bytes) @ 0x0000019db9d090bc [0x0000019db9d08d80+0x000000000000033c]
J 9943 c1 org.bytedeco.javacv.FFmpegFrameGrabber.grabFrame(ZZZZZ)Lorg/bytedeco/javacv/Frame; (1821 bytes) @ 0x0000019db9cda46c [0x0000019db9cd92e0+0x000000000000118c]
J 11097 c1 org.bytedeco.javacv.FrameGrabber.grabFrame()Lorg/bytedeco/javacv/Frame; (5 bytes) @ 0x0000019db91becfc [0x0000019db91beca0+0x000000000000005c]
j  com.banalytics.box.module.media.task.ffmpeg.GrabberStreamWorker.run()V+345
j  java.lang.Thread.runWith(Ljava/lang/Object;Ljava/lang/Runnable;)V+5 java.base@20.0.2
j  java.lang.Thread.run()V+19 java.base@20.0.2
v  ~StubRoutines::call_stub 0x0000019db8d8100d

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants