Basic info
In MPlatform it's possible to use some of the native FFMPEG video filters with MPlatform objects. For MFormats, support for FFMPEG video filter was introduced in version 2.10.0.14414 and is available exclusively in the Expert and Ultimate editions. FFMPEG video filter offer advanced video processing capabilities, allowing users to apply custom video effects and transformations within the SDK framework.
MFormats SDK
The usage of vfilters in MFormats SDK is similar to working with plugins such as CG, MCCDisplay, etc. In general, it's needed to create a MFXMediaConverter instance, set its parameters, and during the frame processing pipeline, each frame is processed by this converter. Below is an example of how to add and apply the "negate" filter in MFormats SDK:
MFReaderClass m_objReader = new MFReaderClass();
MFPreviewClass m_objPreview = new MFPreviewClass();
MFXMediaConverter m_objConverter = new MFXMediaConverter();
m_objReader.ReaderOpen(pathToVideo, "");
m_objPreview.PreviewEnable("", 1, 1);
// "av_filter_graph_desc_in" - Apply video filter before video processing (e.g. video conversion)
// "av_filter_graph_desc_out" - Apply video filter after video processing (e.g. video conversion)
String VFilter_ConvProps = @"{""av_filter_graph_desc_in"":""negate""}";
(m_objConverter as IMFProps).PropsSet(@"video::xmedia_conversion_props", VFilter_ConvProps);
M_AV_PROPS m_AV_PROPS = new M_AV_PROPS();
m_AV_PROPS.vidProps.eVideoFormat = eMVideoFormat.eMVF_Custom;
int rest = 0;
do
{
m_objReader.SourceFrameGet(-1, out MFFrame pFrame, "");
m_objConverter.ConverterFrameConvert("", pFrame, ref m_AV_PROPS, out var pFrameConverted, out rest, "");
Marshal.ReleaseComObject(pFrame);
if (pFrameConverted != null)
{
m_objPreview.ReceiverFramePut(pFrameConverted, -1, "");
Marshal.ReleaseComObject(pFrameConverted);
}
} while (rest > 0);Important Note! The MFXMediaConverter class is implemented exclusively for 64-bit environments. Therefore, the use of the MFXMediaConverter class and consequently, vfilters are only supported in 64-bit applications.
MPlatform SDK
To implement video filters to your MPlatform object you should use the PropsSet method.
m_objMPPlaylist.PropsSet("object::vfilter", "[name_of_the_video_filter]");For the quick test, you can open a Playlist Sample,
"C:\Program Files (x86)\Medialooks\MPlatform SDK\Sample x64 Playlist.lnk"add a video file, make a double click on the file name, go to the bottom of the available properties list and add new property "object::vfilter".
Now you can manage the vildeo filter of the open file with the value of the "object::vfilter" property.
Note: Video filter will increase the load of your CPU. For example, i7-4770, Playlist Sample, video file 1080 30p, playback without conversion - CPU load 14-16%. With "colorbalance=rs=.3" CPU load 22-24%.
Some vfilters as "fade", can be applied to the video clips only once. If you want to play the video clip with such a vfilter once again, it's needed to reset the vfilter via .PropsSet("object::vfilter", ""); method and set this vfilter once again. Every time when change "object::vfilter" property, you completely reset all the previous settings. So that, if you want to apply more than one vfilter to your video, it's needed to set all the necessary filters at once.
If you need to apply more than one vfilters to the object, create a combined string for "object::vfilter" property, writing all the vfilters with their parameters, separated by commas. Here is an example of applying 3 vfilter to MPlaylist:
m_objPlaylist.PropsSet("object::vfilter", "negate, avgblur=sizeX=10:sizeY=4, crop=1000:1000");List of availible video filters
| Name | Description | Additional parametres | |
|---|---|---|---|
| avgblur |
Apply average blur filter:
|
The filter accepts the following options:
|
|
| ciescope |
Display CIE color diagram with pixels overlaid onto it: |
The filter accepts the following options: Set color system (system):
Set CIE system (cie):
Set what gamuts to draw (gamuts):
|
|
| colorbalance |
Modify intensity of primary colors (red, green and blue) of input frames:
|
The filter allows an input frame to be adjusted in the shadows, midtones or highlights regions for the red-cyan, green-magenta or blue-yellow balance. A positive adjustment value shifts the balance towards the primary color, a negative value towards the complementary color. The filter accepts the following options: Adjusting red, green and blue shadows (darkest pixels):
Adjusting red, green and blue midtones (medium pixels):
Adjusting red, green and blue highlights (brightest pixels):
|
|
| colorlevels |
Adjust video input frames using levels:
|
The filter accepts the following options: Adjust red, green, blue and alpha input black point. Allowed ranges for options are [-1.0, 1.0]. Defaults are 0.
Adjust red, green, blue and alpha input white point. Allowed ranges for options are [-1.0, 1.0]. Defaults are 1. Input levels are used to lighten highlights (bright tones), darken shadows (dark tones), change the balance of bright and dark tones.
Adjust red, green, blue and alpha output black point. Allowed ranges for options are [0, 1.0]. Defaults are 0.
Adjust red, green, blue and alpha output white point. Allowed ranges for options are [0, 1.0]. Defaults are 1. Output levels allows manual selection of a constrained output level range.
|
|
| colorchannelmixer |
Adjust video input frames by re-mixing color channels.
|
This filter modifies a color channel by adding the values associated to the other channels of the same pixels. For example if the value to modify is red, the output value will be:
The filter accepts the following options: Adjust contribution of input red, green, blue and alpha channels for output red channel. Default is 1 for rr, and 0 for rg, rb and ra:
Adjust contribution of input red, green, blue and alpha channels for output green channel. Default is 1 for gg, and 0 for gr, gb and ga:
Adjust contribution of input red, green, blue and alpha channels for output blue channel. Default is 1 for bb, and 0 for br, bg and ba:
Adjust contribution of input red, green, blue and alpha channels for output alpha channel. Default is 1 for aa, and 0 for ar, ag and ab. Allowed ranges for options are [-2.0, 2.0]:
|
|
| convolution |
Apply convolution of 3x3, 5x5, 7x7 or horizontal / vertical up to 49 elements.
|
The filter accepts the following options: Set matrix for each plane. Matrix is sequence of 9, 25 or 49 signed integers in square mode, and from 1 to 49 odd number of signed integers in row mode.
Set multiplier for calculated value for each plane. If unset or 0, it will be sum of all matrix elements.
Set bias for each plane. This value is added to the result of the multiplication. Useful for making the overall image brighter or darker. Default is 0.0.
Set matrix mode for each plane. Can be square, row or column. Default is square.
|
|
| crop |
Crop the input video to given dimensions.
|
Crop the input video to given dimensions. It accepts the following parameters:
The out_w, out_h, x, y parameters are expressions containing the following constants:
The expression for out_w may depend on the value of out_h, and the expression for out_h may depend on out_w, but they cannot depend on x and y, as x and y are evaluated after out_w and out_h. The x and y parameters specify the expressions for the position of the top-left corner of the output (non-cropped) area. They are evaluated for each frame. If the evaluated value is not valid, it is approximated to the nearest valid value. The expression for x may depend on y, and the expression for y may depend on x. |
|
| curves |
Apply color adjustments using curves. Vintage effect example:
|
This filter is similar to the Adobe Photoshop and GIMP curves tools. Each component (red, green and blue) has its values defined by N key points tied from each other using a smooth curve. The x-axis represents the pixel values from the input frame, and the y-axis the new pixel values to be set for the output frame. By default, a component curve is defined by the two points (0;0) and (1;1). This creates a straight line where each original pixel value is "adjusted" to its own value, which means no change to the image. The filter allows you to redefine these two points and add some more. A new curve (using a natural cubic spline interpolation) will be define to pass smoothly through all these new coordinates. The new defined points needs to be strictly increasing over the x-axis, and their x and y values must be in the [0;1] interval. If the computed curves happened to go outside the vector spaces, the values will be clipped accordingly. The filter accepts the following options: preset: Select one of the available color presets. This option can be used in addition to the r, g, b parameters; in this case, the later options takes priority on the preset values (default value is none). Available presets are:
To avoid some filtergraph syntax conflicts, each key points list need to be defined using the following syntax: x0/y0 x1/y1 x2/y2 .... |
|
| fade |
Apply a fade-in/out effect to the input video:
|
It accepts the following parameters:
|
|
| gblur |
Apply Gaussian blur filter:
|
The filter accepts the following options:
|
|
| hflip |
Flips the video horizontally: |
||
| histogram |
Compute and draw a color distribution histogram for the video: |
The computed histogram is a representation of the color component distribution in an image. Standard histogram displays the color components distribution in an image. Displays color graph for each color component. Shows distribution of the Y, U, V, A or R, G, B components, depending on input format, in the current frame. Below each graph a color component scale meter is shown. The filter accepts the following options:
|
|
| hue |
Modify the hue and/or the saturation of the video.
|
It accepts the following parameters:
h and H are mutually exclusive, and can’t be specified at the same time. The b, h, H and s option values are expressions containing the following constants:
|
|
| Libplacebo |
libplacebo vfilter provides high-quality GPU-accelerated video processing. It supports features such as:
HDR Conversion with Custom White Point example:
|
||
| negate |
Negate the video. |
It accepts the following option: negate_alpha: With value 1, it negates the alpha component, if present. Default value is 0. |
|
| showpalette |
Displays the 256 colors palette of each frame. This filter is only relevant for pal8 pixel format frames.
|
It accepts the following option: s: Set the size of the box used to represent one palette color entry. Default is 30 (for a 30x30 pixel box). |
|
| subtitles |
Shows subtitles from .srt file over video:
Examples:
|
||
| swapuv |
Swap U and V plane. |
||
| vectorscope |
Display 2 color component values in the two-dimensional graph (which is called a vectorscope). (all parameters are default):
|
This filter accepts the following options: mode, m : Set vectorscope mode. The mode parameter accepts the following values: gray : Gray values are displayed on graph, higher brightness means more pixels have same component color value on location in graph. This is the default mode. color : Gray values are displayed on graph. Surrounding pixels values which are not present in video frame are drawn in gradient of 2 color components which are set by option x and y. The 3rd color component is static. color2 : Actual color components values present in video frame are displayed on graph. color3 : Similar as color2 but higher frequency of same values x and y on graph increases value of another color component, which is luminance by default values of x and y. color4 : Actual colors present in video frame are displayed on graph. If two different colors map to same position on graph then color with higher value of component not present in graph is picked. color5 : Gray values are displayed on graph. Similar to color but with 3rd color component picked from radial gradient. x : Set which color component will be represented on X-axis. Default is 1. y : Set which color component will be represented on Y-axis. Default is 2. intensity, i : Set intensity, used by modes: gray, color, color3 and color5 for increasing brightness of color component which represents frequency of (X, Y) location in graph. envelope, e : The envelope. The envelope parameter accepts the following values: none : No envelope, this is default. instant : Instant envelope, even darkest single pixel will be clearly highlighted. peak : Hold maximum and minimum values presented in graph over time. This way you can still spot out of range values without constantly looking at vectorscope. peak+instant : Peak and instant envelope combined together. graticule, g : Set what kind of graticule to draw. The graticule parameter accepts the following values: none : No graticule. green : Green graticule. color : Color graticule. opacity, o : Set graticule opacity in [0,1] range. flags, f : Set graticule flags. The graticule flags parameter accepts the following values: white : Draw graticule for the white point. black : Draw graticule for the black point. name : Draw color points short names. bgopacity, b: Set background opacity in [0,1] range. lthreshold, l : Set low threshold for color component not represented on X or Y axis. Values lower than this value will be ignored. Default is 0. Note this value is multiplied with actual max possible value one pixel component can have. So for 8-bit input and low threshold value of 0.1 actual threshold is 0.1 * 255 = 25. hthreshold, h : Set high threshold for color component not represented on X or Y axis. Values higher than this value will be ignored. Default is 1. Note this value is multiplied with actual max possible value one pixel component can have. So for 8-bit input and high threshold value of 0.9 actual threshold is 0.9 * 255 = 230. colorspace, c : Set what kind of colorspace to use when drawing graticule. The colorspace parameter accepts the following values: auto : Detect colorspace automatically. This is a default value. 601 : Set 601 colorspace. 709 : Set 709 colorspace. |
|
| waveform |
Video waveform monitor.
|
||
| vflip |
Flip the input video vertically.
|
||
| yadif | Deinterlace the input video ("yadif" means "yet another deinterlacing filter"). |
Filters writing to metadata
Some FFmpeg video filters (such as 'blackdetect') write their results into frame metadata. Since 2.8.1 SDK version you can use such filters.
Below is an example of using the 'blackdetect' filter with an MFile object.
1. Before SDK version 2.9.2.14025, vfilters did not support planar formats. Therefore, in order for filters to function correctly, planar formats had to be converted by setting the corresponding property to true:
Computer\HKEY_CURRENT_USER\Software\Medialooks\MPlatform\MFile\MFileFFM
decoder.convert_planar = trueStarting from SDK version 2.9.2.14026 and later, vfilters support planar formats, and no conversion is required.
2. Add video filter to the object as usual:
m_objMFile.PropsSet("object::vfilter", "blackdetect=d=0.05");3. Check the result using MFStrGet method in the OnFrameSafe event:
m_objMFile.OnFrame += new IMEvents_OnFrameEventHandler(m_objMFile_OnFrame);
void m_objMFile_OnFrame(string bsChannelID, object pMFrame)
{
(pMFrame as IMFFrame).MFStrGet("lavfi.black_start", out string val);
Console.WriteLine(val);
Marshal.ReleaseComObject(pMFrame);
} More info about this filter - https://ffmpeg.org/ffmpeg-filters.html#blackdetect
Using vfilters with GPU Pipeline
Starting from Video SDK version 2.11.1.14634, it is possible to use vfilters with gpu_pipeline='true'. However, there are some important points to keep in mind:
Vfilters are processed on the CPU
When using the GPU pipeline with vfilters, each video frame is copied from the GPU to the CPU. then the vfilters are applied, and after that the frame is copied back to the GPU. This extra step can reduce performance of your solution.
10-bit video limitations
When using vfilters on a 10-bit video stream in the GPU pipeline, the 10-bit color information will be lost. This happens because each frame is copied from the GPU to the CPU, where the filter is applied, and then copied back to the GPU. The CPU can only handle 8-bit video, so the original 10-bit data is reduced to 8-bit.
To avoid losing the 10-bit quality, do not apply vfilters in the main video path. Instead, you can apply vfilters to a separate MFile. For example, if you want to use a libplacebo vfilter for a preview, create a separate MFile and apply the filter there. This keeps the original 10-bit video unchanged.
For a better understanding, see the diagram below:
In the diagram above:
- The input 10-bit HDR video goes into
MLive SDI. - From there, it is sent directly to
MWriterandMRenderer, keeping 10-bit HDR quality. - If you want to use a vfilter for a preview, for example libplacebo, you can do it without losing 10-bit color:
- Open the 10-bit video source in a separate
MFileusingmp://link. - Apply the libplacebo vfilter on this
MFile. - Send the filtered
MFiletoMPreview.
- Open the 10-bit video source in a separate
Since the vfilter is not applied in the main 10-bit path between MLive and MWriter / MRenderer, the original 10-bit HDR video remains unchanged. Only the preview branch is reduced to 8-bit for display.