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