public void RemoveMutualExclusion(
WMMutualExclusion ME
)
ME
A WMMutualExclusion object that is to be removed from the profile.
For more information, refer to the Microsoft documentation for IWMProfile.RemoveMutualExclusion.
using Leadtools;
using Leadtools.Multimedia;
using LeadtoolsMultimediaExamples.Fixtures;
public bool _result = false;
public ConvertCtrlForm _form = new ConvertCtrlForm();
const int CODEC_AUDIO_MSAUDIO = 353; // Microsoft WMAudio
const int CODEC_VIDEO_WMV1 = 827739479; // FOURCC( 'W', 'M', 'V', '1' )
public void AddStreamExample()
{
ConvertCtrl convertctrl = _form.ConvertCtrl;
string inFile = Path.Combine(LEAD_VARS.MediaDir, "ConvertCtrl_Source.avi");
string outFile = Path.Combine(LEAD_VARS.MediaDir, "WMProfile_RemoveStreamExample.avi");
try
{
WMProfileManager manager = new WMProfileManager();
// create a WMProfile
convertctrl.WMProfile = CreateCustomProfile(manager);
// run the conversion
convertctrl.SourceFile = inFile;
convertctrl.TargetFormat = TargetFormatType.WMV;
convertctrl.TargetFile = outFile;
convertctrl.StartConvert();
// dispose of the manager
manager.Dispose();
}
catch (Exception)
{
_result = false;
}
// we'll loop on the state and pump messages for this example.
// but you should not need to if running from a Windows Forms application.
while (convertctrl.State == ConvertState.Running)
Application.DoEvents();
// check the validity of the output file
MediaInfo mediaInfo = new MediaInfo();
try
{
mediaInfo.SourceFile = outFile;
if (mediaInfo.SourceFormat == SourceFormatType.WMV)
_result = true;
}
catch (Exception)
{
_result = false;
}
}
private WMProfile CreateCustomProfile(WMProfileManager manager)
{
WMProfile profile = manager.CreateEmptyProfile(WMT_Version.V9);
profile.Name = "Custom Profile";
profile.Description = "Custom Profile Description";
bool added = AddAudioStream(manager, profile, 1, CODEC_AUDIO_MSAUDIO, 8000, 8000, 1, true);
// add 5 video streams with bitrates starting from 32KB/s (256Kbps). Increase the bitrate if you increase the video size
for (int i = 0; (i <= 4); i++)
AddVideoStream(manager, profile, (2 + i), CODEC_VIDEO_WMV1,
(1024 * 32) + i * 1024, 400, 300, 5 * (i + 1), 0, 8);
// mark all the video streams for mutual exclusion
AddMutexObject(profile, 2, 5);
return profile;
}
private bool AddVideoStream(WMProfileManager manager,
WMProfile profile,
int streamnum,
long fourcc,
int bitrate,
int width,
int height,
int fps,
int quality,
int secperkey)
{
WMStreamConfig codecformat;
MediaType mediatype;
VideoInfoHeader vih;
bool candidate = false;
VideoInfoHeader candidatevih = new VideoInfoHeader();
MediaType candidatemt = null;
WMStreamConfig candidatestream = null;
bool added = false;
byte[] viharr = new byte[88];
int codecs = manager.GetCodecInfoCount(Constants.MEDIATYPE_Video);
string sinfo = string.Empty;
// width and height must be even
if ((width & 1) != 0)
width++;
if ((height & 1) != 0)
height++;
// search for matching codec until I find a candidate
for (int codecindex = 0; codecindex < codecs && !candidate; codecindex++)
{
sinfo += manager.GetCodecName(Constants.MEDIATYPE_Video, codecindex);
int formats = manager.GetCodecFormatCount(Constants.MEDIATYPE_Video, codecindex);
for (int formatindex = 0; formatindex < formats; formatindex++)
{
sinfo += manager.GetCodecFormatDesc(Constants.MEDIATYPE_Video, codecindex, formatindex);
codecformat = manager.GetCodecFormat(Constants.MEDIATYPE_Video, codecindex, formatindex);
mediatype = codecformat.GetMediaType();
if (mediatype.FormatType == Constants.FORMAT_VideoInfo)
{
vih = mediatype.GetVideoFormatData();
if (vih.bmiHeader.biCompression == fourcc)
{
candidate = true;
candidatevih = vih;
candidatemt = mediatype;
candidatestream = codecformat;
// stop searching if I found a candidate
break;
}
}
}
}
if (candidate)
{
// modify the selected codec to support this bitrate and size
candidatevih.dwBitRate = bitrate;
candidatevih.rcSource.Right = width;
candidatevih.rcSource.Bottom = height;
candidatevih.rcTarget.Right = width;
candidatevih.rcTarget.Bottom = height;
candidatevih.bmiHeader.biWidth = width;
candidatevih.bmiHeader.biHeight = height;
// since fps is integer, 10000000/fps always fits in a 32-bit value, so lowpart=10000000/fps and high part is always 0
candidatevih.AvgTimePerFrame.lowpart = 10000000 / fps;
candidatevih.AvgTimePerFrame.highpart = 0;
StructToByteArray(candidatevih, ref viharr);
// candidatevih is a copy of the media type, so updating candidatevih is not enough to update the media type.
// Call SetVideoFormatData to copy the updated information from candidatevih to the video format data inside candidatemt
// If you just change candidatevih without calling candidatemt.SetVideoFormatData,
// candidatemt is an empty media type with no width and height
candidatemt.SetVideoFormatData(candidatevih, null, 0);
candidatestream.Quality = quality;
candidatestream.MaxKeyFrameSpacing = secperkey;
candidatestream.StreamNumber = streamnum;
candidatestream.StreamName = "Video Stream";
candidatestream.ConnectionName = "Video";
candidatestream.Bitrate = bitrate;
candidatestream.SetMediaType(candidatemt);
profile.AddStream(candidatestream);
added = true;
}
return added;
}
private bool AddAudioStream(WMProfileManager manager,
WMProfile profile,
int streamnum,
int formattag,
int prefbitrate,
int samplespersec,
int channels,
bool withvideo)
{
WMStreamConfig codecformat;
MediaType mediatype;
WaveFormatEx wfex = new WaveFormatEx();
bool added = false;
bool candidate = false;
WaveFormatEx candidatewfex = new WaveFormatEx();
MediaType candidatemt = null;
MediaType mt;
WMStreamConfig stream;
int codecs = manager.GetCodecInfoCount(Constants.MEDIATYPE_Audio);
// search for matching codec
for (int codecindex = 0; codecindex < codecs; codecindex++)
{
int formats = manager.GetCodecFormatCount(Constants.MEDIATYPE_Audio, codecindex);
for (int formatindex = 0; formatindex < formats; formatindex++)
{
codecformat = manager.GetCodecFormat(Constants.MEDIATYPE_Audio, codecindex, formatindex);
mediatype = codecformat.GetMediaType();
if (mediatype.FormatType == Constants.FORMAT_WaveFormatEx)
{
ByteArrayToStruct(mediatype.Format, ref wfex);
int diff = ((wfex.nAvgBytesPerSec * 8) - prefbitrate);
if (diff < 250 && diff > -250
&& wfex.nSamplesPerSec == samplespersec
&& wfex.nChannels == channels
&& wfex.wFormatTag == formattag)
{
if (candidate)
{
if (withvideo)
{
//
// For audio/video configurations, we want to
// find the smaller blockalign. In this case,
// the blockalign is larger, so we want to
// use the old format.
if (wfex.nBlockAlign <= candidatewfex.nBlockAlign)
{
candidatewfex = wfex;
candidatemt = mediatype;
}
}
else if (wfex.nBlockAlign >= candidatewfex.nBlockAlign)
{
candidatewfex = wfex;
candidatemt = mediatype;
}
}
else
{
candidate = true;
candidatewfex = wfex;
candidatemt = mediatype;
}
}
}
}
}
if (candidate)
{
// modify the selected codec to support this bitrate and format
mt = new MediaType();
mt.Type = Constants.MEDIATYPE_Audio;
mt.SubType = "{" + String.Format("{0:X8}", formattag) + "-0000-0010-8000-00AA00389B71}";
mt.FixedSizeSamples = true;
mt.TemporalCompression = false;
mt.SampleSize = candidatewfex.nBlockAlign;
mt.FormatType = Constants.FORMAT_WaveFormatEx;
mt.SetFormatData(-1, candidatemt.Format);
stream = profile.CreateNewStream(Constants.MEDIATYPE_Audio);
stream.StreamNumber = streamnum;
stream.StreamName = "Audio Stream";
stream.ConnectionName = "Audio";
stream.Bitrate = (candidatewfex.nAvgBytesPerSec * 8);
stream.SetMediaType(mt);
profile.AddStream(stream);
profile.ReconfigStream(stream);
added = true;
}
return added;
}
private void StructToByteArray(object o, ref byte[] dest)
{
try
{
//convert the structure to a byte array
int rawSize = Marshal.SizeOf(o);
GCHandle handle = new GCHandle();
IntPtr buffer;
handle = GCHandle.Alloc(dest, GCHandleType.Pinned);
buffer = handle.AddrOfPinnedObject();
Marshal.StructureToPtr(o, buffer, false);
handle.Free();
}
catch (Exception ex)
{
throw ex;
}
}
private void ByteArrayToStruct(object buffer, ref WaveFormatEx vih)
{
try
{
GCHandle handle = new GCHandle();
//convert the structure to a byte array
handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
IntPtr ptr = handle.AddrOfPinnedObject();
vih = (WaveFormatEx)Marshal.PtrToStructure(ptr, typeof(WaveFormatEx));
handle.Free();
}
catch (Exception ex)
{
throw ex;
}
}
private bool AddMutexObject(WMProfile profile, int basestream, int streamcount)
{
WMMutualExclusion excl = profile.CreateNewMutualExclusion();
// indicate that the streams differ by bit rate
excl.Type = "{D6E22A01-35DA-11D1-9034-00A0C90349BE}";
for (int i = 0; i < streamcount; i++)
excl.AddStream(basestream + i);
// assign the exclusion object to the profile
profile.AddMutualExclusion(excl);
return true;
}
private bool RemoveMutexObject(WMProfile profile, WMMutualExclusion excl, int basestream, int streamcount)
{
// indicate that the streams differ by bit rate
excl.Type = "{D6E22A01-35DA-11D1-9034-00A0C90349BE}";
for (int i = 0; i < streamcount; i++)
excl.RemoveStream(basestream + i);
// remove the exclusion object from the profile
profile.RemoveMutualExclusion(excl);
return true;
}
static class LEAD_VARS
{
public const string MediaDir = @"C:\LEADTOOLS22\Media";
}