|
JSR-927 (Maintenance Release) | ||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
Controller
, which extends Clock
,
provides resource-allocation
state information, event generation, and a mechanism for obtaining objects
that provide additional control over a Controller
.
Clock
, a Controller
is always either
Started or Stopped.
However, Controller
subdivides
Clock's
Stopped state into five
resource-allocation phases:
Unrealized, Realizing, Realized,
Prefetching, and Prefetched.
The motivation for these life-cycle states is to provide
programmatic control over potentially time-consuming operations.
For example, when a Controller
is first constructed, it's in
the Unrealized state.
While Realizing, the Controller
performs the communication necessary to locate all of the resources
it needs to function (such as communicating with a server,
other controllers, or a file system).
The realize
method allows an application to initiate this
potentially time-consuming process (Realizing) at an
appropriate time.
When a Controller
is Realizing or Prefetching,
it will eventually transition to another state, such as Realized,
Prefetched, or even Unrealized.
Because a Controller
is often in one state on its way to
another, its destination or target state is an integral part
of the Controller
life-cycle.
You can query a Controller
to determine both its
current state and its target state.
A Controller
typically moves from the Unrealized state
through Realizing to the Realized state,
then through Prefetching
to the Prefetched state, and finally on to the Started state.
When a Controller
finishes because
the end of the media stream is reached,
its stop time is reached,
or the stop
method is invoked,
the Controller
moves from the Started state
back to Prefetched
or possibly back to Realized, ready to
repeat the cycle.
To use a Controller
, you set up parameters to
manage its movement through these life-cycle states and then
move it through the states using the Controller
state transition methods.
To keep track of the Controller's
current state,
you monitor the state transition events that it posts when changing states.
Controller
has five methods that are used to induce
life-cycle state changes:
realize
, prefetch
, deallocate
,
syncStart
, and stop
.
To transition a Controller
to the Realized,
Prefetched, or Started state,
you use the corresponding method: realize
,
prefetch
, or syncStart
. The
deallocate
and stop
methods can change
a requested state transition or trigger a state change.
The forward transition methods (realize
,
prefetch
, and syncStart
) are executed
asynchronously and return immediately.
When the requested operation is complete, the Controller
posts a ControllerEvent
that indicates that the target state has been reached,
stop
or deallocate
has been invoked, or
that an error occurred.
The deallocate
, and stop
methods can
change the target state and induce a transition back to
a previous state. For example, calling deallocate
on
a Controller
in the
Prefetching state will move it back to
Realized. These methods are synchronous.
Controller
often moves between states
in an asynchronous manner.
To facilitate the tracking of a Controller's
state,
every time its state or target state changes,
the Controller
is required to post a TransitionEvent
that describes
its previous state, current state, and new target state.
By monitoring the Controller
event stream, you can determine
exactly what a Controller
is doing at any point in time.
When one of the asynchronous forward state transition methods
completes, the Controller
posts the appropriate TransitionEvent
or a ControllerErrorEvent
indicating that
the Controller
is no longer usable.
For more information about ControllerEvents
, see the Controller Events section.
To facilitate simple asynchronous method protocols,
a Controller
always posts a method completion event
when one of the asynchronous forward state transition methods is invoked, even
if no state or target state change occurs.
For example, if realize
is called on a
Prefetching Controller
,
a RealizeCompleteEvent
is immediately posted, even though the Controller
remains
in the Prefetching state and the target state is still
Prefetched.
The method completion events always report the Controller's
previous,
current, and target state at the time the event was posted.
Controller
states.
Controller
starts in
the Unrealized state.
An Unrealized Controller
knows very little about its
internals and does not have enough information to acquire all of the resources
it needs to function.
In particular, an Unrealized Controller
does
not know enough to properly construct
a Clock
.
Therefore, it is illegal to call the following methods
on an Unrealized Controller
:
getTimeBase
setTimeBase
setMediaTime
setRate
setStopTime
getStartLatency
NotRealizedError
is thrown if any of these methods are called
on an Unrealized Controller
.
Controller
is Realized when it has obtained
all of the information necessary for it to acquire the resources it needs
to function.
A Realizing Controller
is in the process of
identifying the resources that it needs to acquire.
Realizing can be a resource and time-consuming process.
A Realizing Controller
might have to communicate with
a server, read a file, or interact with a set of other objects.
Although a Realized Controller
does not have to acquire
any resources, a Realized Controller
is likely to have
acquired all of the resources it needs except those that imply exclusive use of a
scarce system resource, such as an audio device or MPEG decoding hardware.
Normally, a Controller
moves from the Unrealized state
through Realizing and on to the Realized state.
After realize
has been invoked on a Controller
, the only way it can return
to the Unrealized state is if deallocate
is
invoked before Realizing completes.
Once a Controller
reaches the Realized state, it
never returns to the Unrealized state; it remains in one of four
states: Realized, Prefetching, Prefetched, or
Started.
realize
method executes asynchronously and completion
is signaled by a RealizeCompleteEvent
or a
ControllerErrorEvent
.
Controller
might still need to
perform a number of time-consuming tasks before it is ready to be started.
For example, it might need to acquire scarce hardware resources,
fill buffers with media data, or perform other start-up processing.
While performing these tasks, the Controller
is in the Prefetching state.
When finished, it moves into the Prefetched state.
Over a Controller's
lifetime, Prefetching might have to recur when certain methods are invoked.
For example, calling setMediaTime
might cause a Player
to be
Prefetched again before it is Started.
Once a Controller
is Prefetched, it is capable of starting as quickly
as is possible for that Controller
.
Prefetching reduces the startup latency of a Controller
to the minimum
possible value. (The startup latency is the value returned by getStartLatency
.)
Typically, a Controller
moves from the Realized state through
Prefetching and on to the Prefetched state.
Once Prefetched, a Controller
remains Prefetched unless deallocate
, syncStart
or a method that changes its state and
increases its startup latency is invoked, such as setMediaTime
.
A Started Controller
returns to the Prefetched
or Realized state when it stops.
prefetch
method is asynchronous and its completion is signaled
by a PrefetchCompleteEvent
or a ControllerErrorEvent
.
As a convenience, if prefetch
is invoked before a
Controller
has reached the Realized state,
an implicit realize
is invoked by changing the target state
to Prefetched.
Both a RealizeCompleteEvent
and a PrefetchCompleteEvent
are
posted by the Controller
as it
transitions to the Prefetched state.
If a Controller
is Prefetching and cannot obtain all of the
resources it needs to start, it posts a ResourceUnavailableEvent
instead of a PrefetchCompleteEvent
.
This is a catastrophic error condition
from which the Controller
cannot recover.
Controller
can enter the
Started state. A Started Controller's
Clock
is running and it is processing data.
A Controller
returns to the Prefetched or Realized
state when it stops because it has reached its stop time, reached the end of the media,
or because the stop
method was invoked.
When the Controller
moves from the Prefetched
to the Started state, it posts a StartEvent
.
When it moves from the Started state to a stopped state, it posts a StopEvent
.
A Controller
is a Clock
; therefore, syncStart
,
setTimeBase
, setMediaTime
, and setRate
are illegal when the Controller
is in the Started state.
Controller
is to call
syncStart
.
It is illegal to call syncStart
unless the Controller
is in the Prefetched state. If syncStart
is called before the Controller
is Prefetched,
a NotPrefetchedError
is thrown.
Player
defines a start
method that relaxes this
requirement.
Deallocate
is used to stop a Controller's
resource consumption. For example,
when Applet.stop
is called, deallocate
should be called to free the resources that the Controller
was using.
Deallocate
stops any resource-consuming activity
and releases any exclusive-use resources that the Controller
has acquired.
Deallocate
executes synchronously;
when deallocate
returns, the resources have been released.
If the Controller
is Unrealized or Realizing, calling deallocate
returns it to the
Unrealized state.
Otherwise, calling deallocate
returns a Controller
to the Realized state.
Regardless of the state that a Controller
is in,
deallocate
must relinquish any exclusive-use
system resources that it holds;
the only way to guarantee that a Controller
is not holding
resources is to call the deallocate
method.
It is illegal to call deallocate
on a Started Controller
.
You must stop the Controller
before
it can relinquish its resources.
When deallocate
is called, a Controller
posts a special StopEvent
,
DeallocateEvent
.
Controller Events
Controller
events asynchronously deliver
information about Controller
state changes.
There are four kinds of notifications:
life-cycle transition, method acknowledgement,
state notification, and error notification.
To receive events, an object must implement the ControllerListener
interface and use the addControllerListener
method to register its interest in a Controller's
events.
All Controller
events are posted to each registered listener.
The Controller
event mechanism is extensible and
some Controllers
define events other than
the ones described here.
For example, the DurationUpdateEvents
that a Player
posts
are ControllerEvents
.
TransitionEvent
TransitionEvents
are posted when a Controller's
current or target state changes. TransitionEvent
is subclassed to provide a small set of events
that are posted for particular kinds of transitions that
merit special interest. The class name of the event indicates
either the reason that the event was posted
(such as EndOfMediaEvent
),
or the particular transition that the event represents (such as
PrefetchCompleteEvent
).
In addition to being posted for state transitions,
the method acknowledgement events RealizeCompleteEvent
,
PrefetchCompleteEvent
, StartEvent
,
DeallocateEvent
,
and StopByRequestEvent
are always posted to signify method
completion even if no transition has taken place.
RealizeCompleteEvent
Controller
moves from
Realizing to the Realized state,
or when the realize
method is invoked and the
Controller
is already Realized.
PrefetchCompleteEvent
Controller
moves from Prefetching to
the Prefetched state, or when the prefetch
method is
invoked and the Controller
is already Prefetched.
StartEvent
Controller
moves from Prefetched to
Started.
StopEvent
Controller
moves backward. For example, when moving from Prefetched
to Realized or from Started to Prefetched.
The reason that a stop event occurs is often important; this information is provided through several subclasses
of StopEvent
.
StopAtTimeEvent
Controller
changes state because it has reached
its stop time.
StopByRequestEvent
Controller
changes state because stop
is invoked.
This event is also posted as an acknowledgement to stop
requests.
DeallocateEvent
deallocate
method is invoked, indicating
a possible state change and the loss of exclusive-use resources.
The current state is either Unrealized or Realized.
This event doesn't always indicate a state change. For example, it is posted
even if deallocate
is called on a Realized
Controller
.
EndOfMediaEvent
Controller
has reached the end of the media.
ControllerClosedEvent
Controller
closes it is no longer usable,
and it will post a ControllerClosedEvent
.
Once this has happened method calls on the Controller
have undefined behavior.
A Controller
will close for one of two reasons. Either
the close
method was invoked on the Controller
, or
an error has occurred. If a Controller
is closed because the
close
method was invoked, it posts a ControllerClosedEvent
.
If an error occurs it posts one of the ControllerErrorEvents
.
ControllerErrorEvent
Controller
. While this event is rarely posted, you should watch
for it when processing
other error events--this is how you can detect implementation-specific
error events.
When a ControllerErrorEvent
is posted, it indicates a catastrophic
error from which the Controller
cannot recover. There is no
recovery mechanism for a Controller
once one of these events has
been posted.
ResourceUnavailableEvent
DataLostErrorEvent
Controller
has lost data.
InternalErrorEvent
Controller
for an implementation-specific reason.
This usually indicates that there is a problem with the implementation.
Controller
where notification of the change is useful,
particularly for updating user interface components.
Notification of these changes is provided through three
ControllerEvents
:
RateChangeEvent
Controller
changes.
StopTimeChangeEvent
Controller
changes.
MediaTimeSetEvent
setMediaTime
method.
This event is not periodically posted as media time changes
due to normal Controller
processing and Clock
operation.
Control
is an object that provides a way to
affect some aspect of a Controller's operation
in a specific way.
The Control
interface provides access to a
GUI Component
that is
specific to the particular Control
.
For example, the GainControl
interface provides a way
to display a GUI control that allows the user to change the volume.
A Controller
makes a collection of Controls
available that effect the Controller's
behavior.
To access these Controls
, you use the getControls
method, which returns an array of supported Controls
.
If you know the full class or interface name of the Control
you want, you can use getControl
.
Since an application using a Controller
might not know how
to use all of the Controls
that a Controller
supports, it can make the functionality available to a user by
providing access to the Component
for
the Control
.
Player
,
Control
,
ControllerListener
,
ControllerEvent
,
TransitionEvent
,
RealizeCompleteEvent
,
PrefetchCompleteEvent
,
StartEvent
,
StopEvent
,
EndOfMediaEvent
,
ControllerErrorEvent
,
DataLostErrorEvent
,
ResourceUnavailableEvent
,
InternalErrorEvent
,
RateChangeEvent
,
MediaTimeSetEvent
,
ClockStartedError
,
NotRealizedError
Field Summary | |
static Time |
LATENCY_UNKNOWN
Returned by getStartLatency . |
static int |
Prefetched
Returned by getState . |
static int |
Prefetching
Returned by getState . |
static int |
Realized
Returned by getState . |
static int |
Realizing
Returned by getState . |
static int |
Started
Returned by getState. |
static int |
Unrealized
Returned by getState . |
Fields inherited from interface javax.media.Clock |
RESET |
Fields inherited from interface javax.media.Duration |
DURATION_UNBOUNDED, DURATION_UNKNOWN |
Method Summary | |
void |
addControllerListener(ControllerListener listener)
Specify a ControllerListener to which
this Controller will send events. |
void |
close()
Release all resources and cease all activity. |
void |
deallocate()
Abort the current operation and cease any activity that consumes system resources. |
Control |
getControl(java.lang.String forName)
Get the Control that supports the
class or interface specified. |
Control[] |
getControls()
Get a list of the Control objects that
this Controller supports. |
Time |
getStartLatency()
Get the Controller's start latency in nanoseconds. |
int |
getState()
Get the current state of this Controller . |
int |
getTargetState()
Get the current target state of this Controller . |
void |
prefetch()
Process as much data as necessary to reduce the Controller's start latency to the shortest possible time. |
void |
realize()
Construct the media dependent portions of the Controller . |
void |
removeControllerListener(ControllerListener listener)
Remove the specified listener from this Controller's
listener list. |
Methods inherited from interface javax.media.Clock |
getMediaNanoseconds, getMediaTime, getRate, getStopTime, getSyncTime, getTimeBase, mapToTimeBase, setMediaTime, setRate, setStopTime, setTimeBase, stop, syncStart |
Methods inherited from interface javax.media.Duration |
getDuration |
Field Detail |
public static final Time LATENCY_UNKNOWN
getStartLatency
.
public static final int Unrealized
getState
.
public static final int Realizing
getState
.
public static final int Realized
getState
.
public static final int Prefetching
getState
.
public static final int Prefetched
getState
.
public static final int Started
Method Detail |
public int getState()
Controller
.
The state is an integer constant as defined above.
Note: A race condition can occur between the return of this method and the execution of a state changing method.
Controller's
current state.public int getTargetState()
Controller
.
The state is an integer constant as defined above.
Note: A race condition can occur between the return of this method and the execution of a state changing method.
Controller's
current target state.public void realize()
Controller
.
This can require examining media data and might
take some time to complete.
The realize
method puts the Controller
into the Realizing state and returns immediately.
When realize
is complete and the Controller
is in the
Realized state, the Controller
posts a
RealizeCompleteEvent
.
public void prefetch()
Controller's
start latency to the shortest possible time.
This typically requires examining media data and takes some
time to complete.
The prefetch
method puts the Controller
into the Prefetching state and returns immediately.
When Prefetching is complete and the Controller
is in
the Prefetched state, the Controller
posts
a PrefetchCompleteEvent
.
public void deallocate()
Controller
is not yet
Realized,
it returns to the Unrealized state. Otherwise, the Controller
returns to the Realized state.
It is illegal to call deallocate
on a Started Controller
.
A ClockStartedError
is thrown if deallocate
is called and the Controller
is in the Started state.
public void close()
close
method indicates that the Controller
will
no longer be used, and the Controller
can
shut itself down.
A ControllerClosedEvent
is posted.
Methods invoked on a closed Controller
might throw errors.
public Time getStartLatency()
Controller's
start latency in nanoseconds. The start latency represents a
worst-case estimate of the amount of time it will take
to present the first frame of data.
This method is useful for determining how far in advance the
syncStart
method must be invoked to ensure
that media will be
rendered at the specified start time.
For a Controller
that has a variable start latency,
the value returned represents the maximum possible
start latency. If you call getStartLatency
on a Controller
that isn't Prefetched
and getStartLatency
returns LATENCY_UNKNOWN
, calling
prefetch
and then calling getStartLatency
again after the Controller
posts
a PrefetchCompleteEvent
might
return a more accurate estimate.
If getStartLatency
still returns LATENCY_UNKNOWN
,
the start latency is indeterminate and you might not be able to use
syncStart
to
synchronize the Controller
with other Controllers
.
Note: In most cases, the value returned by
getStartLatency
will change once the
Controller
is Prefetched.
public Control[] getControls()
Control
objects that
this Controller
supports.
If there are no controls, an array of length zero
is returned.
Controller
Controls
.public Control getControl(java.lang.String forName)
Control
that supports the
class or interface specified. The full class
or interface name should be specified.
Null
is returned if the Control
is not supported.
Control
for the class or interface
name.public void addControllerListener(ControllerListener listener)
ControllerListener
to which
this Controller
will send events.
A Controller
can have multiple
ControllerListeners
.
listener
- The listener to which the Controller
will post events.public void removeControllerListener(ControllerListener listener)
Controller's
listener list.
No action is performed if the specified listener
is not on the Controller's
listener list.
listener
- The listener that has been receiving events from this
Controller
.
|
JSR-927 (Maintenance Release) | ||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |