📄 jmfapp-controller.html
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta name="GENERATOR" content="Quadralay WebWorks Publisher 5.0.2">
<meta name="TEMPLATEBASE" content="Portable HTML">
<meta name="LASTUPDATED" content="11/23/99 11:48:16">
<title>Sample Controller Implementation </title>
</head>
<body link="#3366CC" vlink="#9999CC" text="#000000" alink="#0000CC" bgcolor="#FFFFFF"
background="images/backgrnd.gif">
<table width="100%" border="0" align="left" cellpadding="0" cellspacing="0">
<tr>
<td><a href="JMFTOC.html">CONTENTS</a> |
<a href="JMFApp-DataSource.html">PREV </a> |
<a href="JMFApp-RTPUtil.html">NEXT</a> |
<a href="JMFIX.html">INDEX</a></td>
<td align="right"><em>JMF 2.0 API Guide</em>
</tr>
</table>
<p><br clear="all">
</p>
<hr align="left">
<blockquote>
<div align="right">
<a name="46909"> </a><font size="3" face="Palatino, Times New Roman, Times, serif">E <br></font>
</div>
<div align="right">
<h2>
<a name="90340"> </a><font color="#003366" face="Palatino, Times New Roman, Times, serif">Sample Controller Implementation</font>
</h2>
</div>
<p>
<a name="81754"> </a><font face="Palatino, Times New Roman, Times, serif">This sample illustrates how a simple time-line <code>Controller</code> can be implemented in JMF. This sample is provided as a reference for developers who are implementing their own <code>Controllers</code>. Please note that it has not been tested or optimized for production use.</font>
</p>
<p>
<a name="88580"> </a><font face="Palatino, Times New Roman, Times, serif">This sample consists of four classes:</font>
</p>
<ul>
<li><a name="81760"> </a><font face="Palatino, Times New Roman, Times, serif"><code>TimeLineController.java</code></font>
</ul>
<dl>
<dt> <a name="81761"> </a><font face="Palatino, Times New Roman, Times, serif">The <code>Controller</code>. You give it an array of time values (representing a time line) and it keeps track of which segment in the time line you are in.</font>
</dl>
<ul>
<li><a name="81764"> </a><font face="Palatino, Times New Roman, Times, serif"><code>TimeLineEvent.java</code></font>
</ul>
<dl>
<dt> <a name="81765"> </a><font face="Palatino, Times New Roman, Times, serif">An event posted by the <code>TimeLineController</code> when the segment in the time line changes.</font>
</dl>
<ul>
<li><a name="81767"> </a><font face="Palatino, Times New Roman, Times, serif"><code>EventPostingBase.java</code></font>
</ul>
<dl>
<dt> <a name="88556"> </a><font face="Palatino, Times New Roman, Times, serif">A base class used by <code>TimeLineController</code> that handles the <code>Controller</code> methods <code>addControllerListener</code> and <code>removeControllerListener</code>. It also provides a <code>postEvent</code> method that can be used by the subclass to post events.</font>
</dl>
<ul>
<li><a name="88559"> </a><font face="Palatino, Times New Roman, Times, serif"><code>ListenerList.java</code></font>
</ul>
<dl>
<dt> <a name="88562"> </a><font face="Palatino, Times New Roman, Times, serif">A class used to maintain a list of <code>ControllerListener</code> objects that the <code>TimeLineController</code> needs to post events to.</font>
</dl>
<p>
<a name="88557"> </a><font face="Palatino, Times New Roman, Times, serif">This implementation also uses two additional classes whose implementations are not shown here.</font>
</p>
<ul>
<li><a name="81776"> </a><font face="Palatino, Times New Roman, Times, serif"><code>EventPoster</code> </font>
</ul>
<dl>
<dt> <a name="82369"> </a><font face="Palatino, Times New Roman, Times, serif">A class that spins a thread to post events to a <code>ControllerListener</code>.</font>
</dl>
<ul>
<li><a name="81779"> </a><font face="Palatino, Times New Roman, Times, serif"><code>BasicClock</code></font>
</ul>
<dl>
<dt> <a name="90589"> </a><font face="Palatino, Times New Roman, Times, serif">A simple <code>Clock</code> implementation that implements all of the <code>Clock</code> methods.</font>
</dl>
<h4>
<a name="91715"> </a><font color="#003366" face="Palatino, Times New Roman, Times, serif">TimeLineController</font>
</h4>
<a name="90590"> </a><font size="1" face="Palatino, Times New Roman, Times, serif">
<table border="1" bordercolorlight="#FFFFFF" bordercolordark="#000000"
cellpadding="5" cellspacing="0">
<caption><b><i><font face="Palatino, Times New Roman, Times, serif"><a name="90596"> </a>Example E-1: TimeLineController.java (1 of 11)</font></i></b></caption>
<tr>
<td><font face="Palatino, Times New Roman, Times, serif"><pre>
<a name="90623"> </a><code>import javax.media.*;
</code><a name="90624"> </a><code>import com.sun.media.MediaClock;
</code><a name="90625"> </a><code>
</code><a name="90626"> </a><code>// This Controller uses two custom classes:
</code><a name="90627"> </a><code>// The base class is EventPostingBase. It has three methods:
</code><a name="90628"> </a><code>// public void addControllerListener (ControllerListener
</code><a name="90629"> </a><code>// observer);
</code><a name="90630"> </a><code>// public void removeControllerListener (ControllerListener
</code><a name="90631"> </a><code>// observer);
</code><a name="90632"> </a><code>// protected void postEvent (ControllerEvent event);
</code><a name="90633"> </a><code>//
</code><a name="90634"> </a><code>
</code><a name="90635"> </a><code>// This Controller posts TimeLineEvents. TimeLineEvent has
</code><a name="90636"> </a><code>// two methods:
</code><a name="90637"> </a><code>// public TimeLineEvent (Controller who, int
</code><a name="90638"> </a><code>// segmentEntered);
</code><a name="90639"> </a><code>// public final int getSegment ();
</code><a name="90640"> </a><code>
</code><a name="90641"> </a><code>public class TimeLineController extends EventPostingBase
</code><a name="90642"> </a><code> implements Controller, Runnable
</code><a name="90643"> </a><code>{
</code><a name="90644"> </a><code> Clock ourClock;
</code><a name="90645"> </a><code>
</code><a name="90646"> </a><code> // This simple controller really only has two states:
</code><a name="90647"> </a><code> // Prefetched and Started.
</code><a name="90648"> </a><code>
</code><a name="90649"> </a><code> int ourState;
</code><a name="90650"> </a><code> long timeLine[];
</code><a name="90651"> </a><code> int currentSegment = -1;
</code><a name="90652"> </a><code> long duration;
</code><a name="90653"> </a><code> Thread myThread;
</code><a name="90654"> </a><code>
</code><a name="90655"> </a><code> // Create a TimeLineController giving it a sorted time line.
</code><a name="90656"> </a><code> // The TimeLineController will post events indicating when
</code><a name="90669"> </a><code> // it has passed to different parts of the time line.
</code><a name="90670"> </a><code>
</code><a name="90671"> </a><code> public TimeLineController (long timeLine[])
</code><a name="90672"> </a><code> {
</code><a name="90673"> </a><code> this.timeLine = timeLine;
</code><a name="90674"> </a><code> ourClock = new MediaClock ();
</code></pre>
</font></td>
</tr>
<tr>
<td><font face="Palatino, Times New Roman, Times, serif"><pre>
<a name="91752"> </a><code> duration = timeLine[timeLine.length-1];
</code><a name="91753"> </a><code> myThread = null;
</code><a name="90698"> </a><code> // We always start off ready to go!
</code><a name="90699"> </a><code> ourState = Controller.Prefetched;
</code><a name="90705"> </a><code> }
</code><a name="90706"> </a><code>
</code><a name="90707"> </a><code> // Binary search for which segment we are now in. Segment
</code><a name="90708"> </a><code> // 0 is considered to start at 0 and end at timeLine[0].
</code><a name="90709"> </a><code> // Segment timeLine.length is considered to start at
</code><a name="90710"> </a><code> // timeLine[timeLine.length-1] and end at infinity. At the
</code><a name="90711"> </a><code> // points of 0 and timeLine[timeLine.length-1] the
</code><a name="90712"> </a><code> // Controller will stop (and post an EndOfMedia event).
</code><a name="90713"> </a><code>
</code><a name="90714"> </a><code> int computeSegment (long time)
</code><a name="90715"> </a><code> {
</code><a name="90716"> </a><code> int max = timeLine.length;
</code><a name="90717"> </a><code> int min = 0;
</code><a name="90718"> </a><code>
</code><a name="90719"> </a><code> for (;;)
</code><a name="90720"> </a><code> {
</code><a name="90721"> </a><code> if (min == max) return min;
</code><a name="90722"> </a><code> int current = min + ((max - min) >> 1);
</code><a name="90723"> </a><code>
</code><a name="90724"> </a><code> if (time < timeLine[current])
</code><a name="90725"> </a><code> {
</code><a name="90726"> </a><code> max = current;
</code><a name="90727"> </a><code> }
</code><a name="90728"> </a><code>
</code><a name="90729"> </a><code> else
</code><a name="90730"> </a><code> {
</code><a name="90731"> </a><code> min = current + 1;
</code><a name="90732"> </a><code> }
</code><a name="90733"> </a><code> }
</code><a name="90734"> </a><code> }
</code><a name="90768"> </a><code> // These are all simple...
</code><a name="90769"> </a><code>
</code><a name="90770"> </a><code> public float setRate (float factor)
</code><a name="90771"> </a><code> {
</code><a name="90772"> </a><code> // We don't support a rate of 0.0. Not worth the extra math
</code><a name="90773"> </a><code> // to handle something the user should do with the stop()
</code><a name="90774"> </a><code> // method!
</code><a name="90775"> </a><code>
</code><a name="90776"> </a><code> if (factor == 0.0f)
</code><a name="90777"> </a><code> {
</code><a name="90778"> </a><code> factor = 1.0f;
</code><a name="90784"> </a><code> }
</code><a name="90785"> </a><code>
</code><a name="90786"> </a><code> float newRate = ourClock.setRate (factor);
</code></pre>
</font></td>
</tr>
<tr>
<td><font face="Palatino, Times New Roman, Times, serif"><pre>
<a name="91768"> </a><code> postEvent (new RateChangeEvent (this, newRate));
</code><a name="90800"> </a><code> return newRate;
</code><a name="90801"> </a><code> }
</code><a name="90807"> </a><code>
</code><a name="90808"> </a><code> public void setTimeBase (TimeBase master)
</code><a name="90809"> </a><code> throws IncompatibleTimeBaseException
</code><a name="90810"> </a><code> {
</code><a name="90811"> </a><code> ourClock.setTimeBase (master);
</code><a name="90812"> </a><code> }
</code><a name="90813"> </a><code>
</code><a name="90814"> </a><code> public Time getStopTime ()
</code><a name="90815"> </a><code> {
</code><a name="90816"> </a><code> return ourClock.getStopTime ();
</code><a name="90817"> </a><code> }
</code><a name="90818"> </a><code>
</code><a name="90819"> </a><code> public Time getSyncTime ()
</code><a name="90820"> </a><code> {
</code><a name="90821"> </a><code> return ourClock.getSyncTime ();
</code><a name="90822"> </a><code> }
</code><a name="90823"> </a><code>
</code><a name="90824"> </a><code> public Time mapToTimeBase (Time t) throws ClockStoppedException
</code><a name="90825"> </a><code> {
</code><a name="90826"> </a><code> return ourClock.mapToTimeBase (t);
</code><a name="90827"> </a><code> }
</code><a name="90828"> </a><code>
</code><a name="90829"> </a><code> public Time getMediaTime ()
</code><a name="90830"> </a><code> {
</code><a name="90831"> </a><code> return ourClock.getMediaTime ();
</code><a name="90832"> </a><code> }
</code><a name="90833"> </a><code>
</code><a name="90834"> </a><code> public TimeBase getTimeBase ()
</code><a name="90835"> </a><code> {
</code><a name="90836"> </a><code> return ourClock.getTimeBase ();
</code><a name="90837"> </a><code> }
</code><a name="90838"> </a><code> public float getRate ()
</code><a name="90839"> </a><code> {
</code><a name="90840"> </a><code> return ourClock.getRate ();
</code><a name="90841"> </a><code> }
</code><a name="90842"> </a><code>
</code><a name="90843"> </a><code> // From Controller
</code><a name="90844"> </a><code>
</code><a name="90845"> </a><code> public int getState ()
</code><a name="90846"> </a><code> {
</code><a name="90847"> </a><code> return ourState;
</code><a name="90848"> </a><code> }
</code></pre>
</font></td>
</tr>
<tr>
<td><font face="Palatino, Times New Roman, Times, serif"><pre>
<a name="90877"> </a><code> public int getTargetState ()
</code><a name="90878"> </a><code> {
</code><a name="90879"> </a><code> return ourState;
</code><a name="90880"> </a><code> }
</code><a name="90886"> </a><code>
</code><a name="90887"> </a><code> public void realize ()
</code><a name="90888"> </a><code> {
</code><a name="90889"> </a><code> postEvent (new RealizeCompleteEvent (this, ourState,
</code><a name="90890"> </a><code> ourState, ourState));
</code><a name="90891"> </a><code> }
</code><a name="90892"> </a><code>
</code><a name="90893"> </a><code> public void prefetch ()
</code><a name="90894"> </a><code> {
</code><a name="90895"> </a><code> postEvent (new PrefetchCompleteEvent (this, ourState,
</code><a name="90896"> </a><code> ourState, ourState));
</code><a name="90897"> </a><code> }
</code><a name="90898"> </a><code>
</code><a name="90899"> </a><code> public void deallocate ()
</code><a name="90900"> </a><code> {
</code><a name="90901"> </a><code> postEvent (new DeallocateEvent (this, ourState,
</code><a name="90902"> </a><code> ourState, ourState, ourClock.getMediaTime ()));
</code><a name="90903"> </a><code> }
</code><a name="90904"> </a><code>
</code><a name="90905"> </a><code> public Time getStartLatency ()
</code><a name="90906"> </a><code> {
</code><a name="90907"> </a><code> // We can start immediately, of course!
</code><a name="90908"> </a><code>
</code><a name="90909"> </a><code> return new Time(0);
</code><a name="90910"> </a><code> }
</code><a name="90911"> </a><code>
</code><a name="90912"> </a><code> public Control[] getControls ()
</code><a name="90913"> </a><code> {
</code><a name="90914"> </a><code> return new Control[0];
</code><a name="90915"> </a><code> }
</code><a name="90916"> </a><code> public Time getDuration ()
</code><a name="90917"> </a><code> {
</code><a name="90918"> </a><code> return new Time(duration);
</code><a name="90919"> </a><code> }
</code><a name="90920"> </a><code>
</code><a name="90921"> </a><code> // This one takes a little work as we need to compute if we
</code><a name="90922"> </a><code> // changed segments.
</code><a name="90923"> </a><code>
</code><a name="90924"> </a><code> public void setMediaTime (Time now)
</code><a name="90925"> </a><code> {
</code><a name="90926"> </a><code> ourClock.setMediaTime (now);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -