我们正在使用JavaFx和JavaCv开发视频流应用。 我们有8X8的GridPane,每个单元格包含窗格布局和每个窗格 包含ImageView。
每次用户将url拖动到特定时,我都会调用play函数 细胞。 我们有64个Urls,所以我们调用播放功能64次(所有64个url正在播放 在后台线程)。
{{1}}
问题: 在增加一些阈值宽度和之后,我们正面临白屏问题 高度。 在这里,我用不同的屏幕尺寸附加我的应用程序的Snap;
屏蔽1
因为我们长期面对这个问题。 任何领导者都会非常感激。 提前致谢。
答案 0 :(得分:2)
这里只是一个猜测,但是当图像视图与图像的大小不同时,当您调用setImage(...)
(它必须调整图像大小)时,图像视图还有很多工作要做。由于你有很多这样的事情发生,可能是每一个脉冲,你可能会向Platform.runLater(...)
提交比它可以处理的更多的runnable(即你在从同一个线程提交的前一个提交之前提交另一个Platform.runLater(...)
完成)。这将导致渲染问题,因为渲染系统无法跟上。
我无法对此进行测试,所以我不确定它是否能解决这个问题,但是当前一个调用已完成时({1}}只提交新的调用可能是个好主意。应该这样做,即使它不是问题的原因)。
您可以使用
执行此操作Platform.runLater(...)
请注意,在此代码(和原始代码)中, all 图像将在同一个线程(FX应用程序线程)上调整大小。如果可能的话,在自己的线程中调整每个图像的大小可能会更有效。你不能绝对保证这一点(因为没有办法保证图像视图不会改变在后台线程中调整大小的图像和显示图像的图像视图之间的大小),所以你仍然需要绑定{{1 }}和void play(ImageView im,String Url){
new Thread(() -> {
frameGrabber = new FFmpegFrameGrabber(Url);
frameGrabber.setVideoOption("preset","ultrafast");
frameGrabber.setOption("rtsp_transport","tcp");
frameGrabber.setOption("stimeout" , "60000");
frameGrabber.setAudioChannels(0);
frameGrabber.setAudioCodec(0);
try {
frameGrabber.start();
start=true;
} catch (Exception e) {
e.printStackTrace();
}
JavaFXFrameConverter jconverter=new JavaFXFrameConverter();
AtomicReference<Image> imageHolder = new AtomicReference<>(null);
while(true){
Frame frame = frameGrabber.grabImage();
Image image=jconverter.convert(frame);
if (imageHolder.getAndSet(image) == null) {
Platform.runLater(() -> im.setImage(imageHolder.getAndSet(null)));
}
}
}).start();
}
属性,但这应该减少UI线程上发生的图像大小调整量,从而提高性能。这取决于你的帧抓取器API(我不熟悉)中有一些机制来调整图像大小。
fitWidth
和
fitHeight