gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 18:53:43 24 4
gpt4 key购买 nike

我正在编写自定义 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 方法无法足够快地拉出数据),结果是播放视频时延迟增加。有没有人知道从实时源接收数据时我应该如何做时间戳?

    最佳答案

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

  • 您希望在 future 设置一个时间,以允许通过图形和过滤器中的任何缓冲进行延迟。尝试将时间设置为 future 300 毫秒(现在的流时间 + 300 毫秒)。
  • 您希望帧之间保持一致,因此不要根据每个帧的到达时间为它们添加时间戳。对每一帧使用 RTP 时间戳,并将第一帧的基线设置为 future 300 毫秒;随后的帧是 (rtp - rtp_at_baseline) + dshow 基线(具有适当的单位转换。
  • 您需要使用相同的基线以相同的方式为音频和视频流添加时间戳。但是,如果我记得,RTP 时间戳在每个流中都有不同的基线,因此您需要使用 RTCP 数据包将 RTP 时间戳转换为(绝对)NTP 时间,然后使用初始基线将 NTP 转换为 directshow(基线 NTP = dshow现在流时间 + 300 毫秒)。

  • G

    关于filter - 编写自定义 DirectShow RTSP/RTP 源推送过滤器 - 来自实时源的时间戳数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2240151/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com