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 23 24 #include <tools/prewin.h> 25 #if defined _MSC_VER 26 #pragma warning(push, 1) 27 #pragma warning(disable: 4917) 28 #endif 29 #include <windows.h> 30 #include <objbase.h> 31 #include <strmif.h> 32 #include <Amvideo.h> 33 #if defined(_MSC_VER) && (_MSC_VER < 1500) 34 #include <Qedit.h> 35 #else 36 #include "interface.hxx" 37 #endif 38 #include <uuids.h> 39 #if defined _MSC_VER 40 #pragma warning(pop) 41 #endif 42 #include <tools/postwin.h> 43 44 #include "framegrabber.hxx" 45 #include "player.hxx" 46 47 #include <tools/stream.hxx> 48 #include <vcl/graph.hxx> 49 #include <unotools/localfilehelper.hxx> 50 51 #define AVMEDIA_WIN_FRAMEGRABBER_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.FrameGrabber_DirectX" 52 #define AVMEDIA_WIN_FRAMEGRABBER_SERVICENAME "com.sun.star.media.FrameGrabber_DirectX" 53 54 using namespace ::com::sun::star; 55 56 namespace avmedia { namespace win { 57 58 // ---------------- 59 // - FrameGrabber - 60 // ---------------- 61 62 FrameGrabber::FrameGrabber( const uno::Reference< lang::XMultiServiceFactory >& rxMgr ) : 63 mxMgr( rxMgr ) 64 { 65 ::CoInitialize( NULL ); 66 } 67 68 // ------------------------------------------------------------------------------ 69 70 FrameGrabber::~FrameGrabber() 71 { 72 ::CoUninitialize(); 73 } 74 75 // ------------------------------------------------------------------------------ 76 77 IMediaDet* FrameGrabber::implCreateMediaDet( const ::rtl::OUString& rURL ) const 78 { 79 IMediaDet* pDet = NULL; 80 81 if( SUCCEEDED( CoCreateInstance( CLSID_MediaDet, NULL, CLSCTX_INPROC_SERVER, IID_IMediaDet, (void**) &pDet ) ) ) 82 { 83 String aLocalStr; 84 85 if( ::utl::LocalFileHelper::ConvertURLToPhysicalName( rURL, aLocalStr ) && aLocalStr.Len() ) 86 { 87 if( !SUCCEEDED( pDet->put_Filename( ::SysAllocString( reinterpret_cast<LPCOLESTR>(aLocalStr.GetBuffer()) ) ) ) ) 88 { 89 pDet->Release(); 90 pDet = NULL; 91 } 92 } 93 } 94 95 return pDet; 96 } 97 98 // ------------------------------------------------------------------------------ 99 100 bool FrameGrabber::create( const ::rtl::OUString& rURL ) 101 { 102 // just check if a MediaDet interface can be created with the given URL 103 IMediaDet* pDet = implCreateMediaDet( rURL ); 104 105 if( pDet ) 106 { 107 maURL = rURL; 108 pDet->Release(); 109 pDet = NULL; 110 } 111 else 112 maURL = ::rtl::OUString(); 113 114 return( maURL.getLength() > 0 ); 115 } 116 117 // ------------------------------------------------------------------------------ 118 119 uno::Reference< graphic::XGraphic > SAL_CALL FrameGrabber::grabFrame( double fMediaTime ) 120 throw (uno::RuntimeException) 121 { 122 uno::Reference< graphic::XGraphic > xRet; 123 IMediaDet* pDet = implCreateMediaDet( maURL ); 124 125 if( pDet ) 126 { 127 double fLength; 128 long nStreamCount; 129 bool bFound = false; 130 131 if( SUCCEEDED( pDet->get_OutputStreams( &nStreamCount ) ) ) 132 { 133 for( long n = 0; ( n < nStreamCount ) && !bFound; ++n ) 134 { 135 GUID aMajorType; 136 137 if( SUCCEEDED( pDet->put_CurrentStream( n ) ) && 138 SUCCEEDED( pDet->get_StreamType( &aMajorType ) ) && 139 ( aMajorType == MEDIATYPE_Video ) ) 140 { 141 bFound = true; 142 } 143 } 144 } 145 146 if( bFound && 147 ( S_OK == pDet->get_StreamLength( &fLength ) ) && 148 ( fLength > 0.0 ) && ( fMediaTime >= 0.0 ) && ( fMediaTime <= fLength ) ) 149 { 150 AM_MEDIA_TYPE aMediaType; 151 long nWidth = 0, nHeight = 0, nSize = 0; 152 153 if( SUCCEEDED( pDet->get_StreamMediaType( &aMediaType ) ) ) 154 { 155 if( ( aMediaType.formattype == FORMAT_VideoInfo ) && 156 ( aMediaType.cbFormat >= sizeof( VIDEOINFOHEADER ) ) ) 157 { 158 VIDEOINFOHEADER* pVih = reinterpret_cast< VIDEOINFOHEADER* >( aMediaType.pbFormat ); 159 160 nWidth = pVih->bmiHeader.biWidth; 161 nHeight = pVih->bmiHeader.biHeight; 162 163 if( nHeight < 0 ) 164 nHeight *= -1; 165 } 166 167 if( aMediaType.cbFormat != 0 ) 168 { 169 ::CoTaskMemFree( (PVOID) aMediaType.pbFormat ); 170 aMediaType.cbFormat = 0; 171 aMediaType.pbFormat = NULL; 172 } 173 174 if( aMediaType.pUnk != NULL ) 175 { 176 aMediaType.pUnk->Release(); 177 aMediaType.pUnk = NULL; 178 } 179 } 180 181 if( ( nWidth > 0 ) && ( nHeight > 0 ) && 182 SUCCEEDED( pDet->GetBitmapBits( 0, &nSize, NULL, nWidth, nHeight ) ) && 183 ( nSize > 0 ) ) 184 { 185 char* pBuffer = new char[ nSize ]; 186 187 try 188 { 189 if( SUCCEEDED( pDet->GetBitmapBits( fMediaTime, NULL, pBuffer, nWidth, nHeight ) ) ) 190 { 191 SvMemoryStream aMemStm( pBuffer, nSize, STREAM_READ | STREAM_WRITE ); 192 Bitmap aBmp; 193 194 if( aBmp.Read( aMemStm, false ) && !aBmp.IsEmpty() ) 195 { 196 const Graphic aGraphic( aBmp ); 197 xRet = aGraphic.GetXGraphic(); 198 } 199 } 200 } 201 catch( ... ) 202 { 203 } 204 205 delete [] pBuffer; 206 } 207 } 208 209 pDet->Release(); 210 } 211 212 return xRet; 213 } 214 215 // ------------------------------------------------------------------------------ 216 217 ::rtl::OUString SAL_CALL FrameGrabber::getImplementationName( ) 218 throw (uno::RuntimeException) 219 { 220 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( AVMEDIA_WIN_FRAMEGRABBER_IMPLEMENTATIONNAME ) ); 221 } 222 223 // ------------------------------------------------------------------------------ 224 225 sal_Bool SAL_CALL FrameGrabber::supportsService( const ::rtl::OUString& ServiceName ) 226 throw (uno::RuntimeException) 227 { 228 return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( AVMEDIA_WIN_FRAMEGRABBER_SERVICENAME ) ); 229 } 230 231 // ------------------------------------------------------------------------------ 232 233 uno::Sequence< ::rtl::OUString > SAL_CALL FrameGrabber::getSupportedServiceNames( ) 234 throw (uno::RuntimeException) 235 { 236 uno::Sequence< ::rtl::OUString > aRet(1); 237 aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( AVMEDIA_WIN_FRAMEGRABBER_SERVICENAME ) ); 238 239 return aRet; 240 } 241 242 } // namespace win 243 } // namespace avmedia 244