如何解决Java Graphics drawImage 在 JPanel 上有时很慢有时会暂停
- 操作系统:Windows 10 专业版
- Java:OpenJDK 11.0.7
我创建了一个可以读取视频文件并在 JPanel 上播放的程序。目前我遇到了两个问题。
- Graphics.drawImage(Image,x,y,null) 有时很慢(大于 50 毫秒),有时很快(小于 5 毫秒)
- 在Graphics.drawImage的速度小于5毫秒期间,我有时仍然发现在JPanel上播放的视频暂停了50毫秒以上,这是肉眼可以感觉到的。
那么,有什么建议吗?
下面是关键代码和日志
public class UI {
private static final Logger log = LoggerFactory.getLogger(UI.class);
...
private reentrantreadwritelock postVideoFrameReadWriteLock = new reentrantreadwritelock();
private reentrantreadwritelock.ReadLock postVideoFrameReadLock = postVideoFrameReadWriteLock.readLock();
private reentrantreadwritelock.WriteLock postVideoFrameWriteLock = postVideoFrameReadWriteLock.writeLock();
private BufferedImage _lcdPanelImage ;
private JPanel lcdPanel;
...
public UI() {
...
lcdPanel = new JPanel() {
@Override
public void paintComponent(Graphics g) {
// super.paintComponent(g);
long timer0 = System.currentTimeMillis(),timer1=0,timer2=-1,timer3 = 0;
postVideoFrameReadLock.lock();
if (_lcdPanelImage != null) {
timer1 = System.currentTimeMillis();
g.drawImage(_lcdPanelImage,null);
timer2 = System.currentTimeMillis();
}
postVideoFrameReadLock.unlock();
timer3 = System.currentTimeMillis();
int diff = (int) (timer2-timer1);
if (diff >5) {
log.trace(" paint total cost:{} ms,drawImage cost: {} ms",(timer3- timer0),(timer2-timer1));
}
}
};
lcdPanel.setDoubleBuffered(true);
...
}
private void postOnLcdPanel(BufferedImage bufferedImage) {
long timer0 = System.currentTimeMillis();
postVideoFrameWriteLock.lock();
_lcdPanelImage = bufferedImage;
postVideoFrameWriteLock.unlock();
long timer1 = System.currentTimeMillis();
lcdPanel.repaint();
long timer2 = System.currentTimeMillis();
int diff1 = (int) (timer1 - timer0);
int diff2 = (int) (timer2 - timer1);
if (diff1 >0 || diff2 > 0) {
log.trace(String.format("set and lock cost:%4d ms,repaint cost:%4d ms",diff1,diff2
));
}
}
@Singleton
private class displayVideoOnLcdPanelWorker implements Runnable {
private final Logger log = LoggerFactory.getLogger(displayVideoOnLcdPanelWorker.class);
private void tsleep(long lsec) {
try {
Thread.sleep(lsec);
} catch (InterruptedException e) {
log.error(e.getMessage(),e);
}
}
@Override
public void run() {
log.debug("displayVideoOnLcdPanelWorker starts ....");
boolean running = true;
long timer0 = System.currentTimeMillis(),playVideoCount = 0;
final int targetSleepms = 25;
float fps = 0;
while (running) {
try {
//log.trace("videoQueue size: {} .....",videoQueue.size());
if (videoWaitPlayingQueue.size() == 0) {
Thread.sleep(5);
continue;
}
BufferedImage image = videoWaitPlayingQueue.poll(1,TimeUnit.MILLISECONDS);
long timer1 = System.currentTimeMillis();
postOnLcdPanel(image);
long timer3 = System.currentTimeMillis();
playVideoCount++;
int playCost = (int) (timer3 - timer1);
int diffSleep = targetSleepms -playCost;
if (playCost > 10) {
log.trace(String.format("Play cost:%4d,videoWaitPlayingQueue:%d",playCost,videoWaitPlayingQueue.size()));
}
tsleep(diffSleep > 3? diffSleep: 3);
} catch (InterruptedException ex) {
log.error(ex.getMessage(),ex);
break;
}
}
log.debug("displayVideoOnLcdPanelWorker stops ....");
}
}
}
以下是相关日志
19:19:34.321 TRACE UI$displayVideoOnLcdPanelWorker: Play cost: 236,videoWaitPlayingQueue:200
19:19:40.858 TRACE UI: paint total cost:227 ms,drawImage cost: 227 ms
19:19:40.858 TRACE UI: set and lock cost: 1 ms,repaint cost: 0 ms
19:19:50.798 TRACE UI: paint total cost:182 ms,drawImage cost: 182 ms
19:19:52.596 TRACE UI: set and lock cost: 0 ms,repaint cost: 1 ms
19:19:52.710 TRACE UI: paint total cost:114 ms,drawImage cost: 114 ms
19:19:52.710 TRACE UI: set and lock cost: 2 ms,repaint cost: 0 ms
19:20:26.387 TRACE UI: paint total cost:101 ms,drawImage cost: 101 ms
19:20:28.086 TRACE UI: paint total cost:105 ms,drawImage cost: 105 ms
19:20:28.087 TRACE UI: set and lock cost: 3 ms,repaint cost: 0 ms
19:20:39.319 TRACE UI: set and lock cost: 0 ms,repaint cost: 1 ms
19:21:05.526 TRACE UI: paint total cost:284 ms,drawImage cost: 284 ms
19:21:07.556 TRACE UI: paint total cost:112 ms,drawImage cost: 112 ms
19:21:07.556 TRACE UI: set and lock cost: 3 ms,repaint cost: 0 ms
19:21:32.687 TRACE UI: paint total cost:129 ms,drawImage cost: 129 ms
19:21:32.687 TRACE UI: set and lock cost: 1 ms,repaint cost: 0 ms
19:21:37.217 TRACE UI: set and lock cost: 0 ms,repaint cost: 290 ms
19:21:37.217 TRACE UI$displayVideoOnLcdPanelWorker: Play cost: 290,videoWaitPlayingQueue:200
19:21:41.779 TRACE UI: set and lock cost: 0 ms,repaint cost: 302 ms
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。