我正在创建一个directshow过滤器,其目的是获取3个输入引脚并创建一个视频,该视频在内部固定时间内交替显示来自第一个源,第二个源和第三个源的视频。
因此,如果我有三个网络摄像头连接到我的过滤器,我希望最终视频显示第一个凸轮的5秒,第二个凸轮的5秒,依此类推......
我尝试了两种方法:
接近一个
我使用了一个类TimeManager。该类具有函数 isItPinsTurn(pinname)。如果引脚应该将样本发送到输出,则此函数返回true或false。为此,TimeManager创建一个每隔x秒休眠一次的新线程。 睡眠后,它将更改为当前活动的输入引脚到下一个。 结果是每隔x秒 isItPinSTurn(pinname)函数返回另一个引脚。这样每个引脚在转弯时只输出到输出引脚的秒数,因此我在输入凸轮之间获得了带有x间隔的所需视频。
此方法的问题
睡眠似乎不适用于directshow过滤器。我收到运行时错误:
abort()被称为
接近两个
我使用样本 GetMediaTime 方法和一个缓冲区,该缓冲区记录了媒体时间的视频样本量,已经发送到输出引脚。最好用代码说明:
void MyFilter::acceptFilterInput(LPCWSTR pinname, IMediaSample* sample)
{
mylogger->LogDebug("In acceptFIlterInput", L"D:\\TEMP\\yc.log");
if (wcscmp(pinname, this->currentInputPin) == 0)
{
outpin->Deliver(sample);
LONGLONG timestart;
LONGLONG timeend;
sample->GetTime(×tart, &timeend);
*mediaTimeBuffer += timeend - timestart;
if (*mediaTimeBuffer > this->MEDIATIME)
{
this->SetNextPinActive(pinname);
*mediaTimeBuffer = 0;
}
}
}
当滤波器启动时,currentInputPin设置为pin0(第一个)。调用acceptFilterInput(由输入引脚接收函数调用)使用MediaSample-MediaTime的大小调整mediaTimeBUffer。如果此缓冲区高于MEDIATIME(例如可以是5(秒)),缓冲区将设置回零并且下一个引脚设置为活动状态。
此方法的问题 我甚至不确定CMediaSample-> GetMediaTime是否返回我需要的数据,因为它似乎返回负数,这似乎没有多大意义。我没有找到有关GetMediaTime在网络上的返回值的有用信息。
答案 0 :(得分:1)
您应该阻止输入流上的执行(对IPin::Receive
的传入呼叫),以便其他流可以赶上自己的流线程。您通常通过使用等待/同步API和函数,或者通过保持对媒体示例的引用来实现此目的,以便输入对等体阻塞空分配器,等待媒体样本(缓冲区)可用。
是Sleep
效果很好,虽然民意调查是最糟糕的选择。
方法二对我没有意义,因为我没有看到任何真正的同步:没有执行阻塞,并且没有使引脚处于活动状态。您无法强制输入引脚上的数据,您只能等待使用新的媒体示例进行调用。因此,您应该阻止接受一个输入流/引脚上的数据,直到您获得另一个输入流/引脚上的数据。
有关多路复用的一些有用的相关信息: