Source:
http://www.tech−archive.net/Archive/Development/microsoft.public.win32.programmer.directx.video/2005−12/msg00559.· From: "Daniel Bowen" <DanielBowenWl@xxxxxxxxxxxxxxxxx>
· Date: Thu, 29 Dec 2005 18:27:10 −0700
One of the direct show graphs that we have goes something like this:
RTP Source filter −> WMV DMO Decoder −> Transform filter −> VMR 7
The RTP Source filter inherits from CSource in the DirectShow base classes,
plus a custom interface. It uses a customized output pin that inherits from
CSourceStream. The transform filter inherits from CTransformFilter, plus a
custom interface. It does not currently customize the input or output pins.
The WMV DMO Decoder is explicitly created and connected in the graph. It is
created with something like the following:
#ifndef CLSID_CWMVDecMediaObject
const GUID CLSID_CWMVDecMediaObject =
{ 0x82D353DF, 0x90BD, 0x4382, { 0x8B, 0xC2, 0x3F, 0x61, 0x92, 0xB7,
0x6E, 0x34 } };
#endif
....
CComPtr<IDMOWrapperFilter> pWMVDecoderDMOWrapperFilter;
hr =
pWMVDecoderDMOWrapperFilter.CoCreateInstance(CLSID_DMOWrapperFilter);
if(SUCCEEDED(hr))
{
hr =
pWMVDecoderDMOWrapperFilter−>Init(CLSID_CWMVDecMediaObject,
DMOCATEGORY_VIDEO_DECODER);
}
I'd like to add a media time to samples, to track the samples through the
graph (and a separate graph that feeds this graph). Essentially, I want to
treat it as a frame number, which from what I've read is one of the intended
uses of GetMediaTime/SetMediaTime. However, I'm having a problem getting
the media time to survive through the decoding. The source output pin
creates a media sample with GetDeliveryBuffer (implemented on the output
pin), then a FillBuffer routine calls IMediaSample::SetMediaTime on the new
sample. The media start time I have as the frame number, and the media end
time I have as the frame number plus one. This frame number comes from a
capture device that is delivered in a custom header upstream that gets to
this graph from a separate graph.
In a separate graph that feeds this graph, the media time is properly passed
along. However, we control all of the filters in that graph.
Ideally, I'd like to be able to call GetMediaTime on the source
IMediaSample* in our transform filter's "Transform" method, which is
overriden from CTransformFilter and called by
CTransformFilter::Receive(IMediaSample *pSample). However, when I call it,
it fails with an HRESULT of VFW_E_MEDIA_TIME_NOT_SET. In the source
filter, I've tried both calling and not calling SetTime, but it doesn't make
a difference. I saw a post that seemed to imply you should implement
IAMFilterMiscFlags on the source filter and IAMPushSource on the output pin.
I've tried that as well. IAMFilterMiscFlags ::GetMiscFlags on the source
filter gets called, and I return AM_FILTER_MISC_FLAGS_IS_SOURCE, but
IAMPushSource methods never get called. Whether or not the IAM* interfaces
are implemented also don't seem to make a difference.
So it seems that the wrapper filter for the DMO is dropping the media time
on the floor. Is there some way that I can make it pass the media time
along? Is there some interface that I can implement on the filters or pins
I have control of to help? Is there some method that is getting called
already where I can pick up the media time for each sample? I've also
thought about using COM aggregation or containment to wrap the DMO wrapper,
and try to pass the media time that way . however, I'm not sure if I'm in
the loop enough to override something to set the media time after the
decoding but before it gets delivered to the output pin. I'm also open to
other ways of passing this frame number through the graph, as long as
there's a good way to sync a given media sample to it.
Thanks!
.Daniel
.
Follow.Ups:
RE: Media time not preserved through DMO decoder
a From: "TerryFei"