(DirectX系列08)DirectShow WavDest编码分析

简介:      在DirectShow 中有很多Samples,WavDest就是其中一个,这个Fliter主要用于将采集到的视频流写入到指定的文件,文件格式是.WAV。

     在DirectShow 中有很多Samples,WavDest就是其中一个,这个Fliter主要用于将采集到的视频流写入到指定的文件,文件格式是.WAV。如下来看看具体的代码实现。

    对于每一个Filter都有一个固定的注册区代码,这是必不可少,如下代码;

// {3C78B8E2-6C4D-11d1-ADE2-0000F8754B99} static const GUID CLSID_WavDest = { 0x3c78b8e2, 0x6c4d, 0x11d1, { 0xad, 0xe2, 0x0, 0x0, 0xf8, 0x75, 0x4b, 0x99 } }; const AMOVIESETUP_FILTER sudWavDest = { &CLSID_WavDest, // clsID L"WAV Dest", // strName MERIT_DO_NOT_USE, // dwMerit 0, // nPins 0 // lpPin }; // Global data CFactoryTemplate g_Templates[]= { {L"WAV Dest", &CLSID_WavDest, CWavDestFilter::CreateInstance, NULL, &sudWavDest}, }; int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);

 

       这个Filter主要用于将采集的数据保存在指定的文件当中,因此它的最佳的父类应该是CTransformFilter,还有几个函数也是必须需要实现的如CreateInstance、Transform等,如下来看看CreateInstance是如何实现的。

if(SUCCEEDED(*phr)) { // Create an output pin so we can have control over the connection // media type. CWavDestOutputPin *pOut = new CWavDestOutputPin(this, phr); if(pOut) { if(SUCCEEDED(*phr)) { m_pOutput = pOut; } else { delete pOut; } } else { *phr = E_OUTOFMEMORY; } // // NOTE!: If we've created our own output pin we must also create // the input pin ourselves because the CTransformFilter base class // will create an extra output pin if the input pin wasn't created. // CTransformInputPin *pIn = new CTransformInputPin(NAME("Transform input pin"), this, // Owner filter phr, // Result code L"In"); // Pin name // a failed return code should delete the object if(pIn) { if(SUCCEEDED(*phr)) { m_pInput = pIn; } else { delete pIn; } } else { *phr = E_OUTOFMEMORY; } }

      再来看看Transform代码是如何实现,还有WavDest是如何将数据保存到文件当中;在WavDest中数据处理流程是Transform函数->

Copy函数->StopStreaming函数,其中StopStreaming函数用于保存数据,该函数代码如下;

IStream *pStream; if(m_pOutput->IsConnected() == FALSE) return E_FAIL; IPin * pDwnstrmInputPin = m_pOutput->GetConnected(); if(!pDwnstrmInputPin) return E_FAIL; HRESULT hr = ((IMemInputPin *) pDwnstrmInputPin)->QueryInterface(IID_IStream, (void **)&pStream); if(SUCCEEDED(hr)) { BYTE *pb = (BYTE *)_alloca(m_cbHeader); RIFFLIST *pRiffWave = (RIFFLIST *)pb; RIFFCHUNK *pRiffFmt = (RIFFCHUNK *)(pRiffWave + 1); RIFFCHUNK *pRiffData = (RIFFCHUNK *)(((BYTE *)(pRiffFmt + 1)) + m_pInput->CurrentMediaType().FormatLength()); pRiffData->fcc = FCC('data'); pRiffData->cb = m_cbWavData; pRiffFmt->fcc = FCC('fmt '); pRiffFmt->cb = m_pInput->CurrentMediaType().FormatLength(); CopyMemory(pRiffFmt + 1, m_pInput->CurrentMediaType().Format(), pRiffFmt->cb); pRiffWave->fcc = FCC('RIFF'); pRiffWave->cb = m_cbWavData + m_cbHeader - sizeof(RIFFCHUNK); pRiffWave->fccListType = FCC('WAVE'); LARGE_INTEGER li; ZeroMemory(&li, sizeof(li)); hr = pStream->Seek(li, STREAM_SEEK_SET, 0); if(SUCCEEDED(hr)) { hr = pStream->Write(pb, m_cbHeader, 0); } pStream->Release(); }

    其他代码都是常规实现,具体代码可以查看Directshow C++目录下的Samples.

目录
相关文章
|
6月前
|
编解码 5G Linux
FFmpeg开发笔记(二十一)Windows环境给FFmpeg集成AVS3解码器
AVS3是中国首个8K及5G视频编码标准,相比AVS2和HEVC性能提升约30%。解码器libuavs3d支持8K/60P视频实时解码,兼容多种平台。《FFmpeg开发实战》书中介绍了在Windows环境下如何集成libuavs3d到FFmpeg。集成步骤包括下载源码、使用Visual Studio 2022编译、调整配置、安装库文件和头文件,以及重新配置和编译FFmpeg以启用libuavs3d。
102 0
FFmpeg开发笔记(二十一)Windows环境给FFmpeg集成AVS3解码器
|
存储 缓存 安全
为什么你的Opus编码出来的数据有杂音(解决Android平台架构问题)
Gradle插件分为脚本插件和对象插件,脚本插件就是在普通的gradle中写一系列task,然后在别的gradle构建脚本中通过 apply from: 'xx.gradle' 引用这个脚本插件,下面主要介绍一下对象插件对象插件是指实现了org.gradle.api.Plugin接口的类。并且需要实现void apply(T target)这个方法,该方法中的泛型指的是此Plugin可以应用到的对象,而我们通常是将其应用到Project对象上。 编写对象插件常见创建方式
489 0
|
编译器 C语言
QT应用编程: 使用QTAV得到解码视频每帧图像
QT应用编程: 使用QTAV得到解码视频每帧图像
434 0
QT应用编程: 使用QTAV得到解码视频每帧图像
|
编译器 C语言
QT应用编程: 基于FFMPEG设计的精简版视频播放器
QT应用编程: 基于FFMPEG设计的精简版视频播放器
219 0
QT应用编程: 基于FFMPEG设计的精简版视频播放器
|
存储 编解码 Linux
嵌入式Linux下LCD应用编程: 调用giflib库解码显示GIF动态图
嵌入式Linux下LCD应用编程: 调用giflib库解码显示GIF动态图
772 0
嵌入式Linux下LCD应用编程: 调用giflib库解码显示GIF动态图
|
编译器 开发工具 C语言
QT应用编程:基于VLC开发音视频播放器(句柄方式)
QT应用编程:基于VLC开发音视频播放器(句柄方式)
453 0
QT应用编程:基于VLC开发音视频播放器(句柄方式)
|
Shell C# Windows
Directshow开发的基本技巧
你也可以在graph没有设置时钟的情况下运行graph。当SetSyncSource 函数的参数为NULL的时候就给graph设置了一个空的参考时钟。如果graph没有时钟,graph将运行的快许多。因为renderer 不用再按照sample的presentation 时间了,只要sample到达了renderer filter,就可以立即被提交。
1135 0