1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include "mediawindowbase_impl.hxx"
29 #include <avmedia/mediaitem.hxx>
30 #include "mediamisc.hxx"
31 #include "mediawindow.hrc"
32 #include <tools/urlobj.hxx>
33 #include <comphelper/processfactory.hxx>
34 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
35 #include <com/sun/star/media/XManager.hpp>
36 #ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HDL_
37 #include <com/sun/star/lang/XComponent.hdl>
38 #endif
39 
40 #define MEDIA_TIMER_TIMEOUT 100
41 
42 using namespace ::com::sun::star;
43 
44 namespace avmedia { namespace priv {
45 
46 // -----------------------
47 // - MediaWindowBaseImpl -
48 // -----------------------
49 
50 struct ServiceManager
51 {
52 	const char* pServiceName;
53     sal_Bool    bIsJavaBased;
54 };
55 
56 // ---------------------------------------------------------------------
57 
58 
59 MediaWindowBaseImpl::MediaWindowBaseImpl( MediaWindow* pMediaWindow ) :
60     mpMediaWindow( pMediaWindow ),
61     mbIsMediaWindowJavaBased( sal_False )
62 {
63 }
64 
65 // ---------------------------------------------------------------------
66 
67 MediaWindowBaseImpl::~MediaWindowBaseImpl()
68 {
69     uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
70 }
71 
72 // -------------------------------------------------------------------------
73 
74 uno::Reference< media::XPlayer > MediaWindowBaseImpl::createPlayer( const ::rtl::OUString& rURL, sal_Bool& rbJavaBased )
75 {
76     uno::Reference< lang::XMultiServiceFactory >    xFactory( ::comphelper::getProcessServiceFactory() );
77     uno::Reference< media::XPlayer >                xPlayer;
78 
79     rbJavaBased = sal_False;
80 
81     if( xFactory.is() )
82     {
83         static const ServiceManager aServiceManagers[] =
84         {
85             { AVMEDIA_MANAGER_SERVICE_NAME, AVMEDIA_MANAGER_SERVICE_IS_JAVABASED },
86             { AVMEDIA_MANAGER_SERVICE_NAME_FALLBACK1, AVMEDIA_MANAGER_SERVICE_IS_JAVABASED_FALLBACK1 }
87         };
88 
89         for( sal_uInt32 i = 0; !xPlayer.is() && ( i < ( sizeof( aServiceManagers ) / sizeof( ServiceManager ) ) ); ++i )
90         {
91             const String aServiceName( aServiceManagers[ i ].pServiceName, RTL_TEXTENCODING_ASCII_US );
92 
93             if( aServiceName.Len() )
94             {
95                 OSL_TRACE( "Trying to create media manager service %s", aServiceManagers[ i ].pServiceName );
96 
97                 try
98                 {
99                     uno::Reference< media::XManager > xManager( xFactory->createInstance( aServiceName ), uno::UNO_QUERY );
100 
101                     if( xManager.is() )
102                     {
103                         xPlayer = uno::Reference< media::XPlayer >( xManager->createPlayer( rURL ), uno::UNO_QUERY );
104                     }
105                 }
106                 catch( ... )
107                 {
108                 }
109             }
110 
111             if( xPlayer.is() )
112             {
113                 rbJavaBased = aServiceManagers[ i ].bIsJavaBased;
114             }
115         }
116     }
117 
118     return xPlayer;
119 }
120 
121 // ---------------------------------------------------------------------
122 
123 void MediaWindowBaseImpl::setURL( const ::rtl::OUString& rURL )
124 {
125     if( rURL != getURL() )
126     {
127         INetURLObject aURL( maFileURL = rURL );
128 
129         if( mxPlayer.is() )
130             mxPlayer->stop();
131 
132         if( mxPlayerWindow.is() )
133         {
134             mxPlayerWindow->setVisible( false );
135             mxPlayerWindow.clear();
136         }
137 
138         mxPlayer.clear();
139 
140         if( aURL.GetProtocol() != INET_PROT_NOT_VALID )
141             maFileURL = aURL.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
142 
143         mxPlayer = createPlayer( maFileURL, mbIsMediaWindowJavaBased );
144         onURLChanged();
145     }
146 }
147 
148 // ---------------------------------------------------------------------
149 
150 void MediaWindowBaseImpl::onURLChanged()
151 {
152 }
153 
154 // ---------------------------------------------------------------------
155 
156 const ::rtl::OUString& MediaWindowBaseImpl::getURL() const
157 {
158     return maFileURL;
159 }
160 
161 // ---------------------------------------------------------------------
162 
163 bool MediaWindowBaseImpl::isValid() const
164 {
165     return( getPlayer().is() );
166 }
167 
168 // ---------------------------------------------------------------------
169 
170 void MediaWindowBaseImpl::stopPlayingInternal( bool bStop )
171 {
172     if( isPlaying() )
173     {
174         bStop ? mxPlayer->stop() : mxPlayer->start();
175     }
176 }
177 
178 // ---------------------------------------------------------------------
179 
180 MediaWindow* MediaWindowBaseImpl::getMediaWindow() const
181 {
182     return mpMediaWindow;
183 }
184 
185 // ---------------------------------------------------------------------
186 
187 uno::Reference< media::XPlayer > MediaWindowBaseImpl::getPlayer() const
188 {
189     return mxPlayer;
190 }
191 
192 // ---------------------------------------------------------------------
193 
194 uno::Reference< media::XPlayerWindow > MediaWindowBaseImpl::getPlayerWindow() const
195 {
196     return mxPlayerWindow;
197 }
198 
199 // ---------------------------------------------------------------------
200 
201 void MediaWindowBaseImpl::setPlayerWindow( const uno::Reference< media::XPlayerWindow >& rxPlayerWindow )
202 {
203     mxPlayerWindow = rxPlayerWindow;
204 }
205 
206 // ---------------------------------------------------------------------
207 
208 void MediaWindowBaseImpl::cleanUp()
209 {
210     uno::Reference< lang::XComponent > xComponent( mxPlayer, uno::UNO_QUERY );
211     if( xComponent.is() ) // this stops the player
212         xComponent->dispose();
213 
214     mxPlayer.clear();
215 
216     mpMediaWindow = NULL;
217 }
218 
219 // ---------------------------------------------------------------------
220 
221 bool MediaWindowBaseImpl::hasPreferredSize() const
222 {
223     return( mxPlayerWindow.is() );
224 }
225 
226 // ---------------------------------------------------------------------
227 
228 Size MediaWindowBaseImpl::getPreferredSize() const
229 {
230     Size aRet;
231 
232     if( mxPlayer.is() )
233     {
234         awt::Size aPrefSize( mxPlayer->getPreferredPlayerWindowSize() );
235 
236         aRet.Width() = aPrefSize.Width;
237         aRet.Height() = aPrefSize.Height;
238     }
239 
240     return aRet;
241 }
242 
243 // ---------------------------------------------------------------------
244 
245 bool MediaWindowBaseImpl::setZoom( ::com::sun::star::media::ZoomLevel eLevel )
246 {
247     return( mxPlayerWindow.is() ? mxPlayerWindow->setZoomLevel( eLevel ) : false );
248 }
249 
250 // -------------------------------------------------------------------------
251 
252 ::com::sun::star::media::ZoomLevel MediaWindowBaseImpl::getZoom() const
253 {
254     return( mxPlayerWindow.is() ? mxPlayerWindow->getZoomLevel() : ::com::sun::star::media::ZoomLevel_NOT_AVAILABLE );
255 }
256 
257 // ---------------------------------------------------------------------
258 
259 bool MediaWindowBaseImpl::start()
260 {
261     return( mxPlayer.is() ? ( mxPlayer->start(), true ) : false );
262 }
263 
264 // ---------------------------------------------------------------------
265 
266 void MediaWindowBaseImpl::stop()
267 {
268     if( mxPlayer.is() )
269         mxPlayer->stop();
270 }
271 
272 // ---------------------------------------------------------------------
273 
274 bool MediaWindowBaseImpl::isPlaying() const
275 {
276     return( mxPlayer.is() && mxPlayer->isPlaying() );
277 }
278 
279 // ---------------------------------------------------------------------
280 
281 double MediaWindowBaseImpl::getDuration() const
282 {
283     return( mxPlayer.is() ? mxPlayer->getDuration() : 0.0 );
284 }
285 
286 // ---------------------------------------------------------------------
287 
288 void MediaWindowBaseImpl::setMediaTime( double fTime )
289 {
290     if( mxPlayer.is() )
291         mxPlayer->setMediaTime( fTime );
292 }
293 
294 // ---------------------------------------------------------------------
295 
296 double MediaWindowBaseImpl::getMediaTime() const
297 {
298     return( mxPlayer.is() ? mxPlayer->getMediaTime() : 0.0 );
299 }
300 
301 // ---------------------------------------------------------------------
302 
303 void MediaWindowBaseImpl::setStopTime( double fTime )
304 {
305     if( mxPlayer.is() )
306         mxPlayer->setStopTime( fTime );
307 }
308 
309 // ---------------------------------------------------------------------
310 
311 double MediaWindowBaseImpl::getStopTime() const
312 {
313     return( mxPlayer.is() ? mxPlayer->getStopTime() : 0.0 );
314 }
315 
316 // ---------------------------------------------------------------------
317 
318 void MediaWindowBaseImpl::setRate( double fRate )
319 {
320     if( mxPlayer.is() )
321         mxPlayer->setRate( fRate );
322 }
323 
324 // ---------------------------------------------------------------------
325 
326 double MediaWindowBaseImpl::getRate() const
327 {
328     return( mxPlayer.is() ? mxPlayer->getRate() : 0.0 );
329 }
330 
331 // ---------------------------------------------------------------------
332 
333 void MediaWindowBaseImpl::setPlaybackLoop( bool bSet )
334 {
335     if( mxPlayer.is() )
336         mxPlayer->setPlaybackLoop( bSet );
337 }
338 
339 // ---------------------------------------------------------------------
340 
341 bool MediaWindowBaseImpl::isPlaybackLoop() const
342 {
343     return( mxPlayer.is() ? mxPlayer->isPlaybackLoop() : false );
344 }
345 
346 // ---------------------------------------------------------------------
347 
348 void MediaWindowBaseImpl::setMute( bool bSet )
349 {
350     if( mxPlayer.is() )
351         mxPlayer->setMute( bSet );
352 }
353 
354 // ---------------------------------------------------------------------
355 
356 bool MediaWindowBaseImpl::isMute() const
357 {
358     return( mxPlayer.is() ? mxPlayer->isMute() : false );
359 }
360 
361 // ---------------------------------------------------------------------
362 
363 void MediaWindowBaseImpl::setVolumeDB( sal_Int16 nVolumeDB )
364 {
365     if( mxPlayer.is() )
366         mxPlayer->setVolumeDB( nVolumeDB );
367 }
368 
369 // ---------------------------------------------------------------------
370 
371 sal_Int16 MediaWindowBaseImpl::getVolumeDB() const
372 {
373     return( mxPlayer.is() ? mxPlayer->getVolumeDB() : 0 );
374 }
375 
376 // -------------------------------------------------------------------------
377 
378 void MediaWindowBaseImpl::updateMediaItem( MediaItem& rItem ) const
379 {
380     if( isPlaying() )
381         rItem.setState( ( getRate() > 1.0 ) ? MEDIASTATE_PLAYFFW : MEDIASTATE_PLAY );
382     else
383         rItem.setState( ( 0.0 == getMediaTime() ) ? MEDIASTATE_STOP : MEDIASTATE_PAUSE );
384 
385     rItem.setDuration( getDuration() );
386     rItem.setTime( getMediaTime() );
387     rItem.setLoop( isPlaybackLoop() );
388     rItem.setMute( isMute() );
389     rItem.setVolumeDB( getVolumeDB() );
390     rItem.setZoom( getZoom() );
391     rItem.setURL( getURL() );
392 }
393 
394 // -------------------------------------------------------------------------
395 
396 void MediaWindowBaseImpl::executeMediaItem( const MediaItem& rItem )
397 {
398     const sal_uInt32 nMaskSet = rItem.getMaskSet();
399 
400     // set URL first
401     if( nMaskSet & AVMEDIA_SETMASK_URL )
402         setURL( rItem.getURL() );
403 
404     // set different states next
405     if( nMaskSet & AVMEDIA_SETMASK_TIME )
406         setMediaTime( ::std::min( rItem.getTime(), getDuration() ) );
407 
408     if( nMaskSet & AVMEDIA_SETMASK_LOOP )
409         setPlaybackLoop( rItem.isLoop() );
410 
411     if( nMaskSet & AVMEDIA_SETMASK_MUTE )
412         setMute( rItem.isMute() );
413 
414     if( nMaskSet & AVMEDIA_SETMASK_VOLUMEDB )
415         setVolumeDB( rItem.getVolumeDB() );
416 
417     if( nMaskSet & AVMEDIA_SETMASK_ZOOM )
418         setZoom( rItem.getZoom() );
419 
420     // set play state at last
421     if( nMaskSet & AVMEDIA_SETMASK_STATE )
422     {
423         switch( rItem.getState() )
424         {
425             case( MEDIASTATE_PLAY ):
426             case( MEDIASTATE_PLAYFFW ):
427             {
428 /*
429                 const double fNewRate = ( ( MEDIASTATE_PLAYFFW == rItem.getState() ) ? AVMEDIA_FFW_PLAYRATE : 1.0 );
430 
431                 if( getRate() != fNewRate )
432                     setRate( fNewRate );
433 */
434                 if( !isPlaying() )
435                     start();
436             }
437             break;
438 
439             case( MEDIASTATE_PAUSE ):
440             {
441                 if( isPlaying() )
442                     stop();
443             }
444             break;
445 
446             case( MEDIASTATE_STOP ):
447             {
448                 if( isPlaying() )
449                 {
450                     setMediaTime( 0.0 );
451                     stop();
452                     setMediaTime( 0.0 );
453                 }
454             }
455             break;
456         }
457     }
458 }
459 
460 } // namespace priv
461 } // namespace avemdia
462