1eb7664d6SHerbert Dürr /************************************************************** 2eb7664d6SHerbert Dürr * 3eb7664d6SHerbert Dürr * Licensed to the Apache Software Foundation (ASF) under one 4eb7664d6SHerbert Dürr * or more contributor license agreements. See the NOTICE file 5eb7664d6SHerbert Dürr * distributed with this work for additional information 6eb7664d6SHerbert Dürr * regarding copyright ownership. The ASF licenses this file 7eb7664d6SHerbert Dürr * to you under the Apache License, Version 2.0 (the 8eb7664d6SHerbert Dürr * "License"); you may not use this file except in compliance 9eb7664d6SHerbert Dürr * with the License. You may obtain a copy of the License at 10eb7664d6SHerbert Dürr * 11eb7664d6SHerbert Dürr * http://www.apache.org/licenses/LICENSE-2.0 12eb7664d6SHerbert Dürr * 13eb7664d6SHerbert Dürr * Unless required by applicable law or agreed to in writing, 14eb7664d6SHerbert Dürr * software distributed under the License is distributed on an 15eb7664d6SHerbert Dürr * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16eb7664d6SHerbert Dürr * KIND, either express or implied. See the License for the 17eb7664d6SHerbert Dürr * specific language governing permissions and limitations 18eb7664d6SHerbert Dürr * under the License. 19eb7664d6SHerbert Dürr * 20eb7664d6SHerbert Dürr *************************************************************/ 21eb7664d6SHerbert Dürr 22*e8649ecdSHerbert Dürr #include "macavf_framegrabber.hxx" 23*e8649ecdSHerbert Dürr #include "macavf_player.hxx" 24eb7664d6SHerbert Dürr 25eb7664d6SHerbert Dürr #include <tools/stream.hxx> 26eb7664d6SHerbert Dürr #include <vcl/graph.hxx> 27eb7664d6SHerbert Dürr #include <vcl/cvtgrf.hxx> 28eb7664d6SHerbert Dürr #include <unotools/localfilehelper.hxx> 29eb7664d6SHerbert Dürr 30eb7664d6SHerbert Dürr using namespace ::com::sun::star; 31eb7664d6SHerbert Dürr 32eb7664d6SHerbert Dürr namespace avmedia { namespace macavf { 33eb7664d6SHerbert Dürr 34eb7664d6SHerbert Dürr // ---------------- 35eb7664d6SHerbert Dürr // - FrameGrabber - 36eb7664d6SHerbert Dürr // ---------------- 37eb7664d6SHerbert Dürr 38eb7664d6SHerbert Dürr FrameGrabber::FrameGrabber( const uno::Reference< lang::XMultiServiceFactory >& /*rxMgr*/ ) 39eb7664d6SHerbert Dürr : mpImageGen( NULL ) 40eb7664d6SHerbert Dürr {} 41eb7664d6SHerbert Dürr 42eb7664d6SHerbert Dürr // ------------------------------------------------------------------------------ 43eb7664d6SHerbert Dürr 44eb7664d6SHerbert Dürr FrameGrabber::~FrameGrabber() 45eb7664d6SHerbert Dürr { 46eb7664d6SHerbert Dürr if( mpImageGen ) 47eb7664d6SHerbert Dürr CFRelease( mpImageGen ); 48eb7664d6SHerbert Dürr } 49eb7664d6SHerbert Dürr 50eb7664d6SHerbert Dürr // ------------------------------------------------------------------------------ 51eb7664d6SHerbert Dürr 52eb7664d6SHerbert Dürr bool FrameGrabber::create( const ::rtl::OUString& rURL ) 53eb7664d6SHerbert Dürr { 54eb7664d6SHerbert Dürr // TODO: use AVPlayer's movie directly instead of loading it here? 55eb7664d6SHerbert Dürr 56eb7664d6SHerbert Dürr NSString* pNSStr = [NSString stringWithCharacters:rURL.getStr() length:rURL.getLength()]; 57eb7664d6SHerbert Dürr NSURL* pNSURL = [NSURL URLWithString: [pNSStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; 58eb7664d6SHerbert Dürr AVAsset* pMovie = [AVURLAsset URLAssetWithURL:pNSURL options:nil]; 59eb7664d6SHerbert Dürr if( !pMovie ) 60eb7664d6SHerbert Dürr { 61eb7664d6SHerbert Dürr OSL_TRACE( "AVGrabber::create() cannot load url=\"%s\"", [pNSStr UTF8String] ); 62eb7664d6SHerbert Dürr return false; 63eb7664d6SHerbert Dürr } 64eb7664d6SHerbert Dürr if( [[pMovie tracksWithMediaType:AVMediaTypeVideo] count] == 0) 65eb7664d6SHerbert Dürr { 66eb7664d6SHerbert Dürr OSL_TRACE( "AVGrabber::create() found no video in url=\"%s\"", [pNSStr UTF8String] ); 67eb7664d6SHerbert Dürr return false; 68eb7664d6SHerbert Dürr } 69eb7664d6SHerbert Dürr 70eb7664d6SHerbert Dürr mpImageGen = [AVAssetImageGenerator assetImageGeneratorWithAsset:pMovie]; 71eb7664d6SHerbert Dürr CFRetain( mpImageGen ); 72eb7664d6SHerbert Dürr return true; 73eb7664d6SHerbert Dürr } 74eb7664d6SHerbert Dürr 75eb7664d6SHerbert Dürr // ------------------------------------------------------------------------------ 76eb7664d6SHerbert Dürr 77eb7664d6SHerbert Dürr uno::Reference< graphic::XGraphic > SAL_CALL FrameGrabber::grabFrame( double fMediaTime ) 78eb7664d6SHerbert Dürr throw (uno::RuntimeException) 79eb7664d6SHerbert Dürr { 80eb7664d6SHerbert Dürr uno::Reference< graphic::XGraphic > xRet; 81eb7664d6SHerbert Dürr if( !mpImageGen ) 82eb7664d6SHerbert Dürr return xRet; 83eb7664d6SHerbert Dürr OSL_TRACE( "AVPlayer::grabFrame( %.3fsec)", fMediaTime ); 84eb7664d6SHerbert Dürr 85eb7664d6SHerbert Dürr // get the requested image from the movie 86eb7664d6SHerbert Dürr CGImage* pCGImage = [mpImageGen copyCGImageAtTime:CMTimeMakeWithSeconds(fMediaTime,1000) actualTime:NULL error:NULL]; 87eb7664d6SHerbert Dürr 88eb7664d6SHerbert Dürr // convert the image to a TIFF-formatted byte-array 89eb7664d6SHerbert Dürr CFMutableDataRef pCFData = CFDataCreateMutable( kCFAllocatorDefault, 0 ); 90eb7664d6SHerbert Dürr CGImageDestination* pCGImgDest = CGImageDestinationCreateWithData( pCFData, kUTTypeTIFF, 1, 0 ); 91eb7664d6SHerbert Dürr CGImageDestinationAddImage( pCGImgDest, pCGImage, NULL ); 92eb7664d6SHerbert Dürr CGImageDestinationFinalize( pCGImgDest ); 93eb7664d6SHerbert Dürr CFRelease( pCGImgDest ); 94eb7664d6SHerbert Dürr const long nBitmapLen = CFDataGetLength( pCFData ); 95eb7664d6SHerbert Dürr void* pBitmapBytes = (void*)CFDataGetBytePtr( pCFData ); 96eb7664d6SHerbert Dürr 97eb7664d6SHerbert Dürr // convert the image into the return-value type which is a graphic::XGraphic 98eb7664d6SHerbert Dürr SvMemoryStream aMemStm( pBitmapBytes, nBitmapLen, STREAM_READ | STREAM_WRITE ); 99eb7664d6SHerbert Dürr Graphic aGraphic; 100eb7664d6SHerbert Dürr if( GraphicConverter::Import( aMemStm, aGraphic, CVT_TIF ) == ERRCODE_NONE ) 101eb7664d6SHerbert Dürr xRet = aGraphic.GetXGraphic(); 102eb7664d6SHerbert Dürr 103eb7664d6SHerbert Dürr // clean up resources 104eb7664d6SHerbert Dürr CFRelease( pCFData ); 105eb7664d6SHerbert Dürr return xRet; 106eb7664d6SHerbert Dürr } 107eb7664d6SHerbert Dürr 108eb7664d6SHerbert Dürr // ------------------------------------------------------------------------------ 109eb7664d6SHerbert Dürr 110eb7664d6SHerbert Dürr ::rtl::OUString SAL_CALL FrameGrabber::getImplementationName( ) 111eb7664d6SHerbert Dürr throw (uno::RuntimeException) 112eb7664d6SHerbert Dürr { 113eb7664d6SHerbert Dürr return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( AVMEDIA_MACAVF_FRAMEGRABBER_IMPLEMENTATIONNAME ) ); 114eb7664d6SHerbert Dürr } 115eb7664d6SHerbert Dürr 116eb7664d6SHerbert Dürr // ------------------------------------------------------------------------------ 117eb7664d6SHerbert Dürr 118eb7664d6SHerbert Dürr sal_Bool SAL_CALL FrameGrabber::supportsService( const ::rtl::OUString& ServiceName ) 119eb7664d6SHerbert Dürr throw (uno::RuntimeException) 120eb7664d6SHerbert Dürr { 121eb7664d6SHerbert Dürr return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( AVMEDIA_MACAVF_FRAMEGRABBER_SERVICENAME ) ); 122eb7664d6SHerbert Dürr } 123eb7664d6SHerbert Dürr 124eb7664d6SHerbert Dürr // ------------------------------------------------------------------------------ 125eb7664d6SHerbert Dürr 126eb7664d6SHerbert Dürr uno::Sequence< ::rtl::OUString > SAL_CALL FrameGrabber::getSupportedServiceNames( ) 127eb7664d6SHerbert Dürr throw (uno::RuntimeException) 128eb7664d6SHerbert Dürr { 129eb7664d6SHerbert Dürr uno::Sequence< ::rtl::OUString > aRet(1); 130eb7664d6SHerbert Dürr aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( AVMEDIA_MACAVF_FRAMEGRABBER_SERVICENAME ) ); 131eb7664d6SHerbert Dürr 132eb7664d6SHerbert Dürr return aRet; 133eb7664d6SHerbert Dürr } 134eb7664d6SHerbert Dürr 135eb7664d6SHerbert Dürr } // namespace macavf 136eb7664d6SHerbert Dürr } // namespace avmedia 137eb7664d6SHerbert Dürr 138