编写自定义 DirectShow RTSP/RTP 源推送过滤器 - 来自实时源的时间戳数据

2023-12-15

我正在编写自定义 DirectShow 源推送过滤器,该过滤器应该从视频服务器接收 RTP 数据并将它们推送到渲染器。我编写了一个 CVideoPushPin 类,它继承自 CSourceStream 和 CVideoReceiverThread 类,它是从视频服务器接收 RTP 数据包的线程的包装器。接收器线程本质上做了三件事:

  • 接收原始 RTP 数据包并收集接收器报告所需的一些数据
  • 组装帧,将它们复制到缓冲区并将有关它们的信息存储到 256 元素队列,其定义如下:

    struct queue_elem {
       char *start; // Pointer to a frame in a buffer
       int length; // Lenght of data
       REFERENCE_TIME recvTime; // Timestamp when the frame was received (stream time)
    };
    
    struct data {
       struct queue_elem queue[QUEUE_LENGTH];
       int qWrIdx;
       int qRdIdx;
    HANDLE mutex;
    };
    
  • 每个接收到的帧都带有当前流时间的时间戳

    p->StreamTime(refTime);
    REFERENCE_TIME rt = refTime.GetUnits();
    

问题是我不确定如何为 FillBuffer 方法中的每个 MediaSample 设置时间戳。我尝试了多种方法,但播放要么停止,要么播放速度太慢。 目前 FillBuffer 方法如下所示:

   REFERENCE_TIME thisFrameStartTime, thisFrameEndTime;
// Make sure if there are at least 4 frames in the buffer
    if(noOfFrames >= 4)
    {   
        currentQe = m_myData.queue[m_myData.qRdIdx++]; //Take current frame description     
        if(m_myData.qRdIdx >= QUEUE_LENGTH)
        {
            m_myData.qRdIdx = 0;
        }           
        nextQe = m_myData.queue[m_myData.qRdIdx]; //Take next frame description
        if(currentQe.length > 0)
        {
            memcpy(pData, currentQe.start, currentQe.length);               

             pSample->SetActualDataLength(currentQe.length);                
            CRefTime refTime;
            m_pFilter->StreamTime(refTime);
            REFERENCE_TIME rt;
            rt = refTime.GetUnits();
            pSample->GetTime(&thisFrameStartTime, &thisFrameEndTime);
            thisFrameEndTime = thisFrameStartTime + (nextQe.recvTime - currentQe.recvTime);
            pSample->SetTime(&thisFrameStartTime, &thisFrameEndTime);   
        }
    }
    else 
    {
        pSample->SetActualDataLength(0);
    }

在这种情况下,我注意到队列中的项目数量增加得非常快(由于某种原因 FillBuffer 方法无法足够快地提取数据),结果是播放视频时增加了延迟。有人知道从实时来源接收数据时应该如何做时间戳吗?


当图形的流时间达到示例对象上的时间戳时,渲染器将绘制帧。如果我正确地阅读了您的代码,您将使用到达时的流时间对它们进行时间戳记,因此它们在渲染时总是会迟到。这在某种程度上被音频渲染器混淆了:如果音频渲染器提供图形的时钟,那么它将报告当前流时间为当前正在播放的任何样本,这将导致一些不良的时间行为。

  1. 您想要设置一个未来的时间,以允许图表中的延迟和过滤器中的任何缓冲。尝试将时间设置为未来 300 毫秒(现在的流时间 + 300 毫秒)。

  2. 您希望帧之间保持一致,因此不要根据每个帧的到达时间对它们添加时间戳。对每一帧使用 RTP 时间戳,并将第一帧的基线设置为未来 300 毫秒;随后的帧是 (rtp - rtp_at_baseline) + dshow 基线(具有适当的单位转换。

  3. 您需要使用相同的基线以相同的方式为音频和视频流添加时间戳。但是,如果我记得的话,RTP 时间戳在每个流中都有不同的基线,因此您需要使用 RTCP 数据包将 RTP 时间戳转换为(绝对)NTP 时间,然后使用初始基线将 NTP 转换为 directshow (基线 NTP = dshow现在的流时间 + 300 毫秒)。

G

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

编写自定义 DirectShow RTSP/RTP 源推送过滤器 - 来自实时源的时间戳数据 的相关文章

  • HttpResponse 过滤器不返回任何内容

    我编写了一个 HttpModule 用于拦截对 WebResource axd 处理程序的调用 以便我可以对 javascript 执行一些后处理 该模块包装 Response Filter 流以执行其处理并将其更改写入底层流 我遇到的问题
  • 将实时 Android 网络摄像头视频上传到 RTP/RTSP 服务器

    我已经做了适当的研究 但仍然缺乏关于我想要实现的目标的信息 因此 我想编写一个应用程序 用户可以在其中录制视频并立即 实时 将视频上传到 RTP RTSP 服务器 服务器端不会有问题 我不清楚的是如何在手机端实现这一点 到目前为止 我的研究
  • R - 过滤器坐标

    我是 R 新手 我有一个简单的问题 据我看来 但到目前为止我还没有找到解决方案 我有一组 长 2D x y 坐标 只是 2D 空间中的点 如下所示 ID x y 1 1758 56 1179 26 2 775 67 1197 14 3 29
  • 使用 TextBox 过滤 Datagridview 行

    我有一个绑定的 datagridView 我想使用 TextBox 值对其进行过滤 我使用了这段代码 private void ChercheStextBox TextChanged object sender EventArgs e tr
  • 使用另一个对象数组过滤对象数组

    这个问题与这个问题类似Jquery 过滤带循环的对象数组 https stackoverflow com questions 30998424 jquery filter array of object with loop但这次我需要使用对
  • 无法使用c#更改视频捕获分辨率

    我正在尝试使用 C 中的 DirectShowNet 更改默认网络摄像头分辨率 据我所知 我需要通过调用 windows win32 api dll 中内置的 VideoInfoHeader 类来更改它以进行 avi 捕获 我有来自 Dir
  • VideoCamera 获取支持的分辨率

    我使用 DirectShow 库 DirectShowLib 2005 dll 和 C 来捕获摄像机图像 当我定义捕获对象的大小时 我有以下参数 const int VIDEOWIDTH 640 Depends on video devic
  • 在 Ubuntu 中使用 Gstreamer 通过 RTP 协议流式传输 Mp4 视频

    我正在尝试从本地目录获取视频文件 启用来自服务器的流并从客户端捕获这些帧 我使用了以下管道 服务器端 gst launch v filesrc location home gokul Videos Econ TestVideo radioa
  • 如何修复日期过滤器 VBA,因为它没有拾取我范围内的所有日期

    我正在尝试创建一个过滤器来过滤掉我选择的日期内的所有日期 我选择的日期将始终反映整个月 例如 如果我需要 2019 年 5 月的数据 我将输入开始日期为 01 05 2019 结束日期为 31 05 2019 我的数据过滤器将需要选取经过我
  • 使用 ransack 在 Rails ActiveAdmin 中自定义过滤器

    我创建了一个 activeadmin 过滤器 在其下拉菜单中具有以下用于过滤表数据的选项 Choice A Choice B Choice C Choice D 我想添加第五个选项 F 它可以选择 B 或 C 即 B 和 C 的结果 Cho
  • Grails:如何在过滤器中使用createLink?

    简短的问题 我该如何使用创建链接 http grails org doc latest ref Tags createLink html createLink在过滤器中 我收到错误 无方法签名 MyFilters createLink 适用
  • 是否可以使用 http url 作为 DirectShow .Net 中源过滤器的源位置?

    我正在使用 DirectShow Net 库创建一个过滤器图 该过滤器图通过使用 http 地址和 WM Asf Writer 来流式传输视频 然后 在网页上 我可以使用对象元素在 Windows Media Player 对象中呈现视频源
  • 使用webrtc时可以关闭SRTP吗

    现在我测试webrtc与SIP客户端 sx20 的通信 我使用 webrtc sdp 发送邀请消息 但 sip 客户端答案没有指纹 并且 sip 客户端的答案不是 SRTP 只是 RTP 所以我需要关闭WEBRTC中的SRTP 我可以做吗
  • 在 Windows 上以 QML 播放 RTSP 视频

    我正在尝试将 QML 中的 RTSP 流播放到视频标签中 如下所示 Repeater model 8 Video Layout fillWidth true Layout fillHeight true fillMode VideoOutp
  • 过滤器返回 true 或 false

    我正在使用过滤器在 data it 返回对象中查找 id 它返回的对象不是 true 或 false 如果我怎样才能返回 true 或 falseval recoredId valueId var hasMatch data filter
  • 在 C# 中显示来自原始未压缩数据源的实时视频:WPF 与 Winforms

    我有一个实时的 16 位灰度视频流 它作为原始 未压缩的字节流 每像素 2 字节 2 18 像素 帧 32 帧 秒 通过内存中的环形缓冲区推送 这是通过 PCI 图像采集卡来自科学级相机的 我想对视频进行一些简单的处理 剪辑动态范围 着色
  • django-过滤器和聚合函数

    这是一个特定于应用程序的问题 Django 过滤器 https github com alex django filter 这里给没用过的人简单说明一下 f ProductFilter request GET queryset Produc
  • 用于实时传输协议的开源 .net C# 库

    net中有好的RTP开源库吗 我的目的是用于音频和视频同步问题并提高每秒帧数速率 我对 RTP 不太了解 但你可能想看看本文 http www codeproject com KB IP Using RTP in Multicasting
  • 如何组合过滤条件

    过滤器类函数接受一个条件 a gt Bool 并在过滤时应用它 当您有多个条件时 使用过滤器的最佳方法是什么 使用了应用函数 liftA2 而不是 liftM2 因为出于某种原因我不明白 liftM2 在纯代码中如何工作 liftM2 组合
  • 从 RTSP 流传输 WebRTC

    目前 我有一个来自 IP 摄像机的 RTSP 流 我当然有 IP 如果我尝试在 vlc 上显示它 一切都很好 rtsp IP PORT channel 下一步是在我的网站上展示它 能够将其集成为 js 视频组件 有什么方法可以将其转换为 W

随机推荐