📄 abstractplayer.java
字号:
postManagedControllerErrorEvent(); return false; } // Now that the Player is prefetched, getDuration() may // be more accurate. updateDuration(); return true; } /** * Start player and all of its managed Controllers at the * given time. Subclasses should override doPlayerSyncStart() * to do the actual work to transition the Controller. * <p> * This method should not be called directly. Instead, call * syncStart(). */ public final boolean doSyncStart(Time t) { // Synchronize on the controllers Vector so that // Controllers cannot be added or deleted while we are // transitioning them. resetControllerError(); // SyncStart each managed Controller for(int i = 0; i < controllers.size(); i++) { Controller c = (Controller)controllers.elementAt(i); c.syncStart(t); } // SyncStart this Player. If it fails, then assume a // ControllerErrorEvent was posted and return false. if( ! doPlayerSyncStart(t) ) { return false; } // Now wait for our all of our managed Controllers to // complete the state transition or post an error. // controllerUpdate() will catch such events and // notify us. synchronized(controllers) { while( controllerError == null && ! isStateReached(Started) ) { try { controllers.wait(); } catch(InterruptedException e) {} } } if( controllerError != null ) { postManagedControllerErrorEvent(); return false; } return true; } /** * Deallocate player on current thread. Subclasses should * override doPlayerDeallocate() to do the actual work to * transition the Controller. * <p> * This method should not be called directly. Instead, call * deallocate(). */ public final boolean doDeallocate() { // Synchronize on the controllers Vector so that // Controllers cannot be added or deleted while we are // transitioning them. resetControllerError(); // If there is a large number of managed Controllers, // then deallocating each synchronously could be time // consuming. Instead, spawn a thread to deallocate // each controller. Later on, after this Player has // been deallocated, wait for each deallocating // thread to finish before returning. int size = controllers.size(); Thread[] threads = new Thread[size]; for(int i = 0; i < size; i++) { final Controller c = (Controller)controllers.elementAt(i); threads[i] = new Thread() { public void run() { c.deallocate(); } }; threads[i].start(); } // Deallocate this Player. If it fails, then assume a // ControllerErrorEvent was posted and return false. if( ! doPlayerDeallocate() ) { return false; } // Wait for each Controller to deallocate for(int i = 0; i < size; i++) { try { threads[i].join(); } catch(InterruptedException e) {} } // Check for errors during deallocation if( controllerError != null ) { postManagedControllerErrorEvent(); return false; } return true; } /** * Stop player on current thread. Subclasses should override * doPlayerStop() to do the actual work to transition the * Controller. * <p> * This method should not be called directly. Instead, call * stop(). */ public final boolean doStop() { // Synchronize on the controllers Vector so that // Controllers cannot be added or deleted while we are // transitioning them. resetControllerError(); // If there is a large number of managed Controllers, // then stopping each synchronously could be time // consuming, and could leave each Controller stopped // at different media times. Instead, spawn a thread // to stop each controller. Later on, after this // Player has been stopped, wait for each thread to // finish before returning. int size = controllers.size(); Thread[] threads = new Thread[size]; for(int i = 0; i < size; i++) { final Controller c = (Controller)controllers.elementAt(i); threads[i] = new Thread() { public void run() { c.stop(); } }; threads[i].start(); } // Stop this Player. If it fails, then assume a // ControllerErrorEvent was posted and return false. if( ! doPlayerStop() ) { return false; } // Wait for each Controller to stop for(int i = 0; i < size; i++) { try { threads[i].join(); } catch(InterruptedException e) {} } // Check for errors while stoping if( controllerError != null ) { postManagedControllerErrorEvent(); return false; } return true; } /** * Close the Player. First close all Controllers under the * control of this Player. Then release resources held by * this Player. Subclasses should implement doPlayerClose() * to add additional functionality. * <p> * This method should not be called directly. Instead, call * close(). */ public synchronized final void doClose() { Vector controllers = getControllers(); // Close all Controllers under the control of this Player for(int i = 0, n = controllers.size(); i < n; i++ ) { Controller c = (Controller)controllers.elementAt(i); c.close(); } try { // Stop the data-transfer source.stop(); // Disconnect the DataSource source.disconnect(); } catch(IOException e) {} // Call implementation-specific functionality doPlayerClose(); // Release as many resources as we can controllers = null; source = null; gainControl = null; // duration = null; // this causes problems getting the duration during, say, postDeallocateEvent, so let's leave it non-null controllerError = null; } /** * Sets the media time for this Player and all of its managed * Controllers. * <p> * This method should not be called directly. Instead, call * setMediaTime(). * * @param t * The media time to set. */ public synchronized final void doSetMediaTime(Time t) { // First set the media time on all of the managed Controllers for(int i = 0, n = controllers.size(); i < n; i++ ) { Controller c = (Controller)controllers.elementAt(i); c.setMediaTime(t); } // Set the media time on this Player doPlayerSetMediaTime(t); } /** * Sets the rate for this Player and all of its managed * Controllers. If any of the above cannot accomodate the * given rate, then the rate is set to 1.0 for all of the * above. * <p> * This method should not be called directly. Instead, call * setRate(). * * @param rate * The rate to set. */ public synchronized final float doSetRate(float rate) { float actual; // First set the rate on all of the managed Controllers for(int i = 0, n = controllers.size(); i < n; i++ ) { Controller c = (Controller)controllers.elementAt(i); actual = c.setRate(rate); if( rate != 1.0F && actual != rate ) { doSetRate(1.0F); return 1.0F; } } // Set the rate on this Player actual = doPlayerSetRate(rate); if( ! controllers.isEmpty() && rate != 1.0F && actual != rate ) { doSetRate(1.0F); return 1.0F; } return actual; } //////////////////////////////////////////////////////////// // // ejmf.toolkit.media.content.AbstractPlayer methods // //////////////////////////////////////////////////////////// /** * Sets the controller error that occurred while waiting for a * state transition. */ private void setControllerError(ControllerErrorEvent e) { this.controllerError = e; } /** * Resets the ControllerErrorEvent. */ private void resetControllerError() { setControllerError(null); } /** * Get the ControllerErrorEvent that occurred while waiting * for a state transition. */ private ControllerErrorEvent getControllerError() { return controllerError; } /** * Checks to see if the given Controller state has been * reached in a forward-transitioning Controller. * * @param state * The desired state. * * @return true if the state has been reached, false * otherwise. */ private boolean isStateReached(int state) { synchronized(controllers) { for(int i = 0, n = controllers.size(); i < n; i++) { Controller controller = (Controller)controllers.elementAt(i); if( controller.getState() < state ) { return false; } } return true; } } /** * Checks to see if the all of this Player's managed * Controller have stopped. Usually called from within * endOfMedia() to see if an EndOfMediaEvent can be posted. * * @return true if all of this Player's managed * Controller have stopped, false otherwise. */ private boolean areControllersStopped() { synchronized(controllers) { for(int i = 0, n = controllers.size(); i < n; i++) { Controller controller = (Controller)controllers.elementAt(i); if( controller.getState() == Started ) { return false; } } return true; } } /** * Post a ManagedControllerErrorEvent to the Media Event * Queue. Automatically fill in the managing Player, the * ControllerErrorEvent, and the message properties of the * ManagedControllerErrorEvent. */ private void postManagedControllerErrorEvent() { String message = "Managing Player " + getClass().getName() + " received ControllerErrorEvent from " + controllerError.getSourceController().getClass().getName(); postEvent( new ManagedControllerErrorEvent( this, controllerError, message ) ); resetControllerError(); } /** * Indicates to the framework that the end of media has been * reached. Marks the media time, sets the current and target * states to Prefetched, and posts an EndOfMediaEvent. * * @exception ClockStoppedException * If the AbstractController is not in the Started * state. */ protected void endOfMedia() throws ClockStoppedException { synchronized(controllers) { // Wait for all of the managed Controllers to stop or // post an error. controllerUpdate() will catch such // events and notify us. // controllerError was reset when doSyncStart() was called while( ! areControllersStopped() ) { try { controllers.wait(); } catch(InterruptedException e) {} } } super.endOfMedia(); } //////////////////////////////////////////////////////////// // // Synchronous state-changing methods // // These routines are called indirectly from the // TransitionQueueMonitor class by way of a // TransitionThread. When these methods are called, the // following assumptions can be made: // // 1. The current state is less than the desired state. If // doSyncStart() is called, the Player is guaranteed to // be in the Prefetched state. // // 2. The target state is greater than or equal to the // desired state. // // 3. Any state-related exceptions have been thrown // already. // // 4. There are no other state-changing threads running. // //////////////////////////////////////////////////////////// /** * Start the AbstractPlayer ASAP. * <p> * Synchronous method -- return when transition complete */ protected void synchronousStart() { // Does the controller need to be prefetched? if( getState() < Prefetched ) { synchronousPrefetch(); if (getState() < Prefetched) // prefetch failed, do not proceed. return; } // Start ASAP synchronousSyncStart( getTimeBase().getTime() ); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -