diff options
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llplugin/llpluginclassmedia.cpp | 30 | ||||
-rw-r--r-- | indra/llplugin/llpluginclassmedia.h | 1 | ||||
-rw-r--r-- | indra/llplugin/llpluginclassmediaowner.h | 3 | ||||
-rw-r--r-- | indra/media_plugins/base/media_plugin_base.cpp | 1 | ||||
-rw-r--r-- | indra/media_plugins/base/media_plugin_base.h | 1 | ||||
-rw-r--r-- | indra/media_plugins/quicktime/media_plugin_quicktime.cpp | 26 | ||||
-rw-r--r-- | indra/newview/llviewermedia.cpp | 181 | ||||
-rw-r--r-- | indra/newview/llviewermedia.h | 11 |
8 files changed, 171 insertions, 83 deletions
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 26802bbd1c..457c074ef1 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -552,6 +552,23 @@ void LLPluginClassMedia::loadURI(const std::string &uri) sendMessage(message); } +const char* LLPluginClassMedia::priorityToString(EPriority priority) +{ + const char* result = "UNKNOWN"; + switch(priority) + { + case PRIORITY_UNLOADED: result = "unloaded"; break; + case PRIORITY_STOPPED: result = "stopped"; break; + case PRIORITY_HIDDEN: result = "hidden"; break; + case PRIORITY_SLIDESHOW: result = "slideshow"; break; + case PRIORITY_LOW: result = "low"; break; + case PRIORITY_NORMAL: result = "normal"; break; + case PRIORITY_HIGH: result = "high"; break; + } + + return result; +} + void LLPluginClassMedia::setPriority(EPriority priority) { if(mPriority != priority) @@ -560,35 +577,28 @@ void LLPluginClassMedia::setPriority(EPriority priority) LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_priority"); - std::string priority_string; + std::string priority_string = priorityToString(priority); switch(priority) { case PRIORITY_UNLOADED: - priority_string = "unloaded"; mSleepTime = 1.0f; break; case PRIORITY_STOPPED: - priority_string = "stopped"; mSleepTime = 1.0f; break; case PRIORITY_HIDDEN: - priority_string = "hidden"; mSleepTime = 1.0f; break; case PRIORITY_SLIDESHOW: - priority_string = "slideshow"; mSleepTime = 1.0f; break; case PRIORITY_LOW: - priority_string = "low"; mSleepTime = 1.0f / 50.0f; break; case PRIORITY_NORMAL: - priority_string = "normal"; mSleepTime = 1.0f / 100.0f; break; case PRIORITY_HIGH: - priority_string = "high"; mSleepTime = 1.0f / 100.0f; break; } @@ -794,6 +804,10 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) { mStatus = LLPluginClassMediaOwner::MEDIA_PAUSED; } + else if(status == "done") + { + mStatus = LLPluginClassMediaOwner::MEDIA_DONE; + } else { // empty string or any unknown string diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index 4f9763474e..90ecd1e073 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -150,6 +150,7 @@ public: PRIORITY_HIGH // media has user focus and/or is taking up most of the screen }EPriority; + static const char* priorityToString(EPriority priority); void setPriority(EPriority priority); void setLowPrioritySizeLimit(int size); diff --git a/indra/llplugin/llpluginclassmediaowner.h b/indra/llplugin/llpluginclassmediaowner.h index 4690f09172..c798af29ca 100644 --- a/indra/llplugin/llpluginclassmediaowner.h +++ b/indra/llplugin/llpluginclassmediaowner.h @@ -70,7 +70,8 @@ public: MEDIA_ERROR, // navigation/preroll failed MEDIA_PLAYING, // playing (only for time-based media) MEDIA_PAUSED, // paused (only for time-based media) - + MEDIA_DONE // finished playing (only for time-based media) + } EMediaStatus; virtual ~LLPluginClassMediaOwner() {}; diff --git a/indra/media_plugins/base/media_plugin_base.cpp b/indra/media_plugins/base/media_plugin_base.cpp index 0b7092fad6..6acac07423 100644 --- a/indra/media_plugins/base/media_plugin_base.cpp +++ b/indra/media_plugins/base/media_plugin_base.cpp @@ -64,6 +64,7 @@ std::string MediaPluginBase::statusString() case STATUS_ERROR: result = "error"; break; case STATUS_PLAYING: result = "playing"; break; case STATUS_PAUSED: result = "paused"; break; + case STATUS_DONE: result = "done"; break; default: // keep the empty string break; diff --git a/indra/media_plugins/base/media_plugin_base.h b/indra/media_plugins/base/media_plugin_base.h index 8f600cb8d6..f1e96335f9 100644 --- a/indra/media_plugins/base/media_plugin_base.h +++ b/indra/media_plugins/base/media_plugin_base.h @@ -56,6 +56,7 @@ protected: STATUS_ERROR, STATUS_PLAYING, STATUS_PAUSED, + STATUS_DONE } EStatus; class SharedSegmentInfo diff --git a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp index c9ee1c8ac7..fb6d5b2905 100644 --- a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp +++ b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp @@ -420,7 +420,7 @@ private: {
if ( mCommand == COMMAND_PLAY )
{
- if ( mStatus == STATUS_LOADED || mStatus == STATUS_PAUSED || mStatus == STATUS_PLAYING )
+ if ( mStatus == STATUS_LOADED || mStatus == STATUS_PAUSED || mStatus == STATUS_PLAYING || mStatus == STATUS_DONE )
{
long state = GetMovieLoadState( mMovieHandle );
@@ -446,7 +446,7 @@ private: else
if ( mCommand == COMMAND_STOP )
{
- if ( mStatus == STATUS_PLAYING || mStatus == STATUS_PAUSED )
+ if ( mStatus == STATUS_PLAYING || mStatus == STATUS_PAUSED || mStatus == STATUS_DONE )
{
if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK )
{
@@ -547,12 +547,12 @@ private: // see if title arrived and if so, update member variable with contents
checkTitle();
-
- // special code for looping - need to rewind at the end of the movie
- if ( mIsLooping )
+
+ // QT call to see if we are at the end - can't do with controller
+ if ( IsMovieDone( mMovieHandle ) )
{
- // QT call to see if we are at the end - can't do with controller
- if ( IsMovieDone( mMovieHandle ) )
+ // special code for looping - need to rewind at the end of the movie
+ if ( mIsLooping )
{
// go back to start
rewind();
@@ -565,8 +565,16 @@ private: // set the volume
MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume );
};
- };
- };
+ }
+ else
+ {
+ if(mStatus == STATUS_PLAYING)
+ {
+ setStatus(STATUS_DONE);
+ }
+ }
+ }
+
};
int getDataWidth() const
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 02fda191be..8bd74dcb04 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -156,10 +156,10 @@ public: { if(!mInitialized && ! mime_type.empty()) { - if (mMediaImpl->initializeMedia(mime_type)) + if(mMediaImpl->initializeMedia(mime_type)) { mInitialized = true; - mMediaImpl->play(); + mMediaImpl->loadURI(); } } } @@ -267,10 +267,6 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s { needs_navigate = (media_entry->getCurrentURL() != previous_url); } - else if(!media_entry->getHomeURL().empty()) - { - needs_navigate = (media_entry->getHomeURL() != previous_url); - } } } else @@ -293,8 +289,6 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s if(media_impl && needs_navigate) { std::string url = media_entry->getCurrentURL(); - if(url.empty()) - url = media_entry->getHomeURL(); media_impl->navigateTo(url, "", true, true); } @@ -639,13 +633,14 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id, mUsedInUI(false), mHasFocus(false), mPriority(LLPluginClassMedia::PRIORITY_UNLOADED), - mDoNavigateOnLoad(false), - mDoNavigateOnLoadRediscoverType(false), - mDoNavigateOnLoadServerRequest(false), + mNavigateRediscoverType(false), + mNavigateServerRequest(false), mMediaSourceFailed(false), mRequestedVolume(1.0f), mIsMuted(false), mNeedsMuteCheck(false), + mPreviousMediaState(MEDIA_NONE), + mPreviousMediaTime(0.0f), mIsUpdated(false) { @@ -716,7 +711,6 @@ bool LLViewerMediaImpl::initializeMedia(const std::string& mime_type) mMimeType = mime_type; } - // play(); return (mMediaSource != NULL); } @@ -729,16 +723,13 @@ void LLViewerMediaImpl::createMediaSource() return; } - if(mDoNavigateOnLoad) + if(! mMediaURL.empty()) { - if(! mMediaURL.empty()) - { - navigateTo(mMediaURL, mMimeType, mDoNavigateOnLoadRediscoverType, mDoNavigateOnLoadServerRequest); - } - else if(! mMimeType.empty()) - { - initializeMedia(mMimeType); - } + navigateInternal(); + } + else if(! mMimeType.empty()) + { + initializeMedia(mMimeType); } } @@ -869,6 +860,46 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type) return false; } +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::loadURI() +{ + if(mMediaSource) + { + mMediaSource->loadURI( mMediaURL ); + + if(mPreviousMediaState == MEDIA_PLAYING) + { + // This media was playing before this instance was unloaded. + + if(mPreviousMediaTime != 0.0f) + { + // Seek back to where we left off, if possible. + seek(mPreviousMediaTime); + } + + start(); + } + else if(mPreviousMediaState == MEDIA_PAUSED) + { + // This media was paused before this instance was unloaded. + + if(mPreviousMediaTime != 0.0f) + { + // Seek back to where we left off, if possible. + seek(mPreviousMediaTime); + } + + pause(); + } + else + { + // No relevant previous media play state -- if we're loading the URL, we want to start playing. + start(); + } + } +} + +////////////////////////////////////////////////////////////////////////////////////////// void LLViewerMediaImpl::setSize(int width, int height) { mMediaWidth = width; @@ -882,24 +913,21 @@ void LLViewerMediaImpl::setSize(int width, int height) ////////////////////////////////////////////////////////////////////////////////////////// void LLViewerMediaImpl::play() { - // first stop any previously playing media - // stop(); - - // mMediaSource->addObserver( this ); + // If the media source isn't there, try to initialize it and load an URL. if(mMediaSource == NULL) { - if(!initializePlugin(mMimeType)) + if(!initializeMedia(mMimeType)) { // This may be the case where the plugin's priority is PRIORITY_UNLOADED return; } + + // Only do this if the media source was just loaded. + loadURI(); } - mMediaSource->loadURI( mMediaURL ); - if(/*mMediaSource->pluginSupportsMediaTime()*/ true) - { - start(); - } + // always start the media + start(); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -1165,27 +1193,21 @@ void LLViewerMediaImpl::navigateHome() ////////////////////////////////////////////////////////////////////////////////////////// void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mime_type, bool rediscover_type, bool server_request) { - if(server_request) - { - setNavState(MEDIANAVSTATE_SERVER_SENT); - } - else + if(mMediaURL != url) { - setNavState(MEDIANAVSTATE_NONE); + // Don't carry media play state across distinct URLs. + resetPreviousMediaState(); } // Always set the current URL and MIME type. mMediaURL = url; mMimeType = mime_type; - // If the current URL is not null, make the instance do a navigate on load. - mDoNavigateOnLoad = !mMediaURL.empty(); - // if mime type discovery was requested, we'll need to do it when the media loads - mDoNavigateOnLoadRediscoverType = rediscover_type; + mNavigateRediscoverType = rediscover_type; // and if this was a server request, the navigate on load will also need to be one. - mDoNavigateOnLoadServerRequest = server_request; + mNavigateServerRequest = server_request; // An explicit navigate resets the "failed" flag. mMediaSourceFailed = false; @@ -1193,7 +1215,7 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi if(mPriority == LLPluginClassMedia::PRIORITY_UNLOADED) { // Helpful to have media urls in log file. Shouldn't be spammy. - llinfos << "UNLOADED media id= " << mTextureId << " url=" << url << " mime_type=" << mime_type << llendl; + llinfos << "NOT LOADING media id= " << mTextureId << " url=" << url << " mime_type=" << mime_type << llendl; // This impl should not be loaded at this time. LL_DEBUGS("PluginPriority") << this << "Not loading (PRIORITY_UNLOADED)" << LL_ENDL; @@ -1201,10 +1223,24 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi return; } + navigateInternal(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::navigateInternal() +{ // Helpful to have media urls in log file. Shouldn't be spammy. - llinfos << "media id= " << mTextureId << " url=" << url << " mime_type=" << mime_type << llendl; - - + llinfos << "media id= " << mTextureId << " url=" << mMediaURL << " mime_type=" << mMimeType << llendl; + + if(mNavigateServerRequest) + { + setNavState(MEDIANAVSTATE_SERVER_SENT); + } + else + { + setNavState(MEDIANAVSTATE_NONE); + } + // If the caller has specified a non-empty MIME type, look that up in our MIME types list. // If we have a plugin for that MIME type, use that instead of attempting auto-discovery. // This helps in supporting legacy media content where the server the media resides on returns a bogus MIME type @@ -1216,11 +1252,11 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi if(!plugin_basename.empty()) { // We have a plugin for this mime type - rediscover_type = false; + mNavigateRediscoverType = false; } } - if(rediscover_type) + if(mNavigateRediscoverType) { LLURI uri(mMediaURL); @@ -1236,7 +1272,7 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi // We use "data" internally for a text/html url for loading the login screen if(initializeMedia("text/html")) { - mMediaSource->loadURI( mMediaURL ); + loadURI(); } } else @@ -1244,24 +1280,18 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi // This catches 'rtsp://' urls if(initializeMedia(scheme)) { - mMediaSource->loadURI( mMediaURL ); + loadURI(); } } } - else if (mMediaSource) + else if(initializeMedia(mMimeType)) { - mMediaSource->loadURI( mMediaURL ); - } - else if(initializeMedia(mime_type) && mMediaSource) - { - mMediaSource->loadURI( mMediaURL ); + loadURI(); } else { - LL_WARNS("Media") << "Couldn't navigate to: " << url << " as there is no media type for: " << mime_type << LL_ENDL; - return; + LL_WARNS("Media") << "Couldn't navigate to: " << mMediaURL << " as there is no media type for: " << mMimeType << LL_ENDL; } - } ////////////////////////////////////////////////////////////////////////////////////////// @@ -1390,6 +1420,7 @@ void LLViewerMediaImpl::update() if(mMediaSource->isPluginExited()) { + resetPreviousMediaState(); destroyMediaSource(); return; } @@ -1586,6 +1617,14 @@ bool LLViewerMediaImpl::hasMedia() } ////////////////////////////////////////////////////////////////////////////////////////// +// +void LLViewerMediaImpl::resetPreviousMediaState() +{ + mPreviousMediaState = MEDIA_NONE; + mPreviousMediaTime = 0.0f; +} + +////////////////////////////////////////////////////////////////////////////////////////// void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginClassMediaOwner::EMediaEvent event) { switch(event) @@ -1595,6 +1634,9 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla // The plugin failed to load properly. Make sure the timer doesn't retry. // TODO: maybe mark this plugin as not loadable somehow? mMediaSourceFailed = true; + + // Reset the last known state of the media to defaults. + resetPreviousMediaState(); // TODO: may want a different message for this case? LLSD args; @@ -1608,6 +1650,9 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla // The plugin crashed. mMediaSourceFailed = true; + // Reset the last known state of the media to defaults. + resetPreviousMediaState(); + LLSD args; args["PLUGIN"] = LLMIMETypes::implType(mMimeType); // SJB: This is getting called every frame if the plugin fails to load, continuously respawining the alert! @@ -1833,11 +1878,11 @@ void LLViewerMediaImpl::setUsedInUI(bool used_in_ui) { if(getVisible()) { - mPriority = LLPluginClassMedia::PRIORITY_NORMAL; + setPriority(LLPluginClassMedia::PRIORITY_NORMAL); } else { - mPriority = LLPluginClassMedia::PRIORITY_HIDDEN; + setPriority(LLPluginClassMedia::PRIORITY_HIDDEN); } createMediaSource(); @@ -1858,6 +1903,15 @@ F64 LLViewerMediaImpl::getCPUUsage() const void LLViewerMediaImpl::setPriority(LLPluginClassMedia::EPriority priority) { + if(mPriority != priority) + { + LL_INFOS("PluginPriority") + << "changing priority of media id " << mTextureId + << " from " << LLPluginClassMedia::priorityToString(mPriority) + << " to " << LLPluginClassMedia::priorityToString(priority) + << LL_ENDL; + } + mPriority = priority; if(priority == LLPluginClassMedia::PRIORITY_UNLOADED) @@ -1865,6 +1919,11 @@ void LLViewerMediaImpl::setPriority(LLPluginClassMedia::EPriority priority) if(mMediaSource) { // Need to unload the media source + + // First, save off previous media state + mPreviousMediaState = mMediaSource->getStatus(); + mPreviousMediaTime = mMediaSource->getCurrentTime(); + destroyMediaSource(); } } diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index b15314e954..4f0d39dd80 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -123,6 +123,7 @@ public: void setMediaType(const std::string& media_type); bool initializeMedia(const std::string& mime_type); bool initializePlugin(const std::string& media_type); + void loadURI(); LLPluginClassMedia* getMediaPlugin() { return mMediaSource; } void setSize(int width, int height); @@ -151,6 +152,7 @@ public: void navigateReload(); void navigateHome(); void navigateTo(const std::string& url, const std::string& mime_type = "", bool rediscover_type = false, bool server_request = false); + void navigateInternal(); void navigateStop(); bool handleKeyHere(KEY key, MASK mask); bool handleUnicodeCharHere(llwchar uni_char); @@ -174,6 +176,7 @@ public: bool isMediaPaused(); bool hasMedia(); bool isMediaFailed() { return mMediaSourceFailed; }; + void resetPreviousMediaState(); ECursorType getLastSetCursor() { return mLastSetCursor; }; @@ -287,14 +290,14 @@ public: bool mUsedInUI; bool mHasFocus; LLPluginClassMedia::EPriority mPriority; - bool mDoNavigateOnLoad; - bool mDoNavigateOnLoadRediscoverType; - bool mDoNavigateOnLoadServerRequest; + bool mNavigateRediscoverType; + bool mNavigateServerRequest; bool mMediaSourceFailed; F32 mRequestedVolume; bool mIsMuted; bool mNeedsMuteCheck; - + int mPreviousMediaState; + F64 mPreviousMediaTime; private: BOOL mIsUpdated ; |