我正在尝试为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格式也看不到任何问题。

    示例代码在这里: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;
    

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

    10-13 08:59