AJA NTV2 SDK  18.0.0.2717
NTV2 SDK 18.0.0.2717
mtype.cpp
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
2 // File: MType.cpp
3 //
4 // Desc: DirectShow base classes - implements a class that holds and
5 // manages media type information.
6 //
7 // Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
8 //------------------------------------------------------------------------------
9 
10 
11 // helper class that derived pin objects can use to compare media
12 // types etc. Has same data members as the struct AM_MEDIA_TYPE defined
13 // in the streams IDL file, but also has (non-virtual) functions
14 
15 #include <streams.h>
16 #include <mmreg.h>
17 
19  FreeMediaType(*this);
20 }
21 
22 
24 {
25  InitMediaType();
26 }
27 
28 
29 CMediaType::CMediaType(const GUID * type)
30 {
31  InitMediaType();
32  majortype = *type;
33 }
34 
35 
36 // copy constructor does a deep copy of the format block
37 
38 CMediaType::CMediaType(const AM_MEDIA_TYPE& rt, __out_opt HRESULT* phr)
39 {
40  HRESULT hr = CopyMediaType(this, &rt);
41  if (FAILED(hr) && (NULL != phr)) {
42  *phr = hr;
43  }
44 }
45 
46 
47 CMediaType::CMediaType(const CMediaType& rt, __out_opt HRESULT* phr)
48 {
49  HRESULT hr = CopyMediaType(this, &rt);
50  if (FAILED(hr) && (NULL != phr)) {
51  *phr = hr;
52  }
53 }
54 
55 
56 // this class inherits publicly from AM_MEDIA_TYPE so the compiler could generate
57 // the following assignment operator itself, however it could introduce some
58 // memory conflicts and leaks in the process because the structure contains
59 // a dynamically allocated block (pbFormat) which it will not copy correctly
60 
62 CMediaType::operator=(const AM_MEDIA_TYPE& rt)
63 {
64  Set(rt);
65  return *this;
66 }
67 
70 {
71  *this = (AM_MEDIA_TYPE &) rt;
72  return *this;
73 }
74 
75 BOOL
77 {
78  // I don't believe we need to check sample size or
79  // temporal compression flags, since I think these must
80  // be represented in the type, subtype and format somehow. They
81  // are pulled out as separate flags so that people who don't understand
82  // the particular format representation can still see them, but
83  // they should duplicate information in the format block.
84 
85  return ((IsEqualGUID(majortype,rt.majortype) == TRUE) &&
86  (IsEqualGUID(subtype,rt.subtype) == TRUE) &&
87  (IsEqualGUID(formattype,rt.formattype) == TRUE) &&
88  (cbFormat == rt.cbFormat) &&
89  ( (cbFormat == 0) ||
90  pbFormat != NULL && rt.pbFormat != NULL &&
91  (memcmp(pbFormat, rt.pbFormat, cbFormat) == 0)));
92 }
93 
94 
95 BOOL
97 {
98  /* Check to see if they are equal */
99 
100  if (*this == rt) {
101  return FALSE;
102  }
103  return TRUE;
104 }
105 
106 
107 HRESULT
109 {
110  return Set((AM_MEDIA_TYPE &) rt);
111 }
112 
113 
114 HRESULT
115 CMediaType::Set(const AM_MEDIA_TYPE& rt)
116 {
117  if (&rt != this) {
118  FreeMediaType(*this);
119  HRESULT hr = CopyMediaType(this, &rt);
120  if (FAILED(hr)) {
121  return E_OUTOFMEMORY;
122  }
123  }
124 
125  return S_OK;
126 }
127 
128 
129 BOOL
131 {
132  return (!IsEqualGUID(majortype,GUID_NULL));
133 }
134 
135 
136 void
137 CMediaType::SetType(const GUID* ptype)
138 {
139  majortype = *ptype;
140 }
141 
142 
143 void
144 CMediaType::SetSubtype(const GUID* ptype)
145 {
146  subtype = *ptype;
147 }
148 
149 
150 ULONG
152  if (IsFixedSize()) {
153  return lSampleSize;
154  } else {
155  return 0;
156  }
157 }
158 
159 
160 void
162  if (sz == 0) {
163  SetVariableSize();
164  } else {
165  bFixedSizeSamples = TRUE;
166  lSampleSize = sz;
167  }
168 }
169 
170 
171 void
173  bFixedSizeSamples = FALSE;
174 }
175 
176 
177 void
179  bTemporalCompression = bCompressed;
180 }
181 
182 BOOL
183 CMediaType::SetFormat(__in_bcount(cb) BYTE * pformat, ULONG cb)
184 {
185  if (NULL == AllocFormatBuffer(cb))
186  return(FALSE);
187 
188  ASSERT(pbFormat);
189  memcpy(pbFormat, pformat, cb);
190  return(TRUE);
191 }
192 
193 
194 // set the type of the media type format block, this type defines what you
195 // will actually find in the format pointer. For example FORMAT_VideoInfo or
196 // FORMAT_WaveFormatEx. In the future this may be an interface pointer to a
197 // property set. Before sending out media types this should be filled in.
198 
199 void
200 CMediaType::SetFormatType(const GUID *pformattype)
201 {
202  formattype = *pformattype;
203 }
204 
205 
206 // reset the format buffer
207 
209 {
210  if (cbFormat) {
211  CoTaskMemFree((PVOID)pbFormat);
212  }
213  cbFormat = 0;
214  pbFormat = NULL;
215 }
216 
217 
218 // allocate length bytes for the format and return a read/write pointer
219 // If we cannot allocate the new block of memory we return NULL leaving
220 // the original block of memory untouched (as does ReallocFormatBuffer)
221 
222 BYTE*
224 {
225  ASSERT(length);
226 
227  // do the types have the same buffer size
228 
229  if (cbFormat == length) {
230  return pbFormat;
231  }
232 
233  // allocate the new format buffer
234 
235  BYTE *pNewFormat = (PBYTE)CoTaskMemAlloc(length);
236  if (pNewFormat == NULL) {
237  if (length <= cbFormat) return pbFormat; //reuse the old block anyway.
238  return NULL;
239  }
240 
241  // delete the old format
242 
243  if (cbFormat != 0) {
244  ASSERT(pbFormat);
245  CoTaskMemFree((PVOID)pbFormat);
246  }
247 
248  cbFormat = length;
249  pbFormat = pNewFormat;
250  return pbFormat;
251 }
252 
253 
254 // reallocate length bytes for the format and return a read/write pointer
255 // to it. We keep as much information as we can given the new buffer size
256 // if this fails the original format buffer is left untouched. The caller
257 // is responsible for ensuring the size of memory required is non zero
258 
259 BYTE*
261 {
262  ASSERT(length);
263 
264  // do the types have the same buffer size
265 
266  if (cbFormat == length) {
267  return pbFormat;
268  }
269 
270  // allocate the new format buffer
271 
272  BYTE *pNewFormat = (PBYTE)CoTaskMemAlloc(length);
273  if (pNewFormat == NULL) {
274  if (length <= cbFormat) return pbFormat; //reuse the old block anyway.
275  return NULL;
276  }
277 
278  // copy any previous format (or part of if new is smaller)
279  // delete the old format and replace with the new one
280 
281  if (cbFormat != 0) {
282  ASSERT(pbFormat);
283  memcpy(pNewFormat,pbFormat,min(length,cbFormat));
284  CoTaskMemFree((PVOID)pbFormat);
285  }
286 
287  cbFormat = length;
288  pbFormat = pNewFormat;
289  return pNewFormat;
290 }
291 
292 // initialise a media type structure
293 
295 {
296  ZeroMemory((PVOID)this, sizeof(*this));
297  lSampleSize = 1;
298  bFixedSizeSamples = TRUE;
299 }
300 
301 
302 // a partially specified media type can be passed to IPin::Connect
303 // as a constraint on the media type used in the connection.
304 // the type, subtype or format type can be null.
305 BOOL
307 {
308  if ((majortype == GUID_NULL) ||
309  (formattype == GUID_NULL)) {
310  return TRUE;
311  } else {
312  return FALSE;
313  }
314 }
315 
316 BOOL
318 {
319  if ((ppartial->majortype != GUID_NULL) &&
320  (majortype != ppartial->majortype)) {
321  return FALSE;
322  }
323  if ((ppartial->subtype != GUID_NULL) &&
324  (subtype != ppartial->subtype)) {
325  return FALSE;
326  }
327 
328  if (ppartial->formattype != GUID_NULL) {
329  // if the format block is specified then it must match exactly
330  if (formattype != ppartial->formattype) {
331  return FALSE;
332  }
333  if (cbFormat != ppartial->cbFormat) {
334  return FALSE;
335  }
336  if ((cbFormat != 0) &&
337  (memcmp(pbFormat, ppartial->pbFormat, cbFormat) != 0)) {
338  return FALSE;
339  }
340  }
341 
342  return TRUE;
343 
344 }
345 
346 
347 
348 // general purpose function to delete a heap allocated AM_MEDIA_TYPE structure
349 // which is useful when calling IEnumMediaTypes::Next as the interface
350 // implementation allocates the structures which you must later delete
351 // the format block may also be a pointer to an interface to release
352 
353 void WINAPI DeleteMediaType(__inout_opt AM_MEDIA_TYPE *pmt)
354 {
355  // allow NULL pointers for coding simplicity
356 
357  if (pmt == NULL) {
358  return;
359  }
360 
361  FreeMediaType(*pmt);
362  CoTaskMemFree((PVOID)pmt);
363 }
364 
365 
366 // this also comes in useful when using the IEnumMediaTypes interface so
367 // that you can copy a media type, you can do nearly the same by creating
368 // a CMediaType object but as soon as it goes out of scope the destructor
369 // will delete the memory it allocated (this takes a copy of the memory)
370 
371 AM_MEDIA_TYPE * WINAPI CreateMediaType(AM_MEDIA_TYPE const *pSrc)
372 {
373  ASSERT(pSrc);
374 
375  // Allocate a block of memory for the media type
376 
377  AM_MEDIA_TYPE *pMediaType =
378  (AM_MEDIA_TYPE *)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
379 
380  if (pMediaType == NULL) {
381  return NULL;
382  }
383  // Copy the variable length format block
384 
385  HRESULT hr = CopyMediaType(pMediaType,pSrc);
386  if (FAILED(hr)) {
387  CoTaskMemFree((PVOID)pMediaType);
388  return NULL;
389  }
390 
391  return pMediaType;
392 }
393 
394 
395 // Copy 1 media type to another
396 
397 HRESULT WINAPI CopyMediaType(__out AM_MEDIA_TYPE *pmtTarget, const AM_MEDIA_TYPE *pmtSource)
398 {
399  // We'll leak if we copy onto one that already exists - there's one
400  // case we can check like that - copying to itself.
401  ASSERT(pmtSource != pmtTarget);
402  *pmtTarget = *pmtSource;
403  if (pmtSource->cbFormat != 0) {
404  ASSERT(pmtSource->pbFormat != NULL);
405  pmtTarget->pbFormat = (PBYTE)CoTaskMemAlloc(pmtSource->cbFormat);
406  if (pmtTarget->pbFormat == NULL) {
407  pmtTarget->cbFormat = 0;
408  return E_OUTOFMEMORY;
409  } else {
410  CopyMemory((PVOID)pmtTarget->pbFormat, (PVOID)pmtSource->pbFormat,
411  pmtTarget->cbFormat);
412  }
413  }
414  if (pmtTarget->pUnk != NULL) {
415  pmtTarget->pUnk->AddRef();
416  }
417 
418  return S_OK;
419 }
420 
421 // Free an existing media type (ie free resources it holds)
422 
423 void WINAPI FreeMediaType(__inout AM_MEDIA_TYPE& mt)
424 {
425  if (mt.cbFormat != 0) {
426  CoTaskMemFree((PVOID)mt.pbFormat);
427 
428  // Strictly unnecessary but tidier
429  mt.cbFormat = 0;
430  mt.pbFormat = NULL;
431  }
432  if (mt.pUnk != NULL) {
433  mt.pUnk->Release();
434  mt.pUnk = NULL;
435  }
436 }
437 
438 // Initialize a media type from a WAVEFORMATEX
439 
441  const WAVEFORMATEX *pwfx,
442  __out AM_MEDIA_TYPE *pmt,
443  BOOL bSetFormat
444 )
445 {
446  pmt->majortype = MEDIATYPE_Audio;
447  if (pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
448  pmt->subtype = ((PWAVEFORMATEXTENSIBLE)pwfx)->SubFormat;
449  } else {
450  pmt->subtype = FOURCCMap(pwfx->wFormatTag);
451  }
452  pmt->formattype = FORMAT_WaveFormatEx;
453  pmt->bFixedSizeSamples = TRUE;
454  pmt->bTemporalCompression = FALSE;
455  pmt->lSampleSize = pwfx->nBlockAlign;
456  pmt->pUnk = NULL;
457  if (bSetFormat) {
458  if (pwfx->wFormatTag == WAVE_FORMAT_PCM) {
459  pmt->cbFormat = sizeof(WAVEFORMATEX);
460  } else {
461  pmt->cbFormat = sizeof(WAVEFORMATEX) + pwfx->cbSize;
462  }
463  pmt->pbFormat = (PBYTE)CoTaskMemAlloc(pmt->cbFormat);
464  if (pmt->pbFormat == NULL) {
465  return E_OUTOFMEMORY;
466  }
467  if (pwfx->wFormatTag == WAVE_FORMAT_PCM) {
468  CopyMemory(pmt->pbFormat, pwfx, sizeof(PCMWAVEFORMAT));
469  ((WAVEFORMATEX *)pmt->pbFormat)->cbSize = 0;
470  } else {
471  CopyMemory(pmt->pbFormat, pwfx, pmt->cbFormat);
472  }
473  }
474  return S_OK;
475 }
476 
477 // eliminate very many spurious warnings from MS compiler
478 #pragma warning(disable:4514)
PWAVEFORMATEXTENSIBLE
struct WAVEFORMATEXTENSIBLE * PWAVEFORMATEXTENSIBLE
CMediaType::IsPartiallySpecified
BOOL IsPartiallySpecified(void) const
Definition: mtype.cpp:306
streams.h
NULL
#define NULL
Definition: ntv2caption608types.h:19
CMediaType::SetSubtype
void SetSubtype(const GUID *)
Definition: mtype.cpp:144
CMediaType::Set
HRESULT Set(const CMediaType &rt)
Definition: mtype.cpp:108
CMediaType::SetFormat
BOOL SetFormat(__in_bcount(length) BYTE *pFormat, ULONG length)
Definition: mtype.cpp:183
CMediaType::SetFormatType
void SetFormatType(const GUID *)
Definition: mtype.cpp:200
WAVE_FORMAT_EXTENSIBLE
#define WAVE_FORMAT_EXTENSIBLE
Definition: streams.h:79
CreateAudioMediaType
STDAPI CreateAudioMediaType(const WAVEFORMATEX *pwfx, __out AM_MEDIA_TYPE *pmt, BOOL bSetFormat)
Definition: mtype.cpp:440
CMediaType::MatchesPartial
BOOL MatchesPartial(const CMediaType *ppartial) const
Definition: mtype.cpp:317
CreateMediaType
AM_MEDIA_TYPE *WINAPI CreateMediaType(AM_MEDIA_TYPE const *pSrc)
Definition: mtype.cpp:371
CMediaType::IsValid
BOOL IsValid() const
Definition: mtype.cpp:130
CMediaType
Definition: mtype.h:18
CMediaType::~CMediaType
~CMediaType()
Definition: mtype.cpp:18
CMediaType::operator=
CMediaType & operator=(const CMediaType &)
Definition: mtype.cpp:69
FreeMediaType
void WINAPI FreeMediaType(__inout AM_MEDIA_TYPE &mt)
Definition: mtype.cpp:423
CopyMediaType
HRESULT WINAPI CopyMediaType(__out AM_MEDIA_TYPE *pmtTarget, const AM_MEDIA_TYPE *pmtSource)
Definition: mtype.cpp:397
CMediaType::SetVariableSize
void SetVariableSize()
Definition: mtype.cpp:172
CMediaType::InitMediaType
void InitMediaType()
Definition: mtype.cpp:294
CMediaType::SetType
void SetType(const GUID *)
Definition: mtype.cpp:137
CMediaType::SetSampleSize
void SetSampleSize(ULONG sz)
Definition: mtype.cpp:161
DeleteMediaType
void WINAPI DeleteMediaType(__inout_opt AM_MEDIA_TYPE *pmt)
Definition: mtype.cpp:353
PVOID
void * PVOID
Definition: ajatypes.h:339
CopyMemory
#define CopyMemory(a, b, c)
Definition: ntv2baremetaldriverinterface.h:16
CMediaType::AllocFormatBuffer
BYTE * AllocFormatBuffer(ULONG length)
Definition: mtype.cpp:223
CMediaType::CMediaType
CMediaType()
Definition: mtype.cpp:23
CMediaType::ReallocFormatBuffer
BYTE * ReallocFormatBuffer(ULONG length)
Definition: mtype.cpp:260
CMediaType::operator==
BOOL operator==(const CMediaType &) const
Definition: mtype.cpp:76
FOURCCMap
Definition: fourcc.h:31
CMediaType::ResetFormatBuffer
void ResetFormatBuffer()
Definition: mtype.cpp:208
CMediaType::operator!=
BOOL operator!=(const CMediaType &) const
Definition: mtype.cpp:96
ULONG
ULONG(__stdcall *_RegisterTraceGuids)(__in IN WMIDPREQUEST RequestAddress
CMediaType::SetTemporalCompression
void SetTemporalCompression(BOOL bCompressed)
Definition: mtype.cpp:178
CMediaType::GetSampleSize
ULONG GetSampleSize() const
Definition: mtype.cpp:151
ASSERT
#define ASSERT(_x_)
Definition: wxdebug.h:205
hr
__out HRESULT & hr
Definition: pstream.cpp:145
CMediaType::IsFixedSize
BOOL IsFixedSize() const
Definition: mtype.h:44