9 #define MAKEFOURCC(ch0, ch1, ch2, ch3) \
10 ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
11 ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))
12 #endif /* defined(MAKEFOURCC) */
17 struct QMediaType : public AM_MEDIA_TYPE {
21 memset(this, 0, sizeof(QMediaType));
37 CoTaskMemFree(pbFormat);
41 memset(this, 0, sizeof(QMediaType));
44 void Assign(const AM_MEDIA_TYPE* p)
53 static bool Copy(AM_MEDIA_TYPE* d, const AM_MEDIA_TYPE* p)
55 memcpy(d, p, sizeof(AM_MEDIA_TYPE));
57 if (p->pbFormat != 0) {
58 BYTE* pb = static_cast<BYTE*>(CoTaskMemAlloc(p->cbFormat));
63 memcpy(pb, p->pbFormat, p->cbFormat);
75 static AM_MEDIA_TYPE* CopyFrom(const AM_MEDIA_TYPE* p)
81 AM_MEDIA_TYPE* d = static_cast<AM_MEDIA_TYPE*>(CoTaskMemAlloc(
82 sizeof(AM_MEDIA_TYPE)));
95 static void Free(AM_MEDIA_TYPE* p)
105 if (p->pbFormat != 0) {
106 CoTaskMemFree(p->pbFormat);
114 void SetFormat(const void* pv, SIZE_T cb)
117 CoTaskMemFree(pbFormat);
123 BYTE* pb = static_cast<BYTE*>(CoTaskMemAlloc(cb));
146 void SetVideo(INT32 id, const QT_Format_t* fmt, INT64 rate)
148 majortype = MEDIATYPE_Video;
150 bFixedSizeSamples = TRUE;
151 bTemporalCompression = FALSE;
153 formattype = FORMAT_VideoInfo2;
155 VIDEOINFOHEADER2 v = { 0 };
156 BITMAPINFOHEADER* bmi = &(v.bmiHeader);
158 v.AvgTimePerFrame = rate;
163 INT32 g = gcd(cx, cy);
165 v.dwPictAspectRatioX = cx / g;
166 v.dwPictAspectRatioY = cy / g;
168 bmi->biSize = sizeof(BITMAPINFOHEADER);
177 subtype = MEDIASUBTYPE_YUY2;
178 lSampleSize = 2 * cx * cy;
180 bmi->biBitCount = 16;
181 bmi->biCompression = MAKEFOURCC('Y', 'U', 'Y', '2');
185 subtype = MEDIASUBTYPE_YV12;
186 lSampleSize = cx * cy + (cx * cy) / 2;
188 bmi->biBitCount = 12;
189 bmi->biCompression = MAKEFOURCC('Y', 'V', '1', '2');
193 subtype = MEDIASUBTYPE_RGB32;
194 lSampleSize = (cx * cy) * 4;
196 bmi->biBitCount = 32;
197 bmi->biCompression = BI_RGB;
201 subtype = MEDIASUBTYPE_RGB24;
202 lSampleSize = (cx * cy) * 3;
204 bmi->biBitCount = 24;
205 bmi->biCompression = BI_RGB;
212 bmi->biSizeImage = lSampleSize;
214 SetFormat(&v, sizeof(v));
221 majortype = MEDIATYPE_Audio;
222 subtype = MEDIASUBTYPE_PCM;
224 bFixedSizeSamples = TRUE;
225 bTemporalCompression = FALSE;
227 formattype = FORMAT_WaveFormatEx;
229 lSampleSize = channels * 2 * samplingRate;
231 WAVEFORMATEX wfx = { 0 };
233 wfx.wFormatTag = WAVE_FORMAT_PCM;
234 wfx.nChannels = channels;
235 wfx.nSamplesPerSec = samplingRate;
236 wfx.nAvgBytesPerSec = channels * 2 * samplingRate;
237 wfx.nBlockAlign = channels * 2;
238 wfx.wBitsPerSample = 16;
241 SetFormat(&wfx, sizeof(wfx));
248 static INT32 gcd(INT32 x, INT32 y)
265 class ATL_NO_VTABLE QEnumMediaTypes :
266 public ATL::CComObjectRootEx<ATL::CComMultiThreadModel>,
268 public IEnumMediaTypes {
270 ATL::CComCriticalSection m_cs;
272 AM_MEDIA_TYPE* m_pStart;
273 AM_MEDIA_TYPE* m_pEnd;
277 ATL::CComPtr<IUnknown> m_Pin;
281 DECLARE_NOT_AGGREGATABLE(QEnumMediaTypes)
283 DECLARE_PROTECT_FINAL_CONSTRUCT()
285 BEGIN_COM_MAP(QEnumMediaTypes)
286 COM_INTERFACE_ENTRY(IEnumMediaTypes)
291 QEnumMediaTypes() : m_pStart(0), m_pEnd(0), m_p(0)
299 HRESULT FinalConstruct()
301 ATLTRACE("QEnumMediaTypes::FinalConstruct()\n");
303 HRESULT hRslt = m_cs.Init();
313 ATLTRACE("QEnumMediaTypes::FinalRelease()\n");
318 void Init(AM_MEDIA_TYPE* s, AM_MEDIA_TYPE* e, IUnknown* p)
330 static HRESULT Create(AM_MEDIA_TYPE* s, AM_MEDIA_TYPE* e, IUnknown* p, IEnumMediaTypes** ppEnum)
336 ATL::CComObject<QEnumMediaTypes>* obj = 0;
338 HRESULT hRslt = ATL::CComObject<QEnumMediaTypes>::CreateInstance(&obj);
345 hRslt = obj->QueryInterface(ppEnum);
358 AM_MEDIA_TYPE** ppMediaTypes,
361 ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
363 if (ppMediaTypes == 0) {
367 if (pcFetched == 0 && cMediaTypes != 1) {
371 if (pcFetched != 0) {
376 AM_MEDIA_TYPE** pp = ppMediaTypes;
377 for (i = 0; i < cMediaTypes && m_p < m_pEnd; i++, pp++, m_p++) {
378 AM_MEDIA_TYPE* mt = QMediaType::CopyFrom(m_p);
380 return E_OUTOFMEMORY;
385 if (pcFetched != 0) {
399 ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
411 STDMETHOD(Reset)(void)
413 ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
421 IEnumMediaTypes** ppEnum)
423 ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
425 HRESULT hRslt = Create(m_pStart, m_pEnd, m_Pin, ppEnum);
435 }; // QEnumMediaTypes