Source Code Cross Referenced for ABBBasicPlayer.java in  » 6.0-JDK-Modules » j2me » com » sun » mmedia » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » j2me » com.sun.mmedia 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved.
0003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0004:         * 
0005:         * This program is free software; you can redistribute it and/or
0006:         * modify it under the terms of the GNU General Public License version
0007:         * 2 only, as published by the Free Software Foundation.
0008:         * 
0009:         * This program is distributed in the hope that it will be useful, but
0010:         * WITHOUT ANY WARRANTY; without even the implied warranty of
0011:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0012:         * General Public License version 2 for more details (a copy is
0013:         * included at /legal/license.txt).
0014:         * 
0015:         * You should have received a copy of the GNU General Public License
0016:         * version 2 along with this work; if not, write to the Free Software
0017:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0018:         * 02110-1301 USA
0019:         * 
0020:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0021:         * Clara, CA 95054 or visit www.sun.com if you need additional
0022:         * information or have any questions.
0023:         */
0024:        package com.sun.mmedia;
0025:
0026:        import java.util.Vector;
0027:        import java.util.Enumeration;
0028:        import java.util.Hashtable;
0029:
0030:        import java.io.*;
0031:
0032:        import javax.microedition.media.*;
0033:        import javax.microedition.media.control.*;
0034:
0035:        //import com.sun.mmedia.PermissionAccessor;
0036:
0037:        /**
0038:         * BasicPlayer provides basic implementation for the Player methods.
0039:         * Many of the methods call do<method> to do the actual work that can
0040:         * be overridden by subclasses.
0041:         *
0042:         * @created    January 13, 2005
0043:         */
0044:        public abstract class ABBBasicPlayer implements  Player {
0045:
0046:            /**
0047:             * global player id
0048:             */
0049:            private static int pcount = -1;
0050:
0051:            /**
0052:             * lock object
0053:             */
0054:            private static Object idLock = new Object();
0055:
0056:            /**
0057:             * the state of this player
0058:             */
0059:            public int state = UNREALIZED;
0060:
0061:            /**
0062:             * the loopCount of this player
0063:             */
0064:            int loopCountSet = 1, loopCount;
0065:
0066:            /**
0067:             * the flag to indicate whether the Player is currently paused at EOM.
0068:             * If true, the Player will seek back to the beginning when
0069:             * restarted.
0070:             */
0071:            boolean EOM = false;
0072:
0073:            /**
0074:             * the flag to indicate looping after EOM.
0075:             */
0076:            boolean loopAfterEOM = false;
0077:
0078:            /**
0079:             * this player's playerlisteners
0080:             */
0081:            Vector listeners = new Vector(2);
0082:
0083:            /**
0084:             * flag shows that "listeners" have been modified while 
0085:             * player is executing callbacks from "listeners".
0086:             */
0087:            boolean listenersModified = false;
0088:
0089:            /**
0090:             * Asynchronous event mechanism.
0091:             */
0092:            PlayerEventQueue eventQueue = null;
0093:
0094:            /**
0095:             * event queue lock obj
0096:             */
0097:            Object evtLock = new Object();
0098:
0099:            /**
0100:             * player ID of this player
0101:             */
0102:            protected int pID = 0;
0103:
0104:            /**
0105:             * hastable to map playerID to instances
0106:             */
0107:            private static Hashtable mplayers = new Hashtable(4);
0108:
0109:            /**
0110:             * table of player states
0111:             */
0112:            private static Hashtable pstates = new Hashtable();
0113:
0114:            /**
0115:             * table of media times
0116:             */
0117:            private static Hashtable mtimes = new Hashtable();
0118:
0119:            /**
0120:             * Control package name
0121:             */
0122:            protected final static String pkgName = "javax.microedition.media.control.";
0123:
0124:            /**
0125:             * Centralized control management with string constants for each
0126:             * implemented Control.
0127:             * <p>
0128:             * For adding a new control interfaces, follow the following steps:
0129:             * <ol>
0130:             *  <li>Add new control name here. If it is not in the package
0131:             *     javax.microedition.media.control, then the full package
0132:             *     name of the control must be used.
0133:             *  <li>Add the control's name field to the allCtrls array (see below)
0134:             * </ol>
0135:             * <p>
0136:             * Size note: it would be space saving to declare the array allCtrls
0137:             * with the strings directly and not define the strings constants here.
0138:             * However, it is more convenient for descendants to use
0139:             * these constants, instead of e.g.
0140:             * <code>&nbsp;&nbsp;&nbsp;allCtrls[4]; // RateControl</code>
0141:             *
0142:             * @see    #getControls()
0143:             * @see    #doGetControl(String)
0144:             * @see    #allCtrls
0145:             */
0146:
0147:            /**
0148:             *  Description of the Field
0149:             */
0150:            protected final static String fpcName = "FramePositioningControl";
0151:            /**
0152:             *  Description of the Field
0153:             */
0154:            protected final static String guiName = "GUIControl";
0155:            /**
0156:             *  Description of the Field
0157:             */
0158:            protected final static String mdcName = "MetaDataControl";
0159:            /**
0160:             *  Description of the Field
0161:             */
0162:            protected final static String micName = "MIDIControl";
0163:            /**
0164:             *  Description of the Field
0165:             */
0166:            protected final static String picName = "PitchControl";
0167:            /**
0168:             *  Description of the Field
0169:             */
0170:            protected final static String racName = "RateControl";
0171:            /**
0172:             *  Description of the Field
0173:             */
0174:            protected final static String recName = "RecordControl";
0175:            /**
0176:             *  Description of the Field
0177:             */
0178:            protected final static String stcName = "StopTimeControl";
0179:            /**
0180:             *  Description of the Field
0181:             */
0182:            protected final static String tecName = "TempoControl";
0183:            /**
0184:             *  Description of the Field
0185:             */
0186:            protected final static String tocName = "ToneControl";
0187:            /**
0188:             *  Description of the Field
0189:             */
0190:            protected final static String vicName = "VideoControl";
0191:            /**
0192:             *  Description of the Field
0193:             */
0194:            protected final static String vocName = "VolumeControl";
0195:            /**
0196:             *  This one is not among public JSR135 controls, 
0197:             *  seems that this is used only for RTSP PLayer.
0198:             *  But its participation in "search-by-name" slows down 
0199:             *  all players that use this array for "getControls()".
0200:             */
0201:            protected final static String rtspName = "RtspControl";
0202:
0203:            /**
0204:             * An array containing all available controls in Players
0205:             * extending BasicPlayer.
0206:             * A player can overwrite this array in order to change the list.
0207:             */
0208:            private static final String[] allCtrls = { fpcName, /*FramePositioningControl*/
0209:            guiName, /*GUIControl*/
0210:            mdcName, /*MetaDataControl*/
0211:            micName, /*MIDIControl*/
0212:            picName, /*PitchControl*/
0213:            racName, /*RateControl*/
0214:            recName, /*RecordControl*/
0215:            stcName, /*StopTimeControl*/
0216:            tecName, /*TempoControl*/
0217:            tocName, /*ToneControl*/
0218:            vicName, /*VideoControl*/
0219:            vocName, /*VolumeControl*/
0220:            rtspName, /*(non-standard) RtspControl*/
0221:            };
0222:
0223:            /**
0224:             * An array containing all needed permissions in Players
0225:             * extending BasicPlayer.
0226:             * A player can overwrite this array in order to change the list.
0227:             *
0228:             * By default it is empty.
0229:             */
0230:            private static final int[] allPermissions = {};
0231:
0232:            /**
0233:             * is set by checkPermissions() to bypass further checks
0234:             */
0235:            private boolean isTrusted;
0236:
0237:            /**
0238:             * array of controls for a given player
0239:             */
0240:            private String control_names[];
0241:
0242:            /**
0243:             * array of permissions for a given player
0244:             */
0245:            private int permissions[];
0246:
0247:            /**
0248:             * the default size of the event queue
0249:             * can be overridden by descendants
0250:             */
0251:            int eventQueueSize = 20;
0252:
0253:            /**
0254:             * flag to prevent delivering events after the CLOSED event
0255:             */
0256:            private boolean closedDelivered;
0257:
0258:            /**
0259:             * listener for media events while the midlet is in paused state.
0260:             */
0261:            private static MIDletPauseListener pauseListener = null;
0262:            private static boolean vmPaused = false;
0263:
0264:            /* Source data for player */
0265:            InputStream source;
0266:
0267:            /**
0268:             * Sets the listener for media activity notifications.
0269:             *
0270:             * This interface can only be set once and shall only be used
0271:             * by MIDletState.
0272:             */
0273:            public static void setMIDletPauseListener(
0274:                    MIDletPauseListener listener) {
0275:                //System.out.println("DEBUG: about to BP.setMIDletPauseListener(" + listener + ")");
0276:                // Only set the listener once!
0277:                // If the listener is aleady set then return witout waring.
0278:                if (pauseListener == null) {
0279:                    pauseListener = listener;
0280:                }
0281:            }
0282:
0283:            /**
0284:             * Informs the BasicPlayer that the VM has been paused if
0285:             * paused is set to true - or resumed if paused is set to false
0286:             */
0287:            public static void pauseStateEntered(MIDletPauseListener listener,
0288:                    boolean paused) {
0289:                //System.out.println("DEBUG: about to BP.pauseStateEntered(" + listener + "," + paused + ")");
0290:                // if the listeners don't match then simply return
0291:                if (listener != pauseListener)
0292:                    return;
0293:
0294:                vmPaused = paused;
0295:
0296:                if (vmPaused) {
0297:                    for (Enumeration e = mplayers.elements(); e
0298:                            .hasMoreElements();) {
0299:                        ABBBasicPlayer p = (ABBBasicPlayer) e.nextElement();
0300:
0301:                        if (p.getState() == STARTED) {
0302:                            notifyPauseListener("Player");
0303:                        }
0304:                    }
0305:                    /*pauseAll();
0306:                    } else {
0307:                    resumeAll();*/
0308:                }
0309:            }
0310:
0311:            public static void notifyPauseListener(String msg) {
0312:                if (vmPaused && pauseListener != null) {
0313:                    pauseListener.reportActivity(msg);
0314:                }
0315:            }
0316:
0317:            /**
0318:             *Constructor for the ABBBasicPlayer object
0319:             */
0320:            public ABBBasicPlayer() {
0321:                init();
0322:                control_names = allCtrls;
0323:                permissions = allPermissions;
0324:            }
0325:
0326:            protected ABBBasicPlayer(String[] n, int[] p) {
0327:                init();
0328:                control_names = (n == null) ? allCtrls : n;
0329:                permissions = (p == null) ? allPermissions : p;
0330:            }
0331:
0332:            private void init() {
0333:
0334:                synchronized (idLock) {
0335:                    pcount = (pcount + 1) % 32767;
0336:                    pID = pcount;
0337:                }
0338:                mplayers.put(new Integer(pID), this );
0339:            }
0340:
0341:            /**
0342:             * Initializes Player by Media Encodings obtained from URI and parsed.
0343:             * To be called by Manager when new player (from URI) is being created.
0344:             *
0345:             * @param encodings media encodings in form "key=value", separated by '&'.
0346:             *
0347:             * @returns true if initialization was successful, false otherwise
0348:             */
0349:            public boolean initFromURL(String encodings) {
0350:                return true;
0351:            }
0352:
0353:            /**
0354:             * Checks if user application has all permissions needed to access player
0355:             */
0356:            protected final void checkPermissions() throws SecurityException {
0357:                /*
0358:                 if (isTrusted) return;
0359:                 //TBD: check locator-specific permissions ?
0360:                 for (int i = 0; i < permissions.length; ++i)
0361:                 PermissionAccessor.checkPermissions(permissions[i]);
0362:                 isTrusted = true;
0363:                 */
0364:            }
0365:
0366:            /**
0367:             * Check to see if the Player is closed.  If the
0368:             * unrealized boolean flag is true, check also to
0369:             * see if the Player is UNREALIZED.
0370:             *
0371:             * @param  unrealized  Description of the Parameter
0372:             */
0373:            protected final void chkClosed(boolean unrealized) {
0374:                /*
0375:                 * This method is indended to be called from synchronized methods
0376:                 * (that change player's state), but in fact 
0377:                 * it is invoked from unsynchronized methods too, 
0378:                 * so, as a temporary solution,  
0379:                 * it shall eliminate access to player's state: 
0380:                 * it must get the state only once and then work with a local variable.
0381:                 */
0382:                int theState = this .state;
0383:                if (theState == CLOSED
0384:                        || (unrealized && theState == UNREALIZED)) {
0385:                    throw new IllegalStateException(
0386:                            "Can't invoke the method at the "
0387:                                    + (theState == CLOSED ? "closed"
0388:                                            : "unrealized") + " state ");
0389:                }
0390:            }
0391:
0392:            // JAVADOC COMMENT ELIDED
0393:            public synchronized void setLoopCount(int count) {
0394:                //System.out.println("DEBUG: about to BP.setLoopCount(" + count + ") for player=" + this);
0395:                chkClosed(false);
0396:
0397:                if (state == STARTED) {
0398:                    throw new IllegalStateException("setLoopCount");
0399:                }
0400:
0401:                if (count == 0 || count < -1) {
0402:                    throw new IllegalArgumentException("setLoopCount");
0403:                }
0404:
0405:                loopCountSet = count;
0406:                loopCount = count;
0407:
0408:                doSetLoopCount(count);
0409:            }
0410:
0411:            /**
0412:             *  Description of the Method
0413:             *
0414:             * @param  count  Description of the Parameter
0415:             */
0416:            protected void doSetLoopCount(int count) {
0417:            }
0418:
0419:            public static final int AUDIO_NONE = 0;
0420:            public static final int AUDIO_PCM = 1;
0421:            public static final int AUDIO_MIDI = 2;
0422:
0423:            public int getAudioType() {
0424:                return AUDIO_NONE;
0425:            }
0426:
0427:            public void setOutput(Object output) {
0428:            }
0429:
0430:            public Object getOutput() {
0431:                return null;
0432:            }
0433:
0434:            public void setSource(InputStream source) throws IOException,
0435:                    MediaException {
0436:                this .source = source;
0437:            }
0438:
0439:            // JAVADOC COMMENT ELIDED
0440:            public synchronized void realize() throws MediaException {
0441:                //System.out.println("DEBUG: about to BP.realize() for player=" + this);
0442:                chkClosed(false);
0443:
0444:                if (state >= REALIZED) {
0445:                    return;
0446:                }
0447:
0448:                doRealize();
0449:
0450:                state = REALIZED;
0451:            }
0452:
0453:            /**
0454:             * Subclasses need to implement this to realize
0455:             * the <code>Player</code>.
0456:             *
0457:             * @exception  MediaException  Description of the Exception
0458:             */
0459:            protected abstract void doRealize() throws MediaException;
0460:
0461:            // JAVADOC COMMENT ELIDED
0462:            public synchronized void prefetch() throws MediaException {
0463:                //System.out.println("DEBUG: about to BP.prefetch() for player=" + this);
0464:                chkClosed(false);
0465:
0466:                if (state >= PREFETCHED) {
0467:                    return;
0468:                }
0469:
0470:                if (state < REALIZED) {
0471:                    realize();
0472:                } else {
0473:                    //if realize has been called the permission will be checked from there
0474:                    checkPermissions();
0475:                }
0476:
0477:                doPrefetch();
0478:
0479:                state = PREFETCHED;
0480:            }
0481:
0482:            /**
0483:             * Subclasses need to implement this to prefetch
0484:             * the <code>Player</code>.
0485:             *
0486:             * @exception  MediaException  Description of the Exception
0487:             */
0488:            protected abstract void doPrefetch() throws MediaException;
0489:
0490:            // JAVADOC COMMENT ELIDED
0491:            public synchronized void start() throws MediaException {
0492:                //System.out.println("DEBUG: about to BP.start() for player=" + this + " at time=" + getMediaTime());
0493:                chkClosed(false);
0494:
0495:                if (state >= STARTED) {
0496:                    return;
0497:                }
0498:
0499:                if (state < PREFETCHED) {
0500:                    prefetch();
0501:                } else {
0502:                    //If prefetch has been called the permission will be checked from there
0503:                    if (!EOM && !loopAfterEOM) {
0504:                        checkPermissions();
0505:                    }
0506:                }
0507:
0508:                // If it's at the EOM, it will automatically
0509:                // loop back to the beginning.
0510:                if (EOM)
0511:                    try {
0512:                        setMediaTime(0);
0513:                    } catch (MediaException me) {
0514:                        // Ignore, if setting media time is not supported
0515:                    }
0516:
0517:                if (!doStart()) {
0518:                    throw new MediaException("start");
0519:                }
0520:
0521:                state = STARTED;
0522:                sendEvent(PlayerListener.STARTED, new Long(getMediaTime()));
0523:
0524:                // Finish any pending startup stuff in subclass
0525:                // Typically used to start any threads that might potentially
0526:                // generate events before the STARTED event is delivered
0527:                doPostStart();
0528:                //System.out.println("DEBUG: finished BP.start() for player=" + this);
0529:            }
0530:
0531:            /**
0532:             * Subclasses need to implement this start
0533:             * the <code>Player</code>.
0534:             *
0535:             * @return    Description of the Return Value
0536:             */
0537:            protected abstract boolean doStart();
0538:
0539:            /**
0540:             * Subclasses can override this method to do the actual starting
0541:             * of worker threads.
0542:             */
0543:            protected void doPostStart() {
0544:            }
0545:
0546:            // JAVADOC COMMENT ELIDED
0547:            public synchronized void stop() throws MediaException {
0548:                //System.out.println("DEBUG: about to BP.stop() for player=" + this + " at time=" + getMediaTime());
0549:                chkClosed(false);
0550:
0551:                loopAfterEOM = false;
0552:
0553:                if (state < STARTED) {
0554:                    return;
0555:                }
0556:
0557:                doStop();
0558:
0559:                state = PREFETCHED;
0560:                sendEvent(PlayerListener.STOPPED, new Long(getMediaTime()));
0561:                //System.out.println("DEBUG: finished BP.stop() for player=" + this);
0562:            }
0563:
0564:            /**
0565:             * Subclasses need to implement this to realize
0566:             * the <code>Player</code>.
0567:             *
0568:             * @exception  MediaException  Description of the Exception
0569:             */
0570:            protected abstract void doStop() throws MediaException;
0571:
0572:            // JAVADOC COMMENT ELIDED
0573:            public synchronized void deallocate() {
0574:                //System.out.println("DEBUG: about to BP.deallocate() for player=" + this);
0575:                chkClosed(false);
0576:
0577:                loopAfterEOM = false;
0578:
0579:                if (state < PREFETCHED) {
0580:                    return;
0581:                }
0582:
0583:                if (state == STARTED) {
0584:                    try {
0585:                        stop();
0586:                    } catch (MediaException e) {
0587:                        // Not much we can do here.
0588:                        // e.printStackTrace();
0589:                    }
0590:                }
0591:
0592:                doDeallocate();
0593:
0594:                EOM = true;
0595:
0596:                state = REALIZED;
0597:            }
0598:
0599:            /**
0600:             * Subclasses need to implement this to deallocate
0601:             * the <code>Player</code>.
0602:             */
0603:            protected abstract void doDeallocate();
0604:
0605:            // JAVADOC COMMENT ELIDED
0606:            public synchronized void close() {
0607:                //System.out.println("DEBUG: about to BP.close() for player=" + this);
0608:                if (state == CLOSED) {
0609:                    return;
0610:                }
0611:
0612:                deallocate();
0613:                doClose();
0614:
0615:                state = CLOSED;
0616:
0617:                sendEvent(PlayerListener.CLOSED, null);
0618:                mplayers.remove(new Integer(pID));
0619:            }
0620:
0621:            /**
0622:             * Subclasses need to implement this to close
0623:             * the <code>Player</code>.
0624:             */
0625:            protected abstract void doClose();
0626:
0627:            // JAVADOC COMMENT ELIDED
0628:            public synchronized long setMediaTime(long now)
0629:                    throws MediaException {
0630:                //System.out.println("DEBUG: about to BP.setMediaTime(" + now + ") for player=" + this);
0631:                chkClosed(true);
0632:
0633:                long theDur = doGetDuration();
0634:                if ((theDur != TIME_UNKNOWN) && (now > theDur)) {
0635:                    now = theDur;
0636:                }
0637:
0638:                long rtn = doSetMediaTime(now);
0639:                EOM = false;
0640:
0641:                //System.out.println("DEBUG: finished BP.setMediaTime(" + now + ")=" + rtn + " for player=" + this);
0642:                return rtn;
0643:            }
0644:
0645:            /**
0646:             * Subclasses need to implement this to set the media time
0647:             * of the <code>Player</code>.
0648:             *
0649:             * @param  now                 Description of the Parameter
0650:             * @return                     Description of the Return Value
0651:             * @exception  MediaException  Description of the Exception
0652:             */
0653:            protected abstract long doSetMediaTime(long now)
0654:                    throws MediaException;
0655:
0656:            // JAVADOC COMMENT ELIDED
0657:            public long getMediaTime() {
0658:                //System.out.println("DEBUG: about to BP.getMediaTime() for player=" + this);
0659:                chkClosed(false);
0660:                return doGetMediaTime();
0661:            }
0662:
0663:            /**
0664:             * Subclasses need to implement this to get the media time
0665:             * of the <code>Player</code>
0666:             *
0667:             * @return    Description of the Return Value
0668:             */
0669:            protected abstract long doGetMediaTime();
0670:
0671:            // JAVADOC COMMENT ELIDED
0672:            public int getState() {
0673:                return state;
0674:            }
0675:
0676:            // JAVADOC COMMENT ELIDED
0677:            public long getDuration() {
0678:                //System.out.println("DEBUG: about to BP.getDuration() for player=" + this);
0679:                chkClosed(false);
0680:                return doGetDuration();
0681:            }
0682:
0683:            /**
0684:             * Subclasses need to implement this to get the duration
0685:             * of the <code>Player</code>.
0686:             *
0687:             * @return    Description of the Return Value
0688:             */
0689:            protected abstract long doGetDuration();
0690:
0691:            // JAVADOC COMMENT ELIDED
0692:            public void addPlayerListener(PlayerListener playerListener) {
0693:                chkClosed(false);
0694:                if (playerListener != null) {
0695:                    /* 
0696:                     * Excplicit "sync" is needed to raise "modified" flag. 
0697:                     * Implicit "sync" is already inside addElemet() method, 
0698:                     * so second sync from the same thread will do nothing ...
0699:                     */
0700:                    synchronized (listeners) {
0701:                        listenersModified = true;
0702:                        listeners.addElement(playerListener);
0703:                    }
0704:                }
0705:            }
0706:
0707:            // JAVADOC COMMENT ELIDED
0708:            public void removePlayerListener(PlayerListener playerListener) {
0709:                chkClosed(false);
0710:                if (playerListener != null) {
0711:                    /* 
0712:                     * Excplicit "sync" is needed to raise "modified" flag. 
0713:                     * Implicit "sync" is already inside removeElemet() method, 
0714:                     * so second sync from the same thread will do nothing ...
0715:                     */
0716:                    synchronized (listeners) {
0717:                        listenersModified = true;
0718:                        listeners.removeElement(playerListener);
0719:                    }
0720:                }
0721:            }
0722:
0723:            final void notifyListeners(String message, Object obj) {
0724:                Object copy[];
0725:                synchronized (listeners) {
0726:                    copy = new Object[listeners.size()];
0727:                    listeners.copyInto(copy);
0728:                    listenersModified = false;
0729:                }
0730:                /*
0731:                 * TBD: raise a flag to show that we are in callbacks 
0732:                 * to detect re-entrance ...
0733:                 * (syncState object can also be used, 
0734:                 * however it protects state changes too) 
0735:                 */
0736:                for (int i = 0; i < copy.length; i++) {
0737:                    PlayerListener listener = (PlayerListener) copy[i];
0738:                    listener.playerUpdate(this , message, obj);
0739:                }
0740:                /*
0741:                 * TBD: need to check for "listenersModified == true", 
0742:                 * this means that one of callbacks updated listeners ->
0743:                 * need some actions ...
0744:                 */
0745:            }
0746:
0747:            /**
0748:             *  Description of the Method
0749:             *
0750:             * @param  evtName  Description of the Parameter
0751:             * @param  evtData  Description of the Parameter
0752:             */
0753:            public void sendEvent(String evtName, Object evtData) {
0754:                //System.out.println("DEBUG: about to BP.sendEvent(" + evtName + "," + evtData +") for player=" + this);
0755:                //  There's always one listener for EOM - itself (for loop procesing).
0756:                //  "Deliver" the CLOSED/ERROR events 
0757:                //  so that the eventQueue thread may terminate
0758:                if (listeners.size() == 0
0759:                        && evtName != PlayerListener.END_OF_MEDIA
0760:                        && evtName != PlayerListener.CLOSED
0761:                        && evtName != PlayerListener.ERROR) {
0762:                    return;
0763:                }
0764:
0765:                // Safeguard against sending events after CLOSED event to avoid
0766:                // deadlock in event delivery thread.
0767:                if (closedDelivered) {
0768:                    return;
0769:                }
0770:
0771:                // Deliver the event to the listeners.
0772:                synchronized (evtLock) {
0773:                    if (eventQueue == null) {
0774:                        eventQueue = new PlayerEventQueue(this );
0775:                    }
0776:                    // TBD: attempt to ensure "eventQueue" existence 
0777:                    // in eventQueue.sentEvent() call ...
0778:                    eventQueue.sendEvent(evtName, evtData);
0779:                }
0780:
0781:                if (evtName == PlayerListener.CLOSED
0782:                        || evtName == PlayerListener.ERROR) {
0783:                    closedDelivered = true;
0784:                }
0785:            }
0786:
0787:            synchronized void doFinishLoopIteration() {
0788:                //System.out.println("DEBUG: about to BP.doFinishLoopIteration() for player=" + this);
0789:                EOM = true;
0790:                loopAfterEOM = false;
0791:                if (state > Player.PREFETCHED) {
0792:
0793:                    state = Player.PREFETCHED;
0794:                    if (loopCount > 1 || loopCount == -1) {
0795:                        loopAfterEOM = true;
0796:                    }
0797:                }
0798:                //System.out.println("DEBUG: finished BP.doFinishLoopIteration() for player=" + this);
0799:            }
0800:
0801:            /**
0802:             *  Description of the Method
0803:             */
0804:            synchronized void doNextLoopIteration() {
0805:                //System.out.println("DEBUG: about to BP.doNextLoopIteration() for player=" + this);
0806:                if (loopAfterEOM) {
0807:                    // If a loop count is set, we'll loop back to the beginning.
0808:                    if ((loopCount > 1) || (loopCount == -1)) {
0809:                        try {
0810:                            if (setMediaTime(0) == 0) {
0811:                                if (loopCount > 1) {
0812:                                    loopCount--;
0813:                                }
0814:                                start();
0815:                            } else {
0816:                                loopCount = 1;
0817:                            }
0818:                        } catch (MediaException ex) {
0819:                            loopCount = 1;
0820:                        }
0821:                    } else if (loopCountSet > 1) {
0822:                        loopCount = loopCountSet;
0823:                    }
0824:
0825:                    loopAfterEOM = false;
0826:                }
0827:                //System.out.println("DEBUG: finished BP.doNextLoopIteration() for player=" + this);
0828:            }
0829:
0830:            // "final" to verify that no subclass overrides getControls.
0831:            // can be removed if overload necessary
0832:            /**
0833:             *  Gets the controls attribute of the BasicPlayer object
0834:             *
0835:             * @return    The controls value
0836:             */
0837:            public final Control[] getControls() {
0838:                chkClosed(true);
0839:
0840:                Vector v = new Vector(3);
0841:                // average maximum number of controls
0842:                for (int i = 0; i < control_names.length; i++) {
0843:                    Object c = getControl(control_names[i]);
0844:                    if ((c != null) && !v.contains(c)) {
0845:                        v.addElement(c);
0846:                    }
0847:                }
0848:                Control[] ret = new Control[v.size()];
0849:                v.copyInto(ret);
0850:                return ret;
0851:            }
0852:
0853:            /**
0854:             * Gets the <code>Control</code> that supports the specified
0855:             * class or interface. The full class
0856:             * or interface name should be specified.
0857:             * <code>Null</code> is returned if the <code>Control</code>
0858:             * is not supported.
0859:             *
0860:             * @param  type  Description of the Parameter
0861:             * @return       <code>Control</code> for the class or interface
0862:             * name.
0863:             */
0864:            public final Control getControl(String type) {
0865:                chkClosed(true);
0866:
0867:                if (type == null) {
0868:                    throw new IllegalArgumentException();
0869:                }
0870:
0871:                // Prepend the package name if the type given does not
0872:                // have the package prefix.
0873:                if (type.indexOf('.') < 0) {
0874:                    // for non-fully qualified control names,
0875:                    // look up the package in the allCtrls array
0876:                    for (int i = 0; i < allCtrls.length; i++) {
0877:                        if (allCtrls[i].equals(type)) {
0878:                            // standard controls are specified
0879:                            // without package name in allCtrls
0880:                            return doGetControl(pkgName + type);
0881:                        } else if (allCtrls[i].endsWith(type)) {
0882:                            // non-standard controls are with
0883:                            // full package name in allCtrls
0884:                            return doGetControl(allCtrls[i]);
0885:                        }
0886:                    }
0887:                }
0888:                return doGetControl(type);
0889:            }
0890:
0891:            /**
0892:             * The worker method to actually obtain the control.
0893:             *
0894:             * @param  type  the class name of the <code>Control</code>.
0895:             * @return       <code>Control</code> for the class or interface
0896:             * name.
0897:             */
0898:            protected abstract Control doGetControl(String type);
0899:
0900:            /**
0901:             * For global PlayerID management
0902:             *
0903:             * @param  pid  Description of the Parameter
0904:             * @return      Description of the Return Value
0905:             */
0906:            public static ABBBasicPlayer get(int pid) {
0907:                return (ABBBasicPlayer) (mplayers.get(new Integer(pid)));
0908:            }
0909:
0910:            /**
0911:             *  Pauses and deallocates all media players.
0912:             *
0913:             *  After this call all players are either in realized
0914:             *  or unrealized state.  
0915:             *
0916:             *  Resources are being released during deallocation.
0917:             */
0918:            public static void pauseAll() {
0919:                //System.out.println("DEBUG: about to BP.pauseAll()");
0920:                if (mplayers == null) {
0921:                    return;
0922:                }
0923:
0924:                for (Enumeration e = mplayers.elements(); e.hasMoreElements();) {
0925:                    ABBBasicPlayer p = (ABBBasicPlayer) e.nextElement();
0926:
0927:                    int state = p.getState();
0928:                    long time = p.getMediaTime();
0929:
0930:                    // save the player's state
0931:                    pstates.put(p, new Integer(state));
0932:
0933:                    // save the player's media time
0934:                    mtimes.put(p, new Long(time));
0935:
0936:                    // deallocate the player
0937:                    //
0938:                    // this will implicitly stop all players
0939:                    // and release scarce resources such as
0940:                    // the audio device
0941:                    p.deallocate();
0942:                }
0943:            }
0944:
0945:            /**
0946:             *  Resumes all media players' activities.
0947:             *
0948:             *  Players that were in STARTED state when pause
0949:             *  was called will resume playing at the media time
0950:             *  they were stopped and deallocated.
0951:             */
0952:            public static void resumeAll() {
0953:                //System.out.println("DEBUG: about to BP.resumeAll()");
0954:                if (mplayers == null || pstates.size() == 0) {
0955:                    return;
0956:                }
0957:
0958:                for (Enumeration e = mplayers.elements(); e.hasMoreElements();) {
0959:                    ABBBasicPlayer p = (ABBBasicPlayer) e.nextElement();
0960:
0961:                    int state = ((Integer) pstates.get(p)).intValue();
0962:                    long time = ((Long) mtimes.get(p)).longValue();
0963:
0964:                    switch (state) {
0965:                    case Player.PREFETCHED:
0966:                        try {
0967:                            //System.out.println("DEBUG: BP.resumeAll() for PREFETCHED player=" + p);
0968:                            p.prefetch();
0969:                            p.setMediaTime(time);
0970:                        } catch (MediaException ex) {
0971:                        }
0972:                        break;
0973:                    case Player.STARTED:
0974:                        try {
0975:                            //System.out.println("DEBUG: BP.resumeAll() for STARTED player=" + p);
0976:                            p.realize();
0977:                            p.prefetch();
0978:                            p.setMediaTime(time);
0979:                            p.start();
0980:                        } catch (MediaException ex) {
0981:                        }
0982:                        break;
0983:                    }
0984:                }
0985:
0986:                // clear player states and media times
0987:                pstates.clear();
0988:                mtimes.clear();
0989:            }
0990:
0991:            /**
0992:             * Implementation method for VolumeControl
0993:             *
0994:             * @param  ll  Description of the Parameter
0995:             * @return     Description of the Return Value
0996:             */
0997:            public int doSetLevel(int ll) {
0998:                return ll;
0999:            }
1000:
1001:            // JAVADOC COMMENT ELIDED
1002:            public String getContentType() {
1003:                chkClosed(true);
1004:                return "";
1005:            }
1006:
1007:        }
1008:
1009:        /**
1010:         * The thread that's responsible for delivering Player events.
1011:         * This class lives for only 5 secs.  If no event comes in
1012:         * 5 secs, it will exit.
1013:         *
1014:         * @created    January 13, 2005
1015:         */
1016:        class PlayerEventQueue extends Thread {
1017:            /**
1018:             * the player instance
1019:             */
1020:            private ABBBasicPlayer p;
1021:            /**
1022:             * event info array
1023:             */
1024:            private EventQueueEntry evt;
1025:
1026:            /**
1027:             * The constructor
1028:             *
1029:             * @param  p  the instance of BasicPlayer intending to post event to
1030:             *        this event queue.
1031:             */
1032:            PlayerEventQueue(ABBBasicPlayer p) {
1033:                this .p = p;
1034:                evt = null;
1035:                //System.out.println("DEBUG: Created Player Event Queue ! player=" + p);
1036:                start();
1037:            }
1038:
1039:            /**
1040:             * Put an event in the event queue and wake up the thread to
1041:             * deliver it.  If the event queue is filled, block.
1042:             *
1043:             * @param  evtName  Description of the Parameter
1044:             * @param  evtData  Description of the Parameter
1045:             */
1046:            synchronized void sendEvent(String evtName, Object evtData) {
1047:
1048:                //System.out.println("DEBUG: about to Queue.sendEvent(" + evtName + "," + evtData +") for player=" + this);
1049:
1050:                //add element to the ring ...
1051:                if (evt == null) {
1052:                    evt = new EventQueueEntry(evtName, evtData);
1053:                } else {
1054:                    evt.link = new EventQueueEntry(evtName, evtData, evt.link);
1055:                    evt = evt.link;
1056:                }
1057:                this .notifyAll();
1058:            }
1059:
1060:            /**
1061:             * Event handling thread.
1062:             */
1063:            public void run() {
1064:
1065:                String evtName = "";
1066:                Object evtData = null;
1067:                EventQueueEntry evtLink = null;
1068:
1069:                boolean evtToGo = false; // true if there is an event to send
1070:
1071:                // true if at least one event is sent,
1072:                // in case that posting the initial event
1073:                // takes a long time
1074:                boolean evtSent = false;
1075:
1076:                for (;;) {
1077:
1078:                    synchronized (this ) {
1079:                        // TBD: use a special Object to wait/notify
1080:                        // instead of time delays 
1081:                        // (for synchronization and wake up of 
1082:                        // BasicPlayer.sendEvent(...);s threads and 
1083:                        // PlayerEventQueue.run() thread ) ? 
1084:                        //
1085:                        // If the queue is empty, we'll wait for at most
1086:                        // 5 secs.
1087:                        if (evt == null) {
1088:                            try {
1089:                                this .wait(5000);
1090:                            } catch (InterruptedException ie) {
1091:                            }
1092:                        }
1093:                        if (evt != null) {
1094:                            evtLink = evt.link;
1095:                            //exclude element from the ring ...
1096:                            if (evtLink == evt) {
1097:                                evt = null;
1098:                            } else {
1099:                                evt.link = evtLink.link;
1100:                            }
1101:                            evtToGo = true;
1102:
1103:                            evtName = evtLink.name;
1104:                            evtData = evtLink.data;
1105:
1106:                            // For garbage collection.
1107:                            evtLink.link = null;
1108:                            evtLink.name = null;
1109:                            evtLink.data = null;
1110:                            evtLink = null;
1111:
1112:                        } else {
1113:                            evtToGo = false;
1114:                        }
1115:
1116:                    }
1117:                    // synchronized this
1118:
1119:                    if (evtToGo) {
1120:                        // TBD: move it to "sendEvent(...)" to provide loop-related
1121:                        // reaction on EOM earlier ?
1122:                        //
1123:                        // First, check and handle EOM.
1124:                        if (evtName == PlayerListener.END_OF_MEDIA) {
1125:                            p.doFinishLoopIteration();
1126:                        }
1127:
1128:                        //System.out.println("DEBUG: about to notifyListeners(" + evtName + "," + evtData +") for player=" + p);
1129:                        // Notify the PlayerListeners.
1130:                        p.notifyListeners(evtName, evtData);
1131:
1132:                        // We'll need to loop back if looping was set.
1133:                        p.doNextLoopIteration();
1134:
1135:                        evtSent = true;
1136:
1137:                    }
1138:                    // if (evtToGo)
1139:
1140:                    // We'll exit the event thread if we have already sent one
1141:                    // event and there's no more event after 5 secs; or if the
1142:                    // Player is closed.
1143:
1144:                    if (evtName == PlayerListener.CLOSED
1145:                            || evtName == PlayerListener.ERROR) {
1146:                        // try to nullify queue reference and exit 
1147:                        // if player is closing ...
1148:                        synchronized (p.evtLock) {
1149:                            //System.out.println("DEBUG: Killed Player Event Queue (STOP/ERROR)! player=" + p);
1150:                            p.eventQueue = null;
1151:                            break; // Exit the event thread.
1152:                        }
1153:                    }
1154:
1155:                    synchronized (this ) {
1156:                        // try to nullify queue reference and exit 
1157:                        // if nothing to send (but there were events in the past) ...
1158:                        if (evt == null && evtSent && !evtToGo) {
1159:                            synchronized (p.evtLock) {
1160:                                //System.out.println("DEBUG: Killed Player Event Queue (empty for 5 sec)! player=" + p);
1161:                                p.eventQueue = null;
1162:                                break; // Exit the event thread.
1163:                            }
1164:                        }
1165:                    }
1166:                }
1167:            }
1168:        }
1169:
1170:        class EventQueueEntry {
1171:            String name;
1172:            Object data;
1173:            EventQueueEntry link;
1174:
1175:            public EventQueueEntry(String n, Object d) {
1176:                name = n;
1177:                data = d;
1178:                link = this ;
1179:            }
1180:
1181:            public EventQueueEntry(String n, Object d, EventQueueEntry l) {
1182:                name = n;
1183:                data = d;
1184:                link = l;
1185:            }
1186:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.