Datastead Multipurpose DirectShow Encoder
Datastead Multipurpose DirectShow Encoder
Stop_PauseWhenStop......................................................................................................................14
GetCurrentLog...................................................................................................................................14
IsCurrentLogUpdated........................................................................................................................15
GetExitCode.......................................................................................................................................15
GetInputsTotalDurationMs.................................................................................................................15
GetProgress_FrameCount.................................................................................................................15
GetProgress_TimeMs........................................................................................................................15
GetProgress_DuplicatedCount..........................................................................................................15
GetProgress_DroppedCount.............................................................................................................15
GetProgress_Fps...............................................................................................................................15
GetProgress_Quality.........................................................................................................................15
GetProgress_SizeWrittenKb..............................................................................................................15
GetProgress_BitRateKbps.................................................................................................................15
GetConnectedVideoPinInfo...............................................................................................................15
GetConnectedAudioPinInfo...............................................................................................................16
SetMediaEventSinkNotifyID..............................................................................................................16
Is64BitWindows.................................................................................................................................16
Is64BitApplication..............................................................................................................................16
Reserved command-line keywords........................................................................................................17
PAUSEWHENSTOP..............................................................................................................................17
SHOWCONSOLE..................................................................................................................................17
NOLOG..................................................................................................................................................17
LOWLATENCY.......................................................................................................................................17
NOABORTONERROR...........................................................................................................................17
DONTOVERWRITE...............................................................................................................................17
TOPDOWN.............................................................................................................................................18
COMPRESS...........................................................................................................................................18
RTSPPORT............................................................................................................................................18
UDPPORT..............................................................................................................................................18
RTSPSESSION......................................................................................................................................18
Graph event notification through IMediaEventEx................................................................................19
IMediaEventEx events...........................................................................................................................19
Retrieving the sender instance when several instances of the Multipurpose Encoder are used in the
same graph............................................................................................................................................19
Quick start from GraphEdit.exe..............................................................................................................21
How to debug............................................................................................................................................22
Using the filter for a normal processing, without DirectShow input..................................................23
Screenshots..............................................................................................................................................24
graphedit:...............................................................................................................................................24
graphedit with debug console:...............................................................................................................25
Overview
Features
The Datastead Multipurpose Encoder is a DirectShow Multiplexer/Sink filter able to compress or encode
audio/video streams by invoking in the background a command-line transcoder executable, if this
executable supports a named pipe as input.
A LGPL build of FFmpeg named ffmpegLGPL.exe is included in the filter.
The filter multiplexes the uncompressed DirectShow video and audio streams into an ASF transport
stream and writes this stream to a named pipe. The named pipe is taken as input by the transcoder, that
is invoked as a child process in a non-visible background process from the command line.
There is no binding or C++ linking between the filter and the transcoder, all the settings are passed by
the command-line, and the audio/video stream is passed through the named pipe.
To configure the filter, just invoke SetCommandLine and specify the desired command line, along with
some reserved keywords for the filter control.
When the graph runs, the transcoder process starts in the background, and stops when the graph is
stopped.
Additionally to this default DirectShow behavior, the "PAUSEWHENSTOP" feature allows to pause the
process while the graph is stopped, and to resume it when the graph is ran again, allowing to build in
real time a single audio/video clip from start/stop sequences separated in time.
It is possible to make the transcoder console visible for debugging or control purpose.
System requirements
Windows 7, Windows 8, Windows 8.1, Windows 10 (tested with Windows 10 preview)
32bit or 64 bit operating system supported.
Download
The evaluation package can be downloaded here:
http://www.datastead.com/products/dsfilters/multipurpose.html
License
The license agreement can be found here:
http://www.datastead.com/index.php?option=com_content&id=56
To buy a license visit our online store here:
http://www.datastead.com/purchase.html
Contact
Email:
[email protected]
[email protected].
[email protected]
Alternative email address:
[email protected]
Web:
http://www.datastead.com/contact.html
FAQ
Licensing
Should I buy one license for each one of my customers?
No, it's a per-developer, royalty-free license. After purchasing the developer license you can distribute
the filter along with the end-user application you have developed on as many PCs as needed, without
having to pay anything else.
Does the Multipurpose DirectShow encoder include GPL code?
No, the Multipurpose DirectShow encoder includes only a LGPL build of ffmpeg.exe. There is no GPL
code installed by the package.
Evaluation version
What are the limitations of the evaluation version?
The filter overlays a "Datastead" logo over the video frames or shows a green flash one time then two
times alternatively and periodically.
These limitations are removed in the licensed version.
Troubleshooting
GraphEdit.exe crashes when I click on "DirectShow filters" to insert a filter
The problem is an incompatibility between GraphEdit and new generation of codecs like the LAV filters
codecs.
As the LAV filters may they may required for decoding, instead of GraphEdit, use GraphStudioNext, it
has the same features and there is no compatibility problem.
The MP4 clip recorded does not play in the Windows Media Player
Verify if "-movflags frag_keyframe+empty_moov" if specified in the command-line, if yes just remove
them.
The advantage of these attributes is that they allow to create a clip that can be played while it is being
recorded. The problem being that this format is not supported by the Windows Media Player.
Filter install/Uninstall
The single .exe installer included in the package installs and registers automatically:
- the x86 version of the filter on Windows 32bit,
- both the x86 and x64 versions of the filter on Windows 64bit.
Filter configuration
Adding the filter to the graph
1. create the filter instance
2. add the filter to the graph
3. query the filter's IDatasteadMultipurposeDirectShowEncoder interface
4. invoke SetCommandLine on this interface.
5. render the pins
6. run the graph.
E.g.:
... create filter graph...
... add video and/or audio capture devices ...
IBaseFilter *DatasteadMPE = NULL;
HRESULT hr = CoCreateInstance(CLSID_DatasteadMultipurposeDirectShowEncoder, NULL,
CLSCTX_INPROC_SERVER, (void**) &DatasteadMPE);
if (SUCCEEDED (hr)) {
hr = pGraph->AddFilter(DatasteadMPE, "Datastead Multipurpose Encoder");
if (SUCCEEDED (hr) {
IDatasteadMultipurposeDirectShowEncoder *MPEConfig;
hr = Filter.QueryInterface (IID_IDatasteadMultipurposeDirectShowEncoder,
(void**) &MPEConfig);
if (SUCCEEDED (hr) {
hr = MPEConfig.SetCommandLine (...transcoder's ".exe" command line...);
if (SUCCEEDED (hr)) {
... from render the video and audio output pins, and run the graph
}
MPEConfig->Release();
}
}
DatasteadMPE->Release();
}
ffmpegLGPL.exe is the name of the LGPL build of FFmpeg included in the installation folder of the filter.
Simply specify ffmpegLGPL.exe "as is" without path, it is located in the filter's folder and found
automatically without having to specify the path.
%PIPE% is mandatory for the transcoder to take the filter's output as input. I must be written
exactly as is. It corresponds to the pipe generated by the filter and used as input by the transcoder. At
runtime, %PIPE% is replaced by the real name of the pipe, generated automatically by the filter.
To use another transcoder, specify its path. This path must be specified between quotes if it contains
spaces, like in the example below, unless the transcoder can be found through the DOS search paths.
E.g. to use a third-party ffmpeg.exe that has been saved into "c:\FFmpeg folder":
MPEConfig.SetCommandLine (\"c:\\ffmpeg folder\\ffmpeg.exe\" -r 30 -i %PIPE% -strict
experimental -acodec aac -ab 128k -ac 2 -threads 6 -vcodec mpeg4 -b:v 16200k -g 30
-trellis 2 -cmp 2 -subcmp 2 -mbd rd -flags +mv4+aic \"outputclip.mp4\"");
Frame rate
Depending on the capture device, if the output frame rate looks inconsistent, specify an input frame rate.
E.g. with FFmpeg for a 30 fps input frame rate:
MPEConfig.SetCommandLine ("ffmpegLGPL.exe -r 30 -i %PIPE% ...
10
11
12
IDatasteadMultipurposeDirectShowEncoder interface
The filter exposes the following interface:
DECLARE_INTERFACE_(IDatasteadMultipurposeDirectShowEncoder, IUnknown)
{
virtual HRESULT
STDMETHODCALLTYPE SetCommandLine(/*in*/ LPWSTR CommandLine) PURE;
virtual HRESULT
STDMETHODCALLTYPE GetCommandLine(/*out*/ LPWSTR *CommandLine) PURE;
virtual HRESULT
STDMETHODCALLTYPE Stop_PauseWhenStop() PURE;
virtual HRESULT
STDMETHODCALLTYPE GetCurrentLog(
/*in*/ bool OnlyIfUpdated,
/*in*/ PCHAR pBuffer,
/*in*/ int MaxBufferSize,
/*out*/ int *CurrentLogSize,
/*out*/ int *CurrentLogFlag) PURE;
virtual HRESULT
STDMETHODCALLTYPE IsCurrentLogUpdated() PURE;
virtual int
STDMETHODCALLTYPE GetExitCode() PURE;
virtual unsigned int STDMETHODCALLTYPE GetInputsTotalDurationMs() PURE;
virtual unsigned int STDMETHODCALLTYPE GetProgress_FrameCount() PURE;
virtual unsigned int STDMETHODCALLTYPE GetProgress_TimeMs() PURE;
virtual unsigned int STDMETHODCALLTYPE GetProgress_DuplicatedCount() PURE;
virtual unsigned int STDMETHODCALLTYPE GetProgress_DroppedCount() PURE;
virtual double
STDMETHODCALLTYPE GetProgress_Fps() PURE;
virtual double
STDMETHODCALLTYPE GetProgress_Quality() PURE;
virtual double
STDMETHODCALLTYPE GetProgress_SizeWrittenKb() PURE;
virtual double
STDMETHODCALLTYPE GetProgress_BitRateKbps() PURE;
virtual HRESULT
STDMETHODCALLTYPE GetConnectedVideoPinInfo(
/*out*/ int *VideoWidth,
/*out*/ int *VideoHeight,
/*out*/ int *VideoAvgTimePerFrame) PURE;
virtual HRESULT
STDMETHODCALLTYPE GetConnectedAudioPinInfo(
/*out*/ int *AudioChannels,
/*out*/ int *AudioSampleRate,
/*out*/ int *AudioBitsPerSample) PURE;
virtual HRESULT
STDMETHODCALLTYPE SetMediaEventSinkNotifyID (LONG_PTR Value) PURE;
virtual BOOL
STDMETHODCALLTYPE Is64BitWindows() PURE;
virtual BOOL
STDMETHODCALLTYPE Is64BitApplication() PURE;
};
SetCommandLine
Sets the FFmpeg command line, with eventual extra keywords destined to the filter. The syntax is
described here.
13
GetCommandLine
Retrieves the current command line. Pass LPWSTR pointer to the function. The function allocates
memory and copy the string. If the function succeeds, the LPWSTR pointer must be freed by invoking
CoTaskMemFree.
E.g.:
LPWSTR pCommandLine;
if (SUCCEEDED (MPEConfig.GetCommandLine (&pCommandLine))) {
... do what you need with the pCommandLine string returned
CoTaskMemFree (pCommandLine);
}
Stop_PauseWhenStop
See the PAUSEWHENSTOP keyword in the reserved keywords chapter.
GetCurrentLog
Copies the current FFmpeg log string in a buffer. If the string contains several lines, they are separated
by CR/LF characters: char(13)/char(10).
Note that this function does not work if SHOWCONSOLE has been specified.
You must allocate the buffer and pass its pointer to the function.
To determine the required maximum buffer size and allocate the buffer, invoke GetGurrentLog with all
parameters to 0 / NULL excepted CurrentLogSize that will return the size required to allocate the buffer,
e.g.:
int MaxBufferSize;
CHAR *pBuffer = NULL;
...
if (pBuffer == NULL) {
if SUCCEEDED (MPEConfig.GetCurrentLog (false, NULL, 0, &MaxBufferSize, NULL)) {
pBuffer = new CHAR[MaxBufferSize];
}
}
Then to read the current log:
int BufferSizeRead = 0;
if SUCCEEDED (MPEConfig.GetCurrentLog (true, pBuffer, BufferSize, &BufferSizeRead, NULL)) {
... do anything with the string in the buffer...
}
Notes:
OnlyIfUpdated parameter:
. if false, the buffer returns its content, even if this content has already been returned by the function
- if true and the buffer content has changed, the function fills the buffer and returns S_OK, otherwise it
returns E_NOT_SET
the buffer is "string safe": GetCurrentLog writes a NULL character at the end of the text read.
14
IsCurrentLogUpdated
return S_OK if the buffer content has changed or E_NOT_SET. It is useless to invoke it to determine if
GetBufferLog must be invoked just after, in this case invoke directly with the OnlyIfUpdated parameter =
true, e.g. GetBufferLog (true, ...) so it will return directly E_NOT_SET if no new log is available.
GetExitCode
returns the exit code, 0 on success or another value if the encoding failed for any reason (usually a
wrong command line syntax or a non-writeable output file).
GetInputsTotalDurationMs
(*)
when the input file has a fixed size, it returns the duration reported by FFmpeg in milliseconds. If several
input files are used (e.g. when concatening clips, the value returned is the total duration of final clip (the
sum of the durations of the concatened clips).
GetProgress_FrameCount
returns the current frame count (*)
GetProgress_TimeMs
returns the current stream time in milliseconds (*)
GetProgress_DuplicatedCount
returns the number of duplicated frames, if any (*)
GetProgress_DroppedCount
returns the number of dropped frames, if any (*)
GetProgress_Fps
returns the average number of frames per second (*)
GetProgress_Quality
returns the average quality (the meaning depends on the codec) (*)
GetProgress_SizeWrittenKb
return the size written to disk in KiloBytes (*)
GetProgress_BitRateKbps
returns the average bit rate in KiloBytes per second (*)
(*) these functions are currently supported only with FFmpeg, and only if SHOWCONSOLE has not been
specified.
GetConnectedVideoPinInfo
returns the video size of the input pin, and average time per frame of the video input stream (expressed
in 100 nanoseconds units, 1 second = 10000000, e.g. at 25 fps the average time per frame returns
400000)
15
GetConnectedAudioPinInfo
return the number of audio channels, the sample rate and the number of bits per sample of the audio
input pin
SetMediaEventSinkNotifyID
This is useful only:
- when processing the event notifications sent by the filter to the graph (when implementing
IMediaEventSink),
- and when using more than one instance of the Multipurpose Encoder in the same graph
Is64BitWindows
This helper function lets you know if your app is running on a Windows 64bit PC, or on a Windows 32bit
PC.
Is64BitApplication
This helper function lets you know if the application compiled in 32bit or 64bit.
16
PAUSEWHENSTOP
If specified, when the graph is stopped, the FFmpeg recording is paused (instead of being stopped as
well). When the graph is ran again, the FFmpeg recording is resumed. So this lets record a single,
continuous clip without gap, although the graph has been stopped and restarted, whatever the interval of
time between the stops and starts.
Note that when this feature is enabled, and you want to FINALLY stop the FFmpeg recording, invoke
MPEConfig.Stop_PauseWhenStop().
If Stop_PauseWhenStop is never invoked, the recorded clip will be closed when exiting the application.
Notes:
- while the graph is stopped, the video and audio pins must not be disconnected / reconnected.
SHOWCONSOLE
makes the console visible. Mainly for debugging purpose. In this mode the FFmpeg information (e.g.
current time, frame count) is not available through the the filter interface (see the interface below)
NOLOG
Can be specified to save CPU. if specified, the filter does not analyze the FFmpeg progress information
(e.g. current time, frame count), so the filter does not report them.
LOWLATENCY
Specify it if the filter is used for a live streaming in real time (e.g. to send the stream to a Wowza server).
NOABORTONERROR
If there is an error (e.g. if the syntax is not correct and/or if FFmpeg exits by itself with an error code), the
filter sends an EC_ERRORABORT notification to the graph, that stops the graph.
If
NOABORTONERROR
is
specified,
the
filter
sends
instead
an
"neutral"
EC_MPE_TERMINATED_ERROR notification to the graph that can be handled, but the graph does not
stop.
DONTOVERWRITE
by default, if the command line contains "FFmpeg", the filter passes the "-y" option to FFmpeg to
overwrite a previous clip, if any.
Set this option to prevent overwriting an existing file, however it is NOT RECOMMENDED to use it,
because if SHOWCONSOLE is disabled and FFmpeg waits for the overwrite confirmation, the graph will
17
just hang.
TOPDOWN
If specified, the image is flipped vertically without extra CPU load. Can be required by some encoders if
the image appears inverted.
COMPRESS
If specified, the video stream passed through the pipe, compressed in MPEG-4. If the command line
transcoder does not accept the pipe uncompressed, enabling this option could fix the problem.
Note that enabling this option will significantly increase the CPU load.
RTSPPORT
See the Using the built-in RTSP server chapter.
UDPPORT
See the Using the built-in RTSP server chapter.
RTSPSESSION
See the Using the built-in RTSP server chapter.
18
20
21
How to debug
First verify if the solution is not in the the Support section of the FAQ. If not:
1. add "SHOWCONSOLE" at the beginning of the command line, to see if the FFmpeg process starts
and if any red error report appears.
2. add " -report" or " -report -loglevel debug" to the command line, this will generate the FFmpeg log file
in the current folder.
Verify/fix the FFmpeg syntax, then try again.
PS: don't forget to remove the report and loglevel statements because they slow-down the filter.
22
23
Screenshots
graphedit:
24
25