0
votes

I wrote my own RTSP Push Source DirectShow filter (CBaseFilter), that works for H264 like a charm! But, when I tried to support MPEG4 (MP4V-ES stream), I stumbled upon a problem... My stream gets decoded (with ffdshow Video Decoder filter, or DivX Video Decoder) and rendered perfectly for exactly 10 seconds. Picture is fluent at 15fps, but after 10 secs fps drops drastically, and only IVOPs are decoded, and PVOPs/BVOPs are discarded... even though I recieve them, and send them to the decoder on time.

Then I started to fiddle with my code, and I discovered that I depacketize MPEG4 RTP payload correctly, and I send media samples to decoder correctly, and I release them correctly, also CBaseOutputPin::DecideBufferSize() does its job like it should, and I call IMediaSample::SetTime() correctly... BUT, if I change this code that delivers a sample to the decoder:

hr = videoPin->Deliver(sample);
sample->Release();

with this code (note the first line):

videoPin->DeliverNewSegment(REFERENCE_TIME(start), REFERENCE_TIME(end), 1.0);                                               
hr = videoPin->Deliver(sample);
sample->Release();

the video is fluent after 10 seconds and beyond (fps stays at 15), but the picture is all messed up... like IVOP is not decoded as it should, and there are some artefacts in static parts of the scene.

So, how do I use CBaseOutputPin::DeliverNewSegment()? And why the heck do I need it?

Because I guess I do need it, since it stops my video stream from not being decoded fluently...

I googled, but without luck. Any help will be appreciated. Thanx.

UPDATE

In method videoPin->DeliverNewSegment(tStart, tStop, dRate) parameter dRate is:

Rate at which this segment should be processed, as a percentage of the original rate.

So if instead of 1.0 I put 100.0 stream is flowing as it is supposed to, but with some delay in between some frames. But this is the best so far!

1
I don't think you are correct about percentage thing. 1.0 is what has to be there, it is clear from BaseClasses source code, m_dRate(1.0) in CBasePin constructor. Another thing is that you might be dealing with a buggy filter which in turn interprets this incorrectly.Roman R.
well dang... will check the filter.Cipi

1 Answers

1
votes

I'm not convinced that NewSegment causes the issues you are seeing. NewSegment is used for those cases where the data you push in a single packet crosses the start time or the stop time, and it allows the decoder to only deliver up to the stop time. In this case you could call NewSegment (0, MAX_LONGLONG, 1) once at start of streaming and it should be fine.

If you see problems, then perhaps you should check the latency at the decoder output (compare timestamp with current stream time).

G