一度に 30 本の動画を再生するアプリケーションを使用しています。ビデオファイルとウィンドウXuggler
をデコードして表示するために使用しています。Swing
しかし、私は次のような問題に直面しています:
- 動画がスムーズに表示されない
- 私が見つけたプロファイラーでは、約 25% の時間がガベージ コレクションに費やされていました。
ガベージ コレクターを調整するにはどうすればよいですか? また、その他のパフォーマンス パラメータにはどのような注意が必要ですか?
Xuggler と Java の組み合わせは良くないですか?
編集
私のビデオデコードループは次のとおりです。
private boolean decodeStreams() throws Exception {
IPacket packet = IPacket.make();
long firstTimestampInStream = Global.NO_PTS;
long systemClockStartTime = 0;
viewer.urlStatusUpdate(index, Globals.STATUS_PLAYING);
while (container.readNextPacket(packet) >= 0) {
if (stopPlaying) {
if (isStopPlaying(2)) {
return false;
}
}
if (packet.getStreamIndex() == videoStreamID) {
IVideoPicture picture = IVideoPicture.make(videoCoder.getPixelType(), videoCoder.getWidth(), videoCoder.getHeight());
int offset = 0;
while (offset < packet.getSize()) {
int bytesDecoded = videoCoder.decodeVideo(picture, packet, offset);
if (bytesDecoded < 0) {
throw new Exception("Got error on decoding video");
}
offset += bytesDecoded;
if (picture.isComplete()) {
if (firstTimestampInStream == Global.NO_PTS) {
firstTimestampInStream = picture.getTimeStamp();
systemClockStartTime = System.currentTimeMillis();
} else {
long millisecondsToSleep = (
((picture.getTimeStamp() - firstTimestampInStream) / 1000)
- (System.currentTimeMillis() - systemClockStartTime)
);
if (millisecondsToSleep > 50) {
try {
Thread.sleep(millisecondsToSleep - 50);
} catch (Exception e) {
}
}
}
viewer.videoImageUpdate(index, converter.toImage(picture));
}
}
}
}
return true;
}
そして、IVideoPicture 宣言の場所を変更しました。
private boolean decodeStreams() throws Exception {
IPacket packet = IPacket.make();
long firstTimestampInStream = Global.NO_PTS;
long systemClockStartTime = 0;
viewer.urlStatusUpdate(index, Globals.STATUS_PLAYING);
IVideoPicture picture = IVideoPicture.make(videoCoder.getPixelType(), videoCoder.getWidth(), videoCoder.getHeight());
while (container.readNextPacket(packet) >= 0) {
if (stopPlaying) {
if (isStopPlaying(2)) {
return false;
}
}
if (packet.getStreamIndex() == videoStreamID) {
int offset = 0;
while (offset < packet.getSize()) {
int bytesDecoded = videoCoder.decodeVideo(picture, packet, offset);
if (bytesDecoded < 0) {
throw new Exception("Got error on decoding video");
}
offset += bytesDecoded;
if (picture.isComplete()) {
if (firstTimestampInStream == Global.NO_PTS) {
firstTimestampInStream = picture.getTimeStamp();
systemClockStartTime = System.currentTimeMillis();
} else {
long millisecondsToSleep = (
((picture.getTimeStamp() - firstTimestampInStream) / 1000)
- (System.currentTimeMillis() - systemClockStartTime)
);
if (millisecondsToSleep > 50) {
try {
Thread.sleep(millisecondsToSleep - 50);
} catch (Exception e) {
}
}
}
viewer.videoImageUpdate(index, converter.toImage(picture));
}
}
}
}
return true;
}
現在、GC は 10% 未満の時間を費やしており、通常は約 5% から 8% です。そして、一度に 30 本すべてのビデオをスムーズに再生できました。
場所の変更 (IVideoPicture 宣言を外部に配置し、メモリを 1 回だけ割り当てる) は問題になる可能性がありますか? 新しいビデオ画像が割り当てられたメモリでデコードされるたびに、画像のタイムスタンプが設定されますか?
ありがとう