mtype.cpp.svn-base
来自「ffshow源码」· SVN-BASE 代码 · 共 477 行
SVN-BASE
477 行
//------------------------------------------------------------------------------// File: MType.cpp//// Desc: DirectShow base classes - implements a class that holds and // manages media type information.//// Copyright (c) 1992-2002 Microsoft Corporation. All rights reserved.//------------------------------------------------------------------------------// helper class that derived pin objects can use to compare media// types etc. Has same data members as the struct AM_MEDIA_TYPE defined// in the streams IDL file, but also has (non-virtual) functions#include "stdafx.h"CMediaType::~CMediaType(){ FreeMediaType(*this);}CMediaType::CMediaType(){ InitMediaType();}CMediaType::CMediaType(const GUID * type){ InitMediaType(); majortype = *type;}// copy constructor does a deep copy of the format blockCMediaType::CMediaType(const AM_MEDIA_TYPE& rt, HRESULT* phr){ HRESULT hr = CopyMediaType(this, &rt); if (FAILED(hr) && (NULL != phr)) { *phr = hr; }}CMediaType::CMediaType(const CMediaType& rt, HRESULT* phr){ HRESULT hr = CopyMediaType(this, &rt); if (FAILED(hr) && (NULL != phr)) { *phr = hr; }}// this class inherits publicly from AM_MEDIA_TYPE so the compiler could generate// the following assignment operator itself, however it could introduce some// memory conflicts and leaks in the process because the structure contains// a dynamically allocated block (pbFormat) which it will not copy correctlyCMediaType&CMediaType::operator=(const AM_MEDIA_TYPE& rt){ Set(rt); return *this;}CMediaType&CMediaType::operator=(const CMediaType& rt){ *this = (AM_MEDIA_TYPE &) rt; return *this;}BOOLCMediaType::operator == (const CMediaType& rt) const{ // I don't believe we need to check sample size or // temporal compression flags, since I think these must // be represented in the type, subtype and format somehow. They // are pulled out as separate flags so that people who don't understand // the particular format representation can still see them, but // they should duplicate information in the format block. return ((IsEqualGUID(majortype,rt.majortype) == TRUE) && (IsEqualGUID(subtype,rt.subtype) == TRUE) && (IsEqualGUID(formattype,rt.formattype) == TRUE) && (cbFormat == rt.cbFormat) && ( (cbFormat == 0) || (memcmp(pbFormat, rt.pbFormat, cbFormat) == 0)));}BOOLCMediaType::operator != (const CMediaType& rt) const{ /* Check to see if they are equal */ if (*this == rt) { return FALSE; } return TRUE;}HRESULTCMediaType::Set(const CMediaType& rt){ return Set((AM_MEDIA_TYPE &) rt);}HRESULTCMediaType::Set(const AM_MEDIA_TYPE& rt){ if (&rt != this) { FreeMediaType(*this); HRESULT hr = CopyMediaType(this, &rt); if (FAILED(hr)) { return E_OUTOFMEMORY; } } return S_OK; }BOOLCMediaType::IsValid() const{ return (!IsEqualGUID(majortype,GUID_NULL));}voidCMediaType::SetType(const GUID* ptype){ majortype = *ptype;}voidCMediaType::SetSubtype(const GUID* ptype){ subtype = *ptype;}ULONGCMediaType::GetSampleSize() const { if (IsFixedSize()) { return lSampleSize; } else { return 0; }}voidCMediaType::SetSampleSize(ULONG sz) { if (sz == 0) { SetVariableSize(); } else { bFixedSizeSamples = TRUE; lSampleSize = sz; }}voidCMediaType::SetVariableSize() { bFixedSizeSamples = FALSE;}voidCMediaType::SetTemporalCompression(BOOL bCompressed) { bTemporalCompression = bCompressed;}BOOLCMediaType::SetFormat(BYTE * pformat, ULONG cb){ if (NULL == AllocFormatBuffer(cb)) return(FALSE); ASSERT(pbFormat); memcpy(pbFormat, pformat, cb); return(TRUE);}// set the type of the media type format block, this type defines what you// will actually find in the format pointer. For example FORMAT_VideoInfo or// FORMAT_WaveFormatEx. In the future this may be an interface pointer to a// property set. Before sending out media types this should be filled in.voidCMediaType::SetFormatType(const GUID *pformattype){ formattype = *pformattype;}// reset the format buffervoid CMediaType::ResetFormatBuffer(){ if (cbFormat) { CoTaskMemFree((PVOID)pbFormat); } cbFormat = 0; pbFormat = NULL;}// allocate length bytes for the format and return a read/write pointer// If we cannot allocate the new block of memory we return NULL leaving// the original block of memory untouched (as does ReallocFormatBuffer)BYTE*CMediaType::AllocFormatBuffer(ULONG length){ ASSERT(length); // do the types have the same buffer size if (cbFormat == length) { return pbFormat; } // allocate the new format buffer BYTE *pNewFormat = (PBYTE)CoTaskMemAlloc(length); if (pNewFormat == NULL) { if (length <= cbFormat) return pbFormat; //reuse the old block anyway. return NULL; } // delete the old format if (cbFormat != 0) { ASSERT(pbFormat); CoTaskMemFree((PVOID)pbFormat); } cbFormat = length; pbFormat = pNewFormat; return pbFormat;}// reallocate length bytes for the format and return a read/write pointer// to it. We keep as much information as we can given the new buffer size// if this fails the original format buffer is left untouched. The caller// is responsible for ensuring the size of memory required is non zeroBYTE*CMediaType::ReallocFormatBuffer(ULONG length){ ASSERT(length); // do the types have the same buffer size if (cbFormat == length) { return pbFormat; } // allocate the new format buffer BYTE *pNewFormat = (PBYTE)CoTaskMemAlloc(length); if (pNewFormat == NULL) { if (length <= cbFormat) return pbFormat; //reuse the old block anyway. return NULL; } // copy any previous format (or part of if new is smaller) // delete the old format and replace with the new one if (cbFormat != 0) { ASSERT(pbFormat); memcpy(pNewFormat,pbFormat,std::min(length,cbFormat)); CoTaskMemFree((PVOID)pbFormat); } cbFormat = length; pbFormat = pNewFormat; return pNewFormat;}// initialise a media type structurevoid CMediaType::InitMediaType(){ ZeroMemory((PVOID)this, sizeof(*this)); lSampleSize = 1; bFixedSizeSamples = TRUE;}// a partially specified media type can be passed to IPin::Connect// as a constraint on the media type used in the connection.// the type, subtype or format type can be null.BOOLCMediaType::IsPartiallySpecified(void) const{ if ((majortype == GUID_NULL) || (formattype == GUID_NULL)) { return TRUE; } else { return FALSE; }}BOOLCMediaType::MatchesPartial(const CMediaType* ppartial) const{ if ((ppartial->majortype != GUID_NULL) && (majortype != ppartial->majortype)) { return FALSE; } if ((ppartial->subtype != GUID_NULL) && (subtype != ppartial->subtype)) { return FALSE; } if (ppartial->formattype != GUID_NULL) { // if the format block is specified then it must match exactly if (formattype != ppartial->formattype) { return FALSE; } if (cbFormat != ppartial->cbFormat) { return FALSE; } if ((cbFormat != 0) && (memcmp(pbFormat, ppartial->pbFormat, cbFormat) != 0)) { return FALSE; } } return TRUE;}// general purpose function to delete a heap allocated AM_MEDIA_TYPE structure// which is useful when calling IEnumMediaTypes::Next as the interface// implementation allocates the structures which you must later delete// the format block may also be a pointer to an interface to releasevoid WINAPI DeleteMediaType(AM_MEDIA_TYPE *pmt){ // allow NULL pointers for coding simplicity if (pmt == NULL) { return; } FreeMediaType(*pmt); CoTaskMemFree((PVOID)pmt);}// this also comes in useful when using the IEnumMediaTypes interface so// that you can copy a media type, you can do nearly the same by creating// a CMediaType object but as soon as it goes out of scope the destructor// will delete the memory it allocated (this takes a copy of the memory)AM_MEDIA_TYPE * WINAPI CreateMediaType(AM_MEDIA_TYPE const *pSrc){ ASSERT(pSrc); // Allocate a block of memory for the media type AM_MEDIA_TYPE *pMediaType = (AM_MEDIA_TYPE *)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); if (pMediaType == NULL) { return NULL; } // Copy the variable length format block HRESULT hr = CopyMediaType(pMediaType,pSrc); if (FAILED(hr)) { CoTaskMemFree((PVOID)pMediaType); return NULL; } return pMediaType;}// Copy 1 media type to anotherHRESULT WINAPI CopyMediaType(AM_MEDIA_TYPE *pmtTarget, const AM_MEDIA_TYPE *pmtSource){ // We'll leak if we copy onto one that already exists - there's one // case we can check like that - copying to itself. ASSERT(pmtSource != pmtTarget); *pmtTarget = *pmtSource; if (pmtSource->cbFormat != 0) { ASSERT(pmtSource->pbFormat != NULL); pmtTarget->pbFormat = (PBYTE)CoTaskMemAlloc(pmtSource->cbFormat); if (pmtTarget->pbFormat == NULL) { pmtTarget->cbFormat = 0; return E_OUTOFMEMORY; } else { CopyMemory((PVOID)pmtTarget->pbFormat, (PVOID)pmtSource->pbFormat, pmtTarget->cbFormat); } } if (pmtTarget->pUnk != NULL) { pmtTarget->pUnk->AddRef(); } return S_OK;}// Free an existing media type (ie free resources it holds)void WINAPI FreeMediaType(AM_MEDIA_TYPE& mt){ if (mt.cbFormat != 0) { CoTaskMemFree((PVOID)mt.pbFormat); // Strictly unnecessary but tidier mt.cbFormat = 0; mt.pbFormat = NULL; } if (mt.pUnk != NULL) { mt.pUnk->Release(); mt.pUnk = NULL; }}// Initialize a media type from a WAVEFORMATEXSTDAPI CreateAudioMediaType( const WAVEFORMATEX *pwfx, AM_MEDIA_TYPE *pmt, BOOL bSetFormat){ pmt->majortype = MEDIATYPE_Audio; if (pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) { pmt->subtype = ((PWAVEFORMATEXTENSIBLE)pwfx)->SubFormat; } else { pmt->subtype = FOURCCMap(pwfx->wFormatTag); } pmt->formattype = FORMAT_WaveFormatEx; pmt->bFixedSizeSamples = TRUE; pmt->bTemporalCompression = FALSE; pmt->lSampleSize = pwfx->nBlockAlign; pmt->pUnk = NULL; if (bSetFormat) { if (pwfx->wFormatTag == WAVE_FORMAT_PCM) { pmt->cbFormat = sizeof(WAVEFORMATEX); } else { pmt->cbFormat = sizeof(WAVEFORMATEX) + pwfx->cbSize; } pmt->pbFormat = (PBYTE)CoTaskMemAlloc(pmt->cbFormat); if (pmt->pbFormat == NULL) { return E_OUTOFMEMORY; } if (pwfx->wFormatTag == WAVE_FORMAT_PCM) { CopyMemory(pmt->pbFormat, pwfx, sizeof(PCMWAVEFORMAT)); ((WAVEFORMATEX *)pmt->pbFormat)->cbSize = 0; } else { CopyMemory(pmt->pbFormat, pwfx, pmt->cbFormat); } } return S_OK;}// eliminate very many spurious warnings from MS compiler#pragma warning(disable:4514)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?