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