This is an automated email from the ASF dual-hosted git repository. arielch pushed a commit to branch AOO418 in repository https://gitbox.apache.org/repos/asf/openoffice.git
commit 95ea2752778b7dc1604587fd3fb48734ef686251 Author: Herbert Dürr <[email protected]> AuthorDate: Mon May 12 13:39:08 2014 +0000 #i124875# support Mac AV-Foundation API for multimedia content git-svn-id: https://svn.apache.org/repos/asf/openoffice/trunk@1593965 13f79535-47bb-0310-9956-ffa450edef68 (cherry picked from commit eb7664d6c5c9be8a69ece33db9cd896580c512b8) --- main/avmedia/prj/build.lst | 1 + main/avmedia/prj/d.lst | 2 + main/avmedia/source/inc/mediamisc.hxx | 2 +- main/avmedia/source/macavf/avmediaMacAVF.component | 28 ++ main/avmedia/source/macavf/framegrabber.cxx | 137 ++++++ main/avmedia/source/macavf/framegrabber.hxx | 66 +++ main/avmedia/source/macavf/macavfcommon.hxx | 89 ++++ main/avmedia/source/macavf/macavfuno.cxx | 71 +++ main/avmedia/source/macavf/makefile.mk | 89 ++++ main/avmedia/source/macavf/manager.cxx | 90 ++++ main/avmedia/source/macavf/manager.hxx | 59 +++ main/avmedia/source/macavf/player.cxx | 475 +++++++++++++++++++++ main/avmedia/source/macavf/player.hxx | 97 +++++ main/avmedia/source/macavf/window.cxx | 342 +++++++++++++++ main/avmedia/source/macavf/window.hxx | 123 ++++++ main/scp2/source/ooo/file_library_ooo.scp | 8 + 16 files changed, 1678 insertions(+), 1 deletion(-) diff --git a/main/avmedia/prj/build.lst b/main/avmedia/prj/build.lst index 7d9343b..6b4ba9c 100644 --- a/main/avmedia/prj/build.lst +++ b/main/avmedia/prj/build.lst @@ -7,5 +7,6 @@ av avmedia\source\framework nmake - all av_framework NULL av avmedia\source\win nmake - all av_win NULL av avmedia\source\java nmake - all av_java NULL av avmedia\source\quicktime nmake - all av_quicktime NULL +av avmedia\source\macavf nmake - all av_macavf NULL av avmedia\source\gstreamer nmake - all av_gstreamer NULL av avmedia\util nmake - all av_util av_viewer av_framework av_win av_java av_quicktime av_gstreamer NULL diff --git a/main/avmedia/prj/d.lst b/main/avmedia/prj/d.lst index eb140ed..86c6119 100644 --- a/main/avmedia/prj/d.lst +++ b/main/avmedia/prj/d.lst @@ -19,5 +19,7 @@ mkdir: %_DEST%\inc%_EXT%\avmedia ..\%__SRC%\misc\avmedia.component %_DEST%\xml%_EXT%\avmedia.component ..\%__SRC%\misc\avmedia.jar.component %_DEST%\xml%_EXT%\avmedia.jar.component ..\%__SRC%\misc\avmediaQuickTime.component %_DEST%\xml%_EXT%\avmediaQuickTime.component +..\%__SRC%\misc\avmediaMacAVF.component %_DEST%\xml%_EXT%\avmediaMacAVF.component ..\%__SRC%\misc\avmediagst.component %_DEST%\xml%_EXT%\avmediagst.component ..\%__SRC%\misc\avmediawin.component %_DEST%\xml%_EXT%\avmediawin.component + diff --git a/main/avmedia/source/inc/mediamisc.hxx b/main/avmedia/source/inc/mediamisc.hxx index 03a8fbf..5a4a276 100644 --- a/main/avmedia/source/inc/mediamisc.hxx +++ b/main/avmedia/source/inc/mediamisc.hxx @@ -39,7 +39,7 @@ class ResMgr; #define AVMEDIA_MANAGER_SERVICE_NAME "com.sun.star.comp.avmedia.Manager_QuickTime" #define AVMEDIA_MANAGER_SERVICE_IS_JAVABASED sal_False -#define AVMEDIA_MANAGER_SERVICE_NAME_FALLBACK1 "" +#define AVMEDIA_MANAGER_SERVICE_NAME_FALLBACK1 "com.sun.star.comp.avmedia.Manager_MacAVF" #define AVMEDIA_MANAGER_SERVICE_IS_JAVABASED_FALLBACK1 sal_False #else diff --git a/main/avmedia/source/macavf/avmediaMacAVF.component b/main/avmedia/source/macavf/avmediaMacAVF.component new file mode 100644 index 0000000..6485b70 --- /dev/null +++ b/main/avmedia/source/macavf/avmediaMacAVF.component @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!--*********************************************************** + * + * 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. + * + ***********************************************************--> + +<component loader="com.sun.star.loader.SharedLibrary" + xmlns="http://openoffice.org/2010/uno-components"> + <implementation name="com.sun.star.comp.avmedia.Manager_MacAVF"> + <service name="com.sun.star.media.Manager_MacAVF"/> + </implementation> +</component> diff --git a/main/avmedia/source/macavf/framegrabber.cxx b/main/avmedia/source/macavf/framegrabber.cxx new file mode 100644 index 0000000..1129b90 --- /dev/null +++ b/main/avmedia/source/macavf/framegrabber.cxx @@ -0,0 +1,137 @@ +/************************************************************** + * + * 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 "framegrabber.hxx" +#include "player.hxx" + +#include <tools/stream.hxx> +#include <vcl/graph.hxx> +#include <vcl/cvtgrf.hxx> +#include <unotools/localfilehelper.hxx> + +using namespace ::com::sun::star; + +namespace avmedia { namespace macavf { + +// ---------------- +// - FrameGrabber - +// ---------------- + +FrameGrabber::FrameGrabber( const uno::Reference< lang::XMultiServiceFactory >& /*rxMgr*/ ) +: mpImageGen( NULL ) +{} + +// ------------------------------------------------------------------------------ + +FrameGrabber::~FrameGrabber() +{ + if( mpImageGen ) + CFRelease( mpImageGen ); +} + +// ------------------------------------------------------------------------------ + +bool FrameGrabber::create( const ::rtl::OUString& rURL ) +{ + // TODO: use AVPlayer's movie directly instead of loading it here? + + NSString* pNSStr = [NSString stringWithCharacters:rURL.getStr() length:rURL.getLength()]; + NSURL* pNSURL = [NSURL URLWithString: [pNSStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; + AVAsset* pMovie = [AVURLAsset URLAssetWithURL:pNSURL options:nil]; + if( !pMovie ) + { + OSL_TRACE( "AVGrabber::create() cannot load url=\"%s\"", [pNSStr UTF8String] ); + return false; + } + if( [[pMovie tracksWithMediaType:AVMediaTypeVideo] count] == 0) + { + OSL_TRACE( "AVGrabber::create() found no video in url=\"%s\"", [pNSStr UTF8String] ); + return false; + } + + mpImageGen = [AVAssetImageGenerator assetImageGeneratorWithAsset:pMovie]; + CFRetain( mpImageGen ); + return true; +} + +// ------------------------------------------------------------------------------ + +uno::Reference< graphic::XGraphic > SAL_CALL FrameGrabber::grabFrame( double fMediaTime ) + throw (uno::RuntimeException) +{ + uno::Reference< graphic::XGraphic > xRet; + if( !mpImageGen ) + return xRet; + OSL_TRACE( "AVPlayer::grabFrame( %.3fsec)", fMediaTime ); + + // get the requested image from the movie + CGImage* pCGImage = [mpImageGen copyCGImageAtTime:CMTimeMakeWithSeconds(fMediaTime,1000) actualTime:NULL error:NULL]; + + // convert the image to a TIFF-formatted byte-array + CFMutableDataRef pCFData = CFDataCreateMutable( kCFAllocatorDefault, 0 ); + CGImageDestination* pCGImgDest = CGImageDestinationCreateWithData( pCFData, kUTTypeTIFF, 1, 0 ); + CGImageDestinationAddImage( pCGImgDest, pCGImage, NULL ); + CGImageDestinationFinalize( pCGImgDest ); + CFRelease( pCGImgDest ); + const long nBitmapLen = CFDataGetLength( pCFData ); + void* pBitmapBytes = (void*)CFDataGetBytePtr( pCFData ); + + // convert the image into the return-value type which is a graphic::XGraphic + SvMemoryStream aMemStm( pBitmapBytes, nBitmapLen, STREAM_READ | STREAM_WRITE ); + Graphic aGraphic; + if( GraphicConverter::Import( aMemStm, aGraphic, CVT_TIF ) == ERRCODE_NONE ) + xRet = aGraphic.GetXGraphic(); + + // clean up resources + CFRelease( pCFData ); + return xRet; +} + +// ------------------------------------------------------------------------------ + +::rtl::OUString SAL_CALL FrameGrabber::getImplementationName( ) + throw (uno::RuntimeException) +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( AVMEDIA_MACAVF_FRAMEGRABBER_IMPLEMENTATIONNAME ) ); +} + +// ------------------------------------------------------------------------------ + +sal_Bool SAL_CALL FrameGrabber::supportsService( const ::rtl::OUString& ServiceName ) + throw (uno::RuntimeException) +{ + return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( AVMEDIA_MACAVF_FRAMEGRABBER_SERVICENAME ) ); +} + +// ------------------------------------------------------------------------------ + +uno::Sequence< ::rtl::OUString > SAL_CALL FrameGrabber::getSupportedServiceNames( ) + throw (uno::RuntimeException) +{ + uno::Sequence< ::rtl::OUString > aRet(1); + aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( AVMEDIA_MACAVF_FRAMEGRABBER_SERVICENAME ) ); + + return aRet; +} + +} // namespace macavf +} // namespace avmedia + diff --git a/main/avmedia/source/macavf/framegrabber.hxx b/main/avmedia/source/macavf/framegrabber.hxx new file mode 100644 index 0000000..bcc095d --- /dev/null +++ b/main/avmedia/source/macavf/framegrabber.hxx @@ -0,0 +1,66 @@ +/************************************************************** + * + * 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. + * + *************************************************************/ + + + +#ifndef _FRAMEGRABBER_HXX +#define _FRAMEGRABBER_HXX + +#include "macavfcommon.hxx" + +#include "com/sun/star/media/XFrameGrabber.hdl" + +namespace avmedia { namespace macavf { + +// ---------------- +// - FrameGrabber - +// ---------------- + +class FrameGrabber : public ::cppu::WeakImplHelper2 < ::com::sun::star::media::XFrameGrabber, + ::com::sun::star::lang::XServiceInfo > +{ +public: + + explicit FrameGrabber( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& ); + virtual ~FrameGrabber(); + + bool create( const ::rtl::OUString& rURL ); + + // XFrameGrabber + virtual ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > SAL_CALL grabFrame( double fMediaTime ) throw (::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException); + +private: + + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxMgr; + + AVAssetImageGenerator* mpImageGen; +}; + +} // namespace macavf +} // namespace avmedia + +#endif // _FRAMEGRABBER_HXX + diff --git a/main/avmedia/source/macavf/macavfcommon.hxx b/main/avmedia/source/macavf/macavfcommon.hxx new file mode 100644 index 0000000..ba27e40 --- /dev/null +++ b/main/avmedia/source/macavf/macavfcommon.hxx @@ -0,0 +1,89 @@ +/************************************************************** + * + * 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. + * + *************************************************************/ + +#ifndef MACAVF_COMMON_HXX +#define MACAVF_COMMON_HXX + +#ifdef MACOSX +#include <premac.h> +#import <Cocoa/Cocoa.h> +#import <AVFoundation/AVFoundation.h> +#include <postmac.h> +#endif +#include <osl/mutex.hxx> +#include <rtl/ustring.hxx> +#include <tools/debug.hxx> +#include <tools/stream.hxx> +#include <tools/string.hxx> +#include <tools/urlobj.hxx> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/implbase2.hxx> +#include <cppuhelper/weak.hxx> +#include <cppuhelper/factory.hxx> + +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/awt/Rectangle.hpp> +#include <com/sun/star/awt/KeyModifier.hpp> +#include <com/sun/star/awt/MouseButton.hpp> +#include <com/sun/star/media/XManager.hpp> + + +#define AVMEDIA_MACAVF_MANAGER_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.Manager_MacAVF" +#define AVMEDIA_MACAVF_MANAGER_SERVICENAME "com.sun.star.media.Manager_MacAVF" + +#define AVMEDIA_MACAVF_PLAYER_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.Player_MacAVF" +#define AVMEDIA_MACAVF_PLAYER_SERVICENAME "com.sun.star.media.Player_MacAVF" + +#define AVMEDIA_MACAVF_WINDOW_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.Window_MacAVF" +#define AVMEDIA_MACAVF_WINDOW_SERVICENAME "com.sun.star.media.Window_MacAVF" + +#define AVMEDIA_MACAVF_FRAMEGRABBER_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.FrameGrabber_MacAVF" +#define AVMEDIA_MACAVF_FRAMEGRABBER_SERVICENAME "com.sun.star.media.FrameGrabber_MacAVF" + + +// MacAVObserver handles the notifications used in the AVFoundation framework + +@interface MacAVObserverObject : NSObject +- (void)observeValueForKeyPath:(NSString*)pKeyPath ofObject:(id)pObject change:(NSDictionary*)pChangeDict context:(void*)pContext; +- (void)onNotification:(NSNotification*)pNotification; +@end + +namespace avmedia { namespace macavf { + +class MacAVObserverHandler +{ +private: + static MacAVObserverObject* mpMacAVObserverObject; +public: + MacAVObserverObject* getObserver( void ) const; + virtual bool handleObservation( NSString* pKeyPath ) = 0; +}; + +}} + +#endif // MACAVF_COMMON_HXX + diff --git a/main/avmedia/source/macavf/macavfuno.cxx b/main/avmedia/source/macavf/macavfuno.cxx new file mode 100644 index 0000000..acc0d93 --- /dev/null +++ b/main/avmedia/source/macavf/macavfuno.cxx @@ -0,0 +1,71 @@ +/************************************************************** + * + * 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 "macavfcommon.hxx" +#include "manager.hxx" + +using namespace ::com::sun::star; + +// ------------------- +// - factory methods - +// ------------------- + +static uno::Reference< uno::XInterface > SAL_CALL create_MediaPlayer( const uno::Reference< lang::XMultiServiceFactory >& rxFact ) +{ + return uno::Reference< uno::XInterface >( *new ::avmedia::macavf::Manager( rxFact ) ); +} + +// ------------------------------------------ +// - component_getImplementationEnvironment - +// ------------------------------------------ + +extern "C" void SAL_CALL component_getImplementationEnvironment( const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */ ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +// ------------------------ +// - component_getFactory - +// ------------------------ + +extern "C" void* SAL_CALL component_getFactory( const sal_Char* pImplName, void* pServiceManager, void* /* pRegistryKey */ ) +{ + uno::Reference< lang::XSingleServiceFactory > xFactory; + void* pRet = 0; + + if( rtl_str_compare( pImplName, AVMEDIA_MACAVF_MANAGER_IMPLEMENTATIONNAME ) == 0 ) + { + const ::rtl::OUString aServiceName( ::rtl::OUString::createFromAscii( AVMEDIA_MACAVF_MANAGER_SERVICENAME ) ); + + xFactory = uno::Reference< lang::XSingleServiceFactory >( ::cppu::createSingleFactory( + reinterpret_cast< lang::XMultiServiceFactory* >( pServiceManager ), + ::rtl::OUString::createFromAscii( AVMEDIA_MACAVF_MANAGER_IMPLEMENTATIONNAME ), + create_MediaPlayer, uno::Sequence< ::rtl::OUString >( &aServiceName, 1 ) ) ); + } + + if( xFactory.is() ) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + + return pRet; +} diff --git a/main/avmedia/source/macavf/makefile.mk b/main/avmedia/source/macavf/makefile.mk new file mode 100644 index 0000000..542ba0a --- /dev/null +++ b/main/avmedia/source/macavf/makefile.mk @@ -0,0 +1,89 @@ +#************************************************************** +# +# 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. +# +#************************************************************** + +PRJ=..$/.. +PRJNAME=avmedia +TARGET=avmediaMacAVF + +.IF "$(GUIBASE)" != "aqua" +dummy: + @echo " Nothing to build for GUIBASE=$(GUIBASE)" +.ELSE + +# --- Settings ---------------------------------- + +.INCLUDE : settings.mk + +.IF "$(verbose)"!="" || "$(VERBOSE)"!="" +CDEFS+= -DVERBOSE +.ENDIF + +# --- Files ---------------------------------- + +CFLAGSCXX+=$(OBJCXXFLAGS) + +SLOFILES= \ + $(SLO)$/macavfuno.obj \ + $(SLO)$/framegrabber.obj \ + $(SLO)$/manager.obj \ + $(SLO)$/window.obj \ + $(SLO)$/player.obj + +EXCEPTIONSFILES= \ + $(SLO)$/framegrabber.obj \ + $(SLO)$/macavfuno.obj + +SHL1TARGET= $(TARGET)$(DLLPOSTFIX) + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(SALLIB) \ + $(COMPHELPERLIB) \ + $(CPPUHELPERLIB) \ + $(TOOLSLIB) \ + $(VCLLIB) + +SHL1STDLIBS+= \ + -framework Cocoa \ + -framework AVFoundation \ + -framework CoreMedia + +# build DLL +SHL1LIBS=$(SLB)$/$(TARGET).lib +SHL1IMPLIB=i$(TARGET) +SHL1DEF=$(MISC)$/$(SHL1TARGET).def + +SHL1VERSIONMAP=$(SOLARENV)/src/component.map + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + +.ENDIF + +ALLTAR : $(MISC)/avmediaMacAVF.component + +$(MISC)/avmediaMacAVF.component .ERRREMOVE : \ + $(SOLARENV)/bin/createcomponent.xslt avmediaMacAVF.component + $(XSLTPROC) --nonet --stringparam uri \ + '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL1TARGETN:f)' -o $@ \ + $(SOLARENV)/bin/createcomponent.xslt avmediaMacAVF.component + diff --git a/main/avmedia/source/macavf/manager.cxx b/main/avmedia/source/macavf/manager.cxx new file mode 100644 index 0000000..c11eb19 --- /dev/null +++ b/main/avmedia/source/macavf/manager.cxx @@ -0,0 +1,90 @@ +/************************************************************** + * + * 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 "manager.hxx" +#include "player.hxx" +#include <tools/urlobj.hxx> + +using namespace ::com::sun::star; + +namespace avmedia { namespace macavf { + +// ---------------- +// - Manager - +// ---------------- + +Manager::Manager( const uno::Reference< lang::XMultiServiceFactory >& rxMgr ) : + mxMgr( rxMgr ) +{ + OSL_TRACE( "Constructing avmedia::macavf::Manager" ); +} + +// ------------------------------------------------------------------------------ + +Manager::~Manager() +{} + +// ------------------------------------------------------------------------------ + +uno::Reference< media::XPlayer > SAL_CALL Manager::createPlayer( const ::rtl::OUString& rURL ) + throw (uno::RuntimeException) +{ + Player* pPlayer( new Player( mxMgr ) ); + uno::Reference< media::XPlayer > xRet( pPlayer ); + INetURLObject aURL( rURL ); + + OSL_TRACE( "avmediamacavf: Manager::createPlayer" ); + + if( !pPlayer->create( aURL.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ) ) ) + xRet = uno::Reference< media::XPlayer >(); + + return xRet; +} + +// ------------------------------------------------------------------------------ + +::rtl::OUString SAL_CALL Manager::getImplementationName( ) + throw (uno::RuntimeException) +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( AVMEDIA_MACAVF_MANAGER_IMPLEMENTATIONNAME ) ); +} + +// ------------------------------------------------------------------------------ + +sal_Bool SAL_CALL Manager::supportsService( const ::rtl::OUString& ServiceName ) + throw (uno::RuntimeException) +{ + return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( AVMEDIA_MACAVF_MANAGER_SERVICENAME ) ); +} + +// ------------------------------------------------------------------------------ + +uno::Sequence< ::rtl::OUString > SAL_CALL Manager::getSupportedServiceNames( ) + throw (uno::RuntimeException) +{ + uno::Sequence< ::rtl::OUString > aRet(1); + aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( AVMEDIA_MACAVF_MANAGER_SERVICENAME ) ); + + return aRet; +} + +} // namespace macavf +} // namespace avmedia diff --git a/main/avmedia/source/macavf/manager.hxx b/main/avmedia/source/macavf/manager.hxx new file mode 100644 index 0000000..f8f6ea9 --- /dev/null +++ b/main/avmedia/source/macavf/manager.hxx @@ -0,0 +1,59 @@ +/************************************************************** + * + * 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. + * + *************************************************************/ + +#ifndef _MANAGER_HXX +#define _MANAGER_HXX + +#include "macavfcommon.hxx" + +#include "com/sun/star/media/XManager.hdl" + +// ----------- +// - Manager - +// ----------- + +namespace avmedia { namespace macavf { + +class Manager : public ::cppu::WeakImplHelper2 < ::com::sun::star::media::XManager, + ::com::sun::star::lang::XServiceInfo > +{ +public: + + Manager( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxMgr ); + ~Manager(); + + // XManager + virtual ::com::sun::star::uno::Reference< ::com::sun::star::media::XPlayer > SAL_CALL createPlayer( const ::rtl::OUString& aURL ) throw (::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException); +private: + + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxMgr; +}; + +} // namespace macavf +} // namespace avmedia + +#endif // _MANAGER_HXX + diff --git a/main/avmedia/source/macavf/player.cxx b/main/avmedia/source/macavf/player.cxx new file mode 100644 index 0000000..46a8397 --- /dev/null +++ b/main/avmedia/source/macavf/player.cxx @@ -0,0 +1,475 @@ +/************************************************************** + * + * 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 "player.hxx" +#include "framegrabber.hxx" +#include "window.hxx" + +#include <cmath> // for log10() + +using namespace ::com::sun::star; + +#include <hash_map> +typedef std::hash_map<NSObject*,avmedia::macavf::MacAVObserverHandler*> HandlersForObject; + +@implementation MacAVObserverObject +{ + HandlersForObject maHandlersForObject; +} +- (void)observeValueForKeyPath:(NSString*)pKeyPath ofObject:(id)pObject change:(NSDictionary*)pChangeDict context:(void*)pContext +{ + NSString* pDictStr = [NSString stringWithFormat:@"%@", pChangeDict]; + OSL_TRACE( "MacAVObserver::onKeyChange k=\"%s\" c=%s", [pKeyPath UTF8String], [pDictStr UTF8String]); + avmedia::macavf::MacAVObserverHandler* pHandler = (avmedia::macavf::MacAVObserverHandler*)pContext; + pHandler->handleObservation( pKeyPath ); +} + +- (void)onNotification:(NSNotification*)pNotification +{ + NSString* pNoteName = (NSString*)[pNotification name]; + OSL_TRACE( "MacAVObserver::onNotification key=\"%s\"", [pNoteName UTF8String]); + HandlersForObject::iterator it = maHandlersForObject.find( [pNotification object]); + if( it != maHandlersForObject.end() ) + (*it).second->handleObservation( pNoteName ); +} + +- (void)setHandlerForObject:(NSObject*)pObject handler:(avmedia::macavf::MacAVObserverHandler*)pHandler +{ + maHandlersForObject[ pObject] = pHandler; +} + +- (void)removeHandlerForObject:(NSObject*)pObject +{ + maHandlersForObject.erase( pObject); +} + +@end + + +namespace avmedia { namespace macavf { + +MacAVObserverObject* MacAVObserverHandler::mpMacAVObserverObject = NULL; + +MacAVObserverObject* MacAVObserverHandler::getObserver() const +{ + if( !mpMacAVObserverObject) + { + mpMacAVObserverObject = [MacAVObserverObject alloc]; + [mpMacAVObserverObject retain]; + } + return mpMacAVObserverObject; +} + + +// ---------------- +// - Player - +// ---------------- + +Player::Player( const uno::Reference< lang::XMultiServiceFactory >& rxMgr ) +: mxMgr( rxMgr ) +, mpPlayer( NULL ) +, mfUnmutedVolume( 0 ) +, mfStopTime( DBL_MAX ) +, mbMuted( false ) +, mbLooping( false ) +{} + +// ------------------------------------------------------------------------------ + +Player::~Player() +{ + if( !mpPlayer ) + return; + // remove the observers + [mpPlayer removeObserver:getObserver() forKeyPath:@"currentItem.status"]; + AVPlayerItem* pOldPlayerItem = [mpPlayer currentItem]; + [[NSNotificationCenter defaultCenter] removeObserver:getObserver() + name:AVPlayerItemDidPlayToEndTimeNotification + object:pOldPlayerItem]; + [getObserver() removeHandlerForObject:pOldPlayerItem]; + // release the AVPlayer + CFRelease( mpPlayer ); +} + +// ------------------------------------------------------------------------------ + +AVAsset* Player::getMovie() +{ + if( !mpPlayer ) + return nil; + AVAsset* pMovie = [[mpPlayer currentItem] asset]; + OSL_ASSERT( pMovie ); + return pMovie; +} + +// ------------------------------------------------------------------------------ + +bool Player::handleObservation( NSString* pKeyPath ) +{ + OSL_TRACE( "AVPlayer::handleObservation key=\"%s\"", [pKeyPath UTF8String]); + if( [pKeyPath isEqualToString:AVPlayerItemDidPlayToEndTimeNotification]) + { + OSL_TRACE( "AVPlayer replay=%d", mbLooping); + if( mbLooping ) + setMediaTime( 0.0); + } + return true; +} + +// ------------------------------------------------------------------------------ + +bool Player::create( const ::rtl::OUString& rURL ) +{ + maURL = rURL; + + // get the media asset + NSString* aNSStr = [NSString stringWithCharacters:rURL.getStr() length:rURL.getLength()]; + NSURL* aNSURL = [NSURL URLWithString: [aNSStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; + // get the matching AVPlayerItem + AVPlayerItem* pPlayerItem = [AVPlayerItem playerItemWithURL:aNSURL]; + + // create or update the AVPlayer with the new AVPlayerItem + if( !mpPlayer ) + { + mpPlayer = [AVPlayer playerWithPlayerItem:pPlayerItem]; + CFRetain( mpPlayer ); + [mpPlayer setActionAtItemEnd:AVPlayerActionAtItemEndNone]; + } + else + { + // remove the obsoleted observers + AVPlayerItem* pOldPlayerItem = [mpPlayer currentItem]; + [mpPlayer removeObserver:getObserver() forKeyPath:@"currentItem.status"]; + [getObserver() removeHandlerForObject:pOldPlayerItem]; + [[NSNotificationCenter defaultCenter] removeObserver:getObserver() + name:AVPlayerItemDidPlayToEndTimeNotification + object:pOldPlayerItem]; + // replace the playeritem + [mpPlayer replaceCurrentItemWithPlayerItem:pPlayerItem]; + } + + // observe the status of the current player item + [mpPlayer addObserver:getObserver() forKeyPath:@"currentItem.status" options:0 context:this]; + + // observe playback-end needed for playback looping + [[NSNotificationCenter defaultCenter] addObserver:getObserver() + selector:@selector(onNotification:) + name:AVPlayerItemDidPlayToEndTimeNotification + object:pPlayerItem]; + [getObserver() setHandlerForObject:pPlayerItem handler:this]; + + return true; +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Player::start() + throw (uno::RuntimeException) +{ + if( !mpPlayer ) + return; +#if 0 + const AVPlayerStatus eStatus = [mpPlayer status]; + OSL_TRACE ("Player::start status=%d", (int)eStatus); + if( eStatus == AVPlayerStatusReadyToPlay) +#endif + [mpPlayer play]; + // else // TODO: delay until it becomes ready +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Player::stop() + throw (uno::RuntimeException) +{ + if( !mpPlayer ) + return; + const bool bPlaying = isPlaying(); + OSL_TRACE ("Player::stop() playing=%d", bPlaying); + if( bPlaying ) + [mpPlayer pause]; +} + +// ------------------------------------------------------------------------------ + +sal_Bool SAL_CALL Player::isPlaying() + throw (uno::RuntimeException) +{ + if( !mpPlayer ) + return false; + const float fRate = [mpPlayer rate]; + return (fRate != 0.0); +} + +// ------------------------------------------------------------------------------ + +double SAL_CALL Player::getDuration() + throw (uno::RuntimeException) +{ + // slideshow checks for non-zero duration, so cheat here + double duration = 0.01; + + if( mpPlayer ) + { + AVPlayerItem* pItem = [mpPlayer currentItem]; + duration = CMTimeGetSeconds( [pItem duration] ); + } + + return duration; +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Player::setMediaTime( double fTime ) + throw (uno::RuntimeException) +{ + OSL_TRACE ("Player::setMediaTime( %.3fsec)", fTime); + if( mpPlayer ) + [mpPlayer seekToTime: CMTimeMakeWithSeconds(fTime,1000) ]; +} + +// ------------------------------------------------------------------------------ + +double SAL_CALL Player::getMediaTime() + throw (uno::RuntimeException) +{ + if( !mpPlayer ) + return 0.0; + + const double position = CMTimeGetSeconds( [mpPlayer currentTime] ); + OSL_TRACE( "Player::getMediaTime() = %.3fsec", position); + if( position >= mfStopTime ) + if( isPlaying() ) + stop(); + + return position; +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Player::setStopTime( double fTime ) + throw (uno::RuntimeException) +{ + OSL_TRACE ("Player::setStopTime( %.3fsec)", fTime); + mfStopTime = fTime; +} + +// ------------------------------------------------------------------------------ + +double SAL_CALL Player::getStopTime() + throw (uno::RuntimeException) +{ + return mfStopTime; +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Player::setRate( double fRate ) + throw (uno::RuntimeException) +{ + OSL_TRACE ("Player::setRate( %.3f)", fRate); + if( !mpPlayer ) + return; + + // playback rate: 0 = stop, 1 = normal speed, 2 = double speed, -1 = normal speed backwards + [mpPlayer setRate: fRate]; +} + +// ------------------------------------------------------------------------------ + +double SAL_CALL Player::getRate() + throw (uno::RuntimeException) +{ + // macavf: 0 = stop, 1 = normal speed, 2 = double speed, -1 = normal speed backwards + const double fRate = mpPlayer ? (double)[mpPlayer rate] : 1.0; + OSL_TRACE ("Player::getRate() = %.3f", fRate); + return fRate; +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Player::setPlaybackLoop( sal_Bool bSet ) + throw (uno::RuntimeException) +{ + OSL_TRACE ("Player::setPlaybackLoop( %d)", bSet ); + mbLooping = bSet; +} + +// ------------------------------------------------------------------------------ + +sal_Bool SAL_CALL Player::isPlaybackLoop() + throw (uno::RuntimeException) +{ + const bool bRet = mbLooping; + OSL_TRACE ("Player::isPlaybackLoop() = %d", bRet ); + return bRet; +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Player::setMute( sal_Bool bSet ) + throw (uno::RuntimeException) +{ + OSL_TRACE( "Player::setMute(%d), was-muted: %d unmuted-volume: %.3f", bSet, mbMuted, mfUnmutedVolume ); + + if( !mpPlayer ) + return; + + mbMuted = (bSet == TRUE); + [mpPlayer setMuted:mbMuted]; +} + +// ------------------------------------------------------------------------------ + +sal_Bool SAL_CALL Player::isMute() + throw (uno::RuntimeException) +{ + OSL_TRACE ("Player::isMuted() = %d", mbMuted); + return mbMuted; +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Player::setVolumeDB( sal_Int16 nVolumeDB ) + throw (uno::RuntimeException) +{ + // -40dB <-> AVPlayer volume 0.0 + // 0dB <-> AVPlayer volume 1.0 + mfUnmutedVolume = (nVolumeDB <= -40) ? 0.0 : pow( 10.0, nVolumeDB / 20.0 ); + OSL_TRACE( "Player::setVolume(%ddB), muted=%d, unmuted-volume: %.3f", nVolumeDB, mbMuted, mfUnmutedVolume ); + + // change volume + if( !mbMuted && mpPlayer ) + [mpPlayer setVolume:mfUnmutedVolume]; +} + +// ------------------------------------------------------------------------------ + +sal_Int16 SAL_CALL Player::getVolumeDB() + throw (uno::RuntimeException) +{ + if( !mpPlayer ) + return 0; + + // get the actual volume + const float fVolume = [mpPlayer volume]; + + // convert into Dezibel value + // -40dB <-> AVPlayer volume 0.0 + // 0dB <-> AVPlayer volume 1.0 + const int nVolumeDB = (fVolume <= 0) ? -40 : lrint( 20.0*log10(fVolume)); + + return (sal_Int16)nVolumeDB; +} + +// ------------------------------------------------------------------------------ + +awt::Size SAL_CALL Player::getPreferredPlayerWindowSize() + throw (uno::RuntimeException) +{ + awt::Size aSize( 0, 0 ); // default size + + AVAsset* pMovie = [[mpPlayer currentItem] asset]; + NSArray* pVideoTracks = [pMovie tracksWithMediaType:AVMediaTypeVideo]; + AVAssetTrack* pFirstVideoTrack = (AVAssetTrack*)[pVideoTracks firstObject]; + if( pFirstVideoTrack ) + { + const CGSize aPrefSize = [pFirstVideoTrack naturalSize]; + aSize = awt::Size( aPrefSize.width, aPrefSize.height ); + } + + return aSize; +} + +// ------------------------------------------------------------------------------ + +uno::Reference< ::media::XPlayerWindow > SAL_CALL Player::createPlayerWindow( const uno::Sequence< uno::Any >& aArguments ) + throw (uno::RuntimeException) +{ + // get the preferred window size + const awt::Size aSize( getPreferredPlayerWindowSize() ); + OSL_TRACE( "Player::createPlayerWindow %dx%d argsLength: %d", aSize.Width, aSize.Height, aArguments.getLength() ); + + // get the parent view + sal_IntPtr nNSViewPtr = NULL; + aArguments[0] >>= nNSViewPtr; + NSView* pParentView = reinterpret_cast<NSView*>(nNSViewPtr); + + // check the window parameters + uno::Reference< ::media::XPlayerWindow > xRet; + if( (aSize.Width <= 0) || (aSize.Height <= 0) || (pParentView == NULL) ) + return xRet; + + // create the window + ::avmedia::macavf::Window* pWindow = new ::avmedia::macavf::Window( mxMgr, *this, pParentView ); + xRet = pWindow; + return xRet; +} + +// ------------------------------------------------------------------------------ + +uno::Reference< media::XFrameGrabber > SAL_CALL Player::createFrameGrabber() + throw (uno::RuntimeException) +{ + uno::Reference< media::XFrameGrabber > xRet; + OSL_TRACE ("Player::createFrameGrabber"); + + if( !maURL.isEmpty() ) + { + FrameGrabber* pGrabber = new FrameGrabber( mxMgr ); + if( pGrabber->create( maURL ) ) + xRet = pGrabber; + } + + return xRet; +} + +// ------------------------------------------------------------------------------ + +::rtl::OUString SAL_CALL Player::getImplementationName( ) + throw (uno::RuntimeException) +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( AVMEDIA_MACAVF_PLAYER_IMPLEMENTATIONNAME ) ); +} + +// ------------------------------------------------------------------------------ + +sal_Bool SAL_CALL Player::supportsService( const ::rtl::OUString& ServiceName ) + throw (uno::RuntimeException) +{ + return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( AVMEDIA_MACAVF_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_MACAVF_PLAYER_SERVICENAME ) ); + + return aRet; +} + +} // namespace macavf +} // namespace avmedia + diff --git a/main/avmedia/source/macavf/player.hxx b/main/avmedia/source/macavf/player.hxx new file mode 100644 index 0000000..10ff013 --- /dev/null +++ b/main/avmedia/source/macavf/player.hxx @@ -0,0 +1,97 @@ +/************************************************************** + * + * 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. + * + *************************************************************/ + + + +#ifndef _PLAYER_HXX +#define _PLAYER_HXX + +#include <osl/conditn.h> +#include "macavfcommon.hxx" + +#include "com/sun/star/media/XPlayer.hdl" + +namespace avmedia { namespace macavf { + +/* +// ---------- +// - Player - +// ---------- +*/ + +class Player +: public MacAVObserverHandler +, public ::cppu::WeakImplHelper2< ::com::sun::star::media::XPlayer, + ::com::sun::star::lang::XServiceInfo > +{ +public: + explicit Player( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& ); + virtual ~Player(); + + bool create( const ::rtl::OUString& rURL ); + + // XPlayer + virtual void SAL_CALL start() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL stop() throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isPlaying() throw (::com::sun::star::uno::RuntimeException); + virtual double SAL_CALL getDuration() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setMediaTime( double fTime ) throw (::com::sun::star::uno::RuntimeException); + virtual double SAL_CALL getMediaTime() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setStopTime( double fTime ) throw (::com::sun::star::uno::RuntimeException); + virtual double SAL_CALL getStopTime() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setRate( double fRate ) throw (::com::sun::star::uno::RuntimeException); + virtual double SAL_CALL getRate() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPlaybackLoop( sal_Bool bSet ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isPlaybackLoop() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setMute( sal_Bool bSet ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isMute() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setVolumeDB( sal_Int16 nVolumeDB ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int16 SAL_CALL getVolumeDB() throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Size SAL_CALL getPreferredPlayerWindowSize( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::media::XPlayerWindow > SAL_CALL createPlayerWindow( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::media::XFrameGrabber > SAL_CALL createFrameGrabber( ) throw (::com::sun::star::uno::RuntimeException); + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException); + + AVAsset* getMovie(); + AVPlayer* getAVPlayer() const { return mpPlayer; } + virtual bool handleObservation( NSString* pKeyPath ); + +private: + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxMgr; + + ::rtl::OUString maURL; + + AVPlayer* mpPlayer; + + float mfUnmutedVolume; + double mfStopTime; + + bool mbMuted; + bool mbLooping; +}; + +} // namespace macavf +} // namespace avmedia + +#endif // _PLAYER_HXX diff --git a/main/avmedia/source/macavf/window.cxx b/main/avmedia/source/macavf/window.cxx new file mode 100644 index 0000000..f9e68f7 --- /dev/null +++ b/main/avmedia/source/macavf/window.cxx @@ -0,0 +1,342 @@ +/************************************************************** + * + * 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 <com/sun/star/awt/SystemPointer.hpp> +#include <com/sun/star/awt/PosSize.hpp> + +#include "window.hxx" +#include "player.hxx" + +using namespace ::com::sun::star; + + +namespace avmedia { namespace macavf { + +// --------------- +// - Window - +// --------------- + +Window::Window( const uno::Reference< lang::XMultiServiceFactory >& i_rxMgr, Player& i_rPlayer, NSView* i_pParentView ) +: mxMgr( i_rxMgr ) +, maListeners( maMutex ) +, meZoomLevel( media::ZoomLevel_NOT_AVAILABLE ) +, mrPlayer( i_rPlayer ) +, mnPointerType( awt::SystemPointer::ARROW ) +, mpView( i_pParentView ) +, mpPlayerLayer( NULL ) +{ + OSL_TRACE ("Constructing an avmedia::macavf::Window"); + if( !mpView ) // sanity check + return; + + // check the media asset for video content + AVPlayer* pAVPlayer = mrPlayer.getAVPlayer(); + AVAsset* pMovie = [[pAVPlayer currentItem] asset]; + const int nVideoCount = [pMovie tracksWithMediaType:AVMediaTypeVideo].count; + const int nAudioCount = [pMovie tracksWithMediaType:AVMediaTypeAudio].count; + OSL_TRACE( "Found %d video and %d audio tracks.", nVideoCount, nAudioCount ); + (void)nAudioCount; + if( nVideoCount <= 0 ) + return; + + // setup the AVPlayerLayer + [pAVPlayer retain]; + [pAVPlayer pause]; + mpPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:pAVPlayer]; + [mpPlayerLayer retain]; + [mpPlayerLayer setFrame:[mpView frame]]; + [mpPlayerLayer setHidden:YES]; + [mpPlayerLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; + [mpPlayerLayer addObserver:getObserver() forKeyPath:@"readyForDisplay" options:0 context:this]; + + // setup the target view + [mpView setWantsLayer:YES]; + [mpView.layer addSublayer:mpPlayerLayer]; +} + +// ------------------------------------------------------------------------------ + +Window::~Window() +{ + [mpPlayerLayer removeObserver:getObserver() forKeyPath:@"readyForDisplay"]; + [mpPlayerLayer release]; +} + +// ------------------------------------------------------------------------------ + +bool Window::create( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) +{ + return true; +} + +// ------------------------------------------------------------------------------ + +bool Window::handleObservation( NSString* pKeyPath ) +{ + OSL_TRACE( "AVPlayer::handleObservation key=\"%s\"", [pKeyPath UTF8String]); + const BOOL bReadyForDisplay = [mpPlayerLayer isReadyForDisplay]; + [mpPlayerLayer setHidden:!bReadyForDisplay]; + return true; +} + +// XPlayerWindow +// ------------------------------------------------------------------------------ + +void SAL_CALL Window::update() + throw (uno::RuntimeException) +{} + +// ------------------------------------------------------------------------------ + +sal_Bool SAL_CALL Window::setZoomLevel( media::ZoomLevel eZoomLevel ) + throw (uno::RuntimeException) +{ + return false; +} + +// ------------------------------------------------------------------------------ + +media::ZoomLevel SAL_CALL Window::getZoomLevel( ) + throw (uno::RuntimeException) +{ + return meZoomLevel; +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Window::setPointerType( sal_Int32 nPointerType ) + throw (uno::RuntimeException) +{ + mnPointerType = nPointerType; +} + +// XWindow +// ------------------------------------------------------------------------------ + +void SAL_CALL Window::setPosSize( sal_Int32 X, sal_Int32 Y, sal_Int32 Width, sal_Int32 Height, sal_Int16 Flags ) + throw (uno::RuntimeException) +{ + OSL_TRACE( "AVWindow::setPosSize( %dx%d%+d%+d)", (int)Width,(int)Height,(int)X,(int)Y);//###### + if( !mpView ) + return; + NSRect aRect = [mpView frame]; + // NOTE: if( (Flags & awt::PosSize::WIDTH) ) + aRect.size.width = Width; + // NOTE: if( (Flags & awt::PosSize::HEIGHT) ) + aRect.size.height = Height; + + [mpView setFrameSize: aRect.size]; + [mpPlayerLayer setFrame: [mpView frame]]; +} + +// ------------------------------------------------------------------------------ + +awt::Rectangle SAL_CALL Window::getPosSize() + throw (uno::RuntimeException) +{ + awt::Rectangle aRet; + + NSRect aRect = [mpView frame]; + aRet.X = aRet.Y = 0; + aRet.Width = aRect.size.width; + aRet.Height = aRect.size.height; + + return aRet; +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Window::setVisible( sal_Bool bVisible ) + throw (uno::RuntimeException) +{ + OSL_TRACE ("Window::setVisible(%d)", bVisible); +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Window::setEnable( sal_Bool bEnable ) + throw (uno::RuntimeException) +{ + OSL_TRACE ("Window::setEnable(%d)", bEnable); +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Window::setFocus() + throw (uno::RuntimeException) +{ + OSL_TRACE ("Window::setFocus"); +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Window::addWindowListener( const uno::Reference< awt::XWindowListener >& xListener ) + throw (uno::RuntimeException) +{ + maListeners.addInterface( getCppuType( &xListener ), xListener ); +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Window::removeWindowListener( const uno::Reference< awt::XWindowListener >& xListener ) + throw (uno::RuntimeException) +{ + maListeners.removeInterface( getCppuType( &xListener ), xListener ); +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Window::addFocusListener( const uno::Reference< awt::XFocusListener >& xListener ) + throw (uno::RuntimeException) +{ + maListeners.addInterface( getCppuType( &xListener ), xListener ); +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Window::removeFocusListener( const uno::Reference< awt::XFocusListener >& xListener ) + throw (uno::RuntimeException) +{ + maListeners.removeInterface( getCppuType( &xListener ), xListener ); +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Window::addKeyListener( const uno::Reference< awt::XKeyListener >& xListener ) + throw (uno::RuntimeException) +{ + maListeners.addInterface( getCppuType( &xListener ), xListener ); +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Window::removeKeyListener( const uno::Reference< awt::XKeyListener >& xListener ) + throw (uno::RuntimeException) +{ + maListeners.removeInterface( getCppuType( &xListener ), xListener ); +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Window::addMouseListener( const uno::Reference< awt::XMouseListener >& xListener ) + throw (uno::RuntimeException) +{ + maListeners.addInterface( getCppuType( &xListener ), xListener ); +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Window::removeMouseListener( const uno::Reference< awt::XMouseListener >& xListener ) + throw (uno::RuntimeException) +{ + maListeners.removeInterface( getCppuType( &xListener ), xListener ); +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Window::addMouseMotionListener( const uno::Reference< awt::XMouseMotionListener >& xListener ) + throw (uno::RuntimeException) +{ + maListeners.addInterface( getCppuType( &xListener ), xListener ); +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Window::removeMouseMotionListener( const uno::Reference< awt::XMouseMotionListener >& xListener ) + throw (uno::RuntimeException) +{ + maListeners.removeInterface( getCppuType( &xListener ), xListener ); +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Window::addPaintListener( const uno::Reference< awt::XPaintListener >& xListener ) + throw (uno::RuntimeException) +{ + maListeners.addInterface( getCppuType( &xListener ), xListener ); +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Window::removePaintListener( const uno::Reference< awt::XPaintListener >& xListener ) + throw (uno::RuntimeException) +{ + maListeners.removeInterface( getCppuType( &xListener ), xListener ); +} + + +// XComponent +// ------------------------------------------------------------------------------ + +void SAL_CALL Window::dispose( ) + throw (uno::RuntimeException) +{ +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Window::addEventListener( const uno::Reference< lang::XEventListener >& xListener ) + throw (uno::RuntimeException) +{ + maListeners.addInterface( getCppuType( &xListener ), xListener ); +} + +// ------------------------------------------------------------------------------ + +void SAL_CALL Window::removeEventListener( const uno::Reference< lang::XEventListener >& xListener ) + throw (uno::RuntimeException) +{ + maListeners.removeInterface( getCppuType( &xListener ), xListener ); +} + +// XServiceInfo +// ------------------------------------------------------------------------------ + +::rtl::OUString SAL_CALL Window::getImplementationName( ) + throw (uno::RuntimeException) +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( AVMEDIA_MACAVF_WINDOW_IMPLEMENTATIONNAME ) ); +} + +// ------------------------------------------------------------------------------ + +sal_Bool SAL_CALL Window::supportsService( const ::rtl::OUString& ServiceName ) + throw (uno::RuntimeException) +{ + return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( AVMEDIA_MACAVF_WINDOW_SERVICENAME ) ); +} + +// ------------------------------------------------------------------------------ + +uno::Sequence< ::rtl::OUString > SAL_CALL Window::getSupportedServiceNames( ) + throw (uno::RuntimeException) +{ + uno::Sequence< ::rtl::OUString > aRet(1); + aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( AVMEDIA_MACAVF_WINDOW_SERVICENAME ) ); + + return aRet; +} + +} // namespace macavf +} // namespace avmedia + diff --git a/main/avmedia/source/macavf/window.hxx b/main/avmedia/source/macavf/window.hxx new file mode 100644 index 0000000..83977c2 --- /dev/null +++ b/main/avmedia/source/macavf/window.hxx @@ -0,0 +1,123 @@ +/************************************************************** + * + * 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. + * + *************************************************************/ + +#ifndef _WINDOW_HXX +#define _WINDOW_HXX + +#include "macavfcommon.hxx" +#include <cppuhelper/interfacecontainer.h> + +#include "com/sun/star/media/XPlayerWindow.hdl" + +// --------------- +// - MyMediaView - +// --------------- + +@interface MyMediaView : NSView +@property (nonatomic, readonly, strong) AVPlayer* player; +@property (nonatomic, readonly, strong) AVPlayerLayer* playerLayer; +@property (nonatomic, retain) NSURL* videoURL; +- (void) play; +@end + +namespace avmedia { namespace macavf { + +// --------------- +// - Window - +// --------------- + +class Player; + +class Window +: public MacAVObserverHandler +, public ::cppu::WeakImplHelper2 < ::com::sun::star::media::XPlayerWindow, + ::com::sun::star::lang::XServiceInfo > +{ +public: + + Window( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& i_rxMgr, + Player& i_rPlayer, + NSView* i_pParentView + ); + virtual ~Window(); + + bool create( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ); + void processGraphEvent(); + void updatePointer(); + + // XPlayerWindow + virtual void SAL_CALL update( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL setZoomLevel( ::com::sun::star::media::ZoomLevel ZoomLevel ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::media::ZoomLevel SAL_CALL getZoomLevel( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPointerType( sal_Int32 nPointerType ) throw (::com::sun::star::uno::RuntimeException); + + // XWindow + virtual void SAL_CALL setPosSize( sal_Int32 X, sal_Int32 Y, sal_Int32 Width, sal_Int32 Height, sal_Int16 Flags ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Rectangle SAL_CALL getPosSize( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setVisible( sal_Bool Visible ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setEnable( sal_Bool Enable ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setFocus( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addWindowListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeWindowListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addFocusListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFocusListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeFocusListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFocusListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addKeyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XKeyListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeKeyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XKeyListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addMouseListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeMouseListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addMouseMotionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseMotionListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeMouseMotionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseMotionListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addPaintListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XPaintListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removePaintListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XPaintListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + + // XComponent + virtual void SAL_CALL dispose( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException); + + virtual bool handleObservation( NSString* pKeyPath ); + +private: + + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxMgr; + + ::osl::Mutex maMutex; + ::cppu::OMultiTypeInterfaceContainerHelper maListeners; + ::com::sun::star::media::ZoomLevel meZoomLevel; + Player& mrPlayer; + int mnPointerType; + + NSView* mpView; // parent-view == movie-view + AVPlayerLayer* mpPlayerLayer; + + void ImplLayoutVideoWindow(); +}; + +} // namespace macavf +} // namespace avmedia + +#endif // _WINDOW_HXX + diff --git a/main/scp2/source/ooo/file_library_ooo.scp b/main/scp2/source/ooo/file_library_ooo.scp index 6b94241..df8c8b3 100644 --- a/main/scp2/source/ooo/file_library_ooo.scp +++ b/main/scp2/source/ooo/file_library_ooo.scp @@ -615,6 +615,14 @@ File gid_File_Lib_avmediaQuickTime Name = LIBNAME(avmediaQuickTime); Dir = SCP2_OOO_BIN_DIR; End + +File gid_File_Lib_avmediaMacAVF + TXT_FILE_BODY; + Styles = (PACKED); + Name = LIBNAME(avmediaMacAVF); + Dir = SCP2_OOO_BIN_DIR; +End + #endif // MACOSX #ifdef OS2
