mtype.cpp
上传用户:liguizhu
上传日期:2015-11-01
资源大小:2422k
文件大小:12k
源码类别:

P2P编程

开发平台:

Visual C++

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