aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llviewermedia.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:45:34 -0500
committerJacek Antonelli2008-08-15 23:45:34 -0500
commitcd17687f01420952712a500107e0f93e7ab8d5f8 (patch)
treece48c2b706f2c1176290e39fb555fbdf6648ce01 /linden/indra/newview/llviewermedia.cpp
parentSecond Life viewer sources 1.19.0.5 (diff)
downloadmeta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.zip
meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.gz
meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.bz2
meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.xz
Second Life viewer sources 1.19.1.0
Diffstat (limited to 'linden/indra/newview/llviewermedia.cpp')
-rw-r--r--linden/indra/newview/llviewermedia.cpp634
1 files changed, 634 insertions, 0 deletions
diff --git a/linden/indra/newview/llviewermedia.cpp b/linden/indra/newview/llviewermedia.cpp
new file mode 100644
index 0000000..0cc4e2d
--- /dev/null
+++ b/linden/indra/newview/llviewermedia.cpp
@@ -0,0 +1,634 @@
1/**
2 * @file llviewermedia.cpp
3 * @brief Client interface to the media engine
4 *
5 * $LicenseInfo:firstyear=2007&license=viewergpl$
6 *
7 * Copyright (c) 2007-2008, Linden Research, Inc.
8 *
9 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab
11 * to you under the terms of the GNU General Public License, version 2.0
12 * ("GPL"), unless you have obtained a separate licensing agreement
13 * ("Other License"), formally executed by you and Linden Lab. Terms of
14 * the GPL can be found in doc/GPL-license.txt in this distribution, or
15 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
16 *
17 * There are special exceptions to the terms and conditions of the GPL as
18 * it is applied to this Source Code. View the full text of the exception
19 * in the file doc/FLOSS-exception.txt in this software distribution, or
20 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
21 *
22 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above,
24 * and agree to abide by those obligations.
25 *
26 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
27 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
28 * COMPLETENESS OR PERFORMANCE.
29 * $/LicenseInfo$
30 */
31
32#include "llviewerprecompiledheaders.h"
33
34#include "llviewermedia.h"
35
36#include "llmimetypes.h"
37#include "llviewercontrol.h"
38#include "llviewerimage.h"
39#include "llviewerwindow.h"
40#include "llversionviewer.h"
41#include "llviewerimagelist.h"
42
43#include "llevent.h" // LLSimpleListener
44#include "llmediamanager.h"
45#include "lluuid.h"
46
47// don't want to include llappviewer.h
48extern std::string gChannelName;
49
50// Implementation functions not exported into header file
51class LLViewerMediaImpl
52 : public LLMediaObserver
53{
54 public:
55 LLViewerMediaImpl()
56 : mMediaSource( NULL ),
57 mMovieImageID(),
58 mMovieImageHasMips(false)
59 { }
60
61 void initControlListeners();
62
63 void destroyMediaSource();
64
65 void play(const std::string& media_url,
66 const std::string& mime_type,
67 const LLUUID& placeholder_texture_id,
68 S32 media_width, S32 media_height, U8 media_auto_scale,
69 U8 media_loop);
70
71 void stop();
72 void pause();
73 void start();
74 void seek(F32 time);
75 void setVolume(F32 volume);
76 LLMediaBase::EStatus getStatus();
77
78 /*virtual*/ void onMediaSizeChange(const EventType& event_in);
79 /*virtual*/ void onMediaContentsChange(const EventType& event_in);
80
81 void updateMovieImage(const LLUUID& image_id, BOOL active);
82 void updateImagesMediaStreams();
83 LLUUID getMediaTextureID();
84
85 public:
86
87 // a single media url with some data and an impl.
88 LLMediaBase* mMediaSource;
89 LLUUID mMovieImageID;
90 bool mMovieImageHasMips;
91 std::string mMediaURL;
92 std::string mMimeType;
93 private:
94 void initializePlaceholderImage(LLViewerImage *placeholder_image, LLMediaBase *media_source);
95};
96
97static LLViewerMediaImpl sViewerMediaImpl;
98
99void LLViewerMediaImpl::destroyMediaSource()
100{
101 LLMediaManager* mgr = LLMediaManager::getInstance();
102 if ( mMediaSource )
103 {
104 bool was_playing = LLViewerMedia::isMediaPlaying();
105 mMediaSource->remObserver(this);
106 mgr->destroySource( mMediaSource );
107
108 // Restore the texture
109 updateMovieImage(LLUUID::null, was_playing);
110
111 }
112 mMediaSource = NULL;
113}
114
115void LLViewerMediaImpl::play(const std::string& media_url,
116 const std::string& mime_type,
117 const LLUUID& placeholder_texture_id,
118 S32 media_width, S32 media_height, U8 media_auto_scale,
119 U8 media_loop)
120{
121 // first stop any previously playing media
122 stop();
123
124 // Save this first, as init/load below may fire events
125 mMovieImageID = placeholder_texture_id;
126
127 // If the mime_type passed in is different than the cached one, and
128 // Auto-discovery is turned OFF, replace the cached mime_type with the new one.
129 if(mime_type != mMimeType &&
130 ! gSavedSettings.getBOOL("AutoMimeDiscovery"))
131 {
132 mMimeType = mime_type;
133 }
134 LLURI url(media_url);
135 std::string scheme = url.scheme() != "" ? url.scheme() : "http";
136
137 LLMediaManager* mgr = LLMediaManager::getInstance();
138 mMediaSource = mgr->createSourceFromMimeType(scheme, mMimeType );
139 if ( !mMediaSource )
140 {
141 if (mMimeType != "none/none")
142 {
143 llwarns << "media source create failed " << media_url
144 << " type " << mMimeType
145 << llendl;
146 }
147 return;
148 }
149
150 if ((media_width != 0) && (media_height != 0))
151 {
152 mMediaSource->setRequestedMediaSize(media_width, media_height);
153 }
154
155 mMediaSource->setLooping(media_loop);
156 mMediaSource->setAutoScaled(media_auto_scale);
157 mMediaSource->addObserver( this );
158 mMediaSource->navigateTo( media_url );
159 mMediaSource->addCommand(LLMediaBase::COMMAND_START);
160
161 // Store the URL and Mime Type
162 mMediaURL = media_url;
163
164}
165
166void LLViewerMediaImpl::stop()
167{
168 destroyMediaSource();
169}
170
171void LLViewerMediaImpl::pause()
172{
173 if(mMediaSource)
174 {
175 mMediaSource->addCommand(LLMediaBase::COMMAND_PAUSE);
176 }
177}
178
179void LLViewerMediaImpl::start()
180{
181 if(mMediaSource)
182 {
183 mMediaSource->addCommand(LLMediaBase::COMMAND_START);
184 }
185}
186
187void LLViewerMediaImpl::seek(F32 time)
188{
189 if(mMediaSource)
190 {
191 mMediaSource->seek(time);
192 }
193}
194
195void LLViewerMediaImpl::setVolume(F32 volume)
196{
197 if(mMediaSource)
198 {
199 mMediaSource->setVolume( volume);
200 }
201}
202
203LLMediaBase::EStatus LLViewerMediaImpl::getStatus()
204{
205 if (mMediaSource)
206 {
207 return mMediaSource->getStatus();
208 }
209 else
210 {
211 return LLMediaBase::STATUS_UNKNOWN;
212 }
213}
214
215//////////////////////////////////////////////////////////////////////////////////////////
216// static
217void LLViewerMediaImpl::updateMovieImage(const LLUUID& uuid, BOOL active)
218{
219 // IF the media image hasn't changed, do nothing
220 if (mMovieImageID == uuid)
221 {
222 return;
223 }
224 // If we have changed media uuid, restore the old one
225 if (!mMovieImageID.isNull())
226 {
227 LLViewerImage* oldImage = LLViewerImage::getImage( mMovieImageID );
228 if (oldImage)
229 {
230 oldImage->reinit(mMovieImageHasMips);
231 oldImage->mIsMediaTexture = FALSE;
232 }
233 mMovieImageID.setNull();
234 }
235 // If the movie is playing, set the new media image
236 if (active && !uuid.isNull())
237 {
238 LLViewerImage* viewerImage = LLViewerImage::getImage( uuid );
239 if( viewerImage )
240 {
241 mMovieImageID = uuid;
242 // Can't use mipmaps for movies because they don't update the full image
243 mMovieImageHasMips = viewerImage->getUseMipMaps();
244 viewerImage->reinit(FALSE);
245 viewerImage->mIsMediaTexture = TRUE;
246 }
247 }
248}
249
250
251//////////////////////////////////////////////////////////////////////////////////////////
252// static
253void LLViewerMediaImpl::updateImagesMediaStreams()
254{
255 LLMediaManager::updateClass();
256}
257
258void LLViewerMediaImpl::initializePlaceholderImage(LLViewerImage *placeholder_image, LLMediaBase *media_source)
259{
260 int media_width = media_source->getMediaWidth();
261 int media_height = media_source->getMediaHeight();
262 //int media_rowspan = media_source->getMediaRowSpan();
263
264 // if width & height are invalid, don't bother doing anything
265 if ( media_width < 1 || media_height < 1 )
266 return;
267
268 llinfos << "initializing media placeholder" << llendl;
269 llinfos << "movie image id " << mMovieImageID << llendl;
270
271 int texture_width = LLMediaManager::textureWidthFromMediaWidth( media_width );
272 int texture_height = LLMediaManager::textureHeightFromMediaHeight( media_height );
273 int texture_depth = media_source->getMediaDepth();
274
275 // MEDIAOPT: check to see if size actually changed before doing work
276 placeholder_image->destroyGLTexture();
277 // MEDIAOPT: apparently just calling setUseMipMaps(FALSE) doesn't work?
278 placeholder_image->reinit(FALSE); // probably not needed
279
280 // MEDIAOPT: seems insane that we actually have to make an imageraw then
281 // immediately discard it
282 LLPointer<LLImageRaw> raw = new LLImageRaw(texture_width, texture_height, texture_depth);
283 raw->clear(0x0f, 0x0f, 0x0f, 0xff);
284 int discard_level = 0;
285
286 // ask media source for correct GL image format constants
287 placeholder_image->setExplicitFormat(media_source->getTextureFormatInternal(),
288 media_source->getTextureFormatPrimary(),
289 media_source->getTextureFormatType());
290
291 placeholder_image->createGLTexture(discard_level, raw);
292
293 // placeholder_image->setExplicitFormat()
294 placeholder_image->setUseMipMaps(FALSE);
295
296 // MEDIAOPT: set this dynamically on play/stop
297 placeholder_image->mIsMediaTexture = true;
298}
299
300
301
302// virtual
303void LLViewerMediaImpl::onMediaContentsChange(const EventType& event_in)
304{
305 LLMediaBase* media_source = event_in.getSubject();
306 LLViewerImage* placeholder_image = gImageList.getImage( mMovieImageID );
307 if ((placeholder_image) && (placeholder_image->getHasGLTexture()))
308 {
309 if (placeholder_image->getUseMipMaps())
310 {
311 // bad image! NO MIPMAPS!
312 initializePlaceholderImage(placeholder_image, media_source);
313 }
314
315 U8* data = media_source->getMediaData();
316 S32 x_pos = 0;
317 S32 y_pos = 0;
318 S32 width = media_source->getMediaWidth();
319 S32 height = media_source->getMediaHeight();
320 S32 data_width = media_source->getMediaDataWidth();
321 S32 data_height = media_source->getMediaDataHeight();
322 placeholder_image->setSubImage(data, data_width, data_height,
323 x_pos, y_pos, width, height);
324 }
325}
326
327
328// virtual
329void LLViewerMediaImpl::onMediaSizeChange(const EventType& event_in)
330{
331 LLMediaBase* media_source = event_in.getSubject();
332 LLViewerImage* placeholder_image = gImageList.getImage( mMovieImageID );
333 if (placeholder_image)
334 {
335 initializePlaceholderImage(placeholder_image, media_source);
336 }
337 else
338 {
339 llinfos << "no placeholder image" << llendl;
340 }
341}
342
343
344 // Get the image we're using
345
346 /*
347 // update media stream if required
348 LLMediaEngine* media_engine = LLMediaEngine::getInstance();
349 if (media_engine)
350 {
351 if ( media_engine->update() )
352 {
353 LLUUID media_uuid = media_engine->getImageUUID();
354 updateMovieImage(media_uuid, TRUE);
355 if (!media_uuid.isNull())
356 {
357 LLViewerImage* viewerImage = getImage( media_uuid );
358 if( viewerImage )
359 {
360 LLMediaBase* renderer = media_engine->getMediaRenderer();
361 if ((renderer->getTextureWidth() != viewerImage->getWidth()) ||
362 (renderer->getTextureHeight() != viewerImage->getHeight()) ||
363 (renderer->getTextureDepth() != viewerImage->getComponents()) ||
364 (viewerImage->getHasGLTexture() == FALSE))
365 {
366 // destroy existing GL image
367 viewerImage->destroyGLTexture();
368
369 // set new size
370 viewerImage->setSize( renderer->getTextureWidth(),
371 renderer->getTextureHeight(),
372 renderer->getTextureDepth() );
373
374 LLPointer<LLImageRaw> raw = new LLImageRaw(renderer->getTextureWidth(),
375 renderer->getTextureHeight(),
376 renderer->getTextureDepth());
377 raw->clear(0x7f,0x7f,0x7f,0xff);
378 viewerImage->createGLTexture(0, raw);
379 }
380
381 // Set the explicit format the instance wants
382 viewerImage->setExplicitFormat(renderer->getTextureFormatInternal(),
383 renderer->getTextureFormatPrimary(),
384 renderer->getTextureFormatType(),
385 renderer->getTextureFormatSwapBytes());
386 // This should be redundant, but just in case:
387 viewerImage->setUseMipMaps(FALSE);
388
389 LLImageRaw* rawImage = media_engine->getImageRaw();
390 if ( rawImage )
391 {
392 viewerImage->setSubImage(rawImage, 0, 0,
393 renderer->getMediaWidth(),
394 renderer->getMediaHeight());
395 }
396 }
397 else
398 {
399 llwarns << "MediaEngine update unable to get viewer image for GL texture" << llendl;
400 }
401 }
402 }
403 else
404 {
405 LLUUID media_uuid = media_engine->getImageUUID();
406 updateMovieImage(media_uuid, FALSE);
407 }
408 }
409 */
410
411
412//////////////////////////////////////////////////////////////////////////////////////////
413LLUUID LLViewerMediaImpl::getMediaTextureID()
414{
415 return mMovieImageID;
416}
417
418//////////////////////////////////////////////////////////////////////////////////////////
419// Wrapper class
420//////////////////////////////////////////////////////////////////////////////////////////
421
422//////////////////////////////////////////////////////////////////////////////////////////
423// static
424void LLViewerMedia::initClass()
425{
426 LLMediaManagerData* init_data = new LLMediaManagerData;
427
428// std::string executable_dir = std::string( arg0 ).substr( 0, std::string( arg0 ).find_last_of("\\/") );
429// std::string component_dir = std::string( executable_dir ).substr( 0, std::string( executable_dir ).find_last_of("\\/") );
430// component_dir = std::string( component_dir ).substr( 0, std::string( component_dir ).find_last_of("\\/") );
431// component_dir = std::string( component_dir ).substr( 0, std::string( component_dir ).find_last_of("\\/") );
432// component_dir += "\\newview\\app_settings\\mozilla";
433
434
435#if LL_DARWIN
436 // For Mac OS, we store both the shared libraries and the runtime files (chrome/, plugins/, etc) in
437 // Second Life.app/Contents/MacOS/. This matches the way Firefox is distributed on the Mac.
438 std::string component_dir(gDirUtilp->getExecutableDir());
439#elif LL_WINDOWS
440 std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) );
441 component_dir += gDirUtilp->getDirDelimiter();
442 #ifdef LL_DEBUG
443 component_dir += "mozilla_debug";
444 #else // LL_DEBUG
445 component_dir += "mozilla";
446 #endif // LL_DEBUG
447#elif LL_LINUX
448 std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) );
449 component_dir += gDirUtilp->getDirDelimiter();
450 component_dir += "mozilla-runtime-linux-i686";
451#else
452 std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) );
453 component_dir += gDirUtilp->getDirDelimiter();
454 component_dir += "mozilla";
455#endif
456
457 // append our magic version number string to the browser user agent id
458 std::ostringstream codec;
459 codec << "[Second Life ";
460 codec << "(" << gChannelName << ")";
461 codec << " - " << LL_VERSION_MAJOR << "." << LL_VERSION_MINOR << "." << LL_VERSION_PATCH << "." << LL_VERSION_BUILD;
462 codec << "]";
463 init_data->setBrowserUserAgentId( codec.str() );
464
465 std::string application_dir = gDirUtilp->getExecutableDir();
466
467 init_data->setBrowserApplicationDir( application_dir );
468 std::string profile_dir = gDirUtilp->getExpandedFilename( LL_PATH_MOZILLA_PROFILE, "" );
469 init_data->setBrowserProfileDir( profile_dir );
470 init_data->setBrowserComponentDir( component_dir );
471 std::string profile_name("Second Life");
472 init_data->setBrowserProfileName( profile_name );
473 init_data->setBrowserParentWindow( gViewerWindow->getPlatformWindow() );
474
475 LLMediaManager::initClass( init_data );
476
477 LLMediaManager* mm = LLMediaManager::getInstance();
478 LLMIMETypes::mime_info_map_t::const_iterator it;
479 for (it = LLMIMETypes::sMap.begin(); it != LLMIMETypes::sMap.end(); ++it)
480 {
481 const LLString& mime_type = it->first;
482 const LLMIMETypes::LLMIMEInfo& info = it->second;
483 mm->addMimeTypeImplNameMap( mime_type, info.mImpl );
484 }
485}
486
487//////////////////////////////////////////////////////////////////////////////////////////
488// static
489void LLViewerMedia::cleanupClass()
490{
491 LLMediaManager::cleanupClass();
492}
493
494// static
495void LLViewerMedia::play(const std::string& media_url,
496 const std::string& mime_type,
497 const LLUUID& placeholder_texture_id,
498 S32 media_width, S32 media_height, U8 media_auto_scale,
499 U8 media_loop)
500{
501 sViewerMediaImpl.play(media_url, mime_type, placeholder_texture_id,
502 media_width, media_height, media_auto_scale, media_loop);
503}
504
505// static
506void LLViewerMedia::stop()
507{
508 sViewerMediaImpl.stop();
509}
510
511// static
512void LLViewerMedia::pause()
513{
514 sViewerMediaImpl.pause();
515}
516
517// static
518void LLViewerMedia::start()
519{
520 sViewerMediaImpl.start();
521}
522
523// static
524void LLViewerMedia::seek(F32 time)
525{
526 sViewerMediaImpl.seek(time);
527}
528
529// static
530void LLViewerMedia::setVolume(F32 volume)
531{
532 sViewerMediaImpl.setVolume(volume);
533}
534
535// static
536LLMediaBase::EStatus LLViewerMedia::getStatus()
537{
538 return sViewerMediaImpl.getStatus();
539}
540
541//////////////////////////////////////////////////////////////////////////////////////////
542// static
543LLUUID LLViewerMedia::getMediaTextureID()
544{
545 return sViewerMediaImpl.getMediaTextureID();
546}
547
548//////////////////////////////////////////////////////////////////////////////////////////
549// static
550bool LLViewerMedia::getMediaSize(S32 *media_width, S32 *media_height)
551{
552 // make sure we're valid
553
554 if ( sViewerMediaImpl.mMediaSource != NULL )
555 {
556 *media_width = sViewerMediaImpl.mMediaSource->getMediaWidth();
557 *media_height = sViewerMediaImpl.mMediaSource->getMediaHeight();
558 return true;
559 }
560 return false;
561}
562
563//////////////////////////////////////////////////////////////////////////////////////////
564// static
565bool LLViewerMedia::getTextureSize(S32 *texture_width, S32 *texture_height)
566{
567 if ( sViewerMediaImpl.mMediaSource != NULL )
568 {
569 S32 media_width = sViewerMediaImpl.mMediaSource->getMediaWidth();
570 S32 media_height = sViewerMediaImpl.mMediaSource->getMediaHeight();
571 *texture_width = LLMediaManager::textureWidthFromMediaWidth( media_width );
572 *texture_height = LLMediaManager::textureHeightFromMediaHeight( media_height );
573 return true;
574 }
575 return false;
576}
577
578
579//////////////////////////////////////////////////////////////////////////////////////////
580// static
581void LLViewerMedia::updateImagesMediaStreams()
582{
583 sViewerMediaImpl.updateImagesMediaStreams();
584}
585//////////////////////////////////////////////////////////////////////////////////////////
586// static
587bool LLViewerMedia::isMediaPlaying()
588{
589 LLMediaBase::EStatus status = sViewerMediaImpl.getStatus();
590 return (status == LLMediaBase::STATUS_STARTED );
591}
592//////////////////////////////////////////////////////////////////////////////////////////
593// static
594bool LLViewerMedia::isMediaPaused()
595{
596 LLMediaBase::EStatus status = sViewerMediaImpl.getStatus();
597 return (status == LLMediaBase::STATUS_PAUSED);
598}
599//////////////////////////////////////////////////////////////////////////////////////////
600// static
601bool LLViewerMedia::hasMedia()
602{
603 return sViewerMediaImpl.mMediaSource != NULL;
604}
605
606//////////////////////////////////////////////////////////////////////////////////////////
607//static
608bool LLViewerMedia::isActiveMediaTexture(const LLUUID& id)
609{
610 return (id.notNull()
611 && id == getMediaTextureID()
612 && isMediaPlaying());
613}
614
615//////////////////////////////////////////////////////////////////////////////////////////
616// static
617std::string LLViewerMedia::getMediaURL()
618{
619 return sViewerMediaImpl.mMediaURL;
620}
621//////////////////////////////////////////////////////////////////////////////////////////
622// static
623std::string LLViewerMedia::getMimeType()
624{
625 return sViewerMediaImpl.mMimeType;
626}
627//////////////////////////////////////////////////////////////////////////////////////////
628// static
629void LLViewerMedia::setMimeType(std::string mime_type)
630{
631 sViewerMediaImpl.mMimeType = mime_type;
632}
633
634