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"
00044 #include "llmediamanager.h"
00045 #include "lluuid.h"
00046
00047
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 void onMediaSizeChange(const EventType& event_in);
00076 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
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
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
00119 stop();
00120
00121
00122 mMovieImageID = placeholder_texture_id;
00123
00124
00125
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
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
00213 void LLViewerMediaImpl::updateMovieImage(const LLUUID& uuid, BOOL active)
00214 {
00215
00216 if (mMovieImageID == uuid)
00217 {
00218 return;
00219 }
00220
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
00232 if (active && !uuid.isNull())
00233 {
00234 LLViewerImage* viewerImage = LLViewerImage::getImage( uuid );
00235 if( viewerImage )
00236 {
00237 mMovieImageID = uuid;
00238
00239 mMovieImageHasMips = viewerImage->getUseMipMaps();
00240 viewerImage->reinit(FALSE);
00241 viewerImage->mIsMediaTexture = TRUE;
00242 }
00243 }
00244 }
00245
00246
00248
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
00259
00260
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
00272 placeholder_image->destroyGLTexture();
00273
00274 placeholder_image->reinit(FALSE);
00275
00276
00277
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
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
00290 placeholder_image->setUseMipMaps(FALSE);
00291
00292
00293 placeholder_image->mIsMediaTexture = true;
00294 }
00295
00296
00297
00298
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
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
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
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00409 LLUUID LLViewerMediaImpl::getMediaTextureID()
00410 {
00411 return mMovieImageID;
00412 }
00413
00415
00417
00419
00420 void LLViewerMedia::initClass()
00421 {
00422 LLMediaManagerData* init_data = new LLMediaManagerData;
00423
00424
00425
00426
00427
00428
00429
00430
00431 #if LL_DARWIN
00432
00433
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
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
00485 void LLViewerMedia::cleanupClass()
00486 {
00487 LLMediaManager::cleanupClass();
00488 }
00489
00490
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
00502 void LLViewerMedia::stop()
00503 {
00504 sViewerMediaImpl.stop();
00505 }
00506
00507
00508 void LLViewerMedia::pause()
00509 {
00510 sViewerMediaImpl.pause();
00511 }
00512
00513
00514 void LLViewerMedia::start()
00515 {
00516 sViewerMediaImpl.start();
00517 }
00518
00519
00520 void LLViewerMedia::seek(F32 time)
00521 {
00522 sViewerMediaImpl.seek(time);
00523 }
00524
00525
00526 void LLViewerMedia::setVolume(F32 volume)
00527 {
00528 sViewerMediaImpl.setVolume(volume);
00529 }
00530
00531
00532 LLMediaBase::EStatus LLViewerMedia::getStatus()
00533 {
00534 return sViewerMediaImpl.getStatus();
00535 }
00536
00538
00539 LLUUID LLViewerMedia::getMediaTextureID()
00540 {
00541 return sViewerMediaImpl.getMediaTextureID();
00542 }
00543
00545
00546 bool LLViewerMedia::getMediaSize(S32 *media_width, S32 *media_height)
00547 {
00548
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
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
00577 void LLViewerMedia::updateImagesMediaStreams()
00578 {
00579 sViewerMediaImpl.updateImagesMediaStreams();
00580 }
00582
00583 bool LLViewerMedia::isMediaPlaying()
00584 {
00585 LLMediaBase::EStatus status = sViewerMediaImpl.getStatus();
00586 return (status == LLMediaBase::STATUS_STARTED );
00587 }
00589
00590 bool LLViewerMedia::isMediaPaused()
00591 {
00592 LLMediaBase::EStatus status = sViewerMediaImpl.getStatus();
00593 return (status == LLMediaBase::STATUS_PAUSED);
00594 }
00596
00597 bool LLViewerMedia::hasMedia()
00598 {
00599 return sViewerMediaImpl.mMediaSource != NULL;
00600 }
00601
00603
00604 bool LLViewerMedia::isActiveMediaTexture(const LLUUID& id)
00605 {
00606 return (id.notNull()
00607 && id == getMediaTextureID()
00608 && isMediaPlaying());
00609 }
00610
00612
00613 std::string LLViewerMedia::getMediaURL()
00614 {
00615 return sViewerMediaImpl.mMediaURL;
00616 }
00618
00619 std::string LLViewerMedia::getMimeType()
00620 {
00621 return sViewerMediaImpl.mMimeType;
00622 }
00624
00625 void LLViewerMedia::setMimeType(std::string mime_type)
00626 {
00627 sViewerMediaImpl.mMimeType = mime_type;
00628 }
00629
00630