我试图与DirectShow同时播放多个图形。经过研究后,我在How to play multiple videos in sync over multiple monitors using directshow?处找到了Geraint Davies的出色解决方案


  
  选择一个图作为主图。
  确保主机有时钟。这通常在去的时候完成
  活动,但您可以通过致电强制将其提前发生
  图上的SetDefaultSyncSource。
  查询图表中的IMediaFilter,从主时钟获取时钟
  使用GetSyncSource绘制图形并将其传递给其他图形
  SetSyncSource。
  暂停所有图形。
  等待直到GetState返回S_OK(暂停完成)。
  从图表中获取时间并增加10毫秒左右。
  调用IMediaFilter :: Run在所有图形上运行,经过此时间(现在+ 10ms)
  作为参数。
  


结果证明效果不错,视频在视觉上保持同步。
但是,当我使用IMediaFilter :: Run测试时,确实让我感到困扰。

我尝试将较大的偏移值传递给IMediaFilter :: Run,例如(现在+ 1000ms),该视频似乎仍在视觉上立即开始,而不是在开始之前延迟1000ms。

这是正常现象还是我做错了什么?

编辑:谢谢您的快速答复,罗曼R。我想当您说“视频时间”时,您是指时间戳吗?我会立即检查出来。

编辑:视频不仅显示第一帧,还可以正常播放而没有任何延迟。我还发布了一些我所做的粗略代码。希望有人能对此有所启发。

    CComQIPtr<IMediaFilter>pMasterF(m_pMasterGraphBuilder);
    CComQIPtr<IMediaFilter>pSlaveF(m_pSlaveGraphBuilder);

    IReferenceClock* pClock;
    HRESULT clkHR = pMasterF->GetSyncSource(&pClock); // Get Master Clock
    pSlaveF->SetSyncSource(pClock);  //Set slave to Master Clock

    pMasterF->Pause();  //Pause Master
    pSlaveF->Pause(); // Pause slave

    FILTER_STATE sFs;
    HRESULT hrcue;
    hrcue = pMasterF->GetState(0, &sFs);
    while(hrcue == VFW_S_STATE_INTERMEDIATE) {  // wait for master to cue data
        hrcue = pMasterF->GetState(0, &sFs);
        if (hrcue == S_OK)
            break;
        Sleep(5);
    }

    FILTER_STATE ssFs;
    HRESULT hrcues;
    hrcues = pSlaveF->GetState(0, &ssFs);
    while(hrcues == VFW_S_STATE_INTERMEDIATE) { // wait for slave cue data
        hrcue = pSlaveF->GetState(0, &ssFs);
        if (hrcues == S_OK)
            break;
        Sleep(5);
    }

    REFERENCE_TIME refTime;
    HRESULT timeHR = pClock->GetTime(&refTime);  // get master ref time

    REFERENCE_TIME temp = refTime+100000000000000;  // now + offset
    pMF->Run(temp);    // run master
    pSF->Run(temp);    // run slave


如您所见,我设置了一些荒谬的偏移量。但是,我仍然看不到任何延迟。也许我把“现在”的时间弄错了?

编辑:谢谢您的回复,杰兰特。
我确实发现每个IReferenceClock :: GetTime调用(pClock-> GetTime)都给了我一个巨大的飞跃参考时间(可能是由于我给了很大的偏移量)。
那是指流时间向前跳的意思吗?
如何检查Audio Renderer是否提供时钟?

最佳答案

这可能是由您的音频渲染器引起的。如果提供时钟,它可能会立即开始播放,而忽略实际的开始时间(我已经在某些音频渲染器中看到了此问题)。然后,一旦开始运行,时钟就是您正在播放的时间。这样您将看到流时间向前跳跃。也许您可以检查一下?

08-06 18:31