In DirectShow, a media sample has two time-related properties: its time stamp and its media time. My application needs to seek to specific frames within a video and thus requires the media time. As it seems, however, most decoder filters do not pass on this information.
I have a DirectShow graph that looks like this:
[File Source (Async.)] -> [AVI Splitter] -> [<Video decoder>] -> [My filter]
I have tried the following video decoders:
- DMO Wrapper Filter with Mpeg4s Decoder DMO (that's the default for MPEG-4 on my machine)
- Xvid MPEG-4 Video Decoder
- MainConcept (Demo) MPEG-4 Video Decoder
- ffdshow Video Decoder (ffdshow tryouts)
Of these four, only the ffdshow decoder produces samples with media time. The other three only set the time stamp, but leave the media time empty. This seems strange as each sample they get from the AVI splitter has its media time set correctly.
Does anybody know why this happens? Is there a workaround for getting the media time that works reliably even when the application continually jumps through the video?
Edit (in response to kidjan):
Let's assume I want to read video frame #100. With a 25fps file, this frame is 4 seconds into the video. Using the filter graph's IMediaSeeking interface, I seek to that position. Internally, this seek request is forwarded to the splitter filter (the AVI splitter in the example). However, there are two potential problems:
- Depending on the video format, I cannot be sure that the splitter will be able to seek precisely to frame #100. It may arrive at frame #95 instead and I will have to read 5 frames before getting the correct frame.
- The splitter may be frame-accurate, but due to the asynchronous nature of DirectShow the next frame yielded by the decoder filter may be a relict from before the seeking. If the decoder filter uses threading, it may deliver that frame after the seek action.
In these cases, it would be helpful if the decoder filter set the samples' media time. This way, I would know for certain which frame I receive.
What my question boils down to is basically:
How can I grab a specific video frame (by number) within a DirectShow graph?