我正在尝试为OpenGL应用程序中的视频播放创建自定义媒体接收器(没有各种WGL_NV_DX_INTEROP,因为我不确定我所有的目标设备是否都支持此功能)。
到目前为止,我所做的是编写一个接受 RGB32 样本的自定义流接收器,并设置了媒体会话的播放,但是我在播放mp4文件的初始测试中遇到了问题:
但是,如果我将流接收器配置为接收 NV12 样本,那么一切似乎都可以正常工作。
我的最佳猜测是TopologyLoader生成的色彩转换器MFT需要更多配置,但考虑到我需要使整个过程与原始文件类型保持独立,我不知道该怎么做。
答案 0 :(得分:2)
我做了一个最小的测试用例,展示了自定义视频渲染器与经典媒体会话的结合使用。
我使用big_buck_bunny_720p_50mb.mp4,使用RGB32格式也看不到任何问题。
此处的示例代码:位于MinimalSinkRenderer下的https://github.com/mofo7777/Stackoverflow。
编辑
您的程序与big_buck_bunny_720p_50mb.mp4一起使用时效果很好。我认为您的mp4文件是问题。共享它,如果可以的话。
我刚刚做了一些更改:
您在MESessionEnded上停止,然后在MESessionStopped关闭。
case MediaEventType.MESessionEnded:
Debug.WriteLine("MediaSession:SesssionEndedEvent");
hr = mediaSession.Stop();
break;
case MediaEventType.MESessionClosed:
Debug.WriteLine("MediaSession:SessionClosedEvent");
receiveSessionEvent = false;
break;
case MediaEventType.MESessionStopped:
Debug.WriteLine("MediaSession:SesssionStoppedEvent");
hr = mediaSession.Close();
break;
default:
Debug.WriteLine("MediaSession:Event: " + eventType);
break;
添加它以等待声音并检查样本是可以的:
internal HResult ProcessSample(IMFSample s)
{
//Debug.WriteLine("Received sample!");
CurrentFrame++;
if (s != null)
{
long llSampleTime = 0;
HResult hr = s.GetSampleTime(out llSampleTime);
if (hr == HResult.S_OK && ((CurrentFrame % 50) == 0))
{
TimeSpan ts = TimeSpan.FromMilliseconds(llSampleTime / (10000000 / 1000));
Debug.WriteLine("Frame {0} : {1}", CurrentFrame.ToString(), ts.ToString());
}
// Do not call SafeRelease here, it is done by the caller, it is a parameter
//SafeRelease(s);
}
System.Threading.Thread.Sleep(26);
return HResult.S_OK;
}
在
public HResult SetPresentationClock(IMFPresentationClock pPresentationClock)
添加
SafeRelease(PresentationClock);
之前
if (pPresentationClock != null)
PresentationClock = pPresentationClock;