0
votes

I'm working on video streaming service for ip-cameras. I've implemented RTSP source filter (on Live555) for DirectShow, which is intended to be used in WPF MediaElement inside my company's main product. On my development machine it works fine (Vista), so I'm able to watch streamed H.264 video in Windows Media Player, or any other software, that uses DirectShow for rendering.

But: on other machines (Windows 7), no video is shown. I found out, that Enhanced Video Renderer in Vista (renderer file version 6.0.6002.18005) after receiving "Play" command calls on upstream filter IBaseFilter::Pause and IBaseFilter::Run methods, which are finally routed to my source filter. In Windows 7 EVR has different version (6.1.7601.17514), and its behavior differs too: it calls only IBaseFilter::Pause, and no IBaseFilter::Run is issued. As a result, everything stops on CSourceStream::FillBuffer method until timeout returns E_FAIL, and EndOfStream is sent downstream to renderer. Sometimes, after EndOfStream IBaseFilter::Run is issued, but it has no meaning at this point.

I tried to provide another renderer by creating and adding it to graph manually in CreateInstance method. It worked with Haali Video Renderer, and Windows Media Player successfully plays streamed video on other machines. But, as far as i know, MediaElement (MediaPlayer inside it) uses EVR by default, and it ignores HVR (seems so), created by me, so no video on any machine.

Am i missing something using EVR? Any help is appreciated.

1
The likely cause is video renderer's negotiation of extended stride which your filter should properly handle. I suppose the behavior you are seeing is a result of doing it somehow wrong. - Roman R.
@RomanR. Is it possible, that renderer waits for the first sample, or something similar? - Vladimir Doroshin
The behavior is slightly different, but both filters work reliably. The tricky parts is support of new media type with extended stride. If I had to guess, I'd say it's 95% chance that this is the cause. And you perhaps ignoring some incoming call or error code. What you described is a further symptoms. - Roman R.
I figured out: I didn't override IMediaFilter::GetState() to return VFW_S_CANT_CUE in State_Paused. After it was done, everything worked fine. - Vladimir Doroshin
This is the second top cause. You might want to duplicate this by returning S_FALSE in IBaseFilter::Pause as well. - Roman R.

1 Answers

0
votes

I forgot to reimplement IMediaFilter::GetState() method to return VFW_S_CANT_CUE in State_Paused. Doing so solved the problem.