FreeMediaType与DeleteMediaType

FreeMediaTypeDeleteMediaType

FreeMediaTypeDeleteMediaType很容易被混淆使用,它们的区别主要体现在操作的对象不同。要弄清这个问题,首先要熟悉AM_MEDIA_TYPE这个结构体下面就是这个机构体的定义:

typedef struct  _MediaType {
      
      
    GUID      majortype;
      
      
    GUID      subtype;
      
      
    BOOL      bFixedSizeSamples;
      
      
    BOOL      bTemporalCompression;
      
      
    ULONG     lSampleSize;
      
      
    GUID      formattype;
      
      
    IUnknown  *pUnk;
      
      
    ULONG     cbFormat;
      
      
    [size_is(cbFormat)] BYTE *pbFormat;
      
      
} AM_MEDIA_TYPE;
      
      
 
在这里pbFormat实际上是一个BYTE指针,用来指向一块随机分配的内存。cbFormat
用来指明pbFormat这个指针所指内存块的大小。既然是这样,作为这块内存的使用
者就应该知道这块内存到底有多大。cbFormat就是起这个作用的。AM_MEDIA_TYPE
本身不是通过new得来的,而是有专门的函数来负责:CreateMediaType,其原型如
下:
       
       
AM_MEDIA_TYPE * WINAPI CreateMediaType(AM_MEDIA_TYPE const *pSrc);
       
       
               该函数首先分配一个新的AM_MEDIA_TYPE,包括格式数据块,然后把pSrc所指的
结构体数据全部都拷贝进来。如果不出现意外的话,函数返回的就是这个新分配的
AM_MEDIA_TYPE了。否则返回NULL。为保证程序的健壮性,最好在函数返回时检
查返回值。不论是格式数据块,还是AM_MEDIA_TYPE本身都不能通过new来分配
内存。既然如此,当然就不能简单地delete这些内存了,而也必须有专门的函数来
释放。一个是格式数据,一个是结构体本身。格式数据由FreeMediaType释放,结
构体本身由DeleteMediaType释放。另外格式数据必须在结构体本身释放之前释放,
以免导致异常。为加强理解,下面是它们的等价形式,如果不愿意使用库函数,完全
可以用它们取
而代之:
       
       
void MyDeleteMediaType(AM_MEDIA_TYPE *pmt)
          
          
{
          
          
    if (pmt != NULL)
          
          
    {
          
          
         // See FreeMediaType for the implementation.
          
          
            MyFreeMediaType(*pmt);
          
          
         CoTaskMemFree(pmt);
          
          
    }
          
          
}
          
          
void MyFreeMediaType(AM_MEDIA_TYPE& mt)
          
          
{
          
          
    if (mt.cbFormat != 0)
          
          
    {
          
          
        CoTaskMemFree((PVOID)mt.pbFormat);
          
          
        mt.cbFormat = 0;
          
          
        mt.pbFormat = NULL;
          
          
    }
          
          
    if (mt.pUnk != NULL)
          
          
    {
          
          
        // Unecessary because pUnk should not be used, but safest.
          
          
        mt.pUnk->Release();
          
          
        mt.pUnk = NULL;
          
          
    }
          
          
}
          
          
 
 
其中最让我们犯糊涂的就是结构体的最后两个成员: cbFormat pbFormat
假设你正在使用 DirectShow 框架开发音视频应用程序,并且需要获取音频捕获设备的音频流参数,以便进行音频采集和处理。在这种情况下,可以使用 IAMStreamConfig 接口的 GetStreamCaps 方法来获取音频捕获设备的音频流参数。 要设置 IAMStreamConfig 接口获取的音频流参数为单通道,可以按照以下步骤进行: 1. 获取 IAMStreamConfig 接口指针。 ```c++ IAMStreamConfig* pStreamConfig = nullptr; HRESULT hr = pCaptureGraphBuilder2->FindInterface( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, pAudioCaptureDevice, IID_IAMStreamConfig, (void**)&pStreamConfig); ``` 2. 查询是否支持设置单通道的音频流参数。 ```c++ AM_MEDIA_TYPE* pMediaType = nullptr; hr = pStreamConfig->GetFormat(&pMediaType); if (SUCCEEDED(hr)) { if (pMediaType->majortype == MEDIATYPE_Audio && pMediaType->formattype == FORMAT_WaveFormatEx) { WAVEFORMATEX* pWaveFormatEx = (WAVEFORMATEX*)pMediaType->pbFormat; if (pWaveFormatEx->nChannels != 1) { pWaveFormatEx->nChannels = 1; hr = pStreamConfig->SetFormat(pMediaType); } } FreeMediaType(*pMediaType); CoTaskMemFree(pMediaType); } ``` 在上述代码中,我们首先通过 GetFormat 方法获取当前音频流参数,然后判断是否为 WAVEFORMATEX 格式并且通道数不为 1。如果满足条件,我们将通道数设置为 1,并通过 SetFormat 方法设置新的音频流参数。最后,我们需要释放 AM_MEDIA_TYPE 结构体的内存空间。 请注意,这只是 IAMStreamConfig 接口设置单通道音频流参数的一种方式,具体实现方式可能会有所不同。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值