The Clock interface is implemented by objects that support
the Java Media time model.
For example, this interface might be implemented by an object that
decodes and renders MPEG movies.
Clock and TimeBase
A Clock contains a TimeBase that provides a source of time,
much like a crystal oscillator. The only information that a TimeBase provides is
its current time; it does not provide any methods for influencing how time is kept.
A Clock defines a transformation on the time that its TimeBase keeps, typically marking
time for a particular media stream. The time that a Clock keeps is referred to as the media time.
Clock Transform
The transformation that a Clock defines on a TimeBase
is defined by three parameters: rate, media start-time (mst), and
time-base start-time (tbst).
Given a time-base time (tbt),
the media time (mt) can be calculated
using the following transformation:
mt = mst + (tbt - tbst)*rate
The rate is simply a scale factor that is applied
to the TimeBase .
For example, a rate of 2.0 indicates that the Clock
will run at twice the rate
of its TimeBase . Similarly, a negative rate indicates that
the Clock runs in the opposite direction of its TimeBase .
The time-base start-time and the
media start-time define a common point in time
at which the Clock and the TimeBase are synchronized.
Default Time Base
A Clock has a default TimeBase .
For many objects that support the Clock interface, the default
TimeBase is the system TimeBase .
The system TimeBase can be obtained from Manager through
the getSystemTimeBase method.
Some Clocks have a TimeBase other than
the system TimeBase . For example, an audio renderer that implements the Clock
interface might have a TimeBase that represents a
hardware clock.
Using a Clock
You can get the TimeBase associated with a Clock by calling the getTimeBase method. To change the
TimeBase that a Clock uses, you call the setTimeBase method.
These get and set methods can be used together to synchronize different Clocks to the
same TimeBase .
For example, an application might want to force a video renderer to sync to the TimeBase of an audio renderer. To do this,
the application would call getTimeBase on the audio renderer and then use the value returned to call setTimeBase on the video renderer.
This would ensure that the two rendering objects use the same source of time.
You can reset a Clock to use its default TimeBase by
calling setTimeBase(null) .
Some Clocks are incapable of using another TimeBase .
If this is the case, an IncompatibleTimeBaseException is thrown when setTimeBase
is called.
Clock also provides methods for getting and setting a Clock's media time and rate:
getMediaTime and setMediaTime
getRate and setRate
Starting a Clock
Until a Clock's TimeBase transformation takes effect, the Clock is
in the Stopped state. Once all three transformation parameters (media start-time,
time-base start-time, and rate) have been provided
to the Clock , it enters the Started state.
To start a Clock , syncStart is called with
the time-base start-time as an argument.
The new media start-time is taken as the current
media time, and the current rate defines the Clock's rate parameter.
When syncStart is called, the Clock and its TimeBase are
locked in sync and the Clock is considered to be in the Started state.
When a Clock is stopped and then restarted (using syncStart ),
the media start-time
for the restarted Clock is the current media time.
The syncStart method is often used to synchronize
two Clocks that share the same TimeBase .
When the time-base start-time and rate of each clock are set to the same values and
each Clock is set with the appropriate media start-time,
the two Clocks will run in sync.
When syncStart is called with a
new time-base start-time,
the synchronization with the media time doesn't occur
until the TimeBase
reaches the time-base start-time.
The getMediaTime method returns
the untransformed media time until the TimeBase
reaches the time-base start-time.
The getSyncTime method behaves slightly differently.
Once syncStart is invoked, getSyncTime
always reports the transformed time-base time,
whether or not the time-base start-time has been reached.
You can use getSyncTime to determine how much time remains
before the time-base start-time is reached.
When the time-base start-time is reached,
both
getMediaTime and getSyncTime
return the same value.
Objects that implement
the Clock interface can provide more convenient start
methods than syncStart .
For example, Player defines start ,
which should be used instead of syncStart
to start a Player .
Stopping a Clock
A Stopped Clock is no longer synchronized to
its TimeBase . When a Clock is Stopped,
its media time no longer moves in rate-adjusted synchronization with
the time-base time provided by its TimeBase .
There are two ways to explicitly stop a Clock : you can invoke
stop or set a media stop-time.
When stop is invoked, synchronization with the
TimeBase immediately stops.
When a media stop-time is set,
synchronization stops when the media stop-time passes.
A Clock's rate affects how its media stop-time
is interpreted.
If its rate is positive, the Clock
stops when the media time becomes
greater than or equal to the stop time.
If its rate is negative, the Clock stops
when the media time becomes
less than or equal to the stop time.
If the stop-time is set to a value that the Clock
has already passed, the Clock immediately stops.
Once a stop-time is set, it remains in effect until it is changed
or cleared.
To clear a stop-time, call setStopTime
with Clock.RESET .
A Clock's stop-time is cleared automatically when it stops.
If no stop-time is ever set or if the stop-time is cleared,
the only way to stop the Clock is
to call the stop method.
Clock State
Conceptually, a Clock is
always in one of two states: Started or Stopped.
A Clock enters the Started state after
syncStart has been called and the Clock
is mapped to its TimeBase .
A Clock returns to the Stopped state immediately
when the stop method is called or the
media time passes the stop time.
Certain methods can only be invoked when the Clock is in a
particular state.
If the Clock is in the wrong state when one of these methods
is called, an error or exception is thrown.
Methods Restricted to Started Clocks
The mapToTimeBase method can only be called on a
Clock in the Started state.
If it is invoked on a Stopped Clock ,
a ClockStoppedException is thrown.
This is because the Clock is not synchronized to
a TimeBase when it is Stopped.
Methods Restricted to Stopped Clocks
The following methods can only be called on a
Clock in the Stopped state.
If invoked on a Started
Clock , these methods throw a ClockStartedError .
-
syncStart
-
setTimeBase
-
setMediaTime
-
setRate
Resetting the rate, the media time, the time base, or the
time-base start-time implies a complete remapping
between the Clock and its
TimeBase and is not allowed on
a Started Clock .
Methods with Additional Restrictions
A race condition occurs if a new media stop-time is set
when a Clock is already approaching a previously
set media stop-time.
In this situation, it impossible to guarantee when the Clock
will stop. To prevent this race condition, setStopTime can
only be set once on a Started Clock .
A StopTimeSetError is thrown if setStopTime
is called and the media stop-time has already been set.
There are no restrictions on calling setStopTime on a
Stopped Clock ; the stop time can always be
reset if the Clock is Stopped. |