如何解决Directshow CLSID_AsyncReader:如何设置输出引脚样本大小?
我正在尝试从磁盘播放 wav 文件(44100sr 16 位 2 声道),我需要在 samplegrabber 过滤器回调中处理音频数据,但它总是每秒四次收到 44100 字节数据,我想要要将回调速率更改为每秒 10 次(音频样本大小:每次回调 17640 字节),而不是四次(每次 44100 字节),我该如何使其按预期工作?
''' hr = CoCreateInstance(CLSID_samplegrabber,NULL,CLSCTX_INPROC,IID_IBaseFilter,(void **)&m_pBgmAudioGrabber); BREAK_IF_Failed(小时);
hr = m_pGraph->AddFilter((IBaseFilter*)m_pBgmAudioGrabber,L"Bgm Audio Mix");
BREAK_IF_Failed(hr);
hr = InitBgmAudioGrabble();
BREAK_IF_Failed(hr);
CComPtr<IPin> pAudioMixInputPin;
hr = g_DSHelper.GetPin(m_pBgmAudioGrabber,PINDIR_INPUT,&pAudioMixInputPin);
g_DSHelper.SetAudioFilterBuffer(pAudioMixInputPin);
BREAK_IF_Failed(hr)
CComPtr<IPin> pAudioMixOutputPin;
hr = g_DSHelper.GetPin(m_pBgmAudioGrabber,PINDIR_OUTPUT,&pAudioMixOutputPin);
g_DSHelper.SetAudioFilterBuffer(pAudioMixOutputPin);
BREAK_IF_Failed(hr)
hr = CoCreateInstance(CLSID_AsyncReader,(void**)&m_pBGMAudioSrcFilter);
RETURN_IF_Failed(hr,hr)
InfoLog(_T("Create BGM source filter CLSID_AsyncReader OK!"));
hr = CoCreateInstance(CLSID_WavParser,(void**)&m_pWaveParserFilter);
RETURN_IF_Failed(hr,hr)
InfoLog(_T("Create CLSID_WavParser OK!"));
hr = m_pGraph->AddFilter(m_pWaveParserFilter,L"Wav Parser");
RETURN_IF_Failed(hr,hr)
InfoLog(_T("AddFilter CLSID_WavParser OK!"));
CComPtr<IFileSourceFilter> pSourceFilter;
hr = m_pBGMAudioSrcFilter->QueryInterface(IID_IFileSourceFilter,(void**)&pSourceFilter);
RETURN_IF_Failed(hr,hr)
InfoLog(_T("QueryInterface IID_IFileSourceFilter OK!"));
HRESULT hr = pSourceFilter->Load(m_strBkgMusicPath,NULL );
RETURN_IF_Failed(hr,hr)
InfoLog(_T("Load %s OK!"),m_strBkgMusicPath);
hr = m_pGraph->AddFilter(m_pBGMAudioSrcFilter,L"Async Source");
RETURN_IF_Failed(hr,hr)
InfoLog(_T("AddFilter AsyncSource OK!"));
CComPtr<IPin> pWavParseInputPin;
hr = g_DSHelper.GetPin(m_pWaveParserFilter,&pWavParseInputPin);
g_DSHelper.SetAudioFilterBuffer(pWavParseInputPin);
RETURN_IF_Failed(hr,hr)
CComPtr<IPin> pAudioBGMOutputPin;
hr = g_DSHelper.GetPin(m_pBGMAudioSrcFilter,&pAudioBGMOutputPin);
g_DSHelper.SetAudioFilterBuffer(pAudioBGMOutputPin);
RETURN_IF_Failed(hr,hr)
hr = m_pGraph->ConnectDirect(pAudioBGMOutputPin,pWavParseInputPin,NULL);
RETURN_IF_Failed(hr,hr)
InfoLog(_T("Connect of pBkgAudioPathOutputPin and pWavParseInputPin OK!"));
CComPtr<IPin> pWavParSEOutputPin;
hr = g_DSHelper.GetPin(m_pWaveParserFilter,&pWavParSEOutputPin);
g_DSHelper.SetAudioFilterBuffer(pWavParSEOutputPin);
RETURN_IF_Failed(hr,hr)
hr = m_BgmAudioRenderDevice.Create(m_strAudioRenderdeviceid);
RETURN_IF_Failed(hr,hr);
hr = m_BgmAudioRenderDevice.SetAudioRenderFormat(g_RecordingConfig.AudioSamplePerSecond(),g_RecordingConfig.AudioBitsPerSample(),g_RecordingConfig.AudioChannels());
RETURN_IF_Failed(hr,hr);
hr = m_pGraph->AddFilter(m_BgmAudioRenderDevice.GetBaseFilter(),L"BGM Audio Render");
RETURN_IF_Failed(hr,hr);
CComPtr<IPin> pBgmRenderPin = m_BgmAudioRenderDevice.GetInputPin();
hr = m_pGraph->ConnectDirect(pWavParSEOutputPin,pAudioMixInputPin,hr)
g_DSHelper.SetAudioFilterBuffer(pBgmRenderPin);
hr = m_pGraph->ConnectDirect(pAudioMixOutputPin,pBgmRenderPin,hr)
if (m_pMC)
{
hr = m_pMC->StopWhenReady();
BREAK_IF_Failed(hr)
}
'''
解决方法
...总是每秒收到四次 44100 字节的数据,我想将回调率更改为每秒 10 次...
你不能拥有这个。当您将其设置为以适合您需要的合适格式流式传输数据时,您的任务就是打破它适合您处理的流。
当您从文件播放时,源过滤器以最大速率推送数据,并以对读取器、解复用器、解码器有意义的块的形式推送数据。您几乎永远不会(如果有的话)在此过程中具有灵活性,并且与实时音频捕获相反,您无法请求特定的数据粒度。
只需以这种速率消耗数据并将其拆分为您自己内部处理所需的部分,这是一项相对容易的任务。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。