但是此示例在此方法中使用文件路径作为第一个参数. pGraph-> AddSourceFilter(pszVideoFile,L& quot; Source& quot;& pSourceF),我不没有文件路径,而是我有 m_pMemReader = new CMemReader(m_pMemStream,m_pMediaType和& hr).问题是-如果我有 CMemReader ,如何将对象连接到过滤图? 编辑 更改了这些行 m_pMediaType = new CMediaType();m_pMediaType-> majortype = MEDIATYPE_Audio;< ----------第一行开关(数据类型){//案例SoundDataType :: WAV:m_pMediaType-> subtype = MEDIASUBTYPE_WAVE;休息;情况SoundDataType :: WAV:m_pMediaType-> subtype = MEDIASUBTYPE_PCM;休息;< --------第二行情况SoundDataType :: MP3:m_pMediaType-> subtype = MEDIASUBTYPE_MPEG1Audio;休息;默认值:返回false;否则返回false.} EDIT2 为了在图形中包含 m_pMemReader ,我添加了这一行 hr = m_pGraph-> AddFilter(m_pMemReader,NULL); 然后在我将媒体类型设置为 MEDIATYPE_Audio 时出现错误 0x80040200 -指定的媒体类型无效.,如果我尝试将媒体类型用作 MEDIATYPE_Stream 我得到关注错误 0x80040266 -这是什么问题?我从这里无法理解的是-我的上游过滤器是 CMemReader * m_pMemReader; ,但是 CMemReader 是它继承自 IBaseFilter ,然后是我的下游是 IBaseFilter * m_pGrabberF; ,它也是 IBaseFilter .我在这里想念什么?解决方案 DirectShow已过时.您应该改用MediaFoundation.我没有对其进行测试,但是我认为以下代码将解码音频并让您处理原始音频帧( https://docs.microsoft.com/zh-cn/windows/win32/medfound/tutorial--decoding-audio ): IMFSourceReader * pReader = NULL;hr = MFCreateSourceReaderFromURL(L"C:\\ users \\ video",NULL,& pReader);如果(FAILED(hr)){printf(打开输入文件时出错");}IMFMediaType * type = NULL;IMFMediaType * pPartialType = NULL;hr = MFCreateMediaType(& pPartialType);hr = pPartialType-> SetGUID(MF_MT_MAJOR_TYPE,MFMediaType_Audio);hr = pPartialType-> SetGUID(MF_MT_SUBTYPE,MFAudioFormat_PCM);//在源阅读器上设置此类型.源读者将//加载必要的解码器.如果(成功(小时)){hr = pReader-> SetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM,NULL,pPartialType);}hr = pReader-> GetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM,& type);//使用类型指向IMFMediaType的指针进行操作IMFSample * pSample = NULL;IMFMediaBuffer * pBuffer = NULL;BYTE * pAudioData = NULL;DWORD cbBuffer = 0;while(true){DWORD dwFlags = 0;hr = pReader-> ReadSample((DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM,0,NULL,&dwFlags,NULL,& pSample);hr = pSample-> ConvertToContiguousBuffer(& pBuffer);hr = pBuffer-> Lock(& pAudioData,NULL,& cbBuffer);//使用pAudioData做某事,pAudioData是lenth cbBuffer的无符号字符数组} What I need to do is - get decoded sample frames (like vector<frames>) from DirectShow in order to do it I follow this implementation https://docs.microsoft.com/en-us/windows/win32/directshow/using-the-sample-grabberThere is my implementationbool coAudioPlayerSampleGrabber::LoadImp(SoundDataType dataType, unsigned char const * pData, int64_t dataLen){ Cleanup(); m_bReady = false; HRESULT hr = S_OK; assert(pData); assert(dataLen); m_memBuffer.resize(dataLen); memcpy(m_memBuffer.data(), pData, dataLen); m_memBufferDataType = dataType; m_pMediaType = new CMediaType(); m_pMediaType->majortype = MEDIATYPE_Stream; switch (dataType) { case SoundDataType::WAV: m_pMediaType->subtype = MEDIASUBTYPE_WAVE; break; case SoundDataType::MP3: m_pMediaType->subtype = MEDIASUBTYPE_MPEG1Audio; break; default: return false; } m_pMemStream = new CMemStream((BYTE*)m_memBuffer.data(), m_memBuffer.size()); m_pMemReader = new CMemReader(m_pMemStream, m_pMediaType, &hr); if (FAILED(hr) || m_pMemReader == NULL) { printf("Could not create filter - HRESULT 0x%8.8X\n", hr); return false; } // Make sure we don't accidentally go away! m_pMemReader->AddRef(); // *** Create the Filter Graph Manager hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&m_pGraph)); if (FAILED(hr)) { if (hr == CO_E_NOTINITIALIZED) { printf("coAudioPlayerSampleGrabberImplementation::Load: FAILED CoCreateInstance(CLSID_FilterGraph,...) FAILED hRes: %x (CoInitialize has not been called)\n", hr); } else { printf("coAudioPlayerSampleGrabberImplementation::Load: FAILED CoCreateInstance(CLSID_FilterGraph FAILED hRes: %x\n", hr); } return false; } hr = m_pGraph->QueryInterface(IID_PPV_ARGS(&m_pControl)); if (FAILED(hr)) { std::cout << "coAudioPlayerSampleGrabberImplementation::Load: FAILED QueryInterface IMediaControl" << std::endl; return false; } hr = m_pGraph->QueryInterface(IID_PPV_ARGS(&m_pEvent)); if (FAILED(hr)) { std::cout << "coAudioPlayerSampleGrabberImplementation::Load: FAILED QueryInterface IMediaEventEx" << std::endl; return false; } // *** end Create the Filter Graph Manager // *** Add the Sample Grabber to the Filter Graph // Create the Sample Grabber filter. hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&m_pGrabberF)); if (FAILED(hr)) { std::cout << "coAudioPlayerSampleGrabberImplementation::Load: FAILED CoCreateInstance CLSID_SampleGrabber" << std::endl; return false; } hr = m_pGraph->AddFilter(m_pGrabberF, LPCWSTR("Sample Grabber")); if (FAILED(hr)) { std::cout << "coAudioPlayerSampleGrabberImplementation::Load: FAILED AddFilter m_pGrabberF" << std::endl; return false; } hr = m_pGrabberF->QueryInterface(IID_PPV_ARGS(&m_pGrabber)); if (FAILED(hr)) { std::cout << "coAudioPlayerSampleGrabberImplementation::Load: FAILED QueryInterface ISampleGrabber" << std::endl; return false; } // *** end Add the Sample Grabber to the Filter Graph // *** Set the Media Type hr = m_pGrabber->SetMediaType(m_pMediaType); if (FAILED(hr)) { std::cout << "coAudioPlayerSampleGrabberImplementation::Load: FAILED SetMediaType" << std::endl; return false; } // *** end Set the Media Type IPin *ppinOut = m_pMemReader->GetPin(0); hr = m_pGraph->Render(ppinOut); if (FAILED(hr)) { printf("coAudioPlayerSampleGrabberImplementation::Load: FAILED to load (Render) audio file from data (hRes: %x)\n", hr); return false; } m_bReady = true; return m_bReady;}I get an error here :IPin *ppinOut = m_pMemReader->GetPin(0); hr = m_pGraph->Render(ppinOut); if (FAILED(hr)) <------------- HERE!! { printf("TV_AudioPlayerSampleGrabberImplementation::Load: FAILED to load (Render) audio file from data (hRes: %x)\n", hr); return false; }Error code is - 0x8004025F, which according to this error table https://docs.microsoft.com/en-us/windows/win32/directshow/error-and-success-codes means thatI see there is an example in doc https://docs.microsoft.com/en-us/windows/win32/directshow/using-the-sample-grabber#build-the-filter-graphBut this an example use path to file as a first param in this method pGraph->AddSourceFilter(pszVideoFile, L"Source", &pSourceF), I don't have path to file instead I have m_pMemReader = new CMemReader(m_pMemStream, m_pMediaType, &hr).Question is - How to connect object to the filter graph if I have CMemReader ?EDITchanged these lines m_pMediaType = new CMediaType(); m_pMediaType->majortype = MEDIATYPE_Audio; <---------- First line switch (dataType) { //case SoundDataType::WAV: m_pMediaType->subtype = MEDIASUBTYPE_WAVE; break; case SoundDataType::WAV: m_pMediaType->subtype = MEDIASUBTYPE_PCM; break; <-------- Second line case SoundDataType::MP3: m_pMediaType->subtype = MEDIASUBTYPE_MPEG1Audio; break; default: return false; }EDIT2In order to include m_pMemReader to graph I added this linehr = m_pGraph->AddFilter(m_pMemReader, NULL);Then in I set media type as MEDIATYPE_Audio I get an error 0x80040200 - The specified media type is invalid. , if I try to use media type as MEDIATYPE_Stream I get follow error 0x80040266 -What is a problem here? What I undrstand from here is - my upstream filter is CMemReader * m_pMemReader; , but CMemReader under the hood it inherit from IBaseFilter, then my downstream is IBaseFilter * m_pGrabberF; which is also IBaseFilter. What am I missing here? 解决方案 DirectShow is outdated. You should use MediaFoundation instead. I didn't test it but I think the following code will decode audio and let you manipulate raw audio frames (https://docs.microsoft.com/en-us/windows/win32/medfound/tutorial--decoding-audio):IMFSourceReader *pReader = NULL;hr = MFCreateSourceReaderFromURL(L"C:\\users\\video", NULL, &pReader);if (FAILED(hr)){ printf("Error opening input file");}IMFMediaType *type = NULL;IMFMediaType *pPartialType = NULL;hr = MFCreateMediaType(&pPartialType);hr = pPartialType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);hr = pPartialType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM);// Set this type on the source reader. The source reader will// load the necessary decoder.if (SUCCEEDED(hr)){ hr = pReader->SetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, NULL, pPartialType);}hr = pReader->GetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, &type);//Do something with type which is a pointer to IMFMediaTypeIMFSample *pSample = NULL;IMFMediaBuffer *pBuffer = NULL;BYTE *pAudioData = NULL;DWORD cbBuffer = 0;while(true){ DWORD dwFlags = 0; hr = pReader->ReadSample((DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, NULL, &dwFlags, NULL, &pSample); hr = pSample->ConvertToContiguousBuffer(&pBuffer); hr = pBuffer->Lock(&pAudioData, NULL, &cbBuffer); //Do something with the pAudioData which is an array of unsigned chars of lenth cbBuffer} 这篇关于如何将对象连接到过滤图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 09-04 22:53