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