Рендеринг YUV в JavaFX

Мне нужно отобразить поток yuyv422 в JavaFX с минимальной задержкой. Если я конвертирую его в RGB, я могу использовать ImageView с WritableImage с экземпляром PixelFormat, и это работает, но преобразование RGB потребляет много ресурсов ЦП, особенно при высоких разрешениях. Я видел именно этот запрос функции

https://bugs.openjdk.java.net/browse/JDK-8091933

но, похоже, это не будет реализовано в Java 9. И если это произойдет, интересно, не приведет ли это к задержке или не потребует слишком много ресурсов ЦП. Есть ли другой способ использования JavaFX?


person AmsterdamLuis    schedule 07.04.2017    source источник
comment
Может, vlcj поможет (не знаю). Вы можете попробовать погуглить vlcj JavaFX.   -  person jewelsea    schedule 08.04.2017
comment
Убедитесь, что ваша текущая имплантация не страдает от этих проблем с производительностью: вопросов/29260147/ и stackoverflow.com/questions/33911010/   -  person jewelsea    schedule 08.04.2017
comment
Спасибо, я проверю vlci, но мое приложение не страдает от проблем с производительностью, упомянутых в этих ссылках.   -  person AmsterdamLuis    schedule 09.04.2017


Ответы (1)


В целом:
обработка изображений всегда требует больших затрат, поэтому для этих задач используется векторизация или аппаратное ускорение. Простой цикл по изображению всего одним потоком уже очень медленный, особенно в java. Кроме того, люди склонны использовать Color объекты для изменения цвета, что очень медленно.

Чистая Java:
если вы хотите, чтобы ваш код был написан на чистой Java. Вы должны проверить, какой внутренний формат используется для WriteableImage, вызвав:

myImage.getPixelWriter().getPixelFormat().getType() 

Если внутренний формат не RGB, адаптируйте преобразование цвета к данному формату, чтобы избежать двойного преобразования. Кроме того, убедитесь, что ваш код максимально оптимизирован:
-Не используйте никакие объекты, кроме массивов
-Сведите к минимуму использование локальных переменных
Вы также можете попробовать многопоточность процесса преобразования с помощью параллельных циклов. .

JNI:
Отход от Java открывает множество возможностей. Существует несколько независимых от платформы библиотек для преобразования YUV в RGB и обратно:

OpenCV:
Прост в использовании и уже поставляется с Java API:

byte[] myYuvImage = null; //your image here
byte[] myRgbImage = new byte[width * height * 3]; //the output image
Mat yuvMat = new Mat(height, width, CvType.CV_8UC2); //YUV422 should be 2 channel
Mat rgbMat = new Mat(height, width, CvType.CV_8UC3);
yuvMat.put(0,0, myYuvImage);
Imgproc.cvtColor(yuvMat, rgbMat, Imgproc.COLOR_YUV2RGB_Y422);
rgbMat.get(0, 0, myRgbImage);

Intel IPP:
доступно только через JNI. Вы должны использовать ippiRGBToYUV422_8u_C3C2R для получения дополнительной информации см. RGBToYUV422.

SwScale как часть FFmpeg:
доступно только через JNI. См. этот ответ и адаптируйте пример.

Мой личный опыт показывает, что IPP обеспечивает лучшую производительность даже на машинах AMD. Однако лицензия, с которой он поставляется, может быть бесплатной, но запрещает декомпиляцию, которая может быть несовместима с библиотеками LGPL.

person Crigges    schedule 22.08.2018
comment
Большое спасибо за ответ, это было очень полезно - person AmsterdamLuis; 25.01.2020