llviewerparcelmedia.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 #include "llviewerparcelmedia.h"
00034 
00035 #include "llagent.h"
00036 #include "llviewercontrol.h"
00037 #include "llviewermedia.h"
00038 #include "llviewerregion.h"
00039 #include "llparcel.h"
00040 #include "llviewerparcelmgr.h"
00041 #include "lluuid.h"
00042 #include "message.h"
00043 #include "llviewerparcelmediaautoplay.h"
00044 #include "llviewerwindow.h"
00045 #include "llfirstuse.h"
00046 
00047 // Static Variables
00048 
00049 S32 LLViewerParcelMedia::sMediaParcelLocalID = 0;
00050 LLUUID LLViewerParcelMedia::sMediaRegionID;
00051 
00052 // Local functions
00053 void callback_play_media(S32 option, void* data);
00054 
00055 // Move this to its own file.
00056 // helper class that tries to download a URL from a web site and calls a method
00057 // on the Panel Land Media and to discover the MIME type
00058 class LLMimeDiscoveryResponder : public LLHTTPClient::Responder
00059 {
00060 public:
00061         LLMimeDiscoveryResponder( )
00062           {}
00063 
00064 
00065 
00066           virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content)
00067           {
00068                   std::string media_type = content["content-type"].asString();
00069                   std::string::size_type idx1 = media_type.find_first_of(";");
00070                   std::string mime_type = media_type.substr(0, idx1);
00071                   completeAny(status, mime_type);
00072           }
00073 
00074           virtual void error( U32 status, const std::string& reason )
00075           {
00076                   completeAny(status, "none/none");
00077           }
00078 
00079           void completeAny(U32 status, const std::string& mime_type)
00080           {
00081                   LLViewerMedia::setMimeType(mime_type);
00082           }
00083 };
00084 
00085 // static
00086 void LLViewerParcelMedia::initClass()
00087 {
00088         LLMessageSystem* msg = gMessageSystem;
00089         msg->setHandlerFunc("ParcelMediaCommandMessage", processParcelMediaCommandMessage );
00090         msg->setHandlerFunc("ParcelMediaUpdate", processParcelMediaUpdate );
00091         LLViewerParcelMediaAutoPlay::initClass();
00092 }
00093 
00095 // static
00096 void LLViewerParcelMedia::update(LLParcel* parcel)
00097 {
00098         if (/*LLViewerMedia::hasMedia()*/ true)
00099         {
00100                 // we have a player
00101                 if (parcel)
00102                 {
00103                         // we're in a parcel
00104                         bool new_parcel = false;
00105                         S32 parcelid = parcel->getLocalID();
00106                         
00107                         if(!gAgent.getRegion())
00108                         {
00109                                 llerrs << "gAgent's region is NULL." << llendl ;                                
00110                         }
00111 
00112                         LLUUID regionid = gAgent.getRegion()->getRegionID();
00113                         if (parcelid != sMediaParcelLocalID || regionid != sMediaRegionID)
00114                         {
00115                                 sMediaParcelLocalID = parcelid;
00116                                 sMediaRegionID = regionid;
00117                                 new_parcel = true;
00118                         }
00119 
00120                         std::string mediaUrl = std::string ( parcel->getMediaURL () );
00121                         LLString::trim(mediaUrl);
00122 
00123                         // has something changed?
00124                         if (  ( LLViewerMedia::getMediaURL() != mediaUrl )
00125                                 || ( LLViewerMedia::getMediaTextureID() != parcel->getMediaID () ) )
00126                         {
00127                                 bool video_was_playing = FALSE;
00128                                 bool same_media_id = LLViewerMedia::getMediaTextureID() == parcel->getMediaID ();
00129 
00130                                 if (LLViewerMedia::isMediaPlaying())
00131                                 {
00132                                         video_was_playing = TRUE;
00133                                 }
00134 
00135                                 if ( !mediaUrl.empty() && same_media_id && ! new_parcel)
00136                                 {
00137                                         // Someone has "changed the channel", changing the URL of a video
00138                                         // you were already watching.  Automatically play provided the texture ID is the same
00139                                         if (video_was_playing)
00140                                         {
00141                                                 // Poke the mime type in before calling play.
00142                                                 // This is necessary because in this instance we are not waiting
00143                                                 // for the results of a header curl.  In order to change the channel
00144                                                 // a mime type MUST be provided.
00145                                                 LLViewerMedia::setMimeType(parcel->getMediaType());
00146                                                 play(parcel);
00147                                         }
00148                                 }
00149                                 else
00150                                 {
00151                                         stop();
00152                                 }
00153 
00154                                 // Discover the MIME type
00155                                 // Disabled for the time being.  Get the mime type from the parcel.
00156                                 if(gSavedSettings.getBOOL("AutoMimeDiscovery"))
00157                                 {
00158                                         LLHTTPClient::getHeaderOnly( mediaUrl, new LLMimeDiscoveryResponder());
00159                                 }
00160                                 else
00161                                 {
00162                                         LLViewerMedia::setMimeType(parcel->getMediaType());
00163                                 }
00164 
00165                                 // First use warning
00166                                 if(     gSavedSettings.getWarning("FirstStreamingVideo") )
00167                                 {
00168                                         gViewerWindow->alertXml("ParcelCanPlayMedia",
00169                                                 callback_play_media, (void*)parcel);
00170 
00171                                 }
00172 
00173                         }
00174                 }
00175                 else
00176                 {
00177                         stop();
00178                 }
00179         }
00180         /*
00181         else
00182         {
00183                 // no audio player, do a first use dialog if their is media here
00184                 if (parcel)
00185                 {
00186                         std::string mediaUrl = std::string ( parcel->getMediaURL () );
00187                         if (!mediaUrl.empty ())
00188                         {
00189                                 if (gSavedSettings.getWarning("QuickTimeInstalled"))
00190                                 {
00191                                         gSavedSettings.setWarning("QuickTimeInstalled", FALSE);
00192 
00193                                         LLNotifyBox::showXml("NoQuickTime" );
00194                                 };
00195                         }
00196                 }
00197         }
00198         */
00199 }
00200 
00201 // static
00202 void LLViewerParcelMedia::play(LLParcel* parcel)
00203 {
00204         lldebugs << "LLViewerParcelMedia::play" << llendl;
00205 
00206         if (!parcel) return;
00207 
00208         if (!gSavedSettings.getBOOL("AudioStreamingVideo"))
00209                 return;
00210 
00211         std::string media_url = parcel->getMediaURL();
00212         std::string mime_type = parcel->getMediaType();
00213         LLUUID placeholder_texture_id = parcel->getMediaID();
00214         U8 media_auto_scale = parcel->getMediaAutoScale();
00215         U8 media_loop = parcel->getMediaLoop();
00216         S32 media_width = parcel->getMediaWidth();
00217         S32 media_height = parcel->getMediaHeight();
00218         LLViewerMedia::play(media_url, mime_type, placeholder_texture_id,
00219                                                 media_width, media_height, media_auto_scale,
00220                                                 media_loop);
00221         LLFirstUse::useMedia();
00222 
00223         LLViewerParcelMediaAutoPlay::playStarted();
00224 }
00225 
00226 // static
00227 void LLViewerParcelMedia::stop()
00228 {
00229 
00230         LLViewerMedia::stop();
00231 }
00232 
00233 // static
00234 void LLViewerParcelMedia::pause()
00235 {
00236         LLViewerMedia::pause();
00237 }
00238 
00239 // static
00240 void LLViewerParcelMedia::start()
00241 {
00242         LLViewerMedia::start();
00243         LLFirstUse::useMedia();
00244 
00245         LLViewerParcelMediaAutoPlay::playStarted();
00246 }
00247 
00248 // static
00249 void LLViewerParcelMedia::seek(F32 time)
00250 {
00251         LLViewerMedia::seek(time);
00252 }
00253 
00254 
00255 // static
00256 LLMediaBase::EStatus LLViewerParcelMedia::getStatus()
00257 {
00258         return LLViewerMedia::getStatus();
00259 }
00260 
00262 // static
00263 void LLViewerParcelMedia::processParcelMediaCommandMessage( LLMessageSystem *msg, void ** )
00264 {
00265         // extract the agent id
00266         //      LLUUID agent_id;
00267         //      msg->getUUID( agent_id );
00268 
00269         U32 flags;
00270         U32 command;
00271         F32 time;
00272         msg->getU32( "CommandBlock", "Flags", flags );
00273         msg->getU32( "CommandBlock", "Command", command);
00274         msg->getF32( "CommandBlock", "Time", time );
00275 
00276         if (flags &( (1<<PARCEL_MEDIA_COMMAND_STOP)
00277                                 | (1<<PARCEL_MEDIA_COMMAND_PAUSE)
00278                                 | (1<<PARCEL_MEDIA_COMMAND_PLAY)
00279                                 | (1<<PARCEL_MEDIA_COMMAND_LOOP)
00280                                 | (1<<PARCEL_MEDIA_COMMAND_UNLOAD) ))
00281         {
00282                 // stop
00283                 if( command == PARCEL_MEDIA_COMMAND_STOP )
00284                 {
00285                         stop();
00286                 }
00287                 else
00288                 // pause
00289                 if( command == PARCEL_MEDIA_COMMAND_PAUSE )
00290                 {
00291                         pause();
00292                 }
00293                 else
00294                 // play
00295                 if(( command == PARCEL_MEDIA_COMMAND_PLAY ) ||
00296                    ( command == PARCEL_MEDIA_COMMAND_LOOP ))
00297                 {
00298                         if (LLViewerMedia::isMediaPaused())
00299                         {
00300                                 start();
00301                         }
00302                         else
00303                         {
00304                                 LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
00305                                 play(parcel);
00306                         }
00307                 }
00308                 else
00309                 // unload
00310                 if( command == PARCEL_MEDIA_COMMAND_UNLOAD )
00311                 {
00312                         stop();
00313                 }
00314         }
00315 
00316         if (flags & (1<<PARCEL_MEDIA_COMMAND_TIME))
00317         {
00318                 if(! LLViewerMedia::hasMedia())
00319                 {
00320                         LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
00321                         play(parcel);
00322                 }
00323                 seek(time);
00324         }
00325 }
00326 
00328 // static
00329 void LLViewerParcelMedia::processParcelMediaUpdate( LLMessageSystem *msg, void ** )
00330 {
00331         LLUUID media_id;
00332         std::string media_url;
00333         std::string media_type;
00334         S32 media_width = 0;
00335         S32 media_height = 0;
00336         U8 media_auto_scale = FALSE;
00337         U8 media_loop = FALSE;
00338 
00339         msg->getUUID( "DataBlock", "MediaID", media_id );
00340         char media_url_buffer[257];
00341         msg->getString( "DataBlock", "MediaURL", 255, media_url_buffer );
00342         media_url = media_url_buffer;
00343         msg->getU8("DataBlock", "MediaAutoScale", media_auto_scale);
00344 
00345         if (msg->getNumberOfBlocks("DataBlockExtended")) // do we have the extended data?
00346         {
00347                 char media_type_buffer[257];
00348                 msg->getString("DataBlockExtended", "MediaType", 255, media_type_buffer);
00349                 media_type = media_type_buffer;
00350                 msg->getU8("DataBlockExtended", "MediaLoop", media_loop);
00351                 msg->getS32("DataBlockExtended", "MediaWidth", media_width);
00352                 msg->getS32("DataBlockExtended", "MediaHeight", media_height);
00353         }
00354 
00355         LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
00356         BOOL same = FALSE;
00357         if (parcel)
00358         {
00359                 same = ((parcel->getMediaURL() == media_url) &&
00360                                 (parcel->getMediaType() == media_type) &&
00361                                 (parcel->getMediaID() == media_id) &&
00362                                 (parcel->getMediaWidth() == media_width) &&
00363                                 (parcel->getMediaHeight() == media_height) &&
00364                                 (parcel->getMediaAutoScale() == media_auto_scale) &&
00365                                 (parcel->getMediaLoop() == media_loop));
00366 
00367                 if (!same)
00368                 {
00369                         // temporarily store these new values in the parcel
00370                         parcel->setMediaURL(media_url);
00371                         parcel->setMediaType(media_type.c_str());
00372                         parcel->setMediaID(media_id);
00373                         parcel->setMediaWidth(media_width);
00374                         parcel->setMediaHeight(media_height);
00375                         parcel->setMediaAutoScale(media_auto_scale);
00376                         parcel->setMediaLoop(media_loop);
00377 
00378                         play(parcel);
00379                 }
00380         }
00381 }
00382 
00383 void callback_play_media(S32 option, void* data)
00384 {
00385         LLParcel* parcel = (LLParcel*)data;
00386         if (option == 0)
00387         {
00388                 gSavedSettings.setBOOL("AudioStreamingVideo", TRUE);
00389                 LLViewerParcelMedia::play(parcel);
00390         }
00391         else
00392         {
00393                 gSavedSettings.setBOOL("AudioStreamingVideo", FALSE);
00394         }
00395         gSavedSettings.setWarning("FirstStreamingVideo", FALSE);
00396 
00397 }
00398 

Generated on Fri May 16 08:34:15 2008 for SecondLife by  doxygen 1.5.5