Introduction

Implementation of this filter is based on my BaseClasses.NET library which described in my previous post (Pure .NET DirectShow Filters in C#). So you can see how to implement encoder filters. Implementation uses NVIDIA CUDA Encoding API.

Implementation

Filter implemented same way as described in previous article. It uses TransformFilter as a base class and overrides its methods. Encoding settings can be configured via IH264Encoder interface:

Output types from filter are H264 in VideoInfo and VideoInfo2 formats, AVC1 with Mpeg2Video format and NALU size length - 4. I made filter to be available for connection to Avi Mux filter along with common mp4 mts flv and mkv multiplexors. I set timestamps in media samples according DTS not PTS, but that not issue for good decoders and allows to embed video into AVI even if closed gop used with large IDR period.

I have good perfomance using that filter and it works fine with 4% CPU usage on 30 FPS playback 1280x720 video. And that for VC-1 decoding H264 encoding, decoding and preview.

History

15-07-2012 - Initial version.

License

Share

About the Author

I'm a professional multimedia developer (more than 10 years) in any kind of applications and technologies related to it, such as DirectShow, Direct3D, WinMM, OpenGL, MediaFoundation, WASAPI, Windows Media and other including drivers development of Kernel Streaming, Audio/Video capture drivers and audio effects. Have experience in following languages: C, C++, C#, delphi, C++ builder, VB and VB.NET. Strong knowledge in math and networking.

I read the previous article about save settings in registry.
I think I have to do it by coding...
But I need to directly set the values on the registry and use this filter.
What are the registry keys for
1) profile = High
2) Level = 5.1
3) Rate Control = CBR
4) Bitrate (kbps) = 50000

I think you assume that I am using this filter from my .net application.
No. I am trying to use this filter from a simple capture application where I can pass the CLSID of this encoder. And every thing works fine.

The problem is I open this filter ("CSharp H264 CUDA Encoder Filter") in graphedit and change the settings on the property window and close the graphedit. Usually other directshow filters will save the new settings on the registry and use it while running. And show the new settings next time we see the property window. But right now it doesn't save the new settings on the register nor reading from.

Assume i am not a coder to use the methods you have given me and I need to use the filter at 50000 bitrate from a 3rd party app like AmCap.

How to do this ?
What I except from you is, Saving (and loading) the new values to registry from property window.

I have a video source filter which i designed in unmanaged c++ and its working perfect in unmanaged application (and of coarse in graph edit, graph studio). The graph includes this source filter and VMR9 connected to it and streaming video from the network.

this filter has a custom control interface called IID_ILvmSourceControl with few functions such as SetAudioPort(UINT16 AudioPort) and SetVideoPort(UINT16 VideoPort)

I build the same graph in c# with WPF app, i managed to add the VMR9 successfully and my filter as well, i also found the custom interface in my filer successfully.

The problem starts when I'm trying to call this custom interface. I declared the functions as

Although nVidia seems to have a hidden DirectShow filter (the GUID is in their docs) with the NV encoder, yours is visible in GraphEdit so that helps.
I'm able to generate frames (in a replay in my game), feed them to the CUDA filter, and then store it in an AVI file. When I use the 'Microsoft Windows Media Video 9' codec, this goes ok. When I use your filter, the output AVI plays back choppy.

It's as if the output frames are time-stamped in realtime, so the speed at which recording took place influences the speed at which the AVI plays back. For example, the x264vfw DirectShow filter has an option to output to VFW or a File. Seemingly the File option fixes this type of problem.

Do you know how I could do the same with your filter? Is this an nVidia encoder option thing? The only thing I change from the 'Microsoft Windows Media Video 9' is to insert your filter into the graph (which I make in C++).

You just need to build the filter graph for that file: source filter -> splitter -> decoder, after add the encoder and multiplexor. You can easy render the file using RenderFile method of IGraphBuilder and then change right part of the graph and place encoder and other filters yo need.