I want to grab frames from a video file. Due to some bugs in Directshow's SampleGrabber I decided to create a similar filter (not a transform filter but a renderer).
I'm trying to create an DirectShow filter based on Windows SDK Dump filter (Microsoft SDKs\Windows\v7.1\Samples\multimedia\directshow\filters\dump
).
My filter accepts only RGB24 format.
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;
}
}
I get correct RGB frames, but I do not understand how to interpret values returned from IMediaSample::GetTime() method.
I use pSeeking->SetPositions( &Start, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame, 0, AM_SEEKING_NoPositioning);
to seek to different positions in source file.
See my log when I try to grab 8 frames.
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
I do not understand what these numbers mean and why they are not making up an increasing sequence.
The correct timestamps for these frames should be:
00:00:12
00:00:37
00:01:01
00:01:26
00:01:51
00:02:15
00:02:40
00:03:05
You get correct time - 64-bit values in 100ns units. See REFERENCE_TIME
and Time and Clocks in DirectShow.
The REFERENCE_TIME data type defines the units for reference times in DirectShow. Each unit of reference time is 100 nanoseconds.
...
The time stamp defines a media sample's start and finish times, measured in stream time. The time stamp is sometimes called the presentation time
...
File playback: The first sample is time stamped with a start time of zero. Subsequent time stamps are determined by the sample length and the playback rate, which itself is determined by the file format. The filter that parses the file is responsible for calculating the correct time stamps.
So,
How to get correct frame time in seconds...
DOUBLE Time = tStart / 1E7; // <<--- presentation time (see above) in seconds