aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmedia
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llmedia
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/llmedia')
-rw-r--r--linden/indra/llmedia/files.lst4
-rw-r--r--linden/indra/llmedia/llmedia.vcproj214
-rw-r--r--linden/indra/llmedia/llmediabase.cpp198
-rw-r--r--linden/indra/llmedia/llmediabase.h136
-rw-r--r--linden/indra/llmedia/llmediaemitter.h107
-rw-r--r--linden/indra/llmedia/llmediaemitterevents.h57
-rw-r--r--linden/indra/llmedia/llmediaengine.cpp618
-rw-r--r--linden/indra/llmedia/llmediaengine.h139
-rw-r--r--linden/indra/llmedia/llmediaimplquicktime.cpp911
-rw-r--r--linden/indra/llmedia/llmediaimplquicktime.h131
-rw-r--r--linden/indra/llmedia/llmediamoviebase.cpp222
-rw-r--r--linden/indra/llmedia/llmediamoviebase.h80
-rw-r--r--linden/indra/llmedia/llmediaobservers.h50
13 files changed, 2867 insertions, 0 deletions
diff --git a/linden/indra/llmedia/files.lst b/linden/indra/llmedia/files.lst
new file mode 100644
index 0000000..35ae5ab
--- /dev/null
+++ b/linden/indra/llmedia/files.lst
@@ -0,0 +1,4 @@
1llmedia/llmediabase.cpp
2llmedia/llmediaengine.cpp
3llmedia/llmediaimplquicktime.cpp
4llmedia/llmediamoviebase.cpp
diff --git a/linden/indra/llmedia/llmedia.vcproj b/linden/indra/llmedia/llmedia.vcproj
new file mode 100644
index 0000000..93c11b2
--- /dev/null
+++ b/linden/indra/llmedia/llmedia.vcproj
@@ -0,0 +1,214 @@
1<?xml version="1.0" encoding="Windows-1252"?>
2<VisualStudioProject
3 ProjectType="Visual C++"
4 Version="7.10"
5 Name="llmedia"
6 ProjectGUID="{9D0C7E02-6506-4EE7-BC5C-75671D28D594}"
7 RootNamespace="llmedia"
8 Keyword="Win32Proj">
9 <Platforms>
10 <Platform
11 Name="Win32"/>
12 </Platforms>
13 <Configurations>
14 <Configuration
15 Name="Debug|Win32"
16 OutputDirectory="../lib_$(ConfigurationName)/i686-win32"
17 IntermediateDirectory="Debug"
18 ConfigurationType="4"
19 CharacterSet="1">
20 <Tool
21 Name="VCCLCompilerTool"
22 Optimization="0"
23 AdditionalIncludeDirectories="..\llcommon;..\llrender;..\llwindow;..\llimage;..\llmath;..\llvfs;..\llmessage;..\llui;&quot;..\..\libraries\i686-win32\include&quot;;..\..\libraries\include\;&quot;..\..\libraries\i686-win32\include\quicktime&quot;"
24 PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LL_WINDOWS;LL_DEBUG;XP_WIN;XP_WIN32"
25 MinimalRebuild="TRUE"
26 BasicRuntimeChecks="3"
27 RuntimeLibrary="1"
28 StructMemberAlignment="4"
29 ForceConformanceInForLoopScope="TRUE"
30 UsePrecompiledHeader="0"
31 WarningLevel="3"
32 WarnAsError="TRUE"
33 Detect64BitPortabilityProblems="FALSE"
34 DebugInformationFormat="4"
35 DisableSpecificWarnings="4702"/>
36 <Tool
37 Name="VCCustomBuildTool"/>
38 <Tool
39 Name="VCLibrarianTool"
40 OutputFile="$(OutDir)/llmedia.lib"
41 AdditionalLibraryDirectories=""/>
42 <Tool
43 Name="VCMIDLTool"/>
44 <Tool
45 Name="VCPostBuildEventTool"/>
46 <Tool
47 Name="VCPreBuildEventTool"/>
48 <Tool
49 Name="VCPreLinkEventTool"/>
50 <Tool
51 Name="VCResourceCompilerTool"/>
52 <Tool
53 Name="VCWebServiceProxyGeneratorTool"/>
54 <Tool
55 Name="VCXMLDataGeneratorTool"/>
56 <Tool
57 Name="VCManagedWrapperGeneratorTool"/>
58 <Tool
59 Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
60 </Configuration>
61 <Configuration
62 Name="Release|Win32"
63 OutputDirectory="../lib_$(ConfigurationName)/i686-win32"
64 IntermediateDirectory="Release"
65 ConfigurationType="4"
66 CharacterSet="1">
67 <Tool
68 Name="VCCLCompilerTool"
69 GlobalOptimizations="FALSE"
70 InlineFunctionExpansion="0"
71 EnableIntrinsicFunctions="FALSE"
72 OptimizeForProcessor="0"
73 OptimizeForWindowsApplication="FALSE"
74 AdditionalIncludeDirectories="..\llcommon;..\llrender;..\llwindow;..\llimage;..\llmath;..\llvfs;..\llmessage;..\llui;&quot;..\..\libraries\i686-win32\include&quot;;..\..\libraries\include\;&quot;..\..\libraries\i686-win32\include\quicktime&quot;"
75 PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;LL_RELEASE;XP_WIN;XP_WIN32"
76 RuntimeLibrary="0"
77 StructMemberAlignment="0"
78 ForceConformanceInForLoopScope="TRUE"
79 UsePrecompiledHeader="0"
80 WarningLevel="3"
81 WarnAsError="FALSE"
82 Detect64BitPortabilityProblems="FALSE"
83 DebugInformationFormat="3"
84 DisableSpecificWarnings="4702"/>
85 <Tool
86 Name="VCCustomBuildTool"/>
87 <Tool
88 Name="VCLibrarianTool"
89 OutputFile="$(OutDir)/llmedia.lib"
90 AdditionalLibraryDirectories=""
91 IgnoreAllDefaultLibraries="FALSE"
92 IgnoreDefaultLibraryNames=""/>
93 <Tool
94 Name="VCMIDLTool"/>
95 <Tool
96 Name="VCPostBuildEventTool"/>
97 <Tool
98 Name="VCPreBuildEventTool"/>
99 <Tool
100 Name="VCPreLinkEventTool"/>
101 <Tool
102 Name="VCResourceCompilerTool"/>
103 <Tool
104 Name="VCWebServiceProxyGeneratorTool"/>
105 <Tool
106 Name="VCXMLDataGeneratorTool"/>
107 <Tool
108 Name="VCManagedWrapperGeneratorTool"/>
109 <Tool
110 Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
111 </Configuration>
112 <Configuration
113 Name="ReleaseNoOpt|Win32"
114 OutputDirectory="../lib_$(ConfigurationName)/i686-win32"
115 IntermediateDirectory="$(ConfigurationName)"
116 ConfigurationType="4"
117 CharacterSet="1">
118 <Tool
119 Name="VCCLCompilerTool"
120 Optimization="0"
121 GlobalOptimizations="FALSE"
122 InlineFunctionExpansion="0"
123 EnableIntrinsicFunctions="FALSE"
124 OptimizeForProcessor="0"
125 OptimizeForWindowsApplication="FALSE"
126 AdditionalIncludeDirectories="..\llcommon;..\llrender;..\llwindow;..\llimage;..\llmath;..\llvfs;..\llmessage;..\llui;&quot;..\..\libraries\i686-win32\include&quot;;..\..\libraries\include\;&quot;..\..\libraries\i686-win32\include\quicktime&quot;"
127 PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;LL_RELEASE;XP_WIN;XP_WIN32"
128 RuntimeLibrary="0"
129 StructMemberAlignment="0"
130 ForceConformanceInForLoopScope="TRUE"
131 UsePrecompiledHeader="0"
132 WarningLevel="3"
133 WarnAsError="TRUE"
134 Detect64BitPortabilityProblems="FALSE"
135 DebugInformationFormat="3"
136 DisableSpecificWarnings="4702"/>
137 <Tool
138 Name="VCCustomBuildTool"/>
139 <Tool
140 Name="VCLibrarianTool"
141 OutputFile="$(OutDir)/llmedia.lib"
142 AdditionalLibraryDirectories=""
143 IgnoreAllDefaultLibraries="FALSE"
144 IgnoreDefaultLibraryNames=""/>
145 <Tool
146 Name="VCMIDLTool"/>
147 <Tool
148 Name="VCPostBuildEventTool"/>
149 <Tool
150 Name="VCPreBuildEventTool"/>
151 <Tool
152 Name="VCPreLinkEventTool"/>
153 <Tool
154 Name="VCResourceCompilerTool"/>
155 <Tool
156 Name="VCWebServiceProxyGeneratorTool"/>
157 <Tool
158 Name="VCXMLDataGeneratorTool"/>
159 <Tool
160 Name="VCManagedWrapperGeneratorTool"/>
161 <Tool
162 Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
163 </Configuration>
164 </Configurations>
165 <References>
166 </References>
167 <Files>
168 <Filter
169 Name="Source Files"
170 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
171 UniqueIdentifier="{44DBC47A-0AF0-4726-A094-2D6FBB65FFFA}">
172 <File
173 RelativePath=".\llmediabase.cpp">
174 </File>
175 <File
176 RelativePath=".\llmediaengine.cpp">
177 </File>
178 <File
179 RelativePath=".\llmediaimplquicktime.cpp">
180 </File>
181 <File
182 RelativePath=".\llmediamoviebase.cpp">
183 </File>
184 <File
185 RelativePath=".\llmediamoviebase.h">
186 </File>
187 </Filter>
188 <Filter
189 Name="Header Files"
190 Filter="h;hpp;hxx;hm;inl;inc;xsd"
191 UniqueIdentifier="{D188664C-B9B7-4982-8C4B-8D9A44B4D9EF}">
192 <File
193 RelativePath=".\llmediabase.h">
194 </File>
195 <File
196 RelativePath=".\llmediaemitter.h">
197 </File>
198 <File
199 RelativePath=".\llmediaemitterevents.h">
200 </File>
201 <File
202 RelativePath=".\llmediaengine.h">
203 </File>
204 <File
205 RelativePath=".\llmediaimplquicktime.h">
206 </File>
207 <File
208 RelativePath=".\llmediaobservers.h">
209 </File>
210 </Filter>
211 </Files>
212 <Globals>
213 </Globals>
214</VisualStudioProject>
diff --git a/linden/indra/llmedia/llmediabase.cpp b/linden/indra/llmedia/llmediabase.cpp
new file mode 100644
index 0000000..a27fd34
--- /dev/null
+++ b/linden/indra/llmedia/llmediabase.cpp
@@ -0,0 +1,198 @@
1/**
2 * @file llmediabase.cpp
3 * @brief LLMedia support - base class
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 "linden_common.h"
29
30#include "llmediabase.h"
31#include "llmediaimplquicktime.h"
32
33LLMediaBase::LLMediaBase() :
34 mBufferChangeCount ( 1 ),
35 mLastBufferChangeCount ( 0 ),
36 mMediaWidth ( 0 ),
37 mMediaHeight ( 0 ),
38 mMediaDepthBytes ( 0 ),
39 mMediaRowbytes( 0 ),
40 mTextureWidth ( 0 ),
41 mTextureHeight ( 0 ),
42 mTextureDepth ( 0 ),
43 mTextureFormatInternal ( 0 ),
44 mTextureFormatPrimary ( 0 ),
45 mTextureFormatType ( 0 ),
46 mTextureFormatSwapBytes ( 0 )
47{
48
49}
50
51///////////////////////////////////////////////////////////////////////////////
52// factory method based on explicit media type
53LLMediaBase* LLMediaBase::make( const MediaType mediaTypeIn, S32 width_pixels, S32 height_pixels )
54{
55#if LL_QUICKTIME_ENABLED
56 if ( mediaTypeIn == QuickTime )
57 {
58 return new LLMediaImplQuickTime ();
59 }
60 else
61#endif
62
63 return 0;
64}
65
66///////////////////////////////////////////////////////////////////////////////
67//
68BOOL
69LLMediaBase::
70init ()
71{
72 // build event and emit it
73 LLMediaEvent event ( 0, "" );
74 mMediaEventEmitter.update ( &LLMediaObserver::onInit, event );
75
76 return TRUE;
77}
78
79///////////////////////////////////////////////////////////////////////////////
80//
81BOOL
82LLMediaBase::
83load ( const LLString& urlIn )
84{
85 // build event and emit it
86 LLMediaEvent event ( 0, urlIn );
87 mMediaEventEmitter.update ( &LLMediaObserver::onLoad, event );
88
89 return TRUE;
90}
91
92///////////////////////////////////////////////////////////////////////////////
93//
94BOOL
95LLMediaBase::
96unload ()
97{
98 LLMediaEvent event ( 0, "" );
99 mMediaEventEmitter.update ( &LLMediaObserver::onUnload, event );
100
101 return TRUE;
102}
103
104///////////////////////////////////////////////////////////////////////////////
105//
106S32 LLMediaBase::getTextureWidth() const
107{
108 return mTextureWidth;
109}
110
111///////////////////////////////////////////////////////////////////////////////
112//
113S32 LLMediaBase::getTextureHeight() const
114{
115 return mTextureHeight;
116}
117
118///////////////////////////////////////////////////////////////////////////////
119//
120S32 LLMediaBase::getTextureDepth() const
121{
122 return mTextureDepth;
123}
124
125///////////////////////////////////////////////////////////////////////////////
126//
127S32 LLMediaBase::getTextureFormatInternal() const
128{
129 return mTextureFormatInternal;
130}
131
132///////////////////////////////////////////////////////////////////////////////
133//
134S32 LLMediaBase::getTextureFormatPrimary() const
135{
136 return mTextureFormatPrimary;
137}
138
139///////////////////////////////////////////////////////////////////////////////
140//
141S32 LLMediaBase::getTextureFormatType() const
142{
143 return mTextureFormatType;
144}
145
146///////////////////////////////////////////////////////////////////////////////
147//
148S32 LLMediaBase::getTextureFormatSwapBytes() const
149{
150 return mTextureFormatSwapBytes;
151}
152
153///////////////////////////////////////////////////////////////////////////////
154//
155S32 LLMediaBase::getMediaWidth() const
156{
157 return mMediaWidth;
158}
159
160///////////////////////////////////////////////////////////////////////////////
161//
162S32 LLMediaBase::getMediaHeight() const
163{
164 return mMediaHeight;
165}
166
167///////////////////////////////////////////////////////////////////////////////
168//
169S32 LLMediaBase::getMediaDepthBytes() const
170{
171 return mMediaDepthBytes;
172}
173
174///////////////////////////////////////////////////////////////////////////////
175//
176S32 LLMediaBase::getMediaBufferSize() const
177{
178 if(mMediaRowbytes != 0)
179 {
180 return mMediaHeight * mMediaRowbytes;
181 }
182
183 return mMediaWidth * mMediaHeight * mMediaDepthBytes;
184};
185
186///////////////////////////////////////////////////////////////////////////////
187//
188BOOL LLMediaBase::addMediaObserver( LLMediaObserver* observerIn )
189{
190 return mMediaEventEmitter.addObserver( observerIn );
191}
192
193///////////////////////////////////////////////////////////////////////////////
194//
195BOOL LLMediaBase::remMediaObserver( LLMediaObserver* observerIn )
196{
197 return mMediaEventEmitter.remObserver( observerIn );
198}
diff --git a/linden/indra/llmedia/llmediabase.h b/linden/indra/llmedia/llmediabase.h
new file mode 100644
index 0000000..cf16947
--- /dev/null
+++ b/linden/indra/llmedia/llmediabase.h
@@ -0,0 +1,136 @@
1/**
2 * @file llmediabase.h
3 * @brief LLMedia support - base class
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// header guard
29#ifndef llmediabase_h
30#define llmediabase_h
31
32#include "llstring.h"
33#include "llmediaemitter.h"
34#include "llmediaobservers.h"
35#include "llmediaemitterevents.h"
36
37class LLMediaBase
38{
39 public:
40 LLMediaBase ();
41
42 // do the right thing with dtor
43 virtual ~LLMediaBase ()
44 {
45 };
46
47 ///////////////////////////////////////////////////////////////////////////////
48 // public interface:
49
50 ///////////////////////////////////////////////////////////////////////////////
51 // different types of supported media
52 enum MediaType { Unknown, QuickTime };
53
54 ///////////////////////////////////////////////////////////////////////////////
55 // factory method based on explicit media type
56 static LLMediaBase* make ( const MediaType mediaTypeIn, S32 width_pixels, S32 height_pixels );
57
58 // Result codes for updateMedia
59 enum
60 {
61 updateMediaNoChanges,
62 updateMediaNeedsUpdate,
63 updateMediaNeedsSizeChange
64
65 } updateMediaResult;
66
67 // housekeeping
68 virtual BOOL setBuffer ( U8* bufferIn ) = 0;
69 virtual bool setBufferSize(S32 width_pixels, S32 height_pixels) { return false; }
70 virtual BOOL init ();
71 virtual BOOL load ( const LLString& urlIn );
72 virtual BOOL unload ();
73
74 // media data
75 virtual S32 updateMedia () = 0;
76 virtual U8* getMediaData () = 0;
77 virtual S32 getTextureWidth () const;
78 virtual S32 getTextureHeight () const;
79 virtual S32 getTextureDepth () const;
80 virtual S32 getTextureFormatInternal () const;
81 virtual S32 getTextureFormatPrimary () const;
82 virtual S32 getTextureFormatType () const;
83 virtual S32 getTextureFormatSwapBytes () const;
84 virtual S32 getMediaWidth () const;
85 virtual S32 getMediaHeight () const;
86 virtual S32 getMediaDepthBytes () const;
87 virtual S32 getMediaBufferSize () const;
88
89 // allow consumers to observe media events
90 virtual BOOL addMediaObserver( LLMediaObserver* observerIn );
91 virtual BOOL remMediaObserver( LLMediaObserver* observerIn );
92
93 // MBW -- XXX -- These don't belong here!
94 // LLMediaEngine should really only deal with LLMediaMovieBase subclasses
95 virtual BOOL stop () { return TRUE; }
96 virtual BOOL play () { return TRUE; }
97 virtual BOOL loop ( S32 howMany ) { return TRUE; }
98 virtual BOOL pause () { return TRUE; }
99 virtual BOOL seek ( F64 time ) { return TRUE; }
100 virtual BOOL setVolume ( F32 volumeIn ) { return TRUE; }
101 virtual BOOL isLoaded () const { return TRUE; }
102 virtual BOOL isPaused () const { return FALSE; }
103 virtual BOOL isPlaying () const { return TRUE; }
104 virtual BOOL isLooping () const { return FALSE; }
105 virtual void setAutoScaled ( BOOL autoScaledIn ) {}
106
107 protected:
108 // event emitter
109 LLMediaEmitter<LLMediaObserver> mMediaEventEmitter;
110
111 U32 mBufferChangeCount; // Incremented when the buffer changes
112 U32 mLastBufferChangeCount; // Set to mBufferChangeCount when the buffer is reported as changed
113
114 S32 mMediaWidth;
115 S32 mMediaHeight;
116 S32 mMediaDepthBytes;
117 S32 mMediaRowbytes;
118 S32 mTextureWidth;
119 S32 mTextureHeight;
120 S32 mTextureDepth;
121 S32 mTextureFormatInternal;
122 S32 mTextureFormatPrimary;
123 S32 mTextureFormatType;
124 S32 mTextureFormatSwapBytes;
125
126 public:
127
128 // Has memory buffer been updated? (page content change, scroll, movie frame drawn, etc)
129 void bufferChanged() { mBufferChangeCount++; }
130 bool getBufferChanged() const { return mBufferChangeCount != mLastBufferChangeCount; }
131 void resetBufferChanged() { mLastBufferChangeCount = mBufferChangeCount; }
132
133};
134
135
136#endif // llmediabase_h
diff --git a/linden/indra/llmedia/llmediaemitter.h b/linden/indra/llmedia/llmediaemitter.h
new file mode 100644
index 0000000..fc68303
--- /dev/null
+++ b/linden/indra/llmedia/llmediaemitter.h
@@ -0,0 +1,107 @@
1/**
2 * @file llmediaemitter.h
3 * @brief LLMedia support - templatized emitter class.
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// header guard
29#ifndef llmediaemitter_h
30#define llmediaemitter_h
31
32// standard headers
33#include <algorithm>
34#include <typeinfo>
35#include <iostream>
36#include <list>
37
38#include "stdtypes.h"
39
40///////////////////////////////////////////////////////////////////////////////
41// templatized emitter class
42template < class T >
43class LLMediaEmitter
44{
45 public:
46 typedef typename T::EventType EventType;
47 typedef std::list< T* > ObserverContainer;
48 typedef void ( T::*observerMethod )( const EventType& );
49
50 protected:
51 ObserverContainer observers;
52
53 public:
54 LLMediaEmitter()
55 {
56 };
57
58 ~LLMediaEmitter()
59 {
60 };
61
62 ///////////////////////////////////////////////////////////////////////////////
63 //
64 BOOL addObserver ( T* observerIn )
65 {
66 if ( ! observerIn )
67 return FALSE;
68
69 // check if observer already exists
70 if ( std::find ( observers.begin (), observers.end (), observerIn ) != observers.end () )
71 return FALSE;
72
73 // save it
74 observers.push_back ( observerIn );
75
76 return true;
77 };
78
79 ///////////////////////////////////////////////////////////////////////////////
80 //
81 BOOL remObserver ( T* observerIn )
82 {
83 if ( ! observerIn )
84 return FALSE;
85
86 observers.remove ( observerIn );
87
88 return TRUE;
89 };
90
91 ///////////////////////////////////////////////////////////////////////////////
92 //
93 void update ( observerMethod method, const EventType& msgIn )
94 {
95 typename std::list< T* >::iterator iter = observers.begin ();
96
97 while ( iter != observers.end () )
98 {
99 ( ( *iter )->*method ) ( msgIn );
100
101 ++iter;
102 };
103 };
104 };
105
106
107#endif // llmediaemitter_h
diff --git a/linden/indra/llmedia/llmediaemitterevents.h b/linden/indra/llmedia/llmediaemitterevents.h
new file mode 100644
index 0000000..1a2eb17
--- /dev/null
+++ b/linden/indra/llmedia/llmediaemitterevents.h
@@ -0,0 +1,57 @@
1/**
2 * @file llmediaemitterevents.h
3 * @brief LLMedia support - events emitted by emitter to observer.
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// header guard
29#ifndef llmediaemitterevents_h
30#define llmediaemitterevents_h
31
32#include "stdtypes.h"
33
34
35class LLMediaEvent
36{
37 public:
38 LLMediaEvent ( S32 actionIn, const LLString& urlIn, void* data = NULL ):
39 action ( actionIn ),
40 url ( urlIn ),
41 mData(data)
42 { }
43
44 virtual ~LLMediaEvent () { }
45
46 S32 getAction () const { return action; }
47 LLString getUrl () const { return url; }
48 void* getData() const { return mData; }
49
50 private:
51 S32 action;
52 std::string url;
53 void* mData;
54};
55
56
57#endif // llmediaemitterevents_h
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
diff --git a/linden/indra/llmedia/llmediaengine.h b/linden/indra/llmedia/llmediaengine.h
new file mode 100644
index 0000000..1efebec
--- /dev/null
+++ b/linden/indra/llmedia/llmediaengine.h
@@ -0,0 +1,139 @@
1/**
2 * @file llmediaengine.h
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#ifndef LLMEDIAENGINE_H
29#define LLMEDIAENGINE_H
30
31#include "linden_common.h"
32#include "lluuid.h"
33#include "llimage.h"
34
35#include "llmediabase.h"
36#include "llmediaobservers.h"
37
38
39#include "message.h"
40
41//////////////////////////////////////////////////////////////////////////////
42// media engine singleton
43class LLMediaEngine
44{
45public:
46 static void initClass();
47 static void updateClass(F32 volume);
48 static void cleanupClass();
49
50protected:
51 // don't let anyone else make one of these
52 LLMediaEngine ();
53
54public:
55 virtual ~LLMediaEngine ();
56
57 // used to get access to single instance of the class (singleton pattern)
58 static LLMediaEngine* getInstance ();
59
60 // public methods
61 BOOL init ();
62 BOOL update ();
63
64 // Pass web_url true if it's a web page, false if it's a movie.
65 // path is to mozilla directory for mozila
66 BOOL load( const LLString& urlIn, bool web_url, const LLString& path, S32 width_pixels, S32 height_pixels);
67
68 BOOL isLoaded ();
69 BOOL unload ();
70 BOOL play ();
71 BOOL loop ();
72 BOOL pause ();
73 BOOL stop ();
74 BOOL seek (F64 time);
75 void setAvailable ( BOOL availableIn );
76 BOOL isAvailable ();
77 void setEnabled ( BOOL enabledIn );
78 BOOL isEnabled ();
79 void setAutoScaled ( BOOL autoScaledIn );
80 BOOL isAutoScaled ();
81 BOOL setVolume ( F32 volumeIn );
82
83 void setUrl ( const LLString& urlIn );
84 const LLString& getUrl ();
85 void setImageUUID ( LLUUID textureIdIn );
86 LLUUID getImageUUID ();
87
88 // MBW -- XXX -- This should return a LLMediaMovieBase, but the web and movie media classes still haven't been
89 // fully disentangled.
90 LLMediaBase* getMediaRenderer();
91 LLImageRaw* getImageRaw() { return mImageRaw; }
92 void handleSizeChangedRequest();
93
94 //////////////////////////////////////////////////////////////////////////////////////////
95 //
96 static void convertImageAndLoadUrl ( bool enableLooping, bool web_url, const std::string& path);
97
98 //////////////////////////////////////////////////////////////////////////////////////////
99 //
100 static void process_parcel_media ( LLMessageSystem *msg, void ** );
101 static void process_parcel_media_update ( LLMessageSystem *msg, void ** );
102
103 // proxy configuration
104 void setNetworkProxy ( BOOL enabledIn, const LLString& addressIn,
105 S32 portIn, S32 socksIn, const LLString& excludeIn );
106
107 void getNetworkProxy ( BOOL& enabledOut, LLString& addressOut,
108 S32& portOut, S32& socksOut, LLString& excludeOuy );
109
110private:
111 void createImageRaw();
112 void destroyImageRaw();
113
114private:
115 BOOL mAvailable;
116 BOOL mEnabled;
117 BOOL mAutoScaled;
118 LLString mUrl;
119 // MBW -- XXX -- This should be a LLMediaMovieBase, but the web and movie media classes still haven't been
120 // fully disentangled.
121 LLMediaBase* mMediaRenderer;
122 LLPointer<LLImageRaw> mImageRaw;
123
124 LLUUID mImageUUID;
125 F32 mVolume;
126
127 // proxy information
128 BOOL mProxyEnabled;
129 LLString mProxyAddress;
130 S32 mProxyPort;
131 S32 mProxySocks;
132 LLString mProxyExlude;
133
134private:
135 static LLMediaEngine* sInstance;
136};
137
138#endif // LLMEDIAENGINE_H
139
diff --git a/linden/indra/llmedia/llmediaimplquicktime.cpp b/linden/indra/llmedia/llmediaimplquicktime.cpp
new file mode 100644
index 0000000..74b6cd9
--- /dev/null
+++ b/linden/indra/llmedia/llmediaimplquicktime.cpp
@@ -0,0 +1,911 @@
1/**
2 * @file llmediaimplquicktime.cpp
3 * @brief implementation that supports Apple QuickTime media.
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 "linden_common.h"
29
30#if LL_QUICKTIME_ENABLED
31
32#include <iostream>
33
34#include "llmediaimplquicktime.h"
35
36#include "llgl.h"
37#include "llglheaders.h" // For gl texture modes
38
39///////////////////////////////////////////////////////////////////////////////
40//
41LLMediaImplQuickTime::
42LLMediaImplQuickTime () :
43 theController ( NULL ),
44 currentMode ( ModeIdle ),
45 theGWorld ( 0 ),
46 theMovie ( 0 ),
47 mediaData ( 0 ),
48 loopsLeft ( 0 ),
49 ownBuffer ( TRUE ),
50 curVolume ( 0 ),
51 sizeChangeInProgress ( FALSE ),
52 initialStartDone ( FALSE ),
53 autoScaled ( FALSE )
54{
55// These should probably be in the initializer list above, but that seemed uglier...
56#if LL_DARWIN
57 // Mac OS -- gworld will be xRGB (4 byte pixels, like ARGB, but QuickDraw doesn't actually do alpha...)
58 mMediaDepthBytes = 4;
59 mTextureDepth = 4;
60 mTextureFormatInternal = GL_RGB8;
61 mTextureFormatPrimary = GL_BGRA;
62#ifdef LL_BIG_ENDIAN
63 mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV;
64#else
65 mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8;
66#endif
67
68#else
69 // Windows -- GWorld will be RGB (3 byte pixels)
70 mMediaDepthBytes = 3;
71 mTextureDepth = 3;
72 mTextureFormatInternal = GL_RGB8;
73 mTextureFormatPrimary = GL_RGB;
74 mTextureFormatType = GL_UNSIGNED_BYTE;
75#endif
76};
77
78///////////////////////////////////////////////////////////////////////////////
79//
80LLMediaImplQuickTime::
81~LLMediaImplQuickTime ()
82{
83 unload();
84}
85
86///////////////////////////////////////////////////////////////////////////////
87//
88BOOL
89LLMediaImplQuickTime::
90setBuffer ( U8* bufferIn )
91{
92 OSErr err = noErr;
93
94 // If we're waiting for a size change, we just got one.
95 sizeChangeInProgress = FALSE;
96
97 // Since we've pointed QuickTime at the old media data buffer directly, we need to be somewhat careful deleting it...
98 U8* oldMediaData = mediaData;
99 BOOL ownedMediaData = ownBuffer;
100#if LL_DARWIN
101 GWorldPtr oldGWorld = theGWorld;
102#endif
103
104 if(bufferIn == NULL)
105 {
106 // Passing NULL to this function requests that the object allocate its own buffer.
107 mediaData = new unsigned char [ mMediaHeight * mMediaRowbytes ];
108 ownBuffer = TRUE;
109 }
110 else
111 {
112 // Use the supplied buffer.
113 mediaData = bufferIn;
114 ownBuffer = FALSE;
115 }
116
117 if(mediaData == NULL)
118 {
119 // This is bad.
120 llerrs << "LLMediaImplQuickTime::setBuffer: mediaData is NULL" << llendl;
121 // NOTE: This case doesn't clean up properly. This assert is fatal, so this isn't a huge problem,
122 // but if this assert is ever removed the code should be fixed to clean up correctly.
123 return FALSE;
124 }
125
126 err = NewGWorldFromPtr ( &theGWorld, mMediaDepthBytes * 8, &movieRect, NULL, NULL, 0, (Ptr)mediaData, mMediaRowbytes);
127 if(err == noErr)
128 {
129 if(theMovie)
130 {
131 // tell the movie about it
132 SetMovieGWorld ( theMovie, theGWorld, GetGWorldDevice ( theGWorld ) );
133 }
134
135 if(theController)
136 {
137 // and tell the movie controller about it.
138 MCSetControllerPort(theController, theGWorld);
139 }
140
141#if LL_DARWIN
142// NOTE: (CP) This call ultimately leads to a crash in NewGWorldFromPtr on Windows (only)
143// Not calling DisposeGWorld doesn't appear to leak anything significant and stops the crash occuring.
144// This will eventually be fixed but for now, leaking slightly is better than crashing.
145 if ( oldGWorld != NULL )
146 {
147 // Delete the old GWorld
148 DisposeGWorld ( oldGWorld );
149 oldGWorld = NULL;
150 }
151#endif
152 }
153 else
154 {
155 // Hmm... this may be bad. Assert here?
156 llerrs << "LLMediaImplQuickTime::setBuffer: NewGWorldFromPtr failed" << llendl;
157 theGWorld = NULL;
158 return FALSE;
159 }
160
161 // Delete the old media data buffer iff we owned it.
162 if ( ownedMediaData )
163 {
164 if ( oldMediaData )
165 {
166 delete [] oldMediaData;
167 }
168 }
169
170 // build event and emit it
171
172 return TRUE;
173}
174
175///////////////////////////////////////////////////////////////////////////////
176//
177BOOL
178LLMediaImplQuickTime::
179init ()
180{
181 // movied to main application initialization for now because it's non-trivial and only needs to be done once
182 // (even though it goes against the media framework design)
183 //if ( InitializeQTML ( 0L ) != 0 )
184 //{
185 // return FALSE;
186 //};
187
188 //if ( EnterMovies () != 0 )
189 //{
190 // return FALSE;
191 //};
192
193 return LLMediaMovieBase::init();
194}
195
196///////////////////////////////////////////////////////////////////////////////
197//
198void
199LLMediaImplQuickTime::
200updateMediaSize()
201{
202 if((theController == NULL) && (!isQTLoaded()))
203 {
204 // The movie's not loaded enough to get info about it yet.
205 // Set up a dummy buffer.
206 movieRect.left = movieRect.top = 0;
207 movieRect.right = movieRect.bottom = 64;
208 mMediaRowbytes = mMediaDepthBytes * 64;
209 mMediaWidth = 64;
210 mMediaHeight = 64;
211 mTextureWidth = 64;
212 mTextureHeight = 64;
213
214 return;
215 }
216
217 // pick up the size of the movie
218 GetMovieBox ( theMovie, &movieRect );
219
220 // save the size of the media so consumer of media class can use it
221 mMediaWidth = movieRect.right - movieRect.left;
222 mMediaHeight = movieRect.bottom - movieRect.top;
223
224 // Giant media could make us try to use textures bigger than the opengl implementation can handle.
225 // Pin the maximum X or Y dimension to 1024.
226 // NOTE: 1024x1024 may still hurt a lot, but it shouldn't cause opengl to flame out.
227 if(mMediaWidth > 1024)
228 {
229 mMediaWidth = 1024;
230 }
231 if(mMediaHeight > 1024)
232 {
233 mMediaHeight = 1024;
234 }
235
236 // calculate the texture size required to hold media of this size (next power of 2 bigger)
237 for ( mTextureWidth = 1; mTextureWidth < mMediaWidth; mTextureWidth <<= 1 )
238 {
239 };
240
241 for ( mTextureHeight = 1; mTextureHeight < mMediaHeight; mTextureHeight <<= 1 )
242 {
243 };
244
245// llinfos << "Media texture size will be " << mTextureWidth << " x " << mTextureHeight << llendl;
246
247 // if autoscale is on we simply make the media & texture sizes the same and quicktime does all the hard work
248 if ( autoScaled )
249 {
250 // Stretch the movie to fill the texture.
251 mMediaWidth = mTextureWidth;
252 mMediaHeight = mTextureHeight;
253
254 // scale movie using high quality but slow algorithm.
255 // NOTE: this results in close to same quality as texture scaling option but with (perhaps) significant
256 // loss of performance (e.g. my machine, release build, frame rate goes from 92 -> 82 fps
257 // To revert to original behaviour, just remove the line below.
258
259 // MBW -- There seems to be serious drop in performance above a particular size, on both low and high end machines.
260 // 512x256 is fine, while 512x512 is unusable. I theorize that this is due to CPU cache getting broken around that size.
261 if((mTextureWidth * mTextureHeight) <= (512 * 256))
262 {
263// llinfos << "Setting high-quality hint." << llendl;
264 SetMoviePlayHints ( theMovie, hintsHighQuality, hintsHighQuality );
265 }
266 };
267
268 // always flip movie using quicktime (little performance impact and no loss in quality)
269 if ( TRUE )
270 {
271 // Invert the movie in the Y directon to match the expected orientation of GL textures.
272 MatrixRecord transform;
273 GetMovieMatrix ( theMovie, &transform );
274
275 double centerX = mMediaWidth / 2.0;
276 double centerY = mMediaHeight / 2.0;
277 ScaleMatrix ( &transform, X2Fix ( 1.0 ), X2Fix ( -1.0 ), X2Fix ( centerX ), X2Fix ( centerY ) );
278
279 SetMovieMatrix ( theMovie, &transform );
280 };
281
282 movieRect.left = 0;
283 movieRect.top = 0;
284 movieRect.right = mMediaWidth;
285 movieRect.bottom = mMediaHeight;
286
287 // Calculate the rowbytes of the texture
288 mMediaRowbytes = mMediaWidth * mMediaDepthBytes;
289
290 SetMovieBox(theMovie, &movieRect);
291
292 if(theController == NULL)
293 {
294 SetGWorld(theGWorld, NULL);
295
296 // Create a movie controller for the movie
297 theController = NewMovieController(theMovie, &movieRect, mcNotVisible|mcTopLeftMovie);
298
299 MCSetActionFilterWithRefCon(theController, myMCActionFilterProc, (long)this);
300
301 // Allow the movie to dynamically resize (may be necessary for streaming movies to work right...)
302 SetMoviePlayHints(theMovie, hintsAllowDynamicResize, hintsAllowDynamicResize);
303 }
304 else
305 {
306 MCPositionController(theController, &movieRect, &movieRect, mcTopLeftMovie|mcPositionDontInvalidate);
307 }
308}
309
310///////////////////////////////////////////////////////////////////////////////
311//
312void
313LLMediaImplQuickTime::
314setupDummyBuffer()
315{
316 // Used when the movie can't be drawn for some reason. This sets up a buffer that keeps callers from getting annoyed.
317 movieRect.left = movieRect.top = 0;
318 movieRect.right = movieRect.bottom = 64;
319 mMediaRowbytes = mMediaDepthBytes * 64;
320 mMediaWidth = 64;
321 mMediaHeight = 64;
322 mTextureWidth = 64;
323 mTextureHeight = 64;
324
325 setBuffer ( NULL );
326
327 memset(mediaData, 0, mMediaRowbytes * mMediaHeight );
328}
329
330///////////////////////////////////////////////////////////////////////////////
331//
332BOOL
333LLMediaImplQuickTime::
334load ( const LLString& urlIn )
335{
336 // The movie may do things to the current port when it's created. Make sure we have a valid port set.
337 setupDummyBuffer();
338 SetGWorld(theGWorld, NULL);
339
340 Size mySize = ( Size ) urlIn.length () + 1;
341 if ( mySize == 0 )
342 return FALSE;
343
344 Handle myHandle = NewHandleClear ( mySize );
345 if ( myHandle == NULL )
346 return FALSE;
347
348 BlockMove ( urlIn.c_str (), *myHandle, mySize );
349
350 // Might be able to make this asynchronous with (newMovieActive|newMovieAsyncOK|newMovieIdleImportOK)?
351 OSErr err = NewMovieFromDataRef ( &theMovie, newMovieActive|newMovieDontInteractWithUser|newMovieAsyncOK|newMovieIdleImportOK, NULL, myHandle, URLDataHandlerSubType );
352
353 if ( err != noErr )
354 return false;
355
356 // function that gets called when a frame is drawn
357 SetMovieDrawingCompleteProc ( theMovie, movieDrawingCallWhenChanged, myFrameDrawnCallback, ( long ) this );
358
359 if(isQTLoaded())
360 {
361 updateMediaSize();
362 setBuffer(NULL);
363 }
364
365 // Tell the controller to play the movie. This also deals with the movie still loading.
366 //play();
367
368 return LLMediaMovieBase::load(urlIn);
369}
370
371///////////////////////////////////////////////////////////////////////////////
372//
373OSErr
374LLMediaImplQuickTime::
375myFrameDrawnCallback ( Movie callbackMovie, long refCon )
376{
377 LLMediaImplQuickTime* myQtRenderer = ( LLMediaImplQuickTime* ) refCon;
378
379 // The gworld quicktime is playing back into is now wrapped around myQtRenderer->mediaData,
380 // so there's no need to copy any data here.
381#if 0
382 Ptr pixels = GetPixBaseAddr ( myQtRenderer->pixmapHandle );
383
384 LockPixels ( myQtRenderer->pixmapHandle );
385
386 memcpy ( ( U8* ) myQtRenderer->mediaData, pixels, myQtRenderer->getMediaBufferSize () );
387
388 UnlockPixels ( myQtRenderer->pixmapHandle );
389#endif
390
391 myQtRenderer->bufferChanged();
392
393 return 0;
394}
395
396///////////////////////////////////////////////////////////////////////////////
397Boolean
398LLMediaImplQuickTime::myMCActionFilterProc (MovieController theMC, short theAction, void *theParams, long theRefCon)
399{
400 Boolean result = false;
401 LLMediaImplQuickTime *self = (LLMediaImplQuickTime*)theRefCon;
402
403 switch ( theAction )
404 {
405 // handle window resizing
406 case mcActionControllerSizeChanged:
407 self->sizeChanged();
408 break;
409
410 // Block any movie controller actions that open URLs.
411 case mcActionLinkToURL:
412 case mcActionGetNextURL:
413 case mcActionLinkToURLExtended:
414 // Prevent the movie controller from handling the message
415 result = true;
416 break;
417
418 default:
419 break;
420 };
421
422 return ( result );
423}
424
425///////////////////////////////////////////////////////////////////////////////
426//
427void
428LLMediaImplQuickTime::rewind()
429{
430 // MBW -- XXX -- I don't see an easy way to do this via the movie controller.
431 GoToBeginningOfMovie ( theMovie );
432
433 // Call this afterwards so the movie controller can sync itself with the movie.
434 MCMovieChanged(theController, theMovie);
435
436#if 0
437 // Maybe something like this?
438 TimeRecord when;
439 when.value.hi = 0;
440 when.value.lo = 0;
441 when.scale = GetMovieTimeScale(theMovie);
442
443 // This seems like the obvious thing, but a tech note (http://developer.apple.com/technotes/qt/qt_510.html) says otherwise...
444// when.base = GetMovieTimeBase(theMovie);
445 when.base = 0;
446
447 MCDoAction(theController, mcActionGoToTime, &when);
448#endif
449}
450
451///////////////////////////////////////////////////////////////////////////////
452//
453void
454LLMediaImplQuickTime::sizeChanged()
455{
456 // Set the movie to render (well, actually NOT render) to an internal buffer until the size change can be handled.
457 setupDummyBuffer();
458
459 // Make the next call to updateMedia request a size change.
460 sizeChangeInProgress = true;
461
462 // Recalculate the values that depend on the movie rect.
463 updateMediaSize();
464}
465
466///////////////////////////////////////////////////////////////////////////////
467//
468BOOL
469LLMediaImplQuickTime::
470isQTLoaded()
471{
472 BOOL result = false;
473
474 if(theMovie)
475 {
476 if(GetMovieLoadState(theMovie) >= kMovieLoadStateLoaded)
477 {
478 result = true;
479 }
480 }
481
482 return result;
483}
484
485///////////////////////////////////////////////////////////////////////////////
486//
487BOOL
488LLMediaImplQuickTime::
489isQTPlaythroughOK()
490{
491 BOOL result = false;
492
493 if(theMovie)
494 {
495 if(GetMovieLoadState(theMovie) >= kMovieLoadStatePlaythroughOK)
496 {
497 result = true;
498 }
499 }
500
501 return result;
502}
503
504///////////////////////////////////////////////////////////////////////////////
505//
506BOOL
507LLMediaImplQuickTime::
508unload ()
509{
510
511 if( theController )
512 {
513 // Slight paranoia...
514 MCSetActionFilterWithRefCon(theController, NULL, (long)this);
515
516 DisposeMovieController( theController );
517 theController = NULL;
518 };
519
520 if ( theMovie )
521 {
522 // Slight paranoia...
523 SetMovieDrawingCompleteProc ( theMovie, movieDrawingCallWhenChanged, nil, ( long ) this );
524
525 DisposeMovie ( theMovie );
526 theMovie = NULL;
527 };
528
529 if ( theGWorld )
530 {
531 DisposeGWorld ( theGWorld );
532 theGWorld = NULL;
533 };
534
535 if ( mediaData )
536 {
537 if ( ownBuffer )
538 {
539 delete mediaData;
540 mediaData = NULL;
541 };
542 };
543
544 return TRUE;
545}
546
547///////////////////////////////////////////////////////////////////////////////
548//
549S32
550LLMediaImplQuickTime::
551updateMedia ()
552{
553 if(!theController)
554 {
555 if(isQTLoaded())
556 {
557 // Movie has finished loading. Request a size change to update buffers, etc.
558 // We MUST update the media size here, so it will be correct before the size change request.
559 updateMediaSize();
560 return updateMediaNeedsSizeChange;
561 }
562 else
563 {
564 // Movie is still loading.
565 MoviesTask ( theMovie, 0 );
566 }
567 }
568
569 if(theController)
570 {
571 switch(currentMode)
572 {
573 case ModePlaying:
574 case ModeLooping:
575 if(!initialStartDone)
576 {
577 if(isQTPlaythroughOK())
578 {
579 // The movie is loaded enough to start playing. Start it now.
580 MCDoAction(theController, mcActionPrerollAndPlay, (void*)GetMoviePreferredRate(theMovie));
581
582 MCDoAction(theController, mcActionSetVolume, (void*)curVolume );
583
584 initialStartDone = TRUE;
585 }
586 }
587 break;
588 }
589
590// // This function may copy decompressed movie frames into our media data pointer. JC
591// if (!mediaData)
592// {
593// llwarns << "LLMediaImplQuickTime::updateMedia() about to update with null media pointer" << llendl;
594// }
595// else
596// {
597// // try writing to the pointer to see if it's valid
598// *mediaData = 0;
599// }
600
601 MCIdle(theController);
602 }
603
604 // If we need a size change, that takes precedence.
605 if(sizeChangeInProgress)
606 {
607 return updateMediaNeedsSizeChange;
608 }
609
610 BOOL updated = getBufferChanged();
611
612 resetBufferChanged();
613
614 if(updated)
615 return updateMediaNeedsUpdate;
616
617 // don't use movie controller for looping - appears to be broken on PCs (volume issue)
618 if ( currentMode == ModeLooping )
619 if ( IsMovieDone ( theMovie ) )
620 loop ( 0 );
621
622 return updateMediaNoChanges;
623}
624
625///////////////////////////////////////////////////////////////////////////////
626//
627void
628LLMediaImplQuickTime::
629setAutoScaled ( BOOL autoScaledIn )
630{
631 autoScaled = autoScaledIn;
632}
633
634///////////////////////////////////////////////////////////////////////////////
635//
636BOOL
637LLMediaImplQuickTime::
638stop ()
639{
640 currentMode = ModeStopped;
641
642 if(theController)
643 {
644 Fixed rate = X2Fix(0.0);
645 MCDoAction(theController, mcActionPlay, (void*)rate);
646
647 rewind();
648 }
649
650 return LLMediaMovieBase::stop();
651};
652
653///////////////////////////////////////////////////////////////////////////////
654//
655BOOL
656LLMediaImplQuickTime::
657play ()
658{
659 currentMode = ModePlaying;
660
661 if(theController)
662 {
663 if ( IsMovieDone ( theMovie ) )
664 {
665 rewind();
666 };
667
668 MCDoAction(theController, mcActionPrerollAndPlay, (void*)GetMoviePreferredRate(theMovie));
669
670 MCDoAction(theController, mcActionSetVolume, (void*)curVolume );
671 }
672
673 return LLMediaMovieBase::play();
674};
675
676///////////////////////////////////////////////////////////////////////////////
677//
678BOOL
679LLMediaImplQuickTime::
680loop ( S32 howMany )
681{
682 currentMode = ModeLooping;
683
684 // MBW -- XXX -- This may be harder to do with a movie controller...
685// loopsLeft = howMany;
686
687 if ( theController )
688 {
689 // Movie is loaded and set up.
690 if ( IsMovieDone ( theMovie ) )
691 {
692 rewind();
693 };
694
695 MCDoAction(theController, mcActionPrerollAndPlay, (void*)GetMoviePreferredRate(theMovie));
696
697 MCDoAction(theController, mcActionSetVolume, (void*)curVolume );
698 }
699
700 return LLMediaMovieBase::loop(howMany);
701};
702
703///////////////////////////////////////////////////////////////////////////////
704//
705BOOL
706LLMediaImplQuickTime::
707pause ()
708{
709 currentMode = ModePaused;
710
711 if(theController)
712 {
713 // Movie is loaded and set up.
714 Fixed rate = X2Fix(0.0);
715 MCDoAction(theController, mcActionPlay, (void*)rate);
716 }
717
718 return LLMediaMovieBase::pause();
719};
720
721///////////////////////////////////////////////////////////////////////////////
722//
723BOOL
724LLMediaImplQuickTime::
725setVolume ( F32 volumeIn )
726{
727 // Fixed point signed short, 8.8
728 curVolume = (short)(volumeIn * ( F32 ) 0x100);
729
730 if(theController != NULL)
731 {
732 MCDoAction(theController, mcActionSetVolume, (void*)curVolume);
733 }
734
735 return TRUE;
736}
737
738///////////////////////////////////////////////////////////////////////////////
739//
740F32
741LLMediaImplQuickTime::
742getVolume ()
743{
744 return ( ( F32 ) curVolume ) / ( F32 ) 0x100;
745}
746
747///////////////////////////////////////////////////////////////////////////////
748//
749BOOL
750LLMediaImplQuickTime::
751isIdle () const
752{
753 return ( currentMode == ModeIdle );
754};
755
756///////////////////////////////////////////////////////////////////////////////
757//
758BOOL
759LLMediaImplQuickTime::
760isError () const
761{
762 return ( currentMode == ModeError );
763};
764
765///////////////////////////////////////////////////////////////////////////////
766//
767BOOL
768LLMediaImplQuickTime::
769isBuffering () const
770{
771 return ( currentMode == ModeBuffering );
772};
773
774///////////////////////////////////////////////////////////////////////////////
775//
776BOOL
777LLMediaImplQuickTime::
778isLoaded () const
779{
780 // Only tell the caller the movie is loaded if we've had a chance to set up the movie controller.
781
782 return (theController != NULL);
783};
784
785///////////////////////////////////////////////////////////////////////////////
786//
787BOOL
788LLMediaImplQuickTime::
789isPlaying () const
790{
791 return ( currentMode == ModePlaying );
792};
793
794///////////////////////////////////////////////////////////////////////////////
795//
796BOOL
797LLMediaImplQuickTime::
798isLooping () const
799{
800 return ( currentMode == ModeLooping );
801};
802
803///////////////////////////////////////////////////////////////////////////////
804//
805BOOL
806LLMediaImplQuickTime::
807isPaused () const
808{
809 return ( currentMode == ModePaused );
810};
811
812///////////////////////////////////////////////////////////////////////////////
813//
814BOOL
815LLMediaImplQuickTime::
816isStopped () const
817{
818 return ( currentMode == ModeStopped );
819};
820
821///////////////////////////////////////////////////////////////////////////////
822//
823U8*
824LLMediaImplQuickTime::
825getMediaData ()
826{
827 return mediaData;
828}
829
830///////////////////////////////////////////////////////////////////////////////
831//
832BOOL
833LLMediaImplQuickTime::
834seek ( F64 time )
835{
836 // MBW -- XXX -- This should stash the time if theController is NULL, and seek to there when the movie's loaded.
837 // Do this later.
838 if(theController != NULL)
839 {
840 TimeRecord when;
841 when.scale = GetMovieTimeScale(theMovie);
842 when.base = 0;
843
844 // 'time' is in (floating point) seconds. The timebase time will be in 'units', where
845 // there are 'scale' units per second.
846 S64 rawTime = (S64)(time * (F64)(when.scale));
847
848 when.value.hi = ( SInt32 ) ( rawTime >> 32 );
849 when.value.lo = ( SInt32 ) ( ( rawTime & 0x00000000FFFFFFFF ) );
850
851 MCDoAction(theController, mcActionGoToTime, &when);
852 }
853
854 return TRUE;
855}
856
857///////////////////////////////////////////////////////////////////////////////
858//
859F64
860LLMediaImplQuickTime::
861getTime () const
862{
863 F64 result = 0;
864
865 if(theController != NULL)
866 {
867 TimeValue time;
868 TimeScale scale = 0;
869
870 time = MCGetCurrentTime(theController, &scale);
871 if(scale != 0)
872 {
873 result = ((F64)time) / ((F64)scale);
874 }
875 }
876
877 return result;
878}
879
880///////////////////////////////////////////////////////////////////////////////
881//
882F64
883LLMediaImplQuickTime::
884getMediaDuration () const
885{
886 F64 result = 0;
887 TimeScale scale = GetMovieTimeScale(theMovie);
888 TimeValue duration = GetMovieDuration(theMovie);
889
890 if(duration == kQTSUnknownDuration)
891 {
892 // Hmph.
893 // Return 0 in this case.
894 }
895 else if(duration == kQTSInfiniteDuration)
896 {
897 // This is the magic number for "indefinite duration", i.e. a live stream.
898 // Note that the docs claim this value is 0x7FFFFFF, while the symbolic constant is 0x7FFFFFFF. Go figure.
899 // Return 0 in this case.
900 }
901 else if(scale != 0)
902 {
903 // Timescale is a useful number. Convert to seconds.
904 result = (F64)duration;
905 result /= (F64)scale;
906 }
907
908 return result;
909}
910
911#endif
diff --git a/linden/indra/llmedia/llmediaimplquicktime.h b/linden/indra/llmedia/llmediaimplquicktime.h
new file mode 100644
index 0000000..9eb3a04
--- /dev/null
+++ b/linden/indra/llmedia/llmediaimplquicktime.h
@@ -0,0 +1,131 @@
1/**
2 * @file llmediaimplquicktime.h
3 * @brief implementation that supports Apple QuickTime media.
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#if LL_QUICKTIME_ENABLED
29
30// header guard
31#ifndef llmediaimplquicktime_h
32#define llmediaimplquicktime_h
33
34#include "stdtypes.h"
35
36#include "llmediamoviebase.h"
37
38#if LL_QUICKTIME_ENABLED
39#if LL_DARWIN
40#include <QuickTime/QuickTime.h>
41#else
42#include "MacTypes.h"
43#include "QTML.h"
44#include "Movies.h"
45#include "FixMath.h"
46#include "QuickTimeStreaming.h"
47#endif
48#endif
49
50
51////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
52//
53////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
54class LLMediaImplQuickTime:
55 public LLMediaMovieBase
56{
57 public:
58 LLMediaImplQuickTime ();
59 virtual ~LLMediaImplQuickTime ();
60
61 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
62 // implementation of the media public interface
63
64 // housekeeping
65 virtual BOOL setBuffer ( U8* bufferIn );
66 virtual BOOL init ();
67 virtual BOOL load ( const LLString& urlIn );
68 virtual BOOL unload ();
69
70 // transport controls
71 virtual BOOL stop ();
72 virtual BOOL play ();
73 virtual BOOL loop ( S32 howMany );
74 virtual BOOL pause ();
75 virtual BOOL seek ( F64 time );
76
77 // audio levels
78 virtual BOOL setVolume ( F32 volumeIn );
79 virtual F32 getVolume ();
80
81 // status
82 virtual BOOL isIdle () const;
83 virtual BOOL isBuffering () const;
84 virtual BOOL isError () const;
85 virtual BOOL isLoaded () const;
86 virtual BOOL isStopped () const;
87 virtual BOOL isPaused () const;
88 virtual BOOL isPlaying () const;
89 virtual BOOL isLooping () const;
90 virtual F64 getTime () const;
91
92 // media data
93 virtual S32 updateMedia ();
94 virtual void setAutoScaled ( BOOL autoScaledIn );
95 virtual U8* getMediaData ();
96 virtual F64 getMediaDuration () const;
97
98 private:
99 // quicktime specific
100 Movie theMovie;
101 ComponentInstance theController;
102 PixMapHandle pixmapHandle;
103 GWorldPtr theGWorld;
104 Rect movieRect;
105 U8* mediaData;
106 BOOL movieLoaded;
107 BOOL ownBuffer;
108 short curVolume;
109 S32 loopsLeft;
110
111 BOOL autoScaled;
112 BOOL sizeChangeInProgress;
113 BOOL initialStartDone;
114 BOOL isQTLoaded ();
115 BOOL isQTPlaythroughOK ();
116 void setupDummyBuffer ();
117
118 static OSErr myFrameDrawnCallback ( Movie callbackMovie, long refCon );
119 static Boolean myMCActionFilterProc (MovieController theMC, short theAction, void *theParams, long theRefCon);
120
121 void rewind();
122 void sizeChanged();
123 void updateMediaSize();
124
125 enum { ModeNone, ModeIdle, ModeError, ModeBuffering, ModeLoaded, ModeStopped, ModePaused, ModePlaying, ModeLooping } currentMode;
126};
127
128
129#endif // llmediaimplquicktime_h
130
131#endif
diff --git a/linden/indra/llmedia/llmediamoviebase.cpp b/linden/indra/llmedia/llmediamoviebase.cpp
new file mode 100644
index 0000000..b24e7ab
--- /dev/null
+++ b/linden/indra/llmedia/llmediamoviebase.cpp
@@ -0,0 +1,222 @@
1/**
2 * @file llmediamoviebase.cpp
3 * @brief LLMedia support - base class.
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 "linden_common.h"
29
30#include "llmediamoviebase.h"
31#include "llmediaimplquicktime.h"
32
33LLMediaMovieBase::LLMediaMovieBase()
34{
35
36}
37
38///////////////////////////////////////////////////////////////////////////////
39// factory method based on explicit media type
40LLMediaMovieBase* LLMediaMovieBase::make( const MediaType mediaTypeIn, S32 width_pixels, S32 height_pixels )
41{
42#if LL_QUICKTIME_ENABLED
43 if ( mediaTypeIn == QuickTime )
44 {
45 return new LLMediaImplQuickTime ();
46 }
47 else
48#endif
49
50 return 0;
51}
52
53///////////////////////////////////////////////////////////////////////////////
54//
55BOOL
56LLMediaMovieBase::
57play ()
58{
59 // build event and emit it
60 LLMediaEvent event ( 0, "" );
61 mMediaEventEmitter.update ( &LLMediaObserver::onPlay, event );
62
63 return TRUE;
64}
65
66///////////////////////////////////////////////////////////////////////////////
67//
68BOOL
69LLMediaMovieBase::
70pause ()
71{
72 LLMediaEvent event ( 0, "" );
73 mMediaEventEmitter.update ( &LLMediaObserver::onPause, event );
74
75 return TRUE;
76}
77
78///////////////////////////////////////////////////////////////////////////////
79//
80BOOL
81LLMediaMovieBase::
82stop ()
83{
84 LLMediaEvent event ( 0, "" );
85 mMediaEventEmitter.update ( &LLMediaObserver::onStop, event );
86
87 return TRUE;
88}
89
90///////////////////////////////////////////////////////////////////////////////
91//
92BOOL
93LLMediaMovieBase::
94loop ( S32 howMany )
95{
96 return TRUE;
97};
98
99///////////////////////////////////////////////////////////////////////////////
100//
101void LLMediaMovieBase::setAutoScaled ( BOOL autoScaledIn )
102{
103}
104
105///////////////////////////////////////////////////////////////////////////////
106//
107BOOL
108LLMediaMovieBase::
109setVolume ( F32 volumeIn )
110{
111 return TRUE;
112}
113
114///////////////////////////////////////////////////////////////////////////////
115//
116F32
117LLMediaMovieBase::
118getVolume ()
119{
120 return ( F32 ) 0.0f;
121}
122
123///////////////////////////////////////////////////////////////////////////////
124//
125BOOL
126LLMediaMovieBase::
127isIdle () const
128{
129 return FALSE;
130}
131
132///////////////////////////////////////////////////////////////////////////////
133//
134BOOL
135LLMediaMovieBase::
136isBuffering () const
137{
138 return FALSE;
139}
140
141///////////////////////////////////////////////////////////////////////////////
142//
143BOOL
144LLMediaMovieBase::
145isError () const
146{
147 return FALSE;
148}
149
150///////////////////////////////////////////////////////////////////////////////
151//
152BOOL
153LLMediaMovieBase::
154isLoaded () const
155{
156 return TRUE;
157}
158
159///////////////////////////////////////////////////////////////////////////////
160//
161BOOL
162LLMediaMovieBase::
163isStopped () const
164{
165 return FALSE;
166}
167
168///////////////////////////////////////////////////////////////////////////////
169//
170BOOL
171LLMediaMovieBase::
172isPaused () const
173{
174 return FALSE;
175}
176
177///////////////////////////////////////////////////////////////////////////////
178//
179BOOL
180LLMediaMovieBase::
181isPlaying () const
182{
183 return TRUE;
184}
185
186///////////////////////////////////////////////////////////////////////////////
187//
188BOOL
189LLMediaMovieBase::
190isLooping () const
191{
192 return FALSE;
193}
194
195///////////////////////////////////////////////////////////////////////////////
196//
197BOOL
198LLMediaMovieBase::
199seek ( F64 time )
200{
201 return TRUE;
202}
203
204///////////////////////////////////////////////////////////////////////////////
205//
206F64
207LLMediaMovieBase::
208getTime () const
209{
210 F64 result = 0;
211 return result;
212}
213
214///////////////////////////////////////////////////////////////////////////////
215//
216F64
217LLMediaMovieBase::
218getMediaDuration () const
219{
220 F64 result = 0;
221 return result;
222}
diff --git a/linden/indra/llmedia/llmediamoviebase.h b/linden/indra/llmedia/llmediamoviebase.h
new file mode 100644
index 0000000..e9617c0
--- /dev/null
+++ b/linden/indra/llmedia/llmediamoviebase.h
@@ -0,0 +1,80 @@
1/**
2 * @file llmediamoviebase.h
3 * @brief LLMedia support - intermediate base class, for media types
4 * that want movie-style controls (i.e play/pause and volume)
5 *
6 * Copyright (c) 2005-2007, Linden Research, Inc.
7 *
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29// header guard
30#ifndef llmediamoviebase_h
31#define llmediamoviebase_h
32
33#include "llmediabase.h"
34
35class LLMediaMovieBase : public LLMediaBase
36{
37 public:
38 LLMediaMovieBase ();
39
40 // do the right thing with dtor
41 virtual ~LLMediaMovieBase ()
42 {
43 };
44
45 ///////////////////////////////////////////////////////////////////////////////
46 // factory method based on explicit media type
47 static LLMediaMovieBase* make ( const MediaType mediaTypeIn, S32 width_pixels, S32 height_pixels );
48
49 ///////////////////////////////////////////////////////////////////////////////
50 // public interface:
51
52 // transport controls
53 virtual BOOL stop ();
54 virtual BOOL play ();
55 virtual BOOL loop ( S32 howMany );
56 virtual BOOL pause ();
57 virtual BOOL seek ( F64 time );
58
59 // audio levels
60 virtual BOOL setVolume ( F32 volumeIn );
61 virtual F32 getVolume ();
62
63 // status
64 virtual BOOL isIdle () const;
65 virtual BOOL isBuffering () const;
66 virtual BOOL isError () const;
67 virtual BOOL isLoaded () const;
68 virtual BOOL isStopped () const;
69 virtual BOOL isPaused () const;
70 virtual BOOL isPlaying () const;
71 virtual BOOL isLooping () const;
72 virtual F64 getTime () const;
73
74 // media data
75 virtual void setAutoScaled ( BOOL autoScaledIn );
76 virtual F64 getMediaDuration () const;
77};
78
79
80#endif // llmediamoviebase_h
diff --git a/linden/indra/llmedia/llmediaobservers.h b/linden/indra/llmedia/llmediaobservers.h
new file mode 100644
index 0000000..a604989
--- /dev/null
+++ b/linden/indra/llmedia/llmediaobservers.h
@@ -0,0 +1,50 @@
1/**
2 * @file llmediaobservers.h
3 * @brief LLMedia support - observer classes to be overridden.
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// header guard
29#ifndef llmediaobservers_h
30#define llmediaobservers_h
31
32#include "llmediaemitterevents.h"
33
34class LLMediaObserver
35{
36 public:
37 typedef LLMediaEvent EventType;
38 virtual ~LLMediaObserver() {}
39 virtual void onInit ( const EventType& eventIn ) { }
40 virtual void onSetUrl ( const EventType& eventIn ) { }
41 virtual void onLoad ( const EventType& eventIn ) { }
42 virtual void onPlay ( const EventType& eventIn ) { }
43 virtual void onPause ( const EventType& eventIn ) { }
44 virtual void onStop ( const EventType& eventIn ) { }
45 virtual void onUnload ( const EventType& eventIn ) { }
46 virtual void onPopupMessage ( const EventType& eventIn ) { }
47};
48
49
50#endif // llmediaobservers_h