aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmedia/llmediaengine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llmedia/llmediaengine.cpp')
-rw-r--r--linden/indra/llmedia/llmediaengine.cpp618
1 files changed, 618 insertions, 0 deletions
diff --git a/linden/indra/llmedia/llmediaengine.cpp b/linden/indra/llmedia/llmediaengine.cpp
new file mode 100644
index 0000000..c3930a4
--- /dev/null
+++ b/linden/indra/llmedia/llmediaengine.cpp
@@ -0,0 +1,618 @@
1/**
2 * @file llmediaengine.cpp
3 * @brief Top level media engine - wraps more specific functionality
4 *
5 * Copyright (c) 2005-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "llmediaengine.h"
29
30#include "indra_constants.h"
31#include "llstring.h"
32
33// singleton pattern - initialization
34LLMediaEngine* LLMediaEngine::sInstance = 0;
35
36//////////////////////////////////////////////////////////////////////////////
37
38//static
39void LLMediaEngine::initClass()
40{
41 llassert(!sInstance);
42 sInstance = new LLMediaEngine();
43}
44
45//static
46void LLMediaEngine::updateClass(F32 volume)
47{
48 llassert(sInstance);
49 sInstance->setVolume(volume);
50}
51
52//static
53void LLMediaEngine::cleanupClass()
54{
55 delete sInstance;
56 sInstance = NULL;
57}
58
59//////////////////////////////////////////////////////////////////////////////
60// default ctor
61LLMediaEngine::LLMediaEngine() :
62 mAvailable( TRUE ),
63 mEnabled( TRUE ),
64 mAutoScaled( FALSE ),
65 mUrl( "" ),
66 mMediaRenderer( 0 ),
67 mImageUUID( LLUUID::null ),
68 mVolume( 0.0f ),
69 mProxyEnabled ( FALSE ),
70 mProxyAddress ( "" ),
71 mProxyPort ( 3128 ),
72 mProxySocks ( 5 ),
73 mProxyExlude ( "" )
74{
75}
76
77//////////////////////////////////////////////////////////////////////////////
78// dtor
79LLMediaEngine::~LLMediaEngine()
80{
81 unload();
82 destroyImageRaw();
83}
84
85//////////////////////////////////////////////////////////////////////////////
86// create/destroy raw image
87void LLMediaEngine::createImageRaw()
88{
89 S32 width = getMediaRenderer()->getMediaWidth();
90 S32 height = getMediaRenderer()->getMediaHeight();
91 S32 depth = getMediaRenderer()->getMediaDepthBytes();
92 if ((width > 0) && (height > 0) && (depth > 0))
93 {
94 if (mImageRaw.isNull())
95 {
96 mImageRaw = new LLImageRaw;
97 }
98 mImageRaw->resize(width, height, depth);
99 mImageRaw->clear();
100 }
101 else
102 {
103 destroyImageRaw();
104 }
105}
106
107void LLMediaEngine::destroyImageRaw()
108{
109 mImageRaw = NULL; // deletes image
110}
111
112//////////////////////////////////////////////////////////////////////////////
113// retrieves the single instance of this class - based on singleton pattern
114LLMediaEngine* LLMediaEngine::getInstance()
115{
116 return sInstance;
117}
118
119//////////////////////////////////////////////////////////////////////////////
120//
121LLMediaBase* LLMediaEngine::getMediaRenderer()
122{
123 return mMediaRenderer;
124}
125
126
127//////////////////////////////////////////////////////////////////////////////
128//
129BOOL LLMediaEngine::init()
130{
131 if( ! isAvailable() )
132 return FALSE;
133
134 return TRUE;
135}
136
137//////////////////////////////////////////////////////////////////////////////
138//
139BOOL LLMediaEngine::update()
140{
141 BOOL res = FALSE;
142 if( mMediaRenderer )
143 {
144 S32 result = mMediaRenderer->updateMedia();
145 switch(result)
146 {
147 case LLMediaBase::updateMediaNeedsSizeChange:
148 // Media renderer is requesting a size change.
149 handleSizeChangedRequest();
150 res = TRUE; // Need to update size of texture
151 break;
152
153 case LLMediaBase::updateMediaNeedsUpdate:
154 res = TRUE;
155 break;
156
157 case LLMediaBase::updateMediaNoChanges:
158 default:
159 res = FALSE;
160 break;
161 }
162 }
163 return res;
164}
165
166
167//////////////////////////////////////////////////////////////////////////////
168//
169BOOL LLMediaEngine::load ( const LLString& urlIn, bool web_url, const LLString& path, S32 width_pixels, S32 height_pixels )
170{
171 if( ! isAvailable() )
172 return FALSE;
173
174 if( isLoaded() )
175 return TRUE;
176
177 this->unload();
178
179 mMediaRenderer = LLMediaBase::make( LLMediaBase::QuickTime, width_pixels, height_pixels);
180
181 if( ! mMediaRenderer )
182 return FALSE;
183
184 if( ! mMediaRenderer->init() )
185 {
186 delete mMediaRenderer;
187 mMediaRenderer = 0;
188 return FALSE;
189 }
190
191 // do this here since there is no media renderer when we get the update so we store and use here
192 if( mMediaRenderer )
193 mMediaRenderer->setAutoScaled( mAutoScaled );
194
195 if( ! mMediaRenderer->load( urlIn ) )
196 {
197 delete mMediaRenderer;
198 mMediaRenderer = 0;
199 return FALSE;
200 }
201
202 return TRUE;
203}
204
205//////////////////////////////////////////////////////////////////////////////
206//
207BOOL LLMediaEngine::isLoaded()
208{
209 if( ! isAvailable() )
210 return FALSE;
211
212 if( mMediaRenderer )
213 return mMediaRenderer->isLoaded();
214 else
215 return FALSE;
216}
217
218//////////////////////////////////////////////////////////////////////////////
219//
220BOOL LLMediaEngine::unload()
221{
222 if( ! isAvailable() )
223 return FALSE;
224
225 if( mMediaRenderer )
226 {
227 mMediaRenderer->stop();
228 mMediaRenderer->unload();
229 delete mMediaRenderer;
230 mMediaRenderer = 0;
231 // Don't do this here. load() calls unload(), and things get lost.
232// mUrl.clear();
233// mImageUUID = LLUUID::null;
234 return TRUE;
235 };
236
237 return FALSE;
238};
239
240//////////////////////////////////////////////////////////////////////////////
241//
242BOOL LLMediaEngine::play()
243{
244 if( ! isAvailable() )
245 return FALSE;
246
247 // base movie volume on slider in prefs (currently prefs also sets volume directly but other controls
248 // may eventually control volume and updat ethis variable
249 this->setVolume( mVolume );
250
251 if( mMediaRenderer )
252 if( ! mMediaRenderer->play() )
253 return FALSE;
254
255 return TRUE;
256}
257
258//////////////////////////////////////////////////////////////////////////////
259//
260BOOL LLMediaEngine::loop()
261{
262 if( ! isAvailable() )
263 return FALSE;
264
265 // base movie volume on slider in prefs (currently prefs also sets volume directly but other controls
266 // may eventually control volume and updat ethis variable
267 this->setVolume( mVolume );
268
269 if( mMediaRenderer )
270 if( ! mMediaRenderer->loop( 0 ) )
271 return FALSE;
272
273 return TRUE;
274}
275
276//////////////////////////////////////////////////////////////////////////////
277//
278BOOL LLMediaEngine::pause()
279{
280 if( ! isAvailable() )
281 return FALSE;
282
283 if( mMediaRenderer )
284 if( ! mMediaRenderer->pause() )
285 return FALSE;
286
287 return TRUE;
288}
289
290//////////////////////////////////////////////////////////////////////////////
291//
292BOOL LLMediaEngine::stop()
293{
294 if( ! isAvailable() )
295 return FALSE;
296
297 if( mMediaRenderer )
298 if( ! mMediaRenderer->stop() )
299 return FALSE;
300
301 return TRUE;
302}
303
304//////////////////////////////////////////////////////////////////////////////
305//
306BOOL LLMediaEngine::seek (F64 time)
307{
308 if( ! isAvailable() )
309 return FALSE;
310
311 if( mMediaRenderer )
312 if( ! mMediaRenderer->seek (time) )
313 return FALSE;
314
315 return TRUE;
316}
317
318//////////////////////////////////////////////////////////////////////////////
319//
320void LLMediaEngine::setAvailable( BOOL availableIn )
321{
322 mAvailable = availableIn;
323}
324
325//////////////////////////////////////////////////////////////////////////////
326//
327BOOL LLMediaEngine::isAvailable()
328{
329 return mAvailable;
330}
331
332//////////////////////////////////////////////////////////////////////////////
333//
334BOOL LLMediaEngine::setVolume( F32 volumeIn )
335{
336 if( ! isAvailable() )
337 return FALSE;
338
339 mVolume = volumeIn;
340
341 if( mMediaRenderer )
342 {
343 if( ! mMediaRenderer->setVolume( volumeIn ) )
344 {
345 return FALSE;
346 };
347 };
348
349 return TRUE;
350}
351
352//////////////////////////////////////////////////////////////////////////////
353//
354void LLMediaEngine::setEnabled( BOOL enabledIn )
355{
356 if( mAvailable )
357 mEnabled = enabledIn;
358}
359
360//////////////////////////////////////////////////////////////////////////////
361//
362BOOL LLMediaEngine::isEnabled()
363{
364 if( mAvailable )
365 return mEnabled;
366 else
367 return FALSE;
368}
369
370//////////////////////////////////////////////////////////////////////////////
371//
372void LLMediaEngine::setAutoScaled( BOOL autoScaledIn )
373{
374 mAutoScaled = autoScaledIn;
375}
376
377//////////////////////////////////////////////////////////////////////////////
378//
379BOOL LLMediaEngine::isAutoScaled()
380{
381 return mAutoScaled;
382}
383
384//////////////////////////////////////////////////////////////////////////////
385//
386void LLMediaEngine::setUrl( const LLString& urlIn )
387{
388 mUrl = urlIn;
389};
390
391//////////////////////////////////////////////////////////////////////////////
392//
393const LLString& LLMediaEngine::getUrl ()
394{
395 return mUrl;
396};
397
398//////////////////////////////////////////////////////////////////////////////
399//
400void LLMediaEngine::setImageUUID( LLUUID imageUUIDIn )
401{
402 mImageUUID = imageUUIDIn;
403};
404
405//////////////////////////////////////////////////////////////////////////////
406//
407LLUUID LLMediaEngine::getImageUUID()
408{
409 return mImageUUID;
410};
411
412//////////////////////////////////////////////////////////////////////////////
413//
414void LLMediaEngine::handleSizeChangedRequest()
415{
416 if( ! isAvailable() )
417 return;
418
419 // create / resize Raw image
420 LLMediaEngine::getInstance()->createImageRaw();
421
422 // tell media library to use this buffer instead of it's own
423 if (mImageRaw.notNull())
424 {
425 LLMediaEngine::getInstance()->getMediaRenderer()->setBuffer( mImageRaw->getData() );
426 }
427
428}
429
430//////////////////////////////////////////////////////////////////////////////////////////
431// static
432void LLMediaEngine::convertImageAndLoadUrl( bool enableLooping, bool web_url, const std::string& path)
433{
434 LLMediaEngine* engine = LLMediaEngine::getInstance();
435 LLString url = engine->getUrl();
436 S32 width_pixels = 512;
437 S32 height_pixels = 256;
438 if (web_url)
439 {
440 width_pixels = 512;
441 height_pixels = 512;
442 }
443
444 bool success = false;
445 if (engine->load( url, web_url, path, width_pixels, height_pixels ) )
446 {
447 // create / resize Raw image
448 engine->createImageRaw();
449
450 // tell media library to use this buffer instead of it's own
451 if (engine->getImageRaw())
452 {
453 engine->getMediaRenderer()->setBuffer( engine->mImageRaw->getData() );
454 engine->getMediaRenderer()->setBufferSize(width_pixels, height_pixels);
455
456 // start it playing or looping
457 if( enableLooping )
458 {
459 engine->loop();
460 }
461 else
462 {
463 engine->play();
464 }
465 success = true;
466 }
467 }
468
469 if (!success)
470 {
471 llinfos << "MEDIA> unable to load " << LLMediaEngine::getInstance()->getUrl() << llendl;
472 //LLMediaEngine::getInstance()->setAvailable( FALSE );
473 }
474}
475
476//////////////////////////////////////////////////////////////////////////////////////////
477// static
478void LLMediaEngine::process_parcel_media( LLMessageSystem *msg, void ** )
479{
480 // extract the agent id
481 // LLUUID agent_id;
482 // msg->getUUID( agent_id );
483
484 U32 flags;
485 U32 command;
486 F32 time;
487 msg->getU32( "CommandBlock", "Flags", flags );
488 msg->getU32( "CommandBlock", "Command", command);
489 msg->getF32( "CommandBlock", "Time", time );
490
491 if (flags &( (1<<PARCEL_MEDIA_COMMAND_STOP)
492 | (1<<PARCEL_MEDIA_COMMAND_PAUSE)
493 | (1<<PARCEL_MEDIA_COMMAND_PLAY)
494 | (1<<PARCEL_MEDIA_COMMAND_LOOP)
495 | (1<<PARCEL_MEDIA_COMMAND_UNLOAD) ))
496 {
497 // stop
498 if( command == PARCEL_MEDIA_COMMAND_STOP )
499 {
500 //llinfos << ">>> LLMediaEngine::process_parcel_media with command = " <<( '0' + command ) << llendl;
501
502 LLMediaEngine::getInstance()->stop();
503 }
504 else
505 // pause
506 if( command == PARCEL_MEDIA_COMMAND_PAUSE )
507 {
508 //llinfos << ">>> LLMediaEngine::process_parcel_media with command = " <<( '0' + command ) << llendl;
509
510 LLMediaEngine::getInstance()->pause();
511 }
512 else
513 // play
514 if( command == PARCEL_MEDIA_COMMAND_PLAY )
515 {
516 //llinfos << ">>> LLMediaEngine::process_parcel_media with command = " <<( '0' + command ) << llendl;
517
518 convertImageAndLoadUrl( false, false, std::string() );
519 }
520 else
521 // loop
522 if( command == PARCEL_MEDIA_COMMAND_LOOP )
523 {
524 //llinfos << ">>> LLMediaEngine::process_parcel_media with command = " <<( '0' + command ) << llendl;
525
526 // huh? what is play?
527 //convertImageAndLoadUrl( play );
528 convertImageAndLoadUrl( true, false, std::string() );
529 }
530 else
531 // unload
532 if( command == PARCEL_MEDIA_COMMAND_UNLOAD )
533 {
534 //llinfos << ">>> LLMediaEngine::process_parcel_media with command = " <<( '0' + command ) << llendl;
535
536 if (LLMediaEngine::getInstance()->isLoaded())
537 {
538 LLMediaEngine::getInstance()->unload();
539 LLMediaEngine::getInstance()->destroyImageRaw();
540 }
541 }
542 }
543
544 if (flags & (1<<PARCEL_MEDIA_COMMAND_TIME))
545 {
546 // do something about fast forward
547 LLMediaEngine::getInstance()->seek(time);
548 }
549}
550
551//////////////////////////////////////////////////////////////////////////////////////////
552// static
553/*
554// ParcelMediaUpdate
555// Sends a parcel media update to a single user
556// For global updates use the parcel manager.
557{
558 ParcelMediaUpdate Low NotTrusted Unencoded
559 {
560 DataBlock Single
561 { MediaURL Variable 1 } // string
562 { MediaID LLUUID }
563 { MediaAutoScale U8 }
564 }
565}
566*/
567void LLMediaEngine::process_parcel_media_update( LLMessageSystem *msg, void ** )
568{
569 LLUUID media_uuid;
570 char media_url[255];
571 U8 auto_align;
572 msg->getUUID( "DataBlock", "MediaID", media_uuid );
573 msg->getString( "DataBlock", "MediaURL", 255, media_url );
574 msg->getU8( "DataBlock", "MediaAutoScale", auto_align );
575
576 LLMediaEngine* media_engine = LLMediaEngine::getInstance();
577 LLString url_string ( media_url );
578
579 auto_align = (auto_align) ? TRUE : FALSE;
580
581 if( !( (media_engine->getUrl() == url_string)
582 && (media_engine->getImageUUID() == media_uuid)
583 && (media_engine->isAutoScaled() == auto_align ) ) )
584 {
585 if (media_engine->isLoaded())
586 {
587 media_engine->unload();
588 media_engine->destroyImageRaw();
589 }
590
591 media_engine->setUrl(url_string);
592 media_engine->setImageUUID(media_uuid);
593 media_engine->setAutoScaled(auto_align);
594 }
595}
596
597// sets proxy information for any of the media impls that may want to use it
598void LLMediaEngine::setNetworkProxy ( BOOL enabledIn, const LLString& addressIn,
599 S32 portIn, S32 socksIn, const LLString& excludeIn )
600{
601 mProxyEnabled = enabledIn;
602 mProxyAddress = addressIn;
603 mProxyPort = portIn;
604 mProxySocks = socksIn;
605 mProxyExlude = excludeIn;
606}
607
608// gets proxy information for any of the media impls that may want to use it
609void LLMediaEngine::getNetworkProxy ( BOOL& enabledOut, LLString& addressOut,
610 S32& portOut, S32& socksOut, LLString& excludeOut )
611{
612 enabledOut = mProxyEnabled;
613 addressOut = mProxyAddress;
614 portOut = mProxyPort;
615 socksOut = mProxySocks;
616 excludeOut = mProxyExlude;
617}
618