Как правильно создать экземпляр PixelBuffer для VLCJ mediaPlayer - PullRequest
0 голосов
/ 13 февраля 2020

В настоящее время у меня проблемы с получением VLCJ 4 для ускорения видео. Я могу заставить приложение работать, но кажется, что он сталкивается с проблемой, когда videoPixelBuffer не был создан. Приведенный ниже код взят из учебника по пиксельбуферу на главной странице. Я пытался понять, как это функция, но не могу понять, как когда-либо вызывается функция, которая создает экземпляр videoPixelBuffer. Я попытался вручную вызвать это, которое не работает также. Я полагаю, что проблема с videoPixelBuffer, но не могу найти способ исправить это.

Есть идеи?

Ниже вы увидите код, который я использую, и сообщения об ошибках, которые я получил. Вот ссылка на репозиторий Github для демо-версии. (https://github.com/caprica/vlcj-javafx/blob/pixelbuffer-test/src/test/java/uk/co/caprica/vlcj/javafx/test/WritableImageDemo.java)

Версии:

  • VLCJ 4.1.0
  • VL C 3.0.8
  • Openjdk 13
  • Openjfx 13

Код:

package player;

import java.nio.ByteBuffer;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelBuffer;
import javafx.scene.image.PixelFormat;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import uk.co.caprica.vlcj.factory.MediaPlayerFactory;
import uk.co.caprica.vlcj.player.base.MediaPlayer;
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;
import uk.co.caprica.vlcj.player.embedded.videosurface.CallbackVideoSurface;
import uk.co.caprica.vlcj.player.embedded.videosurface.VideoSurfaceAdapters;
import uk.co.caprica.vlcj.player.embedded.videosurface.callback.BufferFormat;
import uk.co.caprica.vlcj.player.embedded.videosurface.callback.BufferFormatCallback;
import uk.co.caprica.vlcj.player.embedded.videosurface.callback.RenderCallback;
import uk.co.caprica.vlcj.player.embedded.videosurface.callback.format.RV32BufferFormat;

public class Test extends Application {

    private MediaPlayerFactory mediaPlayerFactory;

    private EmbeddedMediaPlayer embeddedMediaPlayer;

    private WritableImage videoImage;

    private PixelBuffer<ByteBuffer> videoPixelBuffer;

    private ImageView videoImageView;

    @Override
    public void init() {
        mediaPlayerFactory = new MediaPlayerFactory();
        embeddedMediaPlayer = mediaPlayerFactory.mediaPlayers().newEmbeddedMediaPlayer();
        embeddedMediaPlayer.videoSurface().set(new FXCallbackVideoSurface());
    }

    @Override
    public final void start(Stage primaryStage) throws Exception {
        StackPane root = new StackPane();
        root.setStyle("-fx-background-color: black;");
        videoImageView = new ImageView();
        videoImageView.setPreserveRatio(true);
        videoImageView.fitWidthProperty().bind(root.widthProperty());
        videoImageView.fitHeightProperty().bind(root.heightProperty());
        root.getChildren().add(videoImageView);

        Scene scene = new Scene(root, 1200, 675);
        primaryStage.setScene(scene);
        primaryStage.show();

        String mrl = getParameters().getRaw().get(0);

        embeddedMediaPlayer.media().play(mrl);
    }

    @Override
    public final void stop() throws Exception {
        embeddedMediaPlayer.controls().stop();
        embeddedMediaPlayer.release();
        mediaPlayerFactory.release();
    }

    private class FXCallbackVideoSurface extends CallbackVideoSurface {
        FXCallbackVideoSurface() {
            super(new FXBufferFormatCallback(), new FXRenderCallback(), true, VideoSurfaceAdapters.getVideoSurfaceAdapter());
        }
    }

    private class FXBufferFormatCallback implements BufferFormatCallback {
        private int sourceWidth;
        private int sourceHeight;

        @Override
        public BufferFormat getBufferFormat(int sourceWidth, int sourceHeight) {
            this.sourceWidth = sourceWidth;
            this.sourceHeight = sourceHeight;
            return new RV32BufferFormat(sourceWidth, sourceHeight);
        }

        public void allocatedBuffers(ByteBuffer[] buffers) {
            assert buffers[0].capacity() == sourceWidth * sourceHeight * 4;
            PixelFormat<ByteBuffer> pixelFormat = PixelFormat.getByteBgraPreInstance();
            videoPixelBuffer = new PixelBuffer<>(sourceWidth, sourceHeight, buffers[0], pixelFormat);
            videoImage = new WritableImage(videoPixelBuffer);
            videoImageView.setImage(videoImage);
        }
    }

    private class FXRenderCallback implements RenderCallback {
        @Override
        public void display(MediaPlayer mediaPlayer, ByteBuffer[] nativeBuffers, BufferFormat bufferFormat) {
            Platform.runLater(() -> {
                videoPixelBuffer.updateBuffer(pb -> null);
            });
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

class WritableImageDemoLauncher {public static void main(String[] args) {Test.main(args);}}

Сообщения об ошибках:

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at player.Test$FXRenderCallback.lambda$0(Test.java:110)
at javafx.graphix/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(AcessController.java:391)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:92)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:830)

Тест. java: 110 это следующая строка: videoPixelBuffer.updateBuffer(pb -> null);

...