Version 4.0.0.1, tag libreoffice-4.0.0.1
[LibreOffice.git] / avmedia / source / quicktime / player.mm
blobfb1f9581ef3d005655515803e3a95774bf8402d4
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  */
20 #include <math.h>
22 #include "player.hxx"
23 #include "framegrabber.hxx"
24 #include "window.hxx"
26 using namespace ::com::sun::star;
28 namespace avmedia { namespace quicktime {
30 // ----------------
31 // - Player -
32 // ----------------
34 Player::Player( const uno::Reference< lang::XMultiServiceFactory >& rxMgr ) :
35     mxMgr( rxMgr ),
36     mpMovie( nil ),
37     /* GST
38     mbFakeVideo (sal_False ),
39     */
40     mnUnmutedVolume( 0 ),
41     mnStopTime( DBL_MAX ),  //max double
42     mbMuted( false ),
43     mbInitialized( false ),
44     maSizeCondition( osl_createCondition() )
46     OSErr result;
48     NSApplicationLoad();
49     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
50     // check the version of QuickTime installed
51     long nVersion;
52     result = Gestalt(gestaltQuickTime,&nVersion);
53     if ((result == noErr) && (nVersion >= QT701))
54     {
55       // we have version 7.01 or later, initialize
56       mbInitialized = true;
57     }
58     [pool release];
61 // ------------------------------------------------------------------------------
63 Player::~Player()
65     if( mpMovie )
66     {
67         [mpMovie release];
68         mpMovie = nil;
69     }
71 // ------------------------------------------------------------------------------
73 QTMovie* Player::getMovie()
75     OSL_ASSERT( mpMovie );
76     return mpMovie;
79 // ------------------------------------------------------------------------------
81 bool Player::create( const ::rtl::OUString& rURL )
83     bool    bRet = false;
84     // create the Movie
85     if( mbInitialized )
86     {
87         NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
89         if( mpMovie )
90         {
91             [mpMovie release];
92             mpMovie = nil;
93         }
95         NSString* aNSStr = [[[NSString alloc] initWithCharacters: rURL.getStr() length: rURL.getLength()]stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] ;
96         NSURL* aURL = [NSURL URLWithString:aNSStr ];
98         NSError* pErr = nil;
99         mpMovie = [QTMovie movieWithURL:aURL error:&pErr];
100         if(mpMovie)
101         {
102             [mpMovie retain];
103             maURL = rURL;
104             bRet = true;
105         }
106         if( pErr )
107         {
108             OSL_TRACE( "NSMovie create failed with error %ld (%s)",
109                        (long)[pErr code],
110                        [[pErr localizedDescription] UTF8String]
111                        );
112         }
113         [pool release];
114     }
116     return bRet;
119 // ------------------------------------------------------------------------------
121 void SAL_CALL Player::start(  )
122     throw (uno::RuntimeException)
124   OSL_TRACE ("Player::start");
126   if( mpMovie )
127   {
128       [mpMovie play];
129   }
132 // ------------------------------------------------------------------------------
134 void SAL_CALL Player::stop(  )
135     throw (uno::RuntimeException)
137     OSL_TRACE ("Player::stop");
138     if( mpMovie )
139     {
140         [mpMovie stop];
141     }
144 // ------------------------------------------------------------------------------
146 sal_Bool SAL_CALL Player::isPlaying()
147     throw (uno::RuntimeException)
149     bool bRet = false;
151     if ( mpMovie )
152     {
153         if ([mpMovie rate] != 0)
154         {
155             bRet = true;
156         }
157     }
159     return bRet;
162 // ------------------------------------------------------------------------------
164 double SAL_CALL Player::getDuration(  )
165     throw (uno::RuntimeException)
167     // slideshow checks for non-zero duration, so cheat here
168     double duration = 0.01;
170     if ( mpMovie ) // && mnDuration > 0 ) {
171     {
172         QTTime structDuration =  [mpMovie duration] ;
173         duration = (double)structDuration.timeValue / (double)structDuration.timeScale;
174     }
176     return duration;
179 // ------------------------------------------------------------------------------
181 void SAL_CALL Player::setMediaTime( double fTime )
182     throw (uno::RuntimeException)
184     OSL_TRACE ("Player::setMediaTime");
186     if ( mpMovie )
187     {
188         [mpMovie setCurrentTime: QTMakeTimeWithTimeInterval(fTime)];
189     }
192 // ------------------------------------------------------------------------------
194 double SAL_CALL Player::getMediaTime(  )
195     throw (uno::RuntimeException)
197   double position = 0.0;
199   if ( mpMovie )
200   {
201       QTTime structDuration =  [mpMovie currentTime] ;
202       position = (double)structDuration.timeValue / (double)structDuration.timeScale;
203   }
205   if(isPlaying() && position>mnStopTime)
206   {
207       stop();
208   }
210   return position;
213 // ------------------------------------------------------------------------------
215 double SAL_CALL Player::getRate(  )
216     throw (uno::RuntimeException)
218     // Quicktime: 0 = stop, 1 = normal speed, 2 = double speed, -1 = normal speed backwards
219     double rate = 1.0;
221     OSL_TRACE ("Player::getRate");
223     if ( mpMovie )
224     {
225         rate = (double) [mpMovie rate];
226     }
228     return rate;
231 // ------------------------------------------------------------------------------
233 void SAL_CALL Player::setPlaybackLoop( sal_Bool bSet )
234     throw (uno::RuntimeException)
236     OSL_TRACE ("Player::setPlaybackLoop? %s", bSet?"True":"False" );
238     if(bSet)
239     {
240         [mpMovie setAttribute:[NSNumber numberWithBool:YES] forKey: QTMovieLoopsAttribute]  ;
241     }
242     else
243     {
244          [mpMovie setAttribute:[NSNumber numberWithBool:NO] forKey: QTMovieLoopsAttribute]  ;
245     }
248 // ------------------------------------------------------------------------------
250 sal_Bool SAL_CALL Player::isPlaybackLoop(  )
251     throw (uno::RuntimeException)
253     bool bRet = [[mpMovie attributeForKey:QTMovieLoopsAttribute] boolValue];
255     OSL_TRACE ("Player::isPlaybackLoop ? %s", bRet?"True":"False" );
257     return bRet;
260 // ------------------------------------------------------------------------------
262 void SAL_CALL Player::setMute( sal_Bool bSet )
263     throw (uno::RuntimeException)
265     OSL_TRACE( "set mute: %d muted: %d unmuted volume: %lf", bSet, mbMuted, mnUnmutedVolume );
267     // change the volume to 0 or the unmuted volume
268     if(  mpMovie && mbMuted != bSet )
269     {
270         [mpMovie setMuted: bSet ];
271         mbMuted = bSet;
272     }
276 // ------------------------------------------------------------------------------
278 sal_Bool SAL_CALL Player::isMute(  )
279     throw (uno::RuntimeException)
281     OSL_TRACE ("Player::isMuted");
283     return mbMuted;
286 // ------------------------------------------------------------------------------
288 void SAL_CALL Player::setVolumeDB( sal_Int16 nVolumeDB )
289     throw (uno::RuntimeException)
291     // OOo db volume -40 = QTVolume 0
292     // OOo db volume 0   = QTvolume 1
293     if(nVolumeDB==-40)
294     {
295         mnUnmutedVolume = 0;
296     }
297     else
298     {
299         mnUnmutedVolume = pow( 10.0, nVolumeDB / 20.0 );
300     }
302     OSL_TRACE( "set volume: %d gst volume: %f", nVolumeDB, mnUnmutedVolume );
304     // change volume
305     if( !mbMuted && mpMovie )
306     {
307         [mpMovie setVolume: mnUnmutedVolume ];
308     }
311 // ------------------------------------------------------------------------------
313 sal_Int16 SAL_CALL Player::getVolumeDB(  )
314     throw (uno::RuntimeException)
316     sal_Int16 nVolumeDB = 0.0;
318     if( mpMovie )
319       {
320           float volume = 0.0;
322           volume = [mpMovie volume];
323           if(volume>0)            //protect from log10(0)
324           {
325               nVolumeDB = (sal_Int16) ( 20.0*log10 ( volume ) );
326           }
327           else
328           {
329               nVolumeDB = -40 ;  // QT zero volume is no volume, -40db
330           }
331       }
333     return nVolumeDB;
336 // ------------------------------------------------------------------------------
338 awt::Size SAL_CALL Player::getPreferredPlayerWindowSize(  )
339     throw (uno::RuntimeException)
341     NSSize  nsSize = [[mpMovie attributeForKey:QTMovieNaturalSizeAttribute] sizeValue];
342     awt::Size aSize( nsSize.width, nsSize.height );
343     return aSize;
346 // ------------------------------------------------------------------------------
348 uno::Reference< ::media::XPlayerWindow > SAL_CALL Player::createPlayerWindow( const uno::Sequence< uno::Any >& aArguments )
349     throw (uno::RuntimeException)
351     uno::Reference< ::media::XPlayerWindow >    xRet;
352     awt::Size                                   aSize( getPreferredPlayerWindowSize() );
354     OSL_TRACE( "Player::createPlayerWindow %d %d length: %d", aSize.Width, aSize.Height, aArguments.getLength() );
356     if( aSize.Width > 0 && aSize.Height > 0 )
357     {
358         sal_IntPtr nPtr = 0;
359         aArguments[0] >>= nPtr;
360         NSView* pParentView = reinterpret_cast< NSView * >(nPtr);
362         ::avmedia::quicktime::Window* pWindow = new ::avmedia::quicktime::Window( mxMgr, *this, pParentView );
363         xRet = pWindow;
364     }
366     return xRet;
369 // ------------------------------------------------------------------------------
371 uno::Reference< media::XFrameGrabber > SAL_CALL Player::createFrameGrabber(  )
372     throw (::com::sun::star::uno::RuntimeException)
374   uno::Reference< media::XFrameGrabber > xRet;
375   OSL_TRACE ("Player::createFrameGrabber");
377   if( maURL.getLength() > 0 )
378   {
379       FrameGrabber* pGrabber = new FrameGrabber( mxMgr );
381       xRet = pGrabber;
383       if( !pGrabber->create( maURL ) )
384       {
385           xRet.clear();
386       }
387   }
389   return xRet;
392 // ------------------------------------------------------------------------------
394 ::rtl::OUString SAL_CALL Player::getImplementationName(  )
395     throw (uno::RuntimeException)
397     return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( AVMEDIA_QUICKTIME_PLAYER_IMPLEMENTATIONNAME ) );
400 // ------------------------------------------------------------------------------
402 sal_Bool SAL_CALL Player::supportsService( const ::rtl::OUString& ServiceName )
403     throw (uno::RuntimeException)
405     return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( AVMEDIA_QUICKTIME_PLAYER_SERVICENAME ) );
408 // ------------------------------------------------------------------------------
410 uno::Sequence< ::rtl::OUString > SAL_CALL Player::getSupportedServiceNames(  )
411     throw (uno::RuntimeException)
413     uno::Sequence< ::rtl::OUString > aRet(1);
414     aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( AVMEDIA_QUICKTIME_PLAYER_SERVICENAME ) );
416     return aRet;
419 } // namespace quicktime
420 } // namespace avmedia
422 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */