|
|
|
date: Fri, 15 Aug 2008 10:11:32 -0700 (PDT),
group: microsoft.public.win32.programmer.directx.video
back
Rendering the output of an exotic decoder
Dear All,
Output of my decoder filter is somewhat exotic because it:
1) Introduces a very long delay (up to one second or even more). This
means that the very first output sample whose presentation time is,
let's say, 0...40ms in fact becomes ready much, much later when the
current time is, for example, 700ms.
The actual delay is not known beforehand and may change for each run.
However, it is equal for all consequent samples.
2) Samples are produced in packs. That is, after the initial delay
almost instantly several samples (up to 16) become available, then a
long pause follows (which is shorter than the time, necessary to show
all previous samples), and then the next pack is ready at the output
etc.
Needless to say, Video Renderers are not overly happy with my samples
and sometimes the playback is jerky.
Unfortunately, I can't do much with these issues in the decoder itself
so currently I'm working on an additional temporal smoothing filter
(it is based on CTransformFilter and uses COutputQueue internally)
which will be inserted between the decoder and video renderer and
hopefully will be able to improve the situation.
As far as I understand, the first problem - delay - is easy to solve.
Everything I have to do is to measure the delay of the very first
sample and correct start and stop times of each sample by adding this
delay. I do it this way (obviously, actual code includes error
checking and other boring stuff):
class CMyFilter : public CTransformFilter
{
private:
bool IsFirstFrame;
REFERENCE_TIME FirstFrameStartTime;
...
};
HRESULT CMyFilter::StartStreaming()
{
IsFirstFrame = true;
...
}
HRESULT CMyFilter::Transform(IMediaSample *pIn, IMediaSamle *pOut)
{
if(IsFirstFrame)
{
/* this is the very first sample so we must determine how much
it is delayed */
CRefTime Rt;
StreamTime(Rt);
FirstFrameStartTime = Rt.operator REFERENCE_TIME();
/* we don't need to measure the delay any more */
IsFirstFrame = false;
}
/* get original sample times */
REFERENCE_TIME FrameStart, FrameStop;
pIn->GetTime(&FrameStart, &FrameStop);
/* correct the times */
FrameStart += FirstFrameStartTime;
FrameStop += FirstFrameStopTime;
pOut->SetTime(&FrameStart, &FrameStart);
...
}
This works pretty well. However, being a perfectionis, I believe there
should be a less ugly and more elegant solution. Any ideas?
The second problem - irregular (however, properly timestamped) samples
- seems to be more difficult to solve.
After brief debugging the SampVid SDK sample and investigating the
CBaseRenderer class source I came to the (probably wrong) conclusion
that CBaseRenderer works this way: it waits for the sample's
StartTime, displays the sample and then immediately returns from the
input pin's Receive() method thus completely ignoring its StopTime. In
my case this leads to a real tragedy: the next sample from the pack is
immediately available and arrives to the renderer at the moment when
it is definitely too early to display this new sample. When the whole
pack is processed, then the next sample reaches the renderer after a
long delay.
As the net result, Video Renderer reports terrible jitter. Also, seems
like due to some internal statistics (this part of the code is totally
incomprehensible to me) the renderer decides to drop some of my
samples (however, it never reports any dropped samples) and the
playback becomes jerky. Funny thing, sometimes it works OK and
sometimes not.
I am highly temped to measure time spent in the renderer and sleep
until the current sample's StopTime before going to the next sample...
If anyone could hold me back from this exceptionally funny (and, most
probably, terribly wrong) solution by suggesting something at least a
bit more appropriate, I am going to be extremely grateful.
Thanks in advance for any suggestions!
PS. Perhaps it's proper time to state that neither DirectShow nor
English are my native languages and beg your pardon for any idiocity
found in the text above.
date: Fri, 15 Aug 2008 10:11:32 -0700 (PDT)
author: Rbr
|
|