Recently I encountered following strange error which I got when running my VideoChat.
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0cd32890, pid=2128, tid=1668
#
# JRE version: 6.0_17-b04
# Java VM: Java HotSpot(TM) Client VM (14.3-b01 mixed mode, sharing windows-x86 )
# Problematic frame:
# C [jmjpeg.dll+0x12890]
At first I thought this was caused by the camera driver, or a bug in the native c code.
I could track the error down to the reception part of an incoming RTP Stream.
Following code was used to display the video stream from a datasource:
Component comp;
JPanel video = new JPanel();
try {
receptionPlayer = Manager.createRealizedPlayer(clientReceptionDS);
receptionPlayer.start();
if ((comp = receptionPlayer.getVisualComponent()) != null) {
video.add(comp);
}
Everything fine, except the random crashes from the JVM.
So I started to debug the code and uncommented the video.add(cmp) and voila no crashes.
That led me to the conclusion there might be a timing problem with the player and its different states.
The solution then was to create just a Player with the incoming DataSource and add a ControllerListener who listens for state changes and tells me when the player is really realized.
Following new code was then used:
If a new stream is received we get informed via the ReceiveStreamListener which offers an Update method
public synchronized void update(ReceiveStreamEvent evt)
Inside this method we can retrive our DataSource with:
ReceiveStream stream = evt.getReceiveStream();
dataSource = stream.getDataSource();
And initialise the Player in the following way:
Player p = null;
try {
p = Manager.createPlayer(dataSource);
} catch (NoPlayerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (p == null)
return;
p.addControllerListener(this);
p.realize();
The ControllerListener:
public void controllerUpdate(ControllerEvent ce) {
Player p = (Player)ce.getSourceController();
if (p == null)
return;
if (ce instanceof RealizeCompleteEvent) {
vsc.startReceptionVideo(dataSource, p);
}
if (ce instanceof ControllerErrorEvent) {
p.removeControllerListener(this);
}
}
You see when there is a RealizeCompleteEvent I hand the realized Player and the DataSource over to the GUI where it will be displayed with this code:
if ((comp = receptionPlayer.getVisualComponent()) != null) {
video.add(comp);
}
receptionPlayer.start();
Result: It does not crash anymore and you have full control over the Player and its states.