IMFSinkWriter::BeginWriting 未初始化,因为 IMFMediaEventGenerator 有未决事件
Posted
技术标签:
【中文标题】IMFSinkWriter::BeginWriting 未初始化,因为 IMFMediaEventGenerator 有未决事件【英文标题】:IMFSinkWriter::BeginWriting does not initialize because the IMFMediaEventGenerator has pending events 【发布时间】:2019-07-03 21:42:56 【问题描述】:我正在尝试使用 IMFSinkWriter 来呈现音频样本 (IMFSample),但在调用 IMFSinkWriter::BeginWriting
方法时遇到问题,因为它返回代码:MF_E_MULTIPLE_SUBSCRIBERS
。这是因为我打电话给IMFStreamSink::BeginGetEvent(Callback, null)
。
我尝试在没有先调用 (BeginGetEvent) 的情况下调用该方法 (BeginWriting),令人惊讶的是,该方法工作正常,我可以成功处理音频样本。
问题是在创建 SinkWriter 后我无法调用 (BeginGetEvent)。
用于创建 SAR(流音频渲染)的代码:
HRESULT Hr = E_FAIL;
IMFMediaSink *pAudioRender = NULL;
IMFStreamSink *pStreamSink = NULL;
IMFMediaTypeHandler *pMediaHandler = NULL;
IMFPresentationClock *pPresentClock = NULL;
IMFPresentationTimeSource* pTimeSource = NULL;
IMFSinkWriter *pSinkWriter = NULL;
Hr = MFCreateAudioRenderer(NULL, &pAudioRender);
我为 Collector 创建了 IMFPresenetationClock:
Hr = MFCreateSystemTimeSource(&pTimeSource);
Hr = MFCreatePresentationClock(&pPresentClock);
pPresentClock ->SetTimeSource(pTimeSource);
IMFMediaSink->SetPresentationClock(pPresentClock );
这部分我配置Stream Sink:
pAudioRender->GetStreamSinkByIndex(0, &pStreamSink);
pStreamSink->GetMediaTypeHandler(&pMediaHandler);
pMediaHandler->SetCurrentMediaType(DecodePCM);
如果我在这里调用 BeginGetEvent,将不会创建 SinkWriter。如果我在创建 SinkWriter 后调用,我会成功,但我不能再次使用 BeginGetEvent,因为它会返回:MF_E_MULTIPLE_SUBSCRIBERS。
我使用这段代码创建了 SinkWriter,创建过程很顺利,但是在第三行,如果我在 IMFStreamSink 中调用 (BeginGetEvent),则会收到错误代码。
Hr = MFCreateSinkWriterFromMediaSink(pAudioRender, NULL, &pSinkWriter);
pSinkWriter->SetInputMediaType(DecodePCM);
pSinkWriter->BeginWriting(); //HR -> MF_E_MULTIPLE_SUBSCRIBERS
我想使用IMFStreamSink
接口的IMFMediaEventGenerator
接收事件(MEStreamSinkRequestSample)调用IMFSourceReader::ReadSample
方法。
为了让我接收这些事件,我需要了解为什么IMFSinkWriter::BeginWriting
从IMFStreamSink
获取事件生成器。
【问题讨论】:
【参考方案1】:在这种情况下,您不应该调用 IMFMediaEventGenerator
方法。
通过使用 Sink Writer API,您可以将 Media Foundation 原语 (SAR) 的管理和独占控制委托给 Sink Writer 实例。它是事件的订阅者,并且只能有一个。
也就是说,如果你想自己处理MEStreamSinkRequestSample
,你不能使用Sink Writer API。
MSDN论坛上有类似的问题,例如
Why IMFMediaEventGenerator::GetEvent() always returns MF_E_MULTIPLE_SUBSCRIBERS?【讨论】:
感谢您回答我。但我有点困惑。那么我将如何使用 IMFStreamSink :: ProcessSample 呢?这个过程只适用于视频,对于音频,我需要 SinkWriter 来处理。我将不得不访问低级 API 来呈现音频,那么在这种情况下是 CoreAudio?但是SAR会怎么做呢?还是我在这里错了,我是否应该创建一个媒体源,无论是否自定义,并使用媒体基础框架中出现的高级 API MediaSession?ProcessSample
只能有一个用户,在您的情况下是 Sink Writer。您不能与另一个更高级别的消费者同时使用媒体/流接收器。如果您对此不满意,则必须停止使用 Sink Writer:管理媒体接收器您自己处理它的操作,在这种情况下,您的部分工作将与样本处理有关,您将根据需要对其进行自定义方式。如果 Sink Writer 拥有媒体接收器,则您不能干预。以上是关于IMFSinkWriter::BeginWriting 未初始化,因为 IMFMediaEventGenerator 有未决事件的主要内容,如果未能解决你的问题,请参考以下文章