/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ #include #include "qt_player.hxx" #include "qt_framegrabber.hxx" #include "qt_window.hxx" using namespace ::com::sun::star; namespace avmedia { namespace quicktime { // ---------------- // - Player - // ---------------- Player::Player( const uno::Reference< lang::XMultiServiceFactory >& rxMgr ) : mxMgr( rxMgr ), mpMovie( nil ), /* GST mbFakeVideo (sal_False ), */ mnUnmutedVolume( 0 ), mnStopTime( DBL_MAX ), //max double mbMuted( false ), mbLooping( false ), mbInitialized( false ), mnWindowID( 0 ), mnDuration( 0 ), mnWidth( 0 ), mnHeight( 0 ), mnVersion( 0 ), maSizeCondition( osl_createCondition() ) { OSErr result; NSApplicationLoad(); NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; mbInitialized = true; [pool release]; } // ------------------------------------------------------------------------------ Player::~Player() { if( mpMovie ) { [mpMovie release]; mpMovie = nil; } } // ------------------------------------------------------------------------------ QTMovie* Player::getMovie() { OSL_ASSERT( mpMovie ); return mpMovie; } // ------------------------------------------------------------------------------ bool Player::create( const ::rtl::OUString& rURL ) { bool bRet = false; // create the Movie if( mbInitialized ) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; if( mpMovie ) { [mpMovie release]; mpMovie = nil; } NSString* aNSStr = [[[NSString alloc] initWithCharacters: rURL.getStr() length: rURL.getLength()]stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] ; NSURL* aURL = [NSURL URLWithString:aNSStr ]; NSError* pErr = nil; mpMovie = [QTMovie movieWithURL:aURL error:&pErr]; if(mpMovie) { [mpMovie retain]; maURL = rURL; bRet = true; } if( pErr ) { OSL_TRACE( "NSMovie create failed with error %ld (%s)", (long)[pErr code], [[pErr localizedDescription] UTF8String] ); } [pool release]; } return bRet; } // ------------------------------------------------------------------------------ void SAL_CALL Player::start( ) throw (uno::RuntimeException) { OSL_TRACE ("Player::start"); if( mpMovie ) { [mpMovie play]; } } // ------------------------------------------------------------------------------ void SAL_CALL Player::stop( ) throw (uno::RuntimeException) { OSL_TRACE ("Player::stop"); if( mpMovie ) { [mpMovie stop]; } } // ------------------------------------------------------------------------------ sal_Bool SAL_CALL Player::isPlaying() throw (uno::RuntimeException) { bool bRet = false; if ( mpMovie ) { if ([mpMovie rate] != 0) { bRet = true; } } return bRet; } // ------------------------------------------------------------------------------ double SAL_CALL Player::getDuration( ) throw (uno::RuntimeException) { // slideshow checks for non-zero duration, so cheat here double duration = 0.01; if ( mpMovie ) // && mnDuration > 0 ) { { QTTime structDuration = [mpMovie duration] ; duration = (double)structDuration.timeValue / (double)structDuration.timeScale; } return duration; } // ------------------------------------------------------------------------------ void SAL_CALL Player::setMediaTime( double fTime ) throw (uno::RuntimeException) { OSL_TRACE ("Player::setMediaTime"); if ( mpMovie ) { [mpMovie setCurrentTime: QTMakeTimeWithTimeInterval(fTime)]; } } // ------------------------------------------------------------------------------ double SAL_CALL Player::getMediaTime( ) throw (uno::RuntimeException) { double position = 0.0; if ( mpMovie ) { QTTime structDuration = [mpMovie currentTime] ; position = (double)structDuration.timeValue / (double)structDuration.timeScale; } if(isPlaying() && position>mnStopTime) { stop(); } return position; } // ------------------------------------------------------------------------------ void SAL_CALL Player::setStopTime( double fTime ) throw (uno::RuntimeException) { OSL_TRACE ("Player::setStopTime %f", fTime); mnStopTime = fTime; } // ------------------------------------------------------------------------------ double SAL_CALL Player::getStopTime( ) throw (uno::RuntimeException) { double fRet = mnStopTime; return fRet; } // ------------------------------------------------------------------------------ void SAL_CALL Player::setRate( double fRate ) throw (uno::RuntimeException) { OSL_TRACE ("Player::setRate"); // Quicktime: 0 = stop, 1 = normal speed, 2 = double speed, -1 = normal speed backwards if ( mpMovie ) { [mpMovie setRate: fRate]; } } // ------------------------------------------------------------------------------ double SAL_CALL Player::getRate( ) throw (uno::RuntimeException) { // Quicktime: 0 = stop, 1 = normal speed, 2 = double speed, -1 = normal speed backwards double rate = 1.0; OSL_TRACE ("Player::getRate"); if ( mpMovie ) { rate = (double) [mpMovie rate]; } return rate; } // ------------------------------------------------------------------------------ void SAL_CALL Player::setPlaybackLoop( sal_Bool bSet ) throw (uno::RuntimeException) { OSL_TRACE ("Player::setPlaybackLoop? %s", bSet?"True":"False" ); if(bSet) { [mpMovie setAttribute:[NSNumber numberWithBool:YES] forKey: QTMovieLoopsAttribute] ; } else { [mpMovie setAttribute:[NSNumber numberWithBool:NO] forKey: QTMovieLoopsAttribute] ; } } // ------------------------------------------------------------------------------ sal_Bool SAL_CALL Player::isPlaybackLoop( ) throw (uno::RuntimeException) { bool bRet = [[mpMovie attributeForKey:QTMovieLoopsAttribute] boolValue]; OSL_TRACE ("Player::isPlaybackLoop ? %s", bRet?"True":"False" ); return bRet; } // ------------------------------------------------------------------------------ void SAL_CALL Player::setMute( sal_Bool bSet ) throw (uno::RuntimeException) { OSL_TRACE( "set mute: %d muted: %d unmuted volume: %lf", bSet, mbMuted, mnUnmutedVolume ); // change the volume to 0 or the unmuted volume if( mpMovie && mbMuted != bSet ) { [mpMovie setMuted: bSet ]; mbMuted = bSet; } } // ------------------------------------------------------------------------------ sal_Bool SAL_CALL Player::isMute( ) throw (uno::RuntimeException) { OSL_TRACE ("Player::isMuted"); return mbMuted; } // ------------------------------------------------------------------------------ void SAL_CALL Player::setVolumeDB( sal_Int16 nVolumeDB ) throw (uno::RuntimeException) { // OOo db volume -40 = QTVolume 0 // OOo db volume 0 = QTvolume 1 if(nVolumeDB==-40) { mnUnmutedVolume = 0; } else { mnUnmutedVolume = pow( 10.0, nVolumeDB / 20.0 ); } OSL_TRACE( "set volume: %d gst volume: %f", nVolumeDB, mnUnmutedVolume ); // change volume if( !mbMuted && mpMovie ) { [mpMovie setVolume: mnUnmutedVolume ]; } } // ------------------------------------------------------------------------------ sal_Int16 SAL_CALL Player::getVolumeDB( ) throw (uno::RuntimeException) { sal_Int16 nVolumeDB = 0.0; if( mpMovie ) { float volume = 0.0; volume = [mpMovie volume]; if(volume>0) //protect from log10(0) { nVolumeDB = (sal_Int16) ( 20.0*log10 ( volume ) ); } else { nVolumeDB = -40 ; // QT zero volume is no volume, -40db } } return nVolumeDB; } // ------------------------------------------------------------------------------ awt::Size SAL_CALL Player::getPreferredPlayerWindowSize( ) throw (uno::RuntimeException) { NSSize nsSize = [[mpMovie attributeForKey:QTMovieNaturalSizeAttribute] sizeValue]; awt::Size aSize( nsSize.width, nsSize.height ); return aSize; } // ------------------------------------------------------------------------------ uno::Reference< ::media::XPlayerWindow > SAL_CALL Player::createPlayerWindow( const uno::Sequence< uno::Any >& aArguments ) throw (uno::RuntimeException) { uno::Reference< ::media::XPlayerWindow > xRet; awt::Size aSize( getPreferredPlayerWindowSize() ); NSSize nsSize( NSMakeSize(aSize.Width, aSize.Height) ); OSL_TRACE( "Player::createPlayerWindow %d %d length: %d", aSize.Width, aSize.Height, aArguments.getLength() ); if( aSize.Width > 0 && aSize.Height > 0 ) { sal_IntPtr nPtr = NULL; aArguments[0] >>= nPtr; NSView* pParentView = reinterpret_cast< NSView * >(nPtr); ::avmedia::quicktime::Window* pWindow = new ::avmedia::quicktime::Window( mxMgr, *this, pParentView ); xRet = pWindow; } return xRet; } // ------------------------------------------------------------------------------ uno::Reference< media::XFrameGrabber > SAL_CALL Player::createFrameGrabber( ) throw (::com::sun::star::uno::RuntimeException) { uno::Reference< media::XFrameGrabber > xRet; OSL_TRACE ("Player::createFrameGrabber"); if( !maURL.isEmpty() ) { FrameGrabber* pGrabber = new FrameGrabber( mxMgr ); xRet = pGrabber; if( !pGrabber->create( maURL ) ) { xRet.clear(); } } return xRet; } // ------------------------------------------------------------------------------ ::rtl::OUString SAL_CALL Player::getImplementationName( ) throw (uno::RuntimeException) { return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( AVMEDIA_QUICKTIME_PLAYER_IMPLEMENTATIONNAME ) ); } // ------------------------------------------------------------------------------ sal_Bool SAL_CALL Player::supportsService( const ::rtl::OUString& ServiceName ) throw (uno::RuntimeException) { return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( AVMEDIA_QUICKTIME_PLAYER_SERVICENAME ) ); } // ------------------------------------------------------------------------------ uno::Sequence< ::rtl::OUString > SAL_CALL Player::getSupportedServiceNames( ) throw (uno::RuntimeException) { uno::Sequence< ::rtl::OUString > aRet(1); aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( AVMEDIA_QUICKTIME_PLAYER_SERVICENAME ) ); return aRet; } } // namespace quicktime } // namespace avmedia