[英]How to get correct frame time in seconds in custom DirectShow filter?
我想从视频文件中抓取帧。 由于Directshow的SampleGrabber中的一些错误,我决定创建一个类似的过滤器(不是转换过滤器,而是渲染器)。
我正在尝试基于Windows SDK转储过滤器( Microsoft SDKs\\Windows\\v7.1\\Samples\\multimedia\\directshow\\filters\\dump
)创建DirectShow过滤Microsoft SDKs\\Windows\\v7.1\\Samples\\multimedia\\directshow\\filters\\dump
。 我的过滤器仅接受RGB24格式。
class CDumpInputPin : public CRenderedInputPin
{
//...
STDMETHODIMP Receive(IMediaSample *pSample) override {
//...
REFERENCE_TIME tStart=0, tStop=0;
if (FAILED(pSample->GetTime(&tStart, &tStop))) {
LOG(ERROR) << "Unable to get sample time";
}
LOG(INFO) << "tStart=" << tStart << " tStop=" << tStop ;
}
HRESULT CheckMediaType(const CMediaType *pmt){
if (*pmt->Type() != MEDIATYPE_Video) {
return S_FALSE;
}
if ((*pmt->FormatType() != FORMAT_VideoInfo)) {
return S_FALSE;
}
if ((*pmt->Subtype() != MEDIASUBTYPE_RGB24)) {
return S_FALSE;
}
return S_OK;
}
}
我得到了正确的RGB帧,但是我不明白如何解释从IMediaSample :: GetTime()方法返回的值。 我使用pSeeking->SetPositions( &Start, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame, 0, AM_SEEKING_NoPositioning);
在源文件中寻找不同的位置。 尝试抓取8帧时,请参阅日志。
tStart=222223 tStop=622223
tStart=266668 tStop=666668
tStart=311113 tStop=711113
tStart=355558 tStop=755558
tStart=3 tStop=400003
tStart=44448 tStop=444448
tStart=88893 tStop=488893
tStart=133338 tStop=533338
我不明白这些数字的含义,以及为什么它们没有按顺序递增。
这些帧的正确时间戳记应为:
00:00:12
00:00:37
00:01:01
00:01:26
00:01:51
00:02:15
00:02:40
00:03:05
您将获得正确的时间-以100ns为单位的64位值。 请参阅REFERENCE_TIME
和DirectShow中的时间和时钟 。
REFERENCE_TIME数据类型定义DirectShow中参考时间的单位。 每个参考时间单位为100纳秒。
...
时间戳定义了媒体样本的开始和结束时间,以流时间衡量。 时间戳有时称为演示时间
...
文件播放:第一个样本带有时间戳,开始时间为零。 随后的时间戳由样本长度和回放速率确定,而采样速率和回放速率本身由文件格式确定。 解析文件的过滤器负责计算正确的时间戳。
所以,
如何以秒为单位获取正确的帧时间...
DOUBLE Time = tStart / 1E7; // <<--- presentation time (see above) in seconds
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.