如何在媒体基础上定制视频媒体/流接收器请求RGB32帧?

问题描述 投票:1回答:1

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

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

  • 生成的拓扑中的一个(或多个)MFT因错误代码MF_E_TRANSFORM_NEED_MORE_INPUT而失败,因此我的流接收器从不接收样本
  • 在请求几个样本后,媒体会话收到事件MF_E_ATTRIBUTENOTFOUND,但我仍然不知道它来自哪里

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

我最好的猜测是由TopologyLoader生成的颜色转换器MFT需要更多配置,但我不知道如何做到这一点,因为我需要保持整个过程与原始文件类型无关。

windows opengl rgb mp4 ms-media-foundation
1个回答
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;
© www.soinside.com 2019 - 2024. All rights reserved.