windows - 如何让自定义视频媒体/流接收器在媒体基础中请求 RGB32 帧?

标签 windows opengl rgb mp4 ms-media-foundation

我正在尝试为 OpenGL 应用程序中的视频播放制作自定义媒体接收器(没有各种 WGL_NV_DX_INTEROP,因为我不确定我的所有目标设备是否都支持此功能)。

到目前为止,我所做的是编写一个自定义流接收器,它接受 RGB32 样本并通过媒体 session 设置播放,但是我在播放 mp4 文件的初始测试中遇到了问题:

  • 生成的拓扑中的一个(或多个)MFT不断失败,并出现错误代码MF_E_TRANSFORM_NEED_MORE_INPUT,因此我的流接收器从未收到样本
  • 请求一些示例后,媒体 session 收到事件 MF_E_ATTRIBUTENOTFOUND,但我仍然不知道它来自何处

但是,如果我将流接收器配置为接收 NV12 样本,则一切似乎都工作正常。

我最好的猜测是由 TopologyLoader 生成的颜色转换器 MFT 需要更多配置,但考虑到我需要使整个过程独立于原始文件类型,我不知道该怎么做。

最佳答案

我制作了一个最小的测试用例,演示了自定义视频渲染器与经典媒体 session 的使用。

我使用big_buck_bunny_720p_50mb.mp4,并且使用RGB32格式没有发现任何问题。

此处的示例代码:https://github.com/mofo7777/Stackoverflow在 MinimalSinkRenderer 下。

编辑

您的程序与 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;

关于windows - 如何让自定义视频媒体/流接收器在媒体基础中请求 RGB32 帧?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52198300/

相关文章:

php - 有没有办法使用 PHP 关闭电脑

c++ - 确定 CPU 缓存中值的值和/或地址

opengl - glPolygonMode(GL_BACK,GL_LINE) 不起作用

javascript - 如何优化 RGB 到 HSL 转换函数的执行时间?

ios - iOS 10 上的 UIColor 缺少蓝色值

Java:如何旋转非方形二维数组

windows - 为什么从函数返回的 gstrings 串联是一个空字符串 - Groovy 1.7.4

c++ - 在 Windows 上构建 Boost

c++ - 如何底部对齐字体

java - 加快 lwjgl 渲染速度?