summaryrefslogtreecommitdiff
path: root/indra/newview/llviewerparcelmedia.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llviewerparcelmedia.cpp')
-rw-r--r--indra/newview/llviewerparcelmedia.cpp337
1 files changed, 254 insertions, 83 deletions
diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp
index 26e21133ac..cb233085e5 100644
--- a/indra/newview/llviewerparcelmedia.cpp
+++ b/indra/newview/llviewerparcelmedia.cpp
@@ -41,47 +41,22 @@
#include "llviewerparcelmgr.h"
#include "lluuid.h"
#include "message.h"
+#include "llviewermediafocus.h"
#include "llviewerparcelmediaautoplay.h"
#include "llviewerwindow.h"
#include "llfirstuse.h"
+#include "llpluginclassmedia.h"
// Static Variables
S32 LLViewerParcelMedia::sMediaParcelLocalID = 0;
LLUUID LLViewerParcelMedia::sMediaRegionID;
+viewer_media_t LLViewerParcelMedia::sMediaImpl;
+
// Local functions
bool callback_play_media(const LLSD& notification, const LLSD& response, LLParcel* parcel);
-// Move this to its own file.
-// helper class that tries to download a URL from a web site and calls a method
-// on the Panel Land Media and to discover the MIME type
-class LLMimeDiscoveryResponder : public LLHTTPClient::Responder
-{
-public:
- LLMimeDiscoveryResponder( )
- {}
-
-
-
- virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content)
- {
- std::string media_type = content["content-type"].asString();
- std::string::size_type idx1 = media_type.find_first_of(";");
- std::string mime_type = media_type.substr(0, idx1);
- completeAny(status, mime_type);
- }
-
- virtual void error( U32 status, const std::string& reason )
- {
- completeAny(status, "none/none");
- }
-
- void completeAny(U32 status, const std::string& mime_type)
- {
- LLViewerMedia::setMimeType(mime_type);
- }
-};
// static
void LLViewerParcelMedia::initClass()
@@ -92,6 +67,13 @@ void LLViewerParcelMedia::initClass()
LLViewerParcelMediaAutoPlay::initClass();
}
+//static
+void LLViewerParcelMedia::cleanupClass()
+{
+ // This needs to be destroyed before global destructor time.
+ sMediaImpl = NULL;
+}
+
//////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerParcelMedia::update(LLParcel* parcel)
@@ -105,6 +87,7 @@ void LLViewerParcelMedia::update(LLParcel* parcel)
{
sMediaRegionID = LLUUID() ;
stop() ;
+ LL_DEBUGS("Media") << "no agent region, bailing out." << LL_ENDL;
return ;
}
@@ -115,64 +98,54 @@ void LLViewerParcelMedia::update(LLParcel* parcel)
LLUUID regionid = gAgent.getRegion()->getRegionID();
if (parcelid != sMediaParcelLocalID || regionid != sMediaRegionID)
{
+ LL_DEBUGS("Media") << "New parcel, parcel id = " << parcelid << ", region id = " << regionid << LL_ENDL;
sMediaParcelLocalID = parcelid;
sMediaRegionID = regionid;
new_parcel = true;
}
std::string mediaUrl = std::string ( parcel->getMediaURL () );
+ std::string mediaCurrentUrl = std::string( parcel->getMediaCurrentURL());
+
+ // First use warning
+ if( ! mediaUrl.empty() && gWarningSettings.getBOOL("FirstStreamingVideo") )
+ {
+ LLNotifications::instance().add("ParcelCanPlayMedia", LLSD(), LLSD(),
+ boost::bind(callback_play_media, _1, _2, parcel));
+ return;
+
+ }
+
+ // if we have a current (link sharing) url, use it instead
+ if (mediaCurrentUrl != "" && parcel->getMediaType() == "text/html")
+ {
+ mediaUrl = mediaCurrentUrl;
+ }
+
LLStringUtil::trim(mediaUrl);
+
+ // If no parcel media is playing, nothing left to do
+ if(sMediaImpl.isNull())
- // has something changed?
- if ( ( LLViewerMedia::getMediaURL() != mediaUrl )
- || ( LLViewerMedia::getMediaTextureID() != parcel->getMediaID () ) )
{
- bool video_was_playing = FALSE;
- bool same_media_id = LLViewerMedia::getMediaTextureID() == parcel->getMediaID ();
+ return;
+ }
- if (LLViewerMedia::isMediaPlaying())
+ // Media is playing...has something changed?
+ else if (( sMediaImpl->getMediaURL() != mediaUrl )
+ || ( sMediaImpl->getMediaTextureID() != parcel->getMediaID() )
+ || ( sMediaImpl->getMimeType() != parcel->getMediaType() ))
+ {
+ // Only play if the media types are the same.
+ if(sMediaImpl->getMimeType() == parcel->getMediaType())
{
- video_was_playing = TRUE;
+ play(parcel);
}
- if ( !mediaUrl.empty() && same_media_id && ! new_parcel)
- {
- // Someone has "changed the channel", changing the URL of a video
- // you were already watching. Automatically play provided the texture ID is the same
- if (video_was_playing)
- {
- // Poke the mime type in before calling play.
- // This is necessary because in this instance we are not waiting
- // for the results of a header curl. In order to change the channel
- // a mime type MUST be provided.
- LLViewerMedia::setMimeType(parcel->getMediaType());
- play(parcel);
- }
- }
else
{
stop();
}
-
- // Discover the MIME type
- // Disabled for the time being. Get the mime type from the parcel.
- if(gSavedSettings.getBOOL("AutoMimeDiscovery"))
- {
- LLHTTPClient::getHeaderOnly( mediaUrl, new LLMimeDiscoveryResponder());
- }
- else
- {
- LLViewerMedia::setMimeType(parcel->getMediaType());
- }
-
- // First use warning
- if( gWarningSettings.getBOOL("FirstStreamingVideo") )
- {
- LLNotifications::instance().add("ParcelCanPlayMedia", LLSD(), LLSD(),
- boost::bind(callback_play_media, _1, _2, parcel));
-
- }
-
}
}
else
@@ -183,7 +156,7 @@ void LLViewerParcelMedia::update(LLParcel* parcel)
/*
else
{
- // no audio player, do a first use dialog if their is media here
+ // no audio player, do a first use dialog if there is media here
if (parcel)
{
std::string mediaUrl = std::string ( parcel->getMediaURL () );
@@ -212,15 +185,53 @@ void LLViewerParcelMedia::play(LLParcel* parcel)
return;
std::string media_url = parcel->getMediaURL();
+ std::string media_current_url = parcel->getMediaCurrentURL();
std::string mime_type = parcel->getMediaType();
LLUUID placeholder_texture_id = parcel->getMediaID();
U8 media_auto_scale = parcel->getMediaAutoScale();
U8 media_loop = parcel->getMediaLoop();
S32 media_width = parcel->getMediaWidth();
S32 media_height = parcel->getMediaHeight();
- LLViewerMedia::play(media_url, mime_type, placeholder_texture_id,
- media_width, media_height, media_auto_scale,
- media_loop);
+
+ if(sMediaImpl)
+ {
+ // If the url and mime type are the same, call play again
+ if(sMediaImpl->getMediaURL() == media_url
+ && sMediaImpl->getMimeType() == mime_type
+ && sMediaImpl->getMediaTextureID() == placeholder_texture_id)
+ {
+ LL_DEBUGS("Media") << "playing with existing url " << media_url << LL_ENDL;
+
+ sMediaImpl->play();
+ }
+ // Else if the texture id's are the same, navigate and rediscover type
+ // MBW -- This causes other state from the previous parcel (texture size, autoscale, and looping) to get re-used incorrectly.
+ // It's also not really necessary -- just creating a new instance is fine.
+// else if(sMediaImpl->getMediaTextureID() == placeholder_texture_id)
+// {
+// sMediaImpl->navigateTo(media_url, mime_type, true);
+// }
+ else
+ {
+ // Since the texture id is different, we need to generate a new impl
+ LL_DEBUGS("Media") << "new media impl with mime type " << mime_type << ", url " << media_url << LL_ENDL;
+
+ // Delete the old one first so they don't fight over the texture.
+ sMediaImpl->stop();
+
+ sMediaImpl = LLViewerMedia::newMediaImpl(media_url, placeholder_texture_id,
+ media_width, media_height, media_auto_scale,
+ media_loop);
+ }
+ }
+ else
+ {
+ // There is no media impl, make a new one
+ sMediaImpl = LLViewerMedia::newMediaImpl(media_url, placeholder_texture_id,
+ media_width, media_height, media_auto_scale,
+ media_loop);
+ }
+
LLFirstUse::useMedia();
LLViewerParcelMediaAutoPlay::playStarted();
@@ -229,20 +240,38 @@ void LLViewerParcelMedia::play(LLParcel* parcel)
// static
void LLViewerParcelMedia::stop()
{
+ if(sMediaImpl.isNull())
+ {
+ return;
+ }
+
+ // We need to remove the media HUD if it is up.
+ LLViewerMediaFocus::getInstance()->clearFocus();
- LLViewerMedia::stop();
+ // This will kill the media instance.
+ sMediaImpl->stop();
+ sMediaImpl = NULL;
}
// static
void LLViewerParcelMedia::pause()
{
- LLViewerMedia::pause();
+ if(sMediaImpl.isNull())
+ {
+ return;
+ }
+ sMediaImpl->pause();
}
// static
void LLViewerParcelMedia::start()
{
- LLViewerMedia::start();
+ if(sMediaImpl.isNull())
+ {
+ return;
+ }
+ sMediaImpl->start();
+
LLFirstUse::useMedia();
LLViewerParcelMediaAutoPlay::playStarted();
@@ -251,16 +280,41 @@ void LLViewerParcelMedia::start()
// static
void LLViewerParcelMedia::seek(F32 time)
{
- LLViewerMedia::seek(time);
+ if(sMediaImpl.isNull())
+ {
+ return;
+ }
+ sMediaImpl->seek(time);
}
-
// static
-LLMediaBase::EStatus LLViewerParcelMedia::getStatus()
+void LLViewerParcelMedia::focus(bool focus)
{
- return LLViewerMedia::getStatus();
+ sMediaImpl->focus(focus);
}
+// static
+LLPluginClassMediaOwner::EMediaStatus LLViewerParcelMedia::getStatus()
+{
+ LLPluginClassMediaOwner::EMediaStatus result = LLPluginClassMediaOwner::MEDIA_NONE;
+
+ if(sMediaImpl.notNull() && sMediaImpl->hasMedia())
+ {
+ result = sMediaImpl->getMediaPlugin()->getStatus();
+ }
+
+ return result;
+}
+
+// static
+std::string LLViewerParcelMedia::getMimeType()
+{
+ return sMediaImpl.notNull() ? sMediaImpl->getMimeType() : "none/none";
+}
+viewer_media_t LLViewerParcelMedia::getParcelMedia()
+{
+ return sMediaImpl;
+}
//////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerParcelMedia::processParcelMediaCommandMessage( LLMessageSystem *msg, void ** )
@@ -298,7 +352,7 @@ void LLViewerParcelMedia::processParcelMediaCommandMessage( LLMessageSystem *msg
if(( command == PARCEL_MEDIA_COMMAND_PLAY ) ||
( command == PARCEL_MEDIA_COMMAND_LOOP ))
{
- if (LLViewerMedia::isMediaPaused())
+ if (getStatus() == LLViewerMediaImpl::MEDIA_PAUSED)
{
start();
}
@@ -318,7 +372,7 @@ void LLViewerParcelMedia::processParcelMediaCommandMessage( LLMessageSystem *msg
if (flags & (1<<PARCEL_MEDIA_COMMAND_TIME))
{
- if(! LLViewerMedia::hasMedia())
+ if(sMediaImpl.isNull())
{
LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
play(parcel);
@@ -382,6 +436,107 @@ void LLViewerParcelMedia::processParcelMediaUpdate( LLMessageSystem *msg, void *
}
}
}
+// Static
+/////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerParcelMedia::sendMediaNavigateMessage(const std::string& url)
+{
+ std::string region_url = gAgent.getRegion()->getCapability("ParcelNavigateMedia");
+ if (!region_url.empty())
+ {
+ // send navigate event to sim for link sharing
+ LLSD body;
+ body["agent-id"] = gAgent.getID();
+ body["local-id"] = LLViewerParcelMgr::getInstance()->getAgentParcel()->getLocalID();
+ body["url"] = url;
+ LLHTTPClient::post(region_url, body, new LLHTTPClient::Responder);
+ }
+ else
+ {
+ llwarns << "can't get ParcelNavigateMedia capability" << llendl;
+ }
+
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// inherited from LLViewerMediaObserver
+// virtual
+void LLViewerParcelMedia::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
+{
+ switch(event)
+ {
+ case MEDIA_EVENT_CONTENT_UPDATED:
+ {
+ // LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CONTENT_UPDATED " << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_TIME_DURATION_UPDATED:
+ {
+ // LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_TIME_DURATION_UPDATED, time is " << self->getCurrentTime() << " of " << self->getDuration() << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_SIZE_CHANGED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_SIZE_CHANGED " << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_CURSOR_CHANGED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_NAVIGATE_BEGIN:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN " << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_NAVIGATE_COMPLETE:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_COMPLETE, result string is: " << self->getNavigateResultString() << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_PROGRESS_UPDATED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PROGRESS_UPDATED, loading at " << self->getProgressPercent() << "%" << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_STATUS_TEXT_CHANGED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_STATUS_TEXT_CHANGED, new status text is: " << self->getStatusText() << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_LOCATION_CHANGED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_LOCATION_CHANGED, new uri is: " << self->getLocation() << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_CLICK_LINK_HREF:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << self->getClickTarget() << "\", uri is " << self->getClickURL() << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_CLICK_LINK_NOFOLLOW:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_PLUGIN_FAILED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED" << LL_ENDL;
+ };
+ break;
+ };
+}
bool callback_play_media(const LLSD& notification, const LLSD& response, LLParcel* parcel)
{
@@ -401,3 +556,19 @@ bool callback_play_media(const LLSD& notification, const LLSD& response, LLParce
return false;
}
+// TODO: observer
+/*
+void LLViewerParcelMediaNavigationObserver::onNavigateComplete( const EventType& event_in )
+{
+ std::string url = event_in.getStringValue();
+
+ if (mCurrentURL != url && ! mFromMessage)
+ {
+ LLViewerParcelMedia::sendMediaNavigateMessage(url);
+ }
+
+ mCurrentURL = url;
+ mFromMessage = false;
+
+}
+*/