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< uno::XComponentContext >& rxContext ) : 64 mxContext( rxContext ) 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.isEmpty(); 116 } 117 118 // ------------------------------------------------------------------------------ 119 120 uno::Reference< graphic::XGraphic > SAL_CALL FrameGrabber::grabFrame( double fMediaTime ) 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( ReadDIB(aBmp, 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 { 219 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( AVMEDIA_WIN_FRAMEGRABBER_IMPLEMENTATIONNAME ) ); 220 } 221 222 // ------------------------------------------------------------------------------ 223 224 sal_Bool SAL_CALL FrameGrabber::supportsService( const ::rtl::OUString& ServiceName ) 225 { 226 return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( AVMEDIA_WIN_FRAMEGRABBER_SERVICENAME ) ); 227 } 228 229 // ------------------------------------------------------------------------------ 230 231 uno::Sequence< ::rtl::OUString > SAL_CALL FrameGrabber::getSupportedServiceNames( ) 232 { 233 uno::Sequence< ::rtl::OUString > aRet(1); 234 aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( AVMEDIA_WIN_FRAMEGRABBER_SERVICENAME ) ); 235 236 return aRet; 237 } 238 239 } // namespace win 240 } // namespace avmedia 241