1 // Defines the transform class.
2 //
3 // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
4 // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
5 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
6 // PARTICULAR PURPOSE.
7 //
8 // Copyright (c) Microsoft Corporation. All rights reserved.
9 
10 #ifndef GRAYSCALE_H
11 #define GRAYSCALE_H
12 
13 #include <new>
14 #include <mfapi.h>
15 #include <mftransform.h>
16 #include <mfidl.h>
17 #include <mferror.h>
18 #include <strsafe.h>
19 #include <assert.h>
20 
21 #include <wrl\implements.h>
22 #include <wrl\module.h>
23 #include <windows.media.h>
24 
25 #include "OcvImageManipulations.h"
26 
27 // CLSID of the MFT.
28 DEFINE_GUID(CLSID_GrayscaleMFT,
29 0x2f3dbc05, 0xc011, 0x4a8f, 0xb2, 0x64, 0xe4, 0x2e, 0x35, 0xc6, 0x7b, 0xf4);
30 
31 //
32 // * IMPORTANT: If you implement your own MFT, create a new GUID for the CLSID. *
33 //
34 
35 
36 // Configuration attributes
37 // {698649BE-8EAE-4551-A4CB-3EC98FBD3D86}
38 DEFINE_GUID(OCV_IMAGE_EFFECT,
39 0x698649be, 0x8eae, 0x4551, 0xa4, 0xcb, 0x3e, 0xc9, 0x8f, 0xbd, 0x3d, 0x86);
40 
41 
42 enum ProcessingType
43 {
44     Preview,
45     GrayScale,
46     Canny,
47     Sobel,
48     Histogram,
49     InvalidEffect
50 };
51 
SafeRelease(T ** ppT)52 template <class T> void SafeRelease(T **ppT)
53 {
54     if (*ppT)
55     {
56         (*ppT)->Release();
57         *ppT = NULL;
58     }
59 }
60 
61 // OcvImageManipulations class:
62 // Implements a grayscale video effect.
63 
64 class OcvImageManipulations
65     : public Microsoft::WRL::RuntimeClass<
66            Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::RuntimeClassType::WinRtClassicComMix >,
67            ABI::Windows::Media::IMediaExtension,
68            IMFTransform >
69 {
70     InspectableClass(RuntimeClass_OcvTransform_OcvImageManipulations, BaseTrust)
71 
72 public:
73     OcvImageManipulations();
74 
75     ~OcvImageManipulations();
76 
77     STDMETHOD(RuntimeClassInitialize)();
78 
79     // IMediaExtension
80     STDMETHODIMP SetProperties(ABI::Windows::Foundation::Collections::IPropertySet *pConfiguration);
81 
82     // IMFTransform
83     STDMETHODIMP GetStreamLimits(
84         DWORD   *pdwInputMinimum,
85         DWORD   *pdwInputMaximum,
86         DWORD   *pdwOutputMinimum,
87         DWORD   *pdwOutputMaximum
88     );
89 
90     STDMETHODIMP GetStreamCount(
91         DWORD   *pcInputStreams,
92         DWORD   *pcOutputStreams
93     );
94 
95     STDMETHODIMP GetStreamIDs(
96         DWORD   dwInputIDArraySize,
97         DWORD   *pdwInputIDs,
98         DWORD   dwOutputIDArraySize,
99         DWORD   *pdwOutputIDs
100     );
101 
102     STDMETHODIMP GetInputStreamInfo(
103         DWORD                     dwInputStreamID,
104         MFT_INPUT_STREAM_INFO *   pStreamInfo
105     );
106 
107     STDMETHODIMP GetOutputStreamInfo(
108         DWORD                     dwOutputStreamID,
109         MFT_OUTPUT_STREAM_INFO *  pStreamInfo
110     );
111 
112     STDMETHODIMP GetAttributes(IMFAttributes** pAttributes);
113 
114     STDMETHODIMP GetInputStreamAttributes(
115         DWORD           dwInputStreamID,
116         IMFAttributes   **ppAttributes
117     );
118 
119     STDMETHODIMP GetOutputStreamAttributes(
120         DWORD           dwOutputStreamID,
121         IMFAttributes   **ppAttributes
122     );
123 
124     STDMETHODIMP DeleteInputStream(DWORD dwStreamID);
125 
126     STDMETHODIMP AddInputStreams(
127         DWORD   cStreams,
128         DWORD   *adwStreamIDs
129     );
130 
131     STDMETHODIMP GetInputAvailableType(
132         DWORD           dwInputStreamID,
133         DWORD           dwTypeIndex, // 0-based
134         IMFMediaType    **ppType
135     );
136 
137     STDMETHODIMP GetOutputAvailableType(
138         DWORD           dwOutputStreamID,
139         DWORD           dwTypeIndex, // 0-based
140         IMFMediaType    **ppType
141     );
142 
143     STDMETHODIMP SetInputType(
144         DWORD           dwInputStreamID,
145         IMFMediaType    *pType,
146         DWORD           dwFlags
147     );
148 
149     STDMETHODIMP SetOutputType(
150         DWORD           dwOutputStreamID,
151         IMFMediaType    *pType,
152         DWORD           dwFlags
153     );
154 
155     STDMETHODIMP GetInputCurrentType(
156         DWORD           dwInputStreamID,
157         IMFMediaType    **ppType
158     );
159 
160     STDMETHODIMP GetOutputCurrentType(
161         DWORD           dwOutputStreamID,
162         IMFMediaType    **ppType
163     );
164 
165     STDMETHODIMP GetInputStatus(
166         DWORD           dwInputStreamID,
167         DWORD           *pdwFlags
168     );
169 
170     STDMETHODIMP GetOutputStatus(DWORD *pdwFlags);
171 
172     STDMETHODIMP SetOutputBounds(
173         LONGLONG        hnsLowerBound,
174         LONGLONG        hnsUpperBound
175     );
176 
177     STDMETHODIMP ProcessEvent(
178         DWORD              dwInputStreamID,
179         IMFMediaEvent      *pEvent
180     );
181 
182     STDMETHODIMP ProcessMessage(
183         MFT_MESSAGE_TYPE    eMessage,
184         ULONG_PTR           ulParam
185     );
186 
187     STDMETHODIMP ProcessInput(
188         DWORD               dwInputStreamID,
189         IMFSample           *pSample,
190         DWORD               dwFlags
191     );
192 
193     STDMETHODIMP ProcessOutput(
194         DWORD                   dwFlags,
195         DWORD                   cOutputBufferCount,
196         MFT_OUTPUT_DATA_BUFFER  *pOutputSamples, // one per stream
197         DWORD                   *pdwStatus
198     );
199 
200 
201 private:
202     // HasPendingOutput: Returns TRUE if the MFT is holding an input sample.
HasPendingOutput()203     BOOL HasPendingOutput() const { return m_pSample != NULL; }
204 
205     // IsValidInputStream: Returns TRUE if dwInputStreamID is a valid input stream identifier.
IsValidInputStream(DWORD dwInputStreamID)206     BOOL IsValidInputStream(DWORD dwInputStreamID) const
207     {
208         return dwInputStreamID == 0;
209     }
210 
211     // IsValidOutputStream: Returns TRUE if dwOutputStreamID is a valid output stream identifier.
IsValidOutputStream(DWORD dwOutputStreamID)212     BOOL IsValidOutputStream(DWORD dwOutputStreamID) const
213     {
214         return dwOutputStreamID == 0;
215     }
216 
217     HRESULT OnGetPartialType(DWORD dwTypeIndex, IMFMediaType **ppmt);
218     HRESULT OnCheckInputType(IMFMediaType *pmt);
219     HRESULT OnCheckOutputType(IMFMediaType *pmt);
220     HRESULT OnCheckMediaType(IMFMediaType *pmt);
221     void    OnSetInputType(IMFMediaType *pmt);
222     void    OnSetOutputType(IMFMediaType *pmt);
223     HRESULT BeginStreaming();
224     HRESULT EndStreaming();
225     HRESULT OnProcessOutput(IMFMediaBuffer *pIn, IMFMediaBuffer *pOut);
226     HRESULT OnFlush();
227     HRESULT UpdateFormatInfo();
228 
229     CRITICAL_SECTION            m_critSec;
230 
231     // Transformation parameters
232     ProcessingType              m_TransformType;
233 
234     // Streaming
235     bool                        m_bStreamingInitialized;
236     IMFSample                   *m_pSample;                 // Input sample.
237     IMFMediaType                *m_pInputType;              // Input media type.
238     IMFMediaType                *m_pOutputType;             // Output media type.
239 
240     // Fomat information
241     UINT32                      m_imageWidthInPixels;
242     UINT32                      m_imageHeightInPixels;
243     DWORD                       m_cbImageSize;              // Image size, in bytes.
244 
245     IMFAttributes               *m_pAttributes;
246 };
247 #endif
248