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