bool MediaPlayerPrivateAVFoundation::hasAvailableVideoFrame() const { if (currentRenderingMode() == MediaRenderingToLayer) return videoLayerIsReadyToDisplay(); // When using the software renderer we hope someone will signal that a frame is available so we might as well // wait until we know that a frame has been drawn. return m_videoFrameHasDrawn; }
void MediaPlayerPrivateAVFoundation::prepareForRendering() { if (m_isAllowedToRender) return; m_isAllowedToRender = true; setUpVideoRendering(); if (currentRenderingMode() == MediaRenderingToLayer || preferredRenderingMode() == MediaRenderingToLayer) m_player->client().mediaPlayerRenderingModeChanged(m_player); }
void MediaPlayerPrivateAVFoundation::setUpVideoRendering() { if (!isReadyForVideoSetup()) return; MediaRenderingMode currentMode = currentRenderingMode(); MediaRenderingMode preferredMode = preferredRenderingMode(); if (preferredMode == MediaRenderingNone) preferredMode = MediaRenderingToContext; if (currentMode == preferredMode && currentMode != MediaRenderingNone) return; LOG(Media, "MediaPlayerPrivateAVFoundation::setUpVideoRendering(%p) - current mode = %d, preferred mode = %d", this, static_cast<int>(currentMode), static_cast<int>(preferredMode)); if (currentMode != MediaRenderingNone) tearDownVideoRendering(); switch (preferredMode) { case MediaRenderingNone: case MediaRenderingToContext: createContextVideoRenderer(); break; #if USE(ACCELERATED_COMPOSITING) case MediaRenderingToLayer: createVideoLayer(); break; #endif } #if USE(ACCELERATED_COMPOSITING) // If using a movie layer, inform the client so the compositing tree is updated. if (currentMode == MediaRenderingToLayer || preferredMode == MediaRenderingToLayer) { LOG(Media, "MediaPlayerPrivateAVFoundation::setUpVideoRendering(%p) - calling mediaPlayerRenderingModeChanged()", this); m_player->mediaPlayerClient()->mediaPlayerRenderingModeChanged(m_player); } #endif }
void MediaPlayerPrivateAVFoundation::updateStates() { if (m_ignoreLoadStateChanges) return; MediaPlayer::NetworkState newNetworkState = m_networkState; MediaPlayer::ReadyState newReadyState = m_readyState; if (m_loadingMetadata) newNetworkState = MediaPlayer::Loading; else { // -loadValuesAsynchronouslyForKeys:completionHandler: has invoked its handler; test status of keys and determine state. AssetStatus assetStatus = this->assetStatus(); ItemStatus itemStatus = playerItemStatus(); m_assetIsPlayable = (assetStatus == MediaPlayerAVAssetStatusPlayable); if (m_readyState < MediaPlayer::HaveMetadata && assetStatus > MediaPlayerAVAssetStatusLoading) { if (m_assetIsPlayable) { if (assetStatus >= MediaPlayerAVAssetStatusLoaded) newReadyState = MediaPlayer::HaveMetadata; if (itemStatus <= MediaPlayerAVPlayerItemStatusUnknown) { if (assetStatus == MediaPlayerAVAssetStatusFailed || m_preload > MediaPlayer::MetaData || isLiveStream()) { // The asset is playable but doesn't support inspection prior to playback (eg. streaming files), // or we are supposed to prepare for playback immediately, so create the player item now. newNetworkState = MediaPlayer::Loading; prepareToPlay(); } else newNetworkState = MediaPlayer::Idle; } } else { // FIX ME: fetch the error associated with the @"playable" key to distinguish between format // and network errors. newNetworkState = MediaPlayer::FormatError; } } if (assetStatus >= MediaPlayerAVAssetStatusLoaded && itemStatus > MediaPlayerAVPlayerItemStatusUnknown) { switch (itemStatus) { case MediaPlayerAVPlayerItemStatusDoesNotExist: case MediaPlayerAVPlayerItemStatusUnknown: case MediaPlayerAVPlayerItemStatusFailed: break; case MediaPlayerAVPlayerItemStatusPlaybackLikelyToKeepUp: case MediaPlayerAVPlayerItemStatusPlaybackBufferFull: // If the status becomes PlaybackBufferFull, loading stops and the status will not // progress to LikelyToKeepUp. Set the readyState to HAVE_ENOUGH_DATA, on the // presumption that if the playback buffer is full, playback will probably not stall. newReadyState = MediaPlayer::HaveEnoughData; break; case MediaPlayerAVPlayerItemStatusReadyToPlay: if (m_readyState != MediaPlayer::HaveEnoughData && maxTimeLoaded() > currentMediaTime()) newReadyState = MediaPlayer::HaveFutureData; break; case MediaPlayerAVPlayerItemStatusPlaybackBufferEmpty: newReadyState = MediaPlayer::HaveCurrentData; break; } if (itemStatus == MediaPlayerAVPlayerItemStatusPlaybackBufferFull) newNetworkState = MediaPlayer::Idle; else if (itemStatus == MediaPlayerAVPlayerItemStatusFailed) newNetworkState = MediaPlayer::DecodeError; else if (itemStatus != MediaPlayerAVPlayerItemStatusPlaybackBufferFull && itemStatus >= MediaPlayerAVPlayerItemStatusReadyToPlay) newNetworkState = (maxTimeLoaded() == durationMediaTime()) ? MediaPlayer::Loaded : MediaPlayer::Loading; } } if (isReadyForVideoSetup() && currentRenderingMode() != preferredRenderingMode()) setUpVideoRendering(); if (!m_haveReportedFirstVideoFrame && m_cachedHasVideo && hasAvailableVideoFrame()) { if (m_readyState < MediaPlayer::HaveCurrentData) newReadyState = MediaPlayer::HaveCurrentData; m_haveReportedFirstVideoFrame = true; m_player->firstVideoFrameAvailable(); } #if !LOG_DISABLED if (m_networkState != newNetworkState || m_readyState != newReadyState) { LOG(Media, "MediaPlayerPrivateAVFoundation::updateStates(%p) - entered with networkState = %i, readyState = %i, exiting with networkState = %i, readyState = %i", this, static_cast<int>(m_networkState), static_cast<int>(m_readyState), static_cast<int>(newNetworkState), static_cast<int>(newReadyState)); } #endif setNetworkState(newNetworkState); setReadyState(newReadyState); if (m_playWhenFramesAvailable && hasAvailableVideoFrame()) { m_playWhenFramesAvailable = false; platformPlay(); } }
void MediaPlayerPrivateAVFoundation::updateStates() { if (m_ignoreLoadStateChanges) return; MediaPlayer::NetworkState oldNetworkState = m_networkState; MediaPlayer::ReadyState oldReadyState = m_readyState; LOG(Media, "MediaPlayerPrivateAVFoundation::updateStates(%p) - entering with networkState = %i, readyState = %i", this, static_cast<int>(m_networkState), static_cast<int>(m_readyState)); if (m_loadingMetadata) m_networkState = MediaPlayer::Loading; else { // -loadValuesAsynchronouslyForKeys:completionHandler: has invoked its handler; test status of keys and determine state. AssetStatus assetStatus = this->assetStatus(); ItemStatus itemStatus = playerItemStatus(); m_assetIsPlayable = (assetStatus == MediaPlayerAVAssetStatusPlayable); if (m_readyState < MediaPlayer::HaveMetadata && assetStatus > MediaPlayerAVAssetStatusLoading) { if (m_assetIsPlayable) { if (assetStatus >= MediaPlayerAVAssetStatusLoaded) m_readyState = MediaPlayer::HaveMetadata; if (itemStatus <= MediaPlayerAVPlayerItemStatusUnknown) { if (assetStatus == MediaPlayerAVAssetStatusFailed || m_preload > MediaPlayer::MetaData || isLiveStream()) { // The asset is playable but doesn't support inspection prior to playback (eg. streaming files), // or we are supposed to prepare for playback immediately, so create the player item now. m_networkState = MediaPlayer::Loading; prepareToPlay(); } else m_networkState = MediaPlayer::Idle; } } else { // FIX ME: fetch the error associated with the @"playable" key to distinguish between format // and network errors. m_networkState = MediaPlayer::FormatError; } } if (assetStatus >= MediaPlayerAVAssetStatusLoaded && itemStatus > MediaPlayerAVPlayerItemStatusUnknown) { switch (itemStatus) { case MediaPlayerAVPlayerItemStatusDoesNotExist: case MediaPlayerAVPlayerItemStatusUnknown: case MediaPlayerAVPlayerItemStatusFailed: break; case MediaPlayerAVPlayerItemStatusPlaybackLikelyToKeepUp: m_readyState = MediaPlayer::HaveEnoughData; break; case MediaPlayerAVPlayerItemStatusPlaybackBufferFull: case MediaPlayerAVPlayerItemStatusReadyToPlay: // If the readyState is already HaveEnoughData, don't go lower because of this state change. if (m_readyState == MediaPlayer::HaveEnoughData) break; case MediaPlayerAVPlayerItemStatusPlaybackBufferEmpty: if (maxTimeLoaded() > currentTime()) m_readyState = MediaPlayer::HaveFutureData; else m_readyState = MediaPlayer::HaveCurrentData; break; } if (itemStatus == MediaPlayerAVPlayerItemStatusPlaybackBufferFull) m_networkState = MediaPlayer::Idle; else if (itemStatus == MediaPlayerAVPlayerItemStatusFailed) m_networkState = MediaPlayer::DecodeError; else if (itemStatus != MediaPlayerAVPlayerItemStatusPlaybackBufferFull && itemStatus >= MediaPlayerAVPlayerItemStatusReadyToPlay) m_networkState = (maxTimeLoaded() == duration()) ? MediaPlayer::Loaded : MediaPlayer::Loading; } } if (isReadyForVideoSetup() && currentRenderingMode() != preferredRenderingMode()) setUpVideoRendering(); if (!m_haveReportedFirstVideoFrame && m_cachedHasVideo && hasAvailableVideoFrame()) { if (m_readyState < MediaPlayer::HaveCurrentData) m_readyState = MediaPlayer::HaveCurrentData; m_haveReportedFirstVideoFrame = true; m_player->firstVideoFrameAvailable(); } if (m_networkState != oldNetworkState) m_player->networkStateChanged(); if (m_readyState != oldReadyState) m_player->readyStateChanged(); if (m_playWhenFramesAvailable && hasAvailableVideoFrame()) { m_playWhenFramesAvailable = false; platformPlay(); } LOG(Media, "MediaPlayerPrivateAVFoundation::updateStates(%p) - exiting with networkState = %i, readyState = %i", this, static_cast<int>(m_networkState), static_cast<int>(m_readyState)); }
void MediaPlayerPrivateAVFoundation::updateStates() { MediaPlayer::NetworkState oldNetworkState = m_networkState; MediaPlayer::ReadyState oldReadyState = m_readyState; LOG(Media, "MediaPlayerPrivateAVFoundation::updateStates(%p) - entering with networkState = %i, readyState = %i", this, static_cast<int>(m_networkState), static_cast<int>(m_readyState)); if (m_loadingMetadata) m_networkState = MediaPlayer::Loading; else { // -loadValuesAsynchronouslyForKeys:completionHandler: has invoked its handler; test status of keys and determine state. AVAssetStatus avAssetStatus = assetStatus(); ItemStatus itemStatus = playerItemStatus(); m_assetIsPlayable = (avAssetStatus == MediaPlayerAVAssetStatusPlayable); if (m_readyState < MediaPlayer::HaveMetadata && avAssetStatus > MediaPlayerAVAssetStatusLoading) { if (m_assetIsPlayable) { if (itemStatus == MediaPlayerAVPlayerItemStatusUnknown) { if (avAssetStatus == MediaPlayerAVAssetStatusFailed || m_preload > MediaPlayer::MetaData) { // We may have a playable asset that doesn't support inspection prior to playback; go ahead // and create the AVPlayerItem now. When the AVPlayerItem becomes ready to play, we will // have access to its metadata. Or we may have been asked to become ready to play immediately. m_networkState = MediaPlayer::Loading; prepareToPlay(); } else m_networkState = MediaPlayer::Idle; } if (avAssetStatus == MediaPlayerAVAssetStatusLoaded) m_readyState = MediaPlayer::HaveMetadata; } else { // FIX ME: fetch the error associated with the @"playable" key to distinguish between format // and network errors. m_networkState = MediaPlayer::FormatError; } } if (avAssetStatus >= MediaPlayerAVAssetStatusLoaded && itemStatus > MediaPlayerAVPlayerItemStatusUnknown) { if (seeking()) m_readyState = m_readyState >= MediaPlayer::HaveMetadata ? MediaPlayer::HaveMetadata : MediaPlayer::HaveNothing; else { float maxLoaded = maxTimeLoaded(); switch (itemStatus) { case MediaPlayerAVPlayerItemStatusUnknown: break; case MediaPlayerAVPlayerItemStatusFailed: m_networkState = MediaPlayer::DecodeError; break; case MediaPlayerAVPlayerItemStatusPlaybackLikelyToKeepUp: m_readyState = MediaPlayer::HaveEnoughData; break; case MediaPlayerAVPlayerItemStatusReadyToPlay: case MediaPlayerAVPlayerItemStatusPlaybackBufferEmpty: case MediaPlayerAVPlayerItemStatusPlaybackBufferFull: if (maxLoaded > currentTime()) m_readyState = MediaPlayer::HaveFutureData; else m_readyState = MediaPlayer::HaveCurrentData; break; } if (itemStatus >= MediaPlayerAVPlayerItemStatusReadyToPlay) m_networkState = (maxLoaded == duration()) ? MediaPlayer::Loaded : MediaPlayer::Loading; } } } if (isReadyForVideoSetup() && currentRenderingMode() != preferredRenderingMode()) setUpVideoRendering(); if (m_networkState != oldNetworkState) m_player->networkStateChanged(); if (m_readyState != oldReadyState) m_player->readyStateChanged(); LOG(Media, "MediaPlayerPrivateAVFoundation::updateStates(%p) - exiting with networkState = %i, readyState = %i", this, static_cast<int>(m_networkState), static_cast<int>(m_readyState)); }