Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <math.h>
21 :
22 : #include <rtl/string.hxx>
23 :
24 : #include <vcl/syschild.hxx>
25 : #include <vcl/sysdata.hxx>
26 :
27 : #include "gstplayer.hxx"
28 : #include "gstframegrabber.hxx"
29 : #include "gstwindow.hxx"
30 :
31 : #ifdef AVMEDIA_GST_0_10
32 : # define AVMEDIA_GST_PLAYER_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.Player_GStreamer_0_10"
33 : # define AVMEDIA_GST_PLAYER_SERVICENAME "com.sun.star.media.Player_GStreamer_0_10"
34 : #else
35 : # include <gst/video/videooverlay.h>
36 : # define AVMEDIA_GST_PLAYER_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.Player_GStreamer"
37 : # define AVMEDIA_GST_PLAYER_SERVICENAME "com.sun.star.media.Player_GStreamer"
38 : #endif
39 :
40 : #if !defined DBG
41 : # if OSL_DEBUG_LEVEL > 2
42 : #ifdef AVMEDIA_GST_0_10
43 : # define AVVERSION "gst 0.10: "
44 : #else
45 : # define AVVERSION "gst 1.0: "
46 : #endif
47 : #define DBG(...) do { fprintf (stderr, "%s", AVVERSION); fprintf (stderr, __VA_ARGS__); fprintf (stderr, "\n"); } while (0);
48 : # else
49 : #define DBG(...)
50 : # endif
51 : #endif
52 :
53 : using namespace ::com::sun::star;
54 :
55 : namespace avmedia { namespace gstreamer {
56 :
57 : // ----------------
58 : // - Player -
59 : // ----------------
60 :
61 0 : Player::Player( const uno::Reference< lang::XMultiServiceFactory >& rxMgr ) :
62 : GstPlayer_BASE( m_aMutex ),
63 : mxMgr( rxMgr ),
64 : mpPlaybin( NULL ),
65 : mbFakeVideo (sal_False ),
66 : mnUnmutedVolume( 0 ),
67 : mbPlayPending ( false ),
68 : mbMuted( false ),
69 : mbLooping( false ),
70 : mbInitialized( false ),
71 : mnWindowID( 0 ),
72 : mpXOverlay( NULL ),
73 : mnDuration( 0 ),
74 : mnWidth( 0 ),
75 0 : mnHeight( 0 )
76 : {
77 : // Initialize GStreamer library
78 0 : int argc = 1;
79 0 : char name[] = "libreoffice";
80 0 : char *arguments[] = { name };
81 0 : char** argv = arguments;
82 0 : GError* pError = NULL;
83 :
84 0 : mbInitialized = gst_init_check( &argc, &argv, &pError );
85 :
86 : DBG( "%p Player::Player", this );
87 :
88 0 : if (pError != NULL)
89 : {
90 : // TODO: thow an exception?
91 : DBG( "%p Player::Player error '%s'", this, pError->message );
92 0 : g_error_free (pError);
93 : }
94 0 : }
95 :
96 : // ------------------------------------------------------------------------------
97 :
98 0 : Player::~Player()
99 : {
100 : DBG( "%p Player::~Player", this );
101 0 : if( mbInitialized )
102 0 : disposing();
103 0 : }
104 :
105 0 : void SAL_CALL Player::disposing()
106 : {
107 0 : ::osl::MutexGuard aGuard(m_aMutex);
108 :
109 0 : stop();
110 :
111 : DBG( "%p Player::disposing", this );
112 :
113 : // Release the elements and pipeline
114 0 : if( mbInitialized )
115 : {
116 0 : if( mpPlaybin )
117 : {
118 0 : gst_element_set_state( mpPlaybin, GST_STATE_NULL );
119 0 : g_object_unref( G_OBJECT( mpPlaybin ) );
120 :
121 0 : mpPlaybin = NULL;
122 : }
123 :
124 0 : if( mpXOverlay ) {
125 0 : g_object_unref( G_OBJECT ( mpXOverlay ) );
126 0 : mpXOverlay = NULL;
127 : }
128 0 : }
129 0 : }
130 :
131 : // ------------------------------------------------------------------------------
132 :
133 0 : static gboolean pipeline_bus_callback( GstBus *, GstMessage *message, gpointer data )
134 : {
135 0 : Player* pPlayer = static_cast<Player*>(data);
136 :
137 0 : pPlayer->processMessage( message );
138 :
139 0 : return TRUE;
140 : }
141 :
142 0 : static GstBusSyncReply pipeline_bus_sync_handler( GstBus *, GstMessage * message, gpointer data )
143 : {
144 0 : Player* pPlayer = static_cast<Player*>(data);
145 :
146 0 : return pPlayer->processSyncMessage( message );
147 : }
148 :
149 0 : void Player::processMessage( GstMessage *message )
150 : {
151 0 : switch( GST_MESSAGE_TYPE( message ) ) {
152 : case GST_MESSAGE_EOS:
153 0 : gst_element_set_state( mpPlaybin, GST_STATE_READY );
154 0 : mbPlayPending = false;
155 0 : if (mbLooping)
156 0 : start();
157 0 : break;
158 : case GST_MESSAGE_STATE_CHANGED:
159 0 : if( message->src == GST_OBJECT( mpPlaybin ) ) {
160 : GstState newstate, pendingstate;
161 :
162 0 : gst_message_parse_state_changed (message, NULL, &newstate, &pendingstate);
163 :
164 0 : if( newstate == GST_STATE_PAUSED &&
165 0 : pendingstate == GST_STATE_VOID_PENDING &&
166 : mpXOverlay )
167 0 : gst_video_overlay_expose( mpXOverlay );
168 :
169 0 : if (mbPlayPending)
170 0 : mbPlayPending = ((newstate == GST_STATE_READY) || (newstate == GST_STATE_PAUSED));
171 : }
172 : default:
173 0 : break;
174 : }
175 0 : }
176 :
177 0 : static gboolean wrap_element_query_position (GstElement *element, GstFormat format, gint64 *cur)
178 : {
179 : #ifdef AVMEDIA_GST_0_10
180 0 : GstFormat my_format = format;
181 0 : return gst_element_query_position( element, &my_format, cur) && my_format == format && *cur > 0L;
182 : #else
183 : return gst_element_query_position( element, format, cur );
184 : #endif
185 : }
186 :
187 0 : static gboolean wrap_element_query_duration (GstElement *element, GstFormat format, gint64 *duration)
188 : {
189 : #ifdef AVMEDIA_GST_0_10
190 0 : GstFormat my_format = format;
191 0 : return gst_element_query_duration( element, &my_format, duration) && my_format == format && *duration > 0L;
192 : #else
193 : return gst_element_query_duration( element, format, duration );
194 : #endif
195 : }
196 :
197 0 : GstBusSyncReply Player::processSyncMessage( GstMessage *message )
198 : {
199 : // DBG( "%p processSyncMessage has handle: %s", this, GST_MESSAGE_TYPE_NAME( message ) );
200 :
201 : #if OSL_DEBUG_LEVEL > 0
202 : if ( GST_MESSAGE_TYPE( message ) == GST_MESSAGE_ERROR )
203 : {
204 : GError* error;
205 : gchar* error_debug;
206 :
207 : gst_message_parse_error( message, &error, &error_debug );
208 : SAL_WARN(
209 : "avmedia",
210 : "gstreamer error: '" << error->message << "' debug: '"
211 : << error_debug << "'");
212 : }
213 : #endif
214 :
215 : #ifdef AVMEDIA_GST_0_10
216 0 : if (message->structure &&
217 0 : !strcmp( gst_structure_get_name( message->structure ), "prepare-xwindow-id" ) )
218 : #else
219 : if (gst_is_video_overlay_prepare_window_handle_message (message) )
220 : #endif
221 : {
222 : DBG( "%p processSyncMessage prepare window id: %s %d", this,
223 : GST_MESSAGE_TYPE_NAME( message ), (int)mnWindowID );
224 0 : if( mpXOverlay )
225 0 : g_object_unref( G_OBJECT ( mpXOverlay ) );
226 0 : g_object_set( GST_MESSAGE_SRC( message ), "force-aspect-ratio", FALSE, NULL );
227 0 : mpXOverlay = GST_VIDEO_OVERLAY( GST_MESSAGE_SRC( message ) );
228 0 : g_object_ref( G_OBJECT ( mpXOverlay ) );
229 0 : if ( mnWindowID != 0 )
230 0 : gst_video_overlay_set_window_handle( mpXOverlay, mnWindowID );
231 0 : return GST_BUS_DROP;
232 : }
233 :
234 : #ifdef AVMEDIA_GST_0_10
235 0 : if( GST_MESSAGE_TYPE( message ) == GST_MESSAGE_STATE_CHANGED ) {
236 0 : if( message->src == GST_OBJECT( mpPlaybin ) ) {
237 : GstState newstate, pendingstate;
238 :
239 0 : gst_message_parse_state_changed (message, NULL, &newstate, &pendingstate);
240 :
241 : DBG( "%p state change received, new state %d pending %d", this,
242 : (int)newstate, (int)pendingstate );
243 0 : if( newstate == GST_STATE_PAUSED &&
244 0 : pendingstate == GST_STATE_VOID_PENDING ) {
245 :
246 : DBG( "%p change to paused received", this );
247 :
248 0 : if( mnDuration == 0) {
249 0 : gint64 gst_duration = 0L;
250 0 : if( wrap_element_query_duration( mpPlaybin, GST_FORMAT_TIME, &gst_duration) )
251 0 : mnDuration = gst_duration;
252 : }
253 :
254 0 : if( mnWidth == 0 ) {
255 0 : GList *pStreamInfo = NULL;
256 :
257 0 : g_object_get( G_OBJECT( mpPlaybin ), "stream-info", &pStreamInfo, NULL );
258 :
259 0 : for ( ; pStreamInfo != NULL; pStreamInfo = pStreamInfo->next) {
260 0 : GObject *pInfo = G_OBJECT( pStreamInfo->data );
261 :
262 0 : if( !pInfo )
263 0 : continue;
264 :
265 : int nType;
266 0 : g_object_get( pInfo, "type", &nType, NULL );
267 0 : GEnumValue *pValue = g_enum_get_value( G_PARAM_SPEC_ENUM( g_object_class_find_property( G_OBJECT_GET_CLASS( pInfo ), "type" ) )->enum_class,
268 0 : nType );
269 :
270 0 : if( !g_ascii_strcasecmp( pValue->value_nick, "video" ) ) {
271 : GstStructure *pStructure;
272 : GstPad *pPad;
273 :
274 0 : g_object_get( pInfo, "object", &pPad, NULL );
275 0 : pStructure = gst_caps_get_structure( GST_PAD_CAPS( pPad ), 0 );
276 0 : if( pStructure ) {
277 0 : gst_structure_get_int( pStructure, "width", &mnWidth );
278 0 : gst_structure_get_int( pStructure, "height", &mnHeight );
279 : DBG( "queried size: %d x %d", mnWidth, mnHeight );
280 : }
281 0 : g_object_unref (pPad);
282 : }
283 : }
284 :
285 0 : maSizeCondition.set();
286 : }
287 : }
288 : }
289 : #else
290 : // We get to use the exciting new playbin2 ! (now known as playbin)
291 : if( GST_MESSAGE_TYPE( message ) == GST_MESSAGE_ASYNC_DONE ) {
292 : if( mnDuration == 0) {
293 : gint64 gst_duration = 0L;
294 : if( wrap_element_query_duration( mpPlaybin, GST_FORMAT_TIME, &gst_duration) )
295 : mnDuration = gst_duration;
296 : }
297 : if( mnWidth == 0 ) {
298 : GstPad *pad = NULL;
299 : GstCaps *caps;
300 :
301 : g_signal_emit_by_name( mpPlaybin, "get-video-pad", 0, &pad );
302 :
303 : if( pad ) {
304 : int w = 0, h = 0;
305 :
306 : caps = gst_pad_get_current_caps( pad );
307 :
308 : if( gst_structure_get( gst_caps_get_structure( caps, 0 ),
309 : "width", G_TYPE_INT, &w,
310 : "height", G_TYPE_INT, &h,
311 : NULL ) ) {
312 : mnWidth = w;
313 : mnHeight = h;
314 :
315 : DBG( "queried size: %d x %d", mnWidth, mnHeight );
316 :
317 : maSizeCondition.set();
318 : }
319 : gst_caps_unref( caps );
320 : g_object_unref( pad );
321 : }
322 : }
323 : #endif
324 0 : } else if( GST_MESSAGE_TYPE( message ) == GST_MESSAGE_ERROR ) {
325 : DBG( "Error !\n" );
326 0 : if( mnWidth == 0 ) {
327 : // an error occurred, set condition so that OOo thread doesn't wait for us
328 0 : maSizeCondition.set();
329 : }
330 : }
331 :
332 0 : return GST_BUS_PASS;
333 : }
334 :
335 0 : void Player::preparePlaybin( const OUString& rURL, GstElement *pSink )
336 : {
337 : GstBus *pBus;
338 :
339 0 : if( mpPlaybin != NULL ) {
340 0 : gst_element_set_state( mpPlaybin, GST_STATE_NULL );
341 0 : mbPlayPending = false;
342 0 : g_object_unref( mpPlaybin );
343 : }
344 :
345 0 : mpPlaybin = gst_element_factory_make( "playbin", NULL );
346 0 : if( pSink != NULL ) // used for getting prefered size etc.
347 : {
348 0 : g_object_set( G_OBJECT( mpPlaybin ), "video-sink", pSink, NULL );
349 0 : mbFakeVideo = true;
350 : }
351 : else
352 0 : mbFakeVideo = false;
353 :
354 0 : OString ascURL = OUStringToOString( rURL, RTL_TEXTENCODING_UTF8 );
355 0 : g_object_set( G_OBJECT( mpPlaybin ), "uri", ascURL.getStr() , NULL );
356 :
357 0 : pBus = gst_element_get_bus( mpPlaybin );
358 0 : gst_bus_add_watch( pBus, pipeline_bus_callback, this );
359 : DBG( "%p set sync handler", this );
360 : #ifdef AVMEDIA_GST_0_10
361 0 : gst_bus_set_sync_handler( pBus, pipeline_bus_sync_handler, this );
362 : #else
363 : gst_bus_set_sync_handler( pBus, pipeline_bus_sync_handler, this, NULL );
364 : #endif
365 0 : g_object_unref( pBus );
366 0 : }
367 :
368 0 : bool Player::create( const OUString& rURL )
369 : {
370 0 : bool bRet = false;
371 :
372 : // create all the elements and link them
373 :
374 : DBG("create player, URL: %s", OUStringToOString( rURL, RTL_TEXTENCODING_UTF8 ).getStr());
375 :
376 0 : if( mbInitialized && !rURL.isEmpty() )
377 : {
378 : // fakesink for pre-roll & sizing ...
379 0 : preparePlaybin( rURL, gst_element_factory_make( "fakesink", NULL ) );
380 :
381 0 : gst_element_set_state( mpPlaybin, GST_STATE_PAUSED );
382 0 : mbPlayPending = false;
383 :
384 0 : bRet = true;
385 : }
386 :
387 0 : if( bRet )
388 0 : maURL = rURL;
389 : else
390 0 : maURL = OUString();
391 :
392 0 : return bRet;
393 : }
394 :
395 : // ------------------------------------------------------------------------------
396 :
397 0 : void SAL_CALL Player::start()
398 : throw (uno::RuntimeException)
399 : {
400 0 : ::osl::MutexGuard aGuard(m_aMutex);
401 :
402 : // set the pipeline state to READY and run the loop
403 0 : if( mbInitialized && NULL != mpPlaybin )
404 : {
405 0 : gst_element_set_state( mpPlaybin, GST_STATE_PLAYING );
406 0 : mbPlayPending = true;
407 0 : }
408 0 : }
409 :
410 : // ------------------------------------------------------------------------------
411 :
412 0 : void SAL_CALL Player::stop()
413 : throw (uno::RuntimeException)
414 : {
415 0 : ::osl::MutexGuard aGuard(m_aMutex);
416 :
417 : // set the pipeline in PAUSED STATE
418 0 : if( mpPlaybin )
419 0 : gst_element_set_state( mpPlaybin, GST_STATE_PAUSED );
420 :
421 0 : mbPlayPending = false;
422 0 : DBG( "stop %p", mpPlaybin );
423 0 : }
424 :
425 : // ------------------------------------------------------------------------------
426 :
427 0 : sal_Bool SAL_CALL Player::isPlaying()
428 : throw (uno::RuntimeException)
429 : {
430 0 : ::osl::MutexGuard aGuard(m_aMutex);
431 :
432 0 : bool bRet = mbPlayPending;
433 :
434 : // return whether the pipeline is in PLAYING STATE or not
435 0 : if( !mbPlayPending && mbInitialized && mpPlaybin )
436 : {
437 0 : bRet = GST_STATE_PLAYING == GST_STATE( mpPlaybin );
438 : }
439 :
440 : DBG( "isPlaying %d", bRet );
441 :
442 0 : return bRet;
443 : }
444 :
445 : // ------------------------------------------------------------------------------
446 :
447 0 : double SAL_CALL Player::getDuration()
448 : throw (uno::RuntimeException)
449 : {
450 0 : ::osl::MutexGuard aGuard(m_aMutex);
451 :
452 : // slideshow checks for non-zero duration, so cheat here
453 0 : double duration = 0.01;
454 :
455 0 : if( mpPlaybin && mnDuration > 0 ) {
456 0 : duration = mnDuration / 1E9;
457 : }
458 :
459 0 : return duration;
460 : }
461 :
462 : // ------------------------------------------------------------------------------
463 :
464 0 : void SAL_CALL Player::setMediaTime( double fTime )
465 : throw (uno::RuntimeException)
466 : {
467 0 : ::osl::MutexGuard aGuard(m_aMutex);
468 :
469 0 : if( mpPlaybin ) {
470 0 : gint64 gst_position = llround (fTime * 1E9);
471 :
472 : gst_element_seek( mpPlaybin, 1.0,
473 : GST_FORMAT_TIME,
474 : GST_SEEK_FLAG_FLUSH,
475 : GST_SEEK_TYPE_SET, gst_position,
476 0 : GST_SEEK_TYPE_NONE, 0 );
477 0 : if( !isPlaying() )
478 0 : gst_element_set_state( mpPlaybin, GST_STATE_PAUSED );
479 :
480 : DBG( "seek to: %" SAL_PRIdINT64 " ns original: %lf s", gst_position, fTime );
481 0 : }
482 0 : }
483 :
484 : // ------------------------------------------------------------------------------
485 :
486 0 : double SAL_CALL Player::getMediaTime()
487 : throw (uno::RuntimeException)
488 : {
489 0 : ::osl::MutexGuard aGuard(m_aMutex);
490 :
491 0 : double position = 0.0;
492 :
493 0 : if( mpPlaybin ) {
494 : // get current position in the stream
495 : gint64 gst_position;
496 0 : if( wrap_element_query_position( mpPlaybin, GST_FORMAT_TIME, &gst_position ) )
497 0 : position = gst_position / 1E9;
498 : }
499 :
500 0 : return position;
501 : }
502 :
503 : // ------------------------------------------------------------------------------
504 :
505 0 : double SAL_CALL Player::getRate()
506 : throw (uno::RuntimeException)
507 : {
508 0 : ::osl::MutexGuard aGuard(m_aMutex);
509 :
510 0 : double rate = 1.0;
511 :
512 : // TODO get the window rate - but no need since
513 : // higher levels never set rate > 1
514 :
515 0 : return rate;
516 : }
517 :
518 : // ------------------------------------------------------------------------------
519 :
520 0 : void SAL_CALL Player::setPlaybackLoop( sal_Bool bSet )
521 : throw (uno::RuntimeException)
522 : {
523 0 : ::osl::MutexGuard aGuard(m_aMutex);
524 : // TODO check how to do with GST
525 0 : mbLooping = bSet;
526 0 : }
527 :
528 : // ------------------------------------------------------------------------------
529 :
530 0 : sal_Bool SAL_CALL Player::isPlaybackLoop()
531 : throw (uno::RuntimeException)
532 : {
533 0 : ::osl::MutexGuard aGuard(m_aMutex);
534 : // TODO check how to do with GST
535 0 : return mbLooping;
536 : }
537 :
538 : // ------------------------------------------------------------------------------
539 :
540 0 : void SAL_CALL Player::setMute( sal_Bool bSet )
541 : throw (uno::RuntimeException)
542 : {
543 0 : ::osl::MutexGuard aGuard(m_aMutex);
544 :
545 : DBG( "set mute: %d muted: %d unmuted volume: %lf", bSet, mbMuted, mnUnmutedVolume );
546 :
547 : // change the volume to 0 or the unmuted volume
548 0 : if( mpPlaybin && mbMuted != bSet )
549 : {
550 0 : double nVolume = mnUnmutedVolume;
551 0 : if( bSet )
552 : {
553 0 : nVolume = 0.0;
554 : }
555 :
556 0 : g_object_set( G_OBJECT( mpPlaybin ), "volume", nVolume, NULL );
557 :
558 0 : mbMuted = bSet;
559 0 : }
560 0 : }
561 :
562 : // ------------------------------------------------------------------------------
563 :
564 0 : sal_Bool SAL_CALL Player::isMute()
565 : throw (uno::RuntimeException)
566 : {
567 0 : ::osl::MutexGuard aGuard(m_aMutex);
568 :
569 0 : return mbMuted;
570 : }
571 :
572 : // ------------------------------------------------------------------------------
573 :
574 0 : void SAL_CALL Player::setVolumeDB( sal_Int16 nVolumeDB )
575 : throw (uno::RuntimeException)
576 : {
577 0 : ::osl::MutexGuard aGuard(m_aMutex);
578 :
579 0 : mnUnmutedVolume = pow( 10.0, nVolumeDB / 20.0 );
580 :
581 : DBG( "set volume: %d gst volume: %lf", nVolumeDB, mnUnmutedVolume );
582 :
583 : // change volume
584 0 : if( !mbMuted && mpPlaybin )
585 : {
586 0 : g_object_set( G_OBJECT( mpPlaybin ), "volume", (gdouble) mnUnmutedVolume, NULL );
587 0 : }
588 0 : }
589 :
590 : // ------------------------------------------------------------------------------
591 :
592 0 : sal_Int16 SAL_CALL Player::getVolumeDB()
593 : throw (uno::RuntimeException)
594 : {
595 0 : ::osl::MutexGuard aGuard(m_aMutex);
596 :
597 0 : sal_Int16 nVolumeDB(0);
598 :
599 0 : if( mpPlaybin ) {
600 0 : double nGstVolume = 0.0;
601 :
602 0 : g_object_get( G_OBJECT( mpPlaybin ), "volume", &nGstVolume, NULL );
603 :
604 0 : nVolumeDB = (sal_Int16) ( 20.0*log10 ( nGstVolume ) );
605 : }
606 :
607 0 : return nVolumeDB;
608 : }
609 :
610 : // ------------------------------------------------------------------------------
611 :
612 0 : awt::Size SAL_CALL Player::getPreferredPlayerWindowSize()
613 : throw (uno::RuntimeException)
614 : {
615 0 : ::osl::MutexGuard aGuard(m_aMutex);
616 :
617 0 : awt::Size aSize( 0, 0 );
618 :
619 0 : if( maURL.isEmpty() )
620 : {
621 : DBG( "%p Player::getPreferredPlayerWindowSize - empty URL => 0x0", this );
622 0 : return aSize;
623 : }
624 :
625 : DBG( "%p pre-Player::getPreferredPlayerWindowSize, member %d x %d", this, mnWidth, mnHeight );
626 :
627 0 : TimeValue aTimeout = { 10, 0 };
628 : #if OSL_DEBUG_LEVEL > 2
629 : osl::Condition::Result aResult =
630 : #endif
631 0 : maSizeCondition.wait( &aTimeout );
632 :
633 : DBG( "%p Player::getPreferredPlayerWindowSize after waitCondition %d, member %d x %d", this, aResult, mnWidth, mnHeight );
634 :
635 0 : if( mnWidth != 0 && mnHeight != 0 ) {
636 0 : aSize.Width = mnWidth;
637 0 : aSize.Height = mnHeight;
638 : }
639 :
640 0 : return aSize;
641 : }
642 :
643 : // ------------------------------------------------------------------------------
644 :
645 0 : uno::Reference< ::media::XPlayerWindow > SAL_CALL Player::createPlayerWindow( const uno::Sequence< uno::Any >& rArguments )
646 : throw (uno::RuntimeException)
647 : {
648 0 : ::osl::MutexGuard aGuard(m_aMutex);
649 :
650 0 : uno::Reference< ::media::XPlayerWindow > xRet;
651 0 : awt::Size aSize( getPreferredPlayerWindowSize() );
652 :
653 0 : if( mbFakeVideo )
654 0 : preparePlaybin( maURL, NULL );
655 :
656 : DBG( "Player::createPlayerWindow %d %d length: %d", aSize.Width, aSize.Height, rArguments.getLength() );
657 :
658 0 : if( aSize.Width > 0 && aSize.Height > 0 )
659 : {
660 0 : ::avmedia::gstreamer::Window* pWindow = new ::avmedia::gstreamer::Window( mxMgr, *this );
661 :
662 0 : xRet = pWindow;
663 :
664 0 : if( rArguments.getLength() > 2 )
665 : {
666 0 : sal_IntPtr pIntPtr = 0;
667 0 : rArguments[ 2 ] >>= pIntPtr;
668 0 : SystemChildWindow *pParentWindow = reinterpret_cast< SystemChildWindow* >( pIntPtr );
669 0 : const SystemEnvData* pEnvData = pParentWindow ? pParentWindow->GetSystemData() : NULL;
670 : OSL_ASSERT(pEnvData);
671 0 : if (pEnvData)
672 : {
673 0 : mnWindowID = pEnvData->aWindow;
674 : DBG( "set window id to %d XOverlay %p\n", (int)mnWindowID, mpXOverlay);
675 0 : gst_element_set_state( mpPlaybin, GST_STATE_PAUSED );
676 0 : if ( mpXOverlay != NULL )
677 0 : gst_video_overlay_set_window_handle( mpXOverlay, mnWindowID );
678 : }
679 : }
680 : }
681 :
682 0 : return xRet;
683 : }
684 :
685 : // ------------------------------------------------------------------------------
686 :
687 0 : uno::Reference< media::XFrameGrabber > SAL_CALL Player::createFrameGrabber()
688 : throw (uno::RuntimeException)
689 : {
690 0 : ::osl::MutexGuard aGuard(m_aMutex);
691 0 : FrameGrabber* pFrameGrabber = NULL;
692 0 : const awt::Size aPrefSize( getPreferredPlayerWindowSize() );
693 :
694 0 : if( ( aPrefSize.Width > 0 ) && ( aPrefSize.Height > 0 ) )
695 0 : pFrameGrabber = FrameGrabber::create( maURL );
696 : DBG( "created FrameGrabber %p", pFrameGrabber );
697 :
698 0 : return pFrameGrabber;
699 : }
700 :
701 : // ------------------------------------------------------------------------------
702 :
703 0 : OUString SAL_CALL Player::getImplementationName()
704 : throw (uno::RuntimeException)
705 : {
706 0 : return OUString( AVMEDIA_GST_PLAYER_IMPLEMENTATIONNAME );
707 : }
708 :
709 : // ------------------------------------------------------------------------------
710 :
711 0 : sal_Bool SAL_CALL Player::supportsService( const OUString& ServiceName )
712 : throw (uno::RuntimeException)
713 : {
714 0 : return ServiceName == AVMEDIA_GST_PLAYER_SERVICENAME;
715 : }
716 :
717 : // ------------------------------------------------------------------------------
718 :
719 0 : uno::Sequence< OUString > SAL_CALL Player::getSupportedServiceNames()
720 : throw (uno::RuntimeException)
721 : {
722 0 : uno::Sequence< OUString > aRet(1);
723 0 : aRet[0] = AVMEDIA_GST_PLAYER_SERVICENAME ;
724 :
725 0 : return aRet;
726 : }
727 :
728 : } // namespace gstreamer
729 : } // namespace avmedia
730 :
731 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|