1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include <tools/prewin.h> 29 #if defined _MSC_VER 30 #pragma warning(push, 1) 31 #pragma warning(disable: 4917) 32 #endif 33 #include <windows.h> 34 #include <objbase.h> 35 #include <strmif.h> 36 #include <Amvideo.h> 37 #if defined(_MSC_VER) && (_MSC_VER < 1500) 38 #include <Qedit.h> 39 #else 40 #include "interface.hxx" 41 #endif 42 #include <uuids.h> 43 #if defined _MSC_VER 44 #pragma warning(pop) 45 #endif 46 #include <tools/postwin.h> 47 48 #include "framegrabber.hxx" 49 #include "player.hxx" 50 51 #include <tools/stream.hxx> 52 #include <vcl/graph.hxx> 53 #include <unotools/localfilehelper.hxx> 54 55 #define AVMEDIA_WIN_FRAMEGRABBER_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.FrameGrabber_DirectX" 56 #define AVMEDIA_WIN_FRAMEGRABBER_SERVICENAME "com.sun.star.media.FrameGrabber_DirectX" 57 58 using namespace ::com::sun::star; 59 60 namespace avmedia { namespace win { 61 62 // ---------------- 63 // - FrameGrabber - 64 // ---------------- 65 66 FrameGrabber::FrameGrabber( const uno::Reference< lang::XMultiServiceFactory >& rxMgr ) : 67 mxMgr( rxMgr ) 68 { 69 ::CoInitialize( NULL ); 70 } 71 72 // ------------------------------------------------------------------------------ 73 74 FrameGrabber::~FrameGrabber() 75 { 76 ::CoUninitialize(); 77 } 78 79 // ------------------------------------------------------------------------------ 80 81 IMediaDet* FrameGrabber::implCreateMediaDet( const ::rtl::OUString& rURL ) const 82 { 83 IMediaDet* pDet = NULL; 84 85 if( SUCCEEDED( CoCreateInstance( CLSID_MediaDet, NULL, CLSCTX_INPROC_SERVER, IID_IMediaDet, (void**) &pDet ) ) ) 86 { 87 String aLocalStr; 88 89 if( ::utl::LocalFileHelper::ConvertURLToPhysicalName( rURL, aLocalStr ) && aLocalStr.Len() ) 90 { 91 if( !SUCCEEDED( pDet->put_Filename( ::SysAllocString( reinterpret_cast<LPCOLESTR>(aLocalStr.GetBuffer()) ) ) ) ) 92 { 93 pDet->Release(); 94 pDet = NULL; 95 } 96 } 97 } 98 99 return pDet; 100 } 101 102 // ------------------------------------------------------------------------------ 103 104 bool FrameGrabber::create( const ::rtl::OUString& rURL ) 105 { 106 // just check if a MediaDet interface can be created with the given URL 107 IMediaDet* pDet = implCreateMediaDet( rURL ); 108 109 if( pDet ) 110 { 111 maURL = rURL; 112 pDet->Release(); 113 pDet = NULL; 114 } 115 else 116 maURL = ::rtl::OUString(); 117 118 return( maURL.getLength() > 0 ); 119 } 120 121 // ------------------------------------------------------------------------------ 122 123 uno::Reference< graphic::XGraphic > SAL_CALL FrameGrabber::grabFrame( double fMediaTime ) 124 throw (uno::RuntimeException) 125 { 126 uno::Reference< graphic::XGraphic > xRet; 127 IMediaDet* pDet = implCreateMediaDet( maURL ); 128 129 if( pDet ) 130 { 131 double fLength; 132 long nStreamCount; 133 bool bFound = false; 134 135 if( SUCCEEDED( pDet->get_OutputStreams( &nStreamCount ) ) ) 136 { 137 for( long n = 0; ( n < nStreamCount ) && !bFound; ++n ) 138 { 139 GUID aMajorType; 140 141 if( SUCCEEDED( pDet->put_CurrentStream( n ) ) && 142 SUCCEEDED( pDet->get_StreamType( &aMajorType ) ) && 143 ( aMajorType == MEDIATYPE_Video ) ) 144 { 145 bFound = true; 146 } 147 } 148 } 149 150 if( bFound && 151 ( S_OK == pDet->get_StreamLength( &fLength ) ) && 152 ( fLength > 0.0 ) && ( fMediaTime >= 0.0 ) && ( fMediaTime <= fLength ) ) 153 { 154 AM_MEDIA_TYPE aMediaType; 155 long nWidth = 0, nHeight = 0, nSize = 0; 156 157 if( SUCCEEDED( pDet->get_StreamMediaType( &aMediaType ) ) ) 158 { 159 if( ( aMediaType.formattype == FORMAT_VideoInfo ) && 160 ( aMediaType.cbFormat >= sizeof( VIDEOINFOHEADER ) ) ) 161 { 162 VIDEOINFOHEADER* pVih = reinterpret_cast< VIDEOINFOHEADER* >( aMediaType.pbFormat ); 163 164 nWidth = pVih->bmiHeader.biWidth; 165 nHeight = pVih->bmiHeader.biHeight; 166 167 if( nHeight < 0 ) 168 nHeight *= -1; 169 } 170 171 if( aMediaType.cbFormat != 0 ) 172 { 173 ::CoTaskMemFree( (PVOID) aMediaType.pbFormat ); 174 aMediaType.cbFormat = 0; 175 aMediaType.pbFormat = NULL; 176 } 177 178 if( aMediaType.pUnk != NULL ) 179 { 180 aMediaType.pUnk->Release(); 181 aMediaType.pUnk = NULL; 182 } 183 } 184 185 if( ( nWidth > 0 ) && ( nHeight > 0 ) && 186 SUCCEEDED( pDet->GetBitmapBits( 0, &nSize, NULL, nWidth, nHeight ) ) && 187 ( nSize > 0 ) ) 188 { 189 char* pBuffer = new char[ nSize ]; 190 191 try 192 { 193 if( SUCCEEDED( pDet->GetBitmapBits( fMediaTime, NULL, pBuffer, nWidth, nHeight ) ) ) 194 { 195 SvMemoryStream aMemStm( pBuffer, nSize, STREAM_READ | STREAM_WRITE ); 196 Bitmap aBmp; 197 198 if( aBmp.Read( aMemStm, false ) && !aBmp.IsEmpty() ) 199 { 200 const Graphic aGraphic( aBmp ); 201 xRet = aGraphic.GetXGraphic(); 202 } 203 } 204 } 205 catch( ... ) 206 { 207 } 208 209 delete [] pBuffer; 210 } 211 } 212 213 pDet->Release(); 214 } 215 216 return xRet; 217 } 218 219 // ------------------------------------------------------------------------------ 220 221 ::rtl::OUString SAL_CALL FrameGrabber::getImplementationName( ) 222 throw (uno::RuntimeException) 223 { 224 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( AVMEDIA_WIN_FRAMEGRABBER_IMPLEMENTATIONNAME ) ); 225 } 226 227 // ------------------------------------------------------------------------------ 228 229 sal_Bool SAL_CALL FrameGrabber::supportsService( const ::rtl::OUString& ServiceName ) 230 throw (uno::RuntimeException) 231 { 232 return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( AVMEDIA_WIN_FRAMEGRABBER_SERVICENAME ) ); 233 } 234 235 // ------------------------------------------------------------------------------ 236 237 uno::Sequence< ::rtl::OUString > SAL_CALL FrameGrabber::getSupportedServiceNames( ) 238 throw (uno::RuntimeException) 239 { 240 uno::Sequence< ::rtl::OUString > aRet(1); 241 aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( AVMEDIA_WIN_FRAMEGRABBER_SERVICENAME ) ); 242 243 return aRet; 244 } 245 246 } // namespace win 247 } // namespace avmedia 248