Live device sources like capture cards or web-cameras are operated by MLive (MPlatform) and MFLive (MFormats) objects:
MLiveClass m_objMLive= new MLiveClass(); MFLiveClass myLiveSource = new MFLiveClass();
Set a video device
This is the 1st action required to initialize a live source. This is done with the DeviceSet method. With MPlatform SDK you should specify a name of the device as a parameter, and with MFormats SDK you should use an index of the desired source. In both cases, it is useful to get a list of all available video devices.
MFormats SDK
// get number of devices available for usage int deviceCount; myLiveSource.DeviceGetCount(eMFDeviceType.eMFDT_Video, out deviceCount); // initialize an array to collect device names string[] deviceArray; if (deviceCount > 0) { deviceArray = new string[deviceCount]; for (int deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++) { // get device by its index string deviceName; int isBusy; // indicates is it possible to use this device or is it busy in another application myLiveSource.DeviceGetByIndex(eMFDeviceType.eMFDT_Video, deviceIndex, out deviceName, out isBusy); deviceArray[deviceIndex] = deviceName; } }
Once all the devices are enumerated, you can specify it with the DeviceSet method:
myLiveSource.DeviceSet(eMFDeviceType.eMFDT_Video, targetIndex, "");
where targetIndex is an index to the target name of your device in the deviceArray list.
MPlatform SDK
int nCount = 0; //Get device count m_objMLive.DeviceGetCount(0, "video", out nCount); string[] deviceArray; if (nCount > 0) { deviceArray = new string[nCount]; for (int i = 0; i < nCount; i++) { string strName; string strDesc; // strDesc="isBusy=true"/"isBusy=false" - indicates is it possible to use this device or is it busy in another application //Get deveice / input line m_objMLive.DeviceGetByIndex(0, "video", i, out strName, out strDesc); deviceArray[deviceIndex] = strName; } }
And to set a device you should call
m_objMLive.DeviceSet("video", deviceArray[targetIndex], "");
where targetIndex is an index to the target name of your device in the deviceArray list. Or you can use a name of a device, like
m_objMLive.DeviceSet("video", "UltraStudio Express", "");
By this step, the device is already initialized and all the input parameters and properties, like input lines and available input video formats, are available for setting. Before video device is set, the object doesn't contain any information about a device. So here is the main idea of working with MLive and MFLive objects:
Set the video device first.
Set an input line
Capture devices, as well as NDI and WebRTC sources, have several inputs, for example, several input NDI streams or HDMI and SDI connectors. To make sure that exact input is used, you should specify input line.
MFormats SDK
To collect all the available lines into array, you should get a number of possible values with the PropsOptionGetCount method and then get each possible value by its index with the PropsOptionGetByIndex method:
int lineCount; string[] linesArray; myLiveSource.PropsOptionGetCount("line-in", out lineCount); if (lineCount > 0) { linesArray = new string[lineCount]; for (int lineIndex = 0; lineIndex < lineCount; lineIndex++) { string shortLineName; string longLineName; myLiveSource.PropsOptionGetByIndex("line-in", lineIndex, out shortLineName, out longLineName); linesArray[lineIndex] = longLineName; } }
To set required line you should use the PropsOptionSetByIndex method:
myLiveSource.PropsOptionSetByIndex("line-in", targetLineIndex);
where targetLineIndex is an index of required line from the list.
MPlatform SDK
The code is the same as for video device initialization, but the device type for DeviceGetByIndex and DeviceSet methods is "video::line-in".
int nCount = 0; //Get device count m_objMLive.DeviceGetCount(0, "video::line-in", out nCount); string[] inputLinesArray; if (nCount > 0) { deviceArray = new string[nCount]; for (int i = 0; i < nCount; i++) { string strName; string strDesc; //Get deveice / input line m_objMLive.DeviceGetByIndex(0, "video::line-in", i, out strName, out strDesc); inputLinesArray[deviceIndex] = strName; } } m_objMLive.DeviceSet("video::line-in", inputLinesArray[targetIndex], "");
Set an input video format
After you set up a video device, you should know what formats your device supports.
The logic is similar to getting all the device names or input lines. You should go through all the available formats and then specify a desired one. To collect all the supported input formats you should get its count with the FormatVideoGetCount method and get each of the formats with the FormatVideoGetByIndex. Methods names are the same, but in MFormats SDK the IMFFormat interface is used, and in MPlatform SDK it is the IMFormat interface.
MFormats SDK & MPlatform SDK
The code is the same for both SDKs.
To list all the available input video formats you should call a code like this:
int formatsCount; myLiveSource.FormatVideoGetCount(eMFormatType.eMFT_Input, out formatsCount); string[] formatsArray; if (formatsCount > 0) { formatsArray = new string[formatsCount]; for (int formatIndex = 0; formatIndex < formatsCount; formatIndex++) { M_VID_PROPS vidProps; string formatName; myLiveSource.FormatVideoGetByIndex(eMFormatType.eMFT_Input, formatIndex, out vidProps, out formatName); formatsArray[formatIndex] = formatName; } }
And to set video format you should get format by its index to obtain M_VID_PROPS structure that represents format settings and set it with the FormatVideoSet method:
// get required format by index M_VID_PROPS vidProps; string formatName; myLiveSource.FormatVideoGetByIndex(eMFormatType.eMFT_Input, targetFormatIndex, out vidProps, out formatName); //set video format myLiveSource.FormatVideoSet(eMFormatType.eMFT_Input, vidProps);
You may mention that IMFormat and IMFFormat interfaces methods contain format type as the first parameter. It is a eMFormatType enumeration value. For live source configuration, the required value is eMFT_Input, that is used to set input format for your devices.
Set an audio source
Because of different video devices supports different audio source it is recommended to update a list of audio source each time you change source video device. The actions to set up audio sources are the same as for video sources. The only difference is that you should use eMFDT_Audio device type in MFormats SDK and "audio" in MPlatform SDK.
MFormats SDK
// get number of devices available for usage int deviceCount; myLiveSource.DeviceGetCount(eMFDeviceType.eMFDT_Audio, out deviceCount); // initialize an array to collect device names string[] deviceArray; if (deviceCount > 0) { deviceArray = new string[vCount]; for (int deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++) { // get device by its index string deviceName; int isBusy; myLiveSource.DeviceGetByIndex(eMFDeviceType.eMFDT_Audio, deviceIndex, out deviceName, out isBusy); deviceArray[deviceIndex] = deviceName; } } m_objLive.DeviceSet(eMFDeviceType.eMFDT_Audio, targetAudioIndex, "");
MPlatform SDK
int nCount = 0; //Get device count m_objMLive.DeviceGetCount(0, "audio", out nCount); string[] deviceArray; if (nCount > 0) { deviceArray = new string[nCount]; for (int i = 0; i < nCount; i++) { string strName; string strDesc; //Get deveice / input line m_objMLive.DeviceGetByIndex(0, "audio", i, out strName, out strDesc); deviceArray[deviceIndex] = strName; } } m_objMLive.DeviceSet("audio", deviceArray[targetIndex], "");
The DeviceSet method contains additional properties as the last parameter, but at the moment it is reserved for future usage.
Note please that if you want to use an audio-only source, you should specify the video device to <None>. See also the article about external audio sources.
Set specific properties
There is a lot of supported devices and there are different properties specific for each vendor. You can specify parameters specific to a device with the PropsSet method.
For MFormats SDK, you just should specify the required property, for example, for a ScreenCapture engine:
(myLiveSource as IMProps).PropsSet("capture.show_mouse", "hide");
But for MPlatform SDK, you should use a "device::" prefix. The same property for MLive looks like:
(m_objMLive as IMProps).PropsSet("device::capture.show_mouse", "hide");
Please refer to the article about prefixes for objects.
Start the device
Finally, all the parameters are set and the source is completely ready for usage and you can start receiving an input stream.
MFormats SDK
Once you set a video device with the DeviceSet method, it is initialized. So you can start grabbing frames from the source. This is a default behavior managed by the "device.start_at_deviceset" property. See the article for reference. Once you disable the property with
(myLiveSource as IMProps).PropsSet("device.start_at_deviceset", "false");
the device starts with the 1st grabbed frame:
// a frame object MFFrame myFrame; // grab a frame ((IMFSource)myLiveSource).SourceFrameGet(-1, out myFrame, ""); // send to receiver ((IMFReceiver)myPreview).ReceiverFramePut(myFrame, -1, "");
The SourceFrameGetByNumber and SourceFrameGetByTime methods of the IMFSource interface are supported for live sources but it is not possible to make a seeking or increase speed of playback - the parameters are ignored and the source always returns you the next frame.
MPlatform SDK
(m_objMLive as IMObject).ObjectStart(null);