Search code examples
c++directshowrenderer

DirectShow video stream ends immediately (m_pMediaSample is NULL)


I have a Video renderer redived from CBaseVideoRenderer. The renderer is used in a graph that receives data from a live source (BDA). It looks like the connections are established properly, but the video rendering immediately ends because there is no sample. However, audio Rendering works, ie I can hear the sound while DoRenderSample of my renderer is never called.

Stepping through the code in the debugger, I found out that in CBaseRenderer::StartStreaming, the stream ends immedately, because the member m_pMediaSample is NULL. If I replace my renderer with the EVR renderer, it shows frames, ie the stream is not ending before the first frame for the EVR renderer, but only for my renderer.

Why is that and how can I fix it? I implemented (following the sample from http://www.codeproject.com/Articles/152317/DirectShow-Filters-Development-Part-Video-Render) what I understand as the basic interface (CheckMediaType, SetMediaType and DoRenderSample), so I do not see any possibility to influence what is happening here...

Edit: This is the graph as seen from the ROT: Running Object Table Entry

What I basically try to do is capturing a DVB stream that uses VIDEOINFOHEADER2, which is not supported by the standard sample grabber. Although the channel is a public German TV channel without encryption, could it be that this is a DRM issue?

Edit 2: I have attached my renderer to another source (a Blackmagic Intensity Shuttle). It seams that the source causes the issue, because I get samples in the other graph.

Edit 3: Following Roman's Suggestion, I have created a transform filter. The graph looks like

ROT of graph with grabber

an has unfortunately the same problem, ie I do not get any sample (Transform is not called).


Solution

  • You supposedly chose wrong path of fetching video frames out of media pipeline. So you are implementing a "network renderer", something that terminates the pipeline to further send data to network.

    A renderer which accepts the feed sounds appropriate. Implementing a custom renderer, however, is an untypical task and then there is not so much information around on this. Additionally, a fully featured renderer is typically equipped with sample scheduling part, which end of stream delivery - things relatively easy to break when you customize it through inheriting from base classes. That is, while the approach sounds good, you might want to compare it to another option you have, which is...

    A combination of Sample Grabber + Null Renderer, two standard filters, which you can attach your callback to and get frames having the pipeline properly terminated. The problem here is that standard Sample Grabber does not support VIDEOINFOHEADER2. With another video decoder you could possibly have the feed decoded info VIDEOINFOHEADER, which is one option. And then improvement of Sample Grabber itself is another solution: DirectX SDK Extras February 2005 (dxsdk_feb2005_extras.exe) was the SDK which included a filter similar to standard Sample Grabber called Grabber \DirectShow\Samples\C++\DirectShow\Filters\Grabber. It is/was available in source code and provided with a good description text file. It is relatively easy to extend to allow it accept VIDEOINFOHEADER2 and make payload data available to your application this way.

    The easiest way to get data out of a DirectShow graph, if youњre not going to use MultiMedia Streaming, is probably to write your own TransInPlace filter, a sub-variety of a Transform filter. Then connect this filter to the desired stream of data you wish to monitor, and then run, pause, seek, or otherwise control the graph. The data, as it passes through the transform filter, can be manipulated however you want. We call this kind of filter, a Њsample grabberћ. Microsoft released a limited-functionality sample grabber with DX8.0. This filter is limited because it doesnњt deal with DV Data or mediatypes with a format of VideoInfo2. It doesnњt allow the user to receive prerolled samples. (Whatњs a preroll sample? See the DX8.1 docs) Its ЊOneShotћ mode also has some problems.

    To add to this, the Grabber sample is pretty simple itself - perhaps 1000 lines of code all together, including comments.