llviewermedia.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "llviewermedia.h"
00035 
00036 #include "llmimetypes.h"
00037 #include "llviewercontrol.h"
00038 #include "llviewerimage.h"
00039 #include "llviewerwindow.h"
00040 #include "llversionviewer.h"
00041 #include "llviewerimagelist.h"
00042 
00043 #include "llevent.h"            // LLSimpleListener
00044 #include "llmediamanager.h"
00045 #include "lluuid.h"
00046 
00047 // Implementation functions not exported into header file
00048 class LLViewerMediaImpl
00049         :       public LLMediaObserver
00050 {
00051         public:
00052                 LLViewerMediaImpl()
00053                 :       mMediaSource( NULL ),
00054                         mMovieImageID(),
00055                         mMovieImageHasMips(false)
00056                 { }
00057 
00058                 void initControlListeners();
00059 
00060                 void destroyMediaSource();
00061 
00062             void play(const std::string& media_url,
00063                                   const std::string& mime_type,
00064                                   const LLUUID& placeholder_texture_id,
00065                                   S32 media_width, S32 media_height, U8 media_auto_scale,
00066                                   U8 media_loop);
00067 
00068                 void stop();
00069                 void pause();
00070                 void start();
00071         void seek(F32 time);
00072         void setVolume(F32 volume);
00073                 LLMediaBase::EStatus getStatus();
00074 
00075                 /*virtual*/ void onMediaSizeChange(const EventType& event_in);
00076                 /*virtual*/ void onMediaContentsChange(const EventType& event_in);
00077 
00078                 void updateMovieImage(const LLUUID& image_id, BOOL active);
00079                 void updateImagesMediaStreams();
00080                 LLUUID getMediaTextureID();
00081 
00082         public:
00083 
00084                 // a single media url with some data and an impl.
00085                 LLMediaBase* mMediaSource;
00086                 LLUUID mMovieImageID;
00087                 bool  mMovieImageHasMips;
00088                 std::string mMediaURL;
00089                 std::string mMimeType;
00090     private:
00091             void initializePlaceholderImage(LLViewerImage *placeholder_image, LLMediaBase *media_source);
00092 };
00093 
00094 static LLViewerMediaImpl sViewerMediaImpl;
00095 
00096 void LLViewerMediaImpl::destroyMediaSource()
00097 {
00098         LLMediaManager* mgr = LLMediaManager::getInstance();
00099         if ( mMediaSource )
00100         {
00101                 bool was_playing = LLViewerMedia::isMediaPlaying();
00102                 mMediaSource->remObserver(this);
00103                 mgr->destroySource( mMediaSource );
00104 
00105                 // Restore the texture
00106                 updateMovieImage(LLUUID::null, was_playing);
00107 
00108         }
00109         mMediaSource = NULL;
00110 }
00111 
00112 void LLViewerMediaImpl::play(const std::string& media_url,
00113                                                          const std::string& mime_type,
00114                                                          const LLUUID& placeholder_texture_id,
00115                                                          S32 media_width, S32 media_height, U8 media_auto_scale,
00116                                                          U8 media_loop)
00117 {
00118         // first stop any previously playing media
00119         stop();
00120 
00121         // Save this first, as init/load below may fire events
00122         mMovieImageID = placeholder_texture_id;
00123 
00124         // If the mime_type passed in is different than the cached one, and
00125         // Auto-discovery is turned OFF, replace the cached mime_type with the new one.
00126         if(mime_type != mMimeType &&
00127                 ! gSavedSettings.getBOOL("AutoMimeDiscovery"))
00128         {
00129                 mMimeType = mime_type;
00130         }
00131         LLURI url(media_url);
00132         std::string scheme = url.scheme() != "" ? url.scheme() : "http";
00133 
00134         LLMediaManager* mgr = LLMediaManager::getInstance();
00135         mMediaSource = mgr->createSourceFromMimeType(scheme, mMimeType );
00136         if ( !mMediaSource )
00137         {
00138                 if (mMimeType != "none/none")
00139                 {
00140                         llwarns << "media source create failed " << media_url
00141                                         << " type " << mMimeType
00142                                         << llendl;
00143                 }
00144                 return;
00145         }
00146 
00147         // Store the URL and Mime Type
00148         mMediaURL = media_url;
00149 
00150         if ((media_width != 0) && (media_height != 0))
00151         {
00152                 mMediaSource->setRequestedMediaSize(media_width, media_height);
00153         }
00154 
00155         mMediaSource->setLooping(media_loop);
00156         mMediaSource->setAutoScaled(media_auto_scale);
00157         mMediaSource->addObserver( this );
00158         mMediaSource->navigateTo( media_url );
00159         mMediaSource->addCommand(LLMediaBase::COMMAND_START);
00160 }
00161 
00162 void LLViewerMediaImpl::stop()
00163 {
00164         destroyMediaSource();
00165 }
00166 
00167 void LLViewerMediaImpl::pause()
00168 {
00169         if(mMediaSource)
00170         {
00171                 mMediaSource->addCommand(LLMediaBase::COMMAND_PAUSE);
00172         }
00173 }
00174 
00175 void LLViewerMediaImpl::start()
00176 {
00177         if(mMediaSource)
00178         {
00179                 mMediaSource->addCommand(LLMediaBase::COMMAND_START);
00180         }
00181 }
00182 
00183 void LLViewerMediaImpl::seek(F32 time)
00184 {
00185         if(mMediaSource)
00186         {
00187                 mMediaSource->seek(time);
00188         }
00189 }
00190 
00191 void LLViewerMediaImpl::setVolume(F32 volume)
00192 {
00193         if(mMediaSource)
00194         {
00195                 mMediaSource->setVolume( volume);
00196         }
00197 }
00198 
00199 LLMediaBase::EStatus LLViewerMediaImpl::getStatus()
00200 {
00201         if (mMediaSource)
00202         {
00203                 return mMediaSource->getStatus();
00204         }
00205         else
00206         {
00207                 return LLMediaBase::STATUS_UNKNOWN;
00208         }
00209 }
00210 
00212 // static
00213 void LLViewerMediaImpl::updateMovieImage(const LLUUID& uuid, BOOL active)
00214 {
00215         // IF the media image hasn't changed, do nothing
00216         if (mMovieImageID == uuid)
00217         {
00218                 return;
00219         }
00220         // If we have changed media uuid, restore the old one
00221         if (!mMovieImageID.isNull())
00222         {
00223                 LLViewerImage* oldImage = LLViewerImage::getImage( mMovieImageID );
00224                 if (oldImage)
00225                 {
00226                         oldImage->reinit(mMovieImageHasMips);
00227                         oldImage->mIsMediaTexture = FALSE;
00228                 }
00229                 mMovieImageID.setNull();
00230         }
00231         // If the movie is playing, set the new media image
00232         if (active && !uuid.isNull())
00233         {
00234                 LLViewerImage* viewerImage = LLViewerImage::getImage( uuid );
00235                 if( viewerImage )
00236                 {
00237                         mMovieImageID = uuid;
00238                         // Can't use mipmaps for movies because they don't update the full image
00239                         mMovieImageHasMips = viewerImage->getUseMipMaps();
00240                         viewerImage->reinit(FALSE);
00241                         viewerImage->mIsMediaTexture = TRUE;
00242                 }
00243         }
00244 }
00245 
00246 
00248 // static
00249 void LLViewerMediaImpl::updateImagesMediaStreams()
00250 {
00251         LLMediaManager::updateClass();
00252 }
00253 
00254 void LLViewerMediaImpl::initializePlaceholderImage(LLViewerImage *placeholder_image, LLMediaBase *media_source)
00255 {
00256         int media_width = media_source->getMediaWidth();
00257         int media_height = media_source->getMediaHeight();
00258         //int media_rowspan = media_source->getMediaRowSpan();
00259 
00260         // if width & height are invalid, don't bother doing anything
00261         if ( media_width < 1 || media_height < 1 )
00262                 return;
00263 
00264         llinfos << "initializing media placeholder" << llendl;
00265         llinfos << "movie image id " << mMovieImageID << llendl;
00266 
00267         int texture_width = LLMediaManager::textureWidthFromMediaWidth( media_width );
00268         int texture_height = LLMediaManager::textureHeightFromMediaHeight( media_height );
00269         int texture_depth = media_source->getMediaDepth();
00270 
00271         // MEDIAOPT: check to see if size actually changed before doing work
00272         placeholder_image->destroyGLTexture();
00273         // MEDIAOPT: apparently just calling setUseMipMaps(FALSE) doesn't work?
00274         placeholder_image->reinit(FALSE);       // probably not needed
00275 
00276         // MEDIAOPT: seems insane that we actually have to make an imageraw then
00277         // immediately discard it
00278         LLPointer<LLImageRaw> raw = new LLImageRaw(texture_width, texture_height, texture_depth);
00279         raw->clear(0x0f, 0x0f, 0x0f, 0xff);
00280         int discard_level = 0;
00281 
00282         // ask media source for correct GL image format constants
00283         placeholder_image->setExplicitFormat(media_source->getTextureFormatInternal(),
00284                                                                                  media_source->getTextureFormatPrimary(),
00285                                                                                  media_source->getTextureFormatType());
00286 
00287         placeholder_image->createGLTexture(discard_level, raw);
00288 
00289         // placeholder_image->setExplicitFormat()
00290         placeholder_image->setUseMipMaps(FALSE);
00291 
00292         // MEDIAOPT: set this dynamically on play/stop
00293         placeholder_image->mIsMediaTexture = true;
00294 }
00295 
00296 
00297 
00298 // virtual
00299 void LLViewerMediaImpl::onMediaContentsChange(const EventType& event_in)
00300 {
00301         LLMediaBase* media_source = event_in.getSubject();
00302         LLViewerImage* placeholder_image = gImageList.getImage( mMovieImageID );
00303         if ((placeholder_image) && (placeholder_image->getHasGLTexture()))
00304         {
00305                 if (placeholder_image->getUseMipMaps())
00306                 {
00307                         // bad image!  NO MIPMAPS!
00308                         initializePlaceholderImage(placeholder_image, media_source);
00309                 }
00310 
00311                 U8* data = media_source->getMediaData();
00312                 S32 x_pos = 0;
00313                 S32 y_pos = 0;
00314                 S32 width = media_source->getMediaWidth();
00315                 S32 height = media_source->getMediaHeight();
00316                 S32 data_width = media_source->getMediaDataWidth();
00317                 S32 data_height = media_source->getMediaDataHeight();
00318                 placeholder_image->setSubImage(data, data_width, data_height,
00319                         x_pos, y_pos, width, height);
00320         }
00321 }
00322 
00323 
00324 // virtual
00325 void LLViewerMediaImpl::onMediaSizeChange(const EventType& event_in)
00326 {
00327         LLMediaBase* media_source = event_in.getSubject();
00328         LLViewerImage* placeholder_image = gImageList.getImage( mMovieImageID );
00329         if (placeholder_image)
00330         {
00331                 initializePlaceholderImage(placeholder_image, media_source);
00332         }
00333         else
00334         {
00335                 llinfos << "no placeholder image" << llendl;
00336         }
00337 }
00338 
00339 
00340                 // Get the image we're using
00341 
00342         /*
00343         // update media stream if required
00344         LLMediaEngine* media_engine = LLMediaEngine::getInstance();
00345         if (media_engine)
00346         {
00347                 if ( media_engine->update() )
00348                 {
00349                         LLUUID media_uuid = media_engine->getImageUUID();
00350                         updateMovieImage(media_uuid, TRUE);
00351                         if (!media_uuid.isNull())
00352                         {
00353                                 LLViewerImage* viewerImage = getImage( media_uuid );
00354                                 if( viewerImage )
00355                                 {
00356                                         LLMediaBase* renderer = media_engine->getMediaRenderer();
00357                                         if ((renderer->getTextureWidth() != viewerImage->getWidth()) ||
00358                                                 (renderer->getTextureHeight() != viewerImage->getHeight()) ||
00359                                                 (renderer->getTextureDepth() != viewerImage->getComponents()) ||
00360                                                 (viewerImage->getHasGLTexture() == FALSE))
00361                                         {
00362                                                 // destroy existing GL image
00363                                                 viewerImage->destroyGLTexture();
00364 
00365                                                 // set new size
00366                                                 viewerImage->setSize( renderer->getTextureWidth(),
00367                                                                                                 renderer->getTextureHeight(),
00368                                                                                                 renderer->getTextureDepth() );
00369 
00370                                                 LLPointer<LLImageRaw> raw = new LLImageRaw(renderer->getTextureWidth(),
00371                                                                                                                                         renderer->getTextureHeight(),
00372                                                                                                                                         renderer->getTextureDepth());
00373                                                 raw->clear(0x7f,0x7f,0x7f,0xff);
00374                                                 viewerImage->createGLTexture(0, raw);
00375                                         }
00376 
00377                                         // Set the explicit format the instance wants
00378                                         viewerImage->setExplicitFormat(renderer->getTextureFormatInternal(),
00379                                                                                                         renderer->getTextureFormatPrimary(),
00380                                                                                                         renderer->getTextureFormatType(),
00381                                                                                                         renderer->getTextureFormatSwapBytes());
00382                                         // This should be redundant, but just in case:
00383                                         viewerImage->setUseMipMaps(FALSE);
00384 
00385                                         LLImageRaw* rawImage = media_engine->getImageRaw();
00386                                         if ( rawImage )
00387                                         {
00388                                                 viewerImage->setSubImage(rawImage, 0, 0,
00389                                                                                                         renderer->getMediaWidth(),
00390                                                                                                         renderer->getMediaHeight());
00391                                         }
00392                                 }
00393                                 else
00394                                 {
00395                                         llwarns << "MediaEngine update unable to get viewer image for GL texture" << llendl;
00396                                 }
00397                         }
00398                 }
00399                 else
00400                 {
00401                         LLUUID media_uuid = media_engine->getImageUUID();
00402                         updateMovieImage(media_uuid, FALSE);
00403                 }
00404         }
00405         */
00406 
00407 
00409 LLUUID LLViewerMediaImpl::getMediaTextureID()
00410 {
00411         return mMovieImageID;
00412 }
00413 
00415 // Wrapper class
00417 
00419 // static
00420 void LLViewerMedia::initClass()
00421 {
00422         LLMediaManagerData* init_data = new LLMediaManagerData;
00423 
00424 //      std::string executable_dir = std::string( arg0 ).substr( 0, std::string( arg0 ).find_last_of("\\/") );
00425 //      std::string component_dir = std::string( executable_dir ).substr( 0, std::string( executable_dir ).find_last_of("\\/") );
00426 //      component_dir = std::string( component_dir ).substr( 0, std::string( component_dir ).find_last_of("\\/") );
00427 //      component_dir = std::string( component_dir ).substr( 0, std::string( component_dir ).find_last_of("\\/") );
00428 //      component_dir += "\\newview\\app_settings\\mozilla";
00429 
00430 
00431 #if LL_DARWIN
00432         // For Mac OS, we store both the shared libraries and the runtime files (chrome/, plugins/, etc) in
00433         // Second Life.app/Contents/MacOS/.  This matches the way Firefox is distributed on the Mac.
00434         std::string component_dir(gDirUtilp->getExecutableDir());
00435 #elif LL_WINDOWS
00436         std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) );
00437         component_dir += gDirUtilp->getDirDelimiter();
00438   #ifdef LL_DEBUG
00439         component_dir += "mozilla_debug";
00440   #else // LL_DEBUG
00441         component_dir += "mozilla";
00442   #endif // LL_DEBUG
00443 #elif LL_LINUX
00444         std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) );
00445         component_dir += gDirUtilp->getDirDelimiter();
00446         component_dir += "mozilla-runtime-linux-i686";
00447 #else
00448         std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) );
00449         component_dir += gDirUtilp->getDirDelimiter();
00450         component_dir += "mozilla";
00451 #endif
00452 
00453         // append our magic version number string to the browser user agent id
00454         std::ostringstream codec;
00455         codec << "[Second Life ";
00456         codec << "(" << gSavedSettings.getString("VersionChannelName") << ")";
00457         codec << " - " << LL_VERSION_MAJOR << "." << LL_VERSION_MINOR << "." << LL_VERSION_PATCH << "." << LL_VERSION_BUILD;
00458         codec << "]";
00459         init_data->setBrowserUserAgentId( codec.str() );
00460 
00461         std::string application_dir = gDirUtilp->getExecutableDir();
00462 
00463         init_data->setBrowserApplicationDir( application_dir );
00464         std::string profile_dir = gDirUtilp->getExpandedFilename( LL_PATH_MOZILLA_PROFILE, "" );
00465         init_data->setBrowserProfileDir( profile_dir );
00466         init_data->setBrowserComponentDir( component_dir );
00467         std::string profile_name("Second Life");
00468         init_data->setBrowserProfileName( profile_name );
00469         init_data->setBrowserParentWindow( gViewerWindow->getPlatformWindow() );
00470 
00471         LLMediaManager::initClass( init_data );
00472 
00473         LLMediaManager* mm = LLMediaManager::getInstance();
00474         LLMIMETypes::mime_info_map_t::const_iterator it;
00475         for (it = LLMIMETypes::sMap.begin(); it != LLMIMETypes::sMap.end(); ++it)
00476         {
00477                 const LLString& mime_type = it->first;
00478                 const LLMIMETypes::LLMIMEInfo& info = it->second;
00479                 mm->addMimeTypeImplNameMap( mime_type, info.mImpl );
00480         }
00481 }
00482 
00484 // static
00485 void LLViewerMedia::cleanupClass()
00486 {
00487         LLMediaManager::cleanupClass();
00488 }
00489 
00490 // static
00491 void LLViewerMedia::play(const std::string& media_url,
00492                                                  const std::string& mime_type,
00493                                                  const LLUUID& placeholder_texture_id,
00494                                                  S32 media_width, S32 media_height, U8 media_auto_scale,
00495                                                  U8 media_loop)
00496 {
00497         sViewerMediaImpl.play(media_url, mime_type, placeholder_texture_id,
00498                                                   media_width, media_height, media_auto_scale, media_loop);
00499 }
00500 
00501 // static
00502 void LLViewerMedia::stop()
00503 {
00504         sViewerMediaImpl.stop();
00505 }
00506 
00507 // static
00508 void LLViewerMedia::pause()
00509 {
00510         sViewerMediaImpl.pause();
00511 }
00512 
00513 // static
00514 void LLViewerMedia::start()
00515 {
00516         sViewerMediaImpl.start();
00517 }
00518 
00519 // static
00520 void LLViewerMedia::seek(F32 time)
00521 {
00522         sViewerMediaImpl.seek(time);
00523 }
00524 
00525 // static
00526 void LLViewerMedia::setVolume(F32 volume)
00527 {
00528         sViewerMediaImpl.setVolume(volume);
00529 }
00530 
00531 // static
00532 LLMediaBase::EStatus LLViewerMedia::getStatus()
00533 {
00534         return sViewerMediaImpl.getStatus();
00535 }
00536 
00538 // static
00539 LLUUID LLViewerMedia::getMediaTextureID()
00540 {
00541         return sViewerMediaImpl.getMediaTextureID();
00542 }
00543 
00545 // static
00546 bool LLViewerMedia::getMediaSize(S32 *media_width, S32 *media_height)
00547 {
00548         // make sure we're valid
00549 
00550         if ( sViewerMediaImpl.mMediaSource != NULL )
00551         {
00552                 *media_width = sViewerMediaImpl.mMediaSource->getMediaWidth();
00553                 *media_height = sViewerMediaImpl.mMediaSource->getMediaHeight();
00554                 return true;
00555         }
00556         return false;
00557 }
00558 
00560 // static
00561 bool LLViewerMedia::getTextureSize(S32 *texture_width, S32 *texture_height)
00562 {
00563         if ( sViewerMediaImpl.mMediaSource != NULL )
00564         {
00565                 S32 media_width = sViewerMediaImpl.mMediaSource->getMediaWidth();
00566                 S32 media_height = sViewerMediaImpl.mMediaSource->getMediaHeight();
00567                 *texture_width = LLMediaManager::textureWidthFromMediaWidth( media_width );
00568                 *texture_height = LLMediaManager::textureHeightFromMediaHeight( media_height );
00569                 return true;
00570         }
00571         return false;
00572 }
00573 
00574 
00576 // static
00577 void LLViewerMedia::updateImagesMediaStreams()
00578 {
00579         sViewerMediaImpl.updateImagesMediaStreams();
00580 }
00582 // static
00583 bool LLViewerMedia::isMediaPlaying()
00584 {
00585         LLMediaBase::EStatus status = sViewerMediaImpl.getStatus();
00586         return (status == LLMediaBase::STATUS_STARTED );
00587 }
00589 // static
00590 bool LLViewerMedia::isMediaPaused()
00591 {
00592         LLMediaBase::EStatus status = sViewerMediaImpl.getStatus();
00593         return (status == LLMediaBase::STATUS_PAUSED);
00594 }
00596 // static
00597 bool LLViewerMedia::hasMedia()
00598 {
00599         return sViewerMediaImpl.mMediaSource != NULL;
00600 }
00601 
00603 //static
00604 bool LLViewerMedia::isActiveMediaTexture(const LLUUID& id)
00605 {
00606         return (id.notNull()
00607                 && id == getMediaTextureID()
00608                 && isMediaPlaying());
00609 }
00610 
00612 // static
00613 std::string LLViewerMedia::getMediaURL()
00614 {
00615         return sViewerMediaImpl.mMediaURL;
00616 }
00618 // static
00619 std::string LLViewerMedia::getMimeType()
00620 {
00621         return sViewerMediaImpl.mMimeType;
00622 }
00624 // static
00625 void LLViewerMedia::setMimeType(std::string mime_type)
00626 {
00627         sViewerMediaImpl.mMimeType = mime_type;
00628 }
00629 
00630 

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