视频录制在IMFSinkWriter上挂起 - > Finalize();

时间:2015-11-17 21:49:38

标签: c++ c++11 video ms-media-foundation

使用Media Foundation将视频录制最终化为.mp4时遇到问题,其中IMFSinkWriter->Finalize();的呼叫永远挂起。它并不总是发生,几乎可以在任何机器上发生(在Windows服务器上看到,7,8,10)。事先在音频和视频流上调用Flush(),并且在FlushFinalize之间不添加新样本。关于什么可能导致Finalize永远挂起的任何想法?

我尝试过的事情:

  • 记录所有HRESULT以检查是否存在任何问题(在进入下一行代码之前已经检查过它们)
  

所有内容都以S_OK的形式返回,没有发现任何问题

  • 在流上添加了IMFSinkWriterCallback以获取回调 流处理标记(每10个样本添加标记)并完成Finalize()
  

自添加此功能后无法重现,但这可以提供有关当我使用它时会发生什么的最佳信息。

  • 在线搜索代码示例,了解其他人如何设置代码示例 Sink Writer以及如何使用Finalize()
  

没找到很多样本,看起来我的代码与找到的代码类似

  • 查看每个系统可用和使用的编码器,包括编码器dll的版本
  

编码器在可能重现问题的机器上的AMD H.264硬件MFT编码器和H264编码器MFT之间变化。版本似乎并不重要,有些机器是最新的视频驱动程序。

以下是一些没有HRESULT检查的代码示例(这使代码量增加了一倍,因此我将其取出)

构建接收器样本:

CComPtr<IMFAttributes> pAttr;
::MFCreateAttributes( &pAttr, 4 );
pAttr->SetGUID( MF_TRANSCODE_CONTAINERTYPE, GetFileContainerType() );
pAttr->SetUINT32( MF_LOW_LATENCY, FALSE ); // Allows better multithreading
pAttr->SetUINT32( MF_SINK_WRITER_DISABLE_THROTTLING, TRUE ); // Does not block
pAttr->SetUINT32( MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, TRUE );

m_pCallback.Attach( new MFSinkWriterCallback() );
pAttr->SetUnknown( MF_SINK_WRITER_ASYNC_CALLBACK, m_pCallback );

::MFCreateSinkWriterFromURL( m_strFilename.c_str(), NULL, pAttr, &m_pSink );

if ( m_pVideoInputType && m_pVideoOutputType )
{
   m_pSink->AddStream( m_pVideoOutputType, &m_dwVideoStreamId );
   // Attributes for encoding?
   CComPtr<IMFAttributes> pAttrVideo;

   // Not sure if these are needed
   //::MFCreateAttributes( &pAttrVideo, 5 );

   m_pSink->SetInputMediaType( m_dwVideoStreamId, m_pVideoInputType, pAttrVideo );
}
if ( m_pAudioInputType && m_pAudioOutputType )
{
   m_pSink->AddStream( m_pAudioOutputType, &m_dwAudioStreamId );
   // Attributes for encoding?
   CComPtr<IMFAttributes> pAttrAudio;

   // Not sure if these are needed
   //::MFCreateAttributes( &pAttrAudio, 2 );
   //pAttrAudio->SetGUID( MF_MT_SUBTYPE, MFAudioFormat_AAC );
   //pAttrAudio->SetUINT32( MF_MT_AUDIO_BITS_PER_SAMPLE, 16 );

   m_pSink->SetInputMediaType( m_dwAudioStreamId, m_pAudioInputType, pAttrAudio );
}
m_pSink->BeginWriting();

停止录制样本:

if ( m_dwVideoStreamId != (DWORD)-1 )
{
   m_sink->Flush( m_dwVideoStreamId );
}
if ( m_dwAudioStreamId != (DWORD)-1 )
{
   m_sink->Flush( m_dwAudioStreamId );
}

m_sink->Finalize();

0 个答案:

没有答案