001: /*
002: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
004: *
005: * This program is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU General Public License version
007: * 2 only, as published by the Free Software Foundation.
008: *
009: * This program is distributed in the hope that it will be useful, but
010: * WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * General Public License version 2 for more details (a copy is
013: * included at /legal/license.txt).
014: *
015: * You should have received a copy of the GNU General Public License
016: * version 2 along with this work; if not, write to the Free Software
017: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
018: * 02110-1301 USA
019: *
020: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
021: * Clara, CA 95054 or visit www.sun.com if you need additional
022: * information or have any questions.
023: */
024: package com.sun.mmedia;
025:
026: import javax.microedition.media.*;
027: import javax.microedition.media.control.*;
028: import com.sun.mmedia.BasicPlayer;
029: import com.sun.mmedia.rtsp.*;
030:
031: /**
032: * Description of the Class
033: *
034: * @created September 11, 2002
035: */
036: public class RTSPPlayer extends com.sun.mmedia.BasicPlayer {
037: private boolean started; // default is FALSE
038: private RtspManager rtspManager; // default is NULL
039: private Player players[]; // default is NULL
040: private int numberOfTracks; // default is 0
041:
042: // media time in milli-seconds
043: private long mediaTime; // default is 0
044:
045: // start time in milli-seconds
046: private long startTime; // default is 0
047:
048: // stop time in milli-seconds
049: private long stopTime; // default is 0
050:
051: private RtspCtrl rtspControl; // default is NULL
052: private boolean setup_ok; // default is FALSE
053: private boolean data_received; // default is FALSE
054:
055: private final boolean RTSP_DEBUG = false;
056:
057: public RTSPPlayer() {
058: rtspControl = new RtspCtrl(this );
059: }
060:
061: /**
062: * Realizes the RTSP Player.
063: *
064: * @see Player#realize()
065: * @exception MediaException Thrown if the <code>Player</code> cannot
066: * be realized.
067: */
068: protected final void doRealize() throws MediaException {
069: if (RTSP_DEBUG)
070: System.err.println("[RTSPPlayer] doRealize");
071:
072: rtspControl.setStatus("Negotiating");
073:
074: String locator = source.getLocator();
075:
076: rtspManager = new RtspManager(locator);
077:
078: setup_ok = rtspManager.createConnection();
079:
080: if (setup_ok) {
081: // setup the RTSP session
082: setup_ok = rtspManager.rtspSetup();
083:
084: if (setup_ok) {
085: numberOfTracks = rtspManager.getNumberOfTracks();
086:
087: int server_ports[] = rtspManager.getServerPorts();
088: int client_ports[] = rtspManager.getClientPorts();
089:
090: players = new Player[numberOfTracks];
091:
092: // start the RTSP server until the internal RTP players
093: // can be realized.
094: rtspManager.setStartPos(0);
095: boolean started = rtspManager.rtspStart();
096:
097: if (!started) {
098: throw new MediaException("cannot start RTSP server");
099: }
100:
101: for (int i = 0; i < numberOfTracks; i++) {
102: // setup the RTP players
103: String url = "rtp://"
104: + rtspManager.getServerAddress() + ":"
105: + client_ports[i];
106:
107: try {
108: players[i] = Manager.createPlayer(url);
109: } catch (Exception e) {
110: throw new MediaException(e.getMessage());
111: }
112:
113: players[i].realize();
114: }
115:
116: // stop the RTSP server
117: rtspManager.rtspStop();
118: } else {
119: rtspControl.setStatus(rtspManager.getProcessError());
120: }
121: } else {
122: rtspControl.setStatus("Server not found ["
123: + rtspManager.getServerAddress() + "]");
124: }
125:
126: if (RTSP_DEBUG)
127: System.err.println("[RTSPPlayer] doRealize done");
128: }
129:
130: /**
131: * Prefetching (not implemented).
132: *
133: * This may be an option for a future implementation. By
134: * prefetching, the startup-time as experienced by the user
135: * could be minimized. For VOD a positive side effect would
136: * be that the first frame of the video would be visible.
137: * Right now this is not guaranteed since the player may
138: * need the first frame for initialization purposes.
139: *
140: * @exception MediaException Description of the Exception
141: */
142: protected final void doPrefetch() throws MediaException {
143: // rtspControl.setStatus( "Buffering...");
144: }
145:
146: /**
147: * Retrieves the duration of the media presentation.
148: *
149: * The duration is communicated via the SDP protocol
150: * as part of the DESCRIBE response message and stored
151: * in RtspManager.
152: *
153: * @return Duration in micro-seconds
154: */
155: public final long doGetDuration() {
156: return rtspManager.getDuration();
157: }
158:
159: /**
160: * Starts the RTSP Player
161: *
162: * @return true, if the RTSP Player was started successfully, false otherwise.
163: */
164: protected final boolean doStart() {
165: rtspControl.setStatus("Sun RTSP Streaming");
166:
167: if (setup_ok && !started) {
168: // start the RTSP session
169: rtspManager.setStartPos(mediaTime * 1000);
170: started = rtspManager.rtspStart();
171:
172: if (!started) {
173: rtspControl.setStatus(rtspManager.getProcessError());
174: } else {
175: // start the RTP players
176: for (int i = 0; i < numberOfTracks; i++) {
177: try {
178: players[i].start();
179: } catch (Exception e) {
180: e.printStackTrace();
181: }
182: }
183:
184: startTime += (System.currentTimeMillis() - stopTime);
185: stopTime = 0;
186: }
187: }
188:
189: return started;
190: }
191:
192: /**
193: * Stopping the RTSP Player.
194: */
195: protected final void doStop() {
196: // stop the RTSP session
197: rtspManager.rtspStop();
198:
199: started = false;
200:
201: stopTime = System.currentTimeMillis();
202:
203: // stop the RTP players
204: for (int i = 0; i < numberOfTracks; i++) {
205: try {
206: players[i].stop();
207: } catch (Exception e) {
208: e.printStackTrace();
209: }
210: }
211:
212: }
213:
214: /**
215: * Deallocates the RTSP Player.
216: */
217: protected final void doDeallocate() {
218: if (RTSP_DEBUG)
219: System.err.println("[RTSPPlayer] doDeallocate");
220:
221: // teardown of the RTSP session
222: rtspManager.rtspTeardown();
223:
224: try {
225: // stopping and deallocating all internal RTP players
226: for (int i = 0; i < numberOfTracks; i++) {
227: players[i].stop();
228: players[i].deallocate();
229: }
230: } catch (MediaException e) {
231: if (RTSP_DEBUG)
232: System.err.println("Error closing RTP players");
233: }
234:
235: rtspManager.closeConnection();
236:
237: if (RTSP_DEBUG)
238: System.err.println("[RTSPPlayer] doDeallocate done");
239: }
240:
241: /**
242: * Closes the RTSP Player.
243: */
244: protected final void doClose() {
245: if (RTSP_DEBUG)
246: System.err.println("[RTSPPlayer] doClose");
247:
248: // closing all internal RTP players
249: for (int i = 0; i < numberOfTracks; i++) {
250: players[i].close();
251: }
252:
253: if (RTSP_DEBUG)
254: System.err.println("[RTSPPlayer] doClose done");
255: }
256:
257: /**
258: * Sets the media time of the RTSP Player.
259: *
260: * @param now the new media time.
261: * @exception MediaException thrown if setMediaTime fails.
262: * @return the new media time in microseconds.
263: */
264: protected final long doSetMediaTime(long now) throws MediaException {
265: if (started) {
266: doStop();
267: }
268:
269: mediaTime = (now / 1000);
270: startTime = System.currentTimeMillis() - mediaTime;
271:
272: doStart();
273:
274: return now;
275: }
276:
277: /**
278: * Retrieves the current media time.
279: *
280: * @return the media time in microseconds.
281: */
282: protected final long doGetMediaTime() {
283: if (started) {
284: mediaTime = System.currentTimeMillis() - startTime;
285:
286: if ((mediaTime * 1000) >= rtspManager.getDuration()) {
287: started = false;
288: sendEvent(PlayerListener.END_OF_MEDIA, new Long(
289: mediaTime * 1000));
290: }
291: }
292:
293: return mediaTime * 1000;
294: }
295:
296: /**
297: * Returns the RTSP Control object.
298: *
299: * @param type Description of the Parameter
300: * @return Description of the Return Value
301: */
302:
303: public RtspCtrl getRtspControl() {
304: return rtspControl;
305: }
306:
307: /**
308: * Description of the Method
309: *
310: * @param type Description of the Parameter
311: * @return Description of the Return Value
312: */
313: protected final Control doGetControl(String type) {
314: Control control = null;
315:
316: if (/*(getState() != UNREALIZED) && */
317: type.startsWith(BasicPlayer.pkgName)) {
318:
319: type = type.substring(BasicPlayer.pkgName.length());
320:
321: if (type.equals(BasicPlayer.vocName)) {
322: // Volume Control
323: for (int i = 0; i < numberOfTracks; i++) {
324: control = players[i].getControl(type);
325:
326: if (control != null) {
327: break;
328: }
329: }
330: } else if (type.equals(BasicPlayer.rtspName)) {
331: // RTSP Control
332: control = rtspControl;
333: } else if (type.equals(BasicPlayer.vicName)) {
334: // Video Control
335: for (int i = 0; i < numberOfTracks; i++) {
336: control = players[i].getControl(type);
337:
338: if (control != null) {
339: if (RTSP_DEBUG)
340: System.err
341: .println("[RTSPPlayer] got video control");
342: break;
343: }
344: }
345: }
346: }
347: return control;
348: }
349: }
|