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