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