📄 dsutils.cs
字号:
// The ConnectedTo call succeeded, release the interface
Marshal.ReleaseComObject(pOutPin);
}
// Is it the right status?
if (
(hr == 0 && vStat == PinConnectedStatus.Connected) ||
(hr == DsResults.E_NotConnected && vStat == PinConnectedStatus.Unconnected)
)
{
// Is is the right index?
if (iIndex == 0)
{
pRet = pPins[0];
break;
}
iIndex--;
}
Marshal.ReleaseComObject(pPins[0]);
}
}
finally
{
Marshal.ReleaseComObject(ppEnum);
}
return pRet;
}
}
sealed public class DsToString
{
private DsToString()
{
// Prevent people from trying to instantiate this class
}
/// <summary>
/// Produces a usable string that describes the MediaType object
/// </summary>
/// <returns>Concatenation of MajorType + SubType + FormatType + Fixed + Temporal + SampleSize.ToString</returns>
public static string AMMediaTypeToString(AMMediaType pmt)
{
return string.Format("{0} {1} {2} {3} {4} {5}",
MediaTypeToString(pmt.majorType),
MediaSubTypeToString(pmt.subType),
MediaFormatTypeToString(pmt.formatType),
(pmt.fixedSizeSamples ? "FixedSamples" : "NotFixedSamples"),
(pmt.temporalCompression ? "temporalCompression" : "NottemporalCompression"),
pmt.sampleSize.ToString());
}
/// <summary>
/// Converts AMMediaType.MajorType Guid to a readable string
/// </summary>
/// <returns>MajorType Guid as a readable string or Guid if unrecognized</returns>
public static string MediaTypeToString(Guid guid)
{
// Walk the MediaSubType class looking for a match
return WalkClass(typeof(MediaType), guid);
}
/// <summary>
/// Converts the AMMediaType.SubType Guid to a readable string
/// </summary>
/// <returns>SubType Guid as a readable string or Guid if unrecognized</returns>
public static string MediaSubTypeToString(Guid guid)
{
// Walk the MediaSubType class looking for a match
string s = WalkClass(typeof(MediaSubType), guid);
// There is a special set of Guids that contain the FourCC code
// as part of the Guid. Check to see if it is one of those.
if (s.Length == 36 && s.Substring(8).ToUpper() == "-0000-0010-8000-00AA00389B71")
{
// Parse out the FourCC code
byte[] asc = {
Convert.ToByte(s.Substring(6, 2), 16),
Convert.ToByte(s.Substring(4, 2), 16),
Convert.ToByte(s.Substring(2, 2), 16),
Convert.ToByte(s.Substring(0, 2), 16)
};
s = Encoding.ASCII.GetString(asc);
}
return s;
}
/// <summary>
/// Converts the AMMediaType.FormatType Guid to a readable string
/// </summary>
/// <returns>FormatType Guid as a readable string or Guid if unrecognized</returns>
public static string MediaFormatTypeToString(Guid guid)
{
// Walk the FormatType class looking for a match
return WalkClass(typeof(FormatType), guid);
}
/// <summary>
/// Use reflection to walk a class looking for a property containing a specified guid
/// </summary>
/// <param name="MyType">Class to scan</param>
/// <param name="guid">Guid to scan for</param>
/// <returns>String representing property name that matches, or Guid.ToString() for no match</returns>
private static string WalkClass(Type MyType, Guid guid)
{
object o = null;
// Read the fields from the class
FieldInfo[] Fields = MyType.GetFields();
// Walk the returned array
foreach (FieldInfo m in Fields)
{
// Read the value of the property. The parameter is ignored.
o = m.GetValue(o);
// Compare it with the sought value
if ((Guid)o == guid)
{
return m.Name;
}
}
return guid.ToString();
}
}
// This abstract class contains definitions for use in implementing a custom marshaler.
//
// MarshalManagedToNative() gets called before the COM method, and MarshalNativeToManaged() gets
// called after. This allows for allocating a correctly sized memory block for the COM call,
// then to break up the memory block and build an object that c# can digest.
abstract internal class DsMarshaler : ICustomMarshaler
{
#region Data Members
// The cookie isn't currently being used.
protected string m_cookie;
// The managed object passed in to MarshalManagedToNative, and modified in MarshalNativeToManaged
protected object m_obj;
#endregion
// The constructor. This is called from GetInstance (below)
public DsMarshaler(string cookie)
{
// If we get a cookie, save it.
m_cookie = cookie;
}
// Called just before invoking the COM method. The returned IntPtr is what goes on the stack
// for the COM call. The input arg is the parameter that was passed to the method.
virtual public IntPtr MarshalManagedToNative(object managedObj)
{
// Save off the passed-in value. Safe since we just checked the type.
m_obj = managedObj;
// Create an appropriately sized buffer, blank it, and send it to the marshaler to
// make the COM call with.
int iSize = GetNativeDataSize() + 3;
IntPtr p = Marshal.AllocCoTaskMem(iSize);
for (int x=0; x < iSize / 4; x++)
{
Marshal.WriteInt32(p, x * 4, 0);
}
return p;
}
// Called just after invoking the COM method. The IntPtr is the same one that just got returned
// from MarshalManagedToNative. The return value is unused.
virtual public object MarshalNativeToManaged(IntPtr pNativeData)
{
return m_obj;
}
// Release the (now unused) buffer
virtual public void CleanUpNativeData(IntPtr pNativeData)
{
if (pNativeData != IntPtr.Zero)
{
Marshal.FreeCoTaskMem(pNativeData);
}
}
// Release the (now unused) managed object
virtual public void CleanUpManagedData(object managedObj)
{
m_obj = null;
}
// This routine is (apparently) never called by the marshaler. However it can be useful.
abstract public int GetNativeDataSize();
// GetInstance is called by the marshaler in preparation to doing custom marshaling. The (optional)
// cookie is the value specified in MarshalCookie="asdf", or "" is none is specified.
// It is commented out in this abstract class, but MUST be implemented in derived classes
//public static ICustomMarshaler GetInstance(string cookie)
}
// c# does not correctly marshal arrays of pointers.
//
internal class EMTMarshaler : DsMarshaler
{
public EMTMarshaler(string cookie) : base(cookie)
{
}
// Called just after invoking the COM method. The IntPtr is the same one that just got returned
// from MarshalManagedToNative. The return value is unused.
override public object MarshalNativeToManaged(IntPtr pNativeData)
{
AMMediaType [] emt = m_obj as AMMediaType [];
for (int x=0; x < emt.Length; x++)
{
// Copy in the value, and advance the pointer
IntPtr p = Marshal.ReadIntPtr(pNativeData, x * IntPtr.Size);
if (p != IntPtr.Zero)
{
emt[x] = (AMMediaType) Marshal.PtrToStructure(p, typeof (AMMediaType));
}
else
{
emt[x] = null;
}
}
return null;
}
// The number of bytes to marshal out
override public int GetNativeDataSize()
{
// Get the array size
int i = ((Array)m_obj).Length;
// Multiply that times the size of a pointer
int j = i * IntPtr.Size;
return j;
}
// This method is called by interop to create the custom marshaler. The (optional)
// cookie is the value specified in MarshalCookie="asdf", or "" is none is specified.
public static ICustomMarshaler GetInstance(string cookie)
{
return new EMTMarshaler(cookie);
}
}
// c# does not correctly create structures that contain ByValArrays of structures (or enums!). Instead
// of allocating enough room for the ByValArray of structures, it only reserves room for a ref,
// even when decorated with ByValArray and SizeConst. Needless to say, if DirectShow tries to
// write to this too-short buffer, bad things will happen.
//
// To work around this for the DvdTitleAttributes structure, use this custom marshaler
// by declaring the parameter DvdTitleAttributes as:
//
// [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(DTAMarshaler))]
// DvdTitleAttributes pTitle
//
// See DsMarshaler for more info on custom marshalers
internal class DTAMarshaler : DsMarshaler
{
public DTAMarshaler(string cookie) : base(cookie)
{
}
// Called just after invoking the COM method. The IntPtr is the same one that just got returned
// from MarshalManagedToNative. The return value is unused.
override public object MarshalNativeToManaged(IntPtr pNativeData)
{
DvdTitleAttributes dta = m_obj as DvdTitleAttributes;
// Copy in the value, and advance the pointer
dta.AppMode = (DvdTitleAppMode)Marshal.ReadInt32(pNativeData);
pNativeData = (IntPtr)(pNativeData.ToInt64() + Marshal.SizeOf(typeof(int)));
// Copy in the value, and advance the pointer
dta.VideoAttributes = (DvdVideoAttributes) Marshal.PtrToStructure(pNativeData, typeof (DvdVideoAttributes));
pNativeData = (IntPtr)(pNativeData.ToInt64() + Marshal.SizeOf(typeof(DvdVideoAttributes)));
// Copy in the value, and advance the pointer
dta.ulNumberOfAudioStreams = (int)Marshal.ReadInt32(pNativeData);
pNativeData = (IntPtr)(pNativeData.ToInt64() + Marshal.SizeOf(typeof(int)));
// Allocate a large enough array to hold all the returned structs.
dta.AudioAttributes = new DvdAudioAttributes[8];
for (int x=0; x < 8; x++)
{
// Copy in the value, and advance the pointer
dta.AudioAttributes[x] = (DvdAudioAttributes) Marshal.PtrToStructure(pNativeData, typeof (DvdAudioAttributes));
pNativeData = (IntPtr)(pNativeData.ToInt64() + Marshal.SizeOf(typeof(DvdAudioAttributes)));
}
// Allocate a large enough array to hold all the returned structs.
dta.MultichannelAudioAttributes = new DvdMultichannelAudioAttributes[8];
for (int x=0; x < 8; x++)
{
// MultichannelAudioAttributes has nested ByValArrays. They need to be individually copied.
dta.MultichannelAudioAttributes[x].Info = new DvdMUAMixingInfo[8];
for (int y=0; y < 8; y++)
{
// Copy in the value, and advance the pointer
dta.MultichannelAudioAttributes[x].Info[y] = (DvdMUAMixingInfo)Marshal.PtrToStructure(pNativeData, typeof(DvdMUAMixingInfo));
pNativeData = (IntPtr)(pNativeData.ToInt64() + Marshal.SizeOf(typeof(DvdMUAMixingInfo)));
}
dta.MultichannelAudioAttributes[x].Coeff = new DvdMUACoeff[8];
for (int y=0; y < 8; y++)
{
// Copy in the value, and advance the pointer
dta.MultichannelAudioAttributes[x].Coeff[y] = (DvdMUACoeff)Marshal.PtrToStructure(pNativeData, typeof(DvdMUACoeff));
pNativeData = (IntPtr)(pNativeData.ToInt64() + Marshal.SizeOf(typeof(DvdMUACoeff)));
}
}
// The DvdMultichannelAudioAttributes needs to be 16 byte aligned
pNativeData = (IntPtr)(pNativeData.ToInt64() + 4);
// Copy in the value, and advance the pointer
dta.ulNumberOfSubpictureStreams = (int)Marshal.ReadInt32(pNativeData);
pNativeData = (IntPtr)(pNativeData.ToInt64() + Marshal.SizeOf(typeof(int)));
// Allocate a large enough array to hold all the returned structs.
dta.SubpictureAttributes = new DvdSubpictureAttributes[32];
for (int x=0; x < 32; x++)
{
// Copy in the value, and advance the pointer
dta.SubpictureAttributes[x] = (DvdSubpictureAttributes) Marshal.PtrToStructure(pNativeData, typeof (DvdSubpictureAttributes));
pNativeData = (IntPtr)(pNativeData.ToInt64() + Marshal.SizeOf(type
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -