aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmedia
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:45:04 -0500
committerJacek Antonelli2008-08-15 23:45:04 -0500
commit117e22047c5752352342d64e3fb7ce00a4eb8113 (patch)
treee32de2cfba0dda8705ae528fcd1fbe23ba075685 /linden/indra/llmedia
parentSecond Life viewer sources 1.18.0.6 (diff)
downloadmeta-impy-117e22047c5752352342d64e3fb7ce00a4eb8113.zip
meta-impy-117e22047c5752352342d64e3fb7ce00a4eb8113.tar.gz
meta-impy-117e22047c5752352342d64e3fb7ce00a4eb8113.tar.bz2
meta-impy-117e22047c5752352342d64e3fb7ce00a4eb8113.tar.xz
Second Life viewer sources 1.18.1.2
Diffstat (limited to 'linden/indra/llmedia')
-rw-r--r--linden/indra/llmedia/files.lst3
-rw-r--r--linden/indra/llmedia/llmedia_vc8.vcproj594
-rw-r--r--linden/indra/llmedia/llmediabase.cpp8
-rw-r--r--linden/indra/llmedia/llmediaimplgstreamer.cpp715
-rw-r--r--linden/indra/llmedia/llmediaimplgstreamer.h126
-rw-r--r--linden/indra/llmedia/llmediaimplgstreamer_syms.cpp189
-rw-r--r--linden/indra/llmedia/llmediaimplgstreamer_syms.h75
-rw-r--r--linden/indra/llmedia/llmediaimplgstreamer_syms_raw.inc42
-rw-r--r--linden/indra/llmedia/llmediaimplgstreamer_syms_rawa.inc5
-rw-r--r--linden/indra/llmedia/llmediaimplgstreamer_syms_rawv.inc5
-rw-r--r--linden/indra/llmedia/llmediaimplgstreamervidplug.cpp461
-rw-r--r--linden/indra/llmedia/llmediaimplgstreamervidplug.h101
-rw-r--r--linden/indra/llmedia/llmediamoviebase.cpp8
13 files changed, 2035 insertions, 297 deletions
diff --git a/linden/indra/llmedia/files.lst b/linden/indra/llmedia/files.lst
index 35ae5ab..bda6459 100644
--- a/linden/indra/llmedia/files.lst
+++ b/linden/indra/llmedia/files.lst
@@ -1,4 +1,7 @@
1llmedia/llmediabase.cpp 1llmedia/llmediabase.cpp
2llmedia/llmediaengine.cpp 2llmedia/llmediaengine.cpp
3llmedia/llmediaimplgstreamer.cpp
4llmedia/llmediaimplgstreamer_syms.cpp
5llmedia/llmediaimplgstreamervidplug.cpp
3llmedia/llmediaimplquicktime.cpp 6llmedia/llmediaimplquicktime.cpp
4llmedia/llmediamoviebase.cpp 7llmedia/llmediamoviebase.cpp
diff --git a/linden/indra/llmedia/llmedia_vc8.vcproj b/linden/indra/llmedia/llmedia_vc8.vcproj
index 12fa817..2bc8014 100644
--- a/linden/indra/llmedia/llmedia_vc8.vcproj
+++ b/linden/indra/llmedia/llmedia_vc8.vcproj
@@ -1,297 +1,297 @@
1<?xml version="1.0" encoding="Windows-1252"?> 1<?xml version="1.0" encoding="Windows-1252"?>
2<VisualStudioProject 2<VisualStudioProject
3 ProjectType="Visual C++" 3 ProjectType="Visual C++"
4 Version="8.00" 4 Version="8.00"
5 Name="llmedia" 5 Name="llmedia"
6 ProjectGUID="{9D0C7E02-6506-4EE7-BC5C-75671D28D594}" 6 ProjectGUID="{9D0C7E02-6506-4EE7-BC5C-75671D28D594}"
7 RootNamespace="llmedia" 7 RootNamespace="llmedia"
8 Keyword="Win32Proj" 8 Keyword="Win32Proj"
9 > 9 >
10 <Platforms> 10 <Platforms>
11 <Platform 11 <Platform
12 Name="Win32" 12 Name="Win32"
13 /> 13 />
14 </Platforms> 14 </Platforms>
15 <ToolFiles> 15 <ToolFiles>
16 </ToolFiles> 16 </ToolFiles>
17 <Configurations> 17 <Configurations>
18 <Configuration 18 <Configuration
19 Name="Debug|Win32" 19 Name="Debug|Win32"
20 OutputDirectory="../lib_$(ConfigurationName)/i686-win32" 20 OutputDirectory="../lib_$(ConfigurationName)/i686-win32"
21 IntermediateDirectory="Debug" 21 IntermediateDirectory="Debug"
22 ConfigurationType="4" 22 ConfigurationType="4"
23 InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" 23 InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
24 CharacterSet="1" 24 CharacterSet="1"
25 > 25 >
26 <Tool 26 <Tool
27 Name="VCPreBuildEventTool" 27 Name="VCPreBuildEventTool"
28 /> 28 />
29 <Tool 29 <Tool
30 Name="VCCustomBuildTool" 30 Name="VCCustomBuildTool"
31 /> 31 />
32 <Tool 32 <Tool
33 Name="VCXMLDataGeneratorTool" 33 Name="VCXMLDataGeneratorTool"
34 /> 34 />
35 <Tool 35 <Tool
36 Name="VCWebServiceProxyGeneratorTool" 36 Name="VCWebServiceProxyGeneratorTool"
37 /> 37 />
38 <Tool 38 <Tool
39 Name="VCMIDLTool" 39 Name="VCMIDLTool"
40 /> 40 />
41 <Tool 41 <Tool
42 Name="VCCLCompilerTool" 42 Name="VCCLCompilerTool"
43 Optimization="0" 43 Optimization="0"
44 AdditionalIncludeDirectories="..\llcommon;..\llrender;..\llwindow;..\llimage;..\llmath;..\llvfs;..\llmessage;..\llui;&quot;..\..\libraries\i686-win32\include&quot;;..\..\libraries\include\;&quot;..\..\libraries\i686-win32\include\quicktime&quot;" 44 AdditionalIncludeDirectories="..\llcommon;..\llrender;..\llwindow;..\llimage;..\llmath;..\llvfs;..\llmessage;..\llui;&quot;..\..\libraries\i686-win32\include&quot;;..\..\libraries\include\;&quot;..\..\libraries\i686-win32\include\quicktime&quot;"
45 PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_DEBUG;XP_WIN;XP_WIN32" 45 PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_DEBUG;XP_WIN;XP_WIN32"
46 MinimalRebuild="true" 46 MinimalRebuild="true"
47 BasicRuntimeChecks="3" 47 BasicRuntimeChecks="3"
48 RuntimeLibrary="1" 48 RuntimeLibrary="1"
49 StructMemberAlignment="4" 49 StructMemberAlignment="4"
50 TreatWChar_tAsBuiltInType="false" 50 TreatWChar_tAsBuiltInType="false"
51 ForceConformanceInForLoopScope="true" 51 ForceConformanceInForLoopScope="true"
52 UsePrecompiledHeader="0" 52 UsePrecompiledHeader="0"
53 WarningLevel="3" 53 WarningLevel="3"
54 WarnAsError="true" 54 WarnAsError="true"
55 Detect64BitPortabilityProblems="false" 55 Detect64BitPortabilityProblems="false"
56 DebugInformationFormat="4" 56 DebugInformationFormat="4"
57 DisableSpecificWarnings="4702" 57 DisableSpecificWarnings="4702"
58 /> 58 />
59 <Tool 59 <Tool
60 Name="VCManagedResourceCompilerTool" 60 Name="VCManagedResourceCompilerTool"
61 /> 61 />
62 <Tool 62 <Tool
63 Name="VCResourceCompilerTool" 63 Name="VCResourceCompilerTool"
64 /> 64 />
65 <Tool 65 <Tool
66 Name="VCPreLinkEventTool" 66 Name="VCPreLinkEventTool"
67 /> 67 />
68 <Tool 68 <Tool
69 Name="VCLibrarianTool" 69 Name="VCLibrarianTool"
70 OutputFile="$(OutDir)/llmedia.lib" 70 OutputFile="$(OutDir)/llmedia.lib"
71 AdditionalLibraryDirectories="" 71 AdditionalLibraryDirectories=""
72 /> 72 />
73 <Tool 73 <Tool
74 Name="VCALinkTool" 74 Name="VCALinkTool"
75 /> 75 />
76 <Tool 76 <Tool
77 Name="VCXDCMakeTool" 77 Name="VCXDCMakeTool"
78 /> 78 />
79 <Tool 79 <Tool
80 Name="VCBscMakeTool" 80 Name="VCBscMakeTool"
81 /> 81 />
82 <Tool 82 <Tool
83 Name="VCFxCopTool" 83 Name="VCFxCopTool"
84 /> 84 />
85 <Tool 85 <Tool
86 Name="VCPostBuildEventTool" 86 Name="VCPostBuildEventTool"
87 /> 87 />
88 </Configuration> 88 </Configuration>
89 <Configuration 89 <Configuration
90 Name="Release|Win32" 90 Name="Release|Win32"
91 OutputDirectory="../lib_$(ConfigurationName)/i686-win32" 91 OutputDirectory="../lib_$(ConfigurationName)/i686-win32"
92 IntermediateDirectory="Release" 92 IntermediateDirectory="Release"
93 ConfigurationType="4" 93 ConfigurationType="4"
94 InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" 94 InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
95 CharacterSet="1" 95 CharacterSet="1"
96 > 96 >
97 <Tool 97 <Tool
98 Name="VCPreBuildEventTool" 98 Name="VCPreBuildEventTool"
99 /> 99 />
100 <Tool 100 <Tool
101 Name="VCCustomBuildTool" 101 Name="VCCustomBuildTool"
102 /> 102 />
103 <Tool 103 <Tool
104 Name="VCXMLDataGeneratorTool" 104 Name="VCXMLDataGeneratorTool"
105 /> 105 />
106 <Tool 106 <Tool
107 Name="VCWebServiceProxyGeneratorTool" 107 Name="VCWebServiceProxyGeneratorTool"
108 /> 108 />
109 <Tool 109 <Tool
110 Name="VCMIDLTool" 110 Name="VCMIDLTool"
111 /> 111 />
112 <Tool 112 <Tool
113 Name="VCCLCompilerTool" 113 Name="VCCLCompilerTool"
114 InlineFunctionExpansion="0" 114 InlineFunctionExpansion="0"
115 EnableIntrinsicFunctions="false" 115 EnableIntrinsicFunctions="false"
116 AdditionalIncludeDirectories="..\llcommon;..\llrender;..\llwindow;..\llimage;..\llmath;..\llvfs;..\llmessage;..\llui;&quot;..\..\libraries\i686-win32\include&quot;;..\..\libraries\include\;&quot;..\..\libraries\i686-win32\include\quicktime&quot;" 116 AdditionalIncludeDirectories="..\llcommon;..\llrender;..\llwindow;..\llimage;..\llmath;..\llvfs;..\llmessage;..\llui;&quot;..\..\libraries\i686-win32\include&quot;;..\..\libraries\include\;&quot;..\..\libraries\i686-win32\include\quicktime&quot;"
117 PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_RELEASE;XP_WIN;XP_WIN32" 117 PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_RELEASE;XP_WIN;XP_WIN32"
118 RuntimeLibrary="0" 118 RuntimeLibrary="0"
119 StructMemberAlignment="0" 119 StructMemberAlignment="0"
120 TreatWChar_tAsBuiltInType="false" 120 TreatWChar_tAsBuiltInType="false"
121 ForceConformanceInForLoopScope="true" 121 ForceConformanceInForLoopScope="true"
122 UsePrecompiledHeader="0" 122 UsePrecompiledHeader="0"
123 WarningLevel="3" 123 WarningLevel="3"
124 WarnAsError="false" 124 WarnAsError="false"
125 Detect64BitPortabilityProblems="false" 125 Detect64BitPortabilityProblems="false"
126 DebugInformationFormat="3" 126 DebugInformationFormat="3"
127 DisableSpecificWarnings="4702" 127 DisableSpecificWarnings="4702"
128 /> 128 />
129 <Tool 129 <Tool
130 Name="VCManagedResourceCompilerTool" 130 Name="VCManagedResourceCompilerTool"
131 /> 131 />
132 <Tool 132 <Tool
133 Name="VCResourceCompilerTool" 133 Name="VCResourceCompilerTool"
134 /> 134 />
135 <Tool 135 <Tool
136 Name="VCPreLinkEventTool" 136 Name="VCPreLinkEventTool"
137 /> 137 />
138 <Tool 138 <Tool
139 Name="VCLibrarianTool" 139 Name="VCLibrarianTool"
140 OutputFile="$(OutDir)/llmedia.lib" 140 OutputFile="$(OutDir)/llmedia.lib"
141 AdditionalLibraryDirectories="" 141 AdditionalLibraryDirectories=""
142 IgnoreAllDefaultLibraries="false" 142 IgnoreAllDefaultLibraries="false"
143 IgnoreDefaultLibraryNames="" 143 IgnoreDefaultLibraryNames=""
144 /> 144 />
145 <Tool 145 <Tool
146 Name="VCALinkTool" 146 Name="VCALinkTool"
147 /> 147 />
148 <Tool 148 <Tool
149 Name="VCXDCMakeTool" 149 Name="VCXDCMakeTool"
150 /> 150 />
151 <Tool 151 <Tool
152 Name="VCBscMakeTool" 152 Name="VCBscMakeTool"
153 /> 153 />
154 <Tool 154 <Tool
155 Name="VCFxCopTool" 155 Name="VCFxCopTool"
156 /> 156 />
157 <Tool 157 <Tool
158 Name="VCPostBuildEventTool" 158 Name="VCPostBuildEventTool"
159 /> 159 />
160 </Configuration> 160 </Configuration>
161 <Configuration 161 <Configuration
162 Name="ReleaseNoOpt|Win32" 162 Name="ReleaseNoOpt|Win32"
163 OutputDirectory="../lib_$(ConfigurationName)/i686-win32" 163 OutputDirectory="../lib_$(ConfigurationName)/i686-win32"
164 IntermediateDirectory="$(ConfigurationName)" 164 IntermediateDirectory="$(ConfigurationName)"
165 ConfigurationType="4" 165 ConfigurationType="4"
166 InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" 166 InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
167 CharacterSet="1" 167 CharacterSet="1"
168 > 168 >
169 <Tool 169 <Tool
170 Name="VCPreBuildEventTool" 170 Name="VCPreBuildEventTool"
171 /> 171 />
172 <Tool 172 <Tool
173 Name="VCCustomBuildTool" 173 Name="VCCustomBuildTool"
174 /> 174 />
175 <Tool 175 <Tool
176 Name="VCXMLDataGeneratorTool" 176 Name="VCXMLDataGeneratorTool"
177 /> 177 />
178 <Tool 178 <Tool
179 Name="VCWebServiceProxyGeneratorTool" 179 Name="VCWebServiceProxyGeneratorTool"
180 /> 180 />
181 <Tool 181 <Tool
182 Name="VCMIDLTool" 182 Name="VCMIDLTool"
183 /> 183 />
184 <Tool 184 <Tool
185 Name="VCCLCompilerTool" 185 Name="VCCLCompilerTool"
186 Optimization="0" 186 Optimization="0"
187 InlineFunctionExpansion="0" 187 InlineFunctionExpansion="0"
188 EnableIntrinsicFunctions="false" 188 EnableIntrinsicFunctions="false"
189 AdditionalIncludeDirectories="..\llcommon;..\llrender;..\llwindow;..\llimage;..\llmath;..\llvfs;..\llmessage;..\llui;&quot;..\..\libraries\i686-win32\include&quot;;..\..\libraries\include\;&quot;..\..\libraries\i686-win32\include\quicktime&quot;" 189 AdditionalIncludeDirectories="..\llcommon;..\llrender;..\llwindow;..\llimage;..\llmath;..\llvfs;..\llmessage;..\llui;&quot;..\..\libraries\i686-win32\include&quot;;..\..\libraries\include\;&quot;..\..\libraries\i686-win32\include\quicktime&quot;"
190 PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_RELEASE;XP_WIN;XP_WIN32" 190 PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_RELEASE;XP_WIN;XP_WIN32"
191 RuntimeLibrary="0" 191 RuntimeLibrary="0"
192 StructMemberAlignment="0" 192 StructMemberAlignment="0"
193 TreatWChar_tAsBuiltInType="false" 193 TreatWChar_tAsBuiltInType="false"
194 ForceConformanceInForLoopScope="true" 194 ForceConformanceInForLoopScope="true"
195 UsePrecompiledHeader="0" 195 UsePrecompiledHeader="0"
196 WarningLevel="3" 196 WarningLevel="3"
197 WarnAsError="true" 197 WarnAsError="true"
198 Detect64BitPortabilityProblems="false" 198 Detect64BitPortabilityProblems="false"
199 DebugInformationFormat="3" 199 DebugInformationFormat="3"
200 DisableSpecificWarnings="4702" 200 DisableSpecificWarnings="4702"
201 /> 201 />
202 <Tool 202 <Tool
203 Name="VCManagedResourceCompilerTool" 203 Name="VCManagedResourceCompilerTool"
204 /> 204 />
205 <Tool 205 <Tool
206 Name="VCResourceCompilerTool" 206 Name="VCResourceCompilerTool"
207 /> 207 />
208 <Tool 208 <Tool
209 Name="VCPreLinkEventTool" 209 Name="VCPreLinkEventTool"
210 /> 210 />
211 <Tool 211 <Tool
212 Name="VCLibrarianTool" 212 Name="VCLibrarianTool"
213 OutputFile="$(OutDir)/llmedia.lib" 213 OutputFile="$(OutDir)/llmedia.lib"
214 AdditionalLibraryDirectories="" 214 AdditionalLibraryDirectories=""
215 IgnoreAllDefaultLibraries="false" 215 IgnoreAllDefaultLibraries="false"
216 IgnoreDefaultLibraryNames="" 216 IgnoreDefaultLibraryNames=""
217 /> 217 />
218 <Tool 218 <Tool
219 Name="VCALinkTool" 219 Name="VCALinkTool"
220 /> 220 />
221 <Tool 221 <Tool
222 Name="VCXDCMakeTool" 222 Name="VCXDCMakeTool"
223 /> 223 />
224 <Tool 224 <Tool
225 Name="VCBscMakeTool" 225 Name="VCBscMakeTool"
226 /> 226 />
227 <Tool 227 <Tool
228 Name="VCFxCopTool" 228 Name="VCFxCopTool"
229 /> 229 />
230 <Tool 230 <Tool
231 Name="VCPostBuildEventTool" 231 Name="VCPostBuildEventTool"
232 /> 232 />
233 </Configuration> 233 </Configuration>
234 </Configurations> 234 </Configurations>
235 <References> 235 <References>
236 </References> 236 </References>
237 <Files> 237 <Files>
238 <Filter 238 <Filter
239 Name="Source Files" 239 Name="Source Files"
240 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" 240 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
241 UniqueIdentifier="{44DBC47A-0AF0-4726-A094-2D6FBB65FFFA}" 241 UniqueIdentifier="{44DBC47A-0AF0-4726-A094-2D6FBB65FFFA}"
242 > 242 >
243 <File 243 <File
244 RelativePath=".\llmediabase.cpp" 244 RelativePath=".\llmediabase.cpp"
245 > 245 >
246 </File> 246 </File>
247 <File 247 <File
248 RelativePath=".\llmediaengine.cpp" 248 RelativePath=".\llmediaengine.cpp"
249 > 249 >
250 </File> 250 </File>
251 <File 251 <File
252 RelativePath=".\llmediaimplquicktime.cpp" 252 RelativePath=".\llmediaimplquicktime.cpp"
253 > 253 >
254 </File> 254 </File>
255 <File 255 <File
256 RelativePath=".\llmediamoviebase.cpp" 256 RelativePath=".\llmediamoviebase.cpp"
257 > 257 >
258 </File> 258 </File>
259 <File 259 <File
260 RelativePath=".\llmediamoviebase.h" 260 RelativePath=".\llmediamoviebase.h"
261 > 261 >
262 </File> 262 </File>
263 </Filter> 263 </Filter>
264 <Filter 264 <Filter
265 Name="Header Files" 265 Name="Header Files"
266 Filter="h;hpp;hxx;hm;inl;inc;xsd" 266 Filter="h;hpp;hxx;hm;inl;inc;xsd"
267 UniqueIdentifier="{D188664C-B9B7-4982-8C4B-8D9A44B4D9EF}" 267 UniqueIdentifier="{D188664C-B9B7-4982-8C4B-8D9A44B4D9EF}"
268 > 268 >
269 <File 269 <File
270 RelativePath=".\llmediabase.h" 270 RelativePath=".\llmediabase.h"
271 > 271 >
272 </File> 272 </File>
273 <File 273 <File
274 RelativePath=".\llmediaemitter.h" 274 RelativePath=".\llmediaemitter.h"
275 > 275 >
276 </File> 276 </File>
277 <File 277 <File
278 RelativePath=".\llmediaemitterevents.h" 278 RelativePath=".\llmediaemitterevents.h"
279 > 279 >
280 </File> 280 </File>
281 <File 281 <File
282 RelativePath=".\llmediaengine.h" 282 RelativePath=".\llmediaengine.h"
283 > 283 >
284 </File> 284 </File>
285 <File 285 <File
286 RelativePath=".\llmediaimplquicktime.h" 286 RelativePath=".\llmediaimplquicktime.h"
287 > 287 >
288 </File> 288 </File>
289 <File 289 <File
290 RelativePath=".\llmediaobservers.h" 290 RelativePath=".\llmediaobservers.h"
291 > 291 >
292 </File> 292 </File>
293 </Filter> 293 </Filter>
294 </Files> 294 </Files>
295 <Globals> 295 <Globals>
296 </Globals> 296 </Globals>
297</VisualStudioProject> 297</VisualStudioProject>
diff --git a/linden/indra/llmedia/llmediabase.cpp b/linden/indra/llmedia/llmediabase.cpp
index 7abf960..17bb563 100644
--- a/linden/indra/llmedia/llmediabase.cpp
+++ b/linden/indra/llmedia/llmediabase.cpp
@@ -30,6 +30,7 @@
30 30
31#include "llmediabase.h" 31#include "llmediabase.h"
32#include "llmediaimplquicktime.h" 32#include "llmediaimplquicktime.h"
33#include "llmediaimplgstreamer.h"
33 34
34LLMediaBase::LLMediaBase() : 35LLMediaBase::LLMediaBase() :
35 mBufferChangeCount ( 1 ), 36 mBufferChangeCount ( 1 ),
@@ -60,6 +61,13 @@ LLMediaBase* LLMediaBase::make( const MediaType mediaTypeIn, S32 width_pixels, S
60 } 61 }
61 else 62 else
62#endif 63#endif
64#if LL_GSTREAMER_ENABLED
65 if ( mediaTypeIn == QuickTime )
66 {
67 return new LLMediaImplGStreamer ();
68 }
69 else
70#endif
63 71
64 return 0; 72 return 0;
65} 73}
diff --git a/linden/indra/llmedia/llmediaimplgstreamer.cpp b/linden/indra/llmedia/llmediaimplgstreamer.cpp
new file mode 100644
index 0000000..f8b4c74
--- /dev/null
+++ b/linden/indra/llmedia/llmediaimplgstreamer.cpp
@@ -0,0 +1,715 @@
1/**
2 * @file llmediaimplgstreamer.cpp
3 * @brief implementation that supports various media through GStreamer.
4 *
5 * Copyright (c) 2007-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
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#include "linden_common.h"
30
31#if LL_GSTREAMER_ENABLED
32
33extern "C" {
34#include <gst/gst.h>
35}
36
37#include "llmediaimplgstreamer.h"
38
39#include "llmediaimplgstreamervidplug.h"
40
41#ifdef LL_GST_SOUNDSINK
42#include "llmediaimplgstreamersndplug.h"
43#endif // LL_GST_SOUNDSINK
44
45#include "llmediaimplgstreamer_syms.h"
46
47#include "llgl.h"
48#include "llglheaders.h" // For gl texture modes
49
50///////////////////////////////////////////////////////////////////////////////
51//
52LLMediaImplGStreamer::
53LLMediaImplGStreamer () :
54 mediaData ( NULL ),
55 ownBuffer ( TRUE ),
56 mVolume ( 1.0f ),
57 currentMode ( ModeIdle ),
58 mPump ( NULL ),
59 mPlaybin ( NULL ),
60 mVideoSink ( NULL )
61#ifdef LL_GST_SOUNDSINK
62 ,mAudioSink ( NULL )
63#endif // LL_GST_SOUNDSINK
64{
65 mMediaDepthBytes = 4;
66 mTextureDepth = 4;
67 mTextureFormatInternal = GL_RGB8;
68 mTextureFormatPrimary = GL_BGRA;
69 mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV;
70}
71
72///////////////////////////////////////////////////////////////////////////////
73//
74LLMediaImplGStreamer::
75~LLMediaImplGStreamer ()
76{
77 unload();
78}
79
80void UnloadGStreamer()
81{
82 ungrab_gst_syms();
83}
84
85
86///////////////////////////////////////////////////////////////////////////////
87//
88BOOL
89LLMediaImplGStreamer::
90setBuffer ( U8* bufferIn )
91{
92 // Since we've pointed GStreamer at the old media data buffer
93 // directly, we need to be somewhat careful deleting it...
94 U8* oldMediaData = mediaData;
95 BOOL ownedMediaData = ownBuffer;
96
97 if(bufferIn == NULL)
98 {
99 // Passing NULL to this function requests that the object
100 // allocate its own buffer.
101 mediaData = new unsigned char[ mMediaHeight * mMediaRowbytes ];
102 ownBuffer = TRUE;
103 }
104 else
105 {
106 // Use the supplied buffer.
107 mediaData = bufferIn;
108 ownBuffer = FALSE;
109 }
110
111 if(mediaData == NULL)
112 {
113 // This is bad - probably out of memory.
114 llerrs << "LLMediaImplGStreamer::setBuffer: mediaData is NULL" << llendl;
115 // NOTE: This case doesn't clean up properly. This assert is fatal, so this isn't a huge problem,
116 // but if this assert is ever removed the code should be fixed to clean up correctly.
117 return FALSE;
118 }
119
120 // [..]
121
122 // Delete the old media data buffer iff we owned it.
123 if ( ownedMediaData )
124 {
125 if ( oldMediaData )
126 {
127 delete [] oldMediaData;
128 }
129 }
130
131 return TRUE;
132}
133
134///////////////////////////////////////////////////////////////////////////////
135//
136BOOL
137LLMediaImplGStreamer::
138init ()
139{
140 static bool done_init = false;
141 if (!done_init)
142 {
143 // Get symbols!
144 if (! grab_gst_syms("libgstreamer-0.10.so.0",
145 "libgstvideo-0.10.so.0",
146 "libgstaudio-0.10.so.0") )
147 {
148 llwarns << "Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled." << llendl;
149 return FALSE;
150 }
151
152 if (llgst_segtrap_set_enabled)
153 llgst_segtrap_set_enabled(FALSE);
154 else
155 llwarns << "gst_segtrap_set_enabled() is not available; Second Life automated crash-reporter may cease to function until next restart." << llendl;
156
157 if (0 == llgst_init_check(NULL, NULL, NULL))
158 {
159 return FALSE;
160 }
161
162 // Init our custom plugins - only really need do this once.
163 gst_slvideo_init_class();
164#if 0
165 gst_slsound_init_class();
166#endif
167
168 done_init = true;
169 }
170
171 // Create a pumpable main-loop for this media
172 mPump = g_main_loop_new (NULL, FALSE);
173 if (!mPump)
174 {
175 return FALSE;
176 }
177
178 // instantiate a playbin element to do the hard work
179 mPlaybin = llgst_element_factory_make ("playbin", "play");
180 if (!mPlaybin)
181 {
182 // todo: cleanup pump
183 return FALSE;
184 }
185
186 if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) {
187 // instantiate and connect a custom video sink
188 mVideoSink =
189 GST_SLVIDEO(llgst_element_factory_make ("private-slvideo", "slvideo"));
190 if (!mVideoSink)
191 {
192 llwarns << "Could not instantiate private-slvideo element."
193 << llendl;
194 // todo: cleanup.
195 return FALSE;
196 }
197
198 g_object_set(mPlaybin, "video-sink", mVideoSink, NULL);
199
200#ifdef LL_GST_SOUNDSINK
201 // instantiate and connect a custom audio sink
202 mAudioSink =
203 GST_SLSOUND(llgst_element_factory_make ("private-slsound", "slsound"));
204 if (!mAudioSink)
205 {
206 llwarns << "Could not instantiate private-slsound element."
207 << llendl;
208 // todo: cleanup.
209 return FALSE;
210 }
211
212 g_object_set(mPlaybin, "audio-sink", mAudioSink, NULL);
213#endif
214 }
215
216 return LLMediaMovieBase::init();
217}
218
219
220///////////////////////////////////////////////////////////////////////////////
221//
222//#define LL_GST_REPORT_STATE_CHANGES
223#ifdef LL_GST_REPORT_STATE_CHANGES
224static char* get_gst_state_name(GstState state)
225{
226 switch (state) {
227 case GST_STATE_VOID_PENDING: return "VOID_PENDING";
228 case GST_STATE_NULL: return "NULL";
229 case GST_STATE_READY: return "READY";
230 case GST_STATE_PAUSED: return "PAUSED";
231 case GST_STATE_PLAYING: return "PLAYING";
232 }
233 return "(unknown)";
234}
235#endif // LL_GST_REPORT_STATE_CHANGES
236
237static gboolean
238my_bus_callback (GstBus *bus,
239 GstMessage *message,
240 gpointer data)
241{
242 if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED &&
243 GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING)
244 {
245 llinfos << "Got GST message type: "
246 << LLGST_MESSAGE_TYPE_NAME (message)
247 << llendl;
248 }
249 else
250 {
251 lldebugs << "Got GST message type: "
252 << LLGST_MESSAGE_TYPE_NAME (message)
253 << llendl;
254 }
255
256 LLMediaImplGStreamer *impl = (LLMediaImplGStreamer*)data;
257
258 switch (GST_MESSAGE_TYPE (message)) {
259 case GST_MESSAGE_BUFFERING: {
260 // NEEDS GST 0.10.11+
261 if (llgst_message_parse_buffering)
262 {
263 gint percent = 0;
264 llgst_message_parse_buffering(message, &percent);
265 llinfos << "GST buffering: " << percent
266 << "%" << llendl;
267 // ModeBuffering seems to do nothing except make
268 // the UI worse
269 /*if (percent < 100) impl->setCurrentMode(LLMediaImplGStreamer::ModeBuffering);*/
270 }
271 break;
272 }
273 case GST_MESSAGE_STATE_CHANGED: {
274 GstState old_state;
275 GstState new_state;
276 GstState pending_state;
277 llgst_message_parse_state_changed(message,
278 &old_state,
279 &new_state,
280 &pending_state);
281#ifdef LL_GST_REPORT_STATE_CHANGES
282 // not generally very useful, and rather spammy.
283 llinfos << "state change (old,<new>,pending): "
284 << get_gst_state_name(old_state) << ", <"
285 << get_gst_state_name(new_state) << ">, "
286 << get_gst_state_name(pending_state) <<
287 llendl;
288#endif // LL_GST_REPORT_STATE_CHANGES
289
290 switch (new_state) {
291 case GST_STATE_VOID_PENDING:
292 impl->setCurrentMode(LLMediaImplGStreamer::ModeNone);
293 break;
294 case GST_STATE_NULL:
295 impl->setCurrentMode(LLMediaImplGStreamer::ModeNone);
296 break;
297 case GST_STATE_READY:
298 impl->setCurrentMode(LLMediaImplGStreamer::ModeStopped);
299 break;
300 case GST_STATE_PAUSED:
301 impl->setCurrentMode(LLMediaImplGStreamer::ModePaused);
302 break;
303 case GST_STATE_PLAYING:
304 impl->setCurrentMode(LLMediaImplGStreamer::ModePlaying);
305 break;
306 }
307 break;
308 }
309 case GST_MESSAGE_ERROR: {
310 GError *err;
311 gchar *debug;
312
313 llgst_message_parse_error (message, &err, &debug);
314 llinfos << "GST error: " << err->message << llendl;
315 g_error_free (err);
316 g_free (debug);
317
318 impl->setCurrentMode(LLMediaImplGStreamer::ModeError);
319
320 impl->stop();
321
322 break;
323 }
324 case GST_MESSAGE_INFO: {
325 if (llgst_message_parse_info)
326 {
327 GError *err;
328 gchar *debug;
329
330 llgst_message_parse_info (message, &err, &debug);
331 llinfos << "GST info: " << err->message << llendl;
332 g_error_free (err);
333 g_free (debug);
334 }
335 break;
336 }
337 case GST_MESSAGE_WARNING: {
338 GError *err;
339 gchar *debug;
340
341 llgst_message_parse_warning (message, &err, &debug);
342 llinfos << "GST warning: " << err->message << llendl;
343 g_error_free (err);
344 g_free (debug);
345
346 break;
347 }
348 case GST_MESSAGE_EOS:
349 /* end-of-stream */
350 llinfos << "GST EOS." << llendl;
351 impl->setCurrentMode(LLMediaImplGStreamer::ModeStopped);//?
352 impl->stop();
353 break;
354 default:
355 /* unhandled message */
356 break;
357 }
358
359 /* we want to be notified again the next time there is a message
360 * on the bus, so returning TRUE (FALSE means we want to stop watching
361 * for messages on the bus and our callback should not be called again)
362 */
363 return TRUE;
364}
365
366BOOL
367LLMediaImplGStreamer::
368load ( const LLString& urlIn )
369{
370 llinfos << "Setting media URI: " << urlIn << llendl;
371
372 // set URI
373 g_object_set (G_OBJECT (mPlaybin), "uri", urlIn.c_str(), NULL);
374 //g_object_set (G_OBJECT (mPlaybin), "uri", "file:///tmp/movie", NULL);
375
376 // get playbin's bus - perhaps this can/should be done at init()
377 GstBus *bus = llgst_pipeline_get_bus (GST_PIPELINE (mPlaybin));
378 if (!bus)
379 {
380 return FALSE;
381 }
382 llgst_bus_add_watch (bus, my_bus_callback, this);
383 llgst_object_unref (bus);
384
385 if (true) // dummy values
386 {
387 const int fixedsize = 2;
388 mMediaRowbytes = mMediaDepthBytes * fixedsize;
389 mMediaWidth = fixedsize;
390 mMediaHeight = fixedsize;
391 mTextureWidth = fixedsize;
392 mTextureHeight = fixedsize;
393 }
394
395 BOOL rtn = LLMediaMovieBase::load(urlIn);
396 llinfos << "load returns " << int(rtn) << llendl;
397 return rtn;
398}
399
400///////////////////////////////////////////////////////////////////////////////
401//
402BOOL
403LLMediaImplGStreamer::
404unload ()
405{
406 if (mPlaybin)
407 {
408 llgst_element_set_state (mPlaybin, GST_STATE_NULL);
409 llgst_object_unref (GST_OBJECT (mPlaybin));
410 mPlaybin = NULL;
411 }
412
413 if (mPump)
414 {
415 g_main_loop_quit(mPump);
416 mPump = NULL;
417 }
418
419 if (mediaData)
420 {
421 if (ownBuffer)
422 {
423 delete mediaData;
424 mediaData = NULL;
425 }
426 }
427
428 mVideoSink = NULL;
429
430 return TRUE;
431}
432
433///////////////////////////////////////////////////////////////////////////////
434//
435S32
436LLMediaImplGStreamer::
437updateMedia ()
438{
439 //llinfos << "updating media..." << llendl;
440 if (g_main_context_pending(g_main_loop_get_context(mPump)))
441 {
442 g_main_context_iteration(g_main_loop_get_context(mPump), FALSE);
443 }
444
445 if (mVideoSink)
446 {
447 GST_OBJECT_LOCK(mVideoSink);
448 if (mVideoSink->retained_frame_ready)
449 {
450 //llinfos << "NEW FRAME " << llendl;
451 if (mVideoSink->retained_frame_width != mMediaWidth ||
452 mVideoSink->retained_frame_height != mMediaHeight)
453 // *TODO: also check for change in format
454 {
455 // just resize container
456 mMediaWidth = mVideoSink->retained_frame_width;
457 mMediaHeight = mVideoSink->retained_frame_height;
458 mTextureWidth = mMediaWidth;
459 mTextureHeight = mMediaHeight;
460 mMediaDepthBytes = mTextureDepth =
461 SLVPixelFormatBytes[mVideoSink->retained_frame_format];
462 if (SLV_PF_RGBX == mVideoSink->retained_frame_format)
463 {
464 mTextureFormatPrimary = GL_RGBA;
465 mTextureFormatType=GL_UNSIGNED_INT_8_8_8_8_REV;
466 }
467 else
468 {
469 mTextureFormatPrimary = GL_BGRA;
470 mTextureFormatType=GL_UNSIGNED_INT_8_8_8_8_REV;
471 }
472 mMediaRowbytes = mMediaWidth * mMediaDepthBytes;
473 llinfos << "video container resized to " <<
474 mMediaWidth << "x" << mMediaHeight << llendl;
475
476 if (ownBuffer)
477 {
478 // we manage the buffer, so we need to realloc
479 delete[] mediaData;
480 mediaData = new U8[mMediaRowbytes *
481 mMediaHeight];
482 }
483
484 GST_OBJECT_UNLOCK(mVideoSink);
485 return updateMediaNeedsSizeChange;
486 }
487
488 // we're gonna totally consume this frame - reset 'ready' flag
489 mVideoSink->retained_frame_ready = FALSE;
490 memcpy(mediaData, mVideoSink->retained_frame_data,
491 mMediaRowbytes * mMediaHeight);
492
493 GST_OBJECT_UNLOCK(mVideoSink);
494 return updateMediaNeedsUpdate;
495 }
496 else
497 {
498 // nothing to do yet.
499 GST_OBJECT_UNLOCK(mVideoSink);
500 return updateMediaNoChanges;
501 }
502 }
503
504 return updateMediaNoChanges;
505}
506
507///////////////////////////////////////////////////////////////////////////////
508//
509void
510LLMediaImplGStreamer::
511setAutoScaled ( BOOL autoScaledIn )
512{
513 autoScaled = autoScaledIn;
514}
515
516///////////////////////////////////////////////////////////////////////////////
517//
518BOOL
519LLMediaImplGStreamer::
520stop ()
521{
522 llinfos << "stopping media..." << llendl;
523 // todo: error-check this?
524 llgst_element_set_state(mPlaybin, GST_STATE_READY);
525
526 BOOL rtn = LLMediaMovieBase::stop();
527 setCurrentMode(LLMediaImplGStreamer::ModeStopped);//?
528 return rtn;
529}
530
531///////////////////////////////////////////////////////////////////////////////
532//
533BOOL
534LLMediaImplGStreamer::
535play ()
536{
537 llinfos << "playing media..." << llendl;
538 // todo: error-check this?
539 llgst_element_set_state(mPlaybin, GST_STATE_PLAYING);
540
541 return LLMediaMovieBase::play();
542}
543
544///////////////////////////////////////////////////////////////////////////////
545//
546BOOL
547LLMediaImplGStreamer::
548loop ( S32 howMany )
549{
550 llinfos << "looping media... " << howMany << llendl;
551 // todo: implement this
552 if (!play())
553 return FALSE;
554
555 return LLMediaMovieBase::loop(howMany);
556};
557
558///////////////////////////////////////////////////////////////////////////////
559//
560BOOL
561LLMediaImplGStreamer::
562pause ()
563{
564 llinfos << "pausing media..." << llendl;
565 // todo: error-check this?
566 llgst_element_set_state(mPlaybin, GST_STATE_PAUSED);
567
568 return LLMediaMovieBase::pause();
569};
570
571///////////////////////////////////////////////////////////////////////////////
572//
573BOOL
574LLMediaImplGStreamer::
575setVolume ( F32 volumeIn )
576{
577 mVolume = volumeIn;
578 g_object_set(mPlaybin, "volume", mVolume, NULL);
579 return TRUE;
580}
581
582///////////////////////////////////////////////////////////////////////////////
583//
584F32
585LLMediaImplGStreamer::
586getVolume ()
587{
588 return mVolume;
589}
590
591///////////////////////////////////////////////////////////////////////////////
592//
593BOOL
594LLMediaImplGStreamer::
595isIdle () const
596{
597 // todo: probably semantically decouple from currentMode
598 return currentMode == ModeIdle;
599}
600
601///////////////////////////////////////////////////////////////////////////////
602//
603BOOL
604LLMediaImplGStreamer::
605isError () const
606{
607 // todo: probably semantically decouple from currentMode
608 return currentMode == ModeError;
609}
610
611///////////////////////////////////////////////////////////////////////////////
612//
613BOOL
614LLMediaImplGStreamer::
615isBuffering () const
616{
617 // todo: probably semantically decouple from currentMode
618 return currentMode == ModeBuffering;
619}
620
621///////////////////////////////////////////////////////////////////////////////
622//
623BOOL
624LLMediaImplGStreamer::
625isLoaded () const
626{
627 // todo: probably semantically decouple from currentMode
628 //return currentMode == ModeLoaded;
629 return (mPump != NULL);
630}
631
632///////////////////////////////////////////////////////////////////////////////
633//
634BOOL
635LLMediaImplGStreamer::
636isPlaying () const
637{
638 // todo: probably semantically decouple from currentMode
639 return currentMode == ModePlaying;
640}
641
642///////////////////////////////////////////////////////////////////////////////
643//
644BOOL
645LLMediaImplGStreamer::
646isLooping () const
647{
648 // todo: probably semantically decouple from currentMode
649 return currentMode == ModeLooping;
650}
651
652///////////////////////////////////////////////////////////////////////////////
653//
654BOOL
655LLMediaImplGStreamer::
656isPaused () const
657{
658 // todo: probably semantically decouple from currentMode
659 return currentMode == ModePaused;
660}
661
662///////////////////////////////////////////////////////////////////////////////
663//
664BOOL
665LLMediaImplGStreamer::
666isStopped () const
667{
668 // todo: probably semantically decouple from currentMode
669 return currentMode == ModeStopped;
670}
671
672///////////////////////////////////////////////////////////////////////////////
673//
674U8*
675LLMediaImplGStreamer::
676getMediaData ()
677{
678 return mediaData;
679}
680
681///////////////////////////////////////////////////////////////////////////////
682//
683BOOL
684LLMediaImplGStreamer::
685seek ( F64 time )
686{
687 // todo: implement this
688 llinfos << "Tried to seek to time " << time
689 << " - faking it" << llendl;
690 return TRUE;
691}
692
693///////////////////////////////////////////////////////////////////////////////
694//
695F64
696LLMediaImplGStreamer::
697getTime () const
698{
699 // todo: implement this
700 F64 result = 0;
701 return result;
702}
703
704///////////////////////////////////////////////////////////////////////////////
705//
706F64
707LLMediaImplGStreamer::
708getMediaDuration () const
709{
710 // todo: implement this
711 F64 result = 0;
712 return result;
713}
714
715#endif // LL_GSTREAMER_ENABLED
diff --git a/linden/indra/llmedia/llmediaimplgstreamer.h b/linden/indra/llmedia/llmediaimplgstreamer.h
new file mode 100644
index 0000000..52a5c84
--- /dev/null
+++ b/linden/indra/llmedia/llmediaimplgstreamer.h
@@ -0,0 +1,126 @@
1/**
2 * @file llmediaimplgstreamer.h
3 * @brief implementation that supports media playback via GStreamer.
4 *
5 * Copyright (c) 2007-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
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 llmediaimplgstreamer_h
31#define llmediaimplgstreamer_h
32
33#if LL_GSTREAMER_ENABLED
34
35extern "C" {
36#include <gst/gst.h>
37
38#include <apr-1/apr_pools.h>
39#include <apr-1/apr_dso.h>
40}
41
42#include "stdtypes.h"
43
44#include "llmediamoviebase.h"
45
46#include "llmediaimplgstreamervidplug.h"
47#ifdef LL_GST_SOUNDSINK
48#include "llmediaimplgstreamersndplug.h"
49#endif // LL_GST_SOUNDSINK
50
51///////////////////////////////////////////////////////////////////////////
52class LLMediaImplGStreamer:
53 public LLMediaMovieBase
54{
55 public:
56 LLMediaImplGStreamer ();
57 virtual ~LLMediaImplGStreamer ();
58
59 ////////////////////////////////////////////////////////
60 // implementation of the media public interface
61
62 // housekeeping
63 virtual BOOL setBuffer ( U8* bufferIn );
64 virtual BOOL init ();
65 virtual BOOL load ( const LLString& urlIn );
66 virtual BOOL unload ();
67
68 // transport controls
69 virtual BOOL stop ();
70 virtual BOOL play ();
71 virtual BOOL loop ( S32 howMany );
72 virtual BOOL pause ();
73 virtual BOOL seek ( F64 time );
74
75 // audio levels
76 virtual BOOL setVolume ( F32 volumeIn );
77 virtual F32 getVolume ();
78
79 // status
80 virtual BOOL isIdle () const;
81 virtual BOOL isBuffering () const;
82 virtual BOOL isError () const;
83 virtual BOOL isLoaded () const;
84 virtual BOOL isStopped () const;
85 virtual BOOL isPaused () const;
86 virtual BOOL isPlaying () const;
87 virtual BOOL isLooping () const;
88 virtual F64 getTime () const;
89
90 // media data
91 virtual S32 updateMedia ();
92 virtual void setAutoScaled ( BOOL autoScaledIn );
93 virtual U8* getMediaData ();
94 virtual F64 getMediaDuration () const;
95
96 // class-specific
97 GMainLoop *getPump() {return mPump;};
98 typedef enum { ModeNone, ModeIdle, ModeError, ModeBuffering, ModeStopped, ModePaused, ModePlaying, ModeLooping } llGstMode;
99 llGstMode getCurrentMode() {return currentMode;};
100 void setCurrentMode(llGstMode mode) {currentMode = mode;};
101
102 private:
103 // misc
104 U8* mediaData;
105 BOOL ownBuffer;
106 BOOL autoScaled;
107 F32 mVolume;
108
109 llGstMode currentMode;
110
111 // GStreamer-specific
112 GMainLoop *mPump; // event pump for this media
113 GstElement *mPlaybin;
114 GstSLVideo *mVideoSink;
115#ifdef LL_GST_SOUNDSINK
116 GstSLSound *mAudioSink;
117#endif // LL_GST_SOUNDSINK
118};
119
120// called during shutdown when no instances may exist
121void UnloadGStreamer();
122
123
124#endif // LL_GSTREAMER_ENABLED
125
126#endif // llmediaimplgstreamer_h
diff --git a/linden/indra/llmedia/llmediaimplgstreamer_syms.cpp b/linden/indra/llmedia/llmediaimplgstreamer_syms.cpp
new file mode 100644
index 0000000..76f62e1
--- /dev/null
+++ b/linden/indra/llmedia/llmediaimplgstreamer_syms.cpp
@@ -0,0 +1,189 @@
1/**
2 * @file llmediaimplgstreamer_syms.cpp
3 * @brief dynamic GStreamer symbol-grabbing code
4 *
5 * Copyright (c) 2007-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
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#include "linden_common.h"
30
31#if LL_GSTREAMER_ENABLED
32
33extern "C" {
34#include <gst/gst.h>
35
36#include <apr-1/apr_pools.h>
37#include <apr-1/apr_dso.h>
38}
39
40#include "llmediaimplgstreamer.h"
41
42#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) RTN (*ll##GSTSYM)(__VA_ARGS__) = NULL
43#include "llmediaimplgstreamer_syms_raw.inc"
44#include "llmediaimplgstreamer_syms_rawa.inc"
45#include "llmediaimplgstreamer_syms_rawv.inc"
46#undef LL_GST_SYM
47
48
49static bool sSymsGrabbed = false;
50static apr_pool_t *sSymGSTDSOMemoryPool = NULL;
51static apr_dso_handle_t *sSymGSTDSOHandleG = NULL;
52static apr_dso_handle_t *sSymGSTDSOHandleV = NULL;
53static apr_dso_handle_t *sSymGSTDSOHandleA = NULL;
54
55
56bool grab_gst_syms(std::string gst_dso_name,
57 std::string gst_dso_name_vid,
58 std::string gst_dso_name_aud)
59{
60 if (sSymsGrabbed)
61 {
62 // already have grabbed good syms
63 return TRUE;
64 }
65
66 bool sym_error = false;
67 bool rtn = false;
68 apr_status_t rv;
69 apr_dso_handle_t *sSymGSTDSOHandle = NULL;
70
71#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##GSTSYM, sSymGSTDSOHandle, #GSTSYM); if (rv != APR_SUCCESS) {llwarns << "Failed to grab symbol: " << #GSTSYM << llendl; if (REQ) sym_error = true;} else llinfos << "grabbed symbol: " << #GSTSYM << " from " << (void*)ll##GSTSYM << llendl;}while(0)
72
73 //attempt to load the shared libraries
74 apr_pool_create(&sSymGSTDSOMemoryPool, NULL);
75
76 if ( APR_SUCCESS == (rv = apr_dso_load(&sSymGSTDSOHandle,
77 gst_dso_name.c_str(),
78 sSymGSTDSOMemoryPool) ))
79 {
80 llinfos << "Found DSO: " << gst_dso_name << llendl;
81#include "llmediaimplgstreamer_syms_raw.inc"
82
83 if ( sSymGSTDSOHandle )
84 {
85 sSymGSTDSOHandleG = sSymGSTDSOHandle;
86 sSymGSTDSOHandle = NULL;
87 }
88
89 if ( APR_SUCCESS == (rv = apr_dso_load(&sSymGSTDSOHandle,
90 gst_dso_name_aud.c_str(),
91 sSymGSTDSOMemoryPool) ))
92 {
93 llinfos << "Found DSO: " << gst_dso_name_aud << llendl;
94#include "llmediaimplgstreamer_syms_rawa.inc"
95
96 if ( sSymGSTDSOHandle )
97 {
98 sSymGSTDSOHandleA = sSymGSTDSOHandle;
99 sSymGSTDSOHandle = NULL;
100 }
101
102 if ( APR_SUCCESS ==
103 (rv = apr_dso_load(&sSymGSTDSOHandle,
104 gst_dso_name_vid.c_str(),
105 sSymGSTDSOMemoryPool) ))
106 {
107 llinfos << "Found DSO: " << gst_dso_name_vid << llendl;
108#include "llmediaimplgstreamer_syms_rawv.inc"
109 }
110 else
111 {
112 llwarns << "Couldn't load DSO: "
113 << gst_dso_name_vid << llendl;
114 rtn = false; // failure
115 }
116 }
117 else
118 {
119 llwarns << "Couldn't load DSO: "
120 << gst_dso_name_aud << llendl;
121 rtn = false; // failure
122 }
123
124 rtn = !sym_error;
125 }
126 else
127 {
128 llwarns << "Couldn't load DSO: " << gst_dso_name << llendl;
129 rtn = false; // failure
130 }
131
132 if (sym_error)
133 {
134 llwarns << "Failed to find necessary symbols in GStreamer libraries." << llendl;
135 }
136
137 if ( sSymGSTDSOHandle )
138 {
139 sSymGSTDSOHandleV = sSymGSTDSOHandle;
140 sSymGSTDSOHandle = NULL;
141 }
142#undef LL_GST_SYM
143
144 sSymsGrabbed = !!rtn;
145 return rtn;
146}
147
148
149void ungrab_gst_syms()
150{
151 // should be safe to call regardless of whether we've
152 // actually grabbed syms.
153
154 if ( sSymGSTDSOHandleG )
155 {
156 apr_dso_unload(sSymGSTDSOHandleG);
157 sSymGSTDSOHandleG = NULL;
158 }
159
160 if ( sSymGSTDSOHandleA )
161 {
162 apr_dso_unload(sSymGSTDSOHandleA);
163 sSymGSTDSOHandleA = NULL;
164 }
165
166 if ( sSymGSTDSOHandleV )
167 {
168 apr_dso_unload(sSymGSTDSOHandleV);
169 sSymGSTDSOHandleV = NULL;
170 }
171
172 if ( sSymGSTDSOMemoryPool )
173 {
174 apr_pool_destroy(sSymGSTDSOMemoryPool);
175 sSymGSTDSOMemoryPool = NULL;
176 }
177
178 // NULL-out all of the symbols we'd grabbed
179#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{ll##GSTSYM = NULL;}while(0)
180#include "llmediaimplgstreamer_syms_raw.inc"
181#include "llmediaimplgstreamer_syms_rawa.inc"
182#include "llmediaimplgstreamer_syms_rawv.inc"
183#undef LL_GST_SYM
184
185 sSymsGrabbed = false;
186}
187
188
189#endif // LL_GSTREAMER_ENABLED
diff --git a/linden/indra/llmedia/llmediaimplgstreamer_syms.h b/linden/indra/llmedia/llmediaimplgstreamer_syms.h
new file mode 100644
index 0000000..6dec2a2
--- /dev/null
+++ b/linden/indra/llmedia/llmediaimplgstreamer_syms.h
@@ -0,0 +1,75 @@
1/**
2 * @file llmediaimplgstreamer_syms.h
3 * @brief dynamic GStreamer symbol-grabbing code
4 *
5 * Copyright (c) 2007-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
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#include "linden_common.h"
30
31#if LL_GSTREAMER_ENABLED
32
33extern "C" {
34#include <gst/gst.h>
35}
36
37bool grab_gst_syms(std::string gst_dso_name,
38 std::string gst_dso_name_vid,
39 std::string gst_dso_name_aud);
40void ungrab_gst_syms();
41
42#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) extern RTN (*ll##GSTSYM)(__VA_ARGS__)
43#include "llmediaimplgstreamer_syms_raw.inc"
44#include "llmediaimplgstreamer_syms_rawa.inc"
45#include "llmediaimplgstreamer_syms_rawv.inc"
46#undef LL_GST_SYM
47
48// regrettable hacks to give us better runtime compatibility with older systems
49#define llg_return_if_fail(COND) do{if (!(COND)) return;}while(0)
50#define llg_return_val_if_fail(COND,V) do{if (!(COND)) return V;}while(0)
51
52// regrettable hacks because GStreamer was not designed for runtime loading
53#undef GST_TYPE_MESSAGE
54#define GST_TYPE_MESSAGE (llgst_message_get_type())
55#undef GST_TYPE_OBJECT
56#define GST_TYPE_OBJECT (llgst_object_get_type())
57#undef GST_TYPE_PIPELINE
58#define GST_TYPE_PIPELINE (llgst_pipeline_get_type())
59#undef GST_TYPE_ELEMENT
60#define GST_TYPE_ELEMENT (llgst_element_get_type())
61#undef GST_TYPE_AUDIO_SINK
62#define GST_TYPE_AUDIO_SINK (llgst_audio_sink_get_type())
63#undef GST_TYPE_VIDEO_SINK
64#define GST_TYPE_VIDEO_SINK (llgst_video_sink_get_type())
65#undef _gst_debug_register_funcptr
66#define _gst_debug_register_funcptr ll_gst_debug_register_funcptr
67#undef _gst_debug_category_new
68#define _gst_debug_category_new ll_gst_debug_category_new
69#undef __gst_debug_enabled
70#define __gst_debug_enabled (0)
71
72// more hacks
73#define LLGST_MESSAGE_TYPE_NAME(M) (llgst_message_type_get_name(GST_MESSAGE_TYPE(M)))
74
75#endif // LL_GSTREAMER_ENABLED
diff --git a/linden/indra/llmedia/llmediaimplgstreamer_syms_raw.inc b/linden/indra/llmedia/llmediaimplgstreamer_syms_raw.inc
new file mode 100644
index 0000000..c00947f
--- /dev/null
+++ b/linden/indra/llmedia/llmediaimplgstreamer_syms_raw.inc
@@ -0,0 +1,42 @@
1
2// required symbols to grab
3LL_GST_SYM(true, gst_init_check, gboolean, int *argc, char **argv[], GError ** err);
4LL_GST_SYM(true, gst_message_get_type, GType, void);
5LL_GST_SYM(true, gst_message_type_get_name, const gchar*, GstMessageType type);
6LL_GST_SYM(true, gst_message_parse_error, void, GstMessage *message, GError **gerror, gchar **debug);
7LL_GST_SYM(true, gst_message_parse_warning, void, GstMessage *message, GError **gerror, gchar **debug);
8LL_GST_SYM(true, gst_message_parse_state_changed, void, GstMessage *message, GstState *oldstate, GstState *newstate, GstState *pending);
9LL_GST_SYM(true, gst_element_set_state, GstStateChangeReturn, GstElement *element, GstState state);
10LL_GST_SYM(true, gst_object_unref, void, gpointer object);
11LL_GST_SYM(true, gst_object_get_type, GType, void);
12LL_GST_SYM(true, gst_pipeline_get_type, GType, void);
13LL_GST_SYM(true, gst_pipeline_get_bus, GstBus*, GstPipeline *pipeline);
14LL_GST_SYM(true, gst_bus_add_watch, guint, GstBus * bus, GstBusFunc func, gpointer user_data);
15LL_GST_SYM(true, gst_element_factory_make, GstElement*, const gchar *factoryname, const gchar *name);
16LL_GST_SYM(true, gst_element_get_type, GType, void);
17LL_GST_SYM(true, gst_static_pad_template_get, GstPadTemplate*, GstStaticPadTemplate *pad_template);
18LL_GST_SYM(true, gst_element_class_add_pad_template, void, GstElementClass *klass, GstPadTemplate *temp);
19LL_GST_SYM(true, gst_element_class_set_details, void, GstElementClass *klass, const GstElementDetails *details);
20LL_GST_SYM(true, gst_caps_unref, void, GstCaps* caps);
21LL_GST_SYM(true, gst_caps_ref, GstCaps *, GstCaps* caps);
22LL_GST_SYM(true, _gst_debug_register_funcptr, void, GstDebugFuncPtr func, gchar* ptrname);
23LL_GST_SYM(true, _gst_debug_category_new, GstDebugCategory *, gchar *name, guint color, gchar *description);
24LL_GST_SYM(true, gst_caps_is_empty, gboolean, const GstCaps *caps);
25LL_GST_SYM(true, gst_caps_from_string, GstCaps *, const gchar *string);
26LL_GST_SYM(true, gst_caps_replace, void, GstCaps **caps, GstCaps *newcaps);
27LL_GST_SYM(true, gst_caps_get_structure, GstStructure *, const GstCaps *caps, guint index);
28LL_GST_SYM(true, gst_caps_copy, GstCaps *, const GstCaps * caps);
29LL_GST_SYM(true, gst_caps_intersect, GstCaps *, const GstCaps *caps1, const GstCaps *caps2);
30LL_GST_SYM(true, gst_element_register, gboolean, GstPlugin *plugin, const gchar *name, guint rank, GType type);
31LL_GST_SYM(true, _gst_plugin_register_static, void, GstPluginDesc *desc);
32LL_GST_SYM(true, gst_structure_get_int, gboolean, const GstStructure *structure, const gchar *fieldname, gint *value);
33LL_GST_SYM(true, gst_structure_get_value, G_CONST_RETURN GValue *, const GstStructure *structure, const gchar *fieldname);
34LL_GST_SYM(true, gst_value_get_fraction_numerator, gint, const GValue *value);
35LL_GST_SYM(true, gst_value_get_fraction_denominator, gint, const GValue *value);
36LL_GST_SYM(true, gst_structure_get_name, G_CONST_RETURN gchar *, const GstStructure *structure);
37
38// optional symbols to grab
39LL_GST_SYM(false, gst_segtrap_set_enabled, void, gboolean enabled);
40LL_GST_SYM(false, gst_message_parse_buffering, void, GstMessage *message, gint *percent);
41LL_GST_SYM(false, expected_to_be_missing, void, gboolean enabled);
42LL_GST_SYM(false, gst_message_parse_info, void, GstMessage *message, GError **gerror, gchar **debug);
diff --git a/linden/indra/llmedia/llmediaimplgstreamer_syms_rawa.inc b/linden/indra/llmedia/llmediaimplgstreamer_syms_rawa.inc
new file mode 100644
index 0000000..0be99b5
--- /dev/null
+++ b/linden/indra/llmedia/llmediaimplgstreamer_syms_rawa.inc
@@ -0,0 +1,5 @@
1
2// required symbols to grab
3LL_GST_SYM(true, gst_audio_sink_get_type, GType, void);
4
5// optional symbols to grab
diff --git a/linden/indra/llmedia/llmediaimplgstreamer_syms_rawv.inc b/linden/indra/llmedia/llmediaimplgstreamer_syms_rawv.inc
new file mode 100644
index 0000000..14fbcb4
--- /dev/null
+++ b/linden/indra/llmedia/llmediaimplgstreamer_syms_rawv.inc
@@ -0,0 +1,5 @@
1
2// required symbols to grab
3LL_GST_SYM(true, gst_video_sink_get_type, GType, void);
4
5// optional symbols to grab
diff --git a/linden/indra/llmedia/llmediaimplgstreamervidplug.cpp b/linden/indra/llmedia/llmediaimplgstreamervidplug.cpp
new file mode 100644
index 0000000..dade946
--- /dev/null
+++ b/linden/indra/llmedia/llmediaimplgstreamervidplug.cpp
@@ -0,0 +1,461 @@
1/**
2 * @file llmediaimplgstreamervidplug.h
3 * @brief Video-consuming static GStreamer plugin for gst-to-LLMediaImpl
4 *
5 * Copyright (c) 2007-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
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#if LL_GSTREAMER_ENABLED
30
31#include <string.h>
32
33#include <gst/gst.h>
34#include <gst/video/video.h>
35#include <gst/video/gstvideosink.h>
36
37#include "llmediaimplgstreamer_syms.h"
38
39#include "llthread.h"
40
41#include "llmediaimplgstreamervidplug.h"
42
43GST_DEBUG_CATEGORY_STATIC (gst_slvideo_debug);
44#define GST_CAT_DEFAULT gst_slvideo_debug
45
46/* Filter signals and args */
47enum
48{
49 /* FILL ME */
50 LAST_SIGNAL
51};
52
53enum
54{
55 ARG_0
56};
57
58#define SLV_SIZECAPS ", width=(int){1,2,4,8,16,32,64,128,256,512,1024}, height=(int){1,2,4,8,16,32,64,128,256,512,1024} "
59#define SLV_ALLCAPS GST_VIDEO_CAPS_RGBx SLV_SIZECAPS ";" GST_VIDEO_CAPS_BGRx SLV_SIZECAPS
60
61static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE (
62 "sink",
63 GST_PAD_SINK,
64 GST_PAD_ALWAYS,
65 GST_STATIC_CAPS (SLV_ALLCAPS)
66 );
67
68GST_BOILERPLATE (GstSLVideo, gst_slvideo, GstVideoSink,
69 GST_TYPE_VIDEO_SINK);
70
71static void gst_slvideo_set_property (GObject * object, guint prop_id,
72 const GValue * value,
73 GParamSpec * pspec);
74static void gst_slvideo_get_property (GObject * object, guint prop_id,
75 GValue * value, GParamSpec * pspec);
76
77static void
78gst_slvideo_base_init (gpointer gclass)
79{
80 static GstElementDetails element_details = {
81 "PluginTemplate",
82 "Generic/PluginTemplate",
83 "Generic Template Element",
84 "Linden Lab"
85 };
86 GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
87
88 llgst_element_class_add_pad_template (element_class,
89 llgst_static_pad_template_get (&sink_factory));
90 llgst_element_class_set_details (element_class, &element_details);
91}
92
93
94static void
95gst_slvideo_finalize (GObject * object)
96{
97 GstSLVideo *slvideo;
98 slvideo = GST_SLVIDEO (object);
99 if (slvideo->caps)
100 {
101 llgst_caps_unref(slvideo->caps);
102 }
103
104 G_OBJECT_CLASS(parent_class)->finalize (object);
105}
106
107
108static GstFlowReturn
109gst_slvideo_show_frame (GstBaseSink * bsink, GstBuffer * buf)
110{
111 GstSLVideo *slvideo;
112 llg_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);
113
114 slvideo = GST_SLVIDEO(bsink);
115
116#if 0
117 fprintf(stderr, "\n\ntransferring a frame of %dx%d <- %p (%d)\n\n",
118 slvideo->width, slvideo->height, GST_BUFFER_DATA(buf),
119 slvideo->format);
120#endif
121 if (GST_BUFFER_DATA(buf))
122 {
123 // copy frame and frame info into neutral territory
124 GST_OBJECT_LOCK(slvideo);
125 slvideo->retained_frame_ready = TRUE;
126 slvideo->retained_frame_width = slvideo->width;
127 slvideo->retained_frame_height = slvideo->height;
128 slvideo->retained_frame_format = slvideo->format;
129 int rowbytes =
130 SLVPixelFormatBytes[slvideo->retained_frame_format] *
131 slvideo->retained_frame_width;
132 int needbytes = rowbytes * slvideo->retained_frame_width;
133 // resize retained frame hunk only if necessary
134 if (needbytes != slvideo->retained_frame_allocbytes)
135 {
136 delete[] slvideo->retained_frame_data;
137 slvideo->retained_frame_data = new U8[needbytes];
138 slvideo->retained_frame_allocbytes = needbytes;
139
140 }
141 // copy the actual frame data to neutral territory -
142 // flipped, for GL reasons
143 for (int ypos=0; ypos<slvideo->height; ++ypos)
144 {
145 memcpy(&slvideo->retained_frame_data[(slvideo->height-1-ypos)*rowbytes],
146 &(((U8*)GST_BUFFER_DATA(buf))[ypos*rowbytes]),
147 rowbytes);
148 }
149 // done with the shared data
150 GST_OBJECT_UNLOCK(slvideo);
151 }
152
153 return GST_FLOW_OK;
154}
155
156
157static GstStateChangeReturn
158gst_slvideo_change_state(GstElement * element, GstStateChange transition)
159{
160 GstSLVideo *slvideo;
161 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
162
163 slvideo = GST_SLVIDEO (element);
164
165 switch (transition) {
166 case GST_STATE_CHANGE_NULL_TO_READY:
167 break;
168 case GST_STATE_CHANGE_READY_TO_PAUSED:
169 break;
170 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
171 break;
172 default:
173 break;
174 }
175
176 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
177 if (ret == GST_STATE_CHANGE_FAILURE)
178 return ret;
179
180 switch (transition) {
181 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
182 break;
183 case GST_STATE_CHANGE_PAUSED_TO_READY:
184 slvideo->fps_n = 0;
185 slvideo->fps_d = 1;
186 GST_VIDEO_SINK_WIDTH(slvideo) = 0;
187 GST_VIDEO_SINK_HEIGHT(slvideo) = 0;
188 break;
189 case GST_STATE_CHANGE_READY_TO_NULL:
190 break;
191 default:
192 break;
193 }
194
195 return ret;
196}
197
198
199static GstCaps *
200gst_slvideo_get_caps (GstBaseSink * bsink)
201{
202 GstSLVideo *slvideo;
203 slvideo = GST_SLVIDEO(bsink);
204
205 return llgst_caps_ref (slvideo->caps);
206}
207
208
209/* this function handles the link with other elements */
210static gboolean
211gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps)
212{
213 GstSLVideo *filter;
214 GstStructure *structure;
215 GstCaps *intersection;
216
217 GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps);
218
219 filter = GST_SLVIDEO(bsink);
220
221 intersection = llgst_caps_intersect (filter->caps, caps);
222 if (llgst_caps_is_empty (intersection))
223 {
224 // no overlap between our caps and requested caps
225 return FALSE;
226 }
227 llgst_caps_unref(intersection);
228
229 int width, height;
230 gboolean ret;
231 const GValue *fps;
232 const GValue *par;
233 structure = llgst_caps_get_structure (caps, 0);
234 ret = llgst_structure_get_int (structure, "width", &width);
235 ret = ret && llgst_structure_get_int (structure, "height", &height);
236 fps = llgst_structure_get_value (structure, "framerate");
237 ret = ret && (fps != NULL);
238 par = llgst_structure_get_value (structure, "pixel-aspect-ratio");
239 if (!ret)
240 return FALSE;
241
242 filter->width = width;
243 filter->height = height;
244 filter->fps_n = llgst_value_get_fraction_numerator(fps);
245 filter->fps_d = llgst_value_get_fraction_denominator(fps);
246 if (par)
247 {
248 filter->par_n = llgst_value_get_fraction_numerator(par);
249 filter->par_d = llgst_value_get_fraction_denominator(par);
250 }
251 else
252 {
253 filter->par_n = 1;
254 filter->par_d = 1;
255 }
256 GST_VIDEO_SINK_WIDTH(filter) = width;
257 GST_VIDEO_SINK_HEIGHT(filter) = height;
258
259 filter->format = SLV_PF_UNKNOWN;
260 if (0 == strcmp(llgst_structure_get_name(structure),
261 "video/x-raw-rgb"))
262 {
263 int red_mask;
264 int green_mask;
265 int blue_mask;
266 llgst_structure_get_int(structure, "red_mask", &red_mask);
267 llgst_structure_get_int(structure, "green_mask", &green_mask);
268 llgst_structure_get_int(structure, "blue_mask", &blue_mask);
269 if ((unsigned int)red_mask == 0xFF000000 &&
270 (unsigned int)green_mask == 0x00FF0000 &&
271 (unsigned int)blue_mask == 0x0000FF00)
272 {
273 filter->format = SLV_PF_RGBX;
274 //fprintf(stderr, "\n\nPIXEL FORMAT RGB\n\n");
275 } else if ((unsigned int)red_mask == 0x0000FF00 &&
276 (unsigned int)green_mask == 0x00FF0000 &&
277 (unsigned int)blue_mask == 0xFF000000)
278 {
279 filter->format = SLV_PF_BGRX;
280 //fprintf(stderr, "\n\nPIXEL FORMAT BGR\n\n");
281 }
282 }
283
284 return TRUE;
285}
286
287
288static gboolean
289gst_slvideo_start (GstBaseSink * bsink)
290{
291 GstSLVideo *slvideo;
292 gboolean ret = TRUE;
293
294 slvideo = GST_SLVIDEO(bsink);
295
296 return ret;
297}
298
299static gboolean
300gst_slvideo_stop (GstBaseSink * bsink)
301{
302 GstSLVideo *slvideo;
303 slvideo = GST_SLVIDEO(bsink);
304
305 // free-up retained frame buffer
306 GST_OBJECT_LOCK(slvideo);
307 slvideo->retained_frame_ready = FALSE;
308 delete[] slvideo->retained_frame_data;
309 slvideo->retained_frame_data = NULL;
310 slvideo->retained_frame_allocbytes = 0;
311 GST_OBJECT_UNLOCK(slvideo);
312
313 return TRUE;
314}
315
316
317static gboolean
318gst_slvideo_unlock (GstBaseSink * bsink)
319{
320 // nothing really to do here.
321 return TRUE;
322}
323
324
325/* initialize the plugin's class */
326static void
327gst_slvideo_class_init (GstSLVideoClass * klass)
328{
329 GObjectClass *gobject_class;
330 GstElementClass *gstelement_class;
331 GstBaseSinkClass *gstbasesink_class;
332
333 gobject_class = (GObjectClass *) klass;
334 gstelement_class = (GstElementClass *) klass;
335 gstbasesink_class = (GstBaseSinkClass *) klass;
336
337 gobject_class->finalize = gst_slvideo_finalize;
338 gobject_class->set_property = gst_slvideo_set_property;
339 gobject_class->get_property = gst_slvideo_get_property;
340
341 gstelement_class->change_state = gst_slvideo_change_state;
342
343 gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_slvideo_get_caps);
344 gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR( gst_slvideo_set_caps);
345 //gstbasesink_class->buffer_alloc=GST_DEBUG_FUNCPTR(gst_slvideo_buffer_alloc);
346 //gstbasesink_class->get_times = GST_DEBUG_FUNCPTR (gst_slvideo_get_times);
347 gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_slvideo_show_frame);
348 gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_slvideo_show_frame);
349
350 gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_slvideo_start);
351 gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_slvideo_stop);
352
353 gstbasesink_class->unlock = GST_DEBUG_FUNCPTR (gst_slvideo_unlock);
354}
355
356
357static void
358gst_slvideo_update_caps (GstSLVideo * slvideo)
359{
360 GstCaps *caps;
361
362 // GStreamer will automatically convert colourspace if necessary.
363 // GStreamer will automatically resize media to one of these enumerated
364 // powers-of-two that we ask for (yay GStreamer!)
365 caps = llgst_caps_from_string (SLV_ALLCAPS);
366
367 llgst_caps_replace (&slvideo->caps, caps);
368}
369
370
371/* initialize the new element
372 * instantiate pads and add them to element
373 * set functions
374 * initialize structure
375 */
376static void
377gst_slvideo_init (GstSLVideo * filter,
378 GstSLVideoClass * gclass)
379{
380 filter->width = -1;
381 filter->height = -1;
382
383 // this is the info we share with the client app
384 GST_OBJECT_LOCK(filter);
385 filter->retained_frame_ready = FALSE;
386 filter->retained_frame_data = NULL;
387 filter->retained_frame_allocbytes = 0;
388 filter->retained_frame_width = filter->width;
389 filter->retained_frame_height = filter->height;
390 filter->retained_frame_format = SLV_PF_UNKNOWN;
391 GST_OBJECT_UNLOCK(filter);
392
393 gst_slvideo_update_caps(filter);
394}
395
396static void
397gst_slvideo_set_property (GObject * object, guint prop_id,
398 const GValue * value, GParamSpec * pspec)
399{
400 llg_return_if_fail (GST_IS_SLVIDEO (object));
401
402 switch (prop_id) {
403 default:
404 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
405 break;
406 }
407}
408
409static void
410gst_slvideo_get_property (GObject * object, guint prop_id,
411 GValue * value, GParamSpec * pspec)
412{
413 llg_return_if_fail (GST_IS_SLVIDEO (object));
414
415 switch (prop_id) {
416 default:
417 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
418 break;
419 }
420}
421
422
423/* entry point to initialize the plug-in
424 * initialize the plug-in itself
425 * register the element factories and pad templates
426 * register the features
427 */
428static gboolean
429plugin_init (GstPlugin * plugin)
430{
431 //fprintf(stderr, "\n\n\nPLUGIN INIT\n\n\n");
432
433 GST_DEBUG_CATEGORY_INIT (gst_slvideo_debug, "private-slvideo-plugin",
434 0, "Second Life Video Sink");
435
436 return llgst_element_register (plugin, "private-slvideo",
437 GST_RANK_NONE, GST_TYPE_SLVIDEO);
438}
439
440/* this is the structure that gstreamer looks for to register plugins
441 */
442/* NOTE: Can't rely upon GST_PLUGIN_DEFINE_STATIC to self-register, since
443 some g++ versions buggily avoid __attribute__((constructor)) functions -
444 so we provide an explicit plugin init function.
445 */
446void gst_slvideo_init_class (void)
447{
448#define PACKAGE "packagehack"
449 static GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
450 GST_VERSION_MINOR,
451 "private-slvideoplugin",
452 "SL Video sink plugin",
453 plugin_init, "0.1", GST_LICENSE_UNKNOWN,
454 "Second Life",
455 "http://www.secondlife.com/");
456#undef PACKAGE
457 ll_gst_plugin_register_static (&gst_plugin_desc);
458 //fprintf(stderr, "\n\n\nCLASS INIT\n\n\n");
459}
460
461#endif // LL_GSTREAMER_ENABLED
diff --git a/linden/indra/llmedia/llmediaimplgstreamervidplug.h b/linden/indra/llmedia/llmediaimplgstreamervidplug.h
new file mode 100644
index 0000000..2bfb853
--- /dev/null
+++ b/linden/indra/llmedia/llmediaimplgstreamervidplug.h
@@ -0,0 +1,101 @@
1/**
2 * @file llmediaimplgstreamervidplug.h
3 * @brief Video-consuming static GStreamer plugin for gst-to-LLMediaImpl
4 *
5 * Copyright (c) 2007-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
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#ifndef __GST_SLVIDEO_H__
30#define __GST_SLVIDEO_H__
31
32#if LL_GSTREAMER_ENABLED
33
34extern "C" {
35#include <gst/gst.h>
36#include <gst/video/video.h>
37#include <gst/video/gstvideosink.h>
38}
39
40G_BEGIN_DECLS
41
42/* #defines don't like whitespacey bits */
43#define GST_TYPE_SLVIDEO \
44 (gst_slvideo_get_type())
45#define GST_SLVIDEO(obj) \
46 (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SLVIDEO,GstSLVideo))
47#define GST_SLVIDEO_CLASS(klass) \
48 (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SLVIDEO,GstSLVideoClass))
49#define GST_IS_SLVIDEO(obj) \
50 (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SLVIDEO))
51#define GST_IS_SLVIDEO_CLASS(klass) \
52 (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SLVIDEO))
53
54typedef struct _GstSLVideo GstSLVideo;
55typedef struct _GstSLVideoClass GstSLVideoClass;
56
57typedef enum {
58 SLV_PF_UNKNOWN = 0,
59 SLV_PF_RGBX = 1,
60 SLV_PF_BGRX = 2,
61 SLV__END = 3
62} SLVPixelFormat;
63const int SLVPixelFormatBytes[SLV__END] = {1, 4, 4};
64
65struct _GstSLVideo
66{
67 GstVideoSink video_sink;
68
69 GstCaps *caps;
70
71 int fps_n, fps_d;
72 int par_n, par_d;
73 int height, width;
74 SLVPixelFormat format;
75
76 // SHARED WITH APPLICATION:
77 // Access to the following should be protected by GST_OBJECT_LOCK() on
78 // the GstSLVideo object, and should be totally consistent upon UNLOCK
79 // (i.e. all written at once to reflect the current retained frame info
80 // when the retained frame is updated.)
81 bool retained_frame_ready; // new frame ready since flag last reset. (*TODO: could get the writer to wait on a semaphore instead of having the reader poll, potentially making dropped frames somewhat cheaper.)
82 U8* retained_frame_data;
83 int retained_frame_allocbytes;
84 int retained_frame_width, retained_frame_height;
85 SLVPixelFormat retained_frame_format;
86};
87
88struct _GstSLVideoClass
89{
90 GstVideoSink parent_class;
91};
92
93GType gst_slvideo_get_type (void);
94
95void gst_slvideo_init_class (void);
96
97G_END_DECLS
98
99#endif // LL_GSTREAMER_ENABLED
100
101#endif /* __GST_SLVIDEO_H__ */
diff --git a/linden/indra/llmedia/llmediamoviebase.cpp b/linden/indra/llmedia/llmediamoviebase.cpp
index 46b76b0..de9933b 100644
--- a/linden/indra/llmedia/llmediamoviebase.cpp
+++ b/linden/indra/llmedia/llmediamoviebase.cpp
@@ -30,6 +30,7 @@
30 30
31#include "llmediamoviebase.h" 31#include "llmediamoviebase.h"
32#include "llmediaimplquicktime.h" 32#include "llmediaimplquicktime.h"
33#include "llmediaimplgstreamer.h"
33 34
34LLMediaMovieBase::LLMediaMovieBase() 35LLMediaMovieBase::LLMediaMovieBase()
35{ 36{
@@ -47,6 +48,13 @@ LLMediaMovieBase* LLMediaMovieBase::make( const MediaType mediaTypeIn, S32 width
47 } 48 }
48 else 49 else
49#endif 50#endif
51#if LL_GSTREAMER_ENABLED
52 if ( mediaTypeIn == QuickTime )
53 {
54 return new LLMediaImplGStreamer ();
55 }
56 else
57#endif
50 58
51 return 0; 59 return 0;
52} 60}