1 | //////////////////////////////////////////////////////////// |
---|
2 | // Copyright (C) Roman Ryltsov, 2013 |
---|
3 | // Created by Roman Ryltsov roman@alax.info |
---|
4 | // |
---|
5 | // NOTE: This is to demonstrate the bugs |
---|
6 | // |
---|
7 | // Video Resizer DSP's IMediaObject::SetOutputType returns E_POINTER when it is not supposed to |
---|
8 | // http://connect.microsoft.com/VisualStudio/feedback/details/812418/video-resizer-dsps-imediaobject-setoutputtype-returns-e-pointer-when-it-is-not-supposed-to |
---|
9 | // |
---|
10 | // Digital Signal Processors do not honor flags arguments on DMO interface IMediaObject when setting input/output types |
---|
11 | // https://connect.microsoft.com/VisualStudio/feedback/details/812482/digital-signal-processors-do-not-honor-flags-arguments-on-dmo-interface-imediaobject-when-setting-input-output-types |
---|
12 | |
---|
13 | #include "stdafx.h" |
---|
14 | #include <windows.h> |
---|
15 | #include <dshow.h> |
---|
16 | #include <dmo.h> |
---|
17 | #include <wmcodecdsp.h> |
---|
18 | #include <atlcom.h> |
---|
19 | |
---|
20 | #pragma comment(lib, "strmiids.lib") |
---|
21 | #pragma comment(lib, "wmcodecdspuuid.lib") |
---|
22 | #pragma comment(lib, "msdmo.lib") |
---|
23 | |
---|
24 | //#define DSP CLSID_CResizerDMO |
---|
25 | //#define OUTPUTSUBTYPE MEDIASUBTYPE_YV12 |
---|
26 | //#define OUTPUTWIDTH 1280 |
---|
27 | //#define OUTPUTHEIGHT 720 |
---|
28 | //#define OUTPUTBITCOUNT 12 |
---|
29 | |
---|
30 | #define DSP CLSID_CColorConvertDMO |
---|
31 | #define OUTPUTSUBTYPE MEDIASUBTYPE_UYVY |
---|
32 | #define OUTPUTWIDTH 1920 |
---|
33 | #define OUTPUTHEIGHT 1080 |
---|
34 | #define OUTPUTBITCOUNT 16 |
---|
35 | |
---|
36 | VOID PrintInputType(IMediaObject* pMediaObject, HRESULT nExpectedResult = S_OK, LPCTSTR pszComment = _T("")) |
---|
37 | { |
---|
38 | ATLASSERT(pMediaObject); |
---|
39 | DMO_MEDIA_TYPE MediaType; |
---|
40 | ZeroMemory(&MediaType, sizeof MediaType); |
---|
41 | const HRESULT nGetInputCurrentTypeResult = pMediaObject->GetInputCurrentType(0, &MediaType); |
---|
42 | if(nGetInputCurrentTypeResult != nExpectedResult && _tcslen(pszComment)) |
---|
43 | _tprintf(_T("nGetInputCurrentTypeResult 0x%08x <<--- Incorrect, %s\n"), nGetInputCurrentTypeResult, pszComment); |
---|
44 | else |
---|
45 | _tprintf(_T("nGetInputCurrentTypeResult 0x%08x\n"), nGetInputCurrentTypeResult); |
---|
46 | if(FAILED(nGetInputCurrentTypeResult)) |
---|
47 | return; |
---|
48 | ATLASSERT(MediaType.formattype == FORMAT_VideoInfo); |
---|
49 | VIDEOINFOHEADER* pVideoInfoHeader = (VIDEOINFOHEADER*) MediaType.pbFormat; |
---|
50 | ATLASSERT(MediaType.cbFormat >= sizeof *pVideoInfoHeader); |
---|
51 | _tprintf(_T("Input: biWidth %d, biHeight %d\n"), pVideoInfoHeader->bmiHeader.biWidth, pVideoInfoHeader->bmiHeader.biHeight); |
---|
52 | ATLVERIFY(SUCCEEDED(MoFreeMediaType(&MediaType))); |
---|
53 | } |
---|
54 | VOID PrintOutputType(IMediaObject* pMediaObject, HRESULT nExpectedResult = S_OK, LPCTSTR pszComment = _T("")) |
---|
55 | { |
---|
56 | ATLASSERT(pMediaObject); |
---|
57 | DMO_MEDIA_TYPE MediaType; |
---|
58 | ZeroMemory(&MediaType, sizeof MediaType); |
---|
59 | const HRESULT nGetOutputCurrentTypeResult = pMediaObject->GetOutputCurrentType(0, &MediaType); |
---|
60 | if(nGetOutputCurrentTypeResult != nExpectedResult && _tcslen(pszComment)) |
---|
61 | _tprintf(_T("nGetOutputCurrentTypeResult 0x%08x <<--- Incorrect, %s\n"), nGetOutputCurrentTypeResult, pszComment); |
---|
62 | else |
---|
63 | _tprintf(_T("nGetOutputCurrentTypeResult 0x%08x\n"), nGetOutputCurrentTypeResult); |
---|
64 | if(FAILED(nGetOutputCurrentTypeResult)) |
---|
65 | return; |
---|
66 | ATLASSERT(MediaType.formattype == FORMAT_VideoInfo); |
---|
67 | VIDEOINFOHEADER* pVideoInfoHeader = (VIDEOINFOHEADER*) MediaType.pbFormat; |
---|
68 | ATLASSERT(MediaType.cbFormat >= sizeof *pVideoInfoHeader); |
---|
69 | _tprintf(_T("Output: biWidth %d, biHeight %d\n"), pVideoInfoHeader->bmiHeader.biWidth, pVideoInfoHeader->bmiHeader.biHeight); |
---|
70 | ATLVERIFY(SUCCEEDED(MoFreeMediaType(&MediaType))); |
---|
71 | } |
---|
72 | |
---|
73 | int _tmain(int argc, _TCHAR* argv[]) |
---|
74 | { |
---|
75 | CoInitialize(NULL); |
---|
76 | { |
---|
77 | CComPtr<IMediaObject> pMediaObject; |
---|
78 | ATLENSURE_SUCCEEDED(pMediaObject.CoCreateInstance(DSP)); |
---|
79 | #pragma region Set |
---|
80 | _tprintf(_T("\n*** Set ***\n\n")); |
---|
81 | #pragma region Input |
---|
82 | DMO_MEDIA_TYPE InputMediaType; |
---|
83 | ZeroMemory(&InputMediaType, sizeof InputMediaType); |
---|
84 | InputMediaType.majortype = MEDIATYPE_Video; |
---|
85 | InputMediaType.subtype = MEDIASUBTYPE_YV12; |
---|
86 | InputMediaType.bFixedSizeSamples = TRUE; |
---|
87 | InputMediaType.bTemporalCompression = FALSE; |
---|
88 | VIDEOINFOHEADER InputVideoInfoHeader; |
---|
89 | ZeroMemory(&InputVideoInfoHeader, sizeof InputVideoInfoHeader); |
---|
90 | BITMAPINFOHEADER& InputBitmapInfoHeader = InputVideoInfoHeader.bmiHeader; |
---|
91 | InputBitmapInfoHeader.biSize = sizeof InputBitmapInfoHeader; |
---|
92 | InputBitmapInfoHeader.biWidth = 1920; |
---|
93 | InputBitmapInfoHeader.biHeight = 1080; |
---|
94 | InputBitmapInfoHeader.biPlanes = 1; |
---|
95 | InputBitmapInfoHeader.biBitCount = 12; |
---|
96 | InputBitmapInfoHeader.biCompression = InputMediaType.subtype.Data1; |
---|
97 | InputBitmapInfoHeader.biSizeImage = InputBitmapInfoHeader.biHeight * InputBitmapInfoHeader.biWidth * InputBitmapInfoHeader.biBitCount / 8; |
---|
98 | InputMediaType.lSampleSize = InputBitmapInfoHeader.biSizeImage; |
---|
99 | InputMediaType.formattype = FORMAT_VideoInfo; |
---|
100 | InputMediaType.cbFormat = sizeof InputVideoInfoHeader; |
---|
101 | InputMediaType.pbFormat = (BYTE*) &InputVideoInfoHeader; |
---|
102 | #pragma endregion |
---|
103 | const HRESULT nTrySetInputTypeResult = pMediaObject->SetInputType(0, &InputMediaType, DMO_SET_TYPEF_TEST_ONLY); |
---|
104 | _tprintf(_T("nTrySetInputTypeResult 0x%08x\n"), nTrySetInputTypeResult); |
---|
105 | PrintInputType(pMediaObject, DMO_E_TYPE_NOT_SET, _T("we only tested, we did not set it")); |
---|
106 | const HRESULT nSetInputTypeResult = pMediaObject->SetInputType(0, &InputMediaType, 0); |
---|
107 | _tprintf(_T("nSetInputTypeResult 0x%08x\n"), nSetInputTypeResult); |
---|
108 | PrintInputType(pMediaObject); |
---|
109 | #pragma region Output |
---|
110 | DMO_MEDIA_TYPE OutputMediaType; |
---|
111 | ZeroMemory(&OutputMediaType, sizeof OutputMediaType); |
---|
112 | OutputMediaType.majortype = MEDIATYPE_Video; |
---|
113 | OutputMediaType.subtype = OUTPUTSUBTYPE; |
---|
114 | OutputMediaType.bFixedSizeSamples = TRUE; |
---|
115 | OutputMediaType.bTemporalCompression = FALSE; |
---|
116 | VIDEOINFOHEADER OutputVideoInfoHeader; |
---|
117 | ZeroMemory(&OutputVideoInfoHeader, sizeof OutputVideoInfoHeader); |
---|
118 | BITMAPINFOHEADER& OutputBitmapInfoHeader = OutputVideoInfoHeader.bmiHeader; |
---|
119 | OutputBitmapInfoHeader.biSize = sizeof OutputBitmapInfoHeader; |
---|
120 | OutputBitmapInfoHeader.biWidth = OUTPUTWIDTH; |
---|
121 | OutputBitmapInfoHeader.biHeight = OUTPUTHEIGHT; |
---|
122 | OutputBitmapInfoHeader.biPlanes = 1; |
---|
123 | OutputBitmapInfoHeader.biBitCount = OUTPUTBITCOUNT; |
---|
124 | OutputBitmapInfoHeader.biCompression = OutputMediaType.subtype.Data1; |
---|
125 | OutputBitmapInfoHeader.biSizeImage = OutputBitmapInfoHeader.biHeight * OutputBitmapInfoHeader.biWidth * OutputBitmapInfoHeader.biBitCount / 8; |
---|
126 | OutputMediaType.lSampleSize = OutputBitmapInfoHeader.biSizeImage; |
---|
127 | OutputMediaType.formattype = FORMAT_VideoInfo; |
---|
128 | OutputMediaType.cbFormat = sizeof OutputVideoInfoHeader; |
---|
129 | OutputMediaType.pbFormat = (BYTE*) &OutputVideoInfoHeader; |
---|
130 | #pragma endregion |
---|
131 | const HRESULT nTrySetOutputTypeResult = pMediaObject->SetOutputType(0, &OutputMediaType, DMO_SET_TYPEF_TEST_ONLY); |
---|
132 | _tprintf(_T("nTrySetOutputTypeResult 0x%08x\n"), nTrySetOutputTypeResult); |
---|
133 | PrintOutputType(pMediaObject, DMO_E_TYPE_NOT_SET, _T("we only tested, we did not set it")); |
---|
134 | const HRESULT nSetOutputTypeResult = pMediaObject->SetOutputType(0, &OutputMediaType, 0); |
---|
135 | _tprintf(_T("nSetOutputTypeResult 0x%08x\n"), nSetOutputTypeResult); |
---|
136 | PrintOutputType(pMediaObject); |
---|
137 | #pragma endregion |
---|
138 | ATLASSERT(nSetInputTypeResult == S_OK && nSetOutputTypeResult == S_OK); |
---|
139 | #pragma region Clear |
---|
140 | _tprintf(_T("\n*** Clear ***\n\n")); |
---|
141 | const HRESULT nResetInputTypeResult = pMediaObject->SetInputType(0, NULL, DMO_SET_TYPEF_CLEAR); |
---|
142 | _tprintf(_T("nResetInputTypeResult 0x%08x%s\n"), nResetInputTypeResult, FAILED(nResetInputTypeResult) ? _T(" <<--- Incorrect") : _T("")); |
---|
143 | PrintInputType(pMediaObject); |
---|
144 | const HRESULT nResetOutputTypeResult = pMediaObject->SetOutputType(0, NULL, DMO_SET_TYPEF_CLEAR); |
---|
145 | _tprintf(_T("nResetOutputTypeResult 0x%08x%s\n"), nResetOutputTypeResult, FAILED(nResetOutputTypeResult) ? _T(" <<--- Incorrect") : _T("")); |
---|
146 | PrintOutputType(pMediaObject); |
---|
147 | const HRESULT nAnotherResetInputTypeResult = pMediaObject->SetInputType(0, &InputMediaType, DMO_SET_TYPEF_CLEAR); |
---|
148 | _tprintf(_T("nAnotherResetInputTypeResult 0x%08x%s\n"), nAnotherResetInputTypeResult, (nAnotherResetInputTypeResult == S_OK) ? _T(" <<--- Incorrect, clearing expects NULL argument") : _T("")); |
---|
149 | PrintInputType(pMediaObject, DMO_E_TYPE_NOT_SET, _T("we were reported clearing success already")); |
---|
150 | const HRESULT nAnotherResetOutputTypeResult = pMediaObject->SetOutputType(0, &OutputMediaType, DMO_SET_TYPEF_CLEAR); |
---|
151 | _tprintf(_T("nAnotherResetOutputTypeResult 0x%08x%s\n"), nAnotherResetOutputTypeResult, (nAnotherResetOutputTypeResult == S_OK) ? _T(" <<--- Incorrect, clearing expects NULL argument") : _T("")); |
---|
152 | PrintOutputType(pMediaObject, DMO_E_TYPE_NOT_SET, _T("we were reported clearing success already")); |
---|
153 | #pragma endregion |
---|
154 | } |
---|
155 | CoUninitialize(); |
---|
156 | return 0; |
---|
157 | } |
---|
158 | |
---|