public IntPtr MarshalManagedToNative(object managedObj) { m_bmi = managedObj as MediaFoundation.Misc.BitmapInfoHeader; IntPtr ip = m_bmi.GetPtr(); return(ip); }
// Called just after invoking the COM method. The IntPtr is the same one that just got returned // from MarshalManagedToNative. The return value is unused. public object MarshalNativeToManaged(IntPtr pNativeData) { MediaFoundation.Misc.BitmapInfoHeader bmi = MediaFoundation.Misc.BitmapInfoHeader.PtrToBMI(pNativeData); // If we this call is In+Out, the return value is ignored. If // this is out, then m_bmi will be null. if (m_bmi != null) { m_bmi.CopyFrom(bmi); bmi = null; } return(bmi); }
/// <summary> /// The GSSF calls this method to determine whether a proposed media type is acceptable. While /// the GSSF offers up the value set in SetMediaType, downstream filters may counter-propose /// media types that are similar. This method allows c# programs to accept or reject proposed /// alternatives. /// </summary> /// <param name="amt">The proposed alternative media type. Do NOT call DsUtils.FreeAMMediaType on this</param> /// <returns>S_Ok to accept the media type, a negative value to decline</returns> public override int CheckMediaType(AMMediaType amt) { // The media types sent down from the EVR can be very different from the one // we proposed. I've seen a basic 320x240 get transformed to one where biWidth // was 384, but TargetRect & SrcRect are still 320 x 240. Further, the formatsize // is sometimes > 1000 bytes, instead of the ~90 you would expect from VIH2. // To "approve" such bizarre constructs requires some creativity. This code is // adapted from the EVRPlayer sample. if (amt == null || amt.formatType != FormatType.VideoInfo2 || amt.formatSize < Marshal.SizeOf(typeof(VideoInfoHeader2))) { return DsResults.E_TypeNotAccepted; } // ValidateBitmapInfoHeader() - doesn't seem necessary. VideoInfoHeader2 pvi = (VideoInfoHeader2)Marshal.PtrToStructure(amt.formatPtr, typeof(VideoInfoHeader2)); AMMediaType pmtDesired = m_pmt; VideoInfoHeader2 vihDesired = (VideoInfoHeader2)Marshal.PtrToStructure(pmtDesired.formatPtr, typeof(VideoInfoHeader2)); // Check the basics if ( (amt.majorType != pmtDesired.majorType) || (amt.subType != pmtDesired.subType) || // (amt.formatType != pmtDesired.formatType) || (amt.formatSize < pmtDesired.formatSize) || (amt.formatSize == 0) || (amt.formatPtr == IntPtr.Zero) ) { return DsResults.E_InvalidMediaType; } // Check some of the basic VIH2 stuff if ((pvi.AvgTimePerFrame != vihDesired.AvgTimePerFrame) || (pvi.InterlaceFlags != vihDesired.InterlaceFlags) || (pvi.PictAspectRatioX != vihDesired.PictAspectRatioX) || (pvi.PictAspectRatioY != vihDesired.PictAspectRatioY) || (pvi.BmiHeader.Compression != vihDesired.BmiHeader.Compression)) { return DsResults.E_InvalidMediaType; } // Check the image size - If the biWidth has changed, we won't be able to just // compare to the value we proposed if (pvi.BmiHeader.ImageSize != 0) { int cbImage; if (pvi.BmiHeader.Compression != 3) { // ARGH! Create a MediaFoundation.Misc.BitmapInfoHeader from a DirectShowLib.BitmapInfoHeader (even // tho they are the same), so we can call MFCalculateBitmapImageSize MediaFoundation.Misc.BitmapInfoHeader bmi = new MediaFoundation.Misc.BitmapInfoHeader(); GCHandle gh = GCHandle.Alloc(pvi.BmiHeader, GCHandleType.Pinned); try { Marshal.PtrToStructure(gh.AddrOfPinnedObject(), bmi); } finally { gh.Free(); } bool b; MFExtern.MFCalculateBitmapImageSize(bmi, Marshal.SizeOf(typeof(BitmapInfo)), out cbImage, out b); } else { cbImage = ((m_bpp * m_Width) / 8) * m_Height; } if (pvi.BmiHeader.ImageSize != cbImage) { return DsResults.E_InvalidMediaType; } } // Check the dimensions Rectangle rcImage = new Rectangle(0, 0, m_Width, Math.Abs(m_Height)); // Heights must match. if (Math.Abs(pvi.BmiHeader.Height) != Math.Abs(vihDesired.BmiHeader.Height)) { return DsResults.E_InvalidMediaType; } // If rcTarget is empty, then biWidth must be our original width. if (pvi.TargetRect == null || pvi.TargetRect.ToRectangle().IsEmpty) { if (pvi.BmiHeader.Width != vihDesired.BmiHeader.Width) { return DsResults.E_InvalidMediaType; } } // Otherwise, rcTarget must be the same as our image size else if (pvi.TargetRect != rcImage) { return DsResults.E_InvalidMediaType; } // Finally, biWidth must be at least as wide as our image width. if (pvi.BmiHeader.Width < vihDesired.BmiHeader.Width) { return DsResults.E_InvalidMediaType; } // Everything checks out. return S_Ok; }
public IntPtr MarshalManagedToNative(object managedObj) { m_bmi = managedObj as MediaFoundation.Misc.BitmapInfoHeader; IntPtr ip = m_bmi.GetPtr(); return ip; }
public void CleanUpManagedData(object ManagedObj) { m_bmi = null; }
/// <summary> /// The GSSF calls this method to determine whether a proposed media type is acceptable. While /// the GSSF offers up the value set in SetMediaType, downstream filters may counter-propose /// media types that are similar. This method allows c# programs to accept or reject proposed /// alternatives. /// </summary> /// <param name="amt">The proposed alternative media type. Do NOT call DsUtils.FreeAMMediaType on this</param> /// <returns>S_Ok to accept the media type, a negative value to decline</returns> override public int CheckMediaType(AMMediaType amt) { // The media types sent down from the EVR can be very different from the one // we proposed. I've seen a basic 320x240 get transformed to one where biWidth // was 384, but TargetRect & SrcRect are still 320 x 240. Further, the formatsize // is sometimes > 1000 bytes, instead of the ~90 you would expect from VIH2. // To "approve" such bizarre constructs requires some creativity. This code is // adapted from the EVRPlayer sample. if (amt == null || amt.formatType != FormatType.VideoInfo2 || amt.formatSize < Marshal.SizeOf(typeof(VideoInfoHeader2))) { return(DsResults.E_TypeNotAccepted); } // ValidateBitmapInfoHeader() - doesn't seem necessary. VideoInfoHeader2 pvi = (VideoInfoHeader2)Marshal.PtrToStructure(amt.formatPtr, typeof(VideoInfoHeader2)); AMMediaType pmtDesired = m_pmt; VideoInfoHeader2 vihDesired = (VideoInfoHeader2)Marshal.PtrToStructure(pmtDesired.formatPtr, typeof(VideoInfoHeader2)); // Check the basics if ( (amt.majorType != pmtDesired.majorType) || (amt.subType != pmtDesired.subType) || // (amt.formatType != pmtDesired.formatType) || (amt.formatSize < pmtDesired.formatSize) || (amt.formatSize == 0) || (amt.formatPtr == IntPtr.Zero) ) { return(DsResults.E_InvalidMediaType); } // Check some of the basic VIH2 stuff if ((pvi.AvgTimePerFrame != vihDesired.AvgTimePerFrame) || (pvi.InterlaceFlags != vihDesired.InterlaceFlags) || (pvi.PictAspectRatioX != vihDesired.PictAspectRatioX) || (pvi.PictAspectRatioY != vihDesired.PictAspectRatioY) || (pvi.BmiHeader.Compression != vihDesired.BmiHeader.Compression)) { return(DsResults.E_InvalidMediaType); } // Check the image size - If the biWidth has changed, we won't be able to just // compare to the value we proposed if (pvi.BmiHeader.ImageSize != 0) { int cbImage; if (pvi.BmiHeader.Compression != 3) { // ARGH! Create a MediaFoundation.Misc.BitmapInfoHeader from a DirectShowLib.BitmapInfoHeader (even // tho they are the same), so we can call MFCalculateBitmapImageSize MediaFoundation.Misc.BitmapInfoHeader bmi = new MediaFoundation.Misc.BitmapInfoHeader(); GCHandle gh = GCHandle.Alloc(pvi.BmiHeader, GCHandleType.Pinned); try { Marshal.PtrToStructure(gh.AddrOfPinnedObject(), bmi); } finally { gh.Free(); } bool b; MFExtern.MFCalculateBitmapImageSize(bmi, Marshal.SizeOf(typeof(BitmapInfo)), out cbImage, out b); } else { cbImage = ((m_bpp * m_Width) / 8) * m_Height; } if (pvi.BmiHeader.ImageSize != cbImage) { return(DsResults.E_InvalidMediaType); } } // Check the dimensions Rectangle rcImage = new Rectangle(0, 0, m_Width, Math.Abs(m_Height)); // Heights must match. if (Math.Abs(pvi.BmiHeader.Height) != Math.Abs(vihDesired.BmiHeader.Height)) { return(DsResults.E_InvalidMediaType); } // If rcTarget is empty, then biWidth must be our original width. if (pvi.TargetRect == null || pvi.TargetRect.ToRectangle().IsEmpty) { if (pvi.BmiHeader.Width != vihDesired.BmiHeader.Width) { return(DsResults.E_InvalidMediaType); } } // Otherwise, rcTarget must be the same as our image size else if (pvi.TargetRect != rcImage) { return(DsResults.E_InvalidMediaType); } // Finally, biWidth must be at least as wide as our image width. if (pvi.BmiHeader.Width < vihDesired.BmiHeader.Width) { return(DsResults.E_InvalidMediaType); } // Everything checks out. return(S_Ok); }
public void CleanUpManagedData(object ManagedObj) { m_bmi = null; }