0
votes

I am using DirectShow/VMR9 to playback a MPEG 4 video in my application. I use IMediaSeeking SetRate to set the speed of the video. Playing back a video I have created plays well at speeds up to 4x, above this the video becomes very jerky. Playing back the same file using Windows media player at speeds above 4x is not jerky. Can anyone shed some light as to why windows media player can play my file OK at speed but my DirectShow filter graph cannot.

My graph topology is Recording.avi -> AVI Splitter -> Mpeg4s Decoder DMO -> Ds.NET Grabber -> Color Space Converter -> Video Mixing Renderer 9.

Please let me know if you need any further information.

Update

I removed the grabber (and thus csc as well) and playback is not jerky up to 8x which would be good enough but I do need the grabber. The CSC ended up there when I added the grabber. I would like if possible to remove the CSC to see if that improves things while retaining the grabber. Below are my graphs with intermediate formats with and without the filter. I tried setting the media subtype of the grabber to NV12 (like the non grabber graph), however I get error a "No combination of intermediate filters could be found to make the connection." I include my code for configuring the grabber.

Is it possible to get this to work without the csc?

Also not sure if it is relevant but I do not understand how the video dimensions are changed on the graph without grabber.

With Grabber

Recording.avi ----- (AVI) ----- AVI Splitter ----- (MP4V - 704*576 – 24bits ) ----- Mpeg4s Decoder DMO ----- (RGB24 704*576) ----- Ds.NET Grabber - (RGB24 704*576) ----- Color Space Converter ----- (ARGB32 704*576) ----- Video Mixing Renderer 9

Without Grabber

Recording.avi ----- (AVI) ----- AVI Splitter ----- (MP4V - 704*576 – 24bits ) ----- Mpeg4s Decoder DMO ----- (NV12 768*576 12 bits) ----- Video Mixing Renderer 9.

 private void ConfigureSampleGrabber(ISampleGrabber sampleGrabber)
 {
        AMMediaType media;
        int hr;

        // Set the media type to Video/RBG24
        media = new AMMediaType();
        media.majorType = MediaType.Video;
        media.subType = MediaSubType.ARGB32; // tried NV12 here, gives error.
        media.formatType = FormatType.VideoInfo;
        hr = sampleGrabber.SetMediaType(media);
        DsError.ThrowExceptionForHR(hr);

        DsUtils.FreeAMMediaType(media);
        media = null;

        // Configure the samplegrabber
        hr = sampleGrabber.SetBufferSamples(true);
        DsError.ThrowExceptionForHR(hr);
    }

CPU Usage details

Core i3 - 3300MHz – with hyperthreading 4GB RAM

4x Speed

CPU1 ~45%

CPU2 ~0%

CPU3 ~33%

CPU4 ~0%

8x Speed

CPU1 ~40%

CPU2 ~25% (but very spiky 0-50%)

CPU3 ~40%

CPU4 ~0%

Core i3 - 3300MHz – Hyperthreading disabled in BIOS.

4x Speed

CPU1 ~45%

CPU2 ~33%

8x Speed (same results at 16x Speed)

CPU1 ~66%

CPU2 ~45%

2

2 Answers

2
votes

A typical cause would be that at this playback rate your decoding thread is running at 100% CPU and is not capable to decode more frames, you start seeing irregular frame presentation and/or frames dropped.

Where to look:

  • check your CPU with task manager or another application to see if one of the cores is maxed out and is no longer going to idle state
  • checked VMR properties to see if frames are dropped, or jitter is getting too high

enter image description here

1
votes

For the playback of videos the MediaPlayer is using MediaFoundation. And for most videos the playback is hardware accelerated. If you have some filters between the decoder and the renderer in DirectShow, there is no hardware acceleration in DirectShow. Try it again without the DS.Net Grabber and the color-space-converter (=> csc is also a huge performance killer)