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