1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
29 #include "interface.hxx"
32 #include "framegrabber.hxx"
35 #include <cppuhelper/supportsservice.hxx>
36 #include <osl/file.hxx>
37 #include <tools/stream.hxx>
38 #include <vcl/graph.hxx>
39 #include <vcl/dibtools.hxx>
40 #include <o3tl/char16_t2wchar_t.hxx>
41 #include <systools/win32/oleauto.hxx>
43 constexpr OUStringLiteral AVMEDIA_WIN_FRAMEGRABBER_IMPLEMENTATIONNAME
= u
"com.sun.star.comp.avmedia.FrameGrabber_DirectX";
44 constexpr OUString AVMEDIA_WIN_FRAMEGRABBER_SERVICENAME
= u
"com.sun.star.media.FrameGrabber_DirectX"_ustr
;
46 using namespace ::com::sun::star
;
48 namespace avmedia::win
{
51 FrameGrabber::FrameGrabber()
52 : sal::systools::CoInitializeGuard(COINIT_APARTMENTTHREADED
, false,
53 sal::systools::CoInitializeGuard::WhenFailed::NoThrow
)
58 FrameGrabber::~FrameGrabber() = default;
62 sal::systools::COMReference
<IMediaDet
> implCreateMediaDet( const OUString
& rURL
)
64 sal::systools::COMReference
<IMediaDet
> pDet
;
66 if( SUCCEEDED(pDet
.CoCreateInstance(CLSID_MediaDet
, nullptr, CLSCTX_INPROC_SERVER
)) )
70 if( osl::FileBase::getSystemPathFromFileURL( rURL
, aLocalStr
)
71 == osl::FileBase::E_None
)
73 if( !SUCCEEDED( pDet
->put_Filename(sal::systools::BStr(aLocalStr
)) ) )
83 bool FrameGrabber::create( const OUString
& rURL
)
85 // just check if a MediaDet interface can be created with the given URL
86 if (implCreateMediaDet(rURL
))
91 return !maURL
.isEmpty();
95 uno::Reference
< graphic::XGraphic
> SAL_CALL
FrameGrabber::grabFrame( double fMediaTime
)
97 uno::Reference
< graphic::XGraphic
> xRet
;
98 if (sal::systools::COMReference
<IMediaDet
> pDet
= implCreateMediaDet(maURL
))
104 if( SUCCEEDED( pDet
->get_OutputStreams( &nStreamCount
) ) )
106 for( long n
= 0; ( n
< nStreamCount
) && !bFound
; ++n
)
110 if( SUCCEEDED( pDet
->put_CurrentStream( n
) ) &&
111 SUCCEEDED( pDet
->get_StreamType( &aMajorType
) ) &&
112 ( aMajorType
== MEDIATYPE_Video
) )
120 ( S_OK
== pDet
->get_StreamLength( &fLength
) ) &&
121 ( fLength
> 0.0 ) && ( fMediaTime
>= 0.0 ) && ( fMediaTime
<= fLength
) )
123 AM_MEDIA_TYPE aMediaType
;
124 LONG nWidth
= 0, nHeight
= 0;
127 if( SUCCEEDED( pDet
->get_StreamMediaType( &aMediaType
) ) )
129 if( ( aMediaType
.formattype
== FORMAT_VideoInfo
) &&
130 ( aMediaType
.cbFormat
>= sizeof( VIDEOINFOHEADER
) ) )
132 VIDEOINFOHEADER
* pVih
= reinterpret_cast< VIDEOINFOHEADER
* >( aMediaType
.pbFormat
);
134 nWidth
= pVih
->bmiHeader
.biWidth
;
135 nHeight
= pVih
->bmiHeader
.biHeight
;
141 if( aMediaType
.cbFormat
!= 0 )
143 ::CoTaskMemFree( aMediaType
.pbFormat
);
144 aMediaType
.cbFormat
= 0;
145 aMediaType
.pbFormat
= nullptr;
148 if( aMediaType
.pUnk
!= nullptr )
150 aMediaType
.pUnk
->Release();
151 aMediaType
.pUnk
= nullptr;
155 if( ( nWidth
> 0 ) && ( nHeight
> 0 ) &&
156 SUCCEEDED( pDet
->GetBitmapBits( 0, &nSize
, nullptr, nWidth
, nHeight
) ) &&
159 auto pBuffer
= std::make_unique
<char[]>(nSize
);
163 if( SUCCEEDED( pDet
->GetBitmapBits( fMediaTime
, nullptr, pBuffer
.get(), nWidth
, nHeight
) ) )
165 SvMemoryStream
aMemStm( pBuffer
.get(), nSize
, StreamMode::READ
| StreamMode::WRITE
);
168 if( ReadDIB(aBmp
, aMemStm
, false ) && !aBmp
.IsEmpty() )
170 BitmapEx
aBitmapEx(aBmp
);
171 Graphic
aGraphic(aBitmapEx
);
172 xRet
= aGraphic
.GetXGraphic();
187 OUString SAL_CALL
FrameGrabber::getImplementationName( )
189 return AVMEDIA_WIN_FRAMEGRABBER_IMPLEMENTATIONNAME
;
193 sal_Bool SAL_CALL
FrameGrabber::supportsService( const OUString
& ServiceName
)
195 return cppu::supportsService(this, ServiceName
);
199 uno::Sequence
< OUString
> SAL_CALL
FrameGrabber::getSupportedServiceNames( )
201 return { AVMEDIA_WIN_FRAMEGRABBER_SERVICENAME
};
204 } // namespace avmedia::win
207 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */