Сбой JVM при выпуске VLCJ MediaPlayer

Я использую OS X 10.11.6 с Java 8u121 и пытаюсь использовать VLCJ 3.10.1 (с VLC 2.2.4) для перекодирования аудиофайла (из MP3 в OGG Vorbis). Транскодирование работает нормально, но я получаю сообщение об ошибке при выпуске файла MediaPlayer.

Ниже приведен мой минимальный тестовый код, основанный на RipAudioTest из репозитория VLCJ:

public class VlcjTestMain {

    public static void main(String[] args) throws InterruptedException {
        Path sourceFile = // source file here
        Path targetFile = // target file here

        new NativeDiscovery().discover();
        MediaPlayerFactory factory = new MediaPlayerFactory();
        MediaPlayer player = factory.newHeadlessMediaPlayer();

        CountDownLatch latch = new CountDownLatch(1);
        player.addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
            @Override
            public void finished(MediaPlayer mediaPlayer) {
                latch.countDown();
            }

            @Override
            public void error(MediaPlayer mediaPlayer) {
                System.out.println("Rip failed");
                latch.countDown();
            }
        });

        String transcodeOpts =
                ":sout=#transcode{acodec=vorb,vcodec=dummy}:std{dst=" + targetFile.toAbsolutePath().toString() + ",mux=ogg,access=file}";
        player.playMedia(
                sourceFile.toAbsolutePath().toString(),
                transcodeOpts);

        latch.await();
        System.out.println("Finished!");

        player.release();
        System.out.println("Player released");

        factory.release();
        System.out.println("Factory released");
    }
}

Транскодирование завершается успешно, но player.release() происходит сбой JVM с ошибкой SIGSEGV:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00000001224e8649, pid=13561, tid=0x000000000000c253
#
# JRE version: Java(TM) SE Runtime Environment (8.0_121-b13) (build 1.8.0_121-b13)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.121-b13 mixed mode bsd-amd64 compressed oops)
# Problematic frame:
# C  [libvlc.dylib+0x6649]  libvlc_event_send+0x19
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

Остальную часть журнала сбоев можно посмотреть здесь.

Кто-нибудь знает, что может быть причиной этого?


person Cyäegha    schedule 09.04.2017    source источник
comment
Основываясь на опубликованном вами дампе, вероятно, собственный код все еще отправляет вам событие (через libvlc_event_send) после того, как вы выпускаете медиаплеер на стороне Java. Где-то может быть проблема с последовательностью или, возможно, ошибка в очистке vlcj. Я не знаю наверняка.   -  person caprica    schedule 10.04.2017
comment
Интересно, я думаю, что попытаюсь зарегистрировать все события, полученные прослушивателем событий, и немного подожду, прежде чем выпустить медиаплеер, чтобы увидеть, что я получаю... Я обновлю свой вопрос, когда попробую это. Я также попытаюсь повторить свои тесты в Windows, чтобы увидеть, отличается ли он.   -  person Cyäegha    schedule 10.04.2017
comment
это сложно, потому что очистка vlcj release() на самом деле явно отменяет регистрацию собственного прослушивателя событий, прежде чем что-либо еще. может быть, это лучше как проблема на странице проекта vlcj github, на ваше усмотрение.   -  person caprica    schedule 10.04.2017
comment
Я посмотрю, смогу ли я сначала узнать немного больше, но я, вероятно, открою проблему на github позже, да.   -  person Cyäegha    schedule 10.04.2017
comment
Я опубликовал ответ с моими наблюдениями - я думаю, что проблема может быть вызвана событиями, запущенными после finished, несмотря на попытку выпустить медиаплеер (конечно, я могу видеть эти события, только когда я don 't сразу не выпускать медиаплеер, так что я могу ошибаться...). Я предполагаю, что это то, о чем я должен сообщить как об ошибке?   -  person Cyäegha    schedule 11.04.2017


Ответы (1)


Я думаю, что смог ответить на свой вопрос благодаря комментариям Каприки.

tl;dr: После события finished VLC по-прежнему запускает два других события: mediaChanged и newMedia. Если это происходит после отпускания плеера, он вылетает.

А теперь подробности моих экспериментов...

Пробовал тот же код на Windows 10. Иногда работало, но чаще всего выдавало ошибку java.lang.Error: Invalid memory access на player.release().

Затем я попытался добавить оператор Thread.sleep(1000) перед player.release() и больше не мог воспроизвести сбой.

Поэтому я использовал прослушиватель событий, который регистрировал большинство событий и сохранял оператор Thread.sleep(1000) перед player.release(). Я заметил два события, полученных после finished: сначала mediaChanged, затем newMedia. вот как выглядел конец лога:

mediaStateChanged
finished
Finished!
mediaChanged
newMedia
[00000000209f45b0] mux_ogg mux: Close [this line logged by VLCJ, not by me]
Player released
Factory released

Наконец, я также попытался удалить оператор sleep, но вызвал player.release() после второго события newMedia (а не первого события finished), и мне также не удалось воспроизвести сбой.

person Cyäegha    schedule 10.04.2017