aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmedia/llmediaimplgstreamer.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:45:34 -0500
committerJacek Antonelli2008-08-15 23:45:34 -0500
commitcd17687f01420952712a500107e0f93e7ab8d5f8 (patch)
treece48c2b706f2c1176290e39fb555fbdf6648ce01 /linden/indra/llmedia/llmediaimplgstreamer.cpp
parentSecond Life viewer sources 1.19.0.5 (diff)
downloadmeta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.zip
meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.gz
meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.bz2
meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.xz
Second Life viewer sources 1.19.1.0
Diffstat (limited to '')
-rw-r--r--linden/indra/llmedia/llmediaimplgstreamer.cpp652
1 files changed, 277 insertions, 375 deletions
diff --git a/linden/indra/llmedia/llmediaimplgstreamer.cpp b/linden/indra/llmedia/llmediaimplgstreamer.cpp
index 50dc052..b54d088 100644
--- a/linden/indra/llmedia/llmediaimplgstreamer.cpp
+++ b/linden/indra/llmedia/llmediaimplgstreamer.cpp
@@ -1,5 +1,6 @@
1/** 1/**
2 * @file llmediaimplgstreamer.cpp 2 * @file llmediaimplgstreamer.cpp
3 * @author Tofu Linden
3 * @brief implementation that supports various media through GStreamer. 4 * @brief implementation that supports various media through GStreamer.
4 * 5 *
5 * $LicenseInfo:firstyear=2007&license=viewergpl$ 6 * $LicenseInfo:firstyear=2007&license=viewergpl$
@@ -29,7 +30,7 @@
29 * $/LicenseInfo$ 30 * $/LicenseInfo$
30 */ 31 */
31 32
32#include "linden_common.h" 33#include "llmediaimplgstreamer.h"
33 34
34#if LL_GSTREAMER_ENABLED 35#if LL_GSTREAMER_ENABLED
35 36
@@ -37,7 +38,8 @@ extern "C" {
37#include <gst/gst.h> 38#include <gst/gst.h>
38} 39}
39 40
40#include "llmediaimplgstreamer.h" 41#include "llmediamanager.h"
42#include "llmediaimplregister.h"
41 43
42#include "llmediaimplgstreamervidplug.h" 44#include "llmediaimplgstreamervidplug.h"
43 45
@@ -47,17 +49,28 @@ extern "C" {
47 49
48#include "llmediaimplgstreamer_syms.h" 50#include "llmediaimplgstreamer_syms.h"
49 51
50#include "llgl.h" 52// register this impl with media manager factory
51#include "llglheaders.h" // For gl texture modes 53static LLMediaImplRegister sLLMediaImplGStreamerReg( "LLMediaImplGStreamer", new LLMediaImplGStreamerMaker() );
54
55LLMediaImplGStreamerMaker::LLMediaImplGStreamerMaker()
56{
57 // Register to handle the scheme
58 mSchema.push_back( "rtsp" );
59 mSchema.push_back( "rtmp" );
60
61 // Register to handle the category
62 mMimeTypeCategories.push_back( "video" );
63 mMimeTypeCategories.push_back( "audio" );
64}
52 65
53/////////////////////////////////////////////////////////////////////////////// 66///////////////////////////////////////////////////////////////////////////////
54// 67//
55LLMediaImplGStreamer:: 68LLMediaImplGStreamer::
56LLMediaImplGStreamer () : 69LLMediaImplGStreamer () :
57 mediaData ( NULL ), 70 mediaData ( NULL ),
58 ownBuffer ( TRUE ), 71 mMediaRowbytes ( 1 ),
59 mVolume ( 1.0f ), 72 mTextureFormatPrimary ( LL_MEDIA_BGRA ),
60 currentMode ( ModeIdle ), 73 mTextureFormatType ( LL_MEDIA_UNSIGNED_INT_8_8_8_8_REV ),
61 mPump ( NULL ), 74 mPump ( NULL ),
62 mPlaybin ( NULL ), 75 mPlaybin ( NULL ),
63 mVideoSink ( NULL ) 76 mVideoSink ( NULL )
@@ -65,80 +78,95 @@ LLMediaImplGStreamer () :
65 ,mAudioSink ( NULL ) 78 ,mAudioSink ( NULL )
66#endif // LL_GST_SOUNDSINK 79#endif // LL_GST_SOUNDSINK
67{ 80{
68 mMediaDepthBytes = 4; 81 DEBUGMSG("constructing media...");
69 mTextureDepth = 4; 82
70 mTextureFormatInternal = GL_RGB8; 83 setMediaDepth(4);
71 mTextureFormatPrimary = GL_BGRA; 84
72 mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV; 85 // Create a pumpable main-loop for this media
86 mPump = g_main_loop_new (NULL, FALSE);
87 if (!mPump)
88 {
89 return; // error
90 }
91
92 // instantiate a playbin element to do the hard work
93 mPlaybin = llgst_element_factory_make ("playbin", "play");
94 if (!mPlaybin)
95 {
96 // todo: cleanup pump
97 return; // error
98 }
99
100 if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) {
101 // instantiate and connect a custom video sink
102 mVideoSink =
103 GST_SLVIDEO(llgst_element_factory_make ("private-slvideo", "slvideo"));
104 if (!mVideoSink)
105 {
106 WARNMSG("Could not instantiate private-slvideo element.");
107 // todo: cleanup.
108 return; // error
109 }
110
111 g_object_set(mPlaybin, "video-sink", mVideoSink, NULL);
112
113#ifdef LL_GST_SOUNDSINK
114 // instantiate and connect a custom audio sink
115 mAudioSink =
116 GST_SLSOUND(llgst_element_factory_make ("private-slsound", "slsound"));
117 if (!mAudioSink)
118 {
119 WARNMSG("Could not instantiate private-slsound element.");
120 // todo: cleanup.
121 return; // error
122 }
123
124 g_object_set(mPlaybin, "audio-sink", mAudioSink, NULL);
125#endif
126 }
73} 127}
74 128
75/////////////////////////////////////////////////////////////////////////////// 129// virtual
76// 130int LLMediaImplGStreamer::getTextureFormatPrimary() const
77LLMediaImplGStreamer::
78~LLMediaImplGStreamer ()
79{ 131{
80 unload(); 132 return mTextureFormatPrimary;
81} 133}
82 134
83void UnloadGStreamer() 135// virtual
136int LLMediaImplGStreamer::getTextureFormatType() const
84{ 137{
85 ungrab_gst_syms(); 138 return mTextureFormatType;
86} 139}
87 140
141// virtual
142int LLMediaImplGStreamer::getTextureFormatInternal() const
143{
144 return LL_MEDIA_RGB8;
145}
88 146
89/////////////////////////////////////////////////////////////////////////////// 147///////////////////////////////////////////////////////////////////////////////
90// 148//
91BOOL
92LLMediaImplGStreamer:: 149LLMediaImplGStreamer::
93setBuffer ( U8* bufferIn ) 150~LLMediaImplGStreamer ()
94{ 151{
95 // Since we've pointed GStreamer at the old media data buffer 152 DEBUGMSG("dtor of media...");
96 // directly, we need to be somewhat careful deleting it... 153 unload();
97 U8* oldMediaData = mediaData; 154}
98 BOOL ownedMediaData = ownBuffer;
99
100 if(bufferIn == NULL)
101 {
102 // Passing NULL to this function requests that the object
103 // allocate its own buffer.
104 mediaData = new unsigned char[ mMediaHeight * mMediaRowbytes ];
105 ownBuffer = TRUE;
106 }
107 else
108 {
109 // Use the supplied buffer.
110 mediaData = bufferIn;
111 ownBuffer = FALSE;
112 }
113
114 if(mediaData == NULL)
115 {
116 // This is bad - probably out of memory.
117 llerrs << "LLMediaImplGStreamer::setBuffer: mediaData is NULL" << llendl;
118 // NOTE: This case doesn't clean up properly. This assert is fatal, so this isn't a huge problem,
119 // but if this assert is ever removed the code should be fixed to clean up correctly.
120 return FALSE;
121 }
122
123 // [..]
124 155
125 // Delete the old media data buffer iff we owned it. 156////////////////////////////////////////////////////////////////////////////////
126 if ( ownedMediaData ) 157// virtual
127 { 158std::string LLMediaImplGStreamer::getVersion()
128 if ( oldMediaData ) 159{
129 { 160 std::string rtn;
130 delete [] oldMediaData; 161 rtn = "[" + sLLMediaImplGStreamerReg.getImplName() + "] - GStreamer 0.10.x";
131 } 162 return rtn;
132 }
133
134 return TRUE;
135} 163}
136 164
137/////////////////////////////////////////////////////////////////////////////// 165///////////////////////////////////////////////////////////////////////////////
138// 166// (static) super-initialization - called once at application startup
139BOOL 167bool
140LLMediaImplGStreamer:: 168LLMediaImplGStreamer::
141init () 169startup ( LLMediaManagerData* init_data )
142{ 170{
143 static bool done_init = false; 171 static bool done_init = false;
144 if (!done_init) 172 if (!done_init)
@@ -148,19 +176,19 @@ init ()
148 "libgstvideo-0.10.so.0", 176 "libgstvideo-0.10.so.0",
149 "libgstaudio-0.10.so.0") ) 177 "libgstaudio-0.10.so.0") )
150 { 178 {
151 llwarns << "Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled." << llendl; 179 WARNMSG("Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled.");
152 return FALSE; 180 return false;
153 } 181 }
154 182
155 if (llgst_segtrap_set_enabled) 183 if (llgst_segtrap_set_enabled)
156 llgst_segtrap_set_enabled(FALSE); 184 llgst_segtrap_set_enabled(FALSE);
157 else 185 else
158 llwarns << "gst_segtrap_set_enabled() is not available; Second Life automated crash-reporter may cease to function until next restart." << llendl; 186 WARNMSG("gst_segtrap_set_enabled() is not available; Automated crash-reporter may cease to function until next restart.");
159 187
160 if (0 == llgst_init_check(NULL, NULL, NULL)) 188 if (0 == llgst_init_check(NULL, NULL, NULL))
161 { 189 {
162 llwarns << "GST init failed for unspecified reason." << llendl; 190 WARNMSG("GST init failed for unspecified reason.");
163 return FALSE; 191 return false;
164 } 192 }
165 193
166 // Init our custom plugins - only really need do this once. 194 // Init our custom plugins - only really need do this once.
@@ -172,52 +200,16 @@ init ()
172 done_init = true; 200 done_init = true;
173 } 201 }
174 202
175 // Create a pumpable main-loop for this media 203 return true;
176 mPump = g_main_loop_new (NULL, FALSE); 204}
177 if (!mPump)
178 {
179 return FALSE;
180 }
181
182 // instantiate a playbin element to do the hard work
183 mPlaybin = llgst_element_factory_make ("playbin", "play");
184 if (!mPlaybin)
185 {
186 // todo: cleanup pump
187 return FALSE;
188 }
189
190 if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) {
191 // instantiate and connect a custom video sink
192 mVideoSink =
193 GST_SLVIDEO(llgst_element_factory_make ("private-slvideo", "slvideo"));
194 if (!mVideoSink)
195 {
196 llwarns << "Could not instantiate private-slvideo element."
197 << llendl;
198 // todo: cleanup.
199 return FALSE;
200 }
201
202 g_object_set(mPlaybin, "video-sink", mVideoSink, NULL);
203 205
204#ifdef LL_GST_SOUNDSINK
205 // instantiate and connect a custom audio sink
206 mAudioSink =
207 GST_SLSOUND(llgst_element_factory_make ("private-slsound", "slsound"));
208 if (!mAudioSink)
209 {
210 llwarns << "Could not instantiate private-slsound element."
211 << llendl;
212 // todo: cleanup.
213 return FALSE;
214 }
215 206
216 g_object_set(mPlaybin, "audio-sink", mAudioSink, NULL); 207bool LLMediaImplGStreamer::
217#endif 208closedown()
218 } 209{
210 ungrab_gst_syms();
219 211
220 return LLMediaMovieBase::init(); 212 return true;
221} 213}
222 214
223 215
@@ -239,22 +231,20 @@ static char* get_gst_state_name(GstState state)
239#endif // LL_GST_REPORT_STATE_CHANGES 231#endif // LL_GST_REPORT_STATE_CHANGES
240 232
241static gboolean 233static gboolean
242my_bus_callback (GstBus *bus, 234bus_callback (GstBus *bus,
243 GstMessage *message, 235 GstMessage *message,
244 gpointer data) 236 gpointer data)
245{ 237{
246 if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED && 238 if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED &&
247 GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING) 239 GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING)
248 { 240 {
249 llinfos << "Got GST message type: " 241 DEBUGMSG("Got GST message type: %s",
250 << LLGST_MESSAGE_TYPE_NAME (message) 242 LLGST_MESSAGE_TYPE_NAME (message));
251 << llendl;
252 } 243 }
253 else 244 else
254 { 245 {
255 lldebugs << "Got GST message type: " 246 DEBUGMSG("Got GST message type: %s",
256 << LLGST_MESSAGE_TYPE_NAME (message) 247 LLGST_MESSAGE_TYPE_NAME (message));
257 << llendl;
258 } 248 }
259 249
260 LLMediaImplGStreamer *impl = (LLMediaImplGStreamer*)data; 250 LLMediaImplGStreamer *impl = (LLMediaImplGStreamer*)data;
@@ -266,11 +256,10 @@ my_bus_callback (GstBus *bus,
266 { 256 {
267 gint percent = 0; 257 gint percent = 0;
268 llgst_message_parse_buffering(message, &percent); 258 llgst_message_parse_buffering(message, &percent);
269 llinfos << "GST buffering: " << percent 259 DEBUGMSG("GST buffering: %d%%", percent);
270 << "%" << llendl; 260 LLMediaEvent event( impl, percent );
271 // ModeBuffering seems to do nothing except make 261 impl->getEventEmitter().update( &LLMediaObserver::onUpdateProgress, event );
272 // the UI worse 262
273 /*if (percent < 100) impl->setCurrentMode(LLMediaImplGStreamer::ModeBuffering);*/
274 } 263 }
275 break; 264 break;
276 } 265 }
@@ -284,66 +273,63 @@ my_bus_callback (GstBus *bus,
284 &pending_state); 273 &pending_state);
285#ifdef LL_GST_REPORT_STATE_CHANGES 274#ifdef LL_GST_REPORT_STATE_CHANGES
286 // not generally very useful, and rather spammy. 275 // not generally very useful, and rather spammy.
287 llinfos << "state change (old,<new>,pending): " 276 DEBUGMSG("state change (old,<new>,pending): %s,<%s>,%s",
288 << get_gst_state_name(old_state) << ", <" 277 get_gst_state_name(old_state),
289 << get_gst_state_name(new_state) << ">, " 278 get_gst_state_name(new_state),
290 << get_gst_state_name(pending_state) << 279 get_gst_state_name(pending_state));
291 llendl;
292#endif // LL_GST_REPORT_STATE_CHANGES 280#endif // LL_GST_REPORT_STATE_CHANGES
293 281
294 switch (new_state) { 282 switch (new_state) {
295 case GST_STATE_VOID_PENDING: 283 case GST_STATE_VOID_PENDING:
296 impl->setCurrentMode(LLMediaImplGStreamer::ModeNone);
297 break; 284 break;
298 case GST_STATE_NULL: 285 case GST_STATE_NULL:
299 impl->setCurrentMode(LLMediaImplGStreamer::ModeNone);
300 break; 286 break;
301 case GST_STATE_READY: 287 case GST_STATE_READY:
302 impl->setCurrentMode(LLMediaImplGStreamer::ModeStopped);
303 break; 288 break;
304 case GST_STATE_PAUSED: 289 case GST_STATE_PAUSED:
305 impl->setCurrentMode(LLMediaImplGStreamer::ModePaused);
306 break; 290 break;
307 case GST_STATE_PLAYING: 291 case GST_STATE_PLAYING:
308 impl->setCurrentMode(LLMediaImplGStreamer::ModePlaying); 292 LLMediaEvent event( impl, 100 );
293 impl->getEventEmitter().update( &LLMediaObserver::onUpdateProgress, event );
294 // emit an event to say that a media source was loaded
295 LLMediaEvent event2( impl );
296 impl->getEventEmitter().update( &LLMediaObserver::onMediaLoaded, event2 );
309 break; 297 break;
310 } 298 }
311 break; 299 break;
312 } 300 }
313 case GST_MESSAGE_ERROR: { 301 case GST_MESSAGE_ERROR: {
314 GError *err; 302 GError *err = NULL;
315 gchar *debug; 303 gchar *debug = NULL;
316 304
317 llgst_message_parse_error (message, &err, &debug); 305 llgst_message_parse_error (message, &err, &debug);
318 llinfos << "GST error: " << err->message << llendl; 306 WARNMSG("GST error: %s", err->message);
319 g_error_free (err); 307 g_error_free (err);
320 g_free (debug); 308 g_free (debug);
321 309
322 impl->setCurrentMode(LLMediaImplGStreamer::ModeError); 310 impl->addCommand(LLMediaBase::COMMAND_STOP);
323
324 impl->stop();
325 311
326 break; 312 break;
327 } 313 }
328 case GST_MESSAGE_INFO: { 314 case GST_MESSAGE_INFO: {
329 if (llgst_message_parse_info) 315 if (llgst_message_parse_info)
330 { 316 {
331 GError *err; 317 GError *err = NULL;
332 gchar *debug; 318 gchar *debug = NULL;
333 319
334 llgst_message_parse_info (message, &err, &debug); 320 llgst_message_parse_info (message, &err, &debug);
335 llinfos << "GST info: " << err->message << llendl; 321 INFOMSG("GST info: %s", err->message);
336 g_error_free (err); 322 g_error_free (err);
337 g_free (debug); 323 g_free (debug);
338 } 324 }
339 break; 325 break;
340 } 326 }
341 case GST_MESSAGE_WARNING: { 327 case GST_MESSAGE_WARNING: {
342 GError *err; 328 GError *err = NULL;
343 gchar *debug; 329 gchar *debug = NULL;
344 330
345 llgst_message_parse_warning (message, &err, &debug); 331 llgst_message_parse_warning (message, &err, &debug);
346 llinfos << "GST warning: " << err->message << llendl; 332 WARNMSG("GST warning: %s", err->message);
347 g_error_free (err); 333 g_error_free (err);
348 g_free (debug); 334 g_free (debug);
349 335
@@ -351,9 +337,18 @@ my_bus_callback (GstBus *bus,
351 } 337 }
352 case GST_MESSAGE_EOS: 338 case GST_MESSAGE_EOS:
353 /* end-of-stream */ 339 /* end-of-stream */
354 llinfos << "GST EOS." << llendl; 340 DEBUGMSG("GST end-of-stream.");
355 impl->setCurrentMode(LLMediaImplGStreamer::ModeStopped);//? 341 if (impl->isLooping())
356 impl->stop(); 342 {
343 DEBUGMSG("looping media...");
344 impl->stop();
345 impl->play();
346 }
347 else
348 {
349 // inject a COMMAND_STOP
350 impl->addCommand(LLMediaBase::COMMAND_STOP);
351 }
357 break; 352 break;
358 default: 353 default:
359 /* unhandled message */ 354 /* unhandled message */
@@ -361,52 +356,57 @@ my_bus_callback (GstBus *bus,
361 } 356 }
362 357
363 /* we want to be notified again the next time there is a message 358 /* we want to be notified again the next time there is a message
364 * on the bus, so returning TRUE (FALSE means we want to stop watching 359 * on the bus, so return true (false means we want to stop watching
365 * for messages on the bus and our callback should not be called again) 360 * for messages on the bus and our callback should not be called again)
366 */ 361 */
367 return TRUE; 362 return TRUE;
368} 363}
369 364
370BOOL 365///////////////////////////////////////////////////////////
366// virtual
367bool
371LLMediaImplGStreamer:: 368LLMediaImplGStreamer::
372load ( const LLString& urlIn ) 369navigateTo ( const std::string urlIn )
373{ 370{
374 llinfos << "Setting media URI: " << urlIn << llendl; 371 DEBUGMSG("Setting media URI: %s", urlIn.c_str());
372
373 if (NULL == mPump
374#ifdef LL_GST_SOUNDSINK
375 || NULL == mAudioSink
376#endif
377 || NULL == mPlaybin)
378 {
379 return false;
380 }
381
382 setStatus( LLMediaBase::STATUS_NAVIGATING );
375 383
376 // set URI 384 // set URI
377 g_object_set (G_OBJECT (mPlaybin), "uri", urlIn.c_str(), NULL); 385 g_object_set (G_OBJECT (mPlaybin), "uri", urlIn.c_str(), NULL);
378 //g_object_set (G_OBJECT (mPlaybin), "uri", "file:///tmp/movie", NULL); 386 //g_object_set (G_OBJECT (mPlaybin), "uri", "file:///tmp/movie", NULL);
379 387
380 // get playbin's bus - perhaps this can/should be done at init() 388 // get playbin's bus - perhaps this can/should be done in ctor
381 GstBus *bus = llgst_pipeline_get_bus (GST_PIPELINE (mPlaybin)); 389 GstBus *bus = llgst_pipeline_get_bus (GST_PIPELINE (mPlaybin));
382 if (!bus) 390 if (!bus)
383 { 391 {
384 return FALSE; 392 return false;
385 } 393 }
386 llgst_bus_add_watch (bus, my_bus_callback, this); 394 llgst_bus_add_watch (bus, bus_callback, this);
387 llgst_object_unref (bus); 395 llgst_object_unref (bus);
388 396
389 if (true) // dummy values 397 // navigateTo implicitly plays, too.
390 { 398 play();
391 const int fixedsize = 2;
392 mMediaRowbytes = mMediaDepthBytes * fixedsize;
393 mMediaWidth = fixedsize;
394 mMediaHeight = fixedsize;
395 mTextureWidth = fixedsize;
396 mTextureHeight = fixedsize;
397 }
398 399
399 BOOL rtn = LLMediaMovieBase::load(urlIn); 400 return true;
400 llinfos << "load returns " << int(rtn) << llendl;
401 return rtn;
402} 401}
403 402
404/////////////////////////////////////////////////////////////////////////////// 403///////////////////////////////////////////////////////////////////////////////
405// 404//
406BOOL 405bool
407LLMediaImplGStreamer:: 406LLMediaImplGStreamer::
408unload () 407unload ()
409{ 408{
409 DEBUGMSG("unloading media...");
410 if (mPlaybin) 410 if (mPlaybin)
411 { 411 {
412 llgst_element_set_state (mPlaybin, GST_STATE_NULL); 412 llgst_element_set_state (mPlaybin, GST_STATE_NULL);
@@ -422,25 +422,75 @@ unload ()
422 422
423 if (mediaData) 423 if (mediaData)
424 { 424 {
425 if (ownBuffer) 425 delete mediaData;
426 { 426 mediaData = NULL;
427 delete mediaData;
428 mediaData = NULL;
429 }
430 } 427 }
431 428
432 mVideoSink = NULL; 429 mVideoSink = NULL;
433 430
434 return TRUE; 431 return true;
435} 432}
436 433
437/////////////////////////////////////////////////////////////////////////////// 434///////////////////////////////////////////////////////////////////////////////
438// 435// virtual
439S32 436bool
440LLMediaImplGStreamer:: 437LLMediaImplGStreamer::
441updateMedia () 438updateMedia ()
442{ 439{
443 //llinfos << "updating media..." << llendl; 440 DEBUGMSG("updating media...");
441
442 // sanity check
443 if (NULL == mPump
444#ifdef LL_GST_SOUNDSINK
445 || NULL == mAudioSink
446#endif
447 || NULL == mPlaybin)
448 {
449 DEBUGMSG("dead media...");
450 return false;
451 }
452
453 // process next outstanding command
454 switch (nextCommand())
455 {
456 case LLMediaBase::COMMAND_START:
457 DEBUGMSG("COMMAND_START");
458 if (getStatus() == LLMediaBase::STATUS_PAUSED ||
459 getStatus() == LLMediaBase::STATUS_NAVIGATING ||
460 getStatus() == LLMediaBase::STATUS_STOPPED)
461 {
462 DEBUGMSG("doing COMMAND_START");
463 play();
464 setStatus(LLMediaBase::STATUS_STARTED);
465 clearCommand();
466 }
467 break;
468 case LLMediaBase::COMMAND_STOP:
469 DEBUGMSG("COMMAND_STOP");
470 DEBUGMSG("doing COMMAND_STOP");
471 stop();
472 setStatus(LLMediaBase::STATUS_STOPPED);
473 clearCommand();
474 break;
475 case LLMediaBase::COMMAND_PAUSE:
476 DEBUGMSG("COMMAND_PAUSE");
477 if (getStatus() == LLMediaBase::STATUS_STARTED)
478 {
479 DEBUGMSG("doing COMMAND_PAUSE");
480 pause();
481 setStatus(LLMediaBase::STATUS_PAUSED);
482 clearCommand();
483 }
484 break;
485 default:
486 DEBUGMSG("COMMAND_?");
487 clearCommand();
488 break;
489 case LLMediaBase::COMMAND_NONE:
490 break;
491 }
492
493 // deal with results
444 if (g_main_context_pending(g_main_loop_get_context(mPump))) 494 if (g_main_context_pending(g_main_loop_get_context(mPump)))
445 { 495 {
446 g_main_context_iteration(g_main_loop_get_context(mPump), FALSE); 496 g_main_context_iteration(g_main_loop_get_context(mPump), FALSE);
@@ -451,269 +501,121 @@ updateMedia ()
451 GST_OBJECT_LOCK(mVideoSink); 501 GST_OBJECT_LOCK(mVideoSink);
452 if (mVideoSink->retained_frame_ready) 502 if (mVideoSink->retained_frame_ready)
453 { 503 {
454 //llinfos << "NEW FRAME " << llendl; 504 DEBUGMSG("NEW FRAME ");
455 if (mVideoSink->retained_frame_width != mMediaWidth || 505 if (mVideoSink->retained_frame_width != getMediaWidth() ||
456 mVideoSink->retained_frame_height != mMediaHeight) 506 mVideoSink->retained_frame_height != getMediaHeight())
457 // *TODO: also check for change in format 507 // *TODO: also check for change in format
458 { 508 {
459 // just resize container 509 // just resize containe
460 mMediaWidth = mVideoSink->retained_frame_width; 510 int neww = mVideoSink->retained_frame_width;
461 mMediaHeight = mVideoSink->retained_frame_height; 511 int newh = mVideoSink->retained_frame_height;
462 mTextureWidth = mMediaWidth; 512 int newd = SLVPixelFormatBytes[mVideoSink->retained_frame_format];
463 mTextureHeight = mMediaHeight;
464 mMediaDepthBytes = mTextureDepth =
465 SLVPixelFormatBytes[mVideoSink->retained_frame_format];
466 if (SLV_PF_RGBX == mVideoSink->retained_frame_format) 513 if (SLV_PF_RGBX == mVideoSink->retained_frame_format)
467 { 514 {
468 mTextureFormatPrimary = GL_RGBA; 515 mTextureFormatPrimary = LL_MEDIA_RGBA;
469 mTextureFormatType=GL_UNSIGNED_INT_8_8_8_8_REV; 516 mTextureFormatType = LL_MEDIA_UNSIGNED_INT_8_8_8_8_REV;
470 } 517 }
471 else 518 else
472 { 519 {
473 mTextureFormatPrimary = GL_BGRA; 520 mTextureFormatPrimary = LL_MEDIA_BGRA;
474 mTextureFormatType=GL_UNSIGNED_INT_8_8_8_8_REV; 521 mTextureFormatType = LL_MEDIA_UNSIGNED_INT_8_8_8_8_REV;
475 } 522 }
476 mMediaRowbytes = mMediaWidth * mMediaDepthBytes; 523 mMediaRowbytes = neww * newd;
477 llinfos << "video container resized to " << 524 DEBUGMSG("video container resized to %dx%d",
478 mMediaWidth << "x" << mMediaHeight << llendl; 525 neww, newh);
479 526
480 if (ownBuffer) 527 delete[] mediaData;
481 { 528 mediaData = new unsigned char[mMediaRowbytes *
482 // we manage the buffer, so we need to realloc 529 newh];
483 delete[] mediaData;
484 mediaData = new U8[mMediaRowbytes *
485 mMediaHeight];
486 }
487 530
488 GST_OBJECT_UNLOCK(mVideoSink); 531 GST_OBJECT_UNLOCK(mVideoSink);
489 return updateMediaNeedsSizeChange; 532
533 setMediaDepth(newd);
534 setMediaSize(neww, newh);
535 return true;
490 } 536 }
491 537
492 // we're gonna totally consume this frame - reset 'ready' flag 538 // we're gonna totally consume this frame - reset 'ready' flag
493 mVideoSink->retained_frame_ready = FALSE; 539 mVideoSink->retained_frame_ready = FALSE;
494 memcpy(mediaData, mVideoSink->retained_frame_data, 540 memcpy(mediaData, mVideoSink->retained_frame_data,
495 mMediaRowbytes * mMediaHeight); 541 mMediaRowbytes * getMediaHeight());
496 542
497 GST_OBJECT_UNLOCK(mVideoSink); 543 GST_OBJECT_UNLOCK(mVideoSink);
498 return updateMediaNeedsUpdate; 544 LLMediaEvent event( this );
545 mEventEmitter.update( &LLMediaObserver::onMediaContentsChange, event );
546 return true;
499 } 547 }
500 else 548 else
501 { 549 {
502 // nothing to do yet. 550 // nothing to do yet.
503 GST_OBJECT_UNLOCK(mVideoSink); 551 GST_OBJECT_UNLOCK(mVideoSink);
504 return updateMediaNoChanges; 552 return true;
505 } 553 }
506 } 554 }
507 555
508 return updateMediaNoChanges; 556 return true;
509}
510
511///////////////////////////////////////////////////////////////////////////////
512//
513void
514LLMediaImplGStreamer::
515setAutoScaled ( BOOL autoScaledIn )
516{
517 autoScaled = autoScaledIn;
518} 557}
519 558
520/////////////////////////////////////////////////////////////////////////////// 559///////////////////////////////////////////////////////////////////////////////
521// 560//
522BOOL 561bool
523LLMediaImplGStreamer:: 562LLMediaImplGStreamer::
524stop () 563stop ()
525{ 564{
526 llinfos << "stopping media..." << llendl; 565 DEBUGMSG("stopping media...");
527 // todo: error-check this? 566 // todo: error-check this?
528 llgst_element_set_state(mPlaybin, GST_STATE_READY); 567 llgst_element_set_state(mPlaybin, GST_STATE_READY);
529 568 return true;
530 BOOL rtn = LLMediaMovieBase::stop();
531 setCurrentMode(LLMediaImplGStreamer::ModeStopped);//?
532 return rtn;
533} 569}
534 570
535/////////////////////////////////////////////////////////////////////////////// 571///////////////////////////////////////////////////////////////////////////////
536// 572//
537BOOL 573bool
538LLMediaImplGStreamer:: 574LLMediaImplGStreamer::
539play () 575play ()
540{ 576{
541 llinfos << "playing media..." << llendl; 577 DEBUGMSG("playing media...");
542 // todo: error-check this? 578 // todo: error-check this?
543 llgst_element_set_state(mPlaybin, GST_STATE_PLAYING); 579 llgst_element_set_state(mPlaybin, GST_STATE_PLAYING);
544 580 return true;
545 return LLMediaMovieBase::play();
546} 581}
547 582
548/////////////////////////////////////////////////////////////////////////////// 583///////////////////////////////////////////////////////////////////////////////
549// 584//
550BOOL 585bool
551LLMediaImplGStreamer::
552loop ( S32 howMany )
553{
554 llinfos << "looping media... " << howMany << llendl;
555 // todo: implement this
556 if (!play())
557 return FALSE;
558
559 return LLMediaMovieBase::loop(howMany);
560};
561
562///////////////////////////////////////////////////////////////////////////////
563//
564BOOL
565LLMediaImplGStreamer:: 586LLMediaImplGStreamer::
566pause () 587pause ()
567{ 588{
568 llinfos << "pausing media..." << llendl; 589 DEBUGMSG("pausing media...");
569 // todo: error-check this? 590 // todo: error-check this?
570 llgst_element_set_state(mPlaybin, GST_STATE_PAUSED); 591 llgst_element_set_state(mPlaybin, GST_STATE_PAUSED);
571 592 return true;
572 return LLMediaMovieBase::pause();
573}; 593};
574 594
575///////////////////////////////////////////////////////////////////////////////
576//
577BOOL
578LLMediaImplGStreamer::
579setVolume ( F32 volumeIn )
580{
581 mVolume = volumeIn;
582 g_object_set(mPlaybin, "volume", mVolume, NULL);
583 return TRUE;
584}
585 595
586/////////////////////////////////////////////////////////////////////////////// 596///////////////////////////////////////////////////////////////////////////////
587// 597// virtual
588F32 598unsigned char*
589LLMediaImplGStreamer::
590getVolume ()
591{
592 return mVolume;
593}
594
595///////////////////////////////////////////////////////////////////////////////
596//
597BOOL
598LLMediaImplGStreamer::
599isIdle () const
600{
601 // todo: probably semantically decouple from currentMode
602 return currentMode == ModeIdle;
603}
604
605///////////////////////////////////////////////////////////////////////////////
606//
607BOOL
608LLMediaImplGStreamer::
609isError () const
610{
611 // todo: probably semantically decouple from currentMode
612 return currentMode == ModeError;
613}
614
615///////////////////////////////////////////////////////////////////////////////
616//
617BOOL
618LLMediaImplGStreamer::
619isBuffering () const
620{
621 // todo: probably semantically decouple from currentMode
622 return currentMode == ModeBuffering;
623}
624
625///////////////////////////////////////////////////////////////////////////////
626//
627BOOL
628LLMediaImplGStreamer::
629isLoaded () const
630{
631 // todo: probably semantically decouple from currentMode
632 //return currentMode == ModeLoaded;
633 return (mPump != NULL);
634}
635
636///////////////////////////////////////////////////////////////////////////////
637//
638BOOL
639LLMediaImplGStreamer::
640isPlaying () const
641{
642 // todo: probably semantically decouple from currentMode
643 return currentMode == ModePlaying;
644}
645
646///////////////////////////////////////////////////////////////////////////////
647//
648BOOL
649LLMediaImplGStreamer::
650isLooping () const
651{
652 // todo: probably semantically decouple from currentMode
653 return currentMode == ModeLooping;
654}
655
656///////////////////////////////////////////////////////////////////////////////
657//
658BOOL
659LLMediaImplGStreamer::
660isPaused () const
661{
662 // todo: probably semantically decouple from currentMode
663 return currentMode == ModePaused;
664}
665
666///////////////////////////////////////////////////////////////////////////////
667//
668BOOL
669LLMediaImplGStreamer::
670isStopped () const
671{
672 // todo: probably semantically decouple from currentMode
673 return currentMode == ModeStopped;
674}
675
676///////////////////////////////////////////////////////////////////////////////
677//
678U8*
679LLMediaImplGStreamer:: 599LLMediaImplGStreamer::
680getMediaData () 600getMediaData ()
681{ 601{
682 return mediaData; 602 return mediaData;
683} 603}
684 604
685///////////////////////////////////////////////////////////////////////////////
686//
687BOOL
688LLMediaImplGStreamer::
689seek ( F64 time )
690{
691 // todo: implement this
692 llinfos << "Tried to seek to time " << time
693 << " - faking it" << llendl;
694 return TRUE;
695}
696
697///////////////////////////////////////////////////////////////////////////////
698//
699F64
700LLMediaImplGStreamer::
701getTime () const
702{
703 // todo: implement this
704 F64 result = 0;
705 return result;
706}
707 605
708/////////////////////////////////////////////////////////////////////////////// 606///////////////////////////////////////////////////////////////////////////////
709// 607// virtual
710F64 608bool
711LLMediaImplGStreamer:: 609LLMediaImplGStreamer::
712getMediaDuration () const 610setVolume(float volume)
713{ 611{
714 // todo: implement this 612 mVolume = volume;
715 F64 result = 0; 613 if (mPlaybin)
716 return result; 614 {
615 g_object_set(mPlaybin, "volume", mVolume, NULL);
616 return true;
617 }
618 return false;
717} 619}
718 620
719#endif // LL_GSTREAMER_ENABLED 621#endif // LL_GSTREAMER_ENABLED