Methods Summary |
---|
protected final void | abortPrefetch()Called when the prefetch() is aborted, i.e. deallocate() was called
while prefetching. Release all resources claimed previously by the
prefetch call.
if (controllerList != null) {
int i = controllerList.size();
while (--i >= 0) {
Controller c = (Controller) controllerList.elementAt(i);
c.deallocate();
}
}
synchronized(this) {
notify();
}
|
protected final void | abortRealize()Called when the realize() is aborted, i.e. deallocate() was called
while realizing. Release all resources claimed previously by the
realize() call.
if (controllerList != null) {
int i = controllerList.size();
while (--i >= 0) {
Controller c = (Controller) controllerList.elementAt(i);
c.deallocate();
}
}
synchronized(this) {
notify();
}
|
public synchronized void | addController(javax.media.Controller newController)Assume control of another Controller.
A Player can accept responsibility for controlling
another Controller.
Once a Controller has been added
this Player will:
- Slave the Controller to the Player's time-base.
- Use the Controller in the Player's computation
of start latency.
The value the Player returns in its getStartLatency
method is the larger
of: getStartLatency before the Controller was added, or
getStartLatency of the Controller.
- Pass along, as is appropriate, events that the Controller
generates.
- Invoke all Controller methods on the Controller.
- For all asynchronous methods (realize, prefetch) a completion
event will not be generated until all added Controllers have
generated completion events.
Note: It is undefined what will happen if a Controller is
under the control of a Player and any of the
Controller's methods are called outside of the controlling
Player.
int playerState = getState();
if (playerState == Started) {
throwError(new ClockStartedError("Cannot add controller to a started player"));
}
if ( (playerState == Unrealized) || (playerState == Realizing) ) {
throwError(new NotRealizedError("A Controller cannot be added to an Unrealized Player"));
}
if (newController == null || newController == this)
return;
int controllerState = newController.getState();
if ( (controllerState == Unrealized) || (controllerState == Realizing) ) {
throwError(new NotRealizedError("An Unrealized Controller cannot be added to a Player"));
}
if (controllerList.contains(newController)) {
return;
}
if (playerState == Prefetched) {
if ( (controllerState == Realized) ||
(controllerState == Prefetching) ) {
// System.out.println("Calling deallocate");
deallocate(); // Transition back to realized state
}
}
manageController(newController);
// Synchronize the players.
newController.setTimeBase(getTimeBase());
newController.setMediaTime(getMediaTime());
newController.setStopTime(getStopTime());
if (newController.setRate(getRate()) != getRate()) {
// The slave does not support the master's rate.
// We'll reset everything back to rate 1.0.
setRate(1.0f);
}
|
protected abstract boolean | audioEnabled()Return true if the player is currently playing media
with an audio track.
|
float | checkRateConfig(javax.media.protocol.RateConfigureable rc, float rate)Check if the given rate configureable supports the given rate.
if not, returns the closest match.
RateConfiguration config[] = rc.getRateConfigurations();
if (config == null)
return 1.0f;
RateConfiguration c;
RateRange rr;
float corrected = 1.0f;
for (int i = 0; i < config.length; i++) {
rr = config[i].getRate();
if (rr != null && rr.inRange(rate)) {
rr.setCurrentRate(rate);
corrected = rate;
c = rc.setRateConfiguration(config[i]);
if (c != null && (rr = c.getRate()) != null)
corrected = rr.getCurrentRate();
break;
}
}
return corrected;
|
protected void | completeConfigure()Called as a last step to complete the configure call.
super.completeConfigure();
synchronized (this) {
notify();
}
|
protected void | completePrefetch()Called as a last step to complete the prefetch call.
super.completePrefetch();
synchronized(this) {
notify();
}
|
protected void | completeRealize()Called as a last step to complete the realize call.
state = Realized;
try {
slaveToMasterTimeBase(getMasterTimeBase());
} catch (IncompatibleTimeBaseException e) {
Log.error(e);
}
super.completeRealize();
synchronized (this) {
notify();
}
|
protected void | controllerSetStopTime(javax.media.Time t)This is for subclass to access Controller's implementation of setStopTime.
super.setStopTime(t);
|
protected void | controllerStopAtTime()This is for subclass to access Controller's implementation of stopAtTime.
super.stopAtTime();
|
public final void | controllerUpdate(javax.media.ControllerEvent evt)This get called when some Controller notifies this player of
any event.
processEvent(evt);
|
protected boolean | deviceBusy(com.sun.media.BasicController mc)Check the given controller to see if it's busy or not.
Needs to be overridden by subclass.
The subclass method should change the master timebase
if necessary. It should handle audio only or video
only tracks properly when the device is busy.
return true;
|
protected void | doClose()This is called when close() is invoked on the Player. close() takes
care of the general behavior before invoking doClose(). Subclasses
should implement this only if it needs to do something specific to
close the player.
synchronized (this) {
closing = true;
notifyAll();
}
if (getState() == Controller.Started) {
// Stop everything first.
stop(LOCAL_STOP);
}
// Ask all its controllers to close themselves.
if (controllerList != null) {
Controller c;
while (!controllerList.isEmpty()) {
c = (Controller)controllerList.firstElement();
c.close();
controllerList.removeElement(c);
}
}
// Close the ui components.
if (controlComp != null)
((DefaultControlPanel)controlComp).dispose();
controlComp = null;
if (statsThread != null)
statsThread.kill();
sendEvent(new ControllerClosedEvent(this));
|
protected synchronized boolean | doConfigure()The stub function (invoked from configure()) to perform the steps to
configure the player. It performs the following:
- call configure() on each controller managed by this player.
- wait for ConfigureCompleteEvent from each controller;
Subclasses are allowed to override doConfigure(). But this should be
done in caution. Subclass should also invoke super.doConfigure().
This is called from a separately running thread.
potentialEventsList = configureEventList; // List of potential events for the
// configure() method
resetReceivedEventList(); // Reset list of received events
receivedAllEvents = false;
currentControllerList.removeAllElements();
int i = controllerList.size();
while (--i >= 0) {
Controller c = (Controller) controllerList.elementAt(i);
if (c.getState() == Unrealized &&
(c instanceof Processor || c instanceof BasicController)) {
currentControllerList.addElement(c);
}
}
i = currentControllerList.size();
while (--i >= 0) {
Controller c = (Controller) currentControllerList.elementAt(i);
if (c instanceof Processor)
((Processor)c).configure();
else if (c instanceof BasicController)
((BasicController)c).configure();
}
if (!currentControllerList.isEmpty()) {
try {
while (!closing && !receivedAllEvents)
wait();
} catch (InterruptedException e) {
}
currentControllerList.removeAllElements();
}
// Make sure all the controllers are in in Configured State.
// If not, it means that configure failed on one or more controllers.
// Currenly, if configure fails then you get a ResourceUnavailableEvent
// instead of RealizeCompleteEvent
i = controllerList.size();
while (--i >= 0) {
Controller c = (Controller) controllerList.elementAt(i);
if ((c instanceof Processor || c instanceof BasicController) &&
c.getState() < Configured) {
Log.error("Error: Unable to configure " + c);
source.disconnect();
return false;
}
}
// subclass will implement this to configure up the signal graph.
return true;
|
protected void | doFailedConfigure()Called when configure fails.
super.doFailedConfigure();
synchronized (this) {
notify();
}
close();
|
protected void | doFailedPrefetch()Called when prefetch fails.
super.doFailedPrefetch();
synchronized (this) {
notify();
}
|
protected void | doFailedRealize()Called when realize fails.
super.doFailedRealize();
synchronized (this) {
notify();
}
close();
|
protected boolean | doPrefetch()The stub function to perform the steps to prefetch the controller.
This will call prefetch() on every controller in the controller list and wait
for their completion events.
This is called from a separately running thread.
potentialEventsList = prefetchEventList; // List of potential events for the
// prefetch() method
resetReceivedEventList(); // Reset list of received events
receivedAllEvents = false;
currentControllerList.removeAllElements();
Vector list = controllerList;
if (list == null) {
return false;
}
int i = list.size();
while (--i >= 0) {
Controller c = (Controller) list.elementAt(i);
if (c.getState() == Realized) {
currentControllerList.addElement(c);
c.prefetch();
}
}
if (!currentControllerList.isEmpty()) {
synchronized(this) {
try {
while (!closing && !receivedAllEvents)
wait();
} catch (InterruptedException e) {
}
currentControllerList.removeAllElements();
}
}
// Make sure all the controllers are in in Prefetched State.
// If not, it means that prefetch failed on one or more controllers.
// Currenly, if prefetch fails then you get a ResourceUnavailableEvent
// instead of PrefetchCompleteEvent
i = list.size();
while (--i >= 0) {
Controller c = (Controller) list.elementAt(i);
if (c.getState() < Prefetched) {
Log.error("Error: Unable to prefetch " + c + "\n");
if (optionalControllerList.contains(c)) {
//System.out.println(c + " Controller is optional... continuing");
removedControllerList.addElement(c);
} else {
// Notify the play thread which could still be waiting.
synchronized (this) {
prefetchFailed = true;
notifyAll();
}
return false;
}
}
}
if (removedControllerList != null) {
i = removedControllerList.size();
while (--i >= 0) {
Object o = removedControllerList.elementAt(i);
controllerList.removeElement(o);
( (BasicController) o).close();
if (! deviceBusy((BasicController) o)) {
// Notify the play thread which could still be waiting.
synchronized (this) {
prefetchFailed = true;
notifyAll();
}
return false; // prefetch failed
}
}
removedControllerList.removeAllElements();
//$ System.err.println("final list of controllers: " + list);
}
return true;
|
protected synchronized boolean | doRealize()The stub function (invoked from configure()) to perform the steps to
configure the player. It performs the following:
- call realize() on each controller managed by this player.
- wait for RealizeCompleteEvent from each controller;
Subclasses are allowed to override doRealize(). But this should be
done in caution. Subclass should also invoke super.doRealize().
This is called from a separately running thread.
potentialEventsList = realizeEventList; // List of potential events for the
// realize() method
resetReceivedEventList(); // Reset list of received events
receivedAllEvents = false;
currentControllerList.removeAllElements();
int i = controllerList.size();
while (--i >= 0) {
Controller c = (Controller) controllerList.elementAt(i);
if (c.getState() == Unrealized || c.getState() == Configured) {
currentControllerList.addElement(c);
}
}
i = currentControllerList.size();
while (--i >= 0) {
Controller c = (Controller) currentControllerList.elementAt(i);
c.realize();
}
if (!currentControllerList.isEmpty()) {
try {
while (!closing && !receivedAllEvents)
wait();
} catch (InterruptedException e) {
}
currentControllerList.removeAllElements();
}
// Make sure all the controllers are in in Realized State.
// If not, it means that realize failed on one or more controllers.
// Currenly, if realize fails then you get a ResourceUnavailableEvent
// instead of RealizeCompleteEvent
i = controllerList.size();
while (--i >= 0) {
Controller c = (Controller) controllerList.elementAt(i);
if (c.getState() < Realized) {
Log.error("Error: Unable to realize " + c);
source.disconnect();
return false;
}
}
updateDuration();
if ( /*securityPrivelege &&*/ (jmfSecurity != null) ) {
String permission = null;
try {
if (jmfSecurity.getName().startsWith("jmf-security")) {
permission = "thread";
jmfSecurity.requestPermission(m, cl, args, JMFSecurity.THREAD);
m[0].invoke(cl[0], args[0]);
permission = "thread group";
jmfSecurity.requestPermission(m, cl, args, JMFSecurity.THREAD_GROUP);
m[0].invoke(cl[0], args[0]);
} else if (jmfSecurity.getName().startsWith("internet")) {
PolicyEngine.checkPermission(PermissionID.THREAD);
PolicyEngine.assertPermission(PermissionID.THREAD);
}
} catch (Exception e) {
if (JMFSecurityManager.DEBUG) {
System.err.println("Unable to get " + permission +
" privilege " + e);
}
securityPrivelege = false;
// TODO: Do the right thing if permissions cannot be obtained.
// User should be notified via an event
}
}
if ( (jmfSecurity != null) && (jmfSecurity.getName().startsWith("jdk12"))) {
try {
Constructor cons = CreateWorkThreadAction.cons;
statsThread = (StatsThread) jdk12.doPrivM.invoke(
jdk12.ac,
new Object[] {
cons.newInstance(
new Object[] {
StatsThread.class,
BasicPlayer.class,
this
})});
statsThread.start();
} catch (Exception e) {
}
} else {
statsThread = new StatsThread(this);
statsThread.start();
}
// subclass will implement this to connect up the signal graph.
return true;
|
protected void | doSetMediaTime(javax.media.Time now)Called from setMediaTime.
This is used for subclasses to add in their own behavior.
|
protected float | doSetRate(float factor)
return factor;
|
private void | doSetStopTime(javax.media.Time t)
getClock().setStopTime(t);
Vector list = controllerList;
int i = list.size();
while (--i >= 0) {
Controller c = (Controller)controllerList.elementAt(i);
c.setStopTime(t);
}
|
protected void | doStart()Invoked by start() or syncstart().
Called from a separate thread called TimedStart thread.
subclasses can override this method to implement its specific behavior.
|
protected void | doStop()The stop() method calls doStop() so that subclasses can
add additional behavior.
|
public void | downloadUpdate()
if (extendedCachingControl == null)
return;
// It will be nice if we can avoid the cast to BasicController
sendEvent(new CachingControlEvent(this, cachingControl,
cachingControl.getContentProgress()));
if ( regionControl == null )
return;
long contentLength = cachingControl.getContentLength();
int maxValuePercent;
if ( (contentLength == javax.media.protocol.SourceStream.LENGTH_UNKNOWN) ||
(contentLength <= 0) ) {
maxValuePercent = 0;
} else {
long endOffset = extendedCachingControl.getEndOffset();
maxValuePercent = (int) ((100.0 * endOffset) / contentLength);
if (maxValuePercent < 0)
maxValuePercent = 0;
else if (maxValuePercent > 100)
maxValuePercent = 100;
}
regionControl.setMinValue(0);
regionControl.setMaxValue(maxValuePercent);
|
public java.lang.String | getContentType()
if (source != null)
return source.getContentType();
return null;
|
public java.awt.Component | getControlPanelComponent()Get the Component with the default user interface for controlling
this player.
If this player has no default control panel null is
returned.
Subclasses should override this method and return the control panel
component but call this method first to ensure that the restrictions
on player methods are enforced.
int state = getState();
if (state < Realized) {
throwError(new NotRealizedError("Cannot get control panel component on an unrealized player"));
}
if (controlComp == null) {
controlComp = new DefaultControlPanel( this );
}
return controlComp;
|
public final java.util.Vector | getControllerList()Return the list of BasicControllers supported by this Player.
return controllerList;
|
public javax.media.Control[] | getControls()Return the list of controls from its slave controllers plus the
ones that this player supports.
if (controls != null)
return controls;
// build the list of controls. It is the total of all the
// controls from each controllers plus the ones that are maintained
// by the player itself (e.g. playbackControl).
Vector cv = new Vector();
if (cachingControl != null)
cv.addElement(cachingControl);
if (bufferControl != null)
cv.addElement(bufferControl);
Control c;
Object cs[];
Controller ctrller;
int i, size = controllerList.size();
for (i = 0; i < size; i++) {
ctrller = (Controller)controllerList.elementAt(i);
cs = ctrller.getControls();
if (cs == null) continue;
for (int j = 0; j < cs.length; j++) {
cv.addElement(cs[j]);
}
}
Control ctrls[];
size = cv.size();
ctrls = new Control[size];
for (i = 0; i < size; i++) {
ctrls[i] = (Control)cv.elementAt(i);
}
// If the player has already been realized, we'll save what
// we've collected this time. Then next time, we won't need
// to go through this expensive search again.
if (getState() >= Realized)
controls = ctrls;
return ctrls;
|
public javax.media.Time | getDuration()Get the duration of the movie.
long t;
if ((t = getMediaNanoseconds()) > lastTime) {
lastTime = t;
updateDuration();
}
return duration;
|
public javax.media.GainControl | getGainControl()Get the object for controlling audio gain. Return null
if this player does not have a GainControl (e.g. no audio).
int state = getState();
if (state < Realized) {
throwError(new NotRealizedError("Cannot get gain control on an unrealized player"));
} else {
return (GainControl)getControl("javax.media.GainControl");
}
return null;
|
protected abstract javax.media.TimeBase | getMasterTimeBase()This should be implemented by the subclass.
The subclass method should return the master TimeBase -- the
TimeBase that all other controllers slave to.
Use SystemTimeBase if unsure.
|
public javax.media.MediaLocator | getMediaLocator()
if (source != null)
return source.getLocator();
return null;
|
private java.util.Vector | getPotentialEventsList()
return potentialEventsList;
|
private java.util.Vector | getReceivedEventsList()Return the list of received events
return receivedEventList;
|
protected javax.media.protocol.DataSource | getSource()Get the DataSource used by this player.
return source;
|
public javax.media.Time | getStartLatency()
super.getStartLatency();
Time latency;
long t = 0;
// Find the longest start latency from all the slave Controllers.
for (int i = 0; i < controllerList.size(); i++) {
Controller c = (Controller) controllerList.elementAt(i);
latency = c.getStartLatency();
if (latency == LATENCY_UNKNOWN)
continue;
if (latency.getNanoseconds() > t)
t = latency.getNanoseconds();
}
if (t == 0)
return LATENCY_UNKNOWN;
return new Time(t);
|
public java.awt.Component | getVisualComponent()Get the Component this player will output its visual media to. If
this player has no visual component (e.g. audio only)
getVisualComponent() will return null.
Subclasses should override this method and return the visual
component but call this method first to ensure that the restrictions
on player methods are enforced.
int state = getState();
if (state < Realized) {
throwError(new NotRealizedError("Cannot get visual component on an unrealized player"));
}
return null;
|
public boolean | isAboutToRestart()Return true if the player is about to restart again.
return aboutToRestart;
|
protected boolean | isConfigurable()A player is not configurable.
return false;
|
public boolean | isFramePositionable()Will return true if the player can do frame
positioning. Hack for now, should be removed when players
actually implement the framePositioning control.
return framePositioning;
|
protected final void | manageController(javax.media.Controller controller)Add a Controller to the list of Controllers under this Player's
management. This is a protected method use only by subclasses.
Use addController() for public access.
manageController(controller, false);
|
protected final void | manageController(javax.media.Controller controller, boolean optional)Add a Controller to the list of Controllers under this Player's
management.
if (controller != null) {
if (!controllerList.contains(controller)) {
controllerList.addElement(controller);
if (optional)
optionalControllerList.addElement(controller);
controller.addControllerListener(this);
}
}
updateDuration();
|
private void | notifyIfAllEventsArrived(java.util.Vector controllerList, java.util.Vector receivedEventList)
if ( (receivedEventList != null) &&
(receivedEventList.size() == currentControllerList.size()) ) {
receivedAllEvents = true;
resetReceivedEventList(); // Reset list of received events
synchronized(this) {
notifyAll();
}
}
|
final synchronized void | play()This method gets run in a separate thread called PlayThread
boolean status;
// If a deallocate() happens before this thread gets to run.
// or if a stop() happens before this thread gets to run.
if (getTargetState() != Started) {
return;
}
prefetchFailed = false;
// The following completed checks should be looked at seriously.
// It should be something like (state < Prefetched) etc.
// It's too late for 2.1.1 release. We'll leave it this way. --ivg
int state = getState();
if ( (state == Unrealized) || (state == Configured) || (state == Realized) ) {
prefetch();
}
while (!closing && !prefetchFailed &&
(getState() == Configuring || getState() == Realizing ||
getState() == Realized || getState() == Prefetching)) {
try {
wait();
} catch (InterruptedException e) {
}
}
if ( getState() != Started &&
getTargetState() == Started && getState() == Prefetched ) {
syncStart(getTimeBase().getTime());
}
|
protected final void | processEndOfMedia()
super.stop();
sendEvent(new EndOfMediaEvent(this, Started, Prefetched,
getTargetState(), getMediaTime()));
|
protected void | processEvent(javax.media.ControllerEvent evt)
Controller source = evt.getSourceController();
if (evt instanceof AudioDeviceUnavailableEvent) {
sendEvent(new AudioDeviceUnavailableEvent(this));
return;
}
// If this is a closed event triggered by one of the
// managed controllers, not triggered by the player,
// then we'll need to programmtically close all the
// controllers and the player itself.
if ( evt instanceof ControllerClosedEvent && !closing &&
controllerList.contains(source) &&
! (evt instanceof ResourceUnavailableEvent) ) {
// The source of the error event should have been closed
// already. So we'll just remove it from the list of
// managed controllers.
controllerList.removeElement(source);
if (evt instanceof ControllerErrorEvent)
sendEvent(new ControllerErrorEvent(this,
((ControllerErrorEvent) evt).getMessage()));
close();
}
//
// Send SizeChangeEvent down to Player
//
if ( (evt instanceof SizeChangeEvent) && controllerList.contains(source) ) {
// System.err.println("width = " + ((SizeChangeEvent)evt).getWidth());
// System.err.println("height = " + ((SizeChangeEvent)evt).getHeight());
sendEvent(new SizeChangeEvent(this,
((SizeChangeEvent)evt).getWidth(),
((SizeChangeEvent)evt).getHeight(),
((SizeChangeEvent)evt).getScale()));
return;
}
//
// Send UnsupportedFormatEvent down to Player
//
/*
if ( (evt instanceof UnsupportedFormatEvent) &&
controllerList.contains(source) ) {
// System.err.println("Reason = " + ((UnsupportedFormatEvent)evt).toString());
sendEvent(new UnsupportedFormatEvent(this,
((UnsupportedFormatEvent)evt).getFormat()));
return;
}
*/
// If we get a DurationUpdateEvent from one of the controllers,
// update the duration of the player
if ((evt instanceof DurationUpdateEvent) && controllerList.contains(source)) {
updateDuration();
return;
}
// HANGS.
// if ((evt instanceof RestartingEvent) && controllerList.contains(source)) {
// System.out.println("MP: Got RestartingEvent from " + source);
// stop(LOCAL_STOP); // Stop without sending any stop event
// sendEvent(new RestartingEvent(this, Started, Prefetching, Started,
// getMediaTime()));
// }
// So I am handling RestartingEvent this way
if ((evt instanceof RestartingEvent) && controllerList.contains(source)) {
restartFrom = source;
int i = controllerList.size();
super.stop(); // Added
setTargetState(Prefetched); // necessary even if super.stop is called.
for (int ii = 0; ii < i; ii++) {
Controller c = (Controller) controllerList.elementAt(ii);
if (c != source) {
c.stop();
}
}
super.stop();
// doStop(); // Allow subclasses to extend the behavior
sendEvent(new RestartingEvent(this, Started, Prefetching, Started,
getMediaTime()));
}
if ((evt instanceof StartEvent) && (source == restartFrom) ) {
restartFrom = null;
// $$ TODO: Should probably send PrefetchCompleteEvent
start();
}
if ( (evt instanceof SeekFailedEvent) && controllerList.contains(source) ) {
int i = controllerList.size();
super.stop(); // Added
setTargetState(Prefetched); // necessary even if super.stop is called.
for (int ii = 0; ii < i; ii++) {
Controller c = (Controller) controllerList.elementAt(ii);
if (c != source) {
c.stop();
}
}
/*
super.stop();
setMediaTime(new Time(0));
start();
*/
sendEvent(new SeekFailedEvent(this, Started, Prefetched, Prefetched,
getMediaTime()));
}
if ( (evt instanceof EndOfMediaEvent) && controllerList.contains(source) ) {
if (eomEventsReceivedFrom.contains(source)) {
return;
}
eomEventsReceivedFrom.addElement(source);
if (eomEventsReceivedFrom.size() == controllerList.size()) {
super.stop();
sendEvent(new EndOfMediaEvent(this, Started, Prefetched,
getTargetState(), getMediaTime()));
}
return;
}
if ((evt instanceof StopAtTimeEvent) && controllerList.contains(source) &&
(getState() == Started)) {
synchronized (stopAtTimeReceivedFrom) {
if (stopAtTimeReceivedFrom.contains(source))
return;
stopAtTimeReceivedFrom.addElement(source);
boolean allStopped = (stopAtTimeReceivedFrom.size() == controllerList.size());
if (!allStopped) {
// Now check if the other controllers have already EOM'ed.
allStopped = true;
for (int i = 0; i < controllerList.size(); i++) {
Controller c = (Controller)controllerList.elementAt(i);
if (!stopAtTimeReceivedFrom.contains(c) &&
!eomEventsReceivedFrom.contains(c)) {
allStopped = false;
break;
}
}
}
if (allStopped) {
super.stop();
doSetStopTime(Clock.RESET);
sendEvent(new StopAtTimeEvent(this, Started, Prefetched,
getTargetState(), getMediaTime()));
}
return;
} // synchronized stopAtTimeReceivedFrom
}
if ((evt instanceof CachingControlEvent) && controllerList.contains(source) ) {
CachingControl mcc = (CachingControl)
((CachingControlEvent) evt).getCachingControl();
sendEvent(new CachingControlEvent(this,
mcc,
mcc.getContentProgress()));
return;
}
Vector eventList = potentialEventsList;
if (controllerList != null && controllerList.contains(source) &&
eventList != null && eventList.contains(evt.getClass().getName())) {
updateReceivedEventsList(evt);
notifyIfAllEventsArrived(controllerList, getReceivedEventsList());
}
|
public final synchronized void | removeController(javax.media.Controller oldController)Stop controlling a Controller.
int state = getState();
if (state < Realized) {
throwError(new NotRealizedError("Cannot remove controller from a unrealized player"));
}
if (state == Started) {
throwError(new ClockStartedError("Cannot remove controller from a started player"));
}
if (oldController == null)
return;
if (controllerList.contains(oldController)) {
controllerList.removeElement(oldController);
oldController.removeControllerListener(this);
updateDuration();
// Reset the controller to its default time base.
try {
oldController.setTimeBase(null);
} catch (IncompatibleTimeBaseException e) {}
}
|
private void | resetReceivedEventList()Resets the list of received events
if (receivedEventList != null)
receivedEventList.removeAllElements();
|
protected void | setMediaLength(long t)Set the upper bound of the media time.
duration = new Time(t);
super.setMediaLength(t);
|
public final void | setMediaTime(javax.media.Time now)Loops through the list of controllers maintained by this
player and invoke setMediaTime on each of them.
This is a "final" method and cannot be overridden by subclasses.
if (state < Realized)
throwError(new NotRealizedError(MediaTimeError));
// Set Media time from EOM and user click on the slider is
// trampling on one another. Causing the player to hang
// this mediaTimeSync will guard against that.
synchronized (mediaTimeSync) {
if (syncStartInProgress())
return;
if (getState() == Controller.Started) {
aboutToRestart = true;
stop(RESTARTING);
}
// If source is Positionable, we'll take care of this
// at the top level.
if (source instanceof Positionable)
now = ((Positionable)source).setPosition(now, Positionable.RoundDown);
super.setMediaTime(now);
int i = controllerList.size();
while (--i >= 0) {
((Controller)controllerList.elementAt(i)).setMediaTime(now);
}
// For subclasses to add in their own behavior.
doSetMediaTime(now);
if (aboutToRestart) {
syncStart(getTimeBase().getTime());
aboutToRestart = false;
}
}
|
public float | setRate(float rate)Set the playback rate on the player.
It loops through its list of controllers and invoke setRate on each
of them.
if (state < Realized) {
throwError(new NotRealizedError("Cannot set rate on an unrealized Player."));
}
// Verify to see if the DataSource supports that rate.
if (source instanceof RateConfigureable)
rate = checkRateConfig((RateConfigureable)source, rate);
float oldRate = getRate();
if (oldRate == rate)
return rate;
if (getState() == Controller.Started) {
aboutToRestart = true;
stop(RESTARTING);
}
float rateSet; // Actual rate set
if (!trySetRate(rate)) {
if (!trySetRate(oldRate)) { // try to go back to the oldRate
trySetRate(1.0F); // try setRate(1.0) which shouldn't fail
rateSet = 1.0F;
} else {
rateSet = oldRate;
}
} else {
rateSet = rate;
}
super.setRate(rateSet);
if (aboutToRestart) {
syncStart(getTimeBase().getTime());
aboutToRestart = false;
}
return rateSet;
|
public void | setSource(javax.media.protocol.DataSource source)Set the DataSource that provides the media for this player.
BasicPlayer only supports PullDataSource by default. Subclasses
can override this method to support other DataSources.
this.source = source;
try {
cachingControl = (CachingControl) source.getControl("javax.media.CachingControl");
if ( (cachingControl != null) &&
(cachingControl instanceof ExtendedCachingControl) ) {
extendedCachingControl = (ExtendedCachingControl) cachingControl;
if (extendedCachingControl != null) {
// update progress every 100 kilobytes
regionControl = new SliderRegionControlAdapter();
extendedCachingControl.addDownloadProgressListener(this, 100);
}
}
} catch (ClassCastException e) {
}
|
public void | setStopTime(javax.media.Time t)
if (state < Realized) {
throwError(new NotRealizedError("Cannot set stop time on an unrealized controller."));
}
if (getClock().getStopTime() == null ||
getClock().getStopTime().getNanoseconds() != t.getNanoseconds()) {
sendEvent(new StopTimeChangeEvent(this, t));
}
doSetStopTime(t);
|
public void | setTimeBase(javax.media.TimeBase tb)Assigns a timebase for the player.
If the BasicPlayer plays back audio, the timebase can be none
other than the master timebase as returned by getMasterTimeBase().
This is to ensure that we won't set to a timebase the audio
cannot handle at this point.
If the playback is video only, the timebase can be set to any
timebase desired.
TimeBase oldTimeBase = getMasterTimeBase();
if (tb == null)
tb = oldTimeBase;
Controller c = null;
int i;
if (controllerList != null) {
try {
i = controllerList.size();
while (--i >= 0) {
c = (Controller)controllerList.elementAt(i);
c.setTimeBase(tb);
}
} catch (IncompatibleTimeBaseException e) {
// SetTimeBase had failed on one Controller. Some
// controllers may have already assigned the new timeBase
// We'll need to reverse that now.
Controller cx;
i = controllerList.size();
while (--i >= 0) {
cx = (Controller)controllerList.elementAt(i);
if (cx == c)
break;
cx.setTimeBase(oldTimeBase);
}
Log.dumpStack(e);
throw e;
}
}
super.setTimeBase(tb);
|
protected void | slaveToMasterTimeBase(javax.media.TimeBase tb)Slave all the controllers to the master time base.
The controllers should be in realized or greater state
This differs from the setTimeBase() as it loops through each
controllers and call setTimeBase on each of them.
//$$ System.out.println("slaveToMasterTimeBase: master timebase is " + tb);
//$ System.out.println("Setting master " + tb + " on " + this);
this.setTimeBase(tb); // For the player
|
public final void | start()Start the Player as soon as possible.
Start attempts to transition the player into the
started state.
If the player has not been realized, or prefetched,
then the equivalent of those actions will occur,
and the appropriate events will be generated.
If the implied realize or prefetch fail, a failure
event will be generated and the Player will remain in
one of the non-started states.
This is a "final" method. Subclasses should override doStart() to
implement its own specific behavior.
synchronized (startSync) {
if (restartFrom != null) {
return;
}
if (getState() == Started) {
sendEvent(new StartEvent(this, Started, Started,
Started, mediaTimeAtStart, startTime));
return; // ignored according to jmf spec.
}
if ( (playThread == null) || (! playThread.isAlive()) ) {
setTargetState(Started);
if ( /*securityPrivelege && */ (jmfSecurity != null) ) {
String permission = null;
try {
if (jmfSecurity.getName().startsWith("jmf-security")) {
permission = "thread";
jmfSecurity.requestPermission(m, cl, args, JMFSecurity.THREAD);
m[0].invoke(cl[0], args[0]);
permission = "thread group";
jmfSecurity.requestPermission(m, cl, args, JMFSecurity.THREAD_GROUP);
m[0].invoke(cl[0], args[0]);
} else if (jmfSecurity.getName().startsWith("internet")) {
PolicyEngine.checkPermission(PermissionID.THREAD);
PolicyEngine.assertPermission(PermissionID.THREAD);
}
} catch (Throwable e) {
if (JMFSecurityManager.DEBUG) {
System.err.println("Unable to get " + permission +
" privilege " + e);
}
securityPrivelege = false;
// TODO: Do the right thing if permissions cannot be obtained.
// User should be notified via an event
}
}
if ( (jmfSecurity != null) && (jmfSecurity.getName().startsWith("jdk12"))) {
try {
Constructor cons = CreateWorkThreadAction.cons;
playThread = (PlayThread) jdk12.doPrivM.invoke(
jdk12.ac,
new Object[] {
cons.newInstance(
new Object[] {
PlayThread.class,
BasicPlayer.class,
this
})});
playThread.start();
} catch (Exception e) {
}
} else {
playThread = new PlayThread(this);
playThread.start();
}
} else {
// $$$$
// System.out.print("WARNING: playThread is alive. start ignored"); // $$$
// System.out.println(": MP State: " + getState());
}
} // startSync
|
public final void | stop()Stop the player.
If current state is Started, sends stop() to all the
managed controllers, and waits for a StopEvent from
all of them. It then sends a StopEvent to any listener(s).
stop(STOP_BY_REQUEST);
|
private void | stop(int stopType)
/*synchronized*/
int state;
switch (state = getState()) {
case Unrealized:
case Realized:
case Prefetched:
setTargetState(state);
break;
case Realizing:
setTargetState(Realized);
break;
case Prefetching:
case Started:
setTargetState(Prefetched);
break;
}
if (getState() != Started) {
switch (stopType) {
case STOP_BY_REQUEST:
sendEvent( new StopByRequestEvent(this, getState(),
getState(),
getTargetState(),
getMediaTime()));
break;
case RESTARTING:
sendEvent( new RestartingEvent(this, getState(),
getState(),
Started,
getMediaTime()));
break;
default:
sendEvent( new StopEvent(this, getState(),
getState(),
getTargetState(),
getMediaTime()));
break;
}
} else if (getState() == Started) {
synchronized(this) {
// List of potential events for stop()
potentialEventsList = stopEventList;
// Reset list of received events
resetReceivedEventList();
receivedAllEvents = false;
currentControllerList.removeAllElements();
int i = controllerList.size();
while (--i >= 0) {
Controller c = (Controller) controllerList.elementAt(i);
currentControllerList.addElement(c);
c.stop();
}
if (currentControllerList == null)
return;
if (!currentControllerList.isEmpty()) {
try {
while (!closing && !receivedAllEvents)
wait();
} catch (InterruptedException e) {
}
currentControllerList.removeAllElements();
}
super.stop();
//doStop(); // Allow subclasses to extend the behavior
switch (stopType) {
case STOP_BY_REQUEST:
sendEvent( new StopByRequestEvent(this, Started,
getState(),
getTargetState(),
getMediaTime()));
break;
case RESTARTING:
sendEvent( new RestartingEvent(this, Started,
getState(),
Started,
getMediaTime()));
break;
default:
sendEvent( new StopEvent(this, Started,
getState(),
getTargetState(),
getMediaTime()));
break;
}
}
}
|
protected void | stopAtTime()Stop because stop time has been reached.
Subclasses should override this method.
// We'll overwrite the parent method which stops the controller.
// For the player, we don't have to do anything in particular
// since the controllers are supposed to stop themselves.
|
public final void | syncStart(javax.media.Time tbt)Start at the given time base time.
This overrides Clock.syncStart() and obeys all its semantics.
This is a "final" method. Subclasses should override doStart() to
implement its own specific behavior.
/**
* To guard against conflict with setMediaTime.
*/
synchronized (mediaTimeSync) {
if (syncStartInProgress())
return;
int state = getState();
if (state == Started) {
throwError(new ClockStartedError("syncStart() cannot be used on an already started player"));
}
if (state != Prefetched) {
throwError(new NotPrefetchedError("Cannot start player before it has been prefetched"));
}
// Clear the EOM and StopAtTime lists.
eomEventsReceivedFrom.removeAllElements();
stopAtTimeReceivedFrom.removeAllElements();
setTargetState(Started);
int i = controllerList.size();
// The start(tbt) will throw a NotPrefetchedError if
// a controller is not in Prefetched state
while (--i >= 0) {
if (getTargetState() == Started) { // ADDED
((Controller)controllerList.elementAt(i)).syncStart(tbt);
}
}
if (getTargetState() == Started) { // ADDED
// If control comes here, the controllers
// are in Started state.
startTime = tbt;
mediaTimeAtStart = getMediaTime();
super.syncStart(tbt); // To start the clock and set the state to Started
}
}
|
private boolean | trySetRate(float rate)
int i = controllerList.size();
while(--i >=0) {
Controller c = (Controller)controllerList.elementAt(i);
if ( c.setRate(rate) != rate ) {
return false;
}
}
return true;
|
public final void | unmanageController(javax.media.Controller controller)Remove a Controller from the list of Controllers under this Player's
management. This is a protected method use only by subclasses.
Use removeController() for public access.
if (controller != null)
if (controllerList.contains(controller)) {
controllerList.removeElement(controller);
controller.removeControllerListener(this);
}
|
protected synchronized void | updateDuration()
Time oldDuration = duration;
duration = DURATION_UNKNOWN;
for (int i = 0; i < controllerList.size(); i++) {
Controller c = (Controller) controllerList.elementAt(i);
Time dur = c.getDuration();
if ( dur.equals(DURATION_UNKNOWN) ) {
if (! (c instanceof BasicController)) {
duration = DURATION_UNKNOWN;
break;
}
} else if (dur.equals(DURATION_UNBOUNDED)) {
duration = DURATION_UNBOUNDED;
break;
} else {
if (duration.equals(DURATION_UNKNOWN))
duration = dur;
else if (duration.getNanoseconds() < dur.getNanoseconds())
duration = dur;
}
}
if (duration.getNanoseconds() != oldDuration.getNanoseconds()) {
setMediaLength(duration.getNanoseconds());
sendEvent( new DurationUpdateEvent(this, duration) );
}
|
private void | updateReceivedEventsList(javax.media.ControllerEvent event)Updates the list of received events. Sources are stored.
if (receivedEventList != null) {
Controller source = event.getSourceController();
if (receivedEventList.contains(source)) {
// System.out.println("DUPLICATE " + event +
// " received from: " + source);
return;
}
receivedEventList.addElement(source);
}
|
public abstract void | updateStats()This is being called from a looping thread to update the stats.
|
protected abstract boolean | videoEnabled()Return true if the player is currently playing media
with a video track.
|