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<uno::XComponentContext> & rxContext)38 FrameGrabber::FrameGrabber( const uno::Reference< uno::XComponentContext >& rxContext )
39 : mpImageGen( NULL ),
40 mxContext( rxContext )
41 {}
42
43 // ------------------------------------------------------------------------------
44
~FrameGrabber()45 FrameGrabber::~FrameGrabber()
46 {
47 if( mpImageGen )
48 CFRelease( mpImageGen );
49 }
50
51 // ------------------------------------------------------------------------------
52
create(const::rtl::OUString & rURL)53 bool FrameGrabber::create( const ::rtl::OUString& rURL )
54 {
55 NSString* pNSStr = [NSString stringWithCharacters:rURL.getStr() length:rURL.getLength()];
56 NSURL* pNSURL = [NSURL URLWithString: [pNSStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
57 AVAsset* pMovie = [AVURLAsset URLAssetWithURL:pNSURL options:nil];
58 if( !pMovie )
59 {
60 OSL_TRACE( "AVGrabber::create() cannot load url=\"%s\"", [pNSStr UTF8String] );
61 return false;
62 }
63
64 return create( pMovie );
65 }
66
67 // ------------------------------------------------------------------------------
68
create(AVAsset * pMovie)69 bool FrameGrabber::create( AVAsset* pMovie )
70 {
71 if( [[pMovie tracksWithMediaType:AVMediaTypeVideo] count] == 0)
72 {
73 OSL_TRACE( "AVGrabber::create() found no video content!" );
74 return false;
75 }
76
77 mpImageGen = [AVAssetImageGenerator assetImageGeneratorWithAsset:pMovie];
78 CFRetain( mpImageGen );
79 return true;
80 }
81
82 // ------------------------------------------------------------------------------
83
grabFrame(double fMediaTime)84 uno::Reference< graphic::XGraphic > SAL_CALL FrameGrabber::grabFrame( double fMediaTime )
85 throw (uno::RuntimeException)
86 {
87 uno::Reference< graphic::XGraphic > xRet;
88 if( !mpImageGen )
89 return xRet;
90 OSL_TRACE( "AVPlayer::grabFrame( %.3fsec)", fMediaTime );
91
92 // get the requested image from the movie
93 CGImage* pCGImage = [mpImageGen copyCGImageAtTime:CMTimeMakeWithSeconds(fMediaTime,1000) actualTime:NULL error:NULL];
94
95 // convert the image to a TIFF-formatted byte-array
96 CFMutableDataRef pCFData = CFDataCreateMutable( kCFAllocatorDefault, 0 );
97 CGImageDestination* pCGImgDest = CGImageDestinationCreateWithData( pCFData, kUTTypeTIFF, 1, 0 );
98 CGImageDestinationAddImage( pCGImgDest, pCGImage, NULL );
99 CGImageDestinationFinalize( pCGImgDest );
100 CFRelease( pCGImgDest );
101 const long nBitmapLen = CFDataGetLength( pCFData );
102 void* pBitmapBytes = (void*)CFDataGetBytePtr( pCFData );
103
104 // convert the image into the return-value type which is a graphic::XGraphic
105 SvMemoryStream aMemStm( pBitmapBytes, nBitmapLen, STREAM_READ | STREAM_WRITE );
106 Graphic aGraphic;
107 if( GraphicConverter::Import( aMemStm, aGraphic, CVT_TIF ) == ERRCODE_NONE )
108 xRet = aGraphic.GetXGraphic();
109
110 // clean up resources
111 CFRelease( pCFData );
112 return xRet;
113 }
114
115 // ------------------------------------------------------------------------------
116
getImplementationName()117 ::rtl::OUString SAL_CALL FrameGrabber::getImplementationName( )
118 throw (uno::RuntimeException)
119 {
120 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( AVMEDIA_MACAVF_FRAMEGRABBER_IMPLEMENTATIONNAME ) );
121 }
122
123 // ------------------------------------------------------------------------------
124
supportsService(const::rtl::OUString & ServiceName)125 sal_Bool SAL_CALL FrameGrabber::supportsService( const ::rtl::OUString& ServiceName )
126 throw (uno::RuntimeException)
127 {
128 return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( AVMEDIA_MACAVF_FRAMEGRABBER_SERVICENAME ) );
129 }
130
131 // ------------------------------------------------------------------------------
132
getSupportedServiceNames()133 uno::Sequence< ::rtl::OUString > SAL_CALL FrameGrabber::getSupportedServiceNames( )
134 throw (uno::RuntimeException)
135 {
136 uno::Sequence< ::rtl::OUString > aRet(1);
137 aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( AVMEDIA_MACAVF_FRAMEGRABBER_SERVICENAME ) );
138
139 return aRet;
140 }
141
142 } // namespace macavf
143 } // namespace avmedia
144