From ac79745f8eabbadb6aff3d59465785d91b08cf56 Mon Sep 17 00:00:00 2001 From: Omer Mor Date: Sat, 18 Aug 2012 00:06:46 +0300 Subject: [PATCH 1/5] Start adding CoClass interfaces --- ClassId.cs | 9 + DirectShowLib.csproj | 1 + Uuids.cs | 3077 +++++++++++++++++++++++++++--------------- 3 files changed, 2018 insertions(+), 1069 deletions(-) create mode 100644 ClassId.cs diff --git a/ClassId.cs b/ClassId.cs new file mode 100644 index 0000000..cab5a9c --- /dev/null +++ b/ClassId.cs @@ -0,0 +1,9 @@ +namespace DirectShowLib +{ + internal static class ClassId + { + public const string StreamBufferSource = "C9F5FE02-F851-4eb5-99EE-AD602AF1E619"; + public const string StreamBufferSink = "2DB47AE5-CF39-43c2-B4D6-0CD8D90946F4"; + public const string SBE2Sink = "E2448508-95DA-4205-9A27-7EC81E723B1A"; + } +} \ No newline at end of file diff --git a/DirectShowLib.csproj b/DirectShowLib.csproj index 25dd901..b2b5139 100644 --- a/DirectShowLib.csproj +++ b/DirectShowLib.csproj @@ -110,6 +110,7 @@ Code + Code diff --git a/Uuids.cs b/Uuids.cs index ca4c713..444b317 100644 --- a/Uuids.cs +++ b/Uuids.cs @@ -24,13 +24,15 @@ You should have received a copy of the GNU Lesser General Public using System; using System.Runtime.InteropServices; +using DirectShowLib.SBE; namespace DirectShowLib { + #region COM Class Objects /// - /// CLSID_StreamBufferRecordingAttributes + /// CLSID_StreamBufferRecordingAttributes /// [ComImport, Guid("CCAA63AC-1057-4778-AE92-1206AB9ACEE6")] public class StreamBufferRecordingAttributes @@ -38,7 +40,7 @@ public class StreamBufferRecordingAttributes } /// - /// CLSID_AudioRecord + /// CLSID_AudioRecord /// [ComImport, Guid("e30629d2-27e5-11ce-875d-00608cb78066")] public class AudioRecord @@ -46,7 +48,7 @@ public class AudioRecord } /// - /// CLSID_AVICo + /// CLSID_AVICo /// [ComImport, Guid("D76E2820-1563-11cf-AC98-00AA004C0FA9")] public class AVICo @@ -54,7 +56,7 @@ public class AVICo } /// - /// CLSID_AVIDoc + /// CLSID_AVIDoc /// [ComImport, Guid("D3588AB0-0781-11ce-B03A-0020AF0BA770")] public class AVIDoc @@ -62,7 +64,7 @@ public class AVIDoc } /// - /// CLSID_AviReader + /// CLSID_AviReader /// [ComImport, Guid("1b544c21-fd0b-11ce-8c63-00aa0044b51e")] public class AviReader @@ -70,16 +72,16 @@ public class AviReader } /// - /// CLSID_FGControl + /// CLSID_FGControl /// [ComImport, Guid("e436ebb4-524f-11ce-9f53-0020af0ba770")] public class FGControl { } - + /// - /// CLSID_FileSource + /// CLSID_FileSource /// [ComImport, Guid("701722e0-8ae3-11ce-a85c-00aa002feab5")] public class FileSource @@ -87,7 +89,7 @@ public class FileSource } /// - /// CLSID_FilterMapper + /// CLSID_FilterMapper /// [ComImport, Guid("e436ebb2-524f-11ce-9f53-0020af0ba770")] public class FilterMapper @@ -95,7 +97,7 @@ public class FilterMapper } /// - /// CLSID_ProtoFilterGraph + /// CLSID_ProtoFilterGraph /// [ComImport, Guid("e436ebb0-524f-11ce-9f53-0020af0ba770")] public class ProtoFilterGraph @@ -103,7 +105,7 @@ public class ProtoFilterGraph } /// - /// CLSID_MOVReader + /// CLSID_MOVReader /// [ComImport, Guid("44584800-F8EE-11ce-B2D4-00DD01101B85")] public class MOVReader @@ -111,7 +113,7 @@ public class MOVReader } /// - /// CLSID_VPObject + /// CLSID_VPObject /// [ComImport, Guid("CE292861-FC88-11d0-9E69-00C04FD7C15B")] public class VPObject @@ -119,7 +121,7 @@ public class VPObject } /// - /// CLSID_VPVBIObject + /// CLSID_VPVBIObject /// [ComImport, Guid("814B9801-1C88-11d1-BAD9-00609744111A")] public class VPVBIObject @@ -127,7 +129,7 @@ public class VPVBIObject } /// - /// CLSID_MPEG1Doc + /// CLSID_MPEG1Doc /// [ComImport, Guid("e4bbd160-4269-11ce-838d-00aa0055595a")] public class MPEG1Doc @@ -135,7 +137,7 @@ public class MPEG1Doc } /// - /// CLSID_TextRender + /// CLSID_TextRender /// [ComImport, Guid("e30629d3-27e5-11ce-875d-00608cb78066")] public class TextRender @@ -143,7 +145,7 @@ public class TextRender } /// - /// CLSID_CDeviceMoniker + /// CLSID_CDeviceMoniker /// [ComImport, Guid("4315D437-5B8C-11d0-BD3B-00A0C911CE86")] public class CDeviceMoniker @@ -151,7 +153,7 @@ public class CDeviceMoniker } /// - /// CLSID_DTFilter + /// CLSID_DTFilter /// [ComImport, Guid("C4C4C4F2-0049-4E2B-98FB-9537F6CE516D")] public class DTFilter @@ -159,7 +161,7 @@ public class DTFilter } /// - /// CLSID_ETFilter + /// CLSID_ETFilter /// [ComImport, Guid("C4C4C4F1-0049-4E2B-98FB-9537F6CE516D")] public class ETFilter @@ -167,7 +169,7 @@ public class ETFilter } /// - /// CLSID_FilterGraphPrivateThread + /// CLSID_FilterGraphPrivateThread /// [ComImport, Guid("a3ecbc41-581a-4476-b693-a63340462d8b")] public class FilterGraphPrivateThread @@ -176,7 +178,7 @@ public class FilterGraphPrivateThread /// - /// CLSID_DtvCcFilter + /// CLSID_DtvCcFilter /// [ComImport, Guid("FB056BA0-2502-45B9-8E86-2B40DE84AD29")] public class DtvCcFilter @@ -185,7 +187,7 @@ public class DtvCcFilter /// - /// CLSID_MSTVCaptionFilter + /// CLSID_MSTVCaptionFilter /// [ComImport, Guid("2F7EE4B6-6FF5-4EB4-B24A-2BFC41117171")] public class MSTVCaptionFilter @@ -194,7 +196,7 @@ public class MSTVCaptionFilter /// - /// CLSID_SystemDeviceEnum + /// CLSID_SystemDeviceEnum /// [ComImport, Guid("62BE5D10-60EB-11d0-BD3B-00A0C911CE86")] public class CreateDevEnum @@ -203,7 +205,7 @@ public class CreateDevEnum /// - /// CLSID_FilterGraph + /// CLSID_FilterGraph /// [ComImport, Guid("e436ebb3-524f-11ce-9f53-0020af0ba770")] public class FilterGraph @@ -212,7 +214,7 @@ public class FilterGraph /// - /// CLSID_FilterGraphNoThread + /// CLSID_FilterGraphNoThread /// [ComImport, Guid("e436ebb8-524f-11ce-9f53-0020af0ba770")] public class FilterGraphNoThread @@ -221,7 +223,7 @@ public class FilterGraphNoThread /// - /// CLSID_CaptureGraphBuilder2 + /// CLSID_CaptureGraphBuilder2 /// [ComImport, Guid("BF87B6E1-8C27-11d0-B3F0-00AA003761C5")] public class CaptureGraphBuilder2 @@ -230,7 +232,7 @@ public class CaptureGraphBuilder2 /// - /// CLSID_DvdGraphBuilder + /// CLSID_DvdGraphBuilder /// [ComImport, Guid("FCC152B7-F372-11d0-8E00-00C04FD7C08B")] public class DvdGraphBuilder @@ -239,7 +241,7 @@ public class DvdGraphBuilder /// - /// CLSID_CaptureGraphBuilder + /// CLSID_CaptureGraphBuilder /// [ComImport, Guid("BF87B6E0-8C27-11d0-B3F0-00AA003761C5")] public class CaptureGraphBuilder @@ -248,7 +250,7 @@ public class CaptureGraphBuilder /// - /// CLSID_StreamBufferConfig + /// CLSID_StreamBufferConfig /// [ComImport, Guid("FA8A68B2-C864-4ba2-AD53-D3876A87494B")] public class StreamBufferConfig @@ -257,7 +259,7 @@ public class StreamBufferConfig /// - /// CLSID_StreamBufferComposeRecording + /// CLSID_StreamBufferComposeRecording /// [ComImport, Guid("D682C4BA-A90A-42fe-B9E1-03109849C423")] public class StreamBufferComposeRecording @@ -266,7 +268,7 @@ public class StreamBufferComposeRecording /// - /// CLSID_SeekingPassThru + /// CLSID_SeekingPassThru /// [ComImport, Guid("060AF76C-68DD-11d0-8FC1-00C04FD9189D")] public class SeekingPassThru @@ -275,7 +277,7 @@ public class SeekingPassThru /// - /// CLSID_FilterMapper2 + /// CLSID_FilterMapper2 /// [ComImport, Guid("CDA42200-BD88-11d0-BD4E-00A0C911CE86")] public class FilterMapper2 @@ -284,7 +286,7 @@ public class FilterMapper2 /// - /// CLSID_MemoryAllocator + /// CLSID_MemoryAllocator /// [ComImport, Guid("1e651cc0-b199-11d0-8212-00c04fc32c45")] public class MemoryAllocator @@ -293,7 +295,7 @@ public class MemoryAllocator /// - /// CLSID_MediaPropertyBag + /// CLSID_MediaPropertyBag /// [ComImport, Guid("CDBD8D00-C193-11d0-BD4E-00A0C911CE86")] public class MediaPropertyBag @@ -302,7 +304,7 @@ public class MediaPropertyBag /// - /// CLSID_DVDState + /// CLSID_DVDState /// [ComImport, Guid("f963c5cf-a659-4a93-9638-caf3cd277d13")] public class DVDState @@ -310,7 +312,7 @@ public class DVDState } /// - /// CLSID_SectionList + /// CLSID_SectionList /// [ComImport, Guid("73DA5D04-4347-45d3-A9DC-FAE9DDBE558D")] public class SectionList @@ -318,7 +320,7 @@ public class SectionList } /// - /// CLSID_Mpeg2Stream + /// CLSID_Mpeg2Stream /// [ComImport, Guid("F91D96C7-8509-4d0b-AB26-A0DD10904BB7")] public class Mpeg2Stream @@ -326,7 +328,7 @@ public class Mpeg2Stream } /// - /// CLSID_Mpeg2Data + /// CLSID_Mpeg2Data /// [ComImport, Guid("C666E115-BB62-4027-A113-82D643FE2D99")] public class Mpeg2Data @@ -334,7 +336,7 @@ public class Mpeg2Data } /// - /// Unnamed clsid + /// Unnamed clsid /// [ComImport, Guid("33facfe0-a9be-11d0-a520-00a0d10129c0")] public class SAMIParser @@ -342,7 +344,7 @@ public class SAMIParser } /// - /// Unnamed clsid + /// Unnamed clsid /// [ComImport, Guid("48025243-2D39-11CE-875D-00608CB78066")] public class InternalScriptCommandRenderer @@ -350,7 +352,7 @@ public class InternalScriptCommandRenderer } /// - /// CLSID_BroadcastEventService + /// CLSID_BroadcastEventService /// [ComImport, Guid("0B3FFB92-0919-4934-9D5B-619C719D0202")] public class BroadcastEventService @@ -358,7 +360,7 @@ public class BroadcastEventService } /// - /// CLSID_AtscPsipParser + /// CLSID_AtscPsipParser /// [ComImport, Guid("3508C064-B94E-420b-A821-20C8096FAADC")] public class AtscPsipParser @@ -366,7 +368,7 @@ public class AtscPsipParser } /// - /// CLSID_DvbSiParser + /// CLSID_DvbSiParser /// [ComImport, Guid("F6B96EDA-1A94-4476-A85F-4D3DC7B39C3F")] public class DvbSiParser @@ -378,7 +380,7 @@ public class DvbSiParser #region Filter Classes /// - /// CLSID_DMOWrapperFilter + /// CLSID_DMOWrapperFilter /// [ComImport, Guid("94297043-bd82-4dfd-b0de-8177739c6d20")] public class DMOWrapperFilter @@ -387,34 +389,61 @@ public class DMOWrapperFilter /// - /// CLSID_StreamBufferSink + /// CLSID_StreamBufferSink /// - [ComImport, Guid("2DB47AE5-CF39-43c2-B4D6-0CD8D90946F4")] - public class StreamBufferSink + [ComImport, Guid(ClassId.StreamBufferSink)] + public class StreamBufferSinkImpl + { + } + + /// + /// CLSID_StreamBufferSink + /// + [ComImport, CoClass(typeof (StreamBufferSinkImpl)), Guid(ClassId.StreamBufferSink)] + public interface StreamBufferSink : IBaseFilter, + ISpecifyPropertyPages, + IStreamBufferInitialize, + IStreamBufferSink3 { } /// - /// CLSID_SampleGrabber + /// CLSID_SampleGrabber /// [ComImport, Guid("C1F400A0-3F08-11d3-9F0B-006008039E37")] public class SampleGrabber { } + /// + /// CLSID_StreamBufferSource + /// + [ComImport, Guid(ClassId.StreamBufferSource)] + public class StreamBufferSourceImpl + { + } /// - /// CLSID_StreamBufferSource + /// CLSID_StreamBufferSource /// - [ComImport, Guid("C9F5FE02-F851-4eb5-99EE-AD602AF1E619")] - public class StreamBufferSource + [ComImport, CoClass(typeof(StreamBufferSourceImpl)), Guid(ClassId.StreamBufferSource)] + public interface StreamBufferSource : IAMFilterMiscFlags, + IBaseFilter, + IFileSourceFilter, + ISpecifyPropertyPages, + IStreamBufferMediaSeeking2, + IStreamBufferInitialize, + IStreamBufferSource, + ISBE2GlobalEvent, + ISBE2SpanningEvent, + ISBE2Crossbar { } /// - /// CLSID_VideoMixingRenderer + /// CLSID_VideoMixingRenderer /// [ComImport, Guid("B87BEB7B-8D29-423f-AE4D-6582C10175AC")] public class VideoMixingRenderer @@ -423,7 +452,7 @@ public class VideoMixingRenderer /// - /// CLSID_VideoMixingRenderer9 + /// CLSID_VideoMixingRenderer9 /// [ComImport, Guid("51b4abf3-748f-4e3b-a276-c828330e926a")] public class VideoMixingRenderer9 @@ -432,7 +461,7 @@ public class VideoMixingRenderer9 /// - /// CLSID_VideoRendererDefault + /// CLSID_VideoRendererDefault /// [ComImport, Guid("6BC1CFFA-8FC1-4261-AC22-CFB4CC38DB50")] public class VideoRendererDefault @@ -441,7 +470,7 @@ public class VideoRendererDefault /// - /// CLSID_AviSplitter + /// CLSID_AviSplitter /// [ComImport, Guid("1b544c20-fd0b-11ce-8c63-00aa0044b51e")] public class AviSplitter @@ -450,7 +479,7 @@ public class AviSplitter /// - /// CLSID_SmartTee + /// CLSID_SmartTee /// [ComImport, Guid("CC58E280-8AA1-11d1-B3F1-00AA003761C5")] public class SmartTee @@ -459,7 +488,7 @@ public class SmartTee /// - /// CLSID_NullRenderer + /// CLSID_NullRenderer /// [ComImport, Guid("C1F400A4-3F08-11d3-9F0B-006008039E37")] public class NullRenderer @@ -468,7 +497,7 @@ public class NullRenderer /// - /// CLSID_ACMWrapper + /// CLSID_ACMWrapper /// [ComImport, Guid("6a08cf80-0e18-11cf-a24d-0020afd79767")] public class ACMWrapper @@ -477,7 +506,7 @@ public class ACMWrapper /// - /// CLSID_AudioRender + /// CLSID_AudioRender /// [ComImport, Guid("e30629d1-27e5-11ce-875d-00608cb78066")] public class AudioRender @@ -486,7 +515,7 @@ public class AudioRender /// - /// CLSID_AVIDec + /// CLSID_AVIDec /// [ComImport, Guid("CF49D4E0-1115-11ce-B03A-0020AF0BA770")] public class AVIDec @@ -495,7 +524,7 @@ public class AVIDec /// - /// CLSID_AVIDraw + /// CLSID_AVIDraw /// [ComImport, Guid("A888DF60-1E90-11cf-AC98-00AA004C0FA9")] public class AVIDraw @@ -504,7 +533,7 @@ public class AVIDraw /// - /// CLSID_AviDest + /// CLSID_AviDest /// [ComImport, Guid("E2510970-F137-11CE-8B67-00AA00A3F1A6")] public class AviDest @@ -513,7 +542,7 @@ public class AviDest /// - /// CLSID_ATSCNetworkProvider + /// CLSID_ATSCNetworkProvider /// [ComImport, Guid("0DAD2FDD-5FD7-11D3-8F50-00C04F7971E2")] public class ATSCNetworkProvider @@ -522,7 +551,7 @@ public class ATSCNetworkProvider /// - /// CLSID_DVBCNetworkProvider + /// CLSID_DVBCNetworkProvider /// [ComImport, Guid("DC0C0FE7-0485-4266-B93F-68FBF80ED834")] public class DVBCNetworkProvider @@ -531,7 +560,7 @@ public class DVBCNetworkProvider /// - /// CLSID_DVBSNetworkProvider + /// CLSID_DVBSNetworkProvider /// [ComImport, Guid("FA4B375A-45B4-4d45-8440-263957B11623")] public class DVBSNetworkProvider @@ -540,7 +569,7 @@ public class DVBSNetworkProvider /// - /// CLSID_DVBTNetworkProvider + /// CLSID_DVBTNetworkProvider /// [ComImport, Guid("216C62DF-6D7F-4e9a-8571-05F14EDB766A")] public class DVBTNetworkProvider @@ -548,7 +577,7 @@ public class DVBTNetworkProvider } /// - /// CLSID_NetworkProvider + /// CLSID_NetworkProvider /// [ComImport, Guid("B2F3A67C-29DA-4c78-8831-091ED509A475")] public class NetworkProvider @@ -556,7 +585,7 @@ public class NetworkProvider } /// - /// CLSID_Colour + /// CLSID_Colour /// [ComImport, Guid("1643e180-90f5-11ce-97d5-00aa0055595a")] public class Colour @@ -565,7 +594,7 @@ public class Colour /// - /// CLSID_DSoundRender + /// CLSID_DSoundRender /// [ComImport, Guid("79376820-07D0-11cf-A24D-0020AFD79767")] public class DSoundRender @@ -574,7 +603,7 @@ public class DSoundRender /// - /// CLSID_DVMux + /// CLSID_DVMux /// [ComImport, Guid("129D7E40-C10D-11d0-AFB9-00AA00B67A42")] public class DVMux @@ -583,7 +612,7 @@ public class DVMux /// - /// CLSID_DVSplitter + /// CLSID_DVSplitter /// [ComImport, Guid("4EB31670-9FC6-11cf-AF6E-00AA00B67A42")] public class DVSplitter @@ -592,7 +621,7 @@ public class DVSplitter /// - /// CLSID_DVVideoCodec + /// CLSID_DVVideoCodec /// [ComImport, Guid("B1B77C00-C3E4-11cf-AF79-00AA00B67A42")] public class DVVideoCodec @@ -601,7 +630,7 @@ public class DVVideoCodec /// - /// CLSID_DVVideoEnc + /// CLSID_DVVideoEnc /// [ComImport, Guid("13AA3650-BB6F-11d0-AFB9-00AA00B67A42")] public class DVVideoEnc @@ -610,7 +639,7 @@ public class DVVideoEnc /// - /// CLSID_DVDNavigator + /// CLSID_DVDNavigator /// [ComImport, Guid("9B8C4620-2C1A-11d0-8493-00A02438AD48")] public class DVDNavigator @@ -619,7 +648,7 @@ public class DVDNavigator /// - /// CLSID_AsyncReader + /// CLSID_AsyncReader /// [ComImport, Guid("e436ebb5-524f-11ce-9f53-0020af0ba770")] public class AsyncReader @@ -628,7 +657,7 @@ public class AsyncReader /// - /// CLSID_URLReader + /// CLSID_URLReader /// [ComImport, Guid("e436ebb6-524f-11ce-9f53-0020af0ba770")] public class URLReader @@ -637,7 +666,7 @@ public class URLReader /// - /// CLSID_FileWriter + /// CLSID_FileWriter /// [ComImport, Guid("8596E5F0-0DA5-11d0-BD21-00A0C911CE86")] public class FileWriter @@ -646,7 +675,7 @@ public class FileWriter /// - /// CLSID_ModexRenderer + /// CLSID_ModexRenderer /// [ComImport, Guid("07167665-5011-11cf-BF33-00AA0055595A")] public class ModexRenderer @@ -655,7 +684,7 @@ public class ModexRenderer /// - /// CLSID_InfTee + /// CLSID_InfTee /// [ComImport, Guid("F8388A40-D5BB-11d0-BE5A-0080C706568E")] public class InfTee @@ -664,7 +693,7 @@ public class InfTee /// - /// CLSID_Line21Decoder + /// CLSID_Line21Decoder /// [ComImport, Guid("6E8D4A20-310C-11d0-B79A-00AA003767A7")] public class Line21Decoder @@ -673,7 +702,7 @@ public class Line21Decoder /// - /// CLSID_Line21Decoder2 + /// CLSID_Line21Decoder2 /// [ComImport, Guid("E4206432-01A1-4BEE-B3E1-3702C8EDC574")] public class Line21Decoder2 @@ -682,7 +711,7 @@ public class Line21Decoder2 /// - /// CLSID_AVIMIDIRender + /// CLSID_AVIMIDIRender /// [ComImport, Guid("07b65360-c445-11ce-afde-00aa006c14f4")] public class AVIMIDIRender @@ -691,7 +720,7 @@ public class AVIMIDIRender /// - /// CLSID_MJPGEnc + /// CLSID_MJPGEnc /// [ComImport, Guid("B80AB0A0-7416-11d2-9EEB-006008039E37")] public class MJPGEnc @@ -700,7 +729,7 @@ public class MJPGEnc /// - /// CLSID_MjpegDec + /// CLSID_MjpegDec /// [ComImport, Guid("301056D0-6DFF-11d2-9EEB-006008039E37")] public class MjpegDec @@ -709,7 +738,7 @@ public class MjpegDec /// - /// CLSID_CMpegAudioCodec + /// CLSID_CMpegAudioCodec /// [ComImport, Guid("4a2286e0-7bef-11ce-9bd9-0000e202599c")] public class CMpegAudioCodec @@ -718,7 +747,7 @@ public class CMpegAudioCodec /// - /// CLSID_MPEG1Splitter + /// CLSID_MPEG1Splitter /// [ComImport, Guid("336475d0-942a-11ce-a870-00aa002feab5")] public class MPEG1Splitter @@ -727,7 +756,7 @@ public class MPEG1Splitter /// - /// CLSID_CMpegVideoCodec + /// CLSID_CMpegVideoCodec /// [ComImport, Guid("feb50740-7bef-11ce-9bd9-0000e202599c")] public class CMpegVideoCodec @@ -736,7 +765,7 @@ public class CMpegVideoCodec /// - /// CLSID_MPEG2Demultiplexer + /// CLSID_MPEG2Demultiplexer /// [ComImport, Guid("afb6c280-2c41-11d3-8a60-0000f81e0e4a")] public class MPEG2Demultiplexer @@ -745,7 +774,7 @@ public class MPEG2Demultiplexer /// - /// CLSID_MMSPLITTER + /// CLSID_MMSPLITTER /// [ComImport, Guid("3ae86b20-7be8-11d1-abe6-00a0c905f375")] public class MMSPLITTER @@ -754,7 +783,7 @@ public class MMSPLITTER /// - /// CLSID_OverlayMixer + /// CLSID_OverlayMixer /// [ComImport, Guid("CD8743A1-3736-11d0-9E69-00C04FD7C15B")] public class OverlayMixer @@ -762,7 +791,7 @@ public class OverlayMixer } /// - /// CLSID_OverlayMixer2 + /// CLSID_OverlayMixer2 /// [ComImport, Guid("A0025E90-E45B-11D1-ABE9-00A0C905F375")] public class OverlayMixer2 @@ -771,7 +800,7 @@ public class OverlayMixer2 /// - /// CLSID_QTDec + /// CLSID_QTDec /// [ComImport, Guid("FDFE9681-74A3-11d0-AFA7-00AA00B67A42")] public class QTDec @@ -780,7 +809,7 @@ public class QTDec /// - /// CLSID_QuickTimeParser + /// CLSID_QuickTimeParser /// [ComImport, Guid("D51BD5A0-7548-11cf-A520-0080C77EF58A")] public class QuickTimeParser @@ -789,7 +818,7 @@ public class QuickTimeParser /// - /// CLSID_VBISurfaces + /// CLSID_VBISurfaces /// [ComImport, Guid("814B9800-1C88-11d1-BAD9-00609744111A")] public class VBISurfaces @@ -798,7 +827,7 @@ public class VBISurfaces /// - /// CLSID_VfwCapture + /// CLSID_VfwCapture /// [ComImport, Guid("1b544c22-fd0b-11ce-8c63-00aa0044b51e")] public class VfwCapture @@ -807,7 +836,7 @@ public class VfwCapture /// - /// CLSID_Dither + /// CLSID_Dither /// [ComImport, Guid("1da08500-9edc-11cf-bc10-00aa00ac74f6")] public class Dither @@ -816,7 +845,7 @@ public class Dither /// - /// CLSID_VideoPortManager + /// CLSID_VideoPortManager /// [ComImport, Guid("6f26a6cd-967b-47fd-874a-7aed2c9d25a2")] public class VideoPortManager @@ -825,7 +854,7 @@ public class VideoPortManager /// - /// CLSID_VideoRenderer + /// CLSID_VideoRenderer /// [ComImport, Guid("70e102b0-5556-11ce-97c0-00aa0055595a")] public class VideoRenderer @@ -834,7 +863,7 @@ public class VideoRenderer /// - /// CLSID_WMAsfReader + /// CLSID_WMAsfReader /// [ComImport, Guid("187463A0-5BB7-11d3-ACBE-0080C75E246E")] public class WMAsfReader @@ -843,7 +872,7 @@ public class WMAsfReader /// - /// CLSID_SystemClock + /// CLSID_SystemClock /// [ComImport, Guid("e436ebb1-524f-11ce-9f53-0020af0ba770")] public class SystemClock @@ -852,7 +881,7 @@ public class SystemClock /// - /// CLSID_WMAsfWriter + /// CLSID_WMAsfWriter /// [ComImport, Guid("7c23220e-55bb-11d3-8b16-00c04fb6bd3d")] public class WMAsfWriter @@ -861,7 +890,7 @@ public class WMAsfWriter /// - /// CLSID_WSTDecoder + /// CLSID_WSTDecoder /// [ComImport, Guid("70BC06E0-5666-11d3-A184-00105AEF9F33")] public class WSTDecoder @@ -870,7 +899,7 @@ public class WSTDecoder /// - /// CLSID_Mpeg2VideoStreamAnalyzer + /// CLSID_Mpeg2VideoStreamAnalyzer /// [ComImport, Guid("6CFAD761-735D-4aa5-8AFC-AF91A7D61EBA")] public class Mpeg2VideoStreamAnalyzer @@ -879,7 +908,7 @@ public class Mpeg2VideoStreamAnalyzer /// - /// CLSID_PTFilter + /// CLSID_PTFilter /// [ComImport, Guid("9CD31617-B303-4f96-8330-2EB173EA4DC6")] public class PTFilter @@ -887,7 +916,7 @@ public class PTFilter } /// - /// CLSID_MPEG2Demultiplexer_NoClock + /// CLSID_MPEG2Demultiplexer_NoClock /// [ComImport, Guid("687D3367-3644-467a-ADFE-6CD7A85C4A2C")] public class MPEG2Demultiplexer_NoClock @@ -896,16 +925,27 @@ public class MPEG2Demultiplexer_NoClock /// - /// CLSID_SBE2Sink + /// CLSID_SBE2Sink /// - [ComImport, Guid("E2448508-95DA-4205-9A27-7EC81E723B1A")] - public class SBE2Sink + [ComImport, Guid(ClassId.SBE2Sink)] + public class SBE2SinkImpl + { + } + + /// + /// CLSID_SBE2Sink + /// + [ComImport, CoClass(typeof (SBE2Sink)), Guid(ClassId.SBE2Sink)] + public interface SBE2Sink : IBaseFilter, + ISpecifyPropertyPages, + IStreamBufferInitialize, + IStreamBufferSink3 { } /// - /// CLSID_StreamBufferPropertyHandler + /// CLSID_StreamBufferPropertyHandler /// [ComImport, Guid("E37A73F8-FB01-43dc-914E-AAEE76095AB9")] public class StreamBufferPropertyHandler @@ -914,7 +954,7 @@ public class StreamBufferPropertyHandler /// - /// CLSID_StreamBufferThumbnailHandler + /// CLSID_StreamBufferThumbnailHandler /// [ComImport, Guid("713790EE-5EE1-45ba-8070-A1337D2762FA")] public class StreamBufferThumbnailHandler @@ -923,7 +963,7 @@ public class StreamBufferThumbnailHandler /// - /// CLSID_SBE2File + /// CLSID_SBE2File /// [ComImport, Guid("93A094D7-51E8-485b-904A-8D6B97DC6B39")] public class SBE2File @@ -932,7 +972,7 @@ public class SBE2File /// - /// CLSID_CCAFilter + /// CLSID_CCAFilter /// [ComImport, Guid("3d07a539-35ca-447c-9b05-8d85ce924f9e")] public class CCAFilter @@ -941,7 +981,7 @@ public class CCAFilter /// - /// CLSID_CaptionsFilter + /// CLSID_CaptionsFilter /// [ComImport, Guid("2F7EE4B6-6FF5-4EB4-B24A-2BFC41117171")] public class CaptionsFilter @@ -950,7 +990,7 @@ public class CaptionsFilter /// - /// CLSID_SubtitlesFilter + /// CLSID_SubtitlesFilter /// [ComImport, Guid("9F22CFEA-CE07-41ab-8BA0-C7364AF90AF9")] public class SubtitlesFilter @@ -959,7 +999,7 @@ public class SubtitlesFilter /// - /// CLSID_DirectShowPluginControl + /// CLSID_DirectShowPluginControl /// [ComImport, Guid("8670C736-F614-427b-8ADA-BBADC587194B")] public class DirectShowPluginControl @@ -968,7 +1008,7 @@ public class DirectShowPluginControl /// - /// CLSID_SBE2MediaTypeProfile + /// CLSID_SBE2MediaTypeProfile /// [ComImport, Guid("1f26a602-2b5c-4b63-b8e8-9ea5c1a7dc2e")] public class SBE2MediaTypeProfile @@ -977,992 +1017,1891 @@ public class SBE2MediaTypeProfile /// - /// CLSID_SBE2FileScan + /// CLSID_SBE2FileScan /// [ComImport, Guid("3E458037-0CA6-41aa-A594-2AA6C02D709B")] public class SBE2FileScan { } - #endregion #region GUIDS - static public class FilterCategory - { - /// CLSID_CPCAFiltersCategory - public static readonly Guid CPCAFiltersCategory = new Guid(0xC4C4C4FC, 0x0049, 0x4E2B, 0x98, 0xFB, 0x95, 0x37, 0xF6, 0xCE, 0x51, 0x6D); - - /// CLSID_MediaEncoderCategory - public static readonly Guid MediaEncoderCategory = new Guid(0x7D22E920, 0x5CA9, 0x4787, 0x8C, 0x2B, 0xA6, 0x77, 0x9B, 0xD1, 0x17, 0x81); - - /// CLSID_MediaMultiplexerCategory - public static readonly Guid MediaMultiplexerCategory = new Guid(0x236C9559, 0xADCE, 0x4736, 0xBF, 0x72, 0xBA, 0xB3, 0x4E, 0x39, 0x21, 0x96); - - /// CLSID_DMOFilterCategory - public static readonly Guid DMOFilterCategory = new Guid(0xbcd5796c, 0xbd52, 0x4d30, 0xab, 0x76, 0x70, 0xf9, 0x75, 0xb8, 0x91, 0x99); - - /// CLSID_AudioInputDeviceCategory, audio capture category - public static readonly Guid AudioInputDevice = new Guid(0x33d9a762, 0x90c8, 0x11d0, 0xbd, 0x43, 0x00, 0xa0, 0xc9, 0x11, 0xce, 0x86); - - /// CLSID_VideoInputDeviceCategory, video capture category - public static readonly Guid VideoInputDevice = new Guid(0x860BB310, 0x5D01, 0x11d0, 0xBD, 0x3B, 0x00, 0xA0, 0xC9, 0x11, 0xCE, 0x86); - - /// CLSID_VideoCompressorCategory, video compressor category - public static readonly Guid VideoCompressorCategory = new Guid(0x33d9a760, 0x90c8, 0x11d0, 0xbd, 0x43, 0x00, 0xa0, 0xc9, 0x11, 0xce, 0x86); - - /// CLSID_AudioCompressorCategory, audio compressor category - public static readonly Guid AudioCompressorCategory = new Guid(0x33d9a761, 0x90c8, 0x11d0, 0xbd, 0x43, 0x00, 0xa0, 0xc9, 0x11, 0xce, 0x86); - - /// CLSID_LegacyAmFilterCategory, legacy filters - public static readonly Guid LegacyAmFilterCategory = new Guid(0x083863F1, 0x70DE, 0x11d0, 0xBD, 0x40, 0x00, 0xA0, 0xC9, 0x11, 0xCE, 0x86); - - /// CLSID_AudioRendererCategory, Audio renderer category - public static readonly Guid AudioRendererCategory = new Guid(0xe0f158e1, 0xcb04, 0x11d0, 0xbd, 0x4e, 0x00, 0xa0, 0xc9, 0x11, 0xce, 0x86); - - /// KSCATEGORY_BDA_RECEIVER_COMPONENT, BDA Receiver Components category - public static readonly Guid BDAReceiverComponentsCategory = new Guid(0xFD0A5AF4, 0xB41D, 0x11d2, 0x9c, 0x95, 0x00, 0xc0, 0x4f, 0x79, 0x71, 0xe0); - - /// KSCATEGORY_BDA_NETWORK_TUNER, BDA Source Filters category - public static readonly Guid BDASourceFiltersCategory = new Guid(0x71985f48, 0x1ca1, 0x11d3, 0x9c, 0xc8, 0x00, 0xc0, 0x4f, 0x79, 0x71, 0xe0); - - /// KSCATEGORY_BDA_IP_SINK, BDA Rendering Filters category - public static readonly Guid BDARenderingFiltersCategory = new Guid(0x71985f4a, 0x1ca1, 0x11d3, 0x9c, 0xc8, 0x00, 0xc0, 0x4f, 0x79, 0x71, 0xe0); - - /// KSCATEGORY_BDA_NETWORK_PROVIDER, BDA Network Providers category - public static readonly Guid BDANetworkProvidersCategory = new Guid(0x71985f4b, 0x1ca1, 0x11d3, 0x9c, 0xc8, 0x00, 0xc0, 0x4f, 0x79, 0x71, 0xe0); - - /// KSCATEGORY_BDA_TRANSPORT_INFORMATION, BDA Transport Information Renderers category - public static readonly Guid BDATransportInformationRenderersCategory = new Guid(0xa2e3074f, 0x6c3d, 0x11d3, 0xb6, 0x53, 0x00, 0xc0, 0x4f, 0x79, 0x49, 0x8e); - - /// CLSID_MidiRendererCategory - public static readonly Guid MidiRendererCategory = new Guid(0x4EfE2452, 0x168A, 0x11d1, 0xBC, 0x76, 0x00, 0xc0, 0x4F, 0xB9, 0x45, 0x3B); - - /// CLSID_TransmitCategory External Renderers Category - public static readonly Guid TransmitCategory = new Guid(0xcc7bfb41, 0xf175, 0x11d1, 0xa3, 0x92, 0x00, 0xe0, 0x29, 0x1f, 0x39, 0x59); - - /// CLSID_DeviceControlCategory Device Control Filters - public static readonly Guid DeviceControlCategory = new Guid(0xcc7bfb46, 0xf175, 0x11d1, 0xa3, 0x92, 0x00, 0xe0, 0x29, 0x1f, 0x39, 0x59); - - /// CLSID_VideoEffects1Category - public static readonly Guid VideoEffects1Category = new Guid(0xcc7bfb42, 0xf175, 0x11d1, 0xa3, 0x92, 0x00, 0xe0, 0x29, 0x1f, 0x39, 0x59); - - /// CLSID_VideoEffects2Category - public static readonly Guid VideoEffects2Category = new Guid(0xcc7bfb43, 0xf175, 0x11d1, 0xa3, 0x92, 0x00, 0xe0, 0x29, 0x1f, 0x39, 0x59); - - /// CLSID_AudioEffects1Category - public static readonly Guid AudioEffects1Category = new Guid(0xcc7bfb44, 0xf175, 0x11d1, 0xa3, 0x92, 0x00, 0xe0, 0x29, 0x1f, 0x39, 0x59); - - /// CLSID_AudioEffects2Category - public static readonly Guid AudioEffects2Category = new Guid(0xcc7bfb45, 0xf175, 0x11d1, 0xa3, 0x92, 0x00, 0xe0, 0x29, 0x1f, 0x39, 0x59); - - /// KSCATEGORY_DATADECOMPRESSOR & CLSID_DVDHWDecodersCategory - public static readonly Guid KSDataDecompressor = new Guid(0x2721AE20, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00); - - /// KSCATEGORY_COMMUNICATIONSTRANSFORM - public static readonly Guid KSCommunicationsTransform = new Guid(0xCF1DDA2C, 0x9743, 0x11D0, 0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96); - - /// KSCATEGORY_DATATRANSFORM - public static readonly Guid KSDataTransform = new Guid(0x2EB07EA0, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00); - - /// KSCATEGORY_INTERFACETRANSFORM - public static readonly Guid KSInterfaceTransform = new Guid(0xCF1DDA2D, 0x9743, 0x11D0, 0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96); - - /// KSCATEGORY_MIXER - public static readonly Guid KSMixer = new Guid(0xAD809C00, 0x7B88, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00); - - /// KSCATEGORY_AUDIO_DEVICE - public static readonly Guid KSAudioDevice = new Guid(0xFBF6F530, 0x07B9, 0x11D2, 0xA7, 0x1E, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88); - - /// CLSID_ActiveMovieCategories - public static readonly Guid ActiveMovieCategories = new Guid(0xda4e3da0, 0xd07d, 0x11d0, 0xbd, 0x50, 0x00, 0xa0, 0xc9, 0x11, 0xce, 0x86); - - /// AM_KSCATEGORY_CAPTURE - public static readonly Guid AMKSCapture = new Guid(0x65E8773D, 0x8F56, 0x11D0, 0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96); - - /// AM_KSCATEGORY_RENDER - public static readonly Guid AMKSRender = new Guid(0x65E8773E, 0x8F56, 0x11D0, 0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96); - - /// AM_KSCATEGORY_DATACOMPRESSOR - public static readonly Guid AMKSDataCompressor = new Guid(0x1E84C900, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00); - - /// AM_KSCATEGORY_AUDIO - public static readonly Guid AMKSAudio = new Guid(0x6994AD04, 0x93EF, 0x11D0, 0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96); - - /// AM_KSCATEGORY_VIDEO - public static readonly Guid AMKSVideo = new Guid(0x6994AD05, 0x93EF, 0x11D0, 0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96); - - /// AM_KSCATEGORY_TVTUNER - public static readonly Guid AMKSTVTuner = new Guid(0xa799a800, 0xa46d, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0x24, 0x01, 0xdc, 0xd4); - - /// AM_KSCATEGORY_CROSSBAR - public static readonly Guid AMKSCrossbar = new Guid(0xa799a801, 0xa46d, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0x24, 0x01, 0xdc, 0xd4); - - /// AM_KSCATEGORY_TVAUDIO - public static readonly Guid AMKSTVAudio = new Guid(0xa799a802, 0xa46d, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0x24, 0x01, 0xdc, 0xd4); - - /// AM_KSCATEGORY_VBICODEC - public static readonly Guid AMKSVBICodec = new Guid(0x07dad660, 0x22f1, 0x11d1, 0xa9, 0xf4, 0x00, 0xc0, 0x4f, 0xbb, 0xde, 0x8f); - - /// AM_KSCATEGORY_SPLITTER - public static readonly Guid AMKSSplitter = new Guid(0x0A4252A0, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00); - - /// Not defined - public static readonly Guid WDMStreamingEncoderDevices = new Guid(0x19689BF6, 0xC384, 0x48FD, 0xAD, 0x51, 0x90, 0xE5, 0x8C, 0x79, 0xF7, 0x0B); - - /// Not defined - public static readonly Guid WDMStreamingMultiplexerDevices = new Guid(0x7A5DE1D3, 0x01A1, 0x452C, 0xB4, 0x81, 0x4F, 0xA2, 0xB9, 0x62, 0x71, 0xE8); - - /// Not defined - public static readonly Guid LTMMVideoProcessors = new Guid(0xE526D606, 0x22E7, 0x494C, 0xB8, 0x1E, 0xAC, 0x0A, 0x94, 0xBF, 0xE6, 0x03); - } - - static public class VMRClsId - { - /// CLSID_AllocPresenter - public static readonly Guid AllocPresenter = new Guid(0x99d54f63, 0x1a69, 0x41ae, 0xaa, 0x4d, 0xc9, 0x76, 0xeb, 0x3f, 0x07, 0x13); - - /// CLSID_AllocPresenterDDXclMode - public static readonly Guid AllocPresenterDDXclMode = new Guid(0x4444ac9e, 0x242e, 0x471b, 0xa3, 0xc7, 0x45, 0xdc, 0xd4, 0x63, 0x52, 0xbc); - } - - static public class TVEClsId - { - /// CLSID_DShowTVEFilter - public static readonly Guid DShowTVEFilter = new Guid(0x05500280, 0xFAA5, 0x4DF9, 0x82, 0x46, 0xBF, 0xC2, 0x3A, 0xC5, 0xCE, 0xA8); - - /// CLSID_TVEFilterTuneProperties - public static readonly Guid TVEFilterTuneProperties = new Guid(0x05500281, 0xFAA5, 0x4DF9, 0x82, 0x46, 0xBF, 0xC2, 0x3A, 0xC5, 0xCE, 0xA8); - - /// CLSID_TVEFilterCCProperties - public static readonly Guid TVEFilterCCProperties = new Guid(0x05500282, 0xFAA5, 0x4DF9, 0x82, 0x46, 0xBF, 0xC2, 0x3A, 0xC5, 0xCE, 0xA8); - - /// CLSID_TVEFilterStatsProperties - public static readonly Guid TVEFilterStatsProperties = new Guid(0x05500283, 0xFAA5, 0x4DF9, 0x82, 0x46, 0xBF, 0xC2, 0x3A, 0xC5, 0xCE, 0xA8); - } - - static public class ENCAPIClsId - { - /// CLSID_IVideoEncoderProxy - public static readonly Guid IVideoEncoderProxy = new Guid(0xb43c4eec, 0x8c32, 0x4791, 0x91, 0x02, 0x50, 0x8a, 0xda, 0x5e, 0xe8, 0xe7); - - /// CLSID_ICodecAPIProxy - public static readonly Guid ICodecAPIProxy = new Guid(0x7ff0997a, 0x1999, 0x4286, 0xa7, 0x3c, 0x62, 0x2b, 0x88, 0x14, 0xe7, 0xeb); - - /// CLSID_IVideoEncoderCodecAPIProxy - public static readonly Guid IVideoEncoderCodecAPIProxy = new Guid(0xb05dabd9, 0x56e5, 0x4fdc, 0xaf, 0xa4, 0x8a, 0x47, 0xe9, 0x1f, 0x1c, 0x9c); - } - - static public class MediaType + public static class FilterCategory + { + /// + /// CLSID_CPCAFiltersCategory + /// + public static readonly Guid CPCAFiltersCategory = new Guid(0xC4C4C4FC, 0x0049, 0x4E2B, 0x98, 0xFB, 0x95, 0x37, + 0xF6, 0xCE, 0x51, 0x6D); + + /// + /// CLSID_MediaEncoderCategory + /// + public static readonly Guid MediaEncoderCategory = new Guid(0x7D22E920, 0x5CA9, 0x4787, 0x8C, 0x2B, 0xA6, 0x77, + 0x9B, 0xD1, 0x17, 0x81); + + /// + /// CLSID_MediaMultiplexerCategory + /// + public static readonly Guid MediaMultiplexerCategory = new Guid(0x236C9559, 0xADCE, 0x4736, 0xBF, 0x72, 0xBA, + 0xB3, 0x4E, 0x39, 0x21, 0x96); + + /// + /// CLSID_DMOFilterCategory + /// + public static readonly Guid DMOFilterCategory = new Guid(0xbcd5796c, 0xbd52, 0x4d30, 0xab, 0x76, 0x70, 0xf9, + 0x75, 0xb8, 0x91, 0x99); + + /// + /// CLSID_AudioInputDeviceCategory, audio capture category + /// + public static readonly Guid AudioInputDevice = new Guid(0x33d9a762, 0x90c8, 0x11d0, 0xbd, 0x43, 0x00, 0xa0, 0xc9, + 0x11, 0xce, 0x86); + + /// + /// CLSID_VideoInputDeviceCategory, video capture category + /// + public static readonly Guid VideoInputDevice = new Guid(0x860BB310, 0x5D01, 0x11d0, 0xBD, 0x3B, 0x00, 0xA0, 0xC9, + 0x11, 0xCE, 0x86); + + /// + /// CLSID_VideoCompressorCategory, video compressor category + /// + public static readonly Guid VideoCompressorCategory = new Guid(0x33d9a760, 0x90c8, 0x11d0, 0xbd, 0x43, 0x00, + 0xa0, 0xc9, 0x11, 0xce, 0x86); + + /// + /// CLSID_AudioCompressorCategory, audio compressor category + /// + public static readonly Guid AudioCompressorCategory = new Guid(0x33d9a761, 0x90c8, 0x11d0, 0xbd, 0x43, 0x00, + 0xa0, 0xc9, 0x11, 0xce, 0x86); + + /// + /// CLSID_LegacyAmFilterCategory, legacy filters + /// + public static readonly Guid LegacyAmFilterCategory = new Guid(0x083863F1, 0x70DE, 0x11d0, 0xBD, 0x40, 0x00, 0xA0, + 0xC9, 0x11, 0xCE, 0x86); + + /// + /// CLSID_AudioRendererCategory, Audio renderer category + /// + public static readonly Guid AudioRendererCategory = new Guid(0xe0f158e1, 0xcb04, 0x11d0, 0xbd, 0x4e, 0x00, 0xa0, + 0xc9, 0x11, 0xce, 0x86); + + /// + /// KSCATEGORY_BDA_RECEIVER_COMPONENT, BDA Receiver Components category + /// + public static readonly Guid BDAReceiverComponentsCategory = new Guid(0xFD0A5AF4, 0xB41D, 0x11d2, 0x9c, 0x95, + 0x00, 0xc0, 0x4f, 0x79, 0x71, 0xe0); + + /// + /// KSCATEGORY_BDA_NETWORK_TUNER, BDA Source Filters category + /// + public static readonly Guid BDASourceFiltersCategory = new Guid(0x71985f48, 0x1ca1, 0x11d3, 0x9c, 0xc8, 0x00, + 0xc0, 0x4f, 0x79, 0x71, 0xe0); + + /// + /// KSCATEGORY_BDA_IP_SINK, BDA Rendering Filters category + /// + public static readonly Guid BDARenderingFiltersCategory = new Guid(0x71985f4a, 0x1ca1, 0x11d3, 0x9c, 0xc8, 0x00, + 0xc0, 0x4f, 0x79, 0x71, 0xe0); + + /// + /// KSCATEGORY_BDA_NETWORK_PROVIDER, BDA Network Providers category + /// + public static readonly Guid BDANetworkProvidersCategory = new Guid(0x71985f4b, 0x1ca1, 0x11d3, 0x9c, 0xc8, 0x00, + 0xc0, 0x4f, 0x79, 0x71, 0xe0); + + /// + /// KSCATEGORY_BDA_TRANSPORT_INFORMATION, BDA Transport Information Renderers category + /// + public static readonly Guid BDATransportInformationRenderersCategory = new Guid(0xa2e3074f, 0x6c3d, 0x11d3, 0xb6, + 0x53, 0x00, 0xc0, 0x4f, 0x79, + 0x49, 0x8e); + + /// + /// CLSID_MidiRendererCategory + /// + public static readonly Guid MidiRendererCategory = new Guid(0x4EfE2452, 0x168A, 0x11d1, 0xBC, 0x76, 0x00, 0xc0, + 0x4F, 0xB9, 0x45, 0x3B); + + /// + /// CLSID_TransmitCategory External Renderers Category + /// + public static readonly Guid TransmitCategory = new Guid(0xcc7bfb41, 0xf175, 0x11d1, 0xa3, 0x92, 0x00, 0xe0, 0x29, + 0x1f, 0x39, 0x59); + + /// + /// CLSID_DeviceControlCategory Device Control Filters + /// + public static readonly Guid DeviceControlCategory = new Guid(0xcc7bfb46, 0xf175, 0x11d1, 0xa3, 0x92, 0x00, 0xe0, + 0x29, 0x1f, 0x39, 0x59); + + /// + /// CLSID_VideoEffects1Category + /// + public static readonly Guid VideoEffects1Category = new Guid(0xcc7bfb42, 0xf175, 0x11d1, 0xa3, 0x92, 0x00, 0xe0, + 0x29, 0x1f, 0x39, 0x59); + + /// + /// CLSID_VideoEffects2Category + /// + public static readonly Guid VideoEffects2Category = new Guid(0xcc7bfb43, 0xf175, 0x11d1, 0xa3, 0x92, 0x00, 0xe0, + 0x29, 0x1f, 0x39, 0x59); + + /// + /// CLSID_AudioEffects1Category + /// + public static readonly Guid AudioEffects1Category = new Guid(0xcc7bfb44, 0xf175, 0x11d1, 0xa3, 0x92, 0x00, 0xe0, + 0x29, 0x1f, 0x39, 0x59); + + /// + /// CLSID_AudioEffects2Category + /// + public static readonly Guid AudioEffects2Category = new Guid(0xcc7bfb45, 0xf175, 0x11d1, 0xa3, 0x92, 0x00, 0xe0, + 0x29, 0x1f, 0x39, 0x59); + + /// + /// KSCATEGORY_DATADECOMPRESSOR & CLSID_DVDHWDecodersCategory + /// + public static readonly Guid KSDataDecompressor = new Guid(0x2721AE20, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, + 0x04, 0xC1, 0x00, 0x00); + + /// + /// KSCATEGORY_COMMUNICATIONSTRANSFORM + /// + public static readonly Guid KSCommunicationsTransform = new Guid(0xCF1DDA2C, 0x9743, 0x11D0, 0xA3, 0xEE, 0x00, + 0xA0, 0xC9, 0x22, 0x31, 0x96); + + /// + /// KSCATEGORY_DATATRANSFORM + /// + public static readonly Guid KSDataTransform = new Guid(0x2EB07EA0, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, + 0xC1, 0x00, 0x00); + + /// + /// KSCATEGORY_INTERFACETRANSFORM + /// + public static readonly Guid KSInterfaceTransform = new Guid(0xCF1DDA2D, 0x9743, 0x11D0, 0xA3, 0xEE, 0x00, 0xA0, + 0xC9, 0x22, 0x31, 0x96); + + /// + /// KSCATEGORY_MIXER + /// + public static readonly Guid KSMixer = new Guid(0xAD809C00, 0x7B88, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, + 0x00, 0x00); + + /// + /// KSCATEGORY_AUDIO_DEVICE + /// + public static readonly Guid KSAudioDevice = new Guid(0xFBF6F530, 0x07B9, 0x11D2, 0xA7, 0x1E, 0x00, 0x00, 0xF8, + 0x00, 0x47, 0x88); + + /// + /// CLSID_ActiveMovieCategories + /// + public static readonly Guid ActiveMovieCategories = new Guid(0xda4e3da0, 0xd07d, 0x11d0, 0xbd, 0x50, 0x00, 0xa0, + 0xc9, 0x11, 0xce, 0x86); + + /// + /// AM_KSCATEGORY_CAPTURE + /// + public static readonly Guid AMKSCapture = new Guid(0x65E8773D, 0x8F56, 0x11D0, 0xA3, 0xB9, 0x00, 0xA0, 0xC9, + 0x22, 0x31, 0x96); + + /// + /// AM_KSCATEGORY_RENDER + /// + public static readonly Guid AMKSRender = new Guid(0x65E8773E, 0x8F56, 0x11D0, 0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, + 0x31, 0x96); + + /// + /// AM_KSCATEGORY_DATACOMPRESSOR + /// + public static readonly Guid AMKSDataCompressor = new Guid(0x1E84C900, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, + 0x04, 0xC1, 0x00, 0x00); + + /// + /// AM_KSCATEGORY_AUDIO + /// + public static readonly Guid AMKSAudio = new Guid(0x6994AD04, 0x93EF, 0x11D0, 0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, + 0x31, 0x96); + + /// + /// AM_KSCATEGORY_VIDEO + /// + public static readonly Guid AMKSVideo = new Guid(0x6994AD05, 0x93EF, 0x11D0, 0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, + 0x31, 0x96); + + /// + /// AM_KSCATEGORY_TVTUNER + /// + public static readonly Guid AMKSTVTuner = new Guid(0xa799a800, 0xa46d, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0x24, + 0x01, 0xdc, 0xd4); + + /// + /// AM_KSCATEGORY_CROSSBAR + /// + public static readonly Guid AMKSCrossbar = new Guid(0xa799a801, 0xa46d, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0x24, + 0x01, 0xdc, 0xd4); + + /// + /// AM_KSCATEGORY_TVAUDIO + /// + public static readonly Guid AMKSTVAudio = new Guid(0xa799a802, 0xa46d, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0x24, + 0x01, 0xdc, 0xd4); + + /// + /// AM_KSCATEGORY_VBICODEC + /// + public static readonly Guid AMKSVBICodec = new Guid(0x07dad660, 0x22f1, 0x11d1, 0xa9, 0xf4, 0x00, 0xc0, 0x4f, + 0xbb, 0xde, 0x8f); + + /// + /// AM_KSCATEGORY_SPLITTER + /// + public static readonly Guid AMKSSplitter = new Guid(0x0A4252A0, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, + 0xC1, 0x00, 0x00); + + /// + /// Not defined + /// + public static readonly Guid WDMStreamingEncoderDevices = new Guid(0x19689BF6, 0xC384, 0x48FD, 0xAD, 0x51, 0x90, + 0xE5, 0x8C, 0x79, 0xF7, 0x0B); + + /// + /// Not defined + /// + public static readonly Guid WDMStreamingMultiplexerDevices = new Guid(0x7A5DE1D3, 0x01A1, 0x452C, 0xB4, 0x81, + 0x4F, 0xA2, 0xB9, 0x62, 0x71, 0xE8); + + /// + /// Not defined + /// + public static readonly Guid LTMMVideoProcessors = new Guid(0xE526D606, 0x22E7, 0x494C, 0xB8, 0x1E, 0xAC, 0x0A, + 0x94, 0xBF, 0xE6, 0x03); + } + + public static class VMRClsId + { + /// + /// CLSID_AllocPresenter + /// + public static readonly Guid AllocPresenter = new Guid(0x99d54f63, 0x1a69, 0x41ae, 0xaa, 0x4d, 0xc9, 0x76, 0xeb, + 0x3f, 0x07, 0x13); + + /// + /// CLSID_AllocPresenterDDXclMode + /// + public static readonly Guid AllocPresenterDDXclMode = new Guid(0x4444ac9e, 0x242e, 0x471b, 0xa3, 0xc7, 0x45, + 0xdc, 0xd4, 0x63, 0x52, 0xbc); + } + + public static class TVEClsId + { + /// + /// CLSID_DShowTVEFilter + /// + public static readonly Guid DShowTVEFilter = new Guid(0x05500280, 0xFAA5, 0x4DF9, 0x82, 0x46, 0xBF, 0xC2, 0x3A, + 0xC5, 0xCE, 0xA8); + + /// + /// CLSID_TVEFilterTuneProperties + /// + public static readonly Guid TVEFilterTuneProperties = new Guid(0x05500281, 0xFAA5, 0x4DF9, 0x82, 0x46, 0xBF, + 0xC2, 0x3A, 0xC5, 0xCE, 0xA8); + + /// + /// CLSID_TVEFilterCCProperties + /// + public static readonly Guid TVEFilterCCProperties = new Guid(0x05500282, 0xFAA5, 0x4DF9, 0x82, 0x46, 0xBF, 0xC2, + 0x3A, 0xC5, 0xCE, 0xA8); + + /// + /// CLSID_TVEFilterStatsProperties + /// + public static readonly Guid TVEFilterStatsProperties = new Guid(0x05500283, 0xFAA5, 0x4DF9, 0x82, 0x46, 0xBF, + 0xC2, 0x3A, 0xC5, 0xCE, 0xA8); + } + + public static class ENCAPIClsId + { + /// + /// CLSID_IVideoEncoderProxy + /// + public static readonly Guid IVideoEncoderProxy = new Guid(0xb43c4eec, 0x8c32, 0x4791, 0x91, 0x02, 0x50, 0x8a, + 0xda, 0x5e, 0xe8, 0xe7); + + /// + /// CLSID_ICodecAPIProxy + /// + public static readonly Guid ICodecAPIProxy = new Guid(0x7ff0997a, 0x1999, 0x4286, 0xa7, 0x3c, 0x62, 0x2b, 0x88, + 0x14, 0xe7, 0xeb); + + /// + /// CLSID_IVideoEncoderCodecAPIProxy + /// + public static readonly Guid IVideoEncoderCodecAPIProxy = new Guid(0xb05dabd9, 0x56e5, 0x4fdc, 0xaf, 0xa4, 0x8a, + 0x47, 0xe9, 0x1f, 0x1c, 0x9c); + } + + public static class MediaType { public static readonly Guid Null = Guid.Empty; - /// MEDIATYPE_Video 'vids' - public static readonly Guid Video = new Guid(0x73646976, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIATYPE_Interleaved 'iavs' - public static readonly Guid Interleaved = new Guid(0x73766169, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIATYPE_Audio 'auds' - public static readonly Guid Audio = new Guid(0x73647561, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIATYPE_Text 'txts' - public static readonly Guid Texts = new Guid(0x73747874, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIATYPE_Stream - public static readonly Guid Stream = new Guid(0xe436eb83, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIATYPE_VBI - public static readonly Guid VBI = new Guid(0xf72a76e1, 0xeb0a, 0x11d0, 0xac, 0xe4, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba); - - /// MEDIATYPE_Midi - public static readonly Guid Midi = new Guid(0x7364696D, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIATYPE_File - public static readonly Guid File = new Guid(0x656c6966, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIATYPE_ScriptCommand - public static readonly Guid ScriptCommand = new Guid(0x73636d64, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIATYPE_AUXLine21Data - public static readonly Guid AuxLine21Data = new Guid(0x670aea80, 0x3a82, 0x11d0, 0xb7, 0x9b, 0x00, 0xaa, 0x00, 0x37, 0x67, 0xa7); - - /// MEDIATYPE_Timecode - public static readonly Guid Timecode = new Guid(0x0482dee3, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65); - - /// MEDIATYPE_LMRT - public static readonly Guid LMRT = new Guid(0x74726c6d, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIATYPE_URL_STREAM - public static readonly Guid URLStream = new Guid(0x736c7275, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIATYPE_AnalogVideo - public static readonly Guid AnalogVideo = new Guid(0x0482dde1, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65); - - /// MEDIATYPE_AnalogAudio - public static readonly Guid AnalogAudio = new Guid(0x0482dee1, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65); - - /// MEDIATYPE_MPEG2_SECTIONS - public static readonly Guid Mpeg2Sections = new Guid(0x455f176c, 0x4b06, 0x47ce, 0x9a, 0xef, 0x8c, 0xae, 0xf7, 0x3d, 0xf7, 0xb5); - - /// MEDIATYPE_DTVCCData - public static readonly Guid DTVCCData = new Guid(0xfb77e152, 0x53b2, 0x499c, 0xb4, 0x6b, 0x50, 0x9f, 0xc3, 0x3e, 0xdf, 0xd7); - - /// MEDIATYPE_MSTVCaption - public static readonly Guid MSTVCaption = new Guid(0xB88B8A89, 0xB049, 0x4C80, 0xAD, 0xCF, 0x58, 0x98, 0x98, 0x5E, 0x22, 0xC1); - - /// MEDIATYPE_AUXTeletextPage - public static readonly Guid AUXTeletextPage = new Guid(0x11264acb, 0x37de, 0x4eba, 0x8c, 0x35, 0x7f, 0x4, 0xa1, 0xa6, 0x83, 0x32); - - /// MEDIATYPE_CC_CONTAINER - public static readonly Guid CC_Container = new Guid(0xaeb312e9, 0x3357, 0x43ca, 0xb7, 0x1, 0x97, 0xec, 0x19, 0x8e, 0x2b, 0x62); - - } - - static public class MediaSubType + /// + /// MEDIATYPE_Video 'vids' + /// + public static readonly Guid Video = new Guid(0x73646976, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, + 0x9b, 0x71); + + /// + /// MEDIATYPE_Interleaved 'iavs' + /// + public static readonly Guid Interleaved = new Guid(0x73766169, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, + 0x38, 0x9b, 0x71); + + /// + /// MEDIATYPE_Audio 'auds' + /// + public static readonly Guid Audio = new Guid(0x73647561, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, + 0x9b, 0x71); + + /// + /// MEDIATYPE_Text 'txts' + /// + public static readonly Guid Texts = new Guid(0x73747874, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, + 0x9b, 0x71); + + /// + /// MEDIATYPE_Stream + /// + public static readonly Guid Stream = new Guid(0xe436eb83, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, + 0xa7, 0x70); + + /// + /// MEDIATYPE_VBI + /// + public static readonly Guid VBI = new Guid(0xf72a76e1, 0xeb0a, 0x11d0, 0xac, 0xe4, 0x00, 0x00, 0xc0, 0xcc, 0x16, + 0xba); + + /// + /// MEDIATYPE_Midi + /// + public static readonly Guid Midi = new Guid(0x7364696D, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIATYPE_File + /// + public static readonly Guid File = new Guid(0x656c6966, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIATYPE_ScriptCommand + /// + public static readonly Guid ScriptCommand = new Guid(0x73636d64, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, + 0x38, 0x9b, 0x71); + + /// + /// MEDIATYPE_AUXLine21Data + /// + public static readonly Guid AuxLine21Data = new Guid(0x670aea80, 0x3a82, 0x11d0, 0xb7, 0x9b, 0x00, 0xaa, 0x00, + 0x37, 0x67, 0xa7); + + /// + /// MEDIATYPE_Timecode + /// + public static readonly Guid Timecode = new Guid(0x0482dee3, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, + 0xcb, 0x65); + + /// + /// MEDIATYPE_LMRT + /// + public static readonly Guid LMRT = new Guid(0x74726c6d, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIATYPE_URL_STREAM + /// + public static readonly Guid URLStream = new Guid(0x736c7275, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, + 0x9b, 0x71); + + /// + /// MEDIATYPE_AnalogVideo + /// + public static readonly Guid AnalogVideo = new Guid(0x0482dde1, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, + 0x6e, 0xcb, 0x65); + + /// + /// MEDIATYPE_AnalogAudio + /// + public static readonly Guid AnalogAudio = new Guid(0x0482dee1, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, + 0x6e, 0xcb, 0x65); + + /// + /// MEDIATYPE_MPEG2_SECTIONS + /// + public static readonly Guid Mpeg2Sections = new Guid(0x455f176c, 0x4b06, 0x47ce, 0x9a, 0xef, 0x8c, 0xae, 0xf7, + 0x3d, 0xf7, 0xb5); + + /// + /// MEDIATYPE_DTVCCData + /// + public static readonly Guid DTVCCData = new Guid(0xfb77e152, 0x53b2, 0x499c, 0xb4, 0x6b, 0x50, 0x9f, 0xc3, 0x3e, + 0xdf, 0xd7); + + /// + /// MEDIATYPE_MSTVCaption + /// + public static readonly Guid MSTVCaption = new Guid(0xB88B8A89, 0xB049, 0x4C80, 0xAD, 0xCF, 0x58, 0x98, 0x98, + 0x5E, 0x22, 0xC1); + + /// + /// MEDIATYPE_AUXTeletextPage + /// + public static readonly Guid AUXTeletextPage = new Guid(0x11264acb, 0x37de, 0x4eba, 0x8c, 0x35, 0x7f, 0x4, 0xa1, + 0xa6, 0x83, 0x32); + + /// + /// MEDIATYPE_CC_CONTAINER + /// + public static readonly Guid CC_Container = new Guid(0xaeb312e9, 0x3357, 0x43ca, 0xb7, 0x1, 0x97, 0xec, 0x19, + 0x8e, 0x2b, 0x62); + } + + public static class MediaSubType { public static readonly Guid Null = Guid.Empty; - /// MEDIASUBTYPE_CLPL - public static readonly Guid CLPL = new Guid(0x4C504C43, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_YUYV - public static readonly Guid YUYV = new Guid(0x56595559, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_IYUV - public static readonly Guid IYUV = new Guid(0x56555949, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_YVU9 - public static readonly Guid YVU9 = new Guid(0x39555659, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_Y411 - public static readonly Guid Y411 = new Guid(0x31313459, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_Y41P - public static readonly Guid Y41P = new Guid(0x50313459, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_YUY2 - public static readonly Guid YUY2 = new Guid(0x32595559, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_YVYU - public static readonly Guid YVYU = new Guid(0x55595659, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_UYVY - public static readonly Guid UYVY = new Guid(0x59565955, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_Y211 - public static readonly Guid Y211 = new Guid(0x31313259, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_CLJR - public static readonly Guid CLJR = new Guid(0x524a4c43, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_IF09 - public static readonly Guid IF09 = new Guid(0x39304649, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_CPLA - public static readonly Guid CPLA = new Guid(0x414c5043, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_MJPG - public static readonly Guid MJPG = new Guid(0x47504A4D, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_TVMJ - public static readonly Guid TVMJ = new Guid(0x4A4D5654, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_WAKE - public static readonly Guid WAKE = new Guid(0x454B4157, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_CFCC - public static readonly Guid CFCC = new Guid(0x43434643, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_IJPG - public static readonly Guid IJPG = new Guid(0x47504A49, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_Plum - public static readonly Guid PLUM = new Guid(0x6D756C50, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_DVCS - public static readonly Guid DVCS = new Guid(0x53435644, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_DVSD - public static readonly Guid DVSD = new Guid(0x44535644, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_MDVF - public static readonly Guid MDVF = new Guid(0x4656444D, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_RGB1 - public static readonly Guid RGB1 = new Guid(0xe436eb78, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIASUBTYPE_RGB4 - public static readonly Guid RGB4 = new Guid(0xe436eb79, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIASUBTYPE_RGB8 - public static readonly Guid RGB8 = new Guid(0xe436eb7a, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIASUBTYPE_RGB565 - public static readonly Guid RGB565 = new Guid(0xe436eb7b, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIASUBTYPE_RGB555 - public static readonly Guid RGB555 = new Guid(0xe436eb7c, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIASUBTYPE_RGB24 - public static readonly Guid RGB24 = new Guid(0xe436eb7d, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIASUBTYPE_RGB32 - public static readonly Guid RGB32 = new Guid(0xe436eb7e, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIASUBTYPE_ARGB1555 - public static readonly Guid ARGB1555 = new Guid(0x297c55af, 0xe209, 0x4cb3, 0xb7, 0x57, 0xc7, 0x6d, 0x6b, 0x9c, 0x88, 0xa8); - - /// MEDIASUBTYPE_ARGB4444 - public static readonly Guid ARGB4444 = new Guid(0x6e6415e6, 0x5c24, 0x425f, 0x93, 0xcd, 0x80, 0x10, 0x2b, 0x3d, 0x1c, 0xca); - - /// MEDIASUBTYPE_ARGB32 - public static readonly Guid ARGB32 = new Guid(0x773c9ac0, 0x3274, 0x11d0, 0xb7, 0x24, 0x00, 0xaa, 0x00, 0x6c, 0x1a, 0x01); - - /// MEDIASUBTYPE_A2R10G10B10 - public static readonly Guid A2R10G10B10 = new Guid(0x2f8bb76d, 0xb644, 0x4550, 0xac, 0xf3, 0xd3, 0x0c, 0xaa, 0x65, 0xd5, 0xc5); - - /// MEDIASUBTYPE_A2B10G10R10 - public static readonly Guid A2B10G10R10 = new Guid(0x576f7893, 0xbdf6, 0x48c4, 0x87, 0x5f, 0xae, 0x7b, 0x81, 0x83, 0x45, 0x67); - - /// MEDIASUBTYPE_AYUV - public static readonly Guid AYUV = new Guid(0x56555941, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_AI44 - public static readonly Guid AI44 = new Guid(0x34344941, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_IA44 - public static readonly Guid IA44 = new Guid(0x34344149, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_RGB32_D3D_DX7_RT - public static readonly Guid RGB32_D3D_DX7_RT = new Guid(0x32335237, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_RGB16_D3D_DX7_RT - public static readonly Guid RGB16_D3D_DX7_RT = new Guid(0x36315237, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_ARGB32_D3D_DX7_RT - public static readonly Guid ARGB32_D3D_DX7_RT = new Guid(0x38384137, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_ARGB4444_D3D_DX7_RT - public static readonly Guid ARGB4444_D3D_DX7_RT = new Guid(0x34344137, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_ARGB1555_D3D_DX7_RT - public static readonly Guid ARGB1555_D3D_DX7_RT = new Guid(0x35314137, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_RGB32_D3D_DX9_RT - public static readonly Guid RGB32_D3D_DX9_RT = new Guid(0x32335239, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_RGB16_D3D_DX9_RT - public static readonly Guid RGB16_D3D_DX9_RT = new Guid(0x36315239, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_ARGB32_D3D_DX9_RT - public static readonly Guid ARGB32_D3D_DX9_RT = new Guid(0x38384139, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_ARGB4444_D3D_DX9_RT - public static readonly Guid ARGB4444_D3D_DX9_RT = new Guid(0x34344139, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_ARGB1555_D3D_DX9_RT - public static readonly Guid ARGB1555_D3D_DX9_RT = new Guid(0x35314139, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_YV12 - public static readonly Guid YV12 = new Guid(0x32315659, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_NV12 - public static readonly Guid NV12 = new Guid(0x3231564E, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_IMC1 - public static readonly Guid IMC1 = new Guid(0x31434D49, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_IMC2 - public static readonly Guid IMC2 = new Guid(0x32434D49, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_IMC3 - public static readonly Guid IMC3 = new Guid(0x33434D49, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_IMC4 - public static readonly Guid IMC4 = new Guid(0x34434D49, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_S340 - public static readonly Guid S340 = new Guid(0x30343353, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_S342 - public static readonly Guid S342 = new Guid(0x32343353, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_Overlay - public static readonly Guid Overlay = new Guid(0xe436eb7f, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIASUBTYPE_MPEG1Packet - public static readonly Guid MPEG1Packet = new Guid(0xe436eb80, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIASUBTYPE_MPEG1Payload - public static readonly Guid MPEG1Payload = new Guid(0xe436eb81, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIASUBTYPE_MPEG1AudioPayload - public static readonly Guid MPEG1AudioPayload = new Guid(0x00000050, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71); - - /// MEDIATYPE_MPEG1SystemStream - public static readonly Guid MPEG1SystemStream = new Guid(0xe436eb82, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIASUBTYPE_MPEG1System - public static readonly Guid MPEG1System = new Guid(0xe436eb84, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIASUBTYPE_MPEG1VideoCD - public static readonly Guid MPEG1VideoCD = new Guid(0xe436eb85, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIASUBTYPE_MPEG1Video - public static readonly Guid MPEG1Video = new Guid(0xe436eb86, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIASUBTYPE_MPEG1Audio - public static readonly Guid MPEG1Audio = new Guid(0xe436eb87, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIASUBTYPE_Avi - public static readonly Guid Avi = new Guid(0xe436eb88, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIASUBTYPE_Asf - public static readonly Guid Asf = new Guid(0x3db80f90, 0x9412, 0x11d1, 0xad, 0xed, 0x00, 0x00, 0xf8, 0x75, 0x4b, 0x99); - - /// MEDIASUBTYPE_QTMovie - public static readonly Guid QTMovie = new Guid(0xe436eb89, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIASUBTYPE_QTRpza - public static readonly Guid QTRpza = new Guid(0x617a7072, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_QTSmc - public static readonly Guid QTSmc = new Guid(0x20636d73, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_QTRle - public static readonly Guid QTRle = new Guid(0x20656c72, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_QTJpeg - public static readonly Guid QTJpeg = new Guid(0x6765706a, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_PCMAudio_Obsolete - public static readonly Guid PCMAudio_Obsolete = new Guid(0xe436eb8a, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIASUBTYPE_PCM - public static readonly Guid PCM = new Guid(0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71); - - /// MEDIASUBTYPE_WAVE - public static readonly Guid WAVE = new Guid(0xe436eb8b, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIASUBTYPE_AU - public static readonly Guid AU = new Guid(0xe436eb8c, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIASUBTYPE_AIFF - public static readonly Guid AIFF = new Guid(0xe436eb8d, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIASUBTYPE_dvhd - public static readonly Guid dvhd = new Guid(0x64687664, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_dvsl - public static readonly Guid dvsl = new Guid(0x6c737664, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_dv25 - public static readonly Guid dv25 = new Guid(0x35327664, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_dv50 - public static readonly Guid dv50 = new Guid(0x30357664, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_dvh1 - public static readonly Guid dvh1 = new Guid(0x31687664, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_Line21_BytePair - public static readonly Guid Line21_BytePair = new Guid(0x6e8d4a22, 0x310c, 0x11d0, 0xb7, 0x9a, 0x00, 0xaa, 0x00, 0x37, 0x67, 0xa7); - - /// MEDIASUBTYPE_Line21_GOPPacket - public static readonly Guid Line21_GOPPacket = new Guid(0x6e8d4a23, 0x310c, 0x11d0, 0xb7, 0x9a, 0x00, 0xaa, 0x00, 0x37, 0x67, 0xa7); - - /// MEDIASUBTYPE_Line21_VBIRawData - public static readonly Guid Line21_VBIRawData = new Guid(0x6e8d4a24, 0x310c, 0x11d0, 0xb7, 0x9a, 0x00, 0xaa, 0x00, 0x37, 0x67, 0xa7); - - /// MEDIASUBTYPE_TELETEXT - public static readonly Guid TELETEXT = new Guid(0xf72a76e3, 0xeb0a, 0x11d0, 0xac, 0xe4, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba); - - /// MEDIASUBTYPE_WSS - public static readonly Guid WSS = new Guid(0x2791D576, 0x8E7A, 0x466F, 0x9E, 0x90, 0x5D, 0x3F, 0x30, 0x83, 0x73, 0x8B); - - /// MEDIASUBTYPE_VPS - public static readonly Guid VPS = new Guid(0xa1b3f620, 0x9792, 0x4d8d, 0x81, 0xa4, 0x86, 0xaf, 0x25, 0x77, 0x20, 0x90); - - /// MEDIASUBTYPE_DRM_Audio - public static readonly Guid DRM_Audio = new Guid(0x00000009, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_IEEE_FLOAT - public static readonly Guid IEEE_FLOAT = new Guid(0x00000003, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_DOLBY_AC3_SPDIF - public static readonly Guid DOLBY_AC3_SPDIF = new Guid(0x00000092, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_RAW_SPORT - public static readonly Guid RAW_SPORT = new Guid(0x00000240, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_SPDIF_TAG_241h - public static readonly Guid SPDIF_TAG_241h = new Guid(0x00000241, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_DssVideo - public static readonly Guid DssVideo = new Guid(0xa0af4f81, 0xe163, 0x11d0, 0xba, 0xd9, 0x00, 0x60, 0x97, 0x44, 0x11, 0x1a); - - /// MEDIASUBTYPE_DssAudio - public static readonly Guid DssAudio = new Guid(0xa0af4f82, 0xe163, 0x11d0, 0xba, 0xd9, 0x00, 0x60, 0x97, 0x44, 0x11, 0x1a); - - /// MEDIASUBTYPE_VPVideo - public static readonly Guid VPVideo = new Guid(0x5a9b6a40, 0x1a22, 0x11d1, 0xba, 0xd9, 0x00, 0x60, 0x97, 0x44, 0x11, 0x1a); - - /// MEDIASUBTYPE_VPVBI - public static readonly Guid VPVBI = new Guid(0x5a9b6a41, 0x1a22, 0x11d1, 0xba, 0xd9, 0x00, 0x60, 0x97, 0x44, 0x11, 0x1a); - - /// MEDIASUBTYPE_AnalogVideo_NTSC_M - public static readonly Guid AnalogVideo_NTSC_M = new Guid(0x0482dde2, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65); - - /// MEDIASUBTYPE_AnalogVideo_PAL_B - public static readonly Guid AnalogVideo_PAL_B = new Guid(0x0482dde5, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65); - - /// MEDIASUBTYPE_AnalogVideo_PAL_D - public static readonly Guid AnalogVideo_PAL_D = new Guid(0x0482dde6, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65); - - /// MEDIASUBTYPE_AnalogVideo_PAL_G - public static readonly Guid AnalogVideo_PAL_G = new Guid(0x0482dde7, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65); - - /// MEDIASUBTYPE_AnalogVideo_PAL_H - public static readonly Guid AnalogVideo_PAL_H = new Guid(0x0482dde8, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65); - - /// MEDIASUBTYPE_AnalogVideo_PAL_I - public static readonly Guid AnalogVideo_PAL_I = new Guid(0x0482dde9, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65); - - /// MEDIASUBTYPE_AnalogVideo_PAL_M - public static readonly Guid AnalogVideo_PAL_M = new Guid(0x0482ddea, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65); - - /// MEDIASUBTYPE_AnalogVideo_PAL_N - public static readonly Guid AnalogVideo_PAL_N = new Guid(0x0482ddeb, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65); - - /// MEDIASUBTYPE_AnalogVideo_PAL_N_COMBO - public static readonly Guid AnalogVideo_PAL_N_COMBO = new Guid(0x0482ddec, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65); - - /// MEDIASUBTYPE_AnalogVideo_SECAM_B - public static readonly Guid AnalogVideo_SECAM_B = new Guid(0x0482ddf0, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65); - - /// MEDIASUBTYPE_AnalogVideo_SECAM_D - public static readonly Guid AnalogVideo_SECAM_D = new Guid(0x0482ddf1, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65); - - /// MEDIASUBTYPE_AnalogVideo_SECAM_G - public static readonly Guid AnalogVideo_SECAM_G = new Guid(0x0482ddf2, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65); - - /// MEDIASUBTYPE_AnalogVideo_SECAM_H - public static readonly Guid AnalogVideo_SECAM_H = new Guid(0x0482ddf3, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65); - - /// MEDIASUBTYPE_AnalogVideo_SECAM_K - public static readonly Guid AnalogVideo_SECAM_K = new Guid(0x0482ddf4, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65); - - /// MEDIASUBTYPE_AnalogVideo_SECAM_K1 - public static readonly Guid AnalogVideo_SECAM_K1 = new Guid(0x0482ddf5, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65); - - /// MEDIASUBTYPE_AnalogVideo_SECAM_L - public static readonly Guid AnalogVideo_SECAM_L = new Guid(0x0482ddf6, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65); - - /// not in uuids.h - public static readonly Guid I420 = new Guid(0x30323449, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// WMMEDIASUBTYPE_VIDEOIMAGE - public static readonly Guid VideoImage = new Guid(0x1d4a45f2, 0xe5f6, 0x4b44, 0x83, 0x88, 0xf0, 0xae, 0x5c, 0x0e, 0x0c, 0x37); - - /// WMMEDIASUBTYPE_MPEG2_VIDEO - public static readonly Guid Mpeg2Video = new Guid(0xe06d8026, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea); - - /// WMMEDIASUBTYPE_WebStream - public static readonly Guid WebStream = new Guid(0x776257d4, 0xc627, 0x41cb, 0x8f, 0x81, 0x7a, 0xc7, 0xff, 0x1c, 0x40, 0xcc); - - /// MEDIASUBTYPE_MPEG2_AUDIO - public static readonly Guid Mpeg2Audio = new Guid(0xe06d802b, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea); - - /// MEDIASUBTYPE_DOLBY_AC3 - public static readonly Guid DolbyAC3 = new Guid(0xe06d802c, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea); - - /// MEDIASUBTYPE_DVB_SI - public static readonly Guid DvbSI = new Guid(0xe9dd31a3, 0x221d, 0x4adb, 0x85, 0x32, 0x9a, 0xf3, 0x09, 0xc1, 0xa4, 0x08); - - /// MEDIASUBTYPE_ATSC_SI - public static readonly Guid AtscSI = new Guid(0xb3c7397c, 0xd303, 0x414d, 0xb3, 0x3c, 0x4e, 0xd2, 0xc9, 0xd2, 0x97, 0x33); - - /// MEDIASUBTYPE_MPEG2DATA - public static readonly Guid Mpeg2Data = new Guid(0xc892e55b, 0x252d, 0x42b5, 0xa3, 0x16, 0xd9, 0x97, 0xe7, 0xa5, 0xd9, 0x95); - - /// MEDIASUBTYPE_MPEG2_PROGRAM - public static readonly Guid Mpeg2Program = new Guid(0xe06d8022, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea); - - /// MEDIASUBTYPE_MPEG2_TRANSPORT - public static readonly Guid Mpeg2Transport = new Guid(0xe06d8023, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea); - - /// MEDIASUBTYPE_MPEG2_TRANSPORT_STRIDE - public static readonly Guid Mpeg2TransportStride = new Guid(0x138aa9a4, 0x1ee2, 0x4c5b, 0x98, 0x8e, 0x19, 0xab, 0xfd, 0xbc, 0x8a, 0x11); - - /// MEDIASUBTYPE_None - public static readonly Guid None = new Guid(0xe436eb8e, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); - - /// MEDIASUBTYPE_H264 - public static readonly Guid H264 = new Guid(0x34363248, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_NV24 - public static readonly Guid NV24 = new Guid(0x3432564E, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_708_608Data - public static readonly Guid Data708_608 = new Guid(0xaf414bc, 0x4ed2, 0x445e, 0x98, 0x39, 0x8f, 0x9, 0x55, 0x68, 0xab, 0x3c); - - /// MEDIASUBTYPE_DtvCcData - public static readonly Guid DtvCcData = new Guid(0xF52ADDAA, 0x36F0, 0x43F5, 0x95, 0xEA, 0x6D, 0x86, 0x64, 0x84, 0x26, 0x2A); - - /// MEDIASUBTYPE_DVB_SUBTITLES - public static readonly Guid DVB_Subtitles = new Guid(0x34FFCBC3, 0xD5B3, 0x4171, 0x90, 0x02, 0xD4, 0xC6, 0x03, 0x01, 0x69, 0x7F); - - /// MEDIASUBTYPE_ISDB_CAPTIONS - public static readonly Guid ISDB_Captions = new Guid(0x059dd67d, 0x2e55, 0x4d41, 0x8d, 0x1b, 0x01, 0xf5, 0xe4, 0xf5, 0x06, 0x07); - - /// MEDIASUBTYPE_ISDB_SUPERIMPOSE - public static readonly Guid ISDB_Superimpose = new Guid(0x36dc6d28, 0xf1a6, 0x4216, 0x90, 0x48, 0x9c, 0xfc, 0xef, 0xeb, 0x5e, 0xba); - - /// MEDIASUBTYPE_NV11 - public static readonly Guid NV11 = new Guid(0x3131564E, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_P208 - public static readonly Guid P208 = new Guid(0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_P210 - public static readonly Guid P210 = new Guid(0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_P216 - public static readonly Guid P216 = new Guid(0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_P010 - public static readonly Guid P010 = new Guid(0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_P016 - public static readonly Guid P016 = new Guid(0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_Y210 - public static readonly Guid Y210 = new Guid(0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_Y216 - public static readonly Guid Y216 = new Guid(0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_P408 - public static readonly Guid P408 = new Guid(0x38303450, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - - /// MEDIASUBTYPE_CC_CONTAINER - public static readonly Guid CC_Container = new Guid(0x7ea626db, 0x54da, 0x437b, 0xbe, 0x9f, 0xf7, 0x30, 0x73, 0xad, 0xfa, 0x3c); - - /// MEDIASUBTYPE_VBI - public static readonly Guid VBI = new Guid(0x663da43c, 0x3e8, 0x4e9a, 0x9c, 0xd5, 0xbf, 0x11, 0xed, 0xd, 0xef, 0x76); - - /// MEDIASUBTYPE_XDS - public static readonly Guid XDS = new Guid(0x1ca73e3, 0xdce6, 0x4575, 0xaf, 0xe1, 0x2b, 0xf1, 0xc9, 0x2, 0xca, 0xf3); - - /// MEDIASUBTYPE_ETDTFilter_Tagged - public static readonly Guid ETDTFilter_Tagged = new Guid(0xC4C4C4D0, 0x0049, 0x4E2B, 0x98, 0xFB, 0x95, 0x37, 0xF6, 0xCE, 0x51, 0x6D); - - /// MEDIASUBTYPE_CPFilters_Processed - public static readonly Guid CPFilters_Processed = new Guid(0x46adbd28, 0x6fd0, 0x4796, 0x93, 0xb2, 0x15, 0x5c, 0x51, 0xdc, 0x4, 0x8d); - - } - - static public class FormatType + /// + /// MEDIASUBTYPE_CLPL + /// + public static readonly Guid CLPL = new Guid(0x4C504C43, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_YUYV + /// + public static readonly Guid YUYV = new Guid(0x56595559, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_IYUV + /// + public static readonly Guid IYUV = new Guid(0x56555949, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_YVU9 + /// + public static readonly Guid YVU9 = new Guid(0x39555659, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_Y411 + /// + public static readonly Guid Y411 = new Guid(0x31313459, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_Y41P + /// + public static readonly Guid Y41P = new Guid(0x50313459, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_YUY2 + /// + public static readonly Guid YUY2 = new Guid(0x32595559, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_YVYU + /// + public static readonly Guid YVYU = new Guid(0x55595659, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_UYVY + /// + public static readonly Guid UYVY = new Guid(0x59565955, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_Y211 + /// + public static readonly Guid Y211 = new Guid(0x31313259, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_CLJR + /// + public static readonly Guid CLJR = new Guid(0x524a4c43, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_IF09 + /// + public static readonly Guid IF09 = new Guid(0x39304649, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_CPLA + /// + public static readonly Guid CPLA = new Guid(0x414c5043, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_MJPG + /// + public static readonly Guid MJPG = new Guid(0x47504A4D, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_TVMJ + /// + public static readonly Guid TVMJ = new Guid(0x4A4D5654, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_WAKE + /// + public static readonly Guid WAKE = new Guid(0x454B4157, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_CFCC + /// + public static readonly Guid CFCC = new Guid(0x43434643, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_IJPG + /// + public static readonly Guid IJPG = new Guid(0x47504A49, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_Plum + /// + public static readonly Guid PLUM = new Guid(0x6D756C50, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_DVCS + /// + public static readonly Guid DVCS = new Guid(0x53435644, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_DVSD + /// + public static readonly Guid DVSD = new Guid(0x44535644, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_MDVF + /// + public static readonly Guid MDVF = new Guid(0x4656444D, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_RGB1 + /// + public static readonly Guid RGB1 = new Guid(0xe436eb78, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, + 0x70); + + /// + /// MEDIASUBTYPE_RGB4 + /// + public static readonly Guid RGB4 = new Guid(0xe436eb79, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, + 0x70); + + /// + /// MEDIASUBTYPE_RGB8 + /// + public static readonly Guid RGB8 = new Guid(0xe436eb7a, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, + 0x70); + + /// + /// MEDIASUBTYPE_RGB565 + /// + public static readonly Guid RGB565 = new Guid(0xe436eb7b, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, + 0xa7, 0x70); + + /// + /// MEDIASUBTYPE_RGB555 + /// + public static readonly Guid RGB555 = new Guid(0xe436eb7c, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, + 0xa7, 0x70); + + /// + /// MEDIASUBTYPE_RGB24 + /// + public static readonly Guid RGB24 = new Guid(0xe436eb7d, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, + 0xa7, 0x70); + + /// + /// MEDIASUBTYPE_RGB32 + /// + public static readonly Guid RGB32 = new Guid(0xe436eb7e, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, + 0xa7, 0x70); + + /// + /// MEDIASUBTYPE_ARGB1555 + /// + public static readonly Guid ARGB1555 = new Guid(0x297c55af, 0xe209, 0x4cb3, 0xb7, 0x57, 0xc7, 0x6d, 0x6b, 0x9c, + 0x88, 0xa8); + + /// + /// MEDIASUBTYPE_ARGB4444 + /// + public static readonly Guid ARGB4444 = new Guid(0x6e6415e6, 0x5c24, 0x425f, 0x93, 0xcd, 0x80, 0x10, 0x2b, 0x3d, + 0x1c, 0xca); + + /// + /// MEDIASUBTYPE_ARGB32 + /// + public static readonly Guid ARGB32 = new Guid(0x773c9ac0, 0x3274, 0x11d0, 0xb7, 0x24, 0x00, 0xaa, 0x00, 0x6c, + 0x1a, 0x01); + + /// + /// MEDIASUBTYPE_A2R10G10B10 + /// + public static readonly Guid A2R10G10B10 = new Guid(0x2f8bb76d, 0xb644, 0x4550, 0xac, 0xf3, 0xd3, 0x0c, 0xaa, + 0x65, 0xd5, 0xc5); + + /// + /// MEDIASUBTYPE_A2B10G10R10 + /// + public static readonly Guid A2B10G10R10 = new Guid(0x576f7893, 0xbdf6, 0x48c4, 0x87, 0x5f, 0xae, 0x7b, 0x81, + 0x83, 0x45, 0x67); + + /// + /// MEDIASUBTYPE_AYUV + /// + public static readonly Guid AYUV = new Guid(0x56555941, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_AI44 + /// + public static readonly Guid AI44 = new Guid(0x34344941, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_IA44 + /// + public static readonly Guid IA44 = new Guid(0x34344149, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_RGB32_D3D_DX7_RT + /// + public static readonly Guid RGB32_D3D_DX7_RT = new Guid(0x32335237, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, + 0x38, 0x9b, 0x71); + + /// + /// MEDIASUBTYPE_RGB16_D3D_DX7_RT + /// + public static readonly Guid RGB16_D3D_DX7_RT = new Guid(0x36315237, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, + 0x38, 0x9b, 0x71); + + /// + /// MEDIASUBTYPE_ARGB32_D3D_DX7_RT + /// + public static readonly Guid ARGB32_D3D_DX7_RT = new Guid(0x38384137, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, + 0x00, 0x38, 0x9b, 0x71); + + /// + /// MEDIASUBTYPE_ARGB4444_D3D_DX7_RT + /// + public static readonly Guid ARGB4444_D3D_DX7_RT = new Guid(0x34344137, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, + 0x00, 0x38, 0x9b, 0x71); + + /// + /// MEDIASUBTYPE_ARGB1555_D3D_DX7_RT + /// + public static readonly Guid ARGB1555_D3D_DX7_RT = new Guid(0x35314137, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, + 0x00, 0x38, 0x9b, 0x71); + + /// + /// MEDIASUBTYPE_RGB32_D3D_DX9_RT + /// + public static readonly Guid RGB32_D3D_DX9_RT = new Guid(0x32335239, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, + 0x38, 0x9b, 0x71); + + /// + /// MEDIASUBTYPE_RGB16_D3D_DX9_RT + /// + public static readonly Guid RGB16_D3D_DX9_RT = new Guid(0x36315239, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, + 0x38, 0x9b, 0x71); + + /// + /// MEDIASUBTYPE_ARGB32_D3D_DX9_RT + /// + public static readonly Guid ARGB32_D3D_DX9_RT = new Guid(0x38384139, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, + 0x00, 0x38, 0x9b, 0x71); + + /// + /// MEDIASUBTYPE_ARGB4444_D3D_DX9_RT + /// + public static readonly Guid ARGB4444_D3D_DX9_RT = new Guid(0x34344139, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, + 0x00, 0x38, 0x9b, 0x71); + + /// + /// MEDIASUBTYPE_ARGB1555_D3D_DX9_RT + /// + public static readonly Guid ARGB1555_D3D_DX9_RT = new Guid(0x35314139, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, + 0x00, 0x38, 0x9b, 0x71); + + /// + /// MEDIASUBTYPE_YV12 + /// + public static readonly Guid YV12 = new Guid(0x32315659, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_NV12 + /// + public static readonly Guid NV12 = new Guid(0x3231564E, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_IMC1 + /// + public static readonly Guid IMC1 = new Guid(0x31434D49, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_IMC2 + /// + public static readonly Guid IMC2 = new Guid(0x32434D49, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_IMC3 + /// + public static readonly Guid IMC3 = new Guid(0x33434D49, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_IMC4 + /// + public static readonly Guid IMC4 = new Guid(0x34434D49, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_S340 + /// + public static readonly Guid S340 = new Guid(0x30343353, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_S342 + /// + public static readonly Guid S342 = new Guid(0x32343353, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_Overlay + /// + public static readonly Guid Overlay = new Guid(0xe436eb7f, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, + 0xa7, 0x70); + + /// + /// MEDIASUBTYPE_MPEG1Packet + /// + public static readonly Guid MPEG1Packet = new Guid(0xe436eb80, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, + 0x0b, 0xa7, 0x70); + + /// + /// MEDIASUBTYPE_MPEG1Payload + /// + public static readonly Guid MPEG1Payload = new Guid(0xe436eb81, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, + 0x0b, 0xa7, 0x70); + + /// + /// MEDIASUBTYPE_MPEG1AudioPayload + /// + public static readonly Guid MPEG1AudioPayload = new Guid(0x00000050, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, + 0x00, 0x38, 0x9B, 0x71); + + /// + /// MEDIATYPE_MPEG1SystemStream + /// + public static readonly Guid MPEG1SystemStream = new Guid(0xe436eb82, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, + 0xaf, 0x0b, 0xa7, 0x70); + + /// + /// MEDIASUBTYPE_MPEG1System + /// + public static readonly Guid MPEG1System = new Guid(0xe436eb84, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, + 0x0b, 0xa7, 0x70); + + /// + /// MEDIASUBTYPE_MPEG1VideoCD + /// + public static readonly Guid MPEG1VideoCD = new Guid(0xe436eb85, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, + 0x0b, 0xa7, 0x70); + + /// + /// MEDIASUBTYPE_MPEG1Video + /// + public static readonly Guid MPEG1Video = new Guid(0xe436eb86, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, + 0xa7, 0x70); + + /// + /// MEDIASUBTYPE_MPEG1Audio + /// + public static readonly Guid MPEG1Audio = new Guid(0xe436eb87, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, + 0xa7, 0x70); + + /// + /// MEDIASUBTYPE_Avi + /// + public static readonly Guid Avi = new Guid(0xe436eb88, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, + 0x70); + + /// + /// MEDIASUBTYPE_Asf + /// + public static readonly Guid Asf = new Guid(0x3db80f90, 0x9412, 0x11d1, 0xad, 0xed, 0x00, 0x00, 0xf8, 0x75, 0x4b, + 0x99); + + /// + /// MEDIASUBTYPE_QTMovie + /// + public static readonly Guid QTMovie = new Guid(0xe436eb89, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, + 0xa7, 0x70); + + /// + /// MEDIASUBTYPE_QTRpza + /// + public static readonly Guid QTRpza = new Guid(0x617a7072, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, + 0x9b, 0x71); + + /// + /// MEDIASUBTYPE_QTSmc + /// + public static readonly Guid QTSmc = new Guid(0x20636d73, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, + 0x9b, 0x71); + + /// + /// MEDIASUBTYPE_QTRle + /// + public static readonly Guid QTRle = new Guid(0x20656c72, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, + 0x9b, 0x71); + + /// + /// MEDIASUBTYPE_QTJpeg + /// + public static readonly Guid QTJpeg = new Guid(0x6765706a, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, + 0x9b, 0x71); + + /// + /// MEDIASUBTYPE_PCMAudio_Obsolete + /// + public static readonly Guid PCMAudio_Obsolete = new Guid(0xe436eb8a, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, + 0xaf, 0x0b, 0xa7, 0x70); + + /// + /// MEDIASUBTYPE_PCM + /// + public static readonly Guid PCM = new Guid(0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, + 0x71); + + /// + /// MEDIASUBTYPE_WAVE + /// + public static readonly Guid WAVE = new Guid(0xe436eb8b, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, + 0x70); + + /// + /// MEDIASUBTYPE_AU + /// + public static readonly Guid AU = new Guid(0xe436eb8c, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, + 0x70); + + /// + /// MEDIASUBTYPE_AIFF + /// + public static readonly Guid AIFF = new Guid(0xe436eb8d, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, + 0x70); + + /// + /// MEDIASUBTYPE_dvhd + /// + public static readonly Guid dvhd = new Guid(0x64687664, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_dvsl + /// + public static readonly Guid dvsl = new Guid(0x6c737664, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_dv25 + /// + public static readonly Guid dv25 = new Guid(0x35327664, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_dv50 + /// + public static readonly Guid dv50 = new Guid(0x30357664, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_dvh1 + /// + public static readonly Guid dvh1 = new Guid(0x31687664, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_Line21_BytePair + /// + public static readonly Guid Line21_BytePair = new Guid(0x6e8d4a22, 0x310c, 0x11d0, 0xb7, 0x9a, 0x00, 0xaa, 0x00, + 0x37, 0x67, 0xa7); + + /// + /// MEDIASUBTYPE_Line21_GOPPacket + /// + public static readonly Guid Line21_GOPPacket = new Guid(0x6e8d4a23, 0x310c, 0x11d0, 0xb7, 0x9a, 0x00, 0xaa, 0x00, + 0x37, 0x67, 0xa7); + + /// + /// MEDIASUBTYPE_Line21_VBIRawData + /// + public static readonly Guid Line21_VBIRawData = new Guid(0x6e8d4a24, 0x310c, 0x11d0, 0xb7, 0x9a, 0x00, 0xaa, + 0x00, 0x37, 0x67, 0xa7); + + /// + /// MEDIASUBTYPE_TELETEXT + /// + public static readonly Guid TELETEXT = new Guid(0xf72a76e3, 0xeb0a, 0x11d0, 0xac, 0xe4, 0x00, 0x00, 0xc0, 0xcc, + 0x16, 0xba); + + /// + /// MEDIASUBTYPE_WSS + /// + public static readonly Guid WSS = new Guid(0x2791D576, 0x8E7A, 0x466F, 0x9E, 0x90, 0x5D, 0x3F, 0x30, 0x83, 0x73, + 0x8B); + + /// + /// MEDIASUBTYPE_VPS + /// + public static readonly Guid VPS = new Guid(0xa1b3f620, 0x9792, 0x4d8d, 0x81, 0xa4, 0x86, 0xaf, 0x25, 0x77, 0x20, + 0x90); + + /// + /// MEDIASUBTYPE_DRM_Audio + /// + public static readonly Guid DRM_Audio = new Guid(0x00000009, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, + 0x9b, 0x71); + + /// + /// MEDIASUBTYPE_IEEE_FLOAT + /// + public static readonly Guid IEEE_FLOAT = new Guid(0x00000003, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, + 0x9b, 0x71); + + /// + /// MEDIASUBTYPE_DOLBY_AC3_SPDIF + /// + public static readonly Guid DOLBY_AC3_SPDIF = new Guid(0x00000092, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, + 0x38, 0x9b, 0x71); + + /// + /// MEDIASUBTYPE_RAW_SPORT + /// + public static readonly Guid RAW_SPORT = new Guid(0x00000240, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, + 0x9b, 0x71); + + /// + /// MEDIASUBTYPE_SPDIF_TAG_241h + /// + public static readonly Guid SPDIF_TAG_241h = new Guid(0x00000241, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, + 0x38, 0x9b, 0x71); + + /// + /// MEDIASUBTYPE_DssVideo + /// + public static readonly Guid DssVideo = new Guid(0xa0af4f81, 0xe163, 0x11d0, 0xba, 0xd9, 0x00, 0x60, 0x97, 0x44, + 0x11, 0x1a); + + /// + /// MEDIASUBTYPE_DssAudio + /// + public static readonly Guid DssAudio = new Guid(0xa0af4f82, 0xe163, 0x11d0, 0xba, 0xd9, 0x00, 0x60, 0x97, 0x44, + 0x11, 0x1a); + + /// + /// MEDIASUBTYPE_VPVideo + /// + public static readonly Guid VPVideo = new Guid(0x5a9b6a40, 0x1a22, 0x11d1, 0xba, 0xd9, 0x00, 0x60, 0x97, 0x44, + 0x11, 0x1a); + + /// + /// MEDIASUBTYPE_VPVBI + /// + public static readonly Guid VPVBI = new Guid(0x5a9b6a41, 0x1a22, 0x11d1, 0xba, 0xd9, 0x00, 0x60, 0x97, 0x44, + 0x11, 0x1a); + + /// + /// MEDIASUBTYPE_AnalogVideo_NTSC_M + /// + public static readonly Guid AnalogVideo_NTSC_M = new Guid(0x0482dde2, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, + 0x00, 0x6e, 0xcb, 0x65); + + /// + /// MEDIASUBTYPE_AnalogVideo_PAL_B + /// + public static readonly Guid AnalogVideo_PAL_B = new Guid(0x0482dde5, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, + 0x00, 0x6e, 0xcb, 0x65); + + /// + /// MEDIASUBTYPE_AnalogVideo_PAL_D + /// + public static readonly Guid AnalogVideo_PAL_D = new Guid(0x0482dde6, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, + 0x00, 0x6e, 0xcb, 0x65); + + /// + /// MEDIASUBTYPE_AnalogVideo_PAL_G + /// + public static readonly Guid AnalogVideo_PAL_G = new Guid(0x0482dde7, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, + 0x00, 0x6e, 0xcb, 0x65); + + /// + /// MEDIASUBTYPE_AnalogVideo_PAL_H + /// + public static readonly Guid AnalogVideo_PAL_H = new Guid(0x0482dde8, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, + 0x00, 0x6e, 0xcb, 0x65); + + /// + /// MEDIASUBTYPE_AnalogVideo_PAL_I + /// + public static readonly Guid AnalogVideo_PAL_I = new Guid(0x0482dde9, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, + 0x00, 0x6e, 0xcb, 0x65); + + /// + /// MEDIASUBTYPE_AnalogVideo_PAL_M + /// + public static readonly Guid AnalogVideo_PAL_M = new Guid(0x0482ddea, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, + 0x00, 0x6e, 0xcb, 0x65); + + /// + /// MEDIASUBTYPE_AnalogVideo_PAL_N + /// + public static readonly Guid AnalogVideo_PAL_N = new Guid(0x0482ddeb, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, + 0x00, 0x6e, 0xcb, 0x65); + + /// + /// MEDIASUBTYPE_AnalogVideo_PAL_N_COMBO + /// + public static readonly Guid AnalogVideo_PAL_N_COMBO = new Guid(0x0482ddec, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, + 0xaa, 0x00, 0x6e, 0xcb, 0x65); + + /// + /// MEDIASUBTYPE_AnalogVideo_SECAM_B + /// + public static readonly Guid AnalogVideo_SECAM_B = new Guid(0x0482ddf0, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, + 0x00, 0x6e, 0xcb, 0x65); + + /// + /// MEDIASUBTYPE_AnalogVideo_SECAM_D + /// + public static readonly Guid AnalogVideo_SECAM_D = new Guid(0x0482ddf1, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, + 0x00, 0x6e, 0xcb, 0x65); + + /// + /// MEDIASUBTYPE_AnalogVideo_SECAM_G + /// + public static readonly Guid AnalogVideo_SECAM_G = new Guid(0x0482ddf2, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, + 0x00, 0x6e, 0xcb, 0x65); + + /// + /// MEDIASUBTYPE_AnalogVideo_SECAM_H + /// + public static readonly Guid AnalogVideo_SECAM_H = new Guid(0x0482ddf3, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, + 0x00, 0x6e, 0xcb, 0x65); + + /// + /// MEDIASUBTYPE_AnalogVideo_SECAM_K + /// + public static readonly Guid AnalogVideo_SECAM_K = new Guid(0x0482ddf4, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, + 0x00, 0x6e, 0xcb, 0x65); + + /// + /// MEDIASUBTYPE_AnalogVideo_SECAM_K1 + /// + public static readonly Guid AnalogVideo_SECAM_K1 = new Guid(0x0482ddf5, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, + 0x00, 0x6e, 0xcb, 0x65); + + /// + /// MEDIASUBTYPE_AnalogVideo_SECAM_L + /// + public static readonly Guid AnalogVideo_SECAM_L = new Guid(0x0482ddf6, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, + 0x00, 0x6e, 0xcb, 0x65); + + /// + /// not in uuids.h + /// + public static readonly Guid I420 = new Guid(0x30323449, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// WMMEDIASUBTYPE_VIDEOIMAGE + /// + public static readonly Guid VideoImage = new Guid(0x1d4a45f2, 0xe5f6, 0x4b44, 0x83, 0x88, 0xf0, 0xae, 0x5c, 0x0e, + 0x0c, 0x37); + + /// + /// WMMEDIASUBTYPE_MPEG2_VIDEO + /// + public static readonly Guid Mpeg2Video = new Guid(0xe06d8026, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, + 0xbb, 0xea); + + /// + /// WMMEDIASUBTYPE_WebStream + /// + public static readonly Guid WebStream = new Guid(0x776257d4, 0xc627, 0x41cb, 0x8f, 0x81, 0x7a, 0xc7, 0xff, 0x1c, + 0x40, 0xcc); + + /// + /// MEDIASUBTYPE_MPEG2_AUDIO + /// + public static readonly Guid Mpeg2Audio = new Guid(0xe06d802b, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, + 0xbb, 0xea); + + /// + /// MEDIASUBTYPE_DOLBY_AC3 + /// + public static readonly Guid DolbyAC3 = new Guid(0xe06d802c, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, + 0xbb, 0xea); + + /// + /// MEDIASUBTYPE_DVB_SI + /// + public static readonly Guid DvbSI = new Guid(0xe9dd31a3, 0x221d, 0x4adb, 0x85, 0x32, 0x9a, 0xf3, 0x09, 0xc1, + 0xa4, 0x08); + + /// + /// MEDIASUBTYPE_ATSC_SI + /// + public static readonly Guid AtscSI = new Guid(0xb3c7397c, 0xd303, 0x414d, 0xb3, 0x3c, 0x4e, 0xd2, 0xc9, 0xd2, + 0x97, 0x33); + + /// + /// MEDIASUBTYPE_MPEG2DATA + /// + public static readonly Guid Mpeg2Data = new Guid(0xc892e55b, 0x252d, 0x42b5, 0xa3, 0x16, 0xd9, 0x97, 0xe7, 0xa5, + 0xd9, 0x95); + + /// + /// MEDIASUBTYPE_MPEG2_PROGRAM + /// + public static readonly Guid Mpeg2Program = new Guid(0xe06d8022, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, + 0x6c, 0xbb, 0xea); + + /// + /// MEDIASUBTYPE_MPEG2_TRANSPORT + /// + public static readonly Guid Mpeg2Transport = new Guid(0xe06d8023, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, + 0x6c, 0xbb, 0xea); + + /// + /// MEDIASUBTYPE_MPEG2_TRANSPORT_STRIDE + /// + public static readonly Guid Mpeg2TransportStride = new Guid(0x138aa9a4, 0x1ee2, 0x4c5b, 0x98, 0x8e, 0x19, 0xab, + 0xfd, 0xbc, 0x8a, 0x11); + + /// + /// MEDIASUBTYPE_None + /// + public static readonly Guid None = new Guid(0xe436eb8e, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, + 0x70); + + /// + /// MEDIASUBTYPE_H264 + /// + public static readonly Guid H264 = new Guid(0x34363248, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_NV24 + /// + public static readonly Guid NV24 = new Guid(0x3432564E, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_708_608Data + /// + public static readonly Guid Data708_608 = new Guid(0xaf414bc, 0x4ed2, 0x445e, 0x98, 0x39, 0x8f, 0x9, 0x55, 0x68, + 0xab, 0x3c); + + /// + /// MEDIASUBTYPE_DtvCcData + /// + public static readonly Guid DtvCcData = new Guid(0xF52ADDAA, 0x36F0, 0x43F5, 0x95, 0xEA, 0x6D, 0x86, 0x64, 0x84, + 0x26, 0x2A); + + /// + /// MEDIASUBTYPE_DVB_SUBTITLES + /// + public static readonly Guid DVB_Subtitles = new Guid(0x34FFCBC3, 0xD5B3, 0x4171, 0x90, 0x02, 0xD4, 0xC6, 0x03, + 0x01, 0x69, 0x7F); + + /// + /// MEDIASUBTYPE_ISDB_CAPTIONS + /// + public static readonly Guid ISDB_Captions = new Guid(0x059dd67d, 0x2e55, 0x4d41, 0x8d, 0x1b, 0x01, 0xf5, 0xe4, + 0xf5, 0x06, 0x07); + + /// + /// MEDIASUBTYPE_ISDB_SUPERIMPOSE + /// + public static readonly Guid ISDB_Superimpose = new Guid(0x36dc6d28, 0xf1a6, 0x4216, 0x90, 0x48, 0x9c, 0xfc, 0xef, + 0xeb, 0x5e, 0xba); + + /// + /// MEDIASUBTYPE_NV11 + /// + public static readonly Guid NV11 = new Guid(0x3131564E, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_P208 + /// + public static readonly Guid P208 = new Guid(0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_P210 + /// + public static readonly Guid P210 = new Guid(0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_P216 + /// + public static readonly Guid P216 = new Guid(0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_P010 + /// + public static readonly Guid P010 = new Guid(0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_P016 + /// + public static readonly Guid P016 = new Guid(0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_Y210 + /// + public static readonly Guid Y210 = new Guid(0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_Y216 + /// + public static readonly Guid Y216 = new Guid(0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_P408 + /// + public static readonly Guid P408 = new Guid(0x38303450, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, + 0x71); + + /// + /// MEDIASUBTYPE_CC_CONTAINER + /// + public static readonly Guid CC_Container = new Guid(0x7ea626db, 0x54da, 0x437b, 0xbe, 0x9f, 0xf7, 0x30, 0x73, + 0xad, 0xfa, 0x3c); + + /// + /// MEDIASUBTYPE_VBI + /// + public static readonly Guid VBI = new Guid(0x663da43c, 0x3e8, 0x4e9a, 0x9c, 0xd5, 0xbf, 0x11, 0xed, 0xd, 0xef, + 0x76); + + /// + /// MEDIASUBTYPE_XDS + /// + public static readonly Guid XDS = new Guid(0x1ca73e3, 0xdce6, 0x4575, 0xaf, 0xe1, 0x2b, 0xf1, 0xc9, 0x2, 0xca, + 0xf3); + + /// + /// MEDIASUBTYPE_ETDTFilter_Tagged + /// + public static readonly Guid ETDTFilter_Tagged = new Guid(0xC4C4C4D0, 0x0049, 0x4E2B, 0x98, 0xFB, 0x95, 0x37, + 0xF6, 0xCE, 0x51, 0x6D); + + /// + /// MEDIASUBTYPE_CPFilters_Processed + /// + public static readonly Guid CPFilters_Processed = new Guid(0x46adbd28, 0x6fd0, 0x4796, 0x93, 0xb2, 0x15, 0x5c, + 0x51, 0xdc, 0x4, 0x8d); + } + + public static class FormatType { public static readonly Guid Null = Guid.Empty; - /// FORMAT_None - public static readonly Guid None = new Guid(0x0F6417D6, 0xc318, 0x11d0, 0xa4, 0x3f, 0x00, 0xa0, 0xc9, 0x22, 0x31, 0x96); - - /// FORMAT_VideoInfo - public static readonly Guid VideoInfo = new Guid(0x05589f80, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a); - - /// FORMAT_VideoInfo2 - public static readonly Guid VideoInfo2 = new Guid(0xf72a76A0, 0xeb0a, 0x11d0, 0xac, 0xe4, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba); - - /// FORMAT_WaveFormatEx - public static readonly Guid WaveEx = new Guid(0x05589f81, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a); - - /// FORMAT_MPEGVideo - public static readonly Guid MpegVideo = new Guid(0x05589f82, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a); - - /// FORMAT_MPEGStreams - public static readonly Guid MpegStreams = new Guid(0x05589f83, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a); - - /// FORMAT_DvInfo - public static readonly Guid DvInfo = new Guid(0x05589f84, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a); - - /// FORMAT_AnalogVideo - public static readonly Guid AnalogVideo = new Guid(0x0482dde0, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65); - - /// FORMAT_MPEG2Video - public static readonly Guid Mpeg2Video = new Guid(0xe06d80e3, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea); - - /// FORMAT_DolbyAC3 - public static readonly Guid DolbyAC3 = new Guid(0xe06d80e4, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea); - - /// FORMAT_MPEG2Audio - public static readonly Guid Mpeg2Audio = new Guid(0xe06d80e5, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea); - - /// FORMAT_525WSS - public static readonly Guid WSS525 = new Guid(0xc7ecf04d, 0x4582, 0x4869, 0x9a, 0xbb, 0xbf, 0xb5, 0x23, 0xb6, 0x2e, 0xdf); - - /// FORMATTYPE_ETDTFilter_Tagged - public static readonly Guid ETDTFilter_Tagged = new Guid(0xC4C4C4D1, 0x0049, 0x4E2B, 0x98, 0xFB, 0x95, 0x37, 0xF6, 0xCE, 0x51, 0x6D); - - /// FORMATTYPE_CPFilters_Processed - public static readonly Guid CPFilters_Processed = new Guid(0x6739b36f, 0x1d5f, 0x4ac2, 0x81, 0x92, 0x28, 0xbb, 0xe, 0x73, 0xd1, 0x6a); - } - - static public class DSAttrib - { - /// DSATTRIB_UDCRTag - public static readonly Guid UDCRTag = new Guid(0xEB7836CA, 0x14FF, 0x4919, 0xbc, 0xe7, 0x3a, 0xf1, 0x23, 0x19, 0xe5, 0x0c); - - /// DSATTRIB_PicSampleSeq - public static readonly Guid PicSampleSeq = new Guid(0x2f5bae02, 0x7b8f, 0x4f60, 0x82, 0xd6, 0xe4, 0xea, 0x2f, 0x1f, 0x4c, 0x99); - - /// DSATTRIB_OptionalVideoAttributes - public static readonly Guid OptionalVideoAttributes = new Guid(0x5A5F08CA, 0x55C2, 0x4033, 0x92, 0xAB, 0x55, 0xDB, 0x8F, 0x78, 0x12, 0x26); - - /// DSATTRIB_CC_CONTAINER_INFO - public static readonly Guid CC_ContainerInfo = new Guid(0xe7e050fb, 0xdd5d, 0x40dd, 0x99, 0x15, 0x35, 0xDC, 0xB8, 0x1B, 0xDC, 0x8a); - - /// DSATTRIB_TRANSPORT_PROPERTIES - public static readonly Guid TransportProperties = new Guid(0xb622f612, 0x47ad, 0x4671, 0xad, 0x6c, 0x5, 0xa9, 0x8e, 0x65, 0xde, 0x3a); - - /// DSATTRIB_PBDATAG_ATTRIBUTE - public static readonly Guid PBDATagAttribute = new Guid(0xe0b56679, 0x12b9, 0x43cc, 0xb7, 0xdf, 0x57, 0x8c, 0xaa, 0x5a, 0x7b, 0x63); - - /// DSATTRIB_CAPTURE_STREAMTIME - public static readonly Guid CaptureStreamtime = new Guid(0x0c1a5614, 0x30cd, 0x4f40, 0xbc, 0xbf, 0xd0, 0x3e, 0x52, 0x30, 0x62, 0x07); - - /// DSATTRIB_DSHOW_STREAM_DESC - public static readonly Guid DShowStreamDesc = new Guid(0x5fb5673b, 0xa2a, 0x4565, 0x82, 0x7b, 0x68, 0x53, 0xfd, 0x75, 0xe6, 0x11); - - /// DSATTRIB_SAMPLE_LIVE_STREAM_TIME - public static readonly Guid SampleLiveStreamtime = new Guid(0x892cd111, 0x72f3, 0x411d, 0x8b, 0x91, 0xa9, 0xe9, 0x12, 0x3a, 0xc2, 0x9a); - - /// DSATTRIB_WMDRMProtectionInfo - public static readonly Guid WMDRMProtectionInfo = new Guid(0x40749583, 0x6b9d, 0x4eec, 0xb4, 0x3c, 0x67, 0xa1, 0x80, 0x1e, 0x1a, 0x9b ); - - /// DSATTRIB_BadSampleInfo - public static readonly Guid BadSampleInfo = new Guid(0xe4846dda, 0x5838, 0x42b4, 0xb8, 0x97, 0x6f, 0x7e, 0x5f, 0xaa, 0x2f, 0x2f); - - } - - static public class PropSetID - { - /// AMPROPSETID_Pin - public static readonly Guid Pin = new Guid(0x9b00f101, 0x1567, 0x11d1, 0xb3, 0xf1, 0x00, 0xaa, 0x00, 0x37, 0x61, 0xc5); - - /// PROPSETID_VIDCAP_DROPPEDFRAMES - public static readonly Guid DroppedFrames = new Guid(0xC6E13344, 0x30AC, 0x11D0, 0xA1, 0x8C, 0x00, 0xA0, 0xC9, 0x11, 0x89, 0x56); - - /// STATIC_ENCAPIPARAM_BITRATE - public static readonly Guid ENCAPIPARAM_BitRate = new Guid(0x49cc4c43, 0xca83, 0x4ad4, 0xa9, 0xaf, 0xf3, 0x69, 0x6a, 0xf6, 0x66, 0xdf); - - /// STATIC_ENCAPIPARAM_PEAK_BITRATE - public static readonly Guid ENCAPIPARAM_PeakBitRate = new Guid(0x703f16a9, 0x3d48, 0x44a1, 0xb0, 0x77, 0x01, 0x8d, 0xff, 0x91, 0x5d, 0x19); - - /// STATIC_ENCAPIPARAM_BITRATE_MODE - public static readonly Guid ENCAPIPARAM_BitRateMode = new Guid(0xee5fb25c, 0xc713, 0x40d1, 0x9d, 0x58, 0xc0, 0xd7, 0x24, 0x1e, 0x25, 0x0f); - - /// ENCAPIPARAM_SAP_MODE - public static readonly Guid ENCAPIPARAM_SAP_MODE = new Guid(0xc0171db, 0xfefc, 0x4af7, 0x99, 0x91, 0xa5, 0x65, 0x7c, 0x19, 0x1c, 0xd1); - - /// CODECAPI_AVDecMmcssClass - public static readonly Guid CODECAPI_AVDecMmcssClass = new Guid(0xe0ad4828, 0xdf66, 0x4893, 0x9f, 0x33, 0x78, 0x8a, 0xa4, 0xec, 0x40, 0x82); - - /// STATIC_CODECAPI_CHANGELISTS - public static readonly Guid CODECAPI_ChangeLists = new Guid(0x62b12acf, 0xf6b0, 0x47d9, 0x94, 0x56, 0x96, 0xf2, 0x2c, 0x4e, 0x0b, 0x9d); - - /// STATIC_CODECAPI_VIDEO_ENCODER - public static readonly Guid CODECAPI_VideoEncoder = new Guid(0x7112e8e1, 0x3d03, 0x47ef, 0x8e, 0x60, 0x03, 0xf1, 0xcf, 0x53, 0x73, 0x01); - - /// STATIC_CODECAPI_AUDIO_ENCODER - public static readonly Guid CODECAPI_AudioEncoder = new Guid(0xb9d19a3e, 0xf897, 0x429c, 0xbc, 0x46, 0x81, 0x38, 0xb7, 0x27, 0x2b, 0x2d); - - /// STATIC_CODECAPI_SETALLDEFAULTS - public static readonly Guid CODECAPI_SetAllDefaults = new Guid(0x6c5e6a7c, 0xacf8, 0x4f55, 0xa9, 0x99, 0x1a, 0x62, 0x81, 0x09, 0x05, 0x1b); - - /// STATIC_CODECAPI_ALLSETTINGS - public static readonly Guid CODECAPI_AllSettings = new Guid(0x6a577e92, 0x83e1, 0x4113, 0xad, 0xc2, 0x4f, 0xce, 0xc3, 0x2f, 0x83, 0xa1); - - /// STATIC_CODECAPI_SUPPORTSEVENTS - public static readonly Guid CODECAPI_SupportsEvents = new Guid(0x0581af97, 0x7693, 0x4dbd, 0x9d, 0xca, 0x3f, 0x9e, 0xbd, 0x65, 0x85, 0xa1); - - /// STATIC_CODECAPI_CURRENTCHANGELIST - public static readonly Guid CODECAPI_CurrentChangeList = new Guid(0x1cb14e83, 0x7d72, 0x4657, 0x83, 0xfd, 0x47, 0xa2, 0xc5, 0xb9, 0xd1, 0x3d); - - } - - static public class PinCategory - { - /// PIN_CATEGORY_CAPTURE - public static readonly Guid Capture = new Guid(0xfb6c4281, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba); - - /// PIN_CATEGORY_PREVIEW - public static readonly Guid Preview = new Guid(0xfb6c4282, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba); - - /// PIN_CATEGORY_ANALOGVIDEOIN - public static readonly Guid AnalogVideoIn = new Guid(0xfb6c4283, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba); - - /// PIN_CATEGORY_VBI - public static readonly Guid VBI = new Guid(0xfb6c4284, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba); - - /// PIN_CATEGORY_VIDEOPORT - public static readonly Guid VideoPort = new Guid(0xfb6c4285, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba); - - /// PIN_CATEGORY_NABTS - public static readonly Guid NABTS = new Guid(0xfb6c4286, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba); - - /// PIN_CATEGORY_EDS - public static readonly Guid EDS = new Guid(0xfb6c4287, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba); - - /// PIN_CATEGORY_TELETEXT - public static readonly Guid TeleText = new Guid(0xfb6c4288, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba); - - /// PIN_CATEGORY_CC - public static readonly Guid CC = new Guid(0xfb6c4289, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba); - - /// PIN_CATEGORY_STILL - public static readonly Guid Still = new Guid(0xfb6c428a, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba); - - /// PIN_CATEGORY_TIMECODE - public static readonly Guid TimeCode = new Guid(0xfb6c428b, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba); - - /// PIN_CATEGORY_VIDEOPORT_VBI - public static readonly Guid VideoPortVBI = new Guid(0xfb6c428c, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba); - - } - - static public class FindDirection - { - /// LOOK_UPSTREAM_ONLY - public static readonly Guid UpstreamOnly = new Guid(0xac798be0, 0x98e3, 0x11d1, 0xb3, 0xf1, 0x00, 0xaa, 0x00, 0x37, 0x61, 0xc5); - - /// LOOK_DOWNSTREAM_ONLY - public static readonly Guid DownstreamOnly = new Guid(0xac798be1, 0x98e3, 0x11d1, 0xb3, 0xf1, 0x00, 0xaa, 0x00, 0x37, 0x61, 0xc5); - } - - static public class TimeFormat + /// + /// FORMAT_None + /// + public static readonly Guid None = new Guid(0x0F6417D6, 0xc318, 0x11d0, 0xa4, 0x3f, 0x00, 0xa0, 0xc9, 0x22, 0x31, + 0x96); + + /// + /// FORMAT_VideoInfo + /// + public static readonly Guid VideoInfo = new Guid(0x05589f80, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, + 0x59, 0x5a); + + /// + /// FORMAT_VideoInfo2 + /// + public static readonly Guid VideoInfo2 = new Guid(0xf72a76A0, 0xeb0a, 0x11d0, 0xac, 0xe4, 0x00, 0x00, 0xc0, 0xcc, + 0x16, 0xba); + + /// + /// FORMAT_WaveFormatEx + /// + public static readonly Guid WaveEx = new Guid(0x05589f81, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, + 0x59, 0x5a); + + /// + /// FORMAT_MPEGVideo + /// + public static readonly Guid MpegVideo = new Guid(0x05589f82, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, + 0x59, 0x5a); + + /// + /// FORMAT_MPEGStreams + /// + public static readonly Guid MpegStreams = new Guid(0x05589f83, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, + 0x55, 0x59, 0x5a); + + /// + /// FORMAT_DvInfo + /// + public static readonly Guid DvInfo = new Guid(0x05589f84, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, + 0x59, 0x5a); + + /// + /// FORMAT_AnalogVideo + /// + public static readonly Guid AnalogVideo = new Guid(0x0482dde0, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, + 0x6e, 0xcb, 0x65); + + /// + /// FORMAT_MPEG2Video + /// + public static readonly Guid Mpeg2Video = new Guid(0xe06d80e3, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, + 0xbb, 0xea); + + /// + /// FORMAT_DolbyAC3 + /// + public static readonly Guid DolbyAC3 = new Guid(0xe06d80e4, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, + 0xbb, 0xea); + + /// + /// FORMAT_MPEG2Audio + /// + public static readonly Guid Mpeg2Audio = new Guid(0xe06d80e5, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, + 0xbb, 0xea); + + /// + /// FORMAT_525WSS + /// + public static readonly Guid WSS525 = new Guid(0xc7ecf04d, 0x4582, 0x4869, 0x9a, 0xbb, 0xbf, 0xb5, 0x23, 0xb6, + 0x2e, 0xdf); + + /// + /// FORMATTYPE_ETDTFilter_Tagged + /// + public static readonly Guid ETDTFilter_Tagged = new Guid(0xC4C4C4D1, 0x0049, 0x4E2B, 0x98, 0xFB, 0x95, 0x37, + 0xF6, 0xCE, 0x51, 0x6D); + + /// + /// FORMATTYPE_CPFilters_Processed + /// + public static readonly Guid CPFilters_Processed = new Guid(0x6739b36f, 0x1d5f, 0x4ac2, 0x81, 0x92, 0x28, 0xbb, + 0xe, 0x73, 0xd1, 0x6a); + } + + public static class DSAttrib + { + /// + /// DSATTRIB_UDCRTag + /// + public static readonly Guid UDCRTag = new Guid(0xEB7836CA, 0x14FF, 0x4919, 0xbc, 0xe7, 0x3a, 0xf1, 0x23, 0x19, + 0xe5, 0x0c); + + /// + /// DSATTRIB_PicSampleSeq + /// + public static readonly Guid PicSampleSeq = new Guid(0x2f5bae02, 0x7b8f, 0x4f60, 0x82, 0xd6, 0xe4, 0xea, 0x2f, + 0x1f, 0x4c, 0x99); + + /// + /// DSATTRIB_OptionalVideoAttributes + /// + public static readonly Guid OptionalVideoAttributes = new Guid(0x5A5F08CA, 0x55C2, 0x4033, 0x92, 0xAB, 0x55, + 0xDB, 0x8F, 0x78, 0x12, 0x26); + + /// + /// DSATTRIB_CC_CONTAINER_INFO + /// + public static readonly Guid CC_ContainerInfo = new Guid(0xe7e050fb, 0xdd5d, 0x40dd, 0x99, 0x15, 0x35, 0xDC, 0xB8, + 0x1B, 0xDC, 0x8a); + + /// + /// DSATTRIB_TRANSPORT_PROPERTIES + /// + public static readonly Guid TransportProperties = new Guid(0xb622f612, 0x47ad, 0x4671, 0xad, 0x6c, 0x5, 0xa9, + 0x8e, 0x65, 0xde, 0x3a); + + /// + /// DSATTRIB_PBDATAG_ATTRIBUTE + /// + public static readonly Guid PBDATagAttribute = new Guid(0xe0b56679, 0x12b9, 0x43cc, 0xb7, 0xdf, 0x57, 0x8c, 0xaa, + 0x5a, 0x7b, 0x63); + + /// + /// DSATTRIB_CAPTURE_STREAMTIME + /// + public static readonly Guid CaptureStreamtime = new Guid(0x0c1a5614, 0x30cd, 0x4f40, 0xbc, 0xbf, 0xd0, 0x3e, + 0x52, 0x30, 0x62, 0x07); + + /// + /// DSATTRIB_DSHOW_STREAM_DESC + /// + public static readonly Guid DShowStreamDesc = new Guid(0x5fb5673b, 0xa2a, 0x4565, 0x82, 0x7b, 0x68, 0x53, 0xfd, + 0x75, 0xe6, 0x11); + + /// + /// DSATTRIB_SAMPLE_LIVE_STREAM_TIME + /// + public static readonly Guid SampleLiveStreamtime = new Guid(0x892cd111, 0x72f3, 0x411d, 0x8b, 0x91, 0xa9, 0xe9, + 0x12, 0x3a, 0xc2, 0x9a); + + /// + /// DSATTRIB_WMDRMProtectionInfo + /// + public static readonly Guid WMDRMProtectionInfo = new Guid(0x40749583, 0x6b9d, 0x4eec, 0xb4, 0x3c, 0x67, 0xa1, + 0x80, 0x1e, 0x1a, 0x9b); + + /// + /// DSATTRIB_BadSampleInfo + /// + public static readonly Guid BadSampleInfo = new Guid(0xe4846dda, 0x5838, 0x42b4, 0xb8, 0x97, 0x6f, 0x7e, 0x5f, + 0xaa, 0x2f, 0x2f); + } + + public static class PropSetID + { + /// + /// AMPROPSETID_Pin + /// + public static readonly Guid Pin = new Guid(0x9b00f101, 0x1567, 0x11d1, 0xb3, 0xf1, 0x00, 0xaa, 0x00, 0x37, 0x61, + 0xc5); + + /// + /// PROPSETID_VIDCAP_DROPPEDFRAMES + /// + public static readonly Guid DroppedFrames = new Guid(0xC6E13344, 0x30AC, 0x11D0, 0xA1, 0x8C, 0x00, 0xA0, 0xC9, + 0x11, 0x89, 0x56); + + /// + /// STATIC_ENCAPIPARAM_BITRATE + /// + public static readonly Guid ENCAPIPARAM_BitRate = new Guid(0x49cc4c43, 0xca83, 0x4ad4, 0xa9, 0xaf, 0xf3, 0x69, + 0x6a, 0xf6, 0x66, 0xdf); + + /// + /// STATIC_ENCAPIPARAM_PEAK_BITRATE + /// + public static readonly Guid ENCAPIPARAM_PeakBitRate = new Guid(0x703f16a9, 0x3d48, 0x44a1, 0xb0, 0x77, 0x01, + 0x8d, 0xff, 0x91, 0x5d, 0x19); + + /// + /// STATIC_ENCAPIPARAM_BITRATE_MODE + /// + public static readonly Guid ENCAPIPARAM_BitRateMode = new Guid(0xee5fb25c, 0xc713, 0x40d1, 0x9d, 0x58, 0xc0, + 0xd7, 0x24, 0x1e, 0x25, 0x0f); + + /// + /// ENCAPIPARAM_SAP_MODE + /// + public static readonly Guid ENCAPIPARAM_SAP_MODE = new Guid(0xc0171db, 0xfefc, 0x4af7, 0x99, 0x91, 0xa5, 0x65, + 0x7c, 0x19, 0x1c, 0xd1); + + /// + /// CODECAPI_AVDecMmcssClass + /// + public static readonly Guid CODECAPI_AVDecMmcssClass = new Guid(0xe0ad4828, 0xdf66, 0x4893, 0x9f, 0x33, 0x78, + 0x8a, 0xa4, 0xec, 0x40, 0x82); + + /// + /// STATIC_CODECAPI_CHANGELISTS + /// + public static readonly Guid CODECAPI_ChangeLists = new Guid(0x62b12acf, 0xf6b0, 0x47d9, 0x94, 0x56, 0x96, 0xf2, + 0x2c, 0x4e, 0x0b, 0x9d); + + /// + /// STATIC_CODECAPI_VIDEO_ENCODER + /// + public static readonly Guid CODECAPI_VideoEncoder = new Guid(0x7112e8e1, 0x3d03, 0x47ef, 0x8e, 0x60, 0x03, 0xf1, + 0xcf, 0x53, 0x73, 0x01); + + /// + /// STATIC_CODECAPI_AUDIO_ENCODER + /// + public static readonly Guid CODECAPI_AudioEncoder = new Guid(0xb9d19a3e, 0xf897, 0x429c, 0xbc, 0x46, 0x81, 0x38, + 0xb7, 0x27, 0x2b, 0x2d); + + /// + /// STATIC_CODECAPI_SETALLDEFAULTS + /// + public static readonly Guid CODECAPI_SetAllDefaults = new Guid(0x6c5e6a7c, 0xacf8, 0x4f55, 0xa9, 0x99, 0x1a, + 0x62, 0x81, 0x09, 0x05, 0x1b); + + /// + /// STATIC_CODECAPI_ALLSETTINGS + /// + public static readonly Guid CODECAPI_AllSettings = new Guid(0x6a577e92, 0x83e1, 0x4113, 0xad, 0xc2, 0x4f, 0xce, + 0xc3, 0x2f, 0x83, 0xa1); + + /// + /// STATIC_CODECAPI_SUPPORTSEVENTS + /// + public static readonly Guid CODECAPI_SupportsEvents = new Guid(0x0581af97, 0x7693, 0x4dbd, 0x9d, 0xca, 0x3f, + 0x9e, 0xbd, 0x65, 0x85, 0xa1); + + /// + /// STATIC_CODECAPI_CURRENTCHANGELIST + /// + public static readonly Guid CODECAPI_CurrentChangeList = new Guid(0x1cb14e83, 0x7d72, 0x4657, 0x83, 0xfd, 0x47, + 0xa2, 0xc5, 0xb9, 0xd1, 0x3d); + } + + public static class PinCategory + { + /// + /// PIN_CATEGORY_CAPTURE + /// + public static readonly Guid Capture = new Guid(0xfb6c4281, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, + 0x16, 0xba); + + /// + /// PIN_CATEGORY_PREVIEW + /// + public static readonly Guid Preview = new Guid(0xfb6c4282, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, + 0x16, 0xba); + + /// + /// PIN_CATEGORY_ANALOGVIDEOIN + /// + public static readonly Guid AnalogVideoIn = new Guid(0xfb6c4283, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, + 0xcc, 0x16, 0xba); + + /// + /// PIN_CATEGORY_VBI + /// + public static readonly Guid VBI = new Guid(0xfb6c4284, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, 0x16, + 0xba); + + /// + /// PIN_CATEGORY_VIDEOPORT + /// + public static readonly Guid VideoPort = new Guid(0xfb6c4285, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, + 0x16, 0xba); + + /// + /// PIN_CATEGORY_NABTS + /// + public static readonly Guid NABTS = new Guid(0xfb6c4286, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, + 0x16, 0xba); + + /// + /// PIN_CATEGORY_EDS + /// + public static readonly Guid EDS = new Guid(0xfb6c4287, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, 0x16, + 0xba); + + /// + /// PIN_CATEGORY_TELETEXT + /// + public static readonly Guid TeleText = new Guid(0xfb6c4288, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, + 0x16, 0xba); + + /// + /// PIN_CATEGORY_CC + /// + public static readonly Guid CC = new Guid(0xfb6c4289, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, 0x16, + 0xba); + + /// + /// PIN_CATEGORY_STILL + /// + public static readonly Guid Still = new Guid(0xfb6c428a, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, + 0x16, 0xba); + + /// + /// PIN_CATEGORY_TIMECODE + /// + public static readonly Guid TimeCode = new Guid(0xfb6c428b, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, + 0x16, 0xba); + + /// + /// PIN_CATEGORY_VIDEOPORT_VBI + /// + public static readonly Guid VideoPortVBI = new Guid(0xfb6c428c, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, + 0xcc, 0x16, 0xba); + } + + public static class FindDirection + { + /// + /// LOOK_UPSTREAM_ONLY + /// + public static readonly Guid UpstreamOnly = new Guid(0xac798be0, 0x98e3, 0x11d1, 0xb3, 0xf1, 0x00, 0xaa, 0x00, + 0x37, 0x61, 0xc5); + + /// + /// LOOK_DOWNSTREAM_ONLY + /// + public static readonly Guid DownstreamOnly = new Guid(0xac798be1, 0x98e3, 0x11d1, 0xb3, 0xf1, 0x00, 0xaa, 0x00, + 0x37, 0x61, 0xc5); + } + + public static class TimeFormat { // 00000000-0000-0000-0000-000000000000 TIME_FORMAT_NONE public static readonly Guid None = new Guid(0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); // 7b785570-8c82-11cf-bc0c-00aa00ac74f6 TIME_FORMAT_FRAME - public static readonly Guid Frame = new Guid(0x7b785570, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, 0x74, 0xf6); + public static readonly Guid Frame = new Guid(0x7b785570, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, + 0x74, 0xf6); // 7b785571-8c82-11cf-bc0c-00aa00ac74f6 TIME_FORMAT_BYTE - public static readonly Guid Byte = new Guid(0x7b785571, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, 0x74, 0xf6); + public static readonly Guid Byte = new Guid(0x7b785571, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, 0x74, + 0xf6); // 7b785572-8c82-11cf-bc0c-00aa00ac74f6 TIME_FORMAT_SAMPLE - public static readonly Guid Sample = new Guid(0x7b785572, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, 0x74, 0xf6); + public static readonly Guid Sample = new Guid(0x7b785572, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, + 0x74, 0xf6); // 7b785573-8c82-11cf-bc0c-00aa00ac74f6 TIME_FORMAT_FIELD - public static readonly Guid Field = new Guid(0x7b785573, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, 0x74, 0xf6); + public static readonly Guid Field = new Guid(0x7b785573, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, + 0x74, 0xf6); // 7b785574-8c82-11cf-bc0c-00aa00ac74f6 TIME_FORMAT_MEDIA_TIME - public static readonly Guid MediaTime = new Guid(0x7b785574, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, 0x74, 0xf6); - } - - static public class PropertyPages - { - /// CLSID_CrossbarFilterPropertyPage - public static readonly Guid CrossbarFilterPropertyPage = new Guid(0x71f96461, 0x78f3, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56); - - /// CLSID_AudioInputMixerProperties - public static readonly Guid AudioInputMixer = new Guid(0x2ca8ca52, 0x3c3f, 0x11d2, 0xb7, 0x3d, 0x00, 0xc0, 0x4f, 0xb6, 0xbd, 0x3d); - - /// CLSID_AudioProperties - public static readonly Guid AudioProperties = new Guid(0x05589faf, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a); - - /// CLSID_AudioRendererAdvancedProperties - public static readonly Guid AudioRendererAdvancedProperties = new Guid(0x37e92a92, 0xd9aa, 0x11d2, 0xbf, 0x84, 0x8e, 0xf2, 0xb1, 0x55, 0x5a, 0xed); - - /// CLSID_AviMuxProptyPage - public static readonly Guid AviMux = new Guid(0xc647b5c0, 0x157c, 0x11d0, 0xbd, 0x23, 0x00, 0xa0, 0xc9, 0x11, 0xce, 0x86); - - /// CLSID_AviMuxProptyPage1 - public static readonly Guid AviMux1 = new Guid(0x0a9ae910, 0x85c0, 0x11d0, 0xbd, 0x42, 0x00, 0xa0, 0xc9, 0x11, 0xce, 0x86); - - /// CLSID_DVDecPropertiesPage - public static readonly Guid DVDec = new Guid(0x101193c0, 0x0bfe, 0x11d0, 0xaf, 0x91, 0x00, 0xaa, 0x00, 0xb6, 0x7a, 0x42); - - /// CLSID_DVEncPropertiesPage - public static readonly Guid DVEnc = new Guid(0x4150f050, 0xbb6f, 0x11d0, 0xaf, 0xb9, 0x00, 0xaa, 0x00, 0xb6, 0x7a, 0x42); - - /// CLSID_ModexProperties - public static readonly Guid Modex = new Guid(0x0618aa30, 0x6bc4, 0x11cf, 0xbf, 0x36, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a); - - /// CLSID_CaptureProperties - public static readonly Guid Capture = new Guid(0x1B544c22, 0xFD0B, 0x11ce, 0x8C, 0x63, 0x00, 0xAA, 0x00, 0x44, 0xB5, 0x1F); - - /// CLSID_WstDecoderPropertyPage - public static readonly Guid WstDecoder = new Guid(0x04e27f80, 0x91e4, 0x11d3, 0xa1, 0x84, 0x00, 0x10, 0x5a, 0xef, 0x9f, 0x33); - - /// CLSID_DVMuxPropertyPage - public static readonly Guid DVMux = new Guid(0x4db880e0, 0xc10d, 0x11d0, 0xaf, 0xb9, 0x00, 0xaa, 0x00, 0xb6, 0x7a, 0x42); - - /// CLSID_VideoProcAmpPropertyPage - public static readonly Guid VideoProcAmpPropertyPage = new Guid(0x71f96464, 0x78f3, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56); - - /// CLSID_CameraControlPropertyPage - public static readonly Guid CameraControlPropertyPage = new Guid(0x71f96465, 0x78f3, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56); - - /// CLSID_AnalogVideoDecoderPropertyPage - public static readonly Guid AnalogVideoDecoderPropertyPage = new Guid(0x71f96466, 0x78f3, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56); - - /// CLSID_VideoStreamConfigPropertyPage - public static readonly Guid VideoStreamConfigPropertyPage = new Guid(0x71f96467, 0x78f3, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56); - - /// CLSID_ATSCNetworkPropertyPage - public static readonly Guid ATSCNetworkPropertyPage = new Guid(0xe3444d16, 0x5ac4, 0x4386, 0x88, 0xdf, 0x13, 0xfd, 0x23, 0x0e, 0x1d, 0xda); - - /// CLSID_TVTunerFilterPropertyPage - public static readonly Guid TVTunerFilterPropertyPage = new Guid(0x266eee41, 0x6c63, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65); - - /// CLSID_TVAudioFilterPropertyPage - public static readonly Guid TVAudioFilterPropertyPage = new Guid(0x71f96463, 0x78f3, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56); - } - - static public class BDANodeCategory - { - /// KSNODE_BDA_RF_TUNER - public static readonly Guid RFTuner = new Guid(0x71985f4c, 0x1ca1, 0x11d3, 0x9c, 0xc8, 0x00, 0xc0, 0x4f, 0x79, 0x71, 0xe0); - - /// KSNODE_BDA_QAM_DEMODULATOR - public static readonly Guid QAMDemodulator = new Guid(0x71985f4d, 0x1ca1, 0x11d3, 0x9c, 0xc8, 0x00, 0xc0, 0x4f, 0x79, 0x71, 0xe0); - - /// KSNODE_BDA_QPSK_DEMODULATOR - public static readonly Guid QPSKDemodulator = new Guid(0x6390c905, 0x27c1, 0x4d67, 0xbd, 0xb7, 0x77, 0xc5, 0x0d, 0x07, 0x93, 0x00); - - /// KSNODE_BDA_8VSB_DEMODULATOR - public static readonly Guid EightVSBDemodulator = new Guid(0x71985f4f, 0x1ca1, 0x11d3, 0x9c, 0xc8, 0x00, 0xc0, 0x4f, 0x79, 0x71, 0xe0); - - /// KSNODE_BDA_COFDM_DEMODULATOR - public static readonly Guid COFDMDemodulator = new Guid(0x2dac6e05, 0xedbe, 0x4b9c, 0xb3, 0x87, 0x1b, 0x6f, 0xad, 0x7d, 0x64, 0x95); - - /// KSNODE_BDA_OPENCABLE_POD - public static readonly Guid OpenCablePod = new Guid(0x345812a0, 0xfb7c, 0x4790, 0xaa, 0x7e, 0xb1, 0xdb, 0x88, 0xac, 0x19, 0xc9); - - /// KSNODE_BDA_COMMON_CA_POD - public static readonly Guid CommonCAPod = new Guid(0xd83ef8fc, 0xf3b8, 0x45ab, 0x8b, 0x71, 0xec, 0xf7, 0xc3, 0x39, 0xde, 0xb4); - - /// KSNODE_BDA_PID_FILTER - public static readonly Guid PidFilter = new Guid(0xf5412789, 0xb0a0, 0x44e1, 0xae, 0x4f, 0xee, 0x99, 0x9b, 0x1b, 0x7f, 0xbe); - - /// KSNODE_BDA_IP_SINK - public static readonly Guid IPSink = new Guid(0x71985f4e, 0x1ca1, 0x11d3, 0x9c, 0xc8, 0x00, 0xc0, 0x4f, 0x79, 0x71, 0xe0); - - } - - static public class TAGTables - { - /// UUID_UdriTagTables - public static readonly Guid UdriTagTables = new Guid(0xe1b98d74, 0x9778, 0x4878, 0xb6, 0x64, 0xeb, 0x20, 0x20, 0x36, 0x4d, 0x88); - - /// UUID_WMDRMTagTables - public static readonly Guid WMDRMTagTables = new Guid(0x5DCD1101, 0x9263, 0x45bb, 0xa4, 0xd5, 0xc4, 0x15, 0xab, 0x8c, 0x58, 0x9c); + public static readonly Guid MediaTime = new Guid(0x7b785574, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, + 0x74, 0xf6); + } + + public static class PropertyPages + { + /// + /// CLSID_CrossbarFilterPropertyPage + /// + public static readonly Guid CrossbarFilterPropertyPage = new Guid(0x71f96461, 0x78f3, 0x11d0, 0xa1, 0x8c, 0x00, + 0xa0, 0xc9, 0x11, 0x89, 0x56); + + /// + /// CLSID_AudioInputMixerProperties + /// + public static readonly Guid AudioInputMixer = new Guid(0x2ca8ca52, 0x3c3f, 0x11d2, 0xb7, 0x3d, 0x00, 0xc0, 0x4f, + 0xb6, 0xbd, 0x3d); + + /// + /// CLSID_AudioProperties + /// + public static readonly Guid AudioProperties = new Guid(0x05589faf, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, + 0x55, 0x59, 0x5a); + + /// + /// CLSID_AudioRendererAdvancedProperties + /// + public static readonly Guid AudioRendererAdvancedProperties = new Guid(0x37e92a92, 0xd9aa, 0x11d2, 0xbf, 0x84, + 0x8e, 0xf2, 0xb1, 0x55, 0x5a, 0xed); + + /// + /// CLSID_AviMuxProptyPage + /// + public static readonly Guid AviMux = new Guid(0xc647b5c0, 0x157c, 0x11d0, 0xbd, 0x23, 0x00, 0xa0, 0xc9, 0x11, + 0xce, 0x86); + + /// + /// CLSID_AviMuxProptyPage1 + /// + public static readonly Guid AviMux1 = new Guid(0x0a9ae910, 0x85c0, 0x11d0, 0xbd, 0x42, 0x00, 0xa0, 0xc9, 0x11, + 0xce, 0x86); + + /// + /// CLSID_DVDecPropertiesPage + /// + public static readonly Guid DVDec = new Guid(0x101193c0, 0x0bfe, 0x11d0, 0xaf, 0x91, 0x00, 0xaa, 0x00, 0xb6, + 0x7a, 0x42); + + /// + /// CLSID_DVEncPropertiesPage + /// + public static readonly Guid DVEnc = new Guid(0x4150f050, 0xbb6f, 0x11d0, 0xaf, 0xb9, 0x00, 0xaa, 0x00, 0xb6, + 0x7a, 0x42); + + /// + /// CLSID_ModexProperties + /// + public static readonly Guid Modex = new Guid(0x0618aa30, 0x6bc4, 0x11cf, 0xbf, 0x36, 0x00, 0xaa, 0x00, 0x55, + 0x59, 0x5a); + + /// + /// CLSID_CaptureProperties + /// + public static readonly Guid Capture = new Guid(0x1B544c22, 0xFD0B, 0x11ce, 0x8C, 0x63, 0x00, 0xAA, 0x00, 0x44, + 0xB5, 0x1F); + + /// + /// CLSID_WstDecoderPropertyPage + /// + public static readonly Guid WstDecoder = new Guid(0x04e27f80, 0x91e4, 0x11d3, 0xa1, 0x84, 0x00, 0x10, 0x5a, 0xef, + 0x9f, 0x33); + + /// + /// CLSID_DVMuxPropertyPage + /// + public static readonly Guid DVMux = new Guid(0x4db880e0, 0xc10d, 0x11d0, 0xaf, 0xb9, 0x00, 0xaa, 0x00, 0xb6, + 0x7a, 0x42); + + /// + /// CLSID_VideoProcAmpPropertyPage + /// + public static readonly Guid VideoProcAmpPropertyPage = new Guid(0x71f96464, 0x78f3, 0x11d0, 0xa1, 0x8c, 0x00, + 0xa0, 0xc9, 0x11, 0x89, 0x56); + + /// + /// CLSID_CameraControlPropertyPage + /// + public static readonly Guid CameraControlPropertyPage = new Guid(0x71f96465, 0x78f3, 0x11d0, 0xa1, 0x8c, 0x00, + 0xa0, 0xc9, 0x11, 0x89, 0x56); + + /// + /// CLSID_AnalogVideoDecoderPropertyPage + /// + public static readonly Guid AnalogVideoDecoderPropertyPage = new Guid(0x71f96466, 0x78f3, 0x11d0, 0xa1, 0x8c, + 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56); + + /// + /// CLSID_VideoStreamConfigPropertyPage + /// + public static readonly Guid VideoStreamConfigPropertyPage = new Guid(0x71f96467, 0x78f3, 0x11d0, 0xa1, 0x8c, + 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56); + + /// + /// CLSID_ATSCNetworkPropertyPage + /// + public static readonly Guid ATSCNetworkPropertyPage = new Guid(0xe3444d16, 0x5ac4, 0x4386, 0x88, 0xdf, 0x13, + 0xfd, 0x23, 0x0e, 0x1d, 0xda); + + /// + /// CLSID_TVTunerFilterPropertyPage + /// + public static readonly Guid TVTunerFilterPropertyPage = new Guid(0x266eee41, 0x6c63, 0x11cf, 0x8a, 0x03, 0x00, + 0xaa, 0x00, 0x6e, 0xcb, 0x65); + + /// + /// CLSID_TVAudioFilterPropertyPage + /// + public static readonly Guid TVAudioFilterPropertyPage = new Guid(0x71f96463, 0x78f3, 0x11d0, 0xa1, 0x8c, 0x00, + 0xa0, 0xc9, 0x11, 0x89, 0x56); + } + + public static class BDANodeCategory + { + /// + /// KSNODE_BDA_RF_TUNER + /// + public static readonly Guid RFTuner = new Guid(0x71985f4c, 0x1ca1, 0x11d3, 0x9c, 0xc8, 0x00, 0xc0, 0x4f, 0x79, + 0x71, 0xe0); + + /// + /// KSNODE_BDA_QAM_DEMODULATOR + /// + public static readonly Guid QAMDemodulator = new Guid(0x71985f4d, 0x1ca1, 0x11d3, 0x9c, 0xc8, 0x00, 0xc0, 0x4f, + 0x79, 0x71, 0xe0); + + /// + /// KSNODE_BDA_QPSK_DEMODULATOR + /// + public static readonly Guid QPSKDemodulator = new Guid(0x6390c905, 0x27c1, 0x4d67, 0xbd, 0xb7, 0x77, 0xc5, 0x0d, + 0x07, 0x93, 0x00); + + /// + /// KSNODE_BDA_8VSB_DEMODULATOR + /// + public static readonly Guid EightVSBDemodulator = new Guid(0x71985f4f, 0x1ca1, 0x11d3, 0x9c, 0xc8, 0x00, 0xc0, + 0x4f, 0x79, 0x71, 0xe0); + + /// + /// KSNODE_BDA_COFDM_DEMODULATOR + /// + public static readonly Guid COFDMDemodulator = new Guid(0x2dac6e05, 0xedbe, 0x4b9c, 0xb3, 0x87, 0x1b, 0x6f, 0xad, + 0x7d, 0x64, 0x95); + + /// + /// KSNODE_BDA_OPENCABLE_POD + /// + public static readonly Guid OpenCablePod = new Guid(0x345812a0, 0xfb7c, 0x4790, 0xaa, 0x7e, 0xb1, 0xdb, 0x88, + 0xac, 0x19, 0xc9); + + /// + /// KSNODE_BDA_COMMON_CA_POD + /// + public static readonly Guid CommonCAPod = new Guid(0xd83ef8fc, 0xf3b8, 0x45ab, 0x8b, 0x71, 0xec, 0xf7, 0xc3, + 0x39, 0xde, 0xb4); + + /// + /// KSNODE_BDA_PID_FILTER + /// + public static readonly Guid PidFilter = new Guid(0xf5412789, 0xb0a0, 0x44e1, 0xae, 0x4f, 0xee, 0x99, 0x9b, 0x1b, + 0x7f, 0xbe); + + /// + /// KSNODE_BDA_IP_SINK + /// + public static readonly Guid IPSink = new Guid(0x71985f4e, 0x1ca1, 0x11d3, 0x9c, 0xc8, 0x00, 0xc0, 0x4f, 0x79, + 0x71, 0xe0); + } + + public static class TAGTables + { + /// + /// UUID_UdriTagTables + /// + public static readonly Guid UdriTagTables = new Guid(0xe1b98d74, 0x9778, 0x4878, 0xb6, 0x64, 0xeb, 0x20, 0x20, + 0x36, 0x4d, 0x88); + + /// + /// UUID_WMDRMTagTables + /// + public static readonly Guid WMDRMTagTables = new Guid(0x5DCD1101, 0x9263, 0x45bb, 0xa4, 0xd5, 0xc4, 0x15, 0xab, + 0x8c, 0x58, 0x9c); } #endregion -} +} \ No newline at end of file From 7e9d48f496e031be965123575a2c89f47dafbffd Mon Sep 17 00:00:00 2001 From: Omer Mor Date: Sat, 18 Aug 2012 00:06:59 +0300 Subject: [PATCH 2/5] Added a solution file --- DirectShowLib.sln | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 DirectShowLib.sln diff --git a/DirectShowLib.sln b/DirectShowLib.sln new file mode 100644 index 0000000..e79362d --- /dev/null +++ b/DirectShowLib.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DirectShowLib", "DirectShowLib.csproj", "{CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal From dc4432cf49686f943ce24c12d6763347f971fc08 Mon Sep 17 00:00:00 2001 From: Omer Mor Date: Sat, 18 Aug 2012 00:07:25 +0300 Subject: [PATCH 3/5] Removed '*' from assembly version --- AssemblyInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AssemblyInfo.cs b/AssemblyInfo.cs index 6e3104c..f95cc46 100644 --- a/AssemblyInfo.cs +++ b/AssemblyInfo.cs @@ -33,7 +33,7 @@ You should have received a copy of the GNU Lesser General Public [assembly : AssemblyConfiguration("")] [assembly : AssemblyCompany("")] [assembly : Guid("6D0386CE-37E6-4f77-B678-07C584105DC6")] -[assembly : AssemblyVersion("2.1.0.*")] +[assembly : AssemblyVersion("2.1.0.0")] #if DEBUG [assembly : AssemblyProduct("Debug Version")] #else From 9d30fd0d4a978954eca93da4e618f426a4b1b002 Mon Sep 17 00:00:00 2001 From: Omer Mor Date: Sat, 18 Aug 2012 00:56:10 +0300 Subject: [PATCH 4/5] moved source project to sub-folder --- DirectShowLib.sln | 2 +- AXExtend.cs => DirectShowLib/AXExtend.cs | 0 AssemblyInfo.cs => DirectShowLib/AssemblyInfo.cs | 0 AxCore.cs => DirectShowLib/AxCore.cs | 0 BDAIface.cs => DirectShowLib/BDAIface.cs | 0 BDATypes.cs => DirectShowLib/BDATypes.cs | 0 Bdatif.cs => DirectShowLib/Bdatif.cs | 0 ClassId.cs => DirectShowLib/ClassId.cs | 0 Control.cs => DirectShowLib/Control.cs | 0 DES.cs => DirectShowLib/DES.cs | 0 DMODShow.cs => DirectShowLib/DMODShow.cs | 0 DShowNET.snk => DirectShowLib/DShowNET.snk | Bin DVDIf.cs => DirectShowLib/DVDIf.cs | 0 DevEnum.cs => DirectShowLib/DevEnum.cs | 0 .../DirectShowLib.csproj | 0 DsUtils.cs => DirectShowLib/DsUtils.cs | 0 DynGraph.cs => DirectShowLib/DynGraph.cs | 0 EvCode.cs => DirectShowLib/EvCode.cs | 0 IL21Dec.cs => DirectShowLib/IL21Dec.cs | 0 MediaObj.cs => DirectShowLib/MediaObj.cs | 0 MediaParam.cs => DirectShowLib/MediaParam.cs | 0 Misc.cs => DirectShowLib/Misc.cs | 0 Mixerocx.cs => DirectShowLib/Mixerocx.cs | 0 Mpeg2Data.cs => DirectShowLib/Mpeg2Data.cs | 0 Mpeg2Structs.cs => DirectShowLib/Mpeg2Structs.cs | 0 PlayList.cs => DirectShowLib/PlayList.cs | 0 QEdit.cs => DirectShowLib/QEdit.cs | 0 RegBag.cs => DirectShowLib/RegBag.cs | 0 Sbe.cs => DirectShowLib/Sbe.cs | 0 Tuner.cs => DirectShowLib/Tuner.cs | 0 TvRatings.cs => DirectShowLib/TvRatings.cs | 0 Uuids.cs => DirectShowLib/Uuids.cs | 0 VidPort.cs => DirectShowLib/VidPort.cs | 0 Vidcap.cs => DirectShowLib/Vidcap.cs | 0 VmRender.cs => DirectShowLib/VmRender.cs | 0 Vmr9.cs => DirectShowLib/Vmr9.cs | 0 amstream.cs => DirectShowLib/amstream.cs | 0 amvideo.cs => DirectShowLib/amvideo.cs | 0 app.config => DirectShowLib/app.config | 0 .../atscpsipparser.cs | 0 austream.cs => DirectShowLib/austream.cs | 0 dsattrib.cs => DirectShowLib/dsattrib.cs | 0 dvbsiparser.cs => DirectShowLib/dvbsiparser.cs | 0 encdec.cs => DirectShowLib/encdec.cs | 0 mmstream.cs => DirectShowLib/mmstream.cs | 0 mpconfig.cs => DirectShowLib/mpconfig.cs | 0 .../mpeg2psiparser.cs | 0 other.cs => DirectShowLib/other.cs | 0 qnetwork.cs => DirectShowLib/qnetwork.cs | 0 49 files changed, 1 insertion(+), 1 deletion(-) rename AXExtend.cs => DirectShowLib/AXExtend.cs (100%) rename AssemblyInfo.cs => DirectShowLib/AssemblyInfo.cs (100%) rename AxCore.cs => DirectShowLib/AxCore.cs (100%) rename BDAIface.cs => DirectShowLib/BDAIface.cs (100%) rename BDATypes.cs => DirectShowLib/BDATypes.cs (100%) rename Bdatif.cs => DirectShowLib/Bdatif.cs (100%) rename ClassId.cs => DirectShowLib/ClassId.cs (100%) rename Control.cs => DirectShowLib/Control.cs (100%) rename DES.cs => DirectShowLib/DES.cs (100%) rename DMODShow.cs => DirectShowLib/DMODShow.cs (100%) rename DShowNET.snk => DirectShowLib/DShowNET.snk (100%) rename DVDIf.cs => DirectShowLib/DVDIf.cs (100%) rename DevEnum.cs => DirectShowLib/DevEnum.cs (100%) rename DirectShowLib.csproj => DirectShowLib/DirectShowLib.csproj (100%) rename DsUtils.cs => DirectShowLib/DsUtils.cs (100%) rename DynGraph.cs => DirectShowLib/DynGraph.cs (100%) rename EvCode.cs => DirectShowLib/EvCode.cs (100%) rename IL21Dec.cs => DirectShowLib/IL21Dec.cs (100%) rename MediaObj.cs => DirectShowLib/MediaObj.cs (100%) rename MediaParam.cs => DirectShowLib/MediaParam.cs (100%) rename Misc.cs => DirectShowLib/Misc.cs (100%) rename Mixerocx.cs => DirectShowLib/Mixerocx.cs (100%) rename Mpeg2Data.cs => DirectShowLib/Mpeg2Data.cs (100%) rename Mpeg2Structs.cs => DirectShowLib/Mpeg2Structs.cs (100%) rename PlayList.cs => DirectShowLib/PlayList.cs (100%) rename QEdit.cs => DirectShowLib/QEdit.cs (100%) rename RegBag.cs => DirectShowLib/RegBag.cs (100%) rename Sbe.cs => DirectShowLib/Sbe.cs (100%) rename Tuner.cs => DirectShowLib/Tuner.cs (100%) rename TvRatings.cs => DirectShowLib/TvRatings.cs (100%) rename Uuids.cs => DirectShowLib/Uuids.cs (100%) rename VidPort.cs => DirectShowLib/VidPort.cs (100%) rename Vidcap.cs => DirectShowLib/Vidcap.cs (100%) rename VmRender.cs => DirectShowLib/VmRender.cs (100%) rename Vmr9.cs => DirectShowLib/Vmr9.cs (100%) rename amstream.cs => DirectShowLib/amstream.cs (100%) rename amvideo.cs => DirectShowLib/amvideo.cs (100%) rename app.config => DirectShowLib/app.config (100%) rename atscpsipparser.cs => DirectShowLib/atscpsipparser.cs (100%) rename austream.cs => DirectShowLib/austream.cs (100%) rename dsattrib.cs => DirectShowLib/dsattrib.cs (100%) rename dvbsiparser.cs => DirectShowLib/dvbsiparser.cs (100%) rename encdec.cs => DirectShowLib/encdec.cs (100%) rename mmstream.cs => DirectShowLib/mmstream.cs (100%) rename mpconfig.cs => DirectShowLib/mpconfig.cs (100%) rename mpeg2psiparser.cs => DirectShowLib/mpeg2psiparser.cs (100%) rename other.cs => DirectShowLib/other.cs (100%) rename qnetwork.cs => DirectShowLib/qnetwork.cs (100%) diff --git a/DirectShowLib.sln b/DirectShowLib.sln index e79362d..16cf0f7 100644 --- a/DirectShowLib.sln +++ b/DirectShowLib.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DirectShowLib", "DirectShowLib.csproj", "{CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DirectShowLib", "DirectShowLib\DirectShowLib.csproj", "{CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/AXExtend.cs b/DirectShowLib/AXExtend.cs similarity index 100% rename from AXExtend.cs rename to DirectShowLib/AXExtend.cs diff --git a/AssemblyInfo.cs b/DirectShowLib/AssemblyInfo.cs similarity index 100% rename from AssemblyInfo.cs rename to DirectShowLib/AssemblyInfo.cs diff --git a/AxCore.cs b/DirectShowLib/AxCore.cs similarity index 100% rename from AxCore.cs rename to DirectShowLib/AxCore.cs diff --git a/BDAIface.cs b/DirectShowLib/BDAIface.cs similarity index 100% rename from BDAIface.cs rename to DirectShowLib/BDAIface.cs diff --git a/BDATypes.cs b/DirectShowLib/BDATypes.cs similarity index 100% rename from BDATypes.cs rename to DirectShowLib/BDATypes.cs diff --git a/Bdatif.cs b/DirectShowLib/Bdatif.cs similarity index 100% rename from Bdatif.cs rename to DirectShowLib/Bdatif.cs diff --git a/ClassId.cs b/DirectShowLib/ClassId.cs similarity index 100% rename from ClassId.cs rename to DirectShowLib/ClassId.cs diff --git a/Control.cs b/DirectShowLib/Control.cs similarity index 100% rename from Control.cs rename to DirectShowLib/Control.cs diff --git a/DES.cs b/DirectShowLib/DES.cs similarity index 100% rename from DES.cs rename to DirectShowLib/DES.cs diff --git a/DMODShow.cs b/DirectShowLib/DMODShow.cs similarity index 100% rename from DMODShow.cs rename to DirectShowLib/DMODShow.cs diff --git a/DShowNET.snk b/DirectShowLib/DShowNET.snk similarity index 100% rename from DShowNET.snk rename to DirectShowLib/DShowNET.snk diff --git a/DVDIf.cs b/DirectShowLib/DVDIf.cs similarity index 100% rename from DVDIf.cs rename to DirectShowLib/DVDIf.cs diff --git a/DevEnum.cs b/DirectShowLib/DevEnum.cs similarity index 100% rename from DevEnum.cs rename to DirectShowLib/DevEnum.cs diff --git a/DirectShowLib.csproj b/DirectShowLib/DirectShowLib.csproj similarity index 100% rename from DirectShowLib.csproj rename to DirectShowLib/DirectShowLib.csproj diff --git a/DsUtils.cs b/DirectShowLib/DsUtils.cs similarity index 100% rename from DsUtils.cs rename to DirectShowLib/DsUtils.cs diff --git a/DynGraph.cs b/DirectShowLib/DynGraph.cs similarity index 100% rename from DynGraph.cs rename to DirectShowLib/DynGraph.cs diff --git a/EvCode.cs b/DirectShowLib/EvCode.cs similarity index 100% rename from EvCode.cs rename to DirectShowLib/EvCode.cs diff --git a/IL21Dec.cs b/DirectShowLib/IL21Dec.cs similarity index 100% rename from IL21Dec.cs rename to DirectShowLib/IL21Dec.cs diff --git a/MediaObj.cs b/DirectShowLib/MediaObj.cs similarity index 100% rename from MediaObj.cs rename to DirectShowLib/MediaObj.cs diff --git a/MediaParam.cs b/DirectShowLib/MediaParam.cs similarity index 100% rename from MediaParam.cs rename to DirectShowLib/MediaParam.cs diff --git a/Misc.cs b/DirectShowLib/Misc.cs similarity index 100% rename from Misc.cs rename to DirectShowLib/Misc.cs diff --git a/Mixerocx.cs b/DirectShowLib/Mixerocx.cs similarity index 100% rename from Mixerocx.cs rename to DirectShowLib/Mixerocx.cs diff --git a/Mpeg2Data.cs b/DirectShowLib/Mpeg2Data.cs similarity index 100% rename from Mpeg2Data.cs rename to DirectShowLib/Mpeg2Data.cs diff --git a/Mpeg2Structs.cs b/DirectShowLib/Mpeg2Structs.cs similarity index 100% rename from Mpeg2Structs.cs rename to DirectShowLib/Mpeg2Structs.cs diff --git a/PlayList.cs b/DirectShowLib/PlayList.cs similarity index 100% rename from PlayList.cs rename to DirectShowLib/PlayList.cs diff --git a/QEdit.cs b/DirectShowLib/QEdit.cs similarity index 100% rename from QEdit.cs rename to DirectShowLib/QEdit.cs diff --git a/RegBag.cs b/DirectShowLib/RegBag.cs similarity index 100% rename from RegBag.cs rename to DirectShowLib/RegBag.cs diff --git a/Sbe.cs b/DirectShowLib/Sbe.cs similarity index 100% rename from Sbe.cs rename to DirectShowLib/Sbe.cs diff --git a/Tuner.cs b/DirectShowLib/Tuner.cs similarity index 100% rename from Tuner.cs rename to DirectShowLib/Tuner.cs diff --git a/TvRatings.cs b/DirectShowLib/TvRatings.cs similarity index 100% rename from TvRatings.cs rename to DirectShowLib/TvRatings.cs diff --git a/Uuids.cs b/DirectShowLib/Uuids.cs similarity index 100% rename from Uuids.cs rename to DirectShowLib/Uuids.cs diff --git a/VidPort.cs b/DirectShowLib/VidPort.cs similarity index 100% rename from VidPort.cs rename to DirectShowLib/VidPort.cs diff --git a/Vidcap.cs b/DirectShowLib/Vidcap.cs similarity index 100% rename from Vidcap.cs rename to DirectShowLib/Vidcap.cs diff --git a/VmRender.cs b/DirectShowLib/VmRender.cs similarity index 100% rename from VmRender.cs rename to DirectShowLib/VmRender.cs diff --git a/Vmr9.cs b/DirectShowLib/Vmr9.cs similarity index 100% rename from Vmr9.cs rename to DirectShowLib/Vmr9.cs diff --git a/amstream.cs b/DirectShowLib/amstream.cs similarity index 100% rename from amstream.cs rename to DirectShowLib/amstream.cs diff --git a/amvideo.cs b/DirectShowLib/amvideo.cs similarity index 100% rename from amvideo.cs rename to DirectShowLib/amvideo.cs diff --git a/app.config b/DirectShowLib/app.config similarity index 100% rename from app.config rename to DirectShowLib/app.config diff --git a/atscpsipparser.cs b/DirectShowLib/atscpsipparser.cs similarity index 100% rename from atscpsipparser.cs rename to DirectShowLib/atscpsipparser.cs diff --git a/austream.cs b/DirectShowLib/austream.cs similarity index 100% rename from austream.cs rename to DirectShowLib/austream.cs diff --git a/dsattrib.cs b/DirectShowLib/dsattrib.cs similarity index 100% rename from dsattrib.cs rename to DirectShowLib/dsattrib.cs diff --git a/dvbsiparser.cs b/DirectShowLib/dvbsiparser.cs similarity index 100% rename from dvbsiparser.cs rename to DirectShowLib/dvbsiparser.cs diff --git a/encdec.cs b/DirectShowLib/encdec.cs similarity index 100% rename from encdec.cs rename to DirectShowLib/encdec.cs diff --git a/mmstream.cs b/DirectShowLib/mmstream.cs similarity index 100% rename from mmstream.cs rename to DirectShowLib/mmstream.cs diff --git a/mpconfig.cs b/DirectShowLib/mpconfig.cs similarity index 100% rename from mpconfig.cs rename to DirectShowLib/mpconfig.cs diff --git a/mpeg2psiparser.cs b/DirectShowLib/mpeg2psiparser.cs similarity index 100% rename from mpeg2psiparser.cs rename to DirectShowLib/mpeg2psiparser.cs diff --git a/other.cs b/DirectShowLib/other.cs similarity index 100% rename from other.cs rename to DirectShowLib/other.cs diff --git a/qnetwork.cs b/DirectShowLib/qnetwork.cs similarity index 100% rename from qnetwork.cs rename to DirectShowLib/qnetwork.cs From f420a0c100f7a962c243bc0c14c3df3fb3e1fe1f Mon Sep 17 00:00:00 2001 From: Omer Mor Date: Sat, 18 Aug 2012 02:11:30 +0300 Subject: [PATCH 5/5] added samples to solution --- DirectShowLib.sln | 744 ++- MediaFoundation/Alt.cs | 511 ++ MediaFoundation/EVR.cs | 784 +++ MediaFoundation/Externs.cs | 1168 ++++ MediaFoundation/MFIdl.cs | 5226 +++++++++++++++++ MediaFoundation/MFObjects.cs | 2217 +++++++ MediaFoundation/MFPlay.cs | 638 ++ MediaFoundation/MFReadWrite.cs | 335 ++ MediaFoundation/MFTransform.cs | 375 ++ MediaFoundation/MFUtils.cs | 3043 ++++++++++ MediaFoundation/MediaFoundation-2010.sln | 32 + MediaFoundation/MediaFoundation.csproj | 141 + MediaFoundation/MediaFoundation.snk | Bin 0 -> 596 bytes MediaFoundation/OpmApi.cs | 443 ++ MediaFoundation/Properties/AssemblyInfo.cs | 50 + MediaFoundation/WMContainer.cs | 999 ++++ MediaFoundation/dxvahd.cs | 734 +++ MediaFoundation/mfmp2dlna.cs | 78 + MediaFoundation/misc.cs | 262 + Samples/BDA/DTVViewer/AboutBox.cs | 163 + Samples/BDA/DTVViewer/AboutBox.resx | 184 + Samples/BDA/DTVViewer/App.ico | Bin 0 -> 1078 bytes Samples/BDA/DTVViewer/AssemblyInfo.cs | 58 + Samples/BDA/DTVViewer/BDAGraphBuilder.cs | 565 ++ Samples/BDA/DTVViewer/DTVViewer-2005.csproj | 146 + Samples/BDA/DTVViewer/DTVViewer-2005.sln | 19 + Samples/BDA/DTVViewer/DTVViewer-2008.sln | 19 + Samples/BDA/DTVViewer/DTVViewer.csproj | 178 + Samples/BDA/DTVViewer/DVBSTuning.cs | 337 ++ Samples/BDA/DTVViewer/DVBSTuning.resx | 256 + Samples/BDA/DTVViewer/DVBTTuning.cs | 275 + Samples/BDA/DTVViewer/DVBTTuning.resx | 220 + Samples/BDA/DTVViewer/ITuningSelector.cs | 22 + Samples/BDA/DTVViewer/MainForm.cs | 277 + Samples/BDA/DTVViewer/MainForm.resx | 217 + Samples/BDA/DTVViewer/StartUp.cs | 27 + .../BDA/DTVViewer/Toolkit/FilterGraphTools.cs | 1015 ++++ Samples/BDA/DTVViewer/readme.txt | 71 + Samples/Capture/CapWMV/App.ico | Bin 0 -> 1078 bytes Samples/Capture/CapWMV/AssemblyInfo.cs | 58 + Samples/Capture/CapWMV/CapWMV-2005.csproj | 113 + Samples/Capture/CapWMV/CapWMV-2005.sln | 19 + Samples/Capture/CapWMV/CapWMV-2008.sln | 19 + Samples/Capture/CapWMV/CapWMV.csproj | 145 + Samples/Capture/CapWMV/Capture.cs | 224 + Samples/Capture/CapWMV/Form1.cs | 155 + Samples/Capture/CapWMV/Form1.resx | 120 + Samples/Capture/CapWMV/readme.txt | 18 + Samples/Capture/DxLogo/App.ico | Bin 0 -> 1078 bytes Samples/Capture/DxLogo/AssemblyInfo.cs | 58 + Samples/Capture/DxLogo/Capture.cs | 422 ++ Samples/Capture/DxLogo/DxLogo-2005.csproj | 113 + Samples/Capture/DxLogo/DxLogo-2005.sln | 19 + Samples/Capture/DxLogo/DxLogo-2008.sln | 19 + Samples/Capture/DxLogo/DxLogo.csproj | 145 + Samples/Capture/DxLogo/Form1.cs | 178 + Samples/Capture/DxLogo/Form1.resx | 184 + Samples/Capture/DxLogo/lgs.jpg | Bin 0 -> 1667 bytes Samples/Capture/DxLogo/readme.txt | 12 + Samples/Capture/DxLogoVB/AssemblyInfo.vb | 31 + Samples/Capture/DxLogoVB/Capture.vb | 367 ++ Samples/Capture/DxLogoVB/DxLogoVB-2005.sln | 19 + Samples/Capture/DxLogoVB/DxLogoVB-2005.vbproj | 116 + Samples/Capture/DxLogoVB/DxLogoVB-2008.sln | 19 + Samples/Capture/DxLogoVB/DxLogoVB.vbproj | 151 + Samples/Capture/DxLogoVB/Form1.resx | 120 + Samples/Capture/DxLogoVB/Form1.vb | 141 + Samples/Capture/DxLogoVB/readme.txt | 13 + Samples/Capture/DxPropPages/AssemblyInfo.cs | 58 + .../DxPropPages/DxPropPages-2005.csproj | 116 + .../Capture/DxPropPages/DxPropPages-2005.sln | 19 + .../Capture/DxPropPages/DxPropPages-2008.sln | 19 + .../Capture/DxPropPages/DxPropPages.csproj | 148 + Samples/Capture/DxPropPages/Form1.cs | 476 ++ Samples/Capture/DxPropPages/Form1.resx | 467 ++ Samples/Capture/DxPropPages/readme.txt | 11 + Samples/Capture/DxSnap/App.ico | Bin 0 -> 1078 bytes Samples/Capture/DxSnap/AssemblyInfo.cs | 58 + Samples/Capture/DxSnap/Capture.cs | 537 ++ Samples/Capture/DxSnap/DxSnap-2005.csproj | 113 + Samples/Capture/DxSnap/DxSnap-2005.sln | 19 + Samples/Capture/DxSnap/DxSnap-2008.sln | 19 + Samples/Capture/DxSnap/DxSnap.csproj | 145 + Samples/Capture/DxSnap/Form1.cs | 171 + Samples/Capture/DxSnap/Form1.resx | 120 + Samples/Capture/DxSnap/readme.txt | 16 + Samples/Capture/DxTuner/AssemblyInfo.cs | 58 + Samples/Capture/DxTuner/DxTuner-2005.csproj | 110 + Samples/Capture/DxTuner/DxTuner-2005.sln | 19 + Samples/Capture/DxTuner/DxTuner-2008.sln | 19 + Samples/Capture/DxTuner/DxTuner.csproj | 142 + Samples/Capture/DxTuner/Form1.cs | 628 ++ Samples/Capture/DxTuner/Form1.resx | 530 ++ Samples/Capture/DxTuner/readme.txt | 27 + Samples/Capture/PlayCap/AssemblyInfo.cs | 58 + Samples/Capture/PlayCap/Form1.cs | 397 ++ Samples/Capture/PlayCap/Form1.resx | 152 + Samples/Capture/PlayCap/PlayCap-2005.csproj | 109 + Samples/Capture/PlayCap/PlayCap-2005.sln | 19 + Samples/Capture/PlayCap/PlayCap-2008.sln | 19 + Samples/Capture/PlayCap/PlayCap.csproj | 141 + Samples/Capture/PlayCap/playcap.ico | Bin 0 -> 1078 bytes Samples/Capture/PlayCap/readme.txt | 18 + Samples/DMO/DmoFlip/DMO/AssemblyInfo.cs | 21 + Samples/DMO/DmoFlip/DMO/DmoFlip-2005.csproj | 108 + Samples/DMO/DmoFlip/DMO/DmoFlip.cs | 643 ++ Samples/DMO/DmoFlip/DMO/DmoFlip.csproj | 140 + Samples/DMO/DmoFlip/DMO/IMediaObjectImpl.cs | 3142 ++++++++++ .../DMO/DmoFlip/DMO/docs/IMediaObjectImpl.chm | Bin 0 -> 60566 bytes Samples/DMO/DmoFlip/DMO/mykey.snk | Bin 0 -> 596 bytes Samples/DMO/DmoFlip/DMO/readme.txt | 97 + Samples/DMO/DmoFlip/DmoFlip-2005.sln | 28 + Samples/DMO/DmoFlip/DmoFlip-2008.sln | 28 + Samples/DMO/DmoFlip/DmoFlip.ndoc | 43 + Samples/DMO/DmoFlip/FormDMO/App.ico | Bin 0 -> 1078 bytes Samples/DMO/DmoFlip/FormDMO/AssemblyInfo.cs | 58 + Samples/DMO/DmoFlip/FormDMO/Form1.cs | 426 ++ Samples/DMO/DmoFlip/FormDMO/Form1.resx | 184 + .../DMO/DmoFlip/FormDMO/FormDMO-2005.csproj | 110 + .../DMO/DmoFlip/FormDMO/FormDmoFlip.csproj | 142 + Samples/DMO/DmoFlip/FormDMO/readme.txt | 5 + Samples/DMO/DmoFlip/readme.txt | 12 + Samples/DMO/DmoSplit/DMO/AssemblyInfo.cs | 21 + Samples/DMO/DmoSplit/DMO/DmoSplit-2005.csproj | 109 + Samples/DMO/DmoSplit/DMO/DmoSplit.cs | 639 ++ Samples/DMO/DmoSplit/DMO/DmoSplit.csproj | 141 + Samples/DMO/DmoSplit/DMO/IMediaObjectImpl.cs | 3142 ++++++++++ Samples/DMO/DmoSplit/DMO/mykey.snk | Bin 0 -> 596 bytes Samples/DMO/DmoSplit/DMO/readme.txt | 20 + Samples/DMO/DmoSplit/DmoSplit-2005.sln | 28 + Samples/DMO/DmoSplit/DmoSplit-2008.sln | 28 + Samples/DMO/DmoSplit/FormDMO/App.ico | Bin 0 -> 1078 bytes Samples/DMO/DmoSplit/FormDMO/AssemblyInfo.cs | 58 + Samples/DMO/DmoSplit/FormDMO/Form1.cs | 240 + Samples/DMO/DmoSplit/FormDMO/Form1.resx | 184 + .../DMO/DmoSplit/FormDMO/FormDMO-2005.csproj | 110 + .../DMO/DmoSplit/FormDMO/FormDmoSplit.csproj | 142 + Samples/DMO/DmoSplit/FormDMO/readme.txt | 4 + Samples/DMO/DmoSplit/readme.txt | 13 + .../Editing/DESCombine/DESCombine-2005.sln | 25 + .../Editing/DESCombine/DESCombine-2008.sln | 25 + Samples/Editing/DESCombine/DESCombine.ndoc | 44 + .../DESCombine/DESCombineLib/AssemblyInfo.cs | 10 + .../DESCombine/DESCombineLib/DESCombine.cs | 1623 +++++ .../DESCombineLib/DESCombineLib-2005.csproj | 102 + .../DESCombineLib/DESCombineLib.csproj | 134 + .../DESCombine/DesCombineVB/AssemblyInfo.vb | 39 + .../DesCombineVB/DesCombineVB-2005.sln | 19 + .../DesCombineVB/DesCombineVB-2005.vbproj | 118 + .../DesCombineVB/DesCombineVB-2008.sln | 19 + .../DesCombineVB/DesCombineVB.vbproj | 153 + .../DESCombine/DesCombineVB/Form1.resx | 148 + .../Editing/DESCombine/DesCombineVB/Form1.vb | 164 + .../DESCombine/DesCombineVB/readme.txt | 4 + .../Editing/DESCombine/TestCombine/App.ico | Bin 0 -> 1078 bytes .../DESCombine/TestCombine/AssemblyInfo.cs | 10 + .../Editing/DESCombine/TestCombine/Form1.cs | 838 +++ .../Editing/DESCombine/TestCombine/Form1.resx | 409 ++ .../Editing/DESCombine/TestCombine/Form2.cs | 271 + .../Editing/DESCombine/TestCombine/Form2.resx | 265 + .../TestCombine/TestCombine-2005.csproj | 120 + .../DESCombine/TestCombine/TestCombine.csproj | 165 + .../Editing/DESCombine/docs/DESCombine.chm | Bin 0 -> 35120 bytes Samples/Editing/DESCombine/readme.txt | 52 + Samples/Editing/DxScan/App.ico | Bin 0 -> 1078 bytes Samples/Editing/DxScan/AssemblyInfo.cs | 58 + Samples/Editing/DxScan/Capture.cs | 327 ++ Samples/Editing/DxScan/DxScan-2005.csproj | 113 + Samples/Editing/DxScan/DxScan-2005.sln | 19 + Samples/Editing/DxScan/DxScan-2008.sln | 19 + Samples/Editing/DxScan/DxScan.csproj | 145 + Samples/Editing/DxScan/Form1.cs | 206 + Samples/Editing/DxScan/Form1.resx | 202 + Samples/Editing/DxScan/readme.txt | 26 + Samples/Misc/BlackList/BlackList.csproj | 64 + Samples/Misc/BlackList/BlackList.sln | 20 + Samples/Misc/BlackList/BlackListManager.cs | 165 + Samples/Misc/BlackList/Program.cs | 33 + .../Misc/BlackList/Properties/AssemblyInfo.cs | 36 + Samples/Misc/BlackList/SimplePlayer.cs | 132 + Samples/Misc/BlackList/readme.txt | 38 + Samples/Misc/DxWebCam/Client/App.ico | Bin 0 -> 1078 bytes Samples/Misc/DxWebCam/Client/AssemblyInfo.cs | 58 + .../DxWebCam/Client/WebCamClient-2005.csproj | 106 + .../Misc/DxWebCam/Client/WebCamClient.csproj | 109 + Samples/Misc/DxWebCam/Client/WebClient.cs | 380 ++ Samples/Misc/DxWebCam/Client/WebClient.resx | 220 + Samples/Misc/DxWebCam/Client/readme.txt | 13 + Samples/Misc/DxWebCam/Service/AssemblyInfo.cs | 58 + Samples/Misc/DxWebCam/Service/Capture.cs | 445 ++ Samples/Misc/DxWebCam/Service/TcpServer.cs | 329 ++ .../Misc/DxWebCam/Service/WebCamInstaller.cs | 51 + .../DxWebCam/Service/WebCamInstaller.resx | 42 + .../Service/WebCamService-2005.csproj | 126 + .../Misc/DxWebCam/Service/WebCamService.cs | 364 ++ .../DxWebCam/Service/WebCamService.csproj | 131 + .../Misc/DxWebCam/Service/WebCamService.resx | 42 + Samples/Misc/DxWebCam/Service/readme.txt | 21 + Samples/Misc/DxWebCam/WebCamService-2005.sln | 25 + Samples/Misc/DxWebCam/WebCamService-2008.sln | 25 + Samples/Misc/DxWebCam/readme.txt | 25 + Samples/Misc/GMFPreview/GMFPreview-2008.sln | 20 + Samples/Misc/GMFPreview/GMFPreview.sln | 20 + .../GMFPreview/DeviceForm.Designer.cs | 97 + .../Misc/GMFPreview/GMFPreview/DeviceForm.cs | 97 + .../GMFPreview/GMFPreview/DeviceForm.resx | 120 + .../Misc/GMFPreview/GMFPreview/GMFBridge.cs | 99 + .../GMFPreview/GMFPreview-2005.csproj | 98 + .../GMFPreview/GMFPreview/GMFPreview.csproj | 108 + .../GMFPreview/MainForm.Designer.cs | 131 + .../Misc/GMFPreview/GMFPreview/MainForm.cs | 160 + .../Misc/GMFPreview/GMFPreview/MainForm.resx | 123 + .../GMFPreview/PreviewController.cs | 418 ++ Samples/Misc/GMFPreview/GMFPreview/Program.cs | 27 + .../GMFPreview/Properties/AssemblyInfo.cs | 33 + .../Properties/Resources.Designer.cs | 63 + .../GMFPreview/Properties/Resources.resx | 117 + .../Properties/Settings.Designer.cs | 26 + .../GMFPreview/Properties/Settings.settings | 7 + .../GMFPreview/Properties/app.manifest | 11 + Samples/Misc/GMFPreview/GMFPreview/readme.txt | 41 + Samples/Misc/GSSF/GSSF-2005.sln | 25 + Samples/Misc/GSSF/GSSF-2008.sln | 25 + Samples/Misc/GSSF/GSSF.ax | Bin 0 -> 81920 bytes Samples/Misc/GSSF/filter/PushGuids.h | 24 + .../Misc/GSSF/filter/PushSource-2005.vcproj | 301 + .../Misc/GSSF/filter/PushSource-2005.vcxproj | 179 + .../filter/PushSource-2005.vcxproj.filters | 34 + Samples/Misc/GSSF/filter/PushSource.def | 13 + Samples/Misc/GSSF/filter/PushSource.h | 108 + Samples/Misc/GSSF/filter/PushSource.rc | 22 + Samples/Misc/GSSF/filter/PushSourceBitmap.cpp | 363 ++ Samples/Misc/GSSF/filter/setup.cpp | 73 + Samples/Misc/GSSF/readme.txt | 156 + Samples/Misc/GSSF/render/App.ico | Bin 0 -> 1078 bytes Samples/Misc/GSSF/render/AssemblyInfo.cs | 65 + Samples/Misc/GSSF/render/BuildGraph.cs | 1032 ++++ Samples/Misc/GSSF/render/Form1.cs | 201 + Samples/Misc/GSSF/render/Form1.resx | 120 + Samples/Misc/GSSF/render/PushClasses.cs | 45 + Samples/Misc/GSSF/render/Render-2005.csproj | 115 + Samples/Misc/GSSF/render/Render.csproj | 120 + .../Misc/MediaDetector/MainForm.Designer.cs | 81 + Samples/Misc/MediaDetector/MainForm.cs | 39 + Samples/Misc/MediaDetector/MainForm.resx | 120 + .../Misc/MediaDetector/MediaDescription.cs | 100 + .../MediaDetector/MediaDetector-2005.csproj | 83 + .../Misc/MediaDetector/MediaDetector-2008.sln | 20 + Samples/Misc/MediaDetector/MediaDetector.cs | 186 + .../Misc/MediaDetector/MediaDetector.csproj | 119 + Samples/Misc/MediaDetector/MediaDetector.sln | 20 + Samples/Misc/MediaDetector/Program.cs | 20 + .../MediaDetector/Properties/AssemblyInfo.cs | 33 + .../Properties/Resources.Designer.cs | 63 + .../MediaDetector/Properties/Resources.resx | 117 + .../Properties/Settings.Designer.cs | 26 + .../Properties/Settings.settings | 7 + Samples/Misc/Toolkit/AssemblyInfo.cs | 58 + .../Toolkit/DirectShowLib.Utils-2005.csproj | 100 + .../Misc/Toolkit/DirectShowLib.Utils-2005.sln | 19 + .../Misc/Toolkit/DirectShowLib.Utils-2008.sln | 19 + .../Misc/Toolkit/DirectShowLib.Utils.csproj | 132 + Samples/Misc/Toolkit/DirectShowLib.Utils.ndoc | 40 + Samples/Misc/Toolkit/DirectShowLib.Utils.xml | 266 + Samples/Misc/Toolkit/FilterGraphTools.cs | 1015 ++++ Samples/Misc/Toolkit/doc/Documentation.chm | Bin 0 -> 28420 bytes Samples/Misc/Toolkit/readme.txt | 19 + Samples/Players/DvdPlay/App.ico | Bin 0 -> 1078 bytes Samples/Players/DvdPlay/AssemblyInfo.cs | 58 + Samples/Players/DvdPlay/DVDPlay-2005.csproj | 110 + Samples/Players/DvdPlay/DVDPlay-2005.sln | 19 + Samples/Players/DvdPlay/DVDPlay-2008.sln | 19 + Samples/Players/DvdPlay/DVDPlay.csproj | 142 + Samples/Players/DvdPlay/MainForm.cs | 1150 ++++ Samples/Players/DvdPlay/MainForm.resx | 259 + Samples/Players/DvdPlay/readme.txt | 15 + Samples/Players/DxPlay/App.ico | Bin 0 -> 1078 bytes Samples/Players/DxPlay/AssemblyInfo.cs | 58 + Samples/Players/DxPlay/Capture.cs | 485 ++ Samples/Players/DxPlay/DxPlay-2005.csproj | 119 + Samples/Players/DxPlay/DxPlay-2005.sln | 19 + Samples/Players/DxPlay/DxPlay-2008.sln | 19 + Samples/Players/DxPlay/DxPlay.csproj | 151 + Samples/Players/DxPlay/Form1.cs | 282 + Samples/Players/DxPlay/Form1.resx | 193 + Samples/Players/DxPlay/readme.txt | 15 + Samples/Players/DxText/App.ico | Bin 0 -> 1078 bytes Samples/Players/DxText/AssemblyInfo.cs | 58 + Samples/Players/DxText/Capture.cs | 428 ++ Samples/Players/DxText/DxText-2005.csproj | 119 + Samples/Players/DxText/DxText-2005.sln | 19 + Samples/Players/DxText/DxText-2008.sln | 19 + Samples/Players/DxText/DxText.cs | 245 + Samples/Players/DxText/DxText.csproj | 151 + Samples/Players/DxText/DxText.resx | 193 + Samples/Players/DxText/readme.txt | 34 + Samples/Players/EVRPlayer/ConvertImage.cs | 294 + Samples/Players/EVRPlayer/DShowPlayer.cs | 855 +++ Samples/Players/EVRPlayer/EVRPlayer-2008.sln | 20 + Samples/Players/EVRPlayer/EVRPlayer.csproj | 133 + Samples/Players/EVRPlayer/Form1.Designer.cs | 283 + Samples/Players/EVRPlayer/Form1.cs | 423 ++ Samples/Players/EVRPlayer/Form1.resx | 126 + Samples/Players/EVRPlayer/Overlay.cs | 941 +++ Samples/Players/EVRPlayer/Program.cs | 26 + Samples/Players/EVRPlayer/PushClasses2.cs | 68 + Samples/Players/EVRPlayer/ReadMe.txt | 30 + .../EVRPlayer/properties/AssemblyInfo.cs | 36 + .../properties/Resources.Designer.cs | 63 + .../EVRPlayer/properties/Resources.resx | 117 + .../EVRPlayer/properties/Settings.Designer.cs | 26 + .../EVRPlayer/properties/Settings.settings | 7 + Samples/Players/GMFPlay/GMFPlay-2008.sln | 20 + Samples/Players/GMFPlay/GMFPlay.sln | 20 + Samples/Players/GMFPlay/GMFPlay/ClipPlayer.cs | 920 +++ Samples/Players/GMFPlay/GMFPlay/GMFBridge.cs | 99 + .../GMFPlay/GMFPlay/GMFPlay-2005.csproj | 94 + .../Players/GMFPlay/GMFPlay/GMFPlay.csproj | 131 + .../GMFPlay/GMFPlay/Limits.Designer.cs | 139 + Samples/Players/GMFPlay/GMFPlay/Limits.cs | 36 + Samples/Players/GMFPlay/GMFPlay/Limits.resx | 120 + .../GMFPlay/GMFPlay/MainDlg.Designer.cs | 189 + Samples/Players/GMFPlay/GMFPlay/MainDlg.cs | 286 + Samples/Players/GMFPlay/GMFPlay/MainDlg.resx | 126 + Samples/Players/GMFPlay/GMFPlay/Program.cs | 27 + .../GMFPlay/Properties/AssemblyInfo.cs | 33 + .../GMFPlay/Properties/Resources.Designer.cs | 63 + .../GMFPlay/GMFPlay/Properties/Resources.resx | 117 + .../GMFPlay/Properties/Settings.Designer.cs | 26 + .../GMFPlay/Properties/Settings.settings | 7 + Samples/Players/GMFPlay/GMFPlay/readme.txt | 17 + Samples/Players/PlayVB/AssemblyInfo.vb | 39 + Samples/Players/PlayVB/Form1.resx | 139 + Samples/Players/PlayVB/Form1.vb | 103 + Samples/Players/PlayVB/PlayVB-2005.sln | 19 + Samples/Players/PlayVB/PlayVB-2005.vbproj | 119 + Samples/Players/PlayVB/PlayVB-2008.sln | 19 + Samples/Players/PlayVB/PlayVB.vbproj | 154 + Samples/Players/PlayVB/readme.txt | 1 + Samples/Players/PlayWnd/AboutBox.cs | 163 + Samples/Players/PlayWnd/AboutBox.resx | 184 + Samples/Players/PlayWnd/AssemblyInfo.cs | 58 + Samples/Players/PlayWnd/MainForm.cs | 1216 ++++ Samples/Players/PlayWnd/MainForm.resx | 310 + Samples/Players/PlayWnd/PlayWnd-2005.csproj | 122 + Samples/Players/PlayWnd/PlayWnd-2005.sln | 19 + Samples/Players/PlayWnd/PlayWnd-2008.sln | 19 + Samples/Players/PlayWnd/PlayWnd.csproj | 154 + Samples/Players/PlayWnd/playwnd.ico | Bin 0 -> 25214 bytes Samples/Players/PlayWnd/readme.txt | 14 + Samples/SBE/DvrMsCutter/App.ico | Bin 0 -> 1078 bytes Samples/SBE/DvrMsCutter/AssemblyInfo.cs | 58 + .../SBE/DvrMsCutter/DvrMsCutter-2005.csproj | 110 + Samples/SBE/DvrMsCutter/DvrMsCutter-2005.sln | 19 + Samples/SBE/DvrMsCutter/DvrMsCutter-2008.sln | 19 + Samples/SBE/DvrMsCutter/DvrMsCutter.csproj | 142 + Samples/SBE/DvrMsCutter/SBECutter.cs | 58 + Samples/SBE/DvrMsCutter/StartUp.cs | 68 + Samples/SBE/DvrMsCutter/readme.txt | 10 + .../SBE/DvrMsCutter2/DvrMsCutter2-2005.csproj | 53 + .../SBE/DvrMsCutter2/DvrMsCutter2-2008.sln | 20 + Samples/SBE/DvrMsCutter2/DvrMsCutter2.csproj | 89 + Samples/SBE/DvrMsCutter2/DvrMsCutter2.sln | 20 + Samples/SBE/DvrMsCutter2/Program.cs | 107 + .../DvrMsCutter2/Properties/AssemblyInfo.cs | 33 + Samples/SBE/DvrMsCutter2/SBECutter2.cs | 97 + Samples/SBE/DvrMsCutter2/readme.txt | 15 + Samples/VMR9/BitmapMixer/AboutBox.cs | 163 + Samples/VMR9/BitmapMixer/AboutBox.resx | 184 + Samples/VMR9/BitmapMixer/App.ico | Bin 0 -> 1078 bytes Samples/VMR9/BitmapMixer/AssemblyInfo.cs | 58 + Samples/VMR9/BitmapMixer/BitmapGenerator.cs | 128 + .../VMR9/BitmapMixer/BitmapMixer-2005.csproj | 130 + Samples/VMR9/BitmapMixer/BitmapMixer-2005.sln | 19 + Samples/VMR9/BitmapMixer/BitmapMixer-2008.sln | 19 + Samples/VMR9/BitmapMixer/BitmapMixer.csproj | 162 + Samples/VMR9/BitmapMixer/MainForm.cs | 572 ++ Samples/VMR9/BitmapMixer/MainForm.resx | 214 + Samples/VMR9/BitmapMixer/NativeMethodes.cs | 31 + Samples/VMR9/BitmapMixer/readme.txt | 30 + Samples/VMR9/VMR9Allocator/AboutBox.cs | 163 + Samples/VMR9/VMR9Allocator/AboutBox.resx | 184 + Samples/VMR9/VMR9Allocator/Allocator.cs | 452 ++ Samples/VMR9/VMR9Allocator/AssemblyInfo.cs | 58 + Samples/VMR9/VMR9Allocator/MainForm.cs | 321 + Samples/VMR9/VMR9Allocator/MainForm.resx | 615 ++ Samples/VMR9/VMR9Allocator/PlaneScene.cs | 193 + .../VMR9Allocator/VMR9Allocator-2005.csproj | 129 + .../VMR9/VMR9Allocator/VMR9Allocator-2005.sln | 19 + .../VMR9/VMR9Allocator/VMR9Allocator-2008.sln | 42 + .../VMR9/VMR9Allocator/VMR9Allocator.csproj | 217 + Samples/VMR9/VMR9Allocator/directx.ico | Bin 0 -> 25214 bytes Samples/VMR9/VMR9Allocator/readme.txt | 29 + Samples/VMR9/VMR9Allocator2/Allocator.cs | 379 ++ Samples/VMR9/VMR9Allocator2/App.ico | Bin 0 -> 1078 bytes Samples/VMR9/VMR9Allocator2/AssemblyInfo.cs | 58 + .../VMR9Allocator2/ConfigForm.Designer.cs | 190 + Samples/VMR9/VMR9Allocator2/ConfigForm.cs | 91 + Samples/VMR9/VMR9Allocator2/ConfigForm.resx | 120 + Samples/VMR9/VMR9Allocator2/MainForm.cs | 438 ++ Samples/VMR9/VMR9Allocator2/MainForm.resx | 42 + Samples/VMR9/VMR9Allocator2/NativeMethods.cs | 24 + Samples/VMR9/VMR9Allocator2/StartUp.cs | 66 + .../VMR9Allocator2/VMR9Allocator2-2005.csproj | 134 + .../VMR9Allocator2/VMR9Allocator2-2005.sln | 19 + .../VMR9Allocator2/VMR9Allocator2-2008.sln | 19 + .../VMR9/VMR9Allocator2/VMR9Allocator2.csproj | 166 + Samples/VMR9/VMR9Allocator2/readme.txt | 76 + Samples/VMR9/VMR9Compositor/AboutBox.resx | 184 + Samples/VMR9/VMR9Compositor/Aboutbox.cs | 163 + Samples/VMR9/VMR9Compositor/Compositor.cs | 244 + .../VMR9/VMR9Compositor/MainForm.Designer.cs | 143 + Samples/VMR9/VMR9Compositor/MainForm.cs | 236 + Samples/VMR9/VMR9Compositor/MainForm.resx | 129 + Samples/VMR9/VMR9Compositor/Program.cs | 30 + .../VMR9Compositor/Properties/AssemblyInfo.cs | 33 + .../Properties/Resources.Designer.cs | 63 + .../VMR9Compositor/Properties/Resources.resx | 121 + .../Properties/Settings.Designer.cs | 26 + .../Properties/Settings.settings | 7 + .../VMR9/VMR9Compositor/Vmr9Compositor.csproj | 137 + .../VMR9/VMR9Compositor/Vmr9Compositor.sln | 20 + Samples/VMR9/VMR9Compositor/readme.txt | 24 + Samples/VMR9/VMR9Compositor/redspider.png | Bin 0 -> 1859 bytes Samples/VMR9/VMR9Snapper/App.ico | Bin 0 -> 1078 bytes Samples/VMR9/VMR9Snapper/AssemblyInfo.cs | 58 + Samples/VMR9/VMR9Snapper/MainForm.cs | 529 ++ Samples/VMR9/VMR9Snapper/MainForm.resx | 132 + .../VMR9/VMR9Snapper/VMR9Snapper-2005.csproj | 118 + Samples/VMR9/VMR9Snapper/VMR9Snapper-2005.sln | 19 + Samples/VMR9/VMR9Snapper/VMR9Snapper-2008.sln | 19 + Samples/VMR9/VMR9Snapper/VMR9Snapper.csproj | 150 + Samples/VMR9/VMR9Snapper/readme.txt | 21 + Samples/lisezmoi-samples.txt | 207 + Samples/readme-samples.txt | 229 + 435 files changed, 79382 insertions(+), 1 deletion(-) create mode 100644 MediaFoundation/Alt.cs create mode 100644 MediaFoundation/EVR.cs create mode 100644 MediaFoundation/Externs.cs create mode 100644 MediaFoundation/MFIdl.cs create mode 100644 MediaFoundation/MFObjects.cs create mode 100644 MediaFoundation/MFPlay.cs create mode 100644 MediaFoundation/MFReadWrite.cs create mode 100644 MediaFoundation/MFTransform.cs create mode 100644 MediaFoundation/MFUtils.cs create mode 100644 MediaFoundation/MediaFoundation-2010.sln create mode 100644 MediaFoundation/MediaFoundation.csproj create mode 100644 MediaFoundation/MediaFoundation.snk create mode 100644 MediaFoundation/OpmApi.cs create mode 100644 MediaFoundation/Properties/AssemblyInfo.cs create mode 100644 MediaFoundation/WMContainer.cs create mode 100644 MediaFoundation/dxvahd.cs create mode 100644 MediaFoundation/mfmp2dlna.cs create mode 100644 MediaFoundation/misc.cs create mode 100644 Samples/BDA/DTVViewer/AboutBox.cs create mode 100644 Samples/BDA/DTVViewer/AboutBox.resx create mode 100644 Samples/BDA/DTVViewer/App.ico create mode 100644 Samples/BDA/DTVViewer/AssemblyInfo.cs create mode 100644 Samples/BDA/DTVViewer/BDAGraphBuilder.cs create mode 100644 Samples/BDA/DTVViewer/DTVViewer-2005.csproj create mode 100644 Samples/BDA/DTVViewer/DTVViewer-2005.sln create mode 100644 Samples/BDA/DTVViewer/DTVViewer-2008.sln create mode 100644 Samples/BDA/DTVViewer/DTVViewer.csproj create mode 100644 Samples/BDA/DTVViewer/DVBSTuning.cs create mode 100644 Samples/BDA/DTVViewer/DVBSTuning.resx create mode 100644 Samples/BDA/DTVViewer/DVBTTuning.cs create mode 100644 Samples/BDA/DTVViewer/DVBTTuning.resx create mode 100644 Samples/BDA/DTVViewer/ITuningSelector.cs create mode 100644 Samples/BDA/DTVViewer/MainForm.cs create mode 100644 Samples/BDA/DTVViewer/MainForm.resx create mode 100644 Samples/BDA/DTVViewer/StartUp.cs create mode 100644 Samples/BDA/DTVViewer/Toolkit/FilterGraphTools.cs create mode 100644 Samples/BDA/DTVViewer/readme.txt create mode 100644 Samples/Capture/CapWMV/App.ico create mode 100644 Samples/Capture/CapWMV/AssemblyInfo.cs create mode 100644 Samples/Capture/CapWMV/CapWMV-2005.csproj create mode 100644 Samples/Capture/CapWMV/CapWMV-2005.sln create mode 100644 Samples/Capture/CapWMV/CapWMV-2008.sln create mode 100644 Samples/Capture/CapWMV/CapWMV.csproj create mode 100644 Samples/Capture/CapWMV/Capture.cs create mode 100644 Samples/Capture/CapWMV/Form1.cs create mode 100644 Samples/Capture/CapWMV/Form1.resx create mode 100644 Samples/Capture/CapWMV/readme.txt create mode 100644 Samples/Capture/DxLogo/App.ico create mode 100644 Samples/Capture/DxLogo/AssemblyInfo.cs create mode 100644 Samples/Capture/DxLogo/Capture.cs create mode 100644 Samples/Capture/DxLogo/DxLogo-2005.csproj create mode 100644 Samples/Capture/DxLogo/DxLogo-2005.sln create mode 100644 Samples/Capture/DxLogo/DxLogo-2008.sln create mode 100644 Samples/Capture/DxLogo/DxLogo.csproj create mode 100644 Samples/Capture/DxLogo/Form1.cs create mode 100644 Samples/Capture/DxLogo/Form1.resx create mode 100644 Samples/Capture/DxLogo/lgs.jpg create mode 100644 Samples/Capture/DxLogo/readme.txt create mode 100644 Samples/Capture/DxLogoVB/AssemblyInfo.vb create mode 100644 Samples/Capture/DxLogoVB/Capture.vb create mode 100644 Samples/Capture/DxLogoVB/DxLogoVB-2005.sln create mode 100644 Samples/Capture/DxLogoVB/DxLogoVB-2005.vbproj create mode 100644 Samples/Capture/DxLogoVB/DxLogoVB-2008.sln create mode 100644 Samples/Capture/DxLogoVB/DxLogoVB.vbproj create mode 100644 Samples/Capture/DxLogoVB/Form1.resx create mode 100644 Samples/Capture/DxLogoVB/Form1.vb create mode 100644 Samples/Capture/DxLogoVB/readme.txt create mode 100644 Samples/Capture/DxPropPages/AssemblyInfo.cs create mode 100644 Samples/Capture/DxPropPages/DxPropPages-2005.csproj create mode 100644 Samples/Capture/DxPropPages/DxPropPages-2005.sln create mode 100644 Samples/Capture/DxPropPages/DxPropPages-2008.sln create mode 100644 Samples/Capture/DxPropPages/DxPropPages.csproj create mode 100644 Samples/Capture/DxPropPages/Form1.cs create mode 100644 Samples/Capture/DxPropPages/Form1.resx create mode 100644 Samples/Capture/DxPropPages/readme.txt create mode 100644 Samples/Capture/DxSnap/App.ico create mode 100644 Samples/Capture/DxSnap/AssemblyInfo.cs create mode 100644 Samples/Capture/DxSnap/Capture.cs create mode 100644 Samples/Capture/DxSnap/DxSnap-2005.csproj create mode 100644 Samples/Capture/DxSnap/DxSnap-2005.sln create mode 100644 Samples/Capture/DxSnap/DxSnap-2008.sln create mode 100644 Samples/Capture/DxSnap/DxSnap.csproj create mode 100644 Samples/Capture/DxSnap/Form1.cs create mode 100644 Samples/Capture/DxSnap/Form1.resx create mode 100644 Samples/Capture/DxSnap/readme.txt create mode 100644 Samples/Capture/DxTuner/AssemblyInfo.cs create mode 100644 Samples/Capture/DxTuner/DxTuner-2005.csproj create mode 100644 Samples/Capture/DxTuner/DxTuner-2005.sln create mode 100644 Samples/Capture/DxTuner/DxTuner-2008.sln create mode 100644 Samples/Capture/DxTuner/DxTuner.csproj create mode 100644 Samples/Capture/DxTuner/Form1.cs create mode 100644 Samples/Capture/DxTuner/Form1.resx create mode 100644 Samples/Capture/DxTuner/readme.txt create mode 100644 Samples/Capture/PlayCap/AssemblyInfo.cs create mode 100644 Samples/Capture/PlayCap/Form1.cs create mode 100644 Samples/Capture/PlayCap/Form1.resx create mode 100644 Samples/Capture/PlayCap/PlayCap-2005.csproj create mode 100644 Samples/Capture/PlayCap/PlayCap-2005.sln create mode 100644 Samples/Capture/PlayCap/PlayCap-2008.sln create mode 100644 Samples/Capture/PlayCap/PlayCap.csproj create mode 100644 Samples/Capture/PlayCap/playcap.ico create mode 100644 Samples/Capture/PlayCap/readme.txt create mode 100644 Samples/DMO/DmoFlip/DMO/AssemblyInfo.cs create mode 100644 Samples/DMO/DmoFlip/DMO/DmoFlip-2005.csproj create mode 100644 Samples/DMO/DmoFlip/DMO/DmoFlip.cs create mode 100644 Samples/DMO/DmoFlip/DMO/DmoFlip.csproj create mode 100644 Samples/DMO/DmoFlip/DMO/IMediaObjectImpl.cs create mode 100644 Samples/DMO/DmoFlip/DMO/docs/IMediaObjectImpl.chm create mode 100644 Samples/DMO/DmoFlip/DMO/mykey.snk create mode 100644 Samples/DMO/DmoFlip/DMO/readme.txt create mode 100644 Samples/DMO/DmoFlip/DmoFlip-2005.sln create mode 100644 Samples/DMO/DmoFlip/DmoFlip-2008.sln create mode 100644 Samples/DMO/DmoFlip/DmoFlip.ndoc create mode 100644 Samples/DMO/DmoFlip/FormDMO/App.ico create mode 100644 Samples/DMO/DmoFlip/FormDMO/AssemblyInfo.cs create mode 100644 Samples/DMO/DmoFlip/FormDMO/Form1.cs create mode 100644 Samples/DMO/DmoFlip/FormDMO/Form1.resx create mode 100644 Samples/DMO/DmoFlip/FormDMO/FormDMO-2005.csproj create mode 100644 Samples/DMO/DmoFlip/FormDMO/FormDmoFlip.csproj create mode 100644 Samples/DMO/DmoFlip/FormDMO/readme.txt create mode 100644 Samples/DMO/DmoFlip/readme.txt create mode 100644 Samples/DMO/DmoSplit/DMO/AssemblyInfo.cs create mode 100644 Samples/DMO/DmoSplit/DMO/DmoSplit-2005.csproj create mode 100644 Samples/DMO/DmoSplit/DMO/DmoSplit.cs create mode 100644 Samples/DMO/DmoSplit/DMO/DmoSplit.csproj create mode 100644 Samples/DMO/DmoSplit/DMO/IMediaObjectImpl.cs create mode 100644 Samples/DMO/DmoSplit/DMO/mykey.snk create mode 100644 Samples/DMO/DmoSplit/DMO/readme.txt create mode 100644 Samples/DMO/DmoSplit/DmoSplit-2005.sln create mode 100644 Samples/DMO/DmoSplit/DmoSplit-2008.sln create mode 100644 Samples/DMO/DmoSplit/FormDMO/App.ico create mode 100644 Samples/DMO/DmoSplit/FormDMO/AssemblyInfo.cs create mode 100644 Samples/DMO/DmoSplit/FormDMO/Form1.cs create mode 100644 Samples/DMO/DmoSplit/FormDMO/Form1.resx create mode 100644 Samples/DMO/DmoSplit/FormDMO/FormDMO-2005.csproj create mode 100644 Samples/DMO/DmoSplit/FormDMO/FormDmoSplit.csproj create mode 100644 Samples/DMO/DmoSplit/FormDMO/readme.txt create mode 100644 Samples/DMO/DmoSplit/readme.txt create mode 100644 Samples/Editing/DESCombine/DESCombine-2005.sln create mode 100644 Samples/Editing/DESCombine/DESCombine-2008.sln create mode 100644 Samples/Editing/DESCombine/DESCombine.ndoc create mode 100644 Samples/Editing/DESCombine/DESCombineLib/AssemblyInfo.cs create mode 100644 Samples/Editing/DESCombine/DESCombineLib/DESCombine.cs create mode 100644 Samples/Editing/DESCombine/DESCombineLib/DESCombineLib-2005.csproj create mode 100644 Samples/Editing/DESCombine/DESCombineLib/DESCombineLib.csproj create mode 100644 Samples/Editing/DESCombine/DesCombineVB/AssemblyInfo.vb create mode 100644 Samples/Editing/DESCombine/DesCombineVB/DesCombineVB-2005.sln create mode 100644 Samples/Editing/DESCombine/DesCombineVB/DesCombineVB-2005.vbproj create mode 100644 Samples/Editing/DESCombine/DesCombineVB/DesCombineVB-2008.sln create mode 100644 Samples/Editing/DESCombine/DesCombineVB/DesCombineVB.vbproj create mode 100644 Samples/Editing/DESCombine/DesCombineVB/Form1.resx create mode 100644 Samples/Editing/DESCombine/DesCombineVB/Form1.vb create mode 100644 Samples/Editing/DESCombine/DesCombineVB/readme.txt create mode 100644 Samples/Editing/DESCombine/TestCombine/App.ico create mode 100644 Samples/Editing/DESCombine/TestCombine/AssemblyInfo.cs create mode 100644 Samples/Editing/DESCombine/TestCombine/Form1.cs create mode 100644 Samples/Editing/DESCombine/TestCombine/Form1.resx create mode 100644 Samples/Editing/DESCombine/TestCombine/Form2.cs create mode 100644 Samples/Editing/DESCombine/TestCombine/Form2.resx create mode 100644 Samples/Editing/DESCombine/TestCombine/TestCombine-2005.csproj create mode 100644 Samples/Editing/DESCombine/TestCombine/TestCombine.csproj create mode 100644 Samples/Editing/DESCombine/docs/DESCombine.chm create mode 100644 Samples/Editing/DESCombine/readme.txt create mode 100644 Samples/Editing/DxScan/App.ico create mode 100644 Samples/Editing/DxScan/AssemblyInfo.cs create mode 100644 Samples/Editing/DxScan/Capture.cs create mode 100644 Samples/Editing/DxScan/DxScan-2005.csproj create mode 100644 Samples/Editing/DxScan/DxScan-2005.sln create mode 100644 Samples/Editing/DxScan/DxScan-2008.sln create mode 100644 Samples/Editing/DxScan/DxScan.csproj create mode 100644 Samples/Editing/DxScan/Form1.cs create mode 100644 Samples/Editing/DxScan/Form1.resx create mode 100644 Samples/Editing/DxScan/readme.txt create mode 100644 Samples/Misc/BlackList/BlackList.csproj create mode 100644 Samples/Misc/BlackList/BlackList.sln create mode 100644 Samples/Misc/BlackList/BlackListManager.cs create mode 100644 Samples/Misc/BlackList/Program.cs create mode 100644 Samples/Misc/BlackList/Properties/AssemblyInfo.cs create mode 100644 Samples/Misc/BlackList/SimplePlayer.cs create mode 100644 Samples/Misc/BlackList/readme.txt create mode 100644 Samples/Misc/DxWebCam/Client/App.ico create mode 100644 Samples/Misc/DxWebCam/Client/AssemblyInfo.cs create mode 100644 Samples/Misc/DxWebCam/Client/WebCamClient-2005.csproj create mode 100644 Samples/Misc/DxWebCam/Client/WebCamClient.csproj create mode 100644 Samples/Misc/DxWebCam/Client/WebClient.cs create mode 100644 Samples/Misc/DxWebCam/Client/WebClient.resx create mode 100644 Samples/Misc/DxWebCam/Client/readme.txt create mode 100644 Samples/Misc/DxWebCam/Service/AssemblyInfo.cs create mode 100644 Samples/Misc/DxWebCam/Service/Capture.cs create mode 100644 Samples/Misc/DxWebCam/Service/TcpServer.cs create mode 100644 Samples/Misc/DxWebCam/Service/WebCamInstaller.cs create mode 100644 Samples/Misc/DxWebCam/Service/WebCamInstaller.resx create mode 100644 Samples/Misc/DxWebCam/Service/WebCamService-2005.csproj create mode 100644 Samples/Misc/DxWebCam/Service/WebCamService.cs create mode 100644 Samples/Misc/DxWebCam/Service/WebCamService.csproj create mode 100644 Samples/Misc/DxWebCam/Service/WebCamService.resx create mode 100644 Samples/Misc/DxWebCam/Service/readme.txt create mode 100644 Samples/Misc/DxWebCam/WebCamService-2005.sln create mode 100644 Samples/Misc/DxWebCam/WebCamService-2008.sln create mode 100644 Samples/Misc/DxWebCam/readme.txt create mode 100644 Samples/Misc/GMFPreview/GMFPreview-2008.sln create mode 100644 Samples/Misc/GMFPreview/GMFPreview.sln create mode 100644 Samples/Misc/GMFPreview/GMFPreview/DeviceForm.Designer.cs create mode 100644 Samples/Misc/GMFPreview/GMFPreview/DeviceForm.cs create mode 100644 Samples/Misc/GMFPreview/GMFPreview/DeviceForm.resx create mode 100644 Samples/Misc/GMFPreview/GMFPreview/GMFBridge.cs create mode 100644 Samples/Misc/GMFPreview/GMFPreview/GMFPreview-2005.csproj create mode 100644 Samples/Misc/GMFPreview/GMFPreview/GMFPreview.csproj create mode 100644 Samples/Misc/GMFPreview/GMFPreview/MainForm.Designer.cs create mode 100644 Samples/Misc/GMFPreview/GMFPreview/MainForm.cs create mode 100644 Samples/Misc/GMFPreview/GMFPreview/MainForm.resx create mode 100644 Samples/Misc/GMFPreview/GMFPreview/PreviewController.cs create mode 100644 Samples/Misc/GMFPreview/GMFPreview/Program.cs create mode 100644 Samples/Misc/GMFPreview/GMFPreview/Properties/AssemblyInfo.cs create mode 100644 Samples/Misc/GMFPreview/GMFPreview/Properties/Resources.Designer.cs create mode 100644 Samples/Misc/GMFPreview/GMFPreview/Properties/Resources.resx create mode 100644 Samples/Misc/GMFPreview/GMFPreview/Properties/Settings.Designer.cs create mode 100644 Samples/Misc/GMFPreview/GMFPreview/Properties/Settings.settings create mode 100644 Samples/Misc/GMFPreview/GMFPreview/Properties/app.manifest create mode 100644 Samples/Misc/GMFPreview/GMFPreview/readme.txt create mode 100644 Samples/Misc/GSSF/GSSF-2005.sln create mode 100644 Samples/Misc/GSSF/GSSF-2008.sln create mode 100644 Samples/Misc/GSSF/GSSF.ax create mode 100644 Samples/Misc/GSSF/filter/PushGuids.h create mode 100644 Samples/Misc/GSSF/filter/PushSource-2005.vcproj create mode 100644 Samples/Misc/GSSF/filter/PushSource-2005.vcxproj create mode 100644 Samples/Misc/GSSF/filter/PushSource-2005.vcxproj.filters create mode 100644 Samples/Misc/GSSF/filter/PushSource.def create mode 100644 Samples/Misc/GSSF/filter/PushSource.h create mode 100644 Samples/Misc/GSSF/filter/PushSource.rc create mode 100644 Samples/Misc/GSSF/filter/PushSourceBitmap.cpp create mode 100644 Samples/Misc/GSSF/filter/setup.cpp create mode 100644 Samples/Misc/GSSF/readme.txt create mode 100644 Samples/Misc/GSSF/render/App.ico create mode 100644 Samples/Misc/GSSF/render/AssemblyInfo.cs create mode 100644 Samples/Misc/GSSF/render/BuildGraph.cs create mode 100644 Samples/Misc/GSSF/render/Form1.cs create mode 100644 Samples/Misc/GSSF/render/Form1.resx create mode 100644 Samples/Misc/GSSF/render/PushClasses.cs create mode 100644 Samples/Misc/GSSF/render/Render-2005.csproj create mode 100644 Samples/Misc/GSSF/render/Render.csproj create mode 100644 Samples/Misc/MediaDetector/MainForm.Designer.cs create mode 100644 Samples/Misc/MediaDetector/MainForm.cs create mode 100644 Samples/Misc/MediaDetector/MainForm.resx create mode 100644 Samples/Misc/MediaDetector/MediaDescription.cs create mode 100644 Samples/Misc/MediaDetector/MediaDetector-2005.csproj create mode 100644 Samples/Misc/MediaDetector/MediaDetector-2008.sln create mode 100644 Samples/Misc/MediaDetector/MediaDetector.cs create mode 100644 Samples/Misc/MediaDetector/MediaDetector.csproj create mode 100644 Samples/Misc/MediaDetector/MediaDetector.sln create mode 100644 Samples/Misc/MediaDetector/Program.cs create mode 100644 Samples/Misc/MediaDetector/Properties/AssemblyInfo.cs create mode 100644 Samples/Misc/MediaDetector/Properties/Resources.Designer.cs create mode 100644 Samples/Misc/MediaDetector/Properties/Resources.resx create mode 100644 Samples/Misc/MediaDetector/Properties/Settings.Designer.cs create mode 100644 Samples/Misc/MediaDetector/Properties/Settings.settings create mode 100644 Samples/Misc/Toolkit/AssemblyInfo.cs create mode 100644 Samples/Misc/Toolkit/DirectShowLib.Utils-2005.csproj create mode 100644 Samples/Misc/Toolkit/DirectShowLib.Utils-2005.sln create mode 100644 Samples/Misc/Toolkit/DirectShowLib.Utils-2008.sln create mode 100644 Samples/Misc/Toolkit/DirectShowLib.Utils.csproj create mode 100644 Samples/Misc/Toolkit/DirectShowLib.Utils.ndoc create mode 100644 Samples/Misc/Toolkit/DirectShowLib.Utils.xml create mode 100644 Samples/Misc/Toolkit/FilterGraphTools.cs create mode 100644 Samples/Misc/Toolkit/doc/Documentation.chm create mode 100644 Samples/Misc/Toolkit/readme.txt create mode 100644 Samples/Players/DvdPlay/App.ico create mode 100644 Samples/Players/DvdPlay/AssemblyInfo.cs create mode 100644 Samples/Players/DvdPlay/DVDPlay-2005.csproj create mode 100644 Samples/Players/DvdPlay/DVDPlay-2005.sln create mode 100644 Samples/Players/DvdPlay/DVDPlay-2008.sln create mode 100644 Samples/Players/DvdPlay/DVDPlay.csproj create mode 100644 Samples/Players/DvdPlay/MainForm.cs create mode 100644 Samples/Players/DvdPlay/MainForm.resx create mode 100644 Samples/Players/DvdPlay/readme.txt create mode 100644 Samples/Players/DxPlay/App.ico create mode 100644 Samples/Players/DxPlay/AssemblyInfo.cs create mode 100644 Samples/Players/DxPlay/Capture.cs create mode 100644 Samples/Players/DxPlay/DxPlay-2005.csproj create mode 100644 Samples/Players/DxPlay/DxPlay-2005.sln create mode 100644 Samples/Players/DxPlay/DxPlay-2008.sln create mode 100644 Samples/Players/DxPlay/DxPlay.csproj create mode 100644 Samples/Players/DxPlay/Form1.cs create mode 100644 Samples/Players/DxPlay/Form1.resx create mode 100644 Samples/Players/DxPlay/readme.txt create mode 100644 Samples/Players/DxText/App.ico create mode 100644 Samples/Players/DxText/AssemblyInfo.cs create mode 100644 Samples/Players/DxText/Capture.cs create mode 100644 Samples/Players/DxText/DxText-2005.csproj create mode 100644 Samples/Players/DxText/DxText-2005.sln create mode 100644 Samples/Players/DxText/DxText-2008.sln create mode 100644 Samples/Players/DxText/DxText.cs create mode 100644 Samples/Players/DxText/DxText.csproj create mode 100644 Samples/Players/DxText/DxText.resx create mode 100644 Samples/Players/DxText/readme.txt create mode 100644 Samples/Players/EVRPlayer/ConvertImage.cs create mode 100644 Samples/Players/EVRPlayer/DShowPlayer.cs create mode 100644 Samples/Players/EVRPlayer/EVRPlayer-2008.sln create mode 100644 Samples/Players/EVRPlayer/EVRPlayer.csproj create mode 100644 Samples/Players/EVRPlayer/Form1.Designer.cs create mode 100644 Samples/Players/EVRPlayer/Form1.cs create mode 100644 Samples/Players/EVRPlayer/Form1.resx create mode 100644 Samples/Players/EVRPlayer/Overlay.cs create mode 100644 Samples/Players/EVRPlayer/Program.cs create mode 100644 Samples/Players/EVRPlayer/PushClasses2.cs create mode 100644 Samples/Players/EVRPlayer/ReadMe.txt create mode 100644 Samples/Players/EVRPlayer/properties/AssemblyInfo.cs create mode 100644 Samples/Players/EVRPlayer/properties/Resources.Designer.cs create mode 100644 Samples/Players/EVRPlayer/properties/Resources.resx create mode 100644 Samples/Players/EVRPlayer/properties/Settings.Designer.cs create mode 100644 Samples/Players/EVRPlayer/properties/Settings.settings create mode 100644 Samples/Players/GMFPlay/GMFPlay-2008.sln create mode 100644 Samples/Players/GMFPlay/GMFPlay.sln create mode 100644 Samples/Players/GMFPlay/GMFPlay/ClipPlayer.cs create mode 100644 Samples/Players/GMFPlay/GMFPlay/GMFBridge.cs create mode 100644 Samples/Players/GMFPlay/GMFPlay/GMFPlay-2005.csproj create mode 100644 Samples/Players/GMFPlay/GMFPlay/GMFPlay.csproj create mode 100644 Samples/Players/GMFPlay/GMFPlay/Limits.Designer.cs create mode 100644 Samples/Players/GMFPlay/GMFPlay/Limits.cs create mode 100644 Samples/Players/GMFPlay/GMFPlay/Limits.resx create mode 100644 Samples/Players/GMFPlay/GMFPlay/MainDlg.Designer.cs create mode 100644 Samples/Players/GMFPlay/GMFPlay/MainDlg.cs create mode 100644 Samples/Players/GMFPlay/GMFPlay/MainDlg.resx create mode 100644 Samples/Players/GMFPlay/GMFPlay/Program.cs create mode 100644 Samples/Players/GMFPlay/GMFPlay/Properties/AssemblyInfo.cs create mode 100644 Samples/Players/GMFPlay/GMFPlay/Properties/Resources.Designer.cs create mode 100644 Samples/Players/GMFPlay/GMFPlay/Properties/Resources.resx create mode 100644 Samples/Players/GMFPlay/GMFPlay/Properties/Settings.Designer.cs create mode 100644 Samples/Players/GMFPlay/GMFPlay/Properties/Settings.settings create mode 100644 Samples/Players/GMFPlay/GMFPlay/readme.txt create mode 100644 Samples/Players/PlayVB/AssemblyInfo.vb create mode 100644 Samples/Players/PlayVB/Form1.resx create mode 100644 Samples/Players/PlayVB/Form1.vb create mode 100644 Samples/Players/PlayVB/PlayVB-2005.sln create mode 100644 Samples/Players/PlayVB/PlayVB-2005.vbproj create mode 100644 Samples/Players/PlayVB/PlayVB-2008.sln create mode 100644 Samples/Players/PlayVB/PlayVB.vbproj create mode 100644 Samples/Players/PlayVB/readme.txt create mode 100644 Samples/Players/PlayWnd/AboutBox.cs create mode 100644 Samples/Players/PlayWnd/AboutBox.resx create mode 100644 Samples/Players/PlayWnd/AssemblyInfo.cs create mode 100644 Samples/Players/PlayWnd/MainForm.cs create mode 100644 Samples/Players/PlayWnd/MainForm.resx create mode 100644 Samples/Players/PlayWnd/PlayWnd-2005.csproj create mode 100644 Samples/Players/PlayWnd/PlayWnd-2005.sln create mode 100644 Samples/Players/PlayWnd/PlayWnd-2008.sln create mode 100644 Samples/Players/PlayWnd/PlayWnd.csproj create mode 100644 Samples/Players/PlayWnd/playwnd.ico create mode 100644 Samples/Players/PlayWnd/readme.txt create mode 100644 Samples/SBE/DvrMsCutter/App.ico create mode 100644 Samples/SBE/DvrMsCutter/AssemblyInfo.cs create mode 100644 Samples/SBE/DvrMsCutter/DvrMsCutter-2005.csproj create mode 100644 Samples/SBE/DvrMsCutter/DvrMsCutter-2005.sln create mode 100644 Samples/SBE/DvrMsCutter/DvrMsCutter-2008.sln create mode 100644 Samples/SBE/DvrMsCutter/DvrMsCutter.csproj create mode 100644 Samples/SBE/DvrMsCutter/SBECutter.cs create mode 100644 Samples/SBE/DvrMsCutter/StartUp.cs create mode 100644 Samples/SBE/DvrMsCutter/readme.txt create mode 100644 Samples/SBE/DvrMsCutter2/DvrMsCutter2-2005.csproj create mode 100644 Samples/SBE/DvrMsCutter2/DvrMsCutter2-2008.sln create mode 100644 Samples/SBE/DvrMsCutter2/DvrMsCutter2.csproj create mode 100644 Samples/SBE/DvrMsCutter2/DvrMsCutter2.sln create mode 100644 Samples/SBE/DvrMsCutter2/Program.cs create mode 100644 Samples/SBE/DvrMsCutter2/Properties/AssemblyInfo.cs create mode 100644 Samples/SBE/DvrMsCutter2/SBECutter2.cs create mode 100644 Samples/SBE/DvrMsCutter2/readme.txt create mode 100644 Samples/VMR9/BitmapMixer/AboutBox.cs create mode 100644 Samples/VMR9/BitmapMixer/AboutBox.resx create mode 100644 Samples/VMR9/BitmapMixer/App.ico create mode 100644 Samples/VMR9/BitmapMixer/AssemblyInfo.cs create mode 100644 Samples/VMR9/BitmapMixer/BitmapGenerator.cs create mode 100644 Samples/VMR9/BitmapMixer/BitmapMixer-2005.csproj create mode 100644 Samples/VMR9/BitmapMixer/BitmapMixer-2005.sln create mode 100644 Samples/VMR9/BitmapMixer/BitmapMixer-2008.sln create mode 100644 Samples/VMR9/BitmapMixer/BitmapMixer.csproj create mode 100644 Samples/VMR9/BitmapMixer/MainForm.cs create mode 100644 Samples/VMR9/BitmapMixer/MainForm.resx create mode 100644 Samples/VMR9/BitmapMixer/NativeMethodes.cs create mode 100644 Samples/VMR9/BitmapMixer/readme.txt create mode 100644 Samples/VMR9/VMR9Allocator/AboutBox.cs create mode 100644 Samples/VMR9/VMR9Allocator/AboutBox.resx create mode 100644 Samples/VMR9/VMR9Allocator/Allocator.cs create mode 100644 Samples/VMR9/VMR9Allocator/AssemblyInfo.cs create mode 100644 Samples/VMR9/VMR9Allocator/MainForm.cs create mode 100644 Samples/VMR9/VMR9Allocator/MainForm.resx create mode 100644 Samples/VMR9/VMR9Allocator/PlaneScene.cs create mode 100644 Samples/VMR9/VMR9Allocator/VMR9Allocator-2005.csproj create mode 100644 Samples/VMR9/VMR9Allocator/VMR9Allocator-2005.sln create mode 100644 Samples/VMR9/VMR9Allocator/VMR9Allocator-2008.sln create mode 100644 Samples/VMR9/VMR9Allocator/VMR9Allocator.csproj create mode 100644 Samples/VMR9/VMR9Allocator/directx.ico create mode 100644 Samples/VMR9/VMR9Allocator/readme.txt create mode 100644 Samples/VMR9/VMR9Allocator2/Allocator.cs create mode 100644 Samples/VMR9/VMR9Allocator2/App.ico create mode 100644 Samples/VMR9/VMR9Allocator2/AssemblyInfo.cs create mode 100644 Samples/VMR9/VMR9Allocator2/ConfigForm.Designer.cs create mode 100644 Samples/VMR9/VMR9Allocator2/ConfigForm.cs create mode 100644 Samples/VMR9/VMR9Allocator2/ConfigForm.resx create mode 100644 Samples/VMR9/VMR9Allocator2/MainForm.cs create mode 100644 Samples/VMR9/VMR9Allocator2/MainForm.resx create mode 100644 Samples/VMR9/VMR9Allocator2/NativeMethods.cs create mode 100644 Samples/VMR9/VMR9Allocator2/StartUp.cs create mode 100644 Samples/VMR9/VMR9Allocator2/VMR9Allocator2-2005.csproj create mode 100644 Samples/VMR9/VMR9Allocator2/VMR9Allocator2-2005.sln create mode 100644 Samples/VMR9/VMR9Allocator2/VMR9Allocator2-2008.sln create mode 100644 Samples/VMR9/VMR9Allocator2/VMR9Allocator2.csproj create mode 100644 Samples/VMR9/VMR9Allocator2/readme.txt create mode 100644 Samples/VMR9/VMR9Compositor/AboutBox.resx create mode 100644 Samples/VMR9/VMR9Compositor/Aboutbox.cs create mode 100644 Samples/VMR9/VMR9Compositor/Compositor.cs create mode 100644 Samples/VMR9/VMR9Compositor/MainForm.Designer.cs create mode 100644 Samples/VMR9/VMR9Compositor/MainForm.cs create mode 100644 Samples/VMR9/VMR9Compositor/MainForm.resx create mode 100644 Samples/VMR9/VMR9Compositor/Program.cs create mode 100644 Samples/VMR9/VMR9Compositor/Properties/AssemblyInfo.cs create mode 100644 Samples/VMR9/VMR9Compositor/Properties/Resources.Designer.cs create mode 100644 Samples/VMR9/VMR9Compositor/Properties/Resources.resx create mode 100644 Samples/VMR9/VMR9Compositor/Properties/Settings.Designer.cs create mode 100644 Samples/VMR9/VMR9Compositor/Properties/Settings.settings create mode 100644 Samples/VMR9/VMR9Compositor/Vmr9Compositor.csproj create mode 100644 Samples/VMR9/VMR9Compositor/Vmr9Compositor.sln create mode 100644 Samples/VMR9/VMR9Compositor/readme.txt create mode 100644 Samples/VMR9/VMR9Compositor/redspider.png create mode 100644 Samples/VMR9/VMR9Snapper/App.ico create mode 100644 Samples/VMR9/VMR9Snapper/AssemblyInfo.cs create mode 100644 Samples/VMR9/VMR9Snapper/MainForm.cs create mode 100644 Samples/VMR9/VMR9Snapper/MainForm.resx create mode 100644 Samples/VMR9/VMR9Snapper/VMR9Snapper-2005.csproj create mode 100644 Samples/VMR9/VMR9Snapper/VMR9Snapper-2005.sln create mode 100644 Samples/VMR9/VMR9Snapper/VMR9Snapper-2008.sln create mode 100644 Samples/VMR9/VMR9Snapper/VMR9Snapper.csproj create mode 100644 Samples/VMR9/VMR9Snapper/readme.txt create mode 100644 Samples/lisezmoi-samples.txt create mode 100644 Samples/readme-samples.txt diff --git a/DirectShowLib.sln b/DirectShowLib.sln index 16cf0f7..4a2f063 100644 --- a/DirectShowLib.sln +++ b/DirectShowLib.sln @@ -1,20 +1,762 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DirectShowLib", "DirectShowLib\DirectShowLib.csproj", "{CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{16D68FD3-F9CD-41D1-B414-9CF7BD07D41B}" + ProjectSection(SolutionItems) = preProject + Samples\readme-samples.txt = Samples\readme-samples.txt + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BDA", "BDA", "{AC6FF501-EE0F-4BA5-B43C-1962161EDF98}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DTVViewer", "Samples\BDA\DTVViewer\DTVViewer.csproj", "{F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Capture", "Capture", "{74AC32C9-EFBB-4DBB-83F5-8DBA0814C42B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DMO", "DMO", "{59A24CFF-BFA4-4F51-A1A7-61B46A5E2BB2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Editing", "Editing", "{DFA3A219-BCD1-4A18-8335-CD7CE6B46D7F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Misc", "Misc", "{FB66AC78-B6D0-44EB-A046-6ABBB3772095}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Players", "Players", "{10B2014A-7C7A-4589-8AA4-0F2609F8B7A3}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SBE", "SBE", "{C0985EC3-0F2C-4E8D-9851-AF7ECE30BC1A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "VMR9", "VMR9", "{3E262EA8-9A2C-477F-8A7C-CBD5309D8E48}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CapWMV", "Samples\Capture\CapWMV\CapWMV.csproj", "{1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DxLogo", "Samples\Capture\DxLogo\DxLogo.csproj", "{17379614-821C-4504-B45D-BBACC866EBFB}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "DxLogoVB", "Samples\Capture\DxLogoVB\DxLogoVB.vbproj", "{8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DxPropPages", "Samples\Capture\DxPropPages\DxPropPages.csproj", "{4AC57653-233F-4862-AF88-139A1D02A007}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DxSnap", "Samples\Capture\DxSnap\DxSnap.csproj", "{E6052609-A070-41D5-85B9-ACABA91170C5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DxTuner", "Samples\Capture\DxTuner\DxTuner.csproj", "{EAB509E6-7797-4911-A201-2FA515386193}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlayCap", "Samples\Capture\PlayCap\PlayCap.csproj", "{156F9A0F-C89B-42D5-9636-0047FE0923CE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DmoFlip", "Samples\DMO\DmoFlip\DMO\DmoFlip.csproj", "{369D647A-7F80-4F06-BEDB-D62AC1627862}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FormDmoFlip", "Samples\DMO\DmoFlip\FormDMO\FormDmoFlip.csproj", "{B72919DC-C5B9-441A-9AD9-6CF9A97AFE85}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DmoSplit", "Samples\DMO\DmoSplit\DMO\DmoSplit.csproj", "{461D3FBA-AD10-4E6E-A1BE-0686547E9B1F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DmoFlip", "DmoFlip", "{1A4540F8-3CB7-4FD7-A856-F08619247021}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DmoSplit", "DmoSplit", "{51420ACE-F02B-4BF8-83FE-72485CC1C8D9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FormDmoSplit", "Samples\DMO\DmoSplit\FormDMO\FormDmoSplit.csproj", "{D6EE33A0-7EAF-4C98-8E2F-7CD39DE72BB2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DESCombineLib", "Samples\Editing\DESCombine\DESCombineLib\DESCombineLib.csproj", "{A10D4671-34C7-4AD8-B537-B2B9C48242F7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DESCombine", "DESCombine", "{0DDD778C-ECB7-43BD-BC24-50D05DA6053F}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "DesCombineVB", "Samples\Editing\DESCombine\DesCombineVB\DesCombineVB.vbproj", "{BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestCombine", "Samples\Editing\DESCombine\TestCombine\TestCombine.csproj", "{B20FEBE5-4895-4930-8017-C7614AB6C49B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DxScan", "Samples\Editing\DxScan\DxScan.csproj", "{4AA43B9C-E987-43BA-A438-B6FDC7DACBD5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DxWebCam", "DxWebCam", "{E31614E8-9AE9-4E22-804D-6066C03BAFF2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlackList", "Samples\Misc\BlackList\BlackList.csproj", "{0178D2F5-5AC7-4B9F-8696-6E1AF14ED013}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebCamService", "Samples\Misc\DxWebCam\Service\WebCamService.csproj", "{5D949877-7015-40CA-83E5-D516C1C2BA97}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebCamClient", "Samples\Misc\DxWebCam\Client\WebCamClient.csproj", "{4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GMFPreview", "Samples\Misc\GMFPreview\GMFPreview\GMFPreview.csproj", "{0E756677-5CB9-488B-B54A-55B32BF087D6}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GSSF", "GSSF", "{94DFCEAC-8CFD-44D6-8C1E-6499411D925C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GenericSampleSourceFilter", "Samples\Misc\GSSF\filter\PushSource-2005.vcxproj", "{70B24BBF-E59F-4F91-A74B-01288E1DECB3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Render", "Samples\Misc\GSSF\render\Render.csproj", "{6E8BB66C-D141-4333-8311-3CF33FACEC1B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaDetector", "Samples\Misc\MediaDetector\MediaDetector.csproj", "{4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DirectShowLib.Utils", "Samples\Misc\Toolkit\DirectShowLib.Utils.csproj", "{FA72F510-5B39-43EC-BA62-04C6F90BD524}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DVDPlay", "Samples\Players\DvdPlay\DVDPlay.csproj", "{00DC331B-E105-44F0-829E-80C2E1120D2F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DxPlay", "Samples\Players\DxPlay\DxPlay.csproj", "{0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DxText", "Samples\Players\DxText\DxText.csproj", "{B0BB5DBF-3B99-4E4E-8793-984153C7D21F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EVRPlayer", "Samples\Players\EVRPlayer\EVRPlayer.csproj", "{4C65947E-100E-4176-B893-C3067ED8DC11}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GMFPlay", "Samples\Players\GMFPlay\GMFPlay\GMFPlay.csproj", "{FE48353B-7945-400B-87B2-660BE9225083}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "PlayVB", "Samples\Players\PlayVB\PlayVB.vbproj", "{72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlayWnd", "Samples\Players\PlayWnd\PlayWnd.csproj", "{20FBEEA4-92C2-409E-9448-219CE60C0041}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaFoundation", "MediaFoundation\MediaFoundation.csproj", "{B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DvrMsCutter", "Samples\SBE\DvrMsCutter\DvrMsCutter.csproj", "{58BA266F-B6DF-4096-8816-6A97C0A343E7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DvrMsCutter2", "Samples\SBE\DvrMsCutter2\DvrMsCutter2.csproj", "{2BB69C76-D153-48A0-95B9-710550D63986}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BitmapMixer", "Samples\VMR9\BitmapMixer\BitmapMixer.csproj", "{4682D111-4503-448E-B5F4-93358502C229}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VMR9Allocator", "Samples\VMR9\VMR9Allocator\VMR9Allocator.csproj", "{B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VMR9Allocator2", "Samples\VMR9\VMR9Allocator2\VMR9Allocator2.csproj", "{16A0709D-4952-4801-9C3C-3607940121B6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vmr9Compositor", "Samples\VMR9\VMR9Compositor\Vmr9Compositor.csproj", "{88B15C8B-9377-4CCB-AA9B-4C3F9D923713}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VMR9Snapper", "Samples\VMR9\VMR9Snapper\VMR9Snapper.csproj", "{19113520-FF5B-4713-8CC6-3704817F1F48}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Debug|Win32.ActiveCfg = Debug|Any CPU + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Debug|x64.ActiveCfg = Debug|Any CPU + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Debug|x86.ActiveCfg = Debug|Any CPU {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Release|Any CPU.ActiveCfg = Release|Any CPU {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Release|Any CPU.Build.0 = Release|Any CPU + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Release|Win32.ActiveCfg = Release|Any CPU + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Release|x64.ActiveCfg = Release|Any CPU + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Release|x86.ActiveCfg = Release|Any CPU + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}.Debug|Win32.ActiveCfg = Debug|Any CPU + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}.Debug|x64.ActiveCfg = Debug|Any CPU + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}.Debug|x86.ActiveCfg = Debug|Any CPU + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}.Release|Any CPU.Build.0 = Release|Any CPU + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}.Release|Win32.ActiveCfg = Release|Any CPU + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}.Release|x64.ActiveCfg = Release|Any CPU + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}.Release|x86.ActiveCfg = Release|Any CPU + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}.Debug|Win32.ActiveCfg = Debug|Any CPU + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}.Debug|x64.ActiveCfg = Debug|Any CPU + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}.Debug|x86.ActiveCfg = Debug|Any CPU + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}.Release|Any CPU.Build.0 = Release|Any CPU + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}.Release|Win32.ActiveCfg = Release|Any CPU + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}.Release|x64.ActiveCfg = Release|Any CPU + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}.Release|x86.ActiveCfg = Release|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Debug|Win32.ActiveCfg = Debug|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Debug|x64.ActiveCfg = Debug|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Debug|x86.ActiveCfg = Debug|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Release|Any CPU.Build.0 = Release|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Release|Win32.ActiveCfg = Release|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Release|x64.ActiveCfg = Release|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Release|x86.ActiveCfg = Release|Any CPU + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}.Debug|Win32.ActiveCfg = Debug|Any CPU + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}.Debug|x64.ActiveCfg = Debug|Any CPU + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}.Debug|x86.ActiveCfg = Debug|Any CPU + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}.Release|Any CPU.Build.0 = Release|Any CPU + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}.Release|Win32.ActiveCfg = Release|Any CPU + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}.Release|x64.ActiveCfg = Release|Any CPU + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}.Release|x86.ActiveCfg = Release|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Debug|Win32.ActiveCfg = Debug|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Debug|x64.ActiveCfg = Debug|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Debug|x86.ActiveCfg = Debug|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Release|Any CPU.Build.0 = Release|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Release|Win32.ActiveCfg = Release|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Release|x64.ActiveCfg = Release|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Release|x86.ActiveCfg = Release|Any CPU + {E6052609-A070-41D5-85B9-ACABA91170C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E6052609-A070-41D5-85B9-ACABA91170C5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E6052609-A070-41D5-85B9-ACABA91170C5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {E6052609-A070-41D5-85B9-ACABA91170C5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {E6052609-A070-41D5-85B9-ACABA91170C5}.Debug|Win32.ActiveCfg = Debug|Any CPU + {E6052609-A070-41D5-85B9-ACABA91170C5}.Debug|x64.ActiveCfg = Debug|Any CPU + {E6052609-A070-41D5-85B9-ACABA91170C5}.Debug|x86.ActiveCfg = Debug|Any CPU + {E6052609-A070-41D5-85B9-ACABA91170C5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E6052609-A070-41D5-85B9-ACABA91170C5}.Release|Any CPU.Build.0 = Release|Any CPU + {E6052609-A070-41D5-85B9-ACABA91170C5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {E6052609-A070-41D5-85B9-ACABA91170C5}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {E6052609-A070-41D5-85B9-ACABA91170C5}.Release|Win32.ActiveCfg = Release|Any CPU + {E6052609-A070-41D5-85B9-ACABA91170C5}.Release|x64.ActiveCfg = Release|Any CPU + {E6052609-A070-41D5-85B9-ACABA91170C5}.Release|x86.ActiveCfg = Release|Any CPU + {EAB509E6-7797-4911-A201-2FA515386193}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EAB509E6-7797-4911-A201-2FA515386193}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EAB509E6-7797-4911-A201-2FA515386193}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {EAB509E6-7797-4911-A201-2FA515386193}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {EAB509E6-7797-4911-A201-2FA515386193}.Debug|Win32.ActiveCfg = Debug|Any CPU + {EAB509E6-7797-4911-A201-2FA515386193}.Debug|x64.ActiveCfg = Debug|Any CPU + {EAB509E6-7797-4911-A201-2FA515386193}.Debug|x86.ActiveCfg = Debug|Any CPU + {EAB509E6-7797-4911-A201-2FA515386193}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EAB509E6-7797-4911-A201-2FA515386193}.Release|Any CPU.Build.0 = Release|Any CPU + {EAB509E6-7797-4911-A201-2FA515386193}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {EAB509E6-7797-4911-A201-2FA515386193}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {EAB509E6-7797-4911-A201-2FA515386193}.Release|Win32.ActiveCfg = Release|Any CPU + {EAB509E6-7797-4911-A201-2FA515386193}.Release|x64.ActiveCfg = Release|Any CPU + {EAB509E6-7797-4911-A201-2FA515386193}.Release|x86.ActiveCfg = Release|Any CPU + {156F9A0F-C89B-42D5-9636-0047FE0923CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {156F9A0F-C89B-42D5-9636-0047FE0923CE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {156F9A0F-C89B-42D5-9636-0047FE0923CE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {156F9A0F-C89B-42D5-9636-0047FE0923CE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {156F9A0F-C89B-42D5-9636-0047FE0923CE}.Debug|Win32.ActiveCfg = Debug|Any CPU + {156F9A0F-C89B-42D5-9636-0047FE0923CE}.Debug|x64.ActiveCfg = Debug|Any CPU + {156F9A0F-C89B-42D5-9636-0047FE0923CE}.Debug|x86.ActiveCfg = Debug|Any CPU + {156F9A0F-C89B-42D5-9636-0047FE0923CE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {156F9A0F-C89B-42D5-9636-0047FE0923CE}.Release|Any CPU.Build.0 = Release|Any CPU + {156F9A0F-C89B-42D5-9636-0047FE0923CE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {156F9A0F-C89B-42D5-9636-0047FE0923CE}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {156F9A0F-C89B-42D5-9636-0047FE0923CE}.Release|Win32.ActiveCfg = Release|Any CPU + {156F9A0F-C89B-42D5-9636-0047FE0923CE}.Release|x64.ActiveCfg = Release|Any CPU + {156F9A0F-C89B-42D5-9636-0047FE0923CE}.Release|x86.ActiveCfg = Release|Any CPU + {369D647A-7F80-4F06-BEDB-D62AC1627862}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {369D647A-7F80-4F06-BEDB-D62AC1627862}.Debug|Any CPU.Build.0 = Debug|Any CPU + {369D647A-7F80-4F06-BEDB-D62AC1627862}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {369D647A-7F80-4F06-BEDB-D62AC1627862}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {369D647A-7F80-4F06-BEDB-D62AC1627862}.Debug|Win32.ActiveCfg = Debug|Any CPU + {369D647A-7F80-4F06-BEDB-D62AC1627862}.Debug|x64.ActiveCfg = Debug|Any CPU + {369D647A-7F80-4F06-BEDB-D62AC1627862}.Debug|x86.ActiveCfg = Debug|Any CPU + {369D647A-7F80-4F06-BEDB-D62AC1627862}.Release|Any CPU.ActiveCfg = Release|Any CPU + {369D647A-7F80-4F06-BEDB-D62AC1627862}.Release|Any CPU.Build.0 = Release|Any CPU + {369D647A-7F80-4F06-BEDB-D62AC1627862}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {369D647A-7F80-4F06-BEDB-D62AC1627862}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {369D647A-7F80-4F06-BEDB-D62AC1627862}.Release|Win32.ActiveCfg = Release|Any CPU + {369D647A-7F80-4F06-BEDB-D62AC1627862}.Release|x64.ActiveCfg = Release|Any CPU + {369D647A-7F80-4F06-BEDB-D62AC1627862}.Release|x86.ActiveCfg = Release|Any CPU + {B72919DC-C5B9-441A-9AD9-6CF9A97AFE85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B72919DC-C5B9-441A-9AD9-6CF9A97AFE85}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B72919DC-C5B9-441A-9AD9-6CF9A97AFE85}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {B72919DC-C5B9-441A-9AD9-6CF9A97AFE85}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {B72919DC-C5B9-441A-9AD9-6CF9A97AFE85}.Debug|Win32.ActiveCfg = Debug|Any CPU + {B72919DC-C5B9-441A-9AD9-6CF9A97AFE85}.Debug|x64.ActiveCfg = Debug|Any CPU + {B72919DC-C5B9-441A-9AD9-6CF9A97AFE85}.Debug|x86.ActiveCfg = Debug|Any CPU + {B72919DC-C5B9-441A-9AD9-6CF9A97AFE85}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B72919DC-C5B9-441A-9AD9-6CF9A97AFE85}.Release|Any CPU.Build.0 = Release|Any CPU + {B72919DC-C5B9-441A-9AD9-6CF9A97AFE85}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {B72919DC-C5B9-441A-9AD9-6CF9A97AFE85}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {B72919DC-C5B9-441A-9AD9-6CF9A97AFE85}.Release|Win32.ActiveCfg = Release|Any CPU + {B72919DC-C5B9-441A-9AD9-6CF9A97AFE85}.Release|x64.ActiveCfg = Release|Any CPU + {B72919DC-C5B9-441A-9AD9-6CF9A97AFE85}.Release|x86.ActiveCfg = Release|Any CPU + {461D3FBA-AD10-4E6E-A1BE-0686547E9B1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {461D3FBA-AD10-4E6E-A1BE-0686547E9B1F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {461D3FBA-AD10-4E6E-A1BE-0686547E9B1F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {461D3FBA-AD10-4E6E-A1BE-0686547E9B1F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {461D3FBA-AD10-4E6E-A1BE-0686547E9B1F}.Debug|Win32.ActiveCfg = Debug|Any CPU + {461D3FBA-AD10-4E6E-A1BE-0686547E9B1F}.Debug|x64.ActiveCfg = Debug|Any CPU + {461D3FBA-AD10-4E6E-A1BE-0686547E9B1F}.Debug|x86.ActiveCfg = Debug|Any CPU + {461D3FBA-AD10-4E6E-A1BE-0686547E9B1F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {461D3FBA-AD10-4E6E-A1BE-0686547E9B1F}.Release|Any CPU.Build.0 = Release|Any CPU + {461D3FBA-AD10-4E6E-A1BE-0686547E9B1F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {461D3FBA-AD10-4E6E-A1BE-0686547E9B1F}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {461D3FBA-AD10-4E6E-A1BE-0686547E9B1F}.Release|Win32.ActiveCfg = Release|Any CPU + {461D3FBA-AD10-4E6E-A1BE-0686547E9B1F}.Release|x64.ActiveCfg = Release|Any CPU + {461D3FBA-AD10-4E6E-A1BE-0686547E9B1F}.Release|x86.ActiveCfg = Release|Any CPU + {D6EE33A0-7EAF-4C98-8E2F-7CD39DE72BB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D6EE33A0-7EAF-4C98-8E2F-7CD39DE72BB2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D6EE33A0-7EAF-4C98-8E2F-7CD39DE72BB2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {D6EE33A0-7EAF-4C98-8E2F-7CD39DE72BB2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {D6EE33A0-7EAF-4C98-8E2F-7CD39DE72BB2}.Debug|Win32.ActiveCfg = Debug|Any CPU + {D6EE33A0-7EAF-4C98-8E2F-7CD39DE72BB2}.Debug|x64.ActiveCfg = Debug|Any CPU + {D6EE33A0-7EAF-4C98-8E2F-7CD39DE72BB2}.Debug|x86.ActiveCfg = Debug|Any CPU + {D6EE33A0-7EAF-4C98-8E2F-7CD39DE72BB2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D6EE33A0-7EAF-4C98-8E2F-7CD39DE72BB2}.Release|Any CPU.Build.0 = Release|Any CPU + {D6EE33A0-7EAF-4C98-8E2F-7CD39DE72BB2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {D6EE33A0-7EAF-4C98-8E2F-7CD39DE72BB2}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {D6EE33A0-7EAF-4C98-8E2F-7CD39DE72BB2}.Release|Win32.ActiveCfg = Release|Any CPU + {D6EE33A0-7EAF-4C98-8E2F-7CD39DE72BB2}.Release|x64.ActiveCfg = Release|Any CPU + {D6EE33A0-7EAF-4C98-8E2F-7CD39DE72BB2}.Release|x86.ActiveCfg = Release|Any CPU + {A10D4671-34C7-4AD8-B537-B2B9C48242F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A10D4671-34C7-4AD8-B537-B2B9C48242F7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A10D4671-34C7-4AD8-B537-B2B9C48242F7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {A10D4671-34C7-4AD8-B537-B2B9C48242F7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {A10D4671-34C7-4AD8-B537-B2B9C48242F7}.Debug|Win32.ActiveCfg = Debug|Any CPU + {A10D4671-34C7-4AD8-B537-B2B9C48242F7}.Debug|x64.ActiveCfg = Debug|Any CPU + {A10D4671-34C7-4AD8-B537-B2B9C48242F7}.Debug|x86.ActiveCfg = Debug|Any CPU + {A10D4671-34C7-4AD8-B537-B2B9C48242F7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A10D4671-34C7-4AD8-B537-B2B9C48242F7}.Release|Any CPU.Build.0 = Release|Any CPU + {A10D4671-34C7-4AD8-B537-B2B9C48242F7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {A10D4671-34C7-4AD8-B537-B2B9C48242F7}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {A10D4671-34C7-4AD8-B537-B2B9C48242F7}.Release|Win32.ActiveCfg = Release|Any CPU + {A10D4671-34C7-4AD8-B537-B2B9C48242F7}.Release|x64.ActiveCfg = Release|Any CPU + {A10D4671-34C7-4AD8-B537-B2B9C48242F7}.Release|x86.ActiveCfg = Release|Any CPU + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}.Debug|Win32.ActiveCfg = Debug|Any CPU + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}.Debug|x64.ActiveCfg = Debug|Any CPU + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}.Debug|x86.ActiveCfg = Debug|Any CPU + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}.Release|Any CPU.Build.0 = Release|Any CPU + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}.Release|Win32.ActiveCfg = Release|Any CPU + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}.Release|x64.ActiveCfg = Release|Any CPU + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}.Release|x86.ActiveCfg = Release|Any CPU + {B20FEBE5-4895-4930-8017-C7614AB6C49B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B20FEBE5-4895-4930-8017-C7614AB6C49B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B20FEBE5-4895-4930-8017-C7614AB6C49B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {B20FEBE5-4895-4930-8017-C7614AB6C49B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {B20FEBE5-4895-4930-8017-C7614AB6C49B}.Debug|Win32.ActiveCfg = Debug|Any CPU + {B20FEBE5-4895-4930-8017-C7614AB6C49B}.Debug|x64.ActiveCfg = Debug|Any CPU + {B20FEBE5-4895-4930-8017-C7614AB6C49B}.Debug|x86.ActiveCfg = Debug|Any CPU + {B20FEBE5-4895-4930-8017-C7614AB6C49B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B20FEBE5-4895-4930-8017-C7614AB6C49B}.Release|Any CPU.Build.0 = Release|Any CPU + {B20FEBE5-4895-4930-8017-C7614AB6C49B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {B20FEBE5-4895-4930-8017-C7614AB6C49B}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {B20FEBE5-4895-4930-8017-C7614AB6C49B}.Release|Win32.ActiveCfg = Release|Any CPU + {B20FEBE5-4895-4930-8017-C7614AB6C49B}.Release|x64.ActiveCfg = Release|Any CPU + {B20FEBE5-4895-4930-8017-C7614AB6C49B}.Release|x86.ActiveCfg = Release|Any CPU + {4AA43B9C-E987-43BA-A438-B6FDC7DACBD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4AA43B9C-E987-43BA-A438-B6FDC7DACBD5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4AA43B9C-E987-43BA-A438-B6FDC7DACBD5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {4AA43B9C-E987-43BA-A438-B6FDC7DACBD5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {4AA43B9C-E987-43BA-A438-B6FDC7DACBD5}.Debug|Win32.ActiveCfg = Debug|Any CPU + {4AA43B9C-E987-43BA-A438-B6FDC7DACBD5}.Debug|x64.ActiveCfg = Debug|Any CPU + {4AA43B9C-E987-43BA-A438-B6FDC7DACBD5}.Debug|x86.ActiveCfg = Debug|Any CPU + {4AA43B9C-E987-43BA-A438-B6FDC7DACBD5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4AA43B9C-E987-43BA-A438-B6FDC7DACBD5}.Release|Any CPU.Build.0 = Release|Any CPU + {4AA43B9C-E987-43BA-A438-B6FDC7DACBD5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {4AA43B9C-E987-43BA-A438-B6FDC7DACBD5}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {4AA43B9C-E987-43BA-A438-B6FDC7DACBD5}.Release|Win32.ActiveCfg = Release|Any CPU + {4AA43B9C-E987-43BA-A438-B6FDC7DACBD5}.Release|x64.ActiveCfg = Release|Any CPU + {4AA43B9C-E987-43BA-A438-B6FDC7DACBD5}.Release|x86.ActiveCfg = Release|Any CPU + {0178D2F5-5AC7-4B9F-8696-6E1AF14ED013}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0178D2F5-5AC7-4B9F-8696-6E1AF14ED013}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0178D2F5-5AC7-4B9F-8696-6E1AF14ED013}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {0178D2F5-5AC7-4B9F-8696-6E1AF14ED013}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {0178D2F5-5AC7-4B9F-8696-6E1AF14ED013}.Debug|Win32.ActiveCfg = Debug|Any CPU + {0178D2F5-5AC7-4B9F-8696-6E1AF14ED013}.Debug|x64.ActiveCfg = Debug|Any CPU + {0178D2F5-5AC7-4B9F-8696-6E1AF14ED013}.Debug|x86.ActiveCfg = Debug|Any CPU + {0178D2F5-5AC7-4B9F-8696-6E1AF14ED013}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0178D2F5-5AC7-4B9F-8696-6E1AF14ED013}.Release|Any CPU.Build.0 = Release|Any CPU + {0178D2F5-5AC7-4B9F-8696-6E1AF14ED013}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {0178D2F5-5AC7-4B9F-8696-6E1AF14ED013}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {0178D2F5-5AC7-4B9F-8696-6E1AF14ED013}.Release|Win32.ActiveCfg = Release|Any CPU + {0178D2F5-5AC7-4B9F-8696-6E1AF14ED013}.Release|x64.ActiveCfg = Release|Any CPU + {0178D2F5-5AC7-4B9F-8696-6E1AF14ED013}.Release|x86.ActiveCfg = Release|Any CPU + {5D949877-7015-40CA-83E5-D516C1C2BA97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5D949877-7015-40CA-83E5-D516C1C2BA97}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5D949877-7015-40CA-83E5-D516C1C2BA97}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {5D949877-7015-40CA-83E5-D516C1C2BA97}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {5D949877-7015-40CA-83E5-D516C1C2BA97}.Debug|Win32.ActiveCfg = Debug|Any CPU + {5D949877-7015-40CA-83E5-D516C1C2BA97}.Debug|x64.ActiveCfg = Debug|Any CPU + {5D949877-7015-40CA-83E5-D516C1C2BA97}.Debug|x86.ActiveCfg = Debug|Any CPU + {5D949877-7015-40CA-83E5-D516C1C2BA97}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5D949877-7015-40CA-83E5-D516C1C2BA97}.Release|Any CPU.Build.0 = Release|Any CPU + {5D949877-7015-40CA-83E5-D516C1C2BA97}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {5D949877-7015-40CA-83E5-D516C1C2BA97}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {5D949877-7015-40CA-83E5-D516C1C2BA97}.Release|Win32.ActiveCfg = Release|Any CPU + {5D949877-7015-40CA-83E5-D516C1C2BA97}.Release|x64.ActiveCfg = Release|Any CPU + {5D949877-7015-40CA-83E5-D516C1C2BA97}.Release|x86.ActiveCfg = Release|Any CPU + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}.Debug|Win32.ActiveCfg = Debug|Any CPU + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}.Debug|x64.ActiveCfg = Debug|Any CPU + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}.Debug|x86.ActiveCfg = Debug|Any CPU + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}.Release|Any CPU.Build.0 = Release|Any CPU + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}.Release|Win32.ActiveCfg = Release|Any CPU + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}.Release|x64.ActiveCfg = Release|Any CPU + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}.Release|x86.ActiveCfg = Release|Any CPU + {0E756677-5CB9-488B-B54A-55B32BF087D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0E756677-5CB9-488B-B54A-55B32BF087D6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0E756677-5CB9-488B-B54A-55B32BF087D6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {0E756677-5CB9-488B-B54A-55B32BF087D6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {0E756677-5CB9-488B-B54A-55B32BF087D6}.Debug|Win32.ActiveCfg = Debug|Any CPU + {0E756677-5CB9-488B-B54A-55B32BF087D6}.Debug|x64.ActiveCfg = Debug|Any CPU + {0E756677-5CB9-488B-B54A-55B32BF087D6}.Debug|x86.ActiveCfg = Debug|Any CPU + {0E756677-5CB9-488B-B54A-55B32BF087D6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0E756677-5CB9-488B-B54A-55B32BF087D6}.Release|Any CPU.Build.0 = Release|Any CPU + {0E756677-5CB9-488B-B54A-55B32BF087D6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {0E756677-5CB9-488B-B54A-55B32BF087D6}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {0E756677-5CB9-488B-B54A-55B32BF087D6}.Release|Win32.ActiveCfg = Release|Any CPU + {0E756677-5CB9-488B-B54A-55B32BF087D6}.Release|x64.ActiveCfg = Release|Any CPU + {0E756677-5CB9-488B-B54A-55B32BF087D6}.Release|x86.ActiveCfg = Release|Any CPU + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Debug|Win32.ActiveCfg = Debug|Win32 + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Debug|Win32.Build.0 = Debug|Win32 + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Debug|x64.ActiveCfg = Debug|Win32 + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Debug|x86.ActiveCfg = Debug|Win32 + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Debug|x86.Build.0 = Debug|Win32 + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Release|Any CPU.ActiveCfg = Release|Win32 + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Release|Mixed Platforms.Build.0 = Release|Win32 + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Release|Win32.ActiveCfg = Release|Win32 + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Release|Win32.Build.0 = Release|Win32 + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Release|x64.ActiveCfg = Release|Win32 + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Release|x86.ActiveCfg = Release|Win32 + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Release|x86.Build.0 = Release|Win32 + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Debug|Win32.ActiveCfg = Debug|Any CPU + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Debug|Win32.Build.0 = Debug|Any CPU + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Debug|x64.ActiveCfg = Debug|Any CPU + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Debug|x86.ActiveCfg = Debug|Any CPU + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Release|Any CPU.Build.0 = Release|Any CPU + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Release|Win32.ActiveCfg = Release|Any CPU + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Release|Win32.Build.0 = Release|Any CPU + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Release|x64.ActiveCfg = Release|Any CPU + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Release|x86.ActiveCfg = Release|Any CPU + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}.Debug|Win32.ActiveCfg = Debug|Any CPU + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}.Debug|x64.ActiveCfg = Debug|Any CPU + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}.Debug|x86.ActiveCfg = Debug|Any CPU + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}.Release|Any CPU.Build.0 = Release|Any CPU + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}.Release|Win32.ActiveCfg = Release|Any CPU + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}.Release|x64.ActiveCfg = Release|Any CPU + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}.Release|x86.ActiveCfg = Release|Any CPU + {FA72F510-5B39-43EC-BA62-04C6F90BD524}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA72F510-5B39-43EC-BA62-04C6F90BD524}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA72F510-5B39-43EC-BA62-04C6F90BD524}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {FA72F510-5B39-43EC-BA62-04C6F90BD524}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {FA72F510-5B39-43EC-BA62-04C6F90BD524}.Debug|Win32.ActiveCfg = Debug|Any CPU + {FA72F510-5B39-43EC-BA62-04C6F90BD524}.Debug|x64.ActiveCfg = Debug|Any CPU + {FA72F510-5B39-43EC-BA62-04C6F90BD524}.Debug|x86.ActiveCfg = Debug|Any CPU + {FA72F510-5B39-43EC-BA62-04C6F90BD524}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA72F510-5B39-43EC-BA62-04C6F90BD524}.Release|Any CPU.Build.0 = Release|Any CPU + {FA72F510-5B39-43EC-BA62-04C6F90BD524}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {FA72F510-5B39-43EC-BA62-04C6F90BD524}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {FA72F510-5B39-43EC-BA62-04C6F90BD524}.Release|Win32.ActiveCfg = Release|Any CPU + {FA72F510-5B39-43EC-BA62-04C6F90BD524}.Release|x64.ActiveCfg = Release|Any CPU + {FA72F510-5B39-43EC-BA62-04C6F90BD524}.Release|x86.ActiveCfg = Release|Any CPU + {00DC331B-E105-44F0-829E-80C2E1120D2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {00DC331B-E105-44F0-829E-80C2E1120D2F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {00DC331B-E105-44F0-829E-80C2E1120D2F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {00DC331B-E105-44F0-829E-80C2E1120D2F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {00DC331B-E105-44F0-829E-80C2E1120D2F}.Debug|Win32.ActiveCfg = Debug|Any CPU + {00DC331B-E105-44F0-829E-80C2E1120D2F}.Debug|x64.ActiveCfg = Debug|Any CPU + {00DC331B-E105-44F0-829E-80C2E1120D2F}.Debug|x86.ActiveCfg = Debug|Any CPU + {00DC331B-E105-44F0-829E-80C2E1120D2F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {00DC331B-E105-44F0-829E-80C2E1120D2F}.Release|Any CPU.Build.0 = Release|Any CPU + {00DC331B-E105-44F0-829E-80C2E1120D2F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {00DC331B-E105-44F0-829E-80C2E1120D2F}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {00DC331B-E105-44F0-829E-80C2E1120D2F}.Release|Win32.ActiveCfg = Release|Any CPU + {00DC331B-E105-44F0-829E-80C2E1120D2F}.Release|x64.ActiveCfg = Release|Any CPU + {00DC331B-E105-44F0-829E-80C2E1120D2F}.Release|x86.ActiveCfg = Release|Any CPU + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}.Debug|Win32.ActiveCfg = Debug|Any CPU + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}.Debug|x64.ActiveCfg = Debug|Any CPU + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}.Debug|x86.ActiveCfg = Debug|Any CPU + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}.Release|Any CPU.Build.0 = Release|Any CPU + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}.Release|Win32.ActiveCfg = Release|Any CPU + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}.Release|x64.ActiveCfg = Release|Any CPU + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}.Release|x86.ActiveCfg = Release|Any CPU + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F}.Debug|Win32.ActiveCfg = Debug|Any CPU + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F}.Debug|x64.ActiveCfg = Debug|Any CPU + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F}.Debug|x86.ActiveCfg = Debug|Any CPU + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F}.Release|Any CPU.Build.0 = Release|Any CPU + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F}.Release|Win32.ActiveCfg = Release|Any CPU + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F}.Release|x64.ActiveCfg = Release|Any CPU + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F}.Release|x86.ActiveCfg = Release|Any CPU + {4C65947E-100E-4176-B893-C3067ED8DC11}.Debug|Any CPU.ActiveCfg = Debug|x86 + {4C65947E-100E-4176-B893-C3067ED8DC11}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 + {4C65947E-100E-4176-B893-C3067ED8DC11}.Debug|Mixed Platforms.Build.0 = Debug|x86 + {4C65947E-100E-4176-B893-C3067ED8DC11}.Debug|Win32.ActiveCfg = Debug|x86 + {4C65947E-100E-4176-B893-C3067ED8DC11}.Debug|Win32.Build.0 = Debug|x86 + {4C65947E-100E-4176-B893-C3067ED8DC11}.Debug|x64.ActiveCfg = Debug|x86 + {4C65947E-100E-4176-B893-C3067ED8DC11}.Debug|x86.ActiveCfg = Debug|x86 + {4C65947E-100E-4176-B893-C3067ED8DC11}.Debug|x86.Build.0 = Debug|x86 + {4C65947E-100E-4176-B893-C3067ED8DC11}.Release|Any CPU.ActiveCfg = Release|x86 + {4C65947E-100E-4176-B893-C3067ED8DC11}.Release|Mixed Platforms.ActiveCfg = Release|x86 + {4C65947E-100E-4176-B893-C3067ED8DC11}.Release|Mixed Platforms.Build.0 = Release|x86 + {4C65947E-100E-4176-B893-C3067ED8DC11}.Release|Win32.ActiveCfg = Release|x86 + {4C65947E-100E-4176-B893-C3067ED8DC11}.Release|Win32.Build.0 = Release|x86 + {4C65947E-100E-4176-B893-C3067ED8DC11}.Release|x64.ActiveCfg = Release|x86 + {4C65947E-100E-4176-B893-C3067ED8DC11}.Release|x86.ActiveCfg = Release|x86 + {4C65947E-100E-4176-B893-C3067ED8DC11}.Release|x86.Build.0 = Release|x86 + {FE48353B-7945-400B-87B2-660BE9225083}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FE48353B-7945-400B-87B2-660BE9225083}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FE48353B-7945-400B-87B2-660BE9225083}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {FE48353B-7945-400B-87B2-660BE9225083}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {FE48353B-7945-400B-87B2-660BE9225083}.Debug|Win32.ActiveCfg = Debug|Any CPU + {FE48353B-7945-400B-87B2-660BE9225083}.Debug|x64.ActiveCfg = Debug|Any CPU + {FE48353B-7945-400B-87B2-660BE9225083}.Debug|x86.ActiveCfg = Debug|Any CPU + {FE48353B-7945-400B-87B2-660BE9225083}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FE48353B-7945-400B-87B2-660BE9225083}.Release|Any CPU.Build.0 = Release|Any CPU + {FE48353B-7945-400B-87B2-660BE9225083}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {FE48353B-7945-400B-87B2-660BE9225083}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {FE48353B-7945-400B-87B2-660BE9225083}.Release|Win32.ActiveCfg = Release|Any CPU + {FE48353B-7945-400B-87B2-660BE9225083}.Release|x64.ActiveCfg = Release|Any CPU + {FE48353B-7945-400B-87B2-660BE9225083}.Release|x86.ActiveCfg = Release|Any CPU + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}.Debug|Win32.ActiveCfg = Debug|Any CPU + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}.Debug|x64.ActiveCfg = Debug|Any CPU + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}.Debug|x86.ActiveCfg = Debug|Any CPU + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}.Release|Any CPU.Build.0 = Release|Any CPU + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}.Release|Win32.ActiveCfg = Release|Any CPU + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}.Release|x64.ActiveCfg = Release|Any CPU + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}.Release|x86.ActiveCfg = Release|Any CPU + {20FBEEA4-92C2-409E-9448-219CE60C0041}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {20FBEEA4-92C2-409E-9448-219CE60C0041}.Debug|Any CPU.Build.0 = Debug|Any CPU + {20FBEEA4-92C2-409E-9448-219CE60C0041}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {20FBEEA4-92C2-409E-9448-219CE60C0041}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {20FBEEA4-92C2-409E-9448-219CE60C0041}.Debug|Win32.ActiveCfg = Debug|Any CPU + {20FBEEA4-92C2-409E-9448-219CE60C0041}.Debug|x64.ActiveCfg = Debug|Any CPU + {20FBEEA4-92C2-409E-9448-219CE60C0041}.Debug|x86.ActiveCfg = Debug|Any CPU + {20FBEEA4-92C2-409E-9448-219CE60C0041}.Release|Any CPU.ActiveCfg = Release|Any CPU + {20FBEEA4-92C2-409E-9448-219CE60C0041}.Release|Any CPU.Build.0 = Release|Any CPU + {20FBEEA4-92C2-409E-9448-219CE60C0041}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {20FBEEA4-92C2-409E-9448-219CE60C0041}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {20FBEEA4-92C2-409E-9448-219CE60C0041}.Release|Win32.ActiveCfg = Release|Any CPU + {20FBEEA4-92C2-409E-9448-219CE60C0041}.Release|x64.ActiveCfg = Release|Any CPU + {20FBEEA4-92C2-409E-9448-219CE60C0041}.Release|x86.ActiveCfg = Release|Any CPU + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Debug|Mixed Platforms.Build.0 = Debug|x86 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Debug|Win32.ActiveCfg = Debug|x86 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Debug|Win32.Build.0 = Debug|x86 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Debug|x64.ActiveCfg = Debug|x64 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Debug|x64.Build.0 = Debug|x64 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Debug|x86.ActiveCfg = Debug|x86 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Debug|x86.Build.0 = Debug|x86 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Release|Any CPU.Build.0 = Release|Any CPU + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Release|Mixed Platforms.ActiveCfg = Release|x86 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Release|Mixed Platforms.Build.0 = Release|x86 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Release|Win32.ActiveCfg = Release|x86 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Release|Win32.Build.0 = Release|x86 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Release|x64.ActiveCfg = Release|x64 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Release|x64.Build.0 = Release|x64 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Release|x86.ActiveCfg = Release|x86 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Release|x86.Build.0 = Release|x86 + {58BA266F-B6DF-4096-8816-6A97C0A343E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {58BA266F-B6DF-4096-8816-6A97C0A343E7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {58BA266F-B6DF-4096-8816-6A97C0A343E7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {58BA266F-B6DF-4096-8816-6A97C0A343E7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {58BA266F-B6DF-4096-8816-6A97C0A343E7}.Debug|Win32.ActiveCfg = Debug|Any CPU + {58BA266F-B6DF-4096-8816-6A97C0A343E7}.Debug|x64.ActiveCfg = Debug|Any CPU + {58BA266F-B6DF-4096-8816-6A97C0A343E7}.Debug|x86.ActiveCfg = Debug|Any CPU + {58BA266F-B6DF-4096-8816-6A97C0A343E7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {58BA266F-B6DF-4096-8816-6A97C0A343E7}.Release|Any CPU.Build.0 = Release|Any CPU + {58BA266F-B6DF-4096-8816-6A97C0A343E7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {58BA266F-B6DF-4096-8816-6A97C0A343E7}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {58BA266F-B6DF-4096-8816-6A97C0A343E7}.Release|Win32.ActiveCfg = Release|Any CPU + {58BA266F-B6DF-4096-8816-6A97C0A343E7}.Release|x64.ActiveCfg = Release|Any CPU + {58BA266F-B6DF-4096-8816-6A97C0A343E7}.Release|x86.ActiveCfg = Release|Any CPU + {2BB69C76-D153-48A0-95B9-710550D63986}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2BB69C76-D153-48A0-95B9-710550D63986}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2BB69C76-D153-48A0-95B9-710550D63986}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {2BB69C76-D153-48A0-95B9-710550D63986}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {2BB69C76-D153-48A0-95B9-710550D63986}.Debug|Win32.ActiveCfg = Debug|Any CPU + {2BB69C76-D153-48A0-95B9-710550D63986}.Debug|x64.ActiveCfg = Debug|Any CPU + {2BB69C76-D153-48A0-95B9-710550D63986}.Debug|x86.ActiveCfg = Debug|Any CPU + {2BB69C76-D153-48A0-95B9-710550D63986}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2BB69C76-D153-48A0-95B9-710550D63986}.Release|Any CPU.Build.0 = Release|Any CPU + {2BB69C76-D153-48A0-95B9-710550D63986}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {2BB69C76-D153-48A0-95B9-710550D63986}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {2BB69C76-D153-48A0-95B9-710550D63986}.Release|Win32.ActiveCfg = Release|Any CPU + {2BB69C76-D153-48A0-95B9-710550D63986}.Release|x64.ActiveCfg = Release|Any CPU + {2BB69C76-D153-48A0-95B9-710550D63986}.Release|x86.ActiveCfg = Release|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Debug|Win32.ActiveCfg = Debug|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Debug|x64.ActiveCfg = Debug|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Debug|x86.ActiveCfg = Debug|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Release|Any CPU.Build.0 = Release|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Release|Win32.ActiveCfg = Release|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Release|x64.ActiveCfg = Release|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Release|x86.ActiveCfg = Release|Any CPU + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Debug|Mixed Platforms.Build.0 = Debug|x86 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Debug|Win32.ActiveCfg = Debug|x86 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Debug|Win32.Build.0 = Debug|x86 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Debug|x64.ActiveCfg = Debug|x64 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Debug|x64.Build.0 = Debug|x64 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Debug|x86.ActiveCfg = Debug|x86 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Debug|x86.Build.0 = Debug|x86 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Release|Any CPU.Build.0 = Release|Any CPU + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Release|Mixed Platforms.ActiveCfg = Release|x86 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Release|Mixed Platforms.Build.0 = Release|x86 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Release|Win32.ActiveCfg = Release|x86 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Release|Win32.Build.0 = Release|x86 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Release|x64.ActiveCfg = Release|x64 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Release|x64.Build.0 = Release|x64 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Release|x86.ActiveCfg = Release|x86 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Release|x86.Build.0 = Release|x86 + {16A0709D-4952-4801-9C3C-3607940121B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {16A0709D-4952-4801-9C3C-3607940121B6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {16A0709D-4952-4801-9C3C-3607940121B6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {16A0709D-4952-4801-9C3C-3607940121B6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {16A0709D-4952-4801-9C3C-3607940121B6}.Debug|Win32.ActiveCfg = Debug|Any CPU + {16A0709D-4952-4801-9C3C-3607940121B6}.Debug|x64.ActiveCfg = Debug|Any CPU + {16A0709D-4952-4801-9C3C-3607940121B6}.Debug|x86.ActiveCfg = Debug|Any CPU + {16A0709D-4952-4801-9C3C-3607940121B6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {16A0709D-4952-4801-9C3C-3607940121B6}.Release|Any CPU.Build.0 = Release|Any CPU + {16A0709D-4952-4801-9C3C-3607940121B6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {16A0709D-4952-4801-9C3C-3607940121B6}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {16A0709D-4952-4801-9C3C-3607940121B6}.Release|Win32.ActiveCfg = Release|Any CPU + {16A0709D-4952-4801-9C3C-3607940121B6}.Release|x64.ActiveCfg = Release|Any CPU + {16A0709D-4952-4801-9C3C-3607940121B6}.Release|x86.ActiveCfg = Release|Any CPU + {88B15C8B-9377-4CCB-AA9B-4C3F9D923713}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {88B15C8B-9377-4CCB-AA9B-4C3F9D923713}.Debug|Any CPU.Build.0 = Debug|Any CPU + {88B15C8B-9377-4CCB-AA9B-4C3F9D923713}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {88B15C8B-9377-4CCB-AA9B-4C3F9D923713}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {88B15C8B-9377-4CCB-AA9B-4C3F9D923713}.Debug|Win32.ActiveCfg = Debug|Any CPU + {88B15C8B-9377-4CCB-AA9B-4C3F9D923713}.Debug|x64.ActiveCfg = Debug|Any CPU + {88B15C8B-9377-4CCB-AA9B-4C3F9D923713}.Debug|x86.ActiveCfg = Debug|Any CPU + {88B15C8B-9377-4CCB-AA9B-4C3F9D923713}.Release|Any CPU.ActiveCfg = Release|Any CPU + {88B15C8B-9377-4CCB-AA9B-4C3F9D923713}.Release|Any CPU.Build.0 = Release|Any CPU + {88B15C8B-9377-4CCB-AA9B-4C3F9D923713}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {88B15C8B-9377-4CCB-AA9B-4C3F9D923713}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {88B15C8B-9377-4CCB-AA9B-4C3F9D923713}.Release|Win32.ActiveCfg = Release|Any CPU + {88B15C8B-9377-4CCB-AA9B-4C3F9D923713}.Release|x64.ActiveCfg = Release|Any CPU + {88B15C8B-9377-4CCB-AA9B-4C3F9D923713}.Release|x86.ActiveCfg = Release|Any CPU + {19113520-FF5B-4713-8CC6-3704817F1F48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {19113520-FF5B-4713-8CC6-3704817F1F48}.Debug|Any CPU.Build.0 = Debug|Any CPU + {19113520-FF5B-4713-8CC6-3704817F1F48}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {19113520-FF5B-4713-8CC6-3704817F1F48}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {19113520-FF5B-4713-8CC6-3704817F1F48}.Debug|Win32.ActiveCfg = Debug|Any CPU + {19113520-FF5B-4713-8CC6-3704817F1F48}.Debug|x64.ActiveCfg = Debug|Any CPU + {19113520-FF5B-4713-8CC6-3704817F1F48}.Debug|x86.ActiveCfg = Debug|Any CPU + {19113520-FF5B-4713-8CC6-3704817F1F48}.Release|Any CPU.ActiveCfg = Release|Any CPU + {19113520-FF5B-4713-8CC6-3704817F1F48}.Release|Any CPU.Build.0 = Release|Any CPU + {19113520-FF5B-4713-8CC6-3704817F1F48}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {19113520-FF5B-4713-8CC6-3704817F1F48}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {19113520-FF5B-4713-8CC6-3704817F1F48}.Release|Win32.ActiveCfg = Release|Any CPU + {19113520-FF5B-4713-8CC6-3704817F1F48}.Release|x64.ActiveCfg = Release|Any CPU + {19113520-FF5B-4713-8CC6-3704817F1F48}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {AC6FF501-EE0F-4BA5-B43C-1962161EDF98} = {16D68FD3-F9CD-41D1-B414-9CF7BD07D41B} + {74AC32C9-EFBB-4DBB-83F5-8DBA0814C42B} = {16D68FD3-F9CD-41D1-B414-9CF7BD07D41B} + {59A24CFF-BFA4-4F51-A1A7-61B46A5E2BB2} = {16D68FD3-F9CD-41D1-B414-9CF7BD07D41B} + {DFA3A219-BCD1-4A18-8335-CD7CE6B46D7F} = {16D68FD3-F9CD-41D1-B414-9CF7BD07D41B} + {FB66AC78-B6D0-44EB-A046-6ABBB3772095} = {16D68FD3-F9CD-41D1-B414-9CF7BD07D41B} + {10B2014A-7C7A-4589-8AA4-0F2609F8B7A3} = {16D68FD3-F9CD-41D1-B414-9CF7BD07D41B} + {C0985EC3-0F2C-4E8D-9851-AF7ECE30BC1A} = {16D68FD3-F9CD-41D1-B414-9CF7BD07D41B} + {3E262EA8-9A2C-477F-8A7C-CBD5309D8E48} = {16D68FD3-F9CD-41D1-B414-9CF7BD07D41B} + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC} = {AC6FF501-EE0F-4BA5-B43C-1962161EDF98} + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59} = {74AC32C9-EFBB-4DBB-83F5-8DBA0814C42B} + {17379614-821C-4504-B45D-BBACC866EBFB} = {74AC32C9-EFBB-4DBB-83F5-8DBA0814C42B} + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E} = {74AC32C9-EFBB-4DBB-83F5-8DBA0814C42B} + {4AC57653-233F-4862-AF88-139A1D02A007} = {74AC32C9-EFBB-4DBB-83F5-8DBA0814C42B} + {E6052609-A070-41D5-85B9-ACABA91170C5} = {74AC32C9-EFBB-4DBB-83F5-8DBA0814C42B} + {EAB509E6-7797-4911-A201-2FA515386193} = {74AC32C9-EFBB-4DBB-83F5-8DBA0814C42B} + {156F9A0F-C89B-42D5-9636-0047FE0923CE} = {74AC32C9-EFBB-4DBB-83F5-8DBA0814C42B} + {1A4540F8-3CB7-4FD7-A856-F08619247021} = {59A24CFF-BFA4-4F51-A1A7-61B46A5E2BB2} + {51420ACE-F02B-4BF8-83FE-72485CC1C8D9} = {59A24CFF-BFA4-4F51-A1A7-61B46A5E2BB2} + {0DDD778C-ECB7-43BD-BC24-50D05DA6053F} = {DFA3A219-BCD1-4A18-8335-CD7CE6B46D7F} + {4AA43B9C-E987-43BA-A438-B6FDC7DACBD5} = {DFA3A219-BCD1-4A18-8335-CD7CE6B46D7F} + {E31614E8-9AE9-4E22-804D-6066C03BAFF2} = {FB66AC78-B6D0-44EB-A046-6ABBB3772095} + {0178D2F5-5AC7-4B9F-8696-6E1AF14ED013} = {FB66AC78-B6D0-44EB-A046-6ABBB3772095} + {94DFCEAC-8CFD-44D6-8C1E-6499411D925C} = {FB66AC78-B6D0-44EB-A046-6ABBB3772095} + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7} = {FB66AC78-B6D0-44EB-A046-6ABBB3772095} + {FA72F510-5B39-43EC-BA62-04C6F90BD524} = {FB66AC78-B6D0-44EB-A046-6ABBB3772095} + {0E756677-5CB9-488B-B54A-55B32BF087D6} = {FB66AC78-B6D0-44EB-A046-6ABBB3772095} + {00DC331B-E105-44F0-829E-80C2E1120D2F} = {10B2014A-7C7A-4589-8AA4-0F2609F8B7A3} + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE} = {10B2014A-7C7A-4589-8AA4-0F2609F8B7A3} + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F} = {10B2014A-7C7A-4589-8AA4-0F2609F8B7A3} + {4C65947E-100E-4176-B893-C3067ED8DC11} = {10B2014A-7C7A-4589-8AA4-0F2609F8B7A3} + {FE48353B-7945-400B-87B2-660BE9225083} = {10B2014A-7C7A-4589-8AA4-0F2609F8B7A3} + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1} = {10B2014A-7C7A-4589-8AA4-0F2609F8B7A3} + {20FBEEA4-92C2-409E-9448-219CE60C0041} = {10B2014A-7C7A-4589-8AA4-0F2609F8B7A3} + {58BA266F-B6DF-4096-8816-6A97C0A343E7} = {C0985EC3-0F2C-4E8D-9851-AF7ECE30BC1A} + {2BB69C76-D153-48A0-95B9-710550D63986} = {C0985EC3-0F2C-4E8D-9851-AF7ECE30BC1A} + {4682D111-4503-448E-B5F4-93358502C229} = {3E262EA8-9A2C-477F-8A7C-CBD5309D8E48} + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1} = {3E262EA8-9A2C-477F-8A7C-CBD5309D8E48} + {16A0709D-4952-4801-9C3C-3607940121B6} = {3E262EA8-9A2C-477F-8A7C-CBD5309D8E48} + {88B15C8B-9377-4CCB-AA9B-4C3F9D923713} = {3E262EA8-9A2C-477F-8A7C-CBD5309D8E48} + {19113520-FF5B-4713-8CC6-3704817F1F48} = {3E262EA8-9A2C-477F-8A7C-CBD5309D8E48} + {B72919DC-C5B9-441A-9AD9-6CF9A97AFE85} = {1A4540F8-3CB7-4FD7-A856-F08619247021} + {369D647A-7F80-4F06-BEDB-D62AC1627862} = {1A4540F8-3CB7-4FD7-A856-F08619247021} + {461D3FBA-AD10-4E6E-A1BE-0686547E9B1F} = {51420ACE-F02B-4BF8-83FE-72485CC1C8D9} + {D6EE33A0-7EAF-4C98-8E2F-7CD39DE72BB2} = {51420ACE-F02B-4BF8-83FE-72485CC1C8D9} + {A10D4671-34C7-4AD8-B537-B2B9C48242F7} = {0DDD778C-ECB7-43BD-BC24-50D05DA6053F} + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9} = {0DDD778C-ECB7-43BD-BC24-50D05DA6053F} + {B20FEBE5-4895-4930-8017-C7614AB6C49B} = {0DDD778C-ECB7-43BD-BC24-50D05DA6053F} + {5D949877-7015-40CA-83E5-D516C1C2BA97} = {E31614E8-9AE9-4E22-804D-6066C03BAFF2} + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC} = {E31614E8-9AE9-4E22-804D-6066C03BAFF2} + {70B24BBF-E59F-4F91-A74B-01288E1DECB3} = {94DFCEAC-8CFD-44D6-8C1E-6499411D925C} + {6E8BB66C-D141-4333-8311-3CF33FACEC1B} = {94DFCEAC-8CFD-44D6-8C1E-6499411D925C} + EndGlobalSection EndGlobal diff --git a/MediaFoundation/Alt.cs b/MediaFoundation/Alt.cs new file mode 100644 index 0000000..24ea4c5 --- /dev/null +++ b/MediaFoundation/Alt.cs @@ -0,0 +1,511 @@ +#region license + +/* +MediaFoundationLib - Provide access to MediaFoundation interfaces via .NET +Copyright (C) 2007 +http://mfnet.sourceforge.net + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#endregion + +// This entire file only exists to work around bugs in Media Foundation. The core problem +// is that there are some objects in MF that don't correctly support QueryInterface. In c++ +// this isn't a problem, since if you tell c++ that something is a pointer to an interface, +// it just believes you. In fact, that's one of the places where c++ gets its performance: +// it doesn't check anything. + +// In .Net, it checks. And the way it checks is that every time it receives an interfaces +// from unmanaged code, it does a couple of QI calls on it. First it does a QI for IUnknown. +// Second it does a QI for the specific interface it is supposed to be (ie IMFMediaSink or +// whatever). + +// Since c++ *doesn't* check, oftentimes the first people to even try to call QI on some of +// MF's objects are c# programmers. And, not surprisingly, sometimes the first time code is +// run, it doesn't work correctly. + +// The only way you can work around it is to change the definition of the method from +// IMFMediaSink (or whatever interface MF is trying to pass you) to IntPtr. Of course, +// that limits what you can do with it. You can't call methods on an IntPtr. + +// Something to keep in mind is that while the work-around involves changing the interface, +// the problem isn't in the interface, it is in the object that implements the inteface. +// This means that while the inteface may experience problems on one object, it may work +// correctly on another object. If you are unclear on the differences between an interface +// and an object, it's time to hit the books. + +// In W7, MS has fixed a few of these issues that were reported in Vista. The problem +// is that even if they are fixed in W7, if your program also needs to run on Vista, you +// still have to use the work-arounds. + +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; +using System.Security; + +using MediaFoundation.Misc; +using MediaFoundation.EVR; + +namespace MediaFoundation.Alt +{ + #region Bugs in Vista and W7 + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("FA993888-4383-415A-A930-DD472A8CF6F7")] + public interface IMFGetServiceAlt + { + [PreserveSig] + int GetService( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidService, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + out IntPtr ppvObject + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("FA993889-4383-415A-A930-DD472A8CF6F7"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFTopologyServiceLookupAlt + { + [PreserveSig] + int LookupService( + [In] MFServiceLookupType type, + [In] int dwIndex, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidService, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.SysInt)] IntPtr[] ppvObjects, + [In, Out] ref int pnObjects + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("FA99388A-4383-415A-A930-DD472A8CF6F7"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFTopologyServiceLookupClientAlt + { + [PreserveSig] + int InitServicePointers( + IntPtr pLookup + ); + + [PreserveSig] + int ReleaseServicePointers(); + } + + #endregion + + #region Bugs in Vista that appear to be fixed in W7 + + public class MFExternAlt + { + [DllImport("MFPlat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateEventQueue( + out IMFMediaEventQueueAlt ppMediaEventQueue + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("2CD0BD52-BCD5-4B89-B62C-EADC0C031E7D"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFMediaEventGeneratorAlt + { + [PreserveSig] + int GetEvent( + [In] MFEventFlag dwFlags, + [MarshalAs(UnmanagedType.Interface)] out IMFMediaEvent ppEvent + ); + + [PreserveSig] + int BeginGetEvent( + //[In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + IntPtr pCallback, + [In, MarshalAs(UnmanagedType.IUnknown)] object o + ); + + [PreserveSig] + int EndGetEvent( + //IMFAsyncResult pResult, + IntPtr pResult, + out IMFMediaEvent ppEvent + ); + + [PreserveSig] + int QueueEvent( + [In] MediaEventType met, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidExtendedType, + [In] int hrStatus, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvValue + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("D182108F-4EC6-443F-AA42-A71106EC825F")] + public interface IMFMediaStreamAlt : IMFMediaEventGeneratorAlt + { + #region IMFMediaEventGeneratorAlt methods + + [PreserveSig] + new int GetEvent( + [In] MFEventFlag dwFlags, + [MarshalAs(UnmanagedType.Interface)] out IMFMediaEvent ppEvent + ); + + [PreserveSig] + new int BeginGetEvent( + //[In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + IntPtr p1, + [In, MarshalAs(UnmanagedType.IUnknown)] object o + ); + + [PreserveSig] + new int EndGetEvent( + //IMFAsyncResult pResult, + IntPtr pResult, + out IMFMediaEvent ppEvent + ); + + [PreserveSig] + new int QueueEvent( + [In] MediaEventType met, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidExtendedType, + [In] int hrStatus, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvValue + ); + + #endregion + + [PreserveSig] + int GetMediaSource( + [MarshalAs(UnmanagedType.Interface)] out IMFMediaSource ppMediaSource + ); + + [PreserveSig] + int GetStreamDescriptor( + [MarshalAs(UnmanagedType.Interface)] out IMFStreamDescriptor ppStreamDescriptor + ); + + [PreserveSig] + int RequestSample( + [In, MarshalAs(UnmanagedType.IUnknown)] object pToken + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("36F846FC-2256-48B6-B58E-E2B638316581"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFMediaEventQueueAlt + { + [PreserveSig] + int GetEvent( + [In] MFEventFlag dwFlags, + [MarshalAs(UnmanagedType.Interface)] out IMFMediaEvent ppEvent + ); + + [PreserveSig] + int BeginGetEvent( + IntPtr pCallBack, + //[In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnkState + ); + + [PreserveSig] + int EndGetEvent( + IntPtr p1, + //[In, MarshalAs(UnmanagedType.Interface)] IMFAsyncResult pResult, + [MarshalAs(UnmanagedType.Interface)] out IMFMediaEvent ppEvent + ); + + [PreserveSig] + int QueueEvent( + [In, MarshalAs(UnmanagedType.Interface)] IMFMediaEvent pEvent + ); + + [PreserveSig] + int QueueEventParamVar( + [In] MediaEventType met, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidExtendedType, + [In, MarshalAs(UnmanagedType.Error)] int hrStatus, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvValue + ); + + [PreserveSig] + int QueueEventParamUnk( + [In] MediaEventType met, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidExtendedType, + [In, MarshalAs(UnmanagedType.Error)] int hrStatus, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnk + ); + + [PreserveSig] + int Shutdown(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("279A808D-AEC7-40C8-9C6B-A6B492C78A66")] + public interface IMFMediaSourceAlt : IMFMediaEventGeneratorAlt + { + #region IMFMediaEventGeneratorAlt methods + + [PreserveSig] + new int GetEvent( + [In] MFEventFlag dwFlags, + [MarshalAs(UnmanagedType.Interface)] out IMFMediaEvent ppEvent + ); + + [PreserveSig] + new int BeginGetEvent( + //[In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + IntPtr pCallback, + [In, MarshalAs(UnmanagedType.IUnknown)] object o + ); + + [PreserveSig] + new int EndGetEvent( + //IMFAsyncResult pResult, + IntPtr pResult, + out IMFMediaEvent ppEvent + ); + + [PreserveSig] + new int QueueEvent( + [In] MediaEventType met, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidExtendedType, + [In] int hrStatus, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvValue + ); + + #endregion + + [PreserveSig] + int GetCharacteristics( + out MFMediaSourceCharacteristics pdwCharacteristics + ); + + [PreserveSig] + int CreatePresentationDescriptor( + out IMFPresentationDescriptor ppPresentationDescriptor + ); + + [PreserveSig] + int Start( + [In, MarshalAs(UnmanagedType.Interface)] IMFPresentationDescriptor pPresentationDescriptor, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid pguidTimeFormat, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvarStartPosition + ); + + [PreserveSig] + int Stop(); + + [PreserveSig] + int Pause(); + + [PreserveSig] + int Shutdown(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("0A97B3CF-8E7C-4A3D-8F8C-0C843DC247FB"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFStreamSinkAlt : IMFMediaEventGeneratorAlt + { + #region IMFMediaEventGeneratorAlt methods + + [PreserveSig] + new int GetEvent( + [In] MFEventFlag dwFlags, + [MarshalAs(UnmanagedType.Interface)] out IMFMediaEvent ppEvent + ); + + [PreserveSig] + new int BeginGetEvent( + //[In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + IntPtr pCallback, + [In, MarshalAs(UnmanagedType.IUnknown)] object o); + + [PreserveSig] + new int EndGetEvent( + //IMFAsyncResult pResult, + IntPtr pResult, + out IMFMediaEvent ppEvent); + + [PreserveSig] + new int QueueEvent( + [In] MediaEventType met, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidExtendedType, + [In] int hrStatus, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvValue + ); + + #endregion + + [PreserveSig] + int GetMediaSink( + [MarshalAs(UnmanagedType.Interface)] out IMFMediaSinkAlt ppMediaSink + ); + + [PreserveSig] + int GetIdentifier( + out int pdwIdentifier + ); + + [PreserveSig] + int GetMediaTypeHandler( + [MarshalAs(UnmanagedType.Interface)] out IMFMediaTypeHandler ppHandler + ); + + [PreserveSig] + int ProcessSample( + [In, MarshalAs(UnmanagedType.Interface)] IMFSample pSample + ); + + [PreserveSig] + int PlaceMarker( + [In] MFStreamSinkMarkerType eMarkerType, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvarMarkerValue, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvarContextValue + ); + + [PreserveSig] + int Flush(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("6EF2A660-47C0-4666-B13D-CBB717F2FA2C"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFMediaSinkAlt + { + [PreserveSig] + int GetCharacteristics( + out MFMediaSinkCharacteristics pdwCharacteristics + ); + + [PreserveSig] + int AddStreamSink( + [In] int dwStreamSinkIdentifier, + [In, MarshalAs(UnmanagedType.Interface)] IMFMediaType pMediaType, + [MarshalAs(UnmanagedType.Interface)] out IMFStreamSinkAlt ppStreamSink + ); + + [PreserveSig] + int RemoveStreamSink( + [In] int dwStreamSinkIdentifier + ); + + [PreserveSig] + int GetStreamSinkCount( + out int pcStreamSinkCount + ); + + [PreserveSig] + int GetStreamSinkByIndex( + [In] int dwIndex, + [MarshalAs(UnmanagedType.Interface)] out IMFStreamSinkAlt ppStreamSink + ); + + [PreserveSig] + int GetStreamSinkById( + [In] int dwStreamSinkIdentifier, + [MarshalAs(UnmanagedType.Interface)] out IMFStreamSinkAlt ppStreamSink + ); + + [PreserveSig] + int SetPresentationClock( + [In, MarshalAs(UnmanagedType.Interface)] IMFPresentationClock pPresentationClock + ); + + [PreserveSig] + int GetPresentationClock( + [MarshalAs(UnmanagedType.Interface)] out IMFPresentationClock ppPresentationClock + ); + + [PreserveSig] + int Shutdown(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("EAECB74A-9A50-42CE-9541-6A7F57AA4AD7"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFFinalizableMediaSinkAlt : IMFMediaSinkAlt + { + #region IMFMediaSinkAlt methods + + [PreserveSig] + new int GetCharacteristics( + out MFMediaSinkCharacteristics pdwCharacteristics); + + [PreserveSig] + new int AddStreamSink( + [In] int dwStreamSinkIdentifier, + [In, MarshalAs(UnmanagedType.Interface)] IMFMediaType pMediaType, + [MarshalAs(UnmanagedType.Interface)] out IMFStreamSinkAlt ppStreamSink + ); + + [PreserveSig] + new int RemoveStreamSink( + [In] int dwStreamSinkIdentifier + ); + + [PreserveSig] + new int GetStreamSinkCount( + out int pcStreamSinkCount + ); + + [PreserveSig] + new int GetStreamSinkByIndex( + [In] int dwIndex, + [MarshalAs(UnmanagedType.Interface)] out IMFStreamSinkAlt ppStreamSink + ); + + [PreserveSig] + new int GetStreamSinkById( + [In] int dwStreamSinkIdentifier, + [MarshalAs(UnmanagedType.Interface)] out IMFStreamSinkAlt ppStreamSink + ); + + [PreserveSig] + new int SetPresentationClock( + [In, MarshalAs(UnmanagedType.Interface)] IMFPresentationClock pPresentationClock + ); + + [PreserveSig] + new int GetPresentationClock( + [MarshalAs(UnmanagedType.Interface)] out IMFPresentationClock ppPresentationClock + ); + + [PreserveSig] + new int Shutdown(); + + #endregion + + [PreserveSig] + int BeginFinalize( + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnkState + ); + + [PreserveSig] + int EndFinalize( + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncResult pResult + ); + } + + #endregion + +} diff --git a/MediaFoundation/EVR.cs b/MediaFoundation/EVR.cs new file mode 100644 index 0000000..385b26d --- /dev/null +++ b/MediaFoundation/EVR.cs @@ -0,0 +1,784 @@ +#region license + +/* +MediaFoundationLib - Provide access to MediaFoundation interfaces via .NET +Copyright (C) 2007 +http://mfnet.sourceforge.net + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#endregion + +using System; +using System.Runtime.InteropServices; + +using MediaFoundation; +using MediaFoundation.Misc; +using MediaFoundation.Transform; +using System.Drawing; + +namespace MediaFoundation.EVR +{ + #region COM Class Objects + + [UnmanagedName("CLSID_EnhancedVideoRenderer"), + ComImport, + Guid("FA10746C-9B63-4b6c-BC49-FC300EA5F256")] + public class EnhancedVideoRenderer + { + } + + [UnmanagedName("CLSID_MFVideoMixer9"), + ComImport, + Guid("E474E05A-AB65-4f6a-827C-218B1BAAF31F")] + public class MFVideoMixer9 + { + } + + [UnmanagedName("CLSID_MFVideoPresenter9"), + ComImport, + Guid("98455561-5136-4d28-AB08-4CEE40EA2781")] + public class MFVideoPresenter9 + { + } + + [UnmanagedName("CLSID_EVRTearlessWindowPresenter9"), + ComImport, + Guid("a0a7a57b-59b2-4919-a694-add0a526c373")] + public class EVRTearlessWindowPresenter9 + { + } + + #endregion + + #region Declarations + + [UnmanagedName("MFVP_MESSAGE_TYPE")] + public enum MFVPMessageType + { + Flush = 0, + InvalidateMediaType, + ProcessInputNotify, + BeginStreaming, + EndStreaming, + EndOfStream, + Step, + CancelStep + } + + [UnmanagedName("MF_SERVICE_LOOKUP_TYPE")] + public enum MFServiceLookupType + { + Upstream = 0, + UpstreamDirect, + Downstream, + DownstreamDirect, + All, + Global + } + + [Flags, UnmanagedName("MFVideoRenderPrefs")] + public enum MFVideoRenderPrefs + { + None = 0, + DoNotRenderBorder = 0x00000001, + DoNotClipToDevice = 0x00000002, + AllowOutputThrottling = 0x00000004, + ForceOutputThrottling = 0x00000008, + ForceBatching = 0x00000010, + AllowBatching = 0x00000020, + ForceScaling = 0x00000040, + AllowScaling = 0x00000080, + DoNotRepaintOnStop = 0x00000100, + Mask = 0x000001ff, + } + + [Flags, UnmanagedName("MFVideoAspectRatioMode")] + public enum MFVideoAspectRatioMode + { + None = 0x00000000, + PreservePicture = 0x00000001, + PreservePixel = 0x00000002, + NonLinearStretch = 0x00000004, + Mask = 0x00000007 + } + + [Flags, UnmanagedName("DXVA2_ProcAmp_* defines")] + public enum DXVA2ProcAmp + { + None = 0, + Brightness = 0x0001, + Contrast = 0x0002, + Hue = 0x0004, + Saturation = 0x0008 + } + + [UnmanagedName("Unnamed enum")] + public enum DXVA2Filters + { + None = 0, + NoiseFilterLumaLevel = 1, + NoiseFilterLumaThreshold = 2, + NoiseFilterLumaRadius = 3, + NoiseFilterChromaLevel = 4, + NoiseFilterChromaThreshold = 5, + NoiseFilterChromaRadius = 6, + DetailFilterLumaLevel = 7, + DetailFilterLumaThreshold = 8, + DetailFilterLumaRadius = 9, + DetailFilterChromaLevel = 10, + DetailFilterChromaThreshold = 11, + DetailFilterChromaRadius = 12 + } + + [Flags, UnmanagedName("MFVideoAlphaBitmapFlags")] + public enum MFVideoAlphaBitmapFlags + { + None = 0, + EntireDDS = 0x00000001, + SrcColorKey = 0x00000002, + SrcRect = 0x00000004, + DestRect = 0x00000008, + FilterMode = 0x00000010, + Alpha = 0x00000020, + BitMask = 0x0000003f + } + + [Flags, UnmanagedName("MFVideoMixPrefs")] + public enum MFVideoMixPrefs + { + None = 0, + ForceHalfInterlace = 0x00000001, + AllowDropToHalfInterlace = 0x00000002, + AllowDropToBob = 0x00000004, + ForceBob = 0x00000008, + Mask = 0x0000000f + } + + [UnmanagedName("EVRFilterConfigPrefs")] + public enum EVRFilterConfigPrefs + { + None = 0, + EnableQoS = 0x1, + Mask = 0x1 + } + + [StructLayout(LayoutKind.Sequential, Pack = 4), UnmanagedName("MFVideoNormalizedRect")] + public class MFVideoNormalizedRect + { + public float left; + public float top; + public float right; + public float bottom; + + public MFVideoNormalizedRect() + { + } + + public MFVideoNormalizedRect(float l, float t, float r, float b) + { + left = l; + top = t; + right = r; + bottom = b; + } + + public override string ToString() + { + return string.Format("left = {0}, top = {1}, right = {2}, bottom = {3}", left, top, right, bottom); + } + + public override int GetHashCode() + { + return left.GetHashCode() | + top.GetHashCode() | + right.GetHashCode() | + bottom.GetHashCode(); + } + + public override bool Equals(object obj) + { + if (obj is MFVideoNormalizedRect) + { + MFVideoNormalizedRect cmp = (MFVideoNormalizedRect)obj; + + return right == cmp.right && bottom == cmp.bottom && left == cmp.left && top == cmp.top; + } + + return false; + } + + public bool IsEmpty() + { + return (right <= left || bottom <= top); + } + + public void CopyFrom(MFVideoNormalizedRect from) + { + left = from.left; + top = from.top; + right = from.right; + bottom = from.bottom; + } + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("DXVA2_VideoProcessorCaps")] + public struct DXVA2VideoProcessorCaps + { + public int DeviceCaps; + public int InputPool; + public int NumForwardRefSamples; + public int NumBackwardRefSamples; + public int Reserved; + public int DeinterlaceTechnology; + public int ProcAmpControlCaps; + public int VideoProcessorOperations; + public int NoiseFilterTechnology; + public int DetailFilterTechnology; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("DXVA2_ValueRange")] + public struct DXVA2ValueRange + { + public int MinValue; + public int MaxValue; + public int DefaultValue; + public int StepSize; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("DXVA2_ProcAmpValues")] + public struct DXVA2ProcAmpValues + { + public int Brightness; + public int Contrast; + public int Hue; + public int Saturation; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MFVideoAlphaBitmapParams")] + public class MFVideoAlphaBitmapParams + { + public MFVideoAlphaBitmapFlags dwFlags; + public int clrSrcKey; + public MFRect rcSrc; + public MFVideoNormalizedRect nrcDest; + public float fAlpha; + public int dwFilterMode; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MFVideoAlphaBitmap")] + public class MFVideoAlphaBitmap + { + public bool GetBitmapFromDC; + public IntPtr stru; + public MFVideoAlphaBitmapParams paras; + } + + #endregion + + #region Interfaces + +#if ALLOW_UNTESTED_INTERFACES + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("83A4CE40-7710-494b-A893-A472049AF630")] + public interface IEVRTrustedVideoPlugin + { + [PreserveSig] + int IsInTrustedVideoMode( + [MarshalAs(UnmanagedType.Bool)] out bool pYes + ); + + [PreserveSig] + int CanConstrict( + [MarshalAs(UnmanagedType.Bool)] out bool pYes + ); + + [PreserveSig] + int SetConstriction( + int dwKPix + ); + + [PreserveSig] + int DisableImageExport( + [MarshalAs(UnmanagedType.Bool)] bool bDisable + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("AEA36028-796D-454F-BEEE-B48071E24304")] + public interface IEVRFilterConfigEx : IEVRFilterConfig + { + #region IEVRFilterConfig methods + + [PreserveSig] + new int SetNumberOfStreams( + [In] int dwMaxStreams + ); + + [PreserveSig] + new int GetNumberOfStreams( + out int pdwMaxStreams + ); + + #endregion + + [PreserveSig] + int SetConfigPrefs( + [In] EVRFilterConfigPrefs dwConfigFlags + ); + + [PreserveSig] + int GetConfigPrefs( + out EVRFilterConfigPrefs pdwConfigFlags + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("8459616D-966E-4930-B658-54FA7E5A16D3")] + public interface IMFVideoMixerControl2 : IMFVideoMixerControl + { + #region IMFVideoMixerControl methods + + [PreserveSig] + new int SetStreamZOrder( + [In] int dwStreamID, + [In] int dwZ + ); + + [PreserveSig] + new int GetStreamZOrder( + [In] int dwStreamID, + out int pdwZ + ); + + [PreserveSig] + new int SetStreamOutputRect( + [In] int dwStreamID, + [In] MFVideoNormalizedRect pnrcOutput + ); + + [PreserveSig] + new int GetStreamOutputRect( + [In] int dwStreamID, + [Out, MarshalAs(UnmanagedType.LPStruct)] MFVideoNormalizedRect pnrcOutput + ); + + #endregion + + [PreserveSig] + int SetMixingPrefs( + [In] MFVideoMixPrefs dwMixFlags + ); + + [PreserveSig] + int GetMixingPrefs( + out MFVideoMixPrefs pdwMixFlags + ); + } + +#endif + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("A490B1E4-AB84-4D31-A1B2-181E03B1077A"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFVideoDisplayControl + { + [PreserveSig] + int GetNativeVideoSize( + [Out] Size pszVideo, + [Out] Size pszARVideo + ); + + [PreserveSig] + int GetIdealVideoSize( + [Out] Size pszMin, + [Out] Size pszMax + ); + + [PreserveSig] + int SetVideoPosition( + [In] MFVideoNormalizedRect pnrcSource, + [In] MFRect prcDest + ); + + [PreserveSig] + int GetVideoPosition( + [Out] MFVideoNormalizedRect pnrcSource, + [Out] MFRect prcDest + ); + + [PreserveSig] + int SetAspectRatioMode( + [In] MFVideoAspectRatioMode dwAspectRatioMode + ); + + [PreserveSig] + int GetAspectRatioMode( + out MFVideoAspectRatioMode pdwAspectRatioMode + ); + + [PreserveSig] + int SetVideoWindow( + [In] IntPtr hwndVideo + ); + + [PreserveSig] + int GetVideoWindow( + out IntPtr phwndVideo + ); + + [PreserveSig] + int RepaintVideo(); + + [PreserveSig] + int GetCurrentImage( + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMMarshaler))] BitmapInfoHeader pBih, + out IntPtr pDib, + out int pcbDib, + out long pTimeStamp + ); + + [PreserveSig] + int SetBorderColor( + [In] int Clr + ); + + [PreserveSig] + int GetBorderColor( + out int pClr + ); + + [PreserveSig] + int SetRenderingPrefs( + [In] MFVideoRenderPrefs dwRenderFlags + ); + + [PreserveSig] + int GetRenderingPrefs( + out MFVideoRenderPrefs pdwRenderFlags + ); + + [PreserveSig] + int SetFullscreen( + [In, MarshalAs(UnmanagedType.Bool)] bool fFullscreen + ); + + [PreserveSig] + int GetFullscreen( + [MarshalAs(UnmanagedType.Bool)] out bool pfFullscreen + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("83E91E85-82C1-4ea7-801D-85DC50B75086")] + public interface IEVRFilterConfig + { + [PreserveSig] + int SetNumberOfStreams( + int dwMaxStreams + ); + + [PreserveSig] + int GetNumberOfStreams( + out int pdwMaxStreams + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("1F6A9F17-E70B-4E24-8AE4-0B2C3BA7A4AE"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFVideoPositionMapper + { + [PreserveSig] + int MapOutputCoordinateToInputStream( + [In] float xOut, + [In] float yOut, + [In] int dwOutputStreamIndex, + [In] int dwInputStreamIndex, + out float pxIn, + out float pyIn + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("A5C6C53F-C202-4AA5-9695-175BA8C508A5")] + public interface IMFVideoMixerControl + { + [PreserveSig] + int SetStreamZOrder( + [In] int dwStreamID, + [In] int dwZ + ); + + [PreserveSig] + int GetStreamZOrder( + [In] int dwStreamID, + out int pdwZ + ); + + [PreserveSig] + int SetStreamOutputRect( + [In] int dwStreamID, + [In] MFVideoNormalizedRect pnrcOutput + ); + + [PreserveSig] + int GetStreamOutputRect( + [In] int dwStreamID, + [Out, MarshalAs(UnmanagedType.LPStruct)] MFVideoNormalizedRect pnrcOutput + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("FA99388A-4383-415A-A930-DD472A8CF6F7"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFTopologyServiceLookupClient + { + [PreserveSig] + int InitServicePointers( + IMFTopologyServiceLookup pLookup + ); + + [PreserveSig] + int ReleaseServicePointers(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("29AFF080-182A-4A5D-AF3B-448F3A6346CB")] + public interface IMFVideoPresenter : IMFClockStateSink + { + #region IMFClockStateSink + + [PreserveSig] + new int OnClockStart( + [In] long hnsSystemTime, + [In] long llClockStartOffset + ); + + [PreserveSig] + new int OnClockStop( + [In] long hnsSystemTime + ); + + [PreserveSig] + new int OnClockPause( + [In] long hnsSystemTime + ); + + [PreserveSig] + new int OnClockRestart( + [In] long hnsSystemTime + ); + + [PreserveSig] + new int OnClockSetRate( + [In] long hnsSystemTime, + [In] float flRate + ); + + #endregion + + [PreserveSig] + int ProcessMessage( + MFVPMessageType eMessage, + IntPtr ulParam + ); + + [PreserveSig] + int GetCurrentMediaType( + [MarshalAs(UnmanagedType.Interface)] out IMFVideoMediaType ppMediaType + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("FA993889-4383-415A-A930-DD472A8CF6F7"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFTopologyServiceLookup + { + [PreserveSig] + int LookupService( + [In] MFServiceLookupType type, + [In] int dwIndex, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidService, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface), Out] object[] ppvObjects, + [In, Out] ref int pnObjects + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("A38D9567-5A9C-4F3C-B293-8EB415B279BA")] + public interface IMFVideoDeviceID + { + [PreserveSig] + int GetDeviceID( + out Guid pDeviceID + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("DFDFD197-A9CA-43D8-B341-6AF3503792CD"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFVideoRenderer + { + [PreserveSig] + int InitializeRenderer( + [In, MarshalAs(UnmanagedType.Interface)] IMFTransform pVideoMixer, + [In, MarshalAs(UnmanagedType.Interface)] IMFVideoPresenter pVideoPresenter + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("245BF8E9-0755-40F7-88A5-AE0F18D55E17")] + public interface IMFTrackedSample + { + [PreserveSig] + int SetAllocator( + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pSampleAllocator, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnkState + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("56C294D0-753E-4260-8D61-A3D8820B1D54"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFDesiredSample + { + [PreserveSig] + int GetDesiredSampleTimeAndDuration( + out long phnsSampleTime, + out long phnsSampleDuration + ); + + [PreserveSig] + void SetDesiredSampleTimeAndDuration( + [In] long hnsSampleTime, + [In] long hnsSampleDuration + ); + + [PreserveSig] + void Clear(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("6AB0000C-FECE-4d1f-A2AC-A9573530656E")] + public interface IMFVideoProcessor + { + [PreserveSig] + int GetAvailableVideoProcessorModes( + out int lpdwNumProcessingModes, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(GMarshaler))] Guid[] ppVideoProcessingModes); + + [PreserveSig] + int GetVideoProcessorCaps( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid lpVideoProcessorMode, + out DXVA2VideoProcessorCaps lpVideoProcessorCaps); + + [PreserveSig] + int GetVideoProcessorMode( + out Guid lpMode); + + [PreserveSig] + int SetVideoProcessorMode( + [In] Guid lpMode); + + [PreserveSig] + int GetProcAmpRange( + DXVA2ProcAmp dwProperty, + out DXVA2ValueRange pPropRange); + + [PreserveSig] + int GetProcAmpValues( + DXVA2ProcAmp dwFlags, + out DXVA2ProcAmpValues Values); + + [PreserveSig] + int SetProcAmpValues( + DXVA2ProcAmp dwFlags, + [In] DXVA2ProcAmpValues pValues); + + [PreserveSig] + int GetFilteringRange( + DXVA2Filters dwProperty, + out DXVA2ValueRange pPropRange); + + [PreserveSig] + int GetFilteringValue( + DXVA2Filters dwProperty, + out int pValue); + + [PreserveSig] + int SetFilteringValue( + DXVA2Filters dwProperty, + [In] ref int pValue); + + [PreserveSig] + int GetBackgroundColor( + out int lpClrBkg); + + [PreserveSig] + int SetBackgroundColor( + int ClrBkg); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("814C7B20-0FDB-4eec-AF8F-F957C8F69EDC")] + public interface IMFVideoMixerBitmap + { + [PreserveSig] + int SetAlphaBitmap( + [In, MarshalAs(UnmanagedType.LPStruct)] MFVideoAlphaBitmap pBmpParms); + + [PreserveSig] + int ClearAlphaBitmap(); + + [PreserveSig] + int UpdateAlphaBitmapParameters( + [In] MFVideoAlphaBitmapParams pBmpParms); + + [PreserveSig] + int GetAlphaBitmapParameters( + [Out] MFVideoAlphaBitmapParams pBmpParms); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("d0cfe38b-93e7-4772-8957-0400c49a4485")] + public interface IEVRVideoStreamControl + { + [PreserveSig] + int SetStreamActiveState( + [MarshalAs(UnmanagedType.Bool)] bool fActive); + + [PreserveSig] + int GetStreamActiveState( + [MarshalAs(UnmanagedType.Bool)] out bool lpfActive); + } + + #endregion + +} diff --git a/MediaFoundation/Externs.cs b/MediaFoundation/Externs.cs new file mode 100644 index 0000000..10f5f57 --- /dev/null +++ b/MediaFoundation/Externs.cs @@ -0,0 +1,1168 @@ +#region license + +/* +MediaFoundationLib - Provide access to MediaFoundation interfaces via .NET +Copyright (C) 2007 +http://mfnet.sourceforge.net + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#endregion + +using System; +using System.Collections; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.ComTypes; +using System.Security; + +using MediaFoundation.Misc; +using MediaFoundation.Transform; +using MediaFoundation.ReadWrite; +using MediaFoundation.MFPlayer; + +namespace MediaFoundation +{ + public static class MFExtern + { + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFShutdown(); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFStartup( + int Version, + MFStartup dwFlags + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateSystemTimeSource( + out IMFPresentationTimeSource ppSystemTimeSource + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateCollection( + out IMFCollection ppIMFCollection + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateStreamDescriptor( + int dwStreamIdentifier, + int cMediaTypes, + [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] IMFMediaType[] apMediaTypes, + out IMFStreamDescriptor ppDescriptor + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int CreatePropertyStore( + out IPropertyStore ppStore + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateAttributes( + out IMFAttributes ppMFAttributes, + int cInitialSize + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateWaveFormatExFromMFMediaType( + IMFMediaType pMFType, + [Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(WEMarshaler))] out WaveFormatEx ppWF, + out int pcbSize, + MFWaveFormatExConvertFlags Flags + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateAsyncResult( + [MarshalAs(UnmanagedType.IUnknown)] object punkObject, + IMFAsyncCallback pCallback, + [MarshalAs(UnmanagedType.IUnknown)] object punkState, + out IMFAsyncResult ppAsyncResult + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFInvokeCallback( + IMFAsyncResult pAsyncResult + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreatePresentationDescriptor( + int cStreamDescriptors, + [In, MarshalAs(UnmanagedType.LPArray)] IMFStreamDescriptor[] apStreamDescriptors, + out IMFPresentationDescriptor ppPresentationDescriptor + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFInitMediaTypeFromWaveFormatEx( + IMFMediaType pMFType, + [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(WEMarshaler))] WaveFormatEx ppWF, + int cbBufSize + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateEventQueue( + out IMFMediaEventQueue ppMediaEventQueue + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateMediaType( + out IMFMediaType ppMFType + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateMediaEvent( + MediaEventType met, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidExtendedType, + int hrStatus, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvValue, + out IMFMediaEvent ppEvent + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateSample( + out IMFSample ppIMFSample + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateMemoryBuffer( + int cbMaxLength, + out IMFMediaBuffer ppBuffer + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFGetService( + [In, MarshalAs(UnmanagedType.Interface)] object punkObject, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidService, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [Out, MarshalAs(UnmanagedType.Interface)] out object ppvObject + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateVideoRendererActivate( + IntPtr hwndVideo, + out IMFActivate ppActivate + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateTopologyNode( + MFTopologyType NodeType, + out IMFTopologyNode ppNode + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateSourceResolver( + out IMFSourceResolver ppISourceResolver + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateMediaSession( + IMFAttributes pConfiguration, + out IMFMediaSession ppMediaSession + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateTopology( + out IMFTopology ppTopo + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateAudioRendererActivate( + out IMFActivate ppActivate + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreatePresentationClock( + out IMFPresentationClock ppPresentationClock + ); + + [DllImport("mfplat.dll", CharSet = CharSet.Unicode, ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFTRegister( + [In, MarshalAs(UnmanagedType.Struct)] Guid clsidMFT, + [In, MarshalAs(UnmanagedType.Struct)] Guid guidCategory, + [In, MarshalAs(UnmanagedType.LPWStr)] string pszName, + [In] int Flags, // Must be zero + [In] int cInputTypes, + [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(RTAMarshaler))] + object pInputTypes, // should be MFTRegisterTypeInfo[], but .Net bug prevents in x64 + [In] int cOutputTypes, + [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(RTAMarshaler))] + object pOutputTypes, // should be MFTRegisterTypeInfo[], but .Net bug prevents in x64 + [In] IMFAttributes pAttributes + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFTUnregister( + [In, MarshalAs(UnmanagedType.Struct)] Guid clsidMFT + ); + + [DllImport("mfplat.dll", CharSet = CharSet.Unicode, ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFTGetInfo( + [In, MarshalAs(UnmanagedType.Struct)] Guid clsidMFT, + [MarshalAs(UnmanagedType.LPWStr)] out string pszName, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = "0", MarshalTypeRef = typeof(RTIMarshaler))] + ArrayList ppInputTypes, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = "0", MarshalTypeRef = typeof(RTIMarshaler))] + MFInt pcInputTypes, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = "1", MarshalTypeRef = typeof(RTIMarshaler))] + ArrayList ppOutputTypes, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = "1", MarshalTypeRef = typeof(RTIMarshaler))] + MFInt pcOutputTypes, + IntPtr ip // Must be IntPtr.Zero due to MF bug, but should be out IMFAttributes ppAttributes + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int CreateNamedPropertyStore( + out INamedPropertyStore ppStore + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFLockPlatform(); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFUnlockPlatform(); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFGetTimerPeriodicity( + out int Periodicity); + + [DllImport("mfplat.dll", CharSet = CharSet.Unicode, ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateFile( + MFFileAccessMode AccessMode, + MFFileOpenMode OpenMode, + MFFileFlags fFlags, + [MarshalAs(UnmanagedType.LPWStr)] string pwszFileURL, + out IMFByteStream ppIByteStream); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateTempFile( + MFFileAccessMode AccessMode, + MFFileOpenMode OpenMode, + MFFileFlags fFlags, + out IMFByteStream ppIByteStream); + + [DllImport("mfplat.dll", CharSet = CharSet.Unicode, ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFBeginCreateFile( + [In] MFFileAccessMode AccessMode, + [In] MFFileOpenMode OpenMode, + [In] MFFileFlags fFlags, + [In, MarshalAs(UnmanagedType.LPWStr)] string pwszFilePath, + [In] IMFAsyncCallback pCallback, + [In] [MarshalAs(UnmanagedType.IUnknown)] object pState, + [MarshalAs(UnmanagedType.IUnknown)] out object ppCancelCookie); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFEndCreateFile( + [In] IMFAsyncResult pResult, + out IMFByteStream ppFile); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCancelCreateFile( + [In] [MarshalAs(UnmanagedType.IUnknown)] object pCancelCookie); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateAlignedMemoryBuffer( + [In] int cbMaxLength, + [In] int cbAligment, + out IMFMediaBuffer ppBuffer); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern long MFGetSystemTime( + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFGetSupportedSchemes( + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pPropVarSchemeArray + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFGetSupportedMimeTypes( + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pPropVarSchemeArray + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateSimpleTypeHandler( + out IMFMediaTypeHandler ppHandler + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateSequencerSegmentOffset( + int dwId, + long hnsOffset, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pvarSegmentOffset + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateVideoRenderer( + [MarshalAs(UnmanagedType.LPStruct)] Guid riidRenderer, + [MarshalAs(UnmanagedType.IUnknown)] out object ppVideoRenderer + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateMediaBufferWrapper( + [In] IMFMediaBuffer pBuffer, + [In] int cbOffset, + [In] int dwLength, + out IMFMediaBuffer ppBuffer); + + // Technically, the last param should be an IMediaBuffer. However, that interface is + // beyond the scope of this library. If you are using DirectShowNet (where this *is* + // defined), you can cast from the object to the IMediaBuffer. + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateLegacyMediaBufferOnMFMediaBuffer( + [In] IMFSample pSample, + [In] IMFMediaBuffer pMFMediaBuffer, + [In] int cbOffset, + [MarshalAs(UnmanagedType.IUnknown)] out object ppMediaBuffer); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFInitAttributesFromBlob( + [In] IMFAttributes pAttributes, + IntPtr pBuf, + [In] int cbBufSize + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFGetAttributesAsBlobSize( + [In] IMFAttributes pAttributes, + out int pcbBufSize + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFGetAttributesAsBlob( + [In] IMFAttributes pAttributes, + IntPtr pBuf, + [In] int cbBufSize + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFSerializeAttributesToStream( + IMFAttributes pAttr, + MFAttributeSerializeOptions dwOptions, + IStream pStm); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFDeserializeAttributesFromStream( + IMFAttributes pAttr, + MFAttributeSerializeOptions dwOptions, + IStream pStm); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateMFVideoFormatFromMFMediaType( + [In] IMFMediaType pMFType, + out MFVideoFormat ppMFVF, + out int pcbSize + ); + + [DllImport("evr.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFGetUncompressedVideoFormat( + [In, MarshalAs(UnmanagedType.LPStruct)] MFVideoFormat pVideoFormat + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFInitMediaTypeFromMFVideoFormat( + [In] IMFMediaType pMFType, + MFVideoFormat pMFVF, + [In] int cbBufSize + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFInitAMMediaTypeFromMFMediaType( + [In] IMFMediaType pMFType, + [In, MarshalAs(UnmanagedType.Struct)] Guid guidFormatBlockType, + [Out] AMMediaType pAMType + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateAMMediaTypeFromMFMediaType( + [In] IMFMediaType pMFType, + [In, MarshalAs(UnmanagedType.Struct)] Guid guidFormatBlockType, + out AMMediaType ppAMType // delete with DeleteMediaType + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFInitMediaTypeFromAMMediaType( + [In] IMFMediaType pMFType, + [In] AMMediaType pAMType + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFInitMediaTypeFromVideoInfoHeader( + [In] IMFMediaType pMFType, + VideoInfoHeader pVIH, + [In] int cbBufSize, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid pSubtype + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFInitMediaTypeFromVideoInfoHeader2( + [In] IMFMediaType pMFType, + VideoInfoHeader2 pVIH2, + [In] int cbBufSize, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid pSubtype + ); + + [DllImport("evr.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateVideoMediaType( + MFVideoFormat pVideoFormat, + out IMFVideoMediaType ppIVideoMediaType + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFTEnum( + [In, MarshalAs(UnmanagedType.Struct)] Guid guidCategory, + [In] int Flags, // Must be zero + [In, MarshalAs(UnmanagedType.LPStruct)] MFTRegisterTypeInfo pInputType, + [In, MarshalAs(UnmanagedType.LPStruct)] MFTRegisterTypeInfo pOutputType, + [In] IMFAttributes pAttributes, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = "0", MarshalTypeRef = typeof(GAMarshaler))] + ArrayList ppclsidMFT, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = "0", MarshalTypeRef = typeof(GAMarshaler))] + MFInt pcMFTs + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateSequencerSource( + [MarshalAs(UnmanagedType.IUnknown)] object pReserved, + out IMFSequencerSource ppSequencerSource + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFAllocateWorkQueue( + out int pdwWorkQueue); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFUnlockWorkQueue( + [In] int dwWorkQueue); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFPutWorkItem( + int dwQueue, + IMFAsyncCallback pCallback, + [MarshalAs(UnmanagedType.IUnknown)] object pState); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreatePMPMediaSession( + MFPMPSessionCreationFlags dwCreationFlags, + IMFAttributes pConfiguration, + out IMFMediaSession ppMediaSession, + out IMFActivate ppEnablerActivate + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateASFContentInfo( + out IMFASFContentInfo ppIContentInfo); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateASFSplitter( + out IMFASFSplitter ppISplitter); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateASFProfile( + out IMFASFProfile ppIProfile); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateAudioRenderer( + IMFAttributes pAudioAttributes, + out IMFMediaSink ppSink + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateASFIndexer( + out IMFASFIndexer ppIIndexer); + + [DllImport("evr.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFGetStrideForBitmapInfoHeader( + int format, + int dwWidth, + out int pStride + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCalculateBitmapImageSize( + [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMMarshaler))] BitmapInfoHeader pBMIH, + [In] int cbBufSize, + out int pcbImageSize, + out bool pbKnown + ); + + [DllImport("evr.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateVideoSampleFromSurface( + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnkSurface, + out IMFSample ppSample + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFFrameRateToAverageTimePerFrame( + [In] int unNumerator, + [In] int unDenominator, + out long punAverageTimePerFrame + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFUnwrapMediaType( + [In] IMFMediaType pWrap, + out IMFMediaType ppOrig + ); + +#if ALLOW_UNTESTED_INTERFACES + + #region Tested + // While these methods are tested, the interfaces they use are not + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateTopoLoader( + out IMFTopoLoader ppObj + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateStandardQualityManager( + out IMFQualityManager ppQualityManager + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreatePMPServer( + MFPMPSessionCreationFlags dwCreationFlags, + out IMFPMPServer ppPMPServer + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateASFMultiplexer( + out IMFASFMultiplexer ppIMultiplexer); + + #endregion + + #region Work Queue + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFPutWorkItemEx( + int dwQueue, + IMFAsyncResult pResult); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFScheduleWorkItem( + IMFAsyncCallback pCallback, + [MarshalAs(UnmanagedType.IUnknown)] object pState, + long Timeout, + long pKey); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFScheduleWorkItemEx( + IMFAsyncResult pResult, + long Timeout, + long pKey); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCancelWorkItem( + long Key); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFAddPeriodicCallback( + IntPtr Callback, + [MarshalAs(UnmanagedType.IUnknown)] object pContext, + out int pdwKey); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFRemovePeriodicCallback( + int dwKey); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFLockWorkQueue( + [In] int dwWorkQueue); + + [DllImport("mfplat.dll", CharSet = CharSet.Unicode, ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFBeginRegisterWorkQueueWithMMCSS( + int dwWorkQueueId, + [In, MarshalAs(UnmanagedType.LPWStr)] string wszClass, + int dwTaskId, + [In] IMFAsyncCallback pDoneCallback, + [In] [MarshalAs(UnmanagedType.IUnknown)] object pDoneState); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFEndRegisterWorkQueueWithMMCSS( + [In] IMFAsyncResult pResult, + out int pdwTaskId); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFBeginUnregisterWorkQueueWithMMCSS( + int dwWorkQueueId, + [In] IMFAsyncCallback pDoneCallback, + [In] [MarshalAs(UnmanagedType.IUnknown)] object pDoneState); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFEndUnregisterWorkQueueWithMMCSS( + [In] IMFAsyncResult pResult); + + [DllImport("mf.dll", CharSet = CharSet.Unicode, ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFSetWorkQueueClass( + int dwWorkQueueId, + [MarshalAs(UnmanagedType.LPWStr)] string szClass); + + [DllImport("mfplat.dll", CharSet = CharSet.Unicode, ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFGetWorkQueueMMCSSClass( + int dwWorkQueueId, + [MarshalAs(UnmanagedType.LPWStr)] out string pwszClass, + out int pcchClass); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFGetWorkQueueMMCSSTaskId( + int dwWorkQueueId, + out int pdwTaskId); + + #endregion + + [DllImport("Mfreadwrite.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateSinkWriterFromURL( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwszOutputURL, + IMFByteStream pByteStream, + IMFAttributes pAttributes, + out IMFSinkWriter ppSinkWriter + ); + + [DllImport("Mfreadwrite.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateSinkWriterFromMediaSink( + IMFMediaSink pMediaSink, + IMFAttributes pAttributes, + out IMFSinkWriter ppSinkWriter + ); + + [DllImport("Mfreadwrite.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateSourceReaderFromURL( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwszURL, + IMFAttributes pAttributes, + out IMFSourceReader ppSourceReader + ); + + [DllImport("Mfreadwrite.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateSourceReaderFromByteStream( + IMFByteStream pByteStream, + IMFAttributes pAttributes, + out IMFSourceReader ppSourceReader + ); + + [DllImport("Mfreadwrite.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateSourceReaderFromMediaSource( + IMFMediaSource pMediaSource, + IMFAttributes pAttributes, + out IMFSourceReader ppSourceReader + ); + + [DllImport("mfplay.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFPCreateMediaPlayer( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwszURL, + [MarshalAs(UnmanagedType.Bool)] bool fStartPlayback, + MFP_CREATION_OPTIONS creationOptions, + IMFPMediaPlayerCallback pCallback, + IntPtr hWnd, + out IMFPMediaPlayer ppMediaPlayer); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateRemoteDesktopPlugin( + out IMFRemoteDesktopPlugin ppPlugin + ); + + [DllImport("evr.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateDXSurfaceBuffer( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [In] [MarshalAs(UnmanagedType.IUnknown)] object punkSurface, + [In] bool fBottomUpWhenLinear, + out IMFMediaBuffer ppBuffer); + + // -------------------------------------------------- + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFValidateMediaTypeSize( + [In, MarshalAs(UnmanagedType.Struct)] Guid FormatType, + IntPtr pBlock, + [In] int cbSize + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFInitMediaTypeFromMPEG1VideoInfo( + [In] IMFMediaType pMFType, + MPEG1VideoInfo pMP1VI, + [In] int cbBufSize, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid pSubtype + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFInitMediaTypeFromMPEG2VideoInfo( + [In] IMFMediaType pMFType, + Mpeg2VideoInfo pMP2VI, + [In] int cbBufSize, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid pSubtype + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCalculateImageSize( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidSubtype, + [In] int unWidth, + [In] int unHeight, + out int pcbImageSize + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFAverageTimePerFrameToFrameRate( + [In] long unAverageTimePerFrame, + out int punNumerator, + out int punDenominator + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCompareFullToPartialMediaType( + [In] IMFMediaType pMFTypeFull, + [In] IMFMediaType pMFTypePartial + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFWrapMediaType( + [In] IMFMediaType pOrig, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid MajorType, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid SubType, + out IMFMediaType ppWrap + ); + + [DllImport("evr.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateVideoMediaTypeFromSubtype( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid pAMSubtype, + out IMFVideoMediaType ppIVideoMediaType + ); + + [DllImport("evr.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern bool MFIsFormatYUV( + int Format + ); + + [DllImport("evr.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFGetPlaneSize( + int format, + int dwWidth, + int dwHeight, + out int pdwPlaneSize + ); + + [DllImport("evr.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFInitVideoFormat( + [In] MFVideoFormat pVideoFormat, + [In] MFStandardVideoFormat type + ); + + [DllImport("evr.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFInitVideoFormat_RGB( + [In] MFVideoFormat pVideoFormat, + [In] int dwWidth, + [In] int dwHeight, + [In] int D3Dfmt + ); + + [DllImport("evr.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFConvertColorInfoToDXVA( + out int pdwToDXVA, + MFVideoFormat pFromFormat + ); + + [DllImport("evr.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFConvertColorInfoFromDXVA( + MFVideoFormat pToFormat, + int dwFromDXVA + ); + + [DllImport("evr.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCopyImage( + IntPtr pDest, + int lDestStride, + IntPtr pSrc, + int lSrcStride, + int dwWidthInBytes, + int dwLines + ); + + [DllImport("evr.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFConvertFromFP16Array( + float[] pDest, + short[] pSrc, + int dwCount + ); + + [DllImport("evr.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFConvertToFP16Array( + short[] pDest, + float[] pSrc, + int dwCount + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateMediaTypeFromRepresentation( + [MarshalAs(UnmanagedType.Struct)] Guid guidRepresentation, + IntPtr pvRepresentation, + out IMFMediaType ppIMediaType + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFRequireProtectedEnvironment( + IMFPresentationDescriptor pPresentationDescriptor + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFSerializePresentationDescriptor( + IMFPresentationDescriptor pPD, + out int pcbData, + IntPtr ppbData + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFDeserializePresentationDescriptor( + int cbData, + IntPtr pbData, + out IMFPresentationDescriptor ppPD + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFShutdownObject( + object pUnk + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateSampleGrabberSinkActivate( + IMFMediaType pIMFMediaType, + IMFSampleGrabberSinkCallback pIMFSampleGrabberSinkCallback, + out IMFActivate ppIActivate + ); + + [DllImport("mf.dll", CharSet = CharSet.Unicode, ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateProxyLocator( + [MarshalAs(UnmanagedType.LPWStr)] string pszProtocol, + IPropertyStore pProxyConfig, + out IMFNetProxyLocator ppProxyLocator + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateNetSchemePlugin( + [MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.IUnknown)] object ppvHandler + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateASFProfileFromPresentationDescriptor( + [In] IMFPresentationDescriptor pIPD, + out IMFASFProfile ppIProfile); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateASFIndexerByteStream( + [In] IMFByteStream pIContentByteStream, + [In] long cbIndexStartOffset, + out IMFByteStream pIIndexByteStream); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateASFStreamSelector( + [In] IMFASFProfile pIASFProfile, + out IMFASFStreamSelector ppSelector); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateASFMediaSink( + IMFByteStream pIByteStream, + out IMFMediaSink ppIMediaSink + ); + + [DllImport("mf.dll", CharSet = CharSet.Unicode, ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateASFMediaSinkActivate( + [MarshalAs(UnmanagedType.LPWStr)] string pwszFileName, + IMFASFContentInfo pContentInfo, + out IMFActivate ppIActivate + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateWMVEncoderActivate( + IMFMediaType pMediaType, + IPropertyStore pEncodingConfigurationProperties, + out IMFActivate ppActivate + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateWMAEncoderActivate( + IMFMediaType pMediaType, + IPropertyStore pEncodingConfigurationProperties, + out IMFActivate ppActivate + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreatePresentationDescriptorFromASFProfile( + [In] IMFASFProfile pIProfile, + out IMFPresentationDescriptor ppIPD); + + [DllImport("evr.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateVideoPresenter( + [In, MarshalAs(UnmanagedType.IUnknown)] object pOwner, + [MarshalAs(UnmanagedType.LPStruct)] Guid riidDevice, + [MarshalAs(UnmanagedType.LPStruct)] Guid riid, + out IntPtr ppVideoPresenter + ); + + [DllImport("evr.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateVideoMixer( + [In, MarshalAs(UnmanagedType.IUnknown)] object pOwner, + [MarshalAs(UnmanagedType.LPStruct)] Guid riidDevice, + [MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.IUnknown)] out object ppVideoMixer + ); + + [DllImport("evr.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateVideoMixerAndPresenter( + [In, MarshalAs(UnmanagedType.IUnknown)] object pMixerOwner, + [In, MarshalAs(UnmanagedType.IUnknown)] object pPresenterOwner, + [MarshalAs(UnmanagedType.LPStruct)] Guid riidMixer, + out IntPtr ppvVideoMixer, + [MarshalAs(UnmanagedType.LPStruct)] Guid riidPresenter, + out IntPtr ppvVideoPresenter + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateASFStreamingMediaSink( + IMFByteStream pIByteStream, + out IMFMediaSink ppIMediaSink + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateASFStreamingMediaSinkActivate( + IMFActivate pByteStreamActivate, + IMFASFContentInfo pContentInfo, + out IMFActivate ppIActivate + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateTransformActivate( + out IMFActivate ppActivate + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFEnumDeviceSources( + IMFAttributes pAttributes, + out IMFActivate[] pppSourceActivate, + out int pcSourceActivate + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateDeviceSource( + IMFAttributes pAttributes, + out IMFMediaSource ppSource + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateDeviceSourceActivate( + IMFAttributes pAttributes, + out IMFActivate ppActivate + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateSampleCopierMFT(out IMFTransform ppCopierMFT); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateTranscodeProfile( + out IMFTranscodeProfile ppTranscodeProfile + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateTranscodeTopology( + IMFMediaSource pSrc, + [MarshalAs(UnmanagedType.LPWStr)] string pwszOutputFilePath, + IMFTranscodeProfile pProfile, + out IMFTopology ppTranscodeTopo + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFTranscodeGetAudioOutputAvailableTypes( + Guid guidSubType, + int dwMFTFlags, + IMFAttributes pCodecConfig, + out IMFCollection ppAvailableTypes + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateTranscodeSinkActivate( + out IMFActivate ppActivate + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateMFByteStreamOnStream( + IStream pStream, + out IMFByteStream ppByteStream + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateAggregateSource( + IMFCollection pSourceCollection, + out IMFMediaSource ppAggSource + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFGetTopoNodeCurrentType( + IMFTopologyNode pNode, + int dwStreamIndex, + [MarshalAs(UnmanagedType.Bool)] bool fOutput, + out IMFMediaType ppType); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateMPEG4MediaSink( + IMFByteStream pIByteStream, + IMFMediaType pVideoMediaType, + IMFMediaType pAudioMediaType, + out IMFMediaSink ppIMediaSink + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreate3GPMediaSink( + IMFByteStream pIByteStream, + IMFMediaType pVideoMediaType, + IMFMediaType pAudioMediaType, + out IMFMediaSink ppIMediaSink + ); + + [DllImport("mf.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateMP3MediaSink( + IMFByteStream pTargetByteStream, + out IMFMediaSink ppMediaSink + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateVideoMediaTypeFromBitMapInfoHeaderEx( + BitmapInfoHeader[] pbmihBitMapInfoHeader, + int cbBitMapInfoHeader, + int dwPixelAspectRatioX, + int dwPixelAspectRatioY, + MFVideoInterlaceMode InterlaceMode, + long VideoFlags, + int dwFramesPerSecondNumerator, + int dwFramesPerSecondDenominator, + int dwMaxBitRate, + out IMFVideoMediaType ppIVideoMediaType + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFGetPluginControl( + out IMFPluginControl ppPluginControl + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFGetMFTMerit( + [MarshalAs(UnmanagedType.IUnknown)] object pMFT, + int cbVerifier, + IntPtr verifier, + out int merit + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFTEnumEx( + Guid guidCategory, + int Flags, + MFTRegisterTypeInfo pInputType, + MFTRegisterTypeInfo pOutputType, + out IMFActivate[] pppMFTActivate, + out int pnumMFTActivate + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFAllocateWorkQueueEx( + MFASYNC_WORKQUEUE_TYPE WorkQueueType, + out int pdwWorkQueue + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFTRegisterLocal( + [MarshalAs(UnmanagedType.IUnknown)] object pClassFactory, + Guid guidCategory, + [MarshalAs(UnmanagedType.LPWStr)] string pszName, + int Flags, + int cInputTypes, + MFTRegisterTypeInfo[] pInputTypes, + int cOutputTypes, + MFTRegisterTypeInfo[] pOutputTypes + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFTUnregisterLocal( + [MarshalAs(UnmanagedType.IUnknown)] object pClassFactory + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFTRegisterLocalByCLSID( + Guid clisdMFT, + Guid guidCategory, + [MarshalAs(UnmanagedType.LPWStr)] string pszName, + int Flags, + int cInputTypes, + MFTRegisterTypeInfo[] pInputTypes, + int cOutputTypes, + MFTRegisterTypeInfo[] pOutputTypes + ); + + [DllImport("mfplat.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + public static extern int MFTUnregisterLocalByCLSID( + Guid clsidMFT + ); + + #region Untestable + + [DllImport("mfplat.dll", ExactSpelling = true), Obsolete("This function is deprecated"), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateAudioMediaType( + [In] WaveFormatEx pAudioFormat, + out IMFAudioMediaType ppIAudioMediaType + ); + + [DllImport("mf.dll", ExactSpelling = true), Obsolete("The returned object doesn't support QI"), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateCredentialCache( + out IMFNetCredentialCache ppCache + ); + + [DllImport("evr.dll", ExactSpelling = true), Obsolete("Not implemented"), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateVideoMediaTypeFromBitMapInfoHeader( + [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMMarshaler))] BitmapInfoHeader pbmihBitMapInfoHeader, + int dwPixelAspectRatioX, + int dwPixelAspectRatioY, + MFVideoInterlaceMode InterlaceMode, + long VideoFlags, + long qwFramesPerSecondNumerator, + long qwFramesPerSecondDenominator, + int dwMaxBitRate, + out IMFVideoMediaType ppIVideoMediaType + ); + + [DllImport("mf.dll", ExactSpelling = true), Obsolete("Interface doesn't exist"), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateQualityManager( + out IMFQualityManager ppQualityManager + ); + + [DllImport("evr.dll", ExactSpelling = true), Obsolete("Undoc'ed"), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateVideoMediaTypeFromVideoInfoHeader( + VideoInfoHeader pVideoInfoHeader, + int cbVideoInfoHeader, + int dwPixelAspectRatioX, + int dwPixelAspectRatioY, + MFVideoInterlaceMode InterlaceMode, + long VideoFlags, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid pSubtype, + out IMFVideoMediaType ppIVideoMediaType + ); + + [DllImport("evr.dll", ExactSpelling = true), Obsolete("Undoc'ed"), SuppressUnmanagedCodeSecurity] + public static extern int MFCreateVideoMediaTypeFromVideoInfoHeader2( + VideoInfoHeader2 pVideoInfoHeader, + int cbVideoInfoHeader, + long AdditionalVideoFlags, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid pSubtype, + out IMFVideoMediaType ppIVideoMediaType + ); + + #endregion +#endif + } +} diff --git a/MediaFoundation/MFIdl.cs b/MediaFoundation/MFIdl.cs new file mode 100644 index 0000000..cbd06e0 --- /dev/null +++ b/MediaFoundation/MFIdl.cs @@ -0,0 +1,5226 @@ +#region license + +/* +MediaFoundationLib - Provide access to MediaFoundation interfaces via .NET +Copyright (C) 2007 +http://mfnet.sourceforge.net + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#endregion + +using System; +using System.Text; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.ComTypes; + +using MediaFoundation.Misc; +using MediaFoundation; + +namespace MediaFoundation +{ + #region GUIDs, IIDs + + [UnmanagedName("CLSID_UrlmonSchemePlugin"), + ComImport, + Guid("9ec4b4f9-3029-45ad-947b-344de2a249e2")] + public class UrlmonSchemePlugin + { + } + + public static class MFAttributesClsid + { + // Audio Renderer Attributes + public static readonly Guid MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID = new Guid(0xb10aaec3, 0xef71, 0x4cc3, 0xb8, 0x73, 0x5, 0xa9, 0xa0, 0x8b, 0x9f, 0x8e); + public static readonly Guid MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE = new Guid(0x6ba644ff, 0x27c5, 0x4d02, 0x98, 0x87, 0xc2, 0x86, 0x19, 0xfd, 0xb9, 0x1b); + public static readonly Guid MF_AUDIO_RENDERER_ATTRIBUTE_FLAGS = new Guid(0xede4b5e0, 0xf805, 0x4d6c, 0x99, 0xb3, 0xdb, 0x01, 0xbf, 0x95, 0xdf, 0xab); + public static readonly Guid MF_AUDIO_RENDERER_ATTRIBUTE_SESSION_ID = new Guid(0xede4b5e3, 0xf805, 0x4d6c, 0x99, 0xb3, 0xdb, 0x01, 0xbf, 0x95, 0xdf, 0xab); + + // Byte Stream Attributes + public static readonly Guid MF_BYTESTREAM_ORIGIN_NAME = new Guid(0xfc358288, 0x3cb6, 0x460c, 0xa4, 0x24, 0xb6, 0x68, 0x12, 0x60, 0x37, 0x5a); + public static readonly Guid MF_BYTESTREAM_CONTENT_TYPE = new Guid(0xfc358289, 0x3cb6, 0x460c, 0xa4, 0x24, 0xb6, 0x68, 0x12, 0x60, 0x37, 0x5a); + public static readonly Guid MF_BYTESTREAM_DURATION = new Guid(0xfc35828a, 0x3cb6, 0x460c, 0xa4, 0x24, 0xb6, 0x68, 0x12, 0x60, 0x37, 0x5a); + public static readonly Guid MF_BYTESTREAM_LAST_MODIFIED_TIME = new Guid(0xfc35828b, 0x3cb6, 0x460c, 0xa4, 0x24, 0xb6, 0x68, 0x12, 0x60, 0x37, 0x5a); + public static readonly Guid MF_BYTESTREAM_IFO_FILE_URI = new Guid(0xfc35828c, 0x3cb6, 0x460c, 0xa4, 0x24, 0xb6, 0x68, 0x12, 0x60, 0x37, 0x5a); + public static readonly Guid MF_BYTESTREAM_DLNA_PROFILE_ID = new Guid(0xfc35828d, 0x3cb6, 0x460c, 0xa4, 0x24, 0xb6, 0x68, 0x12, 0x60, 0x37, 0x5a); + + // Enhanced Video Renderer Attributes + public static readonly Guid MF_ACTIVATE_CUSTOM_VIDEO_MIXER_ACTIVATE = new Guid(0xba491361, 0xbe50, 0x451e, 0x95, 0xab, 0x6d, 0x4a, 0xcc, 0xc7, 0xda, 0xd8); + public static readonly Guid MF_ACTIVATE_CUSTOM_VIDEO_MIXER_CLSID = new Guid(0xba491360, 0xbe50, 0x451e, 0x95, 0xab, 0x6d, 0x4a, 0xcc, 0xc7, 0xda, 0xd8); + public static readonly Guid MF_ACTIVATE_CUSTOM_VIDEO_MIXER_FLAGS = new Guid(0xba491362, 0xbe50, 0x451e, 0x95, 0xab, 0x6d, 0x4a, 0xcc, 0xc7, 0xda, 0xd8); + public static readonly Guid MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_ACTIVATE = new Guid(0xba491365, 0xbe50, 0x451e, 0x95, 0xab, 0x6d, 0x4a, 0xcc, 0xc7, 0xda, 0xd8); + public static readonly Guid MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_CLSID = new Guid(0xba491364, 0xbe50, 0x451e, 0x95, 0xab, 0x6d, 0x4a, 0xcc, 0xc7, 0xda, 0xd8); + public static readonly Guid MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_FLAGS = new Guid(0xba491366, 0xbe50, 0x451e, 0x95, 0xab, 0x6d, 0x4a, 0xcc, 0xc7, 0xda, 0xd8); + public static readonly Guid MF_ACTIVATE_VIDEO_WINDOW = new Guid(0x9a2dbbdd, 0xf57e, 0x4162, 0x82, 0xb9, 0x68, 0x31, 0x37, 0x76, 0x82, 0xd3); + public static readonly Guid MF_SA_REQUIRED_SAMPLE_COUNT = new Guid(0x18802c61, 0x324b, 0x4952, 0xab, 0xd0, 0x17, 0x6f, 0xf5, 0xc6, 0x96, 0xff); + public static readonly Guid VIDEO_ZOOM_RECT = new Guid(0x7aaa1638, 0x1b7f, 0x4c93, 0xbd, 0x89, 0x5b, 0x9c, 0x9f, 0xb6, 0xfc, 0xf0); + + // Event Attributes + + // MF_EVENT_DO_THINNING {321EA6FB-DAD9-46e4-B31D-D2EAE7090E30} + public static readonly Guid MF_EVENT_DO_THINNING = new Guid(0x321ea6fb, 0xdad9, 0x46e4, 0xb3, 0x1d, 0xd2, 0xea, 0xe7, 0x9, 0xe, 0x30); + + // MF_EVENT_OUTPUT_NODE {830f1a8b-c060-46dd-a801-1c95dec9b107} + public static readonly Guid MF_EVENT_OUTPUT_NODE = new Guid(0x830f1a8b, 0xc060, 0x46dd, 0xa8, 0x01, 0x1c, 0x95, 0xde, 0xc9, 0xb1, 0x07); + + // MF_EVENT_MFT_INPUT_STREAM_ID {F29C2CCA-7AE6-42d2-B284-BF837CC874E2} + public static readonly Guid MF_EVENT_MFT_INPUT_STREAM_ID = new Guid(0xf29c2cca, 0x7ae6, 0x42d2, 0xb2, 0x84, 0xbf, 0x83, 0x7c, 0xc8, 0x74, 0xe2); + + // MF_EVENT_MFT_CONTEXT {B7CD31F1-899E-4b41-80C9-26A896D32977} + public static readonly Guid MF_EVENT_MFT_CONTEXT = new Guid(0xb7cd31f1, 0x899e, 0x4b41, 0x80, 0xc9, 0x26, 0xa8, 0x96, 0xd3, 0x29, 0x77); + + // MF_EVENT_PRESENTATION_TIME_OFFSET {5AD914D1-9B45-4a8d-A2C0-81D1E50BFB07} + public static readonly Guid MF_EVENT_PRESENTATION_TIME_OFFSET = new Guid(0x5ad914d1, 0x9b45, 0x4a8d, 0xa2, 0xc0, 0x81, 0xd1, 0xe5, 0xb, 0xfb, 0x7); + + // MF_EVENT_SCRUBSAMPLE_TIME {9AC712B3-DCB8-44d5-8D0C-37455A2782E3} + public static readonly Guid MF_EVENT_SCRUBSAMPLE_TIME = new Guid(0x9ac712b3, 0xdcb8, 0x44d5, 0x8d, 0xc, 0x37, 0x45, 0x5a, 0x27, 0x82, 0xe3); + + // MF_EVENT_SESSIONCAPS {7E5EBCD0-11B8-4abe-AFAD-10F6599A7F42} + public static readonly Guid MF_EVENT_SESSIONCAPS = new Guid(0x7e5ebcd0, 0x11b8, 0x4abe, 0xaf, 0xad, 0x10, 0xf6, 0x59, 0x9a, 0x7f, 0x42); + + // MF_EVENT_SESSIONCAPS_DELTA {7E5EBCD1-11B8-4abe-AFAD-10F6599A7F42} + // Type: UINT32 + public static readonly Guid MF_EVENT_SESSIONCAPS_DELTA = new Guid(0x7e5ebcd1, 0x11b8, 0x4abe, 0xaf, 0xad, 0x10, 0xf6, 0x59, 0x9a, 0x7f, 0x42); + + // MF_EVENT_SOURCE_ACTUAL_START {a8cc55a9-6b31-419f-845d-ffb351a2434b} + public static readonly Guid MF_EVENT_SOURCE_ACTUAL_START = new Guid(0xa8cc55a9, 0x6b31, 0x419f, 0x84, 0x5d, 0xff, 0xb3, 0x51, 0xa2, 0x43, 0x4b); + + // MF_EVENT_SOURCE_CHARACTERISTICS {47DB8490-8B22-4f52-AFDA-9CE1B2D3CFA8} + public static readonly Guid MF_EVENT_SOURCE_CHARACTERISTICS = new Guid(0x47db8490, 0x8b22, 0x4f52, 0xaf, 0xda, 0x9c, 0xe1, 0xb2, 0xd3, 0xcf, 0xa8); + + // MF_EVENT_SOURCE_CHARACTERISTICS_OLD {47DB8491-8B22-4f52-AFDA-9CE1B2D3CFA8} + public static readonly Guid MF_EVENT_SOURCE_CHARACTERISTICS_OLD = new Guid(0x47db8491, 0x8b22, 0x4f52, 0xaf, 0xda, 0x9c, 0xe1, 0xb2, 0xd3, 0xcf, 0xa8); + + // MF_EVENT_SOURCE_FAKE_START {a8cc55a7-6b31-419f-845d-ffb351a2434b} + public static readonly Guid MF_EVENT_SOURCE_FAKE_START = new Guid(0xa8cc55a7, 0x6b31, 0x419f, 0x84, 0x5d, 0xff, 0xb3, 0x51, 0xa2, 0x43, 0x4b); + + // MF_EVENT_SOURCE_PROJECTSTART {a8cc55a8-6b31-419f-845d-ffb351a2434b} + public static readonly Guid MF_EVENT_SOURCE_PROJECTSTART = new Guid(0xa8cc55a8, 0x6b31, 0x419f, 0x84, 0x5d, 0xff, 0xb3, 0x51, 0xa2, 0x43, 0x4b); + + // MF_EVENT_SOURCE_TOPOLOGY_CANCELED {DB62F650-9A5E-4704-ACF3-563BC6A73364} + public static readonly Guid MF_EVENT_SOURCE_TOPOLOGY_CANCELED = new Guid(0xdb62f650, 0x9a5e, 0x4704, 0xac, 0xf3, 0x56, 0x3b, 0xc6, 0xa7, 0x33, 0x64); + + // MF_EVENT_START_PRESENTATION_TIME {5AD914D0-9B45-4a8d-A2C0-81D1E50BFB07} + public static readonly Guid MF_EVENT_START_PRESENTATION_TIME = new Guid(0x5ad914d0, 0x9b45, 0x4a8d, 0xa2, 0xc0, 0x81, 0xd1, 0xe5, 0xb, 0xfb, 0x7); + + // MF_EVENT_START_PRESENTATION_TIME_AT_OUTPUT {5AD914D2-9B45-4a8d-A2C0-81D1E50BFB07} + public static readonly Guid MF_EVENT_START_PRESENTATION_TIME_AT_OUTPUT = new Guid(0x5ad914d2, 0x9b45, 0x4a8d, 0xa2, 0xc0, 0x81, 0xd1, 0xe5, 0xb, 0xfb, 0x7); + + // MF_EVENT_TOPOLOGY_STATUS {30C5018D-9A53-454b-AD9E-6D5F8FA7C43B} + public static readonly Guid MF_EVENT_TOPOLOGY_STATUS = new Guid(0x30c5018d, 0x9a53, 0x454b, 0xad, 0x9e, 0x6d, 0x5f, 0x8f, 0xa7, 0xc4, 0x3b); + + public static readonly Guid MF_SESSION_APPROX_EVENT_OCCURRENCE_TIME = new Guid(0x190e852f, 0x6238, 0x42d1, 0xb5, 0xaf, 0x69, 0xea, 0x33, 0x8e, 0xf8, 0x50); + + // Media Session Attributes + + public static readonly Guid MF_SESSION_CONTENT_PROTECTION_MANAGER = new Guid(0x1e83d482, 0x1f1c, 0x4571, 0x84, 0x5, 0x88, 0xf4, 0xb2, 0x18, 0x1f, 0x74); + public static readonly Guid MF_SESSION_GLOBAL_TIME = new Guid(0x1e83d482, 0x1f1c, 0x4571, 0x84, 0x5, 0x88, 0xf4, 0xb2, 0x18, 0x1f, 0x72); + public static readonly Guid MF_SESSION_QUALITY_MANAGER = new Guid(0x1e83d482, 0x1f1c, 0x4571, 0x84, 0x5, 0x88, 0xf4, 0xb2, 0x18, 0x1f, 0x73); + public static readonly Guid MF_SESSION_REMOTE_SOURCE_MODE = new Guid(0xf4033ef4, 0x9bb3, 0x4378, 0x94, 0x1f, 0x85, 0xa0, 0x85, 0x6b, 0xc2, 0x44); + public static readonly Guid MF_SESSION_SERVER_CONTEXT = new Guid(0xafe5b291, 0x50fa, 0x46e8, 0xb9, 0xbe, 0xc, 0xc, 0x3c, 0xe4, 0xb3, 0xa5); + public static readonly Guid MF_SESSION_TOPOLOADER = new Guid(0x1e83d482, 0x1f1c, 0x4571, 0x84, 0x5, 0x88, 0xf4, 0xb2, 0x18, 0x1f, 0x71); + + // Media Type Attributes + + // {48eba18e-f8c9-4687-bf11-0a74c9f96a8f} MF_MT_MAJOR_TYPE {GUID} + public static readonly Guid MF_MT_MAJOR_TYPE = new Guid(0x48eba18e, 0xf8c9, 0x4687, 0xbf, 0x11, 0x0a, 0x74, 0xc9, 0xf9, 0x6a, 0x8f); + + // {f7e34c9a-42e8-4714-b74b-cb29d72c35e5} MF_MT_SUBTYPE {GUID} + public static readonly Guid MF_MT_SUBTYPE = new Guid(0xf7e34c9a, 0x42e8, 0x4714, 0xb7, 0x4b, 0xcb, 0x29, 0xd7, 0x2c, 0x35, 0xe5); + + // {c9173739-5e56-461c-b713-46fb995cb95f} MF_MT_ALL_SAMPLES_INDEPENDENT {UINT32 (BOOL)} + public static readonly Guid MF_MT_ALL_SAMPLES_INDEPENDENT = new Guid(0xc9173739, 0x5e56, 0x461c, 0xb7, 0x13, 0x46, 0xfb, 0x99, 0x5c, 0xb9, 0x5f); + + // {b8ebefaf-b718-4e04-b0a9-116775e3321b} MF_MT_FIXED_SIZE_SAMPLES {UINT32 (BOOL)} + public static readonly Guid MF_MT_FIXED_SIZE_SAMPLES = new Guid(0xb8ebefaf, 0xb718, 0x4e04, 0xb0, 0xa9, 0x11, 0x67, 0x75, 0xe3, 0x32, 0x1b); + + // {3afd0cee-18f2-4ba5-a110-8bea502e1f92} MF_MT_COMPRESSED {UINT32 (BOOL)} + public static readonly Guid MF_MT_COMPRESSED = new Guid(0x3afd0cee, 0x18f2, 0x4ba5, 0xa1, 0x10, 0x8b, 0xea, 0x50, 0x2e, 0x1f, 0x92); + + // {dad3ab78-1990-408b-bce2-eba673dacc10} MF_MT_SAMPLE_SIZE {UINT32} + public static readonly Guid MF_MT_SAMPLE_SIZE = new Guid(0xdad3ab78, 0x1990, 0x408b, 0xbc, 0xe2, 0xeb, 0xa6, 0x73, 0xda, 0xcc, 0x10); + + // 4d3f7b23-d02f-4e6c-9bee-e4bf2c6c695d MF_MT_WRAPPED_TYPE {Blob} + public static readonly Guid MF_MT_WRAPPED_TYPE = new Guid(0x4d3f7b23, 0xd02f, 0x4e6c, 0x9b, 0xee, 0xe4, 0xbf, 0x2c, 0x6c, 0x69, 0x5d); + + // {37e48bf5-645e-4c5b-89de-ada9e29b696a} MF_MT_AUDIO_NUM_CHANNELS {UINT32} + public static readonly Guid MF_MT_AUDIO_NUM_CHANNELS = new Guid(0x37e48bf5, 0x645e, 0x4c5b, 0x89, 0xde, 0xad, 0xa9, 0xe2, 0x9b, 0x69, 0x6a); + + // {5faeeae7-0290-4c31-9e8a-c534f68d9dba} MF_MT_AUDIO_SAMPLES_PER_SECOND {UINT32} + public static readonly Guid MF_MT_AUDIO_SAMPLES_PER_SECOND = new Guid(0x5faeeae7, 0x0290, 0x4c31, 0x9e, 0x8a, 0xc5, 0x34, 0xf6, 0x8d, 0x9d, 0xba); + + // {fb3b724a-cfb5-4319-aefe-6e42b2406132} MF_MT_AUDIO_FLOAT_SAMPLES_PER_SECOND {double} + public static readonly Guid MF_MT_AUDIO_FLOAT_SAMPLES_PER_SECOND = new Guid(0xfb3b724a, 0xcfb5, 0x4319, 0xae, 0xfe, 0x6e, 0x42, 0xb2, 0x40, 0x61, 0x32); + + // {1aab75c8-cfef-451c-ab95-ac034b8e1731} MF_MT_AUDIO_AVG_BYTES_PER_SECOND {UINT32} + public static readonly Guid MF_MT_AUDIO_AVG_BYTES_PER_SECOND = new Guid(0x1aab75c8, 0xcfef, 0x451c, 0xab, 0x95, 0xac, 0x03, 0x4b, 0x8e, 0x17, 0x31); + + // {322de230-9eeb-43bd-ab7a-ff412251541d} MF_MT_AUDIO_BLOCK_ALIGNMENT {UINT32} + public static readonly Guid MF_MT_AUDIO_BLOCK_ALIGNMENT = new Guid(0x322de230, 0x9eeb, 0x43bd, 0xab, 0x7a, 0xff, 0x41, 0x22, 0x51, 0x54, 0x1d); + + // {f2deb57f-40fa-4764-aa33-ed4f2d1ff669} MF_MT_AUDIO_BITS_PER_SAMPLE {UINT32} + public static readonly Guid MF_MT_AUDIO_BITS_PER_SAMPLE = new Guid(0xf2deb57f, 0x40fa, 0x4764, 0xaa, 0x33, 0xed, 0x4f, 0x2d, 0x1f, 0xf6, 0x69); + + // {d9bf8d6a-9530-4b7c-9ddf-ff6fd58bbd06} MF_MT_AUDIO_VALID_BITS_PER_SAMPLE {UINT32} + public static readonly Guid MF_MT_AUDIO_VALID_BITS_PER_SAMPLE = new Guid(0xd9bf8d6a, 0x9530, 0x4b7c, 0x9d, 0xdf, 0xff, 0x6f, 0xd5, 0x8b, 0xbd, 0x06); + + // {aab15aac-e13a-4995-9222-501ea15c6877} MF_MT_AUDIO_SAMPLES_PER_BLOCK {UINT32} + public static readonly Guid MF_MT_AUDIO_SAMPLES_PER_BLOCK = new Guid(0xaab15aac, 0xe13a, 0x4995, 0x92, 0x22, 0x50, 0x1e, 0xa1, 0x5c, 0x68, 0x77); + + // {55fb5765-644a-4caf-8479-938983bb1588}` MF_MT_AUDIO_CHANNEL_MASK {UINT32} + public static readonly Guid MF_MT_AUDIO_CHANNEL_MASK = new Guid(0x55fb5765, 0x644a, 0x4caf, 0x84, 0x79, 0x93, 0x89, 0x83, 0xbb, 0x15, 0x88); + + // {9d62927c-36be-4cf2-b5c4-a3926e3e8711}` MF_MT_AUDIO_FOLDDOWN_MATRIX {BLOB, MFFOLDDOWN_MATRIX} + public static readonly Guid MF_MT_AUDIO_FOLDDOWN_MATRIX = new Guid(0x9d62927c, 0x36be, 0x4cf2, 0xb5, 0xc4, 0xa3, 0x92, 0x6e, 0x3e, 0x87, 0x11); + + // {0x9d62927d-36be-4cf2-b5c4-a3926e3e8711}` MF_MT_AUDIO_WMADRC_PEAKREF {UINT32} + public static readonly Guid MF_MT_AUDIO_WMADRC_PEAKREF = new Guid(0x9d62927d, 0x36be, 0x4cf2, 0xb5, 0xc4, 0xa3, 0x92, 0x6e, 0x3e, 0x87, 0x11); + + // {0x9d62927e-36be-4cf2-b5c4-a3926e3e8711}` MF_MT_AUDIO_WMADRC_PEAKTARGET {UINT32} + public static readonly Guid MF_MT_AUDIO_WMADRC_PEAKTARGET = new Guid(0x9d62927e, 0x36be, 0x4cf2, 0xb5, 0xc4, 0xa3, 0x92, 0x6e, 0x3e, 0x87, 0x11); + + // {0x9d62927f-36be-4cf2-b5c4-a3926e3e8711}` MF_MT_AUDIO_WMADRC_AVGREF {UINT32} + public static readonly Guid MF_MT_AUDIO_WMADRC_AVGREF = new Guid(0x9d62927f, 0x36be, 0x4cf2, 0xb5, 0xc4, 0xa3, 0x92, 0x6e, 0x3e, 0x87, 0x11); + + // {0x9d629280-36be-4cf2-b5c4-a3926e3e8711}` MF_MT_AUDIO_WMADRC_AVGTARGET {UINT32} + public static readonly Guid MF_MT_AUDIO_WMADRC_AVGTARGET = new Guid(0x9d629280, 0x36be, 0x4cf2, 0xb5, 0xc4, 0xa3, 0x92, 0x6e, 0x3e, 0x87, 0x11); + + // {a901aaba-e037-458a-bdf6-545be2074042} MF_MT_AUDIO_PREFER_WAVEFORMATEX {UINT32 (BOOL)} + public static readonly Guid MF_MT_AUDIO_PREFER_WAVEFORMATEX = new Guid(0xa901aaba, 0xe037, 0x458a, 0xbd, 0xf6, 0x54, 0x5b, 0xe2, 0x07, 0x40, 0x42); + + // {BFBABE79-7434-4d1c-94F0-72A3B9E17188} MF_MT_AAC_PAYLOAD_TYPE {UINT32} + public static readonly Guid MF_MT_AAC_PAYLOAD_TYPE = new Guid(0xbfbabe79, 0x7434, 0x4d1c, 0x94, 0xf0, 0x72, 0xa3, 0xb9, 0xe1, 0x71, 0x88); + + // {7632F0E6-9538-4d61-ACDA-EA29C8C14456} MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION {UINT32} + public static readonly Guid MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION = new Guid(0x7632f0e6, 0x9538, 0x4d61, 0xac, 0xda, 0xea, 0x29, 0xc8, 0xc1, 0x44, 0x56); + + // {1652c33d-d6b2-4012-b834-72030849a37d} MF_MT_FRAME_SIZE {UINT64 (HI32(Width),LO32(Height))} + public static readonly Guid MF_MT_FRAME_SIZE = new Guid(0x1652c33d, 0xd6b2, 0x4012, 0xb8, 0x34, 0x72, 0x03, 0x08, 0x49, 0xa3, 0x7d); + + // {c459a2e8-3d2c-4e44-b132-fee5156c7bb0} MF_MT_FRAME_RATE {UINT64 (HI32(Numerator),LO32(Denominator))} + public static readonly Guid MF_MT_FRAME_RATE = new Guid(0xc459a2e8, 0x3d2c, 0x4e44, 0xb1, 0x32, 0xfe, 0xe5, 0x15, 0x6c, 0x7b, 0xb0); + + // {c6376a1e-8d0a-4027-be45-6d9a0ad39bb6} MF_MT_PIXEL_ASPECT_RATIO {UINT64 (HI32(Numerator),LO32(Denominator))} + public static readonly Guid MF_MT_PIXEL_ASPECT_RATIO = new Guid(0xc6376a1e, 0x8d0a, 0x4027, 0xbe, 0x45, 0x6d, 0x9a, 0x0a, 0xd3, 0x9b, 0xb6); + + // {8772f323-355a-4cc7-bb78-6d61a048ae82} MF_MT_DRM_FLAGS {UINT32 (anyof MFVideoDRMFlags)} + public static readonly Guid MF_MT_DRM_FLAGS = new Guid(0x8772f323, 0x355a, 0x4cc7, 0xbb, 0x78, 0x6d, 0x61, 0xa0, 0x48, 0xae, 0x82); + + // {4d0e73e5-80ea-4354-a9d0-1176ceb028ea} MF_MT_PAD_CONTROL_FLAGS {UINT32 (oneof MFVideoPadFlags)} + public static readonly Guid MF_MT_PAD_CONTROL_FLAGS = new Guid(0x4d0e73e5, 0x80ea, 0x4354, 0xa9, 0xd0, 0x11, 0x76, 0xce, 0xb0, 0x28, 0xea); + + // {68aca3cc-22d0-44e6-85f8-28167197fa38} MF_MT_SOURCE_CONTENT_HINT {UINT32 (oneof MFVideoSrcContentHintFlags)} + public static readonly Guid MF_MT_SOURCE_CONTENT_HINT = new Guid(0x68aca3cc, 0x22d0, 0x44e6, 0x85, 0xf8, 0x28, 0x16, 0x71, 0x97, 0xfa, 0x38); + + // {65df2370-c773-4c33-aa64-843e068efb0c} MF_MT_CHROMA_SITING {UINT32 (anyof MFVideoChromaSubsampling)} + public static readonly Guid MF_MT_VIDEO_CHROMA_SITING = new Guid(0x65df2370, 0xc773, 0x4c33, 0xaa, 0x64, 0x84, 0x3e, 0x06, 0x8e, 0xfb, 0x0c); + + // {e2724bb8-e676-4806-b4b2-a8d6efb44ccd} MF_MT_INTERLACE_MODE {UINT32 (oneof MFVideoInterlaceMode)} + public static readonly Guid MF_MT_INTERLACE_MODE = new Guid(0xe2724bb8, 0xe676, 0x4806, 0xb4, 0xb2, 0xa8, 0xd6, 0xef, 0xb4, 0x4c, 0xcd); + + // {5fb0fce9-be5c-4935-a811-ec838f8eed93} MF_MT_TRANSFER_FUNCTION {UINT32 (oneof MFVideoTransferFunction)} + public static readonly Guid MF_MT_TRANSFER_FUNCTION = new Guid(0x5fb0fce9, 0xbe5c, 0x4935, 0xa8, 0x11, 0xec, 0x83, 0x8f, 0x8e, 0xed, 0x93); + + // {dbfbe4d7-0740-4ee0-8192-850ab0e21935} MF_MT_VIDEO_PRIMARIES {UINT32 (oneof MFVideoPrimaries)} + public static readonly Guid MF_MT_VIDEO_PRIMARIES = new Guid(0xdbfbe4d7, 0x0740, 0x4ee0, 0x81, 0x92, 0x85, 0x0a, 0xb0, 0xe2, 0x19, 0x35); + + // {47537213-8cfb-4722-aa34-fbc9e24d77b8} MF_MT_CUSTOM_VIDEO_PRIMARIES {BLOB (MT_CUSTOM_VIDEO_PRIMARIES)} + public static readonly Guid MF_MT_CUSTOM_VIDEO_PRIMARIES = new Guid(0x47537213, 0x8cfb, 0x4722, 0xaa, 0x34, 0xfb, 0xc9, 0xe2, 0x4d, 0x77, 0xb8); + + // {3e23d450-2c75-4d25-a00e-b91670d12327} MF_MT_YUV_MATRIX {UINT32 (oneof MFVideoTransferMatrix)} + public static readonly Guid MF_MT_YUV_MATRIX = new Guid(0x3e23d450, 0x2c75, 0x4d25, 0xa0, 0x0e, 0xb9, 0x16, 0x70, 0xd1, 0x23, 0x27); + + // {53a0529c-890b-4216-8bf9-599367ad6d20} MF_MT_VIDEO_LIGHTING {UINT32 (oneof MFVideoLighting)} + public static readonly Guid MF_MT_VIDEO_LIGHTING = new Guid(0x53a0529c, 0x890b, 0x4216, 0x8b, 0xf9, 0x59, 0x93, 0x67, 0xad, 0x6d, 0x20); + + // {c21b8ee5-b956-4071-8daf-325edf5cab11} MF_MT_VIDEO_NOMINAL_RANGE {UINT32 (oneof MFNominalRange)} + public static readonly Guid MF_MT_VIDEO_NOMINAL_RANGE = new Guid(0xc21b8ee5, 0xb956, 0x4071, 0x8d, 0xaf, 0x32, 0x5e, 0xdf, 0x5c, 0xab, 0x11); + + // {66758743-7e5f-400d-980a-aa8596c85696} MF_MT_GEOMETRIC_APERTURE {BLOB (MFVideoArea)} + public static readonly Guid MF_MT_GEOMETRIC_APERTURE = new Guid(0x66758743, 0x7e5f, 0x400d, 0x98, 0x0a, 0xaa, 0x85, 0x96, 0xc8, 0x56, 0x96); + + // {d7388766-18fe-48c6-a177-ee894867c8c4} MF_MT_MINIMUM_DISPLAY_APERTURE {BLOB (MFVideoArea)} + public static readonly Guid MF_MT_MINIMUM_DISPLAY_APERTURE = new Guid(0xd7388766, 0x18fe, 0x48c6, 0xa1, 0x77, 0xee, 0x89, 0x48, 0x67, 0xc8, 0xc4); + + // {79614dde-9187-48fb-b8c7-4d52689de649} MF_MT_PAN_SCAN_APERTURE {BLOB (MFVideoArea)} + public static readonly Guid MF_MT_PAN_SCAN_APERTURE = new Guid(0x79614dde, 0x9187, 0x48fb, 0xb8, 0xc7, 0x4d, 0x52, 0x68, 0x9d, 0xe6, 0x49); + + // {4b7f6bc3-8b13-40b2-a993-abf630b8204e} MF_MT_PAN_SCAN_ENABLED {UINT32 (BOOL)} + public static readonly Guid MF_MT_PAN_SCAN_ENABLED = new Guid(0x4b7f6bc3, 0x8b13, 0x40b2, 0xa9, 0x93, 0xab, 0xf6, 0x30, 0xb8, 0x20, 0x4e); + + // {20332624-fb0d-4d9e-bd0d-cbf6786c102e} MF_MT_AVG_BITRATE {UINT32} + public static readonly Guid MF_MT_AVG_BITRATE = new Guid(0x20332624, 0xfb0d, 0x4d9e, 0xbd, 0x0d, 0xcb, 0xf6, 0x78, 0x6c, 0x10, 0x2e); + + // {799cabd6-3508-4db4-a3c7-569cd533deb1} MF_MT_AVG_BIT_ERROR_RATE {UINT32} + public static readonly Guid MF_MT_AVG_BIT_ERROR_RATE = new Guid(0x799cabd6, 0x3508, 0x4db4, 0xa3, 0xc7, 0x56, 0x9c, 0xd5, 0x33, 0xde, 0xb1); + + // {c16eb52b-73a1-476f-8d62-839d6a020652} MF_MT_MAX_KEYFRAME_SPACING {UINT32} + public static readonly Guid MF_MT_MAX_KEYFRAME_SPACING = new Guid(0xc16eb52b, 0x73a1, 0x476f, 0x8d, 0x62, 0x83, 0x9d, 0x6a, 0x02, 0x06, 0x52); + + // {644b4e48-1e02-4516-b0eb-c01ca9d49ac6} MF_MT_DEFAULT_STRIDE {UINT32 (INT32)} // in bytes + public static readonly Guid MF_MT_DEFAULT_STRIDE = new Guid(0x644b4e48, 0x1e02, 0x4516, 0xb0, 0xeb, 0xc0, 0x1c, 0xa9, 0xd4, 0x9a, 0xc6); + + // {6d283f42-9846-4410-afd9-654d503b1a54} MF_MT_PALETTE {BLOB (array of MFPaletteEntry - usually 256)} + public static readonly Guid MF_MT_PALETTE = new Guid(0x6d283f42, 0x9846, 0x4410, 0xaf, 0xd9, 0x65, 0x4d, 0x50, 0x3b, 0x1a, 0x54); + + // {b6bc765f-4c3b-40a4-bd51-2535b66fe09d} MF_MT_USER_DATA {BLOB} + public static readonly Guid MF_MT_USER_DATA = new Guid(0xb6bc765f, 0x4c3b, 0x40a4, 0xbd, 0x51, 0x25, 0x35, 0xb6, 0x6f, 0xe0, 0x9d); + + // {73d1072d-1870-4174-a063-29ff4ff6c11e} + public static readonly Guid MF_MT_AM_FORMAT_TYPE = new Guid(0x73d1072d, 0x1870, 0x4174, 0xa0, 0x63, 0x29, 0xff, 0x4f, 0xf6, 0xc1, 0x1e); + + // {91f67885-4333-4280-97cd-bd5a6c03a06e} MF_MT_MPEG_START_TIME_CODE {UINT32} + public static readonly Guid MF_MT_MPEG_START_TIME_CODE = new Guid(0x91f67885, 0x4333, 0x4280, 0x97, 0xcd, 0xbd, 0x5a, 0x6c, 0x03, 0xa0, 0x6e); + + // {ad76a80b-2d5c-4e0b-b375-64e520137036} MF_MT_MPEG2_PROFILE {UINT32 (oneof AM_MPEG2Profile)} + public static readonly Guid MF_MT_MPEG2_PROFILE = new Guid(0xad76a80b, 0x2d5c, 0x4e0b, 0xb3, 0x75, 0x64, 0xe5, 0x20, 0x13, 0x70, 0x36); + + // {96f66574-11c5-4015-8666-bff516436da7} MF_MT_MPEG2_LEVEL {UINT32 (oneof AM_MPEG2Level)} + public static readonly Guid MF_MT_MPEG2_LEVEL = new Guid(0x96f66574, 0x11c5, 0x4015, 0x86, 0x66, 0xbf, 0xf5, 0x16, 0x43, 0x6d, 0xa7); + + // {31e3991d-f701-4b2f-b426-8ae3bda9e04b} MF_MT_MPEG2_FLAGS {UINT32 (anyof AMMPEG2_xxx flags)} + public static readonly Guid MF_MT_MPEG2_FLAGS = new Guid(0x31e3991d, 0xf701, 0x4b2f, 0xb4, 0x26, 0x8a, 0xe3, 0xbd, 0xa9, 0xe0, 0x4b); + + // {3c036de7-3ad0-4c9e-9216-ee6d6ac21cb3} MF_MT_MPEG_SEQUENCE_HEADER {BLOB} + public static readonly Guid MF_MT_MPEG_SEQUENCE_HEADER = new Guid(0x3c036de7, 0x3ad0, 0x4c9e, 0x92, 0x16, 0xee, 0x6d, 0x6a, 0xc2, 0x1c, 0xb3); + + // {84bd5d88-0fb8-4ac8-be4b-a8848bef98f3} MF_MT_DV_AAUX_SRC_PACK_0 {UINT32} + public static readonly Guid MF_MT_DV_AAUX_SRC_PACK_0 = new Guid(0x84bd5d88, 0x0fb8, 0x4ac8, 0xbe, 0x4b, 0xa8, 0x84, 0x8b, 0xef, 0x98, 0xf3); + + // {f731004e-1dd1-4515-aabe-f0c06aa536ac} MF_MT_DV_AAUX_CTRL_PACK_0 {UINT32} + public static readonly Guid MF_MT_DV_AAUX_CTRL_PACK_0 = new Guid(0xf731004e, 0x1dd1, 0x4515, 0xaa, 0xbe, 0xf0, 0xc0, 0x6a, 0xa5, 0x36, 0xac); + + // {720e6544-0225-4003-a651-0196563a958e} MF_MT_DV_AAUX_SRC_PACK_1 {UINT32} + public static readonly Guid MF_MT_DV_AAUX_SRC_PACK_1 = new Guid(0x720e6544, 0x0225, 0x4003, 0xa6, 0x51, 0x01, 0x96, 0x56, 0x3a, 0x95, 0x8e); + + // {cd1f470d-1f04-4fe0-bfb9-d07ae0386ad8} MF_MT_DV_AAUX_CTRL_PACK_1 {UINT32} + public static readonly Guid MF_MT_DV_AAUX_CTRL_PACK_1 = new Guid(0xcd1f470d, 0x1f04, 0x4fe0, 0xbf, 0xb9, 0xd0, 0x7a, 0xe0, 0x38, 0x6a, 0xd8); + + // {41402d9d-7b57-43c6-b129-2cb997f15009} MF_MT_DV_VAUX_SRC_PACK {UINT32} + public static readonly Guid MF_MT_DV_VAUX_SRC_PACK = new Guid(0x41402d9d, 0x7b57, 0x43c6, 0xb1, 0x29, 0x2c, 0xb9, 0x97, 0xf1, 0x50, 0x09); + + // {2f84e1c4-0da1-4788-938e-0dfbfbb34b48} MF_MT_DV_VAUX_CTRL_PACK {UINT32} + public static readonly Guid MF_MT_DV_VAUX_CTRL_PACK = new Guid(0x2f84e1c4, 0x0da1, 0x4788, 0x93, 0x8e, 0x0d, 0xfb, 0xfb, 0xb3, 0x4b, 0x48); + + // Sample Attributes + + // {941ce0a3-6ae3-4dda-9a08-a64298340617} MFSampleExtension_BottomFieldFirst + public static readonly Guid MFSampleExtension_BottomFieldFirst = new Guid(0x941ce0a3, 0x6ae3, 0x4dda, 0x9a, 0x08, 0xa6, 0x42, 0x98, 0x34, 0x06, 0x17); + + // MFSampleExtension_CleanPoint {9cdf01d8-a0f0-43ba-b077-eaa06cbd728a} + public static readonly Guid MFSampleExtension_CleanPoint = new Guid(0x9cdf01d8, 0xa0f0, 0x43ba, 0xb0, 0x77, 0xea, 0xa0, 0x6c, 0xbd, 0x72, 0x8a); + + // {6852465a-ae1c-4553-8e9b-c3420fcb1637} MFSampleExtension_DerivedFromTopField + public static readonly Guid MFSampleExtension_DerivedFromTopField = new Guid(0x6852465a, 0xae1c, 0x4553, 0x8e, 0x9b, 0xc3, 0x42, 0x0f, 0xcb, 0x16, 0x37); + + // MFSampleExtension_Discontinuity {9cdf01d9-a0f0-43ba-b077-eaa06cbd728a} + public static readonly Guid MFSampleExtension_Discontinuity = new Guid(0x9cdf01d9, 0xa0f0, 0x43ba, 0xb0, 0x77, 0xea, 0xa0, 0x6c, 0xbd, 0x72, 0x8a); + + // {b1d5830a-deb8-40e3-90fa-389943716461} MFSampleExtension_Interlaced + public static readonly Guid MFSampleExtension_Interlaced = new Guid(0xb1d5830a, 0xdeb8, 0x40e3, 0x90, 0xfa, 0x38, 0x99, 0x43, 0x71, 0x64, 0x61); + + // {304d257c-7493-4fbd-b149-9228de8d9a99} MFSampleExtension_RepeatFirstField + public static readonly Guid MFSampleExtension_RepeatFirstField = new Guid(0x304d257c, 0x7493, 0x4fbd, 0xb1, 0x49, 0x92, 0x28, 0xde, 0x8d, 0x9a, 0x99); + + // {9d85f816-658b-455a-bde0-9fa7e15ab8f9} MFSampleExtension_SingleField + public static readonly Guid MFSampleExtension_SingleField = new Guid(0x9d85f816, 0x658b, 0x455a, 0xbd, 0xe0, 0x9f, 0xa7, 0xe1, 0x5a, 0xb8, 0xf9); + + // MFSampleExtension_Token {8294da66-f328-4805-b551-00deb4c57a61} + public static readonly Guid MFSampleExtension_Token = new Guid(0x8294da66, 0xf328, 0x4805, 0xb5, 0x51, 0x00, 0xde, 0xb4, 0xc5, 0x7a, 0x61); + + // Sample Grabber Sink Attributes + public static readonly Guid MF_SAMPLEGRABBERSINK_SAMPLE_TIME_OFFSET = new Guid(0x62e3d776, 0x8100, 0x4e03, 0xa6, 0xe8, 0xbd, 0x38, 0x57, 0xac, 0x9c, 0x47); + + // Stream descriptor Attributes + + public static readonly Guid MF_SD_LANGUAGE = new Guid(0xaf2180, 0xbdc2, 0x423c, 0xab, 0xca, 0xf5, 0x3, 0x59, 0x3b, 0xc1, 0x21); + public static readonly Guid MF_SD_PROTECTED = new Guid(0xaf2181, 0xbdc2, 0x423c, 0xab, 0xca, 0xf5, 0x3, 0x59, 0x3b, 0xc1, 0x21); + public static readonly Guid MF_SD_SAMI_LANGUAGE = new Guid(0x36fcb98a, 0x6cd0, 0x44cb, 0xac, 0xb9, 0xa8, 0xf5, 0x60, 0xd, 0xd0, 0xbb); + + // Topology Attributes + public static readonly Guid MF_TOPOLOGY_NO_MARKIN_MARKOUT = new Guid(0x7ed3f804, 0x86bb, 0x4b3f, 0xb7, 0xe4, 0x7c, 0xb4, 0x3a, 0xfd, 0x4b, 0x80); + public static readonly Guid MF_TOPOLOGY_PROJECTSTART = new Guid(0x7ed3f802, 0x86bb, 0x4b3f, 0xb7, 0xe4, 0x7c, 0xb4, 0x3a, 0xfd, 0x4b, 0x80); + public static readonly Guid MF_TOPOLOGY_PROJECTSTOP = new Guid(0x7ed3f803, 0x86bb, 0x4b3f, 0xb7, 0xe4, 0x7c, 0xb4, 0x3a, 0xfd, 0x4b, 0x80); + public static readonly Guid MF_TOPOLOGY_RESOLUTION_STATUS = new Guid(0x494bbcde, 0xb031, 0x4e38, 0x97, 0xc4, 0xd5, 0x42, 0x2d, 0xd6, 0x18, 0xdc); + + // Topology Node Attributes + public static readonly Guid MF_TOPONODE_CONNECT_METHOD = new Guid(0x494bbcf1, 0xb031, 0x4e38, 0x97, 0xc4, 0xd5, 0x42, 0x2d, 0xd6, 0x18, 0xdc); + public static readonly Guid MF_TOPONODE_D3DAWARE = new Guid(0x494bbced, 0xb031, 0x4e38, 0x97, 0xc4, 0xd5, 0x42, 0x2d, 0xd6, 0x18, 0xdc); + public static readonly Guid MF_TOPONODE_DECODER = new Guid(0x494bbd02, 0xb031, 0x4e38, 0x97, 0xc4, 0xd5, 0x42, 0x2d, 0xd6, 0x18, 0xdc); + public static readonly Guid MF_TOPONODE_DECRYPTOR = new Guid(0x494bbcfa, 0xb031, 0x4e38, 0x97, 0xc4, 0xd5, 0x42, 0x2d, 0xd6, 0x18, 0xdc); + public static readonly Guid MF_TOPONODE_DISABLE_PREROLL = new Guid(0x14932f9e, 0x9087, 0x4bb4, 0x84, 0x12, 0x51, 0x67, 0x14, 0x5c, 0xbe, 0x04); + public static readonly Guid MF_TOPONODE_DISCARDABLE = new Guid(0x494bbcfb, 0xb031, 0x4e38, 0x97, 0xc4, 0xd5, 0x42, 0x2d, 0xd6, 0x18, 0xdc); + public static readonly Guid MF_TOPONODE_DRAIN = new Guid(0x494bbce9, 0xb031, 0x4e38, 0x97, 0xc4, 0xd5, 0x42, 0x2d, 0xd6, 0x18, 0xdc); + public static readonly Guid MF_TOPONODE_ERROR_MAJORTYPE = new Guid(0x494bbcfd, 0xb031, 0x4e38, 0x97, 0xc4, 0xd5, 0x42, 0x2d, 0xd6, 0x18, 0xdc); + public static readonly Guid MF_TOPONODE_ERROR_SUBTYPE = new Guid(0x494bbcfe, 0xb031, 0x4e38, 0x97, 0xc4, 0xd5, 0x42, 0x2d, 0xd6, 0x18, 0xdc); + public static readonly Guid MF_TOPONODE_ERRORCODE = new Guid(0x494bbcee, 0xb031, 0x4e38, 0x97, 0xc4, 0xd5, 0x42, 0x2d, 0xd6, 0x18, 0xdc); + public static readonly Guid MF_TOPONODE_FLUSH = new Guid(0x494bbce8, 0xb031, 0x4e38, 0x97, 0xc4, 0xd5, 0x42, 0x2d, 0xd6, 0x18, 0xdc); + public static readonly Guid MF_TOPONODE_LOCKED = new Guid(0x494bbcf7, 0xb031, 0x4e38, 0x97, 0xc4, 0xd5, 0x42, 0x2d, 0xd6, 0x18, 0xdc); + public static readonly Guid MF_TOPONODE_MARKIN_HERE = new Guid(0x494bbd00, 0xb031, 0x4e38, 0x97, 0xc4, 0xd5, 0x42, 0x2d, 0xd6, 0x18, 0xdc); + public static readonly Guid MF_TOPONODE_MARKOUT_HERE = new Guid(0x494bbd01, 0xb031, 0x4e38, 0x97, 0xc4, 0xd5, 0x42, 0x2d, 0xd6, 0x18, 0xdc); + public static readonly Guid MF_TOPONODE_MEDIASTART = new Guid(0x835c58ea, 0xe075, 0x4bc7, 0xbc, 0xba, 0x4d, 0xe0, 0x00, 0xdf, 0x9a, 0xe6); + public static readonly Guid MF_TOPONODE_MEDIASTOP = new Guid(0x835c58eb, 0xe075, 0x4bc7, 0xbc, 0xba, 0x4d, 0xe0, 0x00, 0xdf, 0x9a, 0xe6); + public static readonly Guid MF_TOPONODE_NOSHUTDOWN_ON_REMOVE = new Guid(0x14932f9c, 0x9087, 0x4bb4, 0x84, 0x12, 0x51, 0x67, 0x14, 0x5c, 0xbe, 0x04); + public static readonly Guid MF_TOPONODE_PRESENTATION_DESCRIPTOR = new Guid(0x835c58ed, 0xe075, 0x4bc7, 0xbc, 0xba, 0x4d, 0xe0, 0x00, 0xdf, 0x9a, 0xe6); + public static readonly Guid MF_TOPONODE_PRIMARYOUTPUT = new Guid(0x6304ef99, 0x16b2, 0x4ebe, 0x9d, 0x67, 0xe4, 0xc5, 0x39, 0xb3, 0xa2, 0x59); + public static readonly Guid MF_TOPONODE_RATELESS = new Guid(0x14932f9d, 0x9087, 0x4bb4, 0x84, 0x12, 0x51, 0x67, 0x14, 0x5c, 0xbe, 0x04); + public static readonly Guid MF_TOPONODE_SEQUENCE_ELEMENTID = new Guid(0x835c58ef, 0xe075, 0x4bc7, 0xbc, 0xba, 0x4d, 0xe0, 0x00, 0xdf, 0x9a, 0xe6); + public static readonly Guid MF_TOPONODE_SOURCE = new Guid(0x835c58ec, 0xe075, 0x4bc7, 0xbc, 0xba, 0x4d, 0xe0, 0x00, 0xdf, 0x9a, 0xe6); + public static readonly Guid MF_TOPONODE_STREAM_DESCRIPTOR = new Guid(0x835c58ee, 0xe075, 0x4bc7, 0xbc, 0xba, 0x4d, 0xe0, 0x00, 0xdf, 0x9a, 0xe6); + public static readonly Guid MF_TOPONODE_STREAMID = new Guid(0x14932f9b, 0x9087, 0x4bb4, 0x84, 0x12, 0x51, 0x67, 0x14, 0x5c, 0xbe, 0x04); + public static readonly Guid MF_TOPONODE_TRANSFORM_OBJECTID = new Guid(0x88dcc0c9, 0x293e, 0x4e8b, 0x9a, 0xeb, 0xa, 0xd6, 0x4c, 0xc0, 0x16, 0xb0); + public static readonly Guid MF_TOPONODE_WORKQUEUE_ID = new Guid(0x494bbcf8, 0xb031, 0x4e38, 0x97, 0xc4, 0xd5, 0x42, 0x2d, 0xd6, 0x18, 0xdc); + public static readonly Guid MF_TOPONODE_WORKQUEUE_MMCSS_CLASS = new Guid(0x494bbcf9, 0xb031, 0x4e38, 0x97, 0xc4, 0xd5, 0x42, 0x2d, 0xd6, 0x18, 0xdc); + public static readonly Guid MF_TOPONODE_WORKQUEUE_MMCSS_TASKID = new Guid(0x494bbcff, 0xb031, 0x4e38, 0x97, 0xc4, 0xd5, 0x42, 0x2d, 0xd6, 0x18, 0xdc); + + // Transform Attributes + public static readonly Guid MF_ACTIVATE_MFT_LOCKED = new Guid(0xc1f6093c, 0x7f65, 0x4fbd, 0x9e, 0x39, 0x5f, 0xae, 0xc3, 0xc4, 0xfb, 0xd7); + public static readonly Guid MF_SA_D3D_AWARE = new Guid(0xeaa35c29, 0x775e, 0x488e, 0x9b, 0x61, 0xb3, 0x28, 0x3e, 0x49, 0x58, 0x3b); + + // {53476A11-3F13-49fb-AC42-EE2733C96741} MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE {UINT32 (BOOL)} + public static readonly Guid MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE = new Guid(0x53476a11, 0x3f13, 0x49fb, 0xac, 0x42, 0xee, 0x27, 0x33, 0xc9, 0x67, 0x41); + + // Presentation Descriptor Attributes + + public static readonly Guid MF_PD_APP_CONTEXT = new Guid(0x6c990d32, 0xbb8e, 0x477a, 0x85, 0x98, 0xd, 0x5d, 0x96, 0xfc, 0xd8, 0x8a); + public static readonly Guid MF_PD_DURATION = new Guid(0x6c990d33, 0xbb8e, 0x477a, 0x85, 0x98, 0xd, 0x5d, 0x96, 0xfc, 0xd8, 0x8a); + public static readonly Guid MF_PD_LAST_MODIFIED_TIME = new Guid(0x6c990d38, 0xbb8e, 0x477a, 0x85, 0x98, 0xd, 0x5d, 0x96, 0xfc, 0xd8, 0x8a); + public static readonly Guid MF_PD_MIME_TYPE = new Guid(0x6c990d37, 0xbb8e, 0x477a, 0x85, 0x98, 0xd, 0x5d, 0x96, 0xfc, 0xd8, 0x8a); + public static readonly Guid MF_PD_PMPHOST_CONTEXT = new Guid(0x6c990d31, 0xbb8e, 0x477a, 0x85, 0x98, 0xd, 0x5d, 0x96, 0xfc, 0xd8, 0x8a); + public static readonly Guid MF_PD_SAMI_STYLELIST = new Guid(0xe0b73c7f, 0x486d, 0x484e, 0x98, 0x72, 0x4d, 0xe5, 0x19, 0x2a, 0x7b, 0xf8); + public static readonly Guid MF_PD_TOTAL_FILE_SIZE = new Guid(0x6c990d34, 0xbb8e, 0x477a, 0x85, 0x98, 0xd, 0x5d, 0x96, 0xfc, 0xd8, 0x8a); + public static readonly Guid MF_PD_AUDIO_ENCODING_BITRATE = new Guid(0x6c990d35, 0xbb8e, 0x477a, 0x85, 0x98, 0xd, 0x5d, 0x96, 0xfc, 0xd8, 0x8a); + public static readonly Guid MF_PD_VIDEO_ENCODING_BITRATE = new Guid(0x6c990d36, 0xbb8e, 0x477a, 0x85, 0x98, 0xd, 0x5d, 0x96, 0xfc, 0xd8, 0x8a); + + // wmcontainer.h Attributes + public static readonly Guid MF_PD_ASF_FILEPROPERTIES_FILE_ID = new Guid(0x3de649b4, 0xd76d, 0x4e66, 0x9e, 0xc9, 0x78, 0x12, 0xf, 0xb4, 0xc7, 0xe3); + public static readonly Guid MF_PD_ASF_FILEPROPERTIES_CREATION_TIME = new Guid(0x3de649b6, 0xd76d, 0x4e66, 0x9e, 0xc9, 0x78, 0x12, 0xf, 0xb4, 0xc7, 0xe3); + public static readonly Guid MF_PD_ASF_FILEPROPERTIES_PACKETS = new Guid(0x3de649b7, 0xd76d, 0x4e66, 0x9e, 0xc9, 0x78, 0x12, 0xf, 0xb4, 0xc7, 0xe3); + public static readonly Guid MF_PD_ASF_FILEPROPERTIES_PLAY_DURATION = new Guid(0x3de649b8, 0xd76d, 0x4e66, 0x9e, 0xc9, 0x78, 0x12, 0xf, 0xb4, 0xc7, 0xe3); + public static readonly Guid MF_PD_ASF_FILEPROPERTIES_SEND_DURATION = new Guid(0x3de649b9, 0xd76d, 0x4e66, 0x9e, 0xc9, 0x78, 0x12, 0xf, 0xb4, 0xc7, 0xe3); + public static readonly Guid MF_PD_ASF_FILEPROPERTIES_PREROLL = new Guid(0x3de649ba, 0xd76d, 0x4e66, 0x9e, 0xc9, 0x78, 0x12, 0xf, 0xb4, 0xc7, 0xe3); + public static readonly Guid MF_PD_ASF_FILEPROPERTIES_FLAGS = new Guid(0x3de649bb, 0xd76d, 0x4e66, 0x9e, 0xc9, 0x78, 0x12, 0xf, 0xb4, 0xc7, 0xe3); + public static readonly Guid MF_PD_ASF_FILEPROPERTIES_MIN_PACKET_SIZE = new Guid(0x3de649bc, 0xd76d, 0x4e66, 0x9e, 0xc9, 0x78, 0x12, 0xf, 0xb4, 0xc7, 0xe3); + public static readonly Guid MF_PD_ASF_FILEPROPERTIES_MAX_PACKET_SIZE = new Guid(0x3de649bd, 0xd76d, 0x4e66, 0x9e, 0xc9, 0x78, 0x12, 0xf, 0xb4, 0xc7, 0xe3); + public static readonly Guid MF_PD_ASF_FILEPROPERTIES_MAX_BITRATE = new Guid(0x3de649be, 0xd76d, 0x4e66, 0x9e, 0xc9, 0x78, 0x12, 0xf, 0xb4, 0xc7, 0xe3); + public static readonly Guid MF_PD_ASF_CONTENTENCRYPTION_TYPE = new Guid(0x8520fe3d, 0x277e, 0x46ea, 0x99, 0xe4, 0xe3, 0xa, 0x86, 0xdb, 0x12, 0xbe); + public static readonly Guid MF_PD_ASF_CONTENTENCRYPTION_KEYID = new Guid(0x8520fe3e, 0x277e, 0x46ea, 0x99, 0xe4, 0xe3, 0xa, 0x86, 0xdb, 0x12, 0xbe); + public static readonly Guid MF_PD_ASF_CONTENTENCRYPTION_SECRET_DATA = new Guid(0x8520fe3f, 0x277e, 0x46ea, 0x99, 0xe4, 0xe3, 0xa, 0x86, 0xdb, 0x12, 0xbe); + public static readonly Guid MF_PD_ASF_CONTENTENCRYPTION_LICENSE_URL = new Guid(0x8520fe40, 0x277e, 0x46ea, 0x99, 0xe4, 0xe3, 0xa, 0x86, 0xdb, 0x12, 0xbe); + public static readonly Guid MF_PD_ASF_CONTENTENCRYPTIONEX_ENCRYPTION_DATA = new Guid(0x62508be5, 0xecdf, 0x4924, 0xa3, 0x59, 0x72, 0xba, 0xb3, 0x39, 0x7b, 0x9d); + public static readonly Guid MF_PD_ASF_LANGLIST = new Guid(0xf23de43c, 0x9977, 0x460d, 0xa6, 0xec, 0x32, 0x93, 0x7f, 0x16, 0xf, 0x7d); + public static readonly Guid MF_PD_ASF_MARKER = new Guid(0x5134330e, 0x83a6, 0x475e, 0xa9, 0xd5, 0x4f, 0xb8, 0x75, 0xfb, 0x2e, 0x31); + public static readonly Guid MF_PD_ASF_SCRIPT = new Guid(0xe29cd0d7, 0xd602, 0x4923, 0xa7, 0xfe, 0x73, 0xfd, 0x97, 0xec, 0xc6, 0x50); + public static readonly Guid MF_PD_ASF_CODECLIST = new Guid(0xe4bb3509, 0xc18d, 0x4df1, 0xbb, 0x99, 0x7a, 0x36, 0xb3, 0xcc, 0x41, 0x19); + public static readonly Guid MF_PD_ASF_METADATA_IS_VBR = new Guid(0x5fc6947a, 0xef60, 0x445d, 0xb4, 0x49, 0x44, 0x2e, 0xcc, 0x78, 0xb4, 0xc1); + public static readonly Guid MF_PD_ASF_METADATA_V8_VBRPEAK = new Guid(0x5fc6947b, 0xef60, 0x445d, 0xb4, 0x49, 0x44, 0x2e, 0xcc, 0x78, 0xb4, 0xc1); + public static readonly Guid MF_PD_ASF_METADATA_V8_BUFFERAVERAGE = new Guid(0x5fc6947c, 0xef60, 0x445d, 0xb4, 0x49, 0x44, 0x2e, 0xcc, 0x78, 0xb4, 0xc1); + public static readonly Guid MF_PD_ASF_METADATA_LEAKY_BUCKET_PAIRS = new Guid(0x5fc6947d, 0xef60, 0x445d, 0xb4, 0x49, 0x44, 0x2e, 0xcc, 0x78, 0xb4, 0xc1); + public static readonly Guid MF_PD_ASF_DATA_START_OFFSET = new Guid(0xe7d5b3e7, 0x1f29, 0x45d3, 0x88, 0x22, 0x3e, 0x78, 0xfa, 0xe2, 0x72, 0xed); + public static readonly Guid MF_PD_ASF_DATA_LENGTH = new Guid(0xe7d5b3e8, 0x1f29, 0x45d3, 0x88, 0x22, 0x3e, 0x78, 0xfa, 0xe2, 0x72, 0xed); + public static readonly Guid MF_SD_ASF_EXTSTRMPROP_LANGUAGE_ID_INDEX = new Guid(0x48f8a522, 0x305d, 0x422d, 0x85, 0x24, 0x25, 0x2, 0xdd, 0xa3, 0x36, 0x80); + public static readonly Guid MF_SD_ASF_EXTSTRMPROP_AVG_DATA_BITRATE = new Guid(0x48f8a523, 0x305d, 0x422d, 0x85, 0x24, 0x25, 0x2, 0xdd, 0xa3, 0x36, 0x80); + public static readonly Guid MF_SD_ASF_EXTSTRMPROP_AVG_BUFFERSIZE = new Guid(0x48f8a524, 0x305d, 0x422d, 0x85, 0x24, 0x25, 0x2, 0xdd, 0xa3, 0x36, 0x80); + public static readonly Guid MF_SD_ASF_EXTSTRMPROP_MAX_DATA_BITRATE = new Guid(0x48f8a525, 0x305d, 0x422d, 0x85, 0x24, 0x25, 0x2, 0xdd, 0xa3, 0x36, 0x80); + public static readonly Guid MF_SD_ASF_EXTSTRMPROP_MAX_BUFFERSIZE = new Guid(0x48f8a526, 0x305d, 0x422d, 0x85, 0x24, 0x25, 0x2, 0xdd, 0xa3, 0x36, 0x80); + public static readonly Guid MF_SD_ASF_STREAMBITRATES_BITRATE = new Guid(0xa8e182ed, 0xafc8, 0x43d0, 0xb0, 0xd1, 0xf6, 0x5b, 0xad, 0x9d, 0xa5, 0x58); + public static readonly Guid MF_SD_ASF_METADATA_DEVICE_CONFORMANCE_TEMPLATE = new Guid(0x245e929d, 0xc44e, 0x4f7e, 0xbb, 0x3c, 0x77, 0xd4, 0xdf, 0xd2, 0x7f, 0x8a); + public static readonly Guid MF_PD_ASF_INFO_HAS_AUDIO = new Guid(0x80e62295, 0x2296, 0x4a44, 0xb3, 0x1c, 0xd1, 0x3, 0xc6, 0xfe, 0xd2, 0x3c); + public static readonly Guid MF_PD_ASF_INFO_HAS_VIDEO = new Guid(0x80e62296, 0x2296, 0x4a44, 0xb3, 0x1c, 0xd1, 0x3, 0xc6, 0xfe, 0xd2, 0x3c); + public static readonly Guid MF_PD_ASF_INFO_HAS_NON_AUDIO_VIDEO = new Guid(0x80e62297, 0x2296, 0x4a44, 0xb3, 0x1c, 0xd1, 0x3, 0xc6, 0xfe, 0xd2, 0x3c); + public static readonly Guid MF_ASFSTREAMCONFIG_LEAKYBUCKET1 = new Guid(0xc69b5901, 0xea1a, 0x4c9b, 0xb6, 0x92, 0xe2, 0xa0, 0xd2, 0x9a, 0x8a, 0xdd); + public static readonly Guid MF_ASFSTREAMCONFIG_LEAKYBUCKET2 = new Guid(0xc69b5902, 0xea1a, 0x4c9b, 0xb6, 0x92, 0xe2, 0xa0, 0xd2, 0x9a, 0x8a, 0xdd); + + // Arbitrary + + // {9E6BD6F5-0109-4f95-84AC-9309153A19FC} MF_MT_ARBITRARY_HEADER {MT_ARBITRARY_HEADER} + public static readonly Guid MF_MT_ARBITRARY_HEADER = new Guid(0x9e6bd6f5, 0x109, 0x4f95, 0x84, 0xac, 0x93, 0x9, 0x15, 0x3a, 0x19, 0xfc); + + // {5A75B249-0D7D-49a1-A1C3-E0D87F0CADE5} MF_MT_ARBITRARY_FORMAT {Blob} + public static readonly Guid MF_MT_ARBITRARY_FORMAT = new Guid(0x5a75b249, 0xd7d, 0x49a1, 0xa1, 0xc3, 0xe0, 0xd8, 0x7f, 0xc, 0xad, 0xe5); + + // Image + + // {ED062CF4-E34E-4922-BE99-934032133D7C} MF_MT_IMAGE_LOSS_TOLERANT {UINT32 (BOOL)} + public static readonly Guid MF_MT_IMAGE_LOSS_TOLERANT = new Guid(0xed062cf4, 0xe34e, 0x4922, 0xbe, 0x99, 0x93, 0x40, 0x32, 0x13, 0x3d, 0x7c); + + // MPEG-4 Media Type Attributes + + // {261E9D83-9529-4B8F-A111-8B9C950A81A9} MF_MT_MPEG4_SAMPLE_DESCRIPTION {BLOB} + public static readonly Guid MF_MT_MPEG4_SAMPLE_DESCRIPTION = new Guid(0x261e9d83, 0x9529, 0x4b8f, 0xa1, 0x11, 0x8b, 0x9c, 0x95, 0x0a, 0x81, 0xa9); + + // {9aa7e155-b64a-4c1d-a500-455d600b6560} MF_MT_MPEG4_CURRENT_SAMPLE_ENTRY {UINT32} + public static readonly Guid MF_MT_MPEG4_CURRENT_SAMPLE_ENTRY = new Guid(0x9aa7e155, 0xb64a, 0x4c1d, 0xa5, 0x00, 0x45, 0x5d, 0x60, 0x0b, 0x65, 0x60); + + // Save original format information for AVI and WAV files + + // {d7be3fe0-2bc7-492d-b843-61a1919b70c3} MF_MT_ORIGINAL_4CC (UINT32) + public static readonly Guid MF_MT_ORIGINAL_4CC = new Guid(0xd7be3fe0, 0x2bc7, 0x492d, 0xb8, 0x43, 0x61, 0xa1, 0x91, 0x9b, 0x70, 0xc3); + + // {8cbbc843-9fd9-49c2-882f-a72586c408ad} MF_MT_ORIGINAL_WAVE_FORMAT_TAG (UINT32) + public static readonly Guid MF_MT_ORIGINAL_WAVE_FORMAT_TAG = new Guid(0x8cbbc843, 0x9fd9, 0x49c2, 0x88, 0x2f, 0xa7, 0x25, 0x86, 0xc4, 0x08, 0xad); + + // Video Capture Media Type Attributes + + // {D2E7558C-DC1F-403f-9A72-D28BB1EB3B5E} MF_MT_FRAME_RATE_RANGE_MIN {UINT64 (HI32(Numerator),LO32(Denominator))} + public static readonly Guid MF_MT_FRAME_RATE_RANGE_MIN = new Guid(0xd2e7558c, 0xdc1f, 0x403f, 0x9a, 0x72, 0xd2, 0x8b, 0xb1, 0xeb, 0x3b, 0x5e); + + // {E3371D41-B4CF-4a05-BD4E-20B88BB2C4D6} MF_MT_FRAME_RATE_RANGE_MAX {UINT64 (HI32(Numerator),LO32(Denominator))} + public static readonly Guid MF_MT_FRAME_RATE_RANGE_MAX = new Guid(0xe3371d41, 0xb4cf, 0x4a05, 0xbd, 0x4e, 0x20, 0xb8, 0x8b, 0xb2, 0xc4, 0xd6); + + public static readonly Guid MF_TOPOLOGY_DXVA_MODE = new Guid(0x1e8d34f6, 0xf5ab, 0x4e23, 0xbb, 0x88, 0x87, 0x4a, 0xa3, 0xa1, 0xa7, 0x4d); + public static readonly Guid MF_TOPOLOGY_STATIC_PLAYBACK_OPTIMIZATIONS = new Guid(0xb86cac42, 0x41a6, 0x4b79, 0x89, 0x7a, 0x1a, 0xb0, 0xe5, 0x2b, 0x4a, 0x1b); + public static readonly Guid MF_TOPOLOGY_PLAYBACK_MAX_DIMS = new Guid(0x5715cf19, 0x5768, 0x44aa, 0xad, 0x6e, 0x87, 0x21, 0xf1, 0xb0, 0xf9, 0xbb); + + public static readonly Guid MF_TOPOLOGY_HARDWARE_MODE = new Guid(0xd2d362fd, 0x4e4f, 0x4191, 0xa5, 0x79, 0xc6, 0x18, 0xb6, 0x67, 0x6, 0xaf); + public static readonly Guid MF_TOPOLOGY_PLAYBACK_FRAMERATE = new Guid(0xc164737a, 0xc2b1, 0x4553, 0x83, 0xbb, 0x5a, 0x52, 0x60, 0x72, 0x44, 0x8f); + public static readonly Guid MF_TOPOLOGY_DYNAMIC_CHANGE_NOT_ALLOWED = new Guid(0xd529950b, 0xd484, 0x4527, 0xa9, 0xcd, 0xb1, 0x90, 0x95, 0x32, 0xb5, 0xb0); + public static readonly Guid MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES = new Guid(0x6248c36d, 0x5d0b, 0x4f40, 0xa0, 0xbb, 0xb0, 0xb3, 0x05, 0xf7, 0x76, 0x98); + public static readonly Guid MF_TOPOLOGY_START_TIME_ON_PRESENTATION_SWITCH = new Guid(0xc8cc113f, 0x7951, 0x4548, 0xaa, 0xd6, 0x9e, 0xd6, 0x20, 0x2e, 0x62, 0xb3); + + public static readonly Guid MF_PD_PLAYBACK_ELEMENT_ID = new Guid(0x6c990d39, 0xbb8e, 0x477a, 0x85, 0x98, 0xd, 0x5d, 0x96, 0xfc, 0xd8, 0x8a); + public static readonly Guid MF_PD_PREFERRED_LANGUAGE = new Guid(0x6c990d3A, 0xbb8e, 0x477a, 0x85, 0x98, 0xd, 0x5d, 0x96, 0xfc, 0xd8, 0x8a); + public static readonly Guid MF_PD_PLAYBACK_BOUNDARY_TIME = new Guid(0x6c990d3b, 0xbb8e, 0x477a, 0x85, 0x98, 0xd, 0x5d, 0x96, 0xfc, 0xd8, 0x8a); + public static readonly Guid MF_PD_AUDIO_ISVARIABLEBITRATE = new Guid(0x33026ee0, 0xe387, 0x4582, 0xae, 0x0a, 0x34, 0xa2, 0xad, 0x3b, 0xaa, 0x18); + + public static readonly Guid MF_SD_STREAM_NAME = new Guid(0x4f1b099d, 0xd314, 0x41e5, 0xa7, 0x81, 0x7f, 0xef, 0xaa, 0x4c, 0x50, 0x1f); + public static readonly Guid MF_SD_MUTUALLY_EXCLUSIVE = new Guid(0x23ef79c, 0x388d, 0x487f, 0xac, 0x17, 0x69, 0x6c, 0xd6, 0xe3, 0xc6, 0xf5); + + public static readonly Guid MF_SAMPLEGRABBERSINK_IGNORE_CLOCK = new Guid(0x0efda2c0, 0x2b69, 0x4e2e, 0xab, 0x8d, 0x46, 0xdc, 0xbf, 0xf7, 0xd2, 0x5d); + public static readonly Guid MF_BYTESTREAMHANDLER_ACCEPTS_SHARE_WRITE = new Guid(0xa6e1f733, 0x3001, 0x4915, 0x81, 0x50, 0x15, 0x58, 0xa2, 0x18, 0xe, 0xc8); + + public static readonly Guid MF_TRANSCODE_CONTAINERTYPE = new Guid(0x150ff23f, 0x4abc, 0x478b, 0xac, 0x4f, 0xe1, 0x91, 0x6f, 0xba, 0x1c, 0xca); + public static readonly Guid MF_TRANSCODE_SKIP_METADATA_TRANSFER = new Guid(0x4e4469ef, 0xb571, 0x4959, 0x8f, 0x83, 0x3d, 0xcf, 0xba, 0x33, 0xa3, 0x93); + public static readonly Guid MF_TRANSCODE_TOPOLOGYMODE = new Guid(0x3e3df610, 0x394a, 0x40b2, 0x9d, 0xea, 0x3b, 0xab, 0x65, 0xb, 0xeb, 0xf2); + public static readonly Guid MF_TRANSCODE_ADJUST_PROFILE = new Guid(0x9c37c21b, 0x60f, 0x487c, 0xa6, 0x90, 0x80, 0xd7, 0xf5, 0xd, 0x1c, 0x72); + + public static readonly Guid MF_TRANSCODE_ENCODINGPROFILE = new Guid(0x6947787c, 0xf508, 0x4ea9, 0xb1, 0xe9, 0xa1, 0xfe, 0x3a, 0x49, 0xfb, 0xc9); + public static readonly Guid MF_TRANSCODE_QUALITYVSSPEED = new Guid(0x98332df8, 0x03cd, 0x476b, 0x89, 0xfa, 0x3f, 0x9e, 0x44, 0x2d, 0xec, 0x9f); + public static readonly Guid MF_TRANSCODE_DONOT_INSERT_ENCODER = new Guid(0xf45aa7ce, 0xab24, 0x4012, 0xa1, 0x1b, 0xdc, 0x82, 0x20, 0x20, 0x14, 0x10); + + public static readonly Guid MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE = new Guid(0xc60ac5fe, 0x252a, 0x478f, 0xa0, 0xef, 0xbc, 0x8f, 0xa5, 0xf7, 0xca, 0xd3); + public static readonly Guid MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_HW_SOURCE = new Guid(0xde7046ba, 0x54d6, 0x4487, 0xa2, 0xa4, 0xec, 0x7c, 0xd, 0x1b, 0xd1, 0x63); + public static readonly Guid MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME = new Guid(0x60d0e559, 0x52f8, 0x4fa2, 0xbb, 0xce, 0xac, 0xdb, 0x34, 0xa8, 0xec, 0x1); + public static readonly Guid MF_DEVSOURCE_ATTRIBUTE_MEDIA_TYPE = new Guid(0x56a819ca, 0xc78, 0x4de4, 0xa0, 0xa7, 0x3d, 0xda, 0xba, 0xf, 0x24, 0xd4); + public static readonly Guid MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_CATEGORY = new Guid(0x77f0ae69, 0xc3bd, 0x4509, 0x94, 0x1d, 0x46, 0x7e, 0x4d, 0x24, 0x89, 0x9e); + public static readonly Guid MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK = new Guid(0x58f0aad8, 0x22bf, 0x4f8a, 0xbb, 0x3d, 0xd2, 0xc4, 0x97, 0x8c, 0x6e, 0x2f); + public static readonly Guid MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_MAX_BUFFERS = new Guid(0x7dd9b730, 0x4f2d, 0x41d5, 0x8f, 0x95, 0xc, 0xc9, 0xa9, 0x12, 0xba, 0x26); + public static readonly Guid MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ENDPOINT_ID = new Guid(0x30da9258, 0xfeb9, 0x47a7, 0xa4, 0x53, 0x76, 0x3a, 0x7a, 0x8e, 0x1c, 0x5f); + public static readonly Guid MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ROLE = new Guid(0xbc9d118e, 0x8c67, 0x4a18, 0x85, 0xd4, 0x12, 0xd3, 0x0, 0x40, 0x5, 0x52); + + public static readonly Guid MFSampleExtension_DeviceTimestamp = new Guid(0x8f3e35e7, 0x2dcd, 0x4887, 0x86, 0x22, 0x2a, 0x58, 0xba, 0xa6, 0x52, 0xb0); + + public static readonly Guid MF_TRANSFORM_ASYNC = new Guid(0xf81a699a, 0x649a, 0x497d, 0x8c, 0x73, 0x29, 0xf8, 0xfe, 0xd6, 0xad, 0x7a); + public static readonly Guid MF_TRANSFORM_ASYNC_UNLOCK = new Guid(0xe5666d6b, 0x3422, 0x4eb6, 0xa4, 0x21, 0xda, 0x7d, 0xb1, 0xf8, 0xe2, 0x7); + public static readonly Guid MF_TRANSFORM_FLAGS_Attribute = new Guid(0x9359bb7e, 0x6275, 0x46c4, 0xa0, 0x25, 0x1c, 0x1, 0xe4, 0x5f, 0x1a, 0x86); + public static readonly Guid MF_TRANSFORM_CATEGORY_Attribute = new Guid(0xceabba49, 0x506d, 0x4757, 0xa6, 0xff, 0x66, 0xc1, 0x84, 0x98, 0x7e, 0x4e); + public static readonly Guid MFT_TRANSFORM_CLSID_Attribute = new Guid(0x6821c42b, 0x65a4, 0x4e82, 0x99, 0xbc, 0x9a, 0x88, 0x20, 0x5e, 0xcd, 0xc); + public static readonly Guid MFT_INPUT_TYPES_Attributes = new Guid(0x4276c9b1, 0x759d, 0x4bf3, 0x9c, 0xd0, 0xd, 0x72, 0x3d, 0x13, 0x8f, 0x96); + public static readonly Guid MFT_OUTPUT_TYPES_Attributes = new Guid(0x8eae8cf3, 0xa44f, 0x4306, 0xba, 0x5c, 0xbf, 0x5d, 0xda, 0x24, 0x28, 0x18); + public static readonly Guid MFT_ENUM_HARDWARE_URL_Attribute = new Guid(0x2fb866ac, 0xb078, 0x4942, 0xab, 0x6c, 0x0, 0x3d, 0x5, 0xcd, 0xa6, 0x74); + public static readonly Guid MFT_FRIENDLY_NAME_Attribute = new Guid(0x314ffbae, 0x5b41, 0x4c95, 0x9c, 0x19, 0x4e, 0x7d, 0x58, 0x6f, 0xac, 0xe3); + public static readonly Guid MFT_CONNECTED_STREAM_ATTRIBUTE = new Guid(0x71eeb820, 0xa59f, 0x4de2, 0xbc, 0xec, 0x38, 0xdb, 0x1d, 0xd6, 0x11, 0xa4); + public static readonly Guid MFT_CONNECTED_TO_HW_STREAM = new Guid(0x34e6e728, 0x6d6, 0x4491, 0xa5, 0x53, 0x47, 0x95, 0x65, 0xd, 0xb9, 0x12); + public static readonly Guid MFT_PREFERRED_OUTPUTTYPE_Attribute = new Guid(0x7e700499, 0x396a, 0x49ee, 0xb1, 0xb4, 0xf6, 0x28, 0x2, 0x1e, 0x8c, 0x9d); + public static readonly Guid MFT_PROCESS_LOCAL_Attribute = new Guid(0x543186e4, 0x4649, 0x4e65, 0xb5, 0x88, 0x4a, 0xa3, 0x52, 0xaf, 0xf3, 0x79); + public static readonly Guid MFT_PREFERRED_ENCODER_PROFILE = new Guid(0x53004909, 0x1ef5, 0x46d7, 0xa1, 0x8e, 0x5a, 0x75, 0xf8, 0xb5, 0x90, 0x5f); + public static readonly Guid MFT_HW_TIMESTAMP_WITH_QPC_Attribute = new Guid(0x8d030fb8, 0xcc43, 0x4258, 0xa2, 0x2e, 0x92, 0x10, 0xbe, 0xf8, 0x9b, 0xe4); + public static readonly Guid MFT_FIELDOFUSE_UNLOCK_Attribute = new Guid(0x8ec2e9fd, 0x9148, 0x410d, 0x83, 0x1e, 0x70, 0x24, 0x39, 0x46, 0x1a, 0x8e); + public static readonly Guid MFT_CODEC_MERIT_Attribute = new Guid(0x88a7cb15, 0x7b07, 0x4a34, 0x91, 0x28, 0xe6, 0x4c, 0x67, 0x3, 0xc4, 0xd3); + public static readonly Guid MFT_ENUM_TRANSCODE_ONLY_ATTRIBUTE = new Guid(0x111ea8cd, 0xb62a, 0x4bdb, 0x89, 0xf6, 0x67, 0xff, 0xcd, 0xc2, 0x45, 0x8b); + + public static readonly Guid MF_MP2DLNA_USE_MMCSS = new Guid(0x54f3e2ee, 0xa2a2, 0x497d, 0x98, 0x34, 0x97, 0x3a, 0xfd, 0xe5, 0x21, 0xeb); + public static readonly Guid MF_MP2DLNA_VIDEO_BIT_RATE = new Guid(0xe88548de, 0x73b4, 0x42d7, 0x9c, 0x75, 0xad, 0xfa, 0xa, 0x2a, 0x6e, 0x4c); + public static readonly Guid MF_MP2DLNA_AUDIO_BIT_RATE = new Guid(0x2d1c070e, 0x2b5f, 0x4ab3, 0xa7, 0xe6, 0x8d, 0x94, 0x3b, 0xa8, 0xd0, 0x0a); + public static readonly Guid MF_MP2DLNA_ENCODE_QUALITY = new Guid(0xb52379d7, 0x1d46, 0x4fb6, 0xa3, 0x17, 0xa4, 0xa5, 0xf6, 0x09, 0x59, 0xf8); + public static readonly Guid MF_MP2DLNA_STATISTICS = new Guid(0x75e488a3, 0xd5ad, 0x4898, 0x85, 0xe0, 0xbc, 0xce, 0x24, 0xa7, 0x22, 0xd7); + + public static readonly Guid MF_SINK_WRITER_ASYNC_CALLBACK = new Guid(0x48cb183e, 0x7b0b, 0x46f4, 0x82, 0x2e, 0x5e, 0x1d, 0x2d, 0xda, 0x43, 0x54); + public static readonly Guid MF_SINK_WRITER_DISABLE_THROTTLING = new Guid(0x08b845d8, 0x2b74, 0x4afe, 0x9d, 0x53, 0xbe, 0x16, 0xd2, 0xd5, 0xae, 0x4f); + public static readonly Guid MF_READWRITE_DISABLE_CONVERTERS = new Guid(0x98d5b065, 0x1374, 0x4847, 0x8d, 0x5d, 0x31, 0x52, 0x0f, 0xee, 0x71, 0x56); + public static readonly Guid MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS = new Guid(0xa634a91c, 0x822b, 0x41b9, 0xa4, 0x94, 0x4d, 0xe4, 0x64, 0x36, 0x12, 0xb0); + + public static readonly Guid MF_SOURCE_READER_ASYNC_CALLBACK = new Guid(0x1e3dbeac, 0xbb43, 0x4c35, 0xb5, 0x07, 0xcd, 0x64, 0x44, 0x64, 0xc9, 0x65); + public static readonly Guid MF_SOURCE_READER_D3D_MANAGER = new Guid(0xec822da2, 0xe1e9, 0x4b29, 0xa0, 0xd8, 0x56, 0x3c, 0x71, 0x9f, 0x52, 0x69); + public static readonly Guid MF_SOURCE_READER_DISABLE_DXVA = new Guid(0xaa456cfd, 0x3943, 0x4a1e, 0xa7, 0x7d, 0x18, 0x38, 0xc0, 0xea, 0x2e, 0x35); + public static readonly Guid MF_SOURCE_READER_MEDIASOURCE_CONFIG = new Guid(0x9085abeb, 0x0354, 0x48f9, 0xab, 0xb5, 0x20, 0x0d, 0xf8, 0x38, 0xc6, 0x8e); + public static readonly Guid MF_SOURCE_READER_MEDIASOURCE_CHARACTERISTICS = new Guid(0x6d23f5c8, 0xc5d7, 0x4a9b, 0x99, 0x71, 0x5d, 0x11, 0xf8, 0xbc, 0xa8, 0x80); + public static readonly Guid MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING = new Guid(0xfb394f3d, 0xccf1, 0x42ee, 0xbb, 0xb3, 0xf9, 0xb8, 0x45, 0xd5, 0x68, 0x1d); + public static readonly Guid MF_SOURCE_READER_DISCONNECT_MEDIASOURCE_ON_SHUTDOWN = new Guid(0x56b67165, 0x219e, 0x456d, 0xa2, 0x2e, 0x2d, 0x30, 0x04, 0xc7, 0xfe, 0x56); + } + + public static class MFTranscodeContainerType + { + public static readonly Guid ASF = new Guid(0x430f6f6e, 0xb6bf, 0x4fc1, 0xa0, 0xbd, 0x9e, 0xe4, 0x6e, 0xee, 0x2a, 0xfb); + public static readonly Guid MPEG4 = new Guid(0xdc6cd05d, 0xb9d0, 0x40ef, 0xbd, 0x35, 0xfa, 0x62, 0x2c, 0x1a, 0xb2, 0x8a); + public static readonly Guid MP3 = new Guid(0xe438b912, 0x83f1, 0x4de6, 0x9e, 0x3a, 0x9f, 0xfb, 0xc6, 0xdd, 0x24, 0xd1); + public static readonly Guid x3GP = new Guid(0x34c50167, 0x4472, 0x4f34, 0x9e, 0xa0, 0xc4, 0x9f, 0xba, 0xcf, 0x03, 0x7d); + } + + public static class MFConnector + { + public static readonly Guid MFCONNECTOR_AGP = new Guid(0xac3aef60, 0xce43, 0x11d9, 0x92, 0xdb, 0x00, 0x0b, 0xdb, 0x28, 0xff, 0x98); + public static readonly Guid MFCONNECTOR_COMPONENT = new Guid(0x57cd596b, 0xce47, 0x11d9, 0x92, 0xdb, 0x00, 0x0b, 0xdb, 0x28, 0xff, 0x98); + public static readonly Guid MFCONNECTOR_COMPOSITE = new Guid(0x57cd596a, 0xce47, 0x11d9, 0x92, 0xdb, 0x00, 0x0b, 0xdb, 0x28, 0xff, 0x98); + public static readonly Guid MFCONNECTOR_D_JPN = new Guid(0x57cd5970, 0xce47, 0x11d9, 0x92, 0xdb, 0x00, 0x0b, 0xdb, 0x28, 0xff, 0x98); + public static readonly Guid MFCONNECTOR_DISPLAYPORT_EMBEDDED = new Guid(0x57cd5973, 0xce47, 0x11d9, 0x92, 0xdb, 0x00, 0x0b, 0xdb, 0x28, 0xff, 0x98); + public static readonly Guid MFCONNECTOR_DISPLAYPORT_EXTERNAL = new Guid(0x57cd5972, 0xce47, 0x11d9, 0x92, 0xdb, 0x00, 0x0b, 0xdb, 0x28, 0xff, 0x98); + public static readonly Guid MFCONNECTOR_DVI = new Guid(0x57cd596c, 0xce47, 0x11d9, 0x92, 0xdb, 0x00, 0x0b, 0xdb, 0x28, 0xff, 0x98); + public static readonly Guid MFCONNECTOR_HDMI = new Guid(0x57cd596d, 0xce47, 0x11d9, 0x92, 0xdb, 0x00, 0x0b, 0xdb, 0x28, 0xff, 0x98); + public static readonly Guid MFCONNECTOR_LVDS = new Guid(0x57cd596e, 0xce47, 0x11d9, 0x92, 0xdb, 0x00, 0x0b, 0xdb, 0x28, 0xff, 0x98); + public static readonly Guid MFCONNECTOR_PCI = new Guid(0xac3aef5d, 0xce43, 0x11d9, 0x92, 0xdb, 0x00, 0x0b, 0xdb, 0x28, 0xff, 0x98); + public static readonly Guid MFCONNECTOR_PCI_Express = new Guid(0xac3aef5f, 0xce43, 0x11d9, 0x92, 0xdb, 0x00, 0x0b, 0xdb, 0x28, 0xff, 0x98); + public static readonly Guid MFCONNECTOR_PCIX = new Guid(0xac3aef5e, 0xce43, 0x11d9, 0x92, 0xdb, 0x00, 0x0b, 0xdb, 0x28, 0xff, 0x98); + public static readonly Guid MFCONNECTOR_SPDIF = new Guid(0xb94a712, 0xad3e, 0x4cee, 0x83, 0xce, 0xce, 0x32, 0xe3, 0xdb, 0x65, 0x22); + public static readonly Guid MFCONNECTOR_SVIDEO = new Guid(0x57cd5969, 0xce47, 0x11d9, 0x92, 0xdb, 0x00, 0x0b, 0xdb, 0x28, 0xff, 0x98); + public static readonly Guid MFCONNECTOR_UDI_EMBEDDED = new Guid(0x57cd5975, 0xce47, 0x11d9, 0x92, 0xdb, 0x00, 0x0b, 0xdb, 0x28, 0xff, 0x98); + public static readonly Guid MFCONNECTOR_UDI_EXTERNAL = new Guid(0x57cd5974, 0xce47, 0x11d9, 0x92, 0xdb, 0x00, 0x0b, 0xdb, 0x28, 0xff, 0x98); + public static readonly Guid MFCONNECTOR_UNKNOWN = new Guid(0xac3aef5c, 0xce43, 0x11d9, 0x92, 0xdb, 0x00, 0x0b, 0xdb, 0x28, 0xff, 0x98); + public static readonly Guid MFCONNECTOR_VGA = new Guid(0x57cd5968, 0xce47, 0x11d9, 0x92, 0xdb, 0x00, 0x0b, 0xdb, 0x28, 0xff, 0x98); + } + + public static class MFTransformCategory + { + // {d6c02d4b-6833-45b4-971a-05a4b04bab91} MFT_CATEGORY_VIDEO_DECODER + public static readonly Guid MFT_CATEGORY_VIDEO_DECODER = new Guid(0xd6c02d4b, 0x6833, 0x45b4, 0x97, 0x1a, 0x05, 0xa4, 0xb0, 0x4b, 0xab, 0x91); + + // {f79eac7d-e545-4387-bdee-d647d7bde42a} MFT_CATEGORY_VIDEO_ENCODER + public static readonly Guid MFT_CATEGORY_VIDEO_ENCODER = new Guid(0xf79eac7d, 0xe545, 0x4387, 0xbd, 0xee, 0xd6, 0x47, 0xd7, 0xbd, 0xe4, 0x2a); + + // {12e17c21-532c-4a6e-8a1c-40825a736397} MFT_CATEGORY_VIDEO_EFFECT + public static readonly Guid MFT_CATEGORY_VIDEO_EFFECT = new Guid(0x12e17c21, 0x532c, 0x4a6e, 0x8a, 0x1c, 0x40, 0x82, 0x5a, 0x73, 0x63, 0x97); + + // {059c561e-05ae-4b61-b69d-55b61ee54a7b} MFT_CATEGORY_MULTIPLEXER + public static readonly Guid MFT_CATEGORY_MULTIPLEXER = new Guid(0x059c561e, 0x05ae, 0x4b61, 0xb6, 0x9d, 0x55, 0xb6, 0x1e, 0xe5, 0x4a, 0x7b); + + // {a8700a7a-939b-44c5-99d7-76226b23b3f1} MFT_CATEGORY_DEMULTIPLEXER + public static readonly Guid MFT_CATEGORY_DEMULTIPLEXER = new Guid(0xa8700a7a, 0x939b, 0x44c5, 0x99, 0xd7, 0x76, 0x22, 0x6b, 0x23, 0xb3, 0xf1); + + // {9ea73fb4-ef7a-4559-8d5d-719d8f0426c7} MFT_CATEGORY_AUDIO_DECODER + public static readonly Guid MFT_CATEGORY_AUDIO_DECODER = new Guid(0x9ea73fb4, 0xef7a, 0x4559, 0x8d, 0x5d, 0x71, 0x9d, 0x8f, 0x04, 0x26, 0xc7); + + // {91c64bd0-f91e-4d8c-9276-db248279d975} MFT_CATEGORY_AUDIO_ENCODER + public static readonly Guid MFT_CATEGORY_AUDIO_ENCODER = new Guid(0x91c64bd0, 0xf91e, 0x4d8c, 0x92, 0x76, 0xdb, 0x24, 0x82, 0x79, 0xd9, 0x75); + + // {11064c48-3648-4ed0-932e-05ce8ac811b7} MFT_CATEGORY_AUDIO_EFFECT + public static readonly Guid MFT_CATEGORY_AUDIO_EFFECT = new Guid(0x11064c48, 0x3648, 0x4ed0, 0x93, 0x2e, 0x05, 0xce, 0x8a, 0xc8, 0x11, 0xb7); + + // {302EA3FC-AA5F-47f9-9F7A-C2188BB163021} MFT_CATEGORY_VIDEO_PROCESSOR + public static readonly Guid MFT_CATEGORY_VIDEO_PROCESSOR = new Guid(0x302ea3fc, 0xaa5f, 0x47f9, 0x9f, 0x7a, 0xc2, 0x18, 0x8b, 0xb1, 0x63, 0x2); + + // {90175d57-b7ea-4901-aeb3-933a8747756f} MFT_CATEGORY_OTHER + public static readonly Guid MFT_CATEGORY_OTHER = new Guid(0x90175d57, 0xb7ea, 0x4901, 0xae, 0xb3, 0x93, 0x3a, 0x87, 0x47, 0x75, 0x6f); + + } + + public static class MFEnabletype + { + public static readonly Guid MFENABLETYPE_MF_RebootRequired = new Guid(0x6d4d3d4b, 0x0ece, 0x4652, 0x8b, 0x3a, 0xf2, 0xd2, 0x42, 0x60, 0xd8, 0x87); + public static readonly Guid MFENABLETYPE_MF_UpdateRevocationInformation = new Guid(0xe558b0b5, 0xb3c4, 0x44a0, 0x92, 0x4c, 0x50, 0xd1, 0x78, 0x93, 0x23, 0x85); + public static readonly Guid MFENABLETYPE_MF_UpdateUntrustedComponent = new Guid(0x9879f3d6, 0xcee2, 0x48e6, 0xb5, 0x73, 0x97, 0x67, 0xab, 0x17, 0x2f, 0x16); + public static readonly Guid MFENABLETYPE_WMDRMV1_LicenseAcquisition = new Guid(0x4ff6eeaf, 0xb43, 0x4797, 0x9b, 0x85, 0xab, 0xf3, 0x18, 0x15, 0xe7, 0xb0); + public static readonly Guid MFENABLETYPE_WMDRMV7_Individualization = new Guid(0xacd2c84a, 0xb303, 0x4f65, 0xbc, 0x2c, 0x2c, 0x84, 0x8d, 0x1, 0xa9, 0x89); + public static readonly Guid MFENABLETYPE_WMDRMV7_LicenseAcquisition = new Guid(0x3306df, 0x4a06, 0x4884, 0xa0, 0x97, 0xef, 0x6d, 0x22, 0xec, 0x84, 0xa3); + } + + public static class MFRepresentation + { + /// AM_MEDIA_TYPE_REPRESENTATION + public static readonly Guid AMMediaType = new Guid(0xe2e42ad2, 0x132c, 0x491e, 0xa2, 0x68, 0x3c, 0x7c, 0x2d, 0xca, 0x18, 0x1f); + /// FORMAT_MFVideoFormat + public static readonly Guid MFVideoFormat = new Guid(0xaed4ab2d, 0x7326, 0x43cb, 0x94, 0x64, 0xc8, 0x79, 0xca, 0xb9, 0xc4, 0x3d); + /// FORMAT_VideoInfo + public static readonly Guid VideoInfo = new Guid(0x05589f80, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a); + /// FORMAT_VideoInfo2 + public static readonly Guid VideoInfo2 = new Guid(0xf72a76A0, 0xeb0a, 0x11d0, 0xac, 0xe4, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba); + + } + + public static class MFProperties + { + // Media Foundation Properties + public static readonly Guid MFNETSOURCE_ACCELERATEDSTREAMINGDURATION = new Guid(0x3cb1f277, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_AUTORECONNECTLIMIT = new Guid(0x3cb1f27a, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_AUTORECONNECTPROGRESS = new Guid(0x3cb1f282, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_BROWSERUSERAGENT = new Guid(0x3cb1f28b, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_BROWSERWEBPAGE = new Guid(0x3cb1f28c, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_BUFFERINGTIME = new Guid(0x3cb1f276, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_CACHEENABLED = new Guid(0x3cb1f279, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_CONNECTIONBANDWIDTH = new Guid(0x3cb1f278, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_CREDENTIAL_MANAGER = new Guid(0x3cb1f280, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_DRMNET_LICENSE_REPRESENTATION = new Guid(0x47eae1bd, 0xbdfe, 0x42e2, 0x82, 0xf3, 0x54, 0xa4, 0x8c, 0x17, 0x96, 0x2d); + public static readonly Guid MFNETSOURCE_ENABLE_DOWNLOAD = new Guid(0x3cb1f29d, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_ENABLE_HTTP = new Guid(0x3cb1f299, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_ENABLE_RTSP = new Guid(0x3cb1f298, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_ENABLE_STREAMING = new Guid(0x3cb1f29c, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_ENABLE_TCP = new Guid(0x3cb1f295, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_ENABLE_UDP = new Guid(0x3cb1f294, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_HOSTEXE = new Guid(0x3cb1f28f, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_HOSTVERSION = new Guid(0x3cb1f291, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_LOGURL = new Guid(0x3cb1f293, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_MAXBUFFERTIMEMS = new Guid(0x408b24e6, 0x4038, 0x4401, 0xb5, 0xb2, 0xfe, 0x70, 0x1a, 0x9e, 0xbf, 0x10); + public static readonly Guid MFNETSOURCE_MAXUDPACCELERATEDSTREAMINGDURATION = new Guid(0x4aab2879, 0xbbe1, 0x4994, 0x9f, 0xf0, 0x54, 0x95, 0xbd, 0x25, 0x1, 0x29); + public static readonly Guid MFNETSOURCE_PLAYERID = new Guid(0x3cb1f28e, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_PLAYERUSERAGENT = new Guid(0x3cb1f292, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_PLAYERVERSION = new Guid(0x3cb1f28d, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_PPBANDWIDTH = new Guid(0x3cb1f281, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_PROTOCOL = new Guid(0x3cb1f27d, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_PROXYBYPASSFORLOCAL = new Guid(0x3cb1f286, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_PROXYEXCEPTIONLIST = new Guid(0x3cb1f285, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_PROXYHOSTNAME = new Guid(0x3cb1f284, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_PROXYINFO = new Guid(0x3cb1f29b, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_PROXYLOCATORFACTORY = new Guid(0x3cb1f283, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_PROXYPORT = new Guid(0x3cb1f288, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_PROXYRERUNAUTODETECTION = new Guid(0x3cb1f289, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_PROXYSETTINGS = new Guid(0x3cb1f287, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_RESENDSENABLED = new Guid(0x3cb1f27b, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_STATISTICS = new Guid(0x3cb1f274, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_THINNINGENABLED = new Guid(0x3cb1f27c, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_TRANSPORT = new Guid(0x3cb1f27e, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_UDP_PORT_RANGE = new Guid(0x3cb1f29a, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + + public static readonly Guid MFNETSOURCE_SSLCERTIFICATE_MANAGER = new Guid(0x55e6cb27, 0xe69b, 0x4267, 0x94, 0x0c, 0x2d, 0x7e, 0xc5, 0xbb, 0x8a, 0x0f); + + public static readonly Guid MFNETSOURCE_PREVIEWMODEENABLED = new Guid(0x3cb1f27f, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_CLIENTGUID = new Guid(0x60a2c4a6, 0xf197, 0x4c14, 0xa5, 0xbf, 0x88, 0x83, 0xd, 0x24, 0x58, 0xaf); + public static readonly Guid MFNETSOURCE_ENABLE_MSB = new Guid(0x3cb1f296, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MFNETSOURCE_STREAM_LANGUAGE = new Guid(0x9ab44318, 0xf7cd, 0x4f2d, 0x8d, 0x6d, 0xfa, 0x35, 0xb4, 0x92, 0xce, 0xcb); + public static readonly Guid MFNETSOURCE_LOGPARAMS = new Guid(0x64936ae8, 0x9418, 0x453a, 0x8c, 0xda, 0x3e, 0xa, 0x66, 0x8b, 0x35, 0x3b); + } + + public static class MFServices + { + public static readonly Guid MF_TIMECODE_SERVICE = new Guid(0xa0d502a7, 0x0eb3, 0x4885, 0xb1, 0xb9, 0x9f, 0xeb, 0x0d, 0x08, 0x34, 0x54); + public static readonly Guid MF_PROPERTY_HANDLER_SERVICE = new Guid(0xa3face02, 0x32b8, 0x41dd, 0x90, 0xe7, 0x5f, 0xef, 0x7c, 0x89, 0x91, 0xb5); + public static readonly Guid MF_METADATA_PROVIDER_SERVICE = new Guid(0xdb214084, 0x58a4, 0x4d2e, 0xb8, 0x4f, 0x6f, 0x75, 0x5b, 0x2f, 0x7a, 0xd); + public static readonly Guid MF_PMP_SERVER_CONTEXT = new Guid(0x2f00c910, 0xd2cf, 0x4278, 0x8b, 0x6a, 0xd0, 0x77, 0xfa, 0xc3, 0xa2, 0x5f); + public static readonly Guid MF_QUALITY_SERVICES = new Guid(0xb7e2be11, 0x2f96, 0x4640, 0xb5, 0x2c, 0x28, 0x23, 0x65, 0xbd, 0xf1, 0x6c); + public static readonly Guid MF_RATE_CONTROL_SERVICE = new Guid(0x866fa297, 0xb802, 0x4bf8, 0x9d, 0xc9, 0x5e, 0x3b, 0x6a, 0x9f, 0x53, 0xc9); + public static readonly Guid MF_REMOTE_PROXY = new Guid(0x2f00c90e, 0xd2cf, 0x4278, 0x8b, 0x6a, 0xd0, 0x77, 0xfa, 0xc3, 0xa2, 0x5f); + public static readonly Guid MF_SAMI_SERVICE = new Guid(0x49a89ae7, 0xb4d9, 0x4ef2, 0xaa, 0x5c, 0xf6, 0x5a, 0x3e, 0x5, 0xae, 0x4e); + public static readonly Guid MF_SOURCE_PRESENTATION_PROVIDER_SERVICE = new Guid(0xe002aadc, 0xf4af, 0x4ee5, 0x98, 0x47, 0x05, 0x3e, 0xdf, 0x84, 0x04, 0x26); + public static readonly Guid MF_TOPONODE_ATTRIBUTE_EDITOR_SERVICE = new Guid(0x65656e1a, 0x077f, 0x4472, 0x83, 0xef, 0x31, 0x6f, 0x11, 0xd5, 0x08, 0x7a); + public static readonly Guid MF_WORKQUEUE_SERVICES = new Guid(0x8e37d489, 0x41e0, 0x413a, 0x90, 0x68, 0x28, 0x7c, 0x88, 0x6d, 0x8d, 0xda); + public static readonly Guid MFNET_SAVEJOB_SERVICE = new Guid(0xb85a587f, 0x3d02, 0x4e52, 0x95, 0x65, 0x55, 0xd3, 0xec, 0x1e, 0x7f, 0xf7); + public static readonly Guid MFNETSOURCE_STATISTICS_SERVICE = new Guid(0x3cb1f275, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1); + public static readonly Guid MR_AUDIO_POLICY_SERVICE = new Guid(0x911fd737, 0x6775, 0x4ab0, 0xa6, 0x14, 0x29, 0x78, 0x62, 0xfd, 0xac, 0x88); + public static readonly Guid MR_POLICY_VOLUME_SERVICE = new Guid(0x1abaa2ac, 0x9d3b, 0x47c6, 0xab, 0x48, 0xc5, 0x95, 0x6, 0xde, 0x78, 0x4d); + public static readonly Guid MR_STREAM_VOLUME_SERVICE = new Guid(0xf8b5fa2f, 0x32ef, 0x46f5, 0xb1, 0x72, 0x13, 0x21, 0x21, 0x2f, 0xb2, 0xc4); + public static readonly Guid MR_VIDEO_RENDER_SERVICE = new Guid(0x1092a86c, 0xab1a, 0x459a, 0xa3, 0x36, 0x83, 0x1f, 0xbc, 0x4d, 0x11, 0xff); + public static readonly Guid MR_VIDEO_MIXER_SERVICE = new Guid(0x73cd2fc, 0x6cf4, 0x40b7, 0x88, 0x59, 0xe8, 0x95, 0x52, 0xc8, 0x41, 0xf8); + public static readonly Guid MR_VIDEO_ACCELERATION_SERVICE = new Guid(0xefef5175, 0x5c7d, 0x4ce2, 0xbb, 0xbd, 0x34, 0xff, 0x8b, 0xca, 0x65, 0x54); + public static readonly Guid MR_BUFFER_SERVICE = new Guid(0xa562248c, 0x9ac6, 0x4ffc, 0x9f, 0xba, 0x3a, 0xf8, 0xf8, 0xad, 0x1a, 0x4d); + public static readonly Guid MF_PMP_SERVICE = new Guid(0x2F00C90C, 0xD2CF, 0x4278, 0x8B, 0x6A, 0xD0, 0x77, 0xFA, 0xC3, 0xA2, 0x5F); + public static readonly Guid MF_LOCAL_MFT_REGISTRATION_SERVICE = new Guid(0xddf5cf9c, 0x4506, 0x45aa, 0xab, 0xf0, 0x6d, 0x5d, 0x94, 0xdd, 0x1b, 0x4a); + } + + public static class MFPKEY + { + public static readonly PropertyKey CATEGORY = new PropertyKey(new Guid(0xc57a84c0, 0x1a80, 0x40a3, 0x97, 0xb5, 0x92, 0x72, 0xa4, 0x3, 0xc8, 0xae), 0x02); + public static readonly PropertyKey CLSID = new PropertyKey(new Guid(0xc57a84c0, 0x1a80, 0x40a3, 0x97, 0xb5, 0x92, 0x72, 0xa4, 0x3, 0xc8, 0xae), 0x01); + public static readonly PropertyKey EXATTRIBUTE_SUPPORTED = new PropertyKey(new Guid(0x456fe843, 0x3c87, 0x40c0, 0x94, 0x9d, 0x14, 0x9, 0xc9, 0x7d, 0xab, 0x2c), 0x01); + public static readonly PropertyKey SourceOpenMonitor = new PropertyKey(new Guid(0x074d4637, 0xb5ae, 0x465d, 0xaf, 0x17, 0x1a, 0x53, 0x8d, 0x28, 0x59, 0xdd), 0x02); + public static readonly PropertyKey ASFMediaSource_ApproxSeek = new PropertyKey(new Guid(0xb4cd270f, 0x244d, 0x4969, 0xbb, 0x92, 0x3f, 0x0f, 0xb8, 0x31, 0x6f, 0x10), 0x01); + public static readonly PropertyKey MULTICHANNEL_CHANNEL_MASK = new PropertyKey(new Guid(0x58bdaf8c, 0x3224, 0x4692, 0x86, 0xd0, 0x44, 0xd6, 0x5c, 0x5b, 0xf8, 0x2b), 0x01); + public static readonly PropertyKey ASFMediaSource_IterativeSeekIfNoIndex = new PropertyKey(new Guid(0x170b65dc, 0x4a4e, 0x407a, 0xac, 0x22, 0x57, 0x7f, 0x50, 0xe4, 0xa3, 0x7c), 0x01); + public static readonly PropertyKey ASFMediaSource_IterativeSeek_Max_Count = new PropertyKey(new Guid(0x170b65dc, 0x4a4e, 0x407a, 0xac, 0x22, 0x57, 0x7f, 0x50, 0xe4, 0xa3, 0x7c), 0x02); + public static readonly PropertyKey ASFMediaSource_IterativeSeek_Tolerance_In_MilliSecond = new PropertyKey(new Guid(0x170b65dc, 0x4a4e, 0x407a, 0xac, 0x22, 0x57, 0x7f, 0x50, 0xe4, 0xa3, 0x7c), 0x03); + public static readonly PropertyKey Content_DLNA_Profile_ID = new PropertyKey(new Guid(0xcfa31b45, 0x525d, 0x4998, 0xbb, 0x44, 0x3f, 0x7d, 0x81, 0x54, 0x2f, 0xa4), 0x01); + public static readonly PropertyKey MediaSource_DisableReadAhead = new PropertyKey(new Guid(0x26366c14, 0xc5bf, 0x4c76, 0x88, 0x7b, 0x9f, 0x17, 0x54, 0xdb, 0x5f, 0x9), 0x01); + + public static readonly PropertyKey MFP_PKEY_StreamIndex = new PropertyKey(new Guid(0xa7cf9740, 0xe8d9, 0x4a87, 0xbd, 0x8e, 0x29, 0x67, 0x0, 0x1f, 0xd3, 0xad), 0x00); + public static readonly PropertyKey MFP_PKEY_StreamRenderingResults = new PropertyKey(new Guid(0xa7cf9740, 0xe8d9, 0x4a87, 0xbd, 0x8e, 0x29, 0x67, 0x0, 0x1f, 0xd3, 0xad), 0x01); + } + + public static class CLSID + { + // Unknown + public static readonly Guid MFASFINDEXER_TYPE_TIMECODE = new Guid(0x49815231, 0x6bad, 0x44fd, 0x81, 0xa, 0x3f, 0x60, 0x98, 0x4e, 0xc7, 0xfd ); + + public static readonly Guid MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID = new Guid(0x14dd9a1c, 0x7cff, 0x41be, 0xb1, 0xb9, 0xba, 0x1a, 0xc6, 0xec, 0xb5, 0x71); + public static readonly Guid MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID= new Guid( 0x8ac3587a, 0x4ae7, 0x42d8, 0x99, 0xe0, 0x0a, 0x60, 0x13, 0xee, 0xf9, 0x0f); + + public static readonly Guid MFCONNECTOR_SDI = new Guid(0x57cd5971, 0xce47, 0x11d9, 0x92, 0xdb, 0x00, 0x0b, 0xdb, 0x28, 0xff, 0x98); + public static readonly Guid MFPROTECTION_ACP = new Guid(0xc3fd11c6, 0xf8b7, 0x4d20, 0xb0, 0x08, 0x1d, 0xb1, 0x7d, 0x61, 0xf2, 0xda); + public static readonly Guid MFPROTECTION_CGMSA = new Guid(0xE57E69E9, 0x226B, 0x4d31, 0xB4, 0xE3, 0xD3, 0xDB, 0x00, 0x87, 0x36, 0xDD); + public static readonly Guid MFPROTECTION_CONSTRICTAUDIO = new Guid(0xffc99b44, 0xdf48, 0x4e16, 0x8e, 0x66, 0x09, 0x68, 0x92, 0xc1, 0x57, 0x8a); + public static readonly Guid MFPROTECTION_CONSTRICTVIDEO = new Guid(0x193370ce, 0xc5e4, 0x4c3a, 0x8a, 0x66, 0x69, 0x59, 0xb4, 0xda, 0x44, 0x42); + public static readonly Guid MFPROTECTION_DISABLE = new Guid(0x8cc6d81b, 0xfec6, 0x4d8f, 0x96, 0x4b, 0xcf, 0xba, 0x0b, 0x0d, 0xad, 0x0d); + public static readonly Guid MFPROTECTION_FFT = new Guid(0x462a56b2, 0x2866, 0x4bb6, 0x98, 0x0d, 0x6d, 0x8d, 0x9e, 0xdb, 0x1a, 0x8c); + public static readonly Guid MFPROTECTION_HDCP = new Guid(0xAE7CC03D, 0xC828, 0x4021, 0xac, 0xb7, 0xd5, 0x78, 0xd2, 0x7a, 0xaf, 0x13); + public static readonly Guid MFPROTECTION_TRUSTEDAUDIODRIVERS = new Guid(0x65bdf3d2, 0x0168, 0x4816, 0xa5, 0x33, 0x55, 0xd4, 0x7b, 0x02, 0x71, 0x01); + public static readonly Guid MFPROTECTION_WMDRMOTA = new Guid(0xa267a6a1, 0x362e, 0x47d0, 0x88, 0x05, 0x46, 0x28, 0x59, 0x8a, 0x23, 0xe4); + public static readonly Guid MFPROTECTIONATTRIBUTE_CONSTRICTVIDEO_IMAGESIZE = new Guid(0x8476fc, 0x4b58, 0x4d80, 0xa7, 0x90, 0xe7, 0x29, 0x76, 0x73, 0x16, 0x1d); + public static readonly Guid MFPROTECTIONATTRIBUTE_HDCP_SRM = new Guid(0x6f302107, 0x3477, 0x4468, 0x8a, 0x8, 0xee, 0xf9, 0xdb, 0x10, 0xe2, 0xf); + public static readonly Guid MFSampleExtension_DescrambleData = new Guid(0x43483be6, 0x4903, 0x4314, 0xb0, 0x32, 0x29, 0x51, 0x36, 0x59, 0x36, 0xfc); + public static readonly Guid MFSampleExtension_SampleKeyID = new Guid(0x9ed713c8, 0x9b87, 0x4b26, 0x82, 0x97, 0xa9, 0x3b, 0x0c, 0x5a, 0x8a, 0xcc); + public static readonly Guid MFSampleExtension_GenKeyFunc = new Guid(0x441ca1ee, 0x6b1f, 0x4501, 0x90, 0x3a, 0xde, 0x87, 0xdf, 0x42, 0xf6, 0xed); + public static readonly Guid MFSampleExtension_GenKeyCtx = new Guid(0x188120cb, 0xd7da, 0x4b59, 0x9b, 0x3e, 0x92, 0x52, 0xfd, 0x37, 0x30, 0x1c); + public static readonly Guid MFSampleExtension_PacketCrossOffsets = new Guid(0x2789671d, 0x389f, 0x40bb, 0x90, 0xd9, 0xc2, 0x82, 0xf7, 0x7f, 0x9a, 0xbd); + public static readonly Guid MF_SampleProtectionSalt = new Guid(0x5403deee, 0xb9ee, 0x438f, 0xaa, 0x83, 0x38, 0x4, 0x99, 0x7e, 0x56, 0x9d); + public static readonly Guid CLSID_MFSourceResolver = new Guid(0x90eab60f, 0xe43a, 0x4188, 0xbc, 0xc4, 0xe4, 0x7f, 0xdf, 0x04, 0x86, 0x8c); + + // Generic + + public static readonly Guid CLSID_MFSinkWriter = new Guid(0xa3bbfb17, 0x8273, 0x4e52, 0x9e, 0x0e, 0x97, 0x39, 0xdc, 0x88, 0x79, 0x90); + public static readonly Guid CLSID_MFSourceReader = new Guid(0x1777133c, 0x0881, 0x411b, 0xa5, 0x77, 0xad, 0x54, 0x5f, 0x07, 0x14, 0xc4); + + public static readonly Guid MF_QUALITY_NOTIFY_PROCESSING_LATENCY = new Guid(0xf6b44af8, 0x604d, 0x46fe, 0xa9, 0x5d, 0x45, 0x47, 0x9b, 0x10, 0xc9, 0xbc); + public static readonly Guid MF_QUALITY_NOTIFY_SAMPLE_LAG = new Guid(0x30d15206, 0xed2a, 0x4760, 0xbe, 0x17, 0xeb, 0x4a, 0x9f, 0x12, 0x29, 0x5c); + public static readonly Guid MF_TIME_FORMAT_SEGMENT_OFFSET = new Guid(0xc8b8be77, 0x869c, 0x431d, 0x81, 0x2e, 0x16, 0x96, 0x93, 0xf6, 0x5a, 0x39); + public static readonly Guid MF_TIME_FORMAT_ENTRY_RELATIVE = new Guid(0x4399f178, 0x46d3, 0x4504, 0xaf, 0xda, 0x20, 0xd3, 0x2e, 0x9b, 0xa3, 0x60); + public static readonly Guid MFP_POSITIONTYPE_100NS = Guid.Empty; + } + + public static class MFMediaType + { + /// From MFMediaType_Default + public static readonly Guid Default = new Guid(0x81A412E6, 0x8103, 0x4B06, 0x85, 0x7F, 0x18, 0x62, 0x78, 0x10, 0x24, 0xAC); + /// From MFMediaType_Audio + public static readonly Guid Audio = new Guid(0x73647561, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71); + /// From MFMediaType_Video + public static readonly Guid Video = new Guid(0x73646976, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71); + /// From MFMediaType_Protected + public static readonly Guid Protected = new Guid(0x7b4b6fe6, 0x9d04, 0x4494, 0xbe, 0x14, 0x7e, 0x0b, 0xd0, 0x76, 0xc8, 0xe4); + /// From MFMediaType_SAMI + public static readonly Guid SAMI = new Guid(0xe69669a0, 0x3dcd, 0x40cb, 0x9e, 0x2e, 0x37, 0x08, 0x38, 0x7c, 0x06, 0x16); + /// From MFMediaType_Script + public static readonly Guid Script = new Guid(0x72178C22, 0xE45B, 0x11D5, 0xBC, 0x2A, 0x00, 0xB0, 0xD0, 0xF3, 0xF4, 0xAB); + /// From MFMediaType_Image + public static readonly Guid Image = new Guid(0x72178C23, 0xE45B, 0x11D5, 0xBC, 0x2A, 0x00, 0xB0, 0xD0, 0xF3, 0xF4, 0xAB); + /// From MFMediaType_HTML + public static readonly Guid HTML = new Guid(0x72178C24, 0xE45B, 0x11D5, 0xBC, 0x2A, 0x00, 0xB0, 0xD0, 0xF3, 0xF4, 0xAB); + /// From MFMediaType_Binary + public static readonly Guid Binary = new Guid(0x72178C25, 0xE45B, 0x11D5, 0xBC, 0x2A, 0x00, 0xB0, 0xD0, 0xF3, 0xF4, 0xAB); + /// From MFMediaType_FileTransfer + public static readonly Guid FileTransfer = new Guid(0x72178C26, 0xE45B, 0x11D5, 0xBC, 0x2A, 0x00, 0xB0, 0xD0, 0xF3, 0xF4, 0xAB); + + public static readonly Guid Base = new Guid(0x00000000, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + public static readonly Guid PCM = new Guid(0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + public static readonly Guid Float = new Guid(0x0003, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + public static readonly Guid DTS = new Guid(0x0008, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + public static readonly Guid Dolby_AC3_SPDIF = new Guid(0x0092, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + public static readonly Guid DRM = new Guid(0x0009, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + public static readonly Guid WMAudioV8 = new Guid(0x0161, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + public static readonly Guid WMAudioV9 = new Guid(0x0162, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + public static readonly Guid WMAudio_Lossless = new Guid(0x0163, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + public static readonly Guid WMASPDIF = new Guid(0x0164, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + public static readonly Guid MSP1 = new Guid(0x000A, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + public static readonly Guid MP3 = new Guid(0x0055, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + public static readonly Guid MPEG = new Guid(0x0050, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + public static readonly Guid AAC = new Guid(0x1610, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + public static readonly Guid ADTS = new Guid(0x1600, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + + // {00000000-767a-494d-b478-f29d25dc9037} MFMPEG4Format_Base + public static readonly Guid MFMPEG4Format = new Guid(0x00000000, 0x767a, 0x494d, 0xb4, 0x78, 0xf2, 0x9d, 0x25, 0xdc, 0x90, 0x37); + + public static readonly Guid RGB32 = new Guid(22, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + public static readonly Guid ARGB32 = new Guid(21, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + public static readonly Guid RGB24 = new Guid(20, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + public static readonly Guid RGB555 = new Guid(24, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + public static readonly Guid RGB565 = new Guid(23, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + public static readonly Guid RGB8 = new Guid(41, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + public static readonly Guid AI44 = new FourCC("AI44").ToMediaSubtype(); + public static readonly Guid AYUV = new FourCC("AYUV").ToMediaSubtype(); + public static readonly Guid YUY2 = new FourCC("YUY2").ToMediaSubtype(); + public static readonly Guid YVYU = new FourCC("YVYU").ToMediaSubtype(); + public static readonly Guid YVU9 = new FourCC("YVU9").ToMediaSubtype(); + public static readonly Guid UYVY = new FourCC("UYVY").ToMediaSubtype(); + public static readonly Guid NV11 = new FourCC("NV11").ToMediaSubtype(); + public static readonly Guid NV12 = new FourCC("NV12").ToMediaSubtype(); + public static readonly Guid YV12 = new FourCC("YV12").ToMediaSubtype(); + public static readonly Guid I420 = new FourCC("I420").ToMediaSubtype(); + public static readonly Guid IYUV = new FourCC("IYUV").ToMediaSubtype(); + public static readonly Guid Y210 = new FourCC("Y210").ToMediaSubtype(); + public static readonly Guid Y216 = new FourCC("Y216").ToMediaSubtype(); + public static readonly Guid Y410 = new FourCC("Y410").ToMediaSubtype(); + public static readonly Guid Y416 = new FourCC("Y416").ToMediaSubtype(); + public static readonly Guid Y41P = new FourCC("Y41P").ToMediaSubtype(); + public static readonly Guid Y41T = new FourCC("Y41T").ToMediaSubtype(); + public static readonly Guid Y42T = new FourCC("Y42T").ToMediaSubtype(); + public static readonly Guid P210 = new FourCC("P210").ToMediaSubtype(); + public static readonly Guid P216 = new FourCC("P216").ToMediaSubtype(); + public static readonly Guid P010 = new FourCC("P010").ToMediaSubtype(); + public static readonly Guid P016 = new FourCC("P016").ToMediaSubtype(); + public static readonly Guid v210 = new FourCC("v210").ToMediaSubtype(); + public static readonly Guid v216 = new FourCC("v216").ToMediaSubtype(); + public static readonly Guid v410 = new FourCC("v410").ToMediaSubtype(); + public static readonly Guid MP43 = new FourCC("MP43").ToMediaSubtype(); + public static readonly Guid MP4S = new FourCC("MP4S").ToMediaSubtype(); + public static readonly Guid M4S2 = new FourCC("M4S2").ToMediaSubtype(); + public static readonly Guid MP4V = new FourCC("MP4V").ToMediaSubtype(); + public static readonly Guid WMV1 = new FourCC("WMV1").ToMediaSubtype(); + public static readonly Guid WMV2 = new FourCC("WMV2").ToMediaSubtype(); + public static readonly Guid WMV3 = new FourCC("WMV3").ToMediaSubtype(); + public static readonly Guid WVC1 = new FourCC("WVC1").ToMediaSubtype(); + public static readonly Guid MSS1 = new FourCC("MSS1").ToMediaSubtype(); + public static readonly Guid MSS2 = new FourCC("MSS2").ToMediaSubtype(); + public static readonly Guid MPG1 = new FourCC("MPG1").ToMediaSubtype(); + public static readonly Guid DVSL = new FourCC("dvsl").ToMediaSubtype(); + public static readonly Guid DVSD = new FourCC("dvsd").ToMediaSubtype(); + public static readonly Guid DVHD = new FourCC("dvhd").ToMediaSubtype(); + public static readonly Guid DV25 = new FourCC("dv25").ToMediaSubtype(); + public static readonly Guid DV50 = new FourCC("dv50").ToMediaSubtype(); + public static readonly Guid DVH1 = new FourCC("dvh1").ToMediaSubtype(); + public static readonly Guid DVC = new FourCC("dvc ").ToMediaSubtype(); + public static readonly Guid H264 = new FourCC("H264").ToMediaSubtype(); + public static readonly Guid MJPG = new FourCC("MJPG").ToMediaSubtype(); + + public static readonly Guid MPEG2 = new Guid(0xe06d8026, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea); + } + + #endregion + + #region Declarations + +#if ALLOW_UNTESTED_INTERFACES + + [UnmanagedName("MFNETSOURCE_STATISTICS_IDS")] + public enum MFNETSOURCE_STATISTICS_IDS + { + RECVPACKETS_ID = 0, + LOSTPACKETS_ID, + RESENDSREQUESTED_ID, + RESENDSRECEIVED_ID, + RECOVEREDBYECCPACKETS_ID, + RECOVEREDBYRTXPACKETS_ID, + OUTPACKETS_ID, + RECVRATE_ID, + AVGBANDWIDTHBPS_ID, + BYTESRECEIVED_ID, + PROTOCOL_ID, + TRANSPORT_ID, + CACHE_STATE_ID, + LINKBANDWIDTH_ID, + CONTENTBITRATE_ID, + SPEEDFACTOR_ID, + BUFFERSIZE_ID, + BUFFERPROGRESS_ID, + LASTBWSWITCHTS_ID, + SEEKRANGESTART_ID, + SEEKRANGEEND_ID, + BUFFERINGCOUNT_ID, + INCORRECTLYSIGNEDPACKETS_ID, + SIGNEDSESSION_ID, + MAXBITRATE_ID, + RECEPTION_QUALITY_ID, + RECOVEREDPACKETS_ID, + VBR_ID, + DOWNLOADPROGRESS_ID, + UNPREDEFINEDPROTOCOLNAME_ID + } + + [Flags, UnmanagedName("MFOUTPUTATTRIBUTE_ *")] + public enum MFOutputAttribute + { + None = 0, + Digital = 0x00000001, + NonstandardImplementation = 0x00000002, + Video = 0x00000004, + Compressed = 0x00000008, + Software = 0x00000010, + Bus = 0x00000020, + BusImplementation = 0x0000FF00 + } + + [Flags, UnmanagedName("MFNetAuthenticationFlags")] + public enum MFNetAuthenticationFlags + { + None = 0, + Proxy = 0x00000001, + ClearText = 0x00000002, + LoggedOnUser = 0x00000004 + } + + [Flags, UnmanagedName("MFNetCredentialOptions")] + public enum MFNetCredentialOptions + { + None = 0, + Save = 0x00000001, + DontCache = 0x00000002, + AllowClearText = 0x00000004, + } + + [UnmanagedName("MFStandardVideoFormat")] + public enum MFStandardVideoFormat + { + reserved = 0, + NTSC = (reserved + 1), + PAL = (NTSC + 1), + DVD_NTSC = (PAL + 1), + DVD_PAL = (DVD_NTSC + 1), + DV_PAL = (DVD_PAL + 1), + DV_NTSC = (DV_PAL + 1), + ATSC_SD480i = (DV_NTSC + 1), + ATSC_HD1080i = (ATSC_SD480i + 1), + ATSC_HD720p = (ATSC_HD1080i + 1) + } + + [UnmanagedName("MFNetCredentialRequirements")] + public enum MFNetCredentialRequirements + { + None = 0, + RequirePrompt = 0x00000001, + RequireSaveSelected = 0x00000002 + } + + [UnmanagedName("MF_QUALITY_DROP_MODE")] + public enum MFQualitydropMode + { + None, + Mode1, + Mode2, + Mode3, + Mode4, + Mode5, + NumDropModes + } + + [UnmanagedName("MF_QUALITY_LEVEL")] + public enum MFQualityLevel + { + Normal, + NormalMinus1, + NormalMinus2, + NormalMinus3, + NormalMinus4, + NormalMinus5, + NumQualityLevels + } + + [UnmanagedName("MFNETSOURCE_PROTOCOL_TYPE")] + public enum MFNetSourceProtocolType + { + Undefined, + Http, + Rtsp, + File, + MultiCast + } + + [UnmanagedName("MFPolicyManagerAction")] + public enum MFPolicyManagerAction + { + Copy = 2, + Export = 3, + Extract = 4, + Last = 7, + No = 0, + Play = 1, + Reserved1 = 5, + Reserved2 = 6, + Reserved3 = 7 + } + + [Flags, UnmanagedName("MF_CONNECT_METHOD")] + public enum MF_CONNECT_METHOD + { + Direct = 0x00000000, + AllowConverter = 0x00000001, + AllowDecoder = 0x00000003, + ResolveIndependentOutputTypes = 0x00000004, + AsOptional = 0x00010000, + AsOptionalBranch = 0x00020000, + } + + [Flags, UnmanagedName("MF_AUDIO_RENDERER_ATTRIBUTE_FLAGS_* defines")] + public enum MF_AUDIO_RENDERER_ATTRIBUTE_FLAGS + { + None = 0x00000000, + CrossProcess = 0x00000001, + NoPersist = 0x00000002, + DontAllowFormatChanges = 0x00000004 + } + + [Flags, UnmanagedName("MF_TRANSCODE_ADJUST_PROFILE_FLAGS")] + public enum MF_TRANSCODE_ADJUST_PROFILE_FLAGS + { + Default = 0, + UseSourceAttributes = 1 + } + + [Flags, UnmanagedName("MF_TRANSCODE_TOPOLOGYMODE_FLAGS")] + public enum MF_TRANSCODE_TOPOLOGYMODE_FLAGS + { + SoftwareOnly = 0, + HardwareAllowed = 1 + } + + [Flags, UnmanagedName("MFTOPOLOGY_DXVA_MODE")] + public enum MFTOPOLOGY_DXVA_MODE + { + Default = 0, + None = 1, + Full = 2 + } + + [UnmanagedName("MFTOPOLOGY_HARDWARE_MODE")] + public enum MFTOPOLOGY_HARDWARE_MODE + { + SoftwareOnly = 0, + UseHardware = 1, + } + + [Flags, UnmanagedName("MF_QUALITY_ADVISE_FLAGS")] + public enum MFQualityAdviseFlags + { + None = 0, + CannotKeepUp = 0x1 + } + + [UnmanagedName("MFASYNC_WORKQUEUE_TYPE")] + public enum MFASYNC_WORKQUEUE_TYPE + { + StandardWorkqueue = 0, + WindowWorkqueue = 1 + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MPEG2VIDEOINFO")] + public struct Mpeg2VideoInfo + { + VideoInfoHeader2 hdr; + int dwStartTimeCode; // ?? not used for DVD ?? + int cbSequenceHeader; // is 0 for DVD (no sequence header) + int dwProfile; // use enum MPEG2Profile + int dwLevel; // use enum MPEG2Level + int dwFlags; // use AMMPEG2_* defines. Reject connection if undefined bits are not 0 + int[] dwSequenceHeader; // DWORD instead of Byte for alignment purposes + // For MPEG-2, if a sequence_header is included, the sequence_extension + // should also be included + } + + [StructLayout(LayoutKind.Explicit, Pack = 8), UnmanagedName("unnamed internal struct")] + public struct Unnamed1 + { + [FieldOffset(0)] + public double d; + [FieldOffset(0)] + public int u32; + [FieldOffset(0)] + public long u64; + } + + [StructLayout(LayoutKind.Sequential, Pack = 4), UnmanagedName("MF_LEAKY_BUCKET_PAIR")] + public struct MF_LeakyBucketPair + { + public int dwBitrate; + public int msBufferWindow; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MFBYTESTREAM_BUFFERING_PARAMS")] + public struct MFByteStreamBufferingParams + { + public long cbTotalFileSize; + public long cbPlayableDataSize; + public IntPtr prgBuckets; + public int cBuckets; + public long qwNetBufferingTime; + public long qwExtraBufferingTimeDuringSeek; + public long qwPlayDuration; + public float dRate; + } + + [StructLayout(LayoutKind.Sequential, Pack = 4), UnmanagedName("MFINPUTTRUSTAUTHORITY_ACCESS_PARAMS")] + public struct MFInputTrustAuthorityAccessParams + { + public int dwSize; + public int dwVer; + public int cbSignatureOffset; + public int cbSignatureSize; + public int cbExtensionOffset; + public int cbExtensionSize; + public int cActions; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public MFInputTrustAuthorityAction[] rgOutputActions; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MFINPUTTRUSTAUTHORITY_ACTION")] + public struct MFInputTrustAuthorityAction + { + public MFPolicyManagerAction Action; + public IntPtr pbTicket; + public int cbTicket; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MFNetCredentialManagerGetParam")] + public struct MFNetCredentialManagerGetParam + { + [MarshalAs(UnmanagedType.Error)] + public int hrOp; + public int fAllowLoggedOnUser; + public int fClearTextPackage; + [MarshalAs(UnmanagedType.LPWStr)] + public string pszUrl; + [MarshalAs(UnmanagedType.LPWStr)] + public string pszSite; + [MarshalAs(UnmanagedType.LPWStr)] + public string pszRealm; + [MarshalAs(UnmanagedType.LPWStr)] + public string pszPackage; + public int nRetries; + } + + [StructLayout(LayoutKind.Sequential, Pack = 8), UnmanagedName("MFTOPONODE_ATTRIBUTE_UPDATE")] + public struct MFTopoNodeAttributeUpdate + { + public long NodeId; + public Guid guidAttributeKey; + public MFAttributeType attrType; + public Unnamed1 u1; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MF_TRANSCODE_SINK_INFO")] + public struct MFTranscodeSinkInfo + { + public int dwVideoStreamID; + public IMFMediaType pVideoMediaType; + public int dwAudioStreamID; + public IMFMediaType pAudioMediaType; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MT_ARBITRARY_HEADER")] + public struct MT_ARBITRARY_HEADER + { + public Guid majortype; + public Guid subtype; + public bool bFixedSizeSamples; + public bool bTemporalCompression; + public int lSampleSize; + public Guid formattype; + } + +#endif + + [UnmanagedName("MFRATE_DIRECTION")] + public enum MFRateDirection + { + Forward = 0, + Reverse + } + + [UnmanagedName("MFSTREAMSINK_MARKER_TYPE")] + public enum MFStreamSinkMarkerType + { + Default, + EndOfSegment, + Tick, + Event + } + + [Flags, UnmanagedName("MFSequencerTopologyFlags")] + public enum MFSequencerTopologyFlags + { + None = 0, + Last = 0x00000001 + } + + [Flags, UnmanagedName("MFSESSION_GETFULLTOPOLOGY_FLAGS")] + public enum MFSessionGetFullTopologyFlags + { + None = 0x0, + Current = 0x1 + } + + [Flags, UnmanagedName("MFSESSIONCAP_* defines")] + public enum MFSessionCapabilities + { + None = 0x00000000, + Start = 0x00000001, + Seek = 0x00000002, + Pause = 0x00000004, + RateForward = 0x00000010, + RateReverse = 0x00000020 + } + + [Flags, UnmanagedName("MFSESSION_SETTOPOLOGY_FLAGS")] + public enum MFSessionSetTopologyFlags + { + None = 0x0, + Immediate = 0x1, + NoResolution = 0x2, + ClearCurrent = 0x4 + } + + [UnmanagedName("MFWaveFormatExConvertFlags")] + public enum MFWaveFormatExConvertFlags + { + Normal = 0, + ForceExtensible = 1 + } + + [UnmanagedName("MF_OBJECT_TYPE")] + public enum MFObjectType + { + MediaSource, + ByteStream, + Invalid + } + + [Flags, UnmanagedName("unnamed enum")] + public enum MFResolution + { + None = 0x0, + MediaSource = 0x00000001, + ByteStream = 0x00000002, + ContentDoesNotHaveToMatchExtensionOrMimeType = 0x00000010, + KeepByteStreamAliveOnFail = 0x00000020, + Read = 0x00010000, + Write = 0x00020000 + } + + [UnmanagedName("MF_TOPOSTATUS")] + public enum MFTopoStatus + { + // MF_TOPOSTATUS_INVALID: Invalid value; will not be sent + Invalid = 0, + + // READY: The topology has been put in place and is + // ready to start. All GetService calls to the Media Session will use + // this topology. + Ready = 100, + + // STARTED_SOURCE: The Media Session has started to read + // and process data from the Media Source(s) in this topology. + StartedSource = 200, + + // MF_TOPOSTATUS_DYNAMIC_CHANGED: The topology has been dynamic changed + // due to the format change. + DynamicChanged = 210, + + // SINK_SWITCHED: The Media Sinks in the pipeline have + // switched from a previous topology to this topology. + // Note that this status does not get sent for the first topology; + // applications can assume that the sinks are playing the first + // topology when they receive MESessionStarted. + SinkSwitched = 300, + + // ENDED: Playback of this topology is complete. + // Before deleting this topology, however, the application should wait + // for either MESessionEnded or the STARTED_SOURCE status + // on the next topology to ensure that the Media Session is no longer + // using this topology. + Ended = 400, + } + + [UnmanagedName("MFSTARTUP_* defines")] + public enum MFStartup + { + NoSocket = 0x1, + Lite = 0x1, + Full = 0 + } + + [UnmanagedName("MFCLOCK_STATE")] + public enum MFClockState + { + Invalid, + Running, + Stopped, + Paused + } + + [Flags, UnmanagedName("MFCLOCK_CHARACTERISTICS_FLAGS")] + public enum MFClockCharacteristicsFlags + { + None = 0, + Frequency10Mhz = 0x2, + AlwaysRunning = 0x4, + IsSystemClock = 0x8 + } + + [UnmanagedName("MF_TOPOLOGY_TYPE")] + public enum MFTopologyType + { + Max = -1, + OutputNode = 0, + SourcestreamNode = 1, + TeeNode = 3, + TransformNode = 2 + } + + [Flags, UnmanagedName("MFMEDIASOURCE_CHARACTERISTICS")] + public enum MFMediaSourceCharacteristics + { + None = 0, + IsLive = 0x1, + CanSeek = 0x2, + CanPause = 0x4, + HasSlowSeek = 0x8, + HasMultiplePresentations = 0x10, + CanSkipForward = 0x20, + CanSkipBackward = 0x40 + } + + [Flags, UnmanagedName("MEDIASINK_ defines")] + public enum MFMediaSinkCharacteristics + { + None = 0, + FixedStreams = 0x00000001, + CannotMatchClock = 0x00000002, + Rateless = 0x00000004, + ClockRequired = 0x00000008, + CanPreroll = 0x00000010, + RequireReferenceMediaType = 0x00000020 + } + + [UnmanagedName("MF_ATTRIBUTE_SERIALIZE_OPTIONS"), Flags] + public enum MFAttributeSerializeOptions + { + None = 0, + UnknownByRef = 0x00000001 + } + + [UnmanagedName("MF_FILE_ACCESSMODE")] + public enum MFFileAccessMode + { + None = 0, + Read = 1, + Write = 2, + ReadWrite = 3 + } + + [UnmanagedName("MF_FILE_OPENMODE")] + public enum MFFileOpenMode + { + FailIfNotExist = 0, + FailIfExist = 1, + ResetIfExist = 2, + AppendIfExist = 3, + DeleteIfExist = 4 + } + + [Flags, UnmanagedName("MF_FILE_FLAGS")] + public enum MFFileFlags + { + None = 0, + NoBuffering = 0x1, + AllowWriteSharing = 0x2 + } + + [UnmanagedName("MF_URL_TRUST_STATUS")] + public enum MFURLTrustStatus + { + Untrusted, + Trusted, + Tampered + } + + [Flags, UnmanagedName("MFPMPSESSION_CREATION_FLAGS")] + public enum MFPMPSessionCreationFlags + { + None = 0, + UnprotectedProcess = 0x1 + } + + [Flags, UnmanagedName("MFCLOCK_RELATIONAL_FLAGS")] + public enum MFClockRelationalFlags + { + None = 0, + JitterNeverAhead = 0x1 + } + + [UnmanagedName("MFSHUTDOWN_STATUS")] + public enum MFShutdownStatus + { + Initiated, + Completed + } + + [Flags, UnmanagedName("MFTIMER_FLAGS")] + public enum MFTimeFlags + { + None = 0, + Relative = 0x00000001 + } + + [StructLayout(LayoutKind.Sequential, Pack = 1), UnmanagedName("MFAYUVSample")] + public struct MFAYUVSample + { + public byte bCrValue; + public byte bCbValue; + public byte bYValue; + public byte bSampleAlpha8; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1), UnmanagedName("MFARGB")] + public struct MFARGB + { + public byte rgbBlue; + public byte rgbGreen; + public byte rgbRed; + public byte rgbAlpha; + } + + [StructLayout(LayoutKind.Explicit, Pack = 1), UnmanagedName("MFPaletteEntry")] + public struct MFPaletteEntry + { + [FieldOffset(0)] + public MFARGB ARGB; + [FieldOffset(0)] + public MFAYUVSample AYCbCr; + } + + [StructLayout(LayoutKind.Sequential, Pack = 8), UnmanagedName("MFCLOCK_PROPERTIES")] + public struct MFClockProperties + { + public long qwCorrelationRate; + public Guid guidClockId; + public MFClockRelationalFlags dwClockFlags; + public long qwClockFrequency; + public int dwClockTolerance; + public int dwClockJitter; + } + + #endregion + + #region Interfaces + +#if ALLOW_UNTESTED_INTERFACES + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("86CBC910-E533-4751-8E3B-F19B5B806A03"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFVideoSampleAllocator + { + [PreserveSig] + int SetDirectXManager( + [In, MarshalAs(UnmanagedType.IUnknown)] object pManager + ); + + [PreserveSig] + int UninitializeSampleAllocator(); + + [PreserveSig] + int InitializeSampleAllocator( + [In] int cRequestedFrames, + [In, MarshalAs(UnmanagedType.Interface)] IMFMediaType pMediaType + ); + + [PreserveSig] + int AllocateSample( + [MarshalAs(UnmanagedType.Interface)] out IMFSample ppSample + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("A0638C2B-6465-4395-9AE7-A321A9FD2856")] + public interface IMFAudioPolicy + { + [PreserveSig] + int SetGroupingParam( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid rguidClass + ); + + [PreserveSig] + int GetGroupingParam( + out Guid pguidClass + ); + + [PreserveSig] + int SetDisplayName( + [In, MarshalAs(UnmanagedType.LPWStr)] string pszName + ); + + [PreserveSig] + int GetDisplayName( + [MarshalAs(UnmanagedType.LPWStr)] out string pszName + ); + + [PreserveSig] + int SetIconPath( + [In, MarshalAs(UnmanagedType.LPWStr)] string pszPath + ); + + [PreserveSig] + int GetIconPath( + [MarshalAs(UnmanagedType.LPWStr)] out string pszPath + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("76B1BBDB-4EC8-4F36-B106-70A9316DF593")] + public interface IMFAudioStreamVolume + { + [PreserveSig] + int GetChannelCount( + out int pdwCount + ); + + [PreserveSig] + int SetChannelVolume( + [In] int dwIndex, + [In] float fLevel + ); + + [PreserveSig] + int GetChannelVolume( + [In] int dwIndex, + out float pfLevel + ); + + [PreserveSig] + int SetAllVolumes( + [In] int dwCount, + [In] ref float pfVolumes + ); + + [PreserveSig] + int GetAllVolumes( + [In] int dwCount, + out float pfVolumes + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("6D66D782-1D4F-4DB7-8C63-CB8C77F1EF5E"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFByteStreamBuffering + { + [PreserveSig] + int SetBufferingParams( + [In] ref MFByteStreamBufferingParams pParams + ); + + [PreserveSig] + int EnableBuffering( + [In] int fEnable + ); + + [PreserveSig] + int StopBuffering(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("D19F8E98-B126-4446-890C-5DCB7AD71453"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFInputTrustAuthority + { + [PreserveSig] + int GetDecrypter( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.Interface)] out object ppv + ); + + [PreserveSig] + int RequestAccess( + [In] MFPolicyManagerAction Action, + [MarshalAs(UnmanagedType.Interface)] out IMFActivate ppContentEnablerActivate + ); + + [PreserveSig] + int GetPolicy( + [In] MFPolicyManagerAction Action, + [MarshalAs(UnmanagedType.Interface)] out IMFOutputPolicy ppPolicy + ); + + [PreserveSig] + int BindAccess( + [In] ref MFInputTrustAuthorityAccessParams pParam + ); + + [PreserveSig] + int UpdateAccess( + [In] ref MFInputTrustAuthorityAccessParams pParam + ); + + [PreserveSig] + int Reset(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("5DFD4B2A-7674-4110-A4E6-8A68FD5F3688"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFMediaSinkPreroll + { + [PreserveSig] + int NotifyPreroll( + [In] long hnsUpcomingStartTime + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("0E1D600A-C9F3-442D-8C51-A42D2D49452F"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFMediaSourcePresentationProvider + { + [PreserveSig] + int ForceEndOfPresentation( + [In, MarshalAs(UnmanagedType.Interface)] IMFPresentationDescriptor pPresentationDescriptor + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("5B87EF6A-7ED8-434F-BA0E-184FAC1628D1")] + public interface IMFNetCredential + { + [PreserveSig] + int SetUser( + [In] ref byte pbData, + [In] int cbData, + [In] int fDataIsEncrypted + ); + + [PreserveSig] + int SetPassword( + [In] ref byte pbData, + [In] int cbData, + [In] int fDataIsEncrypted + ); + + [PreserveSig] + int GetUser( + out byte pbData, + [In, Out] ref int pcbData, + [In] int fEncryptData + ); + + [PreserveSig] + int GetPassword( + out byte pbData, + [In, Out] ref int pcbData, + [In, MarshalAs(UnmanagedType.Bool)] bool fEncryptData + ); + + [PreserveSig] + int LoggedOnUser( + [MarshalAs(UnmanagedType.Bool)] out bool pfLoggedOnUser + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("5B87EF6C-7ED8-434F-BA0E-184FAC1628D1")] + public interface IMFNetCredentialCache + { + [PreserveSig] + int GetCredential( + [In, MarshalAs(UnmanagedType.LPWStr)] string pszUrl, + [In, MarshalAs(UnmanagedType.LPWStr)] string pszRealm, + [In] MFNetAuthenticationFlags dwAuthenticationFlags, + [MarshalAs(UnmanagedType.Interface)] out IMFNetCredential ppCred, + out MFNetCredentialRequirements pdwRequirementsFlags + ); + + [PreserveSig] + int SetGood( + [In, MarshalAs(UnmanagedType.Interface)] IMFNetCredential pCred, + [In] bool fGood + ); + + [PreserveSig] + int SetUserOptions( + [In, MarshalAs(UnmanagedType.Interface)] IMFNetCredential pCred, + [In] MFNetCredentialOptions dwOptionsFlags + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("5B87EF6B-7ED8-434F-BA0E-184FAC1628D1"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFNetCredentialManager + { + [PreserveSig] + int BeginGetCredentials( + [In] ref MFNetCredentialManagerGetParam pParam, + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + [In, MarshalAs(UnmanagedType.IUnknown)] object pState + ); + + [PreserveSig] + int EndGetCredentials( + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncResult pResult, + [MarshalAs(UnmanagedType.Interface)] out IMFNetCredential ppCred + ); + + [PreserveSig] + int SetGood( + [In, MarshalAs(UnmanagedType.Interface)] IMFNetCredential pCred, + [In] bool fGood + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("E9CD0383-A268-4BB4-82DE-658D53574D41")] + public interface IMFNetProxyLocator + { + [PreserveSig] + int FindFirstProxy( + [In, MarshalAs(UnmanagedType.LPWStr)] string pszHost, + [In, MarshalAs(UnmanagedType.LPWStr)] string pszUrl, + [In, MarshalAs(UnmanagedType.Bool)] bool fReserved + ); + + [PreserveSig] + int FindNextProxy(); + + [PreserveSig] + int RegisterProxyResult( + [In, MarshalAs(UnmanagedType.Error)] int hrOp + ); + + [PreserveSig] + int GetCurrentProxy( + [Out, MarshalAs(UnmanagedType.LPWStr)] string pszStr, + [In, Out] ref int pcchStr + ); + + [PreserveSig] + int Clone( + [MarshalAs(UnmanagedType.Interface)] out IMFNetProxyLocator ppProxyLocator + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("E9CD0384-A268-4BB4-82DE-658D53574D41"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFNetProxyLocatorFactory + { + [PreserveSig] + int CreateProxyLocator( + [In, MarshalAs(UnmanagedType.LPWStr)] string pszProtocol, + [MarshalAs(UnmanagedType.Interface)] out IMFNetProxyLocator ppProxyLocator + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("7BE19E73-C9BF-468A-AC5A-A5E8653BEC87")] + public interface IMFNetSchemeHandlerConfig + { + [PreserveSig] + int GetNumberOfSupportedProtocols( + out int pcProtocols + ); + + [PreserveSig] + int GetSupportedProtocolType( + [In] int nProtocolIndex, + out MFNetSourceProtocolType pnProtocolType + ); + + [PreserveSig] + int ResetProtocolRolloverSettings(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("09EF5BE3-C8A7-469E-8B70-73BF25BB193F"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFObjectReferenceStream + { + [PreserveSig] + int SaveReference( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnk + ); + + [PreserveSig] + int LoadReference( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.Interface)] out object ppv + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("7F00F10A-DAED-41AF-AB26-5FDFA4DFBA3C"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFOutputPolicy : IMFAttributes + { + #region IMFAttributes methods + + [PreserveSig] + new int GetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int GetItemType( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out MFAttributeType pType + ); + + [PreserveSig] + new int CompareItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int Compare( + [MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, + MFAttributesMatchType MatchType, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int GetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int punValue + ); + + [PreserveSig] + new int GetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out long punValue + ); + + [PreserveSig] + new int GetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out double pfValue + ); + + [PreserveSig] + new int GetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out Guid pguidValue + ); + + [PreserveSig] + new int GetStringLength( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcchLength + ); + + [PreserveSig] + new int GetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, + int cchBufSize, + out int pcchLength + ); + + [PreserveSig] + new int GetAllocatedString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, + out int pcchLength + ); + + [PreserveSig] + new int GetBlobSize( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcbBlobSize + ); + + [PreserveSig] + new int GetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, + int cbBufSize, + out int pcbBlobSize + ); + + // Use GetBlob instead of this + [PreserveSig] + new int GetAllocatedBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out IntPtr ip, // Read w/Marshal.Copy, Free w/Marshal.FreeCoTaskMem + out int pcbSize + ); + + [PreserveSig] + new int GetUnknown( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.IUnknown)] out object ppv + ); + + [PreserveSig] + new int SetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value + ); + + [PreserveSig] + new int DeleteItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey + ); + + [PreserveSig] + new int DeleteAllItems(); + + [PreserveSig] + new int SetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + int unValue + ); + + [PreserveSig] + new int SetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + long unValue + ); + + [PreserveSig] + new int SetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + double fValue + ); + + [PreserveSig] + new int SetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue + ); + + [PreserveSig] + new int SetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue + ); + + [PreserveSig] + new int SetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, + int cbBufSize + ); + + [PreserveSig] + new int SetUnknown( + [MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown + ); + + [PreserveSig] + new int LockStore(); + + [PreserveSig] + new int UnlockStore(); + + [PreserveSig] + new int GetCount( + out int pcItems + ); + + [PreserveSig] + new int GetItemByIndex( + int unIndex, + out Guid pguidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int CopyAllItems( + [In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest + ); + + #endregion + + [PreserveSig] + int GenerateRequiredSchemas( + [In] MFOutputAttribute dwAttributes, + [In, MarshalAs(UnmanagedType.Struct)] Guid guidOutputSubType, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid rgGuidProtectionSchemasSupported, + [In] int cProtectionSchemasSupported, + [MarshalAs(UnmanagedType.Interface)] out IMFCollection ppRequiredProtectionSchemas + ); + + [PreserveSig] + int GetOriginatorID( + out Guid pguidOriginatorID + ); + + [PreserveSig] + int GetMinimumGRLVersion( + out int pdwMinimumGRLVersion + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("7BE0FC5B-ABD9-44FB-A5C8-F50136E71599")] + public interface IMFOutputSchema : IMFAttributes + { + #region IMFAttributes methods + + [PreserveSig] + new int GetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int GetItemType( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out MFAttributeType pType + ); + + [PreserveSig] + new int CompareItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int Compare( + [MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, + MFAttributesMatchType MatchType, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int GetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int punValue + ); + + [PreserveSig] + new int GetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out long punValue + ); + + [PreserveSig] + new int GetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out double pfValue + ); + + [PreserveSig] + new int GetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out Guid pguidValue + ); + + [PreserveSig] + new int GetStringLength( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcchLength + ); + + [PreserveSig] + new int GetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, + int cchBufSize, + out int pcchLength + ); + + [PreserveSig] + new int GetAllocatedString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, + out int pcchLength + ); + + [PreserveSig] + new int GetBlobSize( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcbBlobSize + ); + + [PreserveSig] + new int GetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, + int cbBufSize, + out int pcbBlobSize + ); + + // Use GetBlob instead of this + [PreserveSig] + new int GetAllocatedBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out IntPtr ip, // Read w/Marshal.Copy, Free w/Marshal.FreeCoTaskMem + out int pcbSize + ); + + [PreserveSig] + new int GetUnknown( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.IUnknown)] out object ppv + ); + + [PreserveSig] + new int SetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value + ); + + [PreserveSig] + new int DeleteItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey + ); + + [PreserveSig] + new int DeleteAllItems(); + + [PreserveSig] + new int SetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + int unValue + ); + + [PreserveSig] + new int SetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + long unValue + ); + + [PreserveSig] + new int SetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + double fValue + ); + + [PreserveSig] + new int SetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue + ); + + [PreserveSig] + new int SetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue + ); + + [PreserveSig] + new int SetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, + int cbBufSize + ); + + [PreserveSig] + new int SetUnknown( + [MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown + ); + + [PreserveSig] + new int LockStore(); + + [PreserveSig] + new int UnlockStore(); + + [PreserveSig] + new int GetCount( + out int pcItems + ); + + [PreserveSig] + new int GetItemByIndex( + int unIndex, + out Guid pguidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int CopyAllItems( + [In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest + ); + + #endregion + + [PreserveSig] + int GetSchemaType( + out Guid pguidSchemaType + ); + + [PreserveSig] + int GetConfigurationData( + out int pdwVal + ); + + [PreserveSig] + int GetOriginatorID( + out Guid pguidOriginatorID + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("D19F8E94-B126-4446-890C-5DCB7AD71453"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFOutputTrustAuthority + { + [PreserveSig] + int GetAction( + out MFPolicyManagerAction pAction + ); + + [PreserveSig] + int SetPolicy( + [In, MarshalAs(UnmanagedType.Interface)] ref IMFOutputPolicy ppPolicy, + [In] int nPolicy, + [Out] IntPtr ppbTicket, + out int pcbTicket + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("6C4E655D-EAD8-4421-B6B9-54DCDBBDF820")] + public interface IMFPMPClient + { + [PreserveSig] + int SetPMPHost( + [In, MarshalAs(UnmanagedType.Interface)] IMFPMPHost pPMPHost + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("F70CA1A9-FDC7-4782-B994-ADFFB1C98606"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFPMPHost + { + [PreserveSig] + int LockProcess(); + + [PreserveSig] + int UnlockProcess(); + + [PreserveSig] + int CreateObjectByCLSID( + [MarshalAs(UnmanagedType.LPStruct)] Guid clsid, + IStream pStream, + [MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.Interface)] object ppv + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("994E23AF-1CC2-493C-B9FA-46F1CB040FA4")] + public interface IMFPMPServer + { + [PreserveSig] + int LockProcess(); + + [PreserveSig] + int UnlockProcess(); + + [PreserveSig] + int CreateObjectByCLSID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid clsid, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.Interface)] out object ppObject + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("EC15E2E9-E36B-4F7C-8758-77D452EF4CE7")] + public interface IMFQualityAdvise + { + [PreserveSig] + int SetDropMode( + [In] MFQualitydropMode eDropMode + ); + + [PreserveSig] + int SetQualityLevel( + [In] MFQualityLevel eQualityLevel + ); + + [PreserveSig] + int GetDropMode( + out MFQualitydropMode peDropMode + ); + + [PreserveSig] + int GetQualityLevel( + out MFQualityLevel peQualityLevel + ); + + [PreserveSig] + int DropTime( + [In] long hnsAmountToDrop + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("8D009D86-5B9F-4115-B1FC-9F80D52AB8AB")] + public interface IMFQualityManager + { + [PreserveSig] + int NotifyTopology( + [In, MarshalAs(UnmanagedType.Interface)] IMFTopology pTopology + ); + + [PreserveSig] + int NotifyPresentationClock( + [In, MarshalAs(UnmanagedType.Interface)] IMFPresentationClock pClock + ); + + [PreserveSig] + int NotifyProcessInput( + [In, MarshalAs(UnmanagedType.Interface)] IMFTopologyNode pNode, + [In] int lInputIndex, + [In, MarshalAs(UnmanagedType.Interface)] IMFSample pSample + ); + + [PreserveSig] + int NotifyProcessOutput( + [In, MarshalAs(UnmanagedType.Interface)] IMFTopologyNode pNode, + [In] int lOutputIndex, + [In, MarshalAs(UnmanagedType.Interface)] IMFSample pSample + ); + + [PreserveSig] + int NotifyQualityEvent( + [In, MarshalAs(UnmanagedType.IUnknown)] object pObject, + [In, MarshalAs(UnmanagedType.Interface)] IMFMediaEvent pEvent + ); + + [PreserveSig] + int Shutdown(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("2347D60B-3FB5-480C-8803-8DF3ADCD3EF0")] + public interface IMFRealTimeClient + { + [PreserveSig] + int RegisterThreads( + [In] int dwTaskIndex, + [In, MarshalAs(UnmanagedType.LPWStr)] string wszClass + ); + + [PreserveSig] + int UnregisterThreads(); + + [PreserveSig] + int SetWorkQueue( + [In] int dwWorkQueueId + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("1CDE6309-CAE0-4940-907E-C1EC9C3D1D4A"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFRemoteDesktopPlugin + { + [PreserveSig] + int UpdateTopology( + [In, Out, MarshalAs(UnmanagedType.Interface)] IMFTopology pTopology + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("994E23AD-1CC2-493C-B9FA-46F1CB040FA4")] + public interface IMFRemoteProxy + { + [PreserveSig] + int GetRemoteObject( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.Interface)] out object ppv + ); + + [PreserveSig] + int GetRemoteHost( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.Interface)] out object ppv + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("A7E025DD-5303-4A62-89D6-E747E1EFAC73"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFSAMIStyle + { + [PreserveSig] + int GetStyleCount( + out int pdwCount + ); + + [PreserveSig] + int GetStyles( + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pPropVarStyleArray + ); + + [PreserveSig] + int SetSelectedStyle( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwszStyle + ); + + [PreserveSig] + int GetSelectedStyle( + [MarshalAs(UnmanagedType.LPWStr)] out string ppwszStyle + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("8C7B80BF-EE42-4B59-B1DF-55668E1BDCA8")] + public interface IMFSampleGrabberSinkCallback : IMFClockStateSink + { + #region IMFClockStateSink methods + + [PreserveSig] + new int OnClockStart( + [In] long hnsSystemTime, + [In] long llClockStartOffset + ); + + [PreserveSig] + new int OnClockStop( + [In] long hnsSystemTime + ); + + [PreserveSig] + new int OnClockPause( + [In] long hnsSystemTime + ); + + [PreserveSig] + new int OnClockRestart( + [In] long hnsSystemTime + ); + + [PreserveSig] + new int OnClockSetRate( + [In] long hnsSystemTime, + [In] float flRate + ); + + #endregion + + [PreserveSig] + int OnSetPresentationClock( + [In, MarshalAs(UnmanagedType.Interface)] IMFPresentationClock pPresentationClock + ); + + [PreserveSig] + int OnProcessSample( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidMajorMediaType, + [In] int dwSampleFlags, // must be zero + [In] long llSampleTime, + [In] long llSampleDuration, + [In] ref byte pSampleBuffer, + [In] int dwSampleSize + ); + + [PreserveSig] + int OnShutdown(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("8E36395F-C7B9-43C4-A54D-512B4AF63C95")] + public interface IMFSampleProtection + { + [PreserveSig] + int GetInputProtectionVersion( + out int pdwVersion + ); + + [PreserveSig] + int GetOutputProtectionVersion( + out int pdwVersion + ); + + [PreserveSig] + int GetProtectionCertificate( + [In] int dwVersion, + [Out] IntPtr ppCert, + out int pcbCert + ); + + [PreserveSig] + int InitOutputProtection( + [In] int dwVersion, + [In] int dwOutputId, + [In] ref byte pbCert, + [In] int cbCert, + [Out] IntPtr ppbSeed, + out int pcbSeed + ); + + [PreserveSig] + int InitInputProtection( + [In] int dwVersion, + [In] int dwInputId, + [In] ref byte pbSeed, + [In] int cbSeed + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("E9931663-80BF-4C6E-98AF-5DCF58747D1F")] + public interface IMFSaveJob + { + [PreserveSig] + int BeginSave( + [In, MarshalAs(UnmanagedType.Interface)] IMFByteStream pStream, + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + [In, MarshalAs(UnmanagedType.IUnknown)] object pState + ); + + [PreserveSig] + int EndSave( + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncResult pResult + ); + + [PreserveSig] + int CancelSave(); + + [PreserveSig] + int GetProgress( + out int pdwPercentComplete + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("6D4C7B74-52A0-4BB7-B0DB-55F29F47A668")] + public interface IMFSchemeHandler + { + [PreserveSig] + int BeginCreateObject( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwszURL, + [In] MFResolution dwFlags, + [In, MarshalAs(UnmanagedType.Interface)] IPropertyStore pProps, + [MarshalAs(UnmanagedType.IUnknown)] out object ppIUnknownCancelCookie, + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnkState + ); + + [PreserveSig] + int EndCreateObject( + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncResult pResult, + out MFObjectType pObjectType, + [MarshalAs(UnmanagedType.IUnknown)] out object ppObject + ); + + [PreserveSig] + int CancelObjectCreation( + [In, MarshalAs(UnmanagedType.IUnknown)] object pIUnknownCancelCookie + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("D0AE555D-3B12-4D97-B060-0990BC5AEB67"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFSecureChannel + { + [PreserveSig] + int GetCertificate( + [Out] IntPtr ppCert, + out int pcbCert + ); + + [PreserveSig] + int SetupSession( + [In] ref byte pbEncryptedSessionKey, + [In] int cbSessionKey + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("089EDF13-CF71-4338-8D13-9E569DBDC319"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFSimpleAudioVolume + { + [PreserveSig] + int SetMasterVolume( + [In] float fLevel + ); + + [PreserveSig] + int GetMasterVolume( + out float pfLevel + ); + + [PreserveSig] + int SetMute( + [In, MarshalAs(UnmanagedType.Bool)] bool bMute + ); + + [PreserveSig] + int GetMute( + [MarshalAs(UnmanagedType.Bool)] out bool pbMute + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("DE9A6157-F660-4643-B56A-DF9F7998C7CD")] + public interface IMFTopoLoader + { + [PreserveSig] + int Load( + [In, MarshalAs(UnmanagedType.Interface)] IMFTopology pInputTopo, + [MarshalAs(UnmanagedType.Interface)] out IMFTopology ppOutputTopo, + [In, MarshalAs(UnmanagedType.Interface)] IMFTopology pCurrentTopo + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("676AA6DD-238A-410D-BB99-65668D01605A"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFTopologyNodeAttributeEditor + { + [PreserveSig] + int UpdateNodeAttributes( + [In] long TopoId, + [In] int cUpdates, + [In] ref MFTopoNodeAttributeUpdate pUpdates + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("542612C4-A1B8-4632-B521-DE11EA64A0B0")] + public interface IMFTrustedInput + { + [PreserveSig] + int GetInputTrustAuthority( + [In] int dwStreamID, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.IUnknown)] out object ppunkObject + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("D19F8E95-B126-4446-890C-5DCB7AD71453"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFTrustedOutput + { + [PreserveSig] + int GetOutputTrustAuthorityCount( + out int pcOutputTrustAuthorities + ); + + [PreserveSig] + int GetOutputTrustAuthorityByIndex( + [In] int dwIndex, + [MarshalAs(UnmanagedType.Interface)] out IMFOutputTrustAuthority ppauthority + ); + + [PreserveSig] + int IsFinal( + [MarshalAs(UnmanagedType.Bool)] out bool pfIsFinal + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("35FE1BB8-A3A9-40FE-BBEC-EB569C9CCCA3"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFWorkQueueServices + { + [PreserveSig] + int BeginRegisterTopologyWorkQueuesWithMMCSS( + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + [MarshalAs(UnmanagedType.IUnknown)] object pState + ); + + [PreserveSig] + int EndRegisterTopologyWorkQueuesWithMMCSS( + IMFAsyncResult pResult + ); + + [PreserveSig] + int BeginUnregisterTopologyWorkQueuesWithMMCSS( + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + [MarshalAs(UnmanagedType.IUnknown)] object pState + ); + + [PreserveSig] + int EndUnregisterTopologyWorkQueuesWithMMCSS( + IMFAsyncResult pResult + ); + + [PreserveSig] + int GetTopologyWorkQueueMMCSSClass( + [In] int dwTopologyWorkQueueId, + [Out, MarshalAs(UnmanagedType.LPWStr)] string pwszClass, + [In, Out] ref int pcchClass + ); + + [PreserveSig] + int GetTopologyWorkQueueMMCSSTaskId( + [In] int dwTopologyWorkQueueId, + out int pdwTaskId + ); + + [PreserveSig] + int BeginRegisterPlatformWorkQueueWithMMCSS( + [In] int dwPlatformWorkQueue, + [In, MarshalAs(UnmanagedType.LPWStr)] string wszClass, + [In] int dwTaskId, + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + [MarshalAs(UnmanagedType.IUnknown)] object pState + ); + + [PreserveSig] + int EndRegisterPlatformWorkQueueWithMMCSS( + IMFAsyncResult pResult, + out int pdwTaskId + ); + + [PreserveSig] + int BeginUnregisterPlatformWorkQueueWithMMCSS( + [In] int dwPlatformWorkQueue, + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + [MarshalAs(UnmanagedType.IUnknown)] object pState + ); + + [PreserveSig] + int EndUnregisterPlatformWorkQueueWithMMCSS( + IMFAsyncResult pResult + ); + + [PreserveSig] + int GetPlaftormWorkQueueMMCSSClass( + [In] int dwPlatformWorkQueueId, + [Out, MarshalAs(UnmanagedType.LPWStr)] string pwszClass, + [In, Out] ref int pcchClass); + + [PreserveSig] + int GetPlatformWorkQueueMMCSSTaskId( + [In] int dwPlatformWorkQueueId, + out int pdwTaskId + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("F5042EA4-7A96-4A75-AA7B-2BE1EF7F88D5")] + public interface IMFByteStreamCacheControl + { + [PreserveSig] + int StopBackgroundTransfer(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("508E71D3-EC66-4FC3-8775-B4B9ED6BA847")] + public interface IMFFieldOfUseMFTUnlock + { + [PreserveSig] + int Unlock( + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnkMFT + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("F3706F0D-8EA2-4886-8000-7155E9EC2EAE")] + public interface IMFQualityAdvise2 : IMFQualityAdvise + { + #region IMFQualityAdvise methods + + [PreserveSig] + new int SetDropMode( + [In] MFQualitydropMode eDropMode + ); + + [PreserveSig] + new int SetQualityLevel( + [In] MFQualityLevel eQualityLevel + ); + + [PreserveSig] + new int GetDropMode( + out MFQualitydropMode peDropMode + ); + + [PreserveSig] + new int GetQualityLevel( + out MFQualityLevel peQualityLevel + ); + + [PreserveSig] + new int DropTime( + [In] long hnsAmountToDrop + ); + + #endregion + + [PreserveSig] + int NotifyQualityEvent( + IMFMediaEvent pEvent, + out MFQualityAdviseFlags pdwFlags + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("DFCD8E4D-30B5-4567-ACAA-8EB5B7853DC9")] + public interface IMFQualityAdviseLimits + { + [PreserveSig] + int GetMaximumDropMode( + out MFQualitydropMode peDropMode + ); + + [PreserveSig] + int GetMinimumQualityLevel( + out MFQualityLevel peQualityLevel + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("CA86AA50-C46E-429E-AB27-16D6AC6844CB")] + public interface IMFSampleGrabberSinkCallback2 : IMFSampleGrabberSinkCallback + { + #region IMFClockStateSink methods + + [PreserveSig] + new int OnClockStart( + [In] long hnsSystemTime, + [In] long llClockStartOffset + ); + + [PreserveSig] + new int OnClockStop( + [In] long hnsSystemTime + ); + + [PreserveSig] + new int OnClockPause( + [In] long hnsSystemTime + ); + + [PreserveSig] + new int OnClockRestart( + [In] long hnsSystemTime + ); + + [PreserveSig] + new int OnClockSetRate( + [In] long hnsSystemTime, + [In] float flRate + ); + + #endregion + + #region IMFSampleGrabberSinkCallback methods + + [PreserveSig] + new int OnSetPresentationClock( + [In, MarshalAs(UnmanagedType.Interface)] IMFPresentationClock pPresentationClock + ); + + [PreserveSig] + new int OnProcessSample( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidMajorMediaType, + [In] int dwSampleFlags, // must be zero + [In] long llSampleTime, + [In] long llSampleDuration, + [In] ref byte pSampleBuffer, + [In] int dwSampleSize + ); + + [PreserveSig] + new int OnShutdown(); + + #endregion + + [PreserveSig] + int OnProcessSampleEx( + [MarshalAs(UnmanagedType.LPStruct)] Guid guidMajorMediaType, + [In] int dwSampleFlags, // No flags are defined + [In] long llSampleTime, + [In] long llSampleDuration, + [In] IntPtr pSampleBuffer, + [In] int dwSampleSize, + IMFAttributes pAttributes + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("61F7D887-1230-4A8B-AEBA-8AD434D1A64D")] + public interface IMFSSLCertificateManager + { + [PreserveSig] + int GetClientCertificate( + [In, MarshalAs(UnmanagedType.LPWStr)] string pszUrl, + [Out] IntPtr ppbData, + out int pcbData + ); + + [PreserveSig] + int BeginGetClientCertificate( + [In, MarshalAs(UnmanagedType.LPWStr)] string pszUrl, + IMFAsyncCallback pCallback, + [In, MarshalAs(UnmanagedType.IUnknown)] object pState + ); + + [PreserveSig] + int EndGetClientCertificate( + IMFAsyncResult pResult, + [Out] IntPtr ppbData, + out int pcbData + ); + + [PreserveSig] + int GetCertificatePolicy( + [In, MarshalAs(UnmanagedType.LPWStr)] string pszUrl, + [MarshalAs(UnmanagedType.Bool)] out bool pfOverrideAutomaticCheck, + [MarshalAs(UnmanagedType.Bool)] out bool pfClientCertificateAvailable + ); + + [PreserveSig] + int OnServerCertificate( + [In, MarshalAs(UnmanagedType.LPWStr)] string pszUrl, + [In] IntPtr pbData, + [In] int cbData, + [MarshalAs(UnmanagedType.Bool)] out bool pfIsGood + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("9DB7AA41-3CC5-40D4-8509-555804AD34CC")] + public interface IMFStreamingSinkConfig + { + [PreserveSig] + int StartStreaming( + [MarshalAs(UnmanagedType.Bool)] bool fSeekOffsetIsByteOffset, + [In] long qwSeekOffset + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("AB9D8661-F7E8-4EF4-9861-89F334F94E74")] + public interface IMFTimecodeTranslate + { + [PreserveSig] + int BeginConvertTimecodeToHNS( + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pPropVarTimecode, + IMFAsyncCallback pCallback, + [In, MarshalAs(UnmanagedType.IUnknown)] object punkState + ); + + [PreserveSig] + int EndConvertTimecodeToHNS( + IMFAsyncResult pResult, + out long phnsTime + ); + + [PreserveSig] + int BeginConvertHNSToTimecode( + [In] long hnsTime, + IMFAsyncCallback pCallback, + [In, MarshalAs(UnmanagedType.IUnknown)] object punkState + ); + + [PreserveSig] + int EndConvertHNSToTimecode( + IMFAsyncResult pResult, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pPropVarTimecode + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("4ADFDBA3-7AB0-4953-A62B-461E7FF3DA1E")] + public interface IMFTranscodeProfile + { + [PreserveSig] + int SetAudioAttributes( + IMFAttributes pAttrs + ); + + [PreserveSig] + int GetAudioAttributes( + out IMFAttributes ppAttrs + ); + + [PreserveSig] + int SetVideoAttributes( + IMFAttributes pAttrs + ); + + [PreserveSig] + int GetVideoAttributes( + out IMFAttributes ppAttrs + ); + + [PreserveSig] + int SetContainerAttributes( + IMFAttributes pAttrs + ); + + [PreserveSig] + int GetContainerAttributes( + out IMFAttributes ppAttrs + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("8CFFCD2E-5A03-4A3A-AFF7-EDCD107C620E")] + public interface IMFTranscodeSinkInfoProvider + { + [PreserveSig] + int SetOutputFile( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwszFileName + ); + + [PreserveSig] + int SetOutputByteStream( + IMFActivate pByteStreamActivate + ); + + [PreserveSig] + int SetProfile( + IMFTranscodeProfile pProfile + ); + + [PreserveSig] + int GetSinkInfo( + out MFTranscodeSinkInfo pSinkInfo + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("992388B4-3372-4F67-8B6F-C84C071F4751")] + public interface IMFVideoSampleAllocatorCallback + { + [PreserveSig] + int SetCallback( + IMFVideoSampleAllocatorNotify pNotify + ); + + [PreserveSig] + int GetFreeSampleCount( + out int plSamples + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("A792CDBE-C374-4E89-8335-278E7B9956A4")] + public interface IMFVideoSampleAllocatorNotify + { + [PreserveSig] + int NotifyRelease(); + } + + #endif + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("279A808D-AEC7-40C8-9C6B-A6B492C78A66")] + public interface IMFMediaSource : IMFMediaEventGenerator + { + #region IMFMediaEventGenerator methods + + [PreserveSig] + new int GetEvent( + [In] MFEventFlag dwFlags, + [MarshalAs(UnmanagedType.Interface)] out IMFMediaEvent ppEvent + ); + + [PreserveSig] + new int BeginGetEvent( + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + [In, MarshalAs(UnmanagedType.IUnknown)] object o + ); + + [PreserveSig] + new int EndGetEvent( + IMFAsyncResult pResult, + out IMFMediaEvent ppEvent + ); + + [PreserveSig] + new int QueueEvent( + [In] MediaEventType met, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidExtendedType, + [In] int hrStatus, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvValue + ); + + #endregion + + [PreserveSig] + int GetCharacteristics( + out MFMediaSourceCharacteristics pdwCharacteristics + ); + + [PreserveSig] + int CreatePresentationDescriptor( + out IMFPresentationDescriptor ppPresentationDescriptor + ); + + [PreserveSig] + int Start( + [In, MarshalAs(UnmanagedType.Interface)] IMFPresentationDescriptor pPresentationDescriptor, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid pguidTimeFormat, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvarStartPosition + ); + + [PreserveSig] + int Stop(); + + [PreserveSig] + int Pause(); + + [PreserveSig] + int Shutdown(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("03CB2711-24D7-4DB6-A17F-F3A7A479A536"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFPresentationDescriptor : IMFAttributes + { + #region IMFAttributes methods + + [PreserveSig] + new int GetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int GetItemType( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out MFAttributeType pType + ); + + [PreserveSig] + new int CompareItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int Compare( + [MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, + MFAttributesMatchType MatchType, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int GetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int punValue + ); + + [PreserveSig] + new int GetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out long punValue + ); + + [PreserveSig] + new int GetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out double pfValue + ); + + [PreserveSig] + new int GetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out Guid pguidValue + ); + + [PreserveSig] + new int GetStringLength( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcchLength + ); + + [PreserveSig] + new int GetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, + int cchBufSize, + out int pcchLength + ); + + [PreserveSig] + new int GetAllocatedString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, + out int pcchLength + ); + + [PreserveSig] + new int GetBlobSize( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcbBlobSize + ); + + [PreserveSig] + new int GetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, + int cbBufSize, + out int pcbBlobSize + ); + + // Use GetBlob instead of this + [PreserveSig] + new int GetAllocatedBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out IntPtr ip, // Read w/Marshal.Copy, Free w/Marshal.FreeCoTaskMem + out int pcbSize + ); + + [PreserveSig] + new int GetUnknown( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.IUnknown)] out object ppv + ); + + [PreserveSig] + new int SetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value + ); + + [PreserveSig] + new int DeleteItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey + ); + + [PreserveSig] + new int DeleteAllItems(); + + [PreserveSig] + new int SetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + int unValue + ); + + [PreserveSig] + new int SetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + long unValue + ); + + [PreserveSig] + new int SetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + double fValue + ); + + [PreserveSig] + new int SetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue + ); + + [PreserveSig] + new int SetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue + ); + + [PreserveSig] + new int SetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, + int cbBufSize + ); + + [PreserveSig] + new int SetUnknown( + [MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown + ); + + [PreserveSig] + new int LockStore(); + + [PreserveSig] + new int UnlockStore(); + + [PreserveSig] + new int GetCount( + out int pcItems + ); + + [PreserveSig] + new int GetItemByIndex( + int unIndex, + out Guid pguidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int CopyAllItems( + [In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest + ); + + #endregion + + [PreserveSig] + int GetStreamDescriptorCount( + out int pdwDescriptorCount + ); + + [PreserveSig] + int GetStreamDescriptorByIndex( + [In] int dwIndex, + [MarshalAs(UnmanagedType.Bool)] out bool pfSelected, + [MarshalAs(UnmanagedType.Interface)] out IMFStreamDescriptor ppDescriptor + ); + + [PreserveSig] + int SelectStream( + [In] int dwDescriptorIndex + ); + + [PreserveSig] + int DeselectStream( + [In] int dwDescriptorIndex + ); + + [PreserveSig] + int Clone( + [MarshalAs(UnmanagedType.Interface)] out IMFPresentationDescriptor ppPresentationDescriptor + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("56C03D9C-9DBB-45F5-AB4B-D80F47C05938"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFStreamDescriptor : IMFAttributes + { + #region IMFAttributes methods + + [PreserveSig] + new int GetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int GetItemType( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out MFAttributeType pType + ); + + [PreserveSig] + new int CompareItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int Compare( + [MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, + MFAttributesMatchType MatchType, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int GetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int punValue + ); + + [PreserveSig] + new int GetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out long punValue + ); + + [PreserveSig] + new int GetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out double pfValue + ); + + [PreserveSig] + new int GetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out Guid pguidValue + ); + + [PreserveSig] + new int GetStringLength( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcchLength + ); + + [PreserveSig] + new int GetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, + int cchBufSize, + out int pcchLength + ); + + [PreserveSig] + new int GetAllocatedString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, + out int pcchLength + ); + + [PreserveSig] + new int GetBlobSize( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcbBlobSize + ); + + [PreserveSig] + new int GetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, + int cbBufSize, + out int pcbBlobSize + ); + + // Use GetBlob instead of this + [PreserveSig] + new int GetAllocatedBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out IntPtr ip, // Read w/Marshal.Copy, Free w/Marshal.FreeCoTaskMem + out int pcbSize + ); + + [PreserveSig] + new int GetUnknown( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.IUnknown)] out object ppv + ); + + [PreserveSig] + new int SetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value + ); + + [PreserveSig] + new int DeleteItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey + ); + + [PreserveSig] + new int DeleteAllItems(); + + [PreserveSig] + new int SetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + int unValue + ); + + [PreserveSig] + new int SetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + long unValue + ); + + [PreserveSig] + new int SetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + double fValue + ); + + [PreserveSig] + new int SetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue + ); + + [PreserveSig] + new int SetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue + ); + + [PreserveSig] + new int SetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, + int cbBufSize + ); + + [PreserveSig] + new int SetUnknown( + [MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown + ); + + [PreserveSig] + new int LockStore(); + + [PreserveSig] + new int UnlockStore(); + + [PreserveSig] + new int GetCount( + out int pcItems + ); + + [PreserveSig] + new int GetItemByIndex( + int unIndex, + out Guid pguidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int CopyAllItems( + [In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest + ); + + #endregion + + [PreserveSig] + int GetStreamIdentifier( + out int pdwStreamIdentifier + ); + + [PreserveSig] + int GetMediaTypeHandler( + [MarshalAs(UnmanagedType.Interface)] out IMFMediaTypeHandler ppMediaTypeHandler + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("E93DCF6C-4B07-4E1E-8123-AA16ED6EADF5"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFMediaTypeHandler + { + [PreserveSig] + int IsMediaTypeSupported( + [In, MarshalAs(UnmanagedType.Interface)] IMFMediaType pMediaType, + IntPtr ppMediaType //[MarshalAs(UnmanagedType.Interface)] out IMFMediaType ppMediaType + ); + + [PreserveSig] + int GetMediaTypeCount( + out int pdwTypeCount + ); + + [PreserveSig] + int GetMediaTypeByIndex( + [In] int dwIndex, + [MarshalAs(UnmanagedType.Interface)] out IMFMediaType ppType + ); + + [PreserveSig] + int SetCurrentMediaType( + [In, MarshalAs(UnmanagedType.Interface)] IMFMediaType pMediaType + ); + + [PreserveSig] + int GetCurrentMediaType( + [MarshalAs(UnmanagedType.Interface)] out IMFMediaType ppMediaType + ); + + [PreserveSig] + int GetMajorType( + out Guid pguidMajorType + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("83CF873A-F6DA-4BC8-823F-BACFD55DC433")] + public interface IMFTopology : IMFAttributes + { + #region IMFAttributes methods + + [PreserveSig] + new int GetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int GetItemType( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out MFAttributeType pType + ); + + [PreserveSig] + new int CompareItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int Compare( + [MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, + MFAttributesMatchType MatchType, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int GetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int punValue + ); + + [PreserveSig] + new int GetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out long punValue + ); + + [PreserveSig] + new int GetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out double pfValue + ); + + [PreserveSig] + new int GetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out Guid pguidValue + ); + + [PreserveSig] + new int GetStringLength( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcchLength + ); + + [PreserveSig] + new int GetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, + int cchBufSize, + out int pcchLength + ); + + [PreserveSig] + new int GetAllocatedString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, + out int pcchLength + ); + + [PreserveSig] + new int GetBlobSize( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcbBlobSize + ); + + [PreserveSig] + new int GetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, + int cbBufSize, + out int pcbBlobSize + ); + + // Use GetBlob instead of this + [PreserveSig] + new int GetAllocatedBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out IntPtr ip, // Read w/Marshal.Copy, Free w/Marshal.FreeCoTaskMem + out int pcbSize + ); + + [PreserveSig] + new int GetUnknown( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.IUnknown)] out object ppv + ); + + [PreserveSig] + new int SetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value + ); + + [PreserveSig] + new int DeleteItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey + ); + + [PreserveSig] + new int DeleteAllItems(); + + [PreserveSig] + new int SetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + int unValue + ); + + [PreserveSig] + new int SetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + long unValue + ); + + [PreserveSig] + new int SetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + double fValue + ); + + [PreserveSig] + new int SetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue + ); + + [PreserveSig] + new int SetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue + ); + + [PreserveSig] + new int SetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, + int cbBufSize + ); + + [PreserveSig] + new int SetUnknown( + [MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown + ); + + [PreserveSig] + new int LockStore(); + + [PreserveSig] + new int UnlockStore(); + + [PreserveSig] + new int GetCount( + out int pcItems + ); + + [PreserveSig] + new int GetItemByIndex( + int unIndex, + out Guid pguidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int CopyAllItems( + [In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest + ); + + #endregion + + [PreserveSig] + int GetTopologyID( + out long pID + ); + + [PreserveSig] + int AddNode( + [In, MarshalAs(UnmanagedType.Interface)] IMFTopologyNode pNode + ); + + [PreserveSig] + int RemoveNode( + [In, MarshalAs(UnmanagedType.Interface)] IMFTopologyNode pNode + ); + + [PreserveSig] + int GetNodeCount( + out short pwNodes + ); + + [PreserveSig] + int GetNode( + [In] short wIndex, + [MarshalAs(UnmanagedType.Interface)] out IMFTopologyNode ppNode + ); + + [PreserveSig] + int Clear(); + + [PreserveSig] + int CloneFrom( + [In, MarshalAs(UnmanagedType.Interface)] IMFTopology pTopology + ); + + [PreserveSig] + int GetNodeByID( + [In] long qwTopoNodeID, + [MarshalAs(UnmanagedType.Interface)] out IMFTopologyNode ppNode + ); + + [PreserveSig] + int GetSourceNodeCollection( + [MarshalAs(UnmanagedType.Interface)] out IMFCollection ppCollection + ); + + [PreserveSig] + int GetOutputNodeCollection( + [MarshalAs(UnmanagedType.Interface)] out IMFCollection ppCollection + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("83CF873A-F6DA-4BC8-823F-BACFD55DC430"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFTopologyNode : IMFAttributes + { + #region IMFAttributes methods + + [PreserveSig] + new int GetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int GetItemType( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out MFAttributeType pType + ); + + [PreserveSig] + new int CompareItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int Compare( + [MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, + MFAttributesMatchType MatchType, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int GetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int punValue + ); + + [PreserveSig] + new int GetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out long punValue + ); + + [PreserveSig] + new int GetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out double pfValue + ); + + [PreserveSig] + new int GetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out Guid pguidValue + ); + + [PreserveSig] + new int GetStringLength( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcchLength + ); + + [PreserveSig] + new int GetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, + int cchBufSize, + out int pcchLength + ); + + [PreserveSig] + new int GetAllocatedString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, + out int pcchLength + ); + + [PreserveSig] + new int GetBlobSize( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcbBlobSize + ); + + [PreserveSig] + new int GetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, + int cbBufSize, + out int pcbBlobSize + ); + + // Use GetBlob instead of this + [PreserveSig] + new int GetAllocatedBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out IntPtr ip, // Read w/Marshal.Copy, Free w/Marshal.FreeCoTaskMem + out int pcbSize + ); + + [PreserveSig] + new int GetUnknown( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.IUnknown)] out object ppv + ); + + [PreserveSig] + new int SetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value + ); + + [PreserveSig] + new int DeleteItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey + ); + + [PreserveSig] + new int DeleteAllItems(); + + [PreserveSig] + new int SetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + int unValue + ); + + [PreserveSig] + new int SetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + long unValue + ); + + [PreserveSig] + new int SetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + double fValue + ); + + [PreserveSig] + new int SetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue + ); + + [PreserveSig] + new int SetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue + ); + + [PreserveSig] + new int SetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, + int cbBufSize + ); + + [PreserveSig] + new int SetUnknown( + [MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown + ); + + [PreserveSig] + new int LockStore(); + + [PreserveSig] + new int UnlockStore(); + + [PreserveSig] + new int GetCount( + out int pcItems + ); + + [PreserveSig] + new int GetItemByIndex( + int unIndex, + out Guid pguidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int CopyAllItems( + [In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest + ); + + #endregion + + [PreserveSig] + int SetObject( + [In, MarshalAs(UnmanagedType.IUnknown)] object pObject + ); + + [PreserveSig] + int GetObject( + [MarshalAs(UnmanagedType.IUnknown)] out object ppObject + ); + + [PreserveSig] + int GetNodeType( + out MFTopologyType pType + ); + + [PreserveSig] + int GetTopoNodeID( + out long pID + ); + + [PreserveSig] + int SetTopoNodeID( + [In] long ullTopoID + ); + + [PreserveSig] + int GetInputCount( + out int pcInputs + ); + + [PreserveSig] + int GetOutputCount( + out int pcOutputs + ); + + [PreserveSig] + int ConnectOutput( + [In] int dwOutputIndex, + [In, MarshalAs(UnmanagedType.Interface)] IMFTopologyNode pDownstreamNode, + [In] int dwInputIndexOnDownstreamNode + ); + + [PreserveSig] + int DisconnectOutput( + [In] int dwOutputIndex + ); + + [PreserveSig] + int GetInput( + [In] int dwInputIndex, + [MarshalAs(UnmanagedType.Interface)] out IMFTopologyNode ppUpstreamNode, + out int pdwOutputIndexOnUpstreamNode + ); + + [PreserveSig] + int GetOutput( + [In] int dwOutputIndex, + [MarshalAs(UnmanagedType.Interface)] out IMFTopologyNode ppDownstreamNode, + out int pdwInputIndexOnDownstreamNode + ); + + [PreserveSig] + int SetOutputPrefType( + [In] int dwOutputIndex, + [In, MarshalAs(UnmanagedType.Interface)] IMFMediaType pType + ); + + [PreserveSig] + int GetOutputPrefType( + [In] int dwOutputIndex, + out IMFMediaType ppType + ); + + [PreserveSig] + int SetInputPrefType( + [In] int dwInputIndex, + [In, MarshalAs(UnmanagedType.Interface)] IMFMediaType pType + ); + + [PreserveSig] + int GetInputPrefType( + [In] int dwInputIndex, + out IMFMediaType ppType + ); + + [PreserveSig] + int CloneFrom( + [In, MarshalAs(UnmanagedType.Interface)] IMFTopologyNode pNode + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("90377834-21D0-4DEE-8214-BA2E3E6C1127"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFMediaSession : IMFMediaEventGenerator + { + #region IMFMediaEventGenerator methods + + [PreserveSig] + new int GetEvent( + [In] MFEventFlag dwFlags, + [MarshalAs(UnmanagedType.Interface)] out IMFMediaEvent ppEvent + ); + + [PreserveSig] + new int BeginGetEvent( + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + [In, MarshalAs(UnmanagedType.IUnknown)] object o); + + [PreserveSig] + new int EndGetEvent( + IMFAsyncResult pResult, + out IMFMediaEvent ppEvent); + + + [PreserveSig] + new int QueueEvent( + [In] MediaEventType met, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidExtendedType, + [In] int hrStatus, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvValue + ); + + #endregion + + [PreserveSig] + int SetTopology( + [In] MFSessionSetTopologyFlags dwSetTopologyFlags, + [In, MarshalAs(UnmanagedType.Interface)] IMFTopology pTopology + ); + + [PreserveSig] + int ClearTopologies(); + + [PreserveSig] + int Start( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid pguidTimeFormat, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvarStartPosition + ); + + [PreserveSig] + int Pause(); + + [PreserveSig] + int Stop(); + + [PreserveSig] + int Close(); + + [PreserveSig] + int Shutdown(); + + [PreserveSig] + int GetClock( + [MarshalAs(UnmanagedType.Interface)] out IMFClock ppClock + ); + + [PreserveSig] + int GetSessionCapabilities( + out MFSessionCapabilities pdwCaps + ); + + [PreserveSig] + int GetFullTopology( + [In] MFSessionGetFullTopologyFlags dwGetFullTopologyFlags, + [In] long TopoId, + [MarshalAs(UnmanagedType.Interface)] out IMFTopology ppFullTopology + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("D182108F-4EC6-443F-AA42-A71106EC825F")] + public interface IMFMediaStream : IMFMediaEventGenerator + { + #region IMFMediaEventGenerator methods + + [PreserveSig] + new int GetEvent( + [In] MFEventFlag dwFlags, + [MarshalAs(UnmanagedType.Interface)] out IMFMediaEvent ppEvent + ); + + [PreserveSig] + new int BeginGetEvent( + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + [In, MarshalAs(UnmanagedType.IUnknown)] object o + ); + + [PreserveSig] + new int EndGetEvent( + IMFAsyncResult pResult, + out IMFMediaEvent ppEvent); + + [PreserveSig] + new int QueueEvent( + [In] MediaEventType met, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidExtendedType, + [In] int hrStatus, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvValue + ); + + #endregion + + [PreserveSig] + int GetMediaSource( + [MarshalAs(UnmanagedType.Interface)] out IMFMediaSource ppMediaSource + ); + + [PreserveSig] + int GetStreamDescriptor( + [MarshalAs(UnmanagedType.Interface)] out IMFStreamDescriptor ppStreamDescriptor + ); + + [PreserveSig] + int RequestSample( + [In, MarshalAs(UnmanagedType.IUnknown)] object pToken + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("FBE5A32D-A497-4B61-BB85-97B1A848A6E3"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFSourceResolver + { + [PreserveSig] + int CreateObjectFromURL( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwszURL, + [In] MFResolution dwFlags, + IPropertyStore pProps, + out MFObjectType pObjectType, + [MarshalAs(UnmanagedType.IUnknown)] out object ppObject + ); + + [PreserveSig] + int CreateObjectFromByteStream( + [In, MarshalAs(UnmanagedType.Interface)] IMFByteStream pByteStream, + [In, MarshalAs(UnmanagedType.LPWStr)] string pwszURL, + [In] MFResolution dwFlags, + [In, MarshalAs(UnmanagedType.Interface)] IPropertyStore pProps, + out MFObjectType pObjectType, + [MarshalAs(UnmanagedType.IUnknown)] out object ppObject + ); + + [PreserveSig] + int BeginCreateObjectFromURL( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwszURL, + MFResolution dwFlags, + IPropertyStore pProps, + [MarshalAs(UnmanagedType.IUnknown)] out object ppIUnknownCancelCookie, + IMFAsyncCallback pCallback, + [In, MarshalAs(UnmanagedType.IUnknown)] object punkState + ); + + [PreserveSig] + int EndCreateObjectFromURL( + IMFAsyncResult pResult, + out MFObjectType pObjectType, + [MarshalAs(UnmanagedType.Interface)] out object ppObject + ); + + [PreserveSig] + int BeginCreateObjectFromByteStream( + [In, MarshalAs(UnmanagedType.Interface)] IMFByteStream pByteStream, + [In, MarshalAs(UnmanagedType.LPWStr)] string pwszURL, + [In] MFResolution dwFlags, + IPropertyStore pProps, + [MarshalAs(UnmanagedType.IUnknown)] out object ppIUnknownCancelCookie, + IMFAsyncCallback pCallback, + [MarshalAs(UnmanagedType.IUnknown)] object punkState + ); + + [PreserveSig] + int EndCreateObjectFromByteStream( + IMFAsyncResult pResult, + out MFObjectType pObjectType, + [MarshalAs(UnmanagedType.IUnknown)] out object ppObject + ); + + [PreserveSig] + int CancelObjectCreation( + [In, MarshalAs(UnmanagedType.IUnknown)] object pIUnknownCancelCookie + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("7FEE9E9A-4A89-47A6-899C-B6A53A70FB67"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFActivate : IMFAttributes + { + #region IMFAttributes methods + + [PreserveSig] + new int GetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int GetItemType( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out MFAttributeType pType + ); + + [PreserveSig] + new int CompareItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int Compare( + [MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, + MFAttributesMatchType MatchType, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int GetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int punValue + ); + + [PreserveSig] + new int GetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out long punValue + ); + + [PreserveSig] + new int GetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out double pfValue + ); + + [PreserveSig] + new int GetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out Guid pguidValue + ); + + [PreserveSig] + new int GetStringLength( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcchLength + ); + + [PreserveSig] + new int GetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, + int cchBufSize, + out int pcchLength + ); + + [PreserveSig] + new int GetAllocatedString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, + out int pcchLength + ); + + [PreserveSig] + new int GetBlobSize( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcbBlobSize + ); + + [PreserveSig] + new int GetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, + int cbBufSize, + out int pcbBlobSize + ); + + // Use GetBlob instead of this + [PreserveSig] + new int GetAllocatedBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out IntPtr ip, // Read w/Marshal.Copy, Free w/Marshal.FreeCoTaskMem + out int pcbSize + ); + + [PreserveSig] + new int GetUnknown( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.IUnknown)] out object ppv + ); + + [PreserveSig] + new int SetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value + ); + + [PreserveSig] + new int DeleteItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey + ); + + [PreserveSig] + new int DeleteAllItems(); + + [PreserveSig] + new int SetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + int unValue + ); + + [PreserveSig] + new int SetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + long unValue + ); + + [PreserveSig] + new int SetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + double fValue + ); + + [PreserveSig] + new int SetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue + ); + + [PreserveSig] + new int SetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue + ); + + [PreserveSig] + new int SetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, + int cbBufSize + ); + + [PreserveSig] + new int SetUnknown( + [MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown + ); + + [PreserveSig] + new int LockStore(); + + [PreserveSig] + new int UnlockStore(); + + [PreserveSig] + new int GetCount( + out int pcItems + ); + + [PreserveSig] + new int GetItemByIndex( + int unIndex, + out Guid pguidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int CopyAllItems( + [In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest + ); + + #endregion + + [PreserveSig] + int ActivateObject( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.Interface)] out object ppv + ); + + [PreserveSig] + int ShutdownObject(); + + [PreserveSig] + int DetachObject(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("FA993888-4383-415A-A930-DD472A8CF6F7")] + public interface IMFGetService + { + [PreserveSig] + int GetService( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidService, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.Interface)] out object ppvObject + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("BB420AA4-765B-4A1F-91FE-D6A8A143924C"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFByteStreamHandler + { + [PreserveSig] + int BeginCreateObject( + [In, MarshalAs(UnmanagedType.Interface)] IMFByteStream pByteStream, + [In, MarshalAs(UnmanagedType.LPWStr)] string pwszURL, + [In] MFResolution dwFlags, + [In, MarshalAs(UnmanagedType.Interface)] IPropertyStore pProps, + [MarshalAs(UnmanagedType.IUnknown)] out object ppIUnknownCancelCookie, + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnkState + ); + + [PreserveSig] + int EndCreateObject( + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncResult pResult, + out MFObjectType pObjectType, + [MarshalAs(UnmanagedType.IUnknown)] out object ppObject + ); + + [PreserveSig] + int CancelObjectCreation( + [In, MarshalAs(UnmanagedType.IUnknown)] object pIUnknownCancelCookie + ); + + [PreserveSig] + int GetMaxNumberOfBytesRequiredForResolution( + out long pqwBytes + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("F6696E82-74F7-4F3D-A178-8A5E09C3659F")] + public interface IMFClockStateSink + { + [PreserveSig] + int OnClockStart( + [In] long hnsSystemTime, + [In] long llClockStartOffset + ); + + [PreserveSig] + int OnClockStop( + [In] long hnsSystemTime + ); + + [PreserveSig] + int OnClockPause( + [In] long hnsSystemTime + ); + + [PreserveSig] + int OnClockRestart( + [In] long hnsSystemTime + ); + + [PreserveSig] + int OnClockSetRate( + [In] long hnsSystemTime, + [In] float flRate + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("2EB1E945-18B8-4139-9B1A-D5D584818530")] + public interface IMFClock + { + [PreserveSig] + int GetClockCharacteristics( + out MFClockCharacteristicsFlags pdwCharacteristics + ); + + [PreserveSig] + int GetCorrelatedTime( + [In] int dwReserved, + out long pllClockTime, + out long phnsSystemTime + ); + + [PreserveSig] + int GetContinuityKey( + out int pdwContinuityKey + ); + + [PreserveSig] + int GetState( + [In] int dwReserved, + out MFClockState peClockState + ); + + [PreserveSig] + int GetProperties( + out MFClockProperties pClockProperties + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("868CE85C-8EA9-4F55-AB82-B009A910A805")] + public interface IMFPresentationClock : IMFClock + { + #region IMFClock methods + + [PreserveSig] + new int GetClockCharacteristics( + out MFClockCharacteristicsFlags pdwCharacteristics + ); + + [PreserveSig] + new int GetCorrelatedTime( + [In] int dwReserved, + out long pllClockTime, + out long phnsSystemTime + ); + + [PreserveSig] + new int GetContinuityKey( + out int pdwContinuityKey + ); + + [PreserveSig] + new int GetState( + [In] int dwReserved, + out MFClockState peClockState + ); + + [PreserveSig] + new int GetProperties( + out MFClockProperties pClockProperties + ); + + #endregion + + [PreserveSig] + int SetTimeSource( + [In, MarshalAs(UnmanagedType.Interface)] IMFPresentationTimeSource pTimeSource + ); + + [PreserveSig] + int GetTimeSource( + [MarshalAs(UnmanagedType.Interface)] out IMFPresentationTimeSource ppTimeSource + ); + + [PreserveSig] + int GetTime( + out long phnsClockTime + ); + + [PreserveSig] + int AddClockStateSink( + [In, MarshalAs(UnmanagedType.Interface)] IMFClockStateSink pStateSink + ); + + [PreserveSig] + int RemoveClockStateSink( + [In, MarshalAs(UnmanagedType.Interface)] IMFClockStateSink pStateSink + ); + + [PreserveSig] + int Start( + [In] long llClockStartOffset + ); + + [PreserveSig] + int Stop(); + + [PreserveSig] + int Pause(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("7FF12CCE-F76F-41C2-863B-1666C8E5E139"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFPresentationTimeSource : IMFClock + { + #region IMFClock methods + + [PreserveSig] + new int GetClockCharacteristics( + out MFClockCharacteristicsFlags pdwCharacteristics + ); + + [PreserveSig] + new int GetCorrelatedTime( + [In] int dwReserved, + out long pllClockTime, + out long phnsSystemTime + ); + + [PreserveSig] + new int GetContinuityKey( + out int pdwContinuityKey + ); + + [PreserveSig] + new int GetState( + [In] int dwReserved, + out MFClockState peClockState + ); + + [PreserveSig] + new int GetProperties( + out MFClockProperties pClockProperties + ); + + #endregion + + [PreserveSig] + int GetUnderlyingClock( + [MarshalAs(UnmanagedType.Interface)] out IMFClock ppClock + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("0E1D6009-C9F3-442D-8C51-A42D2D49452F")] + public interface IMFMediaSourceTopologyProvider + { + [PreserveSig] + int GetMediaSourceTopology( + [In, MarshalAs(UnmanagedType.Interface)] IMFPresentationDescriptor pPresentationDescriptor, + [MarshalAs(UnmanagedType.Interface)] out IMFTopology ppTopology + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("197CD219-19CB-4DE1-A64C-ACF2EDCBE59E"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFSequencerSource + { + [PreserveSig] + int AppendTopology( + [In, MarshalAs(UnmanagedType.Interface)] IMFTopology pTopology, + [In] MFSequencerTopologyFlags dwFlags, + out int pdwId + ); + + [PreserveSig] + int DeleteTopology( + [In] int dwId + ); + + [PreserveSig] + int GetPresentationContext( + [In, MarshalAs(UnmanagedType.Interface)] IMFPresentationDescriptor pPD, + out int pID, + [MarshalAs(UnmanagedType.Interface)] out IMFTopology ppTopology + ); + + [PreserveSig] + int UpdateTopology( + [In] int dwId, + [In, MarshalAs(UnmanagedType.Interface)] IMFTopology pTopology + ); + + [PreserveSig] + int UpdateTopologyFlags( + [In] int dwId, + [In] MFSequencerTopologyFlags dwFlags + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("ACF92459-6A61-42BD-B57C-B43E51203CB0"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFContentProtectionManager + { + [PreserveSig] + int BeginEnableContent( + IMFActivate pEnablerActivate, + IMFTopology pTopo, + IMFAsyncCallback pCallback, + [MarshalAs(UnmanagedType.Interface)] object punkState + ); + + [PreserveSig] + int EndEnableContent( + IMFAsyncResult pResult + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("D3C4EF59-49CE-4381-9071-D5BCD044C770"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFContentEnabler + { + [PreserveSig] + int GetEnableType(out Guid pType); + + [PreserveSig] + int GetEnableURL( + [MarshalAs(UnmanagedType.LPWStr)] out string ppwszURL, + out int pcchURL, + out MFURLTrustStatus pTrustStatus + ); + + [PreserveSig] + int GetEnableData( + [Out] out IntPtr ppbData, + out int pcbData); + + [PreserveSig] + int IsAutomaticSupported( + [MarshalAs(UnmanagedType.Bool)] out bool pfAutomatic + ); + + [PreserveSig] + int AutomaticEnable(); + + [PreserveSig] + int MonitorEnable(); + + [PreserveSig] + int Cancel(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("6EF2A660-47C0-4666-B13D-CBB717F2FA2C"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFMediaSink + { + [PreserveSig] + int GetCharacteristics( + out MFMediaSinkCharacteristics pdwCharacteristics + ); + + [PreserveSig] + int AddStreamSink( + [In] int dwStreamSinkIdentifier, + [In, MarshalAs(UnmanagedType.Interface)] IMFMediaType pMediaType, + [MarshalAs(UnmanagedType.Interface)] out IMFStreamSink ppStreamSink + ); + + [PreserveSig] + int RemoveStreamSink( + [In] int dwStreamSinkIdentifier + ); + + [PreserveSig] + int GetStreamSinkCount( + out int pcStreamSinkCount + ); + + [PreserveSig] + int GetStreamSinkByIndex( + [In] int dwIndex, + [MarshalAs(UnmanagedType.Interface)] out IMFStreamSink ppStreamSink + ); + + [PreserveSig] + int GetStreamSinkById( + [In] int dwStreamSinkIdentifier, + [MarshalAs(UnmanagedType.Interface)] out IMFStreamSink ppStreamSink + ); + + [PreserveSig] + int SetPresentationClock( + [In, MarshalAs(UnmanagedType.Interface)] IMFPresentationClock pPresentationClock + ); + + [PreserveSig] + int GetPresentationClock( + [MarshalAs(UnmanagedType.Interface)] out IMFPresentationClock ppPresentationClock + ); + + [PreserveSig] + int Shutdown(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("0A97B3CF-8E7C-4A3D-8F8C-0C843DC247FB"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFStreamSink : IMFMediaEventGenerator + { + #region IMFMediaEventGenerator methods + + [PreserveSig] + new int GetEvent( + [In] MFEventFlag dwFlags, + [MarshalAs(UnmanagedType.Interface)] out IMFMediaEvent ppEvent + ); + + [PreserveSig] + new int BeginGetEvent( + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + [In, MarshalAs(UnmanagedType.IUnknown)] object o); + + [PreserveSig] + new int EndGetEvent( + IMFAsyncResult pResult, + out IMFMediaEvent ppEvent); + + [PreserveSig] + new int QueueEvent( + [In] MediaEventType met, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidExtendedType, + [In] int hrStatus, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvValue + ); + + #endregion + + [PreserveSig] + int GetMediaSink( + [MarshalAs(UnmanagedType.Interface)] out IMFMediaSink ppMediaSink + ); + + [PreserveSig] + int GetIdentifier( + out int pdwIdentifier + ); + + [PreserveSig] + int GetMediaTypeHandler( + [MarshalAs(UnmanagedType.Interface)] out IMFMediaTypeHandler ppHandler + ); + + [PreserveSig] + int ProcessSample( + [In, MarshalAs(UnmanagedType.Interface)] IMFSample pSample + ); + + [PreserveSig] + int PlaceMarker( + [In] MFStreamSinkMarkerType eMarkerType, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvarMarkerValue, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvarContextValue + ); + + [PreserveSig] + int Flush(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("EAECB74A-9A50-42CE-9541-6A7F57AA4AD7"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFFinalizableMediaSink : IMFMediaSink + { + #region IMFMediaSink methods + + [PreserveSig] + new int GetCharacteristics( + out MFMediaSinkCharacteristics pdwCharacteristics); + + [PreserveSig] + new int AddStreamSink( + [In] int dwStreamSinkIdentifier, + [In, MarshalAs(UnmanagedType.Interface)] IMFMediaType pMediaType, + [MarshalAs(UnmanagedType.Interface)] out IMFStreamSink ppStreamSink + ); + + [PreserveSig] + new int RemoveStreamSink( + [In] int dwStreamSinkIdentifier + ); + + [PreserveSig] + new int GetStreamSinkCount( + out int pcStreamSinkCount + ); + + [PreserveSig] + new int GetStreamSinkByIndex( + [In] int dwIndex, + [MarshalAs(UnmanagedType.Interface)] out IMFStreamSink ppStreamSink + ); + + [PreserveSig] + new int GetStreamSinkById( + [In] int dwStreamSinkIdentifier, + [MarshalAs(UnmanagedType.Interface)] out IMFStreamSink ppStreamSink + ); + + [PreserveSig] + new int SetPresentationClock( + [In, MarshalAs(UnmanagedType.Interface)] IMFPresentationClock pPresentationClock + ); + + [PreserveSig] + new int GetPresentationClock( + [MarshalAs(UnmanagedType.Interface)] out IMFPresentationClock ppPresentationClock + ); + + [PreserveSig] + new int Shutdown(); + + #endregion + + [PreserveSig] + int BeginFinalize( + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnkState + ); + + [PreserveSig] + int EndFinalize( + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncResult pResult + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("0A9CCDBC-D797-4563-9667-94EC5D79292D"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFRateSupport + { + [PreserveSig] + int GetSlowestRate( + [In] MFRateDirection eDirection, + [In, MarshalAs(UnmanagedType.Bool)] bool fThin, + out float pflRate + ); + + [PreserveSig] + int GetFastestRate( + [In] MFRateDirection eDirection, + [In, MarshalAs(UnmanagedType.Bool)] bool fThin, + out float pflRate + ); + + [PreserveSig] + int IsRateSupported( + [In, MarshalAs(UnmanagedType.Bool)] bool fThin, + [In] float flRate, + [In, Out] MfFloat pflNearestSupportedRate + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("059054B3-027C-494C-A27D-9113291CF87F"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFSourceOpenMonitor + { + [PreserveSig] + int OnSourceEvent( + [In, MarshalAs(UnmanagedType.Interface)] IMFMediaEvent pEvent + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("97EC2EA4-0E42-4937-97AC-9D6D328824E1"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFShutdown + { + [PreserveSig] + int Shutdown(); + + [PreserveSig] + int GetShutdownStatus( + out MFShutdownStatus pStatus + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("F88CFB8C-EF16-4991-B450-CB8C69E51704"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFMetadata + { + [PreserveSig] + int SetLanguage( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwszRFC1766 + ); + + [PreserveSig] + int GetLanguage( + [MarshalAs(UnmanagedType.LPWStr)] out string ppwszRFC1766 + ); + + [PreserveSig] + int GetAllLanguages( + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant ppvLanguages + ); + + [PreserveSig] + int SetProperty( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwszName, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant ppvValue + ); + + [PreserveSig] + int GetProperty( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwszName, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant ppvValue + ); + + [PreserveSig] + int DeleteProperty( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwszName + ); + + [PreserveSig] + int GetAllPropertyNames( + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant ppvNames + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("88DDCD21-03C3-4275-91ED-55EE3929328F"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFRateControl + { + [PreserveSig] + int SetRate( + [In, MarshalAs(UnmanagedType.Bool)] bool fThin, + [In] float flRate + ); + + [PreserveSig] + int GetRate( + [In, Out, MarshalAs(UnmanagedType.Bool)] ref bool pfThin, + out float pflRate + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("E56E4CBD-8F70-49D8-A0F8-EDB3D6AB9BF2"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFTimer + { + [PreserveSig] + int SetTimer( + [In] MFTimeFlags dwFlags, + [In] long llClockTime, + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnkState, + [MarshalAs(UnmanagedType.IUnknown)] out object ppunkKey + ); + + [PreserveSig] + int CancelTimer( + [In, MarshalAs(UnmanagedType.IUnknown)] object punkKey + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("56181D2D-E221-4ADB-B1C8-3CEE6A53F76F"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFMetadataProvider + { + [PreserveSig] + int GetMFMetadata( + [In, MarshalAs(UnmanagedType.Interface)] + IMFPresentationDescriptor pPresentationDescriptor, + [In] int dwStreamIdentifier, + [In] int dwFlags, // must be zero + [MarshalAs(UnmanagedType.Interface)] out IMFMetadata ppMFMetadata + ); + } + + #endregion + +} diff --git a/MediaFoundation/MFObjects.cs b/MediaFoundation/MFObjects.cs new file mode 100644 index 0000000..7847d8d --- /dev/null +++ b/MediaFoundation/MFObjects.cs @@ -0,0 +1,2217 @@ +#region license + +/* +MediaFoundationLib - Provide access to MediaFoundation interfaces via .NET +Copyright (C) 2007 +http://mfnet.sourceforge.net + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#endregion + +using System; +using System.Text; +using System.Runtime.InteropServices; + +using MediaFoundation.Misc; +using System.Drawing; + +namespace MediaFoundation +{ + #region Declarations + + [Flags, UnmanagedName("MFVideoFlags")] + public enum MFVideoFlags : long + { + PAD_TO_Mask = 0x0001 | 0x0002, + PAD_TO_None = 0 * 0x0001, + PAD_TO_4x3 = 1 * 0x0001, + PAD_TO_16x9 = 2 * 0x0001, + SrcContentHintMask = 0x0004 | 0x0008 | 0x0010, + SrcContentHintNone = 0 * 0x0004, + SrcContentHint16x9 = 1 * 0x0004, + SrcContentHint235_1 = 2 * 0x0004, + AnalogProtected = 0x0020, + DigitallyProtected = 0x0040, + ProgressiveContent = 0x0080, + FieldRepeatCountMask = 0x0100 | 0x0200 | 0x0400, + FieldRepeatCountShift = 8, + ProgressiveSeqReset = 0x0800, + PanScanEnabled = 0x20000, + LowerFieldFirst = 0x40000, + BottomUpLinearRep = 0x80000, + DXVASurface = 0x100000, + RenderTargetSurface = 0x400000, + ForceQWORD = 0x7FFFFFFF + } + + [UnmanagedName("MFVideoChromaSubsampling")] + public enum MFVideoChromaSubsampling + { + Cosited = 7, + DV_PAL = 6, + ForceDWORD = 0x7fffffff, + Horizontally_Cosited = 4, + Last = 8, + MPEG1 = 1, + MPEG2 = 5, + ProgressiveChroma = 8, + Unknown = 0, + Vertically_AlignedChromaPlanes = 1, + Vertically_Cosited = 2 + } + + [UnmanagedName("MFVideoInterlaceMode")] + public enum MFVideoInterlaceMode + { + FieldInterleavedLowerFirst = 4, + FieldInterleavedUpperFirst = 3, + FieldSingleLower = 6, + FieldSingleUpper = 5, + ForceDWORD = 0x7fffffff, + Last = 8, + MixedInterlaceOrProgressive = 7, + Progressive = 2, + Unknown = 0 + } + + [UnmanagedName("MFVideoTransferFunction")] + public enum MFVideoTransferFunction + { + Unknown = 0, + Func10 = 1, + Func18 = 2, + Func20 = 3, + Func22 = 4, + Func240M = 6, + Func28 = 8, + Func709 = 5, + ForceDWORD = 0x7fffffff, + Last = 9, + sRGB = 7, + Log_100 = 9, + Log_316 = 10, + x709_sym = 11 // symmetric 709 + } + + [UnmanagedName("MFVideoPrimaries")] + public enum MFVideoPrimaries + { + BT470_2_SysBG = 4, + BT470_2_SysM = 3, + BT709 = 2, + EBU3213 = 7, + ForceDWORD = 0x7fffffff, + Last = 9, + reserved = 1, + SMPTE_C = 8, + SMPTE170M = 5, + SMPTE240M = 6, + Unknown = 0 + } + + [UnmanagedName("MFVideoTransferMatrix")] + public enum MFVideoTransferMatrix + { + BT601 = 2, + BT709 = 1, + ForceDWORD = 0x7fffffff, + Last = 4, + SMPTE240M = 3, + Unknown = 0 + } + + [UnmanagedName("MFVideoLighting")] + public enum MFVideoLighting + { + Bright = 1, + Dark = 4, + Dim = 3, + ForceDWORD = 0x7fffffff, + Last = 5, + Office = 2, + Unknown = 0 + } + + [UnmanagedName("MFNominalRange")] + public enum MFNominalRange + { + MFNominalRange_Unknown = 0, + MFNominalRange_Normal = 1, + MFNominalRange_Wide = 2, + + MFNominalRange_0_255 = 1, + MFNominalRange_16_235 = 2, + MFNominalRange_48_208 = 3, + MFNominalRange_64_127 = 4, + + MFNominalRange_Last, + MFNominalRange_ForceDWORD = 0x7fffffff, + } + + [Flags, UnmanagedName("MFBYTESTREAM_SEEK_FLAG_ defines")] + public enum MFByteStreamSeekingFlags + { + None = 0, + CancelPendingIO = 1 + } + + [UnmanagedName("MFBYTESTREAM_SEEK_ORIGIN")] + public enum MFByteStreamSeekOrigin + { + Begin, + Current + } + + [Flags, UnmanagedName("MFBYTESTREAM_* defines")] + public enum MFByteStreamCapabilities + { + None = 0x00000000, + IsReadable = 0x00000001, + IsWritable = 0x00000002, + IsSeekable = 0x00000004, + IsRemote = 0x00000008, + IsDirectory = 0x00000080, + HasSlowSeek = 0x00000100, + IsPartiallyDownloaded = 0x00000200, + ShareWrite = 0x00000400 + } + + [Flags, UnmanagedName("MF_MEDIATYPE_EQUAL_* defines")] + public enum MFMediaEqual + { + None = 0, + MajorTypes = 0x00000001, + FormatTypes = 0x00000002, + FormatData = 0x00000004, + FormatUserData = 0x00000008 + } + + [UnmanagedName("MFASYNC_CALLBACK_QUEUE_ defines")] + public enum MFAsyncCallbackQueue + { + Undefined = 0x00000000, + Standard = 0x00000001, + RT = 0x00000002, + IO = 0x00000003, + Timer = 0x00000004, + LongFunction = 0x00000007, + PrivateMask = unchecked((int)0xFFFF0000), + All = unchecked((int)0xFFFFFFFF) + } + + [Flags, UnmanagedName("MFASYNC_* defines")] + public enum MFASync + { + None = 0, + FastIOProcessingCallback = 0x00000001, + SignalCallback = 0x00000002 + } + + [UnmanagedName("MF_ATTRIBUTES_MATCH_TYPE")] + public enum MFAttributesMatchType + { + OurItems, + TheirItems, + AllItems, + InterSection, + Smaller + } + + [Flags, UnmanagedName("MF_EVENT_FLAG_* defines")] + public enum MFEventFlag + { + None = 0, + NoWait = 0x00000001 + } + + [UnmanagedName("MF_ATTRIBUTE_TYPE")] + public enum MFAttributeType + { + None = 0x0, + Blob = 0x1011, + Double = 0x5, + Guid = 0x48, + IUnknown = 13, + String = 0x1f, + Uint32 = 0x13, + Uint64 = 0x15 + } + + [UnmanagedName("unnamed enum")] + public enum MediaEventType + { + MEUnknown = 0, + MEError = 1, + MEExtendedType = 2, + MENonFatalError = 3, + MEGenericV1Anchor = MENonFatalError, + MESessionUnknown = 100, + MESessionTopologySet = (MESessionUnknown + 1), + MESessionTopologiesCleared = (MESessionTopologySet + 1), + MESessionStarted = (MESessionTopologiesCleared + 1), + MESessionPaused = (MESessionStarted + 1), + MESessionStopped = (MESessionPaused + 1), + MESessionClosed = (MESessionStopped + 1), + MESessionEnded = (MESessionClosed + 1), + MESessionRateChanged = (MESessionEnded + 1), + MESessionScrubSampleComplete = (MESessionRateChanged + 1), + MESessionCapabilitiesChanged = (MESessionScrubSampleComplete + 1), + MESessionTopologyStatus = (MESessionCapabilitiesChanged + 1), + MESessionNotifyPresentationTime = (MESessionTopologyStatus + 1), + MENewPresentation = (MESessionNotifyPresentationTime + 1), + MELicenseAcquisitionStart = (MENewPresentation + 1), + MELicenseAcquisitionCompleted = (MELicenseAcquisitionStart + 1), + MEIndividualizationStart = (MELicenseAcquisitionCompleted + 1), + MEIndividualizationCompleted = (MEIndividualizationStart + 1), + MEEnablerProgress = (MEIndividualizationCompleted + 1), + MEEnablerCompleted = (MEEnablerProgress + 1), + MEPolicyError = (MEEnablerCompleted + 1), + MEPolicyReport = (MEPolicyError + 1), + MEBufferingStarted = (MEPolicyReport + 1), + MEBufferingStopped = (MEBufferingStarted + 1), + MEConnectStart = (MEBufferingStopped + 1), + MEConnectEnd = (MEConnectStart + 1), + MEReconnectStart = (MEConnectEnd + 1), + MEReconnectEnd = (MEReconnectStart + 1), + MERendererEvent = (MEReconnectEnd + 1), + MESessionStreamSinkFormatChanged = (MERendererEvent + 1), + MESessionV1Anchor = MESessionStreamSinkFormatChanged, + MESourceUnknown = 200, + MESourceStarted = (MESourceUnknown + 1), + MEStreamStarted = (MESourceStarted + 1), + MESourceSeeked = (MEStreamStarted + 1), + MEStreamSeeked = (MESourceSeeked + 1), + MENewStream = (MEStreamSeeked + 1), + MEUpdatedStream = (MENewStream + 1), + MESourceStopped = (MEUpdatedStream + 1), + MEStreamStopped = (MESourceStopped + 1), + MESourcePaused = (MEStreamStopped + 1), + MEStreamPaused = (MESourcePaused + 1), + MEEndOfPresentation = (MEStreamPaused + 1), + MEEndOfStream = (MEEndOfPresentation + 1), + MEMediaSample = (MEEndOfStream + 1), + MEStreamTick = (MEMediaSample + 1), + MEStreamThinMode = (MEStreamTick + 1), + MEStreamFormatChanged = (MEStreamThinMode + 1), + MESourceRateChanged = (MEStreamFormatChanged + 1), + MEEndOfPresentationSegment = (MESourceRateChanged + 1), + MESourceCharacteristicsChanged = (MEEndOfPresentationSegment + 1), + MESourceRateChangeRequested = (MESourceCharacteristicsChanged + 1), + MESourceMetadataChanged = (MESourceRateChangeRequested + 1), + MESequencerSourceTopologyUpdated = (MESourceMetadataChanged + 1), + MESourceV1Anchor = MESequencerSourceTopologyUpdated, + MESinkUnknown = 300, + MEStreamSinkStarted = (MESinkUnknown + 1), + MEStreamSinkStopped = (MEStreamSinkStarted + 1), + MEStreamSinkPaused = (MEStreamSinkStopped + 1), + MEStreamSinkRateChanged = (MEStreamSinkPaused + 1), + MEStreamSinkRequestSample = (MEStreamSinkRateChanged + 1), + MEStreamSinkMarker = (MEStreamSinkRequestSample + 1), + MEStreamSinkPrerolled = (MEStreamSinkMarker + 1), + MEStreamSinkScrubSampleComplete = (MEStreamSinkPrerolled + 1), + MEStreamSinkFormatChanged = (MEStreamSinkScrubSampleComplete + 1), + MEStreamSinkDeviceChanged = (MEStreamSinkFormatChanged + 1), + MEQualityNotify = (MEStreamSinkDeviceChanged + 1), + MESinkInvalidated = (MEQualityNotify + 1), + MEAudioSessionNameChanged = (MESinkInvalidated + 1), + MEAudioSessionVolumeChanged = (MEAudioSessionNameChanged + 1), + MEAudioSessionDeviceRemoved = (MEAudioSessionVolumeChanged + 1), + MEAudioSessionServerShutdown = (MEAudioSessionDeviceRemoved + 1), + MEAudioSessionGroupingParamChanged = (MEAudioSessionServerShutdown + 1), + MEAudioSessionIconChanged = (MEAudioSessionGroupingParamChanged + 1), + MEAudioSessionFormatChanged = (MEAudioSessionIconChanged + 1), + MEAudioSessionDisconnected = (MEAudioSessionFormatChanged + 1), + MEAudioSessionExclusiveModeOverride = (MEAudioSessionDisconnected + 1), + MESinkV1Anchor = MEAudioSessionExclusiveModeOverride, + METrustUnknown = 400, + MEPolicyChanged = (METrustUnknown + 1), + MEContentProtectionMessage = (MEPolicyChanged + 1), + MEPolicySet = (MEContentProtectionMessage + 1), + METrustV1Anchor = MEPolicySet, + MEWMDRMLicenseBackupCompleted = 500, + MEWMDRMLicenseBackupProgress = 501, + MEWMDRMLicenseRestoreCompleted = 502, + MEWMDRMLicenseRestoreProgress = 503, + MEWMDRMLicenseAcquisitionCompleted = 506, + MEWMDRMIndividualizationCompleted = 508, + MEWMDRMIndividualizationProgress = 513, + MEWMDRMProximityCompleted = 514, + MEWMDRMLicenseStoreCleaned = 515, + MEWMDRMRevocationDownloadCompleted = 516, + MEWMDRMV1Anchor = MEWMDRMRevocationDownloadCompleted, + METransformUnknown = 600, + METransformNeedInput, + METransformHaveOutput, + METransformDrainComplete, + METransformMarker, + MEReservedMax = 10000 + } + + [UnmanagedName("MF_Plugin_Type")] + public enum MFPluginType + { + MFT = 0, + MediaSource = 1 + } + + [StructLayout(LayoutKind.Sequential, Pack = 8), UnmanagedName("MFVideoCompressedInfo")] + public struct MFVideoCompressedInfo + { + public long AvgBitrate; + public long AvgBitErrorRate; + public int MaxKeyFrameSpacing; + } + + [StructLayout(LayoutKind.Sequential, Pack = 4), UnmanagedName("MFVideoSurfaceInfo")] + public struct MFVideoSurfaceInfo + { + public int Format; + public int PaletteEntries; + public MFPaletteEntry[] Palette; + } + + [StructLayout(LayoutKind.Sequential, Pack = 4), UnmanagedName("MFRatio")] + public struct MFRatio + { + public int Numerator; + public int Denominator; + + public MFRatio(int n, int d) + { + Numerator = n; + Denominator = d; + } + } + + [StructLayout(LayoutKind.Sequential, Pack = 4), UnmanagedName("MFVideoArea")] + public class MFVideoArea + { + public MFOffset OffsetX; + public MFOffset OffsetY; + public Size Area; + + public MFVideoArea() + { + OffsetX = new MFOffset(); + OffsetY = new MFOffset(); + } + + public MFVideoArea(float x, float y, int width, int height) + { + OffsetX = new MFOffset(x); + OffsetY = new MFOffset(y); + Area = new Size(width, height); + } + + public void MakeArea(float x, float y, int width, int height) + { + OffsetX.MakeOffset(x); + OffsetY.MakeOffset(y); + Area.Width = width; + Area.Height = height; + } + } + + [StructLayout(LayoutKind.Sequential, Pack = 2), UnmanagedName("MFOffset")] + public class MFOffset + { + public short fract; + public short Value; + + public MFOffset() + { + } + + public MFOffset(float v) + { + Value = (short)v; + fract = (short)(65536 * (v - Value)); + } + + public void MakeOffset(float v) + { + Value = (short)v; + fract = (short)(65536 * (v-Value)); + } + + public float GetOffset() + { + return ((float)Value) + (((float)fract) / 65536.0f); + } + } + + [StructLayout(LayoutKind.Sequential, Pack = 8), UnmanagedName("MFVideoInfo")] + public struct MFVideoInfo + { + public int dwWidth; + public int dwHeight; + public MFRatio PixelAspectRatio; + public MFVideoChromaSubsampling SourceChromaSubsampling; + public MFVideoInterlaceMode InterlaceMode; + public MFVideoTransferFunction TransferFunction; + public MFVideoPrimaries ColorPrimaries; + public MFVideoTransferMatrix TransferMatrix; + public MFVideoLighting SourceLighting; + public MFRatio FramesPerSecond; + public MFNominalRange NominalRange; + public MFVideoArea GeometricAperture; + public MFVideoArea MinimumDisplayAperture; + public MFVideoArea PanScanAperture; + public MFVideoFlags VideoFlags; + } + + [StructLayout(LayoutKind.Sequential, Pack = 8), UnmanagedName("MFVIDEOFORMAT")] + public class MFVideoFormat + { + public int dwSize; + public MFVideoInfo videoInfo; + public Guid guidFormat; + public MFVideoCompressedInfo compressedInfo; + public MFVideoSurfaceInfo surfaceInfo; + } + + #endregion + + #region Interfaces + +#if ALLOW_UNTESTED_INTERFACES + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("a27003d0-2354-4f2a-8d6a-ab7cff15437e"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFRemoteAsyncCallback + { + [PreserveSig] + int Invoke( + int hr, + [In, MarshalAs(UnmanagedType.IUnknown)] object pRemoteResult + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("26A0ADC3-CE26-4672-9304-69552EDD3FAF"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Obsolete("To get the properties of the audio format, applications should use the media type attributes. If you need to convert the media type into a WAVEFORMATEX structure, call MFCreateWaveFormatExFromMFMediaType")] + public interface IMFAudioMediaType : IMFMediaType + { + #region IMFAttributes methods + + [PreserveSig] + new int GetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int GetItemType( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out MFAttributeType pType + ); + + [PreserveSig] + new int CompareItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int Compare( + [MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, + MFAttributesMatchType MatchType, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int GetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int punValue + ); + + [PreserveSig] + new int GetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out long punValue + ); + + [PreserveSig] + new int GetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out double pfValue + ); + + [PreserveSig] + new int GetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out Guid pguidValue + ); + + [PreserveSig] + new int GetStringLength( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcchLength + ); + + [PreserveSig] + new int GetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, + int cchBufSize, + out int pcchLength + ); + + [PreserveSig] + new int GetAllocatedString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, + out int pcchLength + ); + + [PreserveSig] + new int GetBlobSize( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcbBlobSize + ); + + [PreserveSig] + new int GetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, + int cbBufSize, + out int pcbBlobSize + ); + + // Use GetBlob instead of this + [PreserveSig] + new int GetAllocatedBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out IntPtr ip, // Read w/Marshal.Copy, Free w/Marshal.FreeCoTaskMem + out int pcbSize + ); + + [PreserveSig] + new int GetUnknown( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.IUnknown)] out object ppv + ); + + [PreserveSig] + new int SetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value + ); + + [PreserveSig] + new int DeleteItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey + ); + + [PreserveSig] + new int DeleteAllItems(); + + [PreserveSig] + new int SetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + int unValue + ); + + [PreserveSig] + new int SetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + long unValue + ); + + [PreserveSig] + new int SetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + double fValue + ); + + [PreserveSig] + new int SetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue + ); + + [PreserveSig] + new int SetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue + ); + + [PreserveSig] + new int SetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, + int cbBufSize + ); + + [PreserveSig] + new int SetUnknown( + [MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown + ); + + [PreserveSig] + new int LockStore(); + + [PreserveSig] + new int UnlockStore(); + + [PreserveSig] + new int GetCount( + out int pcItems + ); + + [PreserveSig] + new int GetItemByIndex( + int unIndex, + out Guid pguidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int CopyAllItems( + [In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest + ); + + #endregion + + #region IMFMediaType methods + + [PreserveSig] + new int GetMajorType( + out Guid pguidMajorType + ); + + [PreserveSig] + new int IsCompressedFormat( + [MarshalAs(UnmanagedType.Bool)] out bool pfCompressed + ); + + [PreserveSig] + new int IsEqual( + [In, MarshalAs(UnmanagedType.Interface)] IMFMediaType pIMediaType, + out MFMediaEqual pdwFlags + ); + + [PreserveSig] + new int GetRepresentation( + [In, MarshalAs(UnmanagedType.Struct)] Guid guidRepresentation, + out IntPtr ppvRepresentation + ); + + [PreserveSig] + new int FreeRepresentation( + [In, MarshalAs(UnmanagedType.Struct)] Guid guidRepresentation, + [In] IntPtr pvRepresentation + ); + + #endregion + + [PreserveSig, Obsolete("To get the properties of the audio format, applications should use the media type attributes. If you need to convert the media type into a WAVEFORMATEX structure, call MFCreateWaveFormatExFromMFMediaType")] + IntPtr GetAudioFormat(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("5C6C44BF-1DB6-435B-9249-E8CD10FDEC96")] + public interface IMFPluginControl + { + [PreserveSig] + int GetPreferredClsid( + MFPluginType pluginType, + [MarshalAs(UnmanagedType.LPWStr)] string selector, + out Guid clsid + ); + + [PreserveSig] + int GetPreferredClsidByIndex( + MFPluginType pluginType, + int index, + [MarshalAs(UnmanagedType.LPWStr)] out string selector, + out Guid clsid + ); + + [PreserveSig] + int SetPreferredClsid( + MFPluginType pluginType, + [MarshalAs(UnmanagedType.LPWStr)] string selector, + [MarshalAs(UnmanagedType.LPStruct)] Guid clsid + ); + + [PreserveSig] + int IsDisabled( + MFPluginType pluginType, + [MarshalAs(UnmanagedType.LPStruct)] Guid clsid + ); + + [PreserveSig] + int GetDisabledByIndex( + MFPluginType pluginType, + int index, + out Guid clsid + ); + + [PreserveSig] + int SetDisabled( + MFPluginType pluginType, + [MarshalAs(UnmanagedType.LPStruct)] Guid clsid, + [MarshalAs(UnmanagedType.Bool)] bool disabled + ); + } + +#endif + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("36F846FC-2256-48B6-B58E-E2B638316581"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFMediaEventQueue + { + [PreserveSig] + int GetEvent( + [In] MFEventFlag dwFlags, + [MarshalAs(UnmanagedType.Interface)] out IMFMediaEvent ppEvent + ); + + [PreserveSig] + int BeginGetEvent( + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnkState + ); + + [PreserveSig] + int EndGetEvent( + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncResult pResult, + [MarshalAs(UnmanagedType.Interface)] out IMFMediaEvent ppEvent + ); + + [PreserveSig] + int QueueEvent( + [In, MarshalAs(UnmanagedType.Interface)] IMFMediaEvent pEvent + ); + + [PreserveSig] + int QueueEventParamVar( + [In] MediaEventType met, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidExtendedType, + [In, MarshalAs(UnmanagedType.Error)] int hrStatus, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvValue + ); + + [PreserveSig] + int QueueEventParamUnk( + [In] MediaEventType met, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidExtendedType, + [In, MarshalAs(UnmanagedType.Error)] int hrStatus, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnk + ); + + [PreserveSig] + int Shutdown(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("DF598932-F10C-4E39-BBA2-C308F101DAA3"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFMediaEvent : IMFAttributes + { + #region IMFAttributes methods + + [PreserveSig] + new int GetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int GetItemType( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out MFAttributeType pType + ); + + [PreserveSig] + new int CompareItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int Compare( + [MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, + MFAttributesMatchType MatchType, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int GetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int punValue + ); + + [PreserveSig] + new int GetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out long punValue + ); + + [PreserveSig] + new int GetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out double pfValue + ); + + [PreserveSig] + new int GetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out Guid pguidValue + ); + + [PreserveSig] + new int GetStringLength( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcchLength + ); + + [PreserveSig] + new int GetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, + int cchBufSize, + out int pcchLength + ); + + [PreserveSig] + new int GetAllocatedString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, + out int pcchLength + ); + + [PreserveSig] + new int GetBlobSize( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcbBlobSize + ); + + [PreserveSig] + new int GetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, + int cbBufSize, + out int pcbBlobSize + ); + + // Use GetBlob instead of this + [PreserveSig] + new int GetAllocatedBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out IntPtr ip, // Read w/Marshal.Copy, Free w/Marshal.FreeCoTaskMem + out int pcbSize + ); + + [PreserveSig] + new int GetUnknown( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.IUnknown)] out object ppv + ); + + [PreserveSig] + new int SetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value + ); + + [PreserveSig] + new int DeleteItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey + ); + + [PreserveSig] + new int DeleteAllItems(); + + [PreserveSig] + new int SetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + int unValue + ); + + [PreserveSig] + new int SetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + long unValue + ); + + [PreserveSig] + new int SetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + double fValue + ); + + [PreserveSig] + new int SetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue + ); + + [PreserveSig] + new int SetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue + ); + + [PreserveSig] + new int SetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, + int cbBufSize + ); + + [PreserveSig] + new int SetUnknown( + [MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown + ); + + [PreserveSig] + new int LockStore(); + + [PreserveSig] + new int UnlockStore(); + + [PreserveSig] + new int GetCount( + out int pcItems + ); + + [PreserveSig] + new int GetItemByIndex( + int unIndex, + out Guid pguidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int CopyAllItems( + [In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest + ); + + #endregion + + [PreserveSig] + int GetType( + out MediaEventType pmet + ); + + [PreserveSig] + int GetExtendedType( + out Guid pguidExtendedType + ); + + [PreserveSig] + int GetStatus( + [MarshalAs(UnmanagedType.Error)] out int phrStatus + ); + + [PreserveSig] + int GetValue( + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pvValue + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("2CD2D921-C447-44A7-A13C-4ADABFC247E3"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFAttributes + { + [PreserveSig] + int GetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + int GetItemType( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out MFAttributeType pType + ); + + [PreserveSig] + int CompareItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + int Compare( + [MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, + MFAttributesMatchType MatchType, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + int GetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int punValue + ); + + [PreserveSig] + int GetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out long punValue + ); + + [PreserveSig] + int GetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out double pfValue + ); + + [PreserveSig] + int GetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out Guid pguidValue + ); + + [PreserveSig] + int GetStringLength( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcchLength + ); + + [PreserveSig] + int GetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, + int cchBufSize, + out int pcchLength + ); + + [PreserveSig] + int GetAllocatedString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, + out int pcchLength + ); + + [PreserveSig] + int GetBlobSize( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcbBlobSize + ); + + [PreserveSig] + int GetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, + int cbBufSize, + out int pcbBlobSize + ); + + // Use GetBlob instead of this + [PreserveSig] + int GetAllocatedBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out IntPtr ip, // Read w/Marshal.Copy, Free w/Marshal.FreeCoTaskMem + out int pcbSize + ); + + [PreserveSig] + int GetUnknown( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.IUnknown)] out object ppv + ); + + [PreserveSig] + int SetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value + ); + + [PreserveSig] + int DeleteItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey + ); + + [PreserveSig] + int DeleteAllItems(); + + [PreserveSig] + int SetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + int unValue + ); + + [PreserveSig] + int SetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + long unValue + ); + + [PreserveSig] + int SetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + double fValue + ); + + [PreserveSig] + int SetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue + ); + + [PreserveSig] + int SetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue + ); + + [PreserveSig] + int SetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, + int cbBufSize + ); + + [PreserveSig] + int SetUnknown( + [MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown + ); + + [PreserveSig] + int LockStore(); + + [PreserveSig] + int UnlockStore(); + + [PreserveSig] + int GetCount( + out int pcItems + ); + + [PreserveSig] + int GetItemByIndex( + int unIndex, + out Guid pguidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + int CopyAllItems( + [In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("2CD0BD52-BCD5-4B89-B62C-EADC0C031E7D"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFMediaEventGenerator + { + [PreserveSig] + int GetEvent( + [In] MFEventFlag dwFlags, + [MarshalAs(UnmanagedType.Interface)] out IMFMediaEvent ppEvent + ); + + [PreserveSig] + int BeginGetEvent( + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + + [In, MarshalAs(UnmanagedType.IUnknown)] object o + ); + + [PreserveSig] + int EndGetEvent( + IMFAsyncResult pResult, + + out IMFMediaEvent ppEvent + ); + + [PreserveSig] + int QueueEvent( + [In] MediaEventType met, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidExtendedType, + [In] int hrStatus, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvValue + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("AC6B7889-0740-4D51-8619-905994A55CC6")] + public interface IMFAsyncResult + { + [PreserveSig] + int GetState( + [MarshalAs(UnmanagedType.IUnknown)] out object ppunkState + ); + + [PreserveSig] + int GetStatus(); + + [PreserveSig] + int SetStatus( + [In, MarshalAs(UnmanagedType.Error)] int hrStatus + ); + + [PreserveSig] + int GetObject( + [MarshalAs(UnmanagedType.Interface)] out object ppObject + ); + + [PreserveSig] + IntPtr GetStateNoAddRef(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("A27003CF-2354-4F2A-8D6A-AB7CFF15437E")] + public interface IMFAsyncCallback + { + [PreserveSig] + int GetParameters( + out MFASync pdwFlags, + out MFAsyncCallbackQueue pdwQueue + ); + + [PreserveSig] + int Invoke( + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncResult pAsyncResult + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("44AE0FA8-EA31-4109-8D2E-4CAE4997C555")] + public interface IMFMediaType : IMFAttributes + { + #region IMFAttributes methods + + [PreserveSig] + new int GetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int GetItemType( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out MFAttributeType pType + ); + + [PreserveSig] + new int CompareItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int Compare( + [MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, + MFAttributesMatchType MatchType, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int GetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int punValue + ); + + [PreserveSig] + new int GetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out long punValue + ); + + [PreserveSig] + new int GetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out double pfValue + ); + + [PreserveSig] + new int GetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out Guid pguidValue + ); + + [PreserveSig] + new int GetStringLength( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcchLength + ); + + [PreserveSig] + new int GetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, + int cchBufSize, + out int pcchLength + ); + + [PreserveSig] + new int GetAllocatedString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, + out int pcchLength + ); + + [PreserveSig] + new int GetBlobSize( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcbBlobSize + ); + + [PreserveSig] + new int GetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, + int cbBufSize, + out int pcbBlobSize + ); + + // Use GetBlob instead of this + [PreserveSig] + new int GetAllocatedBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out IntPtr ip, // Read w/Marshal.Copy, Free w/Marshal.FreeCoTaskMem + out int pcbSize + ); + + [PreserveSig] + new int GetUnknown( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.IUnknown)] out object ppv + ); + + [PreserveSig] + new int SetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value + ); + + [PreserveSig] + new int DeleteItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey + ); + + [PreserveSig] + new int DeleteAllItems(); + + [PreserveSig] + new int SetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + int unValue + ); + + [PreserveSig] + new int SetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + long unValue + ); + + [PreserveSig] + new int SetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + double fValue + ); + + [PreserveSig] + new int SetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue + ); + + [PreserveSig] + new int SetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue + ); + + [PreserveSig] + new int SetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, + int cbBufSize + ); + + [PreserveSig] + new int SetUnknown( + [MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown + ); + + [PreserveSig] + new int LockStore(); + + [PreserveSig] + new int UnlockStore(); + + [PreserveSig] + new int GetCount( + out int pcItems + ); + + [PreserveSig] + new int GetItemByIndex( + int unIndex, + out Guid pguidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int CopyAllItems( + [In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest + ); + + #endregion + + [PreserveSig] + int GetMajorType( + out Guid pguidMajorType + ); + + [PreserveSig] + int IsCompressedFormat( + [MarshalAs(UnmanagedType.Bool)] out bool pfCompressed + ); + + [PreserveSig] + int IsEqual( + [In, MarshalAs(UnmanagedType.Interface)] IMFMediaType pIMediaType, + out MFMediaEqual pdwFlags + ); + + [PreserveSig] + int GetRepresentation( + [In, MarshalAs(UnmanagedType.Struct)] Guid guidRepresentation, + out IntPtr ppvRepresentation + ); + + [PreserveSig] + int FreeRepresentation( + [In, MarshalAs(UnmanagedType.Struct)] Guid guidRepresentation, + [In] IntPtr pvRepresentation + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("5BC8A76B-869A-46A3-9B03-FA218A66AEBE")] + public interface IMFCollection + { + [PreserveSig] + int GetElementCount( + out int pcElements + ); + + [PreserveSig] + int GetElement( + [In] int dwElementIndex, + [MarshalAs(UnmanagedType.IUnknown)] out object ppUnkElement + ); + + [PreserveSig] + int AddElement( + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnkElement + ); + + [PreserveSig] + int RemoveElement( + [In] int dwElementIndex, + [MarshalAs(UnmanagedType.IUnknown)] out object ppUnkElement + ); + + [PreserveSig] + int InsertElementAt( + [In] int dwIndex, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown + ); + + [PreserveSig] + int RemoveAllElements(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("AD4C1B00-4BF7-422F-9175-756693D9130D")] + public interface IMFByteStream + { + [PreserveSig] + int GetCapabilities( + out MFByteStreamCapabilities pdwCapabilities + ); + + [PreserveSig] + int GetLength( + out long pqwLength + ); + + [PreserveSig] + int SetLength( + [In] long qwLength + ); + + [PreserveSig] + int GetCurrentPosition( + out long pqwPosition + ); + + [PreserveSig] + int SetCurrentPosition( + [In] long qwPosition + ); + + [PreserveSig] + int IsEndOfStream( + [MarshalAs(UnmanagedType.Bool)] out bool pfEndOfStream + ); + + [PreserveSig] + int Read( + IntPtr pb, + [In] int cb, + out int pcbRead + ); + + [PreserveSig] + int BeginRead( + IntPtr pb, + [In] int cb, + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnkState + ); + + [PreserveSig] + int EndRead( + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncResult pResult, + out int pcbRead + ); + + [PreserveSig] + int Write( + IntPtr pb, + [In] int cb, + out int pcbWritten + ); + + [PreserveSig] + int BeginWrite( + IntPtr pb, + [In] int cb, + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnkState + ); + + [PreserveSig] + int EndWrite( + [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncResult pResult, + out int pcbWritten + ); + + [PreserveSig] + int Seek( + [In] MFByteStreamSeekOrigin SeekOrigin, + [In] long llSeekOffset, + [In] MFByteStreamSeekingFlags dwSeekFlags, + out long pqwCurrentPosition + ); + + [PreserveSig] + int Flush(); + + [PreserveSig] + int Close(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("C40A00F2-B93A-4D80-AE8C-5A1C634F58E4"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFSample : IMFAttributes + { + #region IMFAttributes methods + + [PreserveSig] + new int GetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int GetItemType( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out MFAttributeType pType + ); + + [PreserveSig] + new int CompareItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int Compare( + [MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, + MFAttributesMatchType MatchType, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int GetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int punValue + ); + + [PreserveSig] + new int GetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out long punValue + ); + + [PreserveSig] + new int GetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out double pfValue + ); + + [PreserveSig] + new int GetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out Guid pguidValue + ); + + [PreserveSig] + new int GetStringLength( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcchLength + ); + + [PreserveSig] + new int GetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, + int cchBufSize, + out int pcchLength + ); + + [PreserveSig] + new int GetAllocatedString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, + out int pcchLength + ); + + [PreserveSig] + new int GetBlobSize( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcbBlobSize + ); + + [PreserveSig] + new int GetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, + int cbBufSize, + out int pcbBlobSize + ); + + // Use GetBlob instead of this + [PreserveSig] + new int GetAllocatedBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out IntPtr ip, // Read w/Marshal.Copy, Free w/Marshal.FreeCoTaskMem + out int pcbSize + ); + + [PreserveSig] + new int GetUnknown( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.IUnknown)] out object ppv + ); + + [PreserveSig] + new int SetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value + ); + + [PreserveSig] + new int DeleteItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey + ); + + [PreserveSig] + new int DeleteAllItems(); + + [PreserveSig] + new int SetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + int unValue + ); + + [PreserveSig] + new int SetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + long unValue + ); + + [PreserveSig] + new int SetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + double fValue + ); + + [PreserveSig] + new int SetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue + ); + + [PreserveSig] + new int SetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue + ); + + [PreserveSig] + new int SetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, + int cbBufSize + ); + + [PreserveSig] + new int SetUnknown( + [MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown + ); + + [PreserveSig] + new int LockStore(); + + [PreserveSig] + new int UnlockStore(); + + [PreserveSig] + new int GetCount( + out int pcItems + ); + + [PreserveSig] + new int GetItemByIndex( + int unIndex, + out Guid pguidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int CopyAllItems( + [In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest + ); + + #endregion + + [PreserveSig] + int GetSampleFlags( + out int pdwSampleFlags // Must be zero + ); + + [PreserveSig] + int SetSampleFlags( + [In] int dwSampleFlags // Must be zero + ); + + [PreserveSig] + int GetSampleTime( + out long phnsSampleTime + ); + + [PreserveSig] + int SetSampleTime( + [In] long hnsSampleTime + ); + + [PreserveSig] + int GetSampleDuration( + out long phnsSampleDuration + ); + + [PreserveSig] + int SetSampleDuration( + [In] long hnsSampleDuration + ); + + [PreserveSig] + int GetBufferCount( + out int pdwBufferCount + ); + + [PreserveSig] + int GetBufferByIndex( + [In] int dwIndex, + [MarshalAs(UnmanagedType.Interface)] out IMFMediaBuffer ppBuffer + ); + + [PreserveSig] + int ConvertToContiguousBuffer( + [MarshalAs(UnmanagedType.Interface)] out IMFMediaBuffer ppBuffer + ); + + [PreserveSig] + int AddBuffer( + [In, MarshalAs(UnmanagedType.Interface)] IMFMediaBuffer pBuffer + ); + + [PreserveSig] + int RemoveBufferByIndex( + [In] int dwIndex + ); + + [PreserveSig] + int RemoveAllBuffers(); + + [PreserveSig] + int GetTotalLength( + out int pcbTotalLength + ); + + [PreserveSig] + int CopyToBuffer( + [In, MarshalAs(UnmanagedType.Interface)] IMFMediaBuffer pBuffer + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("045FA593-8799-42B8-BC8D-8968C6453507")] + public interface IMFMediaBuffer + { + [PreserveSig] + int Lock( + out IntPtr ppbBuffer, + out int pcbMaxLength, + out int pcbCurrentLength + ); + + [PreserveSig] + int Unlock(); + + [PreserveSig] + int GetCurrentLength( + out int pcbCurrentLength + ); + + [PreserveSig] + int SetCurrentLength( + [In] int cbCurrentLength + ); + + [PreserveSig] + int GetMaxLength( + out int pcbMaxLength + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("7DC9D5F9-9ED9-44EC-9BBF-0600BB589FBB"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMF2DBuffer + { + [PreserveSig] + int Lock2D( + [Out] out IntPtr pbScanline0, + out int plPitch + ); + + [PreserveSig] + int Unlock2D(); + + [PreserveSig] + int GetScanline0AndPitch( + out IntPtr pbScanline0, + out int plPitch + ); + + [PreserveSig] + int IsContiguousFormat( + [MarshalAs(UnmanagedType.Bool)] out bool pfIsContiguous + ); + + [PreserveSig] + int GetContiguousLength( + out int pcbLength + ); + + [PreserveSig] + int ContiguousCopyTo( + IntPtr pbDestBuffer, + [In] int cbDestBuffer + ); + + [PreserveSig] + int ContiguousCopyFrom( + [In] IntPtr pbSrcBuffer, + [In] int cbSrcBuffer + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + Guid("B99F381F-A8F9-47A2-A5AF-CA3A225A3890"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMFVideoMediaType : IMFMediaType + { + #region IMFAttributes methods + + [PreserveSig] + new int GetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int GetItemType( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out MFAttributeType pType + ); + + [PreserveSig] + new int CompareItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int Compare( + [MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, + MFAttributesMatchType MatchType, + [MarshalAs(UnmanagedType.Bool)] out bool pbResult + ); + + [PreserveSig] + new int GetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int punValue + ); + + [PreserveSig] + new int GetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out long punValue + ); + + [PreserveSig] + new int GetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out double pfValue + ); + + [PreserveSig] + new int GetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out Guid pguidValue + ); + + [PreserveSig] + new int GetStringLength( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcchLength + ); + + [PreserveSig] + new int GetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, + int cchBufSize, + out int pcchLength + ); + + [PreserveSig] + new int GetAllocatedString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, + out int pcchLength + ); + + [PreserveSig] + new int GetBlobSize( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out int pcbBlobSize + ); + + [PreserveSig] + new int GetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, + int cbBufSize, + out int pcbBlobSize + ); + + // Use GetBlob instead of this + [PreserveSig] + new int GetAllocatedBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + out IntPtr ip, // Read w/Marshal.Copy, Free w/Marshal.FreeCoTaskMem + out int pcbSize + ); + + [PreserveSig] + new int GetUnknown( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.IUnknown)] out object ppv + ); + + [PreserveSig] + new int SetItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant Value + ); + + [PreserveSig] + new int DeleteItem( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey + ); + + [PreserveSig] + new int DeleteAllItems(); + + [PreserveSig] + new int SetUINT32( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + int unValue + ); + + [PreserveSig] + new int SetUINT64( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + long unValue + ); + + [PreserveSig] + new int SetDouble( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + double fValue + ); + + [PreserveSig] + new int SetGUID( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue + ); + + [PreserveSig] + new int SetString( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue + ); + + [PreserveSig] + new int SetBlob( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, + int cbBufSize + ); + + [PreserveSig] + new int SetUnknown( + [MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, + [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown + ); + + [PreserveSig] + new int LockStore(); + + [PreserveSig] + new int UnlockStore(); + + [PreserveSig] + new int GetCount( + out int pcItems + ); + + [PreserveSig] + new int GetItemByIndex( + int unIndex, + out Guid pguidKey, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + new int CopyAllItems( + [In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest + ); + + #endregion + + #region IMFMediaType methods + + [PreserveSig] + new int GetMajorType( + out Guid pguidMajorType + ); + + [PreserveSig] + new int IsCompressedFormat( + [MarshalAs(UnmanagedType.Bool)] out bool pfCompressed + ); + + [PreserveSig] + new int IsEqual( + [In, MarshalAs(UnmanagedType.Interface)] IMFMediaType pIMediaType, + out MFMediaEqual pdwFlags + ); + + [PreserveSig] + new int GetRepresentation( + [In, MarshalAs(UnmanagedType.Struct)] Guid guidRepresentation, + out IntPtr ppvRepresentation + ); + + [PreserveSig] + new int FreeRepresentation( + [In, MarshalAs(UnmanagedType.Struct)] Guid guidRepresentation, + [In] IntPtr pvRepresentation + ); + + #endregion + + [PreserveSig, Obsolete("This method is deprecated by MS")] + MFVideoFormat GetVideoFormat(); + + [Obsolete("This method is deprecated by MS")] + [PreserveSig] + int GetVideoRepresentation( + [In, MarshalAs(UnmanagedType.Struct)] Guid guidRepresentation, + out IntPtr ppvRepresentation, + [In] int lStride + ); + } + + #endregion +} diff --git a/MediaFoundation/MFPlay.cs b/MediaFoundation/MFPlay.cs new file mode 100644 index 0000000..087cc2d --- /dev/null +++ b/MediaFoundation/MFPlay.cs @@ -0,0 +1,638 @@ +#region license + +/* +MediaFoundationLib - Provide access to MediaFoundation interfaces via .NET +Copyright (C) 2007 +http://mfnet.sourceforge.net + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#endregion + +using System; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.ComTypes; +using System.Security; + +using MediaFoundation.Misc; +using System.Drawing; + +using MediaFoundation.EVR; + +namespace MediaFoundation.MFPlayer +{ + #region Declarations + +#if ALLOW_UNTESTED_INTERFACES + + [Flags, UnmanagedName("MFP_CREATION_OPTIONS")] + public enum MFP_CREATION_OPTIONS + { + None = 0x00000000, + FreeThreadedCallback = 0x00000001, + NoMMCSS = 0x00000002, + NoRemoteDesktopOptimization = 0x00000004 + } + + [UnmanagedName("MFP_MEDIAPLAYER_STATE")] + public enum MFP_MEDIAPLAYER_STATE + { + Empty = 0x00000000, + Stopped = 0x00000001, + Playing = 0x00000002, + Paused = 0x00000003, + Shutdown = 0x00000004 + } + + [Flags, UnmanagedName("MFP_MEDIAITEM_CHARACTERISTICS")] + public enum MFP_MEDIAITEM_CHARACTERISTICS + { + None = 0x00000000, + IsLive = 0x00000001, + CanSeek = 0x00000002, + CanPause = 0x00000004, + HasSlowSeek = 0x00000008 + } + + [Flags, UnmanagedName("MFP_CREDENTIAL_FLAGS")] + public enum MFP_CREDENTIAL_FLAGS + { + None = 0x00000000, + Prompt = 0x00000001, + Save = 0x00000002, + DoNotCache = 0x00000004, + ClearText = 0x00000008, + Proxy = 0x00000010, + LoggedOnUser = 0x00000020 + } + + [UnmanagedName("MFP_EVENT_TYPE")] + public enum MFP_EVENT_TYPE + { + Play = 0, + Pause = 1, + Stop = 2, + PositionSet = 3, + RateSet = 4, + MediaItemCreated = 5, + MediaItemSet = 6, + FrameStep = 7, + MediaItemCleared = 8, + MF = 9, + Error = 10, + PlaybackEnded = 11, + AcquireUserCredential = 12 + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MFP_EVENT_HEADER")] + public class MFP_EVENT_HEADER + { + public MFP_EVENT_TYPE eEventType; + public int hrEvent; + public IMFPMediaPlayer pMediaPlayer; + public MFP_MEDIAPLAYER_STATE eState; + public IPropertyStore pPropertyStore; + + public IntPtr GetPtr() + { + IntPtr ip; + + int iSize = Marshal.SizeOf(this); + + ip = Marshal.AllocCoTaskMem(iSize); + Marshal.StructureToPtr(this, ip, false); + + return ip; + } + + public static MFP_EVENT_HEADER PtrToEH(IntPtr pNativeData) + { + MFP_EVENT_TYPE met = (MFP_EVENT_TYPE)Marshal.ReadInt32(pNativeData); + object mce; + + switch (met) + { + case MFP_EVENT_TYPE.Play: + mce = Marshal.PtrToStructure(pNativeData, typeof(MFP_PLAY_EVENT)); + break; + case MFP_EVENT_TYPE.Pause: + mce = Marshal.PtrToStructure(pNativeData, typeof(MFP_PAUSE_EVENT)); + break; + case MFP_EVENT_TYPE.Stop: + mce = Marshal.PtrToStructure(pNativeData, typeof(MFP_STOP_EVENT)); + break; + case MFP_EVENT_TYPE.PositionSet: + mce = Marshal.PtrToStructure(pNativeData, typeof(MFP_POSITION_SET_EVENT)); + break; + case MFP_EVENT_TYPE.RateSet: + mce = Marshal.PtrToStructure(pNativeData, typeof(MFP_RATE_SET_EVENT)); + break; + case MFP_EVENT_TYPE.MediaItemCreated: + mce = Marshal.PtrToStructure(pNativeData, typeof(MFP_MEDIAITEM_CREATED_EVENT)); + break; + case MFP_EVENT_TYPE.MediaItemSet: + mce = Marshal.PtrToStructure(pNativeData, typeof(MFP_RATE_SET_EVENT)); + break; + case MFP_EVENT_TYPE.FrameStep: + mce = Marshal.PtrToStructure(pNativeData, typeof(MFP_FRAME_STEP_EVENT)); + break; + case MFP_EVENT_TYPE.MediaItemCleared: + mce = Marshal.PtrToStructure(pNativeData, typeof(MFP_MEDIAITEM_CLEARED_EVENT)); + break; + case MFP_EVENT_TYPE.MF: + mce = Marshal.PtrToStructure(pNativeData, typeof(MFP_MF_EVENT)); + break; + case MFP_EVENT_TYPE.Error: + mce = Marshal.PtrToStructure(pNativeData, typeof(MFP_ERROR_EVENT)); + break; + case MFP_EVENT_TYPE.PlaybackEnded: + mce = Marshal.PtrToStructure(pNativeData, typeof(MFP_PLAYBACK_ENDED_EVENT)); + break; + case MFP_EVENT_TYPE.AcquireUserCredential: + mce = Marshal.PtrToStructure(pNativeData, typeof(MFP_ACQUIRE_USER_CREDENTIAL_EVENT)); + break; + default: + // Don't know what it is. Send back the header. + mce = Marshal.PtrToStructure(pNativeData, typeof(MFP_EVENT_HEADER)); + break; + } + + return mce as MFP_EVENT_HEADER; + } + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MFP_PLAY_EVENT")] + public class MFP_PLAY_EVENT : MFP_EVENT_HEADER + { + public IMFPMediaItem pMediaItem; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MFP_PAUSE_EVENT")] + public class MFP_PAUSE_EVENT : MFP_EVENT_HEADER + { + public IMFPMediaItem pMediaItem; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MFP_STOP_EVENT")] + public class MFP_STOP_EVENT : MFP_EVENT_HEADER + { + public IMFPMediaItem pMediaItem; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MFP_POSITION_SET_EVENT")] + public class MFP_POSITION_SET_EVENT : MFP_EVENT_HEADER + { + public IMFPMediaItem pMediaItem; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MFP_RATE_SET_EVENT")] + public class MFP_RATE_SET_EVENT : MFP_EVENT_HEADER + { + public IMFPMediaItem pMediaItem; + public float flRate; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MFP_MEDIAITEM_CREATED_EVENT")] + public class MFP_MEDIAITEM_CREATED_EVENT : MFP_EVENT_HEADER + { + public IMFPMediaItem pMediaItem; + public IntPtr dwUserData; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MFP_MEDIAITEM_SET_EVENT")] + public class MFP_MEDIAITEM_SET_EVENT : MFP_EVENT_HEADER + { + public IMFPMediaItem pMediaItem; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MFP_FRAME_STEP_EVENT")] + public class MFP_FRAME_STEP_EVENT : MFP_EVENT_HEADER + { + public IMFPMediaItem pMediaItem; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MFP_MEDIAITEM_CLEARED_EVENT")] + public class MFP_MEDIAITEM_CLEARED_EVENT : MFP_EVENT_HEADER + { + public IMFPMediaItem pMediaItem; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MFP_MF_EVENT")] + public class MFP_MF_EVENT : MFP_EVENT_HEADER + { + public MediaEventType MFEventType; + public IMFMediaEvent pMFMediaEvent; + public IMFPMediaItem pMediaItem; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MFP_ERROR_EVENT")] + public class MFP_ERROR_EVENT : MFP_EVENT_HEADER + { + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MFP_PLAYBACK_ENDED_EVENT")] + public class MFP_PLAYBACK_ENDED_EVENT : MFP_EVENT_HEADER + { + public IMFPMediaItem pMediaItem; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MFP_ACQUIRE_USER_CREDENTIAL_EVENT")] + public class MFP_ACQUIRE_USER_CREDENTIAL_EVENT : MFP_EVENT_HEADER + { + public IntPtr dwUserData; + [MarshalAs(UnmanagedType.Bool)] + public bool fProceedWithAuthentication; + public int hrAuthenticationStatus; + [MarshalAs(UnmanagedType.LPWStr)] + public string pwszURL; + [MarshalAs(UnmanagedType.LPWStr)] + public string pwszSite; + [MarshalAs(UnmanagedType.LPWStr)] + public string pwszRealm; + [MarshalAs(UnmanagedType.LPWStr)] + public string pwszPackage; + public int nRetries; + public MFP_CREDENTIAL_FLAGS flags; + public IMFNetCredential pCredential; + } + +#endif + + #endregion + + #region Interfaces + +#if ALLOW_UNTESTED_INTERFACES + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("A714590A-58AF-430a-85BF-44F5EC838D85")] + public interface IMFPMediaPlayer + { + [PreserveSig] + int Play(); + + [PreserveSig] + int Pause(); + + [PreserveSig] + int Stop(); + + [PreserveSig] + int FrameStep(); + + [PreserveSig] + int SetPosition( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidPositionType, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvPositionValue + ); + + [PreserveSig] + int GetPosition( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidPositionType, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pvPositionValue + ); + + [PreserveSig] + int GetDuration( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidPositionType, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pvPositionValue + ); + + [PreserveSig] + int SetRate( + float flRate + ); + + [PreserveSig] + int GetRate( + out float pflRate + ); + + [PreserveSig] + int GetSupportedRates( + [MarshalAs(UnmanagedType.Bool)] bool fForwardDirection, + out float pflSlowestRate, + out float pflFastestRate + ); + + [PreserveSig] + int GetState( + out MFP_MEDIAPLAYER_STATE peState + ); + + [PreserveSig] + int CreateMediaItemFromURL( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwszURL, + [MarshalAs(UnmanagedType.Bool)] bool fSync, + IntPtr dwUserData, + out IMFPMediaItem ppMediaItem + ); + + [PreserveSig] + int CreateMediaItemFromObject( + [MarshalAs(UnmanagedType.IUnknown)] object pIUnknownObj, + [MarshalAs(UnmanagedType.Bool)] bool fSync, + IntPtr dwUserData, + out IMFPMediaItem ppMediaItem + ); + + [PreserveSig] + int SetMediaItem( + IMFPMediaItem pIMFPMediaItem + ); + + [PreserveSig] + int ClearMediaItem(); + + [PreserveSig] + int GetMediaItem( + out IMFPMediaItem ppIMFPMediaItem + ); + + [PreserveSig] + int GetVolume( + out float pflVolume + ); + + [PreserveSig] + int SetVolume( + float flVolume + ); + + [PreserveSig] + int GetBalance( + out float pflBalance + ); + + [PreserveSig] + int SetBalance( + float flBalance + ); + + [PreserveSig] + int GetMute( + [MarshalAs(UnmanagedType.Bool)] out bool pfMute + ); + + [PreserveSig] + int SetMute( + [MarshalAs(UnmanagedType.Bool)] bool fMute + ); + + [PreserveSig] + int GetNativeVideoSize( + out Size pszVideo, + out Size pszARVideo + ); + + [PreserveSig] + int GetIdealVideoSize( + out Size pszMin, + out Size pszMax + ); + + [PreserveSig] + int SetVideoSourceRect( + [In] MFVideoNormalizedRect pnrcSource + ); + + [PreserveSig] + int GetVideoSourceRect( + out MFVideoNormalizedRect pnrcSource + ); + + [PreserveSig] + int SetAspectRatioMode( + MFVideoAspectRatioMode dwAspectRatioMode + ); + + [PreserveSig] + int GetAspectRatioMode( + out MFVideoAspectRatioMode pdwAspectRatioMode + ); + + [PreserveSig] + int GetVideoWindow( + out IntPtr phwndVideo + ); + + [PreserveSig] + int UpdateVideo(); + + [PreserveSig] + int SetBorderColor( + Color Clr + ); + + [PreserveSig] + int GetBorderColor( + out Color pClr + ); + + [PreserveSig] + int InsertEffect( + [MarshalAs(UnmanagedType.IUnknown)] object pEffect, + [MarshalAs(UnmanagedType.Bool)] bool fOptional + ); + + [PreserveSig] + int RemoveEffect( + [MarshalAs(UnmanagedType.IUnknown)] object pEffect + ); + + [PreserveSig] + int RemoveAllEffects(); + + [PreserveSig] + int Shutdown(); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("90EB3E6B-ECBF-45cc-B1DA-C6FE3EA70D57")] + public interface IMFPMediaItem + { + [PreserveSig] + int GetMediaPlayer( + out IMFPMediaPlayer ppMediaPlayer + ); + + [PreserveSig] + int GetURL( + [MarshalAs(UnmanagedType.LPWStr)] out string ppwszURL + ); + + [PreserveSig] + int GetObject( + [MarshalAs(UnmanagedType.IUnknown)] out object ppIUnknown + ); + + [PreserveSig] + int GetUserData( + out IntPtr pdwUserData + ); + + [PreserveSig] + int SetUserData( + IntPtr dwUserData + ); + + [PreserveSig] + int GetStartStopPosition( + out Guid pguidStartPositionType, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pvStartValue, + out Guid pguidStopPositionType, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pvStopValue + ); + + [PreserveSig] + int SetStartStopPosition( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid pguidStartPositionType, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvStartValue, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid pguidStopPositionType, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvStopValue + ); + + [PreserveSig] + int HasVideo( + [MarshalAs(UnmanagedType.Bool)] out bool pfHasVideo, + [MarshalAs(UnmanagedType.Bool)] out bool pfSelected + ); + + [PreserveSig] + int HasAudio( + [MarshalAs(UnmanagedType.Bool)] out bool pfHasAudio, + [MarshalAs(UnmanagedType.Bool)] out bool pfSelected + ); + + [PreserveSig] + int IsProtected( + [MarshalAs(UnmanagedType.Bool)] out bool pfProtected + ); + + [PreserveSig] + int GetDuration( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidPositionType, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pvDurationValue + ); + + [PreserveSig] + int GetNumberOfStreams( + out int pdwStreamCount + ); + + [PreserveSig] + int GetStreamSelection( + int dwStreamIndex, + [MarshalAs(UnmanagedType.Bool)] out bool pfEnabled + ); + + [PreserveSig] + int SetStreamSelection( + int dwStreamIndex, + [MarshalAs(UnmanagedType.Bool)] bool fEnabled + ); + + [PreserveSig] + int GetStreamAttribute( + int dwStreamIndex, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidMFAttribute, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pvValue + ); + + [PreserveSig] + int GetPresentationAttribute( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidMFAttribute, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pvValue + ); + + [PreserveSig] + int GetCharacteristics( + out MFP_MEDIAITEM_CHARACTERISTICS pCharacteristics + ); + + [PreserveSig] + int SetStreamSink( + int dwStreamIndex, + [MarshalAs(UnmanagedType.IUnknown)] object pMediaSink + ); + + [PreserveSig] + int GetMetadata( + out IPropertyStore ppMetadataStore + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("766C8FFB-5FDB-4fea-A28D-B912996F51BD")] + public interface IMFPMediaPlayerCallback + { + [PreserveSig] + int OnMediaPlayerEvent( + [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(EHMarshaler))] MFP_EVENT_HEADER pEventHeader + ); + } + + internal class EHMarshaler : ICustomMarshaler + { + public IntPtr MarshalManagedToNative(object managedObj) + { + MFP_EVENT_HEADER eh = managedObj as MFP_EVENT_HEADER; + + IntPtr ip = eh.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) + { + MFP_EVENT_HEADER eh = MFP_EVENT_HEADER.PtrToEH(pNativeData); + + return eh; + } + + // It appears this routine is never called + public void CleanUpManagedData(object ManagedObj) + { + } + + public void CleanUpNativeData(IntPtr pNativeData) + { + Marshal.FreeCoTaskMem(pNativeData); + } + + // The number of bytes to marshal out - never called + public int GetNativeDataSize() + { + return -1; + } + + // 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 EHMarshaler(); + } + } + +#endif + + #endregion +} diff --git a/MediaFoundation/MFReadWrite.cs b/MediaFoundation/MFReadWrite.cs new file mode 100644 index 0000000..ea123dd --- /dev/null +++ b/MediaFoundation/MFReadWrite.cs @@ -0,0 +1,335 @@ +#region license + +/* +MediaFoundationLib - Provide access to MediaFoundation interfaces via .NET +Copyright (C) 2007 +http://mfnet.sourceforge.net + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#endregion + +using System; +using System.Text; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.ComTypes; +using System.Security; + +using MediaFoundation.Misc; +using System.Drawing; + +using MediaFoundation.EVR; + +namespace MediaFoundation.ReadWrite +{ + #region COM Class Objects + + [UnmanagedName("CLSID_MFReadWriteClassFactory"), + ComImport, + Guid("48e2ed0f-98c2-4a37-bed5-166312ddd83f")] + public class MFReadWriteClassFactory + { + } + + #endregion + + #region Declarations + +#if ALLOW_UNTESTED_INTERFACES + + [UnmanagedName("Unnamed enum")] + public enum MF_SINK_WRITER + { + InvalidStreamIndex = unchecked((int)0xFFFFFFFF), + AllStreams = unchecked((int)0xFFFFFFFE), + MediaSink = unchecked((int)0xFFFFFFFF) + } + + [Flags, UnmanagedName("MF_SOURCE_READER_FLAG")] + public enum MF_SOURCE_READER_FLAG + { + Error = 0x00000001, + EndOfStream = 0x00000002, + NewStream = 0x00000004, + NativeMediaTypeChanged = 0x00000010, + CurrentMediaTypeChanged = 0x00000020, + StreamTick = 0x00000100 + } + + [UnmanagedName("Unnamed enum")] + public enum MF_SOURCE_READER + { + InvalidStreamIndex = unchecked((int)0xFFFFFFFF), + AllStreams = unchecked((int)0xFFFFFFFE), + AnyStream = unchecked((int)0xFFFFFFFE), + FirstAudioStream = unchecked((int)0xFFFFFFFD), + FirstVideoStream = unchecked((int)0xFFFFFFFC), + MediaSource = unchecked((int)0xFFFFFFFF), + } + + [UnmanagedName("MF_SOURCE_READER_CONTROL_FLAG")] + public enum MF_SOURCE_READER_CONTROL_FLAG + { + None = 0, + Drain = 0x00000001 + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MF_SINK_WRITER_STATISTICS")] + public class MF_SINK_WRITER_STATISTICS + { + int cb; + + long llLastTimestampReceived; + long llLastTimestampEncoded; + long llLastTimestampProcessed; + long llLastStreamTickReceived; + long llLastSinkSampleRequest; + + long qwNumSamplesReceived; + long qwNumSamplesEncoded; + long qwNumSamplesProcessed; + long qwNumStreamTicksReceived; + + int dwByteCountQueued; + long qwByteCountProcessed; + + int dwNumOutstandingSinkSampleRequests; + + int dwAverageSampleRateReceived; + int dwAverageSampleRateEncoded; + int dwAverageSampleRateProcessed; + } + +#endif + + #endregion + + #region Interfaces + +#if ALLOW_UNTESTED_INTERFACES + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("E7FE2E12-661C-40DA-92F9-4F002AB67627")] + public interface IMFReadWriteClassFactory + { + [PreserveSig] + int CreateInstanceFromURL( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid clsid, + [In, MarshalAs(UnmanagedType.LPWStr)] string pwszURL, + IMFAttributes pAttributes, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.IUnknown)] out object ppvObject + ); + + [PreserveSig] + int CreateInstanceFromObject( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid clsid, + [MarshalAs(UnmanagedType.IUnknown)] object punkObject, + IMFAttributes pAttributes, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.IUnknown)] out object ppvObject + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("70ae66f2-c809-4e4f-8915-bdcb406b7993")] + public interface IMFSourceReader + { + [PreserveSig] + int GetStreamSelection( + int dwStreamIndex, + [MarshalAs(UnmanagedType.Bool)] out bool pfSelected + ); + + [PreserveSig] + int SetStreamSelection( + int dwStreamIndex, + bool fSelected + ); + + [PreserveSig] + int GetNativeMediaType( + int dwStreamIndex, + int dwMediaTypeIndex, + out IMFMediaType ppMediaType + ); + + [PreserveSig] + int GetCurrentMediaType( + int dwStreamIndex, + out IMFMediaType ppMediaType + ); + + [PreserveSig] + int SetCurrentMediaType( + int dwStreamIndex, + ref int pdwReserved, + IMFMediaType pMediaType + ); + + [PreserveSig] + int SetCurrentPosition( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidTimeFormat, + [In] PropVariant varPosition + ); + + [PreserveSig] + int ReadSample( + int dwStreamIndex, + int dwControlFlags, + out int pdwActualStreamIndex, + out int pdwStreamFlags, + out long pllTimestamp, + out IMFSample ppSample + ); + + [PreserveSig] + int Flush( + int dwStreamIndex + ); + + [PreserveSig] + int GetServiceForStream( + int dwStreamIndex, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidService, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.IUnknown)] out object ppvObject + ); + + [PreserveSig] + int GetPresentationAttribute( + int dwStreamIndex, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidAttribute, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pvarAttribute + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("deec8d99-fa1d-4d82-84c2-2c8969944867")] + public interface IMFSourceReaderCallback + { + [PreserveSig] + int OnReadSample( + int hrStatus, + int dwStreamIndex, + MF_SOURCE_READER_FLAG dwStreamFlags, + long llTimestamp, + IMFSample pSample + ); + + [PreserveSig] + int OnFlush( + int dwStreamIndex + ); + + [PreserveSig] + int OnEvent( + int dwStreamIndex, + IMFMediaEvent pEvent + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("3137f1cd-fe5e-4805-a5d8-fb477448cb3d")] + public interface IMFSinkWriter + { + [PreserveSig] + int AddStream( + IMFMediaType pTargetMediaType, + out int pdwStreamIndex + ); + + [PreserveSig] + int SetInputMediaType( + int dwStreamIndex, + IMFMediaType pInputMediaType, + IMFAttributes pEncodingParameters + ); + + [PreserveSig] + int BeginWriting(); + + [PreserveSig] + int WriteSample( + int dwStreamIndex, + IMFSample pSample + ); + + [PreserveSig] + int SendStreamTick( + int dwStreamIndex, + long llTimestamp + ); + + [PreserveSig] + int PlaceMarker( + int dwStreamIndex, + IntPtr pvContext + ); + + [PreserveSig] + int NotifyEndOfSegment( + int dwStreamIndex + ); + + [PreserveSig] + int Flush( + int dwStreamIndex + ); + + [PreserveSig] + int Finalize_(); + + [PreserveSig] + int GetServiceForStream( + int dwStreamIndex, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidService, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, + [MarshalAs(UnmanagedType.IUnknown)] out object ppvObject + ); + + [PreserveSig] + int GetStatistics( + int dwStreamIndex, + out MF_SINK_WRITER_STATISTICS pStats + ); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("666f76de-33d2-41b9-a458-29ed0a972c58")] + public interface IMFSinkWriterCallback + { + [PreserveSig] + int OnFinalize( + int hrStatus + ); + + [PreserveSig] + int OnMarker( + int dwStreamIndex, + IntPtr pvContext + ); + } + +#endif + + #endregion +} diff --git a/MediaFoundation/MFTransform.cs b/MediaFoundation/MFTransform.cs new file mode 100644 index 0000000..38d8c85 --- /dev/null +++ b/MediaFoundation/MFTransform.cs @@ -0,0 +1,375 @@ +#region license + +/* +MediaFoundationLib - Provide access to MediaFoundation interfaces via .NET +Copyright (C) 2007 +http://mfnet.sourceforge.net + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#endregion + +using System; +using System.Runtime.InteropServices; + +using MediaFoundation.Misc; + +namespace MediaFoundation.Transform +{ + #region Declarations + +#if ALLOW_UNTESTED_INTERFACES + + [StructLayout(LayoutKind.Sequential), UnmanagedName("STREAM_MEDIUM")] + public struct STREAM_MEDIUM + { + Guid gidMedium; + int unMediumInstance; + } + + [Flags, UnmanagedName("MFT_ENUM_FLAG")] + public enum MFT_EnumFlag + { + None = 0x00000000, + SyncMFT = 0x00000001, // Enumerates V1 MFTs. This is default. + AsyncMFT = 0x00000002, // Enumerates only software async MFTs also known as V2 MFTs + Hardware = 0x00000004, // Enumerates V2 hardware async MFTs + FieldOfUse = 0x00000008, // Enumerates MFTs that require unlocking + LocalMFT = 0x00000010, // Enumerates Locally (in-process) registered MFTs + TranscodeOnly = 0x00000020, // Enumerates decoder MFTs used by transcode only + SortAndFilter = 0x00000040, // Apply system local, do not use and preferred sorting and filtering + All = 0x0000003F // Enumerates all MFTs including SW and HW MFTs and applies filtering + } + +#endif + + [UnmanagedName("_MFT_DRAIN_TYPE")] + public enum MFTDrainType + { + ProduceTails = 0x00000000, + NoTails = 0x00000001 + } + + [Flags, UnmanagedName("_MFT_PROCESS_OUTPUT_FLAGS")] + public enum MFTProcessOutputFlags + { + None = 0, + DiscardWhenNoBuffer = 0x00000001 + } + + [Flags, UnmanagedName("_MFT_OUTPUT_STATUS_FLAGS")] + public enum MFTOutputStatusFlags + { + None = 0, + SampleReady = 0x00000001 + } + + [Flags, UnmanagedName("_MFT_INPUT_STATUS_FLAGS")] + public enum MFTInputStatusFlags + { + None = 0, + AcceptData = 0x00000001 + } + + [Flags, UnmanagedName("_MFT_SET_TYPE_FLAGS")] + public enum MFTSetTypeFlags + { + None = 0, + TestOnly = 0x00000001 + } + + [Flags, UnmanagedName("_MFT_OUTPUT_STREAM_INFO_FLAGS")] + public enum MFTOutputStreamInfoFlags + { + None = 0, + WholeSamples = 0x00000001, + SingleSamplePerBuffer = 0x00000002, + FixedSampleSize = 0x00000004, + Discardable = 0x00000008, + Optional = 0x00000010, + ProvidesSamples = 0x00000100, + CanProvideSamples = 0x00000200, + LazyRead = 0x00000400, + Removable = 0x00000800 + } + + [Flags, UnmanagedName("_MFT_INPUT_STREAM_INFO_FLAGS")] + public enum MFTInputStreamInfoFlags + { + WholeSamples = 0x1, + SingleSamplePerBuffer = 0x2, + FixedSampleSize = 0x4, + HoldsBuffers = 0x8, + DoesNotAddRef = 0x100, + Removable = 0x200, + Optional = 0x400, + ProcessesInPlace = 0x800 + } + + [UnmanagedName("MFT_MESSAGE_TYPE")] + public enum MFTMessageType + { + CommandDrain = 1, + CommandFlush = 0, + NotifyBeginStreaming = 0x10000000, + NotifyEndOfStream = 0x10000002, + NotifyEndStreaming = 0x10000001, + NotifyStartOfStream = 0x10000003, + SetD3DManager = 2, + DropSamples = 0x00000003, + CommandMarker = 0x20000000 + } + + [Flags, UnmanagedName("_MFT_OUTPUT_DATA_BUFFER_FLAGS")] + public enum MFTOutputDataBufferFlags + { + None = 0, + Incomplete = 0x01000000, + FormatChange = 0x00000100, + StreamEnd = 0x00000200, + NoSample = 0x00000300 + }; + + [Flags, UnmanagedName("_MFT_PROCESS_OUTPUT_STATUS")] + public enum ProcessOutputStatus + { + None = 0, + NewStreams = 0x00000100 + } + + [StructLayout(LayoutKind.Sequential, Pack = 8), UnmanagedName("MFT_INPUT_STREAM_INFO")] + public struct MFTInputStreamInfo + { + public long hnsMaxLatency; + public MFTInputStreamInfoFlags dwFlags; + public int cbSize; + public int cbMaxLookahead; + public int cbAlignment; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MFT_OUTPUT_DATA_BUFFER")] + public struct MFTOutputDataBuffer + { + public int dwStreamID; + public IntPtr pSample; // Doesn't release correctly when marshaled as IMFSample + public MFTOutputDataBufferFlags dwStatus; + [MarshalAs(UnmanagedType.Interface)] + public IMFCollection pEvents; + } + + [StructLayout(LayoutKind.Sequential, Pack = 4), UnmanagedName("MFT_OUTPUT_STREAM_INFO")] + public struct MFTOutputStreamInfo + { + public MFTOutputStreamInfoFlags dwFlags; + public int cbSize; + public int cbAlignment; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MFT_REGISTER_TYPE_INFO")] + public class MFTRegisterTypeInfo + { + public Guid guidMajorType; + public Guid guidSubtype; + } + + #endregion + + #region Interfaces + +#if ALLOW_UNTESTED_INTERFACES + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("149c4d73-b4be-4f8d-8b87-079e926b6add")] + public interface IMFLocalMFTRegistration + { + [PreserveSig] + int RegisterMFTs( + [In] MFT_REGISTRATION_INFO[] pMFTs, + int cMFTs); + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("MFT_REGISTRATION_INFO")] + public struct MFT_REGISTRATION_INFO + { + Guid clsid; + Guid guidCategory; + int uiFlags; + [MarshalAs(UnmanagedType.LPWStr)] + string pszName; + int cInTypes; + MFTRegisterTypeInfo[] pInTypes; + int cOutTypes; + MFTRegisterTypeInfo[] pOutTypes; + } + +#endif + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("BF94C121-5B05-4E6F-8000-BA598961414D")] + public interface IMFTransform + { + [PreserveSig] + int GetStreamLimits( + [Out] MFInt pdwInputMinimum, + [Out] MFInt pdwInputMaximum, + [Out] MFInt pdwOutputMinimum, + [Out] MFInt pdwOutputMaximum + ); + + [PreserveSig] + int GetStreamCount( + [Out] MFInt pcInputStreams, + [Out] MFInt pcOutputStreams + ); + + [PreserveSig] + int GetStreamIDs( + int dwInputIDArraySize, + [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] int [] pdwInputIDs, + int dwOutputIDArraySize, + [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] int[] pdwOutputIDs + ); + + [PreserveSig] + int GetInputStreamInfo( + int dwInputStreamID, + out MFTInputStreamInfo pStreamInfo + ); + + [PreserveSig] + int GetOutputStreamInfo( + int dwOutputStreamID, + out MFTOutputStreamInfo pStreamInfo + ); + + [PreserveSig] + int GetAttributes( + [MarshalAs(UnmanagedType.Interface)] out IMFAttributes pAttributes + ); + + [PreserveSig] + int GetInputStreamAttributes( + int dwInputStreamID, + [MarshalAs(UnmanagedType.Interface)] out IMFAttributes pAttributes + ); + + [PreserveSig] + int GetOutputStreamAttributes( + int dwOutputStreamID, + [MarshalAs(UnmanagedType.Interface)] out IMFAttributes pAttributes + ); + + [PreserveSig] + int DeleteInputStream( + int dwStreamID + ); + + [PreserveSig] + int AddInputStreams( + int cStreams, + [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] int[] adwStreamIDs + ); + + [PreserveSig] + int GetInputAvailableType( + int dwInputStreamID, + int dwTypeIndex, + [MarshalAs(UnmanagedType.Interface)] out IMFMediaType ppType + ); + + [PreserveSig] + int GetOutputAvailableType( + int dwOutputStreamID, + int dwTypeIndex, + [MarshalAs(UnmanagedType.Interface)] out IMFMediaType ppType + ); + + [PreserveSig] + int SetInputType( + int dwInputStreamID, + [In, MarshalAs(UnmanagedType.Interface)] IMFMediaType pType, + MFTSetTypeFlags dwFlags + ); + + [PreserveSig] + int SetOutputType( + int dwOutputStreamID, + [In, MarshalAs(UnmanagedType.Interface)] IMFMediaType pType, + MFTSetTypeFlags dwFlags + ); + + [PreserveSig] + int GetInputCurrentType( + int dwInputStreamID, + [MarshalAs(UnmanagedType.Interface)] out IMFMediaType ppType + ); + + [PreserveSig] + int GetOutputCurrentType( + int dwOutputStreamID, + [MarshalAs(UnmanagedType.Interface)] out IMFMediaType ppType + ); + + [PreserveSig] + int GetInputStatus( + int dwInputStreamID, + out MFTInputStatusFlags pdwFlags + ); + + [PreserveSig] + int GetOutputStatus( + out MFTOutputStatusFlags pdwFlags + ); + + [PreserveSig] + int SetOutputBounds( + long hnsLowerBound, + long hnsUpperBound + ); + + [PreserveSig] + int ProcessEvent( + int dwInputStreamID, + [In, MarshalAs(UnmanagedType.Interface)] IMFMediaEvent pEvent + ); + + [PreserveSig] + int ProcessMessage( + MFTMessageType eMessage, + IntPtr ulParam + ); + + [PreserveSig] + int ProcessInput( + int dwInputStreamID, + [MarshalAs(UnmanagedType.Interface)] IMFSample pSample, + int dwFlags // Must be zero + ); + + [PreserveSig] + int ProcessOutput( + MFTProcessOutputFlags dwFlags, + int cOutputBufferCount, + [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] MFTOutputDataBuffer [] pOutputSamples, + out ProcessOutputStatus pdwStatus + ); + } + + #endregion + +} diff --git a/MediaFoundation/MFUtils.cs b/MediaFoundation/MFUtils.cs new file mode 100644 index 0000000..bd6e67e --- /dev/null +++ b/MediaFoundation/MFUtils.cs @@ -0,0 +1,3043 @@ +#region license + +/* +MediaFoundationLib - Provide access to MediaFoundation interfaces via .NET +Copyright (C) 2007 +http://mfnet.sourceforge.net + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#endregion + +using System; +using System.Collections; +using System.Text; +using System.Drawing; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Security; + +using MediaFoundation.Misc; +using MediaFoundation.Transform; + +namespace MediaFoundation.Misc +{ + #region Wrapper classes + + [StructLayout(LayoutKind.Sequential)] + public class MfFloat + { + private float Value; + + public MfFloat(float v) + { + Value = v; + } + + public override string ToString() + { + return Value.ToString(); + } + + public override int GetHashCode() + { + return Value.GetHashCode(); + } + + public static implicit operator float(MfFloat l) + { + return l.Value; + } + + public static implicit operator MfFloat(float l) + { + return new MfFloat(l); + } + } + + /// + /// ConstPropVariant is used for [In] parameters. This is important since + /// for [In] parameters, you must *not* clear the PropVariant. The caller + /// will need to do that himself. + /// + /// Likewise, if you want to store a copy of a ConstPropVariant, you should + /// store it to a PropVariant using the PropVariant constructor that takes a + /// ConstPropVariant. If you try to store the ConstPropVariant, when the + /// caller frees his copy, yours will no longer be valid. + /// + [StructLayout(LayoutKind.Explicit)] + public class ConstPropVariant : IDisposable + { + public enum VariantType : short + { + None = 0, + Short = 2, + Int32 = 3, + Float = 4, + Double = 5, + IUnknown = 13, + UByte = 17, + UShort = 18, + UInt32 = 19, + Int64 = 20, + UInt64 = 21, + String = 31, + Guid = 72, + Blob = 0x1000 + 17, + StringArray = 0x1000 + 31 + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("BLOB")] + protected struct Blob + { + public int cbSize; + public IntPtr pBlobData; + } + + [StructLayout(LayoutKind.Sequential), UnmanagedName("CALPWSTR")] + protected struct CALPWstr + { + public int cElems; + public IntPtr pElems; + } + + #region Member variables + + [FieldOffset(0)] + protected VariantType type; + + [FieldOffset(2)] + protected short reserved1; + + [FieldOffset(4)] + protected short reserved2; + + [FieldOffset(6)] + protected short reserved3; + + [FieldOffset(8)] + protected short iVal; + + [FieldOffset(8), CLSCompliant(false)] + protected ushort uiVal; + + [FieldOffset(8), CLSCompliant(false)] + protected byte bVal; + + [FieldOffset(8)] + protected int intValue; + + [FieldOffset(8), CLSCompliant(false)] + protected uint uintVal; + + [FieldOffset(8)] + protected float fltVal; + + [FieldOffset(8)] + protected long longValue; + + [FieldOffset(8), CLSCompliant(false)] + protected ulong ulongValue; + + [FieldOffset(8)] + protected double doubleValue; + + [FieldOffset(8)] + protected Blob blobValue; + + [FieldOffset(8)] + protected IntPtr ptr; + + [FieldOffset(8)] + protected CALPWstr calpwstrVal; + + #endregion + + public ConstPropVariant() + { + type = VariantType.None; + } + + protected ConstPropVariant(VariantType v) + { + type = v; + } + + public static explicit operator string(ConstPropVariant f) + { + return f.GetString(); + } + + public static explicit operator string[](ConstPropVariant f) + { + return f.GetStringArray(); + } + + public static explicit operator byte(ConstPropVariant f) + { + return f.GetUByte(); + } + + public static explicit operator short(ConstPropVariant f) + { + return f.GetShort(); + } + + [CLSCompliant(false)] + public static explicit operator ushort(ConstPropVariant f) + { + return f.GetUShort(); + } + + public static explicit operator int(ConstPropVariant f) + { + return f.GetInt(); + } + + [CLSCompliant(false)] + public static explicit operator uint(ConstPropVariant f) + { + return f.GetUInt(); + } + + public static explicit operator float(ConstPropVariant f) + { + return f.GetFloat(); + } + + public static explicit operator double(ConstPropVariant f) + { + return f.GetDouble(); + } + + public static explicit operator long(ConstPropVariant f) + { + return f.GetLong(); + } + + [CLSCompliant(false)] + public static explicit operator ulong(ConstPropVariant f) + { + return f.GetULong(); + } + + public static explicit operator Guid(ConstPropVariant f) + { + return f.GetGuid(); + } + + public static explicit operator byte[](ConstPropVariant f) + { + return f.GetBlob(); + } + + // I decided not to do implicits since perf is likely to be + // better recycling the PropVariant, and the only way I can + // see to support Implicit is to create a new PropVariant. + // Also, since I can't free the previous instance, IUnknowns + // will linger until the GC cleans up. Not what I think I + // want. + + public MFAttributeType GetMFAttributeType() + { + switch (type) + { + case VariantType.None: + case VariantType.UInt32: + case VariantType.UInt64: + case VariantType.Double: + case VariantType.Guid: + case VariantType.String: + case VariantType.Blob: + case VariantType.IUnknown: + { + return (MFAttributeType)type; + } + default: + { + throw new Exception("Type is not a MFAttributeType"); + } + } + } + + public VariantType GetVariantType() + { + return type; + } + + public string[] GetStringArray() + { + if (type == VariantType.StringArray) + { + string[] sa; + + int iCount = calpwstrVal.cElems; + sa = new string[iCount]; + + for (int x = 0; x < iCount; x++) + { + sa[x] = Marshal.PtrToStringUni(Marshal.ReadIntPtr(calpwstrVal.pElems, x * IntPtr.Size)); + } + + return sa; + } + throw new ArgumentException("PropVariant contents not a string array"); + } + + public string GetString() + { + if (type == VariantType.String) + { + return Marshal.PtrToStringUni(ptr); + } + throw new ArgumentException("PropVariant contents not a string"); + } + + public byte GetUByte() + { + if (type == VariantType.UByte) + { + return bVal; + } + throw new ArgumentException("PropVariant contents not a byte"); + } + + public short GetShort() + { + if (type == VariantType.Short) + { + return iVal; + } + throw new ArgumentException("PropVariant contents not an Short"); + } + + [CLSCompliant(false)] + public ushort GetUShort() + { + if (type == VariantType.UShort) + { + return uiVal; + } + throw new ArgumentException("PropVariant contents not an UShort"); + } + + public int GetInt() + { + if (type == VariantType.Int32) + { + return intValue; + } + throw new ArgumentException("PropVariant contents not an int32"); + } + + [CLSCompliant(false)] + public uint GetUInt() + { + if (type == VariantType.UInt32) + { + return uintVal; + } + throw new ArgumentException("PropVariant contents not an uint32"); + } + + public long GetLong() + { + if (type == VariantType.Int64) + { + return longValue; + } + throw new ArgumentException("PropVariant contents not an int64"); + } + + [CLSCompliant(false)] + public ulong GetULong() + { + if (type == VariantType.UInt64) + { + return ulongValue; + } + throw new ArgumentException("PropVariant contents not an uint64"); + } + + public float GetFloat() + { + if (type == VariantType.Float) + { + return fltVal; + } + throw new ArgumentException("PropVariant contents not a Float"); + } + + public double GetDouble() + { + if (type == VariantType.Double) + { + return doubleValue; + } + throw new ArgumentException("PropVariant contents not a double"); + } + + public Guid GetGuid() + { + if (type == VariantType.Guid) + { + return (Guid)Marshal.PtrToStructure(ptr, typeof(Guid)); + } + throw new ArgumentException("PropVariant contents not a Guid"); + } + + public byte[] GetBlob() + { + if (type == VariantType.Blob) + { + byte[] b = new byte[blobValue.cbSize]; + + Marshal.Copy(blobValue.pBlobData, b, 0, blobValue.cbSize); + + return b; + } + throw new ArgumentException("PropVariant contents are not a Blob"); + } + + public object GetIUnknown() + { + if (type == VariantType.IUnknown) + { + return Marshal.GetObjectForIUnknown(ptr); + } + throw new ArgumentException("PropVariant contents not an IUnknown"); + } + + public override string ToString() + { + // This method is primarily intended for debugging so that a readable string will show + // up in the output window + string sRet; + + switch (type) + { + case VariantType.None: + { + sRet = ""; + break; + } + + case VariantType.Blob: + { + const string FormatString = "x2"; // Hex 2 digit format + const int MaxEntries = 16; + + byte[] blob = GetBlob(); + + // Number of bytes we're going to format + int n = Math.Min(MaxEntries, blob.Length); + + if (n == 0) + { + sRet = ""; + } + else + { + // Only format the first MaxEntries bytes + sRet = blob[0].ToString(FormatString); + for (int i = 1; i < n; i++) + { + sRet += ',' + blob[i].ToString(FormatString); + } + + // If the string is longer, add an indicator + if (blob.Length > n) + { + sRet += "..."; + } + } + break; + } + + case VariantType.Float: + { + sRet = GetFloat().ToString(); + break; + } + + case VariantType.Double: + { + sRet = GetDouble().ToString(); + break; + } + + case VariantType.Guid: + { + sRet = GetGuid().ToString(); + break; + } + + case VariantType.IUnknown: + { + sRet = GetIUnknown().ToString(); + break; + } + + case VariantType.String: + { + sRet = GetString(); + break; + } + + case VariantType.Short: + { + sRet = GetShort().ToString(); + break; + } + + case VariantType.UByte: + { + sRet = GetUByte().ToString(); + break; + } + + case VariantType.UShort: + { + sRet = GetUShort().ToString(); + break; + } + + case VariantType.Int32: + { + sRet = GetInt().ToString(); + break; + } + + case VariantType.UInt32: + { + sRet = GetUInt().ToString(); + break; + } + + case VariantType.Int64: + { + sRet = GetLong().ToString(); + break; + } + + case VariantType.UInt64: + { + sRet = GetULong().ToString(); + break; + } + + case VariantType.StringArray: + { + sRet = ""; + foreach (string entry in GetStringArray()) + { + sRet += (sRet.Length == 0 ? "\"" : ",\"") + entry + '\"'; + } + break; + } + default: + { + sRet = base.ToString(); + break; + } + } + + return sRet; + } + + public override int GetHashCode() + { + // Give a (slightly) better hash value in case someone uses PropVariants + // in a hash table. + int iRet; + + switch (type) + { + case VariantType.None: + { + iRet = base.GetHashCode(); + break; + } + + case VariantType.Blob: + { + iRet = GetBlob().GetHashCode(); + break; + } + + case VariantType.Float: + { + iRet = GetFloat().GetHashCode(); + break; + } + + case VariantType.Double: + { + iRet = GetDouble().GetHashCode(); + break; + } + + case VariantType.Guid: + { + iRet = GetGuid().GetHashCode(); + break; + } + + case VariantType.IUnknown: + { + iRet = GetIUnknown().GetHashCode(); + break; + } + + case VariantType.String: + { + iRet = GetString().GetHashCode(); + break; + } + + case VariantType.UByte: + { + iRet = GetUByte().GetHashCode(); + break; + } + + case VariantType.Short: + { + iRet = GetShort().GetHashCode(); + break; + } + + case VariantType.UShort: + { + iRet = GetUShort().GetHashCode(); + break; + } + + case VariantType.Int32: + { + iRet = GetInt().GetHashCode(); + break; + } + + case VariantType.UInt32: + { + iRet = GetUInt().GetHashCode(); + break; + } + + case VariantType.Int64: + { + iRet = GetLong().GetHashCode(); + break; + } + + case VariantType.UInt64: + { + iRet = GetULong().GetHashCode(); + break; + } + + case VariantType.StringArray: + { + iRet = GetStringArray().GetHashCode(); + break; + } + default: + { + iRet = base.GetHashCode(); + break; + } + } + + return iRet; + } + + public override bool Equals(object obj) + { + bool bRet; + PropVariant p = obj as PropVariant; + + if ((((object)p) == null) || (p.type != type)) + { + bRet = false; + } + else + { + switch (type) + { + case VariantType.None: + { + bRet = true; + break; + } + + case VariantType.Blob: + { + byte[] b1; + byte[] b2; + + b1 = GetBlob(); + b2 = p.GetBlob(); + + if (b1.Length == b2.Length) + { + bRet = true; + for (int x = 0; x < b1.Length; x++) + { + if (b1[x] != b2[x]) + { + bRet = false; + break; + } + } + } + else + { + bRet = false; + } + break; + } + + case VariantType.Float: + { + bRet = GetFloat() == p.GetFloat(); + break; + } + + case VariantType.Double: + { + bRet = GetDouble() == p.GetDouble(); + break; + } + + case VariantType.Guid: + { + bRet = GetGuid() == p.GetGuid(); + break; + } + + case VariantType.IUnknown: + { + bRet = GetIUnknown() == p.GetIUnknown(); + break; + } + + case VariantType.String: + { + bRet = GetString() == p.GetString(); + break; + } + + case VariantType.UByte: + { + bRet = GetUByte() == p.GetUByte(); + break; + } + + case VariantType.Short: + { + bRet = GetShort() == p.GetShort(); + break; + } + + case VariantType.UShort: + { + bRet = GetUShort() == p.GetUShort(); + break; + } + + case VariantType.Int32: + { + bRet = GetInt() == p.GetInt(); + break; + } + + case VariantType.UInt32: + { + bRet = GetUInt() == p.GetUInt(); + break; + } + + case VariantType.Int64: + { + bRet = GetLong() == p.GetLong(); + break; + } + + case VariantType.UInt64: + { + bRet = GetULong() == p.GetULong(); + break; + } + + case VariantType.StringArray: + { + string[] sa1; + string[] sa2; + + sa1 = GetStringArray(); + sa2 = p.GetStringArray(); + + if (sa1.Length == sa2.Length) + { + bRet = true; + for (int x = 0; x < sa1.Length; x++) + { + if (sa1[x] != sa2[x]) + { + bRet = false; + break; + } + } + } + else + { + bRet = false; + } + break; + } + default: + { + bRet = base.Equals(obj); + break; + } + } + } + + return bRet; + } + + public static bool operator ==(ConstPropVariant pv1, ConstPropVariant pv2) + { + // If both are null, or both are same instance, return true. + if (System.Object.ReferenceEquals(pv1, pv2)) + { + return true; + } + + // If one is null, but not both, return false. + if (((object)pv1 == null) || ((object)pv2 == null)) + { + return false; + } + + return pv1.Equals(pv2); + } + + public static bool operator !=(ConstPropVariant pv1, ConstPropVariant pv2) + { + return !(pv1 == pv2); + } + + #region IDisposable Members + + public void Dispose() + { + // If we are a ConstPropVariant, we must *not* call PropVariantClear. That + // would release the *caller's* copy of the data, which would probably make + // him cranky. If we are a PropVariant, the PropVariant.Dispose gets called + // as well, which *does* do a PropVariantClear. + type = VariantType.None; +#if DEBUG + longValue = 0; +#endif + } + + #endregion + } + + [StructLayout(LayoutKind.Explicit)] + public class PropVariant : ConstPropVariant + { + #region Declarations + + [DllImport("ole32.dll", ExactSpelling = true, PreserveSig = false), SuppressUnmanagedCodeSecurity] + protected static extern void PropVariantCopy( + [Out, MarshalAs(UnmanagedType.LPStruct)] PropVariant pvarDest, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant pvarSource + ); + + [DllImport("ole32.dll", ExactSpelling = true, PreserveSig = false), SuppressUnmanagedCodeSecurity] + protected static extern void PropVariantClear( + [In, MarshalAs(UnmanagedType.LPStruct)] PropVariant pvar + ); + + #endregion + + public PropVariant() : base(VariantType.None) + { + } + + public PropVariant(string value) : base(VariantType.String) + { + ptr = Marshal.StringToCoTaskMemUni(value); + } + + public PropVariant(string[] value) : base(VariantType.StringArray) + { + calpwstrVal.cElems = value.Length; + calpwstrVal.pElems = Marshal.AllocCoTaskMem(IntPtr.Size * value.Length); + + for (int x = 0; x < value.Length; x++) + { + Marshal.WriteIntPtr(calpwstrVal.pElems, x * IntPtr.Size, Marshal.StringToCoTaskMemUni(value[x])); + } + } + + public PropVariant(byte value) : base(VariantType.UByte) + { + bVal = value; + } + + public PropVariant(short value) : base(VariantType.Short) + { + iVal = value; + } + + [CLSCompliant(false)] + public PropVariant(ushort value) : base(VariantType.UShort) + { + uiVal = value; + } + + public PropVariant(int value) : base(VariantType.Int32) + { + intValue = value; + } + + [CLSCompliant(false)] + public PropVariant(uint value) : base(VariantType.UInt32) + { + uintVal = value; + } + + public PropVariant(float value) : base(VariantType.Float) + { + fltVal = value; + } + + public PropVariant(double value) : base(VariantType.Double) + { + doubleValue = value; + } + + public PropVariant(long value) : base(VariantType.Int64) + { + longValue = value; + } + + [CLSCompliant(false)] + public PropVariant(ulong value) : base(VariantType.UInt64) + { + ulongValue = value; + } + + public PropVariant(Guid value) : base(VariantType.Guid) + { + ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(value)); + Marshal.StructureToPtr(value, ptr, false); + } + + public PropVariant(byte[] value) : base(VariantType.Blob) + { + blobValue.cbSize = value.Length; + blobValue.pBlobData = Marshal.AllocCoTaskMem(value.Length); + Marshal.Copy(value, 0, blobValue.pBlobData, value.Length); + } + + public PropVariant(object value) : base(VariantType.IUnknown) + { + ptr = Marshal.GetIUnknownForObject(value); + } + + public PropVariant(IntPtr value) + { + Marshal.PtrToStructure(value, this); + } + + public PropVariant(ConstPropVariant value) + { + if (value != null) + { + PropVariantCopy(this, value); + } + else + { + throw new NullReferenceException("null passed to PropVariant constructor"); + } + } + + ~PropVariant() + { + Clear(); + } + + public void Copy(PropVariant pval) + { + if (pval == null) + { + throw new Exception("Null PropVariant sent to Copy"); + } + + pval.Clear(); + + PropVariantCopy(pval, this); + } + + public void Clear() + { + PropVariantClear(this); + } + + #region IDisposable Members + + new public void Dispose() + { + Clear(); + GC.SuppressFinalize(this); + } + + #endregion + } + + [StructLayout(LayoutKind.Sequential)] + public class FourCC + { + private int m_fourCC; + + public FourCC(string fcc) + { + if (fcc.Length != 4) + { + throw new ArgumentException(fcc + " is not a valid FourCC"); + } + + byte[] asc = Encoding.ASCII.GetBytes(fcc); + + LoadFromBytes(asc[0], asc[1], asc[2], asc[3]); + } + + public FourCC(char a, char b, char c, char d) + { + LoadFromBytes((byte)a, (byte)b, (byte)c, (byte)d); + } + + public FourCC(int fcc) + { + m_fourCC = fcc; + } + + public FourCC(byte a, byte b, byte c, byte d) + { + LoadFromBytes(a, b, c, d); + } + + public FourCC(Guid g) + { + if (!IsA4ccSubtype(g)) + { + throw new Exception("Not a FourCC Guid"); + } + + byte[] asc; + asc = g.ToByteArray(); + + LoadFromBytes(asc[0], asc[1], asc[2], asc[3]); + } + + public void LoadFromBytes(byte a, byte b, byte c, byte d) + { + m_fourCC = a | (b << 8) | (c << 16) | (d << 24); + } + + public int ToInt32() + { + return m_fourCC; + } + + public static explicit operator int(FourCC f) + { + return f.ToInt32(); + } + + public static explicit operator Guid(FourCC f) + { + return f.ToMediaSubtype(); + } + + public Guid ToMediaSubtype() + { + return new Guid(m_fourCC, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + } + + public static bool operator ==(FourCC fcc1, FourCC fcc2) + { + // If both are null, or both are same instance, return true. + if (System.Object.ReferenceEquals(fcc1, fcc2)) + { + return true; + } + + // If one is null, but not both, return false. + if (((object)fcc1 == null) || ((object)fcc2 == null)) + { + return false; + } + + return fcc1.m_fourCC == fcc2.m_fourCC; + } + + public static bool operator !=(FourCC fcc1, FourCC fcc2) + { + return !(fcc1 == fcc2); + } + + public override bool Equals(object obj) + { + if (!(obj is FourCC)) + return false; + + return (obj as FourCC).m_fourCC == m_fourCC; + } + + public override int GetHashCode() + { + return m_fourCC.GetHashCode(); + } + + public override string ToString() + { + char c; + char[] ca = new char[4]; + + c = Convert.ToChar(m_fourCC & 255); + if (!Char.IsLetterOrDigit(c)) + { + c = ' '; + } + ca[0] = c; + + c = Convert.ToChar((m_fourCC >> 8) & 255); + if (!Char.IsLetterOrDigit(c)) + { + c = ' '; + } + ca[1] = c; + + c = Convert.ToChar((m_fourCC >> 16) & 255); + if (!Char.IsLetterOrDigit(c)) + { + c = ' '; + } + ca[2] = c; + + c = Convert.ToChar((m_fourCC >> 24) & 255); + if (!Char.IsLetterOrDigit(c)) + { + c = ' '; + } + ca[3] = c; + + string s = new string(ca); + + return s; + } + + public static bool IsA4ccSubtype(Guid g) + { + return (g.ToString().EndsWith("-0000-0010-8000-00aa00389b71")); + } + } + + [StructLayout(LayoutKind.Sequential, Pack = 1), UnmanagedName("WAVEFORMATEX")] + public class WaveFormatEx + { + public short wFormatTag; + public short nChannels; + public int nSamplesPerSec; + public int nAvgBytesPerSec; + public short nBlockAlign; + public short wBitsPerSample; + public short cbSize; + + public override string ToString() + { + return string.Format("{0} {1} {2} {3}", wFormatTag, nChannels, nSamplesPerSec, wBitsPerSample); + } + + public IntPtr GetPtr() + { + IntPtr ip; + + // See what kind of WaveFormat object we've got + if (this is WaveFormatExtensibleWithData) + { + int iExtensibleSize = Marshal.SizeOf(typeof(WaveFormatExtensible)); + int iWaveFormatExSize = Marshal.SizeOf(typeof(WaveFormatEx)); + + // WaveFormatExtensibleWithData - Have to copy the byte array too + WaveFormatExtensibleWithData pData = this as WaveFormatExtensibleWithData; + + int iExtraBytes = pData.cbSize - (iExtensibleSize - iWaveFormatExSize); + + // Account for copying the array. This may result in us allocating more bytes than we + // need (if cbSize < IntPtr.Size), but it prevents us from overrunning the buffer. + int iUseSize = Math.Max(iExtraBytes, IntPtr.Size); + + // Remember, cbSize include the length of WaveFormatExtensible + ip = Marshal.AllocCoTaskMem(iExtensibleSize + iUseSize); + + // Copies the waveformatex + waveformatextensible + Marshal.StructureToPtr(pData, ip, false); + + // Get a pointer to the byte after the copy + IntPtr ip2 = new IntPtr(ip.ToInt64() + iExtensibleSize); + + // Copy the extra bytes + Marshal.Copy(pData.byteData, 0, ip2, pData.cbSize - (iExtensibleSize - iWaveFormatExSize)); + } + else if (this is WaveFormatExtensible) + { + int iWaveFormatExtensibleSize = Marshal.SizeOf(typeof(WaveFormatExtensible)); + + // WaveFormatExtensible - Just do a simple copy + WaveFormatExtensible pExt = this as WaveFormatExtensible; + + ip = Marshal.AllocCoTaskMem(iWaveFormatExtensibleSize); + + Marshal.StructureToPtr(this as WaveFormatExtensible, ip, false); + } + else if (this is WaveFormatExWithData) + { + int iWaveFormatExSize = Marshal.SizeOf(typeof(WaveFormatEx)); + + // WaveFormatExWithData - Have to copy the byte array too + WaveFormatExWithData pData = this as WaveFormatExWithData; + + // Account for copying the array. This may result in us allocating more bytes than we + // need (if cbSize < IntPtr.Size), but it prevents us from overrunning the buffer. + int iUseSize = Math.Max(pData.cbSize, IntPtr.Size); + + ip = Marshal.AllocCoTaskMem(iWaveFormatExSize + iUseSize); + + Marshal.StructureToPtr(pData, ip, false); + + IntPtr ip2 = new IntPtr(ip.ToInt64() + iWaveFormatExSize); + Marshal.Copy(pData.byteData, 0, ip2, pData.cbSize); + } + else if (this is WaveFormatEx) + { + int iWaveFormatExSize = Marshal.SizeOf(typeof(WaveFormatEx)); + + // WaveFormatEx - just do a copy + ip = Marshal.AllocCoTaskMem(iWaveFormatExSize); + Marshal.StructureToPtr(this as WaveFormatEx, ip, false); + } + else + { + // Someone added our custom marshaler to something they shouldn't have + Debug.Assert(false, "Shouldn't ever get here"); + ip = IntPtr.Zero; + } + + return ip; + } + + public static WaveFormatEx PtrToWave(IntPtr pNativeData) + { + short wFormatTag = Marshal.ReadInt16(pNativeData); + WaveFormatEx wfe; + + // WAVE_FORMAT_EXTENSIBLE == -2 + if (wFormatTag != -2) + { + short cbSize; + + // By spec, PCM has no cbSize element + if (wFormatTag != 1) + { + cbSize = Marshal.ReadInt16(pNativeData, 16); + } + else + { + cbSize = 0; + } + + // Does the structure contain extra data? + if (cbSize == 0) + { + // Create a simple WaveFormatEx struct + wfe = new WaveFormatEx(); + Marshal.PtrToStructure(pNativeData, wfe); + + // It probably already has the right value, but there is a special case + // where it might not, so, just to be safe... + wfe.cbSize = 0; + } + else + { + WaveFormatExWithData dat = new WaveFormatExWithData(); + + // Manually parse the data into the structure + dat.wFormatTag = wFormatTag; + dat.nChannels = Marshal.ReadInt16(pNativeData, 2); + dat.nSamplesPerSec = Marshal.ReadInt32(pNativeData, 4); + dat.nAvgBytesPerSec = Marshal.ReadInt32(pNativeData, 8); + dat.nBlockAlign = Marshal.ReadInt16(pNativeData, 12); + dat.wBitsPerSample = Marshal.ReadInt16(pNativeData, 14); + dat.cbSize = cbSize; + + dat.byteData = new byte[dat.cbSize]; + IntPtr ip2 = new IntPtr(pNativeData.ToInt64() + 18); + Marshal.Copy(ip2, dat.byteData, 0, dat.cbSize); + + wfe = dat as WaveFormatEx; + } + } + else + { + short cbSize; + int extrasize = Marshal.SizeOf(typeof(WaveFormatExtensible)) - Marshal.SizeOf(typeof(WaveFormatEx)); + + cbSize = Marshal.ReadInt16(pNativeData, 16); + if (cbSize == extrasize) + { + WaveFormatExtensible ext = new WaveFormatExtensible(); + Marshal.PtrToStructure(pNativeData, ext); + wfe = ext as WaveFormatEx; + } + else + { + WaveFormatExtensibleWithData ext = new WaveFormatExtensibleWithData(); + int iExtraBytes = cbSize - extrasize; + + ext.wFormatTag = wFormatTag; + ext.nChannels = Marshal.ReadInt16(pNativeData, 2); + ext.nSamplesPerSec = Marshal.ReadInt32(pNativeData, 4); + ext.nAvgBytesPerSec = Marshal.ReadInt32(pNativeData, 8); + ext.nBlockAlign = Marshal.ReadInt16(pNativeData, 12); + ext.wBitsPerSample = Marshal.ReadInt16(pNativeData, 14); + ext.cbSize = cbSize; + + ext.wValidBitsPerSample = Marshal.ReadInt16(pNativeData, 18); + ext.dwChannelMask = (WaveMask)Marshal.ReadInt16(pNativeData, 20); + + // Read the Guid + byte[] byteGuid = new byte[16]; + Marshal.Copy(new IntPtr(pNativeData.ToInt64() + 24), byteGuid, 0, 16); + ext.SubFormat = new Guid(byteGuid); + + ext.byteData = new byte[iExtraBytes]; + IntPtr ip2 = new IntPtr(pNativeData.ToInt64() + Marshal.SizeOf(typeof(WaveFormatExtensible))); + Marshal.Copy(ip2, ext.byteData, 0, iExtraBytes); + + wfe = ext as WaveFormatEx; + } + } + + return wfe; + } + + public static bool operator ==(WaveFormatEx a, WaveFormatEx b) + { + // If both are null, or both are same instance, return true. + if (System.Object.ReferenceEquals(a, b)) + { + return true; + } + + // If one is null, but not both, return false. + if (((object)a == null) || ((object)b == null)) + { + return false; + } + + bool bRet; + Type t1 = a.GetType(); + Type t2 = b.GetType(); + + if (t1 == t2 && + a.wFormatTag == b.wFormatTag && + a.nChannels == b.nChannels && + a.nSamplesPerSec == b.nSamplesPerSec && + a.nAvgBytesPerSec == b.nAvgBytesPerSec && + a.nBlockAlign == b.nBlockAlign && + a.wBitsPerSample == b.wBitsPerSample && + a.cbSize == b.cbSize) + { + bRet = true; + } + else + { + bRet = false; + } + + return bRet; + } + + public static bool operator !=(WaveFormatEx a, WaveFormatEx b) + { + return !(a == b); + } + + public override bool Equals(object obj) + { + return this == (obj as WaveFormatEx); + } + + public override int GetHashCode() + { + return nAvgBytesPerSec + wFormatTag; + } + } + + [StructLayout(LayoutKind.Sequential, Pack = 1), UnmanagedName("WAVEFORMATEX")] + public class WaveFormatExWithData : WaveFormatEx + { + public byte[] byteData; + + public static bool operator ==(WaveFormatExWithData a, WaveFormatExWithData b) + { + bool bRet = ((WaveFormatEx)a) == ((WaveFormatEx)b); + + if (bRet) + { + if (b.byteData == null) + { + bRet = a.byteData == null; + } + else + { + if (b.byteData.Length == a.byteData.Length) + { + for (int x = 0; x < b.byteData.Length; x++) + { + if (b.byteData[x] != a.byteData[x]) + { + bRet = false; + break; + } + } + } + else + { + bRet = false; + } + } + } + + return bRet; + } + + public static bool operator !=(WaveFormatExWithData a, WaveFormatExWithData b) + { + return !(a == b); + } + + public override bool Equals(object obj) + { + return this == (obj as WaveFormatExWithData); + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + } + + [StructLayout(LayoutKind.Explicit, Pack = 1), UnmanagedName("WAVEFORMATEXTENSIBLE")] + public class WaveFormatExtensible : WaveFormatEx + { + [FieldOffset(0)] + public short wValidBitsPerSample; + [FieldOffset(0)] + public short wSamplesPerBlock; + [FieldOffset(0)] + public short wReserved; + [FieldOffset(2)] + public WaveMask dwChannelMask; + [FieldOffset(6)] + public Guid SubFormat; + + public static bool operator ==(WaveFormatExtensible a, WaveFormatExtensible b) + { + bool bRet = ((WaveFormatEx)a) == ((WaveFormatEx)b); + + if (bRet) + { + bRet = (a.wValidBitsPerSample == b.wValidBitsPerSample && + a.dwChannelMask == b.dwChannelMask && + a.SubFormat == b.SubFormat); + } + + return bRet; + } + + public static bool operator !=(WaveFormatExtensible a, WaveFormatExtensible b) + { + return !(a == b); + } + + public override bool Equals(object obj) + { + return this == (obj as WaveFormatExtensible); + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + } + + [StructLayout(LayoutKind.Sequential, Pack = 1), UnmanagedName("WAVEFORMATEX")] + public class WaveFormatExtensibleWithData : WaveFormatExtensible + { + public byte[] byteData; + + public static bool operator ==(WaveFormatExtensibleWithData a, WaveFormatExtensibleWithData b) + { + bool bRet = ((WaveFormatExtensible)a) == ((WaveFormatExtensible)b); + + if (bRet) + { + if (b.byteData == null) + { + bRet = a.byteData == null; + } + else + { + if (b.byteData.Length == a.byteData.Length) + { + for (int x = 0; x < b.byteData.Length; x++) + { + if (b.byteData[x] != a.byteData[x]) + { + bRet = false; + break; + } + } + } + else + { + bRet = false; + } + } + } + + return bRet; + } + + public static bool operator !=(WaveFormatExtensibleWithData a, WaveFormatExtensibleWithData b) + { + return !(a == b); + } + + public override bool Equals(object obj) + { + return this == (obj as WaveFormatExtensibleWithData); + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + } + + [StructLayout(LayoutKind.Sequential, Pack = 4), UnmanagedName("BITMAPINFOHEADER")] + public class BitmapInfoHeader + { + public int Size; + public int Width; + public int Height; + public short Planes; + public short BitCount; + public int Compression; + public int ImageSize; + public int XPelsPerMeter; + public int YPelsPerMeter; + public int ClrUsed; + public int ClrImportant; + + public IntPtr GetPtr() + { + IntPtr ip; + + // See what kind of BitmapInfoHeader object we've got + if (this is BitmapInfoHeaderWithData) + { + int iBitmapInfoHeaderSize = Marshal.SizeOf(typeof(BitmapInfoHeader)); + + // BitmapInfoHeaderWithData - Have to copy the array too + BitmapInfoHeaderWithData pData = this as BitmapInfoHeaderWithData; + + // Account for copying the array. This may result in us allocating more bytes than we + // need (if cbSize < IntPtr.Size), but it prevents us from overrunning the buffer. + int iUseSize = Math.Max(pData.bmiColors.Length * 4, IntPtr.Size); + + ip = Marshal.AllocCoTaskMem(iBitmapInfoHeaderSize + iUseSize); + + Marshal.StructureToPtr(pData, ip, false); + + IntPtr ip2 = new IntPtr(ip.ToInt64() + iBitmapInfoHeaderSize); + Marshal.Copy(pData.bmiColors, 0, ip2, pData.bmiColors.Length); + } + else if (this is BitmapInfoHeader) + { + int iBitmapInfoHeaderSize = Marshal.SizeOf(typeof(BitmapInfoHeader)); + + // BitmapInfoHeader - just do a copy + ip = Marshal.AllocCoTaskMem(iBitmapInfoHeaderSize); + Marshal.StructureToPtr(this as BitmapInfoHeader, ip, false); + } + else + { + Debug.Assert(false, "Shouldn't ever get here"); + ip = IntPtr.Zero; + } + + return ip; + } + + public static BitmapInfoHeader PtrToBMI(IntPtr pNativeData) + { + int iEntries; + int biCompression; + int biClrUsed; + int biBitCount; + + biBitCount = Marshal.ReadInt16(pNativeData, 14); + biCompression = Marshal.ReadInt32(pNativeData, 16); + biClrUsed = Marshal.ReadInt32(pNativeData, 32); + + if (biCompression == 3) // BI_BITFIELDS + { + iEntries = 3; + } + else if (biClrUsed > 0) + { + iEntries = biClrUsed; + } + else if (biBitCount <= 8) + { + iEntries = 1 << biBitCount; + } + else + { + iEntries = 0; + } + + BitmapInfoHeader bmi; + + if (iEntries == 0) + { + // Create a simple BitmapInfoHeader struct + bmi = new BitmapInfoHeader(); + Marshal.PtrToStructure(pNativeData, bmi); + } + else + { + BitmapInfoHeaderWithData ext = new BitmapInfoHeaderWithData(); + + ext.Size = Marshal.ReadInt32(pNativeData, 0); + ext.Width = Marshal.ReadInt32(pNativeData, 4); + ext.Height = Marshal.ReadInt32(pNativeData, 8); + ext.Planes = Marshal.ReadInt16(pNativeData, 12); + ext.BitCount = Marshal.ReadInt16(pNativeData, 14); + ext.Compression = Marshal.ReadInt32(pNativeData, 16); + ext.ImageSize = Marshal.ReadInt32(pNativeData, 20); + ext.XPelsPerMeter = Marshal.ReadInt32(pNativeData, 24); + ext.YPelsPerMeter = Marshal.ReadInt32(pNativeData, 28); + ext.ClrUsed = Marshal.ReadInt32(pNativeData, 32); + ext.ClrImportant = Marshal.ReadInt32(pNativeData, 36); + + bmi = ext as BitmapInfoHeader; + + ext.bmiColors = new int[iEntries]; + IntPtr ip2 = new IntPtr(pNativeData.ToInt64() + Marshal.SizeOf(typeof(BitmapInfoHeader))); + Marshal.Copy(ip2, ext.bmiColors, 0, iEntries); + } + + return bmi; + } + + public void CopyFrom(BitmapInfoHeader bmi) + { + Size = bmi.Size; + Width = bmi.Width; + Height = bmi.Height; + Planes = bmi.Planes; + BitCount = bmi.BitCount; + Compression = bmi.Compression; + ImageSize = bmi.ImageSize; + YPelsPerMeter = bmi.YPelsPerMeter; + ClrUsed = bmi.ClrUsed; + ClrImportant = bmi.ClrImportant; + + if (bmi is BitmapInfoHeaderWithData) + { + BitmapInfoHeaderWithData ext = this as BitmapInfoHeaderWithData; + BitmapInfoHeaderWithData ext2 = bmi as BitmapInfoHeaderWithData; + + ext.bmiColors = new int[ext2.bmiColors.Length]; + ext2.bmiColors.CopyTo(ext.bmiColors, 0); + } + } + } + + [StructLayout(LayoutKind.Sequential, Pack = 4), UnmanagedName("BITMAPINFO")] + public class BitmapInfoHeaderWithData : BitmapInfoHeader + { + public int[] bmiColors; + } + + [StructLayout(LayoutKind.Sequential)] + public class MFInt + { + protected int m_value; + + public MFInt(int v) + { + m_value = v; + } + + public int GetValue() + { + return m_value; + } + + // While I *could* enable this code, it almost certainly won't do what you + // think it will. Generally you don't want to create a *new* instance of + // MFInt and assign a value to it. You want to assign a value to an + // existing instance. In order to do this automatically, .Net would have + // to support overloading operator =. But since it doesn't, use Assign() + + //public static implicit operator MFInt(int f) + //{ + // return new MFInt(f); + //} + + public static implicit operator int(MFInt f) + { + return f.m_value; + } + + public int ToInt32() + { + return m_value; + } + + public void Assign(int f) + { + m_value = f; + } + + public override string ToString() + { + return m_value.ToString(); + } + + public override int GetHashCode() + { + return m_value.GetHashCode(); + } + + public override bool Equals(object obj) + { + if (obj is MFInt) + { + return ((MFInt)obj).m_value == m_value; + } + + return Convert.ToInt32(obj) == m_value; + } + } + + /// + /// MFRect is a managed representation of the Win32 RECT structure. + /// + [StructLayout(LayoutKind.Sequential)] + public class MFRect + { + public int left; + public int top; + public int right; + public int bottom; + + /// + /// Empty contructor. Initialize all fields to 0 + /// + public MFRect() + { + } + + /// + /// A parametred constructor. Initialize fields with given values. + /// + /// the left value + /// the top value + /// the right value + /// the bottom value + public MFRect(int l, int t, int r, int b) + { + left = l; + top = t; + right = r; + bottom = b; + } + + /// + /// A parametred constructor. Initialize fields with a given . + /// + /// A + /// + /// Warning, MFRect define a rectangle by defining two of his corners and define a rectangle with his upper/left corner, his width and his height. + /// + public MFRect(Rectangle rectangle) + { + left = rectangle.Left; + top = rectangle.Top; + right = rectangle.Right; + bottom = rectangle.Bottom; + } + + /// + /// Provide de string representation of this MFRect instance + /// + /// A string formated like this : [left, top - right, bottom] + public override string ToString() + { + return string.Format("[{0}, {1}] - [{2}, {3}]", left, top, right, bottom); + } + + public override int GetHashCode() + { + return left.GetHashCode() | + top.GetHashCode() | + right.GetHashCode() | + bottom.GetHashCode(); + } + + public override bool Equals(object obj) + { + if (obj is MFRect) + { + MFRect cmp = (MFRect)obj; + + return right == cmp.right && bottom == cmp.bottom && left == cmp.left && top == cmp.top; + } + + if (obj is Rectangle) + { + Rectangle cmp = (Rectangle)obj; + + return right == cmp.Right && bottom == cmp.Bottom && left == cmp.Left && top == cmp.Top; + } + + return false; + } + + /// + /// Checks to see if the rectangle is empty + /// + /// Returns true if the rectangle is empty + public bool IsEmpty() + { + return (right <= left || bottom <= top); + } + + /// + /// Define implicit cast between MFRect and System.Drawing.Rectangle for languages supporting this feature. + /// VB.Net doesn't support implicit cast. for similar functionality. + /// + /// // Define a new Rectangle instance + /// Rectangle r = new Rectangle(0, 0, 100, 100); + /// // Do implicit cast between Rectangle and MFRect + /// MFRect mfR = r; + /// + /// Console.WriteLine(mfR.ToString()); + /// + /// + /// a MFRect to be cast + /// A casted System.Drawing.Rectangle + public static implicit operator Rectangle(MFRect r) + { + return r.ToRectangle(); + } + + /// + /// Define implicit cast between System.Drawing.Rectangle and MFRect for languages supporting this feature. + /// VB.Net doesn't support implicit cast. for similar functionality. + /// + /// // Define a new MFRect instance + /// MFRect mfR = new MFRect(0, 0, 100, 100); + /// // Do implicit cast between MFRect and Rectangle + /// Rectangle r = mfR; + /// + /// Console.WriteLine(r.ToString()); + /// + /// + /// A System.Drawing.Rectangle to be cast + /// A casted MFRect + public static implicit operator MFRect(Rectangle r) + { + return new MFRect(r); + } + + /// + /// Get the System.Drawing.Rectangle equivalent to this MFRect instance. + /// + /// A System.Drawing.Rectangle + public Rectangle ToRectangle() + { + return new Rectangle(left, top, (right - left), (bottom - top)); + } + + /// + /// Get a new MFRect instance for a given + /// + /// The used to initialize this new MFGuid + /// A new instance of MFGuid + public static MFRect FromRectangle(Rectangle r) + { + return new MFRect(r); + } + + /// + /// Copy the members from an MFRect into this object + /// + /// The rectangle from which to copy the values. + public void CopyFrom(MFRect from) + { + left = from.left; + top = from.top; + right = from.right; + bottom = from.bottom; + } + } + + #endregion + + #region Utility Classes + + public static class MFError + { + #region Errors + + public const int MF_E_PLATFORM_NOT_INITIALIZED = unchecked((int)0xC00D36B0); + public const int MF_E_BUFFERTOOSMALL = unchecked((int)0xC00D36B1); + public const int MF_E_INVALIDREQUEST = unchecked((int)0xC00D36B2); + public const int MF_E_INVALIDSTREAMNUMBER = unchecked((int)0xC00D36B3); + public const int MF_E_INVALIDMEDIATYPE = unchecked((int)0xC00D36B4); + public const int MF_E_NOTACCEPTING = unchecked((int)0xC00D36B5); + public const int MF_E_NOT_INITIALIZED = unchecked((int)0xC00D36B6); + public const int MF_E_UNSUPPORTED_REPRESENTATION = unchecked((int)0xC00D36B7); + public const int MF_E_NO_MORE_TYPES = unchecked((int)0xC00D36B9); + public const int MF_E_UNSUPPORTED_SERVICE = unchecked((int)0xC00D36BA); + public const int MF_E_UNEXPECTED = unchecked((int)0xC00D36BB); + public const int MF_E_INVALIDNAME = unchecked((int)0xC00D36BC); + public const int MF_E_INVALIDTYPE = unchecked((int)0xC00D36BD); + public const int MF_E_INVALID_FILE_FORMAT = unchecked((int)0xC00D36BE); + public const int MF_E_INVALIDINDEX = unchecked((int)0xC00D36BF); + public const int MF_E_INVALID_TIMESTAMP = unchecked((int)0xC00D36C0); + public const int MF_E_UNSUPPORTED_SCHEME = unchecked((int)0xC00D36C3); + public const int MF_E_UNSUPPORTED_BYTESTREAM_TYPE = unchecked((int)0xC00D36C4); + public const int MF_E_UNSUPPORTED_TIME_FORMAT = unchecked((int)0xC00D36C5); + public const int MF_E_NO_SAMPLE_TIMESTAMP = unchecked((int)0xC00D36C8); + public const int MF_E_NO_SAMPLE_DURATION = unchecked((int)0xC00D36C9); + public const int MF_E_INVALID_STREAM_DATA = unchecked((int)0xC00D36CB); + public const int MF_E_RT_UNAVAILABLE = unchecked((int)0xC00D36CF); + public const int MF_E_UNSUPPORTED_RATE = unchecked((int)0xC00D36D0); + public const int MF_E_THINNING_UNSUPPORTED = unchecked((int)0xC00D36D1); + public const int MF_E_REVERSE_UNSUPPORTED = unchecked((int)0xC00D36D2); + public const int MF_E_UNSUPPORTED_RATE_TRANSITION = unchecked((int)0xC00D36D3); + public const int MF_E_RATE_CHANGE_PREEMPTED = unchecked((int)0xC00D36D4); + public const int MF_E_NOT_FOUND = unchecked((int)0xC00D36D5); + public const int MF_E_NOT_AVAILABLE = unchecked((int)0xC00D36D6); + public const int MF_E_NO_CLOCK = unchecked((int)0xC00D36D7); + public const int MF_S_MULTIPLE_BEGIN = unchecked((int)0x000D36D8); + public const int MF_E_MULTIPLE_BEGIN = unchecked((int)0xC00D36D9); + public const int MF_E_MULTIPLE_SUBSCRIBERS = unchecked((int)0xC00D36DA); + public const int MF_E_TIMER_ORPHANED = unchecked((int)0xC00D36DB); + public const int MF_E_STATE_TRANSITION_PENDING = unchecked((int)0xC00D36DC); + public const int MF_E_UNSUPPORTED_STATE_TRANSITION = unchecked((int)0xC00D36DD); + public const int MF_E_UNRECOVERABLE_ERROR_OCCURRED = unchecked((int)0xC00D36DE); + public const int MF_E_SAMPLE_HAS_TOO_MANY_BUFFERS = unchecked((int)0xC00D36DF); + public const int MF_E_SAMPLE_NOT_WRITABLE = unchecked((int)0xC00D36E0); + public const int MF_E_INVALID_KEY = unchecked((int)0xC00D36E2); + public const int MF_E_BAD_STARTUP_VERSION = unchecked((int)0xC00D36E3); + public const int MF_E_UNSUPPORTED_CAPTION = unchecked((int)0xC00D36E4); + public const int MF_E_INVALID_POSITION = unchecked((int)0xC00D36E5); + public const int MF_E_ATTRIBUTENOTFOUND = unchecked((int)0xC00D36E6); + public const int MF_E_PROPERTY_TYPE_NOT_ALLOWED = unchecked((int)0xC00D36E7); + public const int MF_E_PROPERTY_TYPE_NOT_SUPPORTED = unchecked((int)0xC00D36E8); + public const int MF_E_PROPERTY_EMPTY = unchecked((int)0xC00D36E9); + public const int MF_E_PROPERTY_NOT_EMPTY = unchecked((int)0xC00D36EA); + public const int MF_E_PROPERTY_VECTOR_NOT_ALLOWED = unchecked((int)0xC00D36EB); + public const int MF_E_PROPERTY_VECTOR_REQUIRED = unchecked((int)0xC00D36EC); + public const int MF_E_OPERATION_CANCELLED = unchecked((int)0xC00D36ED); + public const int MF_E_BYTESTREAM_NOT_SEEKABLE = unchecked((int)0xC00D36EE); + public const int MF_E_DISABLED_IN_SAFEMODE = unchecked((int)0xC00D36EF); + public const int MF_E_CANNOT_PARSE_BYTESTREAM = unchecked((int)0xC00D36F0); + public const int MF_E_SOURCERESOLVER_MUTUALLY_EXCLUSIVE_FLAGS = unchecked((int)0xC00D36F1); + public const int MF_E_MEDIAPROC_WRONGSTATE = unchecked((int)0xC00D36F2); + public const int MF_E_RT_THROUGHPUT_NOT_AVAILABLE = unchecked((int)0xC00D36F3); + public const int MF_E_RT_TOO_MANY_CLASSES = unchecked((int)0xC00D36F4); + public const int MF_E_RT_WOULDBLOCK = unchecked((int)0xC00D36F5); + public const int MF_E_NO_BITPUMP = unchecked((int)0xC00D36F6); + public const int MF_E_RT_OUTOFMEMORY = unchecked((int)0xC00D36F7); + public const int MF_E_RT_WORKQUEUE_CLASS_NOT_SPECIFIED = unchecked((int)0xC00D36F8); + public const int MF_E_INSUFFICIENT_BUFFER = unchecked((int)0xC00D7170); + public const int MF_E_CANNOT_CREATE_SINK = unchecked((int)0xC00D36FA); + public const int MF_E_BYTESTREAM_UNKNOWN_LENGTH = unchecked((int)0xC00D36FB); + public const int MF_E_SESSION_PAUSEWHILESTOPPED = unchecked((int)0xC00D36FC); + public const int MF_S_ACTIVATE_REPLACED = unchecked((int)0x000D36FD); + public const int MF_E_FORMAT_CHANGE_NOT_SUPPORTED = unchecked((int)0xC00D36FE); + public const int MF_E_INVALID_WORKQUEUE = unchecked((int)0xC00D36FF); + public const int MF_E_DRM_UNSUPPORTED = unchecked((int)0xC00D3700); + public const int MF_E_UNAUTHORIZED = unchecked((int)0xC00D3701); + public const int MF_E_OUT_OF_RANGE = unchecked((int)0xC00D3702); + public const int MF_E_INVALID_CODEC_MERIT = unchecked((int)0xC00D3703); + public const int MF_E_HW_MFT_FAILED_START_STREAMING = unchecked((int)0xC00D3704); + public const int MF_S_ASF_PARSEINPROGRESS = unchecked((int)0x400D3A98); + public const int MF_E_ASF_PARSINGINCOMPLETE = unchecked((int)0xC00D3A98); + public const int MF_E_ASF_MISSINGDATA = unchecked((int)0xC00D3A99); + public const int MF_E_ASF_INVALIDDATA = unchecked((int)0xC00D3A9A); + public const int MF_E_ASF_OPAQUEPACKET = unchecked((int)0xC00D3A9B); + public const int MF_E_ASF_NOINDEX = unchecked((int)0xC00D3A9C); + public const int MF_E_ASF_OUTOFRANGE = unchecked((int)0xC00D3A9D); + public const int MF_E_ASF_INDEXNOTLOADED = unchecked((int)0xC00D3A9E); + public const int MF_E_ASF_TOO_MANY_PAYLOADS = unchecked((int)0xC00D3A9F); + public const int MF_E_ASF_UNSUPPORTED_STREAM_TYPE = unchecked((int)0xC00D3AA0); + public const int MF_E_ASF_DROPPED_PACKET = unchecked((int)0xC00D3AA1); + public const int MF_E_NO_EVENTS_AVAILABLE = unchecked((int)0xC00D3E80); + public const int MF_E_INVALID_STATE_TRANSITION = unchecked((int)0xC00D3E82); + public const int MF_E_END_OF_STREAM = unchecked((int)0xC00D3E84); + public const int MF_E_SHUTDOWN = unchecked((int)0xC00D3E85); + public const int MF_E_MP3_NOTFOUND = unchecked((int)0xC00D3E86); + public const int MF_E_MP3_OUTOFDATA = unchecked((int)0xC00D3E87); + public const int MF_E_MP3_NOTMP3 = unchecked((int)0xC00D3E88); + public const int MF_E_MP3_NOTSUPPORTED = unchecked((int)0xC00D3E89); + public const int MF_E_NO_DURATION = unchecked((int)0xC00D3E8A); + public const int MF_E_INVALID_FORMAT = unchecked((int)0xC00D3E8C); + public const int MF_E_PROPERTY_NOT_FOUND = unchecked((int)0xC00D3E8D); + public const int MF_E_PROPERTY_READ_ONLY = unchecked((int)0xC00D3E8E); + public const int MF_E_PROPERTY_NOT_ALLOWED = unchecked((int)0xC00D3E8F); + public const int MF_E_MEDIA_SOURCE_NOT_STARTED = unchecked((int)0xC00D3E91); + public const int MF_E_UNSUPPORTED_FORMAT = unchecked((int)0xC00D3E98); + public const int MF_E_MP3_BAD_CRC = unchecked((int)0xC00D3E99); + public const int MF_E_NOT_PROTECTED = unchecked((int)0xC00D3E9A); + public const int MF_E_MEDIA_SOURCE_WRONGSTATE = unchecked((int)0xC00D3E9B); + public const int MF_E_MEDIA_SOURCE_NO_STREAMS_SELECTED = unchecked((int)0xC00D3E9C); + public const int MF_E_CANNOT_FIND_KEYFRAME_SAMPLE = unchecked((int)0xC00D3E9D); + public const int MF_E_NETWORK_RESOURCE_FAILURE = unchecked((int)0xC00D4268); + public const int MF_E_NET_WRITE = unchecked((int)0xC00D4269); + public const int MF_E_NET_READ = unchecked((int)0xC00D426A); + public const int MF_E_NET_REQUIRE_NETWORK = unchecked((int)0xC00D426B); + public const int MF_E_NET_REQUIRE_ASYNC = unchecked((int)0xC00D426C); + public const int MF_E_NET_BWLEVEL_NOT_SUPPORTED = unchecked((int)0xC00D426D); + public const int MF_E_NET_STREAMGROUPS_NOT_SUPPORTED = unchecked((int)0xC00D426E); + public const int MF_E_NET_MANUALSS_NOT_SUPPORTED = unchecked((int)0xC00D426F); + public const int MF_E_NET_INVALID_PRESENTATION_DESCRIPTOR = unchecked((int)0xC00D4270); + public const int MF_E_NET_CACHESTREAM_NOT_FOUND = unchecked((int)0xC00D4271); + public const int MF_I_MANUAL_PROXY = unchecked((int)0x400D4272); + public const int MF_E_NET_REQUIRE_INPUT = unchecked((int)0xC00D4274); + public const int MF_E_NET_REDIRECT = unchecked((int)0xC00D4275); + public const int MF_E_NET_REDIRECT_TO_PROXY = unchecked((int)0xC00D4276); + public const int MF_E_NET_TOO_MANY_REDIRECTS = unchecked((int)0xC00D4277); + public const int MF_E_NET_TIMEOUT = unchecked((int)0xC00D4278); + public const int MF_E_NET_CLIENT_CLOSE = unchecked((int)0xC00D4279); + public const int MF_E_NET_BAD_CONTROL_DATA = unchecked((int)0xC00D427A); + public const int MF_E_NET_INCOMPATIBLE_SERVER = unchecked((int)0xC00D427B); + public const int MF_E_NET_UNSAFE_URL = unchecked((int)0xC00D427C); + public const int MF_E_NET_CACHE_NO_DATA = unchecked((int)0xC00D427D); + public const int MF_E_NET_EOL = unchecked((int)0xC00D427E); + public const int MF_E_NET_BAD_REQUEST = unchecked((int)0xC00D427F); + public const int MF_E_NET_INTERNAL_SERVER_ERROR = unchecked((int)0xC00D4280); + public const int MF_E_NET_SESSION_NOT_FOUND = unchecked((int)0xC00D4281); + public const int MF_E_NET_NOCONNECTION = unchecked((int)0xC00D4282); + public const int MF_E_NET_CONNECTION_FAILURE = unchecked((int)0xC00D4283); + public const int MF_E_NET_INCOMPATIBLE_PUSHSERVER = unchecked((int)0xC00D4284); + public const int MF_E_NET_SERVER_ACCESSDENIED = unchecked((int)0xC00D4285); + public const int MF_E_NET_PROXY_ACCESSDENIED = unchecked((int)0xC00D4286); + public const int MF_E_NET_CANNOTCONNECT = unchecked((int)0xC00D4287); + public const int MF_E_NET_INVALID_PUSH_TEMPLATE = unchecked((int)0xC00D4288); + public const int MF_E_NET_INVALID_PUSH_PUBLISHING_POINT = unchecked((int)0xC00D4289); + public const int MF_E_NET_BUSY = unchecked((int)0xC00D428A); + public const int MF_E_NET_RESOURCE_GONE = unchecked((int)0xC00D428B); + public const int MF_E_NET_ERROR_FROM_PROXY = unchecked((int)0xC00D428C); + public const int MF_E_NET_PROXY_TIMEOUT = unchecked((int)0xC00D428D); + public const int MF_E_NET_SERVER_UNAVAILABLE = unchecked((int)0xC00D428E); + public const int MF_E_NET_TOO_MUCH_DATA = unchecked((int)0xC00D428F); + public const int MF_E_NET_SESSION_INVALID = unchecked((int)0xC00D4290); + public const int MF_E_OFFLINE_MODE = unchecked((int)0xC00D4291); + public const int MF_E_NET_UDP_BLOCKED = unchecked((int)0xC00D4292); + public const int MF_E_NET_UNSUPPORTED_CONFIGURATION = unchecked((int)0xC00D4293); + public const int MF_E_NET_PROTOCOL_DISABLED = unchecked((int)0xC00D4294); + public const int MF_E_ALREADY_INITIALIZED = unchecked((int)0xC00D4650); + public const int MF_E_BANDWIDTH_OVERRUN = unchecked((int)0xC00D4651); + public const int MF_E_LATE_SAMPLE = unchecked((int)0xC00D4652); + public const int MF_E_FLUSH_NEEDED = unchecked((int)0xC00D4653); + public const int MF_E_INVALID_PROFILE = unchecked((int)0xC00D4654); + public const int MF_E_INDEX_NOT_COMMITTED = unchecked((int)0xC00D4655); + public const int MF_E_NO_INDEX = unchecked((int)0xC00D4656); + public const int MF_E_CANNOT_INDEX_IN_PLACE = unchecked((int)0xC00D4657); + public const int MF_E_MISSING_ASF_LEAKYBUCKET = unchecked((int)0xC00D4658); + public const int MF_E_INVALID_ASF_STREAMID = unchecked((int)0xC00D4659); + public const int MF_E_STREAMSINK_REMOVED = unchecked((int)0xC00D4A38); + public const int MF_E_STREAMSINKS_OUT_OF_SYNC = unchecked((int)0xC00D4A3A); + public const int MF_E_STREAMSINKS_FIXED = unchecked((int)0xC00D4A3B); + public const int MF_E_STREAMSINK_EXISTS = unchecked((int)0xC00D4A3C); + public const int MF_E_SAMPLEALLOCATOR_CANCELED = unchecked((int)0xC00D4A3D); + public const int MF_E_SAMPLEALLOCATOR_EMPTY = unchecked((int)0xC00D4A3E); + public const int MF_E_SINK_ALREADYSTOPPED = unchecked((int)0xC00D4A3F); + public const int MF_E_ASF_FILESINK_BITRATE_UNKNOWN = unchecked((int)0xC00D4A40); + public const int MF_E_SINK_NO_STREAMS = unchecked((int)0xC00D4A41); + public const int MF_S_SINK_NOT_FINALIZED = unchecked((int)0x000D4A42); + public const int MF_E_METADATA_TOO_LONG = unchecked((int)0xC00D4A43); + public const int MF_E_SINK_NO_SAMPLES_PROCESSED = unchecked((int)0xC00D4A44); + public const int MF_E_VIDEO_REN_NO_PROCAMP_HW = unchecked((int)0xC00D4E20); + public const int MF_E_VIDEO_REN_NO_DEINTERLACE_HW = unchecked((int)0xC00D4E21); + public const int MF_E_VIDEO_REN_COPYPROT_FAILED = unchecked((int)0xC00D4E22); + public const int MF_E_VIDEO_REN_SURFACE_NOT_SHARED = unchecked((int)0xC00D4E23); + public const int MF_E_VIDEO_DEVICE_LOCKED = unchecked((int)0xC00D4E24); + public const int MF_E_NEW_VIDEO_DEVICE = unchecked((int)0xC00D4E25); + public const int MF_E_NO_VIDEO_SAMPLE_AVAILABLE = unchecked((int)0xC00D4E26); + public const int MF_E_NO_AUDIO_PLAYBACK_DEVICE = unchecked((int)0xC00D4E84); + public const int MF_E_AUDIO_PLAYBACK_DEVICE_IN_USE = unchecked((int)0xC00D4E85); + public const int MF_E_AUDIO_PLAYBACK_DEVICE_INVALIDATED = unchecked((int)0xC00D4E86); + public const int MF_E_AUDIO_SERVICE_NOT_RUNNING = unchecked((int)0xC00D4E87); + public const int MF_E_TOPO_INVALID_OPTIONAL_NODE = unchecked((int)0xC00D520E); + public const int MF_E_TOPO_CANNOT_FIND_DECRYPTOR = unchecked((int)0xC00D5211); + public const int MF_E_TOPO_CODEC_NOT_FOUND = unchecked((int)0xC00D5212); + public const int MF_E_TOPO_CANNOT_CONNECT = unchecked((int)0xC00D5213); + public const int MF_E_TOPO_UNSUPPORTED = unchecked((int)0xC00D5214); + public const int MF_E_TOPO_INVALID_TIME_ATTRIBUTES = unchecked((int)0xC00D5215); + public const int MF_E_TOPO_LOOPS_IN_TOPOLOGY = unchecked((int)0xC00D5216); + public const int MF_E_TOPO_MISSING_PRESENTATION_DESCRIPTOR = unchecked((int)0xC00D5217); + public const int MF_E_TOPO_MISSING_STREAM_DESCRIPTOR = unchecked((int)0xC00D5218); + public const int MF_E_TOPO_STREAM_DESCRIPTOR_NOT_SELECTED = unchecked((int)0xC00D5219); + public const int MF_E_TOPO_MISSING_SOURCE = unchecked((int)0xC00D521A); + public const int MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED = unchecked((int)0xC00D521B); + public const int MF_E_SEQUENCER_UNKNOWN_SEGMENT_ID = unchecked((int)0xC00D61AC); + public const int MF_S_SEQUENCER_CONTEXT_CANCELED = unchecked((int)0x000D61AD); + public const int MF_E_NO_SOURCE_IN_CACHE = unchecked((int)0xC00D61AE); + public const int MF_S_SEQUENCER_SEGMENT_AT_END_OF_STREAM = unchecked((int)0x000D61AF); + public const int MF_E_TRANSFORM_TYPE_NOT_SET = unchecked((int)0xC00D6D60); + public const int MF_E_TRANSFORM_STREAM_CHANGE = unchecked((int)0xC00D6D61); + public const int MF_E_TRANSFORM_INPUT_REMAINING = unchecked((int)0xC00D6D62); + public const int MF_E_TRANSFORM_PROFILE_MISSING = unchecked((int)0xC00D6D63); + public const int MF_E_TRANSFORM_PROFILE_INVALID_OR_CORRUPT = unchecked((int)0xC00D6D64); + public const int MF_E_TRANSFORM_PROFILE_TRUNCATED = unchecked((int)0xC00D6D65); + public const int MF_E_TRANSFORM_PROPERTY_PID_NOT_RECOGNIZED = unchecked((int)0xC00D6D66); + public const int MF_E_TRANSFORM_PROPERTY_VARIANT_TYPE_WRONG = unchecked((int)0xC00D6D67); + public const int MF_E_TRANSFORM_PROPERTY_NOT_WRITEABLE = unchecked((int)0xC00D6D68); + public const int MF_E_TRANSFORM_PROPERTY_ARRAY_VALUE_WRONG_NUM_DIM = unchecked((int)0xC00D6D69); + public const int MF_E_TRANSFORM_PROPERTY_VALUE_SIZE_WRONG = unchecked((int)0xC00D6D6A); + public const int MF_E_TRANSFORM_PROPERTY_VALUE_OUT_OF_RANGE = unchecked((int)0xC00D6D6B); + public const int MF_E_TRANSFORM_PROPERTY_VALUE_INCOMPATIBLE = unchecked((int)0xC00D6D6C); + public const int MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_OUTPUT_MEDIATYPE = unchecked((int)0xC00D6D6D); + public const int MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_INPUT_MEDIATYPE = unchecked((int)0xC00D6D6E); + public const int MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_MEDIATYPE_COMBINATION = unchecked((int)0xC00D6D6F); + public const int MF_E_TRANSFORM_CONFLICTS_WITH_OTHER_CURRENTLY_ENABLED_FEATURES = unchecked((int)0xC00D6D70); + public const int MF_E_TRANSFORM_NEED_MORE_INPUT = unchecked((int)0xC00D6D72); + public const int MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_SPKR_CONFIG = unchecked((int)0xC00D6D73); + public const int MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING = unchecked((int)0xC00D6D74); + public const int MF_S_TRANSFORM_DO_NOT_PROPAGATE_EVENT = unchecked((int)0x000D6D75); + public const int MF_E_UNSUPPORTED_D3D_TYPE = unchecked((int)0xC00D6D76); + public const int MF_E_TRANSFORM_ASYNC_LOCKED = unchecked((int)0xC00D6D77); + public const int MF_E_TRANSFORM_CANNOT_INITIALIZE_ACM_DRIVER = unchecked((int)0xC00D6D78L); + public const int MF_E_LICENSE_INCORRECT_RIGHTS = unchecked((int)0xC00D7148); + public const int MF_E_LICENSE_OUTOFDATE = unchecked((int)0xC00D7149); + public const int MF_E_LICENSE_REQUIRED = unchecked((int)0xC00D714A); + public const int MF_E_DRM_HARDWARE_INCONSISTENT = unchecked((int)0xC00D714B); + public const int MF_E_NO_CONTENT_PROTECTION_MANAGER = unchecked((int)0xC00D714C); + public const int MF_E_LICENSE_RESTORE_NO_RIGHTS = unchecked((int)0xC00D714D); + public const int MF_E_BACKUP_RESTRICTED_LICENSE = unchecked((int)0xC00D714E); + public const int MF_E_LICENSE_RESTORE_NEEDS_INDIVIDUALIZATION = unchecked((int)0xC00D714F); + public const int MF_S_PROTECTION_NOT_REQUIRED = unchecked((int)0x000D7150); + public const int MF_E_COMPONENT_REVOKED = unchecked((int)0xC00D7151); + public const int MF_E_TRUST_DISABLED = unchecked((int)0xC00D7152); + public const int MF_E_WMDRMOTA_NO_ACTION = unchecked((int)0xC00D7153); + public const int MF_E_WMDRMOTA_ACTION_ALREADY_SET = unchecked((int)0xC00D7154); + public const int MF_E_WMDRMOTA_DRM_HEADER_NOT_AVAILABLE = unchecked((int)0xC00D7155); + public const int MF_E_WMDRMOTA_DRM_ENCRYPTION_SCHEME_NOT_SUPPORTED = unchecked((int)0xC00D7156); + public const int MF_E_WMDRMOTA_ACTION_MISMATCH = unchecked((int)0xC00D7157); + public const int MF_E_WMDRMOTA_INVALID_POLICY = unchecked((int)0xC00D7158); + public const int MF_E_POLICY_UNSUPPORTED = unchecked((int)0xC00D7159); + public const int MF_E_OPL_NOT_SUPPORTED = unchecked((int)0xC00D715A); + public const int MF_E_TOPOLOGY_VERIFICATION_FAILED = unchecked((int)0xC00D715B); + public const int MF_E_SIGNATURE_VERIFICATION_FAILED = unchecked((int)0xC00D715C); + public const int MF_E_DEBUGGING_NOT_ALLOWED = unchecked((int)0xC00D715D); + public const int MF_E_CODE_EXPIRED = unchecked((int)0xC00D715E); + public const int MF_E_GRL_VERSION_TOO_LOW = unchecked((int)0xC00D715F); + public const int MF_E_GRL_RENEWAL_NOT_FOUND = unchecked((int)0xC00D7160); + public const int MF_E_GRL_EXTENSIBLE_ENTRY_NOT_FOUND = unchecked((int)0xC00D7161); + public const int MF_E_KERNEL_UNTRUSTED = unchecked((int)0xC00D7162); + public const int MF_E_PEAUTH_UNTRUSTED = unchecked((int)0xC00D7163); + public const int MF_E_NON_PE_PROCESS = unchecked((int)0xC00D7165); + public const int MF_E_REBOOT_REQUIRED = unchecked((int)0xC00D7167); + public const int MF_S_WAIT_FOR_POLICY_SET = unchecked((int)0x000D7168); + public const int MF_S_VIDEO_DISABLED_WITH_UNKNOWN_SOFTWARE_OUTPUT = unchecked((int)0x000D7169); + public const int MF_E_GRL_INVALID_FORMAT = unchecked((int)0xC00D716A); + public const int MF_E_GRL_UNRECOGNIZED_FORMAT = unchecked((int)0xC00D716B); + public const int MF_E_ALL_PROCESS_RESTART_REQUIRED = unchecked((int)0xC00D716C); + public const int MF_E_PROCESS_RESTART_REQUIRED = unchecked((int)0xC00D716D); + public const int MF_E_USERMODE_UNTRUSTED = unchecked((int)0xC00D716E); + public const int MF_E_PEAUTH_SESSION_NOT_STARTED = unchecked((int)0xC00D716F); + public const int MF_E_PEAUTH_PUBLICKEY_REVOKED = unchecked((int)0xC00D7171); + public const int MF_E_GRL_ABSENT = unchecked((int)0xC00D7172); + public const int MF_S_PE_TRUSTED = unchecked((int)0x000D7173); + public const int MF_E_PE_UNTRUSTED = unchecked((int)0xC00D7174); + public const int MF_E_PEAUTH_NOT_STARTED = unchecked((int)0xC00D7175); + public const int MF_E_INCOMPATIBLE_SAMPLE_PROTECTION = unchecked((int)0xC00D7176); + public const int MF_E_PE_SESSIONS_MAXED = unchecked((int)0xC00D7177); + public const int MF_E_HIGH_SECURITY_LEVEL_CONTENT_NOT_ALLOWED = unchecked((int)0xC00D7178); + public const int MF_E_TEST_SIGNED_COMPONENTS_NOT_ALLOWED = unchecked((int)0xC00D7179); + public const int MF_E_ITA_UNSUPPORTED_ACTION = unchecked((int)0xC00D717A); + public const int MF_E_ITA_ERROR_PARSING_SAP_PARAMETERS = unchecked((int)0xC00D717B); + public const int MF_E_POLICY_MGR_ACTION_OUTOFBOUNDS = unchecked((int)0xC00D717C); + public const int MF_E_BAD_OPL_STRUCTURE_FORMAT = unchecked((int)0xC00D717D); + public const int MF_E_ITA_UNRECOGNIZED_ANALOG_VIDEO_PROTECTION_GUID = unchecked((int)0xC00D717E); + public const int MF_E_NO_PMP_HOST = unchecked((int)0xC00D717F); + public const int MF_E_ITA_OPL_DATA_NOT_INITIALIZED = unchecked((int)0xC00D7180); + public const int MF_E_ITA_UNRECOGNIZED_ANALOG_VIDEO_OUTPUT = unchecked((int)0xC00D7181); + public const int MF_E_ITA_UNRECOGNIZED_DIGITAL_VIDEO_OUTPUT = unchecked((int)0xC00D7182); + public const int MF_E_CLOCK_INVALID_CONTINUITY_KEY = unchecked((int)0xC00D9C40); + public const int MF_E_CLOCK_NO_TIME_SOURCE = unchecked((int)0xC00D9C41); + public const int MF_E_CLOCK_STATE_ALREADY_SET = unchecked((int)0xC00D9C42); + public const int MF_E_CLOCK_NOT_SIMPLE = unchecked((int)0xC00D9C43); + public const int MF_S_CLOCK_STOPPED = unchecked((int)0x000D9C44); + public const int MF_E_NO_MORE_DROP_MODES = unchecked((int)0xC00DA028); + public const int MF_E_NO_MORE_QUALITY_LEVELS = unchecked((int)0xC00DA029); + public const int MF_E_DROPTIME_NOT_SUPPORTED = unchecked((int)0xC00DA02A); + public const int MF_E_QUALITYKNOB_WAIT_LONGER = unchecked((int)0xC00DA02B); + public const int MF_E_QM_INVALIDSTATE = unchecked((int)0xC00DA02C); + public const int MF_E_TRANSCODE_NO_CONTAINERTYPE = unchecked((int)0xC00DA410); + public const int MF_E_TRANSCODE_PROFILE_NO_MATCHING_STREAMS = unchecked((int)0xC00DA411); + public const int MF_E_TRANSCODE_NO_MATCHING_ENCODER = unchecked((int)0xC00DA412); + public const int MF_E_ALLOCATOR_NOT_INITIALIZED = unchecked((int)0xC00DA7F8); + public const int MF_E_ALLOCATOR_NOT_COMMITED = unchecked((int)0xC00DA7F9); + public const int MF_E_ALLOCATOR_ALREADY_COMMITED = unchecked((int)0xC00DA7FA); + public const int MF_E_STREAM_ERROR = unchecked((int)0xC00DA7FB); + public const int MF_E_INVALID_STREAM_STATE = unchecked((int)0xC00DA7FC); + public const int MF_E_HW_STREAM_NOT_CONNECTED = unchecked((int)0xC00DA7FD); + + #endregion + + #region externs + + [DllImport("kernel32.dll", CharSet = CharSet.Unicode, EntryPoint = "FormatMessageW", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + private static extern int FormatMessage(FormatMessageFlags dwFlags, IntPtr lpSource, + int dwMessageId, int dwLanguageId, out IntPtr lpBuffer, int nSize, IntPtr[] Arguments); + + [DllImport("kernel32.dll", CharSet = CharSet.Unicode, EntryPoint = "LoadLibraryExW", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + private static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, LoadLibraryExFlags dwFlags); + + [DllImport("kernel32.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool FreeLibrary(IntPtr hFile); + + [DllImport("kernel32.dll", ExactSpelling = true), SuppressUnmanagedCodeSecurity] + private static extern IntPtr LocalFree(IntPtr hMem); + + #endregion + + #region Declarations + + [Flags, UnmanagedName("#defines in WinBase.h")] + private enum LoadLibraryExFlags + { + DontResolveDllReferences = 0x00000001, + LoadLibraryAsDataFile = 0x00000002, + LoadWithAlteredSearchPath = 0x00000008, + LoadIgnoreCodeAuthzLevel = 0x00000010 + } + + [Flags, UnmanagedName("FORMAT_MESSAGE_* defines")] + private enum FormatMessageFlags + { + AllocateBuffer = 0x00000100, + IgnoreInserts = 0x00000200, + FromString = 0x00000400, + FromHmodule = 0x00000800, + FromSystem = 0x00001000, + ArgumentArray = 0x00002000, + MaxWidthMask = 0x000000FF + } + + #endregion + + private static IntPtr s_hModule = IntPtr.Zero; + private const string MESSAGEFILE = "mferror.dll"; + + /// + /// Returns a string describing a MF error. Works for both error codes + /// (values < 0) and Status codes (values >= 0) + /// + /// HRESULT for which to get description + /// The string, or null if no error text can be found + public static string GetErrorText(int hr) + { + string sRet = null; + int dwBufferLength; + IntPtr ip = IntPtr.Zero; + + FormatMessageFlags dwFormatFlags = + FormatMessageFlags.AllocateBuffer | + FormatMessageFlags.IgnoreInserts | + FormatMessageFlags.FromSystem | + FormatMessageFlags.MaxWidthMask; + + // Scan both the Windows Media library, and the system library looking for the message + dwBufferLength = FormatMessage( + dwFormatFlags, + s_hModule, // module to get message from (NULL == system) + hr, // error number to get message for + 0, // default language + out ip, + 0, + null + ); + + // Not a system message. In theory, you should be able to get both with one call. In practice (at + // least on my 64bit box), you need to make 2 calls. + if (dwBufferLength == 0) + { + if (s_hModule == IntPtr.Zero) + { + // Load the Media Foundation error message dll + s_hModule = LoadLibraryEx(MESSAGEFILE, IntPtr.Zero, LoadLibraryExFlags.LoadLibraryAsDataFile); + } + + if (s_hModule != IntPtr.Zero) + { + // If the load succeeds, make sure we look in it + dwFormatFlags |= FormatMessageFlags.FromHmodule; + + // Scan both the Windows Media library, and the system library looking for the message + dwBufferLength = FormatMessage( + dwFormatFlags, + s_hModule, // module to get message from (NULL == system) + hr, // error number to get message for + 0, // default language + out ip, + 0, + null + ); + } + } + + try + { + // Convert the returned buffer to a string. If ip is null (due to not finding + // the message), no exception is thrown. sRet just stays null. The + // try/finally is for the (remote) possibility that we run out of memory + // creating the string. + sRet = Marshal.PtrToStringUni(ip); + } + finally + { + // Cleanup + if (ip != IntPtr.Zero) + { + LocalFree(ip); + } + } + + return sRet; + } + + /// + /// If hr has a "failed" status code (E_*), throw an exception. Note that status + /// messages (S_*) are not considered failure codes. If MediaFoundation error text + /// is available, it is used to build the exception, otherwise a generic com error + /// is thrown. + /// + /// The HRESULT to check + public static void ThrowExceptionForHR(int hr) + { + // If a severe error has occurred + if (hr < 0) + { + string s = GetErrorText(hr); + + // If a string is returned, build a COM error from it + if (s != null) + { + throw new COMException(s, hr); + } + else + { + // No string, just use standard com error + Marshal.ThrowExceptionForHR(hr); + } + } + } + } + + abstract public class COMBase + { + public const int S_Ok = 0; + public const int S_False = 1; + + public const int E_NotImplemented = unchecked((int)0x80004001); + public const int E_NoInterface = unchecked((int)0x80004002); + public const int E_Pointer = unchecked((int)0x80004003); + public const int E_Abort = unchecked((int)0x80004004); + public const int E_Fail = unchecked((int)0x80004005); + public const int E_Unexpected = unchecked((int)0x8000FFFF); + public const int E_OutOfMemory = unchecked((int)0x8007000E); + public const int E_InvalidArgument = unchecked((int)0x80070057); + public const int E_BufferTooSmall = unchecked((int)0x8007007a); + + public static bool Succeeded(int hr) + { + return hr >= 0; + } + + public static bool Failed(int hr) + { + return hr < 0; + } + + public static void SafeRelease(object o) + { + if (o != null) + { + if (Marshal.IsComObject(o)) + { + int i = Marshal.ReleaseComObject(o); + Debug.Assert(i >= 0); + } + else + { + IDisposable iDis = o as IDisposable; + if (iDis != null) + { + iDis.Dispose(); + } + else + { + throw new Exception("What the heck was that?"); + } + } + } + } + + public static void TRACE(string s) + { + Debug.WriteLine(s); + } + } + + #endregion + + #region Internal classes + + // These classes are used internally and there is probably no reason you will ever + // need to use them directly. + + // Class to release PropVariants on parameters that output PropVariants. There + // should be no reason for code to call this class directly. It is invoked + // automatically when the appropriate methods are called. + internal class PVMarshaler : ICustomMarshaler + { + // The managed object passed in to MarshalManagedToNative + protected PropVariant m_prop; + + public IntPtr MarshalManagedToNative(object managedObj) + { + IntPtr p; + + // Cast the object back to a PropVariant + m_prop = managedObj as PropVariant; + + if (m_prop != null) + { + // Release any memory currently allocated + m_prop.Clear(); + + // Create an appropriately sized buffer, blank it, and send it to + // the marshaler to make the COM call with. + int iSize = GetNativeDataSize(); + p = Marshal.AllocCoTaskMem(iSize); + + if (IntPtr.Size == 4) + { + Marshal.WriteInt64(p, 0); + Marshal.WriteInt64(p, 8, 0); + } + else + { + Marshal.WriteInt64(p, 0); + Marshal.WriteInt64(p, 8, 0); + Marshal.WriteInt64(p, 16, 0); + } + } + else + { + p = IntPtr.Zero; + } + + 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. + public object MarshalNativeToManaged(IntPtr pNativeData) + { + Marshal.PtrToStructure(pNativeData, m_prop); + m_prop = null; + + return m_prop; + } + + public void CleanUpManagedData(object ManagedObj) + { + m_prop = null; + } + + public void CleanUpNativeData(IntPtr pNativeData) + { + Marshal.FreeCoTaskMem(pNativeData); + } + + // The number of bytes to marshal out + public int GetNativeDataSize() + { + return Marshal.SizeOf(typeof(PropVariant)); + } + + // 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 PVMarshaler(); + } + } + + // Used by MFTGetInfo + internal class RTIMarshaler : ICustomMarshaler + { + private ArrayList m_array; + private MFInt m_int; + private IntPtr m_MFIntPtr; + private IntPtr m_ArrayPtr; + + public IntPtr MarshalManagedToNative(object managedObj) + { + IntPtr p; + + // We get called twice: Once for the MFInt, and once for the array. + // Figure out which call this is. + if (managedObj is MFInt) + { + // Save off the object. We'll need to use Assign() on this later. + m_int = managedObj as MFInt; + + // Allocate room for the int + p = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(MFInt))); + m_MFIntPtr = p; + } + else + { + // Save off the object. We'll be calling methods on this in + // MarshalNativeToManaged. + m_array = managedObj as ArrayList; + + if (m_array != null) + { + m_array.Clear(); + } + + // All we need is room for the pointer + p = Marshal.AllocCoTaskMem(IntPtr.Size); + + // Belt-and-suspenders. Set this to null. + Marshal.WriteIntPtr(p, IntPtr.Zero); + m_ArrayPtr = p; + } + + 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. + public object MarshalNativeToManaged(IntPtr pNativeData) + { + // When we are called with pNativeData == m_ArrayPtr, do nothing. All the + // work is done when: + if (pNativeData == m_MFIntPtr) + { + // Read the count + int count = Marshal.ReadInt32(pNativeData); + + // If we have an array to return things in (ie MFTGetInfo wasn't passed + // nulls) + if (m_array != null) + { + IntPtr ip2 = Marshal.ReadIntPtr(m_ArrayPtr); + + // I don't know why this might happen, but it seems worth the check + if (ip2 != IntPtr.Zero) + { + try + { + int iSize = Marshal.SizeOf(typeof(MFTRegisterTypeInfo)); + + // Size the array + m_array.Capacity = count; + + // Copy in the values + for (int x = 0; x < count; x++) + { + MFTRegisterTypeInfo rti = new MFTRegisterTypeInfo(); + Marshal.PtrToStructure(new IntPtr(ip2.ToInt64() + (x * iSize)), rti); + m_array.Add(rti); + } + } + finally + { + // Free the array we got back + Marshal.FreeCoTaskMem(ip2); + } + } + } + + // Don't forget to assign the value + m_int.Assign(count); + + m_int = null; + m_array = null; + } + + // This value isn't actually used + return null; + } + + public void CleanUpManagedData(object ManagedObj) + { + } + + public void CleanUpNativeData(IntPtr pNativeData) + { + Marshal.FreeCoTaskMem(pNativeData); + } + + // The number of bytes to marshal out + public int GetNativeDataSize() + { + return -1; + } + + // When used with MFTGetInfo, there are 2 parameter pairs (ppInputTypes + pcInputTypes, + // ppOutputTypes + pcOutputTypes). Each need their own instance + static RTIMarshaler[] s_rti = new RTIMarshaler[2]; + + // 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) + { + // Probably not an issue, but just to be safe + lock (s_rti) + { + if (s_rti[0] == null) + { + s_rti[0] = new RTIMarshaler(); + s_rti[1] = new RTIMarshaler(); + } + } + + int i = Convert.ToInt32(cookie); + return s_rti[i]; + } + } + + // Used by MFTRegister + internal class RTAMarshaler : ICustomMarshaler + { + public IntPtr MarshalManagedToNative(object managedObj) + { + IntPtr p; + + int iSize = Marshal.SizeOf(typeof(MFTRegisterTypeInfo)); + + // Save off the object. We'll be calling methods on this in + // MarshalNativeToManaged. + MFTRegisterTypeInfo[] array = managedObj as MFTRegisterTypeInfo[]; + + // All we need is room for the pointer + p = Marshal.AllocCoTaskMem(array.Length * iSize); + + for (int x = 0; x < array.Length; x++) + { + Marshal.StructureToPtr(array[x], new IntPtr(p.ToInt64() + (x * iSize)), false); + } + + return p; + } + + public object MarshalNativeToManaged(IntPtr pNativeData) + { + // This value isn't actually used + return null; + } + + public void CleanUpManagedData(object ManagedObj) + { + } + + public void CleanUpNativeData(IntPtr pNativeData) + { + Marshal.FreeCoTaskMem(pNativeData); + } + + // The number of bytes to marshal out + public int GetNativeDataSize() + { + return -1; + } + + // 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 RTAMarshaler(); + } + } + + // Used by MFTEnum + internal class GAMarshaler : ICustomMarshaler + { + private ArrayList m_array; + private MFInt m_int; + private IntPtr m_MFIntPtr; + private IntPtr m_ArrayPtr; + + public IntPtr MarshalManagedToNative(object managedObj) + { + IntPtr p; + + // We get called twice: Once for the MFInt, and once for the array. + // Figure out which call this is. + if (managedObj is MFInt) + { + // Save off the object. We'll need to use Assign() on this later. + m_int = managedObj as MFInt; + + // Allocate room for the int + p = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(MFInt))); + m_MFIntPtr = p; + } + else + { + // Save off the object. We'll be calling methods on this in + // MarshalNativeToManaged. + m_array = managedObj as ArrayList; + + if (m_array != null) + { + m_array.Clear(); + } + + // All we need is room for the pointer + p = Marshal.AllocCoTaskMem(IntPtr.Size); + + // Belt-and-suspenders. Set this to null. + Marshal.WriteIntPtr(p, IntPtr.Zero); + m_ArrayPtr = p; + } + + 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. + public object MarshalNativeToManaged(IntPtr pNativeData) + { + // When we are called with pNativeData == m_ArrayPtr, do nothing. All the + // work is done when: + if (pNativeData == m_MFIntPtr) + { + // Read the count + int count = Marshal.ReadInt32(pNativeData); + + // If we have an array to return things in (ie MFTGetInfo wasn't passed + // nulls) + if (m_array != null) + { + IntPtr ip2 = Marshal.ReadIntPtr(m_ArrayPtr); + + // I don't know why this might happen, but it seems worth the check + if (ip2 != IntPtr.Zero) + { + try + { + int iSize = Marshal.SizeOf(typeof(Guid)); + // Size the array + m_array.Capacity = count; + byte[] b = new byte[iSize]; + + // Copy in the values + for (int x = 0; x < count; x++) + { + Marshal.Copy(new IntPtr(ip2.ToInt64() + (x * iSize)), b, 0, iSize); + m_array.Add(new Guid(b)); + } + } + finally + { + // Free the array we got back + Marshal.FreeCoTaskMem(ip2); + } + } + } + + // Don't forget to assign the value + m_int.Assign(count); + + m_array = null; + m_int = null; + } + + // This value isn't actually used + return null; + } + + public void CleanUpManagedData(object ManagedObj) + { + } + + public void CleanUpNativeData(IntPtr pNativeData) + { + Marshal.FreeCoTaskMem(pNativeData); + } + + // The number of bytes to marshal out + public int GetNativeDataSize() + { + return -1; + } + + // 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 GAMarshaler(); + } + } + + // Class to handle WAVEFORMATEXTENSIBLE + internal class WEMarshaler : ICustomMarshaler + { + public IntPtr MarshalManagedToNative(object managedObj) + { + WaveFormatEx wfe = managedObj as WaveFormatEx; + + IntPtr ip = wfe.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) + { + WaveFormatEx wfe = WaveFormatEx.PtrToWave(pNativeData); + + return wfe; + } + + public void CleanUpManagedData(object ManagedObj) + { + } + + public void CleanUpNativeData(IntPtr pNativeData) + { + Marshal.FreeCoTaskMem(pNativeData); + } + + // The number of bytes to marshal out - never called + public int GetNativeDataSize() + { + return -1; + } + + // 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 WEMarshaler(); + } + } + + // Class to handle BITMAPINFO + internal class BMMarshaler : ICustomMarshaler + { + protected BitmapInfoHeader m_bmi; + + public IntPtr MarshalManagedToNative(object managedObj) + { + m_bmi = managedObj as 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) + { + BitmapInfoHeader bmi = 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; + } + + public void CleanUpManagedData(object ManagedObj) + { + m_bmi = null; + } + + public void CleanUpNativeData(IntPtr pNativeData) + { + Marshal.FreeCoTaskMem(pNativeData); + } + + // The number of bytes to marshal out - never called + public int GetNativeDataSize() + { + return -1; + } + + // 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 BMMarshaler(); + } + } + + // Class to handle Array of Guid + internal class GMarshaler : ICustomMarshaler + { + protected Guid[] m_Obj; + protected IntPtr m_ip; + + public IntPtr MarshalManagedToNative(object managedObj) + { + if (m_ip == IntPtr.Zero) + { + // If we are being called first from managed + + m_Obj = (Guid[])managedObj; + // Freed in CleanUpManagedData + m_ip = Marshal.AllocCoTaskMem(IntPtr.Size); + } + else + { + // Return the value to native + Guid [] mo = (Guid [])managedObj; + + IntPtr ip = Marshal.AllocCoTaskMem(16 * mo.Length); + Marshal.WriteIntPtr(m_ip, ip); + + for (int x = 0; (mo[x] != Guid.Empty) && (x < mo.Length); x++) + { + Marshal.StructureToPtr(mo[x], ip, false); + ip = new IntPtr(ip.ToInt64() + 16); + } + } + return m_ip; + } + + public object MarshalNativeToManaged(IntPtr pNativeData) + { + if (m_Obj != null) + { + // Return the value to managed + byte[] b = new byte[16]; + IntPtr pBuff = Marshal.ReadIntPtr(pNativeData); + for (int x = 0; x < m_Obj.Length; x++) + { + Marshal.Copy(pBuff, b, 0, 16); + m_Obj[x] = new Guid(b); + + pBuff = new IntPtr(pBuff.ToInt64() + 16); + } + + Marshal.FreeCoTaskMem(Marshal.ReadIntPtr(pNativeData)); + } + else + { + // If we are being called first from native + m_ip = pNativeData; + return new Guid[30]; + } + + return null; + } + + public void CleanUpManagedData(object ManagedObj) + { + m_Obj = null; + } + + public void CleanUpNativeData(IntPtr pNativeData) + { + Marshal.FreeCoTaskMem(pNativeData); + } + + // The number of bytes to marshal out - never called + public int GetNativeDataSize() + { + return -1; + } + + // 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 GMarshaler(); + } + } + + [AttributeUsage(AttributeTargets.Enum | AttributeTargets.Struct | AttributeTargets.Class)] + public class UnmanagedNameAttribute : System.Attribute + { + private string m_Name; + + public UnmanagedNameAttribute(string s) + { + m_Name = s; + } + + public override string ToString() + { + return m_Name; + } + } + + #endregion +} diff --git a/MediaFoundation/MediaFoundation-2010.sln b/MediaFoundation/MediaFoundation-2010.sln new file mode 100644 index 0000000..86e1985 --- /dev/null +++ b/MediaFoundation/MediaFoundation-2010.sln @@ -0,0 +1,32 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaFoundation-2010", "MediaFoundation-2010.csproj", "{B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Debug|x64.ActiveCfg = Debug|x64 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Debug|x64.Build.0 = Debug|x64 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Debug|x86.ActiveCfg = Debug|x86 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Debug|x86.Build.0 = Debug|x86 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Release|Any CPU.Build.0 = Release|Any CPU + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Release|x64.ActiveCfg = Release|x64 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Release|x64.Build.0 = Release|x64 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Release|x86.ActiveCfg = Release|x86 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/MediaFoundation/MediaFoundation.csproj b/MediaFoundation/MediaFoundation.csproj new file mode 100644 index 0000000..b7029b3 --- /dev/null +++ b/MediaFoundation/MediaFoundation.csproj @@ -0,0 +1,141 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {B78C0F3B-071A-4FD2-829D-7A67E0F7BD1C} + Library + Properties + MediaFoundation + MediaFoundation + true + MediaFoundation.snk + + + 3.5 + + + v3.5 + false + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + true + full + false + bin\Debug\ + TRACE;DEBUG;ALLOW_UNTESTED_INTERFACES + prompt + 4 + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + bin\x86\Debug\ + TRACE;DEBUG;ALLOW_UNTESTED_INTERFACES + full + x86 + prompt + false + + + bin\x86\Release\ + TRACE + true + pdbonly + x86 + prompt + + + true + bin\x64\Debug\ + TRACE;DEBUG;ALLOW_UNTESTED_INTERFACES + full + x64 + prompt + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + prompt + + + + + + + + + + + + + + + + + + + + + + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + + + + + + + + + + + \ No newline at end of file diff --git a/MediaFoundation/MediaFoundation.snk b/MediaFoundation/MediaFoundation.snk new file mode 100644 index 0000000000000000000000000000000000000000..5d9d162181c19fed3d7e2173eae96b8b036a021c GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50097*dkJ@yP&(6pkEr5d*e5vbldt;1yWXbY z2J$S1vm`NOM`}dM)(YoI#uwr#L8yQ|aB?cF4hUTtUx`#Kpi{@feKwe7U}oO6@cRElTQGYC=+I>$zYtFWHjm z-6f|TLerwF%`j}NdP;*y6YJxoxM|MgXdM)j{oDIMR10Y!ai0Dw1A``aQT((`;UFF& z3YXer?~@!b8!D64KZ%bNCro~zU9ggAfv!o2e?(Z~{BtGSO8=~daac{5<03Zr9&l=C zuUL6e(tc!lAv}vHS}H!57mC)RDOCENw3`zQuJoVYCo|?C&vcLC4>llhX&ypW$Au0* z!!#p3tCVqrbjN$v(`aQEj4_xuV~i8@2bl^Kj^k?07`~KZa*Qf02}$4Bpmioc|9h$2 zhZodP!4k~vg^v`F z(_OFs`6*N?aS + /// When you are done with an instance of this class, + /// it should be released with FreeAMMediaType() to avoid leaking + /// + [UnmanagedName("AM_MEDIA_TYPE"), StructLayout(LayoutKind.Sequential)] + public class AMMediaType + { + public Guid majorType; + public Guid subType; + [MarshalAs(UnmanagedType.Bool)] + public bool fixedSizeSamples; + [MarshalAs(UnmanagedType.Bool)] + public bool temporalCompression; + public int sampleSize; + public Guid formatType; + public IntPtr unkPtr; // IUnknown Pointer + public int formatSize; + public IntPtr formatPtr; // Pointer to a buff determined by formatType + } + + [UnmanagedName("VIDEOINFOHEADER"), StructLayout(LayoutKind.Sequential)] + public class VideoInfoHeader + { + public MFRect SrcRect; + public MFRect TargetRect; + public int BitRate; + public int BitErrorRate; + public long AvgTimePerFrame; + public BitmapInfoHeader BmiHeader; // Custom marshaler? + } + + [UnmanagedName("VIDEOINFOHEADER2"), StructLayout(LayoutKind.Sequential)] + public class VideoInfoHeader2 + { + public MFRect SrcRect; + public MFRect TargetRect; + public int BitRate; + public int BitErrorRate; + public long AvgTimePerFrame; + public AMInterlace InterlaceFlags; + public AMCopyProtect CopyProtectFlags; + public int PictAspectRatioX; + public int PictAspectRatioY; + public AMControl ControlFlags; + public int Reserved2; + public BitmapInfoHeader BmiHeader; // Custom marshaler? + } + + [StructLayout(LayoutKind.Sequential, Pack = 4), UnmanagedName("PROPERTYKEY")] + public class PropertyKey + { + public Guid fmtid; + public int pID; + + public PropertyKey() + { + } + + public PropertyKey(Guid f, int p) + { + fmtid = f; + pID = p; + } + } + + #endregion + + #region Generic Interfaces + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("71604b0f-97b0-4764-8577-2f13e98a1422")] + public interface INamedPropertyStore + { + [PreserveSig] + int GetNamedValue( + [In, MarshalAs(UnmanagedType.LPWStr)] string pszName, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pValue + ); + + [PreserveSig] + int SetNamedValue( + [In, MarshalAs(UnmanagedType.LPWStr)] string pszName, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant propvar); + + [PreserveSig] + int GetNameCount( + out int pdwCount); + + [PreserveSig] + int GetNameAt( + int iProp, + [MarshalAs(UnmanagedType.BStr)] out string pbstrName); + } + + [ComImport, System.Security.SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99")] + public interface IPropertyStore + { + [PreserveSig] + int GetCount( + out int cProps + ); + + [PreserveSig] + int GetAt( + [In] int iProp, + [Out] PropertyKey pkey + ); + + [PreserveSig] + int GetValue( + [In, MarshalAs(UnmanagedType.LPStruct)] PropertyKey key, + [In, Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PVMarshaler))] PropVariant pv + ); + + [PreserveSig] + int SetValue( + [In, MarshalAs(UnmanagedType.LPStruct)] PropertyKey key, + [In, MarshalAs(UnmanagedType.LPStruct)] ConstPropVariant propvar + ); + + [PreserveSig] + int Commit(); + } + + #endregion + +} diff --git a/Samples/BDA/DTVViewer/AboutBox.cs b/Samples/BDA/DTVViewer/AboutBox.cs new file mode 100644 index 0000000..7517592 --- /dev/null +++ b/Samples/BDA/DTVViewer/AboutBox.cs @@ -0,0 +1,163 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Reflection; +using System.Windows.Forms; + +using DirectShowLib; + +namespace DirectShowLib.Sample +{ + internal class AboutBoxWnd : Form + { + public System.Windows.Forms.Label label1; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.LinkLabel linkLabel1; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label4; + private System.ComponentModel.Container components = null; + + public AboutBoxWnd() + { + InitializeComponent(); + + Type t = typeof(IGraphBuilder); + label3.Text += t.Assembly.GetName().Version; + } + + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if(components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Code généré par le Concepteur Windows Form + /// + /// Méthode requise pour la prise en charge du concepteur - ne modifiez pas + /// le contenu de cette méthode avec l'éditeur de code. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.button1 = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.linkLabel1 = new System.Windows.Forms.LinkLabel(); + this.label3 = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // label1 + // + this.label1.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label1.Location = new System.Drawing.Point(8, 8); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(272, 40); + this.label1.TabIndex = 1; + // + // button1 + // + this.button1.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.button1.Location = new System.Drawing.Point(288, 8); + this.button1.Name = "button1"; + this.button1.TabIndex = 0; + this.button1.Text = "OK"; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // label2 + // + this.label2.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label2.Location = new System.Drawing.Point(8, 64); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(160, 16); + this.label2.TabIndex = 2; + this.label2.Text = "Library source code release under"; + // + // linkLabel1 + // + this.linkLabel1.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.linkLabel1.Location = new System.Drawing.Point(184, 64); + this.linkLabel1.Name = "linkLabel1"; + this.linkLabel1.Size = new System.Drawing.Size(160, 16); + this.linkLabel1.TabIndex = 3; + this.linkLabel1.TabStop = true; + this.linkLabel1.Text = "Lesser General Public License"; + this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked); + // + // label3 + // + this.label3.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label3.Location = new System.Drawing.Point(8, 48); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(320, 16); + this.label3.TabIndex = 4; + this.label3.Text = "DirectShowLib Version : "; + // + // label4 + // + this.label4.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label4.Location = new System.Drawing.Point(8, 80); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(264, 16); + this.label4.TabIndex = 5; + this.label4.Text = "Sample source code release under Public Domain"; + // + // AboutBoxWnd + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(372, 104); + this.Controls.Add(this.label4); + this.Controls.Add(this.label3); + this.Controls.Add(this.linkLabel1); + this.Controls.Add(this.label2); + this.Controls.Add(this.button1); + this.Controls.Add(this.label1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "AboutBoxWnd"; + this.ShowInTaskbar = false; + this.Text = "AboutBox"; + this.ResumeLayout(false); + + } + #endregion + + private void button1_Click(object sender, System.EventArgs e) + { + this.Close(); + } + + private void linkLabel1_LinkClicked(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e) + { + System.Diagnostics.Process.Start("http://www.gnu.org/copyleft/lesser.txt"); + } + } + + public class AboutBox + { + public static void Show(string title, string text) + { + using (AboutBoxWnd form = new AboutBoxWnd()) + { + form.Text = title; + form.label1.Text = text; + form.ShowDialog(); + } + } + } +} diff --git a/Samples/BDA/DTVViewer/AboutBox.resx b/Samples/BDA/DTVViewer/AboutBox.resx new file mode 100644 index 0000000..4b1c550 --- /dev/null +++ b/Samples/BDA/DTVViewer/AboutBox.resx @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + Private + + + Public + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + Private + + + False + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + (Default) + + + False + + + False + + + 8, 8 + + + True + + + AboutBoxWnd + + + 80 + + + True + + + Private + + \ No newline at end of file diff --git a/Samples/BDA/DTVViewer/App.ico b/Samples/BDA/DTVViewer/App.ico new file mode 100644 index 0000000000000000000000000000000000000000..3a5525fd794f7a7c5c8e6187f470ea3af38cd2b6 GIT binary patch literal 1078 zcmeHHJr05}7=1t!Hp3A*8IHkVf+j?-!eHY14Gtcw1Eb*_9>Bq^zETJ@GKj{_2j4$w zo9}xCh!8{T3=X##Skq>ikMjsvB|y%crWBM2iW(4pI}c%z6%lW!=~4v77#3{z!dmB1 z__&l)-{KUYR+|8|;wB^R|9ET$J@(@=#rd^=)qs85?vAy(PSF5CyNkus435LVkZ$rj zNw|JG-P7^hF<(;#o*Vk}5R#e|^13tBbQkeF?djULtvqyxd3<{9 literal 0 HcmV?d00001 diff --git a/Samples/BDA/DTVViewer/AssemblyInfo.cs b/Samples/BDA/DTVViewer/AssemblyInfo.cs new file mode 100644 index 0000000..76201ae --- /dev/null +++ b/Samples/BDA/DTVViewer/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// Les informations générales relatives à un assembly dépendent de +// l'ensemble d'attributs suivant. Pour modifier les informations +// associées à un assembly, changez les valeurs de ces attributs. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Les informations de version pour un assembly se composent des quatre valeurs suivantes : +// +// Version principale +// Version secondaire +// Numéro de build +// Révision +// +// Vous pouvez spécifier toutes les valeurs ou indiquer des numéros de révision et de build par défaut +// en utilisant '*', comme ci-dessous : + +[assembly: AssemblyVersion("1.0.*")] + +// +// Pour signer votre assembly, vous devez spécifier la clé à utiliser. Consultez +// la documentation Microsoft .NET Framework pour plus d'informations sur la signature d'un assembly. +// +// Utilisez les attributs ci-dessous pour contrôler la clé utilisée lors de la signature. +// +// Remarques : +// (*) Si aucune clé n'est spécifiée, l'assembly n'est pas signé. +// (*) KeyName fait référence à une clé installée dans le fournisseur de +// services cryptographiques (CSP) de votre ordinateur. KeyFile fait référence à un fichier qui contient +// une clé. +// (*) Si les valeurs de KeyFile et de KeyName sont spécifiées, le +// traitement suivant se produit : +// (1) Si KeyName se trouve dans le CSP, la clé est utilisée. +// (2) Si KeyName n'existe pas mais que KeyFile existe, la clé +// de KeyFile est installée dans le CSP et utilisée. +// (*) Pour créer KeyFile, vous pouvez utiliser l'utilitaire sn.exe (Strong Name, Nom fort). +// Lors de la spécification de KeyFile, son emplacement doit être +// relatif au répertoire de sortie du projet qui est +// %Project Directory%\obj\. Par exemple, si votre KeyFile se trouve +// dans le répertoire du projet, vous devez spécifier l'attribut +// AssemblyKeyFile sous la forme [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) DelaySign (signature différée) est une option avancée. Pour plus d'informations, consultez la +// documentation Microsoft .NET Framework. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/BDA/DTVViewer/BDAGraphBuilder.cs b/Samples/BDA/DTVViewer/BDAGraphBuilder.cs new file mode 100644 index 0000000..1279d99 --- /dev/null +++ b/Samples/BDA/DTVViewer/BDAGraphBuilder.cs @@ -0,0 +1,565 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +using Microsoft.Win32; + +using DirectShowLib; +using DirectShowLib.BDA; +using DirectShowLib.Utils; + +namespace DirectShowLib.Sample +{ + public class BDAGraphBuilder : IDisposable + { + Control hostingControl = null; + + IFilterGraph2 graphBuilder = null; + DsROTEntry rot = null; + + IBaseFilter networkProvider = null; + IBaseFilter mpeg2Demux = null; + IBaseFilter tuner = null; + IBaseFilter demodulator = null; + IBaseFilter capture = null; + IBaseFilter bdaTIF = null; + IBaseFilter bdaSecTab = null; + IBaseFilter audioRenderer = null; + IBaseFilter videoRenderer = null; + + public BDAGraphBuilder(Control renderingControl) + { + this.hostingControl = renderingControl; + } + + public void BuildGraph(ITuningSpace tuningSpace) + { + this.graphBuilder = (IFilterGraph2) new FilterGraph(); + rot = new DsROTEntry(this.graphBuilder); + + // Method names should be self explanatory + AddNetworkProviderFilter(tuningSpace); + AddMPEG2DemuxFilter(); + AddAndConnectBDABoardFilters(); + AddTransportStreamFiltersToGraph(); + AddRenderers(); + ConfigureVMR9InWindowlessMode(); + ConnectFilters(); + } + + public void SubmitTuneRequest(ITuneRequest tuneRequest) + { + int hr = 0; + + hr = (this.networkProvider as ITuner).put_TuneRequest(tuneRequest); + DsError.ThrowExceptionForHR(hr); + } + + public void RunGraph() + { + int hr = 0; + + hr = (this.graphBuilder as IMediaControl).Run(); + DsError.ThrowExceptionForHR(hr); + } + + public void SaveGraph(string filepath) + { + // Nothing to do with a DTV viewer but can be useful + FilterGraphTools.SaveGraphFile(this.graphBuilder, filepath); + } + + #region Membres de IDisposable + + public void Dispose() + { + Decompose(); + } + + #endregion + + private void AddNetworkProviderFilter(ITuningSpace tuningSpace) + { + int hr = 0; + Guid genProviderClsId = new Guid("{B2F3A67C-29DA-4C78-8831-091ED509A475}"); + Guid networkProviderClsId; + + // First test if the Generic Network Provider is available (only on MCE 2005 + Update Rollup 2 and higher) + if (FilterGraphTools.IsThisComObjectInstalled(genProviderClsId)) + { + this.networkProvider = FilterGraphTools.AddFilterFromClsid(this.graphBuilder, genProviderClsId, "Generic Network Provider"); + + hr = (this.networkProvider as ITuner).put_TuningSpace(tuningSpace); + return; + } + + // Get the network type of the requested Tuning Space + hr = tuningSpace.get__NetworkType(out networkProviderClsId); + + // Get the network type of the requested Tuning Space + if (networkProviderClsId == typeof(DVBTNetworkProvider).GUID) + { + this.networkProvider = FilterGraphTools.AddFilterFromClsid(this.graphBuilder, networkProviderClsId, "DVBT Network Provider"); + } + else if (networkProviderClsId == typeof(DVBSNetworkProvider).GUID) + { + this.networkProvider = FilterGraphTools.AddFilterFromClsid(this.graphBuilder, networkProviderClsId, "DVBS Network Provider"); + } + else if (networkProviderClsId == typeof(ATSCNetworkProvider).GUID) + { + this.networkProvider = FilterGraphTools.AddFilterFromClsid(this.graphBuilder, networkProviderClsId, "ATSC Network Provider"); + } + else if (networkProviderClsId == typeof(DVBCNetworkProvider).GUID) + { + this.networkProvider = FilterGraphTools.AddFilterFromClsid(this.graphBuilder, networkProviderClsId, "DVBC Network Provider"); + } + else + // Tuning Space can also describe Analog TV but this application don't support them + throw new ArgumentException("This application doesn't support this Tuning Space"); + + hr = (this.networkProvider as ITuner).put_TuningSpace(tuningSpace); + } + + private void AddMPEG2DemuxFilter() + { + int hr = 0; + + this.mpeg2Demux = (IBaseFilter) new MPEG2Demultiplexer(); + + hr = this.graphBuilder.AddFilter(this.mpeg2Demux, "MPEG2 Demultiplexer"); + DsError.ThrowExceptionForHR(hr); + } + + private void AddAndConnectBDABoardFilters() + { + int hr = 0; + DsDevice[] devices; + + ICaptureGraphBuilder2 capBuilder = (ICaptureGraphBuilder2) new CaptureGraphBuilder2(); + capBuilder.SetFiltergraph(this.graphBuilder); + + try + { + // Enumerate BDA Source filters category and found one that can connect to the network provider + devices = DsDevice.GetDevicesOfCat(FilterCategory.BDASourceFiltersCategory); + for(int i = 0; i < devices.Length; i++) + { + IBaseFilter tmp; + + hr = graphBuilder.AddSourceFilterForMoniker(devices[i].Mon, null, devices[i].Name, out tmp); + DsError.ThrowExceptionForHR(hr); + + hr = capBuilder.RenderStream(null, null, this.networkProvider, null, tmp); + if (hr == 0) + { + // Got it ! + this.tuner = tmp; + break; + } + else + { + // Try another... + hr = graphBuilder.RemoveFilter(tmp); + Marshal.ReleaseComObject(tmp); + } + } + + if (this.tuner == null) + throw new ApplicationException("Can't find a valid BDA tuner"); + + // trying to connect this filter to the MPEG-2 Demux + hr = capBuilder.RenderStream(null, null, tuner, null, mpeg2Demux); + if (hr >= 0) + { + // this is a one filter model + this.demodulator = null; + this.capture = null; + return; + } + else + { + // Then enumerate BDA Receiver Components category to found a filter connecting + // to the tuner and the MPEG2 Demux + devices = DsDevice.GetDevicesOfCat(FilterCategory.BDAReceiverComponentsCategory); + + for (int i = 0; i < devices.Length; i++) + { + IBaseFilter tmp; + + hr = graphBuilder.AddSourceFilterForMoniker(devices[i].Mon, null, devices[i].Name, out tmp); + DsError.ThrowExceptionForHR(hr); + + hr = capBuilder.RenderStream(null, null, this.tuner, null, tmp); + if (hr == 0) + { + // Got it ! + this.capture = tmp; + + // Connect it to the MPEG-2 Demux + hr = capBuilder.RenderStream(null, null, this.capture, null, this.mpeg2Demux); + if (hr >= 0) + { + // This second filter connect both with the tuner and the demux. + // This is a capture filter... + return; + } + else + { + // This second filter connect with the tuner but not with the demux. + // This is in fact a demodulator filter. We now must find the true capture filter... + + this.demodulator = this.capture; + this.capture = null; + + // saving the Demodulator's DevicePath to avoid creating it twice. + string demodulatorDevicePath = devices[i].DevicePath; + + for (int j = 0; i < devices.Length; j++) + { + if (devices[j].DevicePath.Equals(demodulatorDevicePath)) + continue; + + hr = graphBuilder.AddSourceFilterForMoniker(devices[i].Mon, null, devices[i].Name, out tmp); + DsError.ThrowExceptionForHR(hr); + + hr = capBuilder.RenderStream(null, null, this.demodulator, null, tmp); + if (hr == 0) + { + // Got it ! + this.capture = tmp; + + // Connect it to the MPEG-2 Demux + hr = capBuilder.RenderStream(null, null, this.capture, null, this.mpeg2Demux); + if (hr >= 0) + { + // This second filter connect both with the demodulator and the demux. + // This is a true capture filter... + return; + } + } + else + { + // Try another... + hr = graphBuilder.RemoveFilter(tmp); + Marshal.ReleaseComObject(tmp); + } + } // for j + + // We have a tuner and a capture/demodulator that don't connect with the demux + // and we found no additionals filters to build a working filters chain. + throw new ApplicationException("Can't find a valid BDA filter chain"); + } + } + else + { + // Try another... + hr = graphBuilder.RemoveFilter(tmp); + Marshal.ReleaseComObject(tmp); + } + } // for i + + // We have a tuner that connect to the Network Provider BUT not with the demux + // and we found no additionals filters to build a working filters chain. + throw new ApplicationException("Can't find a valid BDA filter chain"); + } + } + finally + { + Marshal.ReleaseComObject(capBuilder); + } + } + + public void AddTransportStreamFiltersToGraph() + { + int hr = 0; + DsDevice[] devices; + + // Add two filters needed in a BDA graph + devices = DsDevice.GetDevicesOfCat(FilterCategory.BDATransportInformationRenderersCategory); + for(int i = 0; i < devices.Length; i++) + { + if (devices[i].Name.Equals("BDA MPEG2 Transport Information Filter")) + { + hr = graphBuilder.AddSourceFilterForMoniker(devices[i].Mon, null, devices[i].Name, out this.bdaTIF); + DsError.ThrowExceptionForHR(hr); + continue; + } + + if (devices[i].Name.Equals("MPEG-2 Sections and Tables")) + { + hr = graphBuilder.AddSourceFilterForMoniker(devices[i].Mon, null, devices[i].Name, out this.bdaSecTab); + DsError.ThrowExceptionForHR(hr); + continue; + } + } + } + + private void AddRenderers() + { + int hr = 0; + + // To hear something + this.audioRenderer = (IBaseFilter) new DSoundRender(); + + hr = this.graphBuilder.AddFilter(this.audioRenderer, "DirectSound Renderer"); + DsError.ThrowExceptionForHR(hr); + + // To see something + this.videoRenderer = (IBaseFilter) new VideoMixingRenderer9(); + + hr = this.graphBuilder.AddFilter(this.videoRenderer, "Video Mixing Renderer Filter 9"); + DsError.ThrowExceptionForHR(hr); + } + + private void ConfigureVMR9InWindowlessMode() + { + int hr = 0; + IVMRFilterConfig9 filterConfig = this.videoRenderer as IVMRFilterConfig9; + + // Configure VMR-9 in Windowsless mode + hr = filterConfig.SetRenderingMode(VMR9Mode.Windowless); + DsError.ThrowExceptionForHR(hr); + + // With 1 input stream + hr = filterConfig.SetNumberOfStreams(1); + DsError.ThrowExceptionForHR(hr); + + IVMRWindowlessControl9 windowlessControl = this.videoRenderer as IVMRWindowlessControl9; + + // The main form is hosting the VMR-9 + hr = windowlessControl.SetVideoClippingWindow(this.hostingControl.Handle); + DsError.ThrowExceptionForHR(hr); + + // Keep the aspect-ratio OK + hr = windowlessControl.SetAspectRatioMode(VMR9AspectRatioMode.LetterBox); + DsError.ThrowExceptionForHR(hr); + + // Init the VMR-9 with default size values + ResizeMoveHandler(null, null); + + // Add Windows Messages handlers + AddHandlers(); + } + + private void AddHandlers() + { + // Add Windows Messages handlers + this.hostingControl.Paint += new PaintEventHandler(PaintHandler); // for WM_PAINT + this.hostingControl.Resize += new EventHandler(ResizeMoveHandler); // for WM_SIZE + this.hostingControl.Move += new EventHandler(ResizeMoveHandler); // for WM_MOVE + SystemEvents.DisplaySettingsChanged += new EventHandler(DisplayChangedHandler); // for WM_DISPLAYCHANGE + } + + private void RemoveHandlers() + { + // Remove Windows Messages handlers + this.hostingControl.Paint -= new PaintEventHandler(PaintHandler); // for WM_PAINT + this.hostingControl.Resize -= new EventHandler(ResizeMoveHandler); // for WM_SIZE + this.hostingControl.Move -= new EventHandler(ResizeMoveHandler); // for WM_MOVE + SystemEvents.DisplaySettingsChanged -= new EventHandler(DisplayChangedHandler); // for WM_DISPLAYCHANGE + } + + // This method changed to work with Windows 7 + // Under this OS, the MPEG-2 Demux now have dozens of outputs pins. + // Rendering all of them is not a good solution. + // The rendering process must be more smart... + private void ConnectFilters() + { + int hr = 0; + int pinNumber = 0; + IPin pinOut, pinIn; + + // After the rendering process, our 4 downstream filters must be rendered + bool bdaTIFRendered = false; + bool bdaSecTabRendered = false; + bool audioRendered = false; + bool videoRendered = false; + + // for each output pins... + while (true) + { + pinOut = DsFindPin.ByDirection(mpeg2Demux, PinDirection.Output, pinNumber); + // Is the last pin reached ? + if (pinOut == null) + break; + + IEnumMediaTypes enumMediaTypes = null; + AMMediaType[] mediaTypes = new AMMediaType[1]; + + try + { + // Get Pin's MediaType enumerator + hr = pinOut.EnumMediaTypes(out enumMediaTypes); + DsError.ThrowExceptionForHR(hr); + + // for each media types... + while (enumMediaTypes.Next(mediaTypes.Length, mediaTypes, IntPtr.Zero) == 0) + { + // Store the majortype and the subtype and free the structure + Guid majorType = mediaTypes[0].majorType; + Guid subType = mediaTypes[0].subType; + DsUtils.FreeAMMediaType(mediaTypes[0]); + + if (majorType == MediaType.Audio) + { + // Is the Audio already rendered ? + if (!audioRendered) + { + // Get the first input pin + pinIn = DsFindPin.ByDirection(audioRenderer, PinDirection.Input, 0); + + // Render it with IntelliConnect (a decoder should be added between the two filters. + hr = graphBuilder.Connect(pinOut, pinIn); + DsError.ThrowExceptionForHR(hr); + + // Release the Pin + Marshal.ReleaseComObject(pinIn); + pinIn = null; + + // Notify that the audio renderer is connected + audioRendered = true; + } + } + else if (majorType == MediaType.Video) + { + // Is the Video already rendered ? + if (!videoRendered) + { + // Get the first input pin + pinIn = DsFindPin.ByDirection(videoRenderer, PinDirection.Input, 0); + + // Render it with IntelliConnect (a decoder should be added between the two filters. + hr = graphBuilder.Connect(pinOut, pinIn); + DsError.ThrowExceptionForHR(hr); + + // Release the Pin + Marshal.ReleaseComObject(pinIn); + pinIn = null; + + // Notify that the video renderer is connected + videoRendered = true; + } + } + else if (majorType == MediaType.Mpeg2Sections) + { + if (subType == MediaSubType.Mpeg2Data) + { + // Is the MPEG-2 Sections and Tables Filter already rendered ? + if (!bdaSecTabRendered) + { + // Get the first input pin + pinIn = DsFindPin.ByDirection(bdaSecTab, PinDirection.Input, 0); + + // A direct connection is enough + hr = graphBuilder.ConnectDirect(pinOut, pinIn, null); + DsError.ThrowExceptionForHR(hr); + + // Release the Pin + Marshal.ReleaseComObject(pinIn); + pinIn = null; + + // Notify that the MPEG-2 Sections and Tables Filter is connected + bdaSecTabRendered = true; + } + } + // This sample only support DVB-T or DVB-S so only supporting this subtype is enough. + // If you want to support ATSC or ISDB, don't forget to handle these network types. + else if (subType == MediaSubType.DvbSI) + { + // Is the BDA MPEG-2 Transport Information Filter already rendered ? + if (!bdaTIFRendered) + { + // Get the first input pin + pinIn = DsFindPin.ByDirection(bdaTIF, PinDirection.Input, 0); + + // A direct connection is enough + hr = graphBuilder.ConnectDirect(pinOut, pinIn, null); + DsError.ThrowExceptionForHR(hr); + + // Release the Pin + Marshal.ReleaseComObject(pinIn); + pinIn = null; + + // Notify that the BDA MPEG-2 Transport Information Filter is connected + bdaTIFRendered = true; + } + } + } + } + } + finally + { + // Free COM objects + Marshal.ReleaseComObject(enumMediaTypes); + enumMediaTypes = null; + + Marshal.ReleaseComObject(pinOut); + pinOut = null; + } + + // Next pin, please ! + pinNumber++; + } + } + + private void Decompose() + { + int hr = 0; + + // Decompose the graph + hr = (this.graphBuilder as IMediaControl).StopWhenReady(); + hr = (this.graphBuilder as IMediaControl).Stop(); + + RemoveHandlers(); + + FilterGraphTools.RemoveAllFilters(this.graphBuilder); + + Marshal.ReleaseComObject(this.networkProvider); this.networkProvider = null; + Marshal.ReleaseComObject(this.mpeg2Demux); this.mpeg2Demux = null; + Marshal.ReleaseComObject(this.tuner); this.tuner = null; + Marshal.ReleaseComObject(this.capture); this.capture = null; + Marshal.ReleaseComObject(this.bdaTIF); this.bdaTIF = null; + Marshal.ReleaseComObject(this.bdaSecTab); this.bdaSecTab = null; + Marshal.ReleaseComObject(this.audioRenderer); this.audioRenderer = null; + Marshal.ReleaseComObject(this.videoRenderer); this.videoRenderer = null; + + rot.Dispose(); + Marshal.ReleaseComObject(this.graphBuilder); this.graphBuilder = null; + } + + private void PaintHandler(object sender, PaintEventArgs e) + { + if (this.videoRenderer != null) + { + IntPtr hdc = e.Graphics.GetHdc(); + int hr = (this.videoRenderer as IVMRWindowlessControl9).RepaintVideo(this.hostingControl.Handle, hdc); + e.Graphics.ReleaseHdc(hdc); + } + } + + private void ResizeMoveHandler(object sender, EventArgs e) + { + if (this.videoRenderer != null) + { + int hr = (this.videoRenderer as IVMRWindowlessControl9).SetVideoPosition(null, DsRect.FromRectangle(this.hostingControl.ClientRectangle)); + } + } + + private void DisplayChangedHandler(object sender, EventArgs e) + { + if (this.videoRenderer != null) + { + int hr = (this.videoRenderer as IVMRWindowlessControl9).DisplayModeChanged(); + } + } + + } +} diff --git a/Samples/BDA/DTVViewer/DTVViewer-2005.csproj b/Samples/BDA/DTVViewer/DTVViewer-2005.csproj new file mode 100644 index 0000000..135a267 --- /dev/null +++ b/Samples/BDA/DTVViewer/DTVViewer-2005.csproj @@ -0,0 +1,146 @@ + + + Local + 8.0.50727 + 2.0 + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC} + Debug + AnyCPU + App.ico + + + DTVViewer + + + JScript + Grid + IE50 + false + WinExe + DirectShowLib.Sample + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Data + + + System.Drawing + + + System.Windows.Forms + + + System.XML + + + + + Form + + + Code + + + Code + + + Form + + + Form + + + Code + + + Form + + + Code + + + Code + + + AboutBox.cs + + + DVBSTuning.cs + + + DVBTTuning.cs + + + MainForm.cs + + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/BDA/DTVViewer/DTVViewer-2005.sln b/Samples/BDA/DTVViewer/DTVViewer-2005.sln new file mode 100644 index 0000000..08ebe2f --- /dev/null +++ b/Samples/BDA/DTVViewer/DTVViewer-2005.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DTVViewer-2005", "DTVViewer-2005.csproj", "{F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/BDA/DTVViewer/DTVViewer-2008.sln b/Samples/BDA/DTVViewer/DTVViewer-2008.sln new file mode 100644 index 0000000..b3f5ab2 --- /dev/null +++ b/Samples/BDA/DTVViewer/DTVViewer-2008.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DTVViewer-2008", "DTVViewer-2008.csproj", "{F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/BDA/DTVViewer/DTVViewer.csproj b/Samples/BDA/DTVViewer/DTVViewer.csproj new file mode 100644 index 0000000..3509d87 --- /dev/null +++ b/Samples/BDA/DTVViewer/DTVViewer.csproj @@ -0,0 +1,178 @@ + + + + Local + 8.0.50727 + 2.0 + {F3FCD690-6D1A-4A42-AFC1-A3A3D56D7DBC} + Debug + AnyCPU + App.ico + + + DTVViewer + + + JScript + Grid + IE50 + false + WinExe + DirectShowLib.Sample + OnBuildSuccess + + + + + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Data + + + System.Drawing + + + System.Windows.Forms + + + System.XML + + + + + Form + + + Code + + + Code + + + Form + + + Form + + + Code + + + Form + + + Code + + + Code + + + AboutBox.cs + + + DVBSTuning.cs + + + DVBTTuning.cs + + + MainForm.cs + + + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + + + + + + \ No newline at end of file diff --git a/Samples/BDA/DTVViewer/DVBSTuning.cs b/Samples/BDA/DTVViewer/DVBSTuning.cs new file mode 100644 index 0000000..331ffec --- /dev/null +++ b/Samples/BDA/DTVViewer/DVBSTuning.cs @@ -0,0 +1,337 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +using DirectShowLib; +using DirectShowLib.BDA; + +namespace DirectShowLib.Sample +{ + /// + /// Description résumée de DVBSTuning. + /// + public class DVBSTuning : Form, ITuningSelector + { + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textSID; + private System.Windows.Forms.TextBox textTSID; + private System.Windows.Forms.TextBox textONID; + private System.Windows.Forms.TextBox textCarrierFreq; + private System.Windows.Forms.TextBox textSymbolRate; + private System.Windows.Forms.Label label7; + private System.Windows.Forms.ComboBox comboSigPol; + + /// + /// Variable nécessaire au concepteur. + /// + private System.ComponentModel.Container components = null; + + private IDVBSTuningSpace tuningSpace = null; + private IDVBTuneRequest tuneRequest = null; + + public DVBSTuning() + { + InitializeComponent(); + + int hr = 0; + + this.tuningSpace = (IDVBSTuningSpace) new DVBSTuningSpace(); + hr = this.tuningSpace.put_UniqueName("DVBS TuningSpace"); + hr = this.tuningSpace.put_FriendlyName("DVBS TuningSpace"); + hr = this.tuningSpace.put__NetworkType(typeof(DVBSNetworkProvider).GUID); + hr = this.tuningSpace.put_SystemType(DVBSystemType.Satellite); + hr = this.tuningSpace.put_LowOscillator(9750000); + hr = this.tuningSpace.put_HighOscillator(10600000); + + ITuneRequest tr = null; + + hr = this.tuningSpace.CreateTuneRequest(out tr); + DsError.ThrowExceptionForHR(hr); + + this.tuneRequest = (IDVBTuneRequest) tr; + + hr = this.tuneRequest.put_ONID(-1); + hr = this.tuneRequest.put_TSID(-1); + hr = this.tuneRequest.put_SID(-1); + + IDVBSLocator locator = (IDVBSLocator) new DVBSLocator(); + hr = locator.put_CarrierFrequency(-1); + hr = locator.put_SymbolRate(-1); + hr = tr.put_Locator(locator as ILocator); + } + + /// + /// Nettoyage des ressources utilisées. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if(components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Code généré par le Concepteur Windows Form + /// + /// Méthode requise pour la prise en charge du concepteur - ne modifiez pas + /// le contenu de cette méthode avec l'éditeur de code. + /// + private void InitializeComponent() + { + this.button1 = new System.Windows.Forms.Button(); + this.label5 = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.textSID = new System.Windows.Forms.TextBox(); + this.textTSID = new System.Windows.Forms.TextBox(); + this.textONID = new System.Windows.Forms.TextBox(); + this.textCarrierFreq = new System.Windows.Forms.TextBox(); + this.label6 = new System.Windows.Forms.Label(); + this.textSymbolRate = new System.Windows.Forms.TextBox(); + this.label7 = new System.Windows.Forms.Label(); + this.comboSigPol = new System.Windows.Forms.ComboBox(); + this.SuspendLayout(); + // + // button1 + // + this.button1.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.button1.Location = new System.Drawing.Point(224, 136); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(48, 23); + this.button1.TabIndex = 8; + this.button1.Text = "Go"; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // label5 + // + this.label5.Location = new System.Drawing.Point(216, 16); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(32, 23); + this.label5.TabIndex = 18; + this.label5.Text = "Khz"; + // + // label4 + // + this.label4.Location = new System.Drawing.Point(8, 136); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(104, 23); + this.label4.TabIndex = 17; + this.label4.Text = "SID"; + // + // label3 + // + this.label3.Location = new System.Drawing.Point(8, 112); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(104, 23); + this.label3.TabIndex = 16; + this.label3.Text = "TSID"; + // + // label2 + // + this.label2.Location = new System.Drawing.Point(8, 88); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(104, 23); + this.label2.TabIndex = 15; + this.label2.Text = "ONID"; + // + // label1 + // + this.label1.Location = new System.Drawing.Point(8, 16); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(104, 24); + this.label1.TabIndex = 14; + this.label1.Text = "Carrier Frequency"; + // + // textSID + // + this.textSID.Location = new System.Drawing.Point(112, 136); + this.textSID.Name = "textSID"; + this.textSID.TabIndex = 6; + this.textSID.Text = ""; + // + // textTSID + // + this.textTSID.Location = new System.Drawing.Point(112, 112); + this.textTSID.Name = "textTSID"; + this.textTSID.TabIndex = 5; + this.textTSID.Text = ""; + // + // textONID + // + this.textONID.Location = new System.Drawing.Point(112, 88); + this.textONID.Name = "textONID"; + this.textONID.TabIndex = 4; + this.textONID.Text = ""; + // + // textCarrierFreq + // + this.textCarrierFreq.Location = new System.Drawing.Point(112, 16); + this.textCarrierFreq.Name = "textCarrierFreq"; + this.textCarrierFreq.TabIndex = 1; + this.textCarrierFreq.Text = ""; + // + // label6 + // + this.label6.Location = new System.Drawing.Point(8, 64); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(104, 23); + this.label6.TabIndex = 21; + this.label6.Text = "Symbol Rate"; + // + // textSymbolRate + // + this.textSymbolRate.Location = new System.Drawing.Point(112, 64); + this.textSymbolRate.Name = "textSymbolRate"; + this.textSymbolRate.TabIndex = 3; + this.textSymbolRate.Text = ""; + // + // label7 + // + this.label7.Location = new System.Drawing.Point(8, 40); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(104, 23); + this.label7.TabIndex = 23; + this.label7.Text = "Signal Polarisation"; + // + // comboSigPol + // + this.comboSigPol.Items.AddRange(Enum.GetNames(typeof(Polarisation))); + this.comboSigPol.DropDownStyle = ComboBoxStyle.DropDownList; + this.comboSigPol.Location = new System.Drawing.Point(112, 40); + this.comboSigPol.Name = "comboSigPol"; + this.comboSigPol.Size = new System.Drawing.Size(96, 21); + this.comboSigPol.TabIndex = 2; + // + // DVBSTuning + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(280, 166); + this.Controls.Add(this.comboSigPol); + this.Controls.Add(this.label7); + this.Controls.Add(this.label6); + this.Controls.Add(this.textSymbolRate); + this.Controls.Add(this.button1); + this.Controls.Add(this.label5); + this.Controls.Add(this.label4); + this.Controls.Add(this.label3); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.Controls.Add(this.textSID); + this.Controls.Add(this.textTSID); + this.Controls.Add(this.textONID); + this.Controls.Add(this.textCarrierFreq); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "DVBSTuning"; + this.Text = "DVBS Tuning"; + this.ResumeLayout(false); + + } + #endregion + + private void button1_Click(object sender, System.EventArgs e) + { + this.DialogResult = DialogResult.OK; + } + + #region Membres de ITuningSelector + + public DirectShowLib.BDA.ITuningSpace TuningSpace + { + get + { + return (this.tuningSpace as ITuningSpace); + } + } + + public DirectShowLib.BDA.ITuneRequest TuneRequest + { + get + { + return (this.tuneRequest as ITuneRequest); + } + } + + public bool TuneSelect() + { + int hr = 0; + ILocator locator; + int freq, symbolRate; + Polarisation sigPol; + int onid, tsid, sid; + + + hr = this.tuneRequest.get_Locator(out locator); + + hr = locator.get_CarrierFrequency(out freq); + hr = (locator as IDVBSLocator).get_SignalPolarisation(out sigPol); + hr = locator.get_SymbolRate(out symbolRate); + + hr = this.tuneRequest.get_ONID(out onid); + hr = this.tuneRequest.get_TSID(out tsid); + hr = this.tuneRequest.get_SID(out sid); + + textCarrierFreq.Text = freq.ToString(); + comboSigPol.Text = sigPol.ToString(); + textSymbolRate.Text = symbolRate.ToString(); + textONID.Text = onid.ToString(); + textTSID.Text = tsid.ToString(); + textSID.Text = sid.ToString(); + + this.ShowDialog(); + + if (this.DialogResult == DialogResult.OK) + { + hr = locator.put_CarrierFrequency(Convert.ToInt32(textCarrierFreq.Text)); + sigPol = (Polarisation) Enum.Parse(typeof(Polarisation), comboSigPol.Text); + hr = (locator as IDVBSLocator).put_SignalPolarisation(sigPol); + hr = locator.put_SymbolRate(Convert.ToInt32(textSymbolRate.Text)); +/* + hr = (locator as IDVBSLocator).put_InnerFEC(FECMethod.Viterbi); + hr = (locator as IDVBSLocator).put_InnerFECRate(BinaryConvolutionCodeRate.Rate2_3); + hr = (locator as IDVBSLocator).put_OuterFEC(FECMethod.Viterbi); + hr = (locator as IDVBSLocator).put_OuterFECRate(BinaryConvolutionCodeRate.Rate2_3); +*/ + + hr = this.tuneRequest.put_Locator(locator); + Marshal.ReleaseComObject(locator); + + hr = this.tuneRequest.put_ONID(Convert.ToInt32(textONID.Text)); + hr = this.tuneRequest.put_TSID(Convert.ToInt32(textTSID.Text)); + hr = this.tuneRequest.put_SID(Convert.ToInt32(textSID.Text)); + return true; + } + else + { + Marshal.ReleaseComObject(locator); + return false; + } + } + + #endregion + + } +} diff --git a/Samples/BDA/DTVViewer/DVBSTuning.resx b/Samples/BDA/DTVViewer/DVBSTuning.resx new file mode 100644 index 0000000..0429122 --- /dev/null +++ b/Samples/BDA/DTVViewer/DVBSTuning.resx @@ -0,0 +1,256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + Private + + + False + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + False + + + Private + + + Private + + + Private + + + False + + + Private + + + False + + + Private + + + Private + + + Private + + + False + + + Private + + + False + + + (Default) + + + False + + + DVBSTuning + + + False + + + 8, 8 + + + True + + + 80 + + + True + + + Private + + \ No newline at end of file diff --git a/Samples/BDA/DTVViewer/DVBTTuning.cs b/Samples/BDA/DTVViewer/DVBTTuning.cs new file mode 100644 index 0000000..5a4cda0 --- /dev/null +++ b/Samples/BDA/DTVViewer/DVBTTuning.cs @@ -0,0 +1,275 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +using DirectShowLib; +using DirectShowLib.BDA; + +namespace DirectShowLib.Sample +{ + /// + /// Description résumée de DVBTTuning. + /// + public class DVBTTuning : Form, ITuningSelector + { + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.TextBox textCarrierFreq; + private System.Windows.Forms.TextBox textONID; + private System.Windows.Forms.TextBox textTSID; + private System.Windows.Forms.TextBox textSID; + + /// + /// Variable nécessaire au concepteur. + /// + private System.ComponentModel.Container components = null; + + private IDVBTuningSpace tuningSpace = null; + private IDVBTuneRequest tuneRequest = null; + + public DVBTTuning() + { + InitializeComponent(); + + int hr = 0; + + this.tuningSpace = (IDVBTuningSpace) new DVBTuningSpace(); + hr = this.tuningSpace.put_UniqueName("DVBT TuningSpace"); + hr = this.tuningSpace.put_FriendlyName("DVBT TuningSpace"); + hr = this.tuningSpace.put__NetworkType(typeof(DVBTNetworkProvider).GUID); + hr = this.tuningSpace.put_SystemType(DVBSystemType.Terrestrial); + + ITuneRequest tr = null; + + hr = this.tuningSpace.CreateTuneRequest(out tr); + DsError.ThrowExceptionForHR(hr); + + this.tuneRequest = (IDVBTuneRequest) tr; + + hr = this.tuneRequest.put_ONID(-1); + hr = this.tuneRequest.put_TSID(-1); + hr = this.tuneRequest.put_SID(-1); + + IDVBTLocator locator = (IDVBTLocator) new DVBTLocator(); + hr = locator.put_CarrierFrequency(-1); + hr = tr.put_Locator(locator as ILocator); + } + + /// + /// Nettoyage des ressources utilisées. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if(components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Code généré par le Concepteur Windows Form + /// + /// Méthode requise pour la prise en charge du concepteur - ne modifiez pas + /// le contenu de cette méthode avec l'éditeur de code. + /// + private void InitializeComponent() + { + this.textCarrierFreq = new System.Windows.Forms.TextBox(); + this.textONID = new System.Windows.Forms.TextBox(); + this.textTSID = new System.Windows.Forms.TextBox(); + this.textSID = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.button1 = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // textCarrierFreq + // + this.textCarrierFreq.Location = new System.Drawing.Point(104, 16); + this.textCarrierFreq.Name = "textCarrierFreq"; + this.textCarrierFreq.TabIndex = 0; + this.textCarrierFreq.Text = ""; + // + // textONID + // + this.textONID.Location = new System.Drawing.Point(104, 40); + this.textONID.Name = "textONID"; + this.textONID.TabIndex = 1; + this.textONID.Text = ""; + // + // textTSID + // + this.textTSID.Location = new System.Drawing.Point(104, 64); + this.textTSID.Name = "textTSID"; + this.textTSID.TabIndex = 2; + this.textTSID.Text = ""; + // + // textSID + // + this.textSID.Location = new System.Drawing.Point(104, 88); + this.textSID.Name = "textSID"; + this.textSID.TabIndex = 3; + this.textSID.Text = ""; + // + // label1 + // + this.label1.Location = new System.Drawing.Point(8, 16); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(96, 24); + this.label1.TabIndex = 4; + this.label1.Text = "Carrier Frequency"; + // + // label2 + // + this.label2.Location = new System.Drawing.Point(8, 40); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(96, 23); + this.label2.TabIndex = 5; + this.label2.Text = "ONID"; + // + // label3 + // + this.label3.Location = new System.Drawing.Point(8, 64); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(96, 23); + this.label3.TabIndex = 6; + this.label3.Text = "TSID"; + // + // label4 + // + this.label4.Location = new System.Drawing.Point(8, 88); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(96, 23); + this.label4.TabIndex = 7; + this.label4.Text = "SID"; + // + // label5 + // + this.label5.Location = new System.Drawing.Point(208, 16); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(32, 23); + this.label5.TabIndex = 8; + this.label5.Text = "Khz"; + // + // button1 + // + this.button1.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.button1.Location = new System.Drawing.Point(216, 88); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(48, 23); + this.button1.TabIndex = 9; + this.button1.Text = "Go"; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // DVBTTuning + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(274, 120); + this.Controls.Add(this.button1); + this.Controls.Add(this.label5); + this.Controls.Add(this.label4); + this.Controls.Add(this.label3); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.Controls.Add(this.textSID); + this.Controls.Add(this.textTSID); + this.Controls.Add(this.textONID); + this.Controls.Add(this.textCarrierFreq); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "DVBTTuning"; + this.Text = "DVBT Tuning"; + this.ResumeLayout(false); + + } + #endregion + + private void button1_Click(object sender, System.EventArgs e) + { + this.DialogResult = DialogResult.OK; + } + + #region Membres de ITuningSelector + + public DirectShowLib.BDA.ITuningSpace TuningSpace + { + get + { + return (this.tuningSpace as ITuningSpace); + } + } + + public DirectShowLib.BDA.ITuneRequest TuneRequest + { + get + { + return (this.tuneRequest as ITuneRequest); + } + } + + public bool TuneSelect() + { + int hr = 0; + ILocator locator; + int freq; + int onid, tsid, sid; + + + hr = this.tuneRequest.get_Locator(out locator); + + hr = locator.get_CarrierFrequency(out freq); + + hr = this.tuneRequest.get_ONID(out onid); + hr = this.tuneRequest.get_TSID(out tsid); + hr = this.tuneRequest.get_SID(out sid); + + textCarrierFreq.Text = freq.ToString(); + textONID.Text = onid.ToString(); + textTSID.Text = tsid.ToString(); + textSID.Text = sid.ToString(); + + this.ShowDialog(); + + if (this.DialogResult == DialogResult.OK) + { + hr = locator.put_CarrierFrequency(Convert.ToInt32(textCarrierFreq.Text)); + hr = this.tuneRequest.put_Locator(locator); + Marshal.ReleaseComObject(locator); + + hr = this.tuneRequest.put_ONID(Convert.ToInt32(textONID.Text)); + hr = this.tuneRequest.put_TSID(Convert.ToInt32(textTSID.Text)); + hr = this.tuneRequest.put_SID(Convert.ToInt32(textSID.Text)); + return true; + } + else + { + Marshal.ReleaseComObject(locator); + return false; + } + } + + #endregion + + } +} diff --git a/Samples/BDA/DTVViewer/DVBTTuning.resx b/Samples/BDA/DTVViewer/DVBTTuning.resx new file mode 100644 index 0000000..538b964 --- /dev/null +++ b/Samples/BDA/DTVViewer/DVBTTuning.resx @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + (Default) + + + False + + + False + + + DVBTTuning + + + 8, 8 + + + True + + + 80 + + + True + + + Private + + \ No newline at end of file diff --git a/Samples/BDA/DTVViewer/ITuningSelector.cs b/Samples/BDA/DTVViewer/ITuningSelector.cs new file mode 100644 index 0000000..4a521d3 --- /dev/null +++ b/Samples/BDA/DTVViewer/ITuningSelector.cs @@ -0,0 +1,22 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; + +using DirectShowLib; +using DirectShowLib.BDA; + +namespace DirectShowLib.Sample +{ + public interface ITuningSelector + { + ITuningSpace TuningSpace {get;} + ITuneRequest TuneRequest {get;} + + bool TuneSelect(); + } +} diff --git a/Samples/BDA/DTVViewer/MainForm.cs b/Samples/BDA/DTVViewer/MainForm.cs new file mode 100644 index 0000000..07d73e7 --- /dev/null +++ b/Samples/BDA/DTVViewer/MainForm.cs @@ -0,0 +1,277 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Windows.Forms; +using System.Data; + +namespace DirectShowLib.Sample +{ + /// + /// Description résumée de Form1. + /// + public class MainForm : Form + { + private System.Windows.Forms.MainMenu mainMenu; + private System.Windows.Forms.MenuItem menuFile; + private System.Windows.Forms.MenuItem menuItem1; + private System.Windows.Forms.MenuItem menuFileExit; + private System.Windows.Forms.MenuItem menuNetworkDVBT; + private System.Windows.Forms.MenuItem menuNetworkDVBS; + private System.Windows.Forms.MenuItem menuItem2; + private System.Windows.Forms.MenuItem menuDigitalTV; + private System.Windows.Forms.MenuItem menuDigitalTVBuildGraph; + private System.Windows.Forms.MenuItem menuFileSaveGraph; + private System.Windows.Forms.MenuItem menuDigitalTVDoTuneRequest; + private System.Windows.Forms.MenuItem menuDigitalTVDecomposeGraph; + + private System.ComponentModel.Container components = null; + + private ITuningSelector tuningSelector = null; + private System.Windows.Forms.MenuItem menuHelp; + private System.Windows.Forms.MenuItem menuHelpAbout; + private BDAGraphBuilder bdaGraphBuilder = null; + + public MainForm() + { + InitializeComponent(); + } + + /// + /// Nettoyage des ressources utilisées. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if (components != null) + { + components.Dispose(); + } + + if (this.bdaGraphBuilder != null) + { + this.bdaGraphBuilder.Dispose(); + this.bdaGraphBuilder = null; + } + } + base.Dispose( disposing ); + } + + #region Code généré par le Concepteur Windows Form + /// + /// Méthode requise pour la prise en charge du concepteur - ne modifiez pas + /// le contenu de cette méthode avec l'éditeur de code. + /// + private void InitializeComponent() + { + this.mainMenu = new System.Windows.Forms.MainMenu(); + this.menuFile = new System.Windows.Forms.MenuItem(); + this.menuFileSaveGraph = new System.Windows.Forms.MenuItem(); + this.menuItem1 = new System.Windows.Forms.MenuItem(); + this.menuFileExit = new System.Windows.Forms.MenuItem(); + this.menuDigitalTV = new System.Windows.Forms.MenuItem(); + this.menuNetworkDVBT = new System.Windows.Forms.MenuItem(); + this.menuNetworkDVBS = new System.Windows.Forms.MenuItem(); + this.menuItem2 = new System.Windows.Forms.MenuItem(); + this.menuDigitalTVBuildGraph = new System.Windows.Forms.MenuItem(); + this.menuDigitalTVDoTuneRequest = new System.Windows.Forms.MenuItem(); + this.menuDigitalTVDecomposeGraph = new System.Windows.Forms.MenuItem(); + this.menuHelp = new System.Windows.Forms.MenuItem(); + this.menuHelpAbout = new System.Windows.Forms.MenuItem(); + // + // mainMenu + // + this.mainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuFile, + this.menuDigitalTV, + this.menuHelp}); + // + // menuFile + // + this.menuFile.Index = 0; + this.menuFile.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuFileSaveGraph, + this.menuItem1, + this.menuFileExit}); + this.menuFile.Text = "&File"; + // + // menuFileSaveGraph + // + this.menuFileSaveGraph.Enabled = false; + this.menuFileSaveGraph.Index = 0; + this.menuFileSaveGraph.Text = "Save Graph"; + this.menuFileSaveGraph.Click += new System.EventHandler(this.menuFileSaveGraph_Click); + // + // menuItem1 + // + this.menuItem1.Index = 1; + this.menuItem1.Text = "-"; + // + // menuFileExit + // + this.menuFileExit.Index = 2; + this.menuFileExit.Text = "&Exit"; + this.menuFileExit.Click += new System.EventHandler(this.menuFileExit_Click); + // + // menuDigitalTV + // + this.menuDigitalTV.Index = 1; + this.menuDigitalTV.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuNetworkDVBT, + this.menuNetworkDVBS, + this.menuItem2, + this.menuDigitalTVBuildGraph, + this.menuDigitalTVDoTuneRequest, + this.menuDigitalTVDecomposeGraph}); + this.menuDigitalTV.Text = "&Digital TV"; + // + // menuNetworkDVBT + // + this.menuNetworkDVBT.Index = 0; + this.menuNetworkDVBT.Text = "DVB-T"; + this.menuNetworkDVBT.Click += new System.EventHandler(this.menuNetworkDVBT_Click); + // + // menuNetworkDVBS + // + this.menuNetworkDVBS.Index = 1; + this.menuNetworkDVBS.Text = "DVB-S"; + this.menuNetworkDVBS.Click += new System.EventHandler(this.menuNetworkDVBS_Click); + // + // menuItem2 + // + this.menuItem2.Index = 2; + this.menuItem2.Text = "-"; + // + // menuDigitalTVBuildGraph + // + this.menuDigitalTVBuildGraph.Enabled = false; + this.menuDigitalTVBuildGraph.Index = 3; + this.menuDigitalTVBuildGraph.Text = "Build Graph"; + this.menuDigitalTVBuildGraph.Click += new System.EventHandler(this.menuDigitalTVBuildGraph_Click); + // + // menuDigitalTVDoTuneRequest + // + this.menuDigitalTVDoTuneRequest.Enabled = false; + this.menuDigitalTVDoTuneRequest.Index = 4; + this.menuDigitalTVDoTuneRequest.Text = "Do a Tune Request"; + this.menuDigitalTVDoTuneRequest.Click += new System.EventHandler(this.menuDigitalTVDoTuneRequest_Click); + // + // menuDigitalTVDecomposeGraph + // + this.menuDigitalTVDecomposeGraph.Enabled = false; + this.menuDigitalTVDecomposeGraph.Index = 5; + this.menuDigitalTVDecomposeGraph.Text = "Decompose Graph"; + this.menuDigitalTVDecomposeGraph.Click += new System.EventHandler(this.menuDigitalTVDecomposeGraph_Click); + // + // menuHelp + // + this.menuHelp.Index = 2; + this.menuHelp.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuHelpAbout}); + this.menuHelp.Text = "Help"; + // + // menuHelpAbout + // + this.menuHelpAbout.Index = 0; + this.menuHelpAbout.Text = "About..."; + this.menuHelpAbout.Click += new System.EventHandler(this.menuHelpAbout_Click); + // + // MainForm + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(640, 480); + this.Menu = this.mainMenu; + this.Name = "MainForm"; + this.Text = "DTV Viewer"; + + } + #endregion + + private void menuFileSaveGraph_Click(object sender, System.EventArgs e) + { + using (SaveFileDialog saveFileDialog = new SaveFileDialog()) + { + saveFileDialog.Filter = "Filter Graph (*.grf)|*.grf"; + + if (saveFileDialog.ShowDialog() == DialogResult.OK) + { + this.bdaGraphBuilder.SaveGraph(saveFileDialog.FileName); + } + } + } + + private void menuFileExit_Click(object sender, System.EventArgs e) + { + this.Close(); + } + + private void menuNetworkDVBT_Click(object sender, System.EventArgs e) + { + this.tuningSelector = new DVBTTuning(); + this.menuNetworkDVBT.Checked = true; + this.menuNetworkDVBS.Enabled = false; + this.menuDigitalTVBuildGraph.Enabled = true; + } + + private void menuNetworkDVBS_Click(object sender, System.EventArgs e) + { + this.tuningSelector = new DVBSTuning(); + this.menuNetworkDVBS.Checked = true; + this.menuNetworkDVBT.Enabled = false; + this.menuDigitalTVBuildGraph.Enabled = true; + } + + private void menuDigitalTVBuildGraph_Click(object sender, System.EventArgs e) + { + if (this.tuningSelector.TuneSelect() == true) + { + this.bdaGraphBuilder = new BDAGraphBuilder(this); + this.bdaGraphBuilder.BuildGraph(this.tuningSelector.TuningSpace); + this.bdaGraphBuilder.SubmitTuneRequest(this.tuningSelector.TuneRequest); + this.bdaGraphBuilder.RunGraph(); + } + + this.menuDigitalTVBuildGraph.Enabled = false; + this.menuFileSaveGraph.Enabled = true; + this.menuDigitalTVDoTuneRequest.Enabled = true; + this.menuDigitalTVDecomposeGraph.Enabled = true; + } + + private void menuDigitalTVDoTuneRequest_Click(object sender, System.EventArgs e) + { + if (this.tuningSelector.TuneSelect() == true) + { + this.bdaGraphBuilder.SubmitTuneRequest(this.tuningSelector.TuneRequest); + } + } + + private void menuDigitalTVDecomposeGraph_Click(object sender, System.EventArgs e) + { + this.bdaGraphBuilder.Dispose(); + this.bdaGraphBuilder = null; + + this.menuNetworkDVBT.Checked = false; + this.menuNetworkDVBT.Enabled = true; + this.menuNetworkDVBS.Checked = false; + this.menuNetworkDVBS.Enabled = true; + + this.menuFileSaveGraph.Enabled = false; + this.menuDigitalTVBuildGraph.Enabled = false; + this.menuDigitalTVDoTuneRequest.Enabled = false; + this.menuDigitalTVDecomposeGraph.Enabled = false; + } + + private void menuHelpAbout_Click(object sender, System.EventArgs e) + { + AboutBox.Show("Basic Digital TV Viewer", "This sample is a basic Digital TV Viewer for DVB-T and DVB-S networks"); + } + } +} diff --git a/Samples/BDA/DTVViewer/MainForm.resx b/Samples/BDA/DTVViewer/MainForm.resx new file mode 100644 index 0000000..08543d9 --- /dev/null +++ b/Samples/BDA/DTVViewer/MainForm.resx @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Private + + + 17, 17 + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + False + + + (Default) + + + False + + + False + + + 8, 8 + + + True + + + 80 + + + MainForm + + + True + + + Private + + \ No newline at end of file diff --git a/Samples/BDA/DTVViewer/StartUp.cs b/Samples/BDA/DTVViewer/StartUp.cs new file mode 100644 index 0000000..940d438 --- /dev/null +++ b/Samples/BDA/DTVViewer/StartUp.cs @@ -0,0 +1,27 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Windows.Forms; + +namespace DirectShowLib.Sample +{ + public sealed class StartUp + { + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.DoEvents(); + + using(MainForm form = new MainForm()) + { + Application.Run(form); + } + } + } +} diff --git a/Samples/BDA/DTVViewer/Toolkit/FilterGraphTools.cs b/Samples/BDA/DTVViewer/Toolkit/FilterGraphTools.cs new file mode 100644 index 0000000..d0dbfb1 --- /dev/null +++ b/Samples/BDA/DTVViewer/Toolkit/FilterGraphTools.cs @@ -0,0 +1,1015 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Collections; +using System.Runtime.InteropServices; +using System.Security.Permissions; + +using DirectShowLib; + +#if !USING_NET11 +using System.Runtime.InteropServices.ComTypes; +#endif + +namespace DirectShowLib.Utils +{ + /// + /// A collection of methods to do common DirectShow tasks. + /// + + public sealed class FilterGraphTools + { + private FilterGraphTools(){} + + /// + /// Add a filter to a DirectShow Graph using its CLSID + /// + /// the IGraphBuilder interface of the graph + /// a valid CLSID. This object must implement IBaseFilter + /// the name used in the graph (may be null) + /// an instance of the filter if the method successfully created it, null if not + /// + /// You can use IsThisComObjectInstalled to check is the CLSID is valid before calling this method + /// + /// This sample shows how to programmatically add a NVIDIA Video decoder filter to a graph + /// + /// Guid nvidiaVideoDecClsid = new Guid("71E4616A-DB5E-452B-8CA5-71D9CC7805E9"); + /// + /// if (FilterGraphTools.IsThisComObjectInstalled(nvidiaVideoDecClsid)) + /// { + /// filter = FilterGraphTools.AddFilterFromClsid(graphBuilder, nvidiaVideoDecClsid, "NVIDIA Video Decoder"); + /// } + /// else + /// { + /// // use another filter... + /// } + /// + /// + /// + /// Thrown if graphBuilder is null + /// Thrown if errors occur when the filter is add to the graph + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static IBaseFilter AddFilterFromClsid(IGraphBuilder graphBuilder, Guid clsid, string name) + { + int hr = 0; + IBaseFilter filter = null; + + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + try + { + Type type = Type.GetTypeFromCLSID(clsid); + filter = (IBaseFilter) Activator.CreateInstance(type); + + hr = graphBuilder.AddFilter(filter, name); + DsError.ThrowExceptionForHR(hr); + } + catch + { + if (filter != null) + { + Marshal.ReleaseComObject(filter); + filter = null; + } + } + + return filter; + } + + /// + /// Add a filter to a DirectShow Graph using its name + /// + /// the IGraphBuilder interface of the graph + /// the filter category (see DirectShowLib.FilterCategory) + /// the filter name (case-sensitive) + /// an instance of the filter if the method successfully created it, null if not + /// This sample shows how to programmatically add a NVIDIA Video decoder filter to a graph + /// + /// filter = FilterGraphTools.AddFilterByName(graphBuilder, FilterCategory.LegacyAmFilterCategory, "NVIDIA Video Decoder"); + /// + /// + /// Thrown if graphBuilder is null + /// Thrown if errors occur when the filter is add to the graph + + public static IBaseFilter AddFilterByName(IGraphBuilder graphBuilder, Guid deviceCategory, string friendlyName) + { + int hr = 0; + IBaseFilter filter = null; + + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + DsDevice[] devices = DsDevice.GetDevicesOfCat(deviceCategory); + + for(int i = 0; i < devices.Length; i++) + { + if (!devices[i].Name.Equals(friendlyName)) + continue; + + hr = (graphBuilder as IFilterGraph2).AddSourceFilterForMoniker(devices[i].Mon, null, friendlyName, out filter); + DsError.ThrowExceptionForHR(hr); + + break; + } + + return filter; + } + + /// + /// Add a filter to a DirectShow Graph using its Moniker's device path + /// + /// the IGraphBuilder interface of the graph + /// a moniker path + /// the name to use for the filter in the graph + /// an instance of the filter if the method successfully creates it, null if not + /// This sample shows how to programmatically add a NVIDIA Video decoder filter to a graph + /// + /// string devicePath = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{71E4616A-DB5E-452B-8CA5-71D9CC7805E9}"; + /// filter = FilterGraphTools.AddFilterByDevicePath(graphBuilder, devicePath, "NVIDIA Video Decoder"); + /// + /// + /// Thrown if graphBuilder is null + /// Thrown if errors occur when the filter is add to the graph + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static IBaseFilter AddFilterByDevicePath(IGraphBuilder graphBuilder, string devicePath, string name) + { + int hr = 0; + IBaseFilter filter = null; +#if USING_NET11 + UCOMIBindCtx bindCtx = null; + UCOMIMoniker moniker = null; +#else + IBindCtx bindCtx = null; + IMoniker moniker = null; +#endif + int eaten; + + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + try + { + hr = NativeMethods.CreateBindCtx(0, out bindCtx); + Marshal.ThrowExceptionForHR(hr); + + hr = NativeMethods.MkParseDisplayName(bindCtx, devicePath, out eaten, out moniker); + Marshal.ThrowExceptionForHR(hr); + + hr = (graphBuilder as IFilterGraph2).AddSourceFilterForMoniker(moniker, bindCtx, name, out filter); + DsError.ThrowExceptionForHR(hr); + } + catch + { + // An error occur. Just returning null... + } + finally + { + if (bindCtx != null) Marshal.ReleaseComObject(bindCtx); + if (moniker != null) Marshal.ReleaseComObject(moniker); + } + + return filter; + } + + /// + /// Find a filter in a DirectShow Graph using its name + /// + /// the IGraphBuilder interface of the graph + /// the filter name to find (case-sensitive) + /// an instance of the filter if found, null if not + /// + /// Thrown if graphBuilder is null + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static IBaseFilter FindFilterByName(IGraphBuilder graphBuilder, string filterName) + { + int hr = 0; + IBaseFilter filter = null; + IEnumFilters enumFilters = null; + + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + hr = graphBuilder.EnumFilters(out enumFilters); + if (hr == 0) + { + IBaseFilter[] filters = new IBaseFilter[1]; + + while (enumFilters.Next(filters.Length, filters, IntPtr.Zero) == 0) + { + FilterInfo filterInfo; + + hr = filters[0].QueryFilterInfo(out filterInfo); + if (hr == 0) + { + if (filterInfo.pGraph != null) + Marshal.ReleaseComObject(filterInfo.pGraph); + + if (filterInfo.achName.Equals(filterName)) + { + filter = filters[0]; + break; + } + } + + Marshal.ReleaseComObject(filters[0]); + } + Marshal.ReleaseComObject(enumFilters); + } + + return filter; + } + + /// + /// Find a filter in a DirectShow Graph using its CLSID + /// + /// the IGraphBuilder interface of the graph + /// the CLSID to find + /// an instance of the filter if found, null if not + /// + /// Thrown if graphBuilder is null + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static IBaseFilter FindFilterByClsid(IGraphBuilder graphBuilder, Guid filterClsid) + { + int hr = 0; + IBaseFilter filter = null; + IEnumFilters enumFilters = null; + + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + hr = graphBuilder.EnumFilters(out enumFilters); + if (hr == 0) + { + IBaseFilter[] filters = new IBaseFilter[1]; + + while (enumFilters.Next(filters.Length, filters, IntPtr.Zero) == 0) + { + Guid clsid; + + hr = filters[0].GetClassID(out clsid); + + if ((hr == 0) && (clsid == filterClsid)) + { + filter = filters[0]; + break; + } + + Marshal.ReleaseComObject(filters[0]); + } + Marshal.ReleaseComObject(enumFilters); + } + + return filter; + } + + /// + /// Render a filter's pin in a DirectShow Graph + /// + /// the IGraphBuilder interface of the graph + /// the filter containing the pin to render + /// the pin name + /// true if rendering is a success, false if not + /// + /// + /// hr = graphBuilder.AddSourceFilter(@"foo.avi", "Source Filter", out filter); + /// DsError.ThrowExceptionForHR(hr); + /// + /// if (!FilterGraphTools.RenderPin(graphBuilder, filter, "Output")) + /// { + /// // Something went wrong... + /// } + /// + /// + /// Thrown if graphBuilder or source is null + /// This method assumes that the filter is part of the given graph + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static bool RenderPin(IGraphBuilder graphBuilder, IBaseFilter source, string pinName) + { + int hr = 0; + + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + if (source == null) + throw new ArgumentNullException("source"); + + IPin pin = DsFindPin.ByName(source, pinName); + + if (pin != null) + { + hr = graphBuilder.Render(pin); + Marshal.ReleaseComObject(pin); + + return (hr >= 0); + } + + return false; + } + + /// + /// Disconnect all pins on a given filter + /// + /// the filter on which to disconnect all the pins + /// Thrown if filter is null + /// Thrown if errors occured during the disconnection process + /// Both input and output pins are disconnected + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static void DisconnectPins(IBaseFilter filter) + { + int hr = 0; + + if (filter == null) + throw new ArgumentNullException("filter"); + + IEnumPins enumPins; + IPin[] pins = new IPin[1]; + + hr = filter.EnumPins(out enumPins); + DsError.ThrowExceptionForHR(hr); + + try + { + while (enumPins.Next(pins.Length, pins, IntPtr.Zero) == 0) + { + try + { + hr = pins[0].Disconnect(); + DsError.ThrowExceptionForHR(hr); + } + finally + { + Marshal.ReleaseComObject(pins[0]); + } + } + } + finally + { + Marshal.ReleaseComObject(enumPins); + } + } + + /// + /// Disconnect pins of all the filters in a DirectShow Graph + /// + /// the IGraphBuilder interface of the graph + /// Thrown if graphBuilder is null + /// Thrown if the method can't enumerate its filters + /// This method doesn't throw an exception if an error occurs during pin disconnections + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static void DisconnectAllPins(IGraphBuilder graphBuilder) + { + int hr = 0; + IEnumFilters enumFilters; + + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + hr = graphBuilder.EnumFilters(out enumFilters); + DsError.ThrowExceptionForHR(hr); + + try + { + IBaseFilter[] filters = new IBaseFilter[1]; + + while (enumFilters.Next(filters.Length, filters, IntPtr.Zero) == 0) + { + try + { + DisconnectPins(filters[0]); + } + catch{} + Marshal.ReleaseComObject(filters[0]); + } + } + finally + { + Marshal.ReleaseComObject(enumFilters); + } + } + + /// + /// Remove and release all filters from a DirectShow Graph + /// + /// the IGraphBuilder interface of the graph + /// Thrown if graphBuilder is null + /// Thrown if the method can't enumerate its filters + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static void RemoveAllFilters(IGraphBuilder graphBuilder) + { + int hr = 0; + IEnumFilters enumFilters; + ArrayList filtersArray = new ArrayList(); + + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + hr = graphBuilder.EnumFilters(out enumFilters); + DsError.ThrowExceptionForHR(hr); + + try + { + IBaseFilter[] filters = new IBaseFilter[1]; + + while (enumFilters.Next(filters.Length, filters, IntPtr.Zero) == 0) + { + filtersArray.Add(filters[0]); + } + } + finally + { + Marshal.ReleaseComObject(enumFilters); + } + + foreach(IBaseFilter filter in filtersArray) + { + hr = graphBuilder.RemoveFilter(filter); + Marshal.ReleaseComObject(filter); + } + } + + /// + /// Save a DirectShow Graph to a GRF file + /// + /// the IGraphBuilder interface of the graph + /// the file to be saved + /// Thrown if graphBuilder is null + /// Thrown if errors occur during the file creation + /// + /// This method overwrites any existing file + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static void SaveGraphFile(IGraphBuilder graphBuilder, string fileName) + { + int hr = 0; + IStorage storage = null; +#if USING_NET11 + UCOMIStream stream = null; +#else + IStream stream = null; +#endif + + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + try + { + hr = NativeMethods.StgCreateDocfile( + fileName, + STGM.Create | STGM.Transacted | STGM.ReadWrite | STGM.ShareExclusive, + 0, + out storage + ); + + Marshal.ThrowExceptionForHR(hr); + + hr = storage.CreateStream( + @"ActiveMovieGraph", + STGM.Write | STGM.Create | STGM.ShareExclusive, + 0, + 0, + out stream + ); + + Marshal.ThrowExceptionForHR(hr); + + hr = (graphBuilder as IPersistStream).Save(stream, true); + Marshal.ThrowExceptionForHR(hr); + + hr = storage.Commit(STGC.Default); + Marshal.ThrowExceptionForHR(hr); + } + finally + { + if (stream != null) + Marshal.ReleaseComObject(stream); + if (storage != null) + Marshal.ReleaseComObject(storage); + } + } + + /// + /// Load a DirectShow Graph from a file + /// + /// the IGraphBuilder interface of the graph + /// the file to be loaded + /// Thrown if graphBuilder is null + /// Thrown if the given file is not a valid graph file + /// Thrown if errors occur during loading + /// + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static void LoadGraphFile(IGraphBuilder graphBuilder, string fileName) + { + int hr = 0; + IStorage storage = null; +#if USING_NET11 + UCOMIStream stream = null; +#else + IStream stream = null; +#endif + + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + try + { + if (NativeMethods.StgIsStorageFile(fileName) != 0) + throw new ArgumentException(); + + hr = NativeMethods.StgOpenStorage( + fileName, + null, + STGM.Transacted | STGM.Read | STGM.ShareDenyWrite, + IntPtr.Zero, + 0, + out storage + ); + + Marshal.ThrowExceptionForHR(hr); + + hr = storage.OpenStream( + @"ActiveMovieGraph", + IntPtr.Zero, + STGM.Read | STGM.ShareExclusive, + 0, + out stream + ); + + Marshal.ThrowExceptionForHR(hr); + + hr = (graphBuilder as IPersistStream).Load(stream); + Marshal.ThrowExceptionForHR(hr); + } + finally + { + if (stream != null) + Marshal.ReleaseComObject(stream); + if (storage != null) + Marshal.ReleaseComObject(storage); + } + } + + /// + /// Check if a DirectShow filter can display Property Pages + /// + /// A DirectShow Filter + /// Thrown if filter is null + /// + /// true if the filter has Property Pages, false if not + /// + /// This method is intended to be used with ShowFilterPropertyPage + /// + + public static bool HasPropertyPages(IBaseFilter filter) + { + if (filter == null) + throw new ArgumentNullException("filter"); + + return ((filter as ISpecifyPropertyPages) != null); + } + + /// + /// Display Property Pages of a given DirectShow filter + /// + /// A DirectShow Filter + /// A hwnd handle of a window to contain the pages + /// Thrown if filter is null + /// + /// + /// You can check if a filter supports Property Pages with the HasPropertyPages method.
+ /// Warning : This method is blocking. It only returns when the Property Pages are closed. + ///
+ /// This sample shows how to check if a filter supports Property Pages and displays them + /// + /// if (FilterGraphTools.HasPropertyPages(myFilter)) + /// { + /// FilterGraphTools.ShowFilterPropertyPage(myFilter, myForm.Handle); + /// } + /// + /// + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static void ShowFilterPropertyPage(IBaseFilter filter, IntPtr parent) + { + int hr = 0; + FilterInfo filterInfo; + DsCAUUID caGuid; + object[] objs; + + if (filter == null) + throw new ArgumentNullException("filter"); + + if (HasPropertyPages(filter)) + { + hr = filter.QueryFilterInfo(out filterInfo); + DsError.ThrowExceptionForHR(hr); + + if (filterInfo.pGraph != null) + Marshal.ReleaseComObject(filterInfo.pGraph); + + hr = (filter as ISpecifyPropertyPages).GetPages(out caGuid); + DsError.ThrowExceptionForHR(hr); + + try + { + objs = new object[1]; + objs[0] = filter; + + hr = NativeMethods.OleCreatePropertyFrame( + parent, 0, 0, + filterInfo.achName, + objs.Length, objs, + caGuid.cElems, caGuid.pElems, + 0, 0, + IntPtr.Zero + ); + DsError.ThrowExceptionForHR(hr); + } + finally + { + Marshal.FreeCoTaskMem(caGuid.pElems); + } + } + } + + /// + /// Check if a COM Object is available + /// + /// The CLSID of this object + /// This sample shows how to check if the MPEG-2 Demultiplexer filter is available + /// + /// if (FilterGraphTools.IsThisComObjectInstalled(typeof(MPEG2Demultiplexer).GUID)) + /// { + /// // Use it... + /// } + /// + /// + /// true if the object is available, false if not + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static bool IsThisComObjectInstalled(Guid clsid) + { + bool retval = false; + + try + { + Type type = Type.GetTypeFromCLSID(clsid); + object o = Activator.CreateInstance(type); + retval = true; + Marshal.ReleaseComObject(o); + } + catch{} + + return retval; + } + + /// + /// Check if the Video Mixing Renderer 9 Filter is available + /// + /// + /// + /// This method uses IsThisComObjectInstalled internally + /// + /// true if VMR9 is present, false if not + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static bool IsVMR9Present() + { + return IsThisComObjectInstalled(typeof(VideoMixingRenderer9).GUID); + } + + /// + /// Check if the Video Mixing Renderer 7 Filter is available + /// + /// + /// + /// This method uses IsThisComObjectInstalled internally + /// + /// true if VMR7 is present, false if not + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static bool IsVMR7Present() + { + return IsThisComObjectInstalled(typeof(VideoMixingRenderer).GUID); + } + + /// + /// Connect pins from two filters + /// + /// the IGraphBuilder interface of the graph + /// the upstream filter + /// the upstream filter pin name + /// the downstream filter + /// the downstream filter pin name + /// indicate if the method should use DirectShow's Intelligent Connect + /// Thrown if graphBuilder, upFilter or downFilter are null + /// Thrown if pin names are not found in filters + /// Thrown if pins can't connect + /// + /// If useIntelligentConnect is true, this method can add missing filters between the two pins.
+ /// If useIntelligentConnect is false, this method works only if the two media types are compatible. + ///
+ + public static void ConnectFilters(IGraphBuilder graphBuilder, IBaseFilter upFilter, string sourcePinName, IBaseFilter downFilter, string destPinName, bool useIntelligentConnect) + { + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + if (upFilter == null) + throw new ArgumentNullException("upFilter"); + + if (downFilter == null) + throw new ArgumentNullException("downFilter"); + + IPin sourcePin, destPin; + + sourcePin = DsFindPin.ByName(upFilter, sourcePinName); + if (sourcePin == null) + throw new ArgumentException("The source filter has no pin called : " + sourcePinName, sourcePinName); + + destPin = DsFindPin.ByName(downFilter, destPinName); + if (destPin == null) + throw new ArgumentException("The downstream filter has no pin called : " + destPinName, destPinName); + + try + { + ConnectFilters(graphBuilder, sourcePin, destPin, useIntelligentConnect); + } + finally + { + Marshal.ReleaseComObject(sourcePin); + Marshal.ReleaseComObject(destPin); + } + } + + /// + /// Connect pins from two filters + /// + /// the IGraphBuilder interface of the graph + /// the source (upstream / output) pin + /// the destination (downstream / input) pin + /// indicates if the method should use DirectShow's Intelligent Connect + /// Thrown if graphBuilder, sourcePin or destPin are null + /// Thrown if pins can't connect + /// + /// If useIntelligentConnect is true, this method can add missing filters between the two pins.
+ /// If useIntelligentConnect is false, this method works only if the two media types are compatible. + ///
+ + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static void ConnectFilters(IGraphBuilder graphBuilder, IPin sourcePin, IPin destPin, bool useIntelligentConnect) + { + int hr = 0; + + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + if (sourcePin == null) + throw new ArgumentNullException("sourcePin"); + + if (destPin == null) + throw new ArgumentNullException("destPin"); + + if (useIntelligentConnect) + { + hr = graphBuilder.Connect(sourcePin, destPin); + DsError.ThrowExceptionForHR(hr); + } + else + { + hr = graphBuilder.ConnectDirect(sourcePin, destPin, null); + DsError.ThrowExceptionForHR(hr); + } + } + + } + + #region Unmanaged Code declarations + + [Flags] + internal enum STGM + { + Read = 0x00000000, + Write = 0x00000001, + ReadWrite = 0x00000002, + ShareDenyNone = 0x00000040, + ShareDenyRead = 0x00000030, + ShareDenyWrite = 0x00000020, + ShareExclusive = 0x00000010, + Priority = 0x00040000, + Create = 0x00001000, + Convert = 0x00020000, + FailIfThere = 0x00000000, + Direct = 0x00000000, + Transacted = 0x00010000, + NoScratch = 0x00100000, + NoSnapShot = 0x00200000, + Simple = 0x08000000, + DirectSWMR = 0x00400000, + DeleteOnRelease = 0x04000000, + } + + [Flags] + internal enum STGC + { + Default = 0, + Overwrite = 1, + OnlyIfCurrent = 2, + DangerouslyCommitMerelyToDiskCache = 4, + Consolidate = 8 + } + + [Guid("0000000b-0000-0000-C000-000000000046"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + internal interface IStorage + { + [PreserveSig] + int CreateStream( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, + [In] STGM grfMode, + [In] int reserved1, + [In] int reserved2, +#if USING_NET11 + [Out] out UCOMIStream ppstm +#else + [Out] out IStream ppstm +#endif + ); + + [PreserveSig] + int OpenStream( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, + [In] IntPtr reserved1, + [In] STGM grfMode, + [In] int reserved2, +#if USING_NET11 + [Out] out UCOMIStream ppstm +#else + [Out] out IStream ppstm +#endif + ); + + [PreserveSig] + int CreateStorage( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, + [In] STGM grfMode, + [In] int reserved1, + [In] int reserved2, + [Out] out IStorage ppstg + ); + + [PreserveSig] + int OpenStorage( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, + [In] IStorage pstgPriority, + [In] STGM grfMode, + [In] int snbExclude, + [In] int reserved, + [Out] out IStorage ppstg + ); + + [PreserveSig] + int CopyTo( + [In] int ciidExclude, + [In] Guid[] rgiidExclude, + [In] string[] snbExclude, + [In] IStorage pstgDest + ); + + [PreserveSig] + int MoveElementTo( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, + [In] IStorage pstgDest, + [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsNewName, + [In] STGM grfFlags + ); + + [PreserveSig] + int Commit([In] STGC grfCommitFlags); + + [PreserveSig] + int Revert(); + + [PreserveSig] + int EnumElements( + [In] int reserved1, + [In] IntPtr reserved2, + [In] int reserved3, + [Out, MarshalAs(UnmanagedType.Interface)] out object ppenum + ); + + [PreserveSig] + int DestroyElement([In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName); + + [PreserveSig] + int RenameElement( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsOldName, + [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsNewName + ); + + [PreserveSig] + int SetElementTimes( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, +#if USING_NET11 + [In] FILETIME pctime, + [In] FILETIME patime, + [In] FILETIME pmtime +#else + [In] System.Runtime.InteropServices.ComTypes.FILETIME pctime, + [In] System.Runtime.InteropServices.ComTypes.FILETIME patime, + [In] System.Runtime.InteropServices.ComTypes.FILETIME pmtime +#endif + ); + + [PreserveSig] + int SetClass([In, MarshalAs(UnmanagedType.LPStruct)] Guid clsid); + + [PreserveSig] + int SetStateBits( + [In] int grfStateBits, + [In] int grfMask + ); + + [PreserveSig] + int Stat( +#if USING_NET11 + [Out] out STATSTG pStatStg, +#else + [Out] out System.Runtime.InteropServices.ComTypes.STATSTG pStatStg, +#endif + [In] int grfStatFlag + ); + } + + internal sealed class NativeMethods + { + private NativeMethods(){} + + [DllImport("ole32.dll")] +#if USING_NET11 + public static extern int CreateBindCtx(int reserved, out UCOMIBindCtx ppbc); +#else + public static extern int CreateBindCtx(int reserved, out IBindCtx ppbc); +#endif + + [DllImport("ole32.dll")] +#if USING_NET11 + public static extern int MkParseDisplayName(UCOMIBindCtx pcb, [MarshalAs(UnmanagedType.LPWStr)] string szUserName, out int pchEaten, out UCOMIMoniker ppmk); +#else + public static extern int MkParseDisplayName(IBindCtx pcb, [MarshalAs(UnmanagedType.LPWStr)] string szUserName, out int pchEaten, out IMoniker ppmk); +#endif + + [DllImport("oleaut32.dll", CharSet=CharSet.Unicode, ExactSpelling=true)] + public static extern int OleCreatePropertyFrame( + [In] IntPtr hwndOwner, + [In] int x, + [In] int y, + [In, MarshalAs(UnmanagedType.LPWStr)] string lpszCaption, + [In] int cObjects, + [In, MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.IUnknown)] object[] ppUnk, + [In] int cPages, + [In] IntPtr pPageClsID, + [In] int lcid, + [In] int dwReserved, + [In] IntPtr pvReserved + ); + + [DllImport("ole32.dll", CharSet=CharSet.Unicode, ExactSpelling=true)] + public static extern int StgCreateDocfile( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, + [In] STGM grfMode, + [In] int reserved, + [Out] out IStorage ppstgOpen + ); + + [DllImport("ole32.dll", CharSet=CharSet.Unicode, ExactSpelling=true)] + public static extern int StgIsStorageFile([In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName); + + [DllImport("ole32.dll", CharSet=CharSet.Unicode, ExactSpelling=true)] + public static extern int StgOpenStorage( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, + [In] IStorage pstgPriority, + [In] STGM grfMode, + [In] IntPtr snbExclude, + [In] int reserved, + [Out] out IStorage ppstgOpen + ); + + } + #endregion + +} diff --git a/Samples/BDA/DTVViewer/readme.txt b/Samples/BDA/DTVViewer/readme.txt new file mode 100644 index 0000000..86a2f55 --- /dev/null +++ b/Samples/BDA/DTVViewer/readme.txt @@ -0,0 +1,71 @@ +DTVViewer - A basic Digital TV (BDA) viewer sample (version 1.2) + +This sample demonstrates how to use BDA to display Digital TV into a Windows +Form. + +This application asks the user for tuning parameters. You have to know most of +them to have a working Tune Request. + +DVB-T parameters are directly dependent on the emiter to which your roof +antenna is pointing. Each country's broadcasting DVB-T TVs have a website with +that informations. Worst case, http://www.dvb.org/ can be a good start... + +DVB-S parameters depend on the satellite pointed to by your dish antenna. +Websites like http://www.lyngsat.com/ or http://en.kingofsat.net/ can be really +useful! + +Files in this project : + +StartUp.cs : A StartUp class with the application main entry point. Windows XP +enhanced UI is activated here. + +MainForm.cs : The application main form. Nothing DirectShow specific, just +plain .Net stuff. This form uses the BDAGraphBuilder class to drive the +DirectShow graph and do the tuning through a class implementing +ITuningSelector. + +ITuningSelector.cs : An interface to vitualize the tuning process. In this +application, tuning parameters are requested from the user but this task could +easily be replaced by data coming from a DB, an XML file or whatever. + +DVBSTuning.cs & DVBTTuning.cs : Two Windows Forms designed to ask the user the +tuning parameters like the Carrier Frequency, etc. They also implement the +ITuningSelector interface (see later). With this architecture, it's easy to add +support to ATSC or DVB-C networks. + +BDAGraphBuilder.cs : This is here the real Magic is! This class builds the BDA +graph and tunes it with Tune Requests provided by DVBSTuning or DVBTTuning +forms. + +About BDA driver models : + +A Digital TV hardware broadly provide 3 main functions : + 1) Tuner : filters the particular frequency that carries the transport + stream. + 2) Demodulator : translates the analog signal into a digital bit stream. + 3) Capture : moves the data into host memory. + +The BDA driver model allow IHV to provide drivers that physicaly appear in +GraphEdit in three flavor : + 1) The all-in-one filter model : The three functions are grouped in a + single filter. This filter can be connected directly between the Network + Provider and the MPEG-2 Demultiplexor. USB devices usually support this + model... + 2) The two filters model : The driver provide 2 filters. The first combine + the Tuner and the Demodulator functions and the second is for the Capture + function. You need to connect the two filters together to be able to build + a working chain between the Network Provider and the MPEG-2 Demultiplexor. + This is the most commun driver model. Almost all PCI hardware drivers are + built using this model. + 3) The three filters model : The driver provide 3 filters, one for each + functions. You need to connect the three filters together to be able to + build a working chain between the Network Provider and the MPEG-2 + Demultiplexor. I never see this model in real life but it is technicaly + possible... + +The version (1.1) had been upgraded to support the three models (hope so)... + +In this new version, I have modified the ConnectFilters method (from the +BDAGraphBuilder.cs file) to handle the new behaviour of the Windows Seven's +MPEG-2 Demux (see comments in the source code). This sample should also handle +HDTV with the MS's audio and video decoders. diff --git a/Samples/Capture/CapWMV/App.ico b/Samples/Capture/CapWMV/App.ico new file mode 100644 index 0000000000000000000000000000000000000000..3a5525fd794f7a7c5c8e6187f470ea3af38cd2b6 GIT binary patch literal 1078 zcmeHHJr05}7=1t!Hp3A*8IHkVf+j?-!eHY14Gtcw1Eb*_9>Bq^zETJ@GKj{_2j4$w zo9}xCh!8{T3=X##Skq>ikMjsvB|y%crWBM2iW(4pI}c%z6%lW!=~4v77#3{z!dmB1 z__&l)-{KUYR+|8|;wB^R|9ET$J@(@=#rd^=)qs85?vAy(PSF5CyNkus435LVkZ$rj zNw|JG-P7^hF<(;#o*Vk}5R#e|^13tBbQkeF?djULtvqyxd3<{9 literal 0 HcmV?d00001 diff --git a/Samples/Capture/CapWMV/AssemblyInfo.cs b/Samples/Capture/CapWMV/AssemblyInfo.cs new file mode 100644 index 0000000..9f89a32 --- /dev/null +++ b/Samples/Capture/CapWMV/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/Capture/CapWMV/CapWMV-2005.csproj b/Samples/Capture/CapWMV/CapWMV-2005.csproj new file mode 100644 index 0000000..88225ce --- /dev/null +++ b/Samples/Capture/CapWMV/CapWMV-2005.csproj @@ -0,0 +1,113 @@ + + + Local + 8.0.50727 + 2.0 + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59} + Debug + AnyCPU + App.ico + + + CapWMV + + + JScript + Grid + IE50 + false + WinExe + asf + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + + + Code + + + Code + + + Form + + + Form1.cs + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Capture/CapWMV/CapWMV-2005.sln b/Samples/Capture/CapWMV/CapWMV-2005.sln new file mode 100644 index 0000000..bc3e437 --- /dev/null +++ b/Samples/Capture/CapWMV/CapWMV-2005.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CapWMV-2005", "CapWMV-2005.csproj", "{1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Capture/CapWMV/CapWMV-2008.sln b/Samples/Capture/CapWMV/CapWMV-2008.sln new file mode 100644 index 0000000..20af076 --- /dev/null +++ b/Samples/Capture/CapWMV/CapWMV-2008.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CapWMV-2008", "CapWMV-2008.csproj", "{1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Capture/CapWMV/CapWMV.csproj b/Samples/Capture/CapWMV/CapWMV.csproj new file mode 100644 index 0000000..1f6b3e1 --- /dev/null +++ b/Samples/Capture/CapWMV/CapWMV.csproj @@ -0,0 +1,145 @@ + + + + Local + 8.0.50727 + 2.0 + {1E4F75E2-476C-4D6E-87BF-F545CCF5CE59} + Debug + AnyCPU + App.ico + + + CapWMV + + + JScript + Grid + IE50 + false + WinExe + asf + OnBuildSuccess + + + + + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + + + Code + + + Code + + + Form + + + Form1.cs + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Capture/CapWMV/Capture.cs b/Samples/Capture/CapWMV/Capture.cs new file mode 100644 index 0000000..0c7b1f5 --- /dev/null +++ b/Samples/Capture/CapWMV/Capture.cs @@ -0,0 +1,224 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + + +using System; +using System.Runtime.InteropServices; + +using DirectShowLib; + + +namespace AsfFilter +{ + /// Summary description for MainForm. + internal class Capture: IDisposable + { + #region Member variables + + /// graph builder interface. + private IFilterGraph2 m_FilterGraph = null; + IMediaControl m_mediaCtrl = null; + + /// Set by async routine when it captures an image + private bool m_bRunning = false; + +#if DEBUG + DsROTEntry m_rot = null; +#endif + + #endregion + + /// release everything. + public void Dispose() + { + GC.SuppressFinalize(this); + CloseInterfaces(); + } + + ~Capture() + { + Dispose(); + } + + /// + /// Create capture object + /// + /// Zero based index of capture device + /// Output ASF file name + public Capture(int iDeviceNum, string szOutputFileName) + { + DsDevice [] capDevices; + + // Get the collection of video devices + capDevices = DsDevice.GetDevicesOfCat( FilterCategory.VideoInputDevice ); + + if (iDeviceNum + 1 > capDevices.Length) + { + throw new Exception("No video capture devices found at that index!"); + } + + try + { + // Set up the capture graph + SetupGraph( capDevices[iDeviceNum], szOutputFileName); + + m_bRunning = false; + } + catch + { + Dispose(); + throw; + } + } + + + // Start the capture graph + public void Start() + { + if (!m_bRunning) + { + int hr = m_mediaCtrl.Run(); + Marshal.ThrowExceptionForHR( hr ); + + m_bRunning = true; + } + } + + // Pause the capture graph. + // Running the graph takes up a lot of resources. Pause it when it + // isn't needed. + public void Pause() + { + if (m_bRunning) + { + IMediaControl mediaCtrl = m_FilterGraph as IMediaControl; + + int hr = mediaCtrl.Pause(); + Marshal.ThrowExceptionForHR( hr ); + + m_bRunning = false; + } + } + + /// build the capture graph. + private void SetupGraph(DsDevice dev, string szOutputFileName) + { + int hr; + + IBaseFilter capFilter = null; + IBaseFilter asfWriter = null; + ICaptureGraphBuilder2 capGraph = null; + + // Get the graphbuilder object + m_FilterGraph = (IFilterGraph2)new FilterGraph(); + +#if DEBUG + m_rot = new DsROTEntry( m_FilterGraph ); +#endif + + try + { + // Get the ICaptureGraphBuilder2 + capGraph = (ICaptureGraphBuilder2) new CaptureGraphBuilder2(); + + // Start building the graph + hr = capGraph.SetFiltergraph( m_FilterGraph ); + Marshal.ThrowExceptionForHR( hr ); + + // Add the capture device to the graph + hr = m_FilterGraph.AddSourceFilterForMoniker(dev.Mon, null, dev.Name, out capFilter); + Marshal.ThrowExceptionForHR( hr ); + + asfWriter = ConfigAsf(capGraph, szOutputFileName); + + hr = capGraph.RenderStream(null, null, capFilter, null, asfWriter); + Marshal.ThrowExceptionForHR( hr ); + + m_mediaCtrl = m_FilterGraph as IMediaControl; + } + finally + { + if (capFilter != null) + { + Marshal.ReleaseComObject(capFilter); + capFilter = null; + } + if (asfWriter != null) + { + Marshal.ReleaseComObject(asfWriter); + asfWriter = null; + } + if (capGraph != null) + { + Marshal.ReleaseComObject(capGraph); + capGraph = null; + } + } + } + + private IBaseFilter ConfigAsf(ICaptureGraphBuilder2 capGraph, string szOutputFileName) + { + IFileSinkFilter pTmpSink = null; + IBaseFilter asfWriter = null; + + int hr = capGraph.SetOutputFileName( MediaSubType.Asf, szOutputFileName, out asfWriter, out pTmpSink); + Marshal.ThrowExceptionForHR( hr ); + + try + { + IConfigAsfWriter lConfig = asfWriter as IConfigAsfWriter; + + // Windows Media Video 8 for Dial-up Modem (No audio, 56 Kbps) + // READ THE README for info about using guids + Guid cat = new Guid(0x6E2A6955, 0x81DF, 0x4943, 0xBA, 0x50, 0x68, 0xA9, 0x86, 0xA7, 0x08, 0xF6); + + hr = lConfig.ConfigureFilterUsingProfileGuid(cat); + Marshal.ThrowExceptionForHR( hr ); + } + finally + { + Marshal.ReleaseComObject(pTmpSink); + } + + return asfWriter; + } + + /// Shut down capture + private void CloseInterfaces() + { + int hr; + + try + { + if( m_mediaCtrl != null ) + { + // Stop the graph + hr = m_mediaCtrl.Stop(); + m_bRunning = false; + } + } + catch + { + } + +#if DEBUG + // Remove graph from the ROT + if ( m_rot != null ) + { + m_rot.Dispose(); + m_rot = null; + } +#endif + + if (m_FilterGraph != null) + { + Marshal.ReleaseComObject(m_FilterGraph); + m_FilterGraph = null; + } + } + } +} diff --git a/Samples/Capture/CapWMV/Form1.cs b/Samples/Capture/CapWMV/Form1.cs new file mode 100644 index 0000000..e210f77 --- /dev/null +++ b/Samples/Capture/CapWMV/Form1.cs @@ -0,0 +1,155 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace AsfFilter +{ + /// + /// Summary description for Form1. + /// + public class Form1 : System.Windows.Forms.Form + { + private System.Windows.Forms.Button button1; + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.Label label1; + /// + /// Required designer variable. + /// + private System.ComponentModel.Container components = null; + + public Form1() + { + // + // Required for Windows Form Designer support + // + InitializeComponent(); + + // + // TODO: Add any constructor code after InitializeComponent call + // + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if (cam != null) + { + cam.Dispose(); + cam = null; + } + + if (components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.button1 = new System.Windows.Forms.Button(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // button1 + // + this.button1.Location = new System.Drawing.Point(88, 80); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(75, 48); + this.button1.TabIndex = 0; + this.button1.Text = "Start"; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // textBox1 + // + this.textBox1.Location = new System.Drawing.Point(16, 40); + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size(160, 20); + this.textBox1.TabIndex = 1; + this.textBox1.Text = "foo.wmv"; + // + // label1 + // + this.label1.Location = new System.Drawing.Point(16, 24); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(56, 16); + this.label1.TabIndex = 2; + this.label1.Text = "Output file"; + // + // Form1 + // + this.AcceptButton = this.button1; + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(248, 162); + this.Controls.Add(this.label1); + this.Controls.Add(this.textBox1); + this.Controls.Add(this.button1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.Name = "Form1"; + this.Text = "AsfFilter"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + #endregion + + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.Run(new Form1()); + } + + Capture cam = null; + + private void button1_Click(object sender, System.EventArgs e) + { + const int VIDEODEVICE = 0; // zero based index of video capture device to use + + Cursor.Current = Cursors.WaitCursor; + + if (cam == null) + { + cam = new Capture(VIDEODEVICE, textBox1.Text); + cam.Start(); + button1.Text = "Stop"; + textBox1.ReadOnly = true; + } + else + { + button1.Text = "Start"; + textBox1.ReadOnly = false; + + // Pause the recording + cam.Pause(); + + // Close it down + cam.Dispose(); + cam = null; + } + + Cursor.Current = Cursors.Default; + } + } +} diff --git a/Samples/Capture/CapWMV/Form1.resx b/Samples/Capture/CapWMV/Form1.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/Samples/Capture/CapWMV/Form1.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Samples/Capture/CapWMV/readme.txt b/Samples/Capture/CapWMV/readme.txt new file mode 100644 index 0000000..0e89e2c --- /dev/null +++ b/Samples/Capture/CapWMV/readme.txt @@ -0,0 +1,18 @@ +--------------------------------------------------------------------- +CapWMV + +A .NET sample application using the WM ASF Writer filter to create +an wmv file + +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + +--------------------------------------------------------------------- + +This sample uses IConfigAsfWriter::ConfigureFilterUsingProfileGuid to configure the writer. This method is DEPRECATED by Microsoft. The reason they did this is that the number of configuration options grew too large, and creating a separate guid for all the permutations wasn't practical. + +The new method is using IConfigAsfWriter::ConfigureFilterUsingProfile. However, that method requires IWMProfile, which in turn requires IWMStreamConfig, which requires... Rather than duplicate all the "WindowsMedia" interfaces in a "DirectShow" library, if you want to use the new approach, use the WindowsMediaLib. + +However, if you MUST use guids, you can find them defined in %windir%\WMSysPr9.prx \ No newline at end of file diff --git a/Samples/Capture/DxLogo/App.ico b/Samples/Capture/DxLogo/App.ico new file mode 100644 index 0000000000000000000000000000000000000000..3a5525fd794f7a7c5c8e6187f470ea3af38cd2b6 GIT binary patch literal 1078 zcmeHHJr05}7=1t!Hp3A*8IHkVf+j?-!eHY14Gtcw1Eb*_9>Bq^zETJ@GKj{_2j4$w zo9}xCh!8{T3=X##Skq>ikMjsvB|y%crWBM2iW(4pI}c%z6%lW!=~4v77#3{z!dmB1 z__&l)-{KUYR+|8|;wB^R|9ET$J@(@=#rd^=)qs85?vAy(PSF5CyNkus435LVkZ$rj zNw|JG-P7^hF<(;#o*Vk}5R#e|^13tBbQkeF?djULtvqyxd3<{9 literal 0 HcmV?d00001 diff --git a/Samples/Capture/DxLogo/AssemblyInfo.cs b/Samples/Capture/DxLogo/AssemblyInfo.cs new file mode 100644 index 0000000..9f89a32 --- /dev/null +++ b/Samples/Capture/DxLogo/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/Capture/DxLogo/Capture.cs b/Samples/Capture/DxLogo/Capture.cs new file mode 100644 index 0000000..cfab2a6 --- /dev/null +++ b/Samples/Capture/DxLogo/Capture.cs @@ -0,0 +1,422 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.Runtime.InteropServices; +using System.Diagnostics; + +using DirectShowLib; + + +namespace DxLogo +{ + /// Summary description for MainForm. + internal class Capture : ISampleGrabberCB, IDisposable + { + #region Member variables + + /// graph builder interface. + private IFilterGraph2 m_FilterGraph = null; + IMediaControl m_mediaCtrl = null; + + /// Set by async routine when it captures an image + private bool m_bRunning = false; + + /// Dimensions of the image, calculated once in constructor. + private int m_videoWidth; + private int m_videoHeight; + private int m_stride; + + BitmapData m_bmdLogo = null; + Bitmap m_Bitmap = null; + +#if DEBUG + // Allow you to "Connect to remote graph" from GraphEdit + DsROTEntry m_rot = null; +#endif + + #endregion + + #region API + + [DllImport("Kernel32.dll", EntryPoint="RtlMoveMemory")] + private static extern void CopyMemory(IntPtr Destination, IntPtr Source, [MarshalAs(UnmanagedType.U4)] uint Length); + + #endregion + + /// zero based device index, and some device parms, plus the file name to save to + public Capture(int iDeviceNum, int iFrameRate, int iWidth, int iHeight, string FileName) + { + DsDevice[] capDevices; + + // Get the collection of video devices + capDevices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice); + + if (iDeviceNum + 1 > capDevices.Length) + { + throw new Exception("No video capture devices found at that index!"); + } + + try + { + // Set up the capture graph + SetupGraph( capDevices[iDeviceNum], iFrameRate, iWidth, iHeight, FileName); + } + catch + { + Dispose(); + throw; + } + } + + /// release everything. + public void Dispose() + { + CloseInterfaces(); + if (m_Bitmap != null) + { + m_Bitmap.UnlockBits(m_bmdLogo); + m_Bitmap = null; + m_bmdLogo = null; + } + } + // Destructor + ~Capture() + { + CloseInterfaces(); + } + + + /// capture the next image + public void Start() + { + if (!m_bRunning) + { + int hr = m_mediaCtrl.Run(); + DsError.ThrowExceptionForHR( hr ); + + m_bRunning = true; + } + } + // Pause the capture graph. + // Running the graph takes up a lot of resources. Pause it when it + // isn't needed. + public void Pause() + { + if (m_bRunning) + { + int hr = m_mediaCtrl.Pause(); + DsError.ThrowExceptionForHR( hr ); + + m_bRunning = false; + } + } + + /// Specify the logo file to write onto each frame + public void SetLogo(string fileName) + { + lock (this) + { + if (fileName.Length > 0) + { + m_Bitmap = new Bitmap(fileName); + + Rectangle r = new Rectangle(0, 0, m_Bitmap.Width, m_Bitmap.Height); + m_bmdLogo = m_Bitmap.LockBits(r, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); + } + else + { + if (m_Bitmap != null) + { + m_Bitmap.UnlockBits(m_bmdLogo); + + m_Bitmap = null; + m_bmdLogo = null; + } + } + } + } + + + /// build the capture graph for grabber. + private void SetupGraph(DsDevice dev, int iFrameRate, int iWidth, int iHeight, string FileName) + { + int hr; + + ISampleGrabber sampGrabber = null; + IBaseFilter baseGrabFlt = null; + IBaseFilter capFilter = null; + IBaseFilter muxFilter = null; + IFileSinkFilter fileWriterFilter = null; + ICaptureGraphBuilder2 capGraph = null; + + // Get the graphbuilder object + m_FilterGraph = new FilterGraph() as IFilterGraph2; + m_mediaCtrl = m_FilterGraph as IMediaControl; + +#if DEBUG + m_rot = new DsROTEntry(m_FilterGraph); +#endif + try + { + // Get the ICaptureGraphBuilder2 + capGraph = (ICaptureGraphBuilder2) new CaptureGraphBuilder2(); + + // Get the SampleGrabber interface + sampGrabber = (ISampleGrabber) new SampleGrabber(); + + // Start building the graph + hr = capGraph.SetFiltergraph( m_FilterGraph ); + DsError.ThrowExceptionForHR( hr ); + + // Add the video device + hr = m_FilterGraph.AddSourceFilterForMoniker(dev.Mon, null, dev.Name, out capFilter); + DsError.ThrowExceptionForHR( hr ); + + baseGrabFlt = (IBaseFilter) sampGrabber; + ConfigureSampleGrabber(sampGrabber); + + // Add the frame grabber to the graph + hr = m_FilterGraph.AddFilter( baseGrabFlt, "Ds.NET Grabber" ); + DsError.ThrowExceptionForHR( hr ); + + // If any of the default config items are set + if (iFrameRate + iHeight + iWidth > 0) + { + SetConfigParms(capGraph, capFilter, iFrameRate, iWidth, iHeight); + } + + // Create a filter for the output avi file + hr = capGraph.SetOutputFileName(MediaSubType.Avi, FileName, out muxFilter, out fileWriterFilter); + DsError.ThrowExceptionForHR( hr ); + + // Connect everything together + hr = capGraph.RenderStream( PinCategory.Capture, MediaType.Video, capFilter, baseGrabFlt, muxFilter); + DsError.ThrowExceptionForHR( hr ); + + // Now that sizes are fixed, store the sizes + SaveSizeInfo(sampGrabber); + } + finally + { + if (fileWriterFilter != null) + { + Marshal.ReleaseComObject(fileWriterFilter); + fileWriterFilter = null; + } + if (muxFilter != null) + { + Marshal.ReleaseComObject(muxFilter); + muxFilter = null; + } + if (capFilter != null) + { + Marshal.ReleaseComObject(capFilter); + capFilter = null; + } + if (sampGrabber != null) + { + Marshal.ReleaseComObject(sampGrabber); + sampGrabber = null; + } + } + } + + /// Read and store the properties + private void SaveSizeInfo(ISampleGrabber sampGrabber) + { + int hr; + + // Get the media type from the SampleGrabber + AMMediaType media = new AMMediaType(); + hr = sampGrabber.GetConnectedMediaType( media ); + DsError.ThrowExceptionForHR( hr ); + + if( (media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero) ) + { + throw new NotSupportedException( "Unknown Grabber Media Format" ); + } + + // Grab the size info + VideoInfoHeader videoInfoHeader = (VideoInfoHeader) Marshal.PtrToStructure( media.formatPtr, typeof(VideoInfoHeader) ); + m_videoWidth = videoInfoHeader.BmiHeader.Width; + m_videoHeight = videoInfoHeader.BmiHeader.Height; + m_stride = m_videoWidth * (videoInfoHeader.BmiHeader.BitCount / 8); + + DsUtils.FreeAMMediaType(media); + media = null; + } + /// Set the options on the sample grabber + private void ConfigureSampleGrabber(ISampleGrabber sampGrabber) + { + int hr; + AMMediaType media = new AMMediaType(); + + // Set the media type to Video/RBG24 + media.majorType = MediaType.Video; + media.subType = MediaSubType.RGB24; + media.formatType = FormatType.VideoInfo; + hr = sampGrabber.SetMediaType( media ); + DsError.ThrowExceptionForHR( hr ); + + DsUtils.FreeAMMediaType(media); + media = null; + + // Configure the samplegrabber callback + hr = sampGrabber.SetCallback( this, 1 ); + DsError.ThrowExceptionForHR( hr ); + } + + // Set the Framerate, and video size + private void SetConfigParms(ICaptureGraphBuilder2 capGraph, IBaseFilter capFilter, int iFrameRate, int iWidth, int iHeight) + { + int hr; + object o; + AMMediaType media; + IAMStreamConfig videoStreamConfig; + IAMVideoControl videoControl = capFilter as IAMVideoControl; + + // Find the stream config interface + hr = capGraph.FindInterface( + PinCategory.Capture, MediaType.Video, capFilter, typeof(IAMStreamConfig).GUID, out o ); + + videoStreamConfig = o as IAMStreamConfig; + try + { + if (videoStreamConfig == null) + { + throw new Exception("Failed to get IAMStreamConfig"); + } + + hr = videoStreamConfig.GetFormat(out media); + DsError.ThrowExceptionForHR( hr ); + + // copy out the videoinfoheader + VideoInfoHeader v = new VideoInfoHeader(); + Marshal.PtrToStructure( media.formatPtr, v ); + + // if overriding the framerate, set the frame rate + if (iFrameRate > 0) + { + v.AvgTimePerFrame = 10000000 / iFrameRate; + } + + // if overriding the width, set the width + if (iWidth > 0) + { + v.BmiHeader.Width = iWidth; + } + + // if overriding the Height, set the Height + if (iHeight > 0) + { + v.BmiHeader.Height = iHeight; + } + + // Copy the media structure back + Marshal.StructureToPtr( v, media.formatPtr, false ); + + // Set the new format + hr = videoStreamConfig.SetFormat( media ); + DsError.ThrowExceptionForHR( hr ); + + DsUtils.FreeAMMediaType(media); + media = null; + + // Fix upsidedown video + if (videoControl != null) + { + VideoControlFlags pCapsFlags; + + IPin pPin = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0); + hr = videoControl.GetCaps(pPin, out pCapsFlags); + DsError.ThrowExceptionForHR( hr ); + + if ((pCapsFlags & VideoControlFlags.FlipVertical) > 0) + { + hr = videoControl.GetMode(pPin, out pCapsFlags); + DsError.ThrowExceptionForHR( hr ); + + hr = videoControl.SetMode(pPin, 0); + } + } + } + finally + { + Marshal.ReleaseComObject(videoStreamConfig); + } + } + + /// Shut down capture + private void CloseInterfaces() + { + int hr; + + try + { + if( m_mediaCtrl != null ) + { + // Stop the graph + hr = m_mediaCtrl.Stop(); + m_mediaCtrl = null; + m_bRunning = false; + } + } + catch (Exception ex) + { + Debug.WriteLine(ex); + } + +#if DEBUG + if (m_rot != null) + { + m_rot.Dispose(); + } +#endif + + if (m_FilterGraph != null) + { + Marshal.ReleaseComObject(m_FilterGraph); + m_FilterGraph = null; + } + GC.Collect(); + } + + + /// sample callback, NOT USED. + int ISampleGrabberCB.SampleCB( double SampleTime, IMediaSample pSample ) + { + Marshal.ReleaseComObject(pSample); + return 0; + } + + /// buffer callback, COULD BE FROM FOREIGN THREAD. + int ISampleGrabberCB.BufferCB( double SampleTime, IntPtr pBuffer, int BufferLen ) + { + // Avoid the possibility that someone is calling SetLogo() at this instant + lock (this) + { + if (m_bmdLogo != null) + { + IntPtr ipSource = m_bmdLogo.Scan0; + IntPtr ipDest = pBuffer; + + for (int x=0; x < m_bmdLogo.Height; x++) + { + CopyMemory(ipDest, ipSource, (uint)m_bmdLogo.Stride); + ipDest = (IntPtr)(ipDest.ToInt32() + m_stride); + ipSource = (IntPtr)(ipSource.ToInt32() + m_bmdLogo.Stride); + } + } + } + + return 0; + } + } +} diff --git a/Samples/Capture/DxLogo/DxLogo-2005.csproj b/Samples/Capture/DxLogo/DxLogo-2005.csproj new file mode 100644 index 0000000..ed3e4ea --- /dev/null +++ b/Samples/Capture/DxLogo/DxLogo-2005.csproj @@ -0,0 +1,113 @@ + + + Local + 8.0.50727 + 2.0 + {17379614-821C-4504-B45D-BBACC866EBFB} + Debug + AnyCPU + App.ico + + + DxLogo + + + JScript + Grid + IE50 + false + WinExe + DxLogo + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + + Code + + + Code + + + Form + + + Form1.cs + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Capture/DxLogo/DxLogo-2005.sln b/Samples/Capture/DxLogo/DxLogo-2005.sln new file mode 100644 index 0000000..9698c8f --- /dev/null +++ b/Samples/Capture/DxLogo/DxLogo-2005.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DxLogo-2005", "DxLogo-2005.csproj", "{17379614-821C-4504-B45D-BBACC866EBFB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {17379614-821C-4504-B45D-BBACC866EBFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Capture/DxLogo/DxLogo-2008.sln b/Samples/Capture/DxLogo/DxLogo-2008.sln new file mode 100644 index 0000000..4eabf2a --- /dev/null +++ b/Samples/Capture/DxLogo/DxLogo-2008.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DxLogo-2008", "DxLogo-2008.csproj", "{17379614-821C-4504-B45D-BBACC866EBFB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {17379614-821C-4504-B45D-BBACC866EBFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Capture/DxLogo/DxLogo.csproj b/Samples/Capture/DxLogo/DxLogo.csproj new file mode 100644 index 0000000..155272c --- /dev/null +++ b/Samples/Capture/DxLogo/DxLogo.csproj @@ -0,0 +1,145 @@ + + + + Local + 8.0.50727 + 2.0 + {17379614-821C-4504-B45D-BBACC866EBFB} + Debug + AnyCPU + App.ico + + + DxLogo + + + JScript + Grid + IE50 + false + WinExe + DxLogo + OnBuildSuccess + + + + + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + + Code + + + Code + + + Form + + + Form1.cs + + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Capture/DxLogo/Form1.cs b/Samples/Capture/DxLogo/Form1.cs new file mode 100644 index 0000000..f374eea --- /dev/null +++ b/Samples/Capture/DxLogo/Form1.cs @@ -0,0 +1,178 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Windows.Forms; + +namespace DxLogo +{ + /// + /// Summary description for Form1. + /// + public class Form1 : System.Windows.Forms.Form + { + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.TextBox textBox2; + private System.Windows.Forms.Button StartStop; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textBox3; + private System.Windows.Forms.Label label2; + /// + /// Required designer variable. + /// + private System.ComponentModel.Container components = null; + + public Form1() + { + // + // Required for Windows Form Designer support + // + InitializeComponent(); + + // + // TODO: Add any constructor code after InitializeComponent call + // + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if (components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.StartStop = new System.Windows.Forms.Button(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.textBox2 = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.textBox3 = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // StartStop + // + this.StartStop.Location = new System.Drawing.Point(88, 144); + this.StartStop.Name = "StartStop"; + this.StartStop.Size = new System.Drawing.Size(75, 40); + this.StartStop.TabIndex = 2; + this.StartStop.Text = "Start"; + this.StartStop.Click += new System.EventHandler(this.StartStop_Click); + // + // textBox1 + // + this.textBox1.Location = new System.Drawing.Point(16, 224); + this.textBox1.Name = "textBox1"; + this.textBox1.ReadOnly = true; + this.textBox1.TabIndex = 3; + this.textBox1.TabStop = false; + this.textBox1.Text = "Not Running"; + // + // textBox2 + // + this.textBox2.Location = new System.Drawing.Point(24, 32); + this.textBox2.Name = "textBox2"; + this.textBox2.Size = new System.Drawing.Size(240, 20); + this.textBox2.TabIndex = 1; + this.textBox2.Tag = ""; + this.textBox2.Text = "c:\\lgs.jpg"; + // + // label1 + // + this.label1.Location = new System.Drawing.Point(8, 8); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(56, 16); + this.label1.TabIndex = 4; + this.label1.Text = "Logo file"; + // + // textBox3 + // + this.textBox3.Location = new System.Drawing.Point(24, 88); + this.textBox3.Name = "textBox3"; + this.textBox3.Size = new System.Drawing.Size(232, 20); + this.textBox3.TabIndex = 5; + this.textBox3.Text = "c:\\Logo.avi"; + // + // label2 + // + this.label2.Location = new System.Drawing.Point(8, 64); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(56, 16); + this.label2.TabIndex = 6; + this.label2.Text = "Output file"; + // + // Form1 + // + this.AcceptButton = this.StartStop; + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(292, 262); + this.Controls.Add(this.label2); + this.Controls.Add(this.textBox3); + this.Controls.Add(this.textBox2); + this.Controls.Add(this.textBox1); + this.Controls.Add(this.label1); + this.Controls.Add(this.StartStop); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.Name = "Form1"; + this.Text = "DxLogo"; + this.ResumeLayout(false); + + } + #endregion + + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.Run(new Form1()); + } + + const int VIDEODEVICE = 0; // zero based index of video capture device to use + const int FRAMERATE = 15; // Depends on video device caps. Generally 4-30. + const int VIDEOWIDTH = 640; // Depends on video device caps + const int VIDEOHEIGHT = 480; // Depends on video device caps + Capture cam = null; + + private void StartStop_Click(object sender, System.EventArgs e) + { + Cursor.Current = Cursors.WaitCursor; + if (cam == null) + { + cam = new Capture(VIDEODEVICE, FRAMERATE, VIDEOWIDTH, VIDEOHEIGHT, textBox3.Text); + cam.SetLogo(textBox2.Text); + + cam.Start(); + textBox1.Text = "Running"; + StartStop.Text = "Stop"; + } + else + { + cam.Dispose(); + cam = null; + textBox1.Text = "Not Running"; + StartStop.Text = "Start"; + } + Cursor.Current = Cursors.Default; + } + } +} diff --git a/Samples/Capture/DxLogo/Form1.resx b/Samples/Capture/DxLogo/Form1.resx new file mode 100644 index 0000000..10c2588 --- /dev/null +++ b/Samples/Capture/DxLogo/Form1.resx @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + Private + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + False + + + Private + + + Private + + + Private + + + False + + + Private + + + False + + + Private + + + Private + + + False + + + (Default) + + + False + + + False + + + 8, 8 + + + True + + + 80 + + + Form1 + + + True + + + Private + + \ No newline at end of file diff --git a/Samples/Capture/DxLogo/lgs.jpg b/Samples/Capture/DxLogo/lgs.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0905e9cf30c3af9c20438da1a994f61e5ead05af GIT binary patch literal 1667 zcmbW!dpOez7zgm*ZniOxhAo#NMj1*Q3XkbQb7`p%BTI2gbzJAtBI-mW*OW^tcVg|h zW(!AYMMk2m(CR2A<&uy~r0vYPbe`w@bT=KJW8wv`c?+!DW$$DUfIuMN zu(SZlFo30;I^hohPEG~@0{APESAZRWkdcAQzz}da9En88qLk%Pa&jnDMI{Ag4K*!I z4K*BYgYK418+45DIGp}=g3(r@si~>fCJVAT$!d#{taJ`Q(J)1AqK%A_i!WS&tLQp489Z&kBCO!jlKUc zJ~2D@d46GW>C5uUnhOL#{$PEV{lkTpy1-B<1PWhsfxt{@L(ou|Hc>{=#s%)nP|_it zLnzy37T58RcoWwdj9=I@S*)(~9AE+K$|fTYiZpn)C0(ux7M zI2L=|ck^prD&r?dm(I@n-<-opUsi0-Qz}YY{pNDCa$t-R#+MkAcWlEQdAyYFnMV84 z10EsXUakC(AF9E|xQQSG0*4z@tM1~xdCJ0SfWc(SXP4z}m#^1V)s+CoRVsn8DBG-} z`Shiyp1XS$Qc}yE$2C3`lQH-Air9e}vlN`QiZ zoTk|+B+)xyeGYLoWMj8j#fs*SSG7}E_3~bsBcnWg6Cb?v$ZuW0gs&;7Z8)TSU{Y}z zhFWi~i{EA!t8j+QKFKNd$v+h?VA?mvI2-LGmlF=E7HFqZhrhntfZOR^7<{%oRE$m> z64BB0hqy|=K%-=pW9c2UHFmA%=_i)9-WYMr+e7AI#)dFK_w;UCPwg->8}VmQ)oqK;BOwqi4Y#jSXJsfTzi}2*S~nlwu66s?oz#FzZG$ zj;OPos_seCA?WJy$@kx$DHCJji^ij!7h38kER*gW4Pt9ut#s`0iIxBh?7nV;a1lA* z+#zrCn>Pb{c?I_ZXhMI@u2g(aZo4scK`;}@F6uB6Yd3r)Ww#agSO|amyu$Ed)B6)n z55GFmo^#`U&y@_~v)kGoEX`ldF?|DPTrQ-kZ4tNzO$KF795MHNTJ+Iu;}DlgpM#ttK{HSvwazt-PjtZtK?(Vd3A&Ic4j2wJyjJ|nUWyCU{x5LZ^$Z1exs0B Wej!6o??}XOXhi6x(NcB1 + + + + + + + +'The following GUID is for the ID of the typelib if this project is exposed to COM + + +' Version information for an assembly consists of the following four values: +' +' Major Version +' Minor Version +' Build Number +' Revision +' +' You can specify all the values or you can default the Build and Revision Numbers +' by using the '*' as shown below: + + diff --git a/Samples/Capture/DxLogoVB/Capture.vb b/Samples/Capture/DxLogoVB/Capture.vb new file mode 100644 index 0000000..bac8185 --- /dev/null +++ b/Samples/Capture/DxLogoVB/Capture.vb @@ -0,0 +1,367 @@ +'**************************************************************************** +'While the underlying libraries are covered by LGPL, this sample is released +'as public domain. It is distributed in the hope that it will be useful, but +'WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +'or FITNESS FOR A PARTICULAR PURPOSE. +'*****************************************************************************/ + +Imports System +Imports System.Drawing +Imports System.Drawing.Imaging +Imports System.Runtime.InteropServices +Imports System.Diagnostics + +Imports DirectShowLib + +Public Class Capture + Implements ISampleGrabberCB + Implements IDisposable + +#Region "Member variables" + + ' graph builder interface. + Private m_graphBuilder As IFilterGraph2 = Nothing + Private m_mediaCtrl As IMediaControl = Nothing + + ' Set by async routine when it captures an image + Private m_bRunning As Boolean = False + + ' Dimensions of the image, calculated once in constructor. + Private m_videoWidth As Integer + Private m_videoHeight As Integer + Private m_stride As Integer + + Private m_bmdLogo As BitmapData = Nothing + Private m_Bitmap As Bitmap = Nothing + +#If Debug Then + ' Allow you to "Connect to remote graph" from GraphEdit + Private m_rot As DsROTEntry = Nothing +#End If + +#End Region + +#Region "API" + + Declare Sub CopyMemory Lib "Kernel32.dll" Alias "RtlMoveMemory" (ByVal Destination As IntPtr, ByVal Source As IntPtr, ByVal Length As Integer) + +#End Region + + ' zero based device index, and some device parms, plus the file name to save to + Public Sub New(ByVal iDeviceNum As Integer, ByVal iFrameRate As Integer, ByVal iWidth As Integer, ByVal iHeight As Integer, ByVal FileName As String) + Dim capDevices As DsDevice() + + ' Get the collection of video devices + capDevices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice) + + If (iDeviceNum + 1 > capDevices.Length) Then + Throw New Exception("No video capture devices found at that index!") + End If + + Dim dev As DsDevice = capDevices(iDeviceNum) + + Try + ' Set up the capture graph + SetupGraph(dev, iFrameRate, iWidth, iHeight, FileName) + Catch + Dispose() + Throw + End Try + End Sub + ' release everything. + Public Sub Dispose() Implements IDisposable.Dispose + CloseInterfaces() + If (Not m_Bitmap Is Nothing) Then + m_Bitmap.UnlockBits(m_bmdLogo) + m_Bitmap = Nothing + m_bmdLogo = Nothing + End If + End Sub + Protected Overloads Overrides Sub finalize() + CloseInterfaces() + End Sub + + ' capture the next image + Public Sub Start() + If (m_bRunning = False) Then + Dim hr As Integer = m_mediaCtrl.Run() + DsError.ThrowExceptionForHR(hr) + + m_bRunning = True + End If + End Sub + ' Pause the capture graph. + ' Running the graph takes up a lot of resources. Pause it when it + ' isn't needed. + Public Sub Pause() + If (m_bRunning) Then + Dim hr As Integer = m_mediaCtrl.Pause() + DsError.ThrowExceptionForHR(hr) + + m_bRunning = False + End If + End Sub + + ' Specify the logo file to write onto each frame + Public Sub SetLogo(ByVal fileName As String) + SyncLock Me + If (fileName.Length > 0) Then + m_Bitmap = New Bitmap(fileName) + + Dim r As Rectangle = New Rectangle(0, 0, m_Bitmap.Width, m_Bitmap.Height) + m_bmdLogo = m_Bitmap.LockBits(r, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb) + Else + If Not m_Bitmap Is Nothing Then + m_Bitmap.UnlockBits(m_bmdLogo) + m_Bitmap = Nothing + m_bmdLogo = Nothing + End If + End If + End SyncLock + End Sub + + ' build the capture graph for grabber. + Private Sub SetupGraph(ByVal dev As DsDevice, ByVal iFrameRate As Integer, ByVal iWidth As Integer, ByVal iHeight As Integer, ByVal FileName As String) + + Dim hr As Integer + + Dim sampGrabber As ISampleGrabber = Nothing + Dim baseGrabFlt As IBaseFilter = Nothing + Dim capFilter As IBaseFilter = Nothing + Dim muxFilter As IBaseFilter = Nothing + Dim fileWriterFilter As IFileSinkFilter = Nothing + Dim capGraph As ICaptureGraphBuilder2 = Nothing + + ' Get the graphbuilder object + m_graphBuilder = DirectCast(New FilterGraph(), IFilterGraph2) + m_mediaCtrl = DirectCast(m_graphBuilder, IMediaControl) + +#If Debug Then + m_rot = New DsROTEntry(m_graphBuilder) +#End If + + Try + ' Get the ICaptureGraphBuilder2 + capGraph = DirectCast(New CaptureGraphBuilder2(), ICaptureGraphBuilder2) + + ' Get the SampleGrabber interface + sampGrabber = DirectCast(New SampleGrabber(), ISampleGrabber) + + ' Start building the graph + hr = capGraph.SetFiltergraph(DirectCast(m_graphBuilder, IGraphBuilder)) + DsError.ThrowExceptionForHR(hr) + + ' Add the video device + hr = m_graphBuilder.AddSourceFilterForMoniker(dev.Mon, Nothing, dev.Name, capFilter) + DsError.ThrowExceptionForHR(hr) + + baseGrabFlt = DirectCast(sampGrabber, IBaseFilter) + ConfigureSampleGrabber(sampGrabber) + + ' Add the frame grabber to the graph + hr = m_graphBuilder.AddFilter(baseGrabFlt, "Ds.NET Grabber") + DsError.ThrowExceptionForHR(hr) + + ' If any of the default config items are set + If (iFrameRate + iHeight + iWidth > 0) Then + + SetConfigParms(capGraph, capFilter, iFrameRate, iWidth, iHeight) + End If + + hr = capGraph.SetOutputFileName(MediaSubType.Avi, FileName, muxFilter, fileWriterFilter) + DsError.ThrowExceptionForHR(hr) + + hr = capGraph.RenderStream(PinCategory.Capture, MediaType.Video, capFilter, baseGrabFlt, muxFilter) + DsError.ThrowExceptionForHR(hr) + + SaveSizeInfo(sampGrabber) + + Finally + + If (Not fileWriterFilter Is Nothing) Then + Marshal.ReleaseComObject(fileWriterFilter) + fileWriterFilter = Nothing + End If + If (Not muxFilter Is Nothing) Then + Marshal.ReleaseComObject(muxFilter) + muxFilter = Nothing + End If + If (Not capFilter Is Nothing) Then + Marshal.ReleaseComObject(capFilter) + capFilter = Nothing + End If + If (Not sampGrabber Is Nothing) Then + Marshal.ReleaseComObject(sampGrabber) + sampGrabber = Nothing + End If + End Try + End Sub + + ' Read and store the properties + Private Sub SaveSizeInfo(ByVal sampGrabber As ISampleGrabber) + + Dim hr As Integer + + ' Get the media type from the SampleGrabber + Dim media As AMMediaType = New AMMediaType() + hr = sampGrabber.GetConnectedMediaType(media) + DsError.ThrowExceptionForHR(hr) + + If (Not (media.formatType.Equals(FormatType.VideoInfo)) AndAlso Not (media.formatPtr.Equals(IntPtr.Zero))) Then + Throw New NotSupportedException("Unknown Grabber Media Format") + End If + + ' Grab the size info + Dim vInfoHeader As VideoInfoHeader = New VideoInfoHeader() + Marshal.PtrToStructure(media.formatPtr, vInfoHeader) + m_videoWidth = vInfoHeader.BmiHeader.Width + m_videoHeight = vInfoHeader.BmiHeader.Height + m_stride = m_videoWidth * (vInfoHeader.BmiHeader.BitCount / 8) + + DsUtils.FreeAMMediaType(media) + media = Nothing + End Sub + ' Set the options on the sample grabber + Private Sub ConfigureSampleGrabber(ByVal sampGrabber As ISampleGrabber) + Dim hr As Integer + Dim media As AMMediaType = New AMMediaType() + + media.majorType = MediaType.Video + media.subType = MediaSubType.RGB24 + media.formatType = FormatType.VideoInfo + hr = sampGrabber.SetMediaType(media) + DsError.ThrowExceptionForHR(hr) + + DsUtils.FreeAMMediaType(media) + media = Nothing + + ' Configure the samplegrabber callback + hr = sampGrabber.SetCallback(Me, 1) + DsError.ThrowExceptionForHR(hr) + End Sub + + ' Set the Framerate, and video size + Private Sub SetConfigParms(ByVal capGraph As ICaptureGraphBuilder2, ByVal capFilter As IBaseFilter, ByVal iFrameRate As Integer, ByVal iWidth As Integer, ByVal iHeight As Integer) + Dim hr As Integer + + Dim o As Object = Nothing + Dim media As AMMediaType = Nothing + Dim videoStreamConfig As IAMStreamConfig + Dim videoControl As IAMVideoControl = DirectCast(capFilter, IAMVideoControl) + + ' Find the stream config interface + hr = capGraph.FindInterface(PinCategory.Capture, MediaType.Video, capFilter, GetType(IAMStreamConfig).GUID, o) + + videoStreamConfig = DirectCast(o, IAMStreamConfig) + Try + If (videoStreamConfig Is Nothing) Then + Throw New Exception("Failed to get IAMStreamConfig") + End If + + ' Get the existing format block + hr = videoStreamConfig.GetFormat(media) + DsError.ThrowExceptionForHR(hr) + + ' copy out the videoinfoheader + Dim v As VideoInfoHeader = New VideoInfoHeader() + Marshal.PtrToStructure(media.formatPtr, v) + + ' if overriding the framerate, set the frame rate + If (iFrameRate > 0) Then + v.AvgTimePerFrame = 10000000 / iFrameRate + End If + + ' if overriding the width, set the width + If (iWidth > 0) Then + v.BmiHeader.Width = iWidth + End If + + ' if overriding the Height, set the Height + If (iHeight > 0) Then + v.BmiHeader.Height = iHeight + End If + + ' Copy the media structure back + Marshal.StructureToPtr(v, media.formatPtr, False) + + ' Set the new format + hr = videoStreamConfig.SetFormat(media) + DsError.ThrowExceptionForHR(hr) + + DsUtils.FreeAMMediaType(media) + media = Nothing + + ' Fix upsidedown video + If (Not videoControl Is Nothing) Then + Dim pCapsFlags As VideoControlFlags + + Dim pPin As IPin = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0) + hr = videoControl.GetCaps(pPin, pCapsFlags) + DsError.ThrowExceptionForHR(hr) + + If ((pCapsFlags & VideoControlFlags.FlipVertical) > 0) Then + hr = videoControl.GetMode(pPin, pCapsFlags) + DsError.ThrowExceptionForHR(hr) + + hr = videoControl.SetMode(pPin, 0) + End If + End If + Finally + Marshal.ReleaseComObject(videoStreamConfig) + End Try + End Sub + + ' Shut down capture + Private Sub CloseInterfaces() + Dim hr As Integer + + Try + If (Not m_mediaCtrl Is Nothing) Then + + ' Stop the graph + hr = m_mediaCtrl.Stop() + m_mediaCtrl = Nothing + m_bRunning = False + End If + Catch ex As Exception + Debug.WriteLine(ex) + End Try + +#If Debug Then + If (Not m_rot Is Nothing) Then + m_rot.Dispose() + m_rot = Nothing + End If +#End If + + If (Not m_graphBuilder Is Nothing) Then + Marshal.ReleaseComObject(m_graphBuilder) + m_graphBuilder = Nothing + End If + GC.Collect() + End Sub + + ' sample callback, NOT USED. + Function SampleCB(ByVal SampleTime As Double, ByVal pSample As IMediaSample) As Integer Implements ISampleGrabberCB.SampleCB + Marshal.ReleaseComObject(pSample) + Return 0 + End Function + + ' buffer callback, COULD BE FROM FOREIGN THREAD. + Function BufferCB(ByVal SampleTime As Double, ByVal pBuffer As IntPtr, ByVal BufferLen As Integer) As Integer Implements ISampleGrabberCB.BufferCB + SyncLock Me + If (Not m_bmdLogo Is Nothing) Then + Dim ipSource As IntPtr = m_bmdLogo.Scan0 + Dim ipDest As IntPtr = pBuffer + Dim x As Integer + For x = 0 To m_bmdLogo.Height - 1 + CopyMemory(ipDest, ipSource, m_bmdLogo.Stride) + ipDest = New IntPtr(ipDest.ToInt32() + m_stride) + ipSource = New IntPtr(ipSource.ToInt32() + m_bmdLogo.Stride) + Next x + End If + End SyncLock + + Return 0 + End Function +End Class diff --git a/Samples/Capture/DxLogoVB/DxLogoVB-2005.sln b/Samples/Capture/DxLogoVB/DxLogoVB-2005.sln new file mode 100644 index 0000000..c9aa4c0 --- /dev/null +++ b/Samples/Capture/DxLogoVB/DxLogoVB-2005.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Basic Express 2005 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "DxLogoVB-2005", "DxLogoVB-2005.vbproj", "{8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Capture/DxLogoVB/DxLogoVB-2005.vbproj b/Samples/Capture/DxLogoVB/DxLogoVB-2005.vbproj new file mode 100644 index 0000000..d1b7560 --- /dev/null +++ b/Samples/Capture/DxLogoVB/DxLogoVB-2005.vbproj @@ -0,0 +1,116 @@ + + + Local + 8.0.50727 + 2.0 + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E} + Debug + AnyCPU + + + + + DxLogoVB + + + None + JScript + Grid + IE50 + false + WinExe + Binary + On + Off + DxLogoVB + DxLogoVB.Form1 + + + WindowsFormsWithCustomSubMain + + + + + bin\ + DxLogoVB.xml + 285212672 + + + + + true + true + true + false + false + false + false + 1 + 42016,42017,42018,42019,42032 + full + + + bin\ + DxLogoVB.xml + 285212672 + + + + + false + true + false + true + false + false + false + 1 + 42016,42017,42018,42019,42032 + none + + + + False + ..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + + + + + + + + + Code + + + Code + + + Form + + + Form1.vb + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Capture/DxLogoVB/DxLogoVB-2008.sln b/Samples/Capture/DxLogoVB/DxLogoVB-2008.sln new file mode 100644 index 0000000..e14a14c --- /dev/null +++ b/Samples/Capture/DxLogoVB/DxLogoVB-2008.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "DxLogoVB-2008", "DxLogoVB-2008.vbproj", "{8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Capture/DxLogoVB/DxLogoVB.vbproj b/Samples/Capture/DxLogoVB/DxLogoVB.vbproj new file mode 100644 index 0000000..5d0f63a --- /dev/null +++ b/Samples/Capture/DxLogoVB/DxLogoVB.vbproj @@ -0,0 +1,151 @@ + + + + Local + 8.0.50727 + 2.0 + {8D9497ED-F71D-4938-A6AD-0BB6AAF1639E} + Debug + AnyCPU + + + + + DxLogoVB + + + None + JScript + Grid + IE50 + false + WinExe + Binary + On + Off + DxLogoVB + DxLogoVB.Form1 + + + WindowsFormsWithCustomSubMain + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\ + DxLogoVB.xml + 285212672 + + + + + true + true + true + false + false + false + false + 1 + 42016,42017,42018,42019,42032,42353,42354,42355 + full + + + bin\ + DxLogoVB.xml + 285212672 + + + + + false + true + false + true + false + false + false + 1 + 42016,42017,42018,42019,42032,42353,42354,42355 + none + + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + + + + + + + + + Code + + + Code + + + Form + + + Form1.vb + + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Capture/DxLogoVB/Form1.resx b/Samples/Capture/DxLogoVB/Form1.resx new file mode 100644 index 0000000..0f051fe --- /dev/null +++ b/Samples/Capture/DxLogoVB/Form1.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Assembly + + + Assembly + + + Assembly + + + Assembly + + + Assembly + + + Assembly + + + Form1 + + \ No newline at end of file diff --git a/Samples/Capture/DxLogoVB/Form1.vb b/Samples/Capture/DxLogoVB/Form1.vb new file mode 100644 index 0000000..efd3bfd --- /dev/null +++ b/Samples/Capture/DxLogoVB/Form1.vb @@ -0,0 +1,141 @@ +'**************************************************************************** +'While the underlying libraries are covered by LGPL, this sample is released +'as public domain. It is distributed in the hope that it will be useful, but +'WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +'or FITNESS FOR A PARTICULAR PURPOSE. +'*****************************************************************************/ + +Public Class Form1 + Inherits System.Windows.Forms.Form + +#Region " Windows Form Designer generated code " + + Public Sub New() + MyBase.New() + + 'This call is required by the Windows Form Designer. + InitializeComponent() + + 'Add any initialization after the InitializeComponent() call + + End Sub + + 'Form overrides dispose to clean up the component list. + Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) + If disposing Then + If Not (components Is Nothing) Then + components.Dispose() + End If + End If + MyBase.Dispose(disposing) + End Sub + + 'Required by the Windows Form Designer + Private components As System.ComponentModel.IContainer + + 'NOTE: The following procedure is required by the Windows Form Designer + 'It can be modified using the Windows Form Designer. + 'Do not modify it using the code editor. + Friend WithEvents TextBox1 As System.Windows.Forms.TextBox + Friend WithEvents TextBox2 As System.Windows.Forms.TextBox + Friend WithEvents TextBox3 As System.Windows.Forms.TextBox + Friend WithEvents label1 As System.Windows.Forms.Label + Friend WithEvents StartStop As System.Windows.Forms.Button + Friend WithEvents Label2 As System.Windows.Forms.Label + Private Sub InitializeComponent() + Me.TextBox1 = New System.Windows.Forms.TextBox + Me.TextBox2 = New System.Windows.Forms.TextBox + Me.StartStop = New System.Windows.Forms.Button + Me.TextBox3 = New System.Windows.Forms.TextBox + Me.label1 = New System.Windows.Forms.Label + Me.Label2 = New System.Windows.Forms.Label + Me.SuspendLayout() + ' + 'TextBox1 + ' + Me.TextBox1.Location = New System.Drawing.Point(16, 224) + Me.TextBox1.Name = "TextBox1" + Me.TextBox1.ReadOnly = True + Me.TextBox1.TabIndex = 0 + Me.TextBox1.TabStop = False + Me.TextBox1.Text = "Not Running" + ' + 'TextBox2 + ' + Me.TextBox2.Location = New System.Drawing.Point(24, 32) + Me.TextBox2.Name = "TextBox2" + Me.TextBox2.Size = New System.Drawing.Size(240, 20) + Me.TextBox2.TabIndex = 11 + Me.TextBox2.Text = "c:\lgs.jpg" + ' + 'StartStop + ' + Me.StartStop.Location = New System.Drawing.Point(88, 144) + Me.StartStop.Name = "StartStop" + Me.StartStop.Size = New System.Drawing.Size(75, 40) + Me.StartStop.TabIndex = 1 + Me.StartStop.Text = "Start" + ' + 'TextBox3 + ' + Me.TextBox3.Location = New System.Drawing.Point(24, 88) + Me.TextBox3.Name = "TextBox3" + Me.TextBox3.Size = New System.Drawing.Size(232, 20) + Me.TextBox3.TabIndex = 31 + Me.TextBox3.Text = "c:\logo.avi" + ' + 'label1 + ' + Me.label1.Location = New System.Drawing.Point(8, 8) + Me.label1.Name = "label1" + Me.label1.Size = New System.Drawing.Size(56, 16) + Me.label1.TabIndex = 5 + Me.label1.Text = "Logo file" + ' + 'Label2 + ' + Me.Label2.Location = New System.Drawing.Point(8, 64) + Me.Label2.Name = "Label2" + Me.Label2.Size = New System.Drawing.Size(56, 16) + Me.Label2.TabIndex = 32 + Me.Label2.Text = "Output file" + ' + 'Form1 + ' + Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13) + Me.ClientSize = New System.Drawing.Size(292, 262) + Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.Label2, Me.label1, Me.TextBox3, Me.StartStop, Me.TextBox2, Me.TextBox1}) + Me.Name = "Form1" + Me.Text = "DxLogoVB" + Me.ResumeLayout(False) + + End Sub + +#End Region + + Const VIDEODEVICE As Integer = 0 ' zero based index of video capture device to use + Const FRAMERATE As Integer = 15 ' Depends on video device caps. Generally 4-30. + Const VIDEOWIDTH As Integer = 640 ' Depends on video device caps + Const VIDEOHEIGHT As Integer = 480 ' Depends on video device caps + + Dim cam As Capture = Nothing + + Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StartStop.Click + Cursor = Cursors.WaitCursor + If (cam Is Nothing) Then + cam = New Capture(VIDEODEVICE, FRAMERATE, VIDEOWIDTH, VIDEOHEIGHT, TextBox3.Text) + cam.SetLogo(TextBox2.Text) + + cam.Start() + TextBox1.Text = "Running" + StartStop.Text = "Stop" + Else + cam.Dispose() + cam = Nothing + TextBox1.Text = "Not Running" + StartStop.Text = "Start" + End If + Cursor = Cursors.Default + + End Sub +End Class diff --git a/Samples/Capture/DxLogoVB/readme.txt b/Samples/Capture/DxLogoVB/readme.txt new file mode 100644 index 0000000..a43b612 --- /dev/null +++ b/Samples/Capture/DxLogoVB/readme.txt @@ -0,0 +1,13 @@ +/************************************************************************ +DxLogoVB - VB version of DxLogo sample + +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + +**************************************************************************/ + +This is precisely the same sample as DxLogo, except that it's written +in VB. Other than the tediousness of converting C# to VB, this was a +trivial exercise. No changes were required in the library code. \ No newline at end of file diff --git a/Samples/Capture/DxPropPages/AssemblyInfo.cs b/Samples/Capture/DxPropPages/AssemblyInfo.cs new file mode 100644 index 0000000..9f89a32 --- /dev/null +++ b/Samples/Capture/DxPropPages/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/Capture/DxPropPages/DxPropPages-2005.csproj b/Samples/Capture/DxPropPages/DxPropPages-2005.csproj new file mode 100644 index 0000000..14f3141 --- /dev/null +++ b/Samples/Capture/DxPropPages/DxPropPages-2005.csproj @@ -0,0 +1,116 @@ + + + Local + 8.0.50727 + 2.0 + {4AC57653-233F-4862-AF88-139A1D02A007} + Debug + AnyCPU + + + + + DxPropPages + + + JScript + Grid + IE50 + false + WinExe + DxPropPages + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Data + + + System.Drawing + + + System.Windows.Forms + + + System.XML + + + + + Code + + + Form + + + Form1.cs + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Capture/DxPropPages/DxPropPages-2005.sln b/Samples/Capture/DxPropPages/DxPropPages-2005.sln new file mode 100644 index 0000000..0b3c8b4 --- /dev/null +++ b/Samples/Capture/DxPropPages/DxPropPages-2005.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DxPropPages-2005", "DxPropPages-2005.csproj", "{4AC57653-233F-4862-AF88-139A1D02A007}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4AC57653-233F-4862-AF88-139A1D02A007}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Capture/DxPropPages/DxPropPages-2008.sln b/Samples/Capture/DxPropPages/DxPropPages-2008.sln new file mode 100644 index 0000000..ea81843 --- /dev/null +++ b/Samples/Capture/DxPropPages/DxPropPages-2008.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DxPropPages-2008", "DxPropPages-2008.csproj", "{4AC57653-233F-4862-AF88-139A1D02A007}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4AC57653-233F-4862-AF88-139A1D02A007}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Capture/DxPropPages/DxPropPages.csproj b/Samples/Capture/DxPropPages/DxPropPages.csproj new file mode 100644 index 0000000..4ccb3e5 --- /dev/null +++ b/Samples/Capture/DxPropPages/DxPropPages.csproj @@ -0,0 +1,148 @@ + + + + Local + 8.0.50727 + 2.0 + {4AC57653-233F-4862-AF88-139A1D02A007} + Debug + AnyCPU + + + + + DxPropPages + + + JScript + Grid + IE50 + false + WinExe + DxPropPages + OnBuildSuccess + + + + + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Data + + + System.Drawing + + + System.Windows.Forms + + + System.XML + + + + + Code + + + Form + + + Form1.cs + + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Capture/DxPropPages/Form1.cs b/Samples/Capture/DxPropPages/Form1.cs new file mode 100644 index 0000000..ac99e4c --- /dev/null +++ b/Samples/Capture/DxPropPages/Form1.cs @@ -0,0 +1,476 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + +Written by oohansen@gmail.com +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Windows.Forms; +using System.Data; +using System.Runtime.InteropServices; + +using DirectShowLib; + +namespace DirectShowLib.Samples +{ + /// + /// Summary description for Form1. + /// + public class Form1 : System.Windows.Forms.Form + { + private System.Windows.Forms.ComboBox comboBox1; + private System.Windows.Forms.ComboBox comboBox2; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Button button2; + private System.Windows.Forms.Button button3; + private System.Windows.Forms.Button button4; + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.Panel panel1; + /// + /// Required designer variable. + /// + private System.ComponentModel.Container components = null; + + //A (modified) definition of OleCreatePropertyFrame found here: http://groups.google.no/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/db794e9779144a46/55dbed2bab4cd772?lnk=st&q=[DllImport(%22olepro32.dll%22)]&rnum=1&hl=no#55dbed2bab4cd772 + [DllImport("oleaut32.dll", CharSet=CharSet.Unicode, ExactSpelling=true)] + public static extern int OleCreatePropertyFrame( + IntPtr hwndOwner, + int x, + int y, + [MarshalAs(UnmanagedType.LPWStr)] string lpszCaption, + int cObjects, + [MarshalAs(UnmanagedType.Interface, ArraySubType=UnmanagedType.IUnknown)] + ref object ppUnk, + int cPages, + IntPtr lpPageClsID, + int lcid, + int dwReserved, + IntPtr lpvReserved); + + IMediaControl mediaControl = null; + IGraphBuilder graphBuilder = null; + IBaseFilter theDevice = null; + IBaseFilter theCompressor = null; + +#if DEBUG + // Allow you to "Connect to remote graph" from GraphEdit + DsROTEntry m_rot = null; +#endif + + public Form1() + { + // + // Required for Windows Form Designer support + // + InitializeComponent(); + + // + // TODO: Add any constructor code after InitializeComponent call + // + + //enumerate Video Input filters and add them to comboBox1 + foreach (DsDevice ds in DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice)) + { + comboBox1.Items.Add(ds.Name); + } + + //enumerate Video Compressor filters and add them to comboBox1 + foreach (DsDevice ds in DsDevice.GetDevicesOfCat(FilterCategory.VideoCompressorCategory)) + { + comboBox2.Items.Add(ds.Name); + } + + //Select first combobox item + if (comboBox1.Items.Count > 0) + { + comboBox1.SelectedIndex = 0; + } + + //Select first combobox item + if (comboBox2.Items.Count > 0) + { + comboBox2.SelectedIndex = 0; + } + + //Initialize button states + button4.Enabled = true; + button3.Enabled = false; + + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if (components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form1)); + this.comboBox1 = new System.Windows.Forms.ComboBox(); + this.comboBox2 = new System.Windows.Forms.ComboBox(); + this.button1 = new System.Windows.Forms.Button(); + this.button2 = new System.Windows.Forms.Button(); + this.button3 = new System.Windows.Forms.Button(); + this.button4 = new System.Windows.Forms.Button(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.panel1 = new System.Windows.Forms.Panel(); + this.SuspendLayout(); + // + // comboBox1 + // + this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboBox1.Location = new System.Drawing.Point(8, 8); + this.comboBox1.Name = "comboBox1"; + this.comboBox1.Size = new System.Drawing.Size(256, 21); + this.comboBox1.TabIndex = 0; + this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged); + // + // comboBox2 + // + this.comboBox2.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboBox2.Location = new System.Drawing.Point(8, 40); + this.comboBox2.Name = "comboBox2"; + this.comboBox2.Size = new System.Drawing.Size(256, 21); + this.comboBox2.TabIndex = 1; + this.comboBox2.SelectedIndexChanged += new System.EventHandler(this.comboBox2_SelectedIndexChanged); + // + // button1 + // + this.button1.Location = new System.Drawing.Point(272, 8); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(120, 24); + this.button1.TabIndex = 2; + this.button1.Text = "Show property pages"; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // button2 + // + this.button2.Location = new System.Drawing.Point(272, 40); + this.button2.Name = "button2"; + this.button2.Size = new System.Drawing.Size(120, 24); + this.button2.TabIndex = 3; + this.button2.Text = "Show property pages"; + this.button2.Click += new System.EventHandler(this.button2_Click); + // + // button3 + // + this.button3.Location = new System.Drawing.Point(216, 400); + this.button3.Name = "button3"; + this.button3.Size = new System.Drawing.Size(176, 23); + this.button3.TabIndex = 4; + this.button3.Text = "Stop"; + this.button3.Click += new System.EventHandler(this.button3_Click); + // + // button4 + // + this.button4.Location = new System.Drawing.Point(8, 400); + this.button4.Name = "button4"; + this.button4.Size = new System.Drawing.Size(192, 23); + this.button4.TabIndex = 5; + this.button4.Text = "Record"; + this.button4.Click += new System.EventHandler(this.button4_Click); + // + // textBox1 + // + this.textBox1.Location = new System.Drawing.Point(8, 368); + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size(384, 20); + this.textBox1.TabIndex = 6; + this.textBox1.Text = "c:\\test.avi"; + // + // panel1 + // + this.panel1.BackColor = System.Drawing.Color.Black; + this.panel1.Location = new System.Drawing.Point(8, 72); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(384, 288); + this.panel1.TabIndex = 7; + // + // Form1 + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(402, 432); + this.Controls.Add(this.panel1); + this.Controls.Add(this.textBox1); + this.Controls.Add(this.button4); + this.Controls.Add(this.button3); + this.Controls.Add(this.button2); + this.Controls.Add(this.button1); + this.Controls.Add(this.comboBox2); + this.Controls.Add(this.comboBox1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "Form1"; + this.Text = "DxPropPages"; + this.ResumeLayout(false); + + } + #endregion + + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.Run(new Form1()); + } + + /// + /// Stop recording and release the graph + /// + public void StopRecord() + { + //Stop the Graph + mediaControl.Stop(); + + //Release COM objects + Marshal.ReleaseComObject(mediaControl); + Marshal.ReleaseComObject(graphBuilder); + + //Reset button state + button4.Enabled = true; + button3.Enabled = false; +#if DEBUG + if (m_rot != null) + { + m_rot.Dispose(); + m_rot = null; + } +#endif + } + + /// + /// Start recording + /// + public void Record() + { + if (mediaControl != null) + { + //Reset button state + button4.Enabled = false; + button3.Enabled = true; + + //Run the graph + mediaControl.Run(); + } + } + + /// + /// Initialize the graph + /// + public void InitGraph() + { + if (theDevice == null) + return; + + //Create the Graph + graphBuilder = (IGraphBuilder) new FilterGraph(); + + //Create the Capture Graph Builder + ICaptureGraphBuilder2 captureGraphBuilder = null; + captureGraphBuilder = (ICaptureGraphBuilder2) new CaptureGraphBuilder2(); + + //Create the media control for controlling the graph + mediaControl = (IMediaControl) this.graphBuilder; + + // Attach the filter graph to the capture graph + int hr = captureGraphBuilder.SetFiltergraph(this.graphBuilder); + DsError.ThrowExceptionForHR(hr); + + //Add the Video input device to the graph + hr = graphBuilder.AddFilter(theDevice, "source filter"); + DsError.ThrowExceptionForHR(hr); + + + //Add the Video compressor filter to the graph + hr = graphBuilder.AddFilter(theCompressor, "compressor filter"); + DsError.ThrowExceptionForHR(hr); + + //Create the file writer part of the graph. SetOutputFileName does this for us, and returns the mux and sink + IBaseFilter mux; + IFileSinkFilter sink; + hr = captureGraphBuilder.SetOutputFileName(MediaSubType.Avi, textBox1.Text, out mux, out sink); + DsError.ThrowExceptionForHR(hr); + + + //Render any preview pin of the device + hr = captureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, theDevice, null, null); + DsError.ThrowExceptionForHR(hr); + + //Connect the device and compressor to the mux to render the capture part of the graph + hr = captureGraphBuilder.RenderStream(PinCategory.Capture, MediaType.Video, theDevice, theCompressor, mux); + DsError.ThrowExceptionForHR(hr); + +#if DEBUG + m_rot = new DsROTEntry(graphBuilder); +#endif + + //get the video window from the graph + IVideoWindow videoWindow = null; + videoWindow = (IVideoWindow) graphBuilder; + + //Set the owener of the videoWindow to an IntPtr of some sort (the Handle of any control - could be a form / button etc.) + hr = videoWindow.put_Owner(panel1.Handle); + DsError.ThrowExceptionForHR(hr); + + //Set the style of the video window + hr = videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren); + DsError.ThrowExceptionForHR(hr); + + // Position video window in client rect of main application window + hr = videoWindow.SetWindowPosition(0,0, panel1.Width, panel1.Height); + DsError.ThrowExceptionForHR(hr); + + // Make the video window visible + hr = videoWindow.put_Visible(OABool.True); + DsError.ThrowExceptionForHR(hr); + + Marshal.ReleaseComObject(mux); + Marshal.ReleaseComObject(sink); + Marshal.ReleaseComObject(captureGraphBuilder); + } + + + /// + /// Enumerates all filters of the selected category and returns the IBaseFilter for the + /// filter described in friendlyname + /// + /// Category of the filter + /// Friendly name of the filter + /// IBaseFilter for the device + private IBaseFilter CreateFilter(Guid category, string friendlyname) + { + object source = null; + Guid iid = typeof(IBaseFilter).GUID; + foreach (DsDevice device in DsDevice.GetDevicesOfCat(category)) + { + if (device.Name.CompareTo(friendlyname) == 0) + { + device.Mon.BindToObject(null, null, ref iid, out source); + break; + } + } + + return (IBaseFilter)source; + } + + + /// + /// Displays a property page for a filter + /// + /// The filter for which to display a property page + private void DisplayPropertyPage(IBaseFilter dev) + { + //Get the ISpecifyPropertyPages for the filter + ISpecifyPropertyPages pProp = dev as ISpecifyPropertyPages; + int hr = 0; + + if (pProp == null) + { + //If the filter doesn't implement ISpecifyPropertyPages, try displaying IAMVfwCompressDialogs instead! + IAMVfwCompressDialogs compressDialog = dev as IAMVfwCompressDialogs; + if (compressDialog != null) + { + + hr = compressDialog.ShowDialog(VfwCompressDialogs.Config, IntPtr.Zero); + DsError.ThrowExceptionForHR(hr); + } + return; + } + + //Get the name of the filter from the FilterInfo struct + FilterInfo filterInfo; + hr = dev.QueryFilterInfo(out filterInfo); + DsError.ThrowExceptionForHR(hr); + + // Get the propertypages from the property bag + DsCAUUID caGUID; + hr = pProp.GetPages(out caGUID); + DsError.ThrowExceptionForHR(hr); + + // Create and display the OlePropertyFrame + object oDevice = (object)dev; + hr = OleCreatePropertyFrame(this.Handle, 0, 0, filterInfo.achName, 1, ref oDevice, caGUID.cElems, caGUID.pElems, 0, 0, IntPtr.Zero); + DsError.ThrowExceptionForHR(hr); + + // Release COM objects + Marshal.FreeCoTaskMem(caGUID.pElems); + Marshal.ReleaseComObject(pProp); + if (filterInfo.pGraph != null) + { + Marshal.ReleaseComObject(filterInfo.pGraph); + } + } + + private void button1_Click(object sender, System.EventArgs e) + { + //Display property page for the selected video input device + DisplayPropertyPage(theDevice); + } + + private void button2_Click(object sender, System.EventArgs e) + { + //Display property page for the selected video compressor + DisplayPropertyPage(theCompressor); + } + + private void button4_Click(object sender, System.EventArgs e) + { + InitGraph(); + Record(); + } + + private void button3_Click(object sender, System.EventArgs e) + { + StopRecord(); + } + + private void comboBox1_SelectedIndexChanged(object sender, System.EventArgs e) + { + //Release COM objects + if (theDevice != null) + { + Marshal.ReleaseComObject(theDevice); + theDevice = null; + } + //Create the filter for the selected video input device + string devicepath = comboBox1.SelectedItem.ToString(); + theDevice = CreateFilter(FilterCategory.VideoInputDevice, devicepath); + } + + private void comboBox2_SelectedIndexChanged(object sender, System.EventArgs e) + { + //Release COM objects + if (theCompressor != null) + { + Marshal.ReleaseComObject(theCompressor); + theCompressor = null; + } + //Create the filter for the selected video compressor + string devicepath = comboBox2.SelectedItem.ToString(); + theCompressor = CreateFilter(FilterCategory.VideoCompressorCategory, devicepath); + } + } +} diff --git a/Samples/Capture/DxPropPages/Form1.resx b/Samples/Capture/DxPropPages/Form1.resx new file mode 100644 index 0000000..8fd45c0 --- /dev/null +++ b/Samples/Capture/DxPropPages/Form1.resx @@ -0,0 +1,467 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + False + + + Private + + + False + + + True + + + Private + + + 8, 8 + + + True + + + Private + + + False + + + Form1 + + + (Default) + + + False + + + False + + + 8, 8 + + + True + + + 80 + + + True + + + Private + + + + AAABAAMAEBAAAAEAIABoBAAANgAAACAgAAABACAAqBAAAJ4EAAAwMAAAAQAgAKglAABGFQAAKAAAABAA + AAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAP////////////////////////////////// + ///////////////////////////////////////////////////7/f3//f////v////1/f3///7///v/ + ///6/Pz///39//X8//////7////6//j////9//7//P/9//39/f/+/v7/+f/+//Th3v+0i4j/q3lt/7Z9 + bv+1d23/tXtv/61/bv+ufmb/uX5u/7V+cf+uf2r/rnpt/7yXj//7+/v/////////+//Fm3j/xZ2A/+LA + sP////z/5Lix/615cv+5fXH/qHxr/8Cnnf/88/D/4c7B/49HNf+vXT7/olc3/9vLxf/8+fT/x55+/8GY + gf/FnYH/w5eA/8Sbev/InYr//PPv/5ZlT/+hVDr/pFU0/6ZSOf+oXkL/qlg//6RUO//++Pn////+/8ma + fv/Jl4H/xpl+/8eaf//InH3/0Zp//9Kznv+vUjv/q1Q6/6hUOv+jVDn/plc8/6JTOP+uUTr///3///// + ///Im4D/y5mD/8eaf//GmX7/yp5//8yafv/Ws5//olU7/6JVOv+kVTr/o1Q5/6JTOP+lVjv/pk42///+ + ///7/f7/wpmA/8yag//Im4D/x5p//8ebfP/Hm37/3rSh/6hUO/+oVDr/qFQ6/6ZVOv+kUzj/p1Y7/6VT + Ov//+f//9vz//8meg//EmoP/yZp//8eaf//Gm4D/y5mD/86fif+gUzn/p1Y7/6ZVOv+pVTv/pFQ7/6JR + Nv+nVzj/+v3////9///IloT/w5t//8maf//Hmn//xpuA/8qYgf/Gl4H/olU7/6ZVOv+mVTr/qlY8/6RU + O/+mVjn/r1tC///+////////1rqv/8CafP/Jmn//x5p//8Wbfv/Jl4D/x5mB/6FUOv+nVjv/plU6/6hV + Of+jVDn/pVU4/5ZQP//7/v////z+//3/+//nzcH/xZd//8WZfP/CmHv/y5mC/8qchP+lTzn/pFA2/6lY + Pf+sUjr/oVg4/49LOP/78uj//f///////v/8/v7//v3/////+f/FloH/ypiB/8eVfv/FmYL/n08w/6BU + Pf+iTTP/pFg7/7ail//++fr/+f3//////v/8/v7///////3//P/4///////8/+zHsf/OmYT/xZmC/59V + Of+mUzf/lU84//X9/f/9//////7/////+//8/v///////////////////v7+//7+/v///P//9v/6/96y + s/+BSzT///v3//f9/P/9/f3//f39//7+/v////////////////////////////////////////////// + //////////////////////////////////////////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAACAAAABAAAAAAQAgAAAA + AACAEAAAAAAAAAAAAAAAAAAAAAAAAP////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////+v///////////v////7////8///9/////f////3/ + /////v///v3///79////+/////v////8/////f////z////9///9//7//f39///+/////f////3////7 + /////f7///79////+//9//z/+//8//7+/v////////////7+/v///v///f////j9/P/2/fr/+f/9///+ + /v////7///38///++v/4/Pb/9vr0//Pe1v/PtKr/u5yT/62Jf/+ldm7/rHtx/7yRgv/GnpL/2bex/+ve + 3P/07/D//Pv9///7/P///v////7///z+///6/////v7+//39/f/8/Pz//v7+///+///4+/n//f76///+ + +////vr//fzy//Xx5v/Zxbr/zK2k/7GCev+qdm//qX5v/6p7bf+remr/r3tr/7V6av+4fW3/sXl0/7J2 + cP+3fHP/r3pt/6l7av+pfmv/u5mT/8+vqv/w2df/9ufl//729v/9/f3//Pz8//z8/P//////+v////3/ + /v///vv/9OHe/7SLiP+ufnL/q3tv/615bP+zfG//tXxt/7V6a/+1d23/tXtv/7B5bP+temr/pnto/6V6 + Z/+xf2n/sHhl/7l+bv+1fnH/r3tv/6x5b/+wfmr/sH5s/7CAdP+id27/vJeP//v7+//9/f3//v7+//7+ + /v////z/wqWQ/8CThf+8pIz/89/N//Lw8P/8/Pz/7Onh/9XGvf+1iHv/rndq/62Cbf+uf2r/p3Zm/614 + a/+oe23/qHtu/612b/+4fXT/uXxy/7KCcP+0j3v/y6yV//Lr6P////v/zLqv/6eEd/+IVET/o1VE/6BF + PP+aTjf////+/////P/FnYH/2JqC/8WbeP/FnYD/yZaC/9Gmk//z3dH///fv//T5+P/j6On/5Lix/615 + cv+3eXH/uX1x/7J1Z/+0eWn/qH9w/6KAc//Ap53//PPw///+///9+vz/qol6/5NfT/+fSjT/rlk//69d + Pv+iVzf/rlhC/5lPLf//+fX/+f7//8yvlP/Ll4D/w5t+/8mZh//Fm4T/w5mC/8ebg//JnIH/zJ2B/8aX + eP/KmIb/5sK6//vez////e//9fv///f8/f/EqJD/pnVf/5NOOv+nVTz/o1Y7/51VN/+kVzz/p1k8/6ZV + Ov+gTzr/p1dG/6hVOf+qTjv/kkkr//7//f/9//z/3baa/9GXgf/Hnn7/wZiB/8eYff/Im4D/wJh//76W + ff/KmYP/zZiD/8Sbev/InYr/ypqC/8msl////f7/+e/o/4ZNN/+cWUL/oVQ6/6RVNP+jWTX/oFs0/6ZU + O/+gUzj/nlQ4/6NUOf+qWD//pFQ7/65XR/+PSTH//f////v7///jyrr/xpqJ/72bfv/LmXv/wpp+/8ec + gf/FmH3/yZp+/8ubf//MnID/y5p6/8uaiv/HmXr/x6CE///+/P+GX1b/qFk4/6RXN/+iVDf/pFQ9/6NQ + O/+qV0L/olU6/6ZTPf+sUz//qlE9/6dROf+lVzP/o001/49MLf/7+/v//v3//+Hb0P/GmYT/yZp+/8mX + gf/EmX7/xpl+/8maf//Jmn//yJuA/8abgP/InH3/0Zp//8iWgP+/mn7////7/5tmWf+vUjv/rVM6/6tU + Ov+oVDr/plU6/6RVOv+iUzj/o1Q5/6ZXPP+iUzj/olM4/65ROv+kVz3/pHZe///9///+/f//6eXa/8WY + g//Km3//zJqE/8ecgf/Im4D/ypuA/8maf//Hmn//xZp//8qef//TnIH/zJqE/8Kdgf/9/Pj/l2NW/6lT + O/+oVDr/plU6/6RVOv+iVTr/olU6/6RVOv+jVDn/o1Q5/6NUOf+kVTr/rE84/6NUOf+TZ1D//vv9///+ + /////vT/xZqJ/8ibgP/LmYP/xpuA/8eaf//Jmn//yZp//8aZfv/EmX7/yp5//8yafv/JmIL/w5t///z9 + +f+RZFb/olU7/6JVOv+iVTr/pFU6/6RVOv+kVTr/pFU6/6NUOf+iUzj/pFU6/6VWO/+mTjb/pVY7/76d + jv/+/v7//v3/////+P/Gnoz/xJl+/8mXgP/Fmn//x5p//8maf//ImX7/xpl+/8SZfv/Hm3z/y5t//8yb + hf/Fmn///f76/5NoWf+kVDv/pFU6/6ZVOv+oVDr/qFQ6/6hUOv+jVDn/olM4/6NUOf+kVTr/pVY7/6pU + PP+jVTj/rpSI/////v/9/////f/5/922qP/CmYD/zJqD/8abgP/Im4D/yZp//8maf//GmX7/xJl+/8eb + fP/Hm37/xpeB/8ibgP////z/u5eH/6hUO/+oVDr/qFQ6/6hUOv+mVTr/plU6/6ZVOv+lVDn/pVQ5/6ZV + Ov+nVjv/pVM6/51NMP/bzcf//P/6//3///////v/6cK0/8Oagf/MmoP/w5h9/8aZfv/ImX7/yJl+/8ea + f//Fmn//x5t8/8ebfv/Gl4H/yp2C//z9+f/HpZX/plQ7/6ZVOv+mVTr/pFU6/6RVOv+kVTr/plU6/6dW + O/+mVTr/qFc8/6dWO/+kVDv/mkot/9HGwv/6/vj//f7//////P/gzLr/yZ6D/8Sag//Jmn//yZp//8ea + f//Hmn//x5p//8eaf//Gm4D/y5mD/8Saff/Km4X///7//7+ej/+jUzr/plU6/6dWO/+mVTr/plU6/6RV + Ov+nVjv/pVM6/6VVPP+kUzj/olE2/6dXOP+OQTH/6/Pp///8/////f//9/75//bn1//JmIL/wZh//8ma + f//Jmn//x5p//8eaf//Hmn//x5p//8Waf//KmIH/xJp9/8aXgf//+/z/vp2N/6RUO/+mVTr/plU6/6ZV + Ov+mVTr/pFU6/6ZVOv+nVTz/olI5/6VUOf+mVjn/o08z/4lAMv/9//n///z+///7/v/1/vv///fp/8iW + hP/Dm3//yZp//8maf//Hmn//x5p//8eaf//Hmn//xpuA/8qYgf/GnH//xpeB///8/f/An4//pFQ7/6ZV + Ov+mVTr/plU6/6ZVOv+kVTr/plU6/6ZVOv+jUzr/plU6/6ZWOf+vW0L/q2da////+////f////7///j/ + /v///fX/xZ+T/8Kaff/Jmn//yZp//8eaf//Hmn//x5p//8eaf//Emn3/yZeA/8adff/HmYH////+/76d + jf+jUzr/plU6/6dWO/+mVTr/plU6/6RVOv+mVTr/p1Y7/6NUOf+mVTr/qFg7/55SP/+hcGb/+f34//n+ + /f//////9//9///89//Wuq//wJp8/8maf//Jmn//x5p//8eaf//Hmn//x5p//8Wbfv/Jl4D/xp19/8eZ + gf///v3/uZiI/6RUO/+mVTr/p1Y7/6ZVOv+mVTr/pFU6/6dXOv+mVTr/o1Q5/6RUN/+lVTj/llA//8Kb + kv/6//3/+P79///+/v/6///////7/+3XzP/DnX//yZp//8maf//Hmn//x5p//8eaf//Hmn//xpx//8mX + gP/GnX3/x5mB///+/f+2lYX/pFQ7/6ZVOv+mVTr/plU6/6ZVOv+kVTr/p1c6/6ZVOv+nWD3/p1c6/6VV + Nv+NSzn/8dHG//r//v/4/////vz8//z+///0/Pv//f/7/+fNwf/BmoT/xpyF/8WWe//Km3//w5Z7/8ue + g//CmHv/y5mC/8WcfP/GmID////+/62PfP+rVT3/qVQ6/6RQNv+pWD3/qFM5/6xUPP+nUzn/n1Y4/6hV + Of+qVT//j0s4//vy6P////n//vz7//v+/////////f////D7+P/z//n///r1//Lg2f/IqJ3/zpyA/8mf + fP/HnIH/xZN9/8maf//Iln//xZx8/8SYgP///fz/spGB/6VROP+nUzr/qlY9/6ZVOv+mVjn/plk5/6tX + Pf+iVTX/o1Y8/5BNPv/Eo5r////8//v5+P/+/v7//P7////////9+/r////+//z+/v/+/f///P7+//3/ + /v/y4NX/zKqa/8ydgv/FmXz/ypiB/8eVfv/FnHz/xJiA//77/f+3lYj/pFg7/6BWPP+gVD3/ok0z/6pW + Ov+oWTj/qFU//45QQP/7/ff////+//75+v/5/f//8vX5//3///////7/+fv7/////v///P3///3+///9 + ///4/fv//f///////v/7+PD/wp2J/8qRe//ImYP/ypZ//8ufgP/ImoL//fz+/6iMgf+rVDn/n1U5/51W + O/+sVDz/sVc//6dPN/+MYVD/8+nf///+///5+Pz//f////r9///9/////f39//v5+P////7/+/////3/ + /////////f/8///8/v/8/v//+v////z9+/////r/9Pfu/+zHsf/OmYT/zZ5//8qYgf/3/P//zryx/6BX + Of+kWDv/plM3/5VPOP+UZ1L/++PP//v9/v///P7/+v////v9/v///v/////7//369v////7/+vz9//// + ///////////////////////////////////+/v7//v7+//39/f/9/f3/9v34/8GllP/Cln7/xKGH//// + 8v/hycP/tFdA/6dSOP+hVz//vZyT///6/P/6/P///f39//39/f/+/v7//v7+//7+/v////////////// + //////////////////////////////////////////////7+/v/+/v7//f39//39/f///f7///3w/97G + tP+2mIf/+//0/87Iw/+kTjr/i0k2/6J3aP////n/+f/9//T////9/f3//f39//39/f/+/v7//v7+//// + /////////////////////////////////////////////////////////v7+//7+/v/+/v7//v7+///8 + /v/6/v///v7+//j////x/Pr///39////9P/3+fP/+/////z7/////f7///77//39/f/+/v7//v7+//7+ + /v/+/v7///////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAwAAAAYAAAAAEA + IAAAAAAAgCUAAAAAAAAAAAAAAAAAAAAAAAD///////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////r////9///////////+/////v////3////8///9/////f////3/ + ///9//////7///79///+/f///v3////7////+v////v////8/////f////3////8/////f///f/+//3/ + /v/9/f3///7////+/////f////3////7/////v////3+///+/f//+/r////7//3//P/7//z/+v/7//7+ + /v/////////////////+/v7///////////////////////v////7/f3/+/39//z+/v/9////+/////v/ + ///y+/7/9Pv+//X9/f/4/f7//P7////+//////////7+//v////2+/r/+vz8//z+/v/+/v7///39//z6 + +f///v3/9fz///r////6/P3////+///++v////r////3////9//4////9/38//v//v/9//7////+//r7 + +f/8//3//P/9//39/f/+/v7///////7+/v/9/f3////////////////////////+/////////f////j9 + /P/2/fr/9/77//n//f///v7////+///+/f///fz///76//z9+f/4/Pb/9vr0//Pe1v/hy8D/z7Sq/7uc + k/+tiX//qH10/6V2bv+se3H/roFz/7yRgv/GnpL/2bex/+DHw//r3tz/9O/w//z7/f/+/Pz///v8///+ + ///++fr///7///z+///6////8vn8//7+/v/9/f3//Pz8//39/f/+/v7////////////////////////+ + ///8/Pz/+Pv5//3++v///vv///76///++v/9/PL/9fHm/+fd0//Zxbr/zK2k/72Wjf+xgnr/qnZv/6l+ + b/+keWr/qntt/6t6av+ve2v/tH5t/7V6av+4fW3/rHRv/7F5dP+ydnD/t3xz/693bP+vem3/qXtq/6l+ + a/+qiIL/u5mT/8+vqv/bvrr/8NnX//bn5f/+9vb////+//39/f/8/Pz//Pz8//39/f////////////// + //////////////r////5//7//f/+///++//04d7/0bCt/7SLiP+ufnL/q3tv/6t5bf+teWz/s3xv/7Z9 + bv+1fG3/tXpr/7V3bf+zdmz/tXtv/7B5bP+temr/rX9u/6Z7aP+lemf/rn5m/7F/af+weGX/uX5u/7Z7 + bP+1fnH/r3tv/6x5b/+uf2r/sH5q/7B+bP+uem3/sIB0/6J3bv+8l4//7MvC//v7+//9/f3//v7+//// + ///+/v7///////////////////////r+///x////+fXq///08f////j///r9/+Th3f/mxbz/yKOb/6+A + eP+sdm//s3px/7B4bf+rd2v/rXtv/615bf+4fHD/q3xu/6d9cf+veW7/sndo/7V+b/+4eG3/s39v/6p3 + Z/+pemz/p3pt/6p9cP+teG7/snZw/7d3cv+2d2//snx1/7WPiv/KtK//4tfT///79P///fT/6uHX/76u + nv/GpJ7/17ij/+38/v/1/////////////////////////////P/5+fn/wqWQ/8CThf+8pIz/3MK2//Pf + zf/y8PD//Pz8//3++v/s6eH/1ca9/8Kkmf+1iHv/rndq/62Cbf+qeGT/rn9q/6d2Zv+teGv/sX1t/6h7 + bf+oe27/rnpz/612b/+4fXT/uXxy/612af+ygnD/tI97/8uslf/Xzsv/8uvo////+//79Ov/zLqv/6eE + d/+IVET/iUg5/6NVRP+gRTz/mk43/+XV1v////7//////////////////////////P////v/xZ2B/9ia + gv/Fm3j/w5R+/8WdgP/JloL/0aaT/+LAsP/z3dH///fv/////P/0+fj/4+jp/+S4sf/FmZL/rXly/7d5 + cf+5fXH/uX1x/7J1Z/+0eWn/qHxr/6h/cP+igHP/wKed/9rKxP/88/D///7///36/P/hzsH/qol6/5Nf + T/+PRzX/n0o0/65ZP/+vXT7/nlEx/6JXN/+uWEL/mU8t/9vLxf//+fX///////////////////////f7 + /P////7/vJuB/9GZgP/LoH//zpmF/8yYgf/InH3/yJl9/8yYgf/LmIT/xpiH/8qnmv/hx7v/8d/U//36 + 9f/6//z////7//Dh2P/Hv7L/v6+o/8Cgm//cu7L/4MHE//nk4////Pj////1/9bLvf+1koT/o2ZY/5FC + Nf+dSC7/rFk9/6ZWN/+kWDT/plo2/6laOf+cSiv/r1pA/5tXMv+lWD3/lFQx/8/Kwf/7/ff///////// + //////////////n+///9//7/zK+U/8uXgP/Dm37/ypaJ/8mZh//Fm4T/w5mC/8aagv/Hm4P/yZyB/8uf + gv/MnYH/xpd4/8qYhv/LqZz/5sK6//vez////e//9v////X7///3/P3///Lb/8SokP+mdV//k046/5pK + M/+nVTz/o1Y7/51VN/+gVjr/pFc8/6dZPP+hUTT/plU6/6BPOv+nV0b/nU5B/6hVOf+qTjv/kkkr/+DX + 1P/+//3///////////////////////3//P/8+fT/3baa/9GXgf/Hnn7/w5WD/8GYgf/HmH3/yJuA/8Wd + gf/AmH//vpZ9/8OXgP/KmYP/zZiD/8Sbev+7loL/yJ2K/8qagv/JrJf//PPv///9/v/57+j/lmVP/4ZN + N/+cWUL/oVQ6/6dXOv+kVTT/o1k1/6BbNP+mUjn/plQ7/6BTOP+oXkL/nlQ4/6NUOf+qWD//o001/6RU + O/+uV0f/j0kx//74+f/9/////////////////////////////v////7/6MSs/9GYg//Bmnr/xJV//8ie + gf/HmIL/yZiC/8qZg//Nm4X/zpyF/8uZgv/Jl4D/ypuA/8SegP/EmYj/wI9//8+cfP/Emn3/49DD///9 + 8//HqZj/oUw8/6RQPv+mUkD/plM+/6pXQf+mVDv/qVc+/6BPNP+rVTf/pVM0/6NXOv+eVjj/oFs6/5hU + Mf+iXDf/nFcw/6paPf+mUD7/fzwh///+/v/0/Pv///////////////////////v7///6/v//48q6/8aa + if+9m37/yZeD/8uZe//Cmn7/x5yB/8eaf//FmH3/yZp+/8ucgP/Lm3//zJyA/8uaev/Ll4f/y5qK/8eZ + ev/HoIT/vbCo///+/P+GX1b/o1Ux/6hZOP+kVzf/olQ3/6JSOf+kVD3/o1A7/6pXQv+eVzb/olU6/6ZT + Pf+lTjr/rFM//6pRPf+nUTn/qlQ8/6VXM/+jTTX/j0wt/////P/7+/v///////////////////////79 + //////7/4dvQ/8aZhP/Jmn7/y5qA/8mXgf/EmX7/xpl+/8aZfv/Jmn//yZp//8eaf//Im4D/xpuA/8ic + ff/HlX7/0Zp//8iWgP+/mn7/0rOe////+/+bZln/r1I7/69SO/+tUzr/q1Q6/6lUOv+oVDr/plU6/6RV + Ov+jVDn/olM4/6NUOf+mVzz/plc8/6JTOP+iUzj/pFU6/65ROv+kVz3/pHZe///9/////f////////// + //////////////79/////v//6eXa/8WYg//Km3//zJuB/8yahP/HnIH/yJuA/8ibgP/Km4D/yZp//8ea + f//Hmn//xZp//8qef//LmYL/05yB/8yahP/CnYH/0rOe//38+P+XY1b/qVM7/6lTO/+oVDr/plU6/6ZV + Ov+kVTr/olU6/6JVOv+kVTr/pFU6/6NUOf+jVDn/o1Q5/6NUOf+kVTr/plc8/6xPOP+jVDn/k2dQ///+ + ///++/3///////////////////////38/v///f7/9fHm/8KXhP/Gmn3/yZh+/8uZg//Fmn//x5p//8ea + f//Jmn//ypuA/8ibgP/Im4D/x5yB/8aae//ImID/zJd8/8eWgP/DnID/07Ke//79+f+XZlj/pFQ7/6RU + O/+iVTr/olU6/6JVOv+iVTr/olU6/6JVOv+jVDn/pVY7/6ZXPP+lVjv/pFU6/6RVOv+iUzj/oFE2/7FX + P/+mVzz/qYFu///9/////v/////////////////////////+//////////70/8Waif/Im4D/ypl//8uZ + g//Gm4D/x5p//8eaf//Jmn//yZp//8aZfv/GmX7/xJl+/8qef//Jm4P/zJp+/8mYgv/Dm3//1rOf//z9 + +f+RZFb/olU7/6JVO/+iVTr/olU6/6JVOv+kVTr/pFU6/6RVOv+jVDn/pFU6/6NUOf+iUzj/olM4/6RV + Ov+lVjv/plc8/6ZONv+lVjv/vp2O///+///+/v7///////////////////////79///+/f/////4/8ae + jP/EmX7/yJl+/8mXgP/Fmn//x5p//8eaf//Jmn//yJl+/8aZfv/GmX7/xJl+/8ebfP/GmID/y5t//8yb + hf/Fmn//2rWh//3++v+TaFn/pFQ7/6RUO/+kVTr/plU6/6ZVOv+oVDr/qFQ6/6hUOv+kVTr/o1Q5/6JT + OP+jVDn/o1Q5/6RVOv+lVjv/plc8/6pUPP+jVTj/rpSI///7//////7////////////////////////+ + /////v/////7/9Kpmv/Em4L/y5yB/82bhP/EmX7/xpl+/8eaf//Jmn//yZp//8ibgP/Im4D/xpuA/8ic + ff/EmID/ypt//8qZg//DmH3/2rKf//v8+P+ddmf/qFQ7/6hUO/+oVDr/qFQ6/6hUOv+pVDr/qVQ6/6lU + Ov+nVjv/plU6/6ZVOv+oVzz/p1Y7/6VUOf+jUjf/o1I3/6hUO/+lVzr/yLWu///9///9//z///////// + //////////////3////7/f7//f/5/922qP/CmYD/yJl+/8yag//Gm4D/yJuA/8ibgP/Jmn//yZp//8ea + f//GmX7/xJl+/8ebfP/EmID/x5t+/8aXgf/Im4D/3rSh/////P+7l4f/qFQ7/6hUO/+oVDr/qFQ6/6hU + Ov+oVDr/plU6/6ZVOv+mVTr/plU6/6VUOf+kUzj/pVQ5/6ZVOv+nVjv/p1Y7/6VTOv+dTTD/283H///5 + ///8//r///////////////////////3////8/f/////7/+nCtP/DmoH/x5h9/8yag//DmH3/xpl+/8aZ + fv/ImX7/yJl+/8eaf//Hmn//xZp//8ebfP/FmYH/x5t+/8aXgf/KnYL/3LKf//z9+f/HpZX/plQ7/6ZU + O/+mVTr/plU6/6RVOv+kVTr/pFU6/6RVOv+kUzj/plU6/6dWO/+lVDn/plU6/6hXPP+nVjv/o1I3/6RU + O/+aSi3/0cbC///8///6/vj///////////////////////3+///2/P/////8/+DMuv/JnoP/ypl//8Sa + g//Jmn//yZp//8maf//Hmn//x5p//8eaf//Hmn//x5p//8abgP/Jmn//y5mD/8Saff/Km4X/zp+J///+ + //+/no//oFM5/6NTOv+mVTr/p1Y7/6lVO/+mVTr/plU6/6RVOv+pVTv/p1Y7/6VTOv+kVDv/pVU8/6RT + OP+iUTb/plM3/6dXOP+OQTH/6/Pp//r9/////P/////////////////////////+///7/v///P/7/+nX + xv/KnIT/zph//8KZgP/Jmn//yZp//8maf//Hmn//x5p//8eaf//Hmn//x5p//8Waf//ImX7/ypiB/8OZ + fP/HmIL/y5yG///8/f++nY7/oVQ6/6RUO/+mVTr/plU6/6hUOv+mVTr/plU6/6RVOv+nUzn/plU6/6ZU + O/+kVDv/pFQ7/6VUOf+mVjn/q1g8/6dVNv+DOCj/9//1//v+/////f/////////////////////////9 + /////v//9/75//bn1//JmIL/0pmA/8GYf//Jmn//yZp//8maf//Hmn//x5p//8eaf//Hmn//x5p//8Wa + f//ImX7/ypiB/8Saff/Gl4H/x5iC///7/P++nY3/olU7/6RUO/+mVTr/plU6/6hUOv+mVTr/plU6/6RV + Ov+oVDr/plU6/6dVPP+kVDv/olI5/6VUOf+mVjn/qFU5/6NPM/+JQDL//f/5//r7/////P7///////// + ///////////////7/v///f//9f77///36f/IloT/1pqE/8Obf//Jmn//yZp//8maf//Hmn//x5p//8ea + f//Hmn//x5p//8abgP/Jmn//ypiB/8acf//Gl4H/xpeB///8/f/An4//olU7/6RUO/+mVTr/plU6/6hU + Ov+mVTr/plU6/6RVOv+qVjz/plU6/6ZVOv+kVDv/o1M6/6ZVOv+mVjn/o1A0/69bQv+rZ1r////7///+ + /////f/////////////////////////9/////f//9v/+////9P/ElYf/05qF/8ScgP/Jmn//yZp//8ma + f//Hmn//x5p//8eaf//Hmn//x5p//8Waf//ImX7/ypiB/8edgP/HmYH/x5mB///+///BoJD/oVQ6/6NT + Ov+mVTr/p1Y7/6hUOv+mVTr/plU6/6RVOv+pVjr/plU6/6ZVOv+lVTz/pFU6/6lYPf+oWDv/plQ1/6RT + Pv+lamD/+fr2///+///+/f/////////////////////////+/////v//+P/+///99f/Fn5P/yJaA/8Ka + ff/Jmn//yZp//8maf//Hmn//x5p//8eaf//Hmn//x5p//8Saff/ImX3/yZeA/8adff/HmYH/x5mB//// + /v++nY3/oFM5/6NTOv+mVTr/p1Y7/6lVO/+mVTr/plU6/6RVOv+oVTn/plU6/6dWO/+kVTr/o1Q5/6ZV + Ov+oWDv/qlg5/55SP/+hcGb/+f34//3+///5/v3/////////////////////////////////9//9///8 + 9//Wuq//wZiC/8CafP/Jmn//yZp//8maf//Hmn//x5p//8eaf//Hmn//x5p//8Wbfv/ImX3/yZeA/8ad + ff/HmYH/x5mB///+/f+5mIj/oVQ6/6RUO/+mVTr/p1Y7/6hUOv+mVTr/plU6/6RVOv+oVTn/p1c6/6ZV + Ov+jVDn/o1Q5/6RUN/+lVTj/qVc4/5ZQP//Cm5L/+v/9//v+///4/v3////////////////////////+ + /v/7////+v//////+//t18z/w56I/8Odf//Jmn//yZp//8maf//Hmn//x5p//8eaf//Hmn//x5p//8ac + f//Km3//yZeA/8adff/HmYH/x5mB///+/f+2lYX/olU7/6RUO/+mVTr/plU6/6hUOv+mVTr/plU6/6RV + Ov+oVTn/p1c6/6ZVOv+lVjv/p1g9/6dXOv+lVTb/qVc4/41LOf/x0cb/+v/+//f8///4//////////// + ///////////////+/f///f///v3///f7/P///vn/2L6y/7+ShP/BmnT/yp18/86bgf/Ml4P/ypeD/8iZ + g//InH//x5t8/8Wfgf/DmXz/ypiB/8icf//ImID/yZuD//z6+f+ulYH/n1Q+/6BUPf+iUzj/qlo9/6JU + N/+lVjv/plM9/6hSPv+gVjr/o1Q5/6xVO/+rUTj/p1I4/6ZXPP+kUzj/rFU7/39yYv///fP////8//v+ + ///6/v////////////////////////78/P///P7//P7///T8+//9//v/+Ozi/+fNwf/BmoT/xpyF/8WX + f//Flnv/ypt//8WZfP/Dlnv/y56D/8KYe//KnoH/y5mC/8WcfP/GmID/ypyE/////v+tj3z/pU85/6tV + Pf+pVDr/pFA2/6VUOf+pWD3/qFM5/6xUPP+sUjr/p1M5/59WOP+hWDj/qFU5/6pVP/+PSzj/ilxK//vy + 6P////n//vz7//3////7/v///////////////////////////////v///f////D7+P/z//n//f/7///6 + 9f/y4Nn/yKid/8CRfP/OnID/yZ98/8Ode//HnIH/xZN9/8maf//ImX7/yJZ//8WcfP/EmID/x5mB///9 + /P+ykYH/qVU7/6VROP+nUzr/qlY9/6tXPf+mVTr/plY5/6ZZOf+pVD7/q1c9/6JVNf+kVzf/o1Y8/5BN + Pv/Eo5r//f71/////P/7+fj//v7+///////8/v///////////////////////////////f7/+/z6//r/ + /v/y/fv/+P////j8/f////////Pv/+fHuv/HnYb/xJV5/8aae//Gmn3/yp2C/8ybgf/JmH7/zpyF/8ad + ff/EmID/yZ2F///6+/+0kYP/n1c5/59VOf+hVDr/pFE7/6pWPf+mUjj/pVo6/5tVMP+kUDb/nlU5/6BV + O/+cTTr/nWZX//Lm2v/3/vn//fz+//n8///7/f7///////39/f////7///////////////////////// + //////7//fv6/////v/8/v7//f////79///8/v7//f/+////+f/y4NX/zKqa/8WWgf/MnYL/xZl8/8qY + gf/GlH3/x5V+/8WcfP/EmID/xZmC//77/f+3lYj/n08w/6RYO/+gVjz/oFQ9/6lWQP+iTTP/qlY6/6hZ + OP+kWDv/qFU//45QQP+2opf/+/33/////v/++fr/+f7///n9///y9fn//f///////v////7///////// + //////////////n7+//////////+///8/f///f7///7////9///4/fv//f////7+/v////7/+/jw/9rK + vf/CnYn/ypF7/8iZg//NnYX/ypZ//8ufgP/ImoL/wZV+//38/v+ojIH/t1Y8/6tUOf+fVTn/nVY7/6VV + PP+sVDz/sVc//6dPN/+eUj//jGFQ//Pp3//5+vj///7///n4/P/9////+v37//r9///9/////f39//7+ + /v/7+fj///////////////////////v7+//9///////////+/v////////////37+v/6//////7////9 + ///4/P3/8f/7//n/9//x39T/1Kqd/8CXgf/ImYP/zZmC/8iae//Gln7/yJyF//v+//+okob/slM5/6dT + N/+kWDv/nlQ4/6VTOv+nVkH/kks3/5BRPf++n5b////4//v//v/5+/z///f+///8////////9/77///9 + /P////7/+Pj4/////////////////////////////////////v/8/v7/+/////3/////////+//6//3/ + /P///P7//P7///j////6/////P37/////P////r/9Pfu/+zHsf/InIX/zpmE/82ef//KmIH/xZmC//f8 + ///OvLH/n1U5/6BXOf+kWDv/plM3/6lVPP+VTzj/lGdS//vjz//1/f3/+/3+///8/v/9////+v////v9 + /v///v////z+////+//9+vb////+//z+///6/P3///////////////////////////////////////// + //////////////////////////////7+/v/+/v7//v7+//39/f/9/f3//f39//b9+P/x6N7/waWU/8KW + fv/EoYf/0JWF////8v/hycP/rE86/7RXQP+nUjj/oVc//4NLOP+9nJP///r8//r8///9/f3//f39//39 + /f/9/f3//v7+//7+/v/+/v7//v7+//////////////////////////////////////////////////// + //////////////////////////////////////////////7+/v/+/v7//v7+//39/f/9/f3//f39///9 + /v////r///3w/97GtP+2mIf/zZKJ//v/9P/OyMP/tFQ9/6ROOv+LSTb/ondo///x5v////n/+f/9//T/ + ///9/f3//f39//39/f/9/f3//f39//7+/v/+/v7//v7+//////////////////////////////////// + //////////////////////////////////////////////////////////////7+/v/+/v7//v7+//7+ + /v/+/v7//f39///8///6//7/9v/6///+9//t39n/3rKz//r//P/e4+L/gUs0/3BFMv/dw7f///v3//v/ + ///3/fz/9/z6//b69P/9/f3//f39//39/f/9/f3//f39//7+/v/+/v7//v7+//////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///+/v7//v7+//7+/v/+/v7//v7+///8/v/5/f7/+v7///7+/v/4//////f5//H8+v///f3////u//// + 9P/3+fP/+/////n8///8+/////3+///++//9/f3//f39//7+/v/+/v7//v7+//7+/v/+/v7//v7+//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + + + \ No newline at end of file diff --git a/Samples/Capture/DxPropPages/readme.txt b/Samples/Capture/DxPropPages/readme.txt new file mode 100644 index 0000000..0072480 --- /dev/null +++ b/Samples/Capture/DxPropPages/readme.txt @@ -0,0 +1,11 @@ +--------------------------------------------------------------------- +DxPropPages + +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +--------------------------------------------------------------------- + +This sample uses DirectShow to preview video, as well as capturing and compressing +video in realtime. This sample also demonstrates the use of property pages. \ No newline at end of file diff --git a/Samples/Capture/DxSnap/App.ico b/Samples/Capture/DxSnap/App.ico new file mode 100644 index 0000000000000000000000000000000000000000..3a5525fd794f7a7c5c8e6187f470ea3af38cd2b6 GIT binary patch literal 1078 zcmeHHJr05}7=1t!Hp3A*8IHkVf+j?-!eHY14Gtcw1Eb*_9>Bq^zETJ@GKj{_2j4$w zo9}xCh!8{T3=X##Skq>ikMjsvB|y%crWBM2iW(4pI}c%z6%lW!=~4v77#3{z!dmB1 z__&l)-{KUYR+|8|;wB^R|9ET$J@(@=#rd^=)qs85?vAy(PSF5CyNkus435LVkZ$rj zNw|JG-P7^hF<(;#o*Vk}5R#e|^13tBbQkeF?djULtvqyxd3<{9 literal 0 HcmV?d00001 diff --git a/Samples/Capture/DxSnap/AssemblyInfo.cs b/Samples/Capture/DxSnap/AssemblyInfo.cs new file mode 100644 index 0000000..9f89a32 --- /dev/null +++ b/Samples/Capture/DxSnap/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/Capture/DxSnap/Capture.cs b/Samples/Capture/DxSnap/Capture.cs new file mode 100644 index 0000000..4015f5e --- /dev/null +++ b/Samples/Capture/DxSnap/Capture.cs @@ -0,0 +1,537 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.Collections; +using System.Runtime.InteropServices; +using System.Threading; +using System.Diagnostics; +using System.Windows.Forms; + +using DirectShowLib; + + +namespace SnapShot +{ + /// Summary description for MainForm. + internal class Capture : ISampleGrabberCB, IDisposable + { + #region Member variables + + /// graph builder interface. + private IFilterGraph2 m_FilterGraph = null; + + // Used to snap picture on Still pin + private IAMVideoControl m_VidControl = null; + private IPin m_pinStill = null; + + /// so we can wait for the async job to finish + private ManualResetEvent m_PictureReady = null; + + private bool m_WantOne = false; + + /// Dimensions of the image, calculated once in constructor for perf. + private int m_videoWidth; + private int m_videoHeight; + private int m_stride; + + /// buffer for bitmap data. Always release by caller + private IntPtr m_ipBuffer = IntPtr.Zero; + +#if DEBUG + // Allow you to "Connect to remote graph" from GraphEdit + DsROTEntry m_rot = null; +#endif + #endregion + + #region APIs + [DllImport("Kernel32.dll", EntryPoint="RtlMoveMemory")] + private static extern void CopyMemory(IntPtr Destination, IntPtr Source, [MarshalAs(UnmanagedType.U4)] int Length); + #endregion + + // Zero based device index and device params and output window + public Capture(int iDeviceNum, int iWidth, int iHeight, short iBPP, Control hControl) + { + DsDevice [] capDevices; + + // Get the collection of video devices + capDevices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice); + + if (iDeviceNum + 1 > capDevices.Length) + { + throw new Exception("No video capture devices found at that index!"); + } + + try + { + // Set up the capture graph + SetupGraph( capDevices[iDeviceNum], iWidth, iHeight, iBPP, hControl); + + // tell the callback to ignore new images + m_PictureReady = new ManualResetEvent(false); + } + catch + { + Dispose(); + throw; + } + } + + /// release everything. + public void Dispose() + { +#if DEBUG + if (m_rot != null) + { + m_rot.Dispose(); + } +#endif + CloseInterfaces(); + if (m_PictureReady != null) + { + m_PictureReady.Close(); + } + } + // Destructor + ~Capture() + { + Dispose(); + } + + /// + /// Get the image from the Still pin. The returned image can turned into a bitmap with + /// Bitmap b = new Bitmap(cam.Width, cam.Height, cam.Stride, PixelFormat.Format24bppRgb, m_ip); + /// If the image is upside down, you can fix it with + /// b.RotateFlip(RotateFlipType.RotateNoneFlipY); + /// + /// Returned pointer to be freed by caller with Marshal.FreeCoTaskMem + public IntPtr Click() + { + int hr; + + // get ready to wait for new image + m_PictureReady.Reset(); + m_ipBuffer = Marshal.AllocCoTaskMem(Math.Abs(m_stride) * m_videoHeight); + + try + { + m_WantOne = true; + + // If we are using a still pin, ask for a picture + if (m_VidControl != null) + { + // Tell the camera to send an image + hr = m_VidControl.SetMode(m_pinStill, VideoControlFlags.Trigger); + DsError.ThrowExceptionForHR( hr ); + } + + // Start waiting + if ( ! m_PictureReady.WaitOne(9000, false) ) + { + throw new Exception("Timeout waiting to get picture"); + } + } + catch + { + Marshal.FreeCoTaskMem(m_ipBuffer); + m_ipBuffer = IntPtr.Zero; + throw; + } + + // Got one + return m_ipBuffer; + } + + public int Width + { + get + { + return m_videoWidth; + } + } + public int Height + { + get + { + return m_videoHeight; + } + } + public int Stride + { + get + { + return m_stride; + } + } + + + /// build the capture graph for grabber. + private void SetupGraph(DsDevice dev, int iWidth, int iHeight, short iBPP, Control hControl) + { + int hr; + + ISampleGrabber sampGrabber = null; + IBaseFilter capFilter = null; + IPin pCaptureOut = null; + IPin pSampleIn = null; + IPin pRenderIn = null; + + // Get the graphbuilder object + m_FilterGraph = new FilterGraph() as IFilterGraph2; + + try + { +#if DEBUG + m_rot = new DsROTEntry(m_FilterGraph); +#endif + // add the video input device + hr = m_FilterGraph.AddSourceFilterForMoniker(dev.Mon, null, dev.Name, out capFilter); + DsError.ThrowExceptionForHR( hr ); + + // Find the still pin + m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Still, 0); + + // Didn't find one. Is there a preview pin? + if (m_pinStill == null) + { + m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Preview, 0); + } + + // Still haven't found one. Need to put a splitter in so we have + // one stream to capture the bitmap from, and one to display. Ok, we + // don't *have* to do it that way, but we are going to anyway. + if (m_pinStill == null) + { + IPin pRaw = null; + IPin pSmart = null; + + // There is no still pin + m_VidControl = null; + + // Add a splitter + IBaseFilter iSmartTee = (IBaseFilter)new SmartTee(); + + try + { + hr = m_FilterGraph.AddFilter(iSmartTee, "SmartTee"); + DsError.ThrowExceptionForHR( hr ); + + // Find the find the capture pin from the video device and the + // input pin for the splitter, and connnect them + pRaw = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0); + pSmart = DsFindPin.ByDirection(iSmartTee, PinDirection.Input, 0); + + hr = m_FilterGraph.Connect(pRaw, pSmart); + DsError.ThrowExceptionForHR( hr ); + + // Now set the capture and still pins (from the splitter) + m_pinStill = DsFindPin.ByName(iSmartTee, "Preview"); + pCaptureOut = DsFindPin.ByName(iSmartTee, "Capture"); + + // If any of the default config items are set, perform the config + // on the actual video device (rather than the splitter) + if (iHeight + iWidth + iBPP > 0) + { + SetConfigParms(pRaw, iWidth, iHeight, iBPP); + } + } + finally + { + if (pRaw != null) + { + Marshal.ReleaseComObject(pRaw); + } + if (pRaw != pSmart) + { + Marshal.ReleaseComObject(pSmart); + } + if (pRaw != iSmartTee) + { + Marshal.ReleaseComObject(iSmartTee); + } + } + } + else + { + // Get a control pointer (used in Click()) + m_VidControl = capFilter as IAMVideoControl; + + pCaptureOut = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0); + + // If any of the default config items are set + if (iHeight + iWidth + iBPP > 0) + { + SetConfigParms(m_pinStill, iWidth, iHeight, iBPP); + } + } + + // Get the SampleGrabber interface + sampGrabber = new SampleGrabber() as ISampleGrabber; + + // Configure the sample grabber + IBaseFilter baseGrabFlt = sampGrabber as IBaseFilter; + ConfigureSampleGrabber(sampGrabber); + pSampleIn = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Input, 0); + + // Get the default video renderer + IBaseFilter pRenderer = new VideoRendererDefault() as IBaseFilter; + hr = m_FilterGraph.AddFilter(pRenderer, "Renderer"); + DsError.ThrowExceptionForHR( hr ); + + pRenderIn = DsFindPin.ByDirection(pRenderer, PinDirection.Input, 0); + + // Add the sample grabber to the graph + hr = m_FilterGraph.AddFilter( baseGrabFlt, "Ds.NET Grabber" ); + DsError.ThrowExceptionForHR( hr ); + + if (m_VidControl == null) + { + // Connect the Still pin to the sample grabber + hr = m_FilterGraph.Connect(m_pinStill, pSampleIn); + DsError.ThrowExceptionForHR( hr ); + + // Connect the capture pin to the renderer + hr = m_FilterGraph.Connect(pCaptureOut, pRenderIn); + DsError.ThrowExceptionForHR( hr ); + } + else + { + // Connect the capture pin to the renderer + hr = m_FilterGraph.Connect(pCaptureOut, pRenderIn); + DsError.ThrowExceptionForHR( hr ); + + // Connect the Still pin to the sample grabber + hr = m_FilterGraph.Connect(m_pinStill, pSampleIn); + DsError.ThrowExceptionForHR( hr ); + } + + // Learn the video properties + SaveSizeInfo(sampGrabber); + ConfigVideoWindow(hControl); + + // Start the graph + IMediaControl mediaCtrl = m_FilterGraph as IMediaControl; + hr = mediaCtrl.Run(); + DsError.ThrowExceptionForHR( hr ); + } + finally + { + if (sampGrabber != null) + { + Marshal.ReleaseComObject(sampGrabber); + sampGrabber = null; + } + if (pCaptureOut != null) + { + Marshal.ReleaseComObject(pCaptureOut); + pCaptureOut = null; + } + if (pRenderIn != null) + { + Marshal.ReleaseComObject(pRenderIn); + pRenderIn = null; + } + if (pSampleIn != null) + { + Marshal.ReleaseComObject(pSampleIn); + pSampleIn = null; + } + } + } + + private void SaveSizeInfo(ISampleGrabber sampGrabber) + { + int hr; + + // Get the media type from the SampleGrabber + AMMediaType media = new AMMediaType(); + + hr = sampGrabber.GetConnectedMediaType( media ); + DsError.ThrowExceptionForHR( hr ); + + if( (media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero) ) + { + throw new NotSupportedException( "Unknown Grabber Media Format" ); + } + + // Grab the size info + VideoInfoHeader videoInfoHeader = (VideoInfoHeader) Marshal.PtrToStructure( media.formatPtr, typeof(VideoInfoHeader) ); + m_videoWidth = videoInfoHeader.BmiHeader.Width; + m_videoHeight = videoInfoHeader.BmiHeader.Height; + m_stride = m_videoWidth * (videoInfoHeader.BmiHeader.BitCount / 8); + + DsUtils.FreeAMMediaType(media); + media = null; + } + + // Set the video window within the control specified by hControl + private void ConfigVideoWindow(Control hControl) + { + int hr; + + IVideoWindow ivw = m_FilterGraph as IVideoWindow; + + // Set the parent + hr = ivw.put_Owner(hControl.Handle); + DsError.ThrowExceptionForHR( hr ); + + // Turn off captions, etc + hr = ivw.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren | WindowStyle.ClipSiblings); + DsError.ThrowExceptionForHR( hr ); + + // Yes, make it visible + hr = ivw.put_Visible( OABool.True ); + DsError.ThrowExceptionForHR( hr ); + + // Move to upper left corner + Rectangle rc = hControl.ClientRectangle; + hr = ivw.SetWindowPosition( 0, 0, rc.Right, rc.Bottom ); + DsError.ThrowExceptionForHR( hr ); + } + + private void ConfigureSampleGrabber(ISampleGrabber sampGrabber) + { + int hr; + AMMediaType media = new AMMediaType(); + + // Set the media type to Video/RBG24 + media.majorType = MediaType.Video; + media.subType = MediaSubType.RGB24; + media.formatType = FormatType.VideoInfo; + hr = sampGrabber.SetMediaType( media ); + DsError.ThrowExceptionForHR( hr ); + + DsUtils.FreeAMMediaType(media); + media = null; + + // Configure the samplegrabber + hr = sampGrabber.SetCallback( this, 1 ); + DsError.ThrowExceptionForHR( hr ); + } + + // Set the Framerate, and video size + private void SetConfigParms(IPin pStill, int iWidth, int iHeight, short iBPP) + { + int hr; + AMMediaType media; + VideoInfoHeader v; + + IAMStreamConfig videoStreamConfig = pStill as IAMStreamConfig; + + // Get the existing format block + hr = videoStreamConfig.GetFormat(out media); + DsError.ThrowExceptionForHR(hr); + + try + { + // copy out the videoinfoheader + v = new VideoInfoHeader(); + Marshal.PtrToStructure( media.formatPtr, v ); + + // if overriding the width, set the width + if (iWidth > 0) + { + v.BmiHeader.Width = iWidth; + } + + // if overriding the Height, set the Height + if (iHeight > 0) + { + v.BmiHeader.Height = iHeight; + } + + // if overriding the bits per pixel + if (iBPP > 0) + { + v.BmiHeader.BitCount = iBPP; + } + + // Copy the media structure back + Marshal.StructureToPtr( v, media.formatPtr, false ); + + // Set the new format + hr = videoStreamConfig.SetFormat( media ); + DsError.ThrowExceptionForHR( hr ); + } + finally + { + DsUtils.FreeAMMediaType(media); + media = null; + } + } + + /// Shut down capture + private void CloseInterfaces() + { + int hr; + + try + { + if( m_FilterGraph != null ) + { + IMediaControl mediaCtrl = m_FilterGraph as IMediaControl; + + // Stop the graph + hr = mediaCtrl.Stop(); + } + } + catch (Exception ex) + { + Debug.WriteLine(ex); + } + + if (m_FilterGraph != null) + { + Marshal.ReleaseComObject(m_FilterGraph); + m_FilterGraph = null; + } + + if (m_VidControl != null) + { + Marshal.ReleaseComObject(m_VidControl); + m_VidControl = null; + } + + if (m_pinStill != null) + { + Marshal.ReleaseComObject(m_pinStill); + m_pinStill = null; + } + } + + /// sample callback, NOT USED. + int ISampleGrabberCB.SampleCB( double SampleTime, IMediaSample pSample ) + { + Marshal.ReleaseComObject(pSample); + return 0; + } + + /// buffer callback, COULD BE FROM FOREIGN THREAD. + int ISampleGrabberCB.BufferCB( double SampleTime, IntPtr pBuffer, int BufferLen ) + { + // Note that we depend on only being called once per call to Click. Otherwise + // a second call can overwrite the previous image. + Debug.Assert(BufferLen == Math.Abs(m_stride) * m_videoHeight, "Incorrect buffer length"); + + if (m_WantOne) + { + m_WantOne = false; + Debug.Assert(m_ipBuffer != IntPtr.Zero, "Unitialized buffer"); + + // Save the buffer + CopyMemory(m_ipBuffer, pBuffer, BufferLen); + + // Picture is ready. + m_PictureReady.Set(); + } + + return 0; + } + } +} diff --git a/Samples/Capture/DxSnap/DxSnap-2005.csproj b/Samples/Capture/DxSnap/DxSnap-2005.csproj new file mode 100644 index 0000000..d9412cd --- /dev/null +++ b/Samples/Capture/DxSnap/DxSnap-2005.csproj @@ -0,0 +1,113 @@ + + + Local + 8.0.50727 + 2.0 + {E6052609-A070-41D5-85B9-ACABA91170C5} + Debug + AnyCPU + App.ico + + + SnapShot + + + JScript + Grid + IE50 + false + WinExe + SnapShot + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + + Code + + + Code + + + Form + + + Form1.cs + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Capture/DxSnap/DxSnap-2005.sln b/Samples/Capture/DxSnap/DxSnap-2005.sln new file mode 100644 index 0000000..e717e19 --- /dev/null +++ b/Samples/Capture/DxSnap/DxSnap-2005.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DxSnap-2005", "DxSnap-2005.csproj", "{E6052609-A070-41D5-85B9-ACABA91170C5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E6052609-A070-41D5-85B9-ACABA91170C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E6052609-A070-41D5-85B9-ACABA91170C5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E6052609-A070-41D5-85B9-ACABA91170C5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E6052609-A070-41D5-85B9-ACABA91170C5}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Capture/DxSnap/DxSnap-2008.sln b/Samples/Capture/DxSnap/DxSnap-2008.sln new file mode 100644 index 0000000..164db0d --- /dev/null +++ b/Samples/Capture/DxSnap/DxSnap-2008.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DxSnap-2008", "DxSnap-2008.csproj", "{E6052609-A070-41D5-85B9-ACABA91170C5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E6052609-A070-41D5-85B9-ACABA91170C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E6052609-A070-41D5-85B9-ACABA91170C5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E6052609-A070-41D5-85B9-ACABA91170C5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E6052609-A070-41D5-85B9-ACABA91170C5}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Capture/DxSnap/DxSnap.csproj b/Samples/Capture/DxSnap/DxSnap.csproj new file mode 100644 index 0000000..4add86d --- /dev/null +++ b/Samples/Capture/DxSnap/DxSnap.csproj @@ -0,0 +1,145 @@ + + + + Local + 8.0.50727 + 2.0 + {E6052609-A070-41D5-85B9-ACABA91170C5} + Debug + AnyCPU + App.ico + + + SnapShot + + + JScript + Grid + IE50 + false + WinExe + SnapShot + OnBuildSuccess + + + + + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + + Code + + + Code + + + Form + + + Form1.cs + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Capture/DxSnap/Form1.cs b/Samples/Capture/DxSnap/Form1.cs new file mode 100644 index 0000000..f6a6821 --- /dev/null +++ b/Samples/Capture/DxSnap/Form1.cs @@ -0,0 +1,171 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using System.Drawing.Imaging; + +namespace SnapShot +{ + /// + /// Summary description for Form1. + /// + public class Form1 : System.Windows.Forms.Form + { + private System.Windows.Forms.Button button1; + private System.Windows.Forms.PictureBox pictureBox1; + /// + /// Required designer variable. + /// + private System.ComponentModel.Container components = null; + private System.Windows.Forms.PictureBox pictureBox2; + private Capture cam; + + public Form1() + { + // + // Required for Windows Form Designer support + // + InitializeComponent(); + + const int VIDEODEVICE = 0; // zero based index of video capture device to use + const int VIDEOWIDTH = 640; // Depends on video device caps + const int VIDEOHEIGHT = 480; // Depends on video device caps + const int VIDEOBITSPERPIXEL = 24; // BitsPerPixel values determined by device + + cam = new Capture(VIDEODEVICE, VIDEOWIDTH, VIDEOHEIGHT, VIDEOBITSPERPIXEL, pictureBox2); + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if (components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + + if (m_ip != IntPtr.Zero) + { + Marshal.FreeCoTaskMem(m_ip); + m_ip = IntPtr.Zero; + } + } + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.button1 = new System.Windows.Forms.Button(); + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.pictureBox2 = new System.Windows.Forms.PictureBox(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit(); + this.SuspendLayout(); + // + // button1 + // + this.button1.Location = new System.Drawing.Point(368, 80); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(75, 40); + this.button1.TabIndex = 0; + this.button1.Text = "Click"; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // pictureBox1 + // + this.pictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.pictureBox1.Location = new System.Drawing.Point(16, 256); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(640, 480); + this.pictureBox1.TabIndex = 1; + this.pictureBox1.TabStop = false; + // + // pictureBox2 + // + this.pictureBox2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.pictureBox2.Location = new System.Drawing.Point(16, 8); + this.pictureBox2.Name = "pictureBox2"; + this.pictureBox2.Size = new System.Drawing.Size(320, 240); + this.pictureBox2.TabIndex = 2; + this.pictureBox2.TabStop = false; + // + // Form1 + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(776, 794); + this.Controls.Add(this.pictureBox2); + this.Controls.Add(this.pictureBox1); + this.Controls.Add(this.button1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.Name = "Form1"; + this.Text = "DxSnap"; + this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.Form1_FormClosed); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit(); + this.ResumeLayout(false); + + } + #endregion + + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.Run(new Form1()); + } + + IntPtr m_ip = IntPtr.Zero; + + private void button1_Click(object sender, System.EventArgs e) + { + Cursor.Current = Cursors.WaitCursor; + + // Release any previous buffer + if (m_ip != IntPtr.Zero) + { + Marshal.FreeCoTaskMem(m_ip); + m_ip = IntPtr.Zero; + } + + // capture image + m_ip = cam.Click(); + Bitmap b = new Bitmap(cam.Width, cam.Height, cam.Stride, PixelFormat.Format24bppRgb, m_ip); + + // If the image is upsidedown + b.RotateFlip(RotateFlipType.RotateNoneFlipY); + pictureBox1.Image = b; + + Cursor.Current = Cursors.Default; + } + + private void Form1_FormClosed(object sender, FormClosedEventArgs e) + { + cam.Dispose(); + + if (m_ip != IntPtr.Zero) + { + Marshal.FreeCoTaskMem(m_ip); + m_ip = IntPtr.Zero; + } + } + } +} diff --git a/Samples/Capture/DxSnap/Form1.resx b/Samples/Capture/DxSnap/Form1.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/Samples/Capture/DxSnap/Form1.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Samples/Capture/DxSnap/readme.txt b/Samples/Capture/DxSnap/readme.txt new file mode 100644 index 0000000..6900f0a --- /dev/null +++ b/Samples/Capture/DxSnap/readme.txt @@ -0,0 +1,16 @@ +--------------------------------------------------------------------- +DxSnap + +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + +--------------------------------------------------------------------- + +Use DirectShow to take snapshots from the Still pin of a capture +device. Note the MS encourages you to use WIA for this, but if +you want to do in with DirectShow and C#, here's how. + +Note that this sample will only work with devices that output uncompressed +video as RBG24. This will include most webcams, but probably zero tv tuners. \ No newline at end of file diff --git a/Samples/Capture/DxTuner/AssemblyInfo.cs b/Samples/Capture/DxTuner/AssemblyInfo.cs new file mode 100644 index 0000000..9f89a32 --- /dev/null +++ b/Samples/Capture/DxTuner/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/Capture/DxTuner/DxTuner-2005.csproj b/Samples/Capture/DxTuner/DxTuner-2005.csproj new file mode 100644 index 0000000..aa0af58 --- /dev/null +++ b/Samples/Capture/DxTuner/DxTuner-2005.csproj @@ -0,0 +1,110 @@ + + + Local + 8.0.50727 + 2.0 + {4AC57653-233F-4862-AF88-139A1D02A007} + Debug + AnyCPU + + + + + DxTuner + + + JScript + Grid + IE50 + false + WinExe + DxTuner + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + Code + + + Form + + + Form1.cs + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Capture/DxTuner/DxTuner-2005.sln b/Samples/Capture/DxTuner/DxTuner-2005.sln new file mode 100644 index 0000000..6098dcd --- /dev/null +++ b/Samples/Capture/DxTuner/DxTuner-2005.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DxTuner-2005", "DxTuner-2005.csproj", "{4AC57653-233F-4862-AF88-139A1D02A007}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4AC57653-233F-4862-AF88-139A1D02A007}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Capture/DxTuner/DxTuner-2008.sln b/Samples/Capture/DxTuner/DxTuner-2008.sln new file mode 100644 index 0000000..0409115 --- /dev/null +++ b/Samples/Capture/DxTuner/DxTuner-2008.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DxTuner-2008", "DxTuner-2008.csproj", "{4AC57653-233F-4862-AF88-139A1D02A007}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4AC57653-233F-4862-AF88-139A1D02A007}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4AC57653-233F-4862-AF88-139A1D02A007}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Capture/DxTuner/DxTuner.csproj b/Samples/Capture/DxTuner/DxTuner.csproj new file mode 100644 index 0000000..1c08ceb --- /dev/null +++ b/Samples/Capture/DxTuner/DxTuner.csproj @@ -0,0 +1,142 @@ + + + + Local + 8.0.50727 + 2.0 + {EAB509E6-7797-4911-A201-2FA515386193} + Debug + AnyCPU + + + + + DxTuner + + + JScript + Grid + IE50 + false + WinExe + DxTuner + OnBuildSuccess + + + + + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + Code + + + Form + + + Form1.cs + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Capture/DxTuner/Form1.cs b/Samples/Capture/DxTuner/Form1.cs new file mode 100644 index 0000000..34d263a --- /dev/null +++ b/Samples/Capture/DxTuner/Form1.cs @@ -0,0 +1,628 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + +Written by oohansen@gmail.com +Adapted by snarfle@sourceforge.net +*****************************************************************************/ + +using System; +using System.Windows.Forms; +using System.Runtime.InteropServices; + +using DirectShowLib; + +namespace DirectShowLib.Samples +{ + /// + /// Summary description for Form1. + /// + public class Form1 : System.Windows.Forms.Form + { + private System.Windows.Forms.ComboBox comboBox1; + private System.Windows.Forms.ComboBox comboBox2; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Button button2; + private System.Windows.Forms.Button button3; + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.NumericUpDown nudChannel; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.Button button4; + private System.Windows.Forms.Button button5; + /// + /// Required designer variable. + /// + private System.ComponentModel.Container components = null; + + //A (modified) definition of OleCreatePropertyFrame found here: http://groups.google.no/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/db794e9779144a46/55dbed2bab4cd772?lnk=st&q=[DllImport(%22olepro32.dll%22)]&rnum=1&hl=no#55dbed2bab4cd772 + [DllImport("oleaut32.dll", CharSet=CharSet.Unicode, ExactSpelling=true)] + public static extern int OleCreatePropertyFrame( + IntPtr hwndOwner, + int x, + int y, + [MarshalAs(UnmanagedType.LPWStr)] string lpszCaption, + int cObjects, + [MarshalAs(UnmanagedType.Interface, ArraySubType=UnmanagedType.IUnknown)] + ref object ppUnk, + int cPages, + IntPtr lpPageClsID, + int lcid, + int dwReserved, + IntPtr lpvReserved); + + IMediaControl mediaControl = null; + IGraphBuilder graphBuilder = null; + IBaseFilter theDevice = null; + IBaseFilter theCompressor = null; + IAMTVTuner tuner = null; + IBaseFilter crossbar = null; + +#if DEBUG + // Allow you to "Connect to remote graph" from GraphEdit + DsROTEntry m_rot = null; +#endif + + public Form1() + { + // + // Required for Windows Form Designer support + // + InitializeComponent(); + + // + // TODO: Add any constructor code after InitializeComponent call + // + + //enumerate Video Input filters and add them to comboBox1 + foreach (DsDevice ds in DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice)) + { + comboBox1.Items.Add(ds.Name); + } + + comboBox2.Items.Add(""); + + //enumerate Video Compressor filters and add them to comboBox1 + foreach (DsDevice ds in DsDevice.GetDevicesOfCat(FilterCategory.VideoCompressorCategory)) + { + comboBox2.Items.Add(ds.Name); + } + + //Select first combobox item + if (comboBox1.Items.Count > 0) + { + comboBox1.SelectedIndex = 0; + } + + //Select first combobox item + if (comboBox2.Items.Count > 0) + { + comboBox2.SelectedIndex = 0; + } + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if (components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); + this.comboBox1 = new System.Windows.Forms.ComboBox(); + this.comboBox2 = new System.Windows.Forms.ComboBox(); + this.button1 = new System.Windows.Forms.Button(); + this.button2 = new System.Windows.Forms.Button(); + this.button3 = new System.Windows.Forms.Button(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.panel1 = new System.Windows.Forms.Panel(); + this.nudChannel = new System.Windows.Forms.NumericUpDown(); + this.label1 = new System.Windows.Forms.Label(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.button5 = new System.Windows.Forms.Button(); + this.button4 = new System.Windows.Forms.Button(); + ((System.ComponentModel.ISupportInitialize)(this.nudChannel)).BeginInit(); + this.groupBox1.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.SuspendLayout(); + // + // comboBox1 + // + this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboBox1.Location = new System.Drawing.Point(8, 8); + this.comboBox1.Name = "comboBox1"; + this.comboBox1.Size = new System.Drawing.Size(256, 21); + this.comboBox1.TabIndex = 0; + this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged); + // + // comboBox2 + // + this.comboBox2.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboBox2.Location = new System.Drawing.Point(8, 40); + this.comboBox2.Name = "comboBox2"; + this.comboBox2.Size = new System.Drawing.Size(256, 21); + this.comboBox2.TabIndex = 1; + this.comboBox2.SelectedIndexChanged += new System.EventHandler(this.comboBox2_SelectedIndexChanged); + // + // button1 + // + this.button1.Location = new System.Drawing.Point(264, 8); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(120, 24); + this.button1.TabIndex = 2; + this.button1.Text = "Show property pages"; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // button2 + // + this.button2.Location = new System.Drawing.Point(264, 40); + this.button2.Name = "button2"; + this.button2.Size = new System.Drawing.Size(120, 24); + this.button2.TabIndex = 3; + this.button2.Text = "Show property pages"; + this.button2.Click += new System.EventHandler(this.button2_Click); + // + // button3 + // + this.button3.Location = new System.Drawing.Point(32, 400); + this.button3.Name = "button3"; + this.button3.Size = new System.Drawing.Size(96, 23); + this.button3.TabIndex = 4; + this.button3.Text = "Record"; + this.button3.Click += new System.EventHandler(this.button3_Click); + // + // textBox1 + // + this.textBox1.Location = new System.Drawing.Point(8, 368); + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size(384, 20); + this.textBox1.TabIndex = 6; + this.textBox1.Text = "c:\\test.avi"; + // + // panel1 + // + this.panel1.BackColor = System.Drawing.Color.Black; + this.panel1.Location = new System.Drawing.Point(8, 72); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(384, 288); + this.panel1.TabIndex = 7; + // + // nudChannel + // + this.nudChannel.Location = new System.Drawing.Point(64, 11); + this.nudChannel.Name = "nudChannel"; + this.nudChannel.Size = new System.Drawing.Size(40, 20); + this.nudChannel.TabIndex = 8; + this.nudChannel.Value = new decimal(new int[] { + 5, + 0, + 0, + 0}); + this.nudChannel.ValueChanged += new System.EventHandler(this.OnValueChanged); + // + // label1 + // + this.label1.Location = new System.Drawing.Point(8, 11); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(48, 16); + this.label1.TabIndex = 9; + this.label1.Text = "Channel"; + this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.button2); + this.groupBox1.Controls.Add(this.button1); + this.groupBox1.Controls.Add(this.comboBox2); + this.groupBox1.Controls.Add(this.comboBox1); + this.groupBox1.Location = new System.Drawing.Point(3, 0); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(392, 68); + this.groupBox1.TabIndex = 10; + this.groupBox1.TabStop = false; + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.button5); + this.groupBox2.Controls.Add(this.button4); + this.groupBox2.Controls.Add(this.label1); + this.groupBox2.Controls.Add(this.nudChannel); + this.groupBox2.Enabled = false; + this.groupBox2.Location = new System.Drawing.Point(152, 390); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(240, 40); + this.groupBox2.TabIndex = 11; + this.groupBox2.TabStop = false; + // + // button5 + // + this.button5.Location = new System.Drawing.Point(168, 11); + this.button5.Name = "button5"; + this.button5.Size = new System.Drawing.Size(64, 23); + this.button5.TabIndex = 11; + this.button5.Text = "CrossBar"; + this.button5.Click += new System.EventHandler(this.button5_Click); + // + // button4 + // + this.button4.Location = new System.Drawing.Point(112, 11); + this.button4.Name = "button4"; + this.button4.Size = new System.Drawing.Size(48, 23); + this.button4.TabIndex = 10; + this.button4.Text = "Tuner"; + this.button4.Click += new System.EventHandler(this.button4_Click); + // + // Form1 + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(402, 432); + this.Controls.Add(this.groupBox2); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.panel1); + this.Controls.Add(this.textBox1); + this.Controls.Add(this.button3); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "Form1"; + this.Text = "DsTuner"; + this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.Form1_FormClosed); + ((System.ComponentModel.ISupportInitialize)(this.nudChannel)).EndInit(); + this.groupBox1.ResumeLayout(false); + this.groupBox2.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + + } + #endregion + + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.Run(new Form1()); + } + + /// + /// Stop recording and release the graph + /// + public void StopRecord() + { + //Stop the Graph + mediaControl.Stop(); + +#if DEBUG + if (m_rot != null) + { + m_rot.Dispose(); + m_rot = null; + } +#endif + + //Release COM objects + Marshal.ReleaseComObject(graphBuilder); + graphBuilder = null; + + if (tuner != null) + { + Marshal.ReleaseComObject(tuner); + tuner = null; + } + + if (crossbar != null) + { + Marshal.ReleaseComObject(crossbar); + crossbar = null; + } + } + + /// + /// Start recording + /// + public void Record() + { + if (mediaControl != null) + { + //Run the graph + mediaControl.Run(); + } + } + + /// + /// Initialize the graph + /// + public void InitGraph() + { + if (theDevice == null) + return; + + object o; + + //Create the Graph + graphBuilder = (IGraphBuilder) new FilterGraph(); + +#if DEBUG + m_rot = new DsROTEntry(graphBuilder); +#endif + + //Create the Capture Graph Builder + ICaptureGraphBuilder2 captureGraphBuilder = null; + captureGraphBuilder = (ICaptureGraphBuilder2) new CaptureGraphBuilder2(); + + //Create the media control for controlling the graph + mediaControl = (IMediaControl) this.graphBuilder; + + // Attach the filter graph to the capture graph + int hr = captureGraphBuilder.SetFiltergraph(this.graphBuilder); + DsError.ThrowExceptionForHR(hr); + + //Add the Video input device to the graph + hr = graphBuilder.AddFilter(theDevice, "source filter"); + DsError.ThrowExceptionForHR(hr); + + //Add the Video compressor filter to the graph + if (theCompressor != null) + { + hr = graphBuilder.AddFilter(theCompressor, "compressor filter"); + DsError.ThrowExceptionForHR(hr); + } + + //Create the file writer part of the graph. SetOutputFileName does this for us, and returns the mux and sink + IBaseFilter mux; + IFileSinkFilter sink; + hr = captureGraphBuilder.SetOutputFileName(MediaSubType.Avi, textBox1.Text, out mux, out sink); + DsError.ThrowExceptionForHR(hr); + + //Connect the device and compressor to the mux to render the capture part of the graph + hr = captureGraphBuilder.RenderStream(PinCategory.Capture, MediaType.Video, theDevice, theCompressor, mux); + DsError.ThrowExceptionForHR(hr); + + //Render any preview pin of the device + hr = captureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, theDevice, null, null); + DsError.ThrowExceptionForHR(hr); + + tuner = null; + crossbar = null; + + hr = captureGraphBuilder.FindInterface(null, null, theDevice, typeof(IAMTVTuner).GUID, out o); + if (hr >= 0) + { + tuner = (IAMTVTuner)o; + o = null; + + hr = captureGraphBuilder.FindInterface(null, null, theDevice, typeof(IAMCrossbar).GUID, out o); + if (hr >= 0) + { + crossbar = (IBaseFilter)o; + o = null; + } + } + + //get the video window from the graph + IVideoWindow videoWindow = null; + videoWindow = (IVideoWindow) graphBuilder; + + //Set the owener of the videoWindow to an IntPtr of some sort (the Handle of any control - could be a form / button etc.) + hr = videoWindow.put_Owner(panel1.Handle); + DsError.ThrowExceptionForHR(hr); + + //Set the style of the video window + hr = videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren); + DsError.ThrowExceptionForHR(hr); + + // Position video window in client rect of main application window + hr = videoWindow.SetWindowPosition(0, 0, panel1.Width, panel1.Height); + DsError.ThrowExceptionForHR(hr); + + // Make the video window visible + hr = videoWindow.put_Visible(OABool.True); + DsError.ThrowExceptionForHR(hr); + + Marshal.ReleaseComObject(mux); + Marshal.ReleaseComObject(sink); + Marshal.ReleaseComObject(captureGraphBuilder); + } + + + /// + /// Enumerates all filters of the selected category and returns the IBaseFilter for the + /// filter described in friendlyname + /// + /// Category of the filter + /// Friendly name of the filter + /// IBaseFilter for the device + private IBaseFilter CreateFilter(Guid category, string friendlyname) + { + object source = null; + Guid iid = typeof(IBaseFilter).GUID; + foreach (DsDevice device in DsDevice.GetDevicesOfCat(category)) + { + if (device.Name.CompareTo(friendlyname) == 0) + { + device.Mon.BindToObject(null, null, ref iid, out source); + break; + } + } + + return (IBaseFilter)source; + } + + + /// + /// Displays a property page for a filter + /// + /// The filter for which to display a property page + private void DisplayPropertyPage(IBaseFilter dev) + { + //Get the ISpecifyPropertyPages for the filter + ISpecifyPropertyPages pProp = dev as ISpecifyPropertyPages; + int hr = 0; + + if (pProp == null) + { + //If the filter doesn't implement ISpecifyPropertyPages, try displaying IAMVfwCompressDialogs instead! + IAMVfwCompressDialogs compressDialog = dev as IAMVfwCompressDialogs; + if (compressDialog != null) + { + + hr = compressDialog.ShowDialog(VfwCompressDialogs.Config, IntPtr.Zero); + DsError.ThrowExceptionForHR(hr); + } + else + { + MessageBox.Show("Item has no property page", "No Property Page", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } + return; + } + + //Get the name of the filter from the FilterInfo struct + FilterInfo filterInfo; + hr = dev.QueryFilterInfo(out filterInfo); + DsError.ThrowExceptionForHR(hr); + + // Get the propertypages from the property bag + DsCAUUID caGUID; + hr = pProp.GetPages(out caGUID); + DsError.ThrowExceptionForHR(hr); + + //Create and display the OlePropertyFrame + object oDevice = (object)dev; + hr = OleCreatePropertyFrame(this.Handle, 0, 0, filterInfo.achName, 1, ref oDevice, caGUID.cElems, caGUID.pElems, 0, 0, IntPtr.Zero); + DsError.ThrowExceptionForHR(hr); + + Marshal.ReleaseComObject(oDevice); + + if (filterInfo.pGraph != null) + { + Marshal.ReleaseComObject(filterInfo.pGraph); + } + + // Release COM objects + Marshal.FreeCoTaskMem(caGUID.pElems); + } + + private void button1_Click(object sender, System.EventArgs e) + { + //Display property page for the selected video input device + DisplayPropertyPage(theDevice); + } + + private void button2_Click(object sender, System.EventArgs e) + { + //Display property page for the selected video compressor + DisplayPropertyPage(theCompressor); + } + + private void button3_Click(object sender, System.EventArgs e) + { + if (button3.Text == "Record") + { + InitGraph(); + SetChannel(); + Record(); + button3.Text = "Stop"; + textBox1.Enabled = false; + groupBox1.Enabled = false; + } + else + { + textBox1.Enabled = true; + groupBox1.Enabled = true; + groupBox2.Enabled = false; + StopRecord(); + button3.Text = "Record"; + } + } + + private void SetChannel() + { + if (tuner != null) + { + groupBox2.Enabled = true; + OnValueChanged(null, null); + } + else + { + groupBox2.Enabled = false; + } + } + + private void comboBox1_SelectedIndexChanged(object sender, System.EventArgs e) + { + //Release COM objects + if (theDevice != null) + { + Marshal.ReleaseComObject(theDevice); + theDevice = null; + } + //Create the filter for the selected video input device + string devicepath = comboBox1.SelectedItem.ToString(); + theDevice = CreateFilter(FilterCategory.VideoInputDevice, devicepath); + } + + private void comboBox2_SelectedIndexChanged(object sender, System.EventArgs e) + { + //Release COM objects + if (theCompressor != null) + { + Marshal.ReleaseComObject(theCompressor); + theCompressor = null; + } + //Create the filter for the selected video compressor + string devicepath = comboBox2.SelectedItem.ToString(); + theCompressor = CreateFilter(FilterCategory.VideoCompressorCategory, devicepath); + } + + private void OnValueChanged(object sender, System.EventArgs e) + { + int hr; + + hr = tuner.put_Channel((int)nudChannel.Value, 0, 0); + DsError.ThrowExceptionForHR(hr); + } + + private void button4_Click(object sender, System.EventArgs e) + { + mediaControl.Pause(); + IBaseFilter ibf = (IBaseFilter)tuner; + DisplayPropertyPage(ibf); + mediaControl.Run(); + } + + private void button5_Click(object sender, System.EventArgs e) + { + mediaControl.Pause(); + DisplayPropertyPage(crossbar); + mediaControl.Run(); + } + + private void Form1_FormClosed(object sender, FormClosedEventArgs e) + { + if (button3.Text != "Record") + { + StopRecord(); + } + } + } +} diff --git a/Samples/Capture/DxTuner/Form1.resx b/Samples/Capture/DxTuner/Form1.resx new file mode 100644 index 0000000..19f1e40 --- /dev/null +++ b/Samples/Capture/DxTuner/Form1.resx @@ -0,0 +1,530 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + False + + + Private + + + False + + + True + + + Private + + + 8, 8 + + + True + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + 8, 8 + + + True + + + False + + + True + + + Private + + + Private + + + 8, 8 + + + True + + + False + + + True + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + (Default) + + + False + + + False + + + 8, 8 + + + True + + + 80 + + + Form1 + + + True + + + Private + + + + AAABAAMAEBAAAAEAIABoBAAANgAAACAgAAABACAAqBAAAJ4EAAAwMAAAAQAgAKglAABGFQAAKAAAABAA + AAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAP////////////////////////////////// + ///////////////////////////////////////////////////7/f3//f////v////1/f3///7///v/ + ///6/Pz///39//X8//////7////6//j////9//7//P/9//39/f/+/v7/+f/+//Th3v+0i4j/q3lt/7Z9 + bv+1d23/tXtv/61/bv+ufmb/uX5u/7V+cf+uf2r/rnpt/7yXj//7+/v/////////+//Fm3j/xZ2A/+LA + sP////z/5Lix/615cv+5fXH/qHxr/8Cnnf/88/D/4c7B/49HNf+vXT7/olc3/9vLxf/8+fT/x55+/8GY + gf/FnYH/w5eA/8Sbev/InYr//PPv/5ZlT/+hVDr/pFU0/6ZSOf+oXkL/qlg//6RUO//++Pn////+/8ma + fv/Jl4H/xpl+/8eaf//InH3/0Zp//9Kznv+vUjv/q1Q6/6hUOv+jVDn/plc8/6JTOP+uUTr///3///// + ///Im4D/y5mD/8eaf//GmX7/yp5//8yafv/Ws5//olU7/6JVOv+kVTr/o1Q5/6JTOP+lVjv/pk42///+ + ///7/f7/wpmA/8yag//Im4D/x5p//8ebfP/Hm37/3rSh/6hUO/+oVDr/qFQ6/6ZVOv+kUzj/p1Y7/6VT + Ov//+f//9vz//8meg//EmoP/yZp//8eaf//Gm4D/y5mD/86fif+gUzn/p1Y7/6ZVOv+pVTv/pFQ7/6JR + Nv+nVzj/+v3////9///IloT/w5t//8maf//Hmn//xpuA/8qYgf/Gl4H/olU7/6ZVOv+mVTr/qlY8/6RU + O/+mVjn/r1tC///+////////1rqv/8CafP/Jmn//x5p//8Wbfv/Jl4D/x5mB/6FUOv+nVjv/plU6/6hV + Of+jVDn/pVU4/5ZQP//7/v////z+//3/+//nzcH/xZd//8WZfP/CmHv/y5mC/8qchP+lTzn/pFA2/6lY + Pf+sUjr/oVg4/49LOP/78uj//f///////v/8/v7//v3/////+f/FloH/ypiB/8eVfv/FmYL/n08w/6BU + Pf+iTTP/pFg7/7ail//++fr/+f3//////v/8/v7///////3//P/4///////8/+zHsf/OmYT/xZmC/59V + Of+mUzf/lU84//X9/f/9//////7/////+//8/v///////////////////v7+//7+/v///P//9v/6/96y + s/+BSzT///v3//f9/P/9/f3//f39//7+/v////////////////////////////////////////////// + //////////////////////////////////////////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAACAAAABAAAAAAQAgAAAA + AACAEAAAAAAAAAAAAAAAAAAAAAAAAP////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////+v///////////v////7////8///9/////f////3/ + /////v///v3///79////+/////v////8/////f////z////9///9//7//f39///+/////f////3////7 + /////f7///79////+//9//z/+//8//7+/v////////////7+/v///v///f////j9/P/2/fr/+f/9///+ + /v////7///38///++v/4/Pb/9vr0//Pe1v/PtKr/u5yT/62Jf/+ldm7/rHtx/7yRgv/GnpL/2bex/+ve + 3P/07/D//Pv9///7/P///v////7///z+///6/////v7+//39/f/8/Pz//v7+///+///4+/n//f76///+ + +////vr//fzy//Xx5v/Zxbr/zK2k/7GCev+qdm//qX5v/6p7bf+remr/r3tr/7V6av+4fW3/sXl0/7J2 + cP+3fHP/r3pt/6l7av+pfmv/u5mT/8+vqv/w2df/9ufl//729v/9/f3//Pz8//z8/P//////+v////3/ + /v///vv/9OHe/7SLiP+ufnL/q3tv/615bP+zfG//tXxt/7V6a/+1d23/tXtv/7B5bP+temr/pnto/6V6 + Z/+xf2n/sHhl/7l+bv+1fnH/r3tv/6x5b/+wfmr/sH5s/7CAdP+id27/vJeP//v7+//9/f3//v7+//7+ + /v////z/wqWQ/8CThf+8pIz/89/N//Lw8P/8/Pz/7Onh/9XGvf+1iHv/rndq/62Cbf+uf2r/p3Zm/614 + a/+oe23/qHtu/612b/+4fXT/uXxy/7KCcP+0j3v/y6yV//Lr6P////v/zLqv/6eEd/+IVET/o1VE/6BF + PP+aTjf////+/////P/FnYH/2JqC/8WbeP/FnYD/yZaC/9Gmk//z3dH///fv//T5+P/j6On/5Lix/615 + cv+3eXH/uX1x/7J1Z/+0eWn/qH9w/6KAc//Ap53//PPw///+///9+vz/qol6/5NfT/+fSjT/rlk//69d + Pv+iVzf/rlhC/5lPLf//+fX/+f7//8yvlP/Ll4D/w5t+/8mZh//Fm4T/w5mC/8ebg//JnIH/zJ2B/8aX + eP/KmIb/5sK6//vez////e//9fv///f8/f/EqJD/pnVf/5NOOv+nVTz/o1Y7/51VN/+kVzz/p1k8/6ZV + Ov+gTzr/p1dG/6hVOf+qTjv/kkkr//7//f/9//z/3baa/9GXgf/Hnn7/wZiB/8eYff/Im4D/wJh//76W + ff/KmYP/zZiD/8Sbev/InYr/ypqC/8msl////f7/+e/o/4ZNN/+cWUL/oVQ6/6RVNP+jWTX/oFs0/6ZU + O/+gUzj/nlQ4/6NUOf+qWD//pFQ7/65XR/+PSTH//f////v7///jyrr/xpqJ/72bfv/LmXv/wpp+/8ec + gf/FmH3/yZp+/8ubf//MnID/y5p6/8uaiv/HmXr/x6CE///+/P+GX1b/qFk4/6RXN/+iVDf/pFQ9/6NQ + O/+qV0L/olU6/6ZTPf+sUz//qlE9/6dROf+lVzP/o001/49MLf/7+/v//v3//+Hb0P/GmYT/yZp+/8mX + gf/EmX7/xpl+/8maf//Jmn//yJuA/8abgP/InH3/0Zp//8iWgP+/mn7////7/5tmWf+vUjv/rVM6/6tU + Ov+oVDr/plU6/6RVOv+iUzj/o1Q5/6ZXPP+iUzj/olM4/65ROv+kVz3/pHZe///9///+/f//6eXa/8WY + g//Km3//zJqE/8ecgf/Im4D/ypuA/8maf//Hmn//xZp//8qef//TnIH/zJqE/8Kdgf/9/Pj/l2NW/6lT + O/+oVDr/plU6/6RVOv+iVTr/olU6/6RVOv+jVDn/o1Q5/6NUOf+kVTr/rE84/6NUOf+TZ1D//vv9///+ + /////vT/xZqJ/8ibgP/LmYP/xpuA/8eaf//Jmn//yZp//8aZfv/EmX7/yp5//8yafv/JmIL/w5t///z9 + +f+RZFb/olU7/6JVOv+iVTr/pFU6/6RVOv+kVTr/pFU6/6NUOf+iUzj/pFU6/6VWO/+mTjb/pVY7/76d + jv/+/v7//v3/////+P/Gnoz/xJl+/8mXgP/Fmn//x5p//8maf//ImX7/xpl+/8SZfv/Hm3z/y5t//8yb + hf/Fmn///f76/5NoWf+kVDv/pFU6/6ZVOv+oVDr/qFQ6/6hUOv+jVDn/olM4/6NUOf+kVTr/pVY7/6pU + PP+jVTj/rpSI/////v/9/////f/5/922qP/CmYD/zJqD/8abgP/Im4D/yZp//8maf//GmX7/xJl+/8eb + fP/Hm37/xpeB/8ibgP////z/u5eH/6hUO/+oVDr/qFQ6/6hUOv+mVTr/plU6/6ZVOv+lVDn/pVQ5/6ZV + Ov+nVjv/pVM6/51NMP/bzcf//P/6//3///////v/6cK0/8Oagf/MmoP/w5h9/8aZfv/ImX7/yJl+/8ea + f//Fmn//x5t8/8ebfv/Gl4H/yp2C//z9+f/HpZX/plQ7/6ZVOv+mVTr/pFU6/6RVOv+kVTr/plU6/6dW + O/+mVTr/qFc8/6dWO/+kVDv/mkot/9HGwv/6/vj//f7//////P/gzLr/yZ6D/8Sag//Jmn//yZp//8ea + f//Hmn//x5p//8eaf//Gm4D/y5mD/8Saff/Km4X///7//7+ej/+jUzr/plU6/6dWO/+mVTr/plU6/6RV + Ov+nVjv/pVM6/6VVPP+kUzj/olE2/6dXOP+OQTH/6/Pp///8/////f//9/75//bn1//JmIL/wZh//8ma + f//Jmn//x5p//8eaf//Hmn//x5p//8Waf//KmIH/xJp9/8aXgf//+/z/vp2N/6RUO/+mVTr/plU6/6ZV + Ov+mVTr/pFU6/6ZVOv+nVTz/olI5/6VUOf+mVjn/o08z/4lAMv/9//n///z+///7/v/1/vv///fp/8iW + hP/Dm3//yZp//8maf//Hmn//x5p//8eaf//Hmn//xpuA/8qYgf/GnH//xpeB///8/f/An4//pFQ7/6ZV + Ov+mVTr/plU6/6ZVOv+kVTr/plU6/6ZVOv+jUzr/plU6/6ZWOf+vW0L/q2da////+////f////7///j/ + /v///fX/xZ+T/8Kaff/Jmn//yZp//8eaf//Hmn//x5p//8eaf//Emn3/yZeA/8adff/HmYH////+/76d + jf+jUzr/plU6/6dWO/+mVTr/plU6/6RVOv+mVTr/p1Y7/6NUOf+mVTr/qFg7/55SP/+hcGb/+f34//n+ + /f//////9//9///89//Wuq//wJp8/8maf//Jmn//x5p//8eaf//Hmn//x5p//8Wbfv/Jl4D/xp19/8eZ + gf///v3/uZiI/6RUO/+mVTr/p1Y7/6ZVOv+mVTr/pFU6/6dXOv+mVTr/o1Q5/6RUN/+lVTj/llA//8Kb + kv/6//3/+P79///+/v/6///////7/+3XzP/DnX//yZp//8maf//Hmn//x5p//8eaf//Hmn//xpx//8mX + gP/GnX3/x5mB///+/f+2lYX/pFQ7/6ZVOv+mVTr/plU6/6ZVOv+kVTr/p1c6/6ZVOv+nWD3/p1c6/6VV + Nv+NSzn/8dHG//r//v/4/////vz8//z+///0/Pv//f/7/+fNwf/BmoT/xpyF/8WWe//Km3//w5Z7/8ue + g//CmHv/y5mC/8WcfP/GmID////+/62PfP+rVT3/qVQ6/6RQNv+pWD3/qFM5/6xUPP+nUzn/n1Y4/6hV + Of+qVT//j0s4//vy6P////n//vz7//v+/////////f////D7+P/z//n///r1//Lg2f/IqJ3/zpyA/8mf + fP/HnIH/xZN9/8maf//Iln//xZx8/8SYgP///fz/spGB/6VROP+nUzr/qlY9/6ZVOv+mVjn/plk5/6tX + Pf+iVTX/o1Y8/5BNPv/Eo5r////8//v5+P/+/v7//P7////////9+/r////+//z+/v/+/f///P7+//3/ + /v/y4NX/zKqa/8ydgv/FmXz/ypiB/8eVfv/FnHz/xJiA//77/f+3lYj/pFg7/6BWPP+gVD3/ok0z/6pW + Ov+oWTj/qFU//45QQP/7/ff////+//75+v/5/f//8vX5//3///////7/+fv7/////v///P3///3+///9 + ///4/fv//f///////v/7+PD/wp2J/8qRe//ImYP/ypZ//8ufgP/ImoL//fz+/6iMgf+rVDn/n1U5/51W + O/+sVDz/sVc//6dPN/+MYVD/8+nf///+///5+Pz//f////r9///9/////f39//v5+P////7/+/////3/ + /////////f/8///8/v/8/v//+v////z9+/////r/9Pfu/+zHsf/OmYT/zZ5//8qYgf/3/P//zryx/6BX + Of+kWDv/plM3/5VPOP+UZ1L/++PP//v9/v///P7/+v////v9/v///v/////7//369v////7/+vz9//// + ///////////////////////////////////+/v7//v7+//39/f/9/f3/9v34/8GllP/Cln7/xKGH//// + 8v/hycP/tFdA/6dSOP+hVz//vZyT///6/P/6/P///f39//39/f/+/v7//v7+//7+/v////////////// + //////////////////////////////////////////////7+/v/+/v7//f39//39/f///f7///3w/97G + tP+2mIf/+//0/87Iw/+kTjr/i0k2/6J3aP////n/+f/9//T////9/f3//f39//39/f/+/v7//v7+//// + /////////////////////////////////////////////////////////v7+//7+/v/+/v7//v7+///8 + /v/6/v///v7+//j////x/Pr///39////9P/3+fP/+/////z7/////f7///77//39/f/+/v7//v7+//7+ + /v/+/v7///////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAwAAAAYAAAAAEA + IAAAAAAAgCUAAAAAAAAAAAAAAAAAAAAAAAD///////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////r////9///////////+/////v////3////8///9/////f////3/ + ///9//////7///79///+/f///v3////7////+v////v////8/////f////3////8/////f///f/+//3/ + /v/9/f3///7////+/////f////3////7/////v////3+///+/f//+/r////7//3//P/7//z/+v/7//7+ + /v/////////////////+/v7///////////////////////v////7/f3/+/39//z+/v/9////+/////v/ + ///y+/7/9Pv+//X9/f/4/f7//P7////+//////////7+//v////2+/r/+vz8//z+/v/+/v7///39//z6 + +f///v3/9fz///r////6/P3////+///++v////r////3////9//4////9/38//v//v/9//7////+//r7 + +f/8//3//P/9//39/f/+/v7///////7+/v/9/f3////////////////////////+/////////f////j9 + /P/2/fr/9/77//n//f///v7////+///+/f///fz///76//z9+f/4/Pb/9vr0//Pe1v/hy8D/z7Sq/7uc + k/+tiX//qH10/6V2bv+se3H/roFz/7yRgv/GnpL/2bex/+DHw//r3tz/9O/w//z7/f/+/Pz///v8///+ + ///++fr///7///z+///6////8vn8//7+/v/9/f3//Pz8//39/f/+/v7////////////////////////+ + ///8/Pz/+Pv5//3++v///vv///76///++v/9/PL/9fHm/+fd0//Zxbr/zK2k/72Wjf+xgnr/qnZv/6l+ + b/+keWr/qntt/6t6av+ve2v/tH5t/7V6av+4fW3/rHRv/7F5dP+ydnD/t3xz/693bP+vem3/qXtq/6l+ + a/+qiIL/u5mT/8+vqv/bvrr/8NnX//bn5f/+9vb////+//39/f/8/Pz//Pz8//39/f////////////// + //////////////r////5//7//f/+///++//04d7/0bCt/7SLiP+ufnL/q3tv/6t5bf+teWz/s3xv/7Z9 + bv+1fG3/tXpr/7V3bf+zdmz/tXtv/7B5bP+temr/rX9u/6Z7aP+lemf/rn5m/7F/af+weGX/uX5u/7Z7 + bP+1fnH/r3tv/6x5b/+uf2r/sH5q/7B+bP+uem3/sIB0/6J3bv+8l4//7MvC//v7+//9/f3//v7+//// + ///+/v7///////////////////////r+///x////+fXq///08f////j///r9/+Th3f/mxbz/yKOb/6+A + eP+sdm//s3px/7B4bf+rd2v/rXtv/615bf+4fHD/q3xu/6d9cf+veW7/sndo/7V+b/+4eG3/s39v/6p3 + Z/+pemz/p3pt/6p9cP+teG7/snZw/7d3cv+2d2//snx1/7WPiv/KtK//4tfT///79P///fT/6uHX/76u + nv/GpJ7/17ij/+38/v/1/////////////////////////////P/5+fn/wqWQ/8CThf+8pIz/3MK2//Pf + zf/y8PD//Pz8//3++v/s6eH/1ca9/8Kkmf+1iHv/rndq/62Cbf+qeGT/rn9q/6d2Zv+teGv/sX1t/6h7 + bf+oe27/rnpz/612b/+4fXT/uXxy/612af+ygnD/tI97/8uslf/Xzsv/8uvo////+//79Ov/zLqv/6eE + d/+IVET/iUg5/6NVRP+gRTz/mk43/+XV1v////7//////////////////////////P////v/xZ2B/9ia + gv/Fm3j/w5R+/8WdgP/JloL/0aaT/+LAsP/z3dH///fv/////P/0+fj/4+jp/+S4sf/FmZL/rXly/7d5 + cf+5fXH/uX1x/7J1Z/+0eWn/qHxr/6h/cP+igHP/wKed/9rKxP/88/D///7///36/P/hzsH/qol6/5Nf + T/+PRzX/n0o0/65ZP/+vXT7/nlEx/6JXN/+uWEL/mU8t/9vLxf//+fX///////////////////////f7 + /P////7/vJuB/9GZgP/LoH//zpmF/8yYgf/InH3/yJl9/8yYgf/LmIT/xpiH/8qnmv/hx7v/8d/U//36 + 9f/6//z////7//Dh2P/Hv7L/v6+o/8Cgm//cu7L/4MHE//nk4////Pj////1/9bLvf+1koT/o2ZY/5FC + Nf+dSC7/rFk9/6ZWN/+kWDT/plo2/6laOf+cSiv/r1pA/5tXMv+lWD3/lFQx/8/Kwf/7/ff///////// + //////////////n+///9//7/zK+U/8uXgP/Dm37/ypaJ/8mZh//Fm4T/w5mC/8aagv/Hm4P/yZyB/8uf + gv/MnYH/xpd4/8qYhv/LqZz/5sK6//vez////e//9v////X7///3/P3///Lb/8SokP+mdV//k046/5pK + M/+nVTz/o1Y7/51VN/+gVjr/pFc8/6dZPP+hUTT/plU6/6BPOv+nV0b/nU5B/6hVOf+qTjv/kkkr/+DX + 1P/+//3///////////////////////3//P/8+fT/3baa/9GXgf/Hnn7/w5WD/8GYgf/HmH3/yJuA/8Wd + gf/AmH//vpZ9/8OXgP/KmYP/zZiD/8Sbev+7loL/yJ2K/8qagv/JrJf//PPv///9/v/57+j/lmVP/4ZN + N/+cWUL/oVQ6/6dXOv+kVTT/o1k1/6BbNP+mUjn/plQ7/6BTOP+oXkL/nlQ4/6NUOf+qWD//o001/6RU + O/+uV0f/j0kx//74+f/9/////////////////////////////v////7/6MSs/9GYg//Bmnr/xJV//8ie + gf/HmIL/yZiC/8qZg//Nm4X/zpyF/8uZgv/Jl4D/ypuA/8SegP/EmYj/wI9//8+cfP/Emn3/49DD///9 + 8//HqZj/oUw8/6RQPv+mUkD/plM+/6pXQf+mVDv/qVc+/6BPNP+rVTf/pVM0/6NXOv+eVjj/oFs6/5hU + Mf+iXDf/nFcw/6paPf+mUD7/fzwh///+/v/0/Pv///////////////////////v7///6/v//48q6/8aa + if+9m37/yZeD/8uZe//Cmn7/x5yB/8eaf//FmH3/yZp+/8ucgP/Lm3//zJyA/8uaev/Ll4f/y5qK/8eZ + ev/HoIT/vbCo///+/P+GX1b/o1Ux/6hZOP+kVzf/olQ3/6JSOf+kVD3/o1A7/6pXQv+eVzb/olU6/6ZT + Pf+lTjr/rFM//6pRPf+nUTn/qlQ8/6VXM/+jTTX/j0wt/////P/7+/v///////////////////////79 + //////7/4dvQ/8aZhP/Jmn7/y5qA/8mXgf/EmX7/xpl+/8aZfv/Jmn//yZp//8eaf//Im4D/xpuA/8ic + ff/HlX7/0Zp//8iWgP+/mn7/0rOe////+/+bZln/r1I7/69SO/+tUzr/q1Q6/6lUOv+oVDr/plU6/6RV + Ov+jVDn/olM4/6NUOf+mVzz/plc8/6JTOP+iUzj/pFU6/65ROv+kVz3/pHZe///9/////f////////// + //////////////79/////v//6eXa/8WYg//Km3//zJuB/8yahP/HnIH/yJuA/8ibgP/Km4D/yZp//8ea + f//Hmn//xZp//8qef//LmYL/05yB/8yahP/CnYH/0rOe//38+P+XY1b/qVM7/6lTO/+oVDr/plU6/6ZV + Ov+kVTr/olU6/6JVOv+kVTr/pFU6/6NUOf+jVDn/o1Q5/6NUOf+kVTr/plc8/6xPOP+jVDn/k2dQ///+ + ///++/3///////////////////////38/v///f7/9fHm/8KXhP/Gmn3/yZh+/8uZg//Fmn//x5p//8ea + f//Jmn//ypuA/8ibgP/Im4D/x5yB/8aae//ImID/zJd8/8eWgP/DnID/07Ke//79+f+XZlj/pFQ7/6RU + O/+iVTr/olU6/6JVOv+iVTr/olU6/6JVOv+jVDn/pVY7/6ZXPP+lVjv/pFU6/6RVOv+iUzj/oFE2/7FX + P/+mVzz/qYFu///9/////v/////////////////////////+//////////70/8Waif/Im4D/ypl//8uZ + g//Gm4D/x5p//8eaf//Jmn//yZp//8aZfv/GmX7/xJl+/8qef//Jm4P/zJp+/8mYgv/Dm3//1rOf//z9 + +f+RZFb/olU7/6JVO/+iVTr/olU6/6JVOv+kVTr/pFU6/6RVOv+jVDn/pFU6/6NUOf+iUzj/olM4/6RV + Ov+lVjv/plc8/6ZONv+lVjv/vp2O///+///+/v7///////////////////////79///+/f/////4/8ae + jP/EmX7/yJl+/8mXgP/Fmn//x5p//8eaf//Jmn//yJl+/8aZfv/GmX7/xJl+/8ebfP/GmID/y5t//8yb + hf/Fmn//2rWh//3++v+TaFn/pFQ7/6RUO/+kVTr/plU6/6ZVOv+oVDr/qFQ6/6hUOv+kVTr/o1Q5/6JT + OP+jVDn/o1Q5/6RVOv+lVjv/plc8/6pUPP+jVTj/rpSI///7//////7////////////////////////+ + /////v/////7/9Kpmv/Em4L/y5yB/82bhP/EmX7/xpl+/8eaf//Jmn//yZp//8ibgP/Im4D/xpuA/8ic + ff/EmID/ypt//8qZg//DmH3/2rKf//v8+P+ddmf/qFQ7/6hUO/+oVDr/qFQ6/6hUOv+pVDr/qVQ6/6lU + Ov+nVjv/plU6/6ZVOv+oVzz/p1Y7/6VUOf+jUjf/o1I3/6hUO/+lVzr/yLWu///9///9//z///////// + //////////////3////7/f7//f/5/922qP/CmYD/yJl+/8yag//Gm4D/yJuA/8ibgP/Jmn//yZp//8ea + f//GmX7/xJl+/8ebfP/EmID/x5t+/8aXgf/Im4D/3rSh/////P+7l4f/qFQ7/6hUO/+oVDr/qFQ6/6hU + Ov+oVDr/plU6/6ZVOv+mVTr/plU6/6VUOf+kUzj/pVQ5/6ZVOv+nVjv/p1Y7/6VTOv+dTTD/283H///5 + ///8//r///////////////////////3////8/f/////7/+nCtP/DmoH/x5h9/8yag//DmH3/xpl+/8aZ + fv/ImX7/yJl+/8eaf//Hmn//xZp//8ebfP/FmYH/x5t+/8aXgf/KnYL/3LKf//z9+f/HpZX/plQ7/6ZU + O/+mVTr/plU6/6RVOv+kVTr/pFU6/6RVOv+kUzj/plU6/6dWO/+lVDn/plU6/6hXPP+nVjv/o1I3/6RU + O/+aSi3/0cbC///8///6/vj///////////////////////3+///2/P/////8/+DMuv/JnoP/ypl//8Sa + g//Jmn//yZp//8maf//Hmn//x5p//8eaf//Hmn//x5p//8abgP/Jmn//y5mD/8Saff/Km4X/zp+J///+ + //+/no//oFM5/6NTOv+mVTr/p1Y7/6lVO/+mVTr/plU6/6RVOv+pVTv/p1Y7/6VTOv+kVDv/pVU8/6RT + OP+iUTb/plM3/6dXOP+OQTH/6/Pp//r9/////P/////////////////////////+///7/v///P/7/+nX + xv/KnIT/zph//8KZgP/Jmn//yZp//8maf//Hmn//x5p//8eaf//Hmn//x5p//8Waf//ImX7/ypiB/8OZ + fP/HmIL/y5yG///8/f++nY7/oVQ6/6RUO/+mVTr/plU6/6hUOv+mVTr/plU6/6RVOv+nUzn/plU6/6ZU + O/+kVDv/pFQ7/6VUOf+mVjn/q1g8/6dVNv+DOCj/9//1//v+/////f/////////////////////////9 + /////v//9/75//bn1//JmIL/0pmA/8GYf//Jmn//yZp//8maf//Hmn//x5p//8eaf//Hmn//x5p//8Wa + f//ImX7/ypiB/8Saff/Gl4H/x5iC///7/P++nY3/olU7/6RUO/+mVTr/plU6/6hUOv+mVTr/plU6/6RV + Ov+oVDr/plU6/6dVPP+kVDv/olI5/6VUOf+mVjn/qFU5/6NPM/+JQDL//f/5//r7/////P7///////// + ///////////////7/v///f//9f77///36f/IloT/1pqE/8Obf//Jmn//yZp//8maf//Hmn//x5p//8ea + f//Hmn//x5p//8abgP/Jmn//ypiB/8acf//Gl4H/xpeB///8/f/An4//olU7/6RUO/+mVTr/plU6/6hU + Ov+mVTr/plU6/6RVOv+qVjz/plU6/6ZVOv+kVDv/o1M6/6ZVOv+mVjn/o1A0/69bQv+rZ1r////7///+ + /////f/////////////////////////9/////f//9v/+////9P/ElYf/05qF/8ScgP/Jmn//yZp//8ma + f//Hmn//x5p//8eaf//Hmn//x5p//8Waf//ImX7/ypiB/8edgP/HmYH/x5mB///+///BoJD/oVQ6/6NT + Ov+mVTr/p1Y7/6hUOv+mVTr/plU6/6RVOv+pVjr/plU6/6ZVOv+lVTz/pFU6/6lYPf+oWDv/plQ1/6RT + Pv+lamD/+fr2///+///+/f/////////////////////////+/////v//+P/+///99f/Fn5P/yJaA/8Ka + ff/Jmn//yZp//8maf//Hmn//x5p//8eaf//Hmn//x5p//8Saff/ImX3/yZeA/8adff/HmYH/x5mB//// + /v++nY3/oFM5/6NTOv+mVTr/p1Y7/6lVO/+mVTr/plU6/6RVOv+oVTn/plU6/6dWO/+kVTr/o1Q5/6ZV + Ov+oWDv/qlg5/55SP/+hcGb/+f34//3+///5/v3/////////////////////////////////9//9///8 + 9//Wuq//wZiC/8CafP/Jmn//yZp//8maf//Hmn//x5p//8eaf//Hmn//x5p//8Wbfv/ImX3/yZeA/8ad + ff/HmYH/x5mB///+/f+5mIj/oVQ6/6RUO/+mVTr/p1Y7/6hUOv+mVTr/plU6/6RVOv+oVTn/p1c6/6ZV + Ov+jVDn/o1Q5/6RUN/+lVTj/qVc4/5ZQP//Cm5L/+v/9//v+///4/v3////////////////////////+ + /v/7////+v//////+//t18z/w56I/8Odf//Jmn//yZp//8maf//Hmn//x5p//8eaf//Hmn//x5p//8ac + f//Km3//yZeA/8adff/HmYH/x5mB///+/f+2lYX/olU7/6RUO/+mVTr/plU6/6hUOv+mVTr/plU6/6RV + Ov+oVTn/p1c6/6ZVOv+lVjv/p1g9/6dXOv+lVTb/qVc4/41LOf/x0cb/+v/+//f8///4//////////// + ///////////////+/f///f///v3///f7/P///vn/2L6y/7+ShP/BmnT/yp18/86bgf/Ml4P/ypeD/8iZ + g//InH//x5t8/8Wfgf/DmXz/ypiB/8icf//ImID/yZuD//z6+f+ulYH/n1Q+/6BUPf+iUzj/qlo9/6JU + N/+lVjv/plM9/6hSPv+gVjr/o1Q5/6xVO/+rUTj/p1I4/6ZXPP+kUzj/rFU7/39yYv///fP////8//v+ + ///6/v////////////////////////78/P///P7//P7///T8+//9//v/+Ozi/+fNwf/BmoT/xpyF/8WX + f//Flnv/ypt//8WZfP/Dlnv/y56D/8KYe//KnoH/y5mC/8WcfP/GmID/ypyE/////v+tj3z/pU85/6tV + Pf+pVDr/pFA2/6VUOf+pWD3/qFM5/6xUPP+sUjr/p1M5/59WOP+hWDj/qFU5/6pVP/+PSzj/ilxK//vy + 6P////n//vz7//3////7/v///////////////////////////////v///f////D7+P/z//n//f/7///6 + 9f/y4Nn/yKid/8CRfP/OnID/yZ98/8Ode//HnIH/xZN9/8maf//ImX7/yJZ//8WcfP/EmID/x5mB///9 + /P+ykYH/qVU7/6VROP+nUzr/qlY9/6tXPf+mVTr/plY5/6ZZOf+pVD7/q1c9/6JVNf+kVzf/o1Y8/5BN + Pv/Eo5r//f71/////P/7+fj//v7+///////8/v///////////////////////////////f7/+/z6//r/ + /v/y/fv/+P////j8/f////////Pv/+fHuv/HnYb/xJV5/8aae//Gmn3/yp2C/8ybgf/JmH7/zpyF/8ad + ff/EmID/yZ2F///6+/+0kYP/n1c5/59VOf+hVDr/pFE7/6pWPf+mUjj/pVo6/5tVMP+kUDb/nlU5/6BV + O/+cTTr/nWZX//Lm2v/3/vn//fz+//n8///7/f7///////39/f////7///////////////////////// + //////7//fv6/////v/8/v7//f////79///8/v7//f/+////+f/y4NX/zKqa/8WWgf/MnYL/xZl8/8qY + gf/GlH3/x5V+/8WcfP/EmID/xZmC//77/f+3lYj/n08w/6RYO/+gVjz/oFQ9/6lWQP+iTTP/qlY6/6hZ + OP+kWDv/qFU//45QQP+2opf/+/33/////v/++fr/+f7///n9///y9fn//f///////v////7///////// + //////////////n7+//////////+///8/f///f7///7////9///4/fv//f////7+/v////7/+/jw/9rK + vf/CnYn/ypF7/8iZg//NnYX/ypZ//8ufgP/ImoL/wZV+//38/v+ojIH/t1Y8/6tUOf+fVTn/nVY7/6VV + PP+sVDz/sVc//6dPN/+eUj//jGFQ//Pp3//5+vj///7///n4/P/9////+v37//r9///9/////f39//7+ + /v/7+fj///////////////////////v7+//9///////////+/v////////////37+v/6//////7////9 + ///4/P3/8f/7//n/9//x39T/1Kqd/8CXgf/ImYP/zZmC/8iae//Gln7/yJyF//v+//+okob/slM5/6dT + N/+kWDv/nlQ4/6VTOv+nVkH/kks3/5BRPf++n5b////4//v//v/5+/z///f+///8////////9/77///9 + /P////7/+Pj4/////////////////////////////////////v/8/v7/+/////3/////////+//6//3/ + /P///P7//P7///j////6/////P37/////P////r/9Pfu/+zHsf/InIX/zpmE/82ef//KmIH/xZmC//f8 + ///OvLH/n1U5/6BXOf+kWDv/plM3/6lVPP+VTzj/lGdS//vjz//1/f3/+/3+///8/v/9////+v////v9 + /v///v////z+////+//9+vb////+//z+///6/P3///////////////////////////////////////// + //////////////////////////////7+/v/+/v7//v7+//39/f/9/f3//f39//b9+P/x6N7/waWU/8KW + fv/EoYf/0JWF////8v/hycP/rE86/7RXQP+nUjj/oVc//4NLOP+9nJP///r8//r8///9/f3//f39//39 + /f/9/f3//v7+//7+/v/+/v7//v7+//////////////////////////////////////////////////// + //////////////////////////////////////////////7+/v/+/v7//v7+//39/f/9/f3//f39///9 + /v////r///3w/97GtP+2mIf/zZKJ//v/9P/OyMP/tFQ9/6ROOv+LSTb/ondo///x5v////n/+f/9//T/ + ///9/f3//f39//39/f/9/f3//f39//7+/v/+/v7//v7+//////////////////////////////////// + //////////////////////////////////////////////////////////////7+/v/+/v7//v7+//7+ + /v/+/v7//f39///8///6//7/9v/6///+9//t39n/3rKz//r//P/e4+L/gUs0/3BFMv/dw7f///v3//v/ + ///3/fz/9/z6//b69P/9/f3//f39//39/f/9/f3//f39//7+/v/+/v7//v7+//////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///+/v7//v7+//7+/v/+/v7//v7+///8/v/5/f7/+v7///7+/v/4//////f5//H8+v///f3////u//// + 9P/3+fP/+/////n8///8+/////3+///++//9/f3//f39//7+/v/+/v7//v7+//7+/v/+/v7//v7+//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + + + \ No newline at end of file diff --git a/Samples/Capture/DxTuner/readme.txt b/Samples/Capture/DxTuner/readme.txt new file mode 100644 index 0000000..d2cedd7 --- /dev/null +++ b/Samples/Capture/DxTuner/readme.txt @@ -0,0 +1,27 @@ +--------------------------------------------------------------------- +DxTuner + +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + +--------------------------------------------------------------------- + +This sample application shows how to change channels on a tv tuner. + +There are several things you should know: + +- The audio pins are not connected in this application. +- The tuner button is greyed out until the graph is constructed. Because +of the way the UI is structured, that means the graph must be running +to change the channel. +- If your video is blank, try playing with the crossbar. Make sure the "Video +Decoder Out" is connected to something that has a signal (Tuner in, Composite In, +etc). +- If your video is jerky, this is probably due to the fact that this program is +saving the video to disk. If you are not using compression, you are writing huge +amounts of data. As a for-instance 640 x 480 x 16bpp x 30fps = ~20meg per sec. If +you are using compression, your compressor may be too slow for use with live capture. +As a test, try using Intel Indeo for compressing. Make sure you click the "Quick +Compress" on the compressor's property page. diff --git a/Samples/Capture/PlayCap/AssemblyInfo.cs b/Samples/Capture/PlayCap/AssemblyInfo.cs new file mode 100644 index 0000000..76201ae --- /dev/null +++ b/Samples/Capture/PlayCap/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// Les informations générales relatives à un assembly dépendent de +// l'ensemble d'attributs suivant. Pour modifier les informations +// associées à un assembly, changez les valeurs de ces attributs. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Les informations de version pour un assembly se composent des quatre valeurs suivantes : +// +// Version principale +// Version secondaire +// Numéro de build +// Révision +// +// Vous pouvez spécifier toutes les valeurs ou indiquer des numéros de révision et de build par défaut +// en utilisant '*', comme ci-dessous : + +[assembly: AssemblyVersion("1.0.*")] + +// +// Pour signer votre assembly, vous devez spécifier la clé à utiliser. Consultez +// la documentation Microsoft .NET Framework pour plus d'informations sur la signature d'un assembly. +// +// Utilisez les attributs ci-dessous pour contrôler la clé utilisée lors de la signature. +// +// Remarques : +// (*) Si aucune clé n'est spécifiée, l'assembly n'est pas signé. +// (*) KeyName fait référence à une clé installée dans le fournisseur de +// services cryptographiques (CSP) de votre ordinateur. KeyFile fait référence à un fichier qui contient +// une clé. +// (*) Si les valeurs de KeyFile et de KeyName sont spécifiées, le +// traitement suivant se produit : +// (1) Si KeyName se trouve dans le CSP, la clé est utilisée. +// (2) Si KeyName n'existe pas mais que KeyFile existe, la clé +// de KeyFile est installée dans le CSP et utilisée. +// (*) Pour créer KeyFile, vous pouvez utiliser l'utilitaire sn.exe (Strong Name, Nom fort). +// Lors de la spécification de KeyFile, son emplacement doit être +// relatif au répertoire de sortie du projet qui est +// %Project Directory%\obj\. Par exemple, si votre KeyFile se trouve +// dans le répertoire du projet, vous devez spécifier l'attribut +// AssemblyKeyFile sous la forme [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) DelaySign (signature différée) est une option avancée. Pour plus d'informations, consultez la +// documentation Microsoft .NET Framework. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/Capture/PlayCap/Form1.cs b/Samples/Capture/PlayCap/Form1.cs new file mode 100644 index 0000000..1c193f1 --- /dev/null +++ b/Samples/Capture/PlayCap/Form1.cs @@ -0,0 +1,397 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ +//------------------------------------------------------------------------------ +// Desc: DirectShow sample code - a very basic application using video capture +// devices. It creates a window and uses the first available capture +// device to render and preview video capture data. +// +// DirectShow Interfaces used : ICaptureGraphBuilder2, IGraphBuilder, +// IMediaEventEx, IMediaControl, IVideoWindow, IBaseFilter +// +// DirectShowLib helper classes used : DsError, DsROTEntry, DsDevice +// +//------------------------------------------------------------------------------ + + +using System; +using System.Diagnostics; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +using DirectShowLib; + +#if !USING_NET11 +using System.Runtime.InteropServices.ComTypes; +#endif + +namespace DirectShowLib.Samples +{ + public class Form1 : System.Windows.Forms.Form + { + // a small enum to record the graph state + enum PlayState + { + Stopped, + Paused, + Running, + Init + }; + + // Application-defined message to notify app of filtergraph events + public const int WM_GRAPHNOTIFY = 0x8000 + 1; + + IVideoWindow videoWindow = null; + IMediaControl mediaControl = null; + IMediaEventEx mediaEventEx = null; + IGraphBuilder graphBuilder = null; + ICaptureGraphBuilder2 captureGraphBuilder = null; + PlayState currentState = PlayState.Stopped; + + DsROTEntry rot = null; + + public Form1() + { + InitializeComponent(); + CaptureVideo(); + } + + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + // Stop capturing and release interfaces + CloseInterfaces(); + } + + base.Dispose( disposing ); + } + + #region Code généré par le Concepteur Windows Form + /// + /// Méthode requise pour la prise en charge du concepteur - ne modifiez pas + /// le contenu de cette méthode avec l'éditeur de code. + /// + private void InitializeComponent() + { + System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form1)); + // + // Form1 + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(320, 320); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "Form1"; + this.Text = "Video Capture Previewer (PlayCap)"; + this.Resize += new System.EventHandler(this.Form1_Resize); + + } + #endregion + + + public void CaptureVideo() + { + int hr = 0; + IBaseFilter sourceFilter = null; + + try + { + // Get DirectShow interfaces + GetInterfaces(); + + // Attach the filter graph to the capture graph + hr = this.captureGraphBuilder.SetFiltergraph(this.graphBuilder); + DsError.ThrowExceptionForHR(hr); + + // Use the system device enumerator and class enumerator to find + // a video capture/preview device, such as a desktop USB video camera. + sourceFilter = FindCaptureDevice(); + + // Add Capture filter to our graph. + hr = this.graphBuilder.AddFilter(sourceFilter, "Video Capture"); + DsError.ThrowExceptionForHR(hr); + + // Render the preview pin on the video capture filter + // Use this instead of this.graphBuilder.RenderFile + hr = this.captureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, sourceFilter, null, null); + DsError.ThrowExceptionForHR(hr); + + // Now that the filter has been added to the graph and we have + // rendered its stream, we can release this reference to the filter. + Marshal.ReleaseComObject(sourceFilter); + + // Set video window style and position + SetupVideoWindow(); + + // Add our graph to the running object table, which will allow + // the GraphEdit application to "spy" on our graph + rot = new DsROTEntry(this.graphBuilder); + + // Start previewing video data + hr = this.mediaControl.Run(); + DsError.ThrowExceptionForHR(hr); + + // Remember current state + this.currentState = PlayState.Running; + } + catch + { + MessageBox.Show("An unrecoverable error has occurred."); + } + } + + // This version of FindCaptureDevice is provide for education only. + // A second version using the DsDevice helper class is define later. + public IBaseFilter FindCaptureDevice() + { + int hr = 0; +#if USING_NET11 + UCOMIEnumMoniker classEnum = null; + UCOMIMoniker[] moniker = new UCOMIMoniker[1]; +#else + IEnumMoniker classEnum = null; + IMoniker[] moniker = new IMoniker[1]; +#endif + object source = null; + + // Create the system device enumerator + ICreateDevEnum devEnum = (ICreateDevEnum) new CreateDevEnum(); + + // Create an enumerator for the video capture devices + hr = devEnum.CreateClassEnumerator(FilterCategory.VideoInputDevice, out classEnum, 0); + DsError.ThrowExceptionForHR(hr); + + // The device enumerator is no more needed + Marshal.ReleaseComObject(devEnum); + + // If there are no enumerators for the requested type, then + // CreateClassEnumerator will succeed, but classEnum will be NULL. + if (classEnum == null) + { + throw new ApplicationException("No video capture device was detected.\r\n\r\n" + + "This sample requires a video capture device, such as a USB WebCam,\r\n" + + "to be installed and working properly. The sample will now close."); + } + + // Use the first video capture device on the device list. + // Note that if the Next() call succeeds but there are no monikers, + // it will return 1 (S_FALSE) (which is not a failure). Therefore, we + // check that the return code is 0 (S_OK). +#if USING_NET11 + int i; + if (classEnum.Next (moniker.Length, moniker, IntPtr.Zero) == 0) +#else + if (classEnum.Next (moniker.Length, moniker, IntPtr.Zero) == 0) +#endif + { + // Bind Moniker to a filter object + Guid iid = typeof(IBaseFilter).GUID; + moniker[0].BindToObject(null, null, ref iid, out source); + } + else + { + throw new ApplicationException("Unable to access video capture device!"); + } + + // Release COM objects + Marshal.ReleaseComObject(moniker[0]); + Marshal.ReleaseComObject(classEnum); + + // An exception is thrown if cast fail + return (IBaseFilter) source; + } +/* + // Uncomment this version of FindCaptureDevice to use the DsDevice helper class + // (and comment the first version of course) + public IBaseFilter FindCaptureDevice() + { + System.Collections.ArrayList devices; + object source; + + // Get all video input devices + devices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice); + + // Take the first device + DsDevice device = (DsDevice)devices[0]; + + // Bind Moniker to a filter object + Guid iid = typeof(IBaseFilter).GUID; + device.Mon.BindToObject(null, null, ref iid, out source); + + // An exception is thrown if cast fail + return (IBaseFilter) source; + } +*/ + public void GetInterfaces() + { + int hr = 0; + + // An exception is thrown if cast fail + this.graphBuilder = (IGraphBuilder) new FilterGraph(); + this.captureGraphBuilder = (ICaptureGraphBuilder2) new CaptureGraphBuilder2(); + this.mediaControl = (IMediaControl) this.graphBuilder; + this.videoWindow = (IVideoWindow) this.graphBuilder; + this.mediaEventEx = (IMediaEventEx) this.graphBuilder; + + hr = this.mediaEventEx.SetNotifyWindow(this.Handle, WM_GRAPHNOTIFY, IntPtr.Zero); + DsError.ThrowExceptionForHR(hr); + } + + public void CloseInterfaces() + { + // Stop previewing data + if (this.mediaControl != null) + this.mediaControl.StopWhenReady(); + + this.currentState = PlayState.Stopped; + + // Stop receiving events + if (this.mediaEventEx != null) + this.mediaEventEx.SetNotifyWindow(IntPtr.Zero, WM_GRAPHNOTIFY, IntPtr.Zero); + + // Relinquish ownership (IMPORTANT!) of the video window. + // Failing to call put_Owner can lead to assert failures within + // the video renderer, as it still assumes that it has a valid + // parent window. + if(this.videoWindow != null) + { + this.videoWindow.put_Visible(OABool.False); + this.videoWindow.put_Owner(IntPtr.Zero); + } + + // Remove filter graph from the running object table + if (rot != null) + { + rot.Dispose(); + rot = null; + } + + // Release DirectShow interfaces + Marshal.ReleaseComObject(this.mediaControl); this.mediaControl = null; + Marshal.ReleaseComObject(this.mediaEventEx); this.mediaEventEx = null; + Marshal.ReleaseComObject(this.videoWindow); this.videoWindow = null; + Marshal.ReleaseComObject(this.graphBuilder); this.graphBuilder = null; + Marshal.ReleaseComObject(this.captureGraphBuilder); this.captureGraphBuilder = null; + } + + public void SetupVideoWindow() + { + int hr = 0; + + // Set the video window to be a child of the main window + hr = this.videoWindow.put_Owner(this.Handle); + DsError.ThrowExceptionForHR(hr); + + hr = this.videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren); + DsError.ThrowExceptionForHR(hr); + + // Use helper function to position video window in client rect + // of main application window + ResizeVideoWindow(); + + // Make the video window visible, now that it is properly positioned + hr = this.videoWindow.put_Visible(OABool.True); + DsError.ThrowExceptionForHR(hr); + } + + public void ResizeVideoWindow() + { + // Resize the video preview window to match owner window size + if (this.videoWindow != null) + { + this.videoWindow.SetWindowPosition(0, 0, this.ClientSize.Width, this.ClientSize.Height); + } + } + + public void ChangePreviewState(bool showVideo) + { + int hr = 0; + + // If the media control interface isn't ready, don't call it + if (this.mediaControl == null) + return; + + if (showVideo) + { + if (this.currentState != PlayState.Running) + { + // Start previewing video data + hr = this.mediaControl.Run(); + this.currentState = PlayState.Running; + } + } + else + { + // Stop previewing video data + hr = this.mediaControl.StopWhenReady(); + this.currentState = PlayState.Stopped; + } + } + + public void HandleGraphEvent() + { + int hr = 0; + EventCode evCode; + IntPtr evParam1, evParam2; + + if (this.mediaEventEx == null) + return; + + while(this.mediaEventEx.GetEvent(out evCode, out evParam1, out evParam2, 0) == 0) + { + // Free event parameters to prevent memory leaks associated with + // event parameter data. While this application is not interested + // in the received events, applications should always process them. + hr = this.mediaEventEx.FreeEventParams(evCode, evParam1, evParam2); + DsError.ThrowExceptionForHR(hr); + + // Insert event processing code here, if desired + } + } + + protected override void WndProc(ref Message m) + { + switch (m.Msg) + { + case WM_GRAPHNOTIFY: + { + HandleGraphEvent(); + break; + } + } + + // Pass this message to the video window for notification of system changes + if (this.videoWindow != null) + this.videoWindow.NotifyOwnerMessage(m.HWnd, m.Msg, m.WParam, m.LParam); + + base.WndProc (ref m); + } + + private void Form1_Resize(object sender, System.EventArgs e) + { + // Stop graph when Form is iconic + if (this.WindowState == FormWindowState.Minimized) + ChangePreviewState(false); + + // Restart Graph when window come back to normal state + if (this.WindowState == FormWindowState.Normal) + ChangePreviewState(true); + + ResizeVideoWindow(); + } + + /// + /// Point d'entrée principal de l'application. + /// + [STAThread] + static void Main() + { + Application.Run(new Form1()); + } + + } +} diff --git a/Samples/Capture/PlayCap/Form1.resx b/Samples/Capture/PlayCap/Form1.resx new file mode 100644 index 0000000..7c363d9 --- /dev/null +++ b/Samples/Capture/PlayCap/Form1.resx @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + (Default) + + + False + + + False + + + 8, 8 + + + True + + + 80 + + + Form1 + + + True + + + Private + + + + AAABAAIAICAQAAAAAADoAgAAJgAAABAQEAAAAAAAKAEAAA4DAAAoAAAAIAAAAEAAAAABAAQAAAAAAAAC + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAICAgADAwMAAAAD/AAD/ + AAAA//8A/wAAAP8A/wD//wAA////AP////////////////////+IiIiIiIiIiIiIiIiIiIiI8A////// + 8A///////////wdwiIiIiAdwiIiIiIiIiIgPhwf//3B3cP//////////gPhwAAAHdw8AAACIiIiIiP8P + h3d3d3Dwd3d3D/////+AAAAAAAAAD4iIhwiIiIiIB3d3d3d3dw////cP///wAA+IiIiIiIhwAAAAiIiI + B3APiZqsyId3d3dw//AAAHdwD4marMiPiIiHgAAHd3B4gA+IiIiIj4iIh4B3B3dwiIAPh3iHeI+IiIeA + dwiIgIiAD494j3iP///3gIgIiICIgA+IiIiIiIh3iID/CIiAiIAPiIiIiIiAB3iA/w//8IiAD4d4h3iI + gHB3cAAP//D4gA+PeI94iIB3AAAP8AAA//APiIiIiIiAh3d3cIiIiA/wD///////8IiIiHD////wAHAA + AAAAAAD4iIhwiIiIiIjw9w/////w/wAAD///////iA9wAAAIgPCIiIiIiIiIiP/w+IiIgPAP//////// + ///3/wAAAAf393/3f3f/f/f/9//39/f/9/f3/39/f3/3//f/9/f3//f39/f/f39/9//39/f3/3f3f3f3 + f/d3d3d/9393/////////////3/3//f/9/f////////////39///////////////////////AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAoAAAAEAAAACAAAAABAAQAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAA + AACAAIAAgIAAAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAACIiIiIiA + AAAPmXqnzHAAAA+ZeqfMcAAAD3d3d3dwAIAPd3d3d3CAcA+IeIeIcHBwD/h/h/hw8HAPd3d3d3AA8A93 + d3d3cAAADwAHd3dwAAAPCIAA//AAAAAHd3cAAAAAAAd//wAAAAAAD/AAAAAAAAAAAAAAAAAAgB8AAAAP + AAAADwAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAPAAAADwAAgB8AAMB/AADA/wAAx/8AAA== + + + \ No newline at end of file diff --git a/Samples/Capture/PlayCap/PlayCap-2005.csproj b/Samples/Capture/PlayCap/PlayCap-2005.csproj new file mode 100644 index 0000000..4560821 --- /dev/null +++ b/Samples/Capture/PlayCap/PlayCap-2005.csproj @@ -0,0 +1,109 @@ + + + Local + 8.0.50727 + 2.0 + {156F9A0F-C89B-42D5-9636-0047FE0923CE} + Debug + AnyCPU + playcap.ico + + + PlayCap + + + JScript + Grid + IE50 + false + WinExe + PlayCap + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + Code + + + Form + + + Form1.cs + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Capture/PlayCap/PlayCap-2005.sln b/Samples/Capture/PlayCap/PlayCap-2005.sln new file mode 100644 index 0000000..6ae9454 --- /dev/null +++ b/Samples/Capture/PlayCap/PlayCap-2005.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlayCap-2005", "PlayCap-2005.csproj", "{156F9A0F-C89B-42D5-9636-0047FE0923CE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {156F9A0F-C89B-42D5-9636-0047FE0923CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {156F9A0F-C89B-42D5-9636-0047FE0923CE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {156F9A0F-C89B-42D5-9636-0047FE0923CE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {156F9A0F-C89B-42D5-9636-0047FE0923CE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Capture/PlayCap/PlayCap-2008.sln b/Samples/Capture/PlayCap/PlayCap-2008.sln new file mode 100644 index 0000000..61467c5 --- /dev/null +++ b/Samples/Capture/PlayCap/PlayCap-2008.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlayCap-2008", "PlayCap-2008.csproj", "{156F9A0F-C89B-42D5-9636-0047FE0923CE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {156F9A0F-C89B-42D5-9636-0047FE0923CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {156F9A0F-C89B-42D5-9636-0047FE0923CE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {156F9A0F-C89B-42D5-9636-0047FE0923CE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {156F9A0F-C89B-42D5-9636-0047FE0923CE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Capture/PlayCap/PlayCap.csproj b/Samples/Capture/PlayCap/PlayCap.csproj new file mode 100644 index 0000000..879328e --- /dev/null +++ b/Samples/Capture/PlayCap/PlayCap.csproj @@ -0,0 +1,141 @@ + + + + Local + 8.0.50727 + 2.0 + {156F9A0F-C89B-42D5-9636-0047FE0923CE} + Debug + AnyCPU + playcap.ico + + + PlayCap + + + JScript + Grid + IE50 + false + WinExe + PlayCap + OnBuildSuccess + + + + + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + Code + + + Form + + + Form1.cs + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Capture/PlayCap/playcap.ico b/Samples/Capture/PlayCap/playcap.ico new file mode 100644 index 0000000000000000000000000000000000000000..623f9cf174857555aca7d26406a61b5d37dbecd9 GIT binary patch literal 1078 zcmc(eF;?U-42CtZ??HF?wq$x)WuZP%LQmS#B@;XLAG?~bmo(sVSuII zKas58l59s-M0Ro^hr?bBe=kIC829_mZ+9Zsmm;^!9gsU@CqK}D*zchtyrS9%G$x{Q zJRWg0f2B3E5FVQ{{ss99O0a;g%^IQwbZu5xhSp+=<}>ITMTQjE#@xAuC8ZP#%2!ex zAmqG^<{xl$U&UX{VPFxwWcH^Jp0Aw93K6!#6l^O&5j!|o;T~D+vs$6r z{`oBjB1W|Y2YckK=lWK=prO{e&Z*6{@zgFe_`qxH+}w#^GN_}c**!S6_!DKRck^WU zY5$|LKHnn;%u4+ zeAF27wB#6LSm$MpCH8qK+bDtdBVNL&bOlR8eS=}P6X3APGxR66{S_ux=lM^T&2KRl Lf1D9kdqLg+^xls1 literal 0 HcmV?d00001 diff --git a/Samples/Capture/PlayCap/readme.txt b/Samples/Capture/PlayCap/readme.txt new file mode 100644 index 0000000..ed5df76 --- /dev/null +++ b/Samples/Capture/PlayCap/readme.txt @@ -0,0 +1,18 @@ +--------------------------------------------------------------------- +PlayCap + +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + +--------------------------------------------------------------------- + +A translation of the DirectShow PlayCap program to show how this would +appear in c#. + +This application creates a preview window for the first video capture device +that it locates on the user's system (if any). It demonstrates a simple +example of using the ICaptureGraphBuilder2 and ICreateDevEnum interfaces +to build a capture graph. + diff --git a/Samples/DMO/DmoFlip/DMO/AssemblyInfo.cs b/Samples/DMO/DmoFlip/DMO/AssemblyInfo.cs new file mode 100644 index 0000000..383abe3 --- /dev/null +++ b/Samples/DMO/DmoFlip/DMO/AssemblyInfo.cs @@ -0,0 +1,21 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("DmoFlip")] +[assembly: AssemblyDescription("A DMO sample to flip video")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("http://DirectShowNet.SourceForge.net")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("Public Domain")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: AssemblyVersion("1.0.0.0")] + +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyName("")] diff --git a/Samples/DMO/DmoFlip/DMO/DmoFlip-2005.csproj b/Samples/DMO/DmoFlip/DMO/DmoFlip-2005.csproj new file mode 100644 index 0000000..8e3a5f1 --- /dev/null +++ b/Samples/DMO/DmoFlip/DMO/DmoFlip-2005.csproj @@ -0,0 +1,108 @@ + + + Local + 8.0.50727 + 2.0 + {369D647A-7F80-4F06-BEDB-D62AC1627862} + Debug + AnyCPU + + + + + DmoFlip + mykey.snk + JScript + Grid + IE50 + false + Library + DmoFlip + OnBuildSuccess + + + + + + + true + + + bin\Debug\ + false + 285212672 + false + + + DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 1 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + USING_NET20 + docs\Dmo.xml + false + 4096 + false + + + false + false + false + false + 1 + none + prompt + + + + False + ..\..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Drawing + + + + + Code + + + Code + + + Code + + + + + + + + + + + "%25windir%25\Microsoft.NET\Framework\v2.0.50727\regasm" /nologo /codebase $(TargetPath) + + \ No newline at end of file diff --git a/Samples/DMO/DmoFlip/DMO/DmoFlip.cs b/Samples/DMO/DmoFlip/DMO/DmoFlip.cs new file mode 100644 index 0000000..c611466 --- /dev/null +++ b/Samples/DMO/DmoFlip/DMO/DmoFlip.cs @@ -0,0 +1,643 @@ +#region license + +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +#endregion + +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; +using MediaObjectTemplate; +using DirectShowLib; +using DirectShowLib.DMO; + +namespace DmoFlip +{ + /// + [ComVisible(true), Guid("7EF28FD7-E88F-45bb-9CDD-8A62956F2D75"), + ClassInterface(ClassInterfaceType.None)] + public class DmoFlip : IMediaObjectImpl + { + #region Declarations + + protected const long MAX_TIME = long.MaxValue; + + // Properties used to register the DMO in the registry + private const string DMOName = "DmoFlip"; + private static readonly Guid DMOCat = DMOCategory.VideoEffect; + private const int InputPinCount = 1; + private const int OutputPinCount = 1; + + // Parameter info + private const int NumParams = 1; + private const FlipMode DEFAULTMODE = FlipMode.FlipY; + + [Flags] + private enum FlipMode + { + None = 0, + FlipY = 1, + FlipX = 2, + LAST = 3 + } + + #endregion + + #region APIs + + [DllImport("Kernel32.dll", EntryPoint="RtlMoveMemory")] + public static extern void CopyMemory(IntPtr Destination, IntPtr Source, [MarshalAs(UnmanagedType.U4)] int Length); + + #endregion + + #region Member Vars + + // Stream info (set once per run) + private int m_Width, m_Height, m_Stride, m_BPP; + + // Currently processing buffer info (set once per buffer) + private long m_TimeStamp; + private long m_TimeLength; + private IMediaBuffer m_pBuffer; + private IntPtr m_InBuffer; + private int m_cbInData; + private DMOOutputDataBufferFlags m_Flags; + + #endregion + + #region Utility Functions + + /// + /// Register the DMO in the registry. Called by regasm. + /// + /// + [ComRegisterFunctionAttribute] + static private void DoRegister(Type t) + { + // Tell what media types you are able to support. This allows + // the smart connect capability of DS to avoid loading your DMO + // if it can't handle the stream type. + + // Note that you don't have to register any (but I recommend + // you do). Also, you don't have to provide a subtype (use + // Guid.Empty). You can negotiate this at run time in + // InternalCheckInputType. + DMOPartialMediatype [] pIn = new DMOPartialMediatype[2]; + pIn[0] = new DMOPartialMediatype(); + pIn[0].type = MediaType.Video; + pIn[0].subtype = MediaSubType.RGB24; + + pIn[1] = new DMOPartialMediatype(); + pIn[1].type = MediaType.Video; + pIn[1].subtype = MediaSubType.RGB32; + + DMOPartialMediatype [] pOut = new DMOPartialMediatype[2]; + pOut[0] = new DMOPartialMediatype(); + pOut[0].type = MediaType.Video; + pOut[0].subtype = MediaSubType.RGB24; + + pOut[1] = new DMOPartialMediatype(); + pOut[1].type = MediaType.Video; + pOut[1].subtype = MediaSubType.RGB32; + + int hr = DMOUtils.DMORegister( + DMOName, + typeof(DmoFlip).GUID, + DMOCat, + DMORegisterFlags.None, + pIn.Length, + pIn, + pOut.Length, + pOut + ); + } + + + /// + /// Remove the DMO from the registry + /// + /// + [ComUnregisterFunctionAttribute] + static private void UnregisterFunction(Type t) + { + int hr = DMOUtils.DMOUnregister(typeof(DmoFlip).GUID, DMOCat); + } + + + /// + /// Release all info for the most recent input buffer + /// + private void ReleaseInputBuffs() + { + if (m_pBuffer != null) + { + Marshal.ReleaseComObject(m_pBuffer); + m_pBuffer = null; + } + m_InBuffer = IntPtr.Zero; + m_cbInData = 0; + m_Flags = 0; + + // I specifically DON'T release the TimeStamp so we can keep track of where we are + } + + /// + /// Perform the requested flip + /// + /// Pointer to the output buffer + /// Size of input buffer + /// Pointer to input buffer + /// Bytes (not bits) per pixel + /// What type of flip to do + private void DoFlip(IntPtr pbOutData, int cbInData, IntPtr pbInData, int BPP, FlipMode mode) + { + switch (mode) + { + // No flip, just copy the data + case FlipMode.None: + CopyMemory(pbOutData, pbInData, cbInData); + break; + + // Flip along the y axis + case FlipMode.FlipY: + + // Point to the last row of the dest and walk backwards + pbOutData = (IntPtr)(pbOutData.ToInt32() + cbInData - m_Stride); + for (int x=0; x < m_Height; x++) + { + // Copy a row + CopyMemory(pbOutData, pbInData, m_Stride); + + // Walk forward thru the src, and backward thru the src + pbInData = (IntPtr)(pbInData.ToInt32() + m_Stride); + pbOutData = (IntPtr)(pbOutData.ToInt32() - m_Stride); + } + break; + + // Flip along the X axis + case FlipMode.FlipX: + // For each row + for (int x=0; x < m_Height; x++) + { + // Calculate the read/write positions + int s = (x * m_Stride); + int src = s; + int dst = (m_Stride - BPP) + s; + + // For each pixel in the row + for (int y=0; y < m_Width; y ++) + { + if (BPP == 4) + { + // Read the pixel, write the pixel + int i1 = Marshal.ReadInt32(pbInData, src); + Marshal.WriteInt32(pbOutData, dst, i1); + } + else + { + // Read the pixel + short s1 = Marshal.ReadInt16(pbInData, 0 + src); + byte i3 = Marshal.ReadByte(pbInData, 2 + src); + + // Write the pixel (if you mess up the order here, + // you can get very strange looking output!) + Marshal.WriteInt16(pbOutData, 0 + dst, s1); + Marshal.WriteByte(pbOutData, 2 + dst, i3); + } + + src += BPP; + dst -= BPP; + } + } + break; + + // Flip along both the X & Y axis + case FlipMode.FlipY | FlipMode.FlipX: + + // For each row + for (int x=0; x < m_Height; x++) + { + // Calculate the read/write positions + int src = (x * m_Stride); + int dst = (m_Stride - BPP) + (cbInData - ((x+1) * m_Stride)); + + // For each pixel in the row + for (int y=0; y < m_Width; y ++) + { + + if (BPP == 4) + { + int i1 = Marshal.ReadInt32(pbInData, 0 + src); + Marshal.WriteInt32(pbOutData, 0 + dst, i1); + } + else + { + short s1 = Marshal.ReadInt16(pbInData, 0 + src); + byte i3 = Marshal.ReadByte(pbInData, 2 + src); + + Marshal.WriteInt16(pbOutData, 0 + dst, s1); + Marshal.WriteByte(pbOutData, 2 + dst, i3); + } + + src += BPP; + dst -= BPP; + } + } + break; + } + } + + #endregion + + /// + /// The constructor. The parameters to the base class + /// describe the number of input and output streams, which + /// DirectShow calls Pins, followed by the number of parameters + /// this class supports (can be zero), and the timeformat of those + /// parameters (should include ParamClass.TimeFormatFlags.Reference + /// if NumParameters > 0). + /// + public DmoFlip() : base(InputPinCount, OutputPinCount, NumParams, TimeFormatFlags.Reference) + { + m_Log.Write("Constructor\r\n"); + + // Initialize the data members + m_Width = 0; + m_Height = 0; + m_Stride = 0; + m_BPP = 0; + m_TimeStamp = 0; + m_TimeLength = 0; + m_cbInData = 0; + m_Flags = 0; + m_InBuffer = IntPtr.Zero; + m_pBuffer = null; + + // Start describing the parameters this DMO supports. Building this + // structure (painful as it is) will allow the base class to automatically + // support IMediaParamInfo & IMediaParams, which allow clients to find + // out what parameters you support, and to set them. + + // Our parameter has a minimum value of zero, and a max of + // FlipMode.LAST, and a default of DEFAULTMODE; See the MSDN + // docs for MP_PARAMINFO for a description of the other parameters + ParamInfo p = new ParamInfo(); + + p.mopCaps = MPCaps.Jump; + p.mpdMinValue.vInt = 0; + p.mpdMaxValue.vInt = (int)FlipMode.LAST; + p.mpdNeutralValue.vInt = (int)DEFAULTMODE; + p.mpType = MPType.ENUM; + p.szLabel = ""; + p.szUnitText = "FlipMode"; + + // Parameter #0, using the struct, and a format string (described in MSDN + // under IMediaParamInfo::GetParamText). Note that when marshaling strings, + // .NET will add another \0 + ParamDefine(0, p, "FlipMode\0\0None\0FlipY\0FlipX\0FlipY|FlipX\0"); + } + + + #region IMediaObjImpl Members + + /// + /// Given a specific AMMediaType, we are asked if we support it + /// + /// Stream number + /// The AMMediaType to check + /// S_OK if it is supported, DMOResults.E_InvalidType if not + override protected int InternalCheckInputType(int dwInputStreamIndex, AMMediaType pmt) + { + int hr; + + // Check the format is defined + if (pmt.majorType == MediaType.Video && + (pmt.subType == MediaSubType.RGB24 || pmt.subType == MediaSubType.RGB32) && + pmt.formatType == FormatType.VideoInfo && + pmt.formatPtr != IntPtr.Zero) + { + hr = S_OK; + } + else + { + hr = DMOResults.E_InvalidType; + } + + return hr; + } + + /// + /// Given a specific AMMediaType, we are asked if we support it + /// + /// Stream number + /// The AMMediaType to check + /// S_OK if it is supported, DMOResults.E_InvalidType if not + override protected int InternalCheckOutputType(int dwOutputStreamIndex, AMMediaType pmt) + { + int hr; + + AMMediaType pIn = InputType(0); + + // We don't support anything until after our input pin is set + if (pIn != null) + { + // Our output type must be the same as the input type + if (TypesMatch(pmt, pIn)) + { + hr = S_OK; + } + else + { + hr = DMOResults.E_InvalidType; + } + } + else + { + hr = DMOResults.E_InvalidType; + } + + return hr; + } + + /// + /// Get the list of supported types. Note this it is NOT required that any types be returned here. + /// If no types are returned, connectors just try media types (InternalCheckInputType) until we + /// accept one. + /// + /// Stream number + /// Index into the array of media types we support + /// + /// DMOResults.E_NoMoreItems if out of range, else S_OK + override protected int InternalGetInputType(int dwInputStreamIndex, int dwTypeIndex, out AMMediaType pmt) + { + int hr; + + switch(dwTypeIndex) + { + case 0: + pmt = new AMMediaType(); + pmt.majorType = MediaType.Video; + pmt.subType = MediaSubType.RGB32; + pmt.formatType = FormatType.VideoInfo; + hr = S_OK; + break; + + case 1: + pmt = new AMMediaType(); + pmt.majorType = MediaType.Video; + pmt.subType = MediaSubType.RGB24; + pmt.formatType = FormatType.VideoInfo; + hr = S_OK; + break; + + default: + pmt = null; + hr = DMOResults.E_NoMoreItems; + break; + } + + return hr; + } + + /// + /// What size (and alignment) do we require of our output buffer? + /// + /// Stream number + /// returns the buffer size needed + /// Returns the alignment needed (don't use zero!) + /// S_OK + override protected int InternalGetOutputSizeInfo(int dwOutputStreamIndex, out int pcbSize, out int pcbAlignment) + { + pcbAlignment = 1; + AMMediaType pmt = OutputType(0); + + VideoInfoHeader v = new VideoInfoHeader(); + Marshal.PtrToStructure(pmt.formatPtr, v); + + pcbSize = v.BmiHeader.ImageSize; + + return S_OK; + } + + /// + /// Flush releases all input buffers without processing them + /// + /// S_OK + override protected int InternalFlush() + { + InternalDiscontinuity(0); + + // Release buffers + ReleaseInputBuffs(); + m_TimeStamp = 0; + + return S_OK; + } + + /// + /// Our chance to allocate any storage we may need + /// + /// S_OK + override protected int InternalAllocateStreamingResources() + { + // Reinitialize variables + InternalDiscontinuity(0); + + AMMediaType pmt = InputType(0); + VideoInfoHeader v = new VideoInfoHeader(); + + Marshal.PtrToStructure(pmt.formatPtr, v); + m_Width = v.BmiHeader.Width; + m_Height = v.BmiHeader.Height; + m_BPP = v.BmiHeader.BitCount / 8; + m_Stride = v.BmiHeader.Width * m_BPP; + + return S_OK; + } + + /// + /// Accept the input buffers to be processed. You'll want to read + /// the MSDN docs on this one. One point worth noting is that DMO + /// doesn't require that one complete block be passed at a time. + /// Picture a case where raw data is being read from a file, and your + /// DMO is the first to process it. The chunk of data you receive + /// might represent one image, 5 images, half an image, etc. Likewise, + /// your input could contain both video and audio that you are splitting + /// into two output streams. + /// That helps explain some of the parameters you see here and in + /// InternalProcessOutput. + /// Note that while DMO doesn't insist on it, for this sample, we + /// specifically request that only complete buffers be provided. + /// + /// Stream Index + /// Interface that holds the input data + /// Flags to control input processing + /// Timestamp of the sample + /// Duration of the sample + /// S_FALSE if there is no output, S_OK otherwise + override protected int InternalProcessInput( + int dwInputStreamIndex, + [In] IMediaBuffer pBuffer, + DMOInputDataBuffer dwFlags, + long rtTimestamp, + long rtTimelength) + { + // Check state - if we already have a buffer, we shouldn't be getting another + Debug.Assert(m_pBuffer == null); + + int cbData; + + int hr = pBuffer.GetBufferAndLength(out m_InBuffer, out m_cbInData); + if (hr >= 0) + { + // Ignore zero length buffers + if (m_cbInData > 0) + { + m_pBuffer = pBuffer; + + // Cast the input flags to become output flags + m_Flags = (DMOOutputDataBufferFlags)dwFlags; + + // If there is a time, store it + if (0 == (dwFlags & DMOInputDataBuffer.Time)) + { + m_TimeStamp = MAX_TIME; + } + else + { + m_TimeStamp = rtTimestamp; + } + + + // If there is a TimeLength, store it + if (0 == (dwFlags & DMOInputDataBuffer.TimeLength)) + { + m_TimeLength = -1; + } + else + { + m_TimeLength = rtTimelength; + } + hr = S_OK; + } + else + { + ReleaseInputBuffs(); + hr = S_FALSE; + } + } + + return hr; + } + + /// + /// Given output buffers, process the input buffers into the output buffers. + /// + /// Flags + /// Number of buffers (will be one per output stream) + /// The buffers + /// Reserved: 0 + /// S_FALSE if there is no output, S_OK otherwise + override protected int InternalProcessOutput( + DMOProcessOutput dwFlags, + int cOutputBufferCount, + [In, Out] DMOOutputDataBuffer [] pOutputBuffers, + out int pdwStatus) + { + // Check buffer + IntPtr pbOutData; + int cbOutData; + int cbCurrent; + int hr = S_OK; + + pdwStatus = 0; + + // No input buffers to process + if (m_pBuffer != null) + { + if (pOutputBuffers[0].pBuffer != null) + { + // Get a pointer to the output buffer + hr = pOutputBuffers[0].pBuffer.GetBufferAndLength(out pbOutData, out cbCurrent); + if (hr >= 0) + { + hr = pOutputBuffers[0].pBuffer.GetMaxLength(out cbOutData); + if (hr >= 0) + { + // Make sure we have room + if (cbOutData >= cbCurrent + OutputType(0).sampleSize) + { + // Get the mode for the current timecode + MPData m = ParamCalcValueForTime(0, m_TimeStamp); + + // Process from input to output according to the mode + DoFlip((IntPtr)(pbOutData.ToInt32() + cbCurrent), m_cbInData, m_InBuffer, m_BPP, (FlipMode)m.vInt); + + // Keep the flags & time info from the input + pOutputBuffers[0].dwStatus = m_Flags; + pOutputBuffers[0].rtTimelength = m_TimeLength; + pOutputBuffers[0].rtTimestamp = m_TimeStamp; + + // Release the buffer. Since we are always processing one buffer at + // a time, we always release on completion. If our input might be + // more than one buffer, we would only release the input when it had + // be complete processed. + ReleaseInputBuffs(); + + // Say we've filled the buffer + hr = pOutputBuffers[0].pBuffer.SetLength(cbOutData); + } + else + { + hr = E_INVALIDARG; + } + } + } + } + else + { + // No output buffer provided. Happens in the DMO Wrapper if one of + // the output pins is not connected. + pOutputBuffers[0].dwStatus = m_Flags; + pOutputBuffers[0].rtTimelength = m_TimeLength; + pOutputBuffers[0].rtTimestamp = m_TimeStamp; + + // Release the buffer. Since we are always processing one buffer at + // a time, we always release on completion. If our input might be + // more than one buffer, we would only release the input when it had + // be complete processed. + ReleaseInputBuffs(); + } + } + else + { + hr = S_FALSE; + } + + return hr; + } + + /// + /// Are we able to accept more input at this time? + /// + /// Stream number + /// S_OK if we can, else S_FALSE + override protected int InternalAcceptingInput(int dwInputStreamIndex) + { + return m_pBuffer == null ? S_OK : S_FALSE; + } + + override protected long InternalGetCurrentTime() + { + return m_TimeStamp; + } + + + #endregion + } +} diff --git a/Samples/DMO/DmoFlip/DMO/DmoFlip.csproj b/Samples/DMO/DmoFlip/DMO/DmoFlip.csproj new file mode 100644 index 0000000..58eac7e --- /dev/null +++ b/Samples/DMO/DmoFlip/DMO/DmoFlip.csproj @@ -0,0 +1,140 @@ + + + + Local + 8.0.50727 + 2.0 + {369D647A-7F80-4F06-BEDB-D62AC1627862} + Debug + AnyCPU + + + + + DmoFlip + mykey.snk + JScript + Grid + IE50 + false + Library + DmoFlip + OnBuildSuccess + + + + + + + true + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\Debug\ + false + 285212672 + false + + + DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 1 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + USING_NET20 + docs\Dmo.xml + false + 4096 + false + + + false + false + false + false + 1 + none + prompt + + + + System + + + System.Drawing + + + + + Code + + + Code + + + Code + + + + + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + + + "%25windir%25\Microsoft.NET\Framework\v2.0.50727\regasm" /nologo /codebase $(TargetPath) + + \ No newline at end of file diff --git a/Samples/DMO/DmoFlip/DMO/IMediaObjectImpl.cs b/Samples/DMO/DmoFlip/DMO/IMediaObjectImpl.cs new file mode 100644 index 0000000..c76a0c7 --- /dev/null +++ b/Samples/DMO/DmoFlip/DMO/IMediaObjectImpl.cs @@ -0,0 +1,3142 @@ +#region license + +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +#endregion + +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; +using DirectShowLib; +using DirectShowLib.DMO; +using System.IO; +using System.Collections; + +namespace MediaObjectTemplate +{ + /// + /// This abstract class can be used to implement a DMO in .NET. + /// + /// + /// Before attempting to use this class, read the MSDN docs on DMOs! In + /// particular read about IMediaObject, IMediaParamInfo, IMediaParams, + /// and the DMO Wrapper Filter (if you are using DirectShow graphs). + /// + /// When you read the MSDN docs about creating a DMO, they refer to a template that + /// you can use to make things easier. That template served as the inspiration for this + /// class. To create a DMO, you can just create a class that implements this abstract class, + /// write code for the abstract methods, and you should be good to go. + /// + /// Here is a more detailed description of the steps you need to take. Note that you can + /// look at the sample code for examples of these steps. + /// + /// 1) Other than ripping out the rather lame logging, you shouldn't need to change + /// any code in IMediaObjectImpl.cs. It is the initial entry point for all the + /// IMediaObject interfaces. It performs parameter checking, makes sure the call + /// is appropriate for the current state, etc. As needed it will make calls to the + /// abstract and virtual methods of the class. + /// + /// 2) Create a class which implements the abstract IMediaObjectImpl class: + /// + /// [ComVisible(true), Guid("7EF28FD7-E88F-45bb-9CDD-8A62956F2D75"), + /// ClassInterface(ClassInterfaceType.None)] + /// public class DmoFlip : IMediaObjectImpl + /// + /// 3) Generate your own guid so the samples won't interfere with your code: + /// If you are running Dev Studio, go to Tools/Create Guid, choose "Registry + /// Format", click "Copy", then paste into your code. + /// + /// 4) Create the constructor for your class. It must not take any parameters: + /// + /// public DmoFlip() : base(InputPinCount, OutputPinCount, ParamCount, TimeFormatFlags.Reference) + /// + /// If you are planning to use this DMO with the DirectShow DMO Wrapper Filter, note + /// that (up to and including DX v9.0) InputPinCount must be 1, and OutputPinCount must + /// be > 0. The ParamCount is the number of parameters your DMO supports, and can be zero. + /// In general, you should use TimeFormatFlags.Reference for the last paramter. + /// + /// 5) Register the parameters your DMO supports using . + /// This must be done in the constructor (unless you have no parameters). Doing this allows you to support + /// IMediaParamInfo and IMediaParams. You will also need to use + /// to find out what parameter value you should use at any given point during the stream. + /// See the docs for these two methods for details. + /// + /// 6) Create the COM register/unregister methods: + /// + /// [ComRegisterFunctionAttribute] + /// static private void DoRegister(Type t) + /// + /// [ComUnregisterFunctionAttribute] + /// static private void UnregisterFunction(Type t) + /// + /// These tell the OS about your DMO. If you are distributing your code, you + /// will need to make sure they get called during installation (read about RegAsm + /// in the .NET docs). At a minimum, you will need to call DMORegister to register + /// your DMO. See the sample for how this is done. + /// + /// WARNING: If you use the "Register for COM Interop" compiler switch, the + /// compiler will attempt to register DirectShowLib.dll as well as your DMO. + /// Since DirectShowLib has no registration to perform, this generates an error. + /// That is why the sample uses pre/post build events to perform the registration. You + /// may need to adjust this command for your particular installation. + /// + /// 7) Do everything else. There are 7 abstract methods for which you must + /// write code. These methods are listed in the IMediaObjectImpl Methods page in + /// the Protected Instance Methods section. These methods will contain the information + /// specific to your DMO, and describe what type of data you are willing to process, and + /// perform the actual processing. Note that since the abstract class has verified the + /// parameters, you do not need to re-check them in your implementation. See the + /// descriptions for each method and the sample for details about what each of these + /// methods must do. + /// + /// You may also need to override some of the 11 virtual methods if their default + /// implementation doesn't match your specific needs. See the documentation for each of + /// these specific methods for details. + /// + ///
+ /// + /// If you aren't already knowledgeable about COM and writing multi-threaded apps, + /// this is probably a good time to do a little research. You may have multiple + /// instances of your DMO running in the same process, in multiple processes, + /// called on different threads, etc. + /// + /// As a simple example of the things you should be thinking of, the logging in + /// (debug builds of) IMediaObjectImpl.cs opens the file as non-sharable. + /// However, if two applications try to instantiate your DMO, the second will fail, + /// solely due to not being able to open the log file. Probably not the desired + /// behavior (told you the logging was lame). + ///
+ abstract public class IMediaObjectImpl : IMediaObject, IMediaParamInfo, IMediaParams + { + #region Declarations + + // Used in IMediaParams to specify that an envelope change should + // be applied to all parameters. + private const int ALLPARAMS = -1; + + /// COM return code indicating success + protected const int S_OK = 0; + + /// COM return code indicating partial success + protected const int S_FALSE = 1; + + /// COM return code indicating method not supported + protected const int E_NOTIMPL = unchecked((int)0x80004001); + + /// COM return code indicating invalid pointer provided + protected const int E_POINTER = unchecked((int)0x80004003); + + /// COM return code indicating invalid argument specified + protected const int E_INVALIDARG = unchecked((int)0x80070057); + + /// COM return code indicating a method called at an unexpected time + protected const int E_UNEXPECTED = unchecked((int)0x8000FFFF); + + /// + /// Info regarding a (input or output) pin + /// + private struct PinDef + { + public bool fTypeSet; + public bool fIncomplete; + public AMMediaType CurrentMediaType; + } + + + /// + /// Used by the IMediaObjectImpl constructor to specify which timeformats are supported + /// + [Flags] + protected enum TimeFormatFlags + { + /// + /// Used only when the DMO has no parameters + /// + None = 0, + /// + /// Reference time, in 100-nanosecond units. All DMOs should support this format. + /// + Reference = 1, + /// + /// Music time, in parts per quarter note. + /// + Music = 2, + /// + /// Samples per second. + /// + Samples = 4 + } + + #endregion + + #region Internal Classes + + // This class holds all the information about the parameters + // for this DMO. Using this class allows IMediaObjectImpl to + // automatically implement IMediaParamInfo & IMediaParams. If + // your DMO has no parameters, you do not need to create an instance + // of this class. + private class ParamClass + { + #region Member variables + + // The param returned to IMediaParamInfo::GetParamInfo + public ParamInfo [] Parms; + + // The list of TimeFormats returned to IMediaParamInfo::GetSupportedTimeFormat + public Guid [] TimeFormats; + + // The index into TimeFormats indicating the currently active format + public int CurrentTimeFormat; + + // The TimeData for the current format (see IMediaParams::SetTimeFormat) + public int TimeData; + + // The string text returned from IMediaParamInfo::GetParamText + public string [] ParamText; + + // The envelopes holding the parameter info. Note that even if parameter + // info isn't sent with IMediaParams::AddEnvelope (ie thru IMediaParams::SetParam), + // this implementation still creates and uses envelopes. It just makes envelopes + // that span the entire media length. + public MPEnvelopes [] Envelopes; + + #endregion + + public ParamClass(int iParams, TimeFormatFlags iTimeFormats) + { + CurrentTimeFormat = 0; + TimeData = 0; + + // Make room for the timeformats + int iCount = CountBits((int)iTimeFormats); + TimeFormats = new Guid[iCount]; + + if ((iTimeFormats & TimeFormatFlags.Samples) > 0) + { + TimeFormats[--iCount] = MediaParamTimeFormat.Samples; + } + if ((iTimeFormats & TimeFormatFlags.Music) > 0) + { + TimeFormats[--iCount] = MediaParamTimeFormat.Music; + } + if ((iTimeFormats & TimeFormatFlags.Reference) > 0) + { + TimeFormats[--iCount] = MediaParamTimeFormat.Reference; + } + Debug.Assert(iCount == 0, "Unrecognized time format specified"); + + // Make room for the parameter info + ParamText = new string[iParams]; + Parms = new ParamInfo[iParams]; + Envelopes = new MPEnvelopes[iParams]; + } + + public void DefineParam(int iParamNum, ParamInfo p, string sText) + { + Debug.Assert(iParamNum < Parms.Length && iParamNum >= 0, "Invalid parameter index"); + + Parms[iParamNum] = p; + Envelopes[iParamNum] = new MPEnvelopes(p.mpdNeutralValue, p.mopCaps, p.mpType, p.mpdMaxValue, p.mpdMaxValue); + ParamText[iParamNum] = sText; + } + + } + + + /// + /// The idea of envelopes (as I understand them) is to allow a parameter value + /// to be applied to a range within the stream. Generally speaking, there is a + /// start time and stop time, a parameter start value and a parameter end value. + /// So, you could say "The volume should go from 0% to 100% over the first 4 + /// seconds." There is also a Curve parameter that controls how quickly the + /// parameter value should change: Linear, Square, Sine, Jump, etc. + /// + /// Also note, the docs for IMediaParams::FlushEnvelope make no sense to me. + /// Instead of trying to make sense of the crazyness they have written, I + /// have done something simpler. If you flush a range, that range gets set + /// back to the NeutralVal for the parameter. + /// + /// The assumption (based on comments in IMediaParams::SetTimeFormat) is that + /// the times specified to the envelope are the same format as will be specified + /// to ProcessInput. If you are changing the format, call flush. + /// + private class MPEnvelopes + { + #region Declarations + + private const long MAX_TIME = 0x7FFFFFFFFFFFFFFF; + protected const int S_OK = 0; + protected const int E_INVALIDARG = unchecked((int)0x80070057); + + #endregion + + #region Member variables + + protected ArrayList m_Envelope; + protected MPData m_DefaultValue; + protected int m_ValidCaps; + protected MPType m_DataType; + protected MPData m_MinVal; + protected MPData m_MaxVal; + + #endregion + + public MPEnvelopes(MPData iDefaultValue, MPCaps iValidCaps, MPType mt, MPData min, MPData max) + { + // Store the neutralValue, min/max value range, data type and supported curve types + m_DefaultValue = iDefaultValue; + m_ValidCaps = (int)iValidCaps; + m_DataType = mt; + m_MinVal = min; + m_MaxVal = max; + + // Create an array to hold the segments (size = 3 was chosen arbitrarily) + m_Envelope = new ArrayList(3); + + // Create one segment that spans all time containing the default values + MPEnvelopeSegment e = new MPEnvelopeSegment(); + e.flags = MPFlags.BeginNeutralVal; + e.iCurve = MPCaps.Jump; + e.rtStart = 0; + e.rtEnd = MAX_TIME; + e.valStart = m_DefaultValue; + e.valEnd = m_DefaultValue; + + m_Envelope.Add(e); + } + + /// + /// Add a segment to the envelope. If this segment overlaps other segments, + /// the other segments are deleted or shortened, and this segment is inserted + /// + /// The segment to add + /// HRESULT + public int AddSegment(MPEnvelopeSegment mNew) + { + int hr; + int y; + MPEnvelopeSegment mOld; + + hr = ValidateEnvelopeSegment(mNew); + if (hr >= 0) + { + // Find the first record to modify. There is always + // at least one record, and ValidateEnvelopeSegment ensures + // that the start time is less than the endtime of the last + // record (MAX_TIME) + y = 0; + + do + { + mOld = (MPEnvelopeSegment)m_Envelope[y]; + + if (mNew.rtStart <= mOld.rtEnd) + { + break; + } + y++; + + } while (true); + + // Process the flags on mNew + UpdateSegment(y, ref mNew); + + // Depending on how the new segment overlaps, adjust the + // other segments and add it + if (mNew.rtStart <= mOld.rtStart) + { + if (mNew.rtEnd >= mOld.rtEnd) + { + // Existing segment is completely replaced + m_Envelope.RemoveAt(y); + m_Envelope.Insert(y, mNew); + + // Subsequent records may need to be deleted/adjusted + if (mNew.rtEnd > mOld.rtEnd) + { + DeleteRest(y+1, mNew.rtEnd); + } + } + else + { + // Existing segment is shortened from the left + mOld.rtStart = mNew.rtEnd + 1; + m_Envelope[y] = mOld; + m_Envelope.Insert(y, mNew); + } + } + else + { + if (mNew.rtEnd >= mOld.rtEnd) + { + // Existing segment is truncated + mOld.rtEnd = mNew.rtStart - 1; + m_Envelope[y] = mOld; + m_Envelope.Insert(y+1, mNew); + + if (mNew.rtEnd > mOld.rtEnd) + { + DeleteRest(y+2, mNew.rtEnd); + } + } + else + { + // Split a segment + MPEnvelopeSegment mAppend = mOld; + mAppend.rtStart = mNew.rtEnd + 1; + + mOld.rtEnd = mNew.rtStart - 1; + m_Envelope[y] = mOld; + + m_Envelope.Insert(y+1, mNew); + m_Envelope.Insert(y+2, mAppend); + } + } + } + + return hr; + } + + /// + /// Returns the Envelope the applies to a specific time. Since there is a + /// default segment that covers all possible times, this will always return + /// a value. + /// + /// Time to check + /// The envelope at that segment + public MPEnvelopeSegment FindEnvelopeForTime(long rt) + { + int x=0; + MPEnvelopeSegment mRet; + + do + { + mRet = (MPEnvelopeSegment)m_Envelope[x++]; + } while (rt > mRet.rtEnd); + + return mRet; + } + + /// + /// Calculate the parameter value at a specified time + /// + /// While there are routines written for all the curve types, I'm not enough + /// of a math whiz to feel comfortable that I got it right. I stole the code + /// from elsewhere and converted it to c#, so there's a chance I messed up. + /// + /// Time at which to calculate + /// MPData value for that time based in the specified Curve + public MPData CalcValueForTime(long rt) + { + long ir, ic; + float p; + MPData ret; + MPEnvelopeSegment m = FindEnvelopeForTime(rt); + + switch(m.iCurve) + { + case MPCaps.Jump: + + // Not quite sure how I want to do this. Consider an envelope + // that goes from time 0 to 10, and value 55 to 99. Obviously + // at time 0, you return 55. At times 1 thru 9, I assume you + // also return 55 (although one could argue they should return + // 99). At time 10, you return 99. + + // If you never have a timestamp that exactly equals 10, you + // would never get the new value. Seems odd. Well, that's + // how I've written it, anyway. + if (rt < m.rtEnd) + { + ret = m.valStart; + } + else + { + ret = m.valEnd; + } + break; + + case MPCaps.Linear: + ir = m.rtEnd - m.rtStart; + ic = rt - m.rtStart; + p = ic / ir; + ret = new MPData(); + + if (m_DataType == MPType.FLOAT) + { + ret.vFloat = (m.valEnd.vFloat - m.valStart.vFloat) * p; + } + else + { + ret.vInt = (int)((m.valEnd.vInt - m.valStart.vInt) * p); + } + break; + + case MPCaps.InvSquare: + ir = m.rtEnd - m.rtStart; + ic = rt - m.rtStart; + p = ic / ir; + p = (float)Math.Sqrt(p); + ret = new MPData(); + + if (m_DataType == MPType.FLOAT) + { + ret.vFloat = (m.valEnd.vFloat - m.valStart.vFloat) * p; + } + else + { + ret.vInt = (int)((m.valEnd.vInt - m.valStart.vInt) * p); + } + break; + + case MPCaps.Sine: + ir = m.rtEnd - m.rtStart; + ic = rt - m.rtStart; + p = ic / ir; + p = (float)((Math.Sin(p * Math.PI - (Math.PI/2)) + 1) / 2); + ret = new MPData(); + + if (m_DataType == MPType.FLOAT) + { + ret.vFloat = (m.valEnd.vFloat - m.valStart.vFloat) * p; + } + else + { + ret.vInt = (int)((m.valEnd.vInt - m.valStart.vInt) * p); + } + break; + + case MPCaps.Square: + ir = m.rtEnd - m.rtStart; + ic = rt - m.rtStart; + p = ic / ir; + p = p * p; + ret = new MPData(); + + if (m_DataType == MPType.FLOAT) + { + ret.vFloat = (m.valEnd.vFloat - m.valStart.vFloat) * p; + } + else + { + ret.vInt = (int)((m.valEnd.vInt - m.valStart.vInt) * p); + } + break; + + default: + Debug.Assert(false, "Invalid flag!"); + ret = new MPData(); + break; + } + + return ret; + } + + /// + /// Make sure the envelope parameters are valid + /// + /// Envelope segment to check + /// E_INVALIDARG if parameters are incorrect, else S_OK + public int ValidateEnvelopeSegment(MPEnvelopeSegment m) + { + int hr; + + // The start time cannot be MAX_TIME + // The end time must be >= start time + // The iCurve must be one of the recognized formats + // The iCurve must be one of the supported formats + // The iCurve can only be one format + // The flags must be one of the recognized formats + // The flags can only be one value + + if ( + (m.rtStart == MAX_TIME) || + (m.rtEnd < m.rtStart) || + ((m.iCurve & (~(MPCaps.InvSquare | MPCaps.Jump | MPCaps.Linear | MPCaps.Sine | MPCaps.Square))) > 0) || + ((((int)m.iCurve) & (~(m_ValidCaps))) > 0) || + (IMediaObjectImpl.CountBits((int)m.iCurve) > 1) || + ((m.flags & (~(MPFlags.BeginCurrentVal | MPFlags.BeginNeutralVal | MPFlags.Standard))) > 0) || + (IMediaObjectImpl.CountBits((int)m.flags) > 1) + ) + { + hr = E_INVALIDARG; + } + else + { + hr = S_OK; + } + + return hr; + } + +#if DEBUG + /// + /// Debug utility to dump an envelope + /// + public void DumpEnvelope() + { + int c = m_Envelope.Count; + Debug.WriteLine("----------------------------"); + + for (int x=0; x < c; x++) + { + MPEnvelopeSegment mOld = (MPEnvelopeSegment)m_Envelope[x]; + + Debug.WriteLine(string.Format("{0}: {1}-{2} {3}-{4}", x, mOld.rtStart, mOld.rtEnd, mOld.valStart.vInt, mOld.valEnd.vInt)); + } + } +#endif + + /// + /// Utility function called from AddEnvelope. When adding an envelope segment, + /// it could happen that the new segment overlaps multiple existing segments. + /// This routine walks starting at the specified segment. It either deletes + /// the segment or adjusts it until it reaches the ending time of the new + /// segment. + /// + /// Starting segment + /// new segment + private void DeleteRest(int z, long rtEnd) + { + // Don't walk past the end of the array + while (z < m_Envelope.Count) + { + MPEnvelopeSegment mOld = (MPEnvelopeSegment)m_Envelope[z]; + + // Have we found the end time of the current segment? + if (mOld.rtEnd <= rtEnd) + { + // Nope. Delete this segment. + m_Envelope.RemoveAt(z); + } + else + { + // Yes, this is the end. Split the old segment + mOld.rtStart = rtEnd + 1; + m_Envelope[z] = mOld; + break; + } + } + } + + /// + /// See if the specified parameter value falls within the allowable range + /// + /// Value to check + /// true if the parameter value is valid + private bool CheckRange(MPData m) + { + bool bRet; + + switch (m_DataType) + { + case MPType.BOOL: + case MPType.ENUM: + case MPType.INT: + bRet = (m.vInt >= m_MinVal.vInt && m.vInt <= m_MaxVal.vInt); + break; + + case MPType.FLOAT: + bRet = (m.vFloat >= m_MinVal.vFloat && m.vFloat <= m_MaxVal.vFloat); + break; + + default: + Debug.Assert(false, "Invalid Type"); + bRet = false; + break; + } + + return bRet; + } + + private void UpdateSegment(int y, ref MPEnvelopeSegment m) + { + if ((m.flags & MPFlags.BeginNeutralVal) > 0) + { + m.valStart = m_DefaultValue; + } + else if ((m.flags & MPFlags.BeginCurrentVal) > 0) + { + if (y > 0) + { + MPEnvelopeSegment mOld = (MPEnvelopeSegment)m_Envelope[y-1]; + m.valStart = mOld.valEnd; + } + else + { + m.valStart = m_DefaultValue; + } + } + } + } + + #endregion + + #region API + + /// + /// Compare two blocks of memory to see if they are identical + /// + /// Pointer to first block + /// Pointer to second block + /// Number of bytes to compare + /// The number of bytes that compare as equal. If all bytes compare as equal, the input Length is returned. + [DllImport("NTDll.dll", EntryPoint="RtlCompareMemory")] + private static extern int CompareMemory(IntPtr Destination, IntPtr Source, [MarshalAs(UnmanagedType.U4)] int Length); + + #endregion + + #region Member variables + + // Keeps a count of the number of instances of this class have + // been instantiated. Only used by logging. + static private int iInstanceCount = 0; + + // Status info about the input/output pins + private PinDef [] m_InputInfo; + private PinDef [] m_OutputInfo; + + // Have the types been set for all the input/output pins + private bool m_fTypesSet; + + // All buffers are empty + private bool m_fFlushed; + + // Has AllocateStreamingResources been successfully been called + private bool m_fResourcesAllocated; + + // Count of the input/output pins + private int m_NumInputs; + private int m_NumOutputs; + + // The log file + internal Logging m_Log; + + // Struct to support IMediaParamInfo & IMediaParams + private ParamClass m_Params; + + #endregion + + #region Utility routines + + /// + /// Count how many bits are set in an flag + /// + /// bitmap to check + /// Count of the number of bits set + internal static int CountBits(int i) + { + int iRet = 0; + + while (i > 0) + { + if ((i & 1) > 0) + { + iRet++; + } + i >>= 1; + } + + return iRet; + } + + /// + /// Set m_fTypesSet by making sure types are set for all input and non-optional output streams. + /// + /// true if all types are set + private bool CheckAllTypesSet() + { + DMOOutputStreamInfo dwFlags; + int dw; + int hr; + + m_fTypesSet = false; + for (dw = 0; dw < m_NumInputs; dw++) + { + if (!InputTypeSet(dw)) + { + return false; + } + } + + for (dw = 0; dw < m_NumOutputs; dw++) + { + if (!OutputTypeSet(dw)) + { + // Check if it's optional + hr = InternalGetOutputStreamInfo(dw, out dwFlags); + + Debug.Assert(0 == (dwFlags & ~(DMOOutputStreamInfo.WholeSamples | + DMOOutputStreamInfo.SingleSamplePerBuffer | + DMOOutputStreamInfo.FixedSampleSize | + DMOOutputStreamInfo.Discardable | + DMOOutputStreamInfo.Optional))); + + if ((dwFlags & DMOOutputStreamInfo.Optional) == 0) + { + return false; + } + } + } + + m_fTypesSet = true; + + return true; + } + + /// + /// Handle thrown exceptions in a consistent way. + /// + /// The exception that was thrown + /// HRESULT to return to COM + private int CatFail(Exception e) + { + m_Log.Write(string.Format("Catastrophic failure: {0}\r\n", e.Message)); + + int hr = Marshal.GetHRForException(e); + if (hr >= 0) + { + hr = E_UNEXPECTED; + } + return hr; + } + + + /// + /// Make a clone of a media type + /// + /// The AMMediaType to clone + /// Returns the clone + /// + /// Note that like all AMMediaTypes, the clone must be released + /// with DsUtils.FreeAMMediaType when it is no longer needed. + /// + static protected AMMediaType MoCloneMediaType(AMMediaType pmt1) + { + AMMediaType pRet = new AMMediaType(); + DMOUtils.MoCopyMediaType(pRet, pmt1); + + return pRet; + } + + /// + /// Create a definition for a parameter that is accessible thru IMediaParamInfo + /// and IMediaParams. + /// + /// Zero based parameter number to set the definition for + /// Populated ParamInfo struct + /// Format string (described in MSDN under IMediaParamInfo::GetParamText) + /// + /// This method should be called from the constructor of the class that implements IMediaObjectImpl. It + /// defines a single parameter that can be set on the DMO. You must call it once for each of the + /// parameters defined in the call to the IMediaObjectImpl constructor. This allows for automatic + /// support of the IMediaParamInfo and IMediaParams methods. See the + /// for additional details. + /// + protected void ParamDefine(int iParamNum, ParamInfo p, string sText) + { + m_Params.DefineParam(iParamNum, p, sText); + } + + /// + /// Given a parameter number and a time, return the parameter value at that time. + /// + /// Zero based parameter number + /// Time + /// Calculated value for the specified time + /// + /// Parameters for DMO can be set in one of two ways. IMediaParams.SetParam can + /// be used to set a parameter to a specific value. It is useful for setting values + /// that aren't intended to change over time. There is also IMediaParams.AddEnvelope. This + /// method can be use for things that change over time. For example, consider a parameter + /// for adjusting the audio volume. You might want to be able to have the volume go from 0% + /// to 150% over the first x seconds. + /// You can easily support both by using this method. + /// As you prepare to process buffers, take the timestamp that applies to that buffer, and + /// call this method to get the desired value for that parameter at that that time. + /// + /// + protected MPData ParamCalcValueForTime(int dwParam, long rtTimeStamp) + { + return m_Params.Envelopes[dwParam].CalcValueForTime(rtTimeStamp); + } + + /// + /// Check to see if two Media Types are exactly the same + /// + /// Media type to compare + /// Media type to compare + /// true if types are identical, else false + static protected bool TypesMatch(AMMediaType pmt1, AMMediaType pmt2) + { + if (pmt1.majorType == pmt2.majorType && + pmt1.subType == pmt2.subType && + pmt1.sampleSize == pmt2.sampleSize && + pmt1.formatType == pmt2.formatType && + pmt1.formatSize == pmt2.formatSize && + pmt1.formatSize == CompareMemory(pmt1.formatPtr, pmt2.formatPtr, pmt1.formatSize)) + { + return true; + } + else + { + return false; + } + } + + /// + /// Check whether the media type is set for the specified input stream + /// + /// Zero based stream number to check + /// true if the stream type is set + protected bool InputTypeSet(int ulInputStreamIndex) + { + Debug.Assert(ulInputStreamIndex < m_NumInputs); + return m_InputInfo[ulInputStreamIndex].fTypeSet; + } + + /// + /// Check whether the media type is set for the specified output stream + /// + /// Zero based stream number to check + /// true if the stream type is set + protected bool OutputTypeSet(int ulOutputStreamIndex) + { + Debug.Assert(ulOutputStreamIndex < m_NumOutputs); + return m_OutputInfo[ulOutputStreamIndex].fTypeSet; + } + /// + /// Get the AMMediaType for the specified Input stream + /// + /// The stream to get the media type for + /// The media type for the stream, or null if not set + /// + /// The abstract class will call to see + /// whether a given media type is supported. To see what media type was actually set, the + /// derived class can call this method. + /// + protected AMMediaType InputType(int ulInputStreamIndex) + { + if (!InputTypeSet(ulInputStreamIndex)) + { + return null; + } + return m_InputInfo[ulInputStreamIndex].CurrentMediaType; + } + /// + /// Get the AMMediaType for the specified Output stream + /// + /// The stream to get the media type for + /// The media type for the stream, or null if not set + /// + /// The abstract class will call to see + /// whether a given media type is supported. To see what media type was actually set, the + /// derived class can call this method. + /// + protected AMMediaType OutputType(int ulOutputStreamIndex) + { + if (!OutputTypeSet(ulOutputStreamIndex)) + { + return null; + } + return m_OutputInfo[ulOutputStreamIndex].CurrentMediaType; + } + + + #endregion + + /// + /// Constructor + /// + /// Number of input streams + /// Number of output streams + /// Number of parameters + /// What time formats the parameters support + /// + /// This constructor will be called from the constructor of the class that implements + /// IMediaObjectImpl. See for a step by step description + /// of the process. + /// + protected IMediaObjectImpl(int iInputs, int iOutputs, int iParams, TimeFormatFlags iTimeFormats) + { + iInstanceCount++; + m_Log = new Logging(iInstanceCount); + m_Log.Write("-------------------------------\r\n"); + m_Log.Write(string.Format("bConstructor {0}\r\n", iInstanceCount)); + + m_NumInputs = iInputs; + m_NumOutputs = iOutputs; + m_fTypesSet = false; + m_fFlushed = true; + m_fResourcesAllocated = false; + m_InputInfo = new PinDef[m_NumInputs]; + m_OutputInfo = new PinDef[m_NumOutputs]; + + // Protect ourselves from incorrectly written children + m_Params = new ParamClass(iParams, iTimeFormats); + } + + /// + /// Destructor + /// + /// + ~IMediaObjectImpl() + { + int dwCurrentType; + + m_Log.Write(string.Format("bDestructor {0}\r\n", iInstanceCount)); + + for (dwCurrentType = 0; dwCurrentType < m_NumInputs; dwCurrentType++) + { + if(InputTypeSet(dwCurrentType)) + { + DsUtils.FreeAMMediaType(m_InputInfo[dwCurrentType].CurrentMediaType); + } + } + + for (dwCurrentType = 0; dwCurrentType < m_NumOutputs; dwCurrentType++) + { + if(OutputTypeSet(dwCurrentType)) + { + DsUtils.FreeAMMediaType(m_OutputInfo[dwCurrentType].CurrentMediaType); + } + } + + m_Log.Dispose(); + } + + + #region Abstract methods + + /// + /// (Abstract) Determine whether the input stream supports a specific media type + /// + /// Input stream number + /// The media type to check + /// S_OK if the specified stream supports the specified media type, + /// else DMOResults.E_InvalidType + /// + /// This method is called by the abstract class. The implementor should check the + /// properties of the AMMediaType to ensure that if a sample of the specified type + /// is sent, it will be able to process it. + /// + abstract protected int InternalCheckInputType(int dwInputStreamIndex, AMMediaType pmt); + + /// + /// (Abstract) Determine whether the output stream supports a specific media type + /// + /// Output stream number + /// The media type to check + /// S_OK if the specified stream supports the specified media type, + /// else DMOResults.E_InvalidType + /// + /// This method is called by the abstract class. The implementor should check the + /// properties of the AMMediaType to ensure that if requested, it can produce an + /// output sample of the specified type. + /// + abstract protected int InternalCheckOutputType(int dwOutputStreamIndex, AMMediaType pmt); + + /// + /// (Abstract) Determine the requirements for the output stream + /// + /// Output stream number + /// The minimum size of an output buffer for this stream, in bytes + /// The required buffer alignment, in bytes. If the output stream + /// has no alignment requirement, the value is 1. + /// S_OK to indicate successful operation. + /// + /// This method is called by the abstract class. You should never return zero for the alignment. + /// + abstract protected int InternalGetOutputSizeInfo(int dwOutputStreamIndex, out int pcbSize, out int pcbAlignment); + + /// + /// (Abstract) Called to flush all pending processing + /// + /// S_OK to indicate successful operation + /// + /// This method is called by the abstract class. In response, the implementor should discard + /// any pending input buffers. + /// + abstract protected int InternalFlush(); + + /// + /// (Abstract) Accept input buffers to be processed + /// + /// Input stream number + /// Input buffer to process + /// Processing flags + /// Timestamp of sample(s) + /// Length of sample(s) + /// S_OK if the operation completes successfully, S_FALSE if there + /// is no input to process. + /// + /// This method is called by the abstract class. It passes the actual data to be process to the + /// implementor. Commonly, the implementor stores these values, waiting for the call to + /// InternalProcessOutput (which contains the buffers into which the results are to be stored), at + /// which point they are released. + /// + abstract protected int InternalProcessInput(int dwInputStreamIndex, IMediaBuffer pBuffer, DMOInputDataBuffer dwFlags, long rtTimestamp, long rtTimelength); + + /// + /// (Abstract) Process the input buffers from a previous call to InternalProcessInput into the provided output buffers + /// + /// Flags controlling the operation + /// The number of buffers provided (one per output stream) + /// The output buffer into which the data is processed + /// Zero + /// S_FALSE if there is no output, S_OK for successful operation. + /// + /// This method is called by the abstract class. It passes the output buffers to the implementor. + /// Typically, this is when the actual work is done, processing the input buffers into the output + /// buffers. + /// + abstract protected int InternalProcessOutput(DMOProcessOutput dwFlags, int cOutputBufferCount, DMOOutputDataBuffer [] pOutputBuffers, out int pdwStatus); + + /// + /// (Abstract) Report whether more input buffers can be accepted + /// + /// Input stream number + /// S_OK if the implementor is ready to accept an input buffer, else S_FALSE + /// + /// This method is called by the abstract class. If the implementor has room for another input buffer, it + /// should return S_OK. It is perfectly acceptable for a DMO to only accept one input buffer at a time, and + /// to return S_FALSE until InternalProcessOutput has been called to process the buffer. + /// + abstract protected int InternalAcceptingInput(int dwInputStreamIndex); + + #endregion + + #region Virtual Methods + + /// + /// (Virtual) Returns the current time in the media stream + /// + /// The current time in the media stream + /// + /// Typically, this function should be overridden to return the most recent timestamp + /// from the last call to InternalProcessInput. It is used to support IMediaParams.GetParam. + /// The default implementation assumes the stream has no time stamps or that the stream is + /// stopped. + /// + virtual protected long InternalGetCurrentTime() + { + return 0; + } + + /// + /// (Virtual) Allows stream resources to be allocated + /// + /// S_OK for successful operation + /// + /// Allows the implementor to allocate any resources necessary for performing the processing. + /// The default implementation assumes we don't need to allocate any addition resources to + /// perform the processing. + /// + virtual protected int InternalAllocateStreamingResources() + { + return S_OK; + } + + /// + /// (Virtual) Allows stream resources to be released + /// + /// S_OK for successful operation + /// + /// Allows the implementor to release any resources used for performing the processing. + /// The default implementation assumes we don't need to release any addition resources. + /// + virtual protected int InternalFreeStreamingResources() + { + return S_OK; + } + + /// + /// (Virtual) Controls information about how input buffers are formatted + /// + /// Input stream number + /// Flags specifying how input buffers need to be formatted + /// S_OK for successful completion + /// + /// Allows the implementor to specify flags controlling the format of input buffers. The default + /// implementation return FixedSampleSize | SingleSamplePerBuffer | WholeSamples + /// + virtual protected int InternalGetInputStreamInfo(int dwInputStreamIndex, out DMOInputStreamInfo pdwFlags) + { + pdwFlags = DMOInputStreamInfo.FixedSampleSize | + DMOInputStreamInfo.SingleSamplePerBuffer | + DMOInputStreamInfo.WholeSamples; + + return S_OK; + } + + /// + /// (Virtual) Controls information about how output buffers are formatted + /// + /// Output stream number + /// Flags specifying how output buffers need to be formatted + /// S_OK for successful completion + /// + /// Allows the implementor to specify flags controlling the format of output buffers. The default + /// implementation returns WholeSamples | SingleSamplePerBuffer | FixedSampleSize + /// + virtual protected int InternalGetOutputStreamInfo(int dwOutputStreamIndex, out DMOOutputStreamInfo pdwFlags) + { + pdwFlags = DMOOutputStreamInfo.WholeSamples | + DMOOutputStreamInfo.SingleSamplePerBuffer | + DMOOutputStreamInfo.FixedSampleSize; + + return S_OK; + } + + /// + /// (Virtual) Retrieves a preferred media type for a specified input stream + /// + /// Input stream number + /// Index into the array of supported media types + /// The media type + /// DMOResults.E_NoMoreItems if out of range or S_OK for successful completion + /// + /// If the implementor supports returning a collection of supported media types, it should override + /// this method. The default implementation assumes we don't enumerate our supported types. The + /// app calling this DMO should just try setting something and see if it works. + /// + virtual protected int InternalGetInputType(int dwInputStreamIndex, int dwTypeIndex, out AMMediaType pmt) + { + pmt = null; + return DMOResults.E_NoMoreItems; + } + + /// + /// (Virtual) Retrieves a preferred media type for a specified output stream + /// + /// Output stream number + /// Index into the array of supported media types + /// The media type + /// DMOResults.E_NoMoreItems if out of range or S_OK for successful completion + /// + /// If the implementor supports returning a collection of supported media types, it should override + /// this method. The default implementation assumes our output type is the same as our input type. + /// + virtual protected int InternalGetOutputType(int dwOutputStreamIndex, int dwTypeIndex, out AMMediaType pmt) + { + int hr; + + if (InputTypeSet(dwOutputStreamIndex)) + { + if (dwTypeIndex == 0) + { + pmt = InputType(dwOutputStreamIndex); + hr = S_OK; + } + else + { + pmt = null; + hr = DMOResults.E_NoMoreItems; + } + } + else + { + pmt = null; + hr = DMOResults.E_TypeNotSet; + } + + return hr; + } + + /// + /// (Virtual) Retrieves the buffer requirements for a specified input stream + /// + /// Input stream number + /// Minimum size of an input buffer for this stream, in bytes + /// Maximum amount of data that the DMO will hold for lookahead, in bytes + /// the required buffer alignment, in bytes. If the input stream has no alignment requirement, the value is 1. + /// S_OK for successful operation + /// + /// The implementator could override this method to specify different values. The default + /// implementation reports that we can accept any alignment, hold no lookahead buffers, and the + /// input buffer must be at least 1 byte long. + /// + virtual protected int InternalGetInputSizeInfo(int dwInputStreamIndex, out int pcbSize, out int pcbMaxLookahead, out int pcbAlignment) + { + pcbSize = 1; + pcbMaxLookahead = 0; + pcbAlignment = 1; + + return S_OK; + } + + /// + /// (Virtual) Retrieves the maximum latency on a specified input stream + /// + /// Input stream number + /// Latency + /// S_OK for successful completion + /// + /// The latency is the difference between a time stamp on the input stream and the corresponding time + /// stamp on the output stream. The maximum latency is the largest possible difference in the time stamps. + /// The default implementation returns E_NOTIMPL indicating the DMO doesn't support reporting latency. + /// + virtual protected int InternalGetInputMaxLatency(int dwInputStreamIndex, out long prtMaxLatency) + { + prtMaxLatency = 0; + + return E_NOTIMPL; + } + + /// + /// (Virtual) Set the maximum latency on a specified input stream + /// + /// Input stream number + /// Maximum latency + /// S_OK for successful operation + /// + /// The default implementation returns E_NOTIMPL indicating the DMO doesn't support reporting latency. + /// + virtual protected int InternalSetInputMaxLatency(int dwInputStreamIndex, long rtMaxLatency) + { + return E_NOTIMPL; + } + + /// + /// (Virtual) Called to notify of a stream discontinuity + /// + /// Input stream number + /// S_OK for successful operation + /// + /// The default implementation assumes no special processing is required for discontinuities. + /// + virtual protected int InternalDiscontinuity(int dwInputStreamIndex) + { + return S_OK; + } + + + #endregion + + #region IMediaObject methods + + /// + /// COM entry point for IMediaObject.GetStreamCount + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int GetStreamCount(out int pulNumberOfInputStreams, out int pulNumberOfOutputStreams) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write("GetStreamCount"); + + // Return the number of input/output streams + pulNumberOfInputStreams = m_NumInputs; + pulNumberOfOutputStreams = m_NumOutputs; + + m_Log.WriteNoTS(string.Format(" {0}:{1}\r\n", m_NumInputs, m_NumOutputs)); + + hr = S_OK; + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have these to make the compiler happy. Should be safe since + // GetStreamCount is doc'ed not to accept NULLs. + pulNumberOfInputStreams = 0; + pulNumberOfOutputStreams = 0; + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.GetInputStreamInfo + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int GetInputStreamInfo(int ulStreamIndex, out DMOInputStreamInfo pdwFlags) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + pdwFlags = 0; + m_Log.Write("GetInputStreamInfo"); + + // Validate the stream number + if (ulStreamIndex < m_NumInputs && ulStreamIndex >= 0) + { + // Call the internal function to get the value + hr = InternalGetInputStreamInfo(ulStreamIndex, out pdwFlags); + + // Validate the value returned by the internal function + Debug.Assert(0 == (pdwFlags & ~(DMOInputStreamInfo.WholeSamples | + DMOInputStreamInfo.SingleSamplePerBuffer | + DMOInputStreamInfo.FixedSampleSize | + DMOInputStreamInfo.HoldsBuffers))); + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + + m_Log.WriteNoTS(string.Format(": {0}\r\n", hr)); + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pdwFlags = 0; + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.GetOutputStreamInfo + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int GetOutputStreamInfo(int ulStreamIndex, out DMOOutputStreamInfo pdwFlags) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + pdwFlags = 0; + m_Log.Write(string.Format("GetOutputStreamInfo({0})", ulStreamIndex)); + + // Validate the stream number + if (ulStreamIndex < m_NumOutputs && ulStreamIndex >= 0) + { + // Call the internal function to get the value + hr = InternalGetOutputStreamInfo(ulStreamIndex, out pdwFlags); + + // Validate the value returned by the internal function + Debug.Assert(0 == (pdwFlags & ~(DMOOutputStreamInfo.WholeSamples | + DMOOutputStreamInfo.SingleSamplePerBuffer | + DMOOutputStreamInfo.FixedSampleSize | + DMOOutputStreamInfo.Discardable | + DMOOutputStreamInfo.Optional))); + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + + m_Log.WriteNoTS(string.Format("= {1}: {0}\r\n", hr, pdwFlags)); + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pdwFlags = 0; + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.GetInputType + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int GetInputType(int ulStreamIndex, int ulTypeIndex, AMMediaType pmt) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write(string.Format("GetInputType({0}, {1})", ulStreamIndex, ulTypeIndex)); + + // Validate the stream number + if (ulStreamIndex < m_NumInputs && ulStreamIndex >= 0 ) + { + AMMediaType pmt2; + + // Call the internal method to get the MediaType + hr = InternalGetInputType(ulStreamIndex, ulTypeIndex, out pmt2); + + // If InternalGetInputType returned a value, and if the caller + // provided a place for it, copy it over + if (hr >= 0 && pmt != null) + { + DMOUtils.MoCopyMediaType(pmt, pmt2); + } + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + m_Log.WriteNoTS(string.Format("= {0}\r\n", hr)); + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.GetOutputType + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int GetOutputType(int ulStreamIndex, int ulTypeIndex, AMMediaType pmt) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write(string.Format("GetOutputType({0}, {1})", ulStreamIndex, ulTypeIndex)); + + // Validate the stream number + if (ulStreamIndex < m_NumOutputs && ulStreamIndex >= 0) + { + AMMediaType pmt2; + + hr = InternalGetOutputType(ulStreamIndex, ulTypeIndex, out pmt2); + + // If InternalGetInputType returned a value, and if the caller + // provided a place for it, copy it over + if (hr >= 0) + { + m_Log.WriteNoTS(string.Format(" out:{0}", DsToString.AMMediaTypeToString(pmt2))); + if (pmt != null) + { + DMOUtils.MoCopyMediaType(pmt, pmt2); + } + } + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + + m_Log.WriteNoTS(string.Format(": {0}\r\n", hr)); + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.GetInputCurrentType + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int GetInputCurrentType(int ulStreamIndex, AMMediaType pmt) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + pmt = null; + m_Log.Write("GetInputCurrentType\r\n"); + + // Validate the stream number + if (ulStreamIndex < m_NumInputs && ulStreamIndex >= 0) + { + // If there *is* a current type + if (InputTypeSet(ulStreamIndex)) + { + pmt = MoCloneMediaType(m_InputInfo[ulStreamIndex].CurrentMediaType); + hr = S_OK; + } + else + { + hr = DMOResults.E_TypeNotSet; + } + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pmt = null; + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.GetOutputCurrentType + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int GetOutputCurrentType(int ulStreamIndex, AMMediaType pmt) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + pmt = null; + m_Log.Write("GetOutputCurrentType\r\n"); + + // Validate the stream number + if (ulStreamIndex < m_NumOutputs && ulStreamIndex >= 0) + { + // If there *is* a current type + if (OutputTypeSet(ulStreamIndex)) + { + pmt = MoCloneMediaType(m_OutputInfo[ulStreamIndex].CurrentMediaType); + hr = S_OK; + } + else + { + hr = DMOResults.E_TypeNotSet; + } + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pmt = null; + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.GetInputSizeInfo + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int GetInputSizeInfo(int ulStreamIndex, out int pulSize, out int pcbMaxLookahead, out int pulAlignment) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + pulSize = 0; + pcbMaxLookahead = 0; + pulAlignment = 0; + + m_Log.Write("GetInputSizeInfo"); + + // Validate the stream number + if (ulStreamIndex < m_NumInputs && ulStreamIndex >= 0) + { + // If there is a type set (otherwise, how can we report a size for it?) + if (InputTypeSet(ulStreamIndex)) + { + hr = InternalGetInputSizeInfo(ulStreamIndex, out pulSize, out pcbMaxLookahead, out pulAlignment); + } + else + { + hr = DMOResults.E_TypeNotSet; + } + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + m_Log.WriteNoTS(string.Format("= {0} {1} {2} : {3}\r\n", pulSize, pcbMaxLookahead, pulAlignment, hr)); + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pulSize = 0; + pcbMaxLookahead = 0; + pulAlignment = 0; + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.GetOutputSizeInfo + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int GetOutputSizeInfo(int ulStreamIndex, out int pulSize, out int pulAlignment) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + pulSize = 0; + pulAlignment = 0; + m_Log.Write("GetOutputSizeInfo\r\n"); + + // Validate the stream number + if (ulStreamIndex < m_NumOutputs && ulStreamIndex >= 0) + { + // If there is a type set (otherwise, how can we report a size for it?) + if (m_fTypesSet && OutputTypeSet(ulStreamIndex)) + { + hr = InternalGetOutputSizeInfo(ulStreamIndex, out pulSize, out pulAlignment); + } + else + { + hr = DMOResults.E_TypeNotSet; + } + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pulSize = 0; + pulAlignment = 0; + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.SetInputType + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int SetInputType(int ulStreamIndex, AMMediaType pmt, DMOSetType dwFlags) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write(string.Format("SetInputType({0}, {1})", ulStreamIndex, dwFlags)); + + // Validate the stream number + if (ulStreamIndex >= m_NumInputs || ulStreamIndex < 0) + { + return DMOResults.E_InvalidStreamIndex; + } + + // Validate the flags + if ( (dwFlags & ~ (DMOSetType.Clear | DMOSetType.TestOnly)) > 0) + { + return E_INVALIDARG; + } + + // If they requested to clear the current type + if ((dwFlags & DMOSetType.Clear) > 0) + { + DsUtils.FreeAMMediaType(m_InputInfo[ulStreamIndex].CurrentMediaType); + m_InputInfo[ulStreamIndex].fTypeSet = false; + + // Re-check to see if all the non-optional streams still have types + if (!CheckAllTypesSet()) + { + // We aren't in a runnable state anymore, flush things + Flush(); + FreeStreamingResources(); + } + hr = S_OK; + } + else + { + if (null != pmt) + { + m_Log.WriteNoTS(string.Format(" requested in: {0}", DsToString.AMMediaTypeToString(pmt))); + + // Check to see if the type is already set + if (!InputTypeSet(ulStreamIndex)) + { + // Check to see if we support the requested format + hr = InternalCheckInputType(ulStreamIndex, pmt); + if (hr >= 0) + { + hr = S_OK; + + // If we weren't just being tested, actually set the type + if ( (dwFlags & DMOSetType.TestOnly) == 0) + { + m_Log.WriteNoTS(string.Format(" input: {0}", DsToString.AMMediaTypeToString(pmt))); + + // Free any previous mediatype + if (InputTypeSet(ulStreamIndex)) + { + DsUtils.FreeAMMediaType(m_InputInfo[ulStreamIndex].CurrentMediaType); + } + m_InputInfo[ulStreamIndex].CurrentMediaType = MoCloneMediaType(pmt); + m_InputInfo[ulStreamIndex].fTypeSet = true; + + // Re-check to see if all the non-optional streams still have types + CheckAllTypesSet(); + } + } + } + else + { + // Type is set, so reject any type that's not identical + if (TypesMatch(pmt, InputType(ulStreamIndex))) + { + hr = S_OK; + } + else + { + hr = DMOResults.E_InvalidType; + } + } + } + else + { + hr = E_POINTER; + } + } + + m_Log.WriteNoTS(string.Format(":{0}\r\n", hr)); + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.SetOutputType + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int SetOutputType(int ulStreamIndex, AMMediaType pmt, DMOSetType dwFlags) + { + int hr = S_OK; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write(string.Format("SetOutputType({0}, {1})", ulStreamIndex, dwFlags)); + + // Validate the stream number + if (ulStreamIndex >= m_NumOutputs || ulStreamIndex < 0) + { + return DMOResults.E_InvalidStreamIndex; + } + + // Validate the flags + if ( (dwFlags & ~ (DMOSetType.Clear | DMOSetType.TestOnly)) > 0) + { + return E_INVALIDARG; + } + + // If they requested to clear the current type + if ( (dwFlags & DMOSetType.Clear) > 0) + { + DsUtils.FreeAMMediaType(m_OutputInfo[ulStreamIndex].CurrentMediaType); + m_OutputInfo[ulStreamIndex].fTypeSet = false; + + // Re-check to see if all the non-optional streams still have types + if (!CheckAllTypesSet()) + { + // We aren't in a runnable state anymore, flush things + Flush(); + FreeStreamingResources(); + } + hr = S_OK; + } + else + { + if (null != pmt) + { + m_Log.WriteNoTS(string.Format(" requested out: {0}", DsToString.AMMediaTypeToString(pmt))); + + // Check if the type is already set + if (!OutputTypeSet(ulStreamIndex)) + { + // Check to see if we support the requested format + hr = InternalCheckOutputType(ulStreamIndex, pmt); + if (hr >= 0) + { + hr = S_OK; + + // If we weren't just being tested, actually set the type + if ( (dwFlags & DMOSetType.TestOnly) == 0) + { + // Free any previous mediatype + if (OutputTypeSet(ulStreamIndex)) + { + DsUtils.FreeAMMediaType(m_OutputInfo[ulStreamIndex].CurrentMediaType); + } + m_OutputInfo[ulStreamIndex].CurrentMediaType = MoCloneMediaType(pmt); + m_OutputInfo[ulStreamIndex].fTypeSet = true; + + // Re-check to see if all the non-optional streams still have types + CheckAllTypesSet(); + } + } + } + else + { + // Type is set, so reject any type that's not identical + if (!TypesMatch(pmt, OutputType(ulStreamIndex))) + { + hr = DMOResults.E_InvalidType; + } + else + { + hr = S_OK; + } + } + } + else + { + hr = E_POINTER; + } + } + + m_Log.WriteNoTS(string.Format(":{0}\r\n", hr)); + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.GetInputStatus + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int GetInputStatus(int ulStreamIndex, out DMOInputStatusFlags pdwStatus) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + pdwStatus = DMOInputStatusFlags.None; + m_Log.Write("GetInputStatus\r\n"); + + // Validate the stream number + if (ulStreamIndex < m_NumInputs && ulStreamIndex >= 0) + { + if (m_fTypesSet) + { + hr = InternalAcceptingInput(ulStreamIndex); + if (hr == S_OK) + { + pdwStatus |= DMOInputStatusFlags.AcceptData; + } + else if (hr == S_FALSE) + { + // Not an error, we just aren't accepting input right now + hr = S_OK; + } + } + else + { + hr = DMOResults.E_TypeNotSet; + } + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pdwStatus = DMOInputStatusFlags.None; + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.GetInputMaxLatency + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int GetInputMaxLatency(int ulStreamIndex, out long prtLatency) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + prtLatency = 0; + m_Log.Write("GetInputMaxLatency\r\n"); + + // Validate the stream number + if (ulStreamIndex < m_NumInputs && ulStreamIndex >= 0) + { + hr = InternalGetInputMaxLatency(ulStreamIndex, out prtLatency); + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + prtLatency = 0; + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.SetInputMaxLatency + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int SetInputMaxLatency(int ulStreamIndex, long rtLatency) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write("SetInputMaxLatency\r\n"); + + // Validate the stream number + if (ulStreamIndex < m_NumInputs && ulStreamIndex >= 0) + { + hr = InternalSetInputMaxLatency(ulStreamIndex, rtLatency); + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.Discontinuity + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int Discontinuity(int ulStreamIndex) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write("Discontinuity\r\n"); + + // Validate the stream number + if (ulStreamIndex < m_NumInputs && ulStreamIndex >= 0) + { + if (m_fTypesSet) + { + // If we are accepting input, tell the internal + // functions about the Discontinuity. + hr = InternalAcceptingInput(ulStreamIndex); + if (S_OK == hr) + { + hr = InternalDiscontinuity(ulStreamIndex); + } + else + { + // No one cares, just return an error + hr = DMOResults.E_NotAccepting; + } + } + else + { + hr = DMOResults.E_TypeNotSet; + } + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.Flush + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int Flush() + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write("Flush()"); + + // Only call the internal flush if there is something to flush + if (m_fTypesSet && !m_fFlushed) + { + hr = InternalFlush(); + } + else + { + hr = S_OK; + } + + m_fFlushed = true; + m_Log.WriteNoTS(string.Format(": {0}\r\n", hr)); + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.AllocateStreamingResources + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int AllocateStreamingResources() + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write("AllocateStreamingResources"); + + // Don't allocate resources until all streams have a type + if (m_fTypesSet) + { + // Only need to call it once + if (!m_fResourcesAllocated) + { + hr = InternalAllocateStreamingResources(); + if (hr >= 0) + { + m_fResourcesAllocated = true; + } + } + else + { + hr = S_OK; + } + } + else + { + hr = DMOResults.E_TypeNotSet; + } + + m_Log.WriteNoTS(string.Format(":{0}\r\n", hr)); + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.FreeStreamingResources + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int FreeStreamingResources() + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write("FreeStreamingResources\r\n"); + + if (m_fResourcesAllocated) + { + m_fResourcesAllocated = false; + InternalFlush(); + hr = InternalFreeStreamingResources(); + GC.Collect(); + } + else + { + hr = S_OK; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.ProcessInput + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int ProcessInput( + int ulStreamIndex, + IMediaBuffer pBuffer, + DMOInputDataBuffer dwFlags, + long rtTimestamp, + long rtTimelength + ) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write(string.Format("ProcessInput ({0}, {1}, {2}, {3})\r\n", ulStreamIndex, dwFlags, rtTimestamp, rtTimelength)); + + if (pBuffer != null) + { + // Validate the stream number + if (ulStreamIndex < m_NumInputs && ulStreamIndex >= 0) + { + // Validate flags + if ( (dwFlags & ~(DMOInputDataBuffer.SyncPoint | + DMOInputDataBuffer.Time | + DMOInputDataBuffer.TimeLength)) == 0) + { + // Make sure all streams have media types set and resources are allocated + hr = AllocateStreamingResources(); + if (hr >= 0) + { + // If we aren't accepting input, forget it + if (InternalAcceptingInput(ulStreamIndex) == S_OK) + { + m_fFlushed = false; + + hr = InternalProcessInput( + ulStreamIndex, + pBuffer, + dwFlags, + rtTimestamp, + rtTimelength); + } + else + { + hr = DMOResults.E_NotAccepting; + } + } + } + else + { + hr = E_INVALIDARG; + } + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + } + else + { + hr = E_POINTER; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + + /// + /// COM entry point for IMediaObject.ProcessOutput + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int ProcessOutput( + DMOProcessOutput dwFlags, + int ulOutputBufferCount, + DMOOutputDataBuffer [] pOutputBuffers, + out int pdwStatus) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write("ProcessOutput\r\n"); + pdwStatus = 0; + + // The number of buffers needs to exactly equal the number of streams + if (ulOutputBufferCount == m_NumOutputs && ( (dwFlags & ~DMOProcessOutput.DiscardWhenNoBuffer) == 0)) + { + // If there are output streams, pOutputBuffers can't be null + if (m_NumOutputs > 0 || pOutputBuffers != null) + { + hr = AllocateStreamingResources(); + if (hr >= 0) + { + // Init the status flags to zero + int dw; + for (dw = 0; dw < m_NumOutputs; dw++) + { + pOutputBuffers[dw].dwStatus = DMOOutputDataBufferFlags.None; + } + + // Fill the buffers + hr = InternalProcessOutput( + dwFlags, + ulOutputBufferCount, + pOutputBuffers, + out pdwStatus); + + // remember the DMO's incomplete status + for (dw = 0; dw < m_NumOutputs; dw++) + { + if ( (pOutputBuffers[dw].dwStatus & DMOOutputDataBufferFlags.InComplete) > 0) + { + m_OutputInfo[dw].fIncomplete = true; + } + else + { + m_OutputInfo[dw].fIncomplete = false; + } + } + } + } + else + { + hr = E_POINTER; + } + } + else + { + hr = E_INVALIDARG; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pdwStatus = 0; + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.Lock + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int Lock(bool lLock) + { + // Lock is doc'ed to limit access to multiple threads at the same time. We + // are doing that with the lock(this) in each entry point, so this is redundant. + return S_OK; + } + + + #endregion + + #region IMediaParamInfo Members + + /// + /// COM entry point for IMediaParamInfo.GetParamCount + /// + /// + /// There should be no need to modify or override this method. See + /// and + /// for details about how this works. + /// + public int GetParamCount(out int pdwParams) + { + int hr; + + try + { + lock(this) + { + m_Log.Write("GetParamCount\r\n"); + + pdwParams = m_Params.Parms.Length; + hr = S_OK; + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pdwParams = 0; + } + + return hr; + } + + /// + /// COM entry point for IMediaParamInfo.GetSupportedTimeFormat + /// + /// + /// There should be no need to modify or override this method. See + /// and + /// for details about how this works. + /// + public int GetSupportedTimeFormat(int dwFormatIndex, out Guid pguidTimeFormat) + { + int hr; + + try + { + m_Log.Write("GetSupportedTimeFormat\r\n"); + lock(this) + { + // If the index is in range, return the specified timeformat + if (dwFormatIndex < m_Params.TimeFormats.Length) + { + pguidTimeFormat = m_Params.TimeFormats[dwFormatIndex]; + hr = S_OK; + } + else + { + pguidTimeFormat = Guid.Empty; + hr = E_INVALIDARG; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pguidTimeFormat = Guid.Empty; + } + + return hr; + } + + /// + /// COM entry point for IMediaParamInfo.GetParamInfo + /// + /// + /// There should be no need to modify or override this method. See + /// and + /// for details about how this works. + /// + public int GetParamInfo(int dwParamIndex, out ParamInfo pInfo) + { + int hr; + + try + { + m_Log.Write("GetParamInfo\r\n"); + lock(this) + { + // If the parameter is in range, return the ParamInfo + if (dwParamIndex < m_Params.Parms.Length) + { + pInfo = m_Params.Parms[dwParamIndex]; + hr = S_OK; + } + else + { + pInfo = new ParamInfo(); + hr = E_INVALIDARG; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pInfo = new ParamInfo(); + } + + return hr; + } + + /// + /// COM entry point for IMediaParamInfo.GetCurrentTimeFormat + /// + /// + /// There should be no need to modify or override this method. See + /// and + /// for details about how this works. + /// + public int GetCurrentTimeFormat(out Guid pguidTimeFormat, out int pTimeData) + { + int hr; + + try + { + m_Log.Write("GetCurrentTimeFormat\r\n"); + lock(this) + { + // Return the current time format from the array + pguidTimeFormat = m_Params.TimeFormats[m_Params.CurrentTimeFormat]; + pTimeData = m_Params.TimeData; + + hr = S_OK; + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pguidTimeFormat = Guid.Empty; + pTimeData = 0; + } + + return hr; + } + + /// + /// COM entry point for IMediaParamInfo.GetParamText + /// + /// + /// There should be no need to modify or override this method. See + /// and + /// for details about how this works. + /// + public int GetParamText(int dwParamIndex, out IntPtr ppwchText) + { + int hr; + + try + { + m_Log.Write("GetParamText\r\n"); + lock(this) + { + // If the parameter is in range, return the text + if (dwParamIndex < m_Params.ParamText.Length) + { + ppwchText = Marshal.StringToCoTaskMemUni(m_Params.ParamText[dwParamIndex]); + hr = S_OK; + } + else + { + ppwchText = IntPtr.Zero; + hr = E_INVALIDARG; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + ppwchText = IntPtr.Zero; + } + + return hr; + } + + /// + /// COM entry point for IMediaParamInfo.GetNumTimeFormats + /// + /// + /// There should be no need to modify or override this method. See + /// and + /// for details about how this works. + /// + public int GetNumTimeFormats(out int pdwNumTimeFormats) + { + int hr; + + try + { + m_Log.Write("GetNumTimeFormats\r\n"); + lock(this) + { + pdwNumTimeFormats = m_Params.TimeFormats.Length; + hr = S_OK; + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pdwNumTimeFormats = 0; + } + + return hr; + } + + #endregion + + #region IMediaParams Members + + /// + /// COM entry point for IMediaParams.SetTimeFormat + /// + /// + /// There should be no need to modify or override this method. See + /// and + /// for details about how this works. + /// + public int SetTimeFormat(Guid guidTimeFormat, int mpTimeData) + { + int hr = E_INVALIDARG; + + try + { + lock(this) + { + m_Log.Write("SetTimeFormat\r\n"); + + // Scan the array of timeformats looking for a match + for (int x=0; x < m_Params.TimeFormats.Length; x++) + { + if (guidTimeFormat == m_Params.TimeFormats[x]) + { + // Found one, grab the index & store the TimeData + m_Params.CurrentTimeFormat = x; + m_Params.TimeData = mpTimeData; + hr = S_OK; + break; + } + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + /// + /// COM entry point for IMediaParams.SetParam + /// + /// + /// There should be no need to modify or override this method. See + /// and + /// for details about how this works. + /// + public int SetParam(int dwParamIndex, MPData value) + { + int hr; + + try + { + lock(this) + { + m_Log.Write("SetParam\r\n"); + + // Check to see if the index is in range + if (dwParamIndex < m_Params.Parms.Length && dwParamIndex >= 0) + { + // Make an envelope that spans from current to end of stream + MPEnvelopeSegment m = new MPEnvelopeSegment(); + + m.flags = MPFlags.Standard; + m.iCurve = MPCaps.Jump; + m.rtStart = 0; + m.rtEnd = long.MaxValue; + m.valStart = value; + m.valEnd = value; + + // Add the struct to the envelope + hr = m_Params.Envelopes[dwParamIndex].AddSegment(m); + } + else + { + hr = E_INVALIDARG; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + + return hr; + } + + /// + /// COM entry point for IMediaParams.AddEnvelope + /// + /// + /// There should be no need to modify or override this method. See + /// and + /// for details about how this works. + /// + public int AddEnvelope(int dwParamIndex, int cSegments, MPEnvelopeSegment[] pEnvelopeSegments) + { + int hr; + + try + { + lock(this) + { + m_Log.Write("AddEnvelope\r\n"); + + hr = S_OK; + + if (dwParamIndex == ALLPARAMS) + { + // Add all the envelopes to all the parameters + for (int y = 0; y < m_Params.Parms.Length && hr >= 0; y++) + { + for (int x = 0; x < cSegments && hr >= 0; x++) + { + // Add the struct to the envelope + hr = m_Params.Envelopes[y].AddSegment(pEnvelopeSegments[x]); + } + } + } + else if (dwParamIndex < m_Params.Parms.Length && dwParamIndex >= 0) + { + // Add all the envelopes to the specified parameter + for (int x = 0; x < cSegments && hr >= 0; x++) + { + // Add the struct to the envelope + hr = m_Params.Envelopes[dwParamIndex].AddSegment(pEnvelopeSegments[x]); + } + } + else + { + hr = E_INVALIDARG; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + /// + /// COM entry point for IMediaParams.GetParam + /// + /// + /// There should be no need to modify or override this method. See + /// and + /// for details about how this works. + /// + public int GetParam(int dwParamIndex, out MPData pValue) + { + int hr; + + try + { + lock(this) + { + m_Log.Write("GetParam\r\n"); + + // If the requested parameter is within range + if (dwParamIndex < m_Params.Parms.Length && dwParamIndex >= 0) + { + // Read the value + pValue = m_Params.Envelopes[dwParamIndex].CalcValueForTime(InternalGetCurrentTime()); + hr = S_OK; + } + else + { + pValue = new MPData(); + hr = E_INVALIDARG; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pValue = new MPData(); + } + + return hr; + } + + /// + /// COM entry point for IMediaParams.FlushEnvelope + /// + /// + /// There should be no need to modify or override this method. See + /// and + /// for details about how this works. + /// + public int FlushEnvelope(int dwParamIndex, long refTimeStart, long refTimeEnd) + { + int hr; + + try + { + lock(this) + { + m_Log.Write("FlushEnvelope\r\n"); + + // If the time range makes sense + if ( (refTimeStart >= 0) && (refTimeEnd >= refTimeStart) ) + { + if (dwParamIndex == ALLPARAMS) + { + hr = S_OK; + + // Apply the flush to all parameters + for (int x=0; x < m_Params.Parms.Length && hr >= 0; x++) + { + MPEnvelopeSegment m = new MPEnvelopeSegment(); + + m.flags = MPFlags.Standard; + m.iCurve = MPCaps.Jump; + m.rtStart = refTimeStart; + m.rtEnd = refTimeEnd; + m.valStart = m_Params.Parms[x].mpdNeutralValue; + m.valEnd = m_Params.Parms[x].mpdNeutralValue; + + hr = m_Params.Envelopes[dwParamIndex].AddSegment(m); + } + } + else if (dwParamIndex < m_Params.Parms.Length) + { + // Apply the flush to the specified parameter + MPEnvelopeSegment m = new MPEnvelopeSegment(); + + m.flags = MPFlags.Standard; + m.iCurve = MPCaps.Jump; + m.rtStart = refTimeStart; + m.rtEnd = refTimeEnd; + m.valStart = m_Params.Parms[dwParamIndex].mpdNeutralValue; + m.valEnd = m_Params.Parms[dwParamIndex].mpdNeutralValue; + + hr = m_Params.Envelopes[dwParamIndex].AddSegment(m); + } + else + { + hr = E_INVALIDARG; + } + } + else + { + hr = E_INVALIDARG; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + #endregion + } + + + /// + /// Pretty lame logging class. Note that during Release builds + /// logging is disabled. + /// + internal class Logging : IDisposable + { +#if DEBUG + private static StreamWriter f = new StreamWriter(@"c:\mog.txt", true); + private int m_Instance; +#endif + + /// + /// Constructor + /// + /// Instance number. Written as part of the header. + public Logging(int i) + { +#if DEBUG + m_Instance = i; +#endif + } + + /// + /// Destructor + /// + ~Logging() + { +#if DEBUG + if (f != null) + { + try + { + f.Close(); + f = null; + } + catch {} + } +#endif + } + + /// + /// Write to the log file without writing the header (Date/Time/Instance). + /// + /// String to write + public void WriteNoTS(string s) + { +#if DEBUG + try + { + if (f != null) + { + f.Write(s); + f.Flush(); + } + } + catch {} +#endif + } + + /// + /// Write an entry to the log file + /// + /// String to write + public void Write(string s) + { +#if DEBUG + try + { + if (f != null) + { + f.Write(string.Format("{0} ({2})- {1}", DateTime.Now, s, m_Instance)); + f.Flush(); + } + } + catch {} +#endif + } + #region IDisposable Members + + /// + /// Dispose + /// + public void Dispose() + { +#if DEBUG + if (f != null) + { + try + { + f.Close(); + f = null; + GC.SuppressFinalize(this); + } + catch {} + } +#endif + } + + + #endregion + } +} diff --git a/Samples/DMO/DmoFlip/DMO/docs/IMediaObjectImpl.chm b/Samples/DMO/DmoFlip/DMO/docs/IMediaObjectImpl.chm new file mode 100644 index 0000000000000000000000000000000000000000..4811fba7d614c279a6a8ba3183853281eb56da2c GIT binary patch literal 60566 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 + + + + + This namespace (and the classes in it) are designed to be used to implement DMOs in .NET. The IMediaObjectImpl class is an abstract class which contains implementations for all the IMediaObject, IMediaParamInfo, and IMediaParams interfaces. There are a number of abstract methods in this class which must be implemented, and some virtual methods which can be overridden if necessary. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/DMO/DmoFlip/FormDMO/App.ico b/Samples/DMO/DmoFlip/FormDMO/App.ico new file mode 100644 index 0000000000000000000000000000000000000000..3a5525fd794f7a7c5c8e6187f470ea3af38cd2b6 GIT binary patch literal 1078 zcmeHHJr05}7=1t!Hp3A*8IHkVf+j?-!eHY14Gtcw1Eb*_9>Bq^zETJ@GKj{_2j4$w zo9}xCh!8{T3=X##Skq>ikMjsvB|y%crWBM2iW(4pI}c%z6%lW!=~4v77#3{z!dmB1 z__&l)-{KUYR+|8|;wB^R|9ET$J@(@=#rd^=)qs85?vAy(PSF5CyNkus435LVkZ$rj zNw|JG-P7^hF<(;#o*Vk}5R#e|^13tBbQkeF?djULtvqyxd3<{9 literal 0 HcmV?d00001 diff --git a/Samples/DMO/DmoFlip/FormDMO/AssemblyInfo.cs b/Samples/DMO/DmoFlip/FormDMO/AssemblyInfo.cs new file mode 100644 index 0000000..9f89a32 --- /dev/null +++ b/Samples/DMO/DmoFlip/FormDMO/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/DMO/DmoFlip/FormDMO/Form1.cs b/Samples/DMO/DmoFlip/FormDMO/Form1.cs new file mode 100644 index 0000000..4d82ec4 --- /dev/null +++ b/Samples/DMO/DmoFlip/FormDMO/Form1.cs @@ -0,0 +1,426 @@ +#region license + +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +#endregion + +using System; +using System.Diagnostics; +using System.Drawing; +using System.Windows.Forms; +using System.Runtime.InteropServices; + +using DirectShowLib; +using DirectShowLib.DMO; + +namespace FormDMO +{ + /// + /// Summary description for Form1. + /// + public class Form1 : System.Windows.Forms.Form + { + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Button button2; + private System.Windows.Forms.Button button3; + + private IFilterGraph2 graphBuilder = null; + private IMediaParams m_param = null; + private System.Windows.Forms.TextBox textBox1; + private DsROTEntry m_rot = null; + + public Form1() + { + // + // Required for Windows Form Designer support + // + InitializeComponent(); + BuildGraph(this.panel1); +#if !USING_NET11 + textBox1.Text = "Running this code under the debugger in vs 2005 will give VERY poor performance. Use \"Debug/Start without Debugging\" or use the unsafe code from the readme for decent performance."; +#endif + // + // TODO: Add any constructor code after InitializeComponent call + // + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + base.Dispose( disposing ); + if (m_param != null) + { + Marshal.ReleaseComObject(m_param); + m_param = null; + } + + if (m_rot != null) + { + m_rot.Dispose(); + m_rot = null; + } + + if (graphBuilder != null) + { + (graphBuilder as IMediaControl).Stop(); + Marshal.ReleaseComObject(graphBuilder); + graphBuilder = null; + } + } + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.button1 = new System.Windows.Forms.Button(); + this.panel1 = new System.Windows.Forms.Panel(); + this.button2 = new System.Windows.Forms.Button(); + this.button3 = new System.Windows.Forms.Button(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.SuspendLayout(); + // + // button1 + // + this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.button1.Location = new System.Drawing.Point(8, 294); + this.button1.Name = "button1"; + this.button1.TabIndex = 0; + this.button1.Text = "Start"; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // panel1 + // + this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.panel1.Location = new System.Drawing.Point(0, 0); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(296, 216); + this.panel1.TabIndex = 1; + // + // button2 + // + this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.button2.Location = new System.Drawing.Point(104, 294); + this.button2.Name = "button2"; + this.button2.TabIndex = 2; + this.button2.Text = "FlipX"; + this.button2.Click += new System.EventHandler(this.button2_Click); + // + // button3 + // + this.button3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.button3.Location = new System.Drawing.Point(208, 294); + this.button3.Name = "button3"; + this.button3.TabIndex = 3; + this.button3.Text = "FlipY"; + this.button3.Click += new System.EventHandler(this.button3_Click); + // + // textBox1 + // + this.textBox1.Enabled = false; + this.textBox1.Location = new System.Drawing.Point(8, 224); + this.textBox1.Multiline = true; + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size(280, 64); + this.textBox1.TabIndex = 4; + this.textBox1.Text = ""; + // + // Form1 + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(292, 324); + this.Controls.Add(this.textBox1); + this.Controls.Add(this.button3); + this.Controls.Add(this.button2); + this.Controls.Add(this.panel1); + this.Controls.Add(this.button1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.Name = "Form1"; + this.Text = "DMOFlip Test"; + this.ResumeLayout(false); + + } + #endregion + + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.Run(new Form1()); + } + + + private void button1_Click(object sender, System.EventArgs e) + { + int hr; + + // Run this graph (just for fun) + hr = (graphBuilder as IMediaControl).Run(); + DsError.ThrowExceptionForHR(hr); + } + + private void BuildGraph(Control hControl) + { + int hr; + DsDevice [] devs; + IBaseFilter ibfSource = null; + IBaseFilter dmoFilter = null; + IBaseFilter ibfRender = null; + IDMOWrapperFilter dmoWrapperFilter = null; + + ICaptureGraphBuilder2 icgb = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); + + graphBuilder = (IFilterGraph2) new FilterGraph(); +#if DEBUG + m_rot = new DsROTEntry(graphBuilder); +#endif + + hr = icgb.SetFiltergraph(graphBuilder); + DsError.ThrowExceptionForHR(hr); + + devs = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice); + + if (devs.Length < 1) + { + throw new Exception("This sample requires a capture device. If you don't " + + "have a capture device, change the BuildGraph routine to use AddSourceFilter " + + "and use a file."); + } + + // Add a source filter + hr = graphBuilder.AddSourceFilterForMoniker(devs[0].Mon, null, "Video Input Device", out ibfSource); + DsError.ThrowExceptionForHR(hr); + + // Add a DMO Wrapper Filter + dmoFilter = (IBaseFilter) new DMOWrapperFilter(); + dmoWrapperFilter = (IDMOWrapperFilter) dmoFilter; + + // Since I know the guid of the DMO I am looking for, I *could* do this. + //hr = dmoWrapperFilter.Init(new Guid("{7EF28FD7-E88F-45bb-9CDD-8A62956F2D75}"), DMOCatergory.VideoEffect); + //DMOError.ThrowExceptionForHR(hr); + + // But it is more useful to show how to scan for the DMO + Guid g = FindGuid("DmoFlip", DMOCategory.VideoEffect); + + hr = dmoWrapperFilter.Init(g, DMOCategory.VideoEffect); + DMOError.ThrowExceptionForHR(hr); + + SetDMOParams(dmoFilter); + + // Add it to the Graph + hr = graphBuilder.AddFilter(dmoFilter, "DMO Filter"); + DsError.ThrowExceptionForHR(hr); + + ibfRender = (IBaseFilter)new VideoRenderer(); + hr = graphBuilder.AddFilter(ibfRender, "renderer"); + DsError.ThrowExceptionForHR(hr); + + hr = icgb.RenderStream(null, null, ibfSource, dmoFilter, ibfRender); + DsError.ThrowExceptionForHR(hr); + + ConfigVideo(graphBuilder as IVideoWindow, hControl); + + Marshal.ReleaseComObject(ibfSource); + Marshal.ReleaseComObject(ibfRender); + } + + private Guid FindGuid(string gn, Guid cat) + { + int hr; + + IEnumDMO pEnum; + Guid [] g2 = new Guid[1]; + string [] sn = new String[1]; + + hr = DMOUtils.DMOEnum(cat, 0, 0, null, 0, null, out pEnum); + DMOError.ThrowExceptionForHR(hr); + + try + { + do + { + hr = pEnum.Next(1, g2, sn, IntPtr.Zero); + } while (hr == 0 && sn[0] != gn); + + // Handle any serious errors + DMOError.ThrowExceptionForHR(hr); + + if (hr != 0) + { + throw new Exception("Cannot find " + gn); + } + } + finally + { + Marshal.ReleaseComObject(pEnum); + } + + return g2[0]; + } + + private void ConfigVideo(IVideoWindow ivw, Control hControl) + { + int hr; + + hr = ivw.put_Owner(hControl.Handle); + DsError.ThrowExceptionForHR(hr); + + hr = ivw.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren | WindowStyle.ClipSiblings); + DsError.ThrowExceptionForHR( hr ); + + // Yes, make it visible + hr = ivw.put_Visible( OABool.True ); + DsError.ThrowExceptionForHR( hr ); + + // Move to upper left corner + Rectangle rc = hControl.ClientRectangle; + hr = ivw.SetWindowPosition( 0, 0, rc.Right, rc.Bottom ); + DsError.ThrowExceptionForHR( hr ); + + } + + private void SetDMOParams(IBaseFilter dmoWrapperFilter) + { + int hr; + Guid g; + int i; + int pc; + ParamInfo pInfo; + IMediaParamInfo paramInfo = dmoWrapperFilter as IMediaParamInfo; + + // With a little effort, a generic parameter handling routine + // could be produced. You know the number of parameters (GetParamCount), + // the type of the parameter (pInfo.mpType), the range of values for + // int and float (pInfo.mpdMinValue, pInfo.mpdMaxValue), if the parameter is an + // enum, you have the strings (GetParamText). + + hr = paramInfo.GetParamCount(out pc); + DMOError.ThrowExceptionForHR(hr); + + // Walk all the parameters + for (int pCur = 0; pCur< pc; pCur++) + { + IntPtr ip; + + hr = paramInfo.GetParamInfo(pCur, out pInfo); + DMOError.ThrowExceptionForHR(hr); + + hr = paramInfo.GetParamText(0, out ip); + DMOError.ThrowExceptionForHR(hr); + + try + { + string sName, sUnits; + string [] sEnum; + ParseParamText(ip, out sName, out sUnits, out sEnum); + + Debug.WriteLine(string.Format("Parameter name: {0}", sName)); + Debug.WriteLine(string.Format("Parameter units: {0}", sUnits)); + + // Not all params will have enumerated strings. + if (pInfo.mpType == MPType.ENUM) + { + // The final entry in "splitted" will be a blank (used to terminate the list). + for (int x=0; x < sEnum.Length; x++) + { + Debug.WriteLine(string.Format("Parameter Enum strings: {0} = {1}", x, sEnum[x])); + } + } + } + finally + { + Marshal.FreeCoTaskMem(ip); + } + } + + hr = paramInfo.GetCurrentTimeFormat(out g, out i); + DMOError.ThrowExceptionForHR(hr); + + hr = paramInfo.GetSupportedTimeFormat(0, out g); + DMOError.ThrowExceptionForHR(hr); + + MPData o = new MPData(); + m_param = dmoWrapperFilter as IMediaParams; + + o.vInt = 0; + hr = m_param.SetParam(0, o); + DMOError.ThrowExceptionForHR(hr); + } + + + private void button2_Click(object sender, System.EventArgs e) + { + int hr; + MPData o; + + hr = m_param.GetParam(0, out o); + DMOError.ThrowExceptionForHR(hr); + + o.vInt ^= 2; + + hr = m_param.SetParam(0, o); + DMOError.ThrowExceptionForHR(hr); + } + + private void button3_Click(object sender, System.EventArgs e) + { + int hr; + MPData o; + + hr = m_param.GetParam(0, out o); + DMOError.ThrowExceptionForHR(hr); + + o.vInt ^= 1; + + hr = m_param.SetParam(0, o); + DMOError.ThrowExceptionForHR(hr); + } + + // Break an the pointer to some ParamText into usable fields + private void ParseParamText(IntPtr ip, out string ParamName, out string ParamUnits, out string [] ParamEnum) + { + int iCount = 0; + string s; + + // Up to the first null is the display name + ParamName = Marshal.PtrToStringUni(ip); + ip = (IntPtr)(ip.ToInt32() + ((ParamName.Length + 1) * 2)); + + // Next is the units + ParamUnits = Marshal.PtrToStringUni(ip); + ip = (IntPtr)(ip.ToInt32() + ((ParamUnits.Length + 1) * 2)); + + // Following, there may b zero or more enum strings. First we count them. + IntPtr ip2 = ip; + while (Marshal.ReadInt16(ip2) != 0) // Terminate on a zero length string + { + s = Marshal.PtrToStringUni(ip2); + ip2 = (IntPtr)(ip2.ToInt32() + ((s.Length + 1) * 2)); + iCount++; + } + + // Now we allocate the array, and copy the values in. + ParamEnum = new string[iCount]; + for(int x=0; x < iCount; x++) + { + ParamEnum[x] = Marshal.PtrToStringUni(ip); + ip = (IntPtr)(ip.ToInt32() + ((ParamEnum[x].Length + 1) * 2)); + } + } + + } +} diff --git a/Samples/DMO/DmoFlip/FormDMO/Form1.resx b/Samples/DMO/DmoFlip/FormDMO/Form1.resx new file mode 100644 index 0000000..34c7e7c --- /dev/null +++ b/Samples/DMO/DmoFlip/FormDMO/Form1.resx @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + Private + + + Private + + + False + + + True + + + Private + + + 8, 8 + + + True + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + False + + + Private + + + False + + + (Default) + + + False + + + False + + + 8, 8 + + + Form1 + + + True + + + 80 + + + True + + + Private + + \ No newline at end of file diff --git a/Samples/DMO/DmoFlip/FormDMO/FormDMO-2005.csproj b/Samples/DMO/DmoFlip/FormDMO/FormDMO-2005.csproj new file mode 100644 index 0000000..71928cd --- /dev/null +++ b/Samples/DMO/DmoFlip/FormDMO/FormDMO-2005.csproj @@ -0,0 +1,110 @@ + + + Local + 8.0.50727 + 2.0 + {B72919DC-C5B9-441A-9AD9-6CF9A97AFE85} + Debug + AnyCPU + App.ico + + + FormDMO + + + JScript + Grid + IE50 + false + WinExe + FormDMO + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + + + Code + + + Form + + + Form1.cs + + + + + + + + + + \ No newline at end of file diff --git a/Samples/DMO/DmoFlip/FormDMO/FormDmoFlip.csproj b/Samples/DMO/DmoFlip/FormDMO/FormDmoFlip.csproj new file mode 100644 index 0000000..942cf6b --- /dev/null +++ b/Samples/DMO/DmoFlip/FormDMO/FormDmoFlip.csproj @@ -0,0 +1,142 @@ + + + + Local + 8.0.50727 + 2.0 + {B72919DC-C5B9-441A-9AD9-6CF9A97AFE85} + Debug + AnyCPU + App.ico + + + FormDMO + + + JScript + Grid + IE50 + false + WinExe + FormDMO + OnBuildSuccess + + + + + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + + + Code + + + Form + + + Form1.cs + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + + + + + + \ No newline at end of file diff --git a/Samples/DMO/DmoFlip/FormDMO/readme.txt b/Samples/DMO/DmoFlip/FormDMO/readme.txt new file mode 100644 index 0000000..dfd56ea --- /dev/null +++ b/Samples/DMO/DmoFlip/FormDMO/readme.txt @@ -0,0 +1,5 @@ +FormDmo - This code exercises the DMOFlip sample code. + +This rather simple-minded example shows how to build a graph using a DMO. It also reads +and sets the DMOFlip mode parameter, and reads parameter info (outputting the results with +Debug.WriteLine). \ No newline at end of file diff --git a/Samples/DMO/DmoFlip/readme.txt b/Samples/DMO/DmoFlip/readme.txt new file mode 100644 index 0000000..f4eaea5 --- /dev/null +++ b/Samples/DMO/DmoFlip/readme.txt @@ -0,0 +1,12 @@ +There are several readme's with this project. In addition to this file, there is a +readme in both the DMO and the FormDmo folders. + +The readme in the DmoForm folder talks about calling DMOs. The readme in the DMO +folder talks about the specific sample. + +There are detailed steps in the IMediaObjectImpl.chm talking about how to make a DMO. In particular, +you should look at the "IMediaObjectImpl Class" page in the file which provides step by step instructions +on how to write a DMO. + +For people who have never written a COM object, you may find the article at +http://community.borland.com/article/0,1410,32754,00.html to be informative. \ No newline at end of file diff --git a/Samples/DMO/DmoSplit/DMO/AssemblyInfo.cs b/Samples/DMO/DmoSplit/DMO/AssemblyInfo.cs new file mode 100644 index 0000000..9cdcce4 --- /dev/null +++ b/Samples/DMO/DmoSplit/DMO/AssemblyInfo.cs @@ -0,0 +1,21 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("DmoSplit")] +[assembly: AssemblyDescription("A DMO sample to split stereo audio to 2 mono streams")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("http://DirectShowNet.SourceForge.net")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("Public Domain")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: AssemblyVersion("1.0.0.0")] + +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyName("")] diff --git a/Samples/DMO/DmoSplit/DMO/DmoSplit-2005.csproj b/Samples/DMO/DmoSplit/DMO/DmoSplit-2005.csproj new file mode 100644 index 0000000..083233a --- /dev/null +++ b/Samples/DMO/DmoSplit/DMO/DmoSplit-2005.csproj @@ -0,0 +1,109 @@ + + + Local + 8.0.50727 + 2.0 + {369D647A-7F80-4F06-BEDB-D62AC1627862} + Debug + AnyCPU + + + + + DmoSplit + mykey.snk + JScript + Grid + IE50 + false + Library + DmoSplit + OnBuildSuccess + + + + + + + true + + + bin\Debug\ + false + 285212672 + false + + + DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 1 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + USING_NET20 + + + false + 4096 + false + + + false + false + false + false + 1 + none + prompt + + + + False + ..\..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Drawing + + + + + Code + + + Code + + + Code + + + + + + + + + + + "%25windir%25\Microsoft.NET\Framework\v2.0.50727\regasm" /nologo /codebase $(TargetPath) + + \ No newline at end of file diff --git a/Samples/DMO/DmoSplit/DMO/DmoSplit.cs b/Samples/DMO/DmoSplit/DMO/DmoSplit.cs new file mode 100644 index 0000000..9097869 --- /dev/null +++ b/Samples/DMO/DmoSplit/DMO/DmoSplit.cs @@ -0,0 +1,639 @@ +#region license + +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +#endregion + +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; +using MediaObjectTemplate; +using DirectShowLib; +using DirectShowLib.DMO; + +namespace DmoSplit +{ + /// + [ComVisible(true), Guid("EAB6CBA9-78DD-4ae4-9A69-1CE1C55369F6"), + ClassInterface(ClassInterfaceType.None)] + public class DmoSplit : IMediaObjectImpl + { + #region Declarations + + protected const long MAX_TIME = long.MaxValue; + + // Properties used to register the DMO in the registry + private const string DMOName = "DmoSplit"; + private static readonly Guid DMOCat = DMOCategory.AudioEffect; + private const int InputPinCount = 1; + private const int OutputPinCount = 2; + + // Parameter info + private const int NumParams = 0; + + #endregion + + #region APIs + + [DllImport("Kernel32.dll", EntryPoint="RtlMoveMemory")] + public static extern void CopyMemory(IntPtr Destination, IntPtr Source, [MarshalAs(UnmanagedType.U4)] int Length); + + #endregion + + #region Member Vars + + // Number of bits per sample (8 or 16) + private short m_Bits; + + // Currently processing buffer info (set once per buffer) + private long m_TimeStamp; + private long m_TimeLength; + private IMediaBuffer m_pBuffer; + private IntPtr m_InBuffer; + private int m_cbInData; + private DMOOutputDataBufferFlags m_Flags; + + #endregion + + #region Utility Functions + + /// + /// Register the DMO in the registry. Called by regasm. + /// + /// + [ComRegisterFunctionAttribute] + static private void DoRegister(Type t) + { + // Tell what media types you are able to support. This allows + // the smart connect capability of DS to avoid loading your DMO + // if it can't handle the stream type. + + // Note that you don't have to register any (but I recommend + // you do). Also, you don't have to provide a subtype (use + // Guid.Empty). You can negotiate this at run time in + // InternalCheckInputType. + DMOPartialMediatype [] pIn = new DMOPartialMediatype[1]; + pIn[0] = new DMOPartialMediatype(); + pIn[0].type = MediaType.Audio; + pIn[0].subtype = MediaSubType.PCM; + + DMOPartialMediatype [] pOut = new DMOPartialMediatype[1]; + pOut[0] = new DMOPartialMediatype(); + pOut[0].type = MediaType.Audio; + pOut[0].subtype = MediaSubType.PCM; + + int hr = DMOUtils.DMORegister( + DMOName, + typeof(DmoSplit).GUID, + DMOCat, + DMORegisterFlags.None, + pIn.Length, + pIn, + pOut.Length, + pOut + ); + } + + + /// + /// Remove the DMO from the registry + /// + /// + [ComUnregisterFunctionAttribute] + static private void UnregisterFunction(Type t) + { + int hr = DMOUtils.DMOUnregister(typeof(DmoSplit).GUID, DMOCat); + } + + + /// + /// Release all info for the most recent input buffer + /// + private void ReleaseInputBuffs() + { + if (m_pBuffer != null) + { + Marshal.ReleaseComObject(m_pBuffer); + m_pBuffer = null; + } + m_InBuffer = IntPtr.Zero; + m_cbInData = 0; + m_Flags = 0; + + // I specifically DON'T release the TimeStamp so we can keep track of where we are + } + + /// + /// Perform the split + /// + /// Number of bytes to process + /// Pointer to input buffer + /// Pointer to the output buffer for stream 1 + /// Pointer to the output buffer for stream 2 + /// + /// This routine would benefit greatly from being re-written in unsafe mode + /// + private void DoSplit( + int cbInData, + IntPtr pbInData, + IntPtr pbOutData1, + IntPtr pbOutData2 + ) + { + if (m_Bits == 16) + { + for (int x=0; x < cbInData; x+=4) + { + if (pbOutData1 != IntPtr.Zero) + { + Marshal.WriteInt16(pbOutData1, x / 2, Marshal.ReadInt16(pbInData, x)); + } + if (pbOutData2 != IntPtr.Zero) + { + Marshal.WriteInt16(pbOutData2, x / 2, Marshal.ReadInt16(pbInData, x + 2)); + } + } + } + else + { + for (int x=0; x < cbInData; x+=2) + { + if (pbOutData1 != IntPtr.Zero) + { + Marshal.WriteByte(pbOutData1, x, Marshal.ReadByte(pbInData, x)); + } + if (pbOutData2 != IntPtr.Zero) + { + Marshal.WriteByte(pbOutData2, x, Marshal.ReadByte(pbInData, x + 1)); + } + } + } + } + + #endregion + + /// + /// The constructor. The parameters to the base class + /// describe the number of input and output streams, which + /// DirectShow calls Pins, followed by the number of parameters + /// this class supports (can be zero), and the timeformat of those + /// parameters (should include ParamClass.TimeFormatFlags.Reference + /// if NumParameters > 0). + /// + public DmoSplit() : base(InputPinCount, OutputPinCount, NumParams, TimeFormatFlags.Reference) + { + m_Log.Write("Constructor\r\n"); + + // Initialize the data members + m_TimeStamp = 0; + m_TimeLength = 0; + m_cbInData = 0; + m_Flags = 0; + m_InBuffer = IntPtr.Zero; + m_pBuffer = null; + } + + + #region IMediaObjImpl Members + + /// + /// Given a specific AMMediaType, we are asked if we support it + /// + /// Stream number + /// The AMMediaType to check + /// S_OK if it is supported, DMOResults.E_InvalidType if not + override protected int InternalCheckInputType(int dwInputStreamIndex, AMMediaType pmt) + { + int hr; + + // Check the format is defined + if (pmt.majorType == MediaType.Audio && + (pmt.subType == MediaSubType.PCM) && + pmt.formatType == FormatType.WaveEx && + pmt.formatPtr != IntPtr.Zero) + { + WaveFormatEx wav = new WaveFormatEx(); + Marshal.PtrToStructure(pmt.formatPtr, wav); + + if (wav.nChannels == 2 && (wav.wBitsPerSample == 8 || wav.wBitsPerSample == 16)) + { + hr = S_OK; + } + else + { + hr = DMOResults.E_InvalidType; + } + } + else + { + hr = DMOResults.E_InvalidType; + } + + return hr; + } + + /// + /// Given a specific AMMediaType, we are asked if we support it + /// + /// Stream number + /// The AMMediaType to check + /// S_OK if it is supported, DMOResults.E_InvalidType if not + override protected int InternalCheckOutputType(int dwOutputStreamIndex, AMMediaType pmt) + { + int hr; + + AMMediaType pIn = InputType(0); + + // We don't support anything until after our input pin is set + if (pIn != null) + { + // Match the types + if (pmt.majorType == MediaType.Audio && + pmt.subType == MediaSubType.PCM && + pmt.formatType == FormatType.WaveEx) + { + // Parse out the wav structure from the input stream + // and the proposed output stream + WaveFormatEx wavOut = new WaveFormatEx(); + Marshal.PtrToStructure(pmt.formatPtr, wavOut); + + WaveFormatEx wavIn = new WaveFormatEx(); + Marshal.PtrToStructure(pIn.formatPtr, wavIn); + + // Output must be one channel, which means half the + // nAvgBytesPerSec and half the nBlockAlign + if (wavOut.nChannels == 1 && + wavOut.wBitsPerSample == wavIn.wBitsPerSample && + wavOut.nAvgBytesPerSec == wavIn.nAvgBytesPerSec / 2 && + wavOut.nBlockAlign == wavIn.nBlockAlign / 2) + { + hr = S_OK; + } + else + { + hr = DMOResults.E_InvalidType; + } + } + else + { + hr = DMOResults.E_InvalidType; + } + } + else + { + hr = DMOResults.E_InvalidType; + } + + return hr; + } + + /// + /// Get the list of supported types. Note this it is NOT required that any types be returned here. + /// If no types are returned, connectors just try media types (InternalCheckInputType) until we + /// accept one. + /// + /// Stream number + /// Index into the array of media types we support + /// The media type + /// DMOResults.E_NoMoreItems if out of range, else S_OK + override protected int InternalGetInputType(int dwInputStreamIndex, int dwTypeIndex, out AMMediaType pmt) + { + int hr; + + switch(dwTypeIndex) + { + case 0: + pmt = new AMMediaType(); + pmt.majorType = MediaType.Audio; + pmt.subType = MediaSubType.PCM; + pmt.formatType = FormatType.WaveEx; + hr = S_OK; + break; + + default: + pmt = null; + hr = DMOResults.E_NoMoreItems; + break; + } + + return hr; + } + + /// + /// Report the list of supported types + /// + /// Output stream number + /// Zero based index into array of supported types + /// Supported type + /// S_OK for successful completion or DMOResults.E_NoMoreItems if dwTypeIndex is + /// out of range. + override protected int InternalGetOutputType(int dwOutputStreamIndex, int dwTypeIndex, out AMMediaType pmt) + { + int hr; + pmt = InputType(0); + + // If the input type hasn't been set, we can't describe out output + if (pmt != null) + { + // Only one possible value + if (dwTypeIndex == 0) + { + // Copy the input type + pmt = MoCloneMediaType(pmt); + + // Parse out the wave struct + WaveFormatEx wav = new WaveFormatEx(); + Marshal.PtrToStructure(pmt.formatPtr, wav); + + // Adjust the struct for half as many channels + wav.nChannels = 1; + wav.nBlockAlign /= 2; + wav.nAvgBytesPerSec /= 2; + + // Put the struct back + Marshal.StructureToPtr(wav, pmt.formatPtr, false); + + hr = S_OK; + } + else + { + pmt = null; + hr = DMOResults.E_NoMoreItems; + } + } + else + { + pmt = null; + hr = DMOResults.E_TypeNotSet; + } + + return hr; + } + + /// + /// What size (and alignment) do we require of our output buffer? + /// + /// Stream number + /// returns the buffer size needed + /// Returns the alignment needed (don't use zero!) + /// S_OK + override protected int InternalGetOutputSizeInfo(int dwOutputStreamIndex, out int pcbSize, out int pcbAlignment) + { + pcbAlignment = 1; + AMMediaType pmt = OutputType(dwOutputStreamIndex); + + VideoInfoHeader v = new VideoInfoHeader(); + WaveFormatEx wav = new WaveFormatEx(); + Marshal.PtrToStructure(pmt.formatPtr, wav); + + pcbSize = wav.nBlockAlign; + + return S_OK; + } + + /// + /// Flush releases all input buffers without processing them + /// + /// S_OK + override protected int InternalFlush() + { + InternalDiscontinuity(0); + + // Release buffers + ReleaseInputBuffs(); + m_TimeStamp = 0; + + return S_OK; + } + + /// + /// Our chance to allocate any storage we may need + /// + /// S_OK + override protected int InternalAllocateStreamingResources() + { + // Reinitialize variables + InternalDiscontinuity(0); + + AMMediaType pmt = InputType(0); + WaveFormatEx wav = new WaveFormatEx(); + Marshal.PtrToStructure(pmt.formatPtr, wav); + + m_Bits = wav.wBitsPerSample; + + return S_OK; + } + + /// + /// Accept the input buffers to be processed. You'll want to read + /// the MSDN docs on this one. One point worth noting is that DMO + /// doesn't require that one complete block be passed at a time. + /// Picture a case where raw data is being read from a file, and your + /// DMO is the first to process it. The chunk of data you receive + /// might represent one image, 5 images, half an image, etc. Likewise, + /// your input could contain both video and audio that you are splitting + /// into two output streams. + /// That helps explain some of the parameters you see here and in + /// InternalProcessOutput. + /// Note that while DMO doesn't insist on it, for this sample, we + /// specifically request that only complete buffers be provided. + /// + /// Stream Index + /// Interface that holds the input data + /// Flags to control input processing + /// Timestamp of the sample + /// Duration of the sample + /// S_FALSE if there is no output, S_OK otherwise + override protected int InternalProcessInput( + int dwInputStreamIndex, + [In] IMediaBuffer pBuffer, + DMOInputDataBuffer dwFlags, + long rtTimestamp, + long rtTimelength) + { + // Check state - if we already have a buffer, we shouldn't be getting another + Debug.Assert(m_pBuffer == null); + + int cbData; + + int hr = pBuffer.GetBufferAndLength(out m_InBuffer, out m_cbInData); + if (hr >= 0) + { + // Ignore zero length buffers + if (m_cbInData > 0) + { + m_pBuffer = pBuffer; + + // Cast the input flags to become output flags + m_Flags = (DMOOutputDataBufferFlags)dwFlags; + + // If there is a time, store it + if (0 == (dwFlags & DMOInputDataBuffer.Time)) + { + m_TimeStamp = MAX_TIME; + } + else + { + m_TimeStamp = rtTimestamp; + } + + + // If there is a TimeLength, store it + if (0 == (dwFlags & DMOInputDataBuffer.TimeLength)) + { + m_TimeLength = -1; + } + else + { + m_TimeLength = rtTimelength; + } + hr = S_OK; + } + else + { + ReleaseInputBuffs(); + hr = S_FALSE; + } + } + + return hr; + } + + /// + /// Given output buffers, process the input buffers into the output buffers. + /// + /// Flags + /// Number of buffers (will be one per output stream) + /// The buffers + /// Reserved: 0 + /// S_FALSE if there is no output, S_OK otherwise + override protected int InternalProcessOutput( + DMOProcessOutput dwFlags, + int cOutputBufferCount, + [In, Out] DMOOutputDataBuffer [] pOutputBuffers, + out int pdwStatus) + { + int hr = 0; + bool bFoundOne = false; + pdwStatus = 0; + + // No input buffers to process + if (m_pBuffer != null) + { + int [] cbCurrent = new int[OutputPinCount]; // 0 + int [] cbOutData = new int[OutputPinCount]; //int.MaxValue; + IntPtr [] pbOutData = new IntPtr[OutputPinCount]; //IntPtr.Zero; + int iProcess = m_cbInData; + + for (int x=0; x < OutputPinCount; x++) + { + if (pOutputBuffers[x].pBuffer != null) + { + // Get a pointer to the output buffer + hr = pOutputBuffers[x].pBuffer.GetBufferAndLength(out pbOutData[x], out cbCurrent[x]); + + if (hr >= 0) + { + pbOutData[x] = (IntPtr)(pbOutData[x].ToInt32() + cbCurrent[x]); + + hr = pOutputBuffers[x].pBuffer.GetMaxLength(out cbOutData[x]); + + if (hr >= 0) + { + iProcess = Math.Min(iProcess, (cbOutData[x] - cbCurrent[x]) * 2); + bFoundOne = true; + } + } + } + else + { + pbOutData[x] = IntPtr.Zero; + cbOutData[x] = int.MaxValue; + cbCurrent[x] = 0; + } + + if (hr < 0) + { + break; + } + } + + if (hr >= 0) + { + if (bFoundOne) + { + // Process from input to output according to the mode + DoSplit( + iProcess, + m_InBuffer, + pbOutData[0], + pbOutData[1] + ); + } + + for (int x=0; x < OutputPinCount; x++) + { + // Keep the flags & time info from the input + pOutputBuffers[x].rtTimelength = m_TimeLength; + pOutputBuffers[x].rtTimestamp = m_TimeStamp; + + if (pOutputBuffers[x].pBuffer != null) + { + pOutputBuffers[x].pBuffer.SetLength((iProcess / 2) + cbCurrent[x]); + } + + if (m_cbInData == iProcess) + { + pOutputBuffers[x].dwStatus = m_Flags; + } + else + { + pOutputBuffers[x].dwStatus = m_Flags | DMOOutputDataBufferFlags.InComplete; + } + } + + // Did we process everything? + if (m_cbInData == iProcess) + { + ReleaseInputBuffs(); + } + else + { + // Reset for next call, skipping processed data + long l = (long)Math.Round(((double)iProcess / m_cbInData) * m_TimeLength); + m_TimeStamp += l; + m_TimeLength -= l; + + m_InBuffer = (IntPtr)(m_InBuffer.ToInt32() + iProcess); + m_cbInData -= iProcess; + } + } + } + else + { + hr = S_FALSE; + } + + return hr; + } + + /// + /// Are we able to accept more input at this time? + /// + /// Stream number + /// S_OK if we can, else S_FALSE + override protected int InternalAcceptingInput(int dwInputStreamIndex) + { + return m_pBuffer == null ? S_OK : S_FALSE; + } + + + + #endregion + } +} diff --git a/Samples/DMO/DmoSplit/DMO/DmoSplit.csproj b/Samples/DMO/DmoSplit/DMO/DmoSplit.csproj new file mode 100644 index 0000000..7a69e7a --- /dev/null +++ b/Samples/DMO/DmoSplit/DMO/DmoSplit.csproj @@ -0,0 +1,141 @@ + + + + Local + 8.0.50727 + 2.0 + {461D3FBA-AD10-4E6E-A1BE-0686547E9B1F} + Debug + AnyCPU + + + + + DmoSplit + mykey.snk + JScript + Grid + IE50 + false + Library + DmoSplit + OnBuildSuccess + + + + + + + true + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\Debug\ + false + 285212672 + false + + + DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 1 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + USING_NET20 + + + false + 4096 + false + + + false + false + false + false + 1 + none + prompt + + + + System + + + System.Drawing + + + + + Code + + + Code + + + Code + + + + + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + + + "%25windir%25\Microsoft.NET\Framework\v2.0.50727\regasm" /nologo /codebase $(TargetPath) + + \ No newline at end of file diff --git a/Samples/DMO/DmoSplit/DMO/IMediaObjectImpl.cs b/Samples/DMO/DmoSplit/DMO/IMediaObjectImpl.cs new file mode 100644 index 0000000..c76a0c7 --- /dev/null +++ b/Samples/DMO/DmoSplit/DMO/IMediaObjectImpl.cs @@ -0,0 +1,3142 @@ +#region license + +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +#endregion + +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; +using DirectShowLib; +using DirectShowLib.DMO; +using System.IO; +using System.Collections; + +namespace MediaObjectTemplate +{ + /// + /// This abstract class can be used to implement a DMO in .NET. + /// + /// + /// Before attempting to use this class, read the MSDN docs on DMOs! In + /// particular read about IMediaObject, IMediaParamInfo, IMediaParams, + /// and the DMO Wrapper Filter (if you are using DirectShow graphs). + /// + /// When you read the MSDN docs about creating a DMO, they refer to a template that + /// you can use to make things easier. That template served as the inspiration for this + /// class. To create a DMO, you can just create a class that implements this abstract class, + /// write code for the abstract methods, and you should be good to go. + /// + /// Here is a more detailed description of the steps you need to take. Note that you can + /// look at the sample code for examples of these steps. + /// + /// 1) Other than ripping out the rather lame logging, you shouldn't need to change + /// any code in IMediaObjectImpl.cs. It is the initial entry point for all the + /// IMediaObject interfaces. It performs parameter checking, makes sure the call + /// is appropriate for the current state, etc. As needed it will make calls to the + /// abstract and virtual methods of the class. + /// + /// 2) Create a class which implements the abstract IMediaObjectImpl class: + /// + /// [ComVisible(true), Guid("7EF28FD7-E88F-45bb-9CDD-8A62956F2D75"), + /// ClassInterface(ClassInterfaceType.None)] + /// public class DmoFlip : IMediaObjectImpl + /// + /// 3) Generate your own guid so the samples won't interfere with your code: + /// If you are running Dev Studio, go to Tools/Create Guid, choose "Registry + /// Format", click "Copy", then paste into your code. + /// + /// 4) Create the constructor for your class. It must not take any parameters: + /// + /// public DmoFlip() : base(InputPinCount, OutputPinCount, ParamCount, TimeFormatFlags.Reference) + /// + /// If you are planning to use this DMO with the DirectShow DMO Wrapper Filter, note + /// that (up to and including DX v9.0) InputPinCount must be 1, and OutputPinCount must + /// be > 0. The ParamCount is the number of parameters your DMO supports, and can be zero. + /// In general, you should use TimeFormatFlags.Reference for the last paramter. + /// + /// 5) Register the parameters your DMO supports using . + /// This must be done in the constructor (unless you have no parameters). Doing this allows you to support + /// IMediaParamInfo and IMediaParams. You will also need to use + /// to find out what parameter value you should use at any given point during the stream. + /// See the docs for these two methods for details. + /// + /// 6) Create the COM register/unregister methods: + /// + /// [ComRegisterFunctionAttribute] + /// static private void DoRegister(Type t) + /// + /// [ComUnregisterFunctionAttribute] + /// static private void UnregisterFunction(Type t) + /// + /// These tell the OS about your DMO. If you are distributing your code, you + /// will need to make sure they get called during installation (read about RegAsm + /// in the .NET docs). At a minimum, you will need to call DMORegister to register + /// your DMO. See the sample for how this is done. + /// + /// WARNING: If you use the "Register for COM Interop" compiler switch, the + /// compiler will attempt to register DirectShowLib.dll as well as your DMO. + /// Since DirectShowLib has no registration to perform, this generates an error. + /// That is why the sample uses pre/post build events to perform the registration. You + /// may need to adjust this command for your particular installation. + /// + /// 7) Do everything else. There are 7 abstract methods for which you must + /// write code. These methods are listed in the IMediaObjectImpl Methods page in + /// the Protected Instance Methods section. These methods will contain the information + /// specific to your DMO, and describe what type of data you are willing to process, and + /// perform the actual processing. Note that since the abstract class has verified the + /// parameters, you do not need to re-check them in your implementation. See the + /// descriptions for each method and the sample for details about what each of these + /// methods must do. + /// + /// You may also need to override some of the 11 virtual methods if their default + /// implementation doesn't match your specific needs. See the documentation for each of + /// these specific methods for details. + /// + ///
+ /// + /// If you aren't already knowledgeable about COM and writing multi-threaded apps, + /// this is probably a good time to do a little research. You may have multiple + /// instances of your DMO running in the same process, in multiple processes, + /// called on different threads, etc. + /// + /// As a simple example of the things you should be thinking of, the logging in + /// (debug builds of) IMediaObjectImpl.cs opens the file as non-sharable. + /// However, if two applications try to instantiate your DMO, the second will fail, + /// solely due to not being able to open the log file. Probably not the desired + /// behavior (told you the logging was lame). + ///
+ abstract public class IMediaObjectImpl : IMediaObject, IMediaParamInfo, IMediaParams + { + #region Declarations + + // Used in IMediaParams to specify that an envelope change should + // be applied to all parameters. + private const int ALLPARAMS = -1; + + /// COM return code indicating success + protected const int S_OK = 0; + + /// COM return code indicating partial success + protected const int S_FALSE = 1; + + /// COM return code indicating method not supported + protected const int E_NOTIMPL = unchecked((int)0x80004001); + + /// COM return code indicating invalid pointer provided + protected const int E_POINTER = unchecked((int)0x80004003); + + /// COM return code indicating invalid argument specified + protected const int E_INVALIDARG = unchecked((int)0x80070057); + + /// COM return code indicating a method called at an unexpected time + protected const int E_UNEXPECTED = unchecked((int)0x8000FFFF); + + /// + /// Info regarding a (input or output) pin + /// + private struct PinDef + { + public bool fTypeSet; + public bool fIncomplete; + public AMMediaType CurrentMediaType; + } + + + /// + /// Used by the IMediaObjectImpl constructor to specify which timeformats are supported + /// + [Flags] + protected enum TimeFormatFlags + { + /// + /// Used only when the DMO has no parameters + /// + None = 0, + /// + /// Reference time, in 100-nanosecond units. All DMOs should support this format. + /// + Reference = 1, + /// + /// Music time, in parts per quarter note. + /// + Music = 2, + /// + /// Samples per second. + /// + Samples = 4 + } + + #endregion + + #region Internal Classes + + // This class holds all the information about the parameters + // for this DMO. Using this class allows IMediaObjectImpl to + // automatically implement IMediaParamInfo & IMediaParams. If + // your DMO has no parameters, you do not need to create an instance + // of this class. + private class ParamClass + { + #region Member variables + + // The param returned to IMediaParamInfo::GetParamInfo + public ParamInfo [] Parms; + + // The list of TimeFormats returned to IMediaParamInfo::GetSupportedTimeFormat + public Guid [] TimeFormats; + + // The index into TimeFormats indicating the currently active format + public int CurrentTimeFormat; + + // The TimeData for the current format (see IMediaParams::SetTimeFormat) + public int TimeData; + + // The string text returned from IMediaParamInfo::GetParamText + public string [] ParamText; + + // The envelopes holding the parameter info. Note that even if parameter + // info isn't sent with IMediaParams::AddEnvelope (ie thru IMediaParams::SetParam), + // this implementation still creates and uses envelopes. It just makes envelopes + // that span the entire media length. + public MPEnvelopes [] Envelopes; + + #endregion + + public ParamClass(int iParams, TimeFormatFlags iTimeFormats) + { + CurrentTimeFormat = 0; + TimeData = 0; + + // Make room for the timeformats + int iCount = CountBits((int)iTimeFormats); + TimeFormats = new Guid[iCount]; + + if ((iTimeFormats & TimeFormatFlags.Samples) > 0) + { + TimeFormats[--iCount] = MediaParamTimeFormat.Samples; + } + if ((iTimeFormats & TimeFormatFlags.Music) > 0) + { + TimeFormats[--iCount] = MediaParamTimeFormat.Music; + } + if ((iTimeFormats & TimeFormatFlags.Reference) > 0) + { + TimeFormats[--iCount] = MediaParamTimeFormat.Reference; + } + Debug.Assert(iCount == 0, "Unrecognized time format specified"); + + // Make room for the parameter info + ParamText = new string[iParams]; + Parms = new ParamInfo[iParams]; + Envelopes = new MPEnvelopes[iParams]; + } + + public void DefineParam(int iParamNum, ParamInfo p, string sText) + { + Debug.Assert(iParamNum < Parms.Length && iParamNum >= 0, "Invalid parameter index"); + + Parms[iParamNum] = p; + Envelopes[iParamNum] = new MPEnvelopes(p.mpdNeutralValue, p.mopCaps, p.mpType, p.mpdMaxValue, p.mpdMaxValue); + ParamText[iParamNum] = sText; + } + + } + + + /// + /// The idea of envelopes (as I understand them) is to allow a parameter value + /// to be applied to a range within the stream. Generally speaking, there is a + /// start time and stop time, a parameter start value and a parameter end value. + /// So, you could say "The volume should go from 0% to 100% over the first 4 + /// seconds." There is also a Curve parameter that controls how quickly the + /// parameter value should change: Linear, Square, Sine, Jump, etc. + /// + /// Also note, the docs for IMediaParams::FlushEnvelope make no sense to me. + /// Instead of trying to make sense of the crazyness they have written, I + /// have done something simpler. If you flush a range, that range gets set + /// back to the NeutralVal for the parameter. + /// + /// The assumption (based on comments in IMediaParams::SetTimeFormat) is that + /// the times specified to the envelope are the same format as will be specified + /// to ProcessInput. If you are changing the format, call flush. + /// + private class MPEnvelopes + { + #region Declarations + + private const long MAX_TIME = 0x7FFFFFFFFFFFFFFF; + protected const int S_OK = 0; + protected const int E_INVALIDARG = unchecked((int)0x80070057); + + #endregion + + #region Member variables + + protected ArrayList m_Envelope; + protected MPData m_DefaultValue; + protected int m_ValidCaps; + protected MPType m_DataType; + protected MPData m_MinVal; + protected MPData m_MaxVal; + + #endregion + + public MPEnvelopes(MPData iDefaultValue, MPCaps iValidCaps, MPType mt, MPData min, MPData max) + { + // Store the neutralValue, min/max value range, data type and supported curve types + m_DefaultValue = iDefaultValue; + m_ValidCaps = (int)iValidCaps; + m_DataType = mt; + m_MinVal = min; + m_MaxVal = max; + + // Create an array to hold the segments (size = 3 was chosen arbitrarily) + m_Envelope = new ArrayList(3); + + // Create one segment that spans all time containing the default values + MPEnvelopeSegment e = new MPEnvelopeSegment(); + e.flags = MPFlags.BeginNeutralVal; + e.iCurve = MPCaps.Jump; + e.rtStart = 0; + e.rtEnd = MAX_TIME; + e.valStart = m_DefaultValue; + e.valEnd = m_DefaultValue; + + m_Envelope.Add(e); + } + + /// + /// Add a segment to the envelope. If this segment overlaps other segments, + /// the other segments are deleted or shortened, and this segment is inserted + /// + /// The segment to add + /// HRESULT + public int AddSegment(MPEnvelopeSegment mNew) + { + int hr; + int y; + MPEnvelopeSegment mOld; + + hr = ValidateEnvelopeSegment(mNew); + if (hr >= 0) + { + // Find the first record to modify. There is always + // at least one record, and ValidateEnvelopeSegment ensures + // that the start time is less than the endtime of the last + // record (MAX_TIME) + y = 0; + + do + { + mOld = (MPEnvelopeSegment)m_Envelope[y]; + + if (mNew.rtStart <= mOld.rtEnd) + { + break; + } + y++; + + } while (true); + + // Process the flags on mNew + UpdateSegment(y, ref mNew); + + // Depending on how the new segment overlaps, adjust the + // other segments and add it + if (mNew.rtStart <= mOld.rtStart) + { + if (mNew.rtEnd >= mOld.rtEnd) + { + // Existing segment is completely replaced + m_Envelope.RemoveAt(y); + m_Envelope.Insert(y, mNew); + + // Subsequent records may need to be deleted/adjusted + if (mNew.rtEnd > mOld.rtEnd) + { + DeleteRest(y+1, mNew.rtEnd); + } + } + else + { + // Existing segment is shortened from the left + mOld.rtStart = mNew.rtEnd + 1; + m_Envelope[y] = mOld; + m_Envelope.Insert(y, mNew); + } + } + else + { + if (mNew.rtEnd >= mOld.rtEnd) + { + // Existing segment is truncated + mOld.rtEnd = mNew.rtStart - 1; + m_Envelope[y] = mOld; + m_Envelope.Insert(y+1, mNew); + + if (mNew.rtEnd > mOld.rtEnd) + { + DeleteRest(y+2, mNew.rtEnd); + } + } + else + { + // Split a segment + MPEnvelopeSegment mAppend = mOld; + mAppend.rtStart = mNew.rtEnd + 1; + + mOld.rtEnd = mNew.rtStart - 1; + m_Envelope[y] = mOld; + + m_Envelope.Insert(y+1, mNew); + m_Envelope.Insert(y+2, mAppend); + } + } + } + + return hr; + } + + /// + /// Returns the Envelope the applies to a specific time. Since there is a + /// default segment that covers all possible times, this will always return + /// a value. + /// + /// Time to check + /// The envelope at that segment + public MPEnvelopeSegment FindEnvelopeForTime(long rt) + { + int x=0; + MPEnvelopeSegment mRet; + + do + { + mRet = (MPEnvelopeSegment)m_Envelope[x++]; + } while (rt > mRet.rtEnd); + + return mRet; + } + + /// + /// Calculate the parameter value at a specified time + /// + /// While there are routines written for all the curve types, I'm not enough + /// of a math whiz to feel comfortable that I got it right. I stole the code + /// from elsewhere and converted it to c#, so there's a chance I messed up. + /// + /// Time at which to calculate + /// MPData value for that time based in the specified Curve + public MPData CalcValueForTime(long rt) + { + long ir, ic; + float p; + MPData ret; + MPEnvelopeSegment m = FindEnvelopeForTime(rt); + + switch(m.iCurve) + { + case MPCaps.Jump: + + // Not quite sure how I want to do this. Consider an envelope + // that goes from time 0 to 10, and value 55 to 99. Obviously + // at time 0, you return 55. At times 1 thru 9, I assume you + // also return 55 (although one could argue they should return + // 99). At time 10, you return 99. + + // If you never have a timestamp that exactly equals 10, you + // would never get the new value. Seems odd. Well, that's + // how I've written it, anyway. + if (rt < m.rtEnd) + { + ret = m.valStart; + } + else + { + ret = m.valEnd; + } + break; + + case MPCaps.Linear: + ir = m.rtEnd - m.rtStart; + ic = rt - m.rtStart; + p = ic / ir; + ret = new MPData(); + + if (m_DataType == MPType.FLOAT) + { + ret.vFloat = (m.valEnd.vFloat - m.valStart.vFloat) * p; + } + else + { + ret.vInt = (int)((m.valEnd.vInt - m.valStart.vInt) * p); + } + break; + + case MPCaps.InvSquare: + ir = m.rtEnd - m.rtStart; + ic = rt - m.rtStart; + p = ic / ir; + p = (float)Math.Sqrt(p); + ret = new MPData(); + + if (m_DataType == MPType.FLOAT) + { + ret.vFloat = (m.valEnd.vFloat - m.valStart.vFloat) * p; + } + else + { + ret.vInt = (int)((m.valEnd.vInt - m.valStart.vInt) * p); + } + break; + + case MPCaps.Sine: + ir = m.rtEnd - m.rtStart; + ic = rt - m.rtStart; + p = ic / ir; + p = (float)((Math.Sin(p * Math.PI - (Math.PI/2)) + 1) / 2); + ret = new MPData(); + + if (m_DataType == MPType.FLOAT) + { + ret.vFloat = (m.valEnd.vFloat - m.valStart.vFloat) * p; + } + else + { + ret.vInt = (int)((m.valEnd.vInt - m.valStart.vInt) * p); + } + break; + + case MPCaps.Square: + ir = m.rtEnd - m.rtStart; + ic = rt - m.rtStart; + p = ic / ir; + p = p * p; + ret = new MPData(); + + if (m_DataType == MPType.FLOAT) + { + ret.vFloat = (m.valEnd.vFloat - m.valStart.vFloat) * p; + } + else + { + ret.vInt = (int)((m.valEnd.vInt - m.valStart.vInt) * p); + } + break; + + default: + Debug.Assert(false, "Invalid flag!"); + ret = new MPData(); + break; + } + + return ret; + } + + /// + /// Make sure the envelope parameters are valid + /// + /// Envelope segment to check + /// E_INVALIDARG if parameters are incorrect, else S_OK + public int ValidateEnvelopeSegment(MPEnvelopeSegment m) + { + int hr; + + // The start time cannot be MAX_TIME + // The end time must be >= start time + // The iCurve must be one of the recognized formats + // The iCurve must be one of the supported formats + // The iCurve can only be one format + // The flags must be one of the recognized formats + // The flags can only be one value + + if ( + (m.rtStart == MAX_TIME) || + (m.rtEnd < m.rtStart) || + ((m.iCurve & (~(MPCaps.InvSquare | MPCaps.Jump | MPCaps.Linear | MPCaps.Sine | MPCaps.Square))) > 0) || + ((((int)m.iCurve) & (~(m_ValidCaps))) > 0) || + (IMediaObjectImpl.CountBits((int)m.iCurve) > 1) || + ((m.flags & (~(MPFlags.BeginCurrentVal | MPFlags.BeginNeutralVal | MPFlags.Standard))) > 0) || + (IMediaObjectImpl.CountBits((int)m.flags) > 1) + ) + { + hr = E_INVALIDARG; + } + else + { + hr = S_OK; + } + + return hr; + } + +#if DEBUG + /// + /// Debug utility to dump an envelope + /// + public void DumpEnvelope() + { + int c = m_Envelope.Count; + Debug.WriteLine("----------------------------"); + + for (int x=0; x < c; x++) + { + MPEnvelopeSegment mOld = (MPEnvelopeSegment)m_Envelope[x]; + + Debug.WriteLine(string.Format("{0}: {1}-{2} {3}-{4}", x, mOld.rtStart, mOld.rtEnd, mOld.valStart.vInt, mOld.valEnd.vInt)); + } + } +#endif + + /// + /// Utility function called from AddEnvelope. When adding an envelope segment, + /// it could happen that the new segment overlaps multiple existing segments. + /// This routine walks starting at the specified segment. It either deletes + /// the segment or adjusts it until it reaches the ending time of the new + /// segment. + /// + /// Starting segment + /// new segment + private void DeleteRest(int z, long rtEnd) + { + // Don't walk past the end of the array + while (z < m_Envelope.Count) + { + MPEnvelopeSegment mOld = (MPEnvelopeSegment)m_Envelope[z]; + + // Have we found the end time of the current segment? + if (mOld.rtEnd <= rtEnd) + { + // Nope. Delete this segment. + m_Envelope.RemoveAt(z); + } + else + { + // Yes, this is the end. Split the old segment + mOld.rtStart = rtEnd + 1; + m_Envelope[z] = mOld; + break; + } + } + } + + /// + /// See if the specified parameter value falls within the allowable range + /// + /// Value to check + /// true if the parameter value is valid + private bool CheckRange(MPData m) + { + bool bRet; + + switch (m_DataType) + { + case MPType.BOOL: + case MPType.ENUM: + case MPType.INT: + bRet = (m.vInt >= m_MinVal.vInt && m.vInt <= m_MaxVal.vInt); + break; + + case MPType.FLOAT: + bRet = (m.vFloat >= m_MinVal.vFloat && m.vFloat <= m_MaxVal.vFloat); + break; + + default: + Debug.Assert(false, "Invalid Type"); + bRet = false; + break; + } + + return bRet; + } + + private void UpdateSegment(int y, ref MPEnvelopeSegment m) + { + if ((m.flags & MPFlags.BeginNeutralVal) > 0) + { + m.valStart = m_DefaultValue; + } + else if ((m.flags & MPFlags.BeginCurrentVal) > 0) + { + if (y > 0) + { + MPEnvelopeSegment mOld = (MPEnvelopeSegment)m_Envelope[y-1]; + m.valStart = mOld.valEnd; + } + else + { + m.valStart = m_DefaultValue; + } + } + } + } + + #endregion + + #region API + + /// + /// Compare two blocks of memory to see if they are identical + /// + /// Pointer to first block + /// Pointer to second block + /// Number of bytes to compare + /// The number of bytes that compare as equal. If all bytes compare as equal, the input Length is returned. + [DllImport("NTDll.dll", EntryPoint="RtlCompareMemory")] + private static extern int CompareMemory(IntPtr Destination, IntPtr Source, [MarshalAs(UnmanagedType.U4)] int Length); + + #endregion + + #region Member variables + + // Keeps a count of the number of instances of this class have + // been instantiated. Only used by logging. + static private int iInstanceCount = 0; + + // Status info about the input/output pins + private PinDef [] m_InputInfo; + private PinDef [] m_OutputInfo; + + // Have the types been set for all the input/output pins + private bool m_fTypesSet; + + // All buffers are empty + private bool m_fFlushed; + + // Has AllocateStreamingResources been successfully been called + private bool m_fResourcesAllocated; + + // Count of the input/output pins + private int m_NumInputs; + private int m_NumOutputs; + + // The log file + internal Logging m_Log; + + // Struct to support IMediaParamInfo & IMediaParams + private ParamClass m_Params; + + #endregion + + #region Utility routines + + /// + /// Count how many bits are set in an flag + /// + /// bitmap to check + /// Count of the number of bits set + internal static int CountBits(int i) + { + int iRet = 0; + + while (i > 0) + { + if ((i & 1) > 0) + { + iRet++; + } + i >>= 1; + } + + return iRet; + } + + /// + /// Set m_fTypesSet by making sure types are set for all input and non-optional output streams. + /// + /// true if all types are set + private bool CheckAllTypesSet() + { + DMOOutputStreamInfo dwFlags; + int dw; + int hr; + + m_fTypesSet = false; + for (dw = 0; dw < m_NumInputs; dw++) + { + if (!InputTypeSet(dw)) + { + return false; + } + } + + for (dw = 0; dw < m_NumOutputs; dw++) + { + if (!OutputTypeSet(dw)) + { + // Check if it's optional + hr = InternalGetOutputStreamInfo(dw, out dwFlags); + + Debug.Assert(0 == (dwFlags & ~(DMOOutputStreamInfo.WholeSamples | + DMOOutputStreamInfo.SingleSamplePerBuffer | + DMOOutputStreamInfo.FixedSampleSize | + DMOOutputStreamInfo.Discardable | + DMOOutputStreamInfo.Optional))); + + if ((dwFlags & DMOOutputStreamInfo.Optional) == 0) + { + return false; + } + } + } + + m_fTypesSet = true; + + return true; + } + + /// + /// Handle thrown exceptions in a consistent way. + /// + /// The exception that was thrown + /// HRESULT to return to COM + private int CatFail(Exception e) + { + m_Log.Write(string.Format("Catastrophic failure: {0}\r\n", e.Message)); + + int hr = Marshal.GetHRForException(e); + if (hr >= 0) + { + hr = E_UNEXPECTED; + } + return hr; + } + + + /// + /// Make a clone of a media type + /// + /// The AMMediaType to clone + /// Returns the clone + /// + /// Note that like all AMMediaTypes, the clone must be released + /// with DsUtils.FreeAMMediaType when it is no longer needed. + /// + static protected AMMediaType MoCloneMediaType(AMMediaType pmt1) + { + AMMediaType pRet = new AMMediaType(); + DMOUtils.MoCopyMediaType(pRet, pmt1); + + return pRet; + } + + /// + /// Create a definition for a parameter that is accessible thru IMediaParamInfo + /// and IMediaParams. + /// + /// Zero based parameter number to set the definition for + /// Populated ParamInfo struct + /// Format string (described in MSDN under IMediaParamInfo::GetParamText) + /// + /// This method should be called from the constructor of the class that implements IMediaObjectImpl. It + /// defines a single parameter that can be set on the DMO. You must call it once for each of the + /// parameters defined in the call to the IMediaObjectImpl constructor. This allows for automatic + /// support of the IMediaParamInfo and IMediaParams methods. See the + /// for additional details. + /// + protected void ParamDefine(int iParamNum, ParamInfo p, string sText) + { + m_Params.DefineParam(iParamNum, p, sText); + } + + /// + /// Given a parameter number and a time, return the parameter value at that time. + /// + /// Zero based parameter number + /// Time + /// Calculated value for the specified time + /// + /// Parameters for DMO can be set in one of two ways. IMediaParams.SetParam can + /// be used to set a parameter to a specific value. It is useful for setting values + /// that aren't intended to change over time. There is also IMediaParams.AddEnvelope. This + /// method can be use for things that change over time. For example, consider a parameter + /// for adjusting the audio volume. You might want to be able to have the volume go from 0% + /// to 150% over the first x seconds. + /// You can easily support both by using this method. + /// As you prepare to process buffers, take the timestamp that applies to that buffer, and + /// call this method to get the desired value for that parameter at that that time. + /// + /// + protected MPData ParamCalcValueForTime(int dwParam, long rtTimeStamp) + { + return m_Params.Envelopes[dwParam].CalcValueForTime(rtTimeStamp); + } + + /// + /// Check to see if two Media Types are exactly the same + /// + /// Media type to compare + /// Media type to compare + /// true if types are identical, else false + static protected bool TypesMatch(AMMediaType pmt1, AMMediaType pmt2) + { + if (pmt1.majorType == pmt2.majorType && + pmt1.subType == pmt2.subType && + pmt1.sampleSize == pmt2.sampleSize && + pmt1.formatType == pmt2.formatType && + pmt1.formatSize == pmt2.formatSize && + pmt1.formatSize == CompareMemory(pmt1.formatPtr, pmt2.formatPtr, pmt1.formatSize)) + { + return true; + } + else + { + return false; + } + } + + /// + /// Check whether the media type is set for the specified input stream + /// + /// Zero based stream number to check + /// true if the stream type is set + protected bool InputTypeSet(int ulInputStreamIndex) + { + Debug.Assert(ulInputStreamIndex < m_NumInputs); + return m_InputInfo[ulInputStreamIndex].fTypeSet; + } + + /// + /// Check whether the media type is set for the specified output stream + /// + /// Zero based stream number to check + /// true if the stream type is set + protected bool OutputTypeSet(int ulOutputStreamIndex) + { + Debug.Assert(ulOutputStreamIndex < m_NumOutputs); + return m_OutputInfo[ulOutputStreamIndex].fTypeSet; + } + /// + /// Get the AMMediaType for the specified Input stream + /// + /// The stream to get the media type for + /// The media type for the stream, or null if not set + /// + /// The abstract class will call to see + /// whether a given media type is supported. To see what media type was actually set, the + /// derived class can call this method. + /// + protected AMMediaType InputType(int ulInputStreamIndex) + { + if (!InputTypeSet(ulInputStreamIndex)) + { + return null; + } + return m_InputInfo[ulInputStreamIndex].CurrentMediaType; + } + /// + /// Get the AMMediaType for the specified Output stream + /// + /// The stream to get the media type for + /// The media type for the stream, or null if not set + /// + /// The abstract class will call to see + /// whether a given media type is supported. To see what media type was actually set, the + /// derived class can call this method. + /// + protected AMMediaType OutputType(int ulOutputStreamIndex) + { + if (!OutputTypeSet(ulOutputStreamIndex)) + { + return null; + } + return m_OutputInfo[ulOutputStreamIndex].CurrentMediaType; + } + + + #endregion + + /// + /// Constructor + /// + /// Number of input streams + /// Number of output streams + /// Number of parameters + /// What time formats the parameters support + /// + /// This constructor will be called from the constructor of the class that implements + /// IMediaObjectImpl. See for a step by step description + /// of the process. + /// + protected IMediaObjectImpl(int iInputs, int iOutputs, int iParams, TimeFormatFlags iTimeFormats) + { + iInstanceCount++; + m_Log = new Logging(iInstanceCount); + m_Log.Write("-------------------------------\r\n"); + m_Log.Write(string.Format("bConstructor {0}\r\n", iInstanceCount)); + + m_NumInputs = iInputs; + m_NumOutputs = iOutputs; + m_fTypesSet = false; + m_fFlushed = true; + m_fResourcesAllocated = false; + m_InputInfo = new PinDef[m_NumInputs]; + m_OutputInfo = new PinDef[m_NumOutputs]; + + // Protect ourselves from incorrectly written children + m_Params = new ParamClass(iParams, iTimeFormats); + } + + /// + /// Destructor + /// + /// + ~IMediaObjectImpl() + { + int dwCurrentType; + + m_Log.Write(string.Format("bDestructor {0}\r\n", iInstanceCount)); + + for (dwCurrentType = 0; dwCurrentType < m_NumInputs; dwCurrentType++) + { + if(InputTypeSet(dwCurrentType)) + { + DsUtils.FreeAMMediaType(m_InputInfo[dwCurrentType].CurrentMediaType); + } + } + + for (dwCurrentType = 0; dwCurrentType < m_NumOutputs; dwCurrentType++) + { + if(OutputTypeSet(dwCurrentType)) + { + DsUtils.FreeAMMediaType(m_OutputInfo[dwCurrentType].CurrentMediaType); + } + } + + m_Log.Dispose(); + } + + + #region Abstract methods + + /// + /// (Abstract) Determine whether the input stream supports a specific media type + /// + /// Input stream number + /// The media type to check + /// S_OK if the specified stream supports the specified media type, + /// else DMOResults.E_InvalidType + /// + /// This method is called by the abstract class. The implementor should check the + /// properties of the AMMediaType to ensure that if a sample of the specified type + /// is sent, it will be able to process it. + /// + abstract protected int InternalCheckInputType(int dwInputStreamIndex, AMMediaType pmt); + + /// + /// (Abstract) Determine whether the output stream supports a specific media type + /// + /// Output stream number + /// The media type to check + /// S_OK if the specified stream supports the specified media type, + /// else DMOResults.E_InvalidType + /// + /// This method is called by the abstract class. The implementor should check the + /// properties of the AMMediaType to ensure that if requested, it can produce an + /// output sample of the specified type. + /// + abstract protected int InternalCheckOutputType(int dwOutputStreamIndex, AMMediaType pmt); + + /// + /// (Abstract) Determine the requirements for the output stream + /// + /// Output stream number + /// The minimum size of an output buffer for this stream, in bytes + /// The required buffer alignment, in bytes. If the output stream + /// has no alignment requirement, the value is 1. + /// S_OK to indicate successful operation. + /// + /// This method is called by the abstract class. You should never return zero for the alignment. + /// + abstract protected int InternalGetOutputSizeInfo(int dwOutputStreamIndex, out int pcbSize, out int pcbAlignment); + + /// + /// (Abstract) Called to flush all pending processing + /// + /// S_OK to indicate successful operation + /// + /// This method is called by the abstract class. In response, the implementor should discard + /// any pending input buffers. + /// + abstract protected int InternalFlush(); + + /// + /// (Abstract) Accept input buffers to be processed + /// + /// Input stream number + /// Input buffer to process + /// Processing flags + /// Timestamp of sample(s) + /// Length of sample(s) + /// S_OK if the operation completes successfully, S_FALSE if there + /// is no input to process. + /// + /// This method is called by the abstract class. It passes the actual data to be process to the + /// implementor. Commonly, the implementor stores these values, waiting for the call to + /// InternalProcessOutput (which contains the buffers into which the results are to be stored), at + /// which point they are released. + /// + abstract protected int InternalProcessInput(int dwInputStreamIndex, IMediaBuffer pBuffer, DMOInputDataBuffer dwFlags, long rtTimestamp, long rtTimelength); + + /// + /// (Abstract) Process the input buffers from a previous call to InternalProcessInput into the provided output buffers + /// + /// Flags controlling the operation + /// The number of buffers provided (one per output stream) + /// The output buffer into which the data is processed + /// Zero + /// S_FALSE if there is no output, S_OK for successful operation. + /// + /// This method is called by the abstract class. It passes the output buffers to the implementor. + /// Typically, this is when the actual work is done, processing the input buffers into the output + /// buffers. + /// + abstract protected int InternalProcessOutput(DMOProcessOutput dwFlags, int cOutputBufferCount, DMOOutputDataBuffer [] pOutputBuffers, out int pdwStatus); + + /// + /// (Abstract) Report whether more input buffers can be accepted + /// + /// Input stream number + /// S_OK if the implementor is ready to accept an input buffer, else S_FALSE + /// + /// This method is called by the abstract class. If the implementor has room for another input buffer, it + /// should return S_OK. It is perfectly acceptable for a DMO to only accept one input buffer at a time, and + /// to return S_FALSE until InternalProcessOutput has been called to process the buffer. + /// + abstract protected int InternalAcceptingInput(int dwInputStreamIndex); + + #endregion + + #region Virtual Methods + + /// + /// (Virtual) Returns the current time in the media stream + /// + /// The current time in the media stream + /// + /// Typically, this function should be overridden to return the most recent timestamp + /// from the last call to InternalProcessInput. It is used to support IMediaParams.GetParam. + /// The default implementation assumes the stream has no time stamps or that the stream is + /// stopped. + /// + virtual protected long InternalGetCurrentTime() + { + return 0; + } + + /// + /// (Virtual) Allows stream resources to be allocated + /// + /// S_OK for successful operation + /// + /// Allows the implementor to allocate any resources necessary for performing the processing. + /// The default implementation assumes we don't need to allocate any addition resources to + /// perform the processing. + /// + virtual protected int InternalAllocateStreamingResources() + { + return S_OK; + } + + /// + /// (Virtual) Allows stream resources to be released + /// + /// S_OK for successful operation + /// + /// Allows the implementor to release any resources used for performing the processing. + /// The default implementation assumes we don't need to release any addition resources. + /// + virtual protected int InternalFreeStreamingResources() + { + return S_OK; + } + + /// + /// (Virtual) Controls information about how input buffers are formatted + /// + /// Input stream number + /// Flags specifying how input buffers need to be formatted + /// S_OK for successful completion + /// + /// Allows the implementor to specify flags controlling the format of input buffers. The default + /// implementation return FixedSampleSize | SingleSamplePerBuffer | WholeSamples + /// + virtual protected int InternalGetInputStreamInfo(int dwInputStreamIndex, out DMOInputStreamInfo pdwFlags) + { + pdwFlags = DMOInputStreamInfo.FixedSampleSize | + DMOInputStreamInfo.SingleSamplePerBuffer | + DMOInputStreamInfo.WholeSamples; + + return S_OK; + } + + /// + /// (Virtual) Controls information about how output buffers are formatted + /// + /// Output stream number + /// Flags specifying how output buffers need to be formatted + /// S_OK for successful completion + /// + /// Allows the implementor to specify flags controlling the format of output buffers. The default + /// implementation returns WholeSamples | SingleSamplePerBuffer | FixedSampleSize + /// + virtual protected int InternalGetOutputStreamInfo(int dwOutputStreamIndex, out DMOOutputStreamInfo pdwFlags) + { + pdwFlags = DMOOutputStreamInfo.WholeSamples | + DMOOutputStreamInfo.SingleSamplePerBuffer | + DMOOutputStreamInfo.FixedSampleSize; + + return S_OK; + } + + /// + /// (Virtual) Retrieves a preferred media type for a specified input stream + /// + /// Input stream number + /// Index into the array of supported media types + /// The media type + /// DMOResults.E_NoMoreItems if out of range or S_OK for successful completion + /// + /// If the implementor supports returning a collection of supported media types, it should override + /// this method. The default implementation assumes we don't enumerate our supported types. The + /// app calling this DMO should just try setting something and see if it works. + /// + virtual protected int InternalGetInputType(int dwInputStreamIndex, int dwTypeIndex, out AMMediaType pmt) + { + pmt = null; + return DMOResults.E_NoMoreItems; + } + + /// + /// (Virtual) Retrieves a preferred media type for a specified output stream + /// + /// Output stream number + /// Index into the array of supported media types + /// The media type + /// DMOResults.E_NoMoreItems if out of range or S_OK for successful completion + /// + /// If the implementor supports returning a collection of supported media types, it should override + /// this method. The default implementation assumes our output type is the same as our input type. + /// + virtual protected int InternalGetOutputType(int dwOutputStreamIndex, int dwTypeIndex, out AMMediaType pmt) + { + int hr; + + if (InputTypeSet(dwOutputStreamIndex)) + { + if (dwTypeIndex == 0) + { + pmt = InputType(dwOutputStreamIndex); + hr = S_OK; + } + else + { + pmt = null; + hr = DMOResults.E_NoMoreItems; + } + } + else + { + pmt = null; + hr = DMOResults.E_TypeNotSet; + } + + return hr; + } + + /// + /// (Virtual) Retrieves the buffer requirements for a specified input stream + /// + /// Input stream number + /// Minimum size of an input buffer for this stream, in bytes + /// Maximum amount of data that the DMO will hold for lookahead, in bytes + /// the required buffer alignment, in bytes. If the input stream has no alignment requirement, the value is 1. + /// S_OK for successful operation + /// + /// The implementator could override this method to specify different values. The default + /// implementation reports that we can accept any alignment, hold no lookahead buffers, and the + /// input buffer must be at least 1 byte long. + /// + virtual protected int InternalGetInputSizeInfo(int dwInputStreamIndex, out int pcbSize, out int pcbMaxLookahead, out int pcbAlignment) + { + pcbSize = 1; + pcbMaxLookahead = 0; + pcbAlignment = 1; + + return S_OK; + } + + /// + /// (Virtual) Retrieves the maximum latency on a specified input stream + /// + /// Input stream number + /// Latency + /// S_OK for successful completion + /// + /// The latency is the difference between a time stamp on the input stream and the corresponding time + /// stamp on the output stream. The maximum latency is the largest possible difference in the time stamps. + /// The default implementation returns E_NOTIMPL indicating the DMO doesn't support reporting latency. + /// + virtual protected int InternalGetInputMaxLatency(int dwInputStreamIndex, out long prtMaxLatency) + { + prtMaxLatency = 0; + + return E_NOTIMPL; + } + + /// + /// (Virtual) Set the maximum latency on a specified input stream + /// + /// Input stream number + /// Maximum latency + /// S_OK for successful operation + /// + /// The default implementation returns E_NOTIMPL indicating the DMO doesn't support reporting latency. + /// + virtual protected int InternalSetInputMaxLatency(int dwInputStreamIndex, long rtMaxLatency) + { + return E_NOTIMPL; + } + + /// + /// (Virtual) Called to notify of a stream discontinuity + /// + /// Input stream number + /// S_OK for successful operation + /// + /// The default implementation assumes no special processing is required for discontinuities. + /// + virtual protected int InternalDiscontinuity(int dwInputStreamIndex) + { + return S_OK; + } + + + #endregion + + #region IMediaObject methods + + /// + /// COM entry point for IMediaObject.GetStreamCount + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int GetStreamCount(out int pulNumberOfInputStreams, out int pulNumberOfOutputStreams) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write("GetStreamCount"); + + // Return the number of input/output streams + pulNumberOfInputStreams = m_NumInputs; + pulNumberOfOutputStreams = m_NumOutputs; + + m_Log.WriteNoTS(string.Format(" {0}:{1}\r\n", m_NumInputs, m_NumOutputs)); + + hr = S_OK; + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have these to make the compiler happy. Should be safe since + // GetStreamCount is doc'ed not to accept NULLs. + pulNumberOfInputStreams = 0; + pulNumberOfOutputStreams = 0; + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.GetInputStreamInfo + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int GetInputStreamInfo(int ulStreamIndex, out DMOInputStreamInfo pdwFlags) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + pdwFlags = 0; + m_Log.Write("GetInputStreamInfo"); + + // Validate the stream number + if (ulStreamIndex < m_NumInputs && ulStreamIndex >= 0) + { + // Call the internal function to get the value + hr = InternalGetInputStreamInfo(ulStreamIndex, out pdwFlags); + + // Validate the value returned by the internal function + Debug.Assert(0 == (pdwFlags & ~(DMOInputStreamInfo.WholeSamples | + DMOInputStreamInfo.SingleSamplePerBuffer | + DMOInputStreamInfo.FixedSampleSize | + DMOInputStreamInfo.HoldsBuffers))); + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + + m_Log.WriteNoTS(string.Format(": {0}\r\n", hr)); + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pdwFlags = 0; + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.GetOutputStreamInfo + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int GetOutputStreamInfo(int ulStreamIndex, out DMOOutputStreamInfo pdwFlags) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + pdwFlags = 0; + m_Log.Write(string.Format("GetOutputStreamInfo({0})", ulStreamIndex)); + + // Validate the stream number + if (ulStreamIndex < m_NumOutputs && ulStreamIndex >= 0) + { + // Call the internal function to get the value + hr = InternalGetOutputStreamInfo(ulStreamIndex, out pdwFlags); + + // Validate the value returned by the internal function + Debug.Assert(0 == (pdwFlags & ~(DMOOutputStreamInfo.WholeSamples | + DMOOutputStreamInfo.SingleSamplePerBuffer | + DMOOutputStreamInfo.FixedSampleSize | + DMOOutputStreamInfo.Discardable | + DMOOutputStreamInfo.Optional))); + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + + m_Log.WriteNoTS(string.Format("= {1}: {0}\r\n", hr, pdwFlags)); + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pdwFlags = 0; + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.GetInputType + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int GetInputType(int ulStreamIndex, int ulTypeIndex, AMMediaType pmt) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write(string.Format("GetInputType({0}, {1})", ulStreamIndex, ulTypeIndex)); + + // Validate the stream number + if (ulStreamIndex < m_NumInputs && ulStreamIndex >= 0 ) + { + AMMediaType pmt2; + + // Call the internal method to get the MediaType + hr = InternalGetInputType(ulStreamIndex, ulTypeIndex, out pmt2); + + // If InternalGetInputType returned a value, and if the caller + // provided a place for it, copy it over + if (hr >= 0 && pmt != null) + { + DMOUtils.MoCopyMediaType(pmt, pmt2); + } + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + m_Log.WriteNoTS(string.Format("= {0}\r\n", hr)); + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.GetOutputType + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int GetOutputType(int ulStreamIndex, int ulTypeIndex, AMMediaType pmt) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write(string.Format("GetOutputType({0}, {1})", ulStreamIndex, ulTypeIndex)); + + // Validate the stream number + if (ulStreamIndex < m_NumOutputs && ulStreamIndex >= 0) + { + AMMediaType pmt2; + + hr = InternalGetOutputType(ulStreamIndex, ulTypeIndex, out pmt2); + + // If InternalGetInputType returned a value, and if the caller + // provided a place for it, copy it over + if (hr >= 0) + { + m_Log.WriteNoTS(string.Format(" out:{0}", DsToString.AMMediaTypeToString(pmt2))); + if (pmt != null) + { + DMOUtils.MoCopyMediaType(pmt, pmt2); + } + } + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + + m_Log.WriteNoTS(string.Format(": {0}\r\n", hr)); + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.GetInputCurrentType + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int GetInputCurrentType(int ulStreamIndex, AMMediaType pmt) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + pmt = null; + m_Log.Write("GetInputCurrentType\r\n"); + + // Validate the stream number + if (ulStreamIndex < m_NumInputs && ulStreamIndex >= 0) + { + // If there *is* a current type + if (InputTypeSet(ulStreamIndex)) + { + pmt = MoCloneMediaType(m_InputInfo[ulStreamIndex].CurrentMediaType); + hr = S_OK; + } + else + { + hr = DMOResults.E_TypeNotSet; + } + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pmt = null; + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.GetOutputCurrentType + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int GetOutputCurrentType(int ulStreamIndex, AMMediaType pmt) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + pmt = null; + m_Log.Write("GetOutputCurrentType\r\n"); + + // Validate the stream number + if (ulStreamIndex < m_NumOutputs && ulStreamIndex >= 0) + { + // If there *is* a current type + if (OutputTypeSet(ulStreamIndex)) + { + pmt = MoCloneMediaType(m_OutputInfo[ulStreamIndex].CurrentMediaType); + hr = S_OK; + } + else + { + hr = DMOResults.E_TypeNotSet; + } + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pmt = null; + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.GetInputSizeInfo + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int GetInputSizeInfo(int ulStreamIndex, out int pulSize, out int pcbMaxLookahead, out int pulAlignment) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + pulSize = 0; + pcbMaxLookahead = 0; + pulAlignment = 0; + + m_Log.Write("GetInputSizeInfo"); + + // Validate the stream number + if (ulStreamIndex < m_NumInputs && ulStreamIndex >= 0) + { + // If there is a type set (otherwise, how can we report a size for it?) + if (InputTypeSet(ulStreamIndex)) + { + hr = InternalGetInputSizeInfo(ulStreamIndex, out pulSize, out pcbMaxLookahead, out pulAlignment); + } + else + { + hr = DMOResults.E_TypeNotSet; + } + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + m_Log.WriteNoTS(string.Format("= {0} {1} {2} : {3}\r\n", pulSize, pcbMaxLookahead, pulAlignment, hr)); + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pulSize = 0; + pcbMaxLookahead = 0; + pulAlignment = 0; + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.GetOutputSizeInfo + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int GetOutputSizeInfo(int ulStreamIndex, out int pulSize, out int pulAlignment) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + pulSize = 0; + pulAlignment = 0; + m_Log.Write("GetOutputSizeInfo\r\n"); + + // Validate the stream number + if (ulStreamIndex < m_NumOutputs && ulStreamIndex >= 0) + { + // If there is a type set (otherwise, how can we report a size for it?) + if (m_fTypesSet && OutputTypeSet(ulStreamIndex)) + { + hr = InternalGetOutputSizeInfo(ulStreamIndex, out pulSize, out pulAlignment); + } + else + { + hr = DMOResults.E_TypeNotSet; + } + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pulSize = 0; + pulAlignment = 0; + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.SetInputType + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int SetInputType(int ulStreamIndex, AMMediaType pmt, DMOSetType dwFlags) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write(string.Format("SetInputType({0}, {1})", ulStreamIndex, dwFlags)); + + // Validate the stream number + if (ulStreamIndex >= m_NumInputs || ulStreamIndex < 0) + { + return DMOResults.E_InvalidStreamIndex; + } + + // Validate the flags + if ( (dwFlags & ~ (DMOSetType.Clear | DMOSetType.TestOnly)) > 0) + { + return E_INVALIDARG; + } + + // If they requested to clear the current type + if ((dwFlags & DMOSetType.Clear) > 0) + { + DsUtils.FreeAMMediaType(m_InputInfo[ulStreamIndex].CurrentMediaType); + m_InputInfo[ulStreamIndex].fTypeSet = false; + + // Re-check to see if all the non-optional streams still have types + if (!CheckAllTypesSet()) + { + // We aren't in a runnable state anymore, flush things + Flush(); + FreeStreamingResources(); + } + hr = S_OK; + } + else + { + if (null != pmt) + { + m_Log.WriteNoTS(string.Format(" requested in: {0}", DsToString.AMMediaTypeToString(pmt))); + + // Check to see if the type is already set + if (!InputTypeSet(ulStreamIndex)) + { + // Check to see if we support the requested format + hr = InternalCheckInputType(ulStreamIndex, pmt); + if (hr >= 0) + { + hr = S_OK; + + // If we weren't just being tested, actually set the type + if ( (dwFlags & DMOSetType.TestOnly) == 0) + { + m_Log.WriteNoTS(string.Format(" input: {0}", DsToString.AMMediaTypeToString(pmt))); + + // Free any previous mediatype + if (InputTypeSet(ulStreamIndex)) + { + DsUtils.FreeAMMediaType(m_InputInfo[ulStreamIndex].CurrentMediaType); + } + m_InputInfo[ulStreamIndex].CurrentMediaType = MoCloneMediaType(pmt); + m_InputInfo[ulStreamIndex].fTypeSet = true; + + // Re-check to see if all the non-optional streams still have types + CheckAllTypesSet(); + } + } + } + else + { + // Type is set, so reject any type that's not identical + if (TypesMatch(pmt, InputType(ulStreamIndex))) + { + hr = S_OK; + } + else + { + hr = DMOResults.E_InvalidType; + } + } + } + else + { + hr = E_POINTER; + } + } + + m_Log.WriteNoTS(string.Format(":{0}\r\n", hr)); + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.SetOutputType + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int SetOutputType(int ulStreamIndex, AMMediaType pmt, DMOSetType dwFlags) + { + int hr = S_OK; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write(string.Format("SetOutputType({0}, {1})", ulStreamIndex, dwFlags)); + + // Validate the stream number + if (ulStreamIndex >= m_NumOutputs || ulStreamIndex < 0) + { + return DMOResults.E_InvalidStreamIndex; + } + + // Validate the flags + if ( (dwFlags & ~ (DMOSetType.Clear | DMOSetType.TestOnly)) > 0) + { + return E_INVALIDARG; + } + + // If they requested to clear the current type + if ( (dwFlags & DMOSetType.Clear) > 0) + { + DsUtils.FreeAMMediaType(m_OutputInfo[ulStreamIndex].CurrentMediaType); + m_OutputInfo[ulStreamIndex].fTypeSet = false; + + // Re-check to see if all the non-optional streams still have types + if (!CheckAllTypesSet()) + { + // We aren't in a runnable state anymore, flush things + Flush(); + FreeStreamingResources(); + } + hr = S_OK; + } + else + { + if (null != pmt) + { + m_Log.WriteNoTS(string.Format(" requested out: {0}", DsToString.AMMediaTypeToString(pmt))); + + // Check if the type is already set + if (!OutputTypeSet(ulStreamIndex)) + { + // Check to see if we support the requested format + hr = InternalCheckOutputType(ulStreamIndex, pmt); + if (hr >= 0) + { + hr = S_OK; + + // If we weren't just being tested, actually set the type + if ( (dwFlags & DMOSetType.TestOnly) == 0) + { + // Free any previous mediatype + if (OutputTypeSet(ulStreamIndex)) + { + DsUtils.FreeAMMediaType(m_OutputInfo[ulStreamIndex].CurrentMediaType); + } + m_OutputInfo[ulStreamIndex].CurrentMediaType = MoCloneMediaType(pmt); + m_OutputInfo[ulStreamIndex].fTypeSet = true; + + // Re-check to see if all the non-optional streams still have types + CheckAllTypesSet(); + } + } + } + else + { + // Type is set, so reject any type that's not identical + if (!TypesMatch(pmt, OutputType(ulStreamIndex))) + { + hr = DMOResults.E_InvalidType; + } + else + { + hr = S_OK; + } + } + } + else + { + hr = E_POINTER; + } + } + + m_Log.WriteNoTS(string.Format(":{0}\r\n", hr)); + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.GetInputStatus + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int GetInputStatus(int ulStreamIndex, out DMOInputStatusFlags pdwStatus) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + pdwStatus = DMOInputStatusFlags.None; + m_Log.Write("GetInputStatus\r\n"); + + // Validate the stream number + if (ulStreamIndex < m_NumInputs && ulStreamIndex >= 0) + { + if (m_fTypesSet) + { + hr = InternalAcceptingInput(ulStreamIndex); + if (hr == S_OK) + { + pdwStatus |= DMOInputStatusFlags.AcceptData; + } + else if (hr == S_FALSE) + { + // Not an error, we just aren't accepting input right now + hr = S_OK; + } + } + else + { + hr = DMOResults.E_TypeNotSet; + } + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pdwStatus = DMOInputStatusFlags.None; + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.GetInputMaxLatency + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int GetInputMaxLatency(int ulStreamIndex, out long prtLatency) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + prtLatency = 0; + m_Log.Write("GetInputMaxLatency\r\n"); + + // Validate the stream number + if (ulStreamIndex < m_NumInputs && ulStreamIndex >= 0) + { + hr = InternalGetInputMaxLatency(ulStreamIndex, out prtLatency); + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + prtLatency = 0; + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.SetInputMaxLatency + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int SetInputMaxLatency(int ulStreamIndex, long rtLatency) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write("SetInputMaxLatency\r\n"); + + // Validate the stream number + if (ulStreamIndex < m_NumInputs && ulStreamIndex >= 0) + { + hr = InternalSetInputMaxLatency(ulStreamIndex, rtLatency); + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.Discontinuity + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int Discontinuity(int ulStreamIndex) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write("Discontinuity\r\n"); + + // Validate the stream number + if (ulStreamIndex < m_NumInputs && ulStreamIndex >= 0) + { + if (m_fTypesSet) + { + // If we are accepting input, tell the internal + // functions about the Discontinuity. + hr = InternalAcceptingInput(ulStreamIndex); + if (S_OK == hr) + { + hr = InternalDiscontinuity(ulStreamIndex); + } + else + { + // No one cares, just return an error + hr = DMOResults.E_NotAccepting; + } + } + else + { + hr = DMOResults.E_TypeNotSet; + } + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.Flush + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int Flush() + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write("Flush()"); + + // Only call the internal flush if there is something to flush + if (m_fTypesSet && !m_fFlushed) + { + hr = InternalFlush(); + } + else + { + hr = S_OK; + } + + m_fFlushed = true; + m_Log.WriteNoTS(string.Format(": {0}\r\n", hr)); + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.AllocateStreamingResources + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int AllocateStreamingResources() + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write("AllocateStreamingResources"); + + // Don't allocate resources until all streams have a type + if (m_fTypesSet) + { + // Only need to call it once + if (!m_fResourcesAllocated) + { + hr = InternalAllocateStreamingResources(); + if (hr >= 0) + { + m_fResourcesAllocated = true; + } + } + else + { + hr = S_OK; + } + } + else + { + hr = DMOResults.E_TypeNotSet; + } + + m_Log.WriteNoTS(string.Format(":{0}\r\n", hr)); + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.FreeStreamingResources + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int FreeStreamingResources() + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write("FreeStreamingResources\r\n"); + + if (m_fResourcesAllocated) + { + m_fResourcesAllocated = false; + InternalFlush(); + hr = InternalFreeStreamingResources(); + GC.Collect(); + } + else + { + hr = S_OK; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.ProcessInput + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int ProcessInput( + int ulStreamIndex, + IMediaBuffer pBuffer, + DMOInputDataBuffer dwFlags, + long rtTimestamp, + long rtTimelength + ) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write(string.Format("ProcessInput ({0}, {1}, {2}, {3})\r\n", ulStreamIndex, dwFlags, rtTimestamp, rtTimelength)); + + if (pBuffer != null) + { + // Validate the stream number + if (ulStreamIndex < m_NumInputs && ulStreamIndex >= 0) + { + // Validate flags + if ( (dwFlags & ~(DMOInputDataBuffer.SyncPoint | + DMOInputDataBuffer.Time | + DMOInputDataBuffer.TimeLength)) == 0) + { + // Make sure all streams have media types set and resources are allocated + hr = AllocateStreamingResources(); + if (hr >= 0) + { + // If we aren't accepting input, forget it + if (InternalAcceptingInput(ulStreamIndex) == S_OK) + { + m_fFlushed = false; + + hr = InternalProcessInput( + ulStreamIndex, + pBuffer, + dwFlags, + rtTimestamp, + rtTimelength); + } + else + { + hr = DMOResults.E_NotAccepting; + } + } + } + else + { + hr = E_INVALIDARG; + } + } + else + { + hr = DMOResults.E_InvalidStreamIndex; + } + } + else + { + hr = E_POINTER; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + + /// + /// COM entry point for IMediaObject.ProcessOutput + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int ProcessOutput( + DMOProcessOutput dwFlags, + int ulOutputBufferCount, + DMOOutputDataBuffer [] pOutputBuffers, + out int pdwStatus) + { + int hr; + + try + { + // Avoid multi-threaded access issues + lock(this) + { + m_Log.Write("ProcessOutput\r\n"); + pdwStatus = 0; + + // The number of buffers needs to exactly equal the number of streams + if (ulOutputBufferCount == m_NumOutputs && ( (dwFlags & ~DMOProcessOutput.DiscardWhenNoBuffer) == 0)) + { + // If there are output streams, pOutputBuffers can't be null + if (m_NumOutputs > 0 || pOutputBuffers != null) + { + hr = AllocateStreamingResources(); + if (hr >= 0) + { + // Init the status flags to zero + int dw; + for (dw = 0; dw < m_NumOutputs; dw++) + { + pOutputBuffers[dw].dwStatus = DMOOutputDataBufferFlags.None; + } + + // Fill the buffers + hr = InternalProcessOutput( + dwFlags, + ulOutputBufferCount, + pOutputBuffers, + out pdwStatus); + + // remember the DMO's incomplete status + for (dw = 0; dw < m_NumOutputs; dw++) + { + if ( (pOutputBuffers[dw].dwStatus & DMOOutputDataBufferFlags.InComplete) > 0) + { + m_OutputInfo[dw].fIncomplete = true; + } + else + { + m_OutputInfo[dw].fIncomplete = false; + } + } + } + } + else + { + hr = E_POINTER; + } + } + else + { + hr = E_INVALIDARG; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pdwStatus = 0; + } + + return hr; + } + + /// + /// COM entry point for IMediaObject.Lock + /// + /// + /// There should be no need to modify or override this method. It will call the + /// abstract and virtual methods to perform its work. + /// + public int Lock(bool lLock) + { + // Lock is doc'ed to limit access to multiple threads at the same time. We + // are doing that with the lock(this) in each entry point, so this is redundant. + return S_OK; + } + + + #endregion + + #region IMediaParamInfo Members + + /// + /// COM entry point for IMediaParamInfo.GetParamCount + /// + /// + /// There should be no need to modify or override this method. See + /// and + /// for details about how this works. + /// + public int GetParamCount(out int pdwParams) + { + int hr; + + try + { + lock(this) + { + m_Log.Write("GetParamCount\r\n"); + + pdwParams = m_Params.Parms.Length; + hr = S_OK; + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pdwParams = 0; + } + + return hr; + } + + /// + /// COM entry point for IMediaParamInfo.GetSupportedTimeFormat + /// + /// + /// There should be no need to modify or override this method. See + /// and + /// for details about how this works. + /// + public int GetSupportedTimeFormat(int dwFormatIndex, out Guid pguidTimeFormat) + { + int hr; + + try + { + m_Log.Write("GetSupportedTimeFormat\r\n"); + lock(this) + { + // If the index is in range, return the specified timeformat + if (dwFormatIndex < m_Params.TimeFormats.Length) + { + pguidTimeFormat = m_Params.TimeFormats[dwFormatIndex]; + hr = S_OK; + } + else + { + pguidTimeFormat = Guid.Empty; + hr = E_INVALIDARG; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pguidTimeFormat = Guid.Empty; + } + + return hr; + } + + /// + /// COM entry point for IMediaParamInfo.GetParamInfo + /// + /// + /// There should be no need to modify or override this method. See + /// and + /// for details about how this works. + /// + public int GetParamInfo(int dwParamIndex, out ParamInfo pInfo) + { + int hr; + + try + { + m_Log.Write("GetParamInfo\r\n"); + lock(this) + { + // If the parameter is in range, return the ParamInfo + if (dwParamIndex < m_Params.Parms.Length) + { + pInfo = m_Params.Parms[dwParamIndex]; + hr = S_OK; + } + else + { + pInfo = new ParamInfo(); + hr = E_INVALIDARG; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pInfo = new ParamInfo(); + } + + return hr; + } + + /// + /// COM entry point for IMediaParamInfo.GetCurrentTimeFormat + /// + /// + /// There should be no need to modify or override this method. See + /// and + /// for details about how this works. + /// + public int GetCurrentTimeFormat(out Guid pguidTimeFormat, out int pTimeData) + { + int hr; + + try + { + m_Log.Write("GetCurrentTimeFormat\r\n"); + lock(this) + { + // Return the current time format from the array + pguidTimeFormat = m_Params.TimeFormats[m_Params.CurrentTimeFormat]; + pTimeData = m_Params.TimeData; + + hr = S_OK; + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pguidTimeFormat = Guid.Empty; + pTimeData = 0; + } + + return hr; + } + + /// + /// COM entry point for IMediaParamInfo.GetParamText + /// + /// + /// There should be no need to modify or override this method. See + /// and + /// for details about how this works. + /// + public int GetParamText(int dwParamIndex, out IntPtr ppwchText) + { + int hr; + + try + { + m_Log.Write("GetParamText\r\n"); + lock(this) + { + // If the parameter is in range, return the text + if (dwParamIndex < m_Params.ParamText.Length) + { + ppwchText = Marshal.StringToCoTaskMemUni(m_Params.ParamText[dwParamIndex]); + hr = S_OK; + } + else + { + ppwchText = IntPtr.Zero; + hr = E_INVALIDARG; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + ppwchText = IntPtr.Zero; + } + + return hr; + } + + /// + /// COM entry point for IMediaParamInfo.GetNumTimeFormats + /// + /// + /// There should be no need to modify or override this method. See + /// and + /// for details about how this works. + /// + public int GetNumTimeFormats(out int pdwNumTimeFormats) + { + int hr; + + try + { + m_Log.Write("GetNumTimeFormats\r\n"); + lock(this) + { + pdwNumTimeFormats = m_Params.TimeFormats.Length; + hr = S_OK; + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pdwNumTimeFormats = 0; + } + + return hr; + } + + #endregion + + #region IMediaParams Members + + /// + /// COM entry point for IMediaParams.SetTimeFormat + /// + /// + /// There should be no need to modify or override this method. See + /// and + /// for details about how this works. + /// + public int SetTimeFormat(Guid guidTimeFormat, int mpTimeData) + { + int hr = E_INVALIDARG; + + try + { + lock(this) + { + m_Log.Write("SetTimeFormat\r\n"); + + // Scan the array of timeformats looking for a match + for (int x=0; x < m_Params.TimeFormats.Length; x++) + { + if (guidTimeFormat == m_Params.TimeFormats[x]) + { + // Found one, grab the index & store the TimeData + m_Params.CurrentTimeFormat = x; + m_Params.TimeData = mpTimeData; + hr = S_OK; + break; + } + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + /// + /// COM entry point for IMediaParams.SetParam + /// + /// + /// There should be no need to modify or override this method. See + /// and + /// for details about how this works. + /// + public int SetParam(int dwParamIndex, MPData value) + { + int hr; + + try + { + lock(this) + { + m_Log.Write("SetParam\r\n"); + + // Check to see if the index is in range + if (dwParamIndex < m_Params.Parms.Length && dwParamIndex >= 0) + { + // Make an envelope that spans from current to end of stream + MPEnvelopeSegment m = new MPEnvelopeSegment(); + + m.flags = MPFlags.Standard; + m.iCurve = MPCaps.Jump; + m.rtStart = 0; + m.rtEnd = long.MaxValue; + m.valStart = value; + m.valEnd = value; + + // Add the struct to the envelope + hr = m_Params.Envelopes[dwParamIndex].AddSegment(m); + } + else + { + hr = E_INVALIDARG; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + + return hr; + } + + /// + /// COM entry point for IMediaParams.AddEnvelope + /// + /// + /// There should be no need to modify or override this method. See + /// and + /// for details about how this works. + /// + public int AddEnvelope(int dwParamIndex, int cSegments, MPEnvelopeSegment[] pEnvelopeSegments) + { + int hr; + + try + { + lock(this) + { + m_Log.Write("AddEnvelope\r\n"); + + hr = S_OK; + + if (dwParamIndex == ALLPARAMS) + { + // Add all the envelopes to all the parameters + for (int y = 0; y < m_Params.Parms.Length && hr >= 0; y++) + { + for (int x = 0; x < cSegments && hr >= 0; x++) + { + // Add the struct to the envelope + hr = m_Params.Envelopes[y].AddSegment(pEnvelopeSegments[x]); + } + } + } + else if (dwParamIndex < m_Params.Parms.Length && dwParamIndex >= 0) + { + // Add all the envelopes to the specified parameter + for (int x = 0; x < cSegments && hr >= 0; x++) + { + // Add the struct to the envelope + hr = m_Params.Envelopes[dwParamIndex].AddSegment(pEnvelopeSegments[x]); + } + } + else + { + hr = E_INVALIDARG; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + /// + /// COM entry point for IMediaParams.GetParam + /// + /// + /// There should be no need to modify or override this method. See + /// and + /// for details about how this works. + /// + public int GetParam(int dwParamIndex, out MPData pValue) + { + int hr; + + try + { + lock(this) + { + m_Log.Write("GetParam\r\n"); + + // If the requested parameter is within range + if (dwParamIndex < m_Params.Parms.Length && dwParamIndex >= 0) + { + // Read the value + pValue = m_Params.Envelopes[dwParamIndex].CalcValueForTime(InternalGetCurrentTime()); + hr = S_OK; + } + else + { + pValue = new MPData(); + hr = E_INVALIDARG; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + + // Have to have this to make the compiler happy. + pValue = new MPData(); + } + + return hr; + } + + /// + /// COM entry point for IMediaParams.FlushEnvelope + /// + /// + /// There should be no need to modify or override this method. See + /// and + /// for details about how this works. + /// + public int FlushEnvelope(int dwParamIndex, long refTimeStart, long refTimeEnd) + { + int hr; + + try + { + lock(this) + { + m_Log.Write("FlushEnvelope\r\n"); + + // If the time range makes sense + if ( (refTimeStart >= 0) && (refTimeEnd >= refTimeStart) ) + { + if (dwParamIndex == ALLPARAMS) + { + hr = S_OK; + + // Apply the flush to all parameters + for (int x=0; x < m_Params.Parms.Length && hr >= 0; x++) + { + MPEnvelopeSegment m = new MPEnvelopeSegment(); + + m.flags = MPFlags.Standard; + m.iCurve = MPCaps.Jump; + m.rtStart = refTimeStart; + m.rtEnd = refTimeEnd; + m.valStart = m_Params.Parms[x].mpdNeutralValue; + m.valEnd = m_Params.Parms[x].mpdNeutralValue; + + hr = m_Params.Envelopes[dwParamIndex].AddSegment(m); + } + } + else if (dwParamIndex < m_Params.Parms.Length) + { + // Apply the flush to the specified parameter + MPEnvelopeSegment m = new MPEnvelopeSegment(); + + m.flags = MPFlags.Standard; + m.iCurve = MPCaps.Jump; + m.rtStart = refTimeStart; + m.rtEnd = refTimeEnd; + m.valStart = m_Params.Parms[dwParamIndex].mpdNeutralValue; + m.valEnd = m_Params.Parms[dwParamIndex].mpdNeutralValue; + + hr = m_Params.Envelopes[dwParamIndex].AddSegment(m); + } + else + { + hr = E_INVALIDARG; + } + } + else + { + hr = E_INVALIDARG; + } + } + } + catch (Exception e) + { + // Generic handling of all exceptions. While .NET will turn exceptions into + // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. + hr = CatFail(e); + } + + return hr; + } + + #endregion + } + + + /// + /// Pretty lame logging class. Note that during Release builds + /// logging is disabled. + /// + internal class Logging : IDisposable + { +#if DEBUG + private static StreamWriter f = new StreamWriter(@"c:\mog.txt", true); + private int m_Instance; +#endif + + /// + /// Constructor + /// + /// Instance number. Written as part of the header. + public Logging(int i) + { +#if DEBUG + m_Instance = i; +#endif + } + + /// + /// Destructor + /// + ~Logging() + { +#if DEBUG + if (f != null) + { + try + { + f.Close(); + f = null; + } + catch {} + } +#endif + } + + /// + /// Write to the log file without writing the header (Date/Time/Instance). + /// + /// String to write + public void WriteNoTS(string s) + { +#if DEBUG + try + { + if (f != null) + { + f.Write(s); + f.Flush(); + } + } + catch {} +#endif + } + + /// + /// Write an entry to the log file + /// + /// String to write + public void Write(string s) + { +#if DEBUG + try + { + if (f != null) + { + f.Write(string.Format("{0} ({2})- {1}", DateTime.Now, s, m_Instance)); + f.Flush(); + } + } + catch {} +#endif + } + #region IDisposable Members + + /// + /// Dispose + /// + public void Dispose() + { +#if DEBUG + if (f != null) + { + try + { + f.Close(); + f = null; + GC.SuppressFinalize(this); + } + catch {} + } +#endif + } + + + #endregion + } +} diff --git a/Samples/DMO/DmoSplit/DMO/mykey.snk b/Samples/DMO/DmoSplit/DMO/mykey.snk new file mode 100644 index 0000000000000000000000000000000000000000..73348d3f5ab83926f629c4715ebe500d22ba7227 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50096uc!+_Ts6xzGtim22McK$$Kc^}&OuT`2 z7|8rr7Pu4-SgYmnH~_?pxW{R0XSv2T$&p)&3BoTGChrOciL~BJtd)Vri+3@Y<^NDA zvto|}t4L>U`-~`1$O9*LPj{S0-zUX~ozMy_L_uTUdm{rb%%o-4@kE!kQ33mMW8J|e z*sQNVj^zd(V^W@9d#LeETcCZi9Eta(?ei*g-U`{3+dYM)rVAPif-k~K#WB5D^1|^W z*ykQ(CJgn zWv^x#(zA$Ihb)YsEl?8?@`$|-VizwNbDsd{Xs(~b)NwLNJ?N;tlE^w}7sGdVm(RYA zh{8dg_%H^al|UhN&jj*(>R=4oe|(HS#RYQ4l4e>d789-lluOlBq^zETJ@GKj{_2j4$w zo9}xCh!8{T3=X##Skq>ikMjsvB|y%crWBM2iW(4pI}c%z6%lW!=~4v77#3{z!dmB1 z__&l)-{KUYR+|8|;wB^R|9ET$J@(@=#rd^=)qs85?vAy(PSF5CyNkus435LVkZ$rj zNw|JG-P7^hF<(;#o*Vk}5R#e|^13tBbQkeF?djULtvqyxd3<{9 literal 0 HcmV?d00001 diff --git a/Samples/DMO/DmoSplit/FormDMO/AssemblyInfo.cs b/Samples/DMO/DmoSplit/FormDMO/AssemblyInfo.cs new file mode 100644 index 0000000..9f89a32 --- /dev/null +++ b/Samples/DMO/DmoSplit/FormDMO/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/DMO/DmoSplit/FormDMO/Form1.cs b/Samples/DMO/DmoSplit/FormDMO/Form1.cs new file mode 100644 index 0000000..641bbf0 --- /dev/null +++ b/Samples/DMO/DmoSplit/FormDMO/Form1.cs @@ -0,0 +1,240 @@ +#region license + +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +#endregion + +using System; +using System.Diagnostics; +using System.Drawing; +using System.Windows.Forms; +using System.Runtime.InteropServices; + +using DirectShowLib; +using DirectShowLib.DMO; + +namespace FormDMO +{ + /// + /// Summary description for Form1. + /// + public class Form1 : System.Windows.Forms.Form + { + + private IFilterGraph2 graphBuilder = null; + private DsROTEntry m_rot = null; + + private System.Windows.Forms.Button btnStart; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.RadioButton rbLeft; + private System.Windows.Forms.RadioButton rbRight; + private System.Windows.Forms.TextBox tbFileName; + + public Form1() + { + // + // Required for Windows Form Designer support + // + InitializeComponent(); + + // + // TODO: Add any constructor code after InitializeComponent call + // + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + base.Dispose( disposing ); + + if (m_rot != null) + { + m_rot.Dispose(); + m_rot = null; + } + if (graphBuilder != null) + { + (graphBuilder as IMediaControl).Stop(); + Marshal.ReleaseComObject(graphBuilder); + graphBuilder = null; + } + } + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnStart = new System.Windows.Forms.Button(); + this.tbFileName = new System.Windows.Forms.TextBox(); + this.rbLeft = new System.Windows.Forms.RadioButton(); + this.rbRight = new System.Windows.Forms.RadioButton(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // btnStart + // + this.btnStart.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnStart.Location = new System.Drawing.Point(80, 136); + this.btnStart.Name = "btnStart"; + this.btnStart.Size = new System.Drawing.Size(75, 40); + this.btnStart.TabIndex = 0; + this.btnStart.Text = "Start"; + this.btnStart.Click += new System.EventHandler(this.button1_Click); + // + // tbFileName + // + this.tbFileName.Location = new System.Drawing.Point(16, 24); + this.tbFileName.Name = "tbFileName"; + this.tbFileName.Size = new System.Drawing.Size(216, 20); + this.tbFileName.TabIndex = 1; + this.tbFileName.Text = "c:\\l2.wav"; + // + // rbLeft + // + this.rbLeft.Checked = true; + this.rbLeft.Location = new System.Drawing.Point(24, 16); + this.rbLeft.Name = "rbLeft"; + this.rbLeft.Size = new System.Drawing.Size(56, 24); + this.rbLeft.TabIndex = 2; + this.rbLeft.TabStop = true; + this.rbLeft.Text = "Left"; + // + // rbRight + // + this.rbRight.Location = new System.Drawing.Point(24, 40); + this.rbRight.Name = "rbRight"; + this.rbRight.Size = new System.Drawing.Size(56, 24); + this.rbRight.TabIndex = 3; + this.rbRight.Text = "Right"; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.rbLeft); + this.groupBox1.Controls.Add(this.rbRight); + this.groupBox1.Location = new System.Drawing.Point(24, 56); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(184, 72); + this.groupBox1.TabIndex = 4; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Channel"; + // + // Form1 + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(242, 188); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.tbFileName); + this.Controls.Add(this.btnStart); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.Name = "Form1"; + this.Text = "DMOSplit Test"; + this.groupBox1.ResumeLayout(false); + this.ResumeLayout(false); + + } + #endregion + + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.Run(new Form1()); + } + + + private void button1_Click(object sender, System.EventArgs e) + { + int hr; + + if (tbFileName.Enabled) + { + BuildGraph(tbFileName.Text, rbLeft.Checked); + + // Run this graph + hr = (graphBuilder as IMediaControl).Run(); + DsError.ThrowExceptionForHR(hr); + tbFileName.Enabled = false; + groupBox1.Enabled = false; + btnStart.Text = "Stop"; + } + else + { + hr = (graphBuilder as IMediaControl).Stop(); + groupBox1.Enabled = true; + tbFileName.Enabled = true; + Marshal.ReleaseComObject(graphBuilder); + graphBuilder = null; + btnStart.Text = "Start"; + } + } + + private void BuildGraph(string sFileName, bool bLeft) + { + int hr; + IBaseFilter ibfFile = null; + IBaseFilter ibfFilter = null; + IBaseFilter ibfRender = null; + IDMOWrapperFilter dmoWrapperFilter = null; + + ICaptureGraphBuilder2 icgb = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); + + graphBuilder = (IFilterGraph2) new FilterGraph(); +#if DEBUG + m_rot = new DsROTEntry(graphBuilder); +#endif + + hr = icgb.SetFiltergraph(graphBuilder); + DsError.ThrowExceptionForHR(hr); + + // Add a DMO Wrapper Filter + ibfFilter = (IBaseFilter) new DMOWrapperFilter(); + dmoWrapperFilter = (IDMOWrapperFilter) ibfFilter; + + // Since I know the guid of the DMO I am looking for, I can do this. + hr = dmoWrapperFilter.Init(new Guid("{EAB6CBA9-78DD-4ae4-9A69-1CE1C55369F6}"), DMOCategory.AudioEffect); + DMOError.ThrowExceptionForHR(hr); + + // Add it to the Graph + hr = graphBuilder.AddFilter(ibfFilter, "DMO Filter"); + DsError.ThrowExceptionForHR(hr); + + ibfRender = (IBaseFilter)new AudioRender(); + hr = graphBuilder.AddFilter(ibfRender, "Renderer"); + DsError.ThrowExceptionForHR(hr); + + ibfFile = (IBaseFilter)new AsyncReader(); + hr = graphBuilder.AddFilter(ibfFile, "Reader"); + DsError.ThrowExceptionForHR(hr); + + IFileSourceFilter ifileSink = (IFileSourceFilter)ibfFile; + hr = ifileSink.Load(sFileName, null); + DsError.ThrowExceptionForHR(hr); + + hr = icgb.RenderStream(null, null, ibfFile, null, ibfFilter); + DsError.ThrowExceptionForHR(hr); + + IPin iPin = DsFindPin.ByDirection(ibfFilter, PinDirection.Output, bLeft ? 0 : 1); + + hr = icgb.RenderStream(null, null, iPin, null, ibfRender); + DsError.ThrowExceptionForHR(hr); + + Marshal.ReleaseComObject(ibfRender); + Marshal.ReleaseComObject(dmoWrapperFilter); + Marshal.ReleaseComObject(iPin); + } + } +} diff --git a/Samples/DMO/DmoSplit/FormDMO/Form1.resx b/Samples/DMO/DmoSplit/FormDMO/Form1.resx new file mode 100644 index 0000000..78d5e96 --- /dev/null +++ b/Samples/DMO/DmoSplit/FormDMO/Form1.resx @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + Private + + + Private + + + Private + + + False + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + 8, 8 + + + True + + + False + + + True + + + Private + + + False + + + (Default) + + + False + + + Form1 + + + False + + + 8, 8 + + + True + + + 80 + + + True + + + Private + + \ No newline at end of file diff --git a/Samples/DMO/DmoSplit/FormDMO/FormDMO-2005.csproj b/Samples/DMO/DmoSplit/FormDMO/FormDMO-2005.csproj new file mode 100644 index 0000000..71928cd --- /dev/null +++ b/Samples/DMO/DmoSplit/FormDMO/FormDMO-2005.csproj @@ -0,0 +1,110 @@ + + + Local + 8.0.50727 + 2.0 + {B72919DC-C5B9-441A-9AD9-6CF9A97AFE85} + Debug + AnyCPU + App.ico + + + FormDMO + + + JScript + Grid + IE50 + false + WinExe + FormDMO + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + + + Code + + + Form + + + Form1.cs + + + + + + + + + + \ No newline at end of file diff --git a/Samples/DMO/DmoSplit/FormDMO/FormDmoSplit.csproj b/Samples/DMO/DmoSplit/FormDMO/FormDmoSplit.csproj new file mode 100644 index 0000000..d370c89 --- /dev/null +++ b/Samples/DMO/DmoSplit/FormDMO/FormDmoSplit.csproj @@ -0,0 +1,142 @@ + + + + Local + 8.0.50727 + 2.0 + {D6EE33A0-7EAF-4C98-8E2F-7CD39DE72BB2} + Debug + AnyCPU + App.ico + + + FormDMO + + + JScript + Grid + IE50 + false + WinExe + FormDMO + OnBuildSuccess + + + + + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + + + Code + + + Form + + + Form1.cs + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + + + + + + \ No newline at end of file diff --git a/Samples/DMO/DmoSplit/FormDMO/readme.txt b/Samples/DMO/DmoSplit/FormDMO/readme.txt new file mode 100644 index 0000000..5b8cb16 --- /dev/null +++ b/Samples/DMO/DmoSplit/FormDMO/readme.txt @@ -0,0 +1,4 @@ +FormDmo - This code exercises the DMOSplit sample code. + +This rather sample shows how to build a graph using the DMOSplit DMO. It connects either +the left or the right channel of a stereo input file to the audio renderer. \ No newline at end of file diff --git a/Samples/DMO/DmoSplit/readme.txt b/Samples/DMO/DmoSplit/readme.txt new file mode 100644 index 0000000..a7df139 --- /dev/null +++ b/Samples/DMO/DmoSplit/readme.txt @@ -0,0 +1,13 @@ +There are several readme's with this project. In addition to this file, there is a +readme in both the DMO and the FormDmo folders. + +The readme in the DmoForm folder talks about calling DMOs. The readme in the DMO +folder talks about the specific sample. + +There are detailed steps in the DMOFlip sample (remember, this directory is the DmoSplit +sample!) in the IMediaObjectImpl.chm file talking about how to make a DMO. In particular, +you should look at the "IMediaObjectImpl Class" page in the file which provides step by +step instructions on how to write a DMO. + +For people who have never written a COM object, you may find the article at +http://community.borland.com/article/0,1410,32754,00.html to be informative. \ No newline at end of file diff --git a/Samples/Editing/DESCombine/DESCombine-2005.sln b/Samples/Editing/DESCombine/DESCombine-2005.sln new file mode 100644 index 0000000..2f1b7df --- /dev/null +++ b/Samples/Editing/DESCombine/DESCombine-2005.sln @@ -0,0 +1,25 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DESCombineLib-2005", "DESCombineLib\DESCombineLib-2005.csproj", "{A10D4671-34C7-4AD8-B537-B2B9C48242F7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestCombine-2005", "TestCombine\TestCombine-2005.csproj", "{B20FEBE5-4895-4930-8017-C7614AB6C49B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A10D4671-34C7-4AD8-B537-B2B9C48242F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A10D4671-34C7-4AD8-B537-B2B9C48242F7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A10D4671-34C7-4AD8-B537-B2B9C48242F7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A10D4671-34C7-4AD8-B537-B2B9C48242F7}.Release|Any CPU.Build.0 = Release|Any CPU + {B20FEBE5-4895-4930-8017-C7614AB6C49B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B20FEBE5-4895-4930-8017-C7614AB6C49B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B20FEBE5-4895-4930-8017-C7614AB6C49B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B20FEBE5-4895-4930-8017-C7614AB6C49B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Editing/DESCombine/DESCombine-2008.sln b/Samples/Editing/DESCombine/DESCombine-2008.sln new file mode 100644 index 0000000..efe2089 --- /dev/null +++ b/Samples/Editing/DESCombine/DESCombine-2008.sln @@ -0,0 +1,25 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DESCombineLib-2008", "DESCombineLib\DESCombineLib-2008.csproj", "{A10D4671-34C7-4AD8-B537-B2B9C48242F7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestCombine-2008", "TestCombine\TestCombine-2008.csproj", "{B20FEBE5-4895-4930-8017-C7614AB6C49B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A10D4671-34C7-4AD8-B537-B2B9C48242F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A10D4671-34C7-4AD8-B537-B2B9C48242F7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A10D4671-34C7-4AD8-B537-B2B9C48242F7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A10D4671-34C7-4AD8-B537-B2B9C48242F7}.Release|Any CPU.Build.0 = Release|Any CPU + {B20FEBE5-4895-4930-8017-C7614AB6C49B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B20FEBE5-4895-4930-8017-C7614AB6C49B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B20FEBE5-4895-4930-8017-C7614AB6C49B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B20FEBE5-4895-4930-8017-C7614AB6C49B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Editing/DESCombine/DESCombine.ndoc b/Samples/Editing/DESCombine/DESCombine.ndoc new file mode 100644 index 0000000..5b7a9e0 --- /dev/null +++ b/Samples/Editing/DESCombine/DESCombine.ndoc @@ -0,0 +1,44 @@ + + + + + + The classes in the DESCombineLib can be used to combine multiple video/audio files. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Editing/DESCombine/DESCombineLib/AssemblyInfo.cs b/Samples/Editing/DESCombine/DESCombineLib/AssemblyInfo.cs new file mode 100644 index 0000000..293902c --- /dev/null +++ b/Samples/Editing/DESCombine/DESCombineLib/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +[assembly: AssemblyTitle("DESCombine")] +[assembly: AssemblyDescription("Library for combining video files")] +[assembly: AssemblyCompany("http://DirectShowNet.SourceForge.net")] +[assembly: AssemblyProduct("DirectShowLib")] +[assembly: AssemblyCopyright("Public Domain")] + +[assembly: AssemblyVersion("1.0.*")] diff --git a/Samples/Editing/DESCombine/DESCombineLib/DESCombine.cs b/Samples/Editing/DESCombine/DESCombineLib/DESCombine.cs new file mode 100644 index 0000000..b8db66d --- /dev/null +++ b/Samples/Editing/DESCombine/DESCombineLib/DESCombine.cs @@ -0,0 +1,1623 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + +Written by snarfle@sourceforge.net +*****************************************************************************/ + +using System; +using System.Runtime.InteropServices; +using System.Diagnostics; +using System.Threading; +using System.Collections; + +using DirectShowLib; +using DirectShowLib.DES; + +namespace DESCombineLib +{ + /// + /// A callback interface that can be implemented by callers to DESCombine + /// who wish to perform processing on video or audio frames. + /// + /// + /// Classes which implement this interfaces can be passed to + /// or . Each audio or video frame that is processed by DES + /// will be passed to this callback which can perform additional processing. + /// + public interface IDESCombineCB + { + /// + /// Callback routine - called once for each audio or video frame + /// + /// + /// The buffer can be examined or modified. + /// + /// Filename currently being processed + /// Time stamp in seconds + /// Pointer to the buffer + /// Length of the buffer + /// Return S_OK if successful, or an HRESULT error code otherwise. This value is sent as + /// the return value to ISampleGrabberCB::BufferCB + int BufferCB( + string sFileName, + double SampleTime, + System.IntPtr pBuffer, + int BufferLen + ); + } + + + /// Used by the event. + /// Reports the event code that exited the graph. + /// + /// Signals that all files have been rendered + public class CompletedArgs : System.EventArgs + { + /// The result of the rendering + /// + /// This code will be a member of DirectShowLib.EventCode. Typically it + /// will be EventCode.Complete, EventCode.ErrorAbort or EventCode.UserAbort. + /// + public EventCode Result; + + /// + /// Used to construct an instace of the class. + /// + /// + internal CompletedArgs(EventCode ec) + { + Result = ec; + } + } + + + /// + /// Used by the event. Reports + /// when a file has completed processing. + /// + /// + /// To determine whether you are receiving a notification for an audio + /// or video file completing, examine the property. Also, when + /// using the RenderToWindow, dropped frames can result in late or missed notifications. + /// + public class FileCompletedArgs : System.EventArgs + { + /// + /// Type of the file that has completed (audio/video) + /// + public enum FileType + { + /// + /// Type is video + /// + Video, + + /// + /// Type is audio + /// + Audio + } + + /// + /// The file name that just completed + /// + /// + /// Use the to determine whether this is a video + /// or audio file. + /// + public string FileName; + + /// + /// The type (audio/video) of file + /// + public FileType Type; + + /// + /// Used to construct an instance of the class. + /// + /// Filename that has been completed + /// Type of the file (audio/video) + internal FileCompletedArgs(string sFilename, FileType eType) + { + FileName = sFilename; + Type = eType; + } + } + + + /// + /// Takes a combination of video or audio files of various formats and stitches them together + /// sequentially. The result can be output to one of several formats including a video window, + /// or an AVI file. + /// + /// The normal sequence when using this class would be: + /// + /// Call the constructor + /// Call the Add*File methods to specify the video/audio files to combine + /// Call RenderTo* to specify where to render the output + /// Call StartRendering to begin the rendering + /// + /// + /// + /// When calling the RenderTo* methods, a callback routine can be registered so that each audio or video + /// frame will be passed to the CB routine. + /// + public class DESCombine : IDisposable + { + #region Declarations + + /// + /// Number of MilliSeconds in a second. + /// + /// + /// This constant may be useful for calculations + /// + public const long MILLISECONDS = (1000); // 10 ^ 3 + + /// + /// Number of NanoSeconds in a second. + /// + /// + /// This constant may be useful for calculations + /// + public const long NANOSECONDS = (1000000000); // 10 ^ 9 + + /// + /// Number of 100NS in a second. + /// + /// + /// To convert from seconds to 100NS + /// units (used by most DES function), multiply the seconds by UNITS. + /// + public const long UNITS = (NANOSECONDS / 100); // 10 ^ 7 + + /// + /// Event code indicating a video file has finished being processed + /// + internal const EventCode EC_VideoFileComplete = (EventCode)0x8000; + + /// + /// Event code indicating an audio file has finished being processed + /// + internal const EventCode EC_AudioFileComplete = (EventCode)0x8001; + + /// + /// Used to indicate the state of the class + /// + private enum ClassState + { + Constructed, + FilesAdded, + RenderSelected, + GraphStarted, + GraphCompleting, + GraphCompleted, + Cancelling, + Cancelled + } + + #endregion + + #region Data Members + + // How much of the process of rendering the class has been completed + volatile private ClassState m_State; + + /// + /// Status of the video timeline + /// + private Group m_Video; + + /// + /// Status of the audio timeline + /// + private Group m_Audio; + + /// + /// Pointer to the timeline containing the audio and video tracks + /// + private IAMTimeline m_pTimeline; + + /// + /// IGraphBuilder object for the timeline + /// + private IGraphBuilder m_pGraph; + + /// + /// Media control interface from m_pGraph + /// + private IMediaControl m_pControl; + + /// + /// The engine to process the timeline (can't be released + /// until the graph processing is complete) + /// + private IRenderEngine m_pRenderEngine; + +#if DEBUG + /// + /// Used when adding the graph to the Running Object Table. + /// This allows the graph to be inspected from GraphEdit using + /// File/Connect + /// + private DsROTEntry m_rot; +#endif + + #endregion + + /// + /// Construct the class + /// + /// + /// The input files do not need to have the same height/width/fps. DES will + /// automatically convert them all to the values specified by the constructor. + /// + /// Frames per second (commonly 15 or 30) + /// Color depth: 16, 24 or 32 + /// Frame width (commonly 320, 640, etc) + /// Frame height (commonly 240, 480, etc) + public DESCombine(double FPS, short BitCount, int Width, int Height) + { + // Initialize the data members + m_State = ClassState.Constructed; + + // Create the timeline + m_pTimeline = (IAMTimeline)new AMTimeline(); + + // Set the frames per second + int hr = m_pTimeline.SetDefaultFPS(FPS); + DESError.ThrowExceptionForHR(hr); + + // Init the video group + m_Video = new Group(GetVideoMediaType(BitCount, Width, Height), m_pTimeline, FPS); + + // Init the audio group + m_Audio = new Group(GetAudioMediaType(), m_pTimeline, FPS); + } + + /// + ~DESCombine() + { + Dispose(); + } + + /// + /// Add a file with both video and audio to the timeline. + /// + /// + /// If a file contains both audio and video, this method can be used + /// to add the file to both groups at the same time. + /// + /// Video files can be of different + /// lengths, frame sizes, color depths, aspect ratios, frame rates, etc. DES + /// converts them all to the values specified in the constructor. + /// + /// A/V file path+name + /// Start position within the file specified in 100ns units + /// End position within the file specified in 100ns units + /// or -1 to add entire file + public void AddAVFile( + string sFileName, + long lStart, + long lStop) + { + if (m_State > ClassState.FilesAdded) + { + throw new Exception("Can't add files since rendering method already selected"); + } + + m_Video.Add(sFileName, lStart, lStop); + m_Audio.Add(sFileName, lStart, lStop); + + // At least one file has now been added + m_State = ClassState.FilesAdded; + + } + + /// + /// Add the video portion of a file to the timeline. + /// + /// + /// If a file contains both audio and video, this method will only add the video portion. + /// + /// Video files can be of different + /// lengths, frame sizes, color depths, aspect ratios, frame rates, etc. DES + /// converts them all to the values specified in the constructor. + /// + /// Video file path+name + /// Start position within the file specified in 100ns units + /// End position within the file specified in 100ns units + /// or -1 to add entire file + public void AddVideoFile( + string sFileName, + long lStart, + long lStop) + { + if (m_State > ClassState.FilesAdded) + { + throw new Exception("Can't add files since rendering method already selected"); + } + + m_Video.Add(sFileName, lStart, lStop); + + // At least one file has now been added + m_State = ClassState.FilesAdded; + + } + + /// + /// Add the audio portion of a file to the timeline. + /// + /// + /// If a file contains both audio and video, this method will only add the audio portion. + /// + /// Audio file path+name + /// Start position within the file specified in 100ns units + /// End position within the file specified in 100ns units + /// or -1 to go to the end of the file + public void AddAudioFile( + string sFileName, + long lStart, + long lStop) + { + if (m_State > ClassState.FilesAdded) + { + throw new Exception("Can't add files since rendering method already selected"); + } + + m_Audio.Add(sFileName, lStart, lStop); + + // At least one file has now been added + m_State = ClassState.FilesAdded; + + } + + /// + /// Configure the graph to output the results to a video window. + /// + /// + /// The callback routines are invoked once for each sample. This allows for additional processing to + /// be performed on the video or audio buffers. + /// + /// Window handle to render to, or IntPtr.Zero to render to its own window + /// Callback routine to be called for each video frame or null for no callback + /// Callback routine to be called for each audio frame or null for no callback + public void RenderToWindow(IntPtr hWnd, IDESCombineCB pVideoCallback, IDESCombineCB pAudioCallback) + { + int hr; + IPin pPin; + IVideoWindow pVidWindow; + IAMTimelineObj pGroup; + + // Perform initialization common to all render routines + RenderCommon(); + + // Contains useful routines for creating the graph + ICaptureGraphBuilder2 icgb = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); + + try + { + hr = icgb.SetFiltergraph(m_pGraph); + DESError.ThrowExceptionForHR(hr); + + int NumGroups; + hr = m_pTimeline.GetGroupCount(out NumGroups); + DESError.ThrowExceptionForHR(hr); + + // Walk the groups. For DESCombine, there is one group that + // contains all the video, and a second group for the audio. + for (int i = 0; i < NumGroups; i++) + { + hr = m_pTimeline.GetGroup(out pGroup, i); + DESError.ThrowExceptionForHR(hr); + + try + { + // Inform the graph we will be previewing (rather than writing to disk) + IAMTimelineGroup pTLGroup = (IAMTimelineGroup)pGroup; + hr = pTLGroup.SetPreviewMode(true); + DESError.ThrowExceptionForHR(hr); + } + finally + { + // Release the group + Marshal.ReleaseComObject(pGroup); + } + + // Get the IPin for the current group + hr = m_pRenderEngine.GetGroupOutputPin(i, out pPin); + DESError.ThrowExceptionForHR(hr); + + try + { + // If this is the video pin + if (IsVideo(pPin)) + { + // Get a video renderer + IBaseFilter ibfVideoRenderer = (IBaseFilter)new VideoRenderer(); + + try + { + // Create a sample grabber, add it to the graph and connect it all up + MyCallback mcb = new MyCallback(m_Video, pVideoCallback, (IMediaEventSink) m_pGraph, EC_VideoFileComplete); + RenderWindowHelper(icgb, mcb, "Video", pPin, ibfVideoRenderer); + } + finally + { + Marshal.ReleaseComObject(ibfVideoRenderer); + } + } + else + { + // Get an audio renderer + IBaseFilter ibfAudioRenderer = (IBaseFilter)new AudioRender(); + + try + { + // Create a sample grabber, add it to the graph and connect it all up + MyCallback mcb = new MyCallback(m_Audio, pAudioCallback, (IMediaEventSink) m_pGraph, EC_AudioFileComplete); + RenderWindowHelper(icgb, mcb, "Audio", pPin, ibfAudioRenderer); + } + finally + { + Marshal.ReleaseComObject(ibfAudioRenderer); + } + } + } + finally + { + Marshal.ReleaseComObject(pPin); + } + } + + // Configure the video window + pVidWindow = (IVideoWindow)m_pGraph; + + // If a window handle was supplied, use it + if (hWnd != IntPtr.Zero) + { + hr = pVidWindow.put_Owner(hWnd); + DESError.ThrowExceptionForHR(hr); + } + else + { + // Use our own window + + hr = pVidWindow.put_Caption("Video Rendering Window"); + DESError.ThrowExceptionForHR(hr); + + // since no user interaction is allowed, remove + // system menu and maximize/minimize buttons + WindowStyle lStyle=0; + hr = pVidWindow.get_WindowStyle(out lStyle); + DESError.ThrowExceptionForHR(hr); + + lStyle &= ~(WindowStyle.MinimizeBox | WindowStyle.MaximizeBox | WindowStyle.SysMenu); + hr = pVidWindow.put_WindowStyle(lStyle); + DESError.ThrowExceptionForHR(hr); + } + } + finally + { + Marshal.ReleaseComObject(icgb); + } + } + + /// + /// Configure the graph to output the results to an AVI file. + /// + /// File name for output (must not be null) + /// IBaseFilter of a video compressor to use (or null for none). + /// Note that no configuration of this compressor is done by this method. It merely adds it + /// to the graph in the appropriate place. Also, the pointer is not invalidated, so any configuration + /// of the compressor that needs to be done after being added to the graph can still be done. + /// IBaseFilter of an audio compressor to use (or null for none). + /// Note that no configuration of this compressor is done by this method. It merely adds it + /// to the graph in the appropriate place. Also, the pointer is not invalidated, so any configuration + /// of the compressor that needs to be done after being added to the graph can still be done. + /// Callback routine to be called for each video frame or null for no callback + /// Callback routine to be called for each audio frame or null for no callback + /// + /// The callback routines are invoked once for each sample. This allows for additional processing to + /// be performed on the video or audio buffers. + /// + public void RenderToAVI( + string sOutputFile, + IBaseFilter ibfVideoCompressor, + IBaseFilter ibfAudioCompressor, + IDESCombineCB pVideoCallback, + IDESCombineCB pAudioCallback) + { + int hr; + IPin pPin; + + if (sOutputFile == null) + { + throw new Exception("Output file name cannot be null"); + } + + // Perform initialization common to all render routines + RenderCommon(); + + // Contains useful routines for creating the graph + ICaptureGraphBuilder2 icgb = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); + + try + { + hr = icgb.SetFiltergraph(m_pGraph); + DESError.ThrowExceptionForHR(hr); + + // Create the file writer + IBaseFilter pMux; + IFileSinkFilter pFilter; + hr = icgb.SetOutputFileName(MediaSubType.Avi, sOutputFile, out pMux, out pFilter); + DESError.ThrowExceptionForHR(hr); + + // We don't need this, so let it go + Marshal.ReleaseComObject(pFilter); + + try + { + int NumGroups; + hr = m_pTimeline.GetGroupCount(out NumGroups); + DESError.ThrowExceptionForHR(hr); + + // Walk the groups. For this class, there is one group that + // contains all the video, and a second group for the audio. + for (int i = 0; i < NumGroups; i++) + { + IAMTimelineObj pGroup; + + hr = m_pTimeline.GetGroup(out pGroup, i); + DESError.ThrowExceptionForHR(hr); + + try + { + // Inform the graph we will be writing to disk (rather than previewing) + IAMTimelineGroup pTLGroup = (IAMTimelineGroup)pGroup; + hr = pTLGroup.SetPreviewMode(false); + DESError.ThrowExceptionForHR(hr); + } + finally + { + Marshal.ReleaseComObject(pGroup); + } + + // Get the IPin for the current group + hr = m_pRenderEngine.GetGroupOutputPin(i, out pPin); + DESError.ThrowExceptionForHR(hr); + + try + { + if (IsVideo(pPin)) + { + // Create a sample grabber, add it to the graph and connect it all up + MyCallback mcb = new MyCallback(m_Video, pVideoCallback, (IMediaEventSink) m_pGraph, EC_VideoFileComplete); + RenderHelper(icgb, mcb, "Video", pPin, ibfVideoCompressor, pMux); + } + else + { + // Create a sample grabber, add it to the graph and connect it all up + MyCallback mcb = new MyCallback(m_Audio, pAudioCallback, (IMediaEventSink) m_pGraph, EC_AudioFileComplete); + RenderHelper(icgb, mcb, "Audio", pPin, ibfAudioCompressor, pMux); + } + } + finally + { + Marshal.ReleaseComObject(pPin); + } + } + } + finally + { + Marshal.ReleaseComObject(pMux); + } + } + finally + { + Marshal.ReleaseComObject(icgb); + } + } + + + /// + /// Begins rendering and returns immediately. + /// + /// + /// Final status is sent as a event. + /// + public void StartRendering() + { + int hr; + + if (m_State < ClassState.RenderSelected) + { + throw new Exception("Render method not selected"); + } + + m_State = ClassState.GraphStarted; + + m_pControl = (IMediaControl)m_pGraph; + + // Create a new thread to process events + Thread t; + t = new Thread(new ThreadStart(EventWait)); + t.Name = "Media Event Thread"; + t.Start(); + + hr = m_pControl.Run( ); + DESError.ThrowExceptionForHR(hr); + } + + /// + /// Returns the length of the timeline in . + /// + /// + /// This will return the longer of the video time line or the audio time line. + /// + public long MediaLength + { + get + { + long len; + int hr = m_pTimeline.GetDuration(out len); + DESError.ThrowExceptionForHR(hr); + + return len; + } + } + + /// + /// Returns the length of the video group in . + /// + /// + /// This will return the length of the video group. + /// + public long VideoLength + { + get + { + return m_Video.Length; + } + } + + /// + /// Returns the length of the audio group in . + /// + /// + /// This will return the length of the audio group. + /// + public long AudioLength + { + get + { + return m_Audio.Length; + } + } + + /// + /// Used to signal that the graph should be cancelled. + /// + /// + /// Only has meaning if called after . + /// + public void Cancel() + { + if (m_State < ClassState.GraphStarted) + { + throw new Exception("Graph not yet started"); + } + +#if DEBUG + if (m_rot != null) + { + m_rot.Dispose(); + m_rot = null; + } +#endif + if (m_State < ClassState.GraphCompleting) + { + ChangeState(ClassState.Cancelling); + } + } + + /// + /// Returns an XML description of the capture graph (as seen by DES). + /// + /// + /// This method can only be called after one + /// of the render functions has been called. Might be useful for debugging. It is also possible (even easy) + /// to build the DES part of a graph from an XML file, however that functionality has not been implemented + /// in this version of the library. + /// + /// String containing XML + public string GetXML() + { + if (m_State < ClassState.RenderSelected) + { + throw new Exception("No render method has been selected"); + } + + IXml2Dex pXML; + string sRet; + int hr; + + pXML = (IXml2Dex)new Xml2Dex(); + + try + { + hr = pXML.WriteXML(m_pTimeline, out sRet); + DESError.ThrowExceptionForHR(hr); + } + finally + { + Marshal.ReleaseComObject(pXML); + } + + return sRet; + } + + + /// + /// Called when the graph has finished running. + /// + /// + /// The + /// contains the result of running the graph (Completed, UserAborted, + /// out of disk space, etc.) + /// This code will be a member of DirectShowLib.EventCode. Typically it + /// will be EventCode.Complete, EventCode.ErrorAbort or EventCode.UserAbort. + /// + public event EventHandler Completed = null; + /// + /// Called when a file has finished processing. + /// + /// + /// The contains the file name and type. + /// Note that if RenderToWindow() is chosen, dropped frames can result in missed notifications. This + /// should not affect other RenderTo* methods. + /// + public event EventHandler FileCompleted = null; + + /// + /// Helps deal with potential conflicts between the eventing thread + /// and client calls to Cancel() + /// + /// State to change to + private void ChangeState(ClassState newState) + { + lock (this) + { + if (m_State == ClassState.GraphStarted) + { + m_State = newState; + } + } + } + + /// + /// Called on a new thread to process events from the graph. The thread + /// exits when the graph finishes. Cancelling is done here. + /// + private void EventWait() + { + // Returned when GetEvent is called but there are no events + const int E_ABORT = unchecked((int)0x80004004); + + int hr; + IntPtr p1, p2; + EventCode ec; + EventCode exitCode = 0; + + IMediaEvent pEvent = (IMediaEvent)m_pGraph; + + do + { + // Read the event + for ( + hr = pEvent.GetEvent(out ec, out p1, out p2, 100); + hr >= 0 && m_State < ClassState.GraphCompleted; + hr = pEvent.GetEvent(out ec, out p1, out p2, 100) + ) + { + switch(ec) + { + // If the clip is finished playing + case EventCode.Complete: + case EventCode.ErrorAbort: + ChangeState(ClassState.GraphCompleting); + exitCode = ec; + + // Release any resources the message allocated + hr = pEvent.FreeEventParams(ec, p1, p2); + DESError.ThrowExceptionForHR(hr); + break; + + // Walked past the end of a video file, send an event + case EC_VideoFileComplete: + if (FileCompleted != null) + { + MediaFile mf = m_Video.File(p1.ToInt32()); + FileCompletedArgs ca = new FileCompletedArgs(mf.FileName, FileCompletedArgs.FileType.Video); + FileCompleted(this, ca); + } + break; + + // Walked past the end of a video file, send an event + case EC_AudioFileComplete: + if (FileCompleted != null) + { + MediaFile mf = m_Audio.File(p1.ToInt32()); + FileCompletedArgs ca = new FileCompletedArgs(mf.FileName, FileCompletedArgs.FileType.Audio); + FileCompleted(this, ca); + } + break; + + default: + // Release any resources the message allocated + hr = pEvent.FreeEventParams(ec, p1, p2); + DESError.ThrowExceptionForHR(hr); + break; + } + } + + // If the error that exited the loop wasn't due to running out of events + if (hr != E_ABORT) + { + DESError.ThrowExceptionForHR(hr); + } + } while (m_State < ClassState.GraphCompleting); + + // If the user cancelled + if (m_State == ClassState.Cancelling) + { + // Stop the graph, send an appropriate exit code + hr = m_pControl.Stop(); + exitCode = EventCode.UserAbort; + } + + // Send an event saying we are complete + if (Completed != null) + { + CompletedArgs ca = new CompletedArgs(exitCode); + Completed(this, ca); + } + + if (m_State == ClassState.GraphCompleting) + { + m_State = ClassState.GraphCompleted; + } + else + { + m_State = ClassState.Cancelled; + } + + } // Exit the thread + + /// + /// Create a video media type from a few parameters + /// + /// Bits per pixel (16, 24, 32) + /// Video width + /// Video height + /// The constructed AMMediaType + private AMMediaType GetVideoMediaType(short BitCount, int Width, int Height) + { + Guid mediaSubType; + AMMediaType VideoGroupType = new AMMediaType(); + + // Calculate the SubType from the Bit count + switch(BitCount) + { + case 16: + mediaSubType = MediaSubType.RGB555; + break; + case 24: + mediaSubType = MediaSubType.RGB24; + break; + case 32: + mediaSubType = MediaSubType.RGB32; + break; + default: + throw new Exception("Unrecognized bit format"); + } + + VideoGroupType.majorType = MediaType.Video; + VideoGroupType.subType = mediaSubType; + VideoGroupType.formatType = FormatType.VideoInfo; + VideoGroupType.fixedSizeSamples = true; + + VideoGroupType.formatSize = Marshal.SizeOf(typeof(VideoInfoHeader)); + VideoInfoHeader vif = new VideoInfoHeader(); + vif.BmiHeader = new BitmapInfoHeader(); + + // The HEADER macro returns the BITMAPINFO within the VIDEOINFOHEADER + vif.BmiHeader.Size = Marshal.SizeOf(typeof(BitmapInfoHeader)); + vif.BmiHeader.Compression = 0; + vif.BmiHeader.BitCount = BitCount; + vif.BmiHeader.Width = Width; + vif.BmiHeader.Height = Height; + vif.BmiHeader.Planes = 1; + + int iSampleSize = vif.BmiHeader.Width * vif.BmiHeader.Height * (vif.BmiHeader.BitCount / 8); + vif.BmiHeader.ImageSize = iSampleSize; + VideoGroupType.sampleSize = iSampleSize; + VideoGroupType.formatPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(vif)); + + Marshal.StructureToPtr(vif, VideoGroupType.formatPtr, false); + + return VideoGroupType; + } + + /// + /// Create an audio media type + /// + /// The constructed media type + private AMMediaType GetAudioMediaType() + { + AMMediaType AudioGroupType = new AMMediaType(); + AudioGroupType.majorType = MediaType.Audio; + + return AudioGroupType; + } + + /// + /// Called from RenderTo* routines to perform common initialization + /// + private void RenderCommon() + { + int hr; + + if (m_State >= ClassState.RenderSelected) + { + throw new Exception("Graph rendering has already been selected"); + } + + if (m_State < ClassState.FilesAdded) + { + throw new Exception("No files added to render."); + } + + m_State = ClassState.RenderSelected; + + // create the render engine + m_pRenderEngine = (IRenderEngine)new RenderEngine(); + + // tell the render engine about the timeline it should use + hr = m_pRenderEngine.SetTimelineObject( m_pTimeline ); + DESError.ThrowExceptionForHR(hr); + + // connect up the front end + hr = m_pRenderEngine.ConnectFrontEnd( ); + DESError.ThrowExceptionForHR(hr); + + // Get the filtergraph - used all over the place + hr = m_pRenderEngine.GetFilterGraph( out m_pGraph ); + DESError.ThrowExceptionForHR(hr); + +#if DEBUG + // Allow the graph to be connected to from GraphEdit + m_rot = new DsROTEntry(m_pGraph); +#endif + } + + /// + /// Determine whether a specified pin is audio or video + /// + /// Pin to check + /// True if pin is video + private bool IsVideo(IPin pPin) + { + int hr; + bool bRet = false; + AMMediaType [] pmt = new AMMediaType[1]; + IEnumMediaTypes ppEnum; + + // Walk the MediaTypes for the pin + hr = pPin.EnumMediaTypes(out ppEnum); + DESError.ThrowExceptionForHR(hr); + + try + { + // Just read the first one + hr = ppEnum.Next(1, pmt, IntPtr.Zero); + DESError.ThrowExceptionForHR(hr); + + bRet = pmt[0].majorType == MediaType.Video; + } + finally + { + Marshal.ReleaseComObject(ppEnum); + } + DsUtils.FreeAMMediaType(pmt[0]); + + return bRet; + } + + /// + /// Called from RenderWindow to add the renderer to the graph, create a sample grabber, add it + /// to the graph and connect it all up + /// + /// ICaptureGraphBuilder2 to use + /// ICaptureGraphBuilder2 to use + /// String to use in creating filter graph object descriptions + /// Pin to connect from + /// Renderer to add + private void RenderWindowHelper(ICaptureGraphBuilder2 icgb, MyCallback pCallback, string sType, IPin pPin, IBaseFilter ibfRenderer) + { + int hr; + + // Add the renderer to the graph + hr = m_pGraph.AddFilter(ibfRenderer, sType + " Renderer"); + DESError.ThrowExceptionForHR(hr); + + // Do everything else + RenderHelper(icgb, pCallback, sType, pPin, null, ibfRenderer); + } + /// + /// Common routine used by RenderTo* + /// + /// ICaptureGraphBuilder2 to use + /// Callback to use (or null) + /// string to use in creating filter graph object descriptions + /// Pin to connect from + /// Compressor to use, or null for none + /// Endpoint (renderer or file writer) to connect to + private void RenderHelper(ICaptureGraphBuilder2 icgb, MyCallback pCallback, string sType, IPin pPin, IBaseFilter ibfCompressor, IBaseFilter pOutput) + { + int hr; + IBaseFilter ibfSampleGrabber = null; + + try + { + // If no callback was provided, don't create a samplegrabber + if (pCallback != null) + { + ISampleGrabber isg = (ISampleGrabber)new SampleGrabber(); + ibfSampleGrabber = (IBaseFilter)isg; + + hr = isg.SetCallback(pCallback, 1); + DESError.ThrowExceptionForHR(hr); + + hr = m_pGraph.AddFilter(ibfSampleGrabber, sType + " sample grabber"); + DESError.ThrowExceptionForHR(hr); + } + + // If a compressor was provided, add it to the graph and connect it up + if (ibfCompressor != null) + { + // Connect the pin. + hr = m_pGraph.AddFilter(ibfCompressor, sType + " Compressor"); + DESError.ThrowExceptionForHR(hr); + + hr = icgb.RenderStream(null, null, pPin, ibfSampleGrabber, ibfCompressor); + DESError.ThrowExceptionForHR(hr); + + // Connect the pin. + hr = icgb.RenderStream(null, null, ibfCompressor, null, pOutput); + DESError.ThrowExceptionForHR(hr); + } + else + { + // Just connect the SampleGrabber (if any) + hr = icgb.RenderStream(null, null, pPin, ibfSampleGrabber, pOutput); + DESError.ThrowExceptionForHR(hr); + } + } + finally + { + if (ibfSampleGrabber != null) + { + Marshal.ReleaseComObject(ibfSampleGrabber); + } + } + } + + /// + /// Release resources used by the class. + /// + /// May fire events, so do not call from Form.Dispose(). + public void Dispose() + { + GC.SuppressFinalize(this); + + if (m_Video != null) + { + m_Video.Dispose(); + m_Video = null; + } + if (m_Audio != null) + { + m_Audio.Dispose(); + m_Audio = null; + } + + if (m_pTimeline != null) + { + Marshal.ReleaseComObject(m_pTimeline); + m_pTimeline = null; + } + + if (m_pRenderEngine != null) + { + Marshal.ReleaseComObject(m_pRenderEngine); + m_pRenderEngine = null; + } + +#if DEBUG + if (m_rot != null) + { + m_rot.Dispose(); + m_rot = null; + } +#endif + if (m_pControl != null) + { + m_pControl.Stop(); + m_pControl = null; + } + + if (m_pGraph != null) + { + Marshal.ReleaseComObject(m_pGraph); + m_pGraph = null; + } + + // No point in calling us from the Finalizer, we're already gone + GC.SuppressFinalize(this); + } + } + + + /// + /// This class wraps a file to be used by DESCombine. In addition to + /// holding the name, it also retrieves the media duration. + /// + internal class MediaFile + { + #region Data members + + // File name from the constructor + private string m_FileName; + + // Actual media length (in 100NS) as reported by IMediaDet + private long m_RealLength; + + // Amount of the real length to use when rendering + private long m_UsingLength; + + // UsingLength reported in # of frames (only available + // after the file has been added to the timeline) + private int m_LengthInFrames; + + #endregion + + /// + /// Constructor takes a file path+name + /// + /// File path+name + public MediaFile(string s) + { + m_FileName = s; + m_RealLength = GetLength(); + m_UsingLength = m_RealLength; + m_LengthInFrames = -1; + } + + /// + /// Return the length of the media file + /// + /// Length in 100NS + private long GetLength() + { + int hr; + double d; + long i; + + IMediaDet imd = (IMediaDet)new MediaDet(); + + // Set the name + hr = imd.put_Filename(m_FileName); + DESError.ThrowExceptionForHR(hr); + + // Read from stream zero + hr = imd.put_CurrentStream(0); + DESError.ThrowExceptionForHR(hr); + + // Get the length in seconds + hr = imd.get_StreamLength(out d); + DESError.ThrowExceptionForHR(hr); + + Marshal.ReleaseComObject(imd); + + // Convert to UNITS + i = (long)(d * DESCombine.UNITS); + return i; + } + + /// + /// Return or set the length of the media file. When setting the + /// value, you can set it from zero to the duration of the media file. + /// If the duration of the media file is zero (jpg, bmp, etc), you can + /// set the duration to any time. Useful for intro, credits, etc. + /// + public long Length + { + get + { + return m_UsingLength; + } + set + { + if ((value < m_RealLength || m_RealLength == 0) && value >= 0) + { + m_UsingLength = value; + } + else + { + throw new Exception("Invalid length specified"); + } + } + } + + /// + /// Return the file name + /// + public string FileName + { + get + { + return m_FileName; + } + } + + public int LengthInFrames + { + set + { + m_LengthInFrames = value; + } + get + { + return m_LengthInFrames; + } + } + } + + + /// + /// Class used by both audio and video callback + /// + internal class MyCallback : ISampleGrabberCB + { + #region Data members + + /// + /// Client callback routine + /// + protected IDESCombineCB m_pCallback; + + // The list of files + protected Group m_Group; + + // The event sink (used to notify on end of file) + protected IMediaEventSink m_pEventSink; + + // The event code to be used for end of file + protected EventCode m_ec; + + // Holds the index into m_Files we are currently processing + protected int m_iCurFile; + + // Which frame number we are currently processing + protected int m_iCurFrame; + + // Maximum frame number for the current file + protected int m_iMaxFrame; + + // File name of the currently processing file + protected string m_CurFileName; + + #endregion + + /// + /// + /// + /// Timeline group info + /// Client callback + /// Event sync to call on file complete + /// Event code to send on file completion + public MyCallback( + Group pGroup, + IDESCombineCB pCallback, + IMediaEventSink pEventSink, + EventCode ec + ) + { + m_pCallback = pCallback; + m_Group = pGroup; + m_pEventSink = pEventSink; + m_ec = ec; + + m_iCurFrame = 0; + m_iCurFile = 0; + MediaFile mf = m_Group.File(m_iCurFile); + if (mf != null) + { + m_CurFileName = mf.FileName; + m_iMaxFrame = mf.LengthInFrames; + } + else + { + m_CurFileName = null; + m_iMaxFrame = int.MaxValue; + } + } + + + // ISampleGrabberCB methods + public int SampleCB(double SampleTime, IMediaSample pSample) + { + Marshal.ReleaseComObject(pSample); + return 0; + } + public int BufferCB(double SampleTime, System.IntPtr pBuffer, int BufferLen) + { + // Call the client + int iRet; + + if (m_pCallback != null) + { + iRet = m_pCallback.BufferCB(m_CurFileName, SampleTime, pBuffer, BufferLen); + } + else + { + iRet = 0; + } + + m_iCurFrame++; + + // Have we finished the current file? + if (m_iCurFrame >= m_iMaxFrame) + { + // Send the notification + int hr = m_pEventSink.Notify(m_ec, new IntPtr(m_iCurFile), new IntPtr(m_iCurFrame)); + + // Find the next file + m_iCurFile++; + if (m_iCurFile < m_Group.Count) + { + MediaFile mf = m_Group.File(m_iCurFile); + m_CurFileName = mf.FileName; + m_iMaxFrame += mf.LengthInFrames; + } + else + { + // A failsafe + m_iMaxFrame = int.MaxValue; + } + } + + return iRet; + } + } + + + /// + /// Class containing information about the timeline groups (one + /// for audio, one for video) + /// + internal class Group : IDisposable + { + #region Members + + /// + /// Used to store the current length + /// + private long m_Length; + + /// + /// An array holding the names and durations of the files to be processed + /// + private ArrayList m_Files; + + /// + /// Pointer to the track + /// + private IAMTimelineTrack m_Track; + + /// + /// FPS of the group + /// + private double m_FPS; + + /// + /// Timeline to add items to + /// + private IAMTimeline m_pTimeline; + + #endregion + + /// + /// Constructor + /// + /// Media type of the new group + /// Timeline to use for the group + /// FPS for the group + public Group(AMMediaType mType, IAMTimeline pTimeline, double fps) + { + int hr; + IAMTimelineObj pGroupObj; + + m_Length = 0; + m_Files = new ArrayList(); + m_FPS = fps; + m_pTimeline = pTimeline; + + // make the root group/composition + hr = m_pTimeline.CreateEmptyNode( out pGroupObj, TimelineMajorType.Group); + DESError.ThrowExceptionForHR(hr); + + try + { + IAMTimelineGroup pGroup = (IAMTimelineGroup)pGroupObj; + + // Set the media type we just created + hr = pGroup.SetMediaType( mType ); + DESError.ThrowExceptionForHR(hr); + DsUtils.FreeAMMediaType(mType); + + // add the video group to the timeline + hr = m_pTimeline.AddGroup( pGroupObj ); + DESError.ThrowExceptionForHR(hr); + + IAMTimelineObj pTrack1Obj; + hr = m_pTimeline.CreateEmptyNode(out pTrack1Obj, TimelineMajorType.Track); + DESError.ThrowExceptionForHR(hr); + + // tell the composition about the track + IAMTimelineComp pRootComp = (IAMTimelineComp)pGroupObj; + hr = pRootComp.VTrackInsBefore( pTrack1Obj, -1 ); + DESError.ThrowExceptionForHR(hr); + + m_Track = (IAMTimelineTrack)pTrack1Obj; + } + finally + { + Marshal.ReleaseComObject(pGroupObj); + } + //Marshal.ReleaseComObject(pTrack1Obj); // Released as m_VideoTrack in dispose + } + + + /// + /// Returns the indexed file + /// + /// Zero based index into list of files in group + /// The specified MediaFile + public MediaFile File(int x) + { + if (m_Files.Count > 0) + { + return (MediaFile)m_Files[x]; + } + + return null; + } + + /// + /// The count of files in the group + /// + /// The count + public int Count + { + get + { + return m_Files.Count; + } + } + + /// + /// Returns the length of the group in . + /// + public long Length + { + get + { + return m_Length; + } + } + /// + /// Add a file to the group + /// + /// File name+path to add + /// Start point in source file in UNITS + /// End point in source file in UNITS or -1 to add entire file + public void Add(string sName, long lStart, long lEnd) + { + int hr; + long lLength; + + // Create a mediafile object to hold the file + MediaFile mf = new MediaFile(sName); + + // Add it to the list of files + m_Files.Add(mf); + + // If the endpoint is -1, find the real file length + if (lEnd < 0) + { + lEnd = mf.Length; + } + lLength = lEnd - lStart; + + // create the timeline source object + IAMTimelineObj pSource1Obj; + hr = m_pTimeline.CreateEmptyNode( out pSource1Obj, TimelineMajorType.Source); + DESError.ThrowExceptionForHR(hr); + + try + { + // set up source length + hr = pSource1Obj.SetStartStop( m_Length, lLength + m_Length ); + DESError.ThrowExceptionForHR(hr); + + IAMTimelineSrc pSource1Src = (IAMTimelineSrc)pSource1Obj; + + // Set the file name + hr = pSource1Src.SetMediaName( mf.FileName ); + DESError.ThrowExceptionForHR(hr); + + // Set the start/end + hr = pSource1Src.SetMediaTimes(lStart, lEnd); + DESError.ThrowExceptionForHR(hr); + + // Connect the track to the source + hr = m_Track.SrcAdd( pSource1Obj ); + DESError.ThrowExceptionForHR(hr); + + // Set the times, get back the times adjusted to fit the frame rate + hr = pSource1Src.FixMediaTimes(ref lStart, ref lEnd); + DESError.ThrowExceptionForHR(hr); + + // Calculate the last frame number for the file + double d1 = (lEnd - lStart); + double d2 = (DESCombine.UNITS/m_FPS); + double d3 = d1 / d2; + int d4 = (int)Math.Round(d3); + + // Update the MediaFile (used to see when we've walked past + // the end of a file) + mf.LengthInFrames = d4; + } + finally + { + Marshal.ReleaseComObject(pSource1Obj); + } + + m_Length += lLength; + } + + #region IDisposable Members + + /// + /// Release everything + /// + public void Dispose() + { + if (m_Track != null) + { + Marshal.ReleaseComObject(m_Track); + m_Track = null; + } + m_Files = null; + m_Length = 0; + GC.SuppressFinalize(this); + } + + #endregion + } +} diff --git a/Samples/Editing/DESCombine/DESCombineLib/DESCombineLib-2005.csproj b/Samples/Editing/DESCombine/DESCombineLib/DESCombineLib-2005.csproj new file mode 100644 index 0000000..1c887bd --- /dev/null +++ b/Samples/Editing/DESCombine/DESCombineLib/DESCombineLib-2005.csproj @@ -0,0 +1,102 @@ + + + Local + 8.0.50727 + 2.0 + {A10D4671-34C7-4AD8-B537-B2B9C48242F7} + Debug + AnyCPU + + + + + DESCombineLib + + + JScript + Grid + IE50 + false + Library + DESCombineLib + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + docs\docs2.xml + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Windows.Forms + + + + + Code + + + Code + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Editing/DESCombine/DESCombineLib/DESCombineLib.csproj b/Samples/Editing/DESCombine/DESCombineLib/DESCombineLib.csproj new file mode 100644 index 0000000..7f7a3b8 --- /dev/null +++ b/Samples/Editing/DESCombine/DESCombineLib/DESCombineLib.csproj @@ -0,0 +1,134 @@ + + + + Local + 8.0.50727 + 2.0 + {A10D4671-34C7-4AD8-B537-B2B9C48242F7} + Debug + AnyCPU + + + + + DESCombineLib + + + JScript + Grid + IE50 + false + Library + DESCombineLib + OnBuildSuccess + + + + + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + docs\docs2.xml + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Windows.Forms + + + + + Code + + + Code + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Editing/DESCombine/DesCombineVB/AssemblyInfo.vb b/Samples/Editing/DESCombine/DesCombineVB/AssemblyInfo.vb new file mode 100644 index 0000000..60c81d2 --- /dev/null +++ b/Samples/Editing/DESCombine/DesCombineVB/AssemblyInfo.vb @@ -0,0 +1,39 @@ +'**************************************************************************** +'While the underlying libraries are covered by LGPL, this sample is released +'as public domain. It is distributed in the hope that it will be useful, but +'WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +'or FITNESS FOR A PARTICULAR PURPOSE. +'*****************************************************************************/ + +Imports System +Imports System.Reflection +Imports System.Runtime.InteropServices + +' General Information about an assembly is controlled through the following +' set of attributes. Change these attribute values to modify the information +' associated with an assembly. + +' Review the values of the assembly attributes + + + + + + + + + +'The following GUID is for the ID of the typelib if this project is exposed to COM + + +' Version information for an assembly consists of the following four values: +' +' Major Version +' Minor Version +' Build Number +' Revision +' +' You can specify all the values or you can default the Build and Revision Numbers +' by using the '*' as shown below: + + diff --git a/Samples/Editing/DESCombine/DesCombineVB/DesCombineVB-2005.sln b/Samples/Editing/DESCombine/DesCombineVB/DesCombineVB-2005.sln new file mode 100644 index 0000000..c385617 --- /dev/null +++ b/Samples/Editing/DESCombine/DesCombineVB/DesCombineVB-2005.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "DesCombineVB-2005", "DesCombineVB-2005.vbproj", "{BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Editing/DESCombine/DesCombineVB/DesCombineVB-2005.vbproj b/Samples/Editing/DESCombine/DesCombineVB/DesCombineVB-2005.vbproj new file mode 100644 index 0000000..f1fcac3 --- /dev/null +++ b/Samples/Editing/DESCombine/DesCombineVB/DesCombineVB-2005.vbproj @@ -0,0 +1,118 @@ + + + Local + 8.0.50727 + 2.0 + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9} + Debug + AnyCPU + + + + + DesCombineVB + + + None + JScript + Grid + IE50 + false + WinExe + Binary + On + Off + DesCombineVB + DesCombineVB.Form1 + + + WindowsFormsWithCustomSubMain + + + + + bin\ + DesCombineVB.xml + 285212672 + + + + + true + true + true + false + false + false + false + 1 + 42016,42017,42018,42019,42032 + full + + + bin\ + DesCombineVB.xml + 285212672 + + + + + false + true + false + true + false + false + false + 1 + 42016,42017,42018,42019,42032 + none + + + + False + ..\DESCombineLib\bin\Debug\DESCombineLib.dll + + + False + ..\..\..\..\lib\DirectShowLib-2005.dll + + + System + + + + System.Drawing + + + System.Windows.Forms + + + + + + + + + + + + + Code + + + Form + + + Form1.vb + Designer + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Editing/DESCombine/DesCombineVB/DesCombineVB-2008.sln b/Samples/Editing/DESCombine/DesCombineVB/DesCombineVB-2008.sln new file mode 100644 index 0000000..9c04796 --- /dev/null +++ b/Samples/Editing/DESCombine/DesCombineVB/DesCombineVB-2008.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "DesCombineVB-2008", "DesCombineVB-2008.vbproj", "{BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Editing/DESCombine/DesCombineVB/DesCombineVB.vbproj b/Samples/Editing/DESCombine/DesCombineVB/DesCombineVB.vbproj new file mode 100644 index 0000000..63861ac --- /dev/null +++ b/Samples/Editing/DESCombine/DesCombineVB/DesCombineVB.vbproj @@ -0,0 +1,153 @@ + + + + Local + 8.0.50727 + 2.0 + {BFB2A0B5-B3AB-4355-9C7D-59F9FBDD38E9} + Debug + AnyCPU + + + + + DesCombineVB + + + None + JScript + Grid + IE50 + false + WinExe + Binary + On + Off + DesCombineVB + DesCombineVB.Form1 + + + WindowsFormsWithCustomSubMain + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\ + DesCombineVB.xml + 285212672 + + + + + true + true + true + false + false + false + false + 1 + 42016,42017,42018,42019,42032,42353,42354,42355 + full + + + bin\ + DesCombineVB.xml + 285212672 + + + + + false + true + false + true + false + false + false + 1 + 42016,42017,42018,42019,42032,42353,42354,42355 + none + + + + System + + + + System.Drawing + + + System.Windows.Forms + + + + + + + + + + + + + Code + + + Form + + + Form1.vb + Designer + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + {a10d4671-34c7-4ad8-b537-b2b9c48242f7} + DESCombineLib + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Editing/DESCombine/DesCombineVB/Form1.resx b/Samples/Editing/DESCombine/DesCombineVB/Form1.resx new file mode 100644 index 0000000..190c673 --- /dev/null +++ b/Samples/Editing/DESCombine/DesCombineVB/Form1.resx @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + Assembly + + + Assembly + + + False + + + Assembly + + + Assembly + + + False + + + (Default) + + + False + + + False + + + 8, 8 + + + True + + + 80 + + + True + + + Form1 + + + Assembly + + \ No newline at end of file diff --git a/Samples/Editing/DESCombine/DesCombineVB/Form1.vb b/Samples/Editing/DESCombine/DesCombineVB/Form1.vb new file mode 100644 index 0000000..04ff4f0 --- /dev/null +++ b/Samples/Editing/DESCombine/DesCombineVB/Form1.vb @@ -0,0 +1,164 @@ +'**************************************************************************** +'While the underlying libraries are covered by LGPL, this sample is released +'as public domain. It is distributed in the hope that it will be useful, but +'WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +'or FITNESS FOR A PARTICULAR PURPOSE. +'*****************************************************************************/ + +Imports DESCombineLib +Imports DirectShowLib + +Public Class Form1 + Inherits System.Windows.Forms.Form + +#Region " Windows Form Designer generated code " + + Public Sub New() + MyBase.New() + + 'This call is required by the Windows Form Designer. + InitializeComponent() + + 'Add any initialization after the InitializeComponent() call + + End Sub + + 'Form overrides dispose to clean up the component list. + Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) + If disposing Then + If Not (components Is Nothing) Then + components.Dispose() + End If + End If + MyBase.Dispose(disposing) + End Sub + + 'Required by the Windows Form Designer + Private components As System.ComponentModel.IContainer + + 'NOTE: The following procedure is required by the Windows Form Designer + 'It can be modified using the Windows Form Designer. + 'Do not modify it using the code editor. + Friend WithEvents Button1 As System.Windows.Forms.Button + Friend WithEvents Label1 As System.Windows.Forms.Label + Private Sub InitializeComponent() + Me.Button1 = New System.Windows.Forms.Button + Me.Label1 = New System.Windows.Forms.Label + Me.SuspendLayout() + ' + 'Button1 + ' + Me.Button1.Location = New System.Drawing.Point(104, 128) + Me.Button1.Name = "Button1" + Me.Button1.Size = New System.Drawing.Size(75, 32) + Me.Button1.TabIndex = 0 + Me.Button1.Text = "Start" + ' + 'Label1 + ' + Me.Label1.Location = New System.Drawing.Point(16, 16) + Me.Label1.Name = "Label1" + Me.Label1.Size = New System.Drawing.Size(256, 96) + Me.Label1.TabIndex = 1 + Me.Label1.Text = "Input: c:\1.avi" & Chr(10) & "Output: c:\test.avi" & Chr(10) & "Assumes c:\1.avi is a video-only file" & Chr(10) & "Compresses output using: Microsoft Video 1" + ' + 'Form1 + ' + Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13) + Me.ClientSize = New System.Drawing.Size(292, 262) + Me.Controls.Add(Me.Label1) + Me.Controls.Add(Me.Button1) + Me.Name = "Form1" + Me.Text = "Form1" + Me.ResumeLayout(False) + + End Sub + +#End Region + + Private ds As DESCombine + + Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click + + Try + If ds Is Nothing Then + Dim ibfVideoCompressor As DirectShowLib.IBaseFilter + + ' Get the video compressor + ibfVideoCompressor = GetVideoCompressor("Microsoft Video 1") + + ' FPS, BPP, Width, Height + ds = New DESCombine(25, 16, 354, 288) + AddHandler ds.Completed, AddressOf Me.Done + + ' Add a file which only contains video (use AddAVFile if the file contains + ' both audio and video, and you want to *use* both the audio and video + ' from the file). + ds.AddVideoFile("c:\1.avi", 0, -1) + + ' Create the output graph using the specified: + ' Output file + ' Video compressor + ' Audio compressor + ' Video callback routine + ' Audio callback routine + ds.RenderToAVI("c:\test.avi", ibfVideoCompressor, Nothing, Nothing, Nothing) + + ' Run the graph + ds.StartRendering() + Button1.Text = "Cancel" + Else + ds.Cancel() + End If + + Catch ex As Exception + MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) + ds.Dispose() + ds = Nothing + End Try + + End Sub + + ' Walk the list of video compressors looking for one by name + Private Function GetVideoCompressor(ByVal sName As String) As DirectShowLib.IBaseFilter + + Dim dsd() As DsDevice = DsDevice.GetDevicesOfCat(FilterCategory.VideoCompressorCategory) + GetVideoCompressor = Nothing + + For Each dev As DsDevice In dsd + If (dev.Name = sName) Then + + ' Found it + Dim o As Object = Nothing + Dim grf As Guid = GetType(DirectShowLib.IBaseFilter).GUID + + dev.Mon.BindToObject(Nothing, Nothing, grf, o) + GetVideoCompressor = DirectCast(o, DirectShowLib.IBaseFilter) + + Exit For + End If + Next + + End Function + + Private Sub Done(ByVal sender As Object, ByVal e As System.EventArgs) + Dim e1 As DESCombineLib.CompletedArgs = e + + ' Close down the graph + ds.Dispose() + ds = Nothing + + ' This isn't the right way to do this, but hey, it's just a sample. + CheckForIllegalCrossThreadCalls = False + + ' Reset the button text + Button1.Text = "Start" + + CheckForIllegalCrossThreadCalls = True + + ' Show the results + MessageBox.Show(e1.Result.ToString(), "Results") + + End Sub + +End Class diff --git a/Samples/Editing/DESCombine/DesCombineVB/readme.txt b/Samples/Editing/DESCombine/DesCombineVB/readme.txt new file mode 100644 index 0000000..f822c8d --- /dev/null +++ b/Samples/Editing/DESCombine/DesCombineVB/readme.txt @@ -0,0 +1,4 @@ +This sample shows how the DesCombineLib (written in c#) can be called from a vb program. The +code is simple (and a true VB programmer would probably call it ugly), but it shows the basics. + +See the DesCombine.chm for a description of all the methods in the lib. \ No newline at end of file diff --git a/Samples/Editing/DESCombine/TestCombine/App.ico b/Samples/Editing/DESCombine/TestCombine/App.ico new file mode 100644 index 0000000000000000000000000000000000000000..3a5525fd794f7a7c5c8e6187f470ea3af38cd2b6 GIT binary patch literal 1078 zcmeHHJr05}7=1t!Hp3A*8IHkVf+j?-!eHY14Gtcw1Eb*_9>Bq^zETJ@GKj{_2j4$w zo9}xCh!8{T3=X##Skq>ikMjsvB|y%crWBM2iW(4pI}c%z6%lW!=~4v77#3{z!dmB1 z__&l)-{KUYR+|8|;wB^R|9ET$J@(@=#rd^=)qs85?vAy(PSF5CyNkus435LVkZ$rj zNw|JG-P7^hF<(;#o*Vk}5R#e|^13tBbQkeF?djULtvqyxd3<{9 literal 0 HcmV?d00001 diff --git a/Samples/Editing/DESCombine/TestCombine/AssemblyInfo.cs b/Samples/Editing/DESCombine/TestCombine/AssemblyInfo.cs new file mode 100644 index 0000000..22f30a4 --- /dev/null +++ b/Samples/Editing/DESCombine/TestCombine/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +[assembly: AssemblyTitle("TestCombine")] +[assembly: AssemblyDescription("Test application for DESCombine library")] +[assembly: AssemblyCompany("http://DirectShowNet.SourceForge.net")] +[assembly: AssemblyProduct("DirectShowLib")] +[assembly: AssemblyCopyright("Public Domain")] + +[assembly: AssemblyVersion("1.0.*")] diff --git a/Samples/Editing/DESCombine/TestCombine/Form1.cs b/Samples/Editing/DESCombine/TestCombine/Form1.cs new file mode 100644 index 0000000..92311ee --- /dev/null +++ b/Samples/Editing/DESCombine/TestCombine/Form1.cs @@ -0,0 +1,838 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + +Written by snarfle@sourceforge.net +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Windows.Forms; +using System.Diagnostics; +using System.IO; +using System.Text; +using System.Runtime.InteropServices; + +using DESCombineLib; +using DirectShowLib; + +namespace TestConverter +{ + /// + /// Summary description for Form1. + /// + public class Form1 : System.Windows.Forms.Form + { + #region Form Controls + + private System.Windows.Forms.Button button1; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.SaveFileDialog saveFileDialog1; + private System.Windows.Forms.OpenFileDialog openFileDialog1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Button btnOutput; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.RadioButton rbToScreen; + private System.Windows.Forms.RadioButton rbToAVI; + private System.Windows.Forms.TextBox tbOutput; + private System.Windows.Forms.TextBox tbStatus; + private System.Windows.Forms.Label labOutput; + private System.Windows.Forms.Label labProfile; + private System.Windows.Forms.CheckBox cbShowXML; + private System.Windows.Forms.TextBox tbVideo; + private System.Windows.Forms.TextBox tbAudio; + private System.Windows.Forms.TextBox tbTime; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.Label labCompressor; + private System.Windows.Forms.TextBox tbCompressor; + private System.Windows.Forms.ListBox listBox1; + private System.Windows.Forms.Button btnDel; + private System.Windows.Forms.Button btnAdd; + private System.Windows.Forms.Label label12; + private System.Windows.Forms.Label label13; + private System.Windows.Forms.TextBox tbElapsed; + private System.Windows.Forms.ProgressBar progressBar1; + /// + /// Required designer variable. + /// + private System.ComponentModel.Container components = null; + + #endregion + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.button1 = new System.Windows.Forms.Button(); + this.tbStatus = new System.Windows.Forms.TextBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.tbCompressor = new System.Windows.Forms.TextBox(); + this.rbToAVI = new System.Windows.Forms.RadioButton(); + this.rbToScreen = new System.Windows.Forms.RadioButton(); + this.labProfile = new System.Windows.Forms.Label(); + this.labCompressor = new System.Windows.Forms.Label(); + this.tbOutput = new System.Windows.Forms.TextBox(); + this.labOutput = new System.Windows.Forms.Label(); + this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog(); + this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + this.label2 = new System.Windows.Forms.Label(); + this.btnOutput = new System.Windows.Forms.Button(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.btnDel = new System.Windows.Forms.Button(); + this.btnAdd = new System.Windows.Forms.Button(); + this.listBox1 = new System.Windows.Forms.ListBox(); + this.label12 = new System.Windows.Forms.Label(); + this.cbShowXML = new System.Windows.Forms.CheckBox(); + this.tbVideo = new System.Windows.Forms.TextBox(); + this.tbAudio = new System.Windows.Forms.TextBox(); + this.tbTime = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.tbElapsed = new System.Windows.Forms.TextBox(); + this.label13 = new System.Windows.Forms.Label(); + this.progressBar1 = new System.Windows.Forms.ProgressBar(); + this.groupBox1.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.SuspendLayout(); + // + // button1 + // + this.button1.Location = new System.Drawing.Point(148, 288); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(75, 40); + this.button1.TabIndex = 30; + this.button1.Text = "Doit"; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // tbStatus + // + this.tbStatus.Location = new System.Drawing.Point(8, 448); + this.tbStatus.Name = "tbStatus"; + this.tbStatus.ReadOnly = true; + this.tbStatus.Size = new System.Drawing.Size(296, 20); + this.tbStatus.TabIndex = 2; + this.tbStatus.TabStop = false; + this.tbStatus.Text = ""; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.tbCompressor); + this.groupBox1.Controls.Add(this.rbToAVI); + this.groupBox1.Controls.Add(this.rbToScreen); + this.groupBox1.Controls.Add(this.labProfile); + this.groupBox1.Controls.Add(this.labCompressor); + this.groupBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); + this.groupBox1.Location = new System.Drawing.Point(8, 128); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(344, 72); + this.groupBox1.TabIndex = 10; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Render Method"; + // + // tbCompressor + // + this.tbCompressor.Location = new System.Drawing.Point(176, 40); + this.tbCompressor.Name = "tbCompressor"; + this.tbCompressor.ReadOnly = true; + this.tbCompressor.Size = new System.Drawing.Size(144, 23); + this.tbCompressor.TabIndex = 12; + this.tbCompressor.Text = "Indeo® video 5.10 Compression Filter"; + this.tbCompressor.Visible = false; + // + // rbToAVI + // + this.rbToAVI.Location = new System.Drawing.Point(8, 40); + this.rbToAVI.Name = "rbToAVI"; + this.rbToAVI.Size = new System.Drawing.Size(80, 24); + this.rbToAVI.TabIndex = 12; + this.rbToAVI.Text = "To AVI"; + this.rbToAVI.CheckedChanged += new System.EventHandler(this.CheckedChanged); + // + // rbToScreen + // + this.rbToScreen.Checked = true; + this.rbToScreen.Location = new System.Drawing.Point(8, 16); + this.rbToScreen.Name = "rbToScreen"; + this.rbToScreen.Size = new System.Drawing.Size(88, 24); + this.rbToScreen.TabIndex = 11; + this.rbToScreen.TabStop = true; + this.rbToScreen.Text = "To Screen"; + this.rbToScreen.CheckedChanged += new System.EventHandler(this.CheckedChanged); + // + // labProfile + // + this.labProfile.Location = new System.Drawing.Point(176, 48); + this.labProfile.Name = "labProfile"; + this.labProfile.Size = new System.Drawing.Size(48, 16); + this.labProfile.TabIndex = 5; + this.labProfile.Text = "Profile"; + this.labProfile.Visible = false; + // + // labCompressor + // + this.labCompressor.Location = new System.Drawing.Point(176, 24); + this.labCompressor.Name = "labCompressor"; + this.labCompressor.TabIndex = 7; + this.labCompressor.Text = "Compressor"; + this.labCompressor.Visible = false; + // + // tbOutput + // + this.tbOutput.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); + this.tbOutput.Location = new System.Drawing.Point(24, 224); + this.tbOutput.Name = "tbOutput"; + this.tbOutput.Size = new System.Drawing.Size(232, 23); + this.tbOutput.TabIndex = 20; + this.tbOutput.Text = "output.avi"; + this.tbOutput.Visible = false; + // + // labOutput + // + this.labOutput.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); + this.labOutput.ImageAlign = System.Drawing.ContentAlignment.TopCenter; + this.labOutput.Location = new System.Drawing.Point(8, 200); + this.labOutput.Name = "labOutput"; + this.labOutput.Size = new System.Drawing.Size(112, 23); + this.labOutput.TabIndex = 5; + this.labOutput.Text = "Output file name"; + this.labOutput.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.labOutput.Visible = false; + // + // label2 + // + this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); + this.label2.Location = new System.Drawing.Point(8, 432); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(48, 16); + this.label2.TabIndex = 6; + this.label2.Text = "Status"; + // + // btnOutput + // + this.btnOutput.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); + this.btnOutput.Location = new System.Drawing.Point(264, 224); + this.btnOutput.Name = "btnOutput"; + this.btnOutput.Size = new System.Drawing.Size(24, 23); + this.btnOutput.TabIndex = 21; + this.btnOutput.Text = "..."; + this.btnOutput.Visible = false; + this.btnOutput.Click += new System.EventHandler(this.btnOutput_Click); + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.btnDel); + this.groupBox2.Controls.Add(this.btnAdd); + this.groupBox2.Controls.Add(this.listBox1); + this.groupBox2.Controls.Add(this.btnOutput); + this.groupBox2.Controls.Add(this.groupBox1); + this.groupBox2.Controls.Add(this.tbOutput); + this.groupBox2.Controls.Add(this.labOutput); + this.groupBox2.Controls.Add(this.label12); + this.groupBox2.Controls.Add(this.cbShowXML); + this.groupBox2.Location = new System.Drawing.Point(5, 0); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(363, 280); + this.groupBox2.TabIndex = 11; + this.groupBox2.TabStop = false; + // + // btnDel + // + this.btnDel.Location = new System.Drawing.Point(296, 14); + this.btnDel.Name = "btnDel"; + this.btnDel.Size = new System.Drawing.Size(40, 23); + this.btnDel.TabIndex = 2; + this.btnDel.Text = "Del"; + this.btnDel.Click += new System.EventHandler(this.btnDel_Click); + // + // btnAdd + // + this.btnAdd.Location = new System.Drawing.Point(240, 14); + this.btnAdd.Name = "btnAdd"; + this.btnAdd.Size = new System.Drawing.Size(40, 23); + this.btnAdd.TabIndex = 1; + this.btnAdd.Text = "Add"; + this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click); + // + // listBox1 + // + this.listBox1.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); + this.listBox1.HorizontalScrollbar = true; + this.listBox1.ItemHeight = 14; + this.listBox1.Location = new System.Drawing.Point(8, 40); + this.listBox1.Name = "listBox1"; + this.listBox1.Size = new System.Drawing.Size(336, 88); + this.listBox1.TabIndex = 3; + // + // label12 + // + this.label12.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); + this.label12.Location = new System.Drawing.Point(8, 16); + this.label12.Name = "label12"; + this.label12.Size = new System.Drawing.Size(40, 23); + this.label12.TabIndex = 23; + this.label12.Text = "Files"; + // + // cbShowXML + // + this.cbShowXML.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); + this.cbShowXML.Location = new System.Drawing.Point(16, 256); + this.cbShowXML.Name = "cbShowXML"; + this.cbShowXML.Size = new System.Drawing.Size(96, 16); + this.cbShowXML.TabIndex = 22; + this.cbShowXML.Text = "Show XML"; + // + // tbVideo + // + this.tbVideo.Location = new System.Drawing.Point(272, 344); + this.tbVideo.Name = "tbVideo"; + this.tbVideo.ReadOnly = true; + this.tbVideo.Size = new System.Drawing.Size(88, 20); + this.tbVideo.TabIndex = 12; + this.tbVideo.TabStop = false; + this.tbVideo.Text = ""; + this.tbVideo.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + // + // tbAudio + // + this.tbAudio.Location = new System.Drawing.Point(272, 368); + this.tbAudio.Name = "tbAudio"; + this.tbAudio.ReadOnly = true; + this.tbAudio.Size = new System.Drawing.Size(88, 20); + this.tbAudio.TabIndex = 13; + this.tbAudio.TabStop = false; + this.tbAudio.Text = ""; + this.tbAudio.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + // + // tbTime + // + this.tbTime.Location = new System.Drawing.Point(104, 368); + this.tbTime.Name = "tbTime"; + this.tbTime.ReadOnly = true; + this.tbTime.Size = new System.Drawing.Size(48, 20); + this.tbTime.TabIndex = 14; + this.tbTime.TabStop = false; + this.tbTime.Text = ""; + // + // label1 + // + this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); + this.label1.Location = new System.Drawing.Point(8, 368); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(80, 16); + this.label1.TabIndex = 15; + this.label1.Text = "Media Time"; + this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // label4 + // + this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); + this.label4.Location = new System.Drawing.Point(184, 344); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(80, 16); + this.label4.TabIndex = 16; + this.label4.Text = "Video Bytes"; + this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // label5 + // + this.label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); + this.label5.Location = new System.Drawing.Point(184, 368); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(80, 16); + this.label5.TabIndex = 17; + this.label5.Text = "Audio Bytes"; + this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // tbElapsed + // + this.tbElapsed.Location = new System.Drawing.Point(104, 344); + this.tbElapsed.Name = "tbElapsed"; + this.tbElapsed.ReadOnly = true; + this.tbElapsed.Size = new System.Drawing.Size(48, 20); + this.tbElapsed.TabIndex = 18; + this.tbElapsed.TabStop = false; + this.tbElapsed.Text = ""; + // + // label13 + // + this.label13.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); + this.label13.Location = new System.Drawing.Point(8, 344); + this.label13.Name = "label13"; + this.label13.Size = new System.Drawing.Size(96, 16); + this.label13.TabIndex = 19; + this.label13.Text = "Elapsed Time"; + this.label13.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // progressBar1 + // + this.progressBar1.Location = new System.Drawing.Point(8, 400); + this.progressBar1.Name = "progressBar1"; + this.progressBar1.Size = new System.Drawing.Size(288, 24); + this.progressBar1.TabIndex = 99; + // + // Form1 + // + this.AcceptButton = this.button1; + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(370, 476); + this.Controls.Add(this.tbElapsed); + this.Controls.Add(this.tbTime); + this.Controls.Add(this.tbAudio); + this.Controls.Add(this.tbVideo); + this.Controls.Add(this.tbStatus); + this.Controls.Add(this.progressBar1); + this.Controls.Add(this.label13); + this.Controls.Add(this.groupBox2); + this.Controls.Add(this.label2); + this.Controls.Add(this.button1); + this.Controls.Add(this.label5); + this.Controls.Add(this.label4); + this.Controls.Add(this.label1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.Name = "Form1"; + this.Text = "Test Converter"; + this.Closing += new System.ComponentModel.CancelEventHandler(this.FormClose); + this.groupBox1.ResumeLayout(false); + this.groupBox2.ResumeLayout(false); + this.ResumeLayout(false); + + } + #endregion + + public Form1() + { + // + // Required for Windows Form Designer support + // + InitializeComponent(); + +#if USING_NET20 + // While I don't believe the cross thread accessing of + // controls I am doing in this program presents any risks, + // it does not follow MS best practices. What's more, + // in .NET 2.0, the debugger will complain. Unless + // you have these two statements. + TextBox.CheckForIllegalCrossThreadCalls = false; + ProgressBar.CheckForIllegalCrossThreadCalls = false; +#endif + } + + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if (components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + private struct Chunk + { + public string sVideoFile; + public string sAudioFile; + public long lStart; + public long lEnd; + + public Chunk(string v, string a, long s, long e) + { + if (v != null && v.Length == 0) + { + v = null; + } + if (a != null && a.Length == 0) + { + a = null; + } + sVideoFile = v; + sAudioFile = a; + lStart = s; + lEnd = e; + } + + public Chunk(string v, string a, string s, string e) + { + if (v != null && v.Length == 0) + { + v = null; + } + if (a != null && a.Length == 0) + { + a = null; + } + sVideoFile = v; + sAudioFile = a; + lStart = Convert.ToInt64(Convert.ToDouble(s) * DESCombine.UNITS); + lEnd = Convert.ToInt64(Convert.ToDouble(e) * DESCombine.UNITS); + } + + override public string ToString() + { + string sV; + string sA; + string e; + + if (sVideoFile != null && sVideoFile.Length > 0) + { + FileInfo fV = new FileInfo(sVideoFile); + sV = fV.Name; + } + else + { + sV = ""; + } + + if (sAudioFile != null && sAudioFile.Length > 0) + { + FileInfo fA = new FileInfo(sAudioFile); + sA = fA.Name; + } + else + { + sA = ""; + } + + if (lEnd > 0) + { + e = ((float)lEnd / DESCombine.UNITS).ToString("###0.0"); + e = e.PadLeft(6, ' '); + } + else + { + e = " -1 "; + } + + string s = ((float)(lStart / DESCombine.UNITS)).ToString("###0.0"); + s = s.PadLeft(6, ' '); + + return string.Format("{0, -16} {1, -16} {2} {3}", sV, sA, s, e); + } + } + + DESCombine ds; + + [STAThread] + static void Main() + { + Application.Run(new Form1()); + } + + private void button1_Click(object sender, System.EventArgs e) + { + try + { + if (ds == null) + { + MyCallback pVideo = new MyCallback(tbVideo, tbTime, tbElapsed, progressBar1); + MyCallback pAudio = new MyCallback(tbAudio); + + // FPS, BPP, Width, Height + ds = new DESCombine(30, 24, 320, 240); + + foreach (Chunk c in listBox1.Items) + { + if (c.sVideoFile == c.sAudioFile) + { + ds.AddAVFile(c.sVideoFile, c.lStart, c.lEnd); + } + else + { + if (c.sVideoFile != null) + { + ds.AddVideoFile(c.sVideoFile, c.lStart, c.lEnd); + } + + if (c.sAudioFile != null) + { + ds.AddAudioFile(c.sAudioFile, c.lStart, c.lEnd); + } + } + } + + if (rbToScreen.Checked) + { + ds.RenderToWindow(IntPtr.Zero, pVideo, pAudio); + } + else if (rbToAVI.Checked) + { + IBaseFilter ibfVideoCompressor = GetVideoCompressor(tbCompressor.Text); + ds.RenderToAVI(tbOutput.Text, ibfVideoCompressor, null, pVideo, pAudio); + } + else + { + MessageBox.Show("Programming error"); + } + + if (cbShowXML.Checked) + { + MessageBox.Show(ds.GetXML(), "XML representation of the DES graph"); + } + + ds.Completed += new EventHandler(Completed); + ds.FileCompleted += new EventHandler(FileCompleted); + + ds.StartRendering(); + + groupBox2.Enabled = false; + progressBar1.Maximum = (int)(ds.MediaLength / (DESCombine.UNITS / 10)); + progressBar1.Step = progressBar1.Maximum / 20; + progressBar1.Value = 0; + tbStatus.Text = "Running"; + button1.Text = "Cancel"; + } + else + { + ds.Cancel(); + } + } + catch(Exception ex) + { + MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + ds.Dispose(); + ds = null; + } + } + + private IBaseFilter GetVideoCompressor(string sName) + { + IBaseFilter ibf = null; + + DsDevice [] dsd = DsDevice.GetDevicesOfCat(FilterCategory.VideoCompressorCategory); + int x; + + for(x=0; x < dsd.Length; x++) + { + if (dsd[x].Name == sName) + { + Guid grf = typeof(IBaseFilter).GUID; + object o; + dsd[x].Mon.BindToObject(null, null, ref grf, out o); + ibf = o as IBaseFilter; + break; + } + } + + return ibf; + } + + private void Completed(object o, System.EventArgs e) + { + CompletedArgs ca = e as CompletedArgs; + button1.Text = "Doit"; + tbStatus.Text = ca.Result.ToString(); + ds.Dispose(); + ds = null; + groupBox2.Enabled = true; + GC.Collect(); GC.WaitForPendingFinalizers(); + } + + private void FileCompleted(object o, System.EventArgs e) + { + FileCompletedArgs ca = e as FileCompletedArgs; + tbStatus.Text = string.Format("Finished file: {0}", ca.FileName); + Debug.WriteLine(string.Format("{0} {1}", ca.FileName, ca.Type)); + } + + private void btnOutput_Click(object sender, System.EventArgs e) + { + SaveFileDialog sfd = new SaveFileDialog(); + sfd.OverwritePrompt = true; + sfd.Filter = "All Files (*.*)|*.*"; + DialogResult r = sfd.ShowDialog(); + if (r == DialogResult.OK) + { + tbOutput.Text = sfd.FileName; + } + } + + private void CheckedChanged(object sender, System.EventArgs e) + { + if (rbToScreen.Checked) + { + tbOutput.Visible = false; + labOutput.Visible = false; + labProfile.Visible = false; + labCompressor.Visible = false; + tbCompressor.Visible = false; + } + else if (rbToAVI.Checked) + { + tbOutput.Visible = true; + labOutput.Visible = true; + labProfile.Visible = false; + labCompressor.Visible = true; + tbCompressor.Visible = true; + } + else + { + MessageBox.Show("Programming error"); + } + } + + private void btnAdd_Click(object sender, System.EventArgs e) + { + Form2 f = new Form2(); + DialogResult r = f.ShowDialog(); + if (r == DialogResult.OK) + { + if (f.tbVideoFile.Text.Length == 0 || File.Exists(f.tbVideoFile.Text)) + { + if (f.tbAudioFile.Text.Length == 0 || File.Exists(f.tbAudioFile.Text)) + { + if (f.tbVideoFile.Text.Length > 0 || f.tbAudioFile.Text.Length > 0) + { + Chunk c = new Chunk( + f.tbVideoFile.Text, + f.tbAudioFile.Text, + f.tbStart.Text, + f.tbEnd.Text); + int i = listBox1.Items.Add(c); + listBox1.SelectedIndex = i; + } + else + { + MessageBox.Show("No file provided"); + } + } + else + { + MessageBox.Show("Audio file does not exist", "File Not Found", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + else + { + MessageBox.Show("Video file does not exist", "File Not Found", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + + private void btnDel_Click(object sender, System.EventArgs e) + { + int iSel = listBox1.SelectedIndex; + if (iSel >= 0) + { + listBox1.Items.RemoveAt(iSel); + + if (listBox1.Items.Count > 0) + { + if (iSel > 0) + { + listBox1.SelectedIndex = iSel - 1; + } + else + { + listBox1.SelectedIndex = 0; + } + } + } + } + + private void FormClose(object sender, System.ComponentModel.CancelEventArgs e) + { + if (ds != null) + { + ds.Cancel(); + } + } + } + + public class MyCallback : IDESCombineCB + { + private int m_FrameCount; + private long m_TotBytes; + private DateTime m_StartTime; + private double m_LastSampleTime; + private bool m_KeepTime; + + private TextBox m_tbBytes; + private TextBox m_MediaTime; + private TextBox m_ElapsedTime; + private ProgressBar m_pb; + + public MyCallback(TextBox c) + { + m_FrameCount = 0; + m_TotBytes = 0; + m_KeepTime = false; + + m_tbBytes = c; + m_MediaTime = null; + m_ElapsedTime = null; + m_pb = null; + } + public MyCallback(TextBox c, TextBox d, TextBox e, ProgressBar f) + { + m_FrameCount = 0; + m_TotBytes = 0; + m_KeepTime = false; + + m_tbBytes = c; + m_MediaTime = d; + m_ElapsedTime = e; + m_pb = f; + } + ~MyCallback() + { + m_tbBytes.Text = m_TotBytes.ToString(); + if (m_MediaTime != null) + { + m_MediaTime.Text = m_LastSampleTime.ToString("0.00"); + m_ElapsedTime.Text = (DateTime.Now - m_StartTime).ToString(); + + m_pb.Value = m_pb.Maximum; + } + } + + public void KeepTime() + { + m_KeepTime = true; + } + + public int BufferCB(string sFilename, double SampleTime, System.IntPtr pBuffer, int BufferLen) + { + if (m_FrameCount == 0 && m_MediaTime != null) + { + m_StartTime = DateTime.Now; + } + + if (m_KeepTime && m_MediaTime != null) + { + TimeSpan ts = DateTime.Now - m_StartTime; + int iSleep = (int)((SampleTime - ts.TotalSeconds) * 1000); + if (iSleep > 0) + { + System.Threading.Thread.Sleep(iSleep); + } + } + + m_FrameCount++; + m_TotBytes += BufferLen; + + if (m_FrameCount % 15 == 0) + { + m_tbBytes.Text = m_TotBytes.ToString(); + if (m_MediaTime != null) + { + m_pb.Value = (int)(SampleTime * 10); + m_MediaTime.Text = SampleTime.ToString("0.00"); + m_ElapsedTime.Text = (DateTime.Now - m_StartTime).ToString(); + } + } + m_LastSampleTime = SampleTime; + + return 0; + } + } + +} diff --git a/Samples/Editing/DESCombine/TestCombine/Form1.resx b/Samples/Editing/DESCombine/TestCombine/Form1.resx new file mode 100644 index 0000000..c405c60 --- /dev/null +++ b/Samples/Editing/DESCombine/TestCombine/Form1.resx @@ -0,0 +1,409 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + Private + + + Private + + + Private + + + False + + + Private + + + Private + + + 8, 8 + + + True + + + False + + + True + + + Private + + + Private + + + Private + + + False + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + False + + + Private + + + False + + + Private + + + Private + + + Private + + + Private + + + 17, 17 + + + Private + + + Private + + + 153, 17 + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + 8, 8 + + + True + + + False + + + True + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + False + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + False + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Form1 + + + (Default) + + + False + + + False + + + 8, 8 + + + True + + + 80 + + + True + + + Private + + \ No newline at end of file diff --git a/Samples/Editing/DESCombine/TestCombine/Form2.cs b/Samples/Editing/DESCombine/TestCombine/Form2.cs new file mode 100644 index 0000000..2ba6c41 --- /dev/null +++ b/Samples/Editing/DESCombine/TestCombine/Form2.cs @@ -0,0 +1,271 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + +Written by snarfle@sourceforge.net +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Windows.Forms; + +namespace TestConverter +{ + /// + /// Summary description for Form2. + /// + public class Form2 : System.Windows.Forms.Form + { + private System.Windows.Forms.Label label3; + public System.Windows.Forms.TextBox tbAudioFile; + private System.Windows.Forms.Button btnAudio; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Button btnVideo; + private System.Windows.Forms.OpenFileDialog openFileDialog1; + public System.Windows.Forms.TextBox tbVideoFile; + private System.Windows.Forms.Button btnOk; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.Label label12; + public System.Windows.Forms.TextBox tbStart; + public System.Windows.Forms.TextBox tbEnd; + private System.Windows.Forms.Label label13; + private System.Windows.Forms.Label label14; + /// + /// Required designer variable. + /// + private System.ComponentModel.Container components = null; + + public Form2() + { + // + // Required for Windows Form Designer support + // + InitializeComponent(); + + // + // TODO: Add any constructor code after InitializeComponent call + // + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if(components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label3 = new System.Windows.Forms.Label(); + this.tbAudioFile = new System.Windows.Forms.TextBox(); + this.btnAudio = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.tbVideoFile = new System.Windows.Forms.TextBox(); + this.btnVideo = new System.Windows.Forms.Button(); + this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + this.btnOk = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.label12 = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.tbEnd = new System.Windows.Forms.TextBox(); + this.tbStart = new System.Windows.Forms.TextBox(); + this.label13 = new System.Windows.Forms.Label(); + this.label14 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // label3 + // + this.label3.Location = new System.Drawing.Point(6, 49); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(100, 16); + this.label3.TabIndex = 21; + this.label3.Text = "Audio File Name"; + // + // tbAudioFile + // + this.tbAudioFile.Location = new System.Drawing.Point(8, 69); + this.tbAudioFile.Name = "tbAudioFile"; + this.tbAudioFile.Size = new System.Drawing.Size(248, 20); + this.tbAudioFile.TabIndex = 4; + this.tbAudioFile.Text = ""; + // + // btnAudio + // + this.btnAudio.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); + this.btnAudio.Location = new System.Drawing.Point(264, 68); + this.btnAudio.Name = "btnAudio"; + this.btnAudio.Size = new System.Drawing.Size(24, 23); + this.btnAudio.TabIndex = 5; + this.btnAudio.Text = "..."; + this.btnAudio.Click += new System.EventHandler(this.btnAudio_Click); + // + // label1 + // + this.label1.Location = new System.Drawing.Point(8, 8); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(100, 16); + this.label1.TabIndex = 24; + this.label1.Text = "Video File Name"; + // + // tbVideoFile + // + this.tbVideoFile.Location = new System.Drawing.Point(8, 24); + this.tbVideoFile.Name = "tbVideoFile"; + this.tbVideoFile.Size = new System.Drawing.Size(248, 20); + this.tbVideoFile.TabIndex = 1; + this.tbVideoFile.Text = ""; + // + // btnVideo + // + this.btnVideo.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); + this.btnVideo.Location = new System.Drawing.Point(264, 23); + this.btnVideo.Name = "btnVideo"; + this.btnVideo.Size = new System.Drawing.Size(24, 23); + this.btnVideo.TabIndex = 2; + this.btnVideo.Text = "..."; + this.btnVideo.Click += new System.EventHandler(this.button1_Click); + // + // btnOk + // + this.btnOk.DialogResult = System.Windows.Forms.DialogResult.OK; + this.btnOk.Location = new System.Drawing.Point(40, 160); + this.btnOk.Name = "btnOk"; + this.btnOk.Size = new System.Drawing.Size(80, 32); + this.btnOk.TabIndex = 20; + this.btnOk.Text = "Ok"; + // + // btnCancel + // + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point(184, 160); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(72, 32); + this.btnCancel.TabIndex = 21; + this.btnCancel.Text = "Cancel"; + // + // label12 + // + this.label12.Location = new System.Drawing.Point(48, 128); + this.label12.Name = "label12"; + this.label12.Size = new System.Drawing.Size(56, 23); + this.label12.TabIndex = 3; + this.label12.Text = "End Time"; + // + // label5 + // + this.label5.Location = new System.Drawing.Point(48, 104); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(56, 23); + this.label5.TabIndex = 2; + this.label5.Text = "Start Time"; + // + // tbEnd + // + this.tbEnd.Location = new System.Drawing.Point(112, 128); + this.tbEnd.Name = "tbEnd"; + this.tbEnd.Size = new System.Drawing.Size(48, 20); + this.tbEnd.TabIndex = 9; + this.tbEnd.Text = "-1"; + this.tbEnd.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + // + // tbStart + // + this.tbStart.Location = new System.Drawing.Point(112, 104); + this.tbStart.Name = "tbStart"; + this.tbStart.Size = new System.Drawing.Size(48, 20); + this.tbStart.TabIndex = 8; + this.tbStart.Text = "0"; + this.tbStart.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + // + // label13 + // + this.label13.Location = new System.Drawing.Point(168, 104); + this.label13.Name = "label13"; + this.label13.Size = new System.Drawing.Size(32, 16); + this.label13.TabIndex = 4; + this.label13.Text = "secs"; + this.label13.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // label14 + // + this.label14.Location = new System.Drawing.Point(168, 128); + this.label14.Name = "label14"; + this.label14.Size = new System.Drawing.Size(32, 23); + this.label14.TabIndex = 5; + this.label14.Text = "secs"; + this.label14.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // Form2 + // + this.AcceptButton = this.btnOk; + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size(296, 204); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnOk); + this.Controls.Add(this.tbVideoFile); + this.Controls.Add(this.tbAudioFile); + this.Controls.Add(this.tbStart); + this.Controls.Add(this.tbEnd); + this.Controls.Add(this.btnVideo); + this.Controls.Add(this.label1); + this.Controls.Add(this.label3); + this.Controls.Add(this.btnAudio); + this.Controls.Add(this.label14); + this.Controls.Add(this.label5); + this.Controls.Add(this.label12); + this.Controls.Add(this.label13); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.Name = "Form2"; + this.Text = "Add Files"; + this.ResumeLayout(false); + + } + #endregion + + private void btnAudio_Click(object sender, System.EventArgs e) + { + OpenFileDialog ofd = new OpenFileDialog(); + ofd.Filter = "All Files (*.*)|*.*"; + ofd.Multiselect = false; + ofd.CheckFileExists = true; + DialogResult r = ofd.ShowDialog(); + if (r == DialogResult.OK) + { + tbAudioFile.Text = ofd.FileName; + } + } + + private void button1_Click(object sender, System.EventArgs e) + { + OpenFileDialog ofd = new OpenFileDialog(); + ofd.Filter = "All Files (*.*)|*.*"; + ofd.Multiselect = false; + ofd.CheckFileExists = true; + DialogResult r = ofd.ShowDialog(); + if (r == DialogResult.OK) + { + tbVideoFile.Text = ofd.FileName; + } + } + } +} diff --git a/Samples/Editing/DESCombine/TestCombine/Form2.resx b/Samples/Editing/DESCombine/TestCombine/Form2.resx new file mode 100644 index 0000000..99da72b --- /dev/null +++ b/Samples/Editing/DESCombine/TestCombine/Form2.resx @@ -0,0 +1,265 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + Private + + + Private + + + Private + + + False + + + Public + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + False + + + Public + + + False + + + Private + + + Private + + + Private + + + Private + + + 17, 17 + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + False + + + Public + + + Private + + + False + + + Public + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + (Default) + + + False + + + False + + + 8, 8 + + + Form2 + + + True + + + 80 + + + True + + + Private + + \ No newline at end of file diff --git a/Samples/Editing/DESCombine/TestCombine/TestCombine-2005.csproj b/Samples/Editing/DESCombine/TestCombine/TestCombine-2005.csproj new file mode 100644 index 0000000..fd1465f --- /dev/null +++ b/Samples/Editing/DESCombine/TestCombine/TestCombine-2005.csproj @@ -0,0 +1,120 @@ + + + Local + 8.0.50727 + 2.0 + {B20FEBE5-4895-4930-8017-C7614AB6C49B} + Debug + AnyCPU + App.ico + + + TestCombine + + + JScript + Grid + IE50 + false + WinExe + TestCombine + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Drawing + + + System.Windows.Forms + + + DESCombineLib-2005 + {A10D4671-34C7-4AD8-B537-B2B9C48242F7} + {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + + + + + + Code + + + Form + + + Form + + + Form1.cs + + + Form2.cs + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Editing/DESCombine/TestCombine/TestCombine.csproj b/Samples/Editing/DESCombine/TestCombine/TestCombine.csproj new file mode 100644 index 0000000..3df0616 --- /dev/null +++ b/Samples/Editing/DESCombine/TestCombine/TestCombine.csproj @@ -0,0 +1,165 @@ + + + + Local + 9.0.30729 + 2.0 + {B20FEBE5-4895-4930-8017-C7614AB6C49B} + Debug + AnyCPU + App.ico + + + TestCombine + + + JScript + Grid + IE50 + false + WinExe + TestCombine + OnBuildSuccess + + + + + + + 3.5 + false + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Drawing + + + System.Windows.Forms + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + DESCombineLib + {A10D4671-34C7-4AD8-B537-B2B9C48242F7} + {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + + + + + + Code + + + Form + + + Form + + + Form1.cs + + + Form2.cs + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + False + .NET Framework 3.5 SP1 + false + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Editing/DESCombine/docs/DESCombine.chm b/Samples/Editing/DESCombine/docs/DESCombine.chm new file mode 100644 index 0000000000000000000000000000000000000000..be7e3124db4ef4215fd76993fa9248d4bff2c51c GIT binary patch literal 35120 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 16), you would have 3 +seconds of audio with black video. + +Here are some step-by-step instructions of how the library might be used. You should +also check out DESCombine.chm. + +Step 1: + +Construct the class. The constructor has parameters for setting the Frames per Second, +BitCount, and Height & Width of the output file. + +Step 2: + +Add the files with AddAVFile, AddVideoFile or AddAudioFile. In addition to the name, you +can specify the start/stop points within the file. + +Step 3: + +Choose one of the RenderTo* options. Parameters are used to configure whichever +rendering option you choose (see the specific rendering option). Callback pointers +can be passed to any of these functions. + +Step 4: + +Start the rendering with StartRendering() + +Misc: + +There are other functions that may be useful: Cancel(), GetXML(), and Dispose(). Note +that Dispose should not be called within a Form.Dispose method. See the method for details. + +Events: + +FileCompleted - Called when a file has finished processing. Note that for RenderToWindow, +sometimes frames get dropped, which can result missed events. + +Completed - Called at the end of processing - contains final event code (Complete, UserAbort, +Disk space problems, etc. + diff --git a/Samples/Editing/DxScan/App.ico b/Samples/Editing/DxScan/App.ico new file mode 100644 index 0000000000000000000000000000000000000000..3a5525fd794f7a7c5c8e6187f470ea3af38cd2b6 GIT binary patch literal 1078 zcmeHHJr05}7=1t!Hp3A*8IHkVf+j?-!eHY14Gtcw1Eb*_9>Bq^zETJ@GKj{_2j4$w zo9}xCh!8{T3=X##Skq>ikMjsvB|y%crWBM2iW(4pI}c%z6%lW!=~4v77#3{z!dmB1 z__&l)-{KUYR+|8|;wB^R|9ET$J@(@=#rd^=)qs85?vAy(PSF5CyNkus435LVkZ$rj zNw|JG-P7^hF<(;#o*Vk}5R#e|^13tBbQkeF?djULtvqyxd3<{9 literal 0 HcmV?d00001 diff --git a/Samples/Editing/DxScan/AssemblyInfo.cs b/Samples/Editing/DxScan/AssemblyInfo.cs new file mode 100644 index 0000000..9f89a32 --- /dev/null +++ b/Samples/Editing/DxScan/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/Editing/DxScan/Capture.cs b/Samples/Editing/DxScan/Capture.cs new file mode 100644 index 0000000..1712e63 --- /dev/null +++ b/Samples/Editing/DxScan/Capture.cs @@ -0,0 +1,327 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.Collections; +using System.Runtime.InteropServices; +using System.Diagnostics; +using System.Threading; + +using DirectShowLib; + +namespace DxScan +{ + ///

Summary description for MainForm. + internal class Capture : ISampleGrabberCB, IDisposable + { + #region Member variables + + /// graph builder interface. + private IFilterGraph2 m_FilterGraph = null; + IMediaControl m_mediaCtrl = null; + IMediaEvent m_MediaEvent = null; + + /// Dimensions of the image, calculated once in constructor. + private int m_videoWidth; + private int m_videoHeight; + private int m_stride; + public int m_Count = 0; + public int m_Blacks = 0; + +#if DEBUG + // Allow you to "Connect to remote graph" from GraphEdit + DsROTEntry m_rot = null; +#endif + + #endregion + + #region API + + [DllImport("Kernel32.dll", EntryPoint="RtlMoveMemory")] + private static extern void CopyMemory(IntPtr Destination, IntPtr Source, [MarshalAs(UnmanagedType.U4)] uint Length); + + #endregion + + /// File name to scan + public Capture(string FileName) + { + try + { + // Set up the capture graph + SetupGraph(FileName); + } + catch + { + Dispose(); + throw; + } + } + /// release everything. + public void Dispose() + { + CloseInterfaces(); + } + // Destructor + ~Capture() + { + CloseInterfaces(); + } + + + /// capture the next image + public void Start() + { + int hr = m_mediaCtrl.Run(); + DsError.ThrowExceptionForHR( hr ); + } + + + public void WaitUntilDone() + { + int hr; + EventCode evCode; + const int E_Abort = unchecked((int)0x80004004); + + do + { + System.Windows.Forms.Application.DoEvents(); + hr = this.m_MediaEvent.WaitForCompletion( 100, out evCode ); + } while (hr == E_Abort); + DsError.ThrowExceptionForHR(hr); + } + + /// build the capture graph for grabber. + private void SetupGraph(string FileName) + { + int hr; + + ISampleGrabber sampGrabber = null; + IBaseFilter baseGrabFlt = null; + IBaseFilter capFilter = null; + IBaseFilter nullrenderer = null; + + // Get the graphbuilder object + m_FilterGraph = new FilterGraph() as IFilterGraph2; + m_mediaCtrl = m_FilterGraph as IMediaControl; + m_MediaEvent = m_FilterGraph as IMediaEvent; + + IMediaFilter mediaFilt = m_FilterGraph as IMediaFilter; + + try + { +#if DEBUG + m_rot = new DsROTEntry( m_FilterGraph ); +#endif + + // Add the video source + hr = m_FilterGraph.AddSourceFilter(FileName, "Ds.NET FileFilter", out capFilter); + DsError.ThrowExceptionForHR( hr ); + + // Get the SampleGrabber interface + sampGrabber = new SampleGrabber() as ISampleGrabber; + baseGrabFlt = sampGrabber as IBaseFilter; + + ConfigureSampleGrabber(sampGrabber); + + // Add the frame grabber to the graph + hr = m_FilterGraph.AddFilter( baseGrabFlt, "Ds.NET Grabber" ); + DsError.ThrowExceptionForHR( hr ); + + // --------------------------------- + // Connect the file filter to the sample grabber + + // Hopefully this will be the video pin, we could check by reading it's mediatype + IPin iPinOut = DsFindPin.ByDirection(capFilter, PinDirection.Output, 0); + + // Get the input pin from the sample grabber + IPin iPinIn = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Input, 0); + + hr = m_FilterGraph.Connect(iPinOut, iPinIn); + DsError.ThrowExceptionForHR( hr ); + + // Add the null renderer to the graph + nullrenderer = new NullRenderer() as IBaseFilter; + hr = m_FilterGraph.AddFilter( nullrenderer, "Null renderer" ); + DsError.ThrowExceptionForHR( hr ); + + // --------------------------------- + // Connect the sample grabber to the null renderer + + iPinOut = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Output, 0); + iPinIn = DsFindPin.ByDirection(nullrenderer, PinDirection.Input, 0); + + hr = m_FilterGraph.Connect(iPinOut, iPinIn); + DsError.ThrowExceptionForHR( hr ); + + // Turn off the clock. This causes the frames to be sent + // thru the graph as fast as possible + hr = mediaFilt.SetSyncSource(null); + DsError.ThrowExceptionForHR( hr ); + + // Read and cache the image sizes + SaveSizeInfo(sampGrabber); + } + finally + { + if (capFilter != null) + { + Marshal.ReleaseComObject(capFilter); + capFilter = null; + } + if (sampGrabber != null) + { + Marshal.ReleaseComObject(sampGrabber); + sampGrabber = null; + } + if (nullrenderer != null) + { + Marshal.ReleaseComObject(nullrenderer); + nullrenderer = null; + } + } + } + + /// Read and store the properties + private void SaveSizeInfo(ISampleGrabber sampGrabber) + { + int hr; + + // Get the media type from the SampleGrabber + AMMediaType media = new AMMediaType(); + hr = sampGrabber.GetConnectedMediaType( media ); + DsError.ThrowExceptionForHR( hr ); + + if( (media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero) ) + { + throw new NotSupportedException( "Unknown Grabber Media Format" ); + } + + // Grab the size info + VideoInfoHeader videoInfoHeader = (VideoInfoHeader) Marshal.PtrToStructure( media.formatPtr, typeof(VideoInfoHeader) ); + m_videoWidth = videoInfoHeader.BmiHeader.Width; + m_videoHeight = videoInfoHeader.BmiHeader.Height; + m_stride = m_videoWidth * (videoInfoHeader.BmiHeader.BitCount / 8); + + DsUtils.FreeAMMediaType(media); + media = null; + } + + /// Set the options on the sample grabber + private void ConfigureSampleGrabber(ISampleGrabber sampGrabber) + { + AMMediaType media; + int hr; + + // Set the media type to Video/RBG24 + media = new AMMediaType(); + media.majorType = MediaType.Video; + media.subType = MediaSubType.RGB24; + media.formatType = FormatType.VideoInfo; + hr = sampGrabber.SetMediaType( media ); + DsError.ThrowExceptionForHR( hr ); + + DsUtils.FreeAMMediaType(media); + media = null; + + // Choose to call BufferCB instead of SampleCB + hr = sampGrabber.SetCallback( this, 1 ); + DsError.ThrowExceptionForHR( hr ); + } + + /// Shut down capture + private void CloseInterfaces() + { + int hr; + + try + { + if( m_mediaCtrl != null ) + { + // Stop the graph + hr = m_mediaCtrl.Stop(); + m_mediaCtrl = null; + } + } + catch (Exception ex) + { + Debug.WriteLine(ex); + } + +#if DEBUG + if (m_rot != null) + { + m_rot.Dispose(); + } +#endif + + if (m_FilterGraph != null) + { + Marshal.ReleaseComObject(m_FilterGraph); + m_FilterGraph = null; + } + GC.Collect(); + } + + /// sample callback, NOT USED. + int ISampleGrabberCB.SampleCB( double SampleTime, IMediaSample pSample ) + { + Marshal.ReleaseComObject(pSample); + return 0; + } + + /// buffer callback, COULD BE FROM FOREIGN THREAD. + unsafe int ISampleGrabberCB.BufferCB( double SampleTime, IntPtr pBuffer, int BufferLen ) + { + + // Performance is essential here. Use unsafe for fastest possible scanning. + + // If every pixel were absolutely black, *b would always be zero. However, few frames, + // no matter how dark they appear, are *completely* black. I'm picking an arbitrary number. + // If the Red, Green or Blue of any pixel is brighter than this, I'm asserting that the frame + // isn't black. Adjust this number to suit. Set to zero to look for absolute blacks only. + const int iMaxBright = 10; + + Debug.Assert(IntPtr.Size == 4, "Change all instances of IntPtr.ToInt32 to .ToInt64"); + + // Walk every Red/Green/Blue of every pixel in the image. + // If any are greater than iMaxBrightness, it's too bright to be a black frame + Byte *b = (byte *)pBuffer; + for (int x = 0; x < m_videoHeight; x++) + { + for (int y = 0; (y < m_stride) && (*b <= iMaxBright); y++) + { + b++; + } + + // Are we done? + if (*b > iMaxBright) + { + break; + } + + // If the image width isn't evenly divisable by 4, sometimes padding bytes + // are added on the end of the rows. We need to make sure we skip those + b = (byte *)(pBuffer); + b += (x * m_stride); + } + + // If we didn't exit due to brightness + if (*b <= iMaxBright) + { + m_Blacks++; + Debug.WriteLine(string.Format("Frame Number: {0} Blacks: {1}", m_Count, m_Blacks)); + } + + // Increment frame number. Done this way, frame are zero indexed. + m_Count++; + + return 0; + } + } +} diff --git a/Samples/Editing/DxScan/DxScan-2005.csproj b/Samples/Editing/DxScan/DxScan-2005.csproj new file mode 100644 index 0000000..d34c2eb --- /dev/null +++ b/Samples/Editing/DxScan/DxScan-2005.csproj @@ -0,0 +1,113 @@ + + + Local + 8.0.50727 + 2.0 + {17379614-821C-4504-B45D-BBACC866EBFB} + Debug + AnyCPU + App.ico + + + DxScan + + + JScript + Grid + IE50 + false + WinExe + DxScan + OnBuildSuccess + + + + + + + + + bin\Debug\ + true + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + true + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + + Code + + + Code + + + Form + + + Form1.cs + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Editing/DxScan/DxScan-2005.sln b/Samples/Editing/DxScan/DxScan-2005.sln new file mode 100644 index 0000000..160dbc0 --- /dev/null +++ b/Samples/Editing/DxScan/DxScan-2005.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DxScan-2005", "DxScan-2005.csproj", "{17379614-821C-4504-B45D-BBACC866EBFB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {17379614-821C-4504-B45D-BBACC866EBFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Editing/DxScan/DxScan-2008.sln b/Samples/Editing/DxScan/DxScan-2008.sln new file mode 100644 index 0000000..98f8986 --- /dev/null +++ b/Samples/Editing/DxScan/DxScan-2008.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DxScan-2008", "DxScan-2008.csproj", "{17379614-821C-4504-B45D-BBACC866EBFB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {17379614-821C-4504-B45D-BBACC866EBFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {17379614-821C-4504-B45D-BBACC866EBFB}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Editing/DxScan/DxScan.csproj b/Samples/Editing/DxScan/DxScan.csproj new file mode 100644 index 0000000..053084d --- /dev/null +++ b/Samples/Editing/DxScan/DxScan.csproj @@ -0,0 +1,145 @@ + + + + Local + 8.0.50727 + 2.0 + {4AA43B9C-E987-43BA-A438-B6FDC7DACBD5} + Debug + AnyCPU + App.ico + + + DxScan + + + JScript + Grid + IE50 + false + WinExe + DxScan + OnBuildSuccess + + + + + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\Debug\ + true + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + true + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + + Code + + + Code + + + Form + + + Form1.cs + + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Editing/DxScan/Form1.cs b/Samples/Editing/DxScan/Form1.cs new file mode 100644 index 0000000..d46f69f --- /dev/null +++ b/Samples/Editing/DxScan/Form1.cs @@ -0,0 +1,206 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Windows.Forms; + +namespace DxScan +{ + /// + /// Summary description for Form1. + /// + public class Form1 : System.Windows.Forms.Form + { + // Application-defined message to notify app of filtergraph events + public const int WM_GRAPHNOTIFY = 0x8000 + 1; + + private System.Windows.Forms.Button StartStop; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Timer timer1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox tbFileName; + private System.Windows.Forms.TextBox tbFrameNum; + private System.Windows.Forms.TextBox tbBlacks; + private System.ComponentModel.IContainer components; + + public Form1() + { + // + // Required for Windows Form Designer support + // + InitializeComponent(); + + // + // TODO: Add any constructor code after InitializeComponent call + // + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if (components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.StartStop = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.tbFileName = new System.Windows.Forms.TextBox(); + this.timer1 = new System.Windows.Forms.Timer(this.components); + this.tbFrameNum = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.tbBlacks = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // StartStop + // + this.StartStop.Location = new System.Drawing.Point(96, 112); + this.StartStop.Name = "StartStop"; + this.StartStop.Size = new System.Drawing.Size(75, 40); + this.StartStop.TabIndex = 2; + this.StartStop.Text = "Start"; + this.StartStop.Click += new System.EventHandler(this.StartStop_Click); + // + // label1 + // + this.label1.Location = new System.Drawing.Point(8, 8); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(72, 16); + this.label1.TabIndex = 4; + this.label1.Text = "Source file"; + // + // tbFileName + // + this.tbFileName.Location = new System.Drawing.Point(24, 32); + this.tbFileName.Name = "tbFileName"; + this.tbFileName.Size = new System.Drawing.Size(232, 20); + this.tbFileName.TabIndex = 5; + this.tbFileName.Text = "c:\\foo.mpg"; + // + // timer1 + // + this.timer1.Interval = 1000; + this.timer1.Tick += new System.EventHandler(this.timer1_Tick); + // + // tbFrameNum + // + this.tbFrameNum.Location = new System.Drawing.Point(160, 160); + this.tbFrameNum.Name = "tbFrameNum"; + this.tbFrameNum.ReadOnly = true; + this.tbFrameNum.Size = new System.Drawing.Size(48, 20); + this.tbFrameNum.TabIndex = 6; + this.tbFrameNum.Text = ""; + // + // label2 + // + this.label2.Location = new System.Drawing.Point(56, 160); + this.label2.Name = "label2"; + this.label2.TabIndex = 7; + this.label2.Text = "Scanning Frame #"; + // + // tbBlacks + // + this.tbBlacks.Location = new System.Drawing.Point(160, 192); + this.tbBlacks.Name = "tbBlacks"; + this.tbBlacks.ReadOnly = true; + this.tbBlacks.Size = new System.Drawing.Size(48, 20); + this.tbBlacks.TabIndex = 8; + this.tbBlacks.Text = ""; + // + // label3 + // + this.label3.Location = new System.Drawing.Point(56, 192); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(96, 23); + this.label3.TabIndex = 9; + this.label3.Text = "# of black frames"; + // + // Form1 + // + this.AcceptButton = this.StartStop; + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(292, 262); + this.Controls.Add(this.label3); + this.Controls.Add(this.tbBlacks); + this.Controls.Add(this.label2); + this.Controls.Add(this.tbFrameNum); + this.Controls.Add(this.tbFileName); + this.Controls.Add(this.label1); + this.Controls.Add(this.StartStop); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "Form1"; + this.Text = "DxScan"; + this.ResumeLayout(false); + + } + #endregion + + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.Run(new Form1()); + } + + Capture cam = null; + + private void StartStop_Click(object sender, System.EventArgs e) + { + Cursor.Current = Cursors.WaitCursor; + + cam = new Capture(tbFileName.Text); + + // Start displaying statistics + timer1.Enabled = true; + cam.Start(); + cam.WaitUntilDone(); + timer1.Enabled = false; + + // Final update + tbFrameNum.Text = cam.m_Count.ToString(); + tbBlacks.Text = cam.m_Blacks.ToString(); + + lock (this) + { + cam.Dispose(); + cam = null; + } + + Cursor.Current = Cursors.Default; + } + + private void timer1_Tick(object sender, System.EventArgs e) + { + if (cam != null) + { + tbFrameNum.Text = cam.m_Count.ToString(); + tbBlacks.Text = cam.m_Blacks.ToString(); + } + } + } +} diff --git a/Samples/Editing/DxScan/Form1.resx b/Samples/Editing/DxScan/Form1.resx new file mode 100644 index 0000000..98f5ec5 --- /dev/null +++ b/Samples/Editing/DxScan/Form1.resx @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + False + + + Private + + + Private + + + 17, 17 + + + Private + + + Private + + + Private + + + False + + + False + + + Private + + + Private + + + Private + + + False + + + Private + + + False + + + Private + + + Private + + + False + + + (Default) + + + False + + + False + + + 8, 8 + + + True + + + 80 + + + True + + + Private + + + Form1 + + \ No newline at end of file diff --git a/Samples/Editing/DxScan/readme.txt b/Samples/Editing/DxScan/readme.txt new file mode 100644 index 0000000..2faa49c --- /dev/null +++ b/Samples/Editing/DxScan/readme.txt @@ -0,0 +1,26 @@ +--------------------------------------------------------------------- +DxScan + +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + +--------------------------------------------------------------------- + +A sample application scanning a media file looking for black frames + +To call it, you basically need: + + Capture cam; + + cam = new Capture(@"C:\foo.mpg"); + cam.Start(); + + cam.m_Count is the number of frames + cam.m_Blacks is how many black frames + +Most of the work is done in ISampleGrabberCB.BufferCB. See the comments +there. Also, the algorithm used to scan for black frames isn't as efficient +as it could be. However, the samples gives you an idea of how this could be +done. \ No newline at end of file diff --git a/Samples/Misc/BlackList/BlackList.csproj b/Samples/Misc/BlackList/BlackList.csproj new file mode 100644 index 0000000..b88e84a --- /dev/null +++ b/Samples/Misc/BlackList/BlackList.csproj @@ -0,0 +1,64 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {0178D2F5-5AC7-4B9F-8696-6E1AF14ED013} + Exe + Properties + DirectShowLib.Samples + BlackList + v2.0 + 512 + + + + + 3.5 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + \ No newline at end of file diff --git a/Samples/Misc/BlackList/BlackList.sln b/Samples/Misc/BlackList/BlackList.sln new file mode 100644 index 0000000..3ea8644 --- /dev/null +++ b/Samples/Misc/BlackList/BlackList.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlackList", "BlackList.csproj", "{0178D2F5-5AC7-4B9F-8696-6E1AF14ED013}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0178D2F5-5AC7-4B9F-8696-6E1AF14ED013}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0178D2F5-5AC7-4B9F-8696-6E1AF14ED013}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0178D2F5-5AC7-4B9F-8696-6E1AF14ED013}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0178D2F5-5AC7-4B9F-8696-6E1AF14ED013}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Misc/BlackList/BlackListManager.cs b/Samples/Misc/BlackList/BlackListManager.cs new file mode 100644 index 0000000..4c10717 --- /dev/null +++ b/Samples/Misc/BlackList/BlackListManager.cs @@ -0,0 +1,165 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.ComTypes; +using System.Text.RegularExpressions; + +using Microsoft.Win32; + +using DirectShowLib; + +namespace DirectShowLib.Samples +{ + /// + /// The BlackListManager class is an implementation of the IAMGraphBuilderCallback interface. + /// + /// + /// Loosly based on the The March Hare's sample: http://tmhare.mvps.org/downloads/GraphBuilderCallback.zip + /// + [ComVisible(true)] + public class BlackListManager : IAMGraphBuilderCallback + { + const int S_OK = 0; + const int E_FAIL = unchecked((int)0x80004005); + + private List blackList; + + /// + /// Create an instance of the BlackListManager + /// + /// The Filter Graph to register on. + public BlackListManager(IGraphBuilder graphBuilder) + { + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + IObjectWithSite ows = (IObjectWithSite)graphBuilder; + + int hr = ows.SetSite(this); + DsError.ThrowExceptionForHR(hr); + + this.blackList = new List(); + } + + /// + /// Add a Filter CLSID to black list during the graph building. + /// + /// The CLSID of the filter to black list. + public void AddBlackListedFilter(Guid clsid) + { + this.blackList.Add(clsid); + } + + /// + /// This method is for internal purpose. Don't call it directly. + /// + /// + /// + public int CreatedFilter(IBaseFilter filter) + { + // The rejection of the blacklisted filter have already been made in the SelectedFilter method. + // So we do nothing here. + return S_OK; + } + + /// + /// This method is for internal purpose. Don't call it directly. + /// + /// + /// + public int SelectedFilter(IMoniker moniker) + { + if (moniker == null) + throw new ArgumentNullException("moniker"); + + int retval = S_OK; + + string monikerDisplayName = null; + Guid filterClsid; + + // Get the moniker's display name. + // DirectShow filter have this form: @device:sw:FilterCategory\CLSID + moniker.GetDisplayName(null, null, out monikerDisplayName); + + Debug.WriteLine(string.Format("\r\nBlackListManager.SelectedFilter:\r\nMoniker: {0}", monikerDisplayName)); + + // Did the display name normally composed ? + int i = monikerDisplayName.LastIndexOf('\\'); + if (i != -1) + { + // Yes, tring to get the CLSID + if (GuidTryParse(monikerDisplayName.Substring(i + 1), out filterClsid)) + { + // Display informations about this filter + this.DisplayDebugInformation(moniker, filterClsid); + + // Test if the filter is black-listed + if (this.blackList.Contains(filterClsid)) + { + Debug.WriteLine("WARNING: This filter is black-listed! Rejecting it."); + + // The filter is black listed. Rejecting it. + retval = E_FAIL; + } + } + } + + return retval; + } + + /// + /// Helper method to parse GUID from strings + /// + private static bool GuidTryParse(string s, out Guid result) + { + result = Guid.Empty; + + string guidMatchPattern = "^[A-Fa-f0-9]{32}$|" + + "^({|\\()?[A-Fa-f0-9]{8}-([A-Fa-f0-9]{4}-){3}[A-Fa-f0-9]{12}(}|\\))?$|" + + "^({)?[0xA-Fa-f0-9]{3,10}(, {0,1}[0xA-Fa-f0-9]{3,6}){2}, {0,1}({)([0xA-Fa-f0-9]{3,4}, {0,1}){7}[0xA-Fa-f0-9]{3,4}(}})$"; + + if (string.IsNullOrEmpty(s) || !(new Regex(guidMatchPattern)).IsMatch(s)) + return false; + + result = new Guid(s); + return true; + } + + /// + /// Display the DLL that host the filter and a Friendly name. + /// + [Conditional("DEBUG")] + private void DisplayDebugInformation(IMoniker moniker, Guid filterClsid) + { + IPropertyBag propertyBag = null; + + try + { + string registryPath = string.Format(@"HKEY_CLASSES_ROOT\CLSID\{0}\InprocServer32", filterClsid.ToString("B")); + string filterLocation = (string)Registry.GetValue(registryPath, string.Empty, string.Empty); + + object o; + Guid IID_IPropertyBag = typeof(IPropertyBag).GUID; + + moniker.BindToStorage(null, null, ref IID_IPropertyBag, out o); + propertyBag = (IPropertyBag)o; + + int hr = propertyBag.Read("FriendlyName", out o, null); + Marshal.ThrowExceptionForHR(hr); + + string friendlyName = o.ToString(); + + Debug.WriteLine(string.Format("Localtion: {0}\r\nFriendly Name: {1}", filterLocation, friendlyName)); + } + catch { } + finally + { + if (propertyBag != null) + Marshal.ReleaseComObject(propertyBag); + } + } + + + } +} diff --git a/Samples/Misc/BlackList/Program.cs b/Samples/Misc/BlackList/Program.cs new file mode 100644 index 0000000..0cfad3a --- /dev/null +++ b/Samples/Misc/BlackList/Program.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; + +namespace DirectShowLib.Samples +{ + class Program + { + [STAThread] + static void Main(string[] args) + { + string filename; + + using (OpenFileDialog dialog = new OpenFileDialog()) + { + dialog.Filter = "Audio Files(*.wav;*.mp3;*.wma)|*.wav;*.mp3;*.wma|Video Files(*.avi;*.wmv)|*.avi;*.wmv|All files (*.*)|*.*"; + + if (dialog.ShowDialog() != DialogResult.OK) + return; + + filename = dialog.FileName; + } + + using (SimplePlayer player = new SimplePlayer(filename)) + { + player.Play(); + + Console.WriteLine("Press Enter to exit this program"); + Console.ReadLine(); + } + } + } +} diff --git a/Samples/Misc/BlackList/Properties/AssemblyInfo.cs b/Samples/Misc/BlackList/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..3079b69 --- /dev/null +++ b/Samples/Misc/BlackList/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Les informations générales relatives à un assembly dépendent de +// l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations +// associées à un assembly. +[assembly: AssemblyTitle("ConsoleApplication1")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ConsoleApplication1")] +[assembly: AssemblyCopyright("Copyright © 2009")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly +// aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de +// COM, affectez la valeur true à l'attribut ComVisible sur ce type. +[assembly: ComVisible(false)] + +// Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM +[assembly: Guid("cab22efa-5846-4033-9cd3-a41bd77a8313")] + +// Les informations de version pour un assembly se composent des quatre valeurs suivantes : +// +// Version principale +// Version secondaire +// Numéro de build +// Révision +// +// Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut +// en utilisant '*', comme indiqué ci-dessous : +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Samples/Misc/BlackList/SimplePlayer.cs b/Samples/Misc/BlackList/SimplePlayer.cs new file mode 100644 index 0000000..c48b0a8 --- /dev/null +++ b/Samples/Misc/BlackList/SimplePlayer.cs @@ -0,0 +1,132 @@ +using System; +using System.IO; +using System.Runtime.InteropServices; + +using DirectShowLib; + +namespace DirectShowLib.Samples +{ + /// + /// The SimplePlayer class implement a very basic player that use DirectShow. + /// + /// The main purpose of this class is to demonstrate the use of the BlackListManager class. + public class SimplePlayer : IDisposable + { + private bool disposed; + private IFilterGraph2 graphBuilder; + private IMediaControl mediaControl; + private IMediaEvent mediaEvent; + + private BlackListManager blackListManager; + +#if DEBUG + private DsROTEntry rot; +#endif + + /// + /// This constructor internally build a DirectShow graph using the given file name parameter. + /// + /// A media file. + /// This constructor use the BlackListManager class to bane the use of the ffdshow Audio and Video decoders during the Intelligent Connect graph building. + public SimplePlayer(string filename) + { + if (string.IsNullOrEmpty(filename)) + throw new ArgumentNullException("filename"); + + if (!File.Exists(filename)) + throw new FileNotFoundException(); + + this.graphBuilder = (IFilterGraph2)new FilterGraph(); + +#if DEBUG + this.rot = new DsROTEntry(this.graphBuilder); +#endif + + this.blackListManager = new BlackListManager(this.graphBuilder); + + // blacklist the ffdshow Audio Decoder filter + this.blackListManager.AddBlackListedFilter(new Guid("0F40E1E5-4F79-4988-B1A9-CC98794E6B55")); + // blacklist the ffdshow Video Decoder filter + this.blackListManager.AddBlackListedFilter(new Guid("04FE9017-F873-410E-871E-AB91661A4EF7")); + + int hr = this.graphBuilder.RenderFile(filename, null); + DsError.ThrowExceptionForHR(hr); + + this.mediaControl = (IMediaControl)this.graphBuilder; + this.mediaEvent = (IMediaEvent)this.graphBuilder; + } + + + public void Dispose() + { + this.Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (this.disposed) + return; + + if (disposing) + { +#if DEBUG + if (this.rot != null) + { + this.rot.Dispose(); + this.rot = null; + } +#endif + if (this.graphBuilder != null) + { + this.mediaControl.StopWhenReady(); + this.mediaControl.Stop(); + + Marshal.ReleaseComObject(this.graphBuilder); + this.graphBuilder = null; + } + } + + this.disposed = true; + } + + /// + /// Play the media file. + /// + public void Play() + { + if (this.disposed) + throw new ObjectDisposedException(this.GetType().ToString()); + + int hr = this.mediaControl.Run(); + DsError.ThrowExceptionForHR(hr); + } + + /// + /// Pause the media file. + /// + public void Pause() + { + if (this.disposed) + throw new ObjectDisposedException(this.GetType().ToString()); + + int hr = this.mediaControl.Pause(); + DsError.ThrowExceptionForHR(hr); + } + + /// + /// Stop the media file. + /// + public void Stop() + { + if (this.disposed) + throw new ObjectDisposedException(this.GetType().ToString()); + + int hr = this.mediaControl.StopWhenReady(); + DsError.ThrowExceptionForHR(hr); + + hr = this.mediaControl.Stop(); + DsError.ThrowExceptionForHR(hr); + } + } +} diff --git a/Samples/Misc/BlackList/readme.txt b/Samples/Misc/BlackList/readme.txt new file mode 100644 index 0000000..3a26a27 --- /dev/null +++ b/Samples/Misc/BlackList/readme.txt @@ -0,0 +1,38 @@ +/************************************************************************ + +DirectShowLib - Provide access to DirectShow interfaces via .NET +Copyright (C) 2005 +http://sourceforge.net/projects/directshownet/ + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +**************************************************************************/ + +This sample illustrate how to use the IAMGraphBuilderCallback interface to +reject some filters during the graph creation. You can adapt this sample for +your uses if some filters are known to break your application. + +This sample is loosly based on the The March Hare's sample: +http://tmhare.mvps.org/downloads/GraphBuilderCallback.zip + +This sample blacklist the ffdshow audio and video filters. This filters are +the best thing and the worst thing in DirectShow. Best, because they allow +reading a vast variety of media files. Worst, because there developpers never +implemented the MERIT correctly so that other filters have no chances to be +choiced by the runtime even when they are better. This is probably one of the +reason why MS added the IAMPluginControl in Windows 7, but that's another +story. Some reading: +http://alax.info/blog/398 +http://alax.info/blog/719 diff --git a/Samples/Misc/DxWebCam/Client/App.ico b/Samples/Misc/DxWebCam/Client/App.ico new file mode 100644 index 0000000000000000000000000000000000000000..3a5525fd794f7a7c5c8e6187f470ea3af38cd2b6 GIT binary patch literal 1078 zcmeHHJr05}7=1t!Hp3A*8IHkVf+j?-!eHY14Gtcw1Eb*_9>Bq^zETJ@GKj{_2j4$w zo9}xCh!8{T3=X##Skq>ikMjsvB|y%crWBM2iW(4pI}c%z6%lW!=~4v77#3{z!dmB1 z__&l)-{KUYR+|8|;wB^R|9ET$J@(@=#rd^=)qs85?vAy(PSF5CyNkus435LVkZ$rj zNw|JG-P7^hF<(;#o*Vk}5R#e|^13tBbQkeF?djULtvqyxd3<{9 literal 0 HcmV?d00001 diff --git a/Samples/Misc/DxWebCam/Client/AssemblyInfo.cs b/Samples/Misc/DxWebCam/Client/AssemblyInfo.cs new file mode 100644 index 0000000..9f89a32 --- /dev/null +++ b/Samples/Misc/DxWebCam/Client/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/Misc/DxWebCam/Client/WebCamClient-2005.csproj b/Samples/Misc/DxWebCam/Client/WebCamClient-2005.csproj new file mode 100644 index 0000000..6634129 --- /dev/null +++ b/Samples/Misc/DxWebCam/Client/WebCamClient-2005.csproj @@ -0,0 +1,106 @@ + + + Local + 8.0.50727 + 2.0 + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC} + Debug + AnyCPU + App.ico + + + WebCamClient + + + JScript + Grid + IE50 + false + WinExe + WebCamClient + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + + Code + + + Form + + + + WebClient.cs + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Misc/DxWebCam/Client/WebCamClient.csproj b/Samples/Misc/DxWebCam/Client/WebCamClient.csproj new file mode 100644 index 0000000..97237ff --- /dev/null +++ b/Samples/Misc/DxWebCam/Client/WebCamClient.csproj @@ -0,0 +1,109 @@ + + + + Local + 8.0.50727 + 2.0 + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC} + Debug + AnyCPU + App.ico + + + WebCamClient + + + JScript + Grid + IE50 + false + WinExe + WebCamClient + OnBuildSuccess + + + + + + + 3.5 + v2.0 + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + + Code + + + Form + + + + WebClient.cs + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Misc/DxWebCam/Client/WebClient.cs b/Samples/Misc/DxWebCam/Client/WebClient.cs new file mode 100644 index 0000000..719915e --- /dev/null +++ b/Samples/Misc/DxWebCam/Client/WebClient.cs @@ -0,0 +1,380 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Windows.Forms; +using System.Net.Sockets; +using System.Threading; +using System.Text; +using System.IO; + +namespace WebCamClient +{ + /// + /// Summary description for Form1. + /// + public class Form1 : System.Windows.Forms.Form + { + DoImages doImages; + static int m_Count; + + private System.Windows.Forms.PictureBox pictureBox1; + private System.Windows.Forms.TextBox txtServer; + private System.Windows.Forms.Button btnPress; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox txtMessage; + private System.Windows.Forms.TextBox txtPort; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Timer timer1; + private System.Windows.Forms.TextBox txtFrames; + private System.ComponentModel.IContainer components; + + public Form1() + { + // + // Required for Windows Form Designer support + // + InitializeComponent(); + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if (components != null) + { + components.Dispose(); + } + } + + if (doImages != null) + { + doImages.Done = true; + doImages = null; + } + base.Dispose( disposing ); + } + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.btnPress = new System.Windows.Forms.Button(); + this.txtServer = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.txtMessage = new System.Windows.Forms.TextBox(); + this.txtPort = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.txtFrames = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.timer1 = new System.Windows.Forms.Timer(this.components); + this.SuspendLayout(); + // + // pictureBox1 + // + this.pictureBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.pictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.pictureBox1.Location = new System.Drawing.Point(0, 0); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(320, 240); + this.pictureBox1.TabIndex = 0; + this.pictureBox1.TabStop = false; + // + // btnPress + // + this.btnPress.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnPress.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnPress.Location = new System.Drawing.Point(232, 328); + this.btnPress.Name = "btnPress"; + this.btnPress.Size = new System.Drawing.Size(80, 32); + this.btnPress.TabIndex = 1; + this.btnPress.Tag = "1"; + this.btnPress.Text = "Start"; + this.btnPress.Click += new System.EventHandler(this.btnPress_Click); + // + // txtServer + // + this.txtServer.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.txtServer.Location = new System.Drawing.Point(16, 288); + this.txtServer.Name = "txtServer"; + this.txtServer.Size = new System.Drawing.Size(96, 20); + this.txtServer.TabIndex = 3; + this.txtServer.Text = "192.168.0.3"; + // + // label1 + // + this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); + this.label1.Location = new System.Drawing.Point(16, 248); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(120, 40); + this.label1.TabIndex = 4; + this.label1.Text = "Enter server name or ip address"; + // + // txtMessage + // + this.txtMessage.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtMessage.Location = new System.Drawing.Point(8, 376); + this.txtMessage.Name = "txtMessage"; + this.txtMessage.ReadOnly = true; + this.txtMessage.Size = new System.Drawing.Size(304, 20); + this.txtMessage.TabIndex = 5; + this.txtMessage.Text = ""; + // + // txtPort + // + this.txtPort.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.txtPort.Location = new System.Drawing.Point(160, 288); + this.txtPort.Name = "txtPort"; + this.txtPort.Size = new System.Drawing.Size(48, 20); + this.txtPort.TabIndex = 6; + this.txtPort.Text = "399"; + // + // label2 + // + this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label2.Location = new System.Drawing.Point(160, 264); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(72, 23); + this.label2.TabIndex = 7; + this.label2.Text = "Port Number"; + // + // txtFrames + // + this.txtFrames.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.txtFrames.Location = new System.Drawing.Point(248, 288); + this.txtFrames.Name = "txtFrames"; + this.txtFrames.ReadOnly = true; + this.txtFrames.Size = new System.Drawing.Size(64, 20); + this.txtFrames.TabIndex = 8; + this.txtFrames.Text = ""; + // + // label3 + // + this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label3.Location = new System.Drawing.Point(248, 264); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(48, 16); + this.label3.TabIndex = 9; + this.label3.Text = "Frames"; + // + // timer1 + // + this.timer1.Interval = 1000; + this.timer1.Tick += new System.EventHandler(this.timer1_Tick); + // + // Form1 + // + this.AcceptButton = this.btnPress; + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.CancelButton = this.btnPress; + this.ClientSize = new System.Drawing.Size(320, 402); + this.Controls.Add(this.label3); + this.Controls.Add(this.txtFrames); + this.Controls.Add(this.label2); + this.Controls.Add(this.txtPort); + this.Controls.Add(this.txtMessage); + this.Controls.Add(this.label1); + this.Controls.Add(this.txtServer); + this.Controls.Add(this.btnPress); + this.Controls.Add(this.pictureBox1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.Name = "Form1"; + this.Text = "WebClient"; + this.ResumeLayout(false); + + } + #endregion + + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Thread.CurrentThread.Name = "Main"; + Application.Run(new Form1()); + } + + private void btnPress_Click(object sender, System.EventArgs e) + { + // If the button says 'Start' + if ((string)btnPress.Tag == "1") + { + // Create a new thread to receive the images + try + { + m_Count = 0; + timer1.Enabled = true; + txtMessage.Text = ""; + doImages = new DoImages(this, Convert.ToInt32(txtPort.Text)); + ThreadStart o = new ThreadStart(doImages.ThreadProc); + Thread thread = new Thread( o ); + thread.Name="Imaging"; + thread.Start(); + } + catch (Exception ex) + { + txtMessage.Text = ex.Message; + return; + } + + // Reset the button tag and description + btnPress.Tag = "2"; + btnPress.Text = "Stop"; + } + else + { + Stop(); + timer1.Enabled = false; + txtFrames.Text = m_Count.ToString(); + } + } + + private void Stop() + { + // Inform the thread it should stop + doImages.Done = true; + doImages = null; + + // Reset the button tag and description + btnPress.Tag = "1"; + btnPress.Text = "Start"; + } + + private void timer1_Tick(object sender, System.EventArgs e) + { + txtFrames.Text = m_Count.ToString(); + } + + // ================================================================================================ + public class DoImages + { + // Abort indicator + public bool Done; + + // Form to write to + private Form1 m_f; + + // Client connection to server + private TcpClient tcpClient; + + // stream to read from + private NetworkStream networkStream; + + public DoImages(Form1 f, int nPort) + { + Done = false; + m_f = f; + + // Connect to the server and get the stream + tcpClient = new TcpClient(m_f.txtServer.Text, nPort); + tcpClient.NoDelay = false; + tcpClient.ReceiveTimeout = 5000; + tcpClient.ReceiveBufferSize = 20000; + networkStream = tcpClient.GetStream(); + } + + public void ThreadProc() + { + string s; + int iBytesComing, iBytesRead, iOffset; + byte [] byLength = new byte[10]; + byte [] byImage = new byte[1000]; + MemoryStream m = new MemoryStream(byImage); + + do + { + try + { + // Read the fixed length string that + // tells the image size + iBytesRead = networkStream.Read(byLength, 0, 10); + + if (iBytesRead != 10) + { + m_f.txtMessage.Text = "No response from host"; + m_f.Stop(); + break; + } + s = Encoding.ASCII.GetString(byLength); + iBytesComing = Convert.ToInt32(s); + + // Make sure our buffer is big enough + if (iBytesComing > byImage.Length) + { + byImage = new byte[iBytesComing]; + m = new MemoryStream(byImage); + tcpClient.ReceiveBufferSize=iBytesComing + 10; + } + else + { + m.Position = 0; + } + + // Read the image + iOffset = 0; + + do + { + iBytesRead = networkStream.Read(byImage, iOffset, iBytesComing - iOffset); + if (iBytesRead != 0) + { + iOffset += iBytesRead; + } + else + { + m_f.txtMessage.Text = "No response from host"; + m_f.Stop(); + } + } while ((iOffset != iBytesComing) && (!Done)); + + + if (!Done) + { + // Write back a byte + networkStream.Write(byImage, 0, 1); + + // Put the image on the screen + m_f.pictureBox1.Image = new System.Drawing.Bitmap(m); + + // Increment the frame count + m_Count++; + } + } + catch(Exception e) + { + // If we get out of sync, we're probably toast, since + // there is currently no resync mechanism + m_f.txtMessage.Text = e.Message; + m_f.Stop(); + } + + } while (!Done); + + networkStream.Close(); + tcpClient.Close(); + networkStream = null; + tcpClient = null; + } + } + } +} diff --git a/Samples/Misc/DxWebCam/Client/WebClient.resx b/Samples/Misc/DxWebCam/Client/WebClient.resx new file mode 100644 index 0000000..4baeb6d --- /dev/null +++ b/Samples/Misc/DxWebCam/Client/WebClient.resx @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + False + + + Private + + + False + + + Private + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + False + + + Private + + + Private + + + Private + + + Private + + + False + + + False + + + Private + + + Private + + + Private + + + 17, 17 + + + Private + + + False + + + (Default) + + + False + + + False + + + 8, 8 + + + True + + + 80 + + + True + + + Form1 + + + Private + + \ No newline at end of file diff --git a/Samples/Misc/DxWebCam/Client/readme.txt b/Samples/Misc/DxWebCam/Client/readme.txt new file mode 100644 index 0000000..a1484e7 --- /dev/null +++ b/Samples/Misc/DxWebCam/Client/readme.txt @@ -0,0 +1,13 @@ +--------------------------------------------------------------------- +WebCamClient + +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + +--------------------------------------------------------------------- + +A poor man's web cam program. This application runs as a Win32 Service. +It takes the output of a capture graph, turns it into a stream of JPEG +files, and sends it thru TCP/IP to a client application. \ No newline at end of file diff --git a/Samples/Misc/DxWebCam/Service/AssemblyInfo.cs b/Samples/Misc/DxWebCam/Service/AssemblyInfo.cs new file mode 100644 index 0000000..9f89a32 --- /dev/null +++ b/Samples/Misc/DxWebCam/Service/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/Misc/DxWebCam/Service/Capture.cs b/Samples/Misc/DxWebCam/Service/Capture.cs new file mode 100644 index 0000000..bac9b49 --- /dev/null +++ b/Samples/Misc/DxWebCam/Service/Capture.cs @@ -0,0 +1,445 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.Collections; +using System.Runtime.InteropServices; +using System.Threading; +using System.Diagnostics; + +using DirectShowLib; + + +namespace WebCamService +{ + /// Summary description for MainForm. + internal class Capture : ISampleGrabberCB, IDisposable + { + #region Member variables + + /// graph builder interface. + private IFilterGraph2 m_FilterGraph = null; + private IMediaControl m_mediaCtrl = null; + + /// so we can wait for the async job to finish + private ManualResetEvent m_PictureReady = null; + + /// Set by async routine when it captures an image + private volatile bool m_bGotOne = false; + + /// Indicates the status of the graph + private bool m_bRunning = false; + + /// Dimensions of the image, calculated once in constructor. + private IntPtr m_handle = IntPtr.Zero; + private int m_videoWidth; + private int m_videoHeight; + private int m_stride; + public int m_Dropped = 0; + + #endregion + + #region API + + [DllImport("Kernel32.dll", EntryPoint="RtlMoveMemory")] + private static extern void CopyMemory(IntPtr Destination, IntPtr Source, int Length); + + #endregion + + /// Use capture device zero, default frame rate and size + public Capture() + { + _Capture(0, 0, 0, 0); + } + /// Use specified capture device, default frame rate and size + public Capture(int iDeviceNum) + { + _Capture(iDeviceNum, 0, 0, 0); + } + /// Use specified capture device, specified frame rate and default size + public Capture(int iDeviceNum, int iFrameRate) + { + _Capture(iDeviceNum, iFrameRate, 0, 0); + } + /// Use specified capture device, specified frame rate and size + public Capture(int iDeviceNum, int iFrameRate, int iWidth, int iHeight) + { + _Capture(iDeviceNum, iFrameRate, iWidth, iHeight); + } + /// release everything. + public void Dispose() + { + CloseInterfaces(); + if (m_PictureReady != null) + { + m_PictureReady.Close(); + m_PictureReady = null; + } + } + // Destructor + ~Capture() + { + Dispose(); + } + + public int Width + { + get + { + return m_videoWidth; + } + } + public int Height + { + get + { + return m_videoHeight; + } + } + public int Stride + { + get + { + return m_stride; + } + } + /// capture the next image + public IntPtr GetBitMap() + { + m_handle = Marshal.AllocCoTaskMem(m_stride * m_videoHeight); + + try + { + // get ready to wait for new image + m_PictureReady.Reset(); + m_bGotOne = false; + + // If the graph hasn't been started, start it. + Start(); + + // Start waiting + if ( ! m_PictureReady.WaitOne(5000, false) ) + { + throw new Exception("Timeout waiting to get picture"); + } + } + catch + { + Marshal.FreeCoTaskMem(m_handle); + throw; + } + + // Got one + return m_handle; + } + // Start the capture graph + public void Start() + { + if (!m_bRunning) + { + int hr = m_mediaCtrl.Run(); + DsError.ThrowExceptionForHR( hr ); + + m_bRunning = true; + } + } + // Pause the capture graph. + // Running the graph takes up a lot of resources. Pause it when it + // isn't needed. + public void Pause() + { + if (m_bRunning) + { + int hr = m_mediaCtrl.Pause(); + DsError.ThrowExceptionForHR( hr ); + + m_bRunning = false; + } + } + + + // Internal capture + private void _Capture(int iDeviceNum, int iFrameRate, int iWidth, int iHeight) + { + DsDevice[] capDevices; + + // Get the collection of video devices + capDevices = DsDevice.GetDevicesOfCat( FilterCategory.VideoInputDevice ); + + if (iDeviceNum + 1 > capDevices.Length) + { + throw new Exception("No video capture devices found at that index!"); + } + + try + { + // Set up the capture graph + SetupGraph( capDevices[iDeviceNum], iFrameRate, iWidth, iHeight); + + // tell the callback to ignore new images + m_PictureReady = new ManualResetEvent(false); + m_bGotOne = true; + m_bRunning = false; + } + catch + { + Dispose(); + throw; + } + } + + /// build the capture graph for grabber. + private void SetupGraph(DsDevice dev, int iFrameRate, int iWidth, int iHeight) + { + int hr; + + ISampleGrabber sampGrabber = null; + IBaseFilter capFilter = null; + ICaptureGraphBuilder2 capGraph = null; + + // Get the graphbuilder object + m_FilterGraph = (IFilterGraph2) new FilterGraph(); + m_mediaCtrl = m_FilterGraph as IMediaControl; + try + { + // Get the ICaptureGraphBuilder2 + capGraph = (ICaptureGraphBuilder2) new CaptureGraphBuilder2(); + + // Get the SampleGrabber interface + sampGrabber = (ISampleGrabber) new SampleGrabber(); + + // Start building the graph + hr = capGraph.SetFiltergraph( m_FilterGraph ); + DsError.ThrowExceptionForHR( hr ); + + // Add the video device + hr = m_FilterGraph.AddSourceFilterForMoniker(dev.Mon, null, "Video input", out capFilter); + DsError.ThrowExceptionForHR( hr ); + + IBaseFilter baseGrabFlt = (IBaseFilter) sampGrabber; + ConfigureSampleGrabber(sampGrabber); + + // Add the frame grabber to the graph + hr = m_FilterGraph.AddFilter( baseGrabFlt, "Ds.NET Grabber" ); + DsError.ThrowExceptionForHR( hr ); + + // If any of the default config items are set + if (iFrameRate + iHeight + iWidth > 0) + { + SetConfigParms(capGraph, capFilter, iFrameRate, iWidth, iHeight); + } + + hr = capGraph.RenderStream( PinCategory.Capture, MediaType.Video, capFilter, null, baseGrabFlt ); + DsError.ThrowExceptionForHR( hr ); + + SaveSizeInfo(sampGrabber); + } + finally + { + if (capFilter != null) + { + Marshal.ReleaseComObject(capFilter); + capFilter = null; + } + if (sampGrabber != null) + { + Marshal.ReleaseComObject(sampGrabber); + sampGrabber = null; + } + if (capGraph != null) + { + Marshal.ReleaseComObject(capGraph); + capGraph = null; + } + } + } + + private void SaveSizeInfo(ISampleGrabber sampGrabber) + { + int hr; + + // Get the media type from the SampleGrabber + AMMediaType media = new AMMediaType(); + hr = sampGrabber.GetConnectedMediaType( media ); + DsError.ThrowExceptionForHR( hr ); + + if( (media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero) ) + { + throw new NotSupportedException( "Unknown Grabber Media Format" ); + } + + // Grab the size info + VideoInfoHeader videoInfoHeader = (VideoInfoHeader) Marshal.PtrToStructure( media.formatPtr, typeof(VideoInfoHeader) ); + m_videoWidth = videoInfoHeader.BmiHeader.Width; + m_videoHeight = videoInfoHeader.BmiHeader.Height; + m_stride = m_videoWidth * (videoInfoHeader.BmiHeader.BitCount / 8); + + DsUtils.FreeAMMediaType(media); + media = null; + } + private void ConfigureSampleGrabber(ISampleGrabber sampGrabber) + { + AMMediaType media; + int hr; + + // Set the media type to Video/RBG24 + media = new AMMediaType(); + media.majorType = MediaType.Video; + media.subType = MediaSubType.RGB24; + media.formatType = FormatType.VideoInfo; + hr = sampGrabber.SetMediaType( media ); + DsError.ThrowExceptionForHR( hr ); + + DsUtils.FreeAMMediaType(media); + media = null; + + // Configure the samplegrabber + hr = sampGrabber.SetCallback( this, 1 ); + DsError.ThrowExceptionForHR( hr ); + } + + // Set the Framerate, and video size + private void SetConfigParms(ICaptureGraphBuilder2 capGraph, IBaseFilter capFilter, int iFrameRate, int iWidth, int iHeight) + { + int hr; + object o; + AMMediaType media; + + // Find the stream config interface + hr = capGraph.FindInterface( + PinCategory.Capture, MediaType.Video, capFilter, typeof(IAMStreamConfig).GUID, out o ); + + IAMStreamConfig videoStreamConfig = o as IAMStreamConfig; + if (videoStreamConfig == null) + { + throw new Exception("Failed to get IAMStreamConfig"); + } + + // Get the existing format block + hr = videoStreamConfig.GetFormat( out media); + DsError.ThrowExceptionForHR( hr ); + + // copy out the videoinfoheader + VideoInfoHeader v = new VideoInfoHeader(); + Marshal.PtrToStructure( media.formatPtr, v ); + + // if overriding the framerate, set the frame rate + if (iFrameRate > 0) + { + v.AvgTimePerFrame = 10000000 / iFrameRate; + } + + // if overriding the width, set the width + if (iWidth > 0) + { + v.BmiHeader.Width = iWidth; + } + + // if overriding the Height, set the Height + if (iHeight > 0) + { + v.BmiHeader.Height = iHeight; + } + + // Copy the media structure back + Marshal.StructureToPtr( v, media.formatPtr, false ); + + // Set the new format + hr = videoStreamConfig.SetFormat( media ); + DsError.ThrowExceptionForHR( hr ); + + DsUtils.FreeAMMediaType(media); + media = null; + } + + /// Shut down capture + private void CloseInterfaces() + { + int hr; + + try + { + if( m_mediaCtrl != null ) + { + // Stop the graph + hr = m_mediaCtrl.Stop(); + m_bRunning = false; + } + } + catch (Exception ex) + { + Debug.WriteLine(ex); + } + + if (m_FilterGraph != null) + { + Marshal.ReleaseComObject(m_FilterGraph); + m_FilterGraph = null; + } + } + + /// sample callback, NOT USED. + int ISampleGrabberCB.SampleCB( double SampleTime, IMediaSample pSample ) + { + if (!m_bGotOne) + { + // Set bGotOne to prevent further calls until we + // request a new bitmap. + m_bGotOne = true; + IntPtr pBuffer; + + pSample.GetPointer(out pBuffer); + int iBufferLen = pSample.GetSize(); + + if (pSample.GetSize() > m_stride * m_videoHeight) + { + throw new Exception("Buffer is wrong size"); + } + + CopyMemory(m_handle, pBuffer, m_stride * m_videoHeight); + + // Picture is ready. + m_PictureReady.Set(); + } + + Marshal.ReleaseComObject(pSample); + return 0; + } + + /// buffer callback, COULD BE FROM FOREIGN THREAD. + int ISampleGrabberCB.BufferCB( double SampleTime, IntPtr pBuffer, int BufferLen ) + { + if (!m_bGotOne) + { + // The buffer should be long enought + if(BufferLen <= m_stride * m_videoHeight) + { + // Copy the frame to the buffer + CopyMemory(m_handle, pBuffer, m_stride * m_videoHeight); + } + else + { + throw new Exception("Buffer is wrong size"); + } + + // Set bGotOne to prevent further calls until we + // request a new bitmap. + m_bGotOne = true; + + // Picture is ready. + m_PictureReady.Set(); + } + else + { + m_Dropped++; + } + return 0; + } + } +} diff --git a/Samples/Misc/DxWebCam/Service/TcpServer.cs b/Samples/Misc/DxWebCam/Service/TcpServer.cs new file mode 100644 index 0000000..d0fd5a4 --- /dev/null +++ b/Samples/Misc/DxWebCam/Service/TcpServer.cs @@ -0,0 +1,329 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Diagnostics; +using System.Net.Sockets; +using System.Collections; +using System.IO; +using System.Net; +using System.Text; +using System.Threading; + +namespace TCP +{ + internal class TcpServer : IDisposable + { + // This is not the max number of connections you can have, it's the number + // that can queue up waiting for you to Accept them. If more than MAXCONNECTION + // more clients try to connect while you are servicing another, OnConnect is + // probably taking too long. + const int MAXCONNECTIONS = 3; + + #region Member variables + + private ArrayList m_aryClients; + private Socket m_sockListener; + private volatile bool m_bShuttingDown; + private ManualResetEvent ShutDownReady; + + #endregion + + // Return an array of the ip addresses assigned to this pc + public static IPAddress [] GetAddresses() + { + IPAddress [] aryLocalAddr = null; + string strHostName = ""; + + // NOTE: DNS lookups are nice and all but quite time consuming. + strHostName = Dns.GetHostName(); +#if USING_NET11 + IPHostEntry ipEntry = Dns.GetHostByName( strHostName ); +#else + IPHostEntry ipEntry = Dns.GetHostEntry( strHostName ); +#endif + aryLocalAddr = ipEntry.AddressList; + + // Verify we got an IP address. + if( aryLocalAddr == null || aryLocalAddr.Length < 1 ) + { + throw new Exception( "Unable to get local address" ); + } + + return aryLocalAddr; + } + + public TcpServer(int nPortListen) + { + _TcpServer(nPortListen, GetAddresses()[0]); + } + public TcpServer(int nPortListen, IPAddress ip) + { + _TcpServer(nPortListen, ip); + } + + // Shut down the listener + public void Dispose() + { + // Shutting down is a real PITA. You can't close the listener + // while there is an outstanding async call active. And you can't + // cancel the async call. Grr. As a workaround, this routine + // makes a connection to the port. The OnConnect routine, recognizing + // that we are in shutdown, doesn't create a new async call. + TcpClient t = null; + + // Only want one thread to be preforming shutdown at a time. + lock (this) + { + // Have we already shutdown? + if (!m_bShuttingDown) + { + m_bShuttingDown = true; + + // Disconnect each client + foreach (SockWrapper s in m_aryClients) + { + try + { + s.Client.Shutdown(SocketShutdown.Both); + s.Client.Close(); + } + catch {} + } + m_aryClients = null; + + // Connect to the port to trigger the async listener + IPEndPoint ep = (IPEndPoint)m_sockListener.LocalEndPoint; + t = new TcpClient(ep.Address.ToString(), ep.Port); + } + } + + if (t != null) + { + // Listen for the async listener to let go. This must be done + // outside the crit section since the listener needs to lock it. + ShutDownReady.WaitOne(3000, false); + + lock (this) + { + // close everything down + m_sockListener.Close(); + m_sockListener = null; + t.Close(); + ShutDownReady.Close(); + ShutDownReady = null; + } + } + } + ~TcpServer() + { + // If Dispose is not called against our class and the destructor is + // called, some of the member variables in this class have already + // been disposed. Such being the case, there's no way to clean up + // nicely. Moral: Always call Dispose. + + //Dispose(); + } + + // Send to all connected clients + public void SendToAll(MemoryStream m) + { + _SendToAll(m.GetBuffer(), (int)m.Length); + } + + public void SendToAll(byte [] b) + { + _SendToAll(b, b.Length); + } + + public int Connections + { + get { return m_aryClients.Count; } + } + + + public event TcpConnected Connected; + public event TcpConnected Disconnected; + public event TcpReceive DataReceived; + public event TcpSend Send; + + private void _TcpServer(int nPortListen, IPAddress ip) + { + try + { + // Initialize member vars + m_aryClients = new ArrayList(5); + ShutDownReady = new ManualResetEvent(false); + m_bShuttingDown = false; + + // Create the listener socket in this machine's IP address + m_sockListener = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp ); + m_sockListener.Bind( new IPEndPoint( ip, nPortListen ) ); + m_sockListener.Listen( MAXCONNECTIONS ); + + // Setup a callback to be notified of connection requests + m_sockListener.BeginAccept( new AsyncCallback( OnConnectRequest ), m_sockListener ); + } + catch + { + m_bShuttingDown = true; + throw; + } + } + + private void _SendToAll(byte [] b, int iLength) + { + lock (this) + { + if (!m_bShuttingDown) + { + foreach (SockWrapper s in m_aryClients) + { + _SendOne(s, b, iLength); + } + } + } + } + + private void _SendOne(SockWrapper s, byte [] b, int iLength) + { + try + { + bool bSend = true; + + if (Send != null) + Send(this, ref s.obj, ref bSend); + + if (bSend) + s.Client.Send(b, iLength, SocketFlags.None); + } + catch + { + // Ignore the error. If the client is dead, OnReceiveData + // will be called to close the connection. I would remove it + // anyway, except bad things happen if you remove an entry + // from a list while using foreach. + } + } + + // Client has connected + private void OnConnectRequest( IAsyncResult ar ) + { + // Get the listener and client + Socket listener = (Socket)ar.AsyncState; + Socket client = listener.EndAccept( ar ); + + lock (this) + { + if (!m_bShuttingDown) + { + // Wrap the client and add it to the array + SockWrapper s = new SockWrapper(client); + m_aryClients.Add( s ); + + // Fire the Connected event + if (Connected != null) + Connected(this, ref s.obj); + + // Set up an async wait for packets from the client + AsyncCallback receiveData = new AsyncCallback( OnReceivedData ); + s.Client.BeginReceive( s.byBuff, 0, s.byBuff.Length, SocketFlags.None, receiveData, s ); + + // (Re)Setup a callback to be notified of connection requests + listener.BeginAccept(new AsyncCallback( OnConnectRequest ) , listener ); + } + else + { + // If we are in shutdown mode, DON'T add + // the connection to the array, DON'T setup + // the async listen, and DO set the event + // to say we are done. + ShutDownReady.Set(); + } + } + } + + // Client has sent data, or has disconnected + private void OnReceivedData( IAsyncResult ar ) + { + // Socket was the passed in object + SockWrapper s = (SockWrapper)ar.AsyncState; + + lock (this) + { + if (!m_bShuttingDown) + { + // Check if we got any data + try + { + int nBytesRec = s.Client.EndReceive( ar ); + if( nBytesRec > 0 ) + { + if (DataReceived != null) + DataReceived(this, ref s.obj, ref s.byBuff, nBytesRec); + + // Restablish the callback + AsyncCallback receiveData = new AsyncCallback( OnReceivedData ); + s.Client.BeginReceive( s.byBuff, 0, s.byBuff.Length, SocketFlags.None, receiveData, s ); + } + else + { + // If no data was received then the connection is probably dead + RemoveConnection(s); + } + } + catch + { + RemoveConnection(s); + } + } + } + } + + // Remove a connection from the list of active connections + private void RemoveConnection(SockWrapper s) + { + try + { + s.Client.Shutdown( SocketShutdown.Both ); + s.Client.Close(); + } + catch {} + + // Remove it from the array + try + { + m_aryClients.Remove( s ); + } + catch {} + + // Fire the Disconnected event + if (Disconnected != null) + Disconnected(this, ref s.obj); + } + + + // Wrapper for each client (stored in m_aryClients) + internal class SockWrapper + { + // The buffer is used by receive + public Socket Client; + public byte [] byBuff; + public object obj; + + public SockWrapper(Socket client) + { + Client = client; + byBuff = new byte[256]; + obj = new object(); + } + } + } + public delegate void TcpConnected(Object sender, ref object o); + public delegate void TcpSend(Object sender, ref object o, ref bool b); + public delegate void TcpReceive(Object sender, ref object o, ref byte [] b, int ByteCount); +} \ No newline at end of file diff --git a/Samples/Misc/DxWebCam/Service/WebCamInstaller.cs b/Samples/Misc/DxWebCam/Service/WebCamInstaller.cs new file mode 100644 index 0000000..7c54c4a --- /dev/null +++ b/Samples/Misc/DxWebCam/Service/WebCamInstaller.cs @@ -0,0 +1,51 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Collections; +using System.ComponentModel; +using System.Configuration.Install; +using System.Configuration; +using System.ServiceProcess; + +namespace WebCamService +{ + /// + /// The service must be installed before it can execute. + /// Services are installed with "installutil.exe" and uninstalled with "installutil.exe /u" with the service executable as the last parameter. + /// For example, "installutil.exe D:\projects\webcam\webcamservice\obj\debug\webcamservice.exe" will install the service to the Services Manager. + /// + [RunInstaller(true)] + public class WebCamInstaller: Installer + { + private ServiceInstaller serviceInstaller; + private ServiceProcessInstaller processInstaller; + + public WebCamInstaller() + { + // Instantiate installers for process and services. + processInstaller = new ServiceProcessInstaller(); + serviceInstaller = new ServiceInstaller(); + + // The services run under the system account. + processInstaller.Account = ServiceAccount.LocalSystem; + + // The services are started automatically. + serviceInstaller.StartType = ServiceStartMode.Automatic; + + // ServiceName must equal those on ServiceBase derived classes. + serviceInstaller.ServiceName = "WebCamService"; + + // displayed in list + serviceInstaller.DisplayName = "WebCamService"; + + // Add installers to collection. Order is not important. + Installers.Add(serviceInstaller); + Installers.Add(processInstaller); + } + } +} diff --git a/Samples/Misc/DxWebCam/Service/WebCamInstaller.resx b/Samples/Misc/DxWebCam/Service/WebCamInstaller.resx new file mode 100644 index 0000000..7e32396 --- /dev/null +++ b/Samples/Misc/DxWebCam/Service/WebCamInstaller.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/Samples/Misc/DxWebCam/Service/WebCamService-2005.csproj b/Samples/Misc/DxWebCam/Service/WebCamService-2005.csproj new file mode 100644 index 0000000..954bd61 --- /dev/null +++ b/Samples/Misc/DxWebCam/Service/WebCamService-2005.csproj @@ -0,0 +1,126 @@ + + + Local + 8.0.50727 + 2.0 + {5D949877-7015-40CA-83E5-D516C1C2BA97} + Debug + AnyCPU + + + + + WebCamService + + + JScript + Grid + IE50 + false + WinExe + WebCamService + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Configuration.Install + + + System.Drawing + + + System.ServiceProcess + + + + + Code + + + Code + + + Code + + + Component + + + Component + + + + WebCamInstaller.cs + + + WebCamService.cs + Designer + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Misc/DxWebCam/Service/WebCamService.cs b/Samples/Misc/DxWebCam/Service/WebCamService.cs new file mode 100644 index 0000000..ce1bfc6 --- /dev/null +++ b/Samples/Misc/DxWebCam/Service/WebCamService.cs @@ -0,0 +1,364 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Diagnostics; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Runtime.InteropServices; +using System.ServiceProcess; +using System.Threading; +using System.Text; +using TCP; + +namespace WebCamService +{ + public class WebCamService : ServiceBase + { + #region Required Service Related Methods + + private System.ComponentModel.Container components = null; + + public WebCamService() + { + InitializeComponent(); + } + + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + this.ServiceName = "WebCamService"; + } + + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if (components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #endregion + + [STAThread] + public static void Main(string[] args) + { + Thread.CurrentThread.Name = "Main thread"; + WebCamService ServiceToRun = new WebCamService() ; + + if ( Debugger.IsAttached ) + { + ServiceToRun.Run(); + } + else + { + ServiceToRun.CanPauseAndContinue = false; + ServiceBase.Run(ServiceToRun); + } + } + + #region Member Variables + private const int MAXOUTSTANDINGPACKETS = 3; + + /// + /// The thread will run the job. + /// The job is the Method Run() below + /// + protected Thread thread = null; + private ManualResetEvent ConnectionReady; + private volatile bool bShutDown; + private volatile int iConnectionCount; + #endregion + + /// + /// Set things in motion so your service can do its work. + /// + protected override void OnStart(string[] args) + { + ThreadStart starter = new ThreadStart(Run); + thread = new Thread(starter); + thread.Start(); + } + + /// + /// Stop this service. + /// The Run() Method tests for this thread state each second + /// + protected override void OnStop() + { + // Set exit condition + bShutDown = true; + + // Need to get out of wait + ConnectionReady.Set(); + } + public void Run() + { + const int VIDEODEVICE = 0; // zero based index of video capture device to use + const int FRAMERATE = 15; // Depends on video device caps. Generally 4-30. + const int VIDEOWIDTH = 640; // Depends on video device caps + const int VIDEOHEIGHT = 480; // Depends on video device caps + const long JPEGQUALITY = 30; // 1-100 or 0 for default + + const int TCPLISTENPORT = 399; + + Capture cam = null; + TcpServer serv = null; + ImageCodecInfo myImageCodecInfo; + EncoderParameters myEncoderParameters; + + // Set up logging + StreamWriter sw = File.AppendText(@"c:\WebCam.log"); + + try + { + // Set up member vars + ConnectionReady = new ManualResetEvent(false); + bShutDown = false; + + // Set up tcp server + iConnectionCount = 0; + serv = new TcpServer(TCPLISTENPORT, TcpServer.GetAddresses()[0]); + serv.Connected += new TcpConnected(Connected); + serv.Disconnected += new TcpConnected(Disconnected); + serv.DataReceived += new TcpReceive(Receive); + serv.Send += new TcpSend(Send); + + myEncoderParameters = null; + myImageCodecInfo = GetEncoderInfo("image/jpeg"); + + if (JPEGQUALITY != 0) + { + // If not using the default jpeg quality setting + EncoderParameter myEncoderParameter; + myEncoderParameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, JPEGQUALITY); + myEncoderParameters = new EncoderParameters(1); + myEncoderParameters.Param[0] = myEncoderParameter; + } + + cam = new Capture(VIDEODEVICE, FRAMERATE, VIDEOWIDTH, VIDEOHEIGHT); + + // Initialization succeeded. Now, start serving up frames + DoIt(cam, serv, sw, myImageCodecInfo, myEncoderParameters); + } + catch(Exception ex) + { + try + { + sw.WriteLine(String.Format("{0}: Failed on startup {1}", DateTime.Now.ToString(), ex)); + } + catch {} + } + finally + { + // Cleanup + if (serv != null) + { + serv.Dispose(); + } + + if (cam != null) + { + cam.Dispose(); + } + sw.Close(); + } + } + + // Start serving up frames + private void DoIt(Capture cam, TcpServer serv, StreamWriter sw, ImageCodecInfo myImageCodecInfo, EncoderParameters myEncoderParameters) + { + MemoryStream m = new MemoryStream(20000); + Bitmap image = null; + IntPtr ip = IntPtr.Zero; + do + { + // Wait til a client connects before we start the graph + ConnectionReady.WaitOne(); + cam.Start(); + + // While not shutting down, and still at least one client + while ((!bShutDown) && (serv.Connections > 0)) + { + try + { + + // capture image + ip = cam.GetBitMap(); + image = new Bitmap(cam.Width, cam.Height, cam.Stride, PixelFormat.Format24bppRgb, ip); + image.RotateFlip(RotateFlipType.RotateNoneFlipY); + + // save it to jpeg using quality options + m.Position = 10; + image.Save(m, myImageCodecInfo, myEncoderParameters); + + // Send the length as a fixed length string + m.Position = 0; + m.Write(Encoding.ASCII.GetBytes( (m.Length - 10).ToString("d8") + "\r\n"), 0, 10); + + // send the jpeg image + serv.SendToAll(m); + + // Empty the stream + m.SetLength(0); + + // remove the image from memory + image.Dispose(); + image = null; + } + catch(Exception ex) + { + try + { + sw.WriteLine(DateTime.Now.ToString()); + sw.WriteLine(ex); + } + catch {} + } + finally + { + if (ip != IntPtr.Zero) + { + Marshal.FreeCoTaskMem(ip); + ip = IntPtr.Zero; + } + } + } + + // Clients have all disconnected. Pause, then sleep and wait for more + cam.Pause(); + sw.WriteLine("Dropped frames: " + cam.m_Dropped.ToString()); + + } while ( !bShutDown ); + } + + class PacketCount : IDisposable + { + private int m_PacketCount; + private int m_MaxPackets; + + public PacketCount(int i) + { + m_MaxPackets = i; + m_PacketCount = 0; + } + + public bool AddPacket() + { + bool b; + + lock (this) + { + b = m_PacketCount < m_MaxPackets; + if (b) + { + m_PacketCount++; + } + else + { + Debug.WriteLine("Max outstanding Packets reached"); + } + } + + return b; + } + + public void RemovePacket() + { + lock (this) + { + if (m_PacketCount > 0) + { + m_PacketCount--; + } + else + { + Debug.WriteLine("Packet count is messed up"); + } + } + } + + public int Count() + { + return m_PacketCount; + } + + #region IDisposable Members + + public void Dispose() + { +#if DEBUG + if (m_PacketCount != 0) + { + Debug.WriteLine("Packets left over: " + m_PacketCount.ToString()); + } +#endif + } + + #endregion + } + + // A client attached to the tcp port + private void Connected(object sender, ref object t) + { + lock (this) + { + t = new PacketCount(MAXOUTSTANDINGPACKETS); + iConnectionCount++; + + if (iConnectionCount == 1) + { + ConnectionReady.Set(); + } + } + } + + // A client detached from the tcp port + private void Disconnected(object sender, ref object t) + { + lock (this) + { + iConnectionCount--; + if (iConnectionCount == 0) + { + ConnectionReady.Reset(); + } + } + } + + private void Receive(Object sender, ref object o, ref byte [] b, int ByteCount) + { + PacketCount pc = (PacketCount)o; + pc.RemovePacket(); + } + + private void Send(Object sender, ref object o, ref bool b) + { + PacketCount pc = (PacketCount)o; + + b = pc.AddPacket(); + } + + // Find the appropriate encoder + private ImageCodecInfo GetEncoderInfo(String mimeType) + { + int j; + ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders(); + for(j = 0; j < encoders.Length; ++j) + { + if(encoders[j].MimeType == mimeType) + return encoders[j]; + } + return null; + } + } +} diff --git a/Samples/Misc/DxWebCam/Service/WebCamService.csproj b/Samples/Misc/DxWebCam/Service/WebCamService.csproj new file mode 100644 index 0000000..884afe5 --- /dev/null +++ b/Samples/Misc/DxWebCam/Service/WebCamService.csproj @@ -0,0 +1,131 @@ + + + + Local + 8.0.50727 + 2.0 + {5D949877-7015-40CA-83E5-D516C1C2BA97} + Debug + AnyCPU + + + + + WebCamService + + + JScript + Grid + IE50 + false + WinExe + WebCamService + OnBuildSuccess + + + + + + + 3.5 + v2.0 + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Configuration.Install + + + System.Drawing + + + System.ServiceProcess + + + + + Code + + + Code + + + Code + + + Component + + + Component + + + + WebCamInstaller.cs + + + WebCamService.cs + Designer + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Misc/DxWebCam/Service/WebCamService.resx b/Samples/Misc/DxWebCam/Service/WebCamService.resx new file mode 100644 index 0000000..7e32396 --- /dev/null +++ b/Samples/Misc/DxWebCam/Service/WebCamService.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/Samples/Misc/DxWebCam/Service/readme.txt b/Samples/Misc/DxWebCam/Service/readme.txt new file mode 100644 index 0000000..cc721a0 --- /dev/null +++ b/Samples/Misc/DxWebCam/Service/readme.txt @@ -0,0 +1,21 @@ +--------------------------------------------------------------------- +WebCamService + +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + +--------------------------------------------------------------------- + +A poor man's web cam program. This application runs as a Win32 Service. +It takes the output of a capture graph, turns it into a stream of JPEG +files, and sends it thru TCP/IP to a client application. + +Vista warnings: + +The debug version of the server tries to create a log file at c:\. Vista doesn't allow +this. Either build retail, or change the location of the file. + +Also, TcpServer.GetAddresses()[0] on vista doesn't always give the ip address of the local +machine. This may require adjustment as well. \ No newline at end of file diff --git a/Samples/Misc/DxWebCam/WebCamService-2005.sln b/Samples/Misc/DxWebCam/WebCamService-2005.sln new file mode 100644 index 0000000..d9177dd --- /dev/null +++ b/Samples/Misc/DxWebCam/WebCamService-2005.sln @@ -0,0 +1,25 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebCamService-2005", "Service\WebCamService-2005.csproj", "{5D949877-7015-40CA-83E5-D516C1C2BA97}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebCamClient-2005", "Client\WebCamClient-2005.csproj", "{4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5D949877-7015-40CA-83E5-D516C1C2BA97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5D949877-7015-40CA-83E5-D516C1C2BA97}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5D949877-7015-40CA-83E5-D516C1C2BA97}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5D949877-7015-40CA-83E5-D516C1C2BA97}.Release|Any CPU.Build.0 = Release|Any CPU + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Misc/DxWebCam/WebCamService-2008.sln b/Samples/Misc/DxWebCam/WebCamService-2008.sln new file mode 100644 index 0000000..80fa4d6 --- /dev/null +++ b/Samples/Misc/DxWebCam/WebCamService-2008.sln @@ -0,0 +1,25 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebCamService-2008", "Service\WebCamService-2008.csproj", "{5D949877-7015-40CA-83E5-D516C1C2BA97}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebCamClient-2008", "Client\WebCamClient-2008.csproj", "{4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5D949877-7015-40CA-83E5-D516C1C2BA97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5D949877-7015-40CA-83E5-D516C1C2BA97}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5D949877-7015-40CA-83E5-D516C1C2BA97}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5D949877-7015-40CA-83E5-D516C1C2BA97}.Release|Any CPU.Build.0 = Release|Any CPU + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4FF60CC6-8D38-4686-A8F8-94BB36DDCFCC}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Misc/DxWebCam/readme.txt b/Samples/Misc/DxWebCam/readme.txt new file mode 100644 index 0000000..e268e4d --- /dev/null +++ b/Samples/Misc/DxWebCam/readme.txt @@ -0,0 +1,25 @@ +/************************************************************************ + +DirectShowLib - Provide access to DirectShow interfaces via .NET +Copyright (C) 2005 +http://sourceforge.net/projects/directshownet/ + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +**************************************************************************/ + +A poor man's web cam program. This application runs as a Win32 Service. +It takes the output of a capture graph, turns it into a stream of JPEG +files, and sends it thru TCP/IP to a client application. \ No newline at end of file diff --git a/Samples/Misc/GMFPreview/GMFPreview-2008.sln b/Samples/Misc/GMFPreview/GMFPreview-2008.sln new file mode 100644 index 0000000..7f689e0 --- /dev/null +++ b/Samples/Misc/GMFPreview/GMFPreview-2008.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GMFPreview-2008", "GMFPreview\GMFPreview-2008.csproj", "{0E756677-5CB9-488B-B54A-55B32BF087D6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0E756677-5CB9-488B-B54A-55B32BF087D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0E756677-5CB9-488B-B54A-55B32BF087D6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0E756677-5CB9-488B-B54A-55B32BF087D6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0E756677-5CB9-488B-B54A-55B32BF087D6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Misc/GMFPreview/GMFPreview.sln b/Samples/Misc/GMFPreview/GMFPreview.sln new file mode 100644 index 0000000..59893bf --- /dev/null +++ b/Samples/Misc/GMFPreview/GMFPreview.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GMFPreview", "GMFPreview\GMFPreview.csproj", "{0E756677-5CB9-488B-B54A-55B32BF087D6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0E756677-5CB9-488B-B54A-55B32BF087D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0E756677-5CB9-488B-B54A-55B32BF087D6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0E756677-5CB9-488B-B54A-55B32BF087D6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0E756677-5CB9-488B-B54A-55B32BF087D6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Misc/GMFPreview/GMFPreview/DeviceForm.Designer.cs b/Samples/Misc/GMFPreview/GMFPreview/DeviceForm.Designer.cs new file mode 100644 index 0000000..4d4a509 --- /dev/null +++ b/Samples/Misc/GMFPreview/GMFPreview/DeviceForm.Designer.cs @@ -0,0 +1,97 @@ +namespace GMFPreview +{ + partial class DeviceForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.lbDevices = new System.Windows.Forms.ListBox(); + this.bnOK = new System.Windows.Forms.Button(); + this.bnCancel = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // lbDevices + // + this.lbDevices.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lbDevices.FormattingEnabled = true; + this.lbDevices.ItemHeight = 16; + this.lbDevices.Location = new System.Drawing.Point(10, 10); + this.lbDevices.Name = "lbDevices"; + this.lbDevices.Size = new System.Drawing.Size(330, 196); + this.lbDevices.TabIndex = 0; + this.lbDevices.DoubleClick += new System.EventHandler(this.lbDevices_DoubleClick); + // + // bnOK + // + this.bnOK.DialogResult = System.Windows.Forms.DialogResult.OK; + this.bnOK.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.bnOK.Location = new System.Drawing.Point(365, 10); + this.bnOK.Name = "bnOK"; + this.bnOK.Size = new System.Drawing.Size(75, 23); + this.bnOK.TabIndex = 1; + this.bnOK.Text = "OK"; + this.bnOK.UseVisualStyleBackColor = true; + this.bnOK.Click += new System.EventHandler(this.bnOK_Click); + // + // bnCancel + // + this.bnCancel.CausesValidation = false; + this.bnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.bnCancel.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.bnCancel.Location = new System.Drawing.Point(363, 38); + this.bnCancel.Name = "bnCancel"; + this.bnCancel.Size = new System.Drawing.Size(75, 23); + this.bnCancel.TabIndex = 2; + this.bnCancel.Text = "Cancel"; + this.bnCancel.UseVisualStyleBackColor = true; + this.bnCancel.Click += new System.EventHandler(this.bnCancel_Click); + // + // Form2 + // + this.AcceptButton = this.bnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.bnCancel; + this.ClientSize = new System.Drawing.Size(450, 230); + this.Controls.Add(this.bnCancel); + this.Controls.Add(this.bnOK); + this.Controls.Add(this.lbDevices); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.Name = "Form2"; + this.ShowInTaskbar = false; + this.Text = "Select Device"; + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button bnOK; + private System.Windows.Forms.Button bnCancel; + public System.Windows.Forms.ListBox lbDevices; + } +} \ No newline at end of file diff --git a/Samples/Misc/GMFPreview/GMFPreview/DeviceForm.cs b/Samples/Misc/GMFPreview/GMFPreview/DeviceForm.cs new file mode 100644 index 0000000..29fce8f --- /dev/null +++ b/Samples/Misc/GMFPreview/GMFPreview/DeviceForm.cs @@ -0,0 +1,97 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Windows.Forms; + +using DirectShowLib; + +namespace GMFPreview +{ + public partial class DeviceForm : Form + { + public DeviceForm() + { + InitializeComponent(); + + // Load the listbox with video capture device names + DsDevice[] devs = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice); + + foreach (DsDevice dev in devs) + { + lbDevices.Items.Add(new VDevice(dev)); + } + + if (devs.Length > 0) + { + lbDevices.SelectedIndex = 0; + bnOK.Enabled = true; + } + else + { + bnOK.Enabled = false; + } + } + + private void bnOK_Click(object sender, EventArgs e) + { + Close(); + } + + private void bnCancel_Click(object sender, EventArgs e) + { + Close(); + } + + private void lbDevices_DoubleClick(object sender, EventArgs e) + { + DialogResult = DialogResult.OK; + Close(); + } + + public void SelectIndex(DsDevice dev) + { + // Highlight the specified device (if we can find it) + if (dev != null) + { + for (int x = 0; x < lbDevices.Items.Count; x++) + { + VDevice d = lbDevices.Items[x] as VDevice; + if (d.Device.DevicePath == dev.DevicePath) + { + lbDevices.SelectedIndex = x; + break; + } + } + } + } + } + + // A wrapper class to put DsDevices into a listbox + public class VDevice + { + private DsDevice m_dev; + + public VDevice(DsDevice dev) + { + m_dev = dev; + } + + public DsDevice Device + { + get + { + return m_dev; + } + } + + public override string ToString() + { + return m_dev.Name; + } + } +} \ No newline at end of file diff --git a/Samples/Misc/GMFPreview/GMFPreview/DeviceForm.resx b/Samples/Misc/GMFPreview/GMFPreview/DeviceForm.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/Samples/Misc/GMFPreview/GMFPreview/DeviceForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Samples/Misc/GMFPreview/GMFPreview/GMFBridge.cs b/Samples/Misc/GMFPreview/GMFPreview/GMFBridge.cs new file mode 100644 index 0000000..a281aac --- /dev/null +++ b/Samples/Misc/GMFPreview/GMFPreview/GMFBridge.cs @@ -0,0 +1,99 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +// These definitions are for use with the GMFBridge filter, which is available +// at http://www.gdcl.co.uk/. Please check out the information there for +// descriptions of how to use these interfaces. + +using System; +using System.Runtime.InteropServices; + +using DirectShowLib; + +namespace DirectShowLib.GDCL +{ + public enum eFormatType + { + Uncompressed, + MuxInputs, + Any, + } + + [ComImport, Guid("08E3287F-3A5C-47e9-8179-A9E9221A5CDE")] + public class GMFBridgeController + { + } + + [Guid("8C4D8054-FCBA-4783-865A-7E8B3C814011"), + InterfaceType(ComInterfaceType.InterfaceIsDual)] + public interface IGMFBridgeController + { + [PreserveSig] + int AddStream( + [In, MarshalAs(UnmanagedType.Bool)] bool bVideo, + [In] eFormatType AllowedTypes, + [In, MarshalAs(UnmanagedType.Bool)] bool bDiscardUnconnected + ); + + [PreserveSig] + int InsertSinkFilter( + [In] IFilterGraph pGraph, + out IBaseFilter ppFilter + ); + + [PreserveSig] + int InsertSourceFilter( + [In] IBaseFilter pUnkSourceGraphSinkFilter, + [In] IGraphBuilder pRenderGraph, + out IBaseFilter ppFilter + ); + + [PreserveSig] + int CreateSourceGraph( + [In, MarshalAs(UnmanagedType.BStr)] string strFile, + [In] IFilterGraph pGraph, + out IBaseFilter pSinkFilter + ); + + [PreserveSig] + int CreateRenderGraph( + [In] IBaseFilter pSourceGraphSinkFilter, + [In] IGraphBuilder pRenderGraph, + out IBaseFilter pRenderGraphSourceFilter + ); + + [PreserveSig] + int BridgeGraphs( + [In] IBaseFilter pSourceGraphSinkFilter, + [In] IBaseFilter pRenderGraphSourceFilter + ); + + [PreserveSig] + int SetNotify( + [In] IntPtr hwnd, + [In] int msg + ); + + [PreserveSig] + int SetBufferMinimum( + [In] int nMillisecs + ); + + [PreserveSig] + int GetSegmentTime( + out double pdSeconds + ); + + [PreserveSig] + int NoMoreSegments(); + + [PreserveSig] + int GetSegmentOffset( + out double pdOffset + ); + } +} diff --git a/Samples/Misc/GMFPreview/GMFPreview/GMFPreview-2005.csproj b/Samples/Misc/GMFPreview/GMFPreview/GMFPreview-2005.csproj new file mode 100644 index 0000000..ae707ea --- /dev/null +++ b/Samples/Misc/GMFPreview/GMFPreview/GMFPreview-2005.csproj @@ -0,0 +1,98 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {0E756677-5CB9-488B-B54A-55B32BF087D6} + WinExe + Properties + GMFPreview + GMFPreview + LocalIntranet + false + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\..\..\..\..\..\..\SourceForge\directshowlib\lib\DirectShowLib-2005.dll + + + + + + + + + Form + + + MainForm.cs + + + Form + + + DeviceForm.cs + + + + + + + Designer + MainForm.cs + + + Designer + DeviceForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + \ No newline at end of file diff --git a/Samples/Misc/GMFPreview/GMFPreview/GMFPreview.csproj b/Samples/Misc/GMFPreview/GMFPreview/GMFPreview.csproj new file mode 100644 index 0000000..e8def15 --- /dev/null +++ b/Samples/Misc/GMFPreview/GMFPreview/GMFPreview.csproj @@ -0,0 +1,108 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {0E756677-5CB9-488B-B54A-55B32BF087D6} + WinExe + Properties + GMFPreview + GMFPreview + LocalIntranet + false + + + 3.5 + + + v2.0 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + Form + + + MainForm.cs + + + Form + + + DeviceForm.cs + + + + + + + Designer + MainForm.cs + + + Designer + DeviceForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + \ No newline at end of file diff --git a/Samples/Misc/GMFPreview/GMFPreview/MainForm.Designer.cs b/Samples/Misc/GMFPreview/GMFPreview/MainForm.Designer.cs new file mode 100644 index 0000000..4eb35ba --- /dev/null +++ b/Samples/Misc/GMFPreview/GMFPreview/MainForm.Designer.cs @@ -0,0 +1,131 @@ +namespace GMFPreview +{ + partial class MainForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.gbPreview = new System.Windows.Forms.GroupBox(); + this.bnDevice = new System.Windows.Forms.Button(); + this.bnFolder = new System.Windows.Forms.Button(); + this.bnCapture = new System.Windows.Forms.Button(); + this.bnStopCapture = new System.Windows.Forms.Button(); + this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog(); + this.SuspendLayout(); + // + // gbPreview + // + this.gbPreview.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.gbPreview.Location = new System.Drawing.Point(11, 11); + this.gbPreview.Name = "gbPreview"; + this.gbPreview.Size = new System.Drawing.Size(347, 302); + this.gbPreview.TabIndex = 0; + this.gbPreview.TabStop = false; + this.gbPreview.Text = "Preview Window"; + // + // bnDevice + // + this.bnDevice.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.bnDevice.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.bnDevice.Location = new System.Drawing.Point(411, 11); + this.bnDevice.Name = "bnDevice"; + this.bnDevice.Size = new System.Drawing.Size(75, 23); + this.bnDevice.TabIndex = 1; + this.bnDevice.Text = "Device..."; + this.bnDevice.UseVisualStyleBackColor = true; + this.bnDevice.Click += new System.EventHandler(this.bnDevice_Click); + // + // bnFolder + // + this.bnFolder.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.bnFolder.Location = new System.Drawing.Point(411, 42); + this.bnFolder.Name = "bnFolder"; + this.bnFolder.Size = new System.Drawing.Size(75, 23); + this.bnFolder.TabIndex = 2; + this.bnFolder.Text = "Folder..."; + this.bnFolder.UseVisualStyleBackColor = true; + this.bnFolder.Click += new System.EventHandler(this.bnFolder_Click); + // + // bnCapture + // + this.bnCapture.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.bnCapture.Location = new System.Drawing.Point(411, 106); + this.bnCapture.Name = "bnCapture"; + this.bnCapture.Size = new System.Drawing.Size(75, 23); + this.bnCapture.TabIndex = 3; + this.bnCapture.Text = "Capture"; + this.bnCapture.UseVisualStyleBackColor = true; + this.bnCapture.Click += new System.EventHandler(this.bnCapture_Click); + // + // bnStopCapture + // + this.bnStopCapture.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.bnStopCapture.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.bnStopCapture.Location = new System.Drawing.Point(411, 137); + this.bnStopCapture.Margin = new System.Windows.Forms.Padding(0); + this.bnStopCapture.Name = "bnStopCapture"; + this.bnStopCapture.Size = new System.Drawing.Size(75, 23); + this.bnStopCapture.TabIndex = 4; + this.bnStopCapture.Text = "Stop Capture"; + this.bnStopCapture.UseVisualStyleBackColor = true; + this.bnStopCapture.Click += new System.EventHandler(this.bnStopCapture_Click); + // + // folderBrowserDialog1 + // + this.folderBrowserDialog1.Description = "Specify output directory for capture files"; + this.folderBrowserDialog1.SelectedPath = "c:\\"; + // + // Form1 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(497, 332); + this.Controls.Add(this.bnStopCapture); + this.Controls.Add(this.bnCapture); + this.Controls.Add(this.bnFolder); + this.Controls.Add(this.bnDevice); + this.Controls.Add(this.gbPreview); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.Name = "Form1"; + this.Text = "GMFPreview"; + this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.Form1_FormClosed); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox gbPreview; + private System.Windows.Forms.Button bnDevice; + private System.Windows.Forms.Button bnFolder; + private System.Windows.Forms.Button bnCapture; + private System.Windows.Forms.Button bnStopCapture; + private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1; + + } +} + diff --git a/Samples/Misc/GMFPreview/GMFPreview/MainForm.cs b/Samples/Misc/GMFPreview/GMFPreview/MainForm.cs new file mode 100644 index 0000000..be2cd0b --- /dev/null +++ b/Samples/Misc/GMFPreview/GMFPreview/MainForm.cs @@ -0,0 +1,160 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.IO; +using System.Text; +using System.Windows.Forms; +using System.Runtime.InteropServices.ComTypes; + +using DirectShowLib; + +namespace GMFPreview +{ + public partial class MainForm : Form + { + #region Member variables + + // The video device to use + private DsDevice m_dev = null; + + // The auto incremented number to tack on the end of the file to make a unique filename + private int m_indexFile = -1; + + // An instance of the PreviewController class (where all the real work is done) + private PreviewController m_Previewer = new PreviewController(); + + #endregion + + public MainForm() + { + InitializeComponent(); + } + + private void bnDevice_Click(object sender, EventArgs e) + { + DeviceForm dlg = new DeviceForm(); + + // Highlight current device in listbox + dlg.SelectIndex(m_dev); + + // Put up the dialog to select a device + DialogResult x = dlg.ShowDialog(this); + + // If a device is selected + if (x == DialogResult.OK) + { + // Store the device + m_dev = ((VDevice)dlg.lbDevices.SelectedItem).Device; + + // Create the capture graphs from the selected device + try + { + m_Previewer.SelectDevice(m_dev, gbPreview.Handle); + } + catch(Exception ex) + { + MessageBox.Show(ex.Message, "GMFPreview capture", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + + private void bnFolder_Click(object sender, EventArgs e) + { + // Show the folder browser + folderBrowserDialog1.ShowDialog(this); + } + + private void bnCapture_Click(object sender, EventArgs e) + { + // If we aren't already capturing + if (!m_Previewer.Capturing) + { + // Make sure a device is selected + if (!m_Previewer.Selected) + { + bnDevice_Click(sender, e); + } + + // If we have a device + if (m_Previewer.Selected) + { + // Generate a name and send it to the m_Previewer + MakeNewCaptureFile(); + + // Start the capture graph + try + { + m_Previewer.StartCapture(); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "GMFPreview capture", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + } + + private void bnStopCapture_Click(object sender, EventArgs e) + { + // Only stop if we are started + if (m_Previewer.Capturing) + { + try + { + m_Previewer.StopCapture(); + string s = string.Format("Captured to {0}", m_Previewer.FileName); + MessageBox.Show(s, "GMFPreview capture"); + } + catch(Exception ex) + { + MessageBox.Show(ex.Message, "GMFPreview capture", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + + private void MakeNewCaptureFile() + { + string sFileName; + + // Find an unused file name + do + { + sFileName = string.Format(@"{0}\Cap{1}.avi", folderBrowserDialog1.SelectedPath, ++m_indexFile); + } while (File.Exists(sFileName)); + + try + { + // Tell the previewer what name to use + m_Previewer.SetNextFilename(sFileName); + } + catch(Exception ex) + { + MessageBox.Show(ex.Message, "GMFPreview capture", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void Form1_FormClosed(object sender, FormClosedEventArgs e) + { + // Release pointers + if (m_dev != null) + { + m_dev.Dispose(); + m_dev = null; + } + + if (m_Previewer != null) + { + m_Previewer.Dispose(); + m_Previewer = null; + } + } + } +} \ No newline at end of file diff --git a/Samples/Misc/GMFPreview/GMFPreview/MainForm.resx b/Samples/Misc/GMFPreview/GMFPreview/MainForm.resx new file mode 100644 index 0000000..b260022 --- /dev/null +++ b/Samples/Misc/GMFPreview/GMFPreview/MainForm.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/Samples/Misc/GMFPreview/GMFPreview/PreviewController.cs b/Samples/Misc/GMFPreview/GMFPreview/PreviewController.cs new file mode 100644 index 0000000..f3861a3 --- /dev/null +++ b/Samples/Misc/GMFPreview/GMFPreview/PreviewController.cs @@ -0,0 +1,418 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Runtime.InteropServices; + +using DirectShowLib; +using DirectShowLib.GDCL; + +namespace GMFPreview +{ + class PreviewController : IDisposable + { + #region Member variables + + const long NEVER = long.MaxValue; + + // The file name to capture to + private string m_strFile; + + // Running object table classes to show the graphs in GraphEdt + private DsROTEntry m_rot1; + private DsROTEntry m_rot2; + + // Has a device been selected yet? + private bool m_DeviceSelected = false; + + // Are we actively capturing? + private bool m_Capturing = false; + + // The graph that contains the source device + private IGraphBuilder m_pSourceGraph; + + // The graph that contains the file writer + private IGraphBuilder m_pCaptureGraph; + + // The bridge controller that stands between the two graphs + private IGMFBridgeController m_pBridge; + + // The capture pin of the capture device (or the smarttee if + // the capture device has no preview pin) + private IPin m_pCapOutput; + + // The source side of the bridge + private IBaseFilter m_pSourceGraphSinkFilter; + + // The other side of the bridge + private IBaseFilter m_pCaptureGraphSourceFilter; + + #endregion + + // Property to return the current filename + public string + FileName + { + get + { + return m_strFile; + } + } + + // Property to report whether we are capturing + public bool + Capturing + { + get + { + return m_Capturing; + } + } + + // Property to report whether we have a device + public bool + Selected + { + get + { + return m_DeviceSelected; + } + } + + // Specify a device, and a window to draw the preview in + public void + SelectDevice(DsDevice dev, IntPtr hwnd) + { + int hr; + IBaseFilter pfDevice = null; + ICaptureGraphBuilder2 pBuilder = null; + + // release any leftovers + ReleaseSelectMembers(); + + try + { + // create source graph and add sink filter + m_pSourceGraph = (IGraphBuilder)new FilterGraph(); + m_rot1 = new DsROTEntry(m_pSourceGraph); + + m_pBridge = (IGMFBridgeController)new GMFBridgeController(); + + // init to video-only, in discard mode (ie when source graph + // is running but not connected, buffers are discarded at the bridge) + hr = m_pBridge.AddStream(true, eFormatType.MuxInputs, true); + DsError.ThrowExceptionForHR(hr); + + // Add the requested device + hr = ((IFilterGraph2)m_pSourceGraph).AddSourceFilterForMoniker(dev.Mon, null, dev.Name, out pfDevice); + DsError.ThrowExceptionForHR(hr); + + // Add the sink filter to the source graph + hr = m_pBridge.InsertSinkFilter(m_pSourceGraph, out m_pSourceGraphSinkFilter); + DsError.ThrowExceptionForHR(hr); + + // use capture graph builder to render preview + pBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); + + // Init the CaptureGraphBuilder2 + hr = pBuilder.SetFiltergraph(m_pSourceGraph); + DsError.ThrowExceptionForHR(hr); + + // Connect the filters together to allow preview + hr = pBuilder.RenderStream(PinCategory.Preview, MediaType.Video, pfDevice, null, null); + DsError.ThrowExceptionForHR(hr); + + // connect capture output to the pseudo-sink filter, + // where it will be discarded until required + hr = pBuilder.RenderStream(PinCategory.Capture, MediaType.Video, pfDevice, null, m_pSourceGraphSinkFilter); + DsError.ThrowExceptionForHR(hr); + + // turn off capture stream if possible except when capturing + hr = pBuilder.FindPin(pfDevice, PinDirection.Output, PinCategory.Capture, MediaType.Video, false, 0, out m_pCapOutput); + if (hr >= 0) + { + IAMStreamControl pSC = (IAMStreamControl)m_pCapOutput; + pSC.StartAt(NEVER, 0); // Ignore any error + } + + ConfigureVideo(hwnd); + + IMediaControl pMC = (IMediaControl)m_pSourceGraph; + + hr = pMC.Run(); + DsError.ThrowExceptionForHR(hr); + + // If we made it here, the device is selected + m_DeviceSelected = true; + } + catch + { + ReleaseSelectMembers(); + throw; + } + finally + { + if (pBuilder != null) + { + Marshal.ReleaseComObject(pBuilder); + } + + if (pfDevice != null) + { + Marshal.ReleaseComObject(pfDevice); + } + } + } + + // Release all the members of the source graph + private void ReleaseSelectMembers() + { + if (m_rot1 != null) + { + m_rot1.Dispose(); + m_rot1 = null; + } + + if (m_pBridge != null) + { + Marshal.ReleaseComObject(m_pBridge); + m_pBridge = null; + } + + if (m_pSourceGraphSinkFilter != null) + { + Marshal.ReleaseComObject(m_pSourceGraphSinkFilter); + m_pSourceGraphSinkFilter = null; + } + + if (m_pSourceGraphSinkFilter != null) + { + Marshal.ReleaseComObject(m_pSourceGraphSinkFilter); + m_pSourceGraphSinkFilter = null; + } + + if (m_pCapOutput != null) + { + Marshal.ReleaseComObject(m_pCapOutput); + m_pCapOutput = null; + } + + if (m_pSourceGraph != null) + { + Marshal.ReleaseComObject(m_pSourceGraph); + m_pSourceGraph = null; + } + } + + // Given a file name, build the output graph + public void + SetNextFilename(string pFile) + { + int hr; + + ICaptureGraphBuilder2 pBuilder = null; + IBaseFilter pfMux = null; + IFileSinkFilter pSink = null; + + if (pFile != null) + { + if (m_DeviceSelected) + { + ReleaseFilenameMembers(); + + m_pCaptureGraph = (IGraphBuilder)new FilterGraph(); + try + { + m_rot2 = new DsROTEntry(m_pCaptureGraph); + + // Use the bridge to add the sourcefilter to the graph + hr = m_pBridge.InsertSourceFilter(m_pSourceGraphSinkFilter, m_pCaptureGraph, out m_pCaptureGraphSourceFilter); + DsError.ThrowExceptionForHR(hr); + + // use capture graph builder to create mux/writer stage + pBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); + + hr = pBuilder.SetFiltergraph(m_pCaptureGraph); + DsError.ThrowExceptionForHR(hr); + + // create the mux/writer + hr = pBuilder.SetOutputFileName(MediaSubType.Avi, pFile, out pfMux, out pSink); + DsError.ThrowExceptionForHR(hr); + + // render source output to mux + hr = pBuilder.RenderStream(null, null, m_pCaptureGraphSourceFilter, null, pfMux); + DsError.ThrowExceptionForHR(hr); + + // Store the file name for later use + m_strFile = pFile; + } + catch + { + ReleaseFilenameMembers(); + } + finally + { + if (pBuilder != null) + { + Marshal.ReleaseComObject(pBuilder); + } + + if (pfMux != null) + { + Marshal.ReleaseComObject(pfMux); + } + + if (pSink != null) + { + Marshal.ReleaseComObject(pSink); + } + } + } + else + { + throw new Exception("Device not selected"); + } + } + else + { + throw new Exception("Invalid parameter"); + } + } + + // Release all the members of the capture graph + private void ReleaseFilenameMembers() + { + if (m_rot2 != null) + { + m_rot2.Dispose(); + m_rot2 = null; + } + + if (m_pCaptureGraphSourceFilter != null) + { + Marshal.ReleaseComObject(m_pCaptureGraphSourceFilter); + m_pCaptureGraphSourceFilter = null; + } + if (m_pCaptureGraph != null) + { + Marshal.ReleaseComObject(m_pCaptureGraph); + m_pCaptureGraph = null; + } + } + + // Start capturing to the file specified to SetNextFilename + public void + StartCapture() + { + int hr; + + if (m_DeviceSelected) + { + if (m_strFile != null) + { + // re-enable capture stream + IAMStreamControl pSC = (IAMStreamControl)m_pCapOutput; + + // immediately! + pSC.StartAt(null, 0); // Ignore any error + + // start capture graph + IMediaControl pMC = (IMediaControl)m_pCaptureGraph; + hr = pMC.Run(); + DsError.ThrowExceptionForHR(hr); + + hr = m_pBridge.BridgeGraphs(m_pSourceGraphSinkFilter, m_pCaptureGraphSourceFilter); + DsError.ThrowExceptionForHR(hr); + + // If we make it here, we are capturing + m_Capturing = true; + } + else + { + throw new Exception("File name not specified"); + } + } + else + { + throw new Exception("Device not selected"); + } + } + + // Stop the file capture (leave the preview running) + public void + StopCapture() + { + int hr; + + // Are we capturing? + if (m_Capturing) + { + // disconnect segments + hr = m_pBridge.BridgeGraphs(null, null); + DsError.ThrowExceptionForHR(hr); + + // stop capture graph + IMediaControl pMC = (IMediaControl)m_pCaptureGraph; + + hr = pMC.Stop(); + DsError.ThrowExceptionForHR(hr); + + // disable capture stream (to save resources) + IAMStreamControl pSC = (IAMStreamControl)m_pCapOutput; + + pSC.StartAt(NEVER, 0); // Ignore any error + + m_Capturing = false; + } + } + + // Configure the video to fit in the provided window (if any) + private void ConfigureVideo(IntPtr hwnd) + { + int hr; + + if (hwnd != IntPtr.Zero) + { + int cx, cy; + IBasicVideo pBV = (IBasicVideo)m_pSourceGraph; + + hr = pBV.GetVideoSize(out cx, out cy); + DsError.ThrowExceptionForHR(hr); + + // reparent playback window + IVideoWindow pVW = (IVideoWindow)m_pSourceGraph; + + hr = pVW.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipSiblings | WindowStyle.ClipChildren); + DsError.ThrowExceptionForHR(hr); + + hr = pVW.put_Owner(hwnd); + DsError.ThrowExceptionForHR(hr); + + hr = pVW.SetWindowPosition(1, 13, cx-7, cy); + DsError.ThrowExceptionForHR(hr); + } + } + + #region IDisposable Members + + public void Dispose() + { + StopCapture(); + + IMediaControl pMC = m_pSourceGraph as IMediaControl; + if (pMC != null) + { + pMC.Stop(); // Ignore any error + } + + ReleaseFilenameMembers(); + ReleaseSelectMembers(); + } + + #endregion + } +} diff --git a/Samples/Misc/GMFPreview/GMFPreview/Program.cs b/Samples/Misc/GMFPreview/GMFPreview/Program.cs new file mode 100644 index 0000000..9bbcc9e --- /dev/null +++ b/Samples/Misc/GMFPreview/GMFPreview/Program.cs @@ -0,0 +1,27 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Windows.Forms; + +namespace GMFPreview +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new MainForm()); + } + } +} \ No newline at end of file diff --git a/Samples/Misc/GMFPreview/GMFPreview/Properties/AssemblyInfo.cs b/Samples/Misc/GMFPreview/GMFPreview/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..193e994 --- /dev/null +++ b/Samples/Misc/GMFPreview/GMFPreview/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("GMFPreview")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Personal")] +[assembly: AssemblyProduct("GMFPreview")] +[assembly: AssemblyCopyright("Copyright © Personal 2006")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("d9a63105-4f68-4340-9f1a-4ce636315dd8")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Samples/Misc/GMFPreview/GMFPreview/Properties/Resources.Designer.cs b/Samples/Misc/GMFPreview/GMFPreview/Properties/Resources.Designer.cs new file mode 100644 index 0000000..5d2b96c --- /dev/null +++ b/Samples/Misc/GMFPreview/GMFPreview/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace GMFPreview.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GMFPreview.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Samples/Misc/GMFPreview/GMFPreview/Properties/Resources.resx b/Samples/Misc/GMFPreview/GMFPreview/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/Samples/Misc/GMFPreview/GMFPreview/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Samples/Misc/GMFPreview/GMFPreview/Properties/Settings.Designer.cs b/Samples/Misc/GMFPreview/GMFPreview/Properties/Settings.Designer.cs new file mode 100644 index 0000000..697ac23 --- /dev/null +++ b/Samples/Misc/GMFPreview/GMFPreview/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace GMFPreview.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Samples/Misc/GMFPreview/GMFPreview/Properties/Settings.settings b/Samples/Misc/GMFPreview/GMFPreview/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Samples/Misc/GMFPreview/GMFPreview/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Samples/Misc/GMFPreview/GMFPreview/Properties/app.manifest b/Samples/Misc/GMFPreview/GMFPreview/Properties/app.manifest new file mode 100644 index 0000000..1fa8e65 --- /dev/null +++ b/Samples/Misc/GMFPreview/GMFPreview/Properties/app.manifest @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Misc/GMFPreview/GMFPreview/readme.txt b/Samples/Misc/GMFPreview/GMFPreview/readme.txt new file mode 100644 index 0000000..c4718a8 --- /dev/null +++ b/Samples/Misc/GMFPreview/GMFPreview/readme.txt @@ -0,0 +1,41 @@ +/************************************************************************ +GMFPreview - Showing how to use the GMFBridge filter in c# + +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + +**************************************************************************/ + +This sample started life as the c++ GMFPreview sample from http://www.gdcl.co.uk/. +I have converted it to c# to show how to use the GMFBridge in c#. + +You MUST install the GMFBridge filter for this code to work. + +Normally if you have a graph that is capturing to disk and showing a preview window +at the same time, you have to stop BOTH parts of the graph to end the file capture. +This causes flicker in the preview window that some people find unacceptable. + +This sample creates a graph like this: + +Video Capture Device -> Smart Tee --> Renderer + \ + \-> GMF Bridge + +And a second graph like this: + +GMF Bridge -> AVI Mux -> File writer + +The second graph can be stopped and started at will without affecting the rendering in +the first graph. + +The key to using the bridge (other than installing it) is in GMFBridge.cs. You should +include a copy of that file in your project if you are going to be using the bridge. + +If you have questions about how to use the bridge, you should direct them to Geraint +Davies, either at his web site, or at +http://msdn.microsoft.com/newsgroups/default.aspx?dg=microsoft.public.win32.programmer.directx.video&lang=en&cr=US + +If you have questions specific to using the library in c#, then you should ask +at http://sourceforge.net/forum/forum.php?forum_id=460697. \ No newline at end of file diff --git a/Samples/Misc/GSSF/GSSF-2005.sln b/Samples/Misc/GSSF/GSSF-2005.sln new file mode 100644 index 0000000..a059696 --- /dev/null +++ b/Samples/Misc/GSSF/GSSF-2005.sln @@ -0,0 +1,25 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GenericSampleSourceFilter", "filter\PushSource-2005.vcproj", "{70B24BBF-E59F-4F91-A74B-01288E1DECB3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Render-2005", "render\Render-2005.csproj", "{6E8BB66C-D141-4333-8311-3CF33FACEC1B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Debug|Win32.ActiveCfg = Debug|Win32 + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Debug|Win32.Build.0 = Debug|Win32 + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Release|Win32.ActiveCfg = Release|Win32 + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Release|Win32.Build.0 = Release|Win32 + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Debug|Win32.ActiveCfg = Debug|Any CPU + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Debug|Win32.Build.0 = Debug|Any CPU + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Release|Win32.ActiveCfg = Release|Any CPU + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Release|Win32.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Misc/GSSF/GSSF-2008.sln b/Samples/Misc/GSSF/GSSF-2008.sln new file mode 100644 index 0000000..66e6cd6 --- /dev/null +++ b/Samples/Misc/GSSF/GSSF-2008.sln @@ -0,0 +1,25 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GenericSampleSourceFilter-2005", "filter\PushSource-2005.vcxproj", "{70B24BBF-E59F-4F91-A74B-01288E1DECB3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Render-2008", "render\Render-2008.csproj", "{6E8BB66C-D141-4333-8311-3CF33FACEC1B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Debug|Win32.ActiveCfg = Debug|Win32 + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Debug|Win32.Build.0 = Debug|Win32 + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Release|Win32.ActiveCfg = Release|Win32 + {70B24BBF-E59F-4F91-A74B-01288E1DECB3}.Release|Win32.Build.0 = Release|Win32 + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Debug|Win32.ActiveCfg = Debug|Any CPU + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Debug|Win32.Build.0 = Debug|Any CPU + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Release|Win32.ActiveCfg = Release|Any CPU + {6E8BB66C-D141-4333-8311-3CF33FACEC1B}.Release|Win32.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Misc/GSSF/GSSF.ax b/Samples/Misc/GSSF/GSSF.ax new file mode 100644 index 0000000000000000000000000000000000000000..eca3491310a263a4fd9f8c00a715a5a4899cb633 GIT binary patch literal 81920 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ⅅ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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Samples/Misc/GSSF/filter/PushSource-2005.vcxproj b/Samples/Misc/GSSF/filter/PushSource-2005.vcxproj new file mode 100644 index 0000000..df3ddba --- /dev/null +++ b/Samples/Misc/GSSF/filter/PushSource-2005.vcxproj @@ -0,0 +1,179 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + GenericSampleSourceFilter + {70B24BBF-E59F-4F91-A74B-01288E1DECB3} + + + + DynamicLibrary + v110 + false + Unicode + + + DynamicLibrary + v110 + false + Unicode + + + + + + + + + + + + + + + <_ProjectFileVersion>11.0.50727.1 + + + .\Debug\ + .\Debug\ + false + + + .\Release\ + .\Release\ + false + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/PushSource.tlb + + + + Disabled + p:\Samples\Multimedia\DirectShow\BaseClasses;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;PUSHSOURCE_EXPORTS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + false + + .\Debug/PushSource.pch + .\Debug/ + .\Debug/ + .\Debug/ + Level4 + true + ProgramDatabase + StdCall + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + /ignore:4089 /ignore:4078 %(AdditionalOptions) + strmbasd.lib;msvcrtd.lib;winmm.lib;ole32.lib;user32.lib;Advapi32.lib;Uuid.Lib;oleaut32.lib;%(AdditionalDependencies) + Debug/GSSF.ax + true + P:\Samples\Multimedia\DirectShow\BaseClasses\debug;%(AdditionalLibraryDirectories) + true + .\PushSource.def + true + .\Debug/PushSource.pdb + .\Debug/PushSource.lib + MachineX86 + + + regsvr32 /s "$(TargetPath)" + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/PushSource.tlb + + + + Full + OnlyExplicitInline + C:\Program Files\Microsoft SDKs\Windows\v1.0\samples\Multimedia\DirectShow\BaseClasses;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;PUSHSOURCE_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + false + + .\Release/PushSource.pch + .\Release/ + .\Release/ + .\Release/ + Level4 + true + StdCall + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + /ignore:4089 /ignore:4078 /ignore:4078 %(AdditionalOptions) + strmbase.lib;msvcrt.lib;winmm.lib;ole32.lib;user32.lib;Advapi32.lib;Uuid.Lib;oleaut32.lib;%(AdditionalDependencies) + Release/GSSF.ax + true + C:\Program Files\Microsoft SDKs\Windows\v1.0\samples\Multimedia\DirectShow\BaseClasses\Release;%(AdditionalLibraryDirectories) + true + .\PushSource.def + .\Release/PushSource.pdb + false + true + .\Release/PushSource.lib + MachineX86 + + + regsvr32 /s "$(TargetPath)" + + + + + + + + Disabled + WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;PUSHSOURCE_EXPORTS + EnableFastChecks + MaxSpeed + WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;PUSHSOURCE_EXPORTS + + + Disabled + WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;PUSHSOURCE_EXPORTS + EnableFastChecks + MaxSpeed + WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;PUSHSOURCE_EXPORTS + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Misc/GSSF/filter/PushSource-2005.vcxproj.filters b/Samples/Misc/GSSF/filter/PushSource-2005.vcxproj.filters new file mode 100644 index 0000000..790a062 --- /dev/null +++ b/Samples/Misc/GSSF/filter/PushSource-2005.vcxproj.filters @@ -0,0 +1,34 @@ + + + + + {5da6cb94-08f3-4345-b3f8-6d458f8b3324} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {65c0b63c-a670-4450-8b18-7f43dc779427} + h;hpp;hxx;hm;inl + + + + + Source Files + + + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/Samples/Misc/GSSF/filter/PushSource.def b/Samples/Misc/GSSF/filter/PushSource.def new file mode 100644 index 0000000..65b53c5 --- /dev/null +++ b/Samples/Misc/GSSF/filter/PushSource.def @@ -0,0 +1,13 @@ +; This sample is released as public domain. It is distributed in the hope that +; it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +LIBRARY GSSF.ax + +EXPORTS + DllMain PRIVATE + DllGetClassObject PRIVATE + DllCanUnloadNow PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE + diff --git a/Samples/Misc/GSSF/filter/PushSource.h b/Samples/Misc/GSSF/filter/PushSource.h new file mode 100644 index 0000000..8f569f2 --- /dev/null +++ b/Samples/Misc/GSSF/filter/PushSource.h @@ -0,0 +1,108 @@ +/**************************************************************************** +This sample is released as public domain. It is distributed in the hope that +it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +#pragma once + +// Filter name strings +#define g_wszPushBitmap L"Generic Sample Source Filter" + + +/********************************************** + * + * Interface Definitions + * + **********************************************/ + +DECLARE_INTERFACE_(IGenericSampleCB, IUnknown) { + STDMETHOD(SampleCallback)(THIS_ + IMediaSample *pSample + ) PURE; +}; + +DECLARE_INTERFACE_(IGenericSampleConfig, IUnknown) { + + STDMETHOD(SetMediaTypeFromBitmap) (THIS_ + BITMAPINFOHEADER *bmi, + LONGLONG lFPS + ) PURE; + + STDMETHOD(SetMediaType) (THIS_ + AM_MEDIA_TYPE *amt + ) PURE; + + STDMETHOD(SetMediaTypeEx) (THIS_ + AM_MEDIA_TYPE *amt, + long lBufferSize + ) PURE; + + STDMETHOD(SetBitmapCB) (THIS_ + IGenericSampleCB *pfn + ) PURE; +}; + +/********************************************** + * + * Class declarations + * + **********************************************/ + +class CPushPinBitmap : public CSourceStream, + public IGenericSampleConfig +{ +protected: + + CMediaType m_amt; + long m_lBufferSize; + IGenericSampleCB *m_Callback; + +public: + + CPushPinBitmap(HRESULT *phr, CSource *pFilter); + ~CPushPinBitmap(); + + // Override the version that offers exactly one media type + HRESULT GetMediaType(CMediaType *pMediaType); + HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pRequest); + HRESULT FillBuffer(IMediaSample *pSample); + + // Quality control + // Not implemented because we aren't going in real time. + // If the file-writing filter slows the graph down, we just do nothing, which means + // wait until we're unblocked. No frames are ever dropped. + STDMETHODIMP Notify(IBaseFilter *pSelf, Quality q) + { + return E_FAIL; + } + + // ---------------------------------------------------------------------- + // override this to reveal our property interface + STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv); + DECLARE_IUNKNOWN; + + STDMETHODIMP SetMediaTypeFromBitmap(BITMAPINFOHEADER *bmi, LONGLONG lFPS); + STDMETHODIMP SetMediaType(AM_MEDIA_TYPE *amt); + STDMETHODIMP SetMediaTypeEx(AM_MEDIA_TYPE *amt, long lBufferSize); + STDMETHODIMP SetBitmapCB(IGenericSampleCB *pfn); + +private: + HRESULT CreateMediaTypeFromBMI(BITMAPINFOHEADER *bmi, LONGLONG lFPS); +}; + + +class CPushSourceBitmap : public CSource +{ + +private: + // Constructor is private because you have to use CreateInstance + CPushSourceBitmap(IUnknown *pUnk, HRESULT *phr); + ~CPushSourceBitmap(); + + CPushPinBitmap *m_pPin; + +public: + static CUnknown * WINAPI CreateInstance(IUnknown *pUnk, HRESULT *phr); +}; + diff --git a/Samples/Misc/GSSF/filter/PushSource.rc b/Samples/Misc/GSSF/filter/PushSource.rc new file mode 100644 index 0000000..d77879a --- /dev/null +++ b/Samples/Misc/GSSF/filter/PushSource.rc @@ -0,0 +1,22 @@ +//==========================================================================; +// +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY +// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR +// PURPOSE. +// +// Copyright (c) 1992-2002 Microsoft Corporation. All Rights Reserved. +// +//--------------------------------------------------------------------------; + +#include +#include + +// Version information + +#define VERSION_RES_BIN_NAME "PushSource.ax\0" +#define VERSION_RES_BIN_DESCRIPTION "In-Memory Source Filter (Sample)\0" +#define AMOVIE_SELF_REGISTER + +#include + diff --git a/Samples/Misc/GSSF/filter/PushSourceBitmap.cpp b/Samples/Misc/GSSF/filter/PushSourceBitmap.cpp new file mode 100644 index 0000000..8549ae9 --- /dev/null +++ b/Samples/Misc/GSSF/filter/PushSourceBitmap.cpp @@ -0,0 +1,363 @@ +/**************************************************************************** +This sample is released as public domain. It is distributed in the hope that +it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +// This sample was born as the PushSourceBitmap sample from the DXSDK. However, +// little remains of that original code except some of the class/method names. + +// See the readme.txt file for a discussion of how to use this filter + +#include + +#include "PushSource.h" +#include "PushGuids.h" + +/********************************************** + * + * CPushPinBitmap Class + * + * + **********************************************/ + +CPushPinBitmap::CPushPinBitmap(HRESULT *phr, CSource *pFilter) + : CSourceStream(NAME("Generic Sample Pin"), phr, pFilter, L"Out"), + m_Callback(NULL), + m_lBufferSize(0) +{ +} + +CPushPinBitmap::~CPushPinBitmap() +{ + if (m_Callback != NULL) + { + m_Callback->Release(); + } +} + + +// GetMediaType: This method tells the downstream pin what types we support. + +// Here is how CSourceStream deals with media types: +// +// If you support exactly one type, override GetMediaType(CMediaType*). It will then be +// called when (a) our filter proposes a media type, (b) the other filter proposes a +// type and we have to check that type. +// +// If you support > 1 type, override GetMediaType(int,CMediaType*) AND CheckMediaType. +// +// In this case we support only one type. + +HRESULT CPushPinBitmap::GetMediaType(CMediaType *pMediaType) +{ + HRESULT hr = S_OK; + + CheckPointer(pMediaType, E_POINTER); + + CAutoLock cAutoLock(m_pFilter->pStateLock()); + + // If the bitmapinfo hasn't been loaded, just fail here. + if (m_amt.IsValid()) + { + hr = pMediaType->Set(m_amt); + } + else + { + hr = E_FAIL; + } + + return hr; +} + +// DecideBufferSize: Calculate the size and number of buffers + +HRESULT CPushPinBitmap::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pRequest) +{ + HRESULT hr; + + CheckPointer(pAlloc, E_POINTER); + CheckPointer(pRequest, E_POINTER); + + CAutoLock cAutoLock(m_pFilter->pStateLock()); + + // If the bitmapinfo hasn't been loaded, just fail here. + if (!m_amt.IsValid()) + { + return E_FAIL; + } + + // Ensure a minimum number of buffers + if (pRequest->cBuffers == 0) + { + pRequest->cBuffers = 2; + } + + pRequest->cbBuffer = m_lBufferSize; + + ALLOCATOR_PROPERTIES Actual; + hr = pAlloc->SetProperties(pRequest, &Actual); + if (SUCCEEDED(hr)) + { + // Is this allocator unsuitable? + if (Actual.cbBuffer < pRequest->cbBuffer) + { + hr = E_FAIL; + } + } + + return hr; +} + + +// FillBuffer: Called by the BaseClasses once for every sample in the stream. + +// It calls the callback to populate the sample + +HRESULT CPushPinBitmap::FillBuffer(IMediaSample *pSample) +{ + HRESULT hr = S_OK; + + CheckPointer(pSample, E_POINTER); + CheckPointer(m_Callback, E_POINTER); + + CAutoLock cAutoLock(m_pFilter->pStateLock()); + + hr = m_Callback->SampleCallback(pSample); + + return hr; +} + + +// Standard COM stuff done with a baseclasses flavor + +STDMETHODIMP CPushPinBitmap::NonDelegatingQueryInterface(REFIID riid, void **ppv) +{ + if (riid == IID_IGenericSampleConfig) + { + return GetInterface((IGenericSampleConfig *) this, ppv); + } + return CSourceStream::NonDelegatingQueryInterface(riid, ppv); +} + + +/********************************************** + * + * IGenericSampleConfig methods + * + **********************************************/ + +// SetMediaTypeFromBitmap: Populate the media type from a passed in bitmap. + +// Note that we need the FramesPerSecond to build the VIDEOINFOHEADER. This +// is the entry point for IGenericSampleConfig::SetMediaTypeFromBitmap + +STDMETHODIMP CPushPinBitmap::SetMediaTypeFromBitmap(BITMAPINFOHEADER *bmi, LONGLONG lFPS) +{ + HRESULT hr = S_OK; + + CheckPointer(bmi, E_POINTER); + + CAutoLock cAutoLock(m_pFilter->pStateLock()); + + // Only allow one init + if (!m_amt.IsValid()) + { + if (bmi->biSize == sizeof(BITMAPINFOHEADER)) + { + hr = CreateMediaTypeFromBMI(bmi, lFPS); + } + else + { + hr = MAKE_HRESULT(1, FACILITY_WIN32, ERROR_BAD_LENGTH); + } + } + else + { + hr = MAKE_HRESULT(1, FACILITY_WIN32, ERROR_ALREADY_INITIALIZED); + } + + return hr; +} + +// SetMediaType: Populate the media type from a completly constructed media type. + +// Note that since I'm going to need the buffer size, the media type +// must be one I know how to parse. Otherwise use SetMediaTypeEx +// and pass in the size. This is the entry point for IGenericSampleConfig::SetMediaType + +STDMETHODIMP CPushPinBitmap::SetMediaType(AM_MEDIA_TYPE *amt) +{ + HRESULT hr = S_OK; + + CheckPointer(amt, E_POINTER); + + // I don't lock the CS here since I'm just calling SetMediaTypeEx (which does) + + if (IsEqualGUID(amt->formattype, FORMAT_VideoInfo) && (amt->pbFormat != NULL) && (amt->cbFormat == sizeof(VIDEOINFOHEADER))) + { + // Parse out the size + VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER*) amt->pbFormat; + hr = SetMediaTypeEx(amt, pvi->bmiHeader.biSizeImage); + } + else + { + hr = MAKE_HRESULT(1, FACILITY_WIN32, ERROR_INVALID_PARAMETER); + } + + return hr; +} + +// SetMediaTypeEx: Populate the media type from a completely constructed media type. + +// If you aren't using a media type that I know how to get the buffer size from, use this +// method and provide it explicitly. This is the entry point for IGenericSampleConfig::SetMediaTypeEx + +STDMETHODIMP CPushPinBitmap::SetMediaTypeEx(AM_MEDIA_TYPE *amt, long lBufferSize) +{ + HRESULT hr = S_OK; + CAutoLock cAutoLock(m_pFilter->pStateLock()); + + // Only allow one init + if (!m_amt.IsValid()) + { + // Don't allow GUID_NULL for the major type (since that's what I + // use to indicate an unpopulated MediaType). + if (!IsEqualGUID(amt->majortype, GUID_NULL)) + { + hr = m_amt.Set(*amt); + m_lBufferSize = lBufferSize; + } + else + { + hr = MAKE_HRESULT(1, FACILITY_WIN32, ERROR_INVALID_PARAMETER); + } + } + else + { + hr = MAKE_HRESULT(1, FACILITY_WIN32, ERROR_ALREADY_INITIALIZED); + } + + return hr; +} + +// SetBitmapCB: Set the callback. + +// You must call one of the SetMediaType* methods first. Notice +// that there is no check to ensure the CB wasn't already set. While +// I haven't tried it, I suspect you could change this even while +// the graph is running. Why you would want to is a more difficult +// question. + +STDMETHODIMP CPushPinBitmap::SetBitmapCB(IGenericSampleCB *pfn) +{ + HRESULT hr = S_OK; + + CheckPointer(pfn, E_POINTER); + + CAutoLock cAutoLock(m_pFilter->pStateLock()); + + if (m_amt.IsValid()) + { + m_Callback = pfn; + m_Callback->AddRef(); + } + else + { + // The media type must be specified first + hr = E_FAIL; + } + + return hr; +} + +// CreateMediaTypeFromBMI: This private method initializes the pin's mediatype from a BITMAPINFOHEADER + +// Note the we also need the FramesPerSecond to correctly create the VIDEOINFOHEADER struct. + +HRESULT CPushPinBitmap::CreateMediaTypeFromBMI(BITMAPINFOHEADER *bmi, LONGLONG lFPS) +{ + // Allocate enough room for the VIDEOINFOHEADER and the color tables + VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER*)m_amt.AllocFormatBuffer(SIZE_PREHEADER + bmi->biSize); + if (pvi == 0) + { + return(E_OUTOFMEMORY); + } + + ZeroMemory(pvi, m_amt.cbFormat); + pvi->AvgTimePerFrame = lFPS; + + // Copy the header info + memcpy(&(pvi->bmiHeader), bmi, bmi->biSize); + + // Set image size for use in FillBuffer + m_lBufferSize = GetBitmapSize(&pvi->bmiHeader); + + pvi->bmiHeader.biSizeImage = m_lBufferSize; + + // Clear source and target rectangles + SetRectEmpty(&(pvi->rcSource)); // we want the whole image area rendered + SetRectEmpty(&(pvi->rcTarget)); // no particular destination rectangle + + // Use standard values for the types + m_amt.SetType(&MEDIATYPE_Video); + m_amt.SetFormatType(&FORMAT_VideoInfo); + m_amt.SetTemporalCompression(FALSE); + + // Work out the GUID for the subtype from the header info. + const GUID SubTypeGUID = GetBitmapSubtype(&pvi->bmiHeader); + m_amt.SetSubtype(&SubTypeGUID); + m_amt.SetSampleSize(pvi->bmiHeader.biSizeImage); + + return S_OK; +} + +/********************************************** + * + * CPushSourceBitmap Class + * + **********************************************/ + +CPushSourceBitmap::CPushSourceBitmap(IUnknown *pUnk, HRESULT *phr) + : CSource(NAME("PushSourceBitmap"), pUnk, CLSID_GenericSampleSourceFilter) +{ + // The pin magically adds itself to our pin array. + m_pPin = new CPushPinBitmap(phr, this); + + if (phr) + { + if (m_pPin == NULL) + { + *phr = E_OUTOFMEMORY; + } + else + { + *phr = S_OK; + } + } +} + +CPushSourceBitmap::~CPushSourceBitmap() +{ + delete m_pPin; +} + + +CUnknown * WINAPI CPushSourceBitmap::CreateInstance(IUnknown *pUnk, HRESULT *phr) +{ + CPushSourceBitmap *pNewFilter = new CPushSourceBitmap(pUnk, phr ); + + if (phr) + { + if (pNewFilter == NULL) + { + *phr = E_OUTOFMEMORY; + } + else + { + *phr = S_OK; + } + } + + return pNewFilter; +} diff --git a/Samples/Misc/GSSF/filter/setup.cpp b/Samples/Misc/GSSF/filter/setup.cpp new file mode 100644 index 0000000..745f6ef --- /dev/null +++ b/Samples/Misc/GSSF/filter/setup.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +This sample is released as public domain. It is distributed in the hope that +it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +#include +#include + +#include "PushGuids.h" +#include "PushSource.h" + +const AMOVIESETUP_PIN sudOutputPinBitmap = +{ + L"Output", // Obsolete, not used. + FALSE, // Is this pin rendered? + TRUE, // Is it an output pin? + FALSE, // Can the filter create zero instances? + FALSE, // Does the filter create multiple instances? + &CLSID_NULL, // Obsolete. + NULL, // Obsolete. + 1, // Number of media types. + NULL // Pointer to media types. +}; + +// List of class IDs and creator functions for the class factory. This +// provides the link between the OLE entry point in the DLL and an object +// being created. The class factory will call the static CreateInstance. +// We provide a set of filters in this one DLL. + +CFactoryTemplate g_Templates[] = +{ + { + g_wszPushBitmap, // Name + &CLSID_GenericSampleSourceFilter, // CLSID + CPushSourceBitmap::CreateInstance, // Method to create an instance of MyComponent + NULL, // Initialization function + NULL // Set-up information (for filters) + } +}; + +int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]); + + +//////////////////////////////////////////////////////////////////////// +// +// Exported entry points for registration and unregistration +// (in this case they only call through to default implementations). +// +//////////////////////////////////////////////////////////////////////// + +STDAPI DllRegisterServer() +{ + return AMovieDllRegisterServer2( TRUE ); +} + +STDAPI DllUnregisterServer() +{ + return AMovieDllRegisterServer2( FALSE ); +} + +// +// DllEntryPoint +// +extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID); + +BOOL APIENTRY DllMain(HANDLE hModule, + DWORD dwReason, + LPVOID lpReserved) +{ + return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved); +} + diff --git a/Samples/Misc/GSSF/readme.txt b/Samples/Misc/GSSF/readme.txt new file mode 100644 index 0000000..6b091be --- /dev/null +++ b/Samples/Misc/GSSF/readme.txt @@ -0,0 +1,156 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +The Generic Sample Source Filter - A way to implement a source filter in c# + +What it does/Why you might want it: +================================== +There are a number of ways you can modify frames as they go down the graph (see DxLogo or +DmoFlip). However, until now there wasn't a way to GENERATE frames. This filter allows +you to be the source of samples for the graph. And it doesn't require those samples +to be video. + + +Why I wrote this filter: +======================= + +(If you don't care why I wrote this filter, skip down to "How to use this filter") + +The reason I wrote this filter was to overcome one of the remaining restrictions to using c# +to do DirectShow programming. When we released version 1.0 of this library, you could build +and run graphs, but only using existing filters. It wasn't until version 1.2 that we added +support for writing DMOs in c#. DMOs are essentially a light-weight filter. Using the DMO +Wrapper Filter, you could write your own filters and add them to the graph (check out the +DmoFlip and DmoSplit samples). + +However, the DMO Wrapper filter has limitations: + +"It does not support DMOs with zero inputs, multiple inputs, or zero outputs. +(It does support DMOs with one input and multiple outputs.)" + +These are the limitations I'm working to overcome. With that, c# can be used to write the +majority of the filters that you are likely to need: + +1) The easiest part of this to overcome was the part about zero outputs. I'm not quite sure +why this limitation is there. DMOWF doesn't seem to have any problem having an output pin with +nothing connected to it. Given this, you should be able to create an output pin, and just reject +all attempts to connect to it. It ain't pretty, but it should work fine. See the existing DMO +samples for how to deal with what DMOWF does when nothing is connected to the output pin. + +2) Zero inputs was a little tougher. That's what this filter is designed to do. Zero inputs means +that the filter only does outputs, which is essentially the definition of a source filter. This source +filter is given its MediaType by the application. It also calls the application to populate each of the +samples to send down the graph. + +It isn't a perfect solution. Specifically, this filter doesn't support multiple output pins (although +you could have this filter output a single stream which is split downstream by a DMO that you write). It +also doesn't allow you to add support for other interfaces. If you need your source filter to support +IQualityControl, IPinFlowControl or some such, you will need to do some c++ coding. However, my (limited) +DS experience suggests those needs are relatively uncommon. + +3) Multiple inputs - Yeah, this one. Well, I don't have a solution to this one just now. If there is +enough demand, I might revisit this, but I don't expect to see it. + +You might ask why you can't just write filters the same way they do in c++. There are several answers to this, +but the core issue is that c++ uses a large, complicated, inter-related library of routines called the BaseClasses. +That library isn't a COM object, it's a set of c++ class & routines that get linked directly into the c++ application. +Converting this to managed code is a non-trivial effort. While it may be possible, it's a huge effort. Not just in +coding, but in testing. The BaseClasses have been available in source form for many years. Any problems have been +shaken out by generations of c++ coders. Unless and until we see that there is enough demand for this by people who +are willing to commit their own time and effort to make it happen, it's not going to happen. Unless someone else does +it. + +Finally, c# is not necessarily a perfect environment for creating filters. As Alessandro once +pointed out to me over in microsoft.public.win32.programmer.directx.video: + +"CPU-intensive tasks or large scale ones, like video +encoders/decoders and effects, HD stuff or multiple streams +processors, sometimes can barely run on fast machines even +when written in highly optimized native code, so you can not +afford the luxury of managed code." + +And he is correct. c# is many things, some good, some bad. However, it does not generate +the fastest possible code. So if you are writing the next generation MPEG encoder/decoder, perhaps +c# isn't your best bet. It should go without saying (but I'm going to say it anyway), that you should +always use the right tool for the job. If performance is king, it's time to consider c++. + + +How to use this filter: +====================== + +Before you can use the filter for the first time, you must register it with COM. Copy the file to where you want to install +it and run "RegSvr32 GSSF.ax". A pre-built copy of the filter is included. + +This is a filter like any other filter. It has a CLSID (6F7BCF72-D0C2-4449-BE0E-B12F580D056D) and can be loaded like any +other COM object. See BuildGraph.cs for an example of how to create an instance of this class and add it to the graph. However, +don't expect to see anything unusual. You might consider copying PushClasses.cs (or its contents) into your project since +it has the class/interface definitions for this filter. + +After you have added the filter to the graph, you will need to configure it. To start, you must tell it the MediaType it +is going to support (AMMediaType). There are three methods that you can use to do this. You can use any ONE of them: + + int SetMediaTypeFromBitmap(BitmapInfoHeader bmi, long lFPS); + int SetMediaType([MarshalAs(UnmanagedType.LPStruct)] AMMediaType amt); + int SetMediaTypeEx([MarshalAs(UnmanagedType.LPStruct)] AMMediaType amt, int lBufferSize); + +If you are going to be doing video, and you are getting your video from files, consider using SetMediaTypeFromBitmap. Parameter1 +is a BitmapInfoHeader that describes the video images. Parameter 2 is the FramesPerSecond at which you will be providing frames. +The rest of the members of the AMMediaType struct are populated with reasonable values. + +If that is too limited for you (for example if you want finer control over the subtype), consider using SetMediaType. Note +that this form still requires the FormatType to be VideoInfoHeader. + +For maximum flexibility, you can use SetMediaTypeEx (for example if you are doing sound or need to support VideoInfoHeader2). +The second parameter is the buffer size for the samples you will be sending. + +After you have used ONE (and only one) of the methods above to set the media type, you will need to set the callback method. + + int SetBitmapCB(IGenericSampleCB pfn); + +The IGenericSampleCB interface only has 1 method: + + int SampleCallback(IMediaSample pSample); + +Each time the c++ FillBuffer method is called by the BaseClasses, it will turn around and call your callback routine and provide +the IMediaSample that the BaseClasses sent to get populated. The callback routine is solely responsible for populating all +necessary members of that class. + +A few things to know: +==================== + +- You MUST MUST MUST release the IMediaSample before returning from the callback routine. Otherwise the graph will hang after +about 2 samples. + +- ALL SAMPLES SENT DOWN THE FILTERGRAPH MUST HAVE THE SAME ATTRIBUTES! When you provide the AMMediaType, you specify information +about the samples (including width/height/pixeldepth, etc). All samples must meet those definitions (which is why you can only +call the SetMediaType* methods once). When other filters connect to this filter, they make assumptions and allocate memory based +on the information in the AMMediaType. That information must remain constant, or those other filters will misbehave (this isn't +100% true, but if you know the exception, you know the implications). + +- Signaling end of stream: When you have no more samples to send to the graph, return 1 (S_FALSE) from your callback. You can +also return any HRESULT error you like, which will terminate the graph with an error. + +- Building the filter: The source to the filter is included. However, you will need to have the base class libraries. MS ships +the code to the libraries, but does not include the actual LIB files, so you need to build them first. Then update this project +to point to them. A pre-built release version of the filter is included (GSSF.ax). Make sure you run "RegSvr32 GSSF.ax" before +you use it. + +- To uninstall the filter, run "regsvr32 /u gssf.ax". + +- The code in the cpp file is pretty clean. It is based on the PushSource sample from the DXSDK, but there isn't much left of the +original sample code (mostly class and file names). If you are comfortable at all with c++ code, this really isn't so bad to read. +The main file of interest is PushSourceBitmap.cpp which is only ~350 (well-commented) lines. I have changed the CLSID, so there is +no conflict with the original sample. + +- The code that shows how to use the sample (the Renderer project) shows bitmaps. It has two different ways to generate bitmaps. +One reads a collection of jpeg files (not included) in a specific directory. The other way just creates random color bitmaps. +Remember, the Generic Sample Source Filter doesn't HAVE to generate video images. You could do sounds, streams, whatever data +you like. I just used video because it's easy. + +- This filter isn't very useful in GraphEdt. Remember, the MediaType comes from the application. GraphEdt doesn't supply +any way to support this, so the filter won't allow anything to connect to its output pin (although in theory I suppose I could +do some sort of property page). Plus, what would it use for the callback? diff --git a/Samples/Misc/GSSF/render/App.ico b/Samples/Misc/GSSF/render/App.ico new file mode 100644 index 0000000000000000000000000000000000000000..3a5525fd794f7a7c5c8e6187f470ea3af38cd2b6 GIT binary patch literal 1078 zcmeHHJr05}7=1t!Hp3A*8IHkVf+j?-!eHY14Gtcw1Eb*_9>Bq^zETJ@GKj{_2j4$w zo9}xCh!8{T3=X##Skq>ikMjsvB|y%crWBM2iW(4pI}c%z6%lW!=~4v77#3{z!dmB1 z__&l)-{KUYR+|8|;wB^R|9ET$J@(@=#rd^=)qs85?vAy(PSF5CyNkus435LVkZ$rj zNw|JG-P7^hF<(;#o*Vk}5R#e|^13tBbQkeF?djULtvqyxd3<{9 literal 0 HcmV?d00001 diff --git a/Samples/Misc/GSSF/render/AssemblyInfo.cs b/Samples/Misc/GSSF/render/AssemblyInfo.cs new file mode 100644 index 0000000..f9bac93 --- /dev/null +++ b/Samples/Misc/GSSF/render/AssemblyInfo.cs @@ -0,0 +1,65 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/Misc/GSSF/render/BuildGraph.cs b/Samples/Misc/GSSF/render/BuildGraph.cs new file mode 100644 index 0000000..5e8bebb --- /dev/null +++ b/Samples/Misc/GSSF/render/BuildGraph.cs @@ -0,0 +1,1032 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +// This code is just to show a couple of ways you could use the +// GenericSampleSourceFilter. For a more details discussion, check out the +// readme.txt + +// Note that in order to use the MP3 methods, you must download and +/// install Bass.Net (which must be added as a reference) and BASS.DLL +/// from http://www.un4seen.com +//#define USING_BASS_DLL + +using System; +using System.Diagnostics; +using System.Drawing; +using System.Drawing.Imaging; +using System.Runtime.InteropServices; +using System.Threading; +using System.Windows.Forms; +using System.IO; + +using DirectShowLib; +using GenericSampleSourceFilterClasses; + +#if USING_BASS_DLL +using Un4seen.Bass; +#endif + +namespace DxPlay +{ + /// + /// A class to construct a graph using the GenericSampleSourceFilter. + /// + internal class DxPlay : IDisposable + { + #region Member variables + + // Event called when the graph stops + public event EventHandler Completed = null; + + /// + /// The class that retrieves the images + /// + private ImageHandler m_ImageHandler; + + /// + /// graph builder interfaces + /// + private IFilterGraph2 m_FilterGraph; + + /// + /// Another graph builder interface + /// + private IMediaControl m_mediaCtrl; + +#if DEBUG + /// + /// Allow you to "Connect to remote graph" from GraphEdit + /// + DsROTEntry m_DsRot; +#endif + + #endregion + + /// + /// Release everything + /// + public void Dispose() + { + GC.SuppressFinalize(this); + CloseInterfaces(); + } + + /// + /// Alternate cleanup + /// + ~DxPlay() + { + CloseInterfaces(); + } + + /// + /// Play a video into a window using the GenericSampleSourceFilter as the video source + /// + /// Path for the ImageFromFiles class (if that's what we are using) + /// to use to find images + /// Window to play the video in + public DxPlay(string sPath, Control hWin) + { + try + { + // pick one of our image providers + //m_ImageHandler = new ImageFromFiles(sPath, 8); + m_ImageHandler = new ImageFromPixels(20); + //m_ImageHandler = new ImageFromMpg(@"c:\c1.mpg"); + //m_ImageHandler = new ImageFromMP3(@"c:\vss\media\track3.mp3"); + + // Set up the graph + SetupGraph(hWin); + } + catch + { + Dispose(); + throw; + } + } + + + /// + /// Start playing + /// + public void Start() + { + // Create a new thread to process events + Thread t; + t = new Thread(new ThreadStart(EventWait)); + t.Name = "Media Event Thread"; + t.Start(); + + int hr = m_mediaCtrl.Run(); + DsError.ThrowExceptionForHR( hr ); + } + + /// + /// Stop the capture graph. + /// + public void Stop() + { + int hr; + + hr = ((IMediaEventSink)m_FilterGraph).Notify(EventCode.UserAbort, IntPtr.Zero, IntPtr.Zero); + DsError.ThrowExceptionForHR( hr ); + + hr = m_mediaCtrl.Stop(); + DsError.ThrowExceptionForHR( hr ); + } + + + /// + /// Build the filter graph + /// + /// Window to draw into + private void SetupGraph(Control hWin) + { + int hr; + + // Get the graphbuilder object + m_FilterGraph = new FilterGraph() as IFilterGraph2; + + // Get a ICaptureGraphBuilder2 to help build the graph + ICaptureGraphBuilder2 icgb2 = (ICaptureGraphBuilder2)new CaptureGraphBuilder2() ; + + try + { + // Link the ICaptureGraphBuilder2 to the IFilterGraph2 + hr = icgb2.SetFiltergraph(m_FilterGraph); + DsError.ThrowExceptionForHR( hr ); + +#if DEBUG + // Allows you to view the graph with GraphEdit File/Connect + m_DsRot = new DsROTEntry(m_FilterGraph); +#endif + + // Our data source + IBaseFilter ipsb = (IBaseFilter)new GenericSampleSourceFilter(); + + try + { + // Get the pin from the filter so we can configure it + IPin ipin = DsFindPin.ByDirection(ipsb, PinDirection.Output, 0); + + try + { + // Configure the pin using the provided BitmapInfo + ConfigurePusher((IGenericSampleConfig)ipin); + } + finally + { + Marshal.ReleaseComObject(ipin); + } + + // Add the filter to the graph + hr = m_FilterGraph.AddFilter(ipsb, "GenericSampleSourceFilter"); + Marshal.ThrowExceptionForHR( hr ); + + // Connect the filters together, use the default renderer + hr = icgb2.RenderStream(null, null, ipsb, null, null); + // DsError.ThrowExceptionForHR( hr ); // Ignore any error. Blindly assume there is no video + + hr = icgb2.RenderStream(null, MediaType.Audio, ipsb, null, null); + // DsError.ThrowExceptionForHR( hr ); // Ignore any error. Blindly assume there is no audio + } + finally + { + Marshal.ReleaseComObject(ipsb); + } + + // Configure the Video Window + IVideoWindow videoWindow = m_FilterGraph as IVideoWindow; + ConfigureVideoWindow(videoWindow, hWin); + + // Grab some other interfaces + m_mediaCtrl = m_FilterGraph as IMediaControl; + } + finally + { + Marshal.ReleaseComObject(icgb2); + } + } + + /// + /// Configure the GenericSampleSourceFilter + /// + /// The interface to the GenericSampleSourceFilter + private void ConfigurePusher(IGenericSampleConfig ips) + { + int hr; + + m_ImageHandler.SetMediaType(ips); + + // Specify the callback routine to call with each sample + hr = ips.SetBitmapCB(m_ImageHandler); + DsError.ThrowExceptionForHR(hr); + } + + /// + /// Configure the video window + /// + /// Interface of the video renderer + /// Handle of the window to draw into + private void ConfigureVideoWindow(IVideoWindow videoWindow, Control hWin) + { + int hr; + + // Set the output window + hr = videoWindow.put_Owner( hWin.Handle ); + if (hr >= 0) // If there is video + { + // Set the window style + hr = videoWindow.put_WindowStyle( (WindowStyle.Child | WindowStyle.ClipChildren | WindowStyle.ClipSiblings) ); + DsError.ThrowExceptionForHR( hr ); + + // Make the window visible + hr = videoWindow.put_Visible( OABool.True ); + DsError.ThrowExceptionForHR( hr ); + + // Position the playing location + Rectangle rc = hWin.ClientRectangle; + hr = videoWindow.SetWindowPosition( 0, 0, rc.Right, rc.Bottom ); + DsError.ThrowExceptionForHR( hr ); + } + } + + /// + /// Shut down graph + /// + private void CloseInterfaces() + { + int hr; + + lock (this) + { + // Stop the graph + if( m_mediaCtrl != null ) + { + // Stop the graph + hr = m_mediaCtrl.Stop(); + m_mediaCtrl = null; + } + + if (m_ImageHandler != null) + { + m_ImageHandler.Dispose(); + m_ImageHandler = null; + } + +#if DEBUG + if (m_DsRot != null) + { + m_DsRot.Dispose(); + m_DsRot = null; + } +#endif + + // Release the graph + if (m_FilterGraph != null) + { + hr = ((IMediaEventSink)m_FilterGraph).Notify(EventCode.UserAbort, IntPtr.Zero, IntPtr.Zero); + + Marshal.ReleaseComObject(m_FilterGraph); + m_FilterGraph = null; + } + } + GC.Collect(); + } + + /// + /// Called on a new thread to process events from the graph. The thread + /// exits when the graph finishes. + /// + private void EventWait() + { + // Returned when GetEvent is called but there are no events + const int E_ABORT = unchecked((int)0x80004004); + + int hr; + IntPtr p1, p2; + EventCode ec; + EventCode exitCode = 0; + + IMediaEvent pEvent = (IMediaEvent)m_FilterGraph; + + do + { + // Read the event + for ( + hr = pEvent.GetEvent(out ec, out p1, out p2, 100); + hr >= 0; + hr = pEvent.GetEvent(out ec, out p1, out p2, 100) + ) + { + Debug.WriteLine(ec); + switch(ec) + { + // If the clip is finished playing + case EventCode.Complete: + case EventCode.ErrorAbort: + case EventCode.UserAbort: + exitCode = ec; + + // Release any resources the message allocated + hr = pEvent.FreeEventParams(ec, p1, p2); + DsError.ThrowExceptionForHR(hr); + break; + + default: + // Release any resources the message allocated + hr = pEvent.FreeEventParams(ec, p1, p2); + DsError.ThrowExceptionForHR(hr); + break; + } + } + + // If the error that exited the loop wasn't due to running out of events + if (hr != E_ABORT) + { + DsError.ThrowExceptionForHR(hr); + } + } while (exitCode == 0); + + // Send an event saying we are complete + if (Completed != null) + { + CompletedArgs ca = new CompletedArgs(exitCode); + Completed(this, ca); + } + + } // Exit the thread + + + public class CompletedArgs : System.EventArgs + { + /// The result of the rendering + /// + /// This code will be a member of DirectShowLib.EventCode. Typically it + /// will be EventCode.Complete, EventCode.ErrorAbort or EventCode.UserAbort. + /// + public EventCode Result; + + /// + /// Used to construct an instace of the class. + /// + /// + internal CompletedArgs(EventCode ec) + { + Result = ec; + } + } + + } + + // A generic class to support easily changing between my different sources of data. + + // Note: You DON'T have to use this class, or anything like it. The key is the SampleCallback + // routine. How/where you get your bitmaps is ENTIRELY up to you. Having SampleCallback call + // members of this class was just the approach I used to isolate the data handling. + abstract internal class ImageHandler : IDisposable, IGenericSampleCB + { + #region Definitions + + /// + /// 100 ns - used by a number of DS methods + /// + protected const long UNIT = 10000000; + + #endregion + + /// + /// Number of callbacks that returned a positive result + /// + protected int m_iFrameNumber = 0; + + virtual public void Dispose() + { + } + + abstract public void SetMediaType(IGenericSampleConfig psc); + abstract public int GetImage(int iFrameNumber, IntPtr ip, int iSize, out int iRead); + virtual public int SetTimeStamps(IMediaSample pSample) + { + return 0; + } + + /// + /// Called by the GenericSampleSourceFilter. This routine populates the MediaSample. + /// + /// Pointer to a sample + /// 0 = success, 1 = end of stream, negative values for errors + virtual public int SampleCallback(IMediaSample pSample) + { + int hr; + IntPtr pData; + + try + { + // Get the buffer into which we will copy the data + hr = pSample.GetPointer(out pData); + if (hr >= 0) + { + // Set TRUE on every sample for uncompressed frames + hr = pSample.SetSyncPoint(true); + if (hr >= 0) + { + // Find out the amount of space in the buffer + int cbData = pSample.GetSize(); + + hr = SetTimeStamps(pSample); + if (hr >= 0) + { + int iRead; + + // Get copy the data into the sample + hr = GetImage(m_iFrameNumber, pData, cbData, out iRead); + if (hr == 0) // 1 == End of stream + { + pSample.SetActualDataLength(iRead); + + // increment the frame number for next time + m_iFrameNumber++; + } + } + } + } + } + finally + { + // Release our pointer the the media sample. THIS IS ESSENTIAL! If + // you don't do this, the graph will stop after about 2 samples. + Marshal.ReleaseComObject(pSample); + } + + return hr; + } + + + } + + /// + /// Class to provide image data. Note that the Bitmap class is very easy to use, + /// but not terribly efficient. If you aren't getting the performance you need, + /// replacing that is a good place start. + /// + /// Note that this class assumes that the images to show are all in the same + /// directory, and are named 00000001.jpg, 00000002.jpg, etc + /// + /// Also, make sure you read the comments on the ImageHandler class. + /// + internal class ImageFromFiles : ImageHandler + { + + #region Defines + + [DllImport("Kernel32.dll", EntryPoint="RtlMoveMemory")] + private static extern void CopyMemory(IntPtr Destination, IntPtr Source, int Length); + + /// + /// How many frames to show the bitmap in. Using 1 will return a new + /// image for each frame. Setting it to 5 would show the same image + /// in 5 frames, etc. So, if you are running at 5 FPS, and you set DIV + /// to 5, each image will show for 1 second. + /// + private const int DIV = 1; + + #endregion + + #region Member Variables + + /// + /// Contains the IntPtr to the raw data + /// + private BitmapData m_bmd; + + /// + /// Needed to release the m_bmd member + /// + private Bitmap m_bmp; + + /// + /// Path that contains the images + /// + private string m_sPath; + + // Number of frames per second + private long m_FPS; + + #endregion + + /// + /// Constructor + /// + /// The directory that contains the images. + public ImageFromFiles(string sPath, long FPS) + { + m_sPath = sPath; + m_FPS = UNIT / FPS; + } + + /// + /// Dispose + /// + override public void Dispose() + { + // Release any outstanding bitmaps + if (m_bmp != null) + { + m_bmp.UnlockBits(m_bmd); + m_bmp = null; + m_bmd = null; + } + } + + /// + /// Set the Mediatype from a bitmap + /// + override public void SetMediaType(IGenericSampleConfig psc) + { + BitmapInfoHeader bmi = new BitmapInfoHeader(); + + // Make sure we have an image to get the data from + if (m_bmp == null) + { + int i; + IntPtr ip = IntPtr.Zero; + GetImage(0, ip, 0, out i); + } + + // Build a BitmapInfo struct using the parms from the file + bmi.Size = Marshal.SizeOf(typeof(BitmapInfoHeader)); + bmi.Width = m_bmd.Width; + bmi.Height = m_bmd.Height * -1; + bmi.Planes = 1; + bmi.BitCount = 32; + bmi.Compression = 0; + bmi.ImageSize = (bmi.BitCount / 8) * bmi.Width * bmi.Height; + bmi.XPelsPerMeter = 0; + bmi.YPelsPerMeter = 0; + bmi.ClrUsed = 0; + bmi.ClrImportant = 0; + + int hr = psc.SetMediaTypeFromBitmap(bmi, m_FPS); + DsError.ThrowExceptionForHR(hr); + } + + /// + /// Populate the data buffer. In this class I'm retrieving bitmaps + /// from files based on the current frame number. + /// + /// Frame number + /// A pointer to the memory to populate with the bitmap data + /// returns the number of parameters read + /// 0 on success and 1 on end of stream + override public int GetImage(int iFrameNumber, IntPtr ip, int iSize, out int iRead) + { + int hr = 0; + + if (iFrameNumber % DIV == 0) + { + try + { + // Open the next image + string sFileName = String.Format(@"{1}\{0:00000000}.jpg", iFrameNumber / DIV + 1, m_sPath); + Bitmap bmp = new Bitmap(sFileName); + Rectangle r = new Rectangle(0, 0, bmp.Width, bmp.Height); + + // Release the previous image + if (m_bmd != null) + { + m_bmp.UnlockBits(m_bmd); + m_bmp.Dispose(); + } + + // Store the pointers + m_bmp = bmp; + m_bmd = m_bmp.LockBits(r, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); + + // Only do the copy if we have a place to put the data + if (ip != IntPtr.Zero) + { + // Copy from the bmd to the MediaSample + CopyMemory(ip, m_bmd.Scan0, iSize); + } + } + catch + { + // Presumably we ran out of files. Terminate the stream + hr = 1; + } + } + + iRead = iSize; + + return hr; + } + // Calculate the timestamps based on the frame number and the frames per second + override public int SetTimeStamps(IMediaSample pSample) + { + // Calculate the start/end times based on the current frame number + // and frame rate + DsLong rtStart = new DsLong(m_iFrameNumber * m_FPS); + DsLong rtStop = new DsLong(rtStart + m_FPS); + + // Set the times into the sample + int hr = pSample.SetTime(rtStart, rtStop); + + return hr; + } + } + + /// + /// Alternate class to provide image data. + /// + /// This class just generates pretty colored bitmaps. + /// + /// Also, make sure you read the comments on the ImageHandler class. + /// + internal class ImageFromPixels : ImageHandler + { + #region Definitions + + // How many frames to return before returning End Of Stream + private const int MAXFRAMES = 1000; + + /// + /// How many frames to show the bitmap in. Using 1 will return a new + /// image for each frame. Setting it to 5 would show the same image + /// in 5 frames, etc. + /// + private const int DIV = 1; + + private const int HEIGHT = 240; + private const int WIDTH = 320; + private const int BPP = 32; + + #endregion + + #region Member Variables + + // Used to make the pretty picture + private int m_g = 0; + private int m_b = 0; + + // Number of frames per second + private long m_FPS; + + #endregion + + /// + /// Constructor + /// + /// Frames per second to use + public ImageFromPixels(long FPS) + { + m_FPS = UNIT / FPS; + m_b = 211; + m_g = 197; + } + + /// + /// Set the media type on the IGenericSampleConfig + /// + override public void SetMediaType(IGenericSampleConfig psc) + { + BitmapInfoHeader bmi = new BitmapInfoHeader(); + + // Build a BitmapInfo struct using the parms from the file + bmi.Size = Marshal.SizeOf(typeof(BitmapInfoHeader)); + bmi.Width = WIDTH; + bmi.Height = HEIGHT * -1; + bmi.Planes = 1; + bmi.BitCount = BPP; + bmi.Compression = 0; + bmi.ImageSize = (bmi.BitCount / 8) * bmi.Width * bmi.Height; + bmi.XPelsPerMeter = 0; + bmi.YPelsPerMeter = 0; + bmi.ClrUsed = 0; + bmi.ClrImportant = 0; + + int hr = psc.SetMediaTypeFromBitmap(bmi, m_FPS); + DsError.ThrowExceptionForHR(hr); + } + + /// + /// Populate the data buffer. In this class I'm just generating bitmaps + /// of random colors. + /// + /// Using Marshal.Write* is *really* slow. For decent performance, consider + /// using pointers and unsafe code. + /// + /// Frame number + /// A pointer to the memory to populate with the bitmap data + /// 0 on success and 1 on end of stream + unsafe override public int GetImage(int iFrameNumber, IntPtr ip, int iSize, out int iRead) + { + int hr = 0; + + if (iFrameNumber % DIV == 0) + { + if (iFrameNumber < MAXFRAMES) + { + Color c = Color.FromArgb(0, ((iFrameNumber * 2) % 255), ((iFrameNumber * 2 + m_g) % 255), ((iFrameNumber * 2 + m_b) % 255)); + + m_g += 3; + m_b += 7; + + // Uncomment this line (and the one inside the loop), and comment out + // the Marshal.WriteInt32 to DRASTICALLY improve performance, particularly + // under the vs 2005 debugger. + //int* bp = (int *)ip.ToPointer(); + + for (int x=0; x < (HEIGHT * WIDTH); x+=1) + { + //*(bp + x) = c.ToArgb(); + + Marshal.WriteInt32(ip, x * (BPP/8), c.ToArgb()); + } + } + else + { + hr = 1; // End of stream + } + } + + iRead = iSize; + + return hr; + } + // Calculate the timestamps based on the frame number and the frames per second + override public int SetTimeStamps(IMediaSample pSample) + { + // Calculate the start/end times based on the current frame number + // and frame rate + DsLong rtStart = new DsLong(m_iFrameNumber * m_FPS); + DsLong rtStop = new DsLong(rtStart + m_FPS); + + // Set the times into the sample + int hr = pSample.SetTime(rtStart, rtStop); + + return hr; + } + } + + /// + /// Alternate class to provide image data. + /// + /// This class reads mpg files (note, the provider won't + /// work for avi files. See the GSPF sample for that. + /// + /// Also, make sure you read the comments on the ImageHandler class. + /// + internal class ImageFromMpg : ImageHandler + { + #region Definitions + + // Size of the read buffer + private const int BUFSIZE = 1024 * 256; + + #endregion + + #region Members + + // File stream to read from + private FileStream m_fs; + + // Binary reader to read data with + private BinaryReader m_br; + + #endregion + + /// + /// Constructor + /// + /// File name to render + public ImageFromMpg(string sFileName) + { + m_fs = new FileStream(sFileName, FileMode.Open, FileAccess.Read, FileShare.Read); + m_br = new BinaryReader(m_fs); + } + + override public void Dispose() + { + if (m_br != null) + { + m_br.Close(); + m_br = null; + m_fs = null; + } + } + + + /// + /// Populate the data buffer. In this class I'm reading raw mpg data + /// from a file + /// + /// + /// + /// + /// + /// + override public int GetImage(int iFrameNumber, IntPtr ip, int iSize, out int iRead) + { + int hr; + + Byte [] b = new byte[iSize]; + + // Read the specified number of bytes + iRead = m_br.Read(b, 0, iSize); + + // Copy the read data into the buffer. Too bad BinaryReader doesn't have an overload + // that takes an IntPtr + Marshal.Copy(b, 0, ip, iSize); + + // A simpleminded check for reading past the eof + if (iRead > 0 || iSize == 0) + { + hr = 0; + } + else + { + hr = 1; + } + + return hr; + } + /// + /// Populate the media type + /// + /// IGenericSampleConfig onto which we set the media type + override public void SetMediaType(IGenericSampleConfig psc) + { + AMMediaType amt = new AMMediaType(); + amt.majorType = MediaType.Stream; + amt.subType = MediaSubType.Mpeg2Program; + amt.formatType = Guid.Empty; + + int hr = psc.SetMediaTypeEx(amt, BUFSIZE); + DsError.ThrowExceptionForHR(hr); + + DsUtils.FreeAMMediaType(amt); + } + } + +#if USING_BASS_DLL + /// + /// Alternate class to provide data, this time using sound + /// instead of video. + /// + /// This class uses mp3 files. Note that it requires + /// BASS.DLL and Bass.Net (which must be added as a reference) + /// from http://www.un4seen.com + /// + /// Also, make sure you read the comments on the ImageHandler class. + /// + internal class ImageFromMP3 : ImageHandler + { + #region Definitions + + private const int BUFSIZE = 1024 * 2; + + #endregion + + #region Members + + private int m_fChan; + private int m_BytesPerSample; + private int m_Frequency; + private int m_Channels; + private long m_FMediaTime; + private long m_FSampleTime; + + #endregion + + public ImageFromMP3(string sFileName) + { + // Turn off unnecessary thread + Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_UPDATEPERIOD, 0); + + // Not sure why we need this since these parms should come + // from the file. However, if you don't call it, the + // CreateFile call fails. + Bass.BASS_Init(0, 48000, 0, 0, null); + + // Open the MP3, MP2, MP1, OGG, WAV, AIFF or plugin supported file + m_fChan = Bass.BASS_StreamCreateFile(sFileName, 0, 0, BASSStream.BASS_STREAM_DECODE); + if (m_fChan == 0) + { + throw new Exception("File not found"); + } + } + + override public void Dispose() + { + if (m_fChan != 0) + { + Bass.BASS_StreamFree(m_fChan); + m_fChan = 0; + } + } + + /// Populate the data buffer. In this class I'm getting data from BASS.DLL. + override public int GetImage(int iFrameNumber, IntPtr ip, int iSize, out int iRead) + { + int hr; + + iRead = Bass.BASS_ChannelGetData(m_fChan, ip, BUFSIZE); + + if (iRead > 0) + { + hr = 0; + } + else + { + hr = 1; + } + + return hr; + } + /// + /// Set the media type based on values from BASS.DLL + /// + /// The IGenericSampleConfig onto which we set the mediatype + override public void SetMediaType(IGenericSampleConfig psc) + { + int lFrequency = 0; + int lVolume = 0; + int lPan = 0; + + WaveFormatEx w = new WaveFormatEx(); + BASS_CHANNELINFO lInfo = new BASS_CHANNELINFO(); + + Bass.BASS_ChannelGetInfo(m_fChan, lInfo); + if ((lInfo.flags & (int)BASSStream.BASS_SAMPLE_8BITS) == (int)BASSStream.BASS_SAMPLE_8BITS) + { + w.wBitsPerSample = 8; + } + else + { + w.wBitsPerSample = 16; + } + Bass.BASS_ChannelGetAttributes(m_fChan, ref lFrequency, ref lVolume, ref lPan); + + w.cbSize = (short)Marshal.SizeOf(typeof(WaveFormatEx)); + w.nChannels = (short)lInfo.chans; + w.nSamplesPerSec = lFrequency; + w.wFormatTag = 1; + w.nAvgBytesPerSec = w.nSamplesPerSec * w.nBlockAlign; + m_BytesPerSample = (short)(w.nChannels * (w.wBitsPerSample / 8)); + m_Frequency = lFrequency; + m_Channels = lInfo.chans; + w.nBlockAlign = (short)m_BytesPerSample; + w.nAvgBytesPerSec = w.nSamplesPerSec * w.nBlockAlign; + + AMMediaType amt = new AMMediaType(); + amt.majorType = MediaType.Audio; + amt.subType = MediaSubType.PCM; + amt.formatType = FormatType.WaveEx; + amt.formatPtr = Marshal.AllocCoTaskMem(w.cbSize); + amt.formatSize = w.cbSize; + Marshal.StructureToPtr(w, amt.formatPtr, false); + + int hr = psc.SetMediaTypeEx(amt, BUFSIZE); + DsError.ThrowExceptionForHR(hr); + + DsUtils.FreeAMMediaType(amt); + } + + + // Set the timestamps + override public int SetTimeStamps(IMediaSample pSample) + { + int hr; + + int iRead = pSample.GetActualDataLength(); + long SampleTime = GetTimeFromBytes(iRead); + long TimeStart = m_FSampleTime; + m_FSampleTime = m_FSampleTime + SampleTime; + long TimeStop = m_FSampleTime; + hr = pSample.SetTime(TimeStart, TimeStop); + + if (hr >= 0) + { + TimeStart = m_FMediaTime; + m_FMediaTime = m_FMediaTime + SampleTime; + TimeStop = m_FMediaTime; + hr = pSample.SetMediaTime(TimeStart, TimeStop); + DsError.ThrowExceptionForHR(hr); + } + + return hr; + } + + // Helper function to perform calc + private long GetTimeFromBytes(long Bytes) + { + return Bytes * UNIT / m_BytesPerSample / m_Frequency / m_Channels; + } + } +#endif +} diff --git a/Samples/Misc/GSSF/render/Form1.cs b/Samples/Misc/GSSF/render/Form1.cs new file mode 100644 index 0000000..aed1c67 --- /dev/null +++ b/Samples/Misc/GSSF/render/Form1.cs @@ -0,0 +1,201 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using System.IO; +using System.Diagnostics; +using System.Threading; +using System.Drawing.Imaging; +using DirectShowLib; + +namespace DxPlay +{ + /// + /// Summary description for Form1. + /// + public class Form1 : System.Windows.Forms.Form + { + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Button btnStart; + private System.Windows.Forms.TextBox tbFileName; + private System.ComponentModel.IContainer components = null; + private TextBox textBox1; + + DxPlay m_play = null; + + public Form1() + { + // + // Required for Windows Form Designer support + // + InitializeComponent(); + +#if USING_NET20 + TextBox.CheckForIllegalCrossThreadCalls = false; + textBox1.Text = "Running this code under the debugger in vs 2005 will give VERY poor performance. Use \"Debug/Start without Debugging\" for decent performance."; +#endif + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + // Make sure to release the DxPlay object to avoid hanging + if (m_play != null) + { + m_play.Dispose(); + } + if( disposing ) + { + if (components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnStart = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.panel1 = new System.Windows.Forms.Panel(); + this.tbFileName = new System.Windows.Forms.TextBox(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.SuspendLayout(); + // + // btnStart + // + this.btnStart.Location = new System.Drawing.Point(8, 37); + this.btnStart.Name = "btnStart"; + this.btnStart.Size = new System.Drawing.Size(57, 32); + this.btnStart.TabIndex = 1; + this.btnStart.Text = "Start"; + this.btnStart.Click += new System.EventHandler(this.btnStart_Click); + // + // label1 + // + this.label1.Location = new System.Drawing.Point(0, 8); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(88, 16); + this.label1.TabIndex = 2; + this.label1.Text = "Source Files dir"; + // + // panel1 + // + this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.panel1.Location = new System.Drawing.Point(8, 88); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(320, 240); + this.panel1.TabIndex = 10; + // + // tbFileName + // + this.tbFileName.Location = new System.Drawing.Point(88, 8); + this.tbFileName.Name = "tbFileName"; + this.tbFileName.Size = new System.Drawing.Size(208, 20); + this.tbFileName.TabIndex = 9; + this.tbFileName.Text = "c:\\vss\\catchpic"; + // + // textBox1 + // + this.textBox1.Enabled = false; + this.textBox1.Location = new System.Drawing.Point(71, 37); + this.textBox1.Multiline = true; + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size(256, 45); + this.textBox1.TabIndex = 11; + // + // Form1 + // + this.AcceptButton = this.btnStart; + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(336, 338); + this.Controls.Add(this.textBox1); + this.Controls.Add(this.panel1); + this.Controls.Add(this.label1); + this.Controls.Add(this.btnStart); + this.Controls.Add(this.tbFileName); + this.Name = "Form1"; + this.Text = "DxPlay"; + this.Closing += new System.ComponentModel.CancelEventHandler(this.Form1_Closing); + this.ResumeLayout(false); + this.PerformLayout(); + + } + #endregion + + /// + /// The main entry point for the application. + /// + [MTAThread] + static void Main() + { + Application.Run(new Form1()); + } + + private void btnStart_Click(object sender, System.EventArgs e) + { + // If we have no class open + if (m_play == null) + { + try + { + m_play = new DxPlay(tbFileName.Text, panel1); + m_play.Completed +=new EventHandler(m_play_Completed); + + m_play.Start(); + + btnStart.Text = "Stop"; + tbFileName.Enabled = false; + + } + catch(COMException ce) + { + MessageBox.Show("Failed create DxPlay: " + ce.Message, "Open Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + else + { + m_play.Stop(); + } + } + + private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e) + { + if (m_play != null) + { + m_play.Stop(); + m_play = null; + } + } + + private void m_play_Completed(object sender, EventArgs e) + { + DxPlay.CompletedArgs c = e as DxPlay.CompletedArgs; + if (m_play != null) + { + m_play.Dispose(); + m_play = null; + } + tbFileName.Enabled = true; + btnStart.Text = "Start"; + } + } +} diff --git a/Samples/Misc/GSSF/render/Form1.resx b/Samples/Misc/GSSF/render/Form1.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/Samples/Misc/GSSF/render/Form1.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Samples/Misc/GSSF/render/PushClasses.cs b/Samples/Misc/GSSF/render/PushClasses.cs new file mode 100644 index 0000000..d205857 --- /dev/null +++ b/Samples/Misc/GSSF/render/PushClasses.cs @@ -0,0 +1,45 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Runtime.InteropServices; + +using DirectShowLib; + +namespace GenericSampleSourceFilterClasses +{ + [ComImport, Guid("6F7BCF72-D0C2-4449-BE0E-B12F580D056D")] + public class GenericSampleSourceFilter + { + } + + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("33B9EE57-1067-45fa-B12D-C37517F09FC0")] + public interface IGenericSampleCB + { + [PreserveSig] + int SampleCallback(IMediaSample pSample); + } + + [Guid("CE50FFF9-1BA8-4788-8131-BDE7D4FFC27F"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IGenericSampleConfig + { + [PreserveSig] + int SetMediaTypeFromBitmap(BitmapInfoHeader bmi, long lFPS); + + [PreserveSig] + int SetMediaType([MarshalAs(UnmanagedType.LPStruct)] AMMediaType amt); + + [PreserveSig] + int SetMediaTypeEx([MarshalAs(UnmanagedType.LPStruct)] AMMediaType amt, int lBufferSize); + + [PreserveSig] + int SetBitmapCB(IGenericSampleCB pfn); + } + +} diff --git a/Samples/Misc/GSSF/render/Render-2005.csproj b/Samples/Misc/GSSF/render/Render-2005.csproj new file mode 100644 index 0000000..c3ca654 --- /dev/null +++ b/Samples/Misc/GSSF/render/Render-2005.csproj @@ -0,0 +1,115 @@ + + + Local + 8.0.50727 + 2.0 + {6E8BB66C-D141-4333-8311-3CF33FACEC1B} + Debug + AnyCPU + App.ico + + + Renderer + + + JScript + Grid + IE50 + false + WinExe + Renderer + OnBuildSuccess + + + + + + + + + bin\Debug\ + true + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + true + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + + Code + + + Code + + + Form + + + Code + + + Form1.cs + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Misc/GSSF/render/Render.csproj b/Samples/Misc/GSSF/render/Render.csproj new file mode 100644 index 0000000..c0e2e7f --- /dev/null +++ b/Samples/Misc/GSSF/render/Render.csproj @@ -0,0 +1,120 @@ + + + + Local + 8.0.50727 + 2.0 + {6E8BB66C-D141-4333-8311-3CF33FACEC1B} + Debug + AnyCPU + App.ico + + + Renderer + + + JScript + Grid + IE50 + false + WinExe + Renderer + OnBuildSuccess + + + + + + + 4.0 + v2.0 + + + bin\Debug\ + true + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + true + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + + Code + + + Code + + + Form + + + Code + + + Form1.cs + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Misc/MediaDetector/MainForm.Designer.cs b/Samples/Misc/MediaDetector/MainForm.Designer.cs new file mode 100644 index 0000000..800abbc --- /dev/null +++ b/Samples/Misc/MediaDetector/MainForm.Designer.cs @@ -0,0 +1,81 @@ +namespace DirectShowLib.Samples +{ + partial class MainForm + { + /// + /// Variable nécessaire au concepteur. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Nettoyage des ressources utilisées. + /// + /// true si les ressources managées doivent être supprimées ; sinon, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Code généré par le Concepteur Windows Form + + /// + /// Méthode requise pour la prise en charge du concepteur - ne modifiez pas + /// le contenu de cette méthode avec l'éditeur de code. + /// + private void InitializeComponent() + { + this.propertyGrid1 = new System.Windows.Forms.PropertyGrid(); + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + this.SuspendLayout(); + // + // propertyGrid1 + // + this.propertyGrid1.Location = new System.Drawing.Point(12, 12); + this.propertyGrid1.Name = "propertyGrid1"; + this.propertyGrid1.PropertySort = System.Windows.Forms.PropertySort.Categorized; + this.propertyGrid1.Size = new System.Drawing.Size(290, 240); + this.propertyGrid1.TabIndex = 0; + // + // pictureBox1 + // + this.pictureBox1.BackColor = System.Drawing.Color.Black; + this.pictureBox1.Location = new System.Drawing.Point(308, 12); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(320, 240); + this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.pictureBox1.TabIndex = 1; + this.pictureBox1.TabStop = false; + // + // MainForm + // + this.AllowDrop = true; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(636, 263); + this.Controls.Add(this.pictureBox1); + this.Controls.Add(this.propertyGrid1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.HelpButton = true; + this.MaximizeBox = false; + this.Name = "MainForm"; + this.Text = "Media Detector (Drag and Drop a media file in this form)"; + this.DragDrop += new System.Windows.Forms.DragEventHandler(this.MainForm_DragDrop); + this.DragEnter += new System.Windows.Forms.DragEventHandler(this.MainForm_DragEnter); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.PropertyGrid propertyGrid1; + private System.Windows.Forms.PictureBox pictureBox1; + + } +} + diff --git a/Samples/Misc/MediaDetector/MainForm.cs b/Samples/Misc/MediaDetector/MainForm.cs new file mode 100644 index 0000000..25c5f73 --- /dev/null +++ b/Samples/Misc/MediaDetector/MainForm.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +using DirectShowLib; + +namespace DirectShowLib.Samples +{ + public partial class MainForm : Form + { + public MainForm() + { + InitializeComponent(); + } + + private void MainForm_DragEnter(object sender, DragEventArgs e) + { + // Display a link icon + e.Effect = DragDropEffects.Link; + } + + private void MainForm_DragDrop(object sender, DragEventArgs e) + { + // Retrieve the files droped into the form + string[] fileNames = (string[])e.Data.GetData("FileNameW"); + + // Get the description of this file + MediaDescription mediaDesc = MediaDetector.GetDescription(fileNames[0]); + + // Display the returned description + propertyGrid1.SelectedObject = mediaDesc; + pictureBox1.Image = mediaDesc.Snapshot; + } + } +} \ No newline at end of file diff --git a/Samples/Misc/MediaDetector/MainForm.resx b/Samples/Misc/MediaDetector/MainForm.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/Samples/Misc/MediaDetector/MainForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Samples/Misc/MediaDetector/MediaDescription.cs b/Samples/Misc/MediaDetector/MediaDescription.cs new file mode 100644 index 0000000..4c990e9 --- /dev/null +++ b/Samples/Misc/MediaDetector/MediaDescription.cs @@ -0,0 +1,100 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace DirectShowLib.Samples +{ + /// + /// This class is mainly a storage class. + /// Its primary purpose is to be used with a PropertyGrid. + /// + public class MediaDescription + { + internal string fileName; + internal Guid audioSubType; + internal int channels; + internal float samplesPerSec; + internal int bitsPerSample; + internal TimeSpan audioLength; + internal Guid videoSubType; + internal Size resolution; + internal int bitsPerPixel; + internal string fourCC; + internal TimeSpan videoLength; + internal Bitmap snapshot; + + [Category("General"), ReadOnly(true), Description("The file name with its path")] + public string FileName + { + get { return fileName; } + } + + [Category("Audio"), ReadOnly(true), Description("Audio subtype GUID")] + public Guid AudioSubType + { + get { return audioSubType; } + } + + [Category("Audio"), ReadOnly(true), Description("Audio channel count")] + public int Channels + { + get { return channels; } + } + + [Category("Audio"), ReadOnly(true), Description("Samples per second in kHz")] + public float SamplesPerSec + { + get { return samplesPerSec; } + } + + [Category("Audio"), ReadOnly(true), Description("How many bits are used per samples")] + public int BitsPerSample + { + get { return bitsPerSample; } + } + + [Category("Audio"), ReadOnly(true), Description("The audio stream length")] + public TimeSpan AudioLength + { + get { return audioLength; } + } + + [Category("Video"), ReadOnly(true), Description("Video subtype GUID")] + public Guid VideoSubType + { + get { return videoSubType; } + } + + [Category("Video"), ReadOnly(true), Description("Specifies the width and height of the bitmap, in pixels")] + public Size Resolution + { + get { return resolution; } + } + + [Category("Video"), ReadOnly(true), Description("Specifies the number of bits per pixel (bpp)")] + public int BitsPerPixel + { + get { return bitsPerPixel; } + } + + [Category("Video"), ReadOnly(true), Description("The Video's FOURCC code")] + public string FourCC + { + get { return fourCC; } + } + + [Category("Video"), ReadOnly(true), Description("The video stream length")] + public TimeSpan VideoLength + { + get { return videoLength; } + } + + [Category("Video"), ReadOnly(true), Description("A snapshot of the video stream at half its duration")] + public Bitmap Snapshot + { + get { return snapshot; } + } + } + +} diff --git a/Samples/Misc/MediaDetector/MediaDetector-2005.csproj b/Samples/Misc/MediaDetector/MediaDetector-2005.csproj new file mode 100644 index 0000000..e82f9be --- /dev/null +++ b/Samples/Misc/MediaDetector/MediaDetector-2005.csproj @@ -0,0 +1,83 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7} + WinExe + Properties + DirectShowLib.Samples + MediaDetector + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\..\..\lib\DirectShowLib-2005.dll + + + + + + + + + Form + + + MainForm.cs + + + + + + + Designer + MainForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + \ No newline at end of file diff --git a/Samples/Misc/MediaDetector/MediaDetector-2008.sln b/Samples/Misc/MediaDetector/MediaDetector-2008.sln new file mode 100644 index 0000000..395eefd --- /dev/null +++ b/Samples/Misc/MediaDetector/MediaDetector-2008.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaDetector-2008", "MediaDetector-2008.csproj", "{4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Misc/MediaDetector/MediaDetector.cs b/Samples/Misc/MediaDetector/MediaDetector.cs new file mode 100644 index 0000000..cceba9a --- /dev/null +++ b/Samples/Misc/MediaDetector/MediaDetector.cs @@ -0,0 +1,186 @@ +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; + +using DirectShowLib; +using DirectShowLib.DES; + +namespace DirectShowLib.Samples +{ + /// + /// A wrapper class around the DirectShow's MediaDet object. + /// + public sealed class MediaDetector + { + public static MediaDescription GetDescription(string fileName) + { + int hr = 0; + MediaDescription mediaDesc = new MediaDescription(); + IMediaDet mediaDet = null; + + try + { + // Create the DirectShow's MediaDet + mediaDet = (IMediaDet)new MediaDet(); + + hr = mediaDet.put_Filename(fileName); + if (hr < 0) + { + MessageBox.Show("This file is not supprted by MediaDet", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + DsError.ThrowExceptionForHR(hr); + } + + mediaDesc.fileName = fileName; + + int streamCount; + hr = mediaDet.get_OutputStreams(out streamCount); + DsError.ThrowExceptionForHR(hr); + + for (int i = 0; i < streamCount; i++) + { + hr = mediaDet.put_CurrentStream(i); + DsError.ThrowExceptionForHR(hr); + + Guid streamType; + hr = mediaDet.get_StreamType(out streamType); + DsError.ThrowExceptionForHR(hr); + + if (streamType == MediaType.Audio) + UpdateAudioPart(mediaDet, mediaDesc); + else if (streamType == MediaType.Video) + UpdateVideoPart(mediaDet, mediaDesc); + else + continue; + } + + if (mediaDesc.videoSubType != Guid.Empty) + mediaDesc.snapshot = GetSnapshot(mediaDet, mediaDesc.resolution.Width, mediaDesc.resolution.Height, mediaDesc.videoLength.TotalSeconds / 2); + } + finally + { + if (mediaDet != null) + Marshal.ReleaseComObject(mediaDet); + } + + return mediaDesc; + } + + private static void UpdateAudioPart(IMediaDet mediaDet, MediaDescription mediaDesc) + { + int hr = 0; + AMMediaType mediaType = new AMMediaType(); + + hr = mediaDet.get_StreamMediaType(mediaType); + DsError.ThrowExceptionForHR(hr); + + mediaDesc.audioSubType = mediaType.subType; + + double streamLength; + hr = mediaDet.get_StreamLength(out streamLength); + DsError.ThrowExceptionForHR(hr); + + mediaDesc.audioLength = TimeSpan.FromSeconds(streamLength); + + if (mediaType.formatType == FormatType.WaveEx) + { + WaveFormatEx waveFormatEx = (WaveFormatEx)Marshal.PtrToStructure(mediaType.formatPtr, typeof(WaveFormatEx)); + mediaDesc.channels = waveFormatEx.nChannels; + mediaDesc.samplesPerSec = ((float)waveFormatEx.nSamplesPerSec) / 1000; + mediaDesc.bitsPerSample = waveFormatEx.wBitsPerSample; + } + } + + private static void UpdateVideoPart(IMediaDet mediaDet, MediaDescription mediaDesc) + { + int hr = 0; + AMMediaType mediaType = new AMMediaType(); + + hr = mediaDet.get_StreamMediaType(mediaType); + DsError.ThrowExceptionForHR(hr); + + mediaDesc.videoSubType = mediaType.subType; + + double streamLength; + hr = mediaDet.get_StreamLength(out streamLength); + DsError.ThrowExceptionForHR(hr); + + mediaDesc.videoLength = TimeSpan.FromSeconds(streamLength); + + if (mediaType.formatType == FormatType.VideoInfo) + { + VideoInfoHeader videoHeader = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.formatPtr, typeof(VideoInfoHeader)); + + mediaDesc.resolution = new Size(videoHeader.BmiHeader.Width, videoHeader.BmiHeader.Height); + mediaDesc.bitsPerPixel = videoHeader.BmiHeader.BitCount; + mediaDesc.fourCC = FourCCToString(videoHeader.BmiHeader.Compression); + } + } + + private static string FourCCToString(int fourcc) + { + byte[] bytes = new byte[4]; + + bytes[0] = (byte)(fourcc & 0x000000ff); fourcc = fourcc >> 8; + bytes[1] = (byte)(fourcc & 0x000000ff); fourcc = fourcc >> 8; + bytes[2] = (byte)(fourcc & 0x000000ff); fourcc = fourcc >> 8; + bytes[3] = (byte)(fourcc & 0x000000ff); + + return Encoding.ASCII.GetString(bytes); + } + + private static Bitmap GetSnapshot(IMediaDet mediaDet, int width, int height, double position) + { + int hr = 0; + Bitmap bitmap = null; + int bufferSize = 0; + IntPtr buffer = IntPtr.Zero; + + try + { + hr = mediaDet.GetBitmapBits(position, out bufferSize, IntPtr.Zero, width, height); + if (hr == 0) + { + buffer = Marshal.AllocCoTaskMem(bufferSize); + hr = mediaDet.GetBitmapBits(position, out bufferSize, buffer, width, height); + + BitmapInfoHeader bitmapHeader = (BitmapInfoHeader)Marshal.PtrToStructure(buffer, typeof(BitmapInfoHeader)); + IntPtr bitmapData; + + if (IntPtr.Size == 4) + bitmapData = new IntPtr(buffer.ToInt32() + bitmapHeader.Size); + else + bitmapData = new IntPtr(buffer.ToInt64() + bitmapHeader.Size); + + bitmap = new Bitmap(bitmapHeader.Width, bitmapHeader.Height, PixelFormat.Format24bppRgb); + BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmapHeader.Width, bitmapHeader.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); + + /* + for (int i = 0; i < width * height * 3 ; i++) + { + byte b = Marshal.ReadByte(bitmapData, i); + Marshal.WriteByte(bmpData.Scan0, i, b); + } + */ + + CopyMemory(bmpData.Scan0, bitmapData, width * height * 3); + bitmap.UnlockBits(bmpData); + + bitmap.RotateFlip(RotateFlipType.Rotate180FlipX); + } + } + finally + { + if (buffer != IntPtr.Zero) + Marshal.FreeCoTaskMem(buffer); + } + return bitmap; + } + + [DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")] + private static extern void CopyMemory(IntPtr Destination, IntPtr Source, int Length); + + } +} diff --git a/Samples/Misc/MediaDetector/MediaDetector.csproj b/Samples/Misc/MediaDetector/MediaDetector.csproj new file mode 100644 index 0000000..1f31422 --- /dev/null +++ b/Samples/Misc/MediaDetector/MediaDetector.csproj @@ -0,0 +1,119 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7} + WinExe + Properties + DirectShowLib.Samples + MediaDetector + + + 3.5 + + + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + Form + + + MainForm.cs + + + + + + + Designer + MainForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + \ No newline at end of file diff --git a/Samples/Misc/MediaDetector/MediaDetector.sln b/Samples/Misc/MediaDetector/MediaDetector.sln new file mode 100644 index 0000000..befb2f2 --- /dev/null +++ b/Samples/Misc/MediaDetector/MediaDetector.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaDetector", "MediaDetector.csproj", "{4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4A1D7E19-8697-4DB8-B54F-1DF30F5C90B7}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Misc/MediaDetector/Program.cs b/Samples/Misc/MediaDetector/Program.cs new file mode 100644 index 0000000..1b501c9 --- /dev/null +++ b/Samples/Misc/MediaDetector/Program.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; + +namespace DirectShowLib.Samples +{ + static class Program + { + /// + /// Point d'entrée principal de l'application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new MainForm()); + } + } +} \ No newline at end of file diff --git a/Samples/Misc/MediaDetector/Properties/AssemblyInfo.cs b/Samples/Misc/MediaDetector/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..9ab7b14 --- /dev/null +++ b/Samples/Misc/MediaDetector/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Les informations générales relatives à un assembly dépendent de +// l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations +// associées à un assembly. +[assembly: AssemblyTitle("MediaDetector")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("MediaDetector")] +[assembly: AssemblyCopyright("Copyright © 2006")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly +// aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de +// COM, affectez la valeur true à l'attribut ComVisible sur ce type. +[assembly: ComVisible(false)] + +// Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM +[assembly: Guid("28231d25-2795-4648-bc65-782863c1e07a")] + +// Les informations de version pour un assembly se composent des quatre valeurs suivantes : +// +// Version principale +// Version secondaire +// Numéro de build +// Révision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Samples/Misc/MediaDetector/Properties/Resources.Designer.cs b/Samples/Misc/MediaDetector/Properties/Resources.Designer.cs new file mode 100644 index 0000000..a04fdba --- /dev/null +++ b/Samples/Misc/MediaDetector/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace DirectShowLib.Samples.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DirectShowLib.Samples.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Samples/Misc/MediaDetector/Properties/Resources.resx b/Samples/Misc/MediaDetector/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/Samples/Misc/MediaDetector/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Samples/Misc/MediaDetector/Properties/Settings.Designer.cs b/Samples/Misc/MediaDetector/Properties/Settings.Designer.cs new file mode 100644 index 0000000..1690ee7 --- /dev/null +++ b/Samples/Misc/MediaDetector/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace DirectShowLib.Samples.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Samples/Misc/MediaDetector/Properties/Settings.settings b/Samples/Misc/MediaDetector/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Samples/Misc/MediaDetector/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Samples/Misc/Toolkit/AssemblyInfo.cs b/Samples/Misc/Toolkit/AssemblyInfo.cs new file mode 100644 index 0000000..76201ae --- /dev/null +++ b/Samples/Misc/Toolkit/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// Les informations générales relatives à un assembly dépendent de +// l'ensemble d'attributs suivant. Pour modifier les informations +// associées à un assembly, changez les valeurs de ces attributs. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Les informations de version pour un assembly se composent des quatre valeurs suivantes : +// +// Version principale +// Version secondaire +// Numéro de build +// Révision +// +// Vous pouvez spécifier toutes les valeurs ou indiquer des numéros de révision et de build par défaut +// en utilisant '*', comme ci-dessous : + +[assembly: AssemblyVersion("1.0.*")] + +// +// Pour signer votre assembly, vous devez spécifier la clé à utiliser. Consultez +// la documentation Microsoft .NET Framework pour plus d'informations sur la signature d'un assembly. +// +// Utilisez les attributs ci-dessous pour contrôler la clé utilisée lors de la signature. +// +// Remarques : +// (*) Si aucune clé n'est spécifiée, l'assembly n'est pas signé. +// (*) KeyName fait référence à une clé installée dans le fournisseur de +// services cryptographiques (CSP) de votre ordinateur. KeyFile fait référence à un fichier qui contient +// une clé. +// (*) Si les valeurs de KeyFile et de KeyName sont spécifiées, le +// traitement suivant se produit : +// (1) Si KeyName se trouve dans le CSP, la clé est utilisée. +// (2) Si KeyName n'existe pas mais que KeyFile existe, la clé +// de KeyFile est installée dans le CSP et utilisée. +// (*) Pour créer KeyFile, vous pouvez utiliser l'utilitaire sn.exe (Strong Name, Nom fort). +// Lors de la spécification de KeyFile, son emplacement doit être +// relatif au répertoire de sortie du projet qui est +// %Project Directory%\obj\. Par exemple, si votre KeyFile se trouve +// dans le répertoire du projet, vous devez spécifier l'attribut +// AssemblyKeyFile sous la forme [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) DelaySign (signature différée) est une option avancée. Pour plus d'informations, consultez la +// documentation Microsoft .NET Framework. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/Misc/Toolkit/DirectShowLib.Utils-2005.csproj b/Samples/Misc/Toolkit/DirectShowLib.Utils-2005.csproj new file mode 100644 index 0000000..c34cff4 --- /dev/null +++ b/Samples/Misc/Toolkit/DirectShowLib.Utils-2005.csproj @@ -0,0 +1,100 @@ + + + Local + 8.0.50727 + 2.0 + {FA72F510-5B39-43EC-BA62-04C6F90BD524} + Debug + AnyCPU + + + + + DirectShowLib.Utils + + + JScript + Grid + IE50 + false + Library + DirectShowLib.Utils + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + DirectShowLib.Utils.xml + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\lib\DirectShowLib-2005.dll + + + System + + + + + Code + + + Code + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Misc/Toolkit/DirectShowLib.Utils-2005.sln b/Samples/Misc/Toolkit/DirectShowLib.Utils-2005.sln new file mode 100644 index 0000000..a4935c5 --- /dev/null +++ b/Samples/Misc/Toolkit/DirectShowLib.Utils-2005.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DirectShowLib.Utils-2005", "DirectShowLib.Utils-2005.csproj", "{FA72F510-5B39-43EC-BA62-04C6F90BD524}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FA72F510-5B39-43EC-BA62-04C6F90BD524}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA72F510-5B39-43EC-BA62-04C6F90BD524}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA72F510-5B39-43EC-BA62-04C6F90BD524}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA72F510-5B39-43EC-BA62-04C6F90BD524}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Misc/Toolkit/DirectShowLib.Utils-2008.sln b/Samples/Misc/Toolkit/DirectShowLib.Utils-2008.sln new file mode 100644 index 0000000..9792cdd --- /dev/null +++ b/Samples/Misc/Toolkit/DirectShowLib.Utils-2008.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DirectShowLib.Utils-2008", "DirectShowLib.Utils-2008.csproj", "{FA72F510-5B39-43EC-BA62-04C6F90BD524}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FA72F510-5B39-43EC-BA62-04C6F90BD524}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA72F510-5B39-43EC-BA62-04C6F90BD524}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA72F510-5B39-43EC-BA62-04C6F90BD524}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA72F510-5B39-43EC-BA62-04C6F90BD524}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Misc/Toolkit/DirectShowLib.Utils.csproj b/Samples/Misc/Toolkit/DirectShowLib.Utils.csproj new file mode 100644 index 0000000..5f23fa8 --- /dev/null +++ b/Samples/Misc/Toolkit/DirectShowLib.Utils.csproj @@ -0,0 +1,132 @@ + + + + Local + 8.0.50727 + 2.0 + {FA72F510-5B39-43EC-BA62-04C6F90BD524} + Debug + AnyCPU + + + + + DirectShowLib.Utils + + + JScript + Grid + IE50 + false + Library + DirectShowLib.Utils + OnBuildSuccess + + + + + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + DirectShowLib.Utils.xml + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + + + Code + + + Code + + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Misc/Toolkit/DirectShowLib.Utils.ndoc b/Samples/Misc/Toolkit/DirectShowLib.Utils.ndoc new file mode 100644 index 0000000..e0180d0 --- /dev/null +++ b/Samples/Misc/Toolkit/DirectShowLib.Utils.ndoc @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Misc/Toolkit/DirectShowLib.Utils.xml b/Samples/Misc/Toolkit/DirectShowLib.Utils.xml new file mode 100644 index 0000000..8e7c996 --- /dev/null +++ b/Samples/Misc/Toolkit/DirectShowLib.Utils.xml @@ -0,0 +1,266 @@ + + + + DirectShowLib.Utils + + + + + A collection of methods to do common DirectShow tasks. + + + + + Add a filter to a DirectShow Graph using its CLSID + + the IGraphBuilder interface of the graph + a valid CLSID. This object must implement IBaseFilter + the name used in the graph (may be null) + an instance of the filter if the method successfully created it, null if not + + You can use IsThisComObjectInstalled to check is the CLSID is valid before calling this method + + This sample shows how to programmatically add a NVIDIA Video decoder filter to a graph + + Guid nvidiaVideoDecClsid = new Guid("71E4616A-DB5E-452B-8CA5-71D9CC7805E9"); + + if (FilterGraphTools.IsThisComObjectInstalled(nvidiaVideoDecClsid)) + { + filter = FilterGraphTools.AddFilterFromClsid(graphBuilder, nvidiaVideoDecClsid, "NVIDIA Video Decoder"); + } + else + { + // use another filter... + } + + + + Thrown if graphBuilder is null + Thrown if errors occur when the filter is add to the graph + + + + Add a filter to a DirectShow Graph using its name + + the IGraphBuilder interface of the graph + the filter category (see DirectShowLib.FilterCategory) + the filter name (case-sensitive) + an instance of the filter if the method successfully created it, null if not + This sample shows how to programmatically add a NVIDIA Video decoder filter to a graph + + filter = FilterGraphTools.AddFilterByName(graphBuilder, FilterCategory.LegacyAmFilterCategory, "NVIDIA Video Decoder"); + + + Thrown if graphBuilder is null + Thrown if errors occur when the filter is add to the graph + + + + Add a filter to a DirectShow Graph using its Moniker's device path + + the IGraphBuilder interface of the graph + a moniker path + the name to use for the filter in the graph + an instance of the filter if the method successfully creates it, null if not + This sample shows how to programmatically add a NVIDIA Video decoder filter to a graph + + string devicePath = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{71E4616A-DB5E-452B-8CA5-71D9CC7805E9}"; + filter = FilterGraphTools.AddFilterByDevicePath(graphBuilder, devicePath, "NVIDIA Video Decoder"); + + + Thrown if graphBuilder is null + Thrown if errors occur when the filter is add to the graph + + + + Find a filter in a DirectShow Graph using its name + + the IGraphBuilder interface of the graph + the filter name to find (case-sensitive) + an instance of the filter if found, null if not + + Thrown if graphBuilder is null + + + + Find a filter in a DirectShow Graph using its CLSID + + the IGraphBuilder interface of the graph + the CLSID to find + an instance of the filter if found, null if not + + Thrown if graphBuilder is null + + + + Render a filter's pin in a DirectShow Graph + + the IGraphBuilder interface of the graph + the filter containing the pin to render + the pin name + true if rendering is a success, false if not + + + hr = graphBuilder.AddSourceFilter(@"foo.avi", "Source Filter", out filter); + DsError.ThrowExceptionForHR(hr); + + if (!FilterGraphTools.RenderPin(graphBuilder, filter, "Output")) + { + // Something went wrong... + } + + + Thrown if graphBuilder or source is null + This method assumes that the filter is part of the given graph + + + + Disconnect all pins on a given filter + + the filter on which to disconnect all the pins + Thrown if filter is null + Thrown if errors occured during the disconnection process + Both input and output pins are disconnected + + + + Disconnect pins of all the filters in a DirectShow Graph + + the IGraphBuilder interface of the graph + Thrown if graphBuilder is null + Thrown if the method can't enumerate its filters + This method doesn't throw an exception if an error occurs during pin disconnections + + + + Remove and release all filters from a DirectShow Graph + + the IGraphBuilder interface of the graph + Thrown if graphBuilder is null + Thrown if the method can't enumerate its filters + + + + Save a DirectShow Graph to a GRF file + + the IGraphBuilder interface of the graph + the file to be saved + Thrown if graphBuilder is null + Thrown if errors occur during the file creation + + This method overwrites any existing file + + + + Load a DirectShow Graph from a file + + the IGraphBuilder interface of the graph + the file to be loaded + Thrown if graphBuilder is null + Thrown if the given file is not a valid graph file + Thrown if errors occur during loading + + + + + Check if a DirectShow filter can display Property Pages + + A DirectShow Filter + Thrown if filter is null + + true if the filter has Property Pages, false if not + + This method is intended to be used with ShowFilterPropertyPage + + + + + Display Property Pages of a given DirectShow filter + + A DirectShow Filter + A hwnd handle of a window to contain the pages + Thrown if filter is null + + + You can check if a filter supports Property Pages with the HasPropertyPages method.
+ Warning : This method is blocking. It only returns when the Property Pages are closed. +
+ This sample shows how to check if a filter supports Property Pages and displays them + + if (FilterGraphTools.HasPropertyPages(myFilter)) + { + FilterGraphTools.ShowFilterPropertyPage(myFilter, myForm.Handle); + } + + +
+ + + Check if a COM Object is available + + The CLSID of this object + This sample shows how to check if the MPEG-2 Demultiplexer filter is available + + if (FilterGraphTools.IsThisComObjectInstalled(typeof(MPEG2Demultiplexer).GUID)) + { + // Use it... + } + + + true if the object is available, false if not + + + + Check if the Video Mixing Renderer 9 Filter is available + + + + This method uses IsThisComObjectInstalled internally + + true if VMR9 is present, false if not + + + + Check if the Video Mixing Renderer 7 Filter is available + + + + This method uses IsThisComObjectInstalled internally + + true if VMR7 is present, false if not + + + + Connect pins from two filters + + the IGraphBuilder interface of the graph + the upstream filter + the upstream filter pin name + the downstream filter + the downstream filter pin name + indicate if the method should use DirectShow's Intelligent Connect + Thrown if graphBuilder, upFilter or downFilter are null + Thrown if pin names are not found in filters + Thrown if pins can't connect + + If useIntelligentConnect is true, this method can add missing filters between the two pins.
+ If useIntelligentConnect is false, this method works only if the two media types are compatible. +
+
+ + + Connect pins from two filters + + the IGraphBuilder interface of the graph + the source (upstream / output) pin + the destination (downstream / input) pin + indicates if the method should use DirectShow's Intelligent Connect + Thrown if graphBuilder, sourcePin or destPin are null + Thrown if pins can't connect + + If useIntelligentConnect is true, this method can add missing filters between the two pins.
+ If useIntelligentConnect is false, this method works only if the two media types are compatible. +
+
+
+
diff --git a/Samples/Misc/Toolkit/FilterGraphTools.cs b/Samples/Misc/Toolkit/FilterGraphTools.cs new file mode 100644 index 0000000..d0dbfb1 --- /dev/null +++ b/Samples/Misc/Toolkit/FilterGraphTools.cs @@ -0,0 +1,1015 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Collections; +using System.Runtime.InteropServices; +using System.Security.Permissions; + +using DirectShowLib; + +#if !USING_NET11 +using System.Runtime.InteropServices.ComTypes; +#endif + +namespace DirectShowLib.Utils +{ + /// + /// A collection of methods to do common DirectShow tasks. + /// + + public sealed class FilterGraphTools + { + private FilterGraphTools(){} + + /// + /// Add a filter to a DirectShow Graph using its CLSID + /// + /// the IGraphBuilder interface of the graph + /// a valid CLSID. This object must implement IBaseFilter + /// the name used in the graph (may be null) + /// an instance of the filter if the method successfully created it, null if not + /// + /// You can use IsThisComObjectInstalled to check is the CLSID is valid before calling this method + /// + /// This sample shows how to programmatically add a NVIDIA Video decoder filter to a graph + /// + /// Guid nvidiaVideoDecClsid = new Guid("71E4616A-DB5E-452B-8CA5-71D9CC7805E9"); + /// + /// if (FilterGraphTools.IsThisComObjectInstalled(nvidiaVideoDecClsid)) + /// { + /// filter = FilterGraphTools.AddFilterFromClsid(graphBuilder, nvidiaVideoDecClsid, "NVIDIA Video Decoder"); + /// } + /// else + /// { + /// // use another filter... + /// } + /// + /// + /// + /// Thrown if graphBuilder is null + /// Thrown if errors occur when the filter is add to the graph + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static IBaseFilter AddFilterFromClsid(IGraphBuilder graphBuilder, Guid clsid, string name) + { + int hr = 0; + IBaseFilter filter = null; + + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + try + { + Type type = Type.GetTypeFromCLSID(clsid); + filter = (IBaseFilter) Activator.CreateInstance(type); + + hr = graphBuilder.AddFilter(filter, name); + DsError.ThrowExceptionForHR(hr); + } + catch + { + if (filter != null) + { + Marshal.ReleaseComObject(filter); + filter = null; + } + } + + return filter; + } + + /// + /// Add a filter to a DirectShow Graph using its name + /// + /// the IGraphBuilder interface of the graph + /// the filter category (see DirectShowLib.FilterCategory) + /// the filter name (case-sensitive) + /// an instance of the filter if the method successfully created it, null if not + /// This sample shows how to programmatically add a NVIDIA Video decoder filter to a graph + /// + /// filter = FilterGraphTools.AddFilterByName(graphBuilder, FilterCategory.LegacyAmFilterCategory, "NVIDIA Video Decoder"); + /// + /// + /// Thrown if graphBuilder is null + /// Thrown if errors occur when the filter is add to the graph + + public static IBaseFilter AddFilterByName(IGraphBuilder graphBuilder, Guid deviceCategory, string friendlyName) + { + int hr = 0; + IBaseFilter filter = null; + + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + DsDevice[] devices = DsDevice.GetDevicesOfCat(deviceCategory); + + for(int i = 0; i < devices.Length; i++) + { + if (!devices[i].Name.Equals(friendlyName)) + continue; + + hr = (graphBuilder as IFilterGraph2).AddSourceFilterForMoniker(devices[i].Mon, null, friendlyName, out filter); + DsError.ThrowExceptionForHR(hr); + + break; + } + + return filter; + } + + /// + /// Add a filter to a DirectShow Graph using its Moniker's device path + /// + /// the IGraphBuilder interface of the graph + /// a moniker path + /// the name to use for the filter in the graph + /// an instance of the filter if the method successfully creates it, null if not + /// This sample shows how to programmatically add a NVIDIA Video decoder filter to a graph + /// + /// string devicePath = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{71E4616A-DB5E-452B-8CA5-71D9CC7805E9}"; + /// filter = FilterGraphTools.AddFilterByDevicePath(graphBuilder, devicePath, "NVIDIA Video Decoder"); + /// + /// + /// Thrown if graphBuilder is null + /// Thrown if errors occur when the filter is add to the graph + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static IBaseFilter AddFilterByDevicePath(IGraphBuilder graphBuilder, string devicePath, string name) + { + int hr = 0; + IBaseFilter filter = null; +#if USING_NET11 + UCOMIBindCtx bindCtx = null; + UCOMIMoniker moniker = null; +#else + IBindCtx bindCtx = null; + IMoniker moniker = null; +#endif + int eaten; + + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + try + { + hr = NativeMethods.CreateBindCtx(0, out bindCtx); + Marshal.ThrowExceptionForHR(hr); + + hr = NativeMethods.MkParseDisplayName(bindCtx, devicePath, out eaten, out moniker); + Marshal.ThrowExceptionForHR(hr); + + hr = (graphBuilder as IFilterGraph2).AddSourceFilterForMoniker(moniker, bindCtx, name, out filter); + DsError.ThrowExceptionForHR(hr); + } + catch + { + // An error occur. Just returning null... + } + finally + { + if (bindCtx != null) Marshal.ReleaseComObject(bindCtx); + if (moniker != null) Marshal.ReleaseComObject(moniker); + } + + return filter; + } + + /// + /// Find a filter in a DirectShow Graph using its name + /// + /// the IGraphBuilder interface of the graph + /// the filter name to find (case-sensitive) + /// an instance of the filter if found, null if not + /// + /// Thrown if graphBuilder is null + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static IBaseFilter FindFilterByName(IGraphBuilder graphBuilder, string filterName) + { + int hr = 0; + IBaseFilter filter = null; + IEnumFilters enumFilters = null; + + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + hr = graphBuilder.EnumFilters(out enumFilters); + if (hr == 0) + { + IBaseFilter[] filters = new IBaseFilter[1]; + + while (enumFilters.Next(filters.Length, filters, IntPtr.Zero) == 0) + { + FilterInfo filterInfo; + + hr = filters[0].QueryFilterInfo(out filterInfo); + if (hr == 0) + { + if (filterInfo.pGraph != null) + Marshal.ReleaseComObject(filterInfo.pGraph); + + if (filterInfo.achName.Equals(filterName)) + { + filter = filters[0]; + break; + } + } + + Marshal.ReleaseComObject(filters[0]); + } + Marshal.ReleaseComObject(enumFilters); + } + + return filter; + } + + /// + /// Find a filter in a DirectShow Graph using its CLSID + /// + /// the IGraphBuilder interface of the graph + /// the CLSID to find + /// an instance of the filter if found, null if not + /// + /// Thrown if graphBuilder is null + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static IBaseFilter FindFilterByClsid(IGraphBuilder graphBuilder, Guid filterClsid) + { + int hr = 0; + IBaseFilter filter = null; + IEnumFilters enumFilters = null; + + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + hr = graphBuilder.EnumFilters(out enumFilters); + if (hr == 0) + { + IBaseFilter[] filters = new IBaseFilter[1]; + + while (enumFilters.Next(filters.Length, filters, IntPtr.Zero) == 0) + { + Guid clsid; + + hr = filters[0].GetClassID(out clsid); + + if ((hr == 0) && (clsid == filterClsid)) + { + filter = filters[0]; + break; + } + + Marshal.ReleaseComObject(filters[0]); + } + Marshal.ReleaseComObject(enumFilters); + } + + return filter; + } + + /// + /// Render a filter's pin in a DirectShow Graph + /// + /// the IGraphBuilder interface of the graph + /// the filter containing the pin to render + /// the pin name + /// true if rendering is a success, false if not + /// + /// + /// hr = graphBuilder.AddSourceFilter(@"foo.avi", "Source Filter", out filter); + /// DsError.ThrowExceptionForHR(hr); + /// + /// if (!FilterGraphTools.RenderPin(graphBuilder, filter, "Output")) + /// { + /// // Something went wrong... + /// } + /// + /// + /// Thrown if graphBuilder or source is null + /// This method assumes that the filter is part of the given graph + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static bool RenderPin(IGraphBuilder graphBuilder, IBaseFilter source, string pinName) + { + int hr = 0; + + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + if (source == null) + throw new ArgumentNullException("source"); + + IPin pin = DsFindPin.ByName(source, pinName); + + if (pin != null) + { + hr = graphBuilder.Render(pin); + Marshal.ReleaseComObject(pin); + + return (hr >= 0); + } + + return false; + } + + /// + /// Disconnect all pins on a given filter + /// + /// the filter on which to disconnect all the pins + /// Thrown if filter is null + /// Thrown if errors occured during the disconnection process + /// Both input and output pins are disconnected + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static void DisconnectPins(IBaseFilter filter) + { + int hr = 0; + + if (filter == null) + throw new ArgumentNullException("filter"); + + IEnumPins enumPins; + IPin[] pins = new IPin[1]; + + hr = filter.EnumPins(out enumPins); + DsError.ThrowExceptionForHR(hr); + + try + { + while (enumPins.Next(pins.Length, pins, IntPtr.Zero) == 0) + { + try + { + hr = pins[0].Disconnect(); + DsError.ThrowExceptionForHR(hr); + } + finally + { + Marshal.ReleaseComObject(pins[0]); + } + } + } + finally + { + Marshal.ReleaseComObject(enumPins); + } + } + + /// + /// Disconnect pins of all the filters in a DirectShow Graph + /// + /// the IGraphBuilder interface of the graph + /// Thrown if graphBuilder is null + /// Thrown if the method can't enumerate its filters + /// This method doesn't throw an exception if an error occurs during pin disconnections + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static void DisconnectAllPins(IGraphBuilder graphBuilder) + { + int hr = 0; + IEnumFilters enumFilters; + + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + hr = graphBuilder.EnumFilters(out enumFilters); + DsError.ThrowExceptionForHR(hr); + + try + { + IBaseFilter[] filters = new IBaseFilter[1]; + + while (enumFilters.Next(filters.Length, filters, IntPtr.Zero) == 0) + { + try + { + DisconnectPins(filters[0]); + } + catch{} + Marshal.ReleaseComObject(filters[0]); + } + } + finally + { + Marshal.ReleaseComObject(enumFilters); + } + } + + /// + /// Remove and release all filters from a DirectShow Graph + /// + /// the IGraphBuilder interface of the graph + /// Thrown if graphBuilder is null + /// Thrown if the method can't enumerate its filters + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static void RemoveAllFilters(IGraphBuilder graphBuilder) + { + int hr = 0; + IEnumFilters enumFilters; + ArrayList filtersArray = new ArrayList(); + + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + hr = graphBuilder.EnumFilters(out enumFilters); + DsError.ThrowExceptionForHR(hr); + + try + { + IBaseFilter[] filters = new IBaseFilter[1]; + + while (enumFilters.Next(filters.Length, filters, IntPtr.Zero) == 0) + { + filtersArray.Add(filters[0]); + } + } + finally + { + Marshal.ReleaseComObject(enumFilters); + } + + foreach(IBaseFilter filter in filtersArray) + { + hr = graphBuilder.RemoveFilter(filter); + Marshal.ReleaseComObject(filter); + } + } + + /// + /// Save a DirectShow Graph to a GRF file + /// + /// the IGraphBuilder interface of the graph + /// the file to be saved + /// Thrown if graphBuilder is null + /// Thrown if errors occur during the file creation + /// + /// This method overwrites any existing file + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static void SaveGraphFile(IGraphBuilder graphBuilder, string fileName) + { + int hr = 0; + IStorage storage = null; +#if USING_NET11 + UCOMIStream stream = null; +#else + IStream stream = null; +#endif + + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + try + { + hr = NativeMethods.StgCreateDocfile( + fileName, + STGM.Create | STGM.Transacted | STGM.ReadWrite | STGM.ShareExclusive, + 0, + out storage + ); + + Marshal.ThrowExceptionForHR(hr); + + hr = storage.CreateStream( + @"ActiveMovieGraph", + STGM.Write | STGM.Create | STGM.ShareExclusive, + 0, + 0, + out stream + ); + + Marshal.ThrowExceptionForHR(hr); + + hr = (graphBuilder as IPersistStream).Save(stream, true); + Marshal.ThrowExceptionForHR(hr); + + hr = storage.Commit(STGC.Default); + Marshal.ThrowExceptionForHR(hr); + } + finally + { + if (stream != null) + Marshal.ReleaseComObject(stream); + if (storage != null) + Marshal.ReleaseComObject(storage); + } + } + + /// + /// Load a DirectShow Graph from a file + /// + /// the IGraphBuilder interface of the graph + /// the file to be loaded + /// Thrown if graphBuilder is null + /// Thrown if the given file is not a valid graph file + /// Thrown if errors occur during loading + /// + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static void LoadGraphFile(IGraphBuilder graphBuilder, string fileName) + { + int hr = 0; + IStorage storage = null; +#if USING_NET11 + UCOMIStream stream = null; +#else + IStream stream = null; +#endif + + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + try + { + if (NativeMethods.StgIsStorageFile(fileName) != 0) + throw new ArgumentException(); + + hr = NativeMethods.StgOpenStorage( + fileName, + null, + STGM.Transacted | STGM.Read | STGM.ShareDenyWrite, + IntPtr.Zero, + 0, + out storage + ); + + Marshal.ThrowExceptionForHR(hr); + + hr = storage.OpenStream( + @"ActiveMovieGraph", + IntPtr.Zero, + STGM.Read | STGM.ShareExclusive, + 0, + out stream + ); + + Marshal.ThrowExceptionForHR(hr); + + hr = (graphBuilder as IPersistStream).Load(stream); + Marshal.ThrowExceptionForHR(hr); + } + finally + { + if (stream != null) + Marshal.ReleaseComObject(stream); + if (storage != null) + Marshal.ReleaseComObject(storage); + } + } + + /// + /// Check if a DirectShow filter can display Property Pages + /// + /// A DirectShow Filter + /// Thrown if filter is null + /// + /// true if the filter has Property Pages, false if not + /// + /// This method is intended to be used with ShowFilterPropertyPage + /// + + public static bool HasPropertyPages(IBaseFilter filter) + { + if (filter == null) + throw new ArgumentNullException("filter"); + + return ((filter as ISpecifyPropertyPages) != null); + } + + /// + /// Display Property Pages of a given DirectShow filter + /// + /// A DirectShow Filter + /// A hwnd handle of a window to contain the pages + /// Thrown if filter is null + /// + /// + /// You can check if a filter supports Property Pages with the HasPropertyPages method.
+ /// Warning : This method is blocking. It only returns when the Property Pages are closed. + ///
+ /// This sample shows how to check if a filter supports Property Pages and displays them + /// + /// if (FilterGraphTools.HasPropertyPages(myFilter)) + /// { + /// FilterGraphTools.ShowFilterPropertyPage(myFilter, myForm.Handle); + /// } + /// + /// + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static void ShowFilterPropertyPage(IBaseFilter filter, IntPtr parent) + { + int hr = 0; + FilterInfo filterInfo; + DsCAUUID caGuid; + object[] objs; + + if (filter == null) + throw new ArgumentNullException("filter"); + + if (HasPropertyPages(filter)) + { + hr = filter.QueryFilterInfo(out filterInfo); + DsError.ThrowExceptionForHR(hr); + + if (filterInfo.pGraph != null) + Marshal.ReleaseComObject(filterInfo.pGraph); + + hr = (filter as ISpecifyPropertyPages).GetPages(out caGuid); + DsError.ThrowExceptionForHR(hr); + + try + { + objs = new object[1]; + objs[0] = filter; + + hr = NativeMethods.OleCreatePropertyFrame( + parent, 0, 0, + filterInfo.achName, + objs.Length, objs, + caGuid.cElems, caGuid.pElems, + 0, 0, + IntPtr.Zero + ); + DsError.ThrowExceptionForHR(hr); + } + finally + { + Marshal.FreeCoTaskMem(caGuid.pElems); + } + } + } + + /// + /// Check if a COM Object is available + /// + /// The CLSID of this object + /// This sample shows how to check if the MPEG-2 Demultiplexer filter is available + /// + /// if (FilterGraphTools.IsThisComObjectInstalled(typeof(MPEG2Demultiplexer).GUID)) + /// { + /// // Use it... + /// } + /// + /// + /// true if the object is available, false if not + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static bool IsThisComObjectInstalled(Guid clsid) + { + bool retval = false; + + try + { + Type type = Type.GetTypeFromCLSID(clsid); + object o = Activator.CreateInstance(type); + retval = true; + Marshal.ReleaseComObject(o); + } + catch{} + + return retval; + } + + /// + /// Check if the Video Mixing Renderer 9 Filter is available + /// + /// + /// + /// This method uses IsThisComObjectInstalled internally + /// + /// true if VMR9 is present, false if not + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static bool IsVMR9Present() + { + return IsThisComObjectInstalled(typeof(VideoMixingRenderer9).GUID); + } + + /// + /// Check if the Video Mixing Renderer 7 Filter is available + /// + /// + /// + /// This method uses IsThisComObjectInstalled internally + /// + /// true if VMR7 is present, false if not + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static bool IsVMR7Present() + { + return IsThisComObjectInstalled(typeof(VideoMixingRenderer).GUID); + } + + /// + /// Connect pins from two filters + /// + /// the IGraphBuilder interface of the graph + /// the upstream filter + /// the upstream filter pin name + /// the downstream filter + /// the downstream filter pin name + /// indicate if the method should use DirectShow's Intelligent Connect + /// Thrown if graphBuilder, upFilter or downFilter are null + /// Thrown if pin names are not found in filters + /// Thrown if pins can't connect + /// + /// If useIntelligentConnect is true, this method can add missing filters between the two pins.
+ /// If useIntelligentConnect is false, this method works only if the two media types are compatible. + ///
+ + public static void ConnectFilters(IGraphBuilder graphBuilder, IBaseFilter upFilter, string sourcePinName, IBaseFilter downFilter, string destPinName, bool useIntelligentConnect) + { + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + if (upFilter == null) + throw new ArgumentNullException("upFilter"); + + if (downFilter == null) + throw new ArgumentNullException("downFilter"); + + IPin sourcePin, destPin; + + sourcePin = DsFindPin.ByName(upFilter, sourcePinName); + if (sourcePin == null) + throw new ArgumentException("The source filter has no pin called : " + sourcePinName, sourcePinName); + + destPin = DsFindPin.ByName(downFilter, destPinName); + if (destPin == null) + throw new ArgumentException("The downstream filter has no pin called : " + destPinName, destPinName); + + try + { + ConnectFilters(graphBuilder, sourcePin, destPin, useIntelligentConnect); + } + finally + { + Marshal.ReleaseComObject(sourcePin); + Marshal.ReleaseComObject(destPin); + } + } + + /// + /// Connect pins from two filters + /// + /// the IGraphBuilder interface of the graph + /// the source (upstream / output) pin + /// the destination (downstream / input) pin + /// indicates if the method should use DirectShow's Intelligent Connect + /// Thrown if graphBuilder, sourcePin or destPin are null + /// Thrown if pins can't connect + /// + /// If useIntelligentConnect is true, this method can add missing filters between the two pins.
+ /// If useIntelligentConnect is false, this method works only if the two media types are compatible. + ///
+ + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] + public static void ConnectFilters(IGraphBuilder graphBuilder, IPin sourcePin, IPin destPin, bool useIntelligentConnect) + { + int hr = 0; + + if (graphBuilder == null) + throw new ArgumentNullException("graphBuilder"); + + if (sourcePin == null) + throw new ArgumentNullException("sourcePin"); + + if (destPin == null) + throw new ArgumentNullException("destPin"); + + if (useIntelligentConnect) + { + hr = graphBuilder.Connect(sourcePin, destPin); + DsError.ThrowExceptionForHR(hr); + } + else + { + hr = graphBuilder.ConnectDirect(sourcePin, destPin, null); + DsError.ThrowExceptionForHR(hr); + } + } + + } + + #region Unmanaged Code declarations + + [Flags] + internal enum STGM + { + Read = 0x00000000, + Write = 0x00000001, + ReadWrite = 0x00000002, + ShareDenyNone = 0x00000040, + ShareDenyRead = 0x00000030, + ShareDenyWrite = 0x00000020, + ShareExclusive = 0x00000010, + Priority = 0x00040000, + Create = 0x00001000, + Convert = 0x00020000, + FailIfThere = 0x00000000, + Direct = 0x00000000, + Transacted = 0x00010000, + NoScratch = 0x00100000, + NoSnapShot = 0x00200000, + Simple = 0x08000000, + DirectSWMR = 0x00400000, + DeleteOnRelease = 0x04000000, + } + + [Flags] + internal enum STGC + { + Default = 0, + Overwrite = 1, + OnlyIfCurrent = 2, + DangerouslyCommitMerelyToDiskCache = 4, + Consolidate = 8 + } + + [Guid("0000000b-0000-0000-C000-000000000046"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + internal interface IStorage + { + [PreserveSig] + int CreateStream( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, + [In] STGM grfMode, + [In] int reserved1, + [In] int reserved2, +#if USING_NET11 + [Out] out UCOMIStream ppstm +#else + [Out] out IStream ppstm +#endif + ); + + [PreserveSig] + int OpenStream( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, + [In] IntPtr reserved1, + [In] STGM grfMode, + [In] int reserved2, +#if USING_NET11 + [Out] out UCOMIStream ppstm +#else + [Out] out IStream ppstm +#endif + ); + + [PreserveSig] + int CreateStorage( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, + [In] STGM grfMode, + [In] int reserved1, + [In] int reserved2, + [Out] out IStorage ppstg + ); + + [PreserveSig] + int OpenStorage( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, + [In] IStorage pstgPriority, + [In] STGM grfMode, + [In] int snbExclude, + [In] int reserved, + [Out] out IStorage ppstg + ); + + [PreserveSig] + int CopyTo( + [In] int ciidExclude, + [In] Guid[] rgiidExclude, + [In] string[] snbExclude, + [In] IStorage pstgDest + ); + + [PreserveSig] + int MoveElementTo( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, + [In] IStorage pstgDest, + [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsNewName, + [In] STGM grfFlags + ); + + [PreserveSig] + int Commit([In] STGC grfCommitFlags); + + [PreserveSig] + int Revert(); + + [PreserveSig] + int EnumElements( + [In] int reserved1, + [In] IntPtr reserved2, + [In] int reserved3, + [Out, MarshalAs(UnmanagedType.Interface)] out object ppenum + ); + + [PreserveSig] + int DestroyElement([In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName); + + [PreserveSig] + int RenameElement( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsOldName, + [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsNewName + ); + + [PreserveSig] + int SetElementTimes( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, +#if USING_NET11 + [In] FILETIME pctime, + [In] FILETIME patime, + [In] FILETIME pmtime +#else + [In] System.Runtime.InteropServices.ComTypes.FILETIME pctime, + [In] System.Runtime.InteropServices.ComTypes.FILETIME patime, + [In] System.Runtime.InteropServices.ComTypes.FILETIME pmtime +#endif + ); + + [PreserveSig] + int SetClass([In, MarshalAs(UnmanagedType.LPStruct)] Guid clsid); + + [PreserveSig] + int SetStateBits( + [In] int grfStateBits, + [In] int grfMask + ); + + [PreserveSig] + int Stat( +#if USING_NET11 + [Out] out STATSTG pStatStg, +#else + [Out] out System.Runtime.InteropServices.ComTypes.STATSTG pStatStg, +#endif + [In] int grfStatFlag + ); + } + + internal sealed class NativeMethods + { + private NativeMethods(){} + + [DllImport("ole32.dll")] +#if USING_NET11 + public static extern int CreateBindCtx(int reserved, out UCOMIBindCtx ppbc); +#else + public static extern int CreateBindCtx(int reserved, out IBindCtx ppbc); +#endif + + [DllImport("ole32.dll")] +#if USING_NET11 + public static extern int MkParseDisplayName(UCOMIBindCtx pcb, [MarshalAs(UnmanagedType.LPWStr)] string szUserName, out int pchEaten, out UCOMIMoniker ppmk); +#else + public static extern int MkParseDisplayName(IBindCtx pcb, [MarshalAs(UnmanagedType.LPWStr)] string szUserName, out int pchEaten, out IMoniker ppmk); +#endif + + [DllImport("oleaut32.dll", CharSet=CharSet.Unicode, ExactSpelling=true)] + public static extern int OleCreatePropertyFrame( + [In] IntPtr hwndOwner, + [In] int x, + [In] int y, + [In, MarshalAs(UnmanagedType.LPWStr)] string lpszCaption, + [In] int cObjects, + [In, MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.IUnknown)] object[] ppUnk, + [In] int cPages, + [In] IntPtr pPageClsID, + [In] int lcid, + [In] int dwReserved, + [In] IntPtr pvReserved + ); + + [DllImport("ole32.dll", CharSet=CharSet.Unicode, ExactSpelling=true)] + public static extern int StgCreateDocfile( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, + [In] STGM grfMode, + [In] int reserved, + [Out] out IStorage ppstgOpen + ); + + [DllImport("ole32.dll", CharSet=CharSet.Unicode, ExactSpelling=true)] + public static extern int StgIsStorageFile([In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName); + + [DllImport("ole32.dll", CharSet=CharSet.Unicode, ExactSpelling=true)] + public static extern int StgOpenStorage( + [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, + [In] IStorage pstgPriority, + [In] STGM grfMode, + [In] IntPtr snbExclude, + [In] int reserved, + [Out] out IStorage ppstgOpen + ); + + } + #endregion + +} diff --git a/Samples/Misc/Toolkit/doc/Documentation.chm b/Samples/Misc/Toolkit/doc/Documentation.chm new file mode 100644 index 0000000000000000000000000000000000000000..70a15c7ab4a6de21528d468baf10870e28392b31 GIT binary patch literal 28420 zcmeFZWpEuylP-M3%*-r{nVFfHnVG=?i~f1XVIMc;oL{V1UJf6{*)B~_Faev4E-D)evWM}OcC z@|*YTqx@$5F2B!z^PoO_vPuBfr6Za_%6j_Kr{B82<^L)Qvf?tq;J>y07axfJqX9`z zA}OLFA)*8n+OL=UM^i=U!-EeI6g`Quijt(9xH3>!x^J-EM^|M{Wff6bfWKOvz(-3( zUid>7D0EM+5b=+uf~4?A-!QvC!jGn^lFWxXP*{vu6vv-U6(Jd*uqgNdjt|S~l5!&Q z>dHXDTgv`2F!ZEil4dTJvWAv+Kp~w1{vr5K^rZ4aQj&7YDnKD6K*{`Q^rY(Qg3iwN z#+HUImTsmpmUh<8zbAnA-wG6*>>W&nv)GWicZ^#8&XQgJdh z1q$9F=#lwjwEv_bV(4NB6q08htbzJp6lDz^KE@Ho#`-Uke{(~ZP=H><(#h1=McKmM zUB=RgPSwTI#+gpc(#FNqN!-cM!9vB}{(~WCV)7?X$Wz4B&C=LZ!O+Em&cemk2FSmM zK7*d?e{4q1(AM-X18aKe2E6}617c40w!${fmL`AMxaZ4O6Zv~KgzfF@K4$#qe4O>| z-AtWq>NGOY0<$FQl=^b2+Y)yZ=M`vzn z_R&Wn@8BfwoOjsN6)6$*tz<>LDNrKId&XlzRVd)dlZI=cV>JQV-VS9Y;?`dE-3 zBYZ3shmRO{HZ`IDxGTGSxCbae_fI3H`CHwc>}`Gz2C%}V{6F^p@W@Wm&deTQ1WEsY z?5yHsXy*tWJ~}K04IP2zyP5ApdtWf0OQ9Qfe;lS@|2(xq{*%)DR{AK%;(yZL z*%@d6C}39=K?Dkb4v>%#Bvkv@3w~_72wCXZS?D;}8JIrgq<`c{e(U`9UYi8$PnVbKP{#N-9xBt@rhx~)UKM4GT zz&{B5gTOxs{DZ(h2>gS2_O;?Py+W3 znqnfoUP_ig_BvcwL^oPzlOgM5$UPL7zP%oYafH}TIoNFaa50ZCV%6S6UrYuH;qj$@^wz=BpmnUXf$S*enM-&?7Lr2UWtwyTV@NpC6QF|%S$lVnUuV|r0OX=@@TpLIi+ zGS6Znc3suzWgQltz&1&}Vo_#%Aj!)OaE8m0T4bUW;xgB&Nyb7fOFQgoahXhwO$&^4 zzqJ>^rJ=sj7Bll1IfqXYAJbWDF*P$uL0?7vB(Co2ZS2s^Gv;%P9#rWvr=qC5X)sPV zUab>~C2yMwrDZ7@BjKVK_6hi`#SUF%M^bFUb?QqzXr+>AW@3o|ltiOpqDLE-_6QH; z9n^Wk8+7&M7iW>GQk?_(S8hrXy5AG*v z^g|9N8Q9dfVg~HxyRE8H^4g8;454^bQe&@gvAeZ?hN}~Ojaq0PGgP8$3-t}k&RA)_ z&4F-8^vY?+3HFhJV=8=<_>&nM@R-(WhMb&vZ0uTWQ@h-^=;mwzJN%rNvhc@-V?Vsj z^(G)Ez0hm3)bHTxzn>OLH#XIdrjPZJ)c7;OZren)*ngL&>$c987E(5Yblo}bTnDA5gO5IyB-s->!dO){Ctv0aP-WQyP+xwV)&w(2JPvk zj{s~!>pp{?&DN!oEs!{;(kgbcaeCvd>AGZ$5^~SGyeJe4%H*NM{j|=Uo$eBA4nj?} zg<&UuzLHY`DHtQ+>;`y@4t#8MH6ww!@`H{CD{1xk;DYUwuwPd=Wmq5Et=ZtL4e!8!s=ZL_zo6 z^JxHPMHk@ZmKHrn4_s;YQhZmbYJ^l5uzbF;fGnZv16#VJM{xIuElRZp>vSTSVUi!>kzG)hJ0-s|Ulb5UkoWoT-cg7*NYhj58>mDuPYWD5zieZf zC|KN(e?;_#+Nh|Bvx0z|X`H#K(ne6qhkgv$W+&PXn6!(*6?OBxP3gjKXtkwHM4ARY zI9w{Qv)&0`ojXzb zx`GVCG43lJ*eyI$6hUtHm9V7XC07K_Aepl_Gv^Jdp=rCnfxFc%DjGrdD+<-qtiHt= z;#_rPaW><-_p%Q~+#_t5np=QVDQqTvR6-6mkQI^Li#o;kmF8Us$@g!MgYqOl(D!si zH?DIeAKokzV8(`}3sXoX<%GehNnU73sVu&ektLEP5GEuIB_QpKl4euB*qwcO0>yC7 z2Vxiv^2wChcVCIGDFJt+#FR`@Z)12&*0vGT8-#oFi_{AQV;W5PN>^NTs4z#Sc~D?4 zO2KcM!KH96L@XMCC+#JhfVDzpLg!Z18_jsqlVnjoOhd)*%43v{3<)Z}j?UpG-eu1m&*(n*3wCV!vsPD4ecS6QycvN& zu8~j}t8X(v{t#1_skOr?Xpb5eJbK8rwGV9yYnCXQ&2gc8$d>`sApkKr^b*%cgrg^( z$R^lB+mPbA%d|kw@=E>DE$w(g8$blyS^_h6mt}>6;~#;}jSxx z>%Jnm6A`f+Y?1c(zN{*8ZN;9prqF)cMG(`@k264)I=*@>1PmI}boxlsR>5WImR!ZT zJ0BurnQ%MCMrft!Ykf*?_xfn|U~q|rB`evu`{zWuhKAv$r10~Y^LlhwuyMA=hFG4f zGWa%~aN!zBH>@kp9}F)-Q{NoDuL9v642&cpo!P_yN`Mv-5F#+j;y5A*XyM6Q|IbMl z(F{RobGsoCmstY7J$qSON4j6{(>^6OU@;HdD=i~Syw!PtLGN(Pn<vHxUmi_;L2^{ja^5$;=%sUS%-R8mOO3|hGu2!T01TOg6l zWe=-lcFYD9X+$>;u$Xo`&`-$2cfm0F2J9Xr4Ecm{$|kypadaW<`zx`&@1T{k6f+=C z8@(@u0VPD10k33ZMs7HFG8Bnq&%!y^0T1oi=r!bQK9HEpYEvH*SDZ3mLqYB#z@fiy zn@bCM5MJ9jdAi^e5#w4PGj6221)k`FRnst3J8C4Y%xIg-0F@)UF4e2NNI^P#uBS-+k!KU7cu zdV)3JN0&AJBL=)hP-pVZ)hZA)<33qYL8~Dm)AYqx!+0i{aA2_s3Dxu$={Pnh&G{?I zSt;um#Lk~uQS%&;5~SjvU7&fV&st8eW_z1j0fldPKk@OUPB^_kef!es5kLfW%rSoi zD&I_E~aOQId{!=M9+ zeIBmChH7u7n6WfS&;0GY1}Wavj90N_x*t+fdl=EVcp6l?U}O0|$8jy^*6PW7TpoJA zr8jz%khVfRTz;l+zTP}vkLR4*Agj|(lXeF`KS9Z3GaDxYRwf9m;@WP|+%oZTj<%dP zhr=IncgJk9{$9-#gQ$Z#Dc+=p<}^$5LxaWYp(}6bWSE;;yv)lO%X7~g%Kvo3)!wO> zg*QC*av5@4T{0<{9pnY`&l+Zp&esDDv+|4PIl8JiCpV#U0*uiKG5f( zJ;}R}QyBRnDEz3^XTrm*SZ@CSSseIv7$lUOizJk{@260$s3}rl*)uR+8r_O3tEW`y zC_Ts&C=AiLn3)I)K8Rn{-Pn-l@)Me4Ki}W#58e}0lX~gHm#9Djco^MNGZ78^P9w*Ph)HR70^h$fP7qjWLZZg1d6eA=lrgf$RH`+D#45F ztYsx5wL-GS>Z>Quf*8+`E3G5y4ulUo5#C;6N>Y-mMqENx`UoOUqmG4Ek5v@3ose`p zjZ3**3+2`fo;G8+dZgr%aC8c)WE}hvLH-cC@z{KFqjxJN$sLXFWz&to&BJD5K;u!Y z|GuHb@aC@izM!PjgPeGx=KXv@;HBP-LtL9MDbO|CkLKS`VHJRqmgqO<*RM)K;+cg* zrC310ZaD!@qTwaiq_zZ+T<)4>1J>jp%>psSA`PS-OhFEG28yTMpl(9fPz#FP8o@KFJI}^c}n)Nw+ls03two zA1FGCauF(DN6j(zqbJ>B1hh)88OMfyd18QS<;JSK3}!~SyZs~@2Yqcz5M!Dtk+HR+ zVPD$ErxCpDL9s+Rs08_i_w#L=)G#z=zPEd}mRq{dXO1;pB}(%_xF8H5wT;Eu^7Qkm zS0ac;|1|iOa;7wUy8yTOd^<=uhw{grbucw_Vv3M>e4opZvdgt9i~?!UfVT-vcXU6d z_sbv)v`&9M)4GbyD{M~i{3n?ZUd(Uo$Zx^MZ}g%GFi3V}t?^|Cgy;ajC?}h;d($I| zNeQLlv{Jd+Eu+Uvzb~RmjodK>(-~LRF|&B_4*Jx1Z)~iBESoR6Wh0we{*9{WoK2l7 z!>GR|CGT=Qdg!Y=U20-S3tc>T@4Tn-ydTat9%gKlf82Wofgj_&sG`TtwrF5RsZ&D?mH2YMtzmK zx|U)!c1||?4wy{!o}CO$Cr)(_21;38&oa0@9S1s`vhOZbV6rjPSlq9THnMNujs*`o zwo~3Db>@1T!WpBAX%-s`guYs;| z<@QvYk^K7soKWDRB1jw_H8e)&mrlsCyF^nkPd$!-fY;p6Nc*qs6#8$)kuu(;R3!aO z7UCEi;Ks+U6KwWnTbSvAzgA^R7G_psHW?G73IG5BFeG9g1bQFLfS>Ge-*Z3y3L^p= z<~k$~KrKi`i*K#U6L~nH_oULd5!3;(zs0zd_7=>^-r{qc@>FwwKZUlMdyn$T%W~E; zw#udR$cM7rZcOXh?cgrY0Ch-n9!3BsqSXNg8=*P6bu)rCReQqJW_4#M(yk$Yg&ETm z@sk0EU&aoAJf*UQwEJli*f>-*aC8vP0^DnKfVClACI{NJcNqMI!QQ?SVu1XYv6#~+ z`^LUc*9lvnPHVdn-WD$UUEA#(&UT}Km~*Isz2jCrV2NR0gT2JX_(w!A6^z@?j#qOuZX=~NOZX7Q0!Ep5sKP~ zQvR>75W80in^C69=zM|s1o+QsDLG5*=O<55=&_&3iO?m|C9FD`aNeEX=dIU-T{qIM zMR3AYcOf7L0WBBa262SJ(q=@Mj{BD6*Cu}H?a=&G9Q2+;%p&ivPSS#4;5!mS?$WKRUJk1CSWy5(k=lAxuuSjG!Y0hqpp;Yb55 zz!$-+kK<}{JIxTmQ26?2Oq^+QJ;yrVXgJ*JY;IZri4nadv-yRAlKiZjH2jSawHvpO z6rchJ2pnV6!klPF&2^%x{{4Q9nDIqiF(xoWZ2ovZWU06?r{zykPq$EUrG!JLY^B;mG{ET{QfqiuQV zsc4z)Vx4w1p^~2G#)fnAh3|!z#`zs81u-%WMHsvc5)c~V4Hz)ApAc24$`=J75fu?o zAQ2t`0AvWjLIjYT3$VcRx9>%lE2mlU&mwfk}_kP7&Cv#7!f z8t@CQy}NzOc~jr+plNt=(o(C@ykP-L%X)drj7T6o-VY2BQG$ggkdzcqfgm8@K>+y( z5l6TfM?dTXx{7}lr&TXQIuajA4>?90>Ecuy9+#Mc2k(OQjlf(;TlXZR=_iXut3tE` zY5ceb#lR2C5(Gcx_zq3F$?c-Wwdes}mEBfs2O|aIhCGNLt|y^kTp6<(x^dBZ-;#t_ z3fmn}%B023%^jJA$|GdbU0Ck?K~Jaz3mj0|n1LdbH)itia`Od`Q>J82ML48-3tG*S z@x%`l14{&z-AF8cxKO$EI)_dLw{e5==DF;JK*XlS9&%}Wh64pjFWG!jB~95EVpptf zd3Y|9nAEk04#O^?Q3Eb{QIUbtMAFJO>8=-10M5c(~#*3pTOeTZ+R?w%ZV8f=#M%<20zUx=i zj2vFU!@*esimVcLSf5BdKI873MhdEO3|ywLSgR`Uc&L&w(kz;V+tQLCMl+GpvI-Za zx|;%~2|;~l7icRn=rJ5h5u++M51?I5 zJ5IN>&2yySVlXq8g7Iw7z!zU5G|M-jaE`bY!N}xtpcv=vIRB;9L>pH)j$q6`u z98%+ByJ=7=Mc!px>jfLf%Nru!-5%HNVHI42=ftw2#Ngay2k}@S7Pf_tn5HZ=N)#zJ{_HX6dlSc~Rf| zP2^WX?7anWm-&S|A9iB;`>K!ud9LidIZucx``WxPIt#c|mycehqJa>Qa zxE3H1O(I0sSo!Fd8N_5#wx4aU6m!O;AtRavKMz29)*U;K6z&HAYb7IO|KB(M0l# z3^{FeyiM=9#Ge8^eZ)4*$TYvBS_D9Pc}_k9;J8a=ae!!s%l+C{2jXTD4%;%F%d1^DV9n7nB5J>aP|T{l99G$OpEOO^)x7pgNKc6d~q2VQSmeI zjP^QwgVPm~K*e@Vf0jIOPrO#A9?msD9}Q%G=?c*M#A<99_8NXB3BW^BxG-hL4Qw@@b@5Nl=1O;2e>Sdg22U6;>AE#0%j*jb0z zy0YKQOXGFI`evK@wMx0TWK*(4r?Gc}yA~`AMQIR_(^_0Y@T0leMGayNg0^n}SOpzd zoh;)rks^3vZlG?ko&$Y4$%SlAa(DjuYn+RI7_GDgp3i-R6i4-5Vb)W6T#dcgW7<+ni3rFWzQX4LAd{wmQ z!<%{@Vcag&(QparI~cni`vM#j-m){yx=@k5apnY0PFl97ensk+dNvMa&d+K_(pqe~YWE-n z@h!F$-ufyluNo0Pxmx+=OR=W}q6)i&%iP>xAlTUF%(aaxx>bvA-gaKx>dST=QY2_| zRW`R-v+Bq7|HN)lWL$J>$-i>qVWFe8Qxug>Mzpr0Y_wA4Mf)bzQ|wf?awTU4XZ!Y@ z50e3#;L8oH+ew1(iL<6JwN5&<=F-{u znY#WwW1JYQHR)M&NUOK0UrYAsX=yWL-e~6p9f{#Kw@KEi>Wv|8BB&vJvS* z#XHE9vxviBEmYkwo!&%7e+EL!B?aQPm9$}t9bsAHvtYsN7tHN$cb2b?&*pXXtB>VE zudB0MW#gw$#G|4=E`;7@be5Y8`_B!t&f(-vH8bJL$tDjR0YuZed%*tYqC2ttB%zBg z8@%_sh|l`3f!(QXKfi|+p2%moxb3JMZuzabW7l+a^>Zpm5C{dHt>LCt*kdEq zIxL`_RJ;VA+VqG&1bsFnGFUg=?!Bm+y>iSZJ?6qeLp4ors<40oW{sOTG`LQ*qQIuT z1-;=nydMsy*@!Wdgc)o*51X$+UODhwYtGk~;<~DsbvW6R7e90tToVbwh_(s0B-=UM zx<;ekz)Bs_r9u0lqAHV*{X`21GfaB&rji6U7yjdNJ|Ci9&5I=O0ccnp7pUnw_Dz&mk_x>8->vSXdSy9j9k+8 z#w@tj62csO9y*x_;Elz`m&J%iaZ7Y+J&L)pxI#8l`)TZNUM^>3;z5aIaa++)&;I<( zeg`#@9!i)VtUp5d%p_^6g|9Zkkf)YIzo807;dyEm&FsXC;ZI#VJQ&M@oVLZ z!j{cJCM~kWw&xsi@IFuT!OugoJL>oGbrOhGtMo0B+9sfcL?*bIFd$YE(bB4ArFeoW zK+a0-!3~i;lT?>V4wtsR8oNE!6`h1Qq=T-tY*@V5b=zLiq8!5$UB$VF6XRKgDzZgb zSlVMIc{{DZRnwd7(r6dIGva`)RS~&$*w5n#(aBNi5^ZE zzFY%LJ8Srj2_0jlDD<>hkzo@Q=uX+2QthA^xCSdG;&GyGU}YjMz;Dd5PQiw|(0PhT z;I%+CNL8$lV!J`ZhDUzw=+JO;{SZ@2a#Iwd3ofzH4YpT+Z<;8>@1|mqxhUqfV@-6r znb>>j?}$oP;=XU1%LIM$vWZyUaup}fWFw^1Q{%TqFc_#nU72x>jX#aR>Nq4xT%mE? zndx|j8T}p!$k-ZXwDIi6UwQRmA(?}~7m;PG^OX>=%9NSmyUy)^Z{%+CcHDw1MA?{~ zG%~3qZN1%QCX@>yQPPCIgpk10NId1kG{Ji(XPSZY)}t8GxVq60Q$#5-KboYT_6bnD z61DY;GA&2Bvl*Ds73SzZ5%t!Ati#$fk{m>7nlAIDXI=F6^;9?*a=U&S$;D%MfYZNd z&0-QOsf?l39%gRfv(?CZZ;&0c3#Pi>e*Hpf?0&h_7?rGnX@ki+E`T2Oc}VMs`fO#J z0Fg!6I&cIPHaIE|CI0P#y%z*EyAqF8y=)791I!lBMnCyT^!QTB&`jq@Rg!$#H;Fk8w<H*qxpnSPYMx zmKl!{YVo1kWu?bg>74Nj%n8mis`07CuC${#K3^x`9bAjC58-1)rM5DOj#FH#>K=;a z?X^Dt)JO5%WhSafS><=l$+F7|g24-ZWleMdc`o_}`-U|UgqORXq%+R_Q)eQ7Q0?GU z=5h9v>hz@xW-v4v{PUVbUh4Mia_HGx0$gbO6{8V!e8Mi+qNFJ4n(h=j za+&32faO?;X5lq)wF3`h`>PVA#2onc!Oi6J2ho5jqFILCeV4wDGEH$_J z$F5(LtpRR3|+_)iU z>xXSWKiLd**T7t)l1k_wwc0ox?xzR|aP|$GgFqoB*AEOL?EeZksC$h!xI4?rLs~*Y z$zoKUhSjIfJx|?m&f+t~-rgorNE0Wguk3mBg=gnTd;*E)riNfiLR*5S6$vKHZ+K^< z-j4Y+qGOUY5tI(z2snwL_vdfT@t$$V)TCf8p3r^A6S*k^syD4Cp`K@Pe3sUC0AdDC z)>wH{JhX@(-$Q$`rfH7!$1+i2fZAnccW=8mC=+!m)Ds=cMc(hNVX%-U;XdMH&3NR{ zu!i?pr~g_sP15vZ+W?k8K7x~~YzJjU6Xk{`_t9A+lF>Hry8W8x9AmJAQ;kiQ3aa6I z?~O^c>|)BHbcZwR`Z2;48XNx6_vgLzxBE{&SS$=EI#1z0F`?eW^ymO`K>(<5+q~O* z0DMbELtbit5=&Gi6?o4uA>3wyj@KCG>S{MHkix`;enc3sjo1d>)_^URl^vLb&}vwl zfMvB`86difv(3`*PO<?LDo#kmnRF@w_7Rf~}E0^ZeiAQ6{41REUwtOP7H|#OE8ZAGbPSoRbfU}?o{S?6( zuLd?fPzf17AwXNG+%Z5!!zN}VJ6KRaoAxa$b&P`ao|Tv?rGwoovfLsDDx_$#ov zHk1K9U9-Vz@t%E-?#8ps%NyCRV-wKIGTR`uMhi#krK#Vq!pn2%IqX<53!M?@Mw#gc zau6J8@OjMF$%>THPY?OFya#Tj;Z~H-Jv*beyLv^>nTIOceVmGT;30_22i>LRF+#H&k}_1q_=!0A;W5oC7IXoOQ9lL z#Z1AOd>RxvEU@|ntv+%RR7o%U{pEM@hYu=f#McPQPb>xkckwlkb0KrB%D&&u5lV`! z*OzQA*CjQ;X6Zmt1KH@$w1b_r?DM`-#;W`1rG{?!Zpaq$8x07C8e0hp$Qc zy%Na^K^bwi0Am1Q0x~ayei^@u(8pU4w%3dTo52jNT$r*moX10DJ4^lvs`MOA? zLTynYDq3E6W$LC@5Q;JDU>9VVEN5jAWTXZWryjmZOzbYWjD=et;MS~cFj%9UEqmatnTo;&$MT|4c zJTdZ&4Stl1mef}9EFvY`yH&D7YWBCM5Lnzu80XpudY&P9ZcC`d-FNb{BgeLoY2t@) z7ZLRxyM>*xSMS?ErZo=qAK$<{byU}e{Ijrf= z!0Z~Wn(sPOFIc0Py)YQg&GF6Fm&`zXm-GqV#ruJJI}V=~`MMTfY-sHfNGWOk=hw}g@A^Y}wp+hy$EiaDp`_qW@Yp-mo9PL7>k@f+m^(q@1Vlua+^!nAUrSCI z4!rEzQqOB_>YY3A)H{DDDM^T}xji>&ZK*t$yF=GG8FZ%C=WL^DUb3H_R94;7aN^jv z^;~YB>aL_&Z#4;by+IPrJ2_-F&9ew&+^8$JJFI!+41sA}n~hxwIaq0=kb`>f*>+L%QtRG4u+xwXfFS+IvCs2U~m5e+`Uy^gznF1;6a#Eg>Fy zsm)uLiQR}j5lxQOu(yc}^nUar__dXW$>>es{ebJ<8_;#l$JQm7^ZJ(H*!}tS7o7J# zeo)*k<9^ixA|TsS0{jK*DS-aVb{hT@gy;>FQWpmNmajvc==awp$Cii9jZG`X=goT# zRlfJjN&BOh{T`Mle%z-Cjxh3YbNG|+j@I5U6puQu#nA(OhS-jfa!TGg`@01Bqb*0D zLNAX=hu*Z$5RkRQcPbr;24}knl4u@;6NY?!Zyx29yw`=3MjqaTBuDu9)4V@Xid_&% z9lRV6IZY-Cb|3KEVx*^Ca**A=eKYCGNpg7*uA0_gdeMCl=%<`^s9Jv_Jbsar^x?n5 zhVV@I?px&bJg@c|$Wrm^`iC-#)DM`;moMH(8^e^ZqydEKm3ov-{MA>}u2;e2W<KWlH(@p2=}d>nkkO3M2NyP&xJV4f$SQReDC!cIF6O}v95d6K3=hQH3(`t z<~1hRUN76{;L|!l&F#+sNgQ1kVnA33z|9YWaIb5Fv#hQw&m;-r3(t2iUxgEW=ndc- zugLrCGyDMeHJwWqL_xU12yB8{M_Y(aZjR|$xo3|b0T-%cQ!S3~qI9=VYcZLTs>nF4 z&IeO&U{C9)d$YgliOb5U%CO1+EsHtL6_#6CR@RfB5<*3yaKQGuheTsZc;JIDhAU|z zjSn61wn`v`ouQObE*2f;3`dOm=9jaPT>Ukq3rQIsq~~VNN_9XUdFg?$^ghd zgN;R%$968{h2@%lv$p7A`vSGenip*^u!gQ(i0fTg3L+#G?{QBgvSV&#+!E-kEu6?g zyG_mTLSTbexEb-J#R(m+PV)6Ny^cUUd{mnvu@X~@`nQ`R$(7cK_~{=aklm$MZr27@ z&GYABwge-VE2W-je8Zb5eVUG%Tp0a2-(pr!`kI}5lsRH(;EUM_K~mWVfS%83ZpodA z*p8dhxg$Hq5mTaJk8lMKJtAcq_d;$iZc4v7Umy3yWFWP|5}^wF3HEu~!HIHtd&F_) zpUN}V?ILWzapE~TF|}IYXF_kU;VWK)qCn~r?HORr?PjM}H1EV2$Lh;x?|Ki)?M04< zQ1J$He?EyP=dA8SbhlFNB=7~?&>Lrjf}W#l5x{It_TQV%?bkN6*0ge&5Z47$xRl<97m8AHp}qUVGBScTTOXOinHiJ zoCl{AiF*bmY9j7ZAOge)srPNoi#C8`6Px%>%4QuM7oN`;Gsf4c{%1-lEDXnj5^|x7 zo}h<)nZQbX@V`7HoEJUB6Q;IEH!#@(6=2SCLu?5fcz{vK9LsC38o*R~+wg3uDI4 z0lEJo-4X%D3HYVg_Y=w;j$o=YdY{4JZ5)@Z_|9%5B!1iR*Q>;=q67m-V2N{!-6~$1 zErdH;%0rX|@RH8%Jka#ik>zi_A(saZsw?0zu*-@^wK8gQWu6g)zB-GffMRNmcEK0GDAh0xE=c zUi-*BtUJa_oM!ZnFm}q{{exWtq@^?hJ}Hp|TO|*uBo!C&K#re_G`g1VhtiQSH>u-k z;f3vd9%AJN;~vi0q4&!(JlfML$1=+-fNA=&@sf5Xm(8_#a@OtnXexn3TbL$FlnJrh zZ{skfz$*f;lGpj%S*P9Uj&V2tiDP^|FtaJ%iRrtWnso8&!*EZsm%s~^1+T-J4S3!9 z(W8%^;~7%?_cC1w%`XrW3;LqlSIjanpb0i^c9OQP%?;i-ow8qn+1t&GtnHowKSV_? zo^^265sBP+Uy?L{7358;Bv z=n7?GzP;R$k?*wKa;Zj+@!AtEZ2~8xJet?U_*i3LootpoP=HkFAaFG2&q6R zz=sXBcyS{~KfZ0ewH$%U&36^ArmCqVn{HciIMSOK2o!LG2l{ zK{6K3{wRky_0M<{`zJd8`3tu=v2 z(H@9l%eep~(&WSqNpxROzg1|kucjJ5R2WDj_G9u8t&8`_Sk(lcXf1vl8Y(xjb+M26 zT*>77v+dg{J9dZRxs5zNELQu^Ram)4;1}p6pUa4C92!iI4GR47BO`yD6=ngoA2h4I zHyb7jNt-*_>=7-fY_bA{^uN4#s4G_T*Sdm_s`(0?mTE;Gh>{`b(RDL|Q=1cYyA8%F$V*H^rApUeT9wd#dZ2Q~LphhAn<>sZ4W$(r24~j|$3f5B zof--<1h2hP`+ z;^F26ZLB)%SxjNM4)C-(1sgH9ZGirqX&5}Hkb9@rJ1?BCG?m;7lk~|_r6=pT6`gfd zhH4zQX8nqGwK!>qb1GY|b^z0SS;Cuqk2F6aDjKLBicr=V-t{s2si70 zO3`7uP$K88%BRfgbL}h>y_MudUyUxiJfafYnq!+poZt{KHLi?n&my}J{uzK$a`o_6N)9}+5yJ$D~ArbN!IF1Nl67nX@EPVRjS z%jK{WWrQplyvUdhrs+;!zKw!SinA`BUEhJ)>6E2enWF^e>Iqs#69b3c(B>HV}PqQYW%?`&qg0V;w3qJ)!@EVu>Q zkdmb8{%i~srQ(ufx}bXvDbyi#I}Bwy4A4l%l_i86qFPUv$? zMB>~6^>K&7ZA8z*>N_w)S$f~E9k+~)aS~rK%}6sG+M=R%$owu#vf}0*NHrMz_Uyd{ov=M%;)o>T3$ByGp9)%i6 zEoZ^=ll?ks9p*6HrxZvjr&G*{F+}J_B7Z$eVGh!s?mw|p%*JguNw(L|6N0yF3{Iu> z1@yCdX|cGzv$7z}tl$pCte4B!a_tYKNSyWlca%4sSA#TAj|sz(QA!a`7cSJ=A7%wy zCpq!O@AGTvnLVGW#=J5t9Qdet8_L3jHYupDU`X&%U`I5kF(EG-chUI-hj@?NNN?x}0pd=`Ru9Q zz1k@i&-2-kO|5m$)S##zBQb1kEbFZrliYzdWohWGlQbJZZC(8-=a;`p9s5o#^~bKp zEssuqB_o`!Y*(dWbgzvMUkLoTIKfhNDNK$^a%HxhW_sx# zV;ghkv>dH9G?gVEFVAKKg?BZ1plcK-Jj~HNJ$|CV^84aE7YXamC-tuHTk^bvpMQzD z*S+!UoGN0lGaO7z3^m%>8q3=^H2M?&h`qQuRr*M*JJ4r*z6_1Ox_?Mnbwo8UzWEoDw386eKr7Qh^a; zC<8`IjFM7`5z?hdclX#n-{<+h=Xr0x-_5x=|J!qM&i|aVbSj66&o<=>AUk>+_)MoU zLRs@Chd1>0Spbwp;O`BM;+fX-%_4}^BU>ANh>uN&vVgkVXL!z`O!g70MW#vM5bpr# zRm3~`^(d=9PcrcRO3~4gL&JQuN+6S?Bi+lFG+3rk7dixBYz4KJ&Hbi)m`M*CX^o z=vBLAu&Gsx=;E>9g#S@>DMT)>iyEjIPxsY6ss1bcc`=i4; zFnpt2c&|mIR>$J&c>o#S{dtfQs8$v3J%%z_(vUV2N^fs}%+i&-FS4a6U88cg(xgb? z)C*o*_;5IDp7-R4(ab=_-|{+iuug&LC1lgm4NHMLpRqCWHgQ;SW6si;l61718r^pb zqSy%?(SI3ipja^}$Cn7)7Wa*bK+h#R{gldG?mmLiBf>BAA8?p*oHGj=oi+>~#o;=SVUN{>a_sb7gE@2{^sX~s)=z~tLXMu50PP-~FL`Y8 z?#h)3H&x0J0Ypz#U=u6fKxNmZ)_*Qb19a4rUeQvGDR*oR{Yug=GD*pgnOtvQr@Hrx z=_U)BYNb;jqDS4l#71xFtjO8j1H5vnhUP!)2g&itiPg-1p(%YO9gw#WKiXYhln;Jq zXb>AB#1wLC{95yb0dhjO_cDIURx4N$MBrTRzq>$kl8&dSz4w!bRl8{?EUbCwwN10i zV%qak>(v3~1hG_MoZkM6hZ^$snrA1V{q$BNQ?2E`o|8sAcAanh{1$)04dBkp(rPK6 z^Uj<%hFA)x5agsn|RYenGwR1P6AdSm<1=la_ zWv04>s80VU0!xO7X(;oVx|2yEh*aJoBXj<&HJv9FctV=$_0)19LHe@yK5wN<3b5sH zx^bCS|I~z271zUcNIfDP-+pKF4B4-d^8m8Km$mIujWvRgkgzz~l{UZ4j=Ao4S}M1G zUJB=$t)17zJt4L8#Y1E@Q(2!+av zPL+D!u!*L2s%MRt68iB|yGp5Q2HR!S`(7^#Z@pD+t!F>ZaV{^X;6_ZZO{G)<^Z6$H z>T%=DuT8J<{Xib^a=5nl4y)LwtutlmA~arRSx<3QkKpSTp$jn;Hfs%}=b!%c_iijf zF#D0#s9%xfZ(da`VMkkv=VpWK1#l7?tsh8bj5NtsP*p$7nS3C!51ZAJB{eaodXIa- zQnraI1(@Fu+vy@&Nm2O3x)joLhWm+Jj-6p*{uSI?XBl)=5>m;PGo@WdRB(pN`KXrL z%mG?+EIbJc@99Aj&-_+l`0ycU0?Q*kRss3^r~`!r1j^mA>%Ju{NGy#hkXhZG8>^qs zJL23TF73t9(q;xPkWbJWbl}DbRbGZQT?~B9%F)>dxFlBO9*yGXzX3)8YRM`?3uR_d zm^daGiyA}L6EyeUEe7m3RNog5fs%+i2Ijm74NlsnuAh#%$%irTtr7p0GxZ#5{WUt$ zy*+SOf2rub@w?>DuRlCtp!jjX>?NAwsdGS5#eyGN6s`81DY6U-3o2pmzn%{?2nhH_ z*h>L@)3~dqJG5}AYLn7#MFQ0N&4;9uzbU3AbCxn{v#p}RuSj1IF5V5+a^4(D(YWbR z*hNZE{7BlKAHdcvQ{ALA3PlYQ9SxzEpA{T~%4GfezCMM|f3C2s8=oKJJ)-5L{Umw; ziyzVfZlnc9gemFbw?9#Z=_X1pca$m_mJunwcXY^NAF-+!sc;`_LBqd=Q=AAf?X=?y z+mN{pgL*>hg_sJ7WVTkrt@Wj#ZwvPi`M&`GwY%?7B{!z zoW^6$`Be95#`UFIW#o3u3zsm|lSrAHTFU*|mZ6Dv{7yr#MWEDmS8jOwJi)NW6JEwR z3##6TU@knC4eiodUr{HYd+M8mz%$aQiho+aJ5Dv{#qo{q!zcgC$vp0OBCzxPBj#aO zkM9WZ=V+96H-2*})3z{m$G*jD$0p#qCH=?A@_lY4iB-gRY@wcB3$%+fwLTA2y_lp> z68Q5~tbf~bhWSOINHFK+&kZwgEL1_~;Cp5(5Hq4-6cU{KJ{tA+eTSHtE6K=uGbfdW zBo7_xc2Lfj{%cPch-sF)P(vWcjC8nS@vT4a{r<2s4wI7@qpTnp=ZExmif=3qKT03D zIk8j&Oy~JnH9>mS3Hw7zMQd%zfl&&Zce3qvrU2E&thSN7wXSR{L{;2s>#l6mU6~pR z_p8$yDO*{qrf0X=u2}YS+pK3VhrVaBX||R?B9#Vd%W;2#>cYI(Z}kn&VBR#5?%vD{ zPDOu@ABG&#_;lwb9#^ub1Thcz9Vr10E2Suf;I)8PV;ny=KT(^#uou3oL+I${782$L zXWTyo2o5sn;Kb5&8UrmOSy;r%hnZS(pAz4(d+t)V0|++ul|Z`X9&~@@XMI!1H)(*P zI#v8>N4F8g-n6K>CP7C@4^I)aT8ZTnw4keG-{GTFXMAjsoU%F|cHa1%iL-fVg!z$S zuQ$ZwQgrI;`=r#N4=Y4mqx*=F+Nb;pBYr+EjbCl`x}Ao{Ih4aGT-q`A`De zc{*nDMN{m@Jg7)CDC+m1=49AcrM9p`33C*e)cRvDwKCBrFgnMO&!)InenE7rYpip^ zijFJl1pZ8x74$Pyc!s^m`ugJ_-*#WKm%FEY(i(v4*%#dtz$F`3i`?@)DTHZeC%ZSh zC_?hg`^*q!sbGT8u1$UN0Q^<;S`$Y^rO;pO5jb~4gkCq`wwTz8$La>g5x52U<`19b zb61!dBvu~O5oXVyS@Xv&7=$$?Ln8FKOQ{75Rp~Mm#U39|5f8IH)s$$~yFYeOB^e$>E~XpafH^{Ba6{& zu1L$s)i;SOnFzVxqV`2+Q@1|O#@LCKf$2H+Ri%|+w>UQZ)-BtxCgTfrz9oMrk5B4R zU4Q}L;lD1T{6hryzR7?hqkcibo_AvqV%7(8J0W8bMVJr>)WeQTVD3Ein49A`J^7w) z^DTfk(^ADc2S-ViFX7itR(q%(|j>u&K`rEU4WmEIN>xcaR}B zsyOHA3mvKesZH%R@?M-4t7%-grp@G@M#4JikYR|JOrdc68=!c#_V*JY)p`0J#%1^PE$ zJV?OYLu!1gEo$ML5bZjp{!t9dCn%j|h!nz!#_QtG6mer}oxPph7 zeegyKEj(f!0lkzw);gRo%KzuV{x2*HVo1pLfr$sQF8%gVYsZZXL(%``{u5alcI@VT zy{#&cq&U{C`oDK*UDQM?sXv^zVT( z(Lcw-)QM=!|BZl;`6bK!ptr7?)gH_+}h&%3sdh! zl9Tsa3bIhXivRJT(?f>bOpu~omz;rG3rbx=Nt8fD^pSzI91wXLvwnPh=wXmZMoyZ3 zXc{j|=F#bMKf!yX!2;2!%}d2+m`Yu!RiW2gB9LBl&uJ^e)QA|+soX=*B)<92^*IMS zDd{^7rJF2xO+yr4`h$>rTBC-==Ou)jT-UsW2RA!(5ScvNDwL`Zbm0;mm^T-zDgcsU z+7rw*h9kD$rFHa8`7$j%v(IV@ffli^Jp3V>IyhR5;C8bTv$y6kO(Z+H*Iip7^1)K< z=%F+D)0l^`FSRL*-wWi>(*zhX4$^8Hr%}=i_UyN{k5h2K9MCfhd{Pakw) zjpry{O2?M2F2g!WlY87NQcl^{Sq)>d38^7@M}BTS!oKV_u^k zEA8uXoLoMT`)kELufN<_h!kNMBW2(xX#<;jaAgKTh0XMV5PDhTK7l`AgnmV7p&n4l zFeD~`Zaq%VIPawADr>Um0}pGj%CC&^m7{`RXVs&|%j#o`j(kg>qebk5&&hj=UOC%T zyR3!0y+0nC*>3LoI-s=mA+>;Uh|zg$lBUZqii7%ASr9I`4ZC0&XfG$h+7HF$9rZ$Z zg8w3w?{Wh{vMD{)4L{7|-l+SUmFaAw+n5OC#ZRt`z3c*3n2$|mUVCS-ifybE@f@0P zOmm*2;9_3Ghk3uY2Jrm9UW&X&}0gQC0dbSB>j%7<%nQ~Um z#rC{Lab;38e5}Z7^m6ui9FF#Q;*;i`2x}WwK~8bjeico-&b{i>?~WYc;;yt)1nEx- z`b
3U-V2kf)wS1&0m>WM!8(jW*_=7)k3;)%rteWISZnU`{dvmM#iaG$*A;q2{uh z9h8^TzqyY4@n4jye5Ix;sowY6JjymyMnq8I4^tiV!Nn^(Lu7}ET;=bTif0= zZ<1cRa-x!2l$bXzd$SWf)24>sDDWF6pFjD68s>Hj`yyM3Z~ z+j^QmX#X5qd=q#5)4}zc6YAiu#um;Loo1k8V>|FV`ZnA3K~};BOSjh8RY}j-?#6D1 zyEI5n@j|+B`?zLVC@FK&{)%_LAp5HvZVTN24&0=Za~oY-y&nE^ok}1myuo)6GKrS{ LQ{n%A3<>`O(&Nqu literal 0 HcmV?d00001 diff --git a/Samples/Misc/Toolkit/readme.txt b/Samples/Misc/Toolkit/readme.txt new file mode 100644 index 0000000..d458bcf --- /dev/null +++ b/Samples/Misc/Toolkit/readme.txt @@ -0,0 +1,19 @@ +--------------------------------------------------------------------- +A small toolkit library + +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + +--------------------------------------------------------------------- + +This sample is a collection of helper methods for the DirectShow FilterGraph +provided as a .Net class library. + +You can use it in your own works by + - compile it and reference it in your project + - just add the FilterGraphTools.cs file in your project + - take just interesting parts + +Documentation is available in the "doc" folder. \ No newline at end of file diff --git a/Samples/Players/DvdPlay/App.ico b/Samples/Players/DvdPlay/App.ico new file mode 100644 index 0000000000000000000000000000000000000000..3a5525fd794f7a7c5c8e6187f470ea3af38cd2b6 GIT binary patch literal 1078 zcmeHHJr05}7=1t!Hp3A*8IHkVf+j?-!eHY14Gtcw1Eb*_9>Bq^zETJ@GKj{_2j4$w zo9}xCh!8{T3=X##Skq>ikMjsvB|y%crWBM2iW(4pI}c%z6%lW!=~4v77#3{z!dmB1 z__&l)-{KUYR+|8|;wB^R|9ET$J@(@=#rd^=)qs85?vAy(PSF5CyNkus435LVkZ$rj zNw|JG-P7^hF<(;#o*Vk}5R#e|^13tBbQkeF?djULtvqyxd3<{9 literal 0 HcmV?d00001 diff --git a/Samples/Players/DvdPlay/AssemblyInfo.cs b/Samples/Players/DvdPlay/AssemblyInfo.cs new file mode 100644 index 0000000..69e7538 --- /dev/null +++ b/Samples/Players/DvdPlay/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("DVDPlayerNET")] +[assembly: AssemblyDescription("DVD Player for .NET")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("netmaster@swissonline.ch")] +[assembly: AssemblyProduct("DirectShow.NET")] +[assembly: AssemblyCopyright("everybody")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.0.1")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/Players/DvdPlay/DVDPlay-2005.csproj b/Samples/Players/DvdPlay/DVDPlay-2005.csproj new file mode 100644 index 0000000..b14613b --- /dev/null +++ b/Samples/Players/DvdPlay/DVDPlay-2005.csproj @@ -0,0 +1,110 @@ + + + Local + 8.0.50727 + 2.0 + {00DC331B-E105-44F0-829E-80C2E1120D2F} + Debug + AnyCPU + App.ico + + + DVDPlayerNET + + + JScript + Grid + IE50 + false + WinExe + DVDPlayerNET + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + + + Code + + + Form + + + MainForm.cs + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Players/DvdPlay/DVDPlay-2005.sln b/Samples/Players/DvdPlay/DVDPlay-2005.sln new file mode 100644 index 0000000..464db5d --- /dev/null +++ b/Samples/Players/DvdPlay/DVDPlay-2005.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DVDPlay-2005", "DVDPlay-2005.csproj", "{00DC331B-E105-44F0-829E-80C2E1120D2F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {00DC331B-E105-44F0-829E-80C2E1120D2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {00DC331B-E105-44F0-829E-80C2E1120D2F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {00DC331B-E105-44F0-829E-80C2E1120D2F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {00DC331B-E105-44F0-829E-80C2E1120D2F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Players/DvdPlay/DVDPlay-2008.sln b/Samples/Players/DvdPlay/DVDPlay-2008.sln new file mode 100644 index 0000000..27b631d --- /dev/null +++ b/Samples/Players/DvdPlay/DVDPlay-2008.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DVDPlay-2008", "DVDPlay-2008.csproj", "{00DC331B-E105-44F0-829E-80C2E1120D2F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {00DC331B-E105-44F0-829E-80C2E1120D2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {00DC331B-E105-44F0-829E-80C2E1120D2F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {00DC331B-E105-44F0-829E-80C2E1120D2F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {00DC331B-E105-44F0-829E-80C2E1120D2F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Players/DvdPlay/DVDPlay.csproj b/Samples/Players/DvdPlay/DVDPlay.csproj new file mode 100644 index 0000000..7260733 --- /dev/null +++ b/Samples/Players/DvdPlay/DVDPlay.csproj @@ -0,0 +1,142 @@ + + + + Local + 8.0.50727 + 2.0 + {00DC331B-E105-44F0-829E-80C2E1120D2F} + Debug + AnyCPU + App.ico + + + DVDPlayerNET + + + JScript + Grid + IE50 + false + WinExe + DVDPlayerNET + OnBuildSuccess + + + + + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Drawing + + + System.Windows.Forms + + + + + + + Code + + + Form + + + MainForm.cs + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Players/DvdPlay/MainForm.cs b/Samples/Players/DvdPlay/MainForm.cs new file mode 100644 index 0000000..5361c9f --- /dev/null +++ b/Samples/Players/DvdPlay/MainForm.cs @@ -0,0 +1,1150 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + + Adapted from + DirectShow .NET + netmaster@swissonline.ch + +Updated to use DirectShowLib from SourceForge by +snarfle@SourceForge.net + +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using System.Text; + +using DirectShowLib; +using DirectShowLib.Dvd; + +namespace DVDPlayerNET +{ + + + /// MainForm for DVD Player. + public class MainForm : System.Windows.Forms.Form + { + /// Required designer variable. + private System.ComponentModel.Container components = null; + private System.Windows.Forms.MainMenu mainMenu; + private System.Windows.Forms.MenuItem menuTopFile; + private System.Windows.Forms.MenuItem menuFileCloseDVD; + private System.Windows.Forms.MenuItem menuFileSep1; + private System.Windows.Forms.MenuItem menuFileExit; + private System.Windows.Forms.MenuItem menuTopPlayback; + private System.Windows.Forms.MenuItem menuPbackPlay; + private System.Windows.Forms.MenuItem menuPbackPause; + private System.Windows.Forms.MenuItem menuPbackStop; + private System.Windows.Forms.MenuItem menuPbackStepFw; + private System.Windows.Forms.MenuItem menuPbackSep1; + private System.Windows.Forms.MenuItem menuPbackGoTo; + private System.Windows.Forms.MenuItem menuPbackNextChapt; + private System.Windows.Forms.MenuItem menuPbackPrevChapt; + private System.Windows.Forms.MenuItem menuPbackSep2; + private System.Windows.Forms.MenuItem menuPbackFullscreen; + private System.Windows.Forms.MenuItem menuTopOptions; + private System.Windows.Forms.MenuItem menuOptionRootMenu; + private System.Windows.Forms.MenuItem menuOptionSep1; + private System.Windows.Forms.MenuItem menuOptionVideoAttr; + private System.Windows.Forms.MenuItem menuOptionTitleMenu; + + public MainForm() + { + // Required for Windows Form Designer support + InitializeComponent(); + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + CloseInterfaces(); + + if (components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.mainMenu = new System.Windows.Forms.MainMenu(); + this.menuTopFile = new System.Windows.Forms.MenuItem(); + this.menuFileCloseDVD = new System.Windows.Forms.MenuItem(); + this.menuFileSep1 = new System.Windows.Forms.MenuItem(); + this.menuFileExit = new System.Windows.Forms.MenuItem(); + this.menuTopPlayback = new System.Windows.Forms.MenuItem(); + this.menuPbackPlay = new System.Windows.Forms.MenuItem(); + this.menuPbackPause = new System.Windows.Forms.MenuItem(); + this.menuPbackStop = new System.Windows.Forms.MenuItem(); + this.menuPbackStepFw = new System.Windows.Forms.MenuItem(); + this.menuPbackSep1 = new System.Windows.Forms.MenuItem(); + this.menuPbackGoTo = new System.Windows.Forms.MenuItem(); + this.menuPbackNextChapt = new System.Windows.Forms.MenuItem(); + this.menuPbackPrevChapt = new System.Windows.Forms.MenuItem(); + this.menuPbackSep2 = new System.Windows.Forms.MenuItem(); + this.menuPbackFullscreen = new System.Windows.Forms.MenuItem(); + this.menuTopOptions = new System.Windows.Forms.MenuItem(); + this.menuOptionRootMenu = new System.Windows.Forms.MenuItem(); + this.menuOptionTitleMenu = new System.Windows.Forms.MenuItem(); + this.menuOptionSep1 = new System.Windows.Forms.MenuItem(); + this.menuOptionVideoAttr = new System.Windows.Forms.MenuItem(); + // + // mainMenu + // + this.mainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuTopFile, + this.menuTopPlayback, + this.menuTopOptions}); + // + // menuTopFile + // + this.menuTopFile.Index = 0; + this.menuTopFile.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuFileCloseDVD, + this.menuFileSep1, + this.menuFileExit}); + this.menuTopFile.Text = "&File"; + // + // menuFileCloseDVD + // + this.menuFileCloseDVD.Enabled = false; + this.menuFileCloseDVD.Index = 0; + this.menuFileCloseDVD.Shortcut = System.Windows.Forms.Shortcut.CtrlF4; + this.menuFileCloseDVD.Text = "&Close DVD"; + this.menuFileCloseDVD.Click += new System.EventHandler(this.menuFileCloseDVD_Click); + // + // menuFileSep1 + // + this.menuFileSep1.Index = 1; + this.menuFileSep1.Text = "-"; + // + // menuFileExit + // + this.menuFileExit.Index = 2; + this.menuFileExit.Text = "E&xit"; + this.menuFileExit.Click += new System.EventHandler(this.menuFileExit_Click); + // + // menuTopPlayback + // + this.menuTopPlayback.Index = 1; + this.menuTopPlayback.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuPbackPlay, + this.menuPbackPause, + this.menuPbackStop, + this.menuPbackStepFw, + this.menuPbackSep1, + this.menuPbackGoTo, + this.menuPbackSep2, + this.menuPbackFullscreen}); + this.menuTopPlayback.Text = "&Playback"; + // + // menuPbackPlay + // + this.menuPbackPlay.Index = 0; + this.menuPbackPlay.Text = "&Play\tP"; + this.menuPbackPlay.Click += new System.EventHandler(this.menuPbackPlay_Click); + // + // menuPbackPause + // + this.menuPbackPause.Enabled = false; + this.menuPbackPause.Index = 1; + this.menuPbackPause.Text = "P&ause\tA"; + this.menuPbackPause.Click += new System.EventHandler(this.menuPbackPause_Click); + // + // menuPbackStop + // + this.menuPbackStop.Enabled = false; + this.menuPbackStop.Index = 2; + this.menuPbackStop.Text = "&Stop\tS"; + this.menuPbackStop.Click += new System.EventHandler(this.menuPbackStop_Click); + // + // menuPbackStepFw + // + this.menuPbackStepFw.Enabled = false; + this.menuPbackStepFw.Index = 3; + this.menuPbackStepFw.Text = "S&tep Forward\t"; + this.menuPbackStepFw.Click += new System.EventHandler(this.menuPbackStepFw_Click); + // + // menuPbackSep1 + // + this.menuPbackSep1.Index = 4; + this.menuPbackSep1.Text = "-"; + // + // menuPbackGoTo + // + this.menuPbackGoTo.Enabled = false; + this.menuPbackGoTo.Index = 5; + this.menuPbackGoTo.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuPbackNextChapt, + this.menuPbackPrevChapt}); + this.menuPbackGoTo.Text = "&Go To"; + // + // menuPbackNextChapt + // + this.menuPbackNextChapt.Enabled = false; + this.menuPbackNextChapt.Index = 0; + this.menuPbackNextChapt.Text = "&Next Chapter\tN"; + this.menuPbackNextChapt.Click += new System.EventHandler(this.menuPbackNextChapt_Click); + // + // menuPbackPrevChapt + // + this.menuPbackPrevChapt.Enabled = false; + this.menuPbackPrevChapt.Index = 1; + this.menuPbackPrevChapt.Text = "&Previous Chapter\tR"; + this.menuPbackPrevChapt.Click += new System.EventHandler(this.menuPbackPrevChapt_Click); + // + // menuPbackSep2 + // + this.menuPbackSep2.Index = 6; + this.menuPbackSep2.Text = "-"; + // + // menuPbackFullscreen + // + this.menuPbackFullscreen.Enabled = false; + this.menuPbackFullscreen.Index = 7; + this.menuPbackFullscreen.Text = "&Fullscreen\tF"; + this.menuPbackFullscreen.Click += new System.EventHandler(this.menuPbackFullscreen_Click); + // + // menuTopOptions + // + this.menuTopOptions.Index = 2; + this.menuTopOptions.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuOptionRootMenu, + this.menuOptionTitleMenu, + this.menuOptionSep1, + this.menuOptionVideoAttr}); + this.menuTopOptions.Text = "&Options"; + // + // menuOptionRootMenu + // + this.menuOptionRootMenu.Enabled = false; + this.menuOptionRootMenu.Index = 0; + this.menuOptionRootMenu.Text = "Show R&oot Menu\t"; + this.menuOptionRootMenu.Click += new System.EventHandler(this.menuOptionRootMenu_Click); + // + // menuOptionTitleMenu + // + this.menuOptionTitleMenu.Enabled = false; + this.menuOptionTitleMenu.Index = 1; + this.menuOptionTitleMenu.Text = "Show Title &Menu\tM"; + this.menuOptionTitleMenu.Click += new System.EventHandler(this.menuOptionTitleMenu_Click); + // + // menuOptionSep1 + // + this.menuOptionSep1.Index = 2; + this.menuOptionSep1.Text = "-"; + // + // menuOptionVideoAttr + // + this.menuOptionVideoAttr.Enabled = false; + this.menuOptionVideoAttr.Index = 3; + this.menuOptionVideoAttr.Text = "Get Video Attributes...\tI"; + this.menuOptionVideoAttr.Click += new System.EventHandler(this.menuOptionVideoAttr_Click); + // + // MainForm + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.BackColor = System.Drawing.Color.Black; + this.ClientSize = new System.Drawing.Size(568, 397); + this.Menu = this.mainMenu; + this.Name = "MainForm"; + this.Text = ".NET DVD Player"; + this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MainForm_KeyDown); + this.Resize += new System.EventHandler(this.MainForm_Resize); + this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.MainForm_MouseDown); + this.Closing += new System.ComponentModel.CancelEventHandler(this.MainForm_Closing); + this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.MainForm_MouseMove); + + } + #endregion + + + /// The main entry point for the application. + [STAThread] + static void Main() + { + Application.Run( new MainForm() ); + } + + private void MainForm_Closing(object sender, System.ComponentModel.CancelEventArgs e) + { + CloseInterfaces(); + } + + private void MainForm_Resize( object sender, System.EventArgs e ) + { + ResizeVideoWindow(); + } + + + /// menu clicked to close DVD volume. + private void menuFileCloseDVD_Click(object sender, System.EventArgs e) + { + CloseInterfaces(); + UpdateMenu(); + UpdateFrameCaption(); + } + + private void menuFileExit_Click(object sender, System.EventArgs e) + { + this.Close(); + } + + /// menu clicked to start playback. + private void menuPbackPlay_Click(object sender, System.EventArgs e) + { + if( playState == PlayState.Init ) + { + FirstPlayDvd(); + } + else + { + if( (mediaCtrl == null) || (playState == PlayState.Playing) ) + { + return; + } + + int hr = mediaCtrl.Run(); + DsError.ThrowExceptionForHR(hr); + + playState = PlayState.Playing; + + if( (menuMode == MenuMode.Still) && (dvdCtrl != null) ) + { + hr = dvdCtrl.StillOff(); + DsError.ThrowExceptionForHR(hr); + } + } + UpdateMenu(); + UpdateFrameCaption(); + } + + /// menu clicked to pause playback. + private void menuPbackPause_Click(object sender, System.EventArgs e) + { + if( (mediaCtrl == null) || (playState != PlayState.Playing) ) + { + return; + } + + int hr = mediaCtrl.Pause(); + DsError.ThrowExceptionForHR(hr); + + playState = PlayState.Paused; + UpdateMenu(); + UpdateFrameCaption(); + } + + /// menu clicked to stop playback. + private void menuPbackStop_Click(object sender, System.EventArgs e) + { + if( (mediaCtrl == null) || + ((playState != PlayState.Playing) && (playState != PlayState.Paused) ) ) + { + return; + } + + int hr = mediaCtrl.Stop(); + DsError.ThrowExceptionForHR(hr); + + playState = PlayState.Stopped; + UpdateMenu(); + UpdateFrameCaption(); + } + + /// menu clicked to single-step. + private void menuPbackStepFw_Click(object sender, System.EventArgs e) + { + int hr; + if( (videoStep == null) || (mediaCtrl == null) ) + { + return; + } + + if( playState != PlayState.Paused ) + { + hr = mediaCtrl.Pause(); + DsError.ThrowExceptionForHR(hr); + } + playState = PlayState.Paused; + hr = videoStep.Step( 1, null ); + DsError.ThrowExceptionForHR(hr); + + UpdateMenu(); + UpdateFrameCaption(); + } + + /// menu clicked to play next chapter. + private void menuPbackNextChapt_Click(object sender, System.EventArgs e) + { + if( (playState != PlayState.Playing) || (dvdCtrl == null) ) + { + return; + } + + int hr = dvdCtrl.PlayNextChapter( DvdCmdFlags.SendEvents, out cmdOption ); + DsError.ThrowExceptionForHR(hr); + + if( cmdOption != null ) + { + pendingCmd = true; + } + + UpdateMenu(); + } + + /// menu clicked to play previous chapter. + private void menuPbackPrevChapt_Click( object sender, System.EventArgs e ) + { + if( (playState != PlayState.Playing) || (dvdCtrl == null) ) + { + return; + } + + int hr = dvdCtrl.PlayPrevChapter( DvdCmdFlags.SendEvents, out cmdOption ); + DsError.ThrowExceptionForHR(hr); + + if( cmdOption != null ) + { + pendingCmd = true; + } + + UpdateMenu(); + } + + + private void menuPbackFullscreen_Click(object sender, System.EventArgs e) + { + ToggleFullScreen(); + } + + /// menu clicked to show dvd-root-menu. + private void menuOptionRootMenu_Click( object sender, System.EventArgs e ) + { + IDvdCmd icmd; + + if( (playState != PlayState.Playing) || (dvdCtrl == null) ) + { + return; + } + + int hr = dvdCtrl.ShowMenu( DvdMenuId.Root, DvdCmdFlags.Block | DvdCmdFlags.Flush, out icmd ); + DsError.ThrowExceptionForHR(hr); + } + + /// menu clicked to show dvd-title-menu. + private void menuOptionTitleMenu_Click( object sender, System.EventArgs e ) + { + IDvdCmd icmd; + + if( (playState != PlayState.Playing) || (dvdCtrl == null) ) + { + return; + } + + int hr = dvdCtrl.ShowMenu( DvdMenuId.Title, DvdCmdFlags.Block | DvdCmdFlags.Flush, out icmd ); + DsError.ThrowExceptionForHR(hr); + } + + /// show dialog about dvd information. + private void menuOptionVideoAttr_Click(object sender, System.EventArgs e) + { + if( (playState != PlayState.Playing) || (dvdInfo == null) ) + { + return; + } + + DvdVideoAttributes att; + dvdInfo.GetCurrentVideoAttributes( out att ); + + StringBuilder txt = new StringBuilder( 600 ); + txt.AppendFormat( "Resolution : {0} / {1}\r\n", att.sourceResolutionX.ToString(), att.sourceResolutionY.ToString() ); + txt.AppendFormat( "Aspect : {0} : {1}\r\n", att.aspectX.ToString(), att.aspectY.ToString() ); + txt.AppendFormat( "Frame Rate : {0}\r\n", att.frameRate.ToString() ); + txt.AppendFormat( "Compression : {0}\r\n", att.compression.ToString() ); + + MessageBox.Show( this, txt.ToString(), "GetCurrentVideoAttributes", MessageBoxButtons.OK, MessageBoxIcon.Information ); + } + + + /// handling the very first start of dvd playback. + bool FirstPlayDvd() + { + int hr; + + try + { + pendingCmd = true; + UpdateMenu(); + + CloseInterfaces(); + if( ! GetInterfaces() ) + { + return false; + } + + hr = dvdCtrl.SetOption( DvdOptionFlag.HMSFTimeCodeEvents, true ); // use new HMSF timecode format + DsError.ThrowExceptionForHR( hr ); + + hr = dvdCtrl.SetOption( DvdOptionFlag.ResetOnStop, false ); + DsError.ThrowExceptionForHR( hr ); + + hr = mediaEvt.SetNotifyWindow( this.Handle, WM_DVD_EVENT, IntPtr.Zero ); + DsError.ThrowExceptionForHR( hr ); + + hr = videoWin.put_Owner( this.Handle ); + DsError.ThrowExceptionForHR( hr ); + + hr = videoWin.put_WindowStyle( WindowStyle.Child | WindowStyle.ClipSiblings | WindowStyle.ClipChildren); + DsError.ThrowExceptionForHR( hr ); + + ResizeVideoWindow(); + + hr = mediaCtrl.Run(); + DsError.ThrowExceptionForHR( hr ); + + hr = videoWin.put_MessageDrain( this.Handle ); + DsError.ThrowExceptionForHR( hr ); + + playState = PlayState.Playing; + pendingCmd = false; + + return true; + } + catch( Exception ee ) + { + MessageBox.Show( this, "Could not start DVD\r\n" + ee.Message, "DVDPlayer.NET", MessageBoxButtons.OK, MessageBoxIcon.Stop ); + CloseInterfaces(); + return false; + } + } + + + /// resize preview video window to fill client area. + void ResizeVideoWindow() + { + if( videoWin == null ) + { + return; + } + + Rectangle rc = this.ClientRectangle; + int hr = videoWin.SetWindowPosition( 0, 0, rc.Right, rc.Bottom ); + DsError.ThrowExceptionForHR( hr ); + } + + + /// create the used COM components and get the interfaces. + bool GetInterfaces() + { + int hr; + AMDvdRenderStatus status; + object comobj = null; + + try + { + dvdGraph = (IDvdGraphBuilder)new DvdGraphBuilder(); + + hr = dvdGraph.RenderDvdVideoVolume( null, AMDvdGraphFlags.None, out status ); + DsError.ThrowExceptionForHR( hr ); + + hr = dvdGraph.GetDvdInterface( typeof( IDvdInfo2 ).GUID, out comobj ); + DsError.ThrowExceptionForHR( hr ); + dvdInfo = (IDvdInfo2) comobj; + comobj = null; + + hr = dvdGraph.GetDvdInterface( typeof( IDvdControl2 ).GUID, out comobj ); + DsError.ThrowExceptionForHR( hr ); + dvdCtrl = (IDvdControl2) comobj; + comobj = null; + + hr = dvdGraph.GetFiltergraph( out graphBuilder ); + DsError.ThrowExceptionForHR( hr ); + + mediaCtrl = (IMediaControl) graphBuilder; + mediaEvt = (IMediaEventEx) graphBuilder; + + hr = dvdGraph.GetDvdInterface( typeof( IVideoWindow ).GUID, out comobj ); + DsError.ThrowExceptionForHR( hr ); + + videoWin = (IVideoWindow) comobj; + comobj = null; + + GetFrameStepInterface(); + return true; + } + catch( Exception ee ) + { + MessageBox.Show( this, "Could not get interfaces\r\n" + ee.Message, "DVDPlayer.NET", MessageBoxButtons.OK, MessageBoxIcon.Stop ); + CloseInterfaces(); + return false; + } + finally + { + if( comobj != null ) + { + Marshal.ReleaseComObject( comobj ); + comobj = null; + } + } + } + + + /// detect if we can single step. + bool GetFrameStepInterface() + { + videoStep = graphBuilder as IVideoFrameStep; + if( videoStep == null ) + { + return false; + } + + // Check if this decoder can step + int hr = videoStep.CanStep( 0, null ); + if( hr != 0 ) + { + videoStep = null; + return false; + } + return true; + } + + + /// do cleanup and release DirectShow. + void CloseInterfaces() + { + int hr; + try + { + if( dvdCtrl != null ) + { + hr = dvdCtrl.SetOption( DvdOptionFlag.ResetOnStop, true ); + } + + if( mediaCtrl != null ) + { + hr = mediaCtrl.Stop(); + mediaCtrl = null; + } + playState = PlayState.Stopped; + + if( mediaEvt != null ) + { + hr = mediaEvt.SetNotifyWindow( IntPtr.Zero, WM_DVD_EVENT, IntPtr.Zero ); + mediaEvt = null; + } + + if( videoWin != null ) + { + hr = videoWin.put_Visible( OABool.False ); + hr = videoWin.put_MessageDrain( IntPtr.Zero ); + hr = videoWin.put_Owner( IntPtr.Zero ); + videoWin = null; + } + + videoStep = null; + + if( cmdOption != null ) + { + Marshal.ReleaseComObject( cmdOption ); + cmdOption = null; + } + + pendingCmd = false; + + if( graphBuilder != null ) + { + Marshal.ReleaseComObject( graphBuilder ); + graphBuilder = null; + } + + dvdCtrl = null; + if( dvdInfo != null ) + { + Marshal.ReleaseComObject( dvdInfo ); + dvdInfo = null; + } + + if( dvdGraph != null ) + { + Marshal.ReleaseComObject( dvdGraph ); + dvdGraph = null; + } + + playState = PlayState.Init; + } + catch( Exception ) + {} + } + + + void ToggleFullScreen() + { + if( videoWin == null ) + { + return; + } + + OABool mode; + int hr = videoWin.get_FullScreenMode( out mode ); + if( mode == OABool.False ) + { + hr = videoWin.put_FullScreenMode( OABool.True ); + if( hr >= 0 ) + { + fullScreen = true; + } + } + else + { + hr = videoWin.put_FullScreenMode( OABool.False ); + if( hr >= 0 ) + { + fullScreen = false; + } + + this.TopMost = true; + this.Refresh(); + } + } + + + /// override message handler to get dvd events + protected override void WndProc( ref Message m ) + { + if( m.Msg == WM_DVD_EVENT ) + { + if( mediaEvt != null ) + { + OnDvdEvent(); + } + } + else + { + base.WndProc( ref m ); + } + } + + + /// DVD event message handler + void OnDvdEvent() + { + IntPtr p1, p2; + int hr = 0; + EventCode code; + do + { + hr = mediaEvt.GetEvent( out code, out p1, out p2, 0 ); + if( hr < 0 ) + { + break; + } + + switch( code ) + { + case EventCode.DvdCurrentHmsfTime: + { + byte[] ati = BitConverter.GetBytes( p1.ToInt32() ); + currnTime.bHours = ati[0]; + currnTime.bMinutes = ati[1]; + currnTime.bSeconds = ati[2]; + currnTime.bFrames = ati[3]; + UpdateFrameCaption(); + break; + } + case EventCode.DvdChapterStart: + { + currnChapter = p1.ToInt32(); + UpdateFrameCaption(); + break; + } + case EventCode.DvdTitleChange: + { + currnTitle = p1.ToInt32(); + UpdateFrameCaption(); + break; + } + case EventCode.DvdDomainChange: + { + currnDomain = (DvdDomain) p1; + UpdateFrameCaption(); + break; + } + + case EventCode.DvdCmdStart: + { + break; + } + case EventCode.DvdCmdEnd: + { + OnCmdComplete( p1, p2 ); + break; + } + + case EventCode.DvdStillOn: + { + if( p1 == IntPtr.Zero ) + { + menuMode = MenuMode.Buttons; + } + else + { + menuMode = MenuMode.Still; + } + break; + } + case EventCode.DvdStillOff: + { + if( menuMode == MenuMode.Still ) + { + menuMode = MenuMode.No; + } + break; + } + case EventCode.DvdButtonChange: + { + if( p1.ToInt32() <= 0 ) + { + menuMode = MenuMode.No; + } + else + { + menuMode = MenuMode.Buttons; + } + break; + } + + case EventCode.DvdNoFpPgc: + { + IDvdCmd icmd; + + if( dvdCtrl != null ) + { + hr = dvdCtrl.PlayTitle( 1, DvdCmdFlags.None, out icmd ); + } + break; + } + } + + hr = mediaEvt.FreeEventParams( code, p1, p2 ); + } + while( hr == 0 ); + } + + + /// update text of window caption + void UpdateFrameCaption() + { + if( playState == PlayState.Init ) + { + this.Text = "DVD"; + return; + } + string ti = String.Format( "{0:00}:{1:00}:{2:00}", currnTime.bHours, currnTime.bMinutes, currnTime.bSeconds ); + if( playState == PlayState.Paused ) + { + ti = ti + " (Paused)"; + } + else if( playState == PlayState.Stopped ) + { + ti = ti + " (Stopped)"; + } + + this.Text = String.Format( "DVD Chapter:{0} Title:{1} {2}", currnChapter, currnTitle, ti ); + } + + + /// asynchronous command completed + void OnCmdComplete( IntPtr p1, IntPtr hrg ) + { + // Trace.WriteLine( "DVD OnCmdComplete.........." ); + if( (pendingCmd == false) || (dvdInfo == null) ) + { + return; + } + + IDvdCmd cmd; + int hr = dvdInfo.GetCmdFromEvent( p1, out cmd ); + DsError.ThrowExceptionForHR(hr); + + if( cmd == null) + { + // DVD OnCmdComplete GetCmdFromEvent failed + return; + } + + if( cmd != cmdOption ) + { + // DVD OnCmdComplete UNKNOWN CMD + Marshal.ReleaseComObject( cmd ); + cmd = null; + return; + } + + Marshal.ReleaseComObject( cmd ); + cmd = null; + Marshal.ReleaseComObject( cmdOption ); + cmdOption = null; + pendingCmd = false; + // Trace.WriteLine( "DVD OnCmdComplete OK." ); + UpdateMenu(); + } + + + /// update menu items to match current playback state + private void UpdateMenu() + { + bool enable = (mediaCtrl != null) && (! pendingCmd); + + menuFileCloseDVD.Enabled = enable; + menuPbackPlay.Enabled = (! pendingCmd) && (playState != PlayState.Playing); + menuPbackPause.Enabled = enable && (playState == PlayState.Playing); + menuPbackStop.Enabled = enable && ( (playState == PlayState.Playing) || (playState == PlayState.Paused)); + menuPbackStepFw.Enabled = enable && ( (playState == PlayState.Playing) || (playState == PlayState.Paused)); + menuPbackGoTo.Enabled = enable; + menuPbackNextChapt.Enabled = enable && (playState == PlayState.Playing); + menuPbackPrevChapt.Enabled = enable && (playState == PlayState.Playing); + menuPbackFullscreen.Enabled = enable; + menuOptionRootMenu.Enabled = enable && (playState == PlayState.Playing); + menuOptionTitleMenu.Enabled = enable && (playState == PlayState.Playing); + menuOptionVideoAttr.Enabled = enable && (playState == PlayState.Playing); + } + + + /// for dvd menus, forward mouse movements + private void MainForm_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) + { + if( (dvdCtrl == null) || (menuMode != MenuMode.Buttons) ) + { + return; + } + Point pt = new Point(); + pt.X = e.X; + pt.Y = e.Y; + dvdCtrl.SelectAtPosition( pt ); + } + + + /// for dvd menus, forward mouse button clicks + private void MainForm_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) + { + if( (dvdCtrl == null) || (menuMode != MenuMode.Buttons) ) + { + return; + } + Point pt = new Point(); + pt.X = e.X; + pt.Y = e.Y; + dvdCtrl.ActivateAtPosition( pt ); + } + + + /// keyboard handling for shortcuts. + private void MainForm_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) + { + if( pendingCmd ) + { + return; + } + + if( e.KeyCode == Keys.P ) + { + menuPbackPlay_Click( null, null ); + return; + } + + if( playState == PlayState.Init ) + { + return; + } + + switch( e.KeyCode ) + { + case Keys.A: + { + menuPbackPause_Click( null, null ); + break; + } + case Keys.S: + { + menuPbackStop_Click( null, null ); + break; + } + case Keys.D1: + case Keys.Space: + { + menuPbackStepFw_Click( null, null ); + break; + } + + case Keys.N: + { + menuPbackNextChapt_Click( null, null ); + break; + } + case Keys.R: + { + menuPbackPrevChapt_Click( null, null ); + break; + } + + case Keys.F: + { + menuPbackFullscreen_Click( null, null ); + break; + } + + case Keys.Escape: + { + if( fullScreen ) + { + ToggleFullScreen(); + } + break; + } + + case Keys.Home: + { + menuOptionRootMenu_Click( null, null ); + break; + } + + case Keys.M: + { + menuOptionTitleMenu_Click( null, null ); + break; + } + + case Keys.I: + { + menuOptionVideoAttr_Click( null, null ); + break; + } + + case Keys.Left: + { + if( (menuMode == MenuMode.Buttons) && (dvdCtrl != null) ) + { + dvdCtrl.SelectRelativeButton( DvdRelativeButton.Left ); + } + break; + } + case Keys.Right: + { + if( (menuMode == MenuMode.Buttons) && (dvdCtrl != null) ) + { + dvdCtrl.SelectRelativeButton( DvdRelativeButton.Right ); + } + break; + } + case Keys.Up: + { + if( (menuMode == MenuMode.Buttons) && (dvdCtrl != null) ) + { + dvdCtrl.SelectRelativeButton( DvdRelativeButton.Upper ); + } + break; + } + case Keys.Down: + { + if( (menuMode == MenuMode.Buttons) && (dvdCtrl != null) ) + { + dvdCtrl.SelectRelativeButton( DvdRelativeButton.Lower ); + } + break; + } + case Keys.Enter: + { + if( (menuMode == MenuMode.Buttons) && (dvdCtrl != null) ) + { + dvdCtrl.ActivateButton(); + } + else if( (menuMode == MenuMode.Still) && (dvdCtrl != null) ) + { + dvdCtrl.StillOff(); + } + break; + } + } + } + + + #region Member Variables + + /// current state of playback (playing/paused/...) + private PlayState playState; + + /// current mode of playback (movie/menu/still). + private MenuMode menuMode; + + /// flag to toggle full-screen. + private bool fullScreen; + + /// asynchronous command interface. + private IDvdCmd cmdOption; + /// asynchronous command pending. + private bool pendingCmd; + + /// dvd graph builder interface. + private IDvdGraphBuilder dvdGraph; + /// dvd control interface. + private IDvdControl2 dvdCtrl; + /// dvd information interface. + private IDvdInfo2 dvdInfo; + + /// dvd video playback window interface. + private IVideoWindow videoWin; + + private IGraphBuilder graphBuilder; + + /// control interface. + private IMediaControl mediaCtrl; + + /// graph event interface. + private IMediaEventEx mediaEvt; + + /// interface to single-step video. + private IVideoFrameStep videoStep; + + private DvdHMSFTimeCode currnTime = new DvdHMSFTimeCode(); // copy of current playback states, see OnDvdEvent() + private int currnTitle; + private int currnChapter; + private DvdDomain currnDomain; + + private const int WM_DVD_EVENT = 0x00008002; // message from dvd graph + + private const int WS_CHILD = 0x40000000; // attributes for video window + private const int WS_CLIPCHILDREN = 0x02000000; + private const int WS_CLIPSIBLINGS = 0x04000000; + + #endregion + } + + + internal enum PlayState + { + Init, Playing, Paused, Stopped + } + + internal enum MenuMode + { + No, Buttons, Still + } + +} diff --git a/Samples/Players/DvdPlay/MainForm.resx b/Samples/Players/DvdPlay/MainForm.resx new file mode 100644 index 0000000..bdb42e1 --- /dev/null +++ b/Samples/Players/DvdPlay/MainForm.resx @@ -0,0 +1,259 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Private + + + 17, 17 + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + False + + + (Default) + + + False + + + MainForm + + + False + + + 8, 8 + + + True + + + 80 + + + True + + + Private + + \ No newline at end of file diff --git a/Samples/Players/DvdPlay/readme.txt b/Samples/Players/DvdPlay/readme.txt new file mode 100644 index 0000000..2706965 --- /dev/null +++ b/Samples/Players/DvdPlay/readme.txt @@ -0,0 +1,15 @@ +--------------------------------------------------------------------- +DVDPlay + +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + +--------------------------------------------------------------------- + +A sample dvd player. + +This is NOT a fully featured dvd player app. However, it +does show the basic. If you need more functionality, check out the msdn docs +(Currently at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directshow/htm/dvdapplications.asp). \ No newline at end of file diff --git a/Samples/Players/DxPlay/App.ico b/Samples/Players/DxPlay/App.ico new file mode 100644 index 0000000000000000000000000000000000000000..3a5525fd794f7a7c5c8e6187f470ea3af38cd2b6 GIT binary patch literal 1078 zcmeHHJr05}7=1t!Hp3A*8IHkVf+j?-!eHY14Gtcw1Eb*_9>Bq^zETJ@GKj{_2j4$w zo9}xCh!8{T3=X##Skq>ikMjsvB|y%crWBM2iW(4pI}c%z6%lW!=~4v77#3{z!dmB1 z__&l)-{KUYR+|8|;wB^R|9ET$J@(@=#rd^=)qs85?vAy(PSF5CyNkus435LVkZ$rj zNw|JG-P7^hF<(;#o*Vk}5R#e|^13tBbQkeF?djULtvqyxd3<{9 literal 0 HcmV?d00001 diff --git a/Samples/Players/DxPlay/AssemblyInfo.cs b/Samples/Players/DxPlay/AssemblyInfo.cs new file mode 100644 index 0000000..9f89a32 --- /dev/null +++ b/Samples/Players/DxPlay/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/Players/DxPlay/Capture.cs b/Samples/Players/DxPlay/Capture.cs new file mode 100644 index 0000000..caac133 --- /dev/null +++ b/Samples/Players/DxPlay/Capture.cs @@ -0,0 +1,485 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +// Two very important things to know when using this class: +// 1) Make sure you DxPlay.Dispose before shutting down the app (to avoid hanging) +// 2) Make sure you Marshal.FreeCoTaskMem items returned from DxPlay.SnapShot (to avoid leaking) + +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.Collections; +using System.Runtime.InteropServices; +using System.Diagnostics; +using System.Windows.Forms; +using System.Threading; + +using DirectShowLib; + + +namespace DxPlay +{ + internal class DxPlay : IDisposable + { + enum GraphState + { + Stopped, + Paused, + Running, + Exiting + } + + #region Member variables + + // File name we are playing + private string m_sFileName; + + // graph builder interfaces + private IFilterGraph2 m_FilterGraph; + private IMediaControl m_mediaCtrl; + private IMediaEvent m_mediaEvent; + + // Used to grab current snapshots + ISampleGrabber m_sampGrabber = null; + + // Grab once. Used to create bitmap + private int m_videoWidth; + private int m_videoHeight; + private int m_stride; + private int m_ImageSize; // In bytes + + // Event used by Media Event thread + private ManualResetEvent m_mre; + + // Current state of the graph (can change async) + volatile private GraphState m_State = GraphState.Stopped; + +#if DEBUG + // Allow you to "Connect to remote graph" from GraphEdit + DsROTEntry m_DsRot; +#endif + + #endregion + + // Release everything. + public void Dispose() + { + CloseInterfaces(); + } + ~DxPlay() + { + CloseInterfaces(); + } + + // Event that is called when a clip finishs playing + public event DxPlayEvent StopPlay; + public delegate void DxPlayEvent(Object sender); + + // Play an avi file into a window. Allow for snapshots. + // (Control to show video in, Avi file to play + public DxPlay(Control hWin, string FileName) + { + try + { + int hr; + IntPtr hEvent; + + // Save off the file name + m_sFileName = FileName; + + // Set up the graph + SetupGraph(hWin, FileName); + + // Get the event handle the graph will use to signal + // when events occur + hr = m_mediaEvent.GetEventHandle(out hEvent); + DsError.ThrowExceptionForHR(hr); + + // Wrap the graph event with a ManualResetEvent + m_mre = new ManualResetEvent(false); +#if USING_NET11 + m_mre.Handle = hEvent; +#else + m_mre.SafeWaitHandle = new Microsoft.Win32.SafeHandles.SafeWaitHandle(hEvent, true); +#endif + + // Create a new thread to wait for events + Thread t = new Thread(new ThreadStart(this.EventWait)); + t.Name = "Media Event Thread"; + t.Start(); + } + catch + { + Dispose(); + throw; + } + } + + // Wait for events to happen. This approach uses waiting on an event handle. + // The nice thing about doing it this way is that you aren't in the windows message + // loop, and don't have to worry about re-entrency or taking too long. Plus, being + // in a class as we are, we don't have access to the message loop. + // Alternately, you can receive your events as windows messages. See + // IMediaEventEx.SetNotifyWindow. + private void EventWait() + { + // Returned when GetEvent is called but there are no events + const int E_ABORT = unchecked((int)0x80004004); + + int hr; + IntPtr p1, p2; + EventCode ec; + + do + { + // Wait for an event + m_mre.WaitOne(-1, true); + + // Avoid contention for m_State + lock(this) + { + // If we are not shutting down + if (m_State != GraphState.Exiting) + { + // Read the event + for ( + hr = m_mediaEvent.GetEvent(out ec, out p1, out p2, 0); + hr >= 0; + hr = m_mediaEvent.GetEvent(out ec, out p1, out p2, 0) + ) + { + // Write the event name to the debug window + Debug.WriteLine(ec.ToString()); + + // If the clip is finished playing + if (ec == EventCode.Complete) + { + // Call Stop() to set state + Stop(); + + // Throw event + if (StopPlay != null) + { + StopPlay(this); + } + } + + // Release any resources the message allocated + hr = m_mediaEvent.FreeEventParams(ec, p1, p2); + DsError.ThrowExceptionForHR(hr); + } + + // If the error that exited the loop wasn't due to running out of events + if (hr != E_ABORT) + { + DsError.ThrowExceptionForHR(hr); + } + } + else + { + // We are shutting down + break; + } + } + } while (true); + } + + // Return the currently playing file name + public string FileName + { + get + { + return m_sFileName; + } + } + + // start playing + public void Start() + { + // If we aren't already playing (or shutting down) + if (m_State == GraphState.Stopped || m_State == GraphState.Paused) + { + int hr = m_mediaCtrl.Run(); + DsError.ThrowExceptionForHR( hr ); + + m_State = GraphState.Running; + } + } + + // Pause the capture graph. + public void Pause() + { + // If we are playing + if (m_State == GraphState.Running) + { + int hr = m_mediaCtrl.Pause(); + DsError.ThrowExceptionForHR( hr ); + + m_State = GraphState.Paused; + } + } + // Pause the capture graph. + public void Stop() + { + // Can only Stop when playing or paused + if (m_State == GraphState.Running || m_State == GraphState.Paused) + { + int hr = m_mediaCtrl.Stop(); + DsError.ThrowExceptionForHR( hr ); + + m_State = GraphState.Stopped; + } + } + + // Reset the clip back to the beginning + public void Rewind() + { + int hr; + + IMediaPosition imp = m_FilterGraph as IMediaPosition; + hr = imp.put_CurrentPosition(0); + } + + // Grab a snapshot of the most recent image played. + // Returns A pointer to the raw pixel data. Caller must release this memory with + // Marshal.FreeCoTaskMem when it is no longer needed. + public IntPtr SnapShot() + { + int hr; + IntPtr ip = IntPtr.Zero; + int iBuffSize = 0; + + // Read the buffer size + hr = m_sampGrabber.GetCurrentBuffer(ref iBuffSize, ip); + DsError.ThrowExceptionForHR( hr ); + + Debug.Assert(iBuffSize == m_ImageSize, "Unexpected buffer size"); + + // Allocate the buffer and read it + ip = Marshal.AllocCoTaskMem(iBuffSize); + + hr = m_sampGrabber.GetCurrentBuffer(ref iBuffSize, ip); + DsError.ThrowExceptionForHR( hr ); + + return ip; + } + + // Convert a point to the raw pixel data to a .NET bitmap + public Bitmap IPToBmp(IntPtr ip) + { + // We know the Bits Per Pixel is 24 (3 bytes) because we forced it + // to be with sampGrabber.SetMediaType() + int iBufSize = m_videoWidth * m_videoHeight * 3; + + return new Bitmap( + m_videoWidth, + m_videoHeight, + -m_stride, + PixelFormat.Format24bppRgb, + (IntPtr)(ip.ToInt32() + iBufSize - m_stride) + ); + } + + // Build the capture graph for grabber and renderer. + // (Control to show video in, Filename to play) + private void SetupGraph(Control hWin, string FileName) + { + int hr; + + // Get the graphbuilder object + m_FilterGraph = new FilterGraph() as IFilterGraph2; + + // Get a ICaptureGraphBuilder2 to help build the graph + ICaptureGraphBuilder2 icgb2 = new CaptureGraphBuilder2() as ICaptureGraphBuilder2; + + try + { + // Link the ICaptureGraphBuilder2 to the IFilterGraph2 + hr = icgb2.SetFiltergraph(m_FilterGraph); + DsError.ThrowExceptionForHR( hr ); + +#if DEBUG + // Allows you to view the graph with GraphEdit File/Connect + m_DsRot = new DsROTEntry(m_FilterGraph); +#endif + // Add the filters necessary to render the file. This function will + // work with a number of different file types. + IBaseFilter sourceFilter = null; + hr = m_FilterGraph.AddSourceFilter(FileName, FileName, out sourceFilter); + DsError.ThrowExceptionForHR( hr ); + + // Get the SampleGrabber interface + m_sampGrabber = (ISampleGrabber) new SampleGrabber(); + IBaseFilter baseGrabFlt = (IBaseFilter) m_sampGrabber; + + // Configure the Sample Grabber + ConfigureSampleGrabber(m_sampGrabber); + + // Add it to the filter + hr = m_FilterGraph.AddFilter( baseGrabFlt, "Ds.NET Grabber" ); + DsError.ThrowExceptionForHR( hr ); + + // Connect the pieces together, use the default renderer + hr = icgb2.RenderStream(null, null, sourceFilter, baseGrabFlt, null); + DsError.ThrowExceptionForHR( hr ); + + // Now that the graph is built, read the dimensions of the bitmaps we'll be getting + SaveSizeInfo(m_sampGrabber); + + // Configure the Video Window + IVideoWindow videoWindow = m_FilterGraph as IVideoWindow; + ConfigureVideoWindow(videoWindow, hWin); + + // Grab some other interfaces + m_mediaEvent = m_FilterGraph as IMediaEvent; + m_mediaCtrl = m_FilterGraph as IMediaControl; + } + finally + { + if (icgb2 != null) + { + Marshal.ReleaseComObject(icgb2); + icgb2 = null; + } + } +#if DEBUG + // Double check to make sure we aren't releasing something + // important. + GC.Collect(); + GC.WaitForPendingFinalizers(); +#endif + } + + // Configure the video window + private void ConfigureVideoWindow(IVideoWindow videoWindow, Control hWin) + { + int hr; + + // Set the output window + hr = videoWindow.put_Owner( hWin.Handle ); + DsError.ThrowExceptionForHR( hr ); + + // Set the window style + hr = videoWindow.put_WindowStyle( (WindowStyle.Child | WindowStyle.ClipChildren | WindowStyle.ClipSiblings) ); + DsError.ThrowExceptionForHR( hr ); + + // Make the window visible + hr = videoWindow.put_Visible( OABool.True ); + DsError.ThrowExceptionForHR( hr ); + + // Position the playing location + Rectangle rc = hWin.ClientRectangle; + hr = videoWindow.SetWindowPosition( 0, 0, rc.Right, rc.Bottom ); + DsError.ThrowExceptionForHR( hr ); + } + + // Set the options on the sample grabber + private void ConfigureSampleGrabber(ISampleGrabber sampGrabber) + { + AMMediaType media; + int hr; + + // Set the media type to Video/RBG24 + media = new AMMediaType(); + media.majorType = MediaType.Video; + media.subType = MediaSubType.RGB24; + media.formatType = FormatType.VideoInfo; + hr = sampGrabber.SetMediaType( media ); + DsError.ThrowExceptionForHR( hr ); + + DsUtils.FreeAMMediaType(media); + media = null; + + // Configure the samplegrabber + hr = sampGrabber.SetBufferSamples( true ); + DsError.ThrowExceptionForHR( hr ); + } + + // Save the size parameters for use in SnapShot + private void SaveSizeInfo(ISampleGrabber sampGrabber) + { + int hr; + + // Get the media type from the SampleGrabber + AMMediaType media = new AMMediaType(); + + hr = sampGrabber.GetConnectedMediaType( media ); + DsError.ThrowExceptionForHR( hr ); + + try + { + + if( (media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero) ) + { + throw new NotSupportedException( "Unknown Grabber Media Format" ); + } + + // Get the struct + VideoInfoHeader videoInfoHeader = new VideoInfoHeader(); + Marshal.PtrToStructure( media.formatPtr, videoInfoHeader); + + // Grab the size info + m_videoWidth = videoInfoHeader.BmiHeader.Width; + m_videoHeight = videoInfoHeader.BmiHeader.Height; + m_stride = videoInfoHeader.BmiHeader.ImageSize / m_videoHeight; + m_ImageSize = videoInfoHeader.BmiHeader.ImageSize; + } + finally + { + DsUtils.FreeAMMediaType(media); + media = null; + } + } + + // Shut down capture + private void CloseInterfaces() + { + int hr; + + lock (this) + { + if (m_State != GraphState.Exiting) + { + m_State = GraphState.Exiting; + + // Release the thread (if the thread was started) + if (m_mre != null) + { + m_mre.Set(); + } + } + + if( m_mediaCtrl != null ) + { + // Stop the graph + hr = m_mediaCtrl.Stop(); + m_mediaCtrl = null; + } + + if (m_sampGrabber != null) + { + Marshal.ReleaseComObject(m_sampGrabber); + m_sampGrabber = null; + } + +#if DEBUG + if (m_DsRot != null) + { + m_DsRot.Dispose(); + } +#endif + + if (m_FilterGraph != null) + { + Marshal.ReleaseComObject(m_FilterGraph); + m_FilterGraph = null; + } + } + GC.Collect(); + } + } +} diff --git a/Samples/Players/DxPlay/DxPlay-2005.csproj b/Samples/Players/DxPlay/DxPlay-2005.csproj new file mode 100644 index 0000000..d7c4a62 --- /dev/null +++ b/Samples/Players/DxPlay/DxPlay-2005.csproj @@ -0,0 +1,119 @@ + + + Local + 8.0.50727 + 2.0 + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE} + Debug + AnyCPU + App.ico + + + DxPlay + + + JScript + Grid + IE50 + false + WinExe + DxPlay + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Data + + + System.Drawing + + + System.Windows.Forms + + + System.XML + + + + + + Code + + + Code + + + Form + + + Form1.cs + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Players/DxPlay/DxPlay-2005.sln b/Samples/Players/DxPlay/DxPlay-2005.sln new file mode 100644 index 0000000..d945d46 --- /dev/null +++ b/Samples/Players/DxPlay/DxPlay-2005.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DxPlay-2005", "DxPlay-2005.csproj", "{0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Players/DxPlay/DxPlay-2008.sln b/Samples/Players/DxPlay/DxPlay-2008.sln new file mode 100644 index 0000000..b540924 --- /dev/null +++ b/Samples/Players/DxPlay/DxPlay-2008.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DxPlay-2008", "DxPlay-2008.csproj", "{0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Players/DxPlay/DxPlay.csproj b/Samples/Players/DxPlay/DxPlay.csproj new file mode 100644 index 0000000..96d923d --- /dev/null +++ b/Samples/Players/DxPlay/DxPlay.csproj @@ -0,0 +1,151 @@ + + + + Local + 8.0.50727 + 2.0 + {0B44B3D7-52D7-4C0E-9B1C-F48CEEDA36FE} + Debug + AnyCPU + App.ico + + + DxPlay + + + JScript + Grid + IE50 + false + WinExe + DxPlay + OnBuildSuccess + + + + + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Data + + + System.Drawing + + + System.Windows.Forms + + + System.XML + + + + + + Code + + + Code + + + Form + + + Form1.cs + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Players/DxPlay/Form1.cs b/Samples/Players/DxPlay/Form1.cs new file mode 100644 index 0000000..d3f1af4 --- /dev/null +++ b/Samples/Players/DxPlay/Form1.cs @@ -0,0 +1,282 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using System.Data; + +namespace DxPlay +{ + /// + /// Summary description for Form1. + /// + public class Form1 : System.Windows.Forms.Form + { + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Button btnStart; + private System.Windows.Forms.Button btnPause; + private System.Windows.Forms.Button btnSnap; + private System.Windows.Forms.TextBox tbFileName; + /// + /// Required designer variable. + /// + private System.ComponentModel.Container components = null; + + public Form1() + { + // + // Required for Windows Form Designer support + // + InitializeComponent(); + + // + // TODO: Add any constructor code after InitializeComponent call + // + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + // Make sure to release the DxPlay object to avoid hanging + if (m_play != null) + { + m_play.Dispose(); + } + if( disposing ) + { + if (components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.tbFileName = new System.Windows.Forms.TextBox(); + this.btnStart = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.panel1 = new System.Windows.Forms.Panel(); + this.btnPause = new System.Windows.Forms.Button(); + this.btnSnap = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // tbFileName + // + this.tbFileName.Location = new System.Drawing.Point(72, 8); + this.tbFileName.Name = "tbFileName"; + this.tbFileName.Size = new System.Drawing.Size(208, 20); + this.tbFileName.TabIndex = 9; + this.tbFileName.Text = "c:\\test.avi"; + // + // btnStart + // + this.btnStart.Location = new System.Drawing.Point(16, 40); + this.btnStart.Name = "btnStart"; + this.btnStart.Size = new System.Drawing.Size(64, 32); + this.btnStart.TabIndex = 1; + this.btnStart.Text = "Start"; + this.btnStart.Click += new System.EventHandler(this.btnStart_Click); + // + // label1 + // + this.label1.Location = new System.Drawing.Point(16, 8); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(56, 16); + this.label1.TabIndex = 2; + this.label1.Text = "FileName"; + // + // panel1 + // + this.panel1.Location = new System.Drawing.Point(8, 88); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(320, 240); + this.panel1.TabIndex = 10; + // + // btnPause + // + this.btnPause.Enabled = false; + this.btnPause.Location = new System.Drawing.Point(96, 40); + this.btnPause.Name = "btnPause"; + this.btnPause.Size = new System.Drawing.Size(56, 32); + this.btnPause.TabIndex = 11; + this.btnPause.Text = "Pause"; + this.btnPause.Click += new System.EventHandler(this.btnPause_Click); + // + // btnSnap + // + this.btnSnap.Enabled = false; + this.btnSnap.Location = new System.Drawing.Point(192, 40); + this.btnSnap.Name = "btnSnap"; + this.btnSnap.Size = new System.Drawing.Size(56, 32); + this.btnSnap.TabIndex = 12; + this.btnSnap.Text = "Snap"; + this.btnSnap.Click += new System.EventHandler(this.btnSnap_Click); + // + // Form1 + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(336, 338); + this.Controls.Add(this.btnSnap); + this.Controls.Add(this.btnPause); + this.Controls.Add(this.panel1); + this.Controls.Add(this.label1); + this.Controls.Add(this.btnStart); + this.Controls.Add(this.tbFileName); + this.Name = "Form1"; + this.Text = "DxPlay"; + this.ResumeLayout(false); + + } + #endregion + + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.Run(new Form1()); + } + + + enum State + { + Uninit, + Stopped, + Paused, + Playing + } + State m_State = State.Uninit; + DxPlay m_play = null; + + private void btnStart_Click(object sender, System.EventArgs e) + { + // If necessary, close the old file + if (m_State == State.Stopped) + { + // Did the filename change? + if (tbFileName.Text != m_play.FileName) + { + // File name changed, close the old file + m_play.Dispose(); + m_play = null; + m_State = State.Uninit; + btnSnap.Enabled = false; + } + } + + // If we have no file open + if (m_play == null) + { + try + { + // Open the file, provide a handle to play it in + m_play = new DxPlay(panel1, tbFileName.Text); + + // Let us know when the file is finished playing + m_play.StopPlay += new DxPlay.DxPlayEvent(m_play_StopPlay); + m_State = State.Stopped; + } + catch(COMException ce) + { + MessageBox.Show("Failed to open file: " + ce.Message, "Open Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + // If we were stopped, start + if (m_State == State.Stopped) + { + btnStart.Text = "Stop"; + m_play.Start(); + btnSnap.Enabled = true; + btnPause.Enabled = true; + tbFileName.Enabled = false; + m_State = State.Playing; + } + // If we are playing or paused, stop + else if (m_State == State.Playing || m_State == State.Paused) + { + m_play.Stop(); + btnPause.Enabled = false; + tbFileName.Enabled = true; + btnStart.Text = "Start"; + btnPause.Text = "Pause"; + m_State = State.Stopped; + } + } + + private void btnPause_Click(object sender, System.EventArgs e) + { + // If we are playing, pause + if (m_State == State.Playing) + { + m_play.Pause(); + btnPause.Text = "Resume"; + m_State = State.Paused; + } + // If we are paused, start + else + { + m_play.Start(); + btnPause.Text = "Pause"; + m_State = State.Playing; + } + } + + private void btnSnap_Click(object sender, System.EventArgs e) + { + // Grab a copy of the current bitmap. Graph can be paused, playing, or stopped + IntPtr ip = m_play.SnapShot(); + try + { + // Turn the raw pixels into a Bitmap + Bitmap bmp = m_play.IPToBmp(ip); + + // Save the bitmap to a file + bmp.Save(@"c:\tryme.bmp"); + } + finally + { + // Free the raw pixels + Marshal.FreeCoTaskMem(ip); + } + } + + // Called when the video is finished playing + private void m_play_StopPlay(Object sender) + { + // This isn't the right way to do this, but heck, it's only a sample + CheckForIllegalCrossThreadCalls = false; + + btnPause.Enabled = false; + tbFileName.Enabled = true; + btnStart.Text = "Start"; + btnPause.Text = "Pause"; + + CheckForIllegalCrossThreadCalls = true; + + m_State = State.Stopped; + + // Rewind clip to beginning to allow DxPlay.Start to work again. + m_play.Rewind(); + } + } +} diff --git a/Samples/Players/DxPlay/Form1.resx b/Samples/Players/DxPlay/Form1.resx new file mode 100644 index 0000000..0b6a56a --- /dev/null +++ b/Samples/Players/DxPlay/Form1.resx @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Private + + + False + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + True + + + Private + + + 8, 8 + + + True + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + (Default) + + + False + + + False + + + 8, 8 + + + True + + + 80 + + + True + + + Private + + + Form1 + + \ No newline at end of file diff --git a/Samples/Players/DxPlay/readme.txt b/Samples/Players/DxPlay/readme.txt new file mode 100644 index 0000000..7ee3f49 --- /dev/null +++ b/Samples/Players/DxPlay/readme.txt @@ -0,0 +1,15 @@ +--------------------------------------------------------------------- +DxPlay + +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + +--------------------------------------------------------------------- + +A sample application showing how to play media files (AVI, WMV, etc) and +capture snapshots. + +Note, this sample is primarily meant to show building the graph and capturing +frames. It does NOT connect the audio pin. \ No newline at end of file diff --git a/Samples/Players/DxText/App.ico b/Samples/Players/DxText/App.ico new file mode 100644 index 0000000000000000000000000000000000000000..3a5525fd794f7a7c5c8e6187f470ea3af38cd2b6 GIT binary patch literal 1078 zcmeHHJr05}7=1t!Hp3A*8IHkVf+j?-!eHY14Gtcw1Eb*_9>Bq^zETJ@GKj{_2j4$w zo9}xCh!8{T3=X##Skq>ikMjsvB|y%crWBM2iW(4pI}c%z6%lW!=~4v77#3{z!dmB1 z__&l)-{KUYR+|8|;wB^R|9ET$J@(@=#rd^=)qs85?vAy(PSF5CyNkus435LVkZ$rj zNw|JG-P7^hF<(;#o*Vk}5R#e|^13tBbQkeF?djULtvqyxd3<{9 literal 0 HcmV?d00001 diff --git a/Samples/Players/DxText/AssemblyInfo.cs b/Samples/Players/DxText/AssemblyInfo.cs new file mode 100644 index 0000000..9f89a32 --- /dev/null +++ b/Samples/Players/DxText/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/Players/DxText/Capture.cs b/Samples/Players/DxText/Capture.cs new file mode 100644 index 0000000..baaa795 --- /dev/null +++ b/Samples/Players/DxText/Capture.cs @@ -0,0 +1,428 @@ +// Capture +// +// Written by Richard L Rosenheim +// richard@rosenheims.com +// May 21, 2005 +// +// Based in a large part upon the DxScan and DxPlayer samples by David Wohlferd +// +// Portions Copyright 2005 - Richard L Rosenheim + +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.Runtime.InteropServices; +using System.Diagnostics; +using System.Windows.Forms; + +using DirectShowLib; + + +namespace DxText +{ + /// Summary description for MainForm. + internal class Capture : ISampleGrabberCB, IDisposable + { + #region Member variables + + /// graph builder interface. + private IFilterGraph2 m_FilterGraph; + + /// Dimensions of the image, calculated once in constructor. + private int m_videoWidth; + private int m_videoHeight; + private int m_stride; + public int m_Count; + + private string m_String; + private Bitmap bitmapOverlay; + private Font fontOverlay; + private Font transparentFont; + private SolidBrush transparentBrush; + +#if DEBUG + // Allow you to "Connect to remote graph" from GraphEdit + DsROTEntry m_rot = null; +#endif + + #endregion + + #region API + + [DllImport("Kernel32.dll", EntryPoint="RtlMoveMemory")] + private static extern void CopyMemory(IntPtr Destination, IntPtr Source, [MarshalAs(UnmanagedType.U4)] uint Length); + + #endregion + + #region Declarations + [ComVisible(false), ComImport, + Guid("e436ebb5-524f-11ce-9f53-0020af0ba770")] + public class AsyncReader + { + } + + // Declare the enum w/o using uint, so it can + // be used in vb + [Flags] + enum WindowStyleFlags + { + OVERLAPPED = 0x00000000, + POPUP = -2147483648, + CHILD = 0x40000000, + MINIMIZE = 0x20000000, + VISIBLE = 0x10000000, + DISABLED = 0x08000000, + CLIPSIBLINGS = 0x04000000, + CLIPCHILDREN = 0x02000000, + MAXIMIZE = 0x01000000, + BORDER = 0x00800000, + DLGFRAME = 0x00400000, + VSCROLL = 0x00200000, + HSCROLL = 0x00100000, + SYSMENU = 0x00080000, + THICKFRAME = 0x00040000, + GROUP = 0x00020000, + TABSTOP = 0x00010000, + MINIMIZEBOX = 0x00020000, + MAXIMIZEBOX = 0x00010000, + } + + #endregion + + /// release everything. + public void Dispose() + { + CloseInterfaces(); + + bitmapOverlay.Dispose(); + fontOverlay.Dispose(); + transparentBrush.Dispose(); + transparentFont.Dispose(); + } + ~Capture() + { + CloseInterfaces(); + + bitmapOverlay.Dispose(); + fontOverlay.Dispose(); + transparentBrush.Dispose(); + transparentFont.Dispose(); + } + + /// Use capture device zero, default frame rate and size + public Capture(string FileName, string TextString, Control hWin) + { + m_Count = 0; + m_String = TextString; + _Capture(FileName, hWin); + } + /// capture the next image + public void Start() + { + IMediaControl mediaCtrl = m_FilterGraph as IMediaControl; + + int hr = mediaCtrl.Run(); + DsError.ThrowExceptionForHR( hr ); + } + + /// + /// Returns an interface to the event notification interface + /// + public IMediaEventEx MediaEventEx + { + get + { + return (IMediaEventEx) m_FilterGraph; + } + } + + + // Internal capture + private void _Capture(string FileName, Control hWin) + { + try + { + // Set up the capture graph + SetupGraph( FileName, hWin); + SetupBitmap(); + } + catch + { + Dispose(); + throw; + } + } + + /// build the capture graph for grabber. + private void SetupGraph(string FileName, Control hWin) + { + int hr; + + IBaseFilter ibfRenderer = null; + ISampleGrabber sampGrabber = null; + IBaseFilter capFilter = null; + IPin iPinInFilter = null; + IPin iPinOutFilter = null; + IPin iPinInDest = null; + + // Get the graphbuilder object + m_FilterGraph = new FilterGraph() as IFilterGraph2; +#if DEBUG + m_rot = new DsROTEntry( m_FilterGraph ); +#endif + + try + { + // Get the SampleGrabber interface + sampGrabber = new SampleGrabber() as ISampleGrabber; + + // Add the video source + hr = m_FilterGraph.AddSourceFilter(FileName, "Ds.NET FileFilter", out capFilter); + DsError.ThrowExceptionForHR( hr ); + + // Hopefully this will be the video pin + IPin iPinOutSource = DsFindPin.ByDirection(capFilter, PinDirection.Output, 0); + + IBaseFilter baseGrabFlt = sampGrabber as IBaseFilter; + ConfigureSampleGrabber(sampGrabber); + + iPinInFilter = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Input, 0); + iPinOutFilter = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Output, 0); + + // Add the frame grabber to the graph + hr = m_FilterGraph.AddFilter( baseGrabFlt, "Ds.NET Grabber" ); + DsError.ThrowExceptionForHR( hr ); + + hr = m_FilterGraph.Connect(iPinOutSource, iPinInFilter); + DsError.ThrowExceptionForHR( hr ); + + // Get the default video renderer + ibfRenderer = (IBaseFilter) new VideoRendererDefault(); + + // Add it to the graph + hr = m_FilterGraph.AddFilter( ibfRenderer, "Ds.NET VideoRendererDefault" ); + DsError.ThrowExceptionForHR( hr ); + iPinInDest = DsFindPin.ByDirection(ibfRenderer, PinDirection.Input, 0); + + // Connect the graph. Many other filters automatically get added here + hr = m_FilterGraph.Connect(iPinOutFilter, iPinInDest); + DsError.ThrowExceptionForHR( hr ); + + SaveSizeInfo(sampGrabber); + + // Set the output window + IVideoWindow videoWindow = m_FilterGraph as IVideoWindow; + hr = videoWindow.put_Owner( hWin.Handle ); + DsError.ThrowExceptionForHR( hr ); + + hr = videoWindow.put_WindowStyle( WindowStyle.Child | WindowStyle.ClipChildren | WindowStyle.ClipSiblings ); + DsError.ThrowExceptionForHR( hr ); + + hr = videoWindow.put_Visible( OABool.True ); + DsError.ThrowExceptionForHR( hr ); + + Rectangle rc = hWin.ClientRectangle; + hr = videoWindow.SetWindowPosition( 0, 0, rc.Right, rc.Bottom ); + DsError.ThrowExceptionForHR( hr ); + } + finally + { + if (capFilter != null) + { + Marshal.ReleaseComObject(capFilter); + capFilter = null; + } + if (sampGrabber != null) + { + Marshal.ReleaseComObject(sampGrabber); + sampGrabber = null; + } + if (ibfRenderer != null) + { + Marshal.ReleaseComObject(ibfRenderer); + ibfRenderer = null; + } + if (iPinInFilter != null) + { + Marshal.ReleaseComObject(iPinInFilter); + iPinInFilter = null; + } + if (iPinOutFilter != null) + { + Marshal.ReleaseComObject(iPinOutFilter); + iPinOutFilter = null; + } + if (iPinInDest != null) + { + Marshal.ReleaseComObject(iPinInDest); + iPinInDest = null; + } + } + } + + /// Read and store the properties + private void SaveSizeInfo(ISampleGrabber sampGrabber) + { + int hr; + + // Get the media type from the SampleGrabber + AMMediaType media = new AMMediaType(); + hr = sampGrabber.GetConnectedMediaType( media ); + DsError.ThrowExceptionForHR( hr ); + + if( (media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero) ) + { + throw new NotSupportedException( "Unknown Grabber Media Format" ); + } + + // Grab the size info + VideoInfoHeader videoInfoHeader = (VideoInfoHeader) Marshal.PtrToStructure( media.formatPtr, typeof(VideoInfoHeader) ); + m_videoWidth = videoInfoHeader.BmiHeader.Width; + m_videoHeight = videoInfoHeader.BmiHeader.Height; + m_stride = m_videoWidth * (videoInfoHeader.BmiHeader.BitCount / 8); + + DsUtils.FreeAMMediaType(media); + media = null; + } + /// Set the options on the sample grabber + private void ConfigureSampleGrabber(ISampleGrabber sampGrabber) + { + AMMediaType media; + int hr; + + // Set the media type to Video/RBG24 + media = new AMMediaType(); + media.majorType = MediaType.Video; + media.subType = MediaSubType.ARGB32; + media.formatType = FormatType.VideoInfo; + + hr = sampGrabber.SetMediaType( media ); + DsError.ThrowExceptionForHR( hr ); + + DsUtils.FreeAMMediaType(media); + media = null; + + hr = sampGrabber.SetCallback( this, 1 ); + DsError.ThrowExceptionForHR( hr ); + } + + /// Shut down capture + private void CloseInterfaces() + { + int hr; + + try + { + if( m_FilterGraph != null ) + { + IMediaControl mediaCtrl = m_FilterGraph as IMediaControl; + + // Stop the graph + hr = mediaCtrl.Stop(); + } + } + catch (Exception ex) + { + Debug.WriteLine(ex); + } + +#if DEBUG + if (m_rot != null) + { + m_rot.Dispose(); + } +#endif + + if (m_FilterGraph != null) + { + Marshal.ReleaseComObject(m_FilterGraph); + m_FilterGraph = null; + } + GC.Collect(); + } + + /// sample callback, NOT USED. + int ISampleGrabberCB.SampleCB( double SampleTime, IMediaSample pSample ) + { + Marshal.ReleaseComObject(pSample); + return 0; + } + + /// buffer callback, COULD BE FROM FOREIGN THREAD. + int ISampleGrabberCB.BufferCB( double SampleTime, IntPtr pBuffer, int BufferLen ) + { + Graphics g; + String s; + float sLeft; + float sTop; + SizeF d; + + g = Graphics.FromImage(bitmapOverlay); + g.Clear(System.Drawing.Color.Transparent); + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + + // Prepare to put the specified string on the image + g.DrawRectangle(System.Drawing.Pens.Blue, 0, 0, m_videoWidth - 1, m_videoHeight - 1); + g.DrawRectangle(System.Drawing.Pens.Blue, 1, 1, m_videoWidth - 3, m_videoHeight - 3); + + d = g.MeasureString(m_String, fontOverlay); + + sLeft = (m_videoWidth - d.Width) / 2; + sTop = (m_videoHeight - d.Height ) / 2; + + g.DrawString(m_String, fontOverlay, System.Drawing.Brushes.Red, + sLeft, sTop, System.Drawing.StringFormat.GenericTypographic); + + // Add a frame number in the bottom right + s = "Frame " + m_Count.ToString(); + d = g.MeasureString(s, transparentFont); + sLeft = (m_videoWidth - d.Width) - 10; + sTop = (m_videoHeight - d.Height ) - 10; + + g.DrawString(s, transparentFont, transparentBrush, sLeft, sTop, + System.Drawing.StringFormat.GenericTypographic); + g.Dispose(); + + // need to flip the bitmap so it's the same orientation as the + // video buffer + bitmapOverlay.RotateFlip(RotateFlipType.RotateNoneFlipY); + + // create and copy the video's buffer image to a bitmap + Bitmap v; + v = new Bitmap(m_videoWidth, m_videoHeight, m_stride, + PixelFormat.Format32bppArgb, pBuffer); + g = Graphics.FromImage(v); + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + + // draw the overlay bitmap over the video's bitmap + g.DrawImage(bitmapOverlay, 0, 0, bitmapOverlay.Width, bitmapOverlay.Height); + + // dispose of the various objects + g.Dispose(); + v.Dispose(); + + // Increment frame number. Done this way, frame are zero indexed. + m_Count++; + + return 0; + } + + void SetupBitmap() + { + int fSize; + + // scale the font size in some portion to the video image + fSize = 9 * (m_videoWidth / 64); + bitmapOverlay = new Bitmap(m_videoWidth, m_videoHeight, + System.Drawing.Imaging.PixelFormat.Format32bppArgb); + fontOverlay = new Font("Times New Roman", fSize, System.Drawing.FontStyle.Bold, + System.Drawing.GraphicsUnit.Point); + + // scale the font size in some portion to the video image + fSize = 5 * (m_videoWidth / 64); + transparentFont = new Font("Tahoma", fSize, System.Drawing.FontStyle.Bold, + System.Drawing.GraphicsUnit.Point); + transparentBrush = new SolidBrush(Color.FromArgb(96, 0, 0, 255)); + } + } +} diff --git a/Samples/Players/DxText/DxText-2005.csproj b/Samples/Players/DxText/DxText-2005.csproj new file mode 100644 index 0000000..c790cd3 --- /dev/null +++ b/Samples/Players/DxText/DxText-2005.csproj @@ -0,0 +1,119 @@ + + + Local + 8.0.50727 + 2.0 + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F} + Debug + AnyCPU + App.ico + + + DxText + + + JScript + Grid + IE50 + false + WinExe + DxText + OnBuildSuccess + + + + + + + + + bin\Debug\ + true + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Data + + + System.Drawing + + + System.Windows.Forms + + + System.XML + + + + + + Code + + + Code + + + Form + + + DxText.cs + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Players/DxText/DxText-2005.sln b/Samples/Players/DxText/DxText-2005.sln new file mode 100644 index 0000000..a041373 --- /dev/null +++ b/Samples/Players/DxText/DxText-2005.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DxText-2005", "DxText-2005.csproj", "{B0BB5DBF-3B99-4E4E-8793-984153C7D21F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Players/DxText/DxText-2008.sln b/Samples/Players/DxText/DxText-2008.sln new file mode 100644 index 0000000..7a277de --- /dev/null +++ b/Samples/Players/DxText/DxText-2008.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DxText-2008", "DxText-2008.csproj", "{B0BB5DBF-3B99-4E4E-8793-984153C7D21F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Players/DxText/DxText.cs b/Samples/Players/DxText/DxText.cs new file mode 100644 index 0000000..021f853 --- /dev/null +++ b/Samples/Players/DxText/DxText.cs @@ -0,0 +1,245 @@ +// DxText +// +// Written by Richard L Rosenheim +// richard@rosenheims.com +// May 21, 2005 +// +// Based in a large part upon the DxScan and DxPlayer samples by David Wohlferd +// +// Portions Copyright 2005 - Richard L Rosenheim + +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Windows.Forms; +using System.Data; +using DirectShowLib; + +namespace DxText +{ + /// + /// Summary description for Form1. + /// + public class DxTextForm : System.Windows.Forms.Form + { + internal System.Windows.Forms.Label label1; + internal System.Windows.Forms.Button button1; + internal System.Windows.Forms.TextBox textBox1; + internal System.Windows.Forms.Panel panel1; + internal System.Windows.Forms.Label label2; + internal System.Windows.Forms.TextBox textBox2; + /// + /// Required designer variable. + /// + private System.ComponentModel.Container components = null; + + public DxTextForm() + { + // + // Required for Windows Form Designer support + // + InitializeComponent(); + + // + // TODO: Add any constructor code after InitializeComponent call + // + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if (components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.button1 = new System.Windows.Forms.Button(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.panel1 = new System.Windows.Forms.Panel(); + this.label2 = new System.Windows.Forms.Label(); + this.textBox2 = new System.Windows.Forms.TextBox(); + this.SuspendLayout(); + // + // label1 + // + this.label1.Location = new System.Drawing.Point(8, 8); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(56, 16); + this.label1.TabIndex = 17; + this.label1.Text = "FileName"; + this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // button1 + // + this.button1.Location = new System.Drawing.Point(8, 80); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(64, 32); + this.button1.TabIndex = 16; + this.button1.Text = "Start"; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // textBox1 + // + this.textBox1.Location = new System.Drawing.Point(64, 8); + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size(208, 20); + this.textBox1.TabIndex = 18; + this.textBox1.Text = "c:\\skiing.avi"; + // + // panel1 + // + this.panel1.Location = new System.Drawing.Point(8, 120); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(272, 204); + this.panel1.TabIndex = 15; + // + // label2 + // + this.label2.Location = new System.Drawing.Point(8, 40); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(56, 16); + this.label2.TabIndex = 19; + this.label2.Text = "Text"; + this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // textBox2 + // + this.textBox2.Location = new System.Drawing.Point(64, 40); + this.textBox2.Name = "textBox2"; + this.textBox2.Size = new System.Drawing.Size(208, 20); + this.textBox2.TabIndex = 20; + this.textBox2.Text = "Sample"; + // + // DxTextForm + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(304, 334); + this.Controls.Add(this.label2); + this.Controls.Add(this.textBox2); + this.Controls.Add(this.label1); + this.Controls.Add(this.button1); + this.Controls.Add(this.textBox1); + this.Controls.Add(this.panel1); + this.Name = "DxTextForm"; + this.Text = "DxText"; + this.ResumeLayout(false); + + } + #endregion + + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.Run(new DxTextForm()); + } + + const int WM_GRAPHNOTIFY = 0x8000 + 1; + + Capture cam = null; + private IMediaEventEx mediaEvent = null; + + private void button1_Click(object sender, System.EventArgs e) + { + if (System.IO.File.Exists(textBox1.Text)) + { + Cursor.Current = Cursors.WaitCursor; + button1.Enabled = false; + + if (cam != null) + { + cam.Dispose(); + cam = null; + } + + if (cam == null) + { + cam = new Capture(textBox1.Text, textBox2.Text, panel1); + + mediaEvent = cam.MediaEventEx; + int hr = mediaEvent.SetNotifyWindow(this.Handle, WM_GRAPHNOTIFY, IntPtr.Zero); + + cam.Start(); + } + } + } + + + private void GraphNotifyEvent(ref Message m) + { + EventCode eventCode; + IntPtr p1, p2; + int hr; + //bool closeCam = false; + + hr = mediaEvent.GetEvent(out eventCode, out p1, out p2, 0); + while (hr == 0) + { + // handle the event + + if ((eventCode == EventCode.ErrorAbort) || + (eventCode == EventCode.Complete)) + { + Cursor.Current = Cursors.Default; + button1.Enabled = true; + + //closeCam = true; + } + + // Release parms + mediaEvent.FreeEventParams(eventCode, p1, p2); + + // check for additional events + hr = mediaEvent.GetEvent(out eventCode, out p1, out p2, 0); + } + + // you can dispose of the cam object here, but when you do, the display + // will disappear. if you attempt to dispose of the cam object in the + // loop above, you will cause an exception when a method in mediaEvent + // is invoked. + // + //if (closeCam) + //{ + // cam.Dispose(); + // cam = null; + //} + } + + protected override void WndProc(ref Message m) + { + switch (m.Msg) + { + // if this is a windows media message + case WM_GRAPHNOTIFY: + GraphNotifyEvent(ref m); + break; + + // all other messages + default: + // unhandled window message + base.WndProc(ref m); + break; + } + } + + + } +} diff --git a/Samples/Players/DxText/DxText.csproj b/Samples/Players/DxText/DxText.csproj new file mode 100644 index 0000000..6878962 --- /dev/null +++ b/Samples/Players/DxText/DxText.csproj @@ -0,0 +1,151 @@ + + + + Local + 8.0.50727 + 2.0 + {B0BB5DBF-3B99-4E4E-8793-984153C7D21F} + Debug + AnyCPU + App.ico + + + DxText + + + JScript + Grid + IE50 + false + WinExe + DxText + OnBuildSuccess + + + + + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\Debug\ + true + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Data + + + System.Drawing + + + System.Windows.Forms + + + System.XML + + + + + + Code + + + Code + + + Form + + + DxText.cs + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Players/DxText/DxText.resx b/Samples/Players/DxText/DxText.resx new file mode 100644 index 0000000..a24ad05 --- /dev/null +++ b/Samples/Players/DxText/DxText.resx @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + Private + + + Assembly + + + False + + + Private + + + Assembly + + + Private + + + False + + + Assembly + + + False + + + True + + + Private + + + 8, 8 + + + True + + + Assembly + + + False + + + Private + + + Assembly + + + Private + + + False + + + Assembly + + + False + + + (Default) + + + False + + + False + + + 8, 8 + + + DxTextForm + + + True + + + 80 + + + True + + + Private + + \ No newline at end of file diff --git a/Samples/Players/DxText/readme.txt b/Samples/Players/DxText/readme.txt new file mode 100644 index 0000000..94ccd8b --- /dev/null +++ b/Samples/Players/DxText/readme.txt @@ -0,0 +1,34 @@ +/************************************************************************ + +DirectShowLib - Provide access to DirectShow interfaces via .NET +Copyright (C) 2005 +http://sourceforge.net/projects/directshownet/ + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +**************************************************************************/ + +A sample application showing how to superimpose text strings on a +datastream. The stream is read from an avi file. + + Written by Richard L Rosenheim + richard@rosenheims.com + May 21, 2005 + +Based in a large part upon the DxScan and DxPlayer samples by David Wohlferd + +Portions Copyright 2004 - David Wohlferd david@LimeGreenSocks.com +Portions Copyright 2005 - Richard L Rosenheim +--------------------------------------------------------------------- diff --git a/Samples/Players/EVRPlayer/ConvertImage.cs b/Samples/Players/EVRPlayer/ConvertImage.cs new file mode 100644 index 0000000..d8f1043 --- /dev/null +++ b/Samples/Players/EVRPlayer/ConvertImage.cs @@ -0,0 +1,294 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Diagnostics; +using System.Drawing; +using System.Drawing.Imaging; +using System.Runtime.InteropServices; +using System.Security; + +namespace EVRPlayer +{ + /// + /// Convert RGB bitmaps to various video formats. There isn't much documentation in the individual + /// methods. If you want to learn about video formats, check out http://www.fourcc.org and google. + /// + /// Most of the code I've written for the samples, I sacrificed performance for readability. In this + /// code, I tried to maximize performance. + /// + internal static class ConvertImage + { + /// + /// The format of a 32bit ARGB struct. In c++, this is an RGBQUAD + /// + private struct RGB + { + public byte B; + public byte G; + public byte R; + public byte A; + } + + /// + /// A struct that describes a YUYV pixel + /// + private struct YUYV + { + public byte Y; + public byte U; + public byte Y2; + public byte V; + } + + /// + /// A struct that describes an AYUV pixel + /// + private struct AYUV + { + public byte V; + public byte U; + public byte Y; + public byte A; + } + + [DllImport("Kernel32.dll", ExactSpelling = true, EntryPoint = "RtlMoveMemory"), SuppressUnmanagedCodeSecurity] + private static extern void CopyMemory(IntPtr Destination, IntPtr Source, int Length); + + /// + /// Call the appropriate converter based on the subtype + /// + /// Subtype + /// Width to copy in pixels + /// Height to copy in pixels + /// Stride of target in bytes + /// Pointer to source data + /// Pointer to destination data + public static int ToFormat( + int st, + int dwWidthInPixels, + int dwHeightInPixels, + int dwDestStride, + IntPtr ipSrc, + IntPtr ipDest) + { + int iRes = 0; + + switch (st) + { + case 0x00000003: // RGB - BI_BITFIELDS + iRes = ARGB32_To_ARGB32(dwWidthInPixels, dwHeightInPixels, dwDestStride, ipSrc, ipDest); + break; + + case 0x56555941: // AYUV + iRes = ARGB32_To_AYUV(dwWidthInPixels, dwHeightInPixels, dwDestStride, ipSrc, ipDest); + break; + + case 0x3231564e: // NV12 + iRes = ARGB32_To_NV12(dwWidthInPixels, dwHeightInPixels, dwDestStride, ipSrc, ipDest); + break; + + case 0x32595559: // YUY2 + iRes = ARGB32_To_YUY2(dwWidthInPixels, dwHeightInPixels, dwDestStride, ipSrc, ipDest); + break; + + // This code serves no functional purpose. However, if you remove it, you get + // warning errors during compiles. + case 0x7fffffff: + RGB r = new RGB(); + r.A = 0; + r.B = 0; + r.G = 0; + r.R = 0; + break; + + default: + throw new Exception("Unrecognized target type"); + } + + return iRes; + } + + static public int ARGB32_To_ARGB32( + int dwWidthInPixels, + int dwHeightInPixels, + int dwDestStride, + IntPtr ipSrc, + IntPtr ipDest + ) + { + // Assume 32bit source and dest + Debug.Assert(dwWidthInPixels * 4 == dwDestStride); + + CopyMemory(ipDest, ipSrc, dwDestStride * dwHeightInPixels); + + return (dwWidthInPixels * 4) * dwHeightInPixels; + } + + /// + /// Convert a 32-bit ARGB image to YUY2 + /// + /// Width to copy in pixels + /// Height to copy in pixels + /// Stride of target in bytes + /// Pointer to source data + /// Pointer to destination data + unsafe static public int ARGB32_To_YUY2( + int dwWidthInPixels, + int dwHeightInPixels, + int dwDestStride, + IntPtr ipSrc, + IntPtr ipDest + ) + { + Debug.Assert(dwDestStride >= (dwWidthInPixels * 2)); + + RGB* pSrcPixel = (RGB*)ipSrc; + YUYV* pDestPixel = (YUYV*)ipDest; + int dwUseWidth = dwWidthInPixels / 2; + + for (int y = 0; y < dwHeightInPixels; y++) + { + for (int x = 0; x < dwUseWidth; x++) + { + pDestPixel[x].Y = (byte)(((66 * pSrcPixel->R + 129 * pSrcPixel->G + 25 * pSrcPixel->B + 128) >> 8) + 16); + pDestPixel[x].U = (byte)(((-38 * pSrcPixel->R - 74 * pSrcPixel->G + 112 * pSrcPixel->B + 128) >> 8) + 128); + + pSrcPixel++; + + pDestPixel[x].Y2 = (byte)(((66 * pSrcPixel->R + 129 * pSrcPixel->G + 25 * pSrcPixel->B + 128) >> 8) + 16); + pDestPixel[x].V = (byte)(((112 * pSrcPixel->R - 94 * pSrcPixel->G - 18 * pSrcPixel->B + 128) >> 8) + 128); + + pSrcPixel++; + } + pDestPixel = &pDestPixel[dwDestStride / sizeof(YUYV)]; + } + + return (int)((byte*)pDestPixel - (byte*)ipDest); + } + + /// + /// Convert a 32-bit ARGB image to AYUV + /// + /// Width to copy in pixels + /// Height to copy in pixels + /// Stride of target in bytes + /// Pointer to source data + /// Pointer to destination data + unsafe static public int ARGB32_To_AYUV( + int dwWidthInPixels, + int dwHeightInPixels, + int dwDestStride, + IntPtr ipSrc, + IntPtr ipDest + ) + { + Debug.Assert(dwDestStride >= (dwWidthInPixels * Marshal.SizeOf(typeof(AYUV)))); + + RGB* pSrcPixel = (RGB*)ipSrc; + AYUV* pDestPixel = (AYUV*)ipDest; + + for (int y = 0; y < dwHeightInPixels; y++) + { + for (int x = 0; x < dwWidthInPixels; x++) + { + pDestPixel[x].V = (byte)(((112 * pSrcPixel->R - 94 * pSrcPixel->G - 18 * pSrcPixel->B + 128) >> 8) + 128); + pDestPixel[x].U = (byte)((((-38 * pSrcPixel->R - 74 * pSrcPixel->G + 112 * pSrcPixel->B + 128) >> 8) + 128)); + pDestPixel[x].Y = (byte)((((66 * pSrcPixel->R + 129 * pSrcPixel->G + 25 * pSrcPixel->B + 128) >> 8) + 16)); + pDestPixel[x].A = pSrcPixel->A; + + pSrcPixel++; + } + pDestPixel = &pDestPixel[dwDestStride / sizeof(AYUV)]; + } + + return (int)((byte*)pDestPixel - (byte*)ipDest); + } + + /// + /// Convert a 32-bit ARGB image to NV12 + /// + /// Width to copy in pixels + /// Height to copy in pixels + /// Stride of target in bytes + /// Pointer to source data + /// Pointer to destination data + unsafe static public int ARGB32_To_NV12( + int dwWidthInPixels, + int dwHeightInPixels, + int dwDestStride, + IntPtr ipSrc, + IntPtr ipDest + ) + { + Debug.Assert(dwWidthInPixels % 2 == 0); + Debug.Assert(dwHeightInPixels % 2 == 0); + Debug.Assert(dwDestStride >= dwWidthInPixels); + + RGB* pSrcRow = (RGB*)ipSrc; + byte* pDestY = (byte*)ipDest; + + // Convert the Y plane. + for (int y = 0; y < dwHeightInPixels; y++) + { + RGB* pSrcPixel = (RGB*)pSrcRow; + + for (int x = 0; x < dwWidthInPixels; x++) + { + // Y0 + pDestY[x] = (byte)(((66 * pSrcPixel[x].R + 129 * pSrcPixel[x].G + 25 * pSrcPixel[x].B + 128) >> 8) + 16); + } + pDestY += dwDestStride; + pSrcRow += dwWidthInPixels; + } + + // Calculate the offsets for the V and U planes. + // In NV12, each chroma plane has equal stride and half the height as the Y plane. + byte* pDestUV = (byte*)ipDest; + pDestUV += (dwDestStride * dwHeightInPixels); + + // Convert the V and U planes. + // NV12 is a 4:2:0 format, so each chroma sample is derived from four RGB pixels. + // The chroma samples are packed in one plane (U,V) + pSrcRow = (RGB*)ipSrc; + for (int y = 0; y < dwHeightInPixels; y += 2) + { + RGB* pSrcPixel = (RGB*)pSrcRow; + RGB* pNextSrcRow = (RGB*)(pSrcRow + dwWidthInPixels); + + byte* pbUV = pDestUV; + + for (int x = 0; x < dwWidthInPixels; x += 2) + { + // Use a simple average to downsample the chroma. + + // U + *pbUV++ = (byte)(( + (byte)(((-38 * pSrcPixel[x].R - 74 * pSrcPixel[x].G + 112 * pSrcPixel[x].B + 128) >> 8) + 128) + + (byte)(((-38 * pSrcPixel[x + 1].R - 74 * pSrcPixel[x + 1].G + 112 * pSrcPixel[x + 1].B + 128) >> 8) + 128) + + (byte)(((-38 * pNextSrcRow[x].R - 74 * pNextSrcRow[x].G + 112 * pNextSrcRow[x].B + 128) >> 8) + 128) + + (byte)(((-38 * pNextSrcRow[x + 1].R - 74 * pNextSrcRow[x + 1].G + 112 * pNextSrcRow[x + 1].B + 128) >> 8) + 128) + ) / 4); + + // V + *pbUV++ = (byte)(( + (byte)(((112 * pSrcPixel[x].R - 94 * pSrcPixel[x].G - 18 * pSrcPixel[x].B + 128) >> 8) + 128) + + (byte)(((112 * pSrcPixel[x + 1].R - 94 * pSrcPixel[x + 1].G - 18 * pSrcPixel[x + 1].B + 128) >> 8) + 128) + + (byte)(((112 * pNextSrcRow[x].R - 94 * pNextSrcRow[x].G - 18 * pNextSrcRow[x].B + 128) >> 8) + 128) + + (byte)(((112 * pNextSrcRow[x + 1].R - 94 * pNextSrcRow[x + 1].G - 18 * pNextSrcRow[x + 1].B + 128) >> 8) + 128) + ) / 4); + } + pDestUV += dwDestStride; + + // Skip two lines on the source image. + pSrcRow += (dwWidthInPixels * 2); + } + + return (int)(pDestUV - (byte*)ipDest); + } + } +} diff --git a/Samples/Players/EVRPlayer/DShowPlayer.cs b/Samples/Players/EVRPlayer/DShowPlayer.cs new file mode 100644 index 0000000..3c7eb3b --- /dev/null +++ b/Samples/Players/EVRPlayer/DShowPlayer.cs @@ -0,0 +1,855 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Diagnostics; +using System.Windows.Forms; + +using DirectShowLib; +using MediaFoundation; +using MediaFoundation.EVR; +using MediaFoundation.Transform; +using MediaFoundation.Misc; +using GenericSampleSourceFilterClasses; + +namespace EVRPlayer +{ + internal enum PlaybackState + { + Running, + Paused, + Stopped, + Closed + } + + // GraphEventCallback: + // Defines a callback for the application to handle filter graph events. + public interface GraphEventCallback + { + void OnGraphEvent(EventCode eventCode, IntPtr param1, IntPtr param2); + } + + class DShowPlayer : COMBase, IDisposable + { + #region Member vars + + private ImageHandler[] m_ImageHandlers; + private IPin[] m_pPins; + + private PlaybackState m_state; + + private Control m_hwndVideo; // Video clipping window + private IntPtr m_hwndEvent; // Window to receive events + private int m_EventMsg; // Windows message for graph events + + private AMSeekingSeekingCapabilities m_seekCaps; // Caps bits for IMediaSeeking + + private Guid m_clsidPresenter; // CLSID of a custom presenter. + private float m_fScale; + private PointF m_ptHitTrack; + + // Filter graph interfaces. + private IGraphBuilder m_pGraph; + private IMediaControl m_pControl; + private IMediaEventEx m_pEvent; + private IMediaSeeking m_pSeek; +#if DEBUG + private DsROTEntry m_rot; +#endif + + // EVR filter + private IBaseFilter m_pEVR; + private IMFVideoDisplayControl m_pDisplay; + private IMFVideoMixerControl m_pMixer; + private IMFVideoPositionMapper m_pMapper; + + #endregion + + public DShowPlayer(Control hwndVideo, IntPtr hwnd, int msg) + { + m_state = PlaybackState.Closed; + m_hwndVideo = hwndVideo; + m_hwndEvent = hwnd; + m_EventMsg = msg; + + m_pGraph = null; + m_pControl = null; + m_pEvent = null; + m_pSeek = null; + m_pDisplay = null; + m_pEVR = null; + m_pMapper = null; + m_seekCaps = 0; + m_clsidPresenter = Guid.Empty; + } + ~DShowPlayer() + { + Dispose(); + } + + public PlaybackState State() { return m_state; } + + public void OpenFile(string sFileName, Guid clsidPresenter) + { + int hr = S_Ok; + + IBaseFilter pSource = null; + + // Create a new filter graph. (This also closes the old one, if any.) + InitializeGraph(); + + m_clsidPresenter = clsidPresenter; + + // Add the source filter to the graph. + hr = m_pGraph.AddSourceFilter(sFileName, null, out pSource); + DsError.ThrowExceptionForHR(hr); + + try + { + // Try to render the streams. + RenderStreams(pSource); + + // Get the seeking capabilities. + hr = m_pSeek.GetCapabilities(out m_seekCaps); + DsError.ThrowExceptionForHR(hr); + + // Update our state. + m_state = PlaybackState.Stopped; + } + finally + { + Marshal.ReleaseComObject(pSource); + } + } + + public void OpenOverlay(Guid gPresenter) + { + object o; + + if (m_ImageHandlers != null) + { + foreach (ImageHandler ih in m_ImageHandlers) + { + ih.Dispose(); + } + m_ImageHandlers = null; + } + + m_ImageHandlers = new ImageHandler[2]; + + m_ImageHandlers[0] = new ImageFromPixels(30, new FourCC("YUY2"), 320, 240, 16); + //m_ImageHandlers[0] = new ImageFromPixels(30, new FourCC(3), 320, 240, 32, 255); + //m_ImageHandlers[0] = new ImageFromPixels(30, new FourCC("AYUV"), 320, 240, 32, 255); + //m_ImageHandlers[0] = new ImageFromPixels(30, new FourCC("NV12"), 320, 240, 12, 255); + //m_ImageHandlers[1] = new ImageFromText(30, new FourCC(3), 320, 240, 32); + m_ImageHandlers[1] = new ImageFromText(30, new FourCC("AYUV"), 320, 240, 32); + + InitializeGraph(); + SetupGraph(gPresenter); + + IMFGetService pGetService = (IMFGetService)m_pEVR; + + pGetService.GetService(MFServices.MR_VIDEO_MIXER_SERVICE, typeof(IMFVideoMixerControl).GUID, out o); + m_pMixer = (IMFVideoMixerControl)o; + + pGetService.GetService(MFServices.MR_VIDEO_RENDER_SERVICE, typeof(IMFVideoPositionMapper).GUID, out o); + m_pMapper = (IMFVideoPositionMapper)o; + } + + public bool HasSubstream() { return m_pMixer != null; } + public void SetScale(float fScale) + { + if (m_ImageHandlers == null || m_ImageHandlers.Length < 2) + { + return; + } + if (fScale < 0 || fScale > 1.0) + { + throw new COMException("Invalid scale", E_InvalidArgument); + } + + if (fScale == m_fScale) + { + return; // no-op + } + + if (m_pMixer == null) + { + throw new COMException("No mixer", E_InvalidArgument); + } + + // Get the current position of the substream rectangle. + MFVideoNormalizedRect rect = new MFVideoNormalizedRect(); + + m_pMixer.GetStreamOutputRect(1, rect); + + // When this method is called, the substream might be positioned anywhere + // within the composition rectangle. To resize it, first we scale the + // right/bottom edges up to the maximum, and then scale the left/top edges. + rect.right = Math.Min(rect.left + fScale, 1.0f); + rect.bottom = Math.Min(rect.top + fScale, 1.0f); + + rect.left -= Math.Max(fScale - (rect.right - rect.left), 0.0f); + rect.top -= Math.Max(fScale - (rect.bottom - rect.top), 0.0f); + + // Set the new position. + m_pMixer.SetStreamOutputRect(1, rect); + + m_fScale = fScale; + } + + public bool HitTest(Point pt) + { + if (m_pMapper == null) + { + throw new COMException("null mapper", MFError.MF_E_INVALIDREQUEST); + } + + int hr = 0; + bool bHit = false; + + float x = -1, y = -1; + + // Normalize the coordinates (ie, calculate them as a percentage of + // the video window's entire client area). + Rectangle r = m_hwndVideo.ClientRectangle; + MFRect rc = new MFRect(r.Left, r.Top, r.Right, r.Bottom); + + float x1 = (float)pt.X / rc.right; + float y1 = (float)pt.Y / rc.bottom; + + // Map these coordinates into the coordinate space of the substream. + m_pMapper.MapOutputCoordinateToInputStream( + x1, y1, // Output coordinates + 0, // Output stream (the mixer only has one) + 1, // Input stream (1 = substream) + out x, out y // Receives the normalized input coordinates. + ); + + // If the mapped coordinates fall within [0-1], it's a hit. + if (Succeeded(hr)) + { + bHit = ((x >= 0) && (x <= 1) && (y >= 0) && (y <= 1)); + } + + if (bHit) + { + // Store the hit point. + // We adjust the hit point by the substream scaling factor, so that the + // hit point is now scaled to the reference stream. + + // Example: + // - The hit point is (0.5,0.5), the center of the image. + // - The scaling factor is 0.5, so the substream image is 50% the size + // of the reference stream. + // The adjusted hit point is (0.25,0.25) FROM the origin of the substream + // rectangle but IN units of the reference stream. See DShowPlayer::Track + // for where this is used. + + m_ptHitTrack = new PointF(x * m_fScale, y * m_fScale); + } + + return bHit ? true : false; + } + public void Track(Point pt) + { + if (m_pMixer == null || m_pMapper == null) + { + throw new COMException("null mixer or mapper", MFError.MF_E_INVALIDREQUEST); + } + + Rectangle r = m_hwndVideo.ClientRectangle; + MFRect rc = new MFRect(r.Left, r.Top, r.Right, r.Bottom); + + // x, y: Mouse coordinates, normalized relative to the composition rectangle. + float x = (float)pt.X / rc.right; + float y = (float)pt.Y / rc.bottom; + + // Map the mouse coordinates to the reference stream. + m_pMapper.MapOutputCoordinateToInputStream( + x, y, // Output coordinates + 0, // Output stream (the mixer only has one) + 0, // Input stream (0 = ref stream) + out x, out y // Receives the normalized input coordinates. + ); + + // Offset by the original hit point. + x -= m_ptHitTrack.X; + y -= m_ptHitTrack.Y; + + float max_offset = 1.0f - m_fScale; // Maximum left and top positions for the substream. + + MFVideoNormalizedRect nrcDest = new MFVideoNormalizedRect(); + + if (x < 0) + { + nrcDest.left = 0; + nrcDest.right = m_fScale; + } + else if (x > max_offset) + { + nrcDest.right = 1; + nrcDest.left = max_offset; + } + else + { + nrcDest.left = x; + nrcDest.right = x + m_fScale; + } + + if (y < 0) + { + nrcDest.top = 0; + nrcDest.bottom = m_fScale; + } + else if (y > max_offset) + { + nrcDest.bottom = 1; + nrcDest.top = max_offset; + } + else + { + nrcDest.top = y; + nrcDest.bottom = y + m_fScale; + } + + // Set the new position. + m_pMixer.SetStreamOutputRect(1, nrcDest); + } + + // Streaming + public void Play() + { + if (m_state != PlaybackState.Paused && m_state != PlaybackState.Stopped) + { + throw new COMException("Object in wrong state", DsResults.E_WrongState); + } + + Debug.Assert(m_pGraph != null); // If state is correct, the graph should exist. + + int hr = m_pControl.Run(); + DsError.ThrowExceptionForHR(hr); + + m_state = PlaybackState.Running; + } + public void Pause() + { + if (m_state == PlaybackState.Closed) + { + throw new COMException("Graph in wrong state", DsResults.E_WrongState); + } + + Debug.Assert(m_pGraph != null); // If state is correct, the graph should exist. + + int hr = m_pControl.Pause(); + DsError.ThrowExceptionForHR(hr); + + m_state = PlaybackState.Paused; + } + public void Stop() + { + if (m_state != PlaybackState.Running && m_state != PlaybackState.Paused) + { + throw new COMException("Graph in wrong state", DsResults.E_WrongState); + } + + Debug.Assert(m_pGraph != null); // If state is correct, the graph should exist. + + int hr = m_pControl.Stop(); + DsError.ThrowExceptionForHR(hr); + + m_state = PlaybackState.Stopped; + } + public void Step(int dwFrames) + { + if (m_pGraph == null) + { + throw new COMException("Graph in wrong state", DsResults.E_WrongState); + } + + IVideoFrameStep pStep = (IVideoFrameStep)m_pGraph; + + int hr = pStep.Step(dwFrames, null); + DsError.ThrowExceptionForHR(hr); + + // To step, the Filter Graph Manager first runs the graph. When + // the step is complete, it pauses the graph. For the application, + // we can just report our new state as paused. + m_state = PlaybackState.Paused; + } + + // Video functionality + public bool HasVideo() { return m_pDisplay != null; } + public void RepaintVideo() + { + if (m_pDisplay != null) + { + m_pDisplay.RepaintVideo(); + } + } + + // Filter graph events + public void HandleGraphEvent(GraphEventCallback pCB) + { + if (pCB == null) + { + throw new COMException("No callback set", E_Pointer); + } + + if (m_pEvent == null) + { + throw new COMException("No event pointer", E_Unexpected); + } + + EventCode evCode = 0; + IntPtr param1, param2; + + // Get the events from the queue. + while (Succeeded(m_pEvent.GetEvent(out evCode, out param1, out param2, 0))) + { + // Invoke the callback. + pCB.OnGraphEvent(evCode, param1, param2); + + // Free the event data. + int hr = m_pEvent.FreeEventParams(evCode, param1, param2); + DsError.ThrowExceptionForHR(hr); + } + } + + // Seeking + public bool CanSeek() + { + const AMSeekingSeekingCapabilities caps = + AMSeekingSeekingCapabilities.CanSeekAbsolute | + AMSeekingSeekingCapabilities.CanGetDuration; + + return ((m_seekCaps & caps) == caps); + } + public void SetPosition(long pos) + { + if (m_pControl == null || m_pSeek == null) + { + throw new COMException("pointers not set", E_Unexpected); + } + + int hr; + + hr = m_pSeek.SetPositions( + pos, + AMSeekingSeekingFlags.AbsolutePositioning, + null, + AMSeekingSeekingFlags.NoPositioning); + DsError.ThrowExceptionForHR(hr); + + if (m_ImageHandlers != null) + { + for (int x = 1; x < m_ImageHandlers.Length; x++) + { + IMediaSeeking ims = m_pPins[x] as IMediaSeeking; + + hr = ims.SetPositions( + pos, + AMSeekingSeekingFlags.AbsolutePositioning, + null, + AMSeekingSeekingFlags.NoPositioning); + DsError.ThrowExceptionForHR(hr); + } + } + + // If playback is stopped, we need to put the graph into the paused + // state to update the video renderer with the new frame, and then stop + // the graph again. The IMediaControl::StopWhenReady does this. + if (m_state == PlaybackState.Stopped) + { + hr = m_pControl.StopWhenReady(); + DsError.ThrowExceptionForHR(hr); + } + } + public void GetStopTime(out long pDuration) + { + if (m_pSeek == null) + { + throw new COMException("No seek pointer", E_Unexpected); + } + + int hr = m_pSeek.GetStopPosition(out pDuration); + + // If we cannot get the stop time, try to get the duration. + if (Failed(hr)) + { + hr = m_pSeek.GetDuration(out pDuration); + } + DsError.ThrowExceptionForHR(hr); + } + public void GetCurrentPosition(out long pTimeNow) + { + if (m_pSeek == null) + { + throw new COMException("No seek pointer", E_Unexpected); + } + + int hr = m_pSeek.GetCurrentPosition(out pTimeNow); + DsError.ThrowExceptionForHR(hr); + } + + // Subpicture stuff + private void SetupGraph(Guid clsidPresenter) + { + m_clsidPresenter = clsidPresenter; + + // Get a ICaptureGraphBuilder2 to help build the graph + ICaptureGraphBuilder2 icgb2 = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); + + try + { + int hr; + + // Link the ICaptureGraphBuilder2 to the IFilterGraph2 + hr = icgb2.SetFiltergraph(m_pGraph); + DsError.ThrowExceptionForHR(hr); + + m_pEVR = (IBaseFilter)new EnhancedVideoRenderer(); + hr = m_pGraph.AddFilter(m_pEVR, "EVR"); + DsError.ThrowExceptionForHR(hr); + + InitializeEVR(m_pEVR, m_ImageHandlers.Length, out m_pDisplay); + m_pPins = new IPin[m_ImageHandlers.Length]; + + for (int x = 0; x < m_ImageHandlers.Length; x++) + { + AddGSSF(m_ImageHandlers[x], icgb2, out m_pPins[x]); + } + + // Get the seeking capabilities. + hr = m_pSeek.GetCapabilities(out m_seekCaps); + DsError.ThrowExceptionForHR(hr); + } + finally + { + Marshal.ReleaseComObject(icgb2); + } + + // Update our state. + m_state = PlaybackState.Stopped; + } + private void AddGSSF(ImageHandler ih, ICaptureGraphBuilder2 icgb2, out IPin pPin) + { + int hr; + + // Our data source. An error here means the GSSF2 sample hasn't + // been registered. + IBaseFilter ipsb = (IBaseFilter)new GenericSampleSourceFilter2(); + + try + { + // Get the pin from the filter so we can configure it + pPin = DsFindPin.ByDirection(ipsb, PinDirection.Output, 0); + + // Configure the pin using the provided BitmapInfo + ConfigurePusher((IGenericSampleConfig2)pPin, ih); + + // Add the filter to the graph + hr = m_pGraph.AddFilter(ipsb, "GenericSampleSourceFilter"); + Marshal.ThrowExceptionForHR(hr); + + // Connect the filters together, use the default renderer + hr = icgb2.RenderStream(null, null, pPin, null, m_pEVR); + DsError.ThrowExceptionForHR(hr); + } + finally + { + Marshal.ReleaseComObject(ipsb); + } + } + private void ConfigurePusher(IGenericSampleConfig2 ips, ImageHandler ih) + { + int hr; + + ih.SetMediaType(ips); + + // Specify the callback routine to call with each sample + hr = ips.SetBitmapCB(ih); + DsError.ThrowExceptionForHR(hr); + } + + private void InitializeGraph() + { + int hr = 0; + + TearDownGraph(); + + // Create the Filter Graph Manager. + m_pGraph = (IGraphBuilder)new FilterGraph(); +#if DEBUG + m_rot = new DsROTEntry(m_pGraph); +#endif + + // Query for graph interfaces. (These interfaces are exposed by the graph + // manager regardless of which filters are in the graph.) + m_pControl = (IMediaControl)m_pGraph; + m_pEvent = (IMediaEventEx)m_pGraph; + m_pSeek = (IMediaSeeking)m_pGraph; + + // Set up event notification. + hr = m_pEvent.SetNotifyWindow(m_hwndEvent, m_EventMsg, IntPtr.Zero); + DsError.ThrowExceptionForHR(hr); + } + private void TearDownGraph() + { +#if DEBUG + if (m_rot != null) + { + m_rot.Dispose(); + m_rot = null; + } +#endif + + // Stop sending event messages + if (m_pEvent != null) + { + m_pEvent.SetNotifyWindow(IntPtr.Zero, 0, IntPtr.Zero); + m_pEvent = null; + } + + if (m_pControl != null) + { + m_pControl.Stop(); + m_pControl = null; + } + + if (m_pDisplay != null) + { + //Marshal.ReleaseComObject(m_pDisplay); + m_pDisplay = null; + } + + if (m_pMapper != null) + { + Marshal.ReleaseComObject(m_pMapper); + m_pMapper = null; + } + + if (m_pMixer != null) + { + Marshal.ReleaseComObject(m_pMixer); + m_pMixer = null; + } + + if (m_pEVR != null) + { + Marshal.ReleaseComObject(m_pEVR); + m_pEVR = null; + } + + if (m_pGraph != null) + { + Marshal.ReleaseComObject(m_pGraph); + m_pGraph = null; + } + + m_state = PlaybackState.Closed; + m_seekCaps = 0; + m_pSeek = null; + } + private void RenderStreams(IBaseFilter pSource) + { + int hr; + + bool bRenderedAudio = false; + bool bRenderedVideo = false; + + IBaseFilter pEVR = (IBaseFilter)new EnhancedVideoRenderer(); + IBaseFilter pAudioRenderer = (IBaseFilter)new DSoundRender(); + + try + { + // Add the EVR to the graph. + hr = m_pGraph.AddFilter(pEVR, "EVR"); + DsError.ThrowExceptionForHR(hr); + + InitializeEVR(pEVR, 1, out m_pDisplay); + + // Add the DSound Renderer to the graph. + hr = m_pGraph.AddFilter(pAudioRenderer, "Audio Renderer"); + DsError.ThrowExceptionForHR(hr); + + ICaptureGraphBuilder2 cgb; + cgb = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); + + try + { + hr = cgb.SetFiltergraph(m_pGraph); + DsError.ThrowExceptionForHR(hr); + + // Connect the streams. + hr = cgb.RenderStream(null, MediaType.Video, pSource, null, pEVR); + DsError.ThrowExceptionForHR(hr); + hr = cgb.RenderStream(null, MediaType.Audio, pSource, null, pAudioRenderer); + DsError.ThrowExceptionForHR(hr); + + // If we are using a splitter, the two lines above did nothing. We + // ignore the errors from the next 2 statements in case the 2 lines above + // *did* do something. + hr = cgb.RenderStream(null, null, pSource, null, pEVR); + //DsError.ThrowExceptionForHR(hr); + hr = cgb.RenderStream(null, null, pSource, null, pAudioRenderer); + //DsError.ThrowExceptionForHR(hr); + + IPin pPin = DsFindPin.ByConnectionStatus(pEVR, PinConnectedStatus.Unconnected, 0); + + if (pPin == null) + { + bRenderedVideo = true; + } + else + { + Marshal.ReleaseComObject(pPin); + } + + pPin = DsFindPin.ByConnectionStatus(pAudioRenderer, PinConnectedStatus.Unconnected, 0); + + if (pPin == null) + { + bRenderedAudio = true; + } + else + { + Marshal.ReleaseComObject(pPin); + } + } + finally + { + Marshal.ReleaseComObject(cgb); + } + + // Remove un-used renderers. + + if (!bRenderedVideo) + { + m_pGraph.RemoveFilter(pEVR); + // If we removed the EVR, then we also need to release our + // pointer to the EVR display interfaace + //Marshal.ReleaseComObject(m_pDisplay); + m_pDisplay = null; + } + else + { + // EVR is still in the graph. Cache the interface pointer. + Debug.Assert(pEVR != null); + m_pEVR = pEVR; + } + + if (!bRenderedAudio) + { + m_pGraph.RemoveFilter(pAudioRenderer); + } + } + finally + { + Marshal.ReleaseComObject(pAudioRenderer); + } + } + + private void InitializeEVR(IBaseFilter pEVR, int dwStreams, out IMFVideoDisplayControl ppDisplay) + { + IMFVideoRenderer pRenderer; + IMFVideoDisplayControl pDisplay; + IEVRFilterConfig pConfig; + IMFVideoPresenter pPresenter; + + // Before doing anything else, set any custom presenter or mixer. + + // Presenter? + if (m_clsidPresenter != Guid.Empty) + { + Type type = Type.GetTypeFromCLSID(m_clsidPresenter); + + // An error here means that the custom presenter sample from + // http://mfnet.sourceforge.net hasn't been installed or + // registered. + pPresenter = (IMFVideoPresenter)Activator.CreateInstance(type); + + try + { + pRenderer = (IMFVideoRenderer)pEVR; + + pRenderer.InitializeRenderer(null, pPresenter); + } + finally + { + //Marshal.ReleaseComObject(pPresenter); + } + } + + // Continue with the rest of the set-up. + + // Set the video window. + object o; + IMFGetService pGetService = null; + pGetService = (IMFGetService)pEVR; + pGetService.GetService(MFServices.MR_VIDEO_RENDER_SERVICE, typeof(IMFVideoDisplayControl).GUID, out o); + + try + { + pDisplay = (IMFVideoDisplayControl)o; + } + catch + { + Marshal.ReleaseComObject(o); + throw; + } + + try + { + // Set the number of streams. + pDisplay.SetVideoWindow(m_hwndVideo.Handle); + + if (dwStreams > 1) + { + pConfig = (IEVRFilterConfig)pEVR; + pConfig.SetNumberOfStreams(dwStreams); + } + + // Set the display position to the entire window. + Rectangle r = m_hwndVideo.ClientRectangle; + MFRect rc = new MFRect(r.Left, r.Top, r.Right, r.Bottom); + + pDisplay.SetVideoPosition(null, rc); + + // Return the IMFVideoDisplayControl pointer to the caller. + ppDisplay = pDisplay; + } + finally + { + //Marshal.ReleaseComObject(pDisplay); + } + m_pMixer = null; + } + + #region IDisposable Members + + public void Dispose() + { + GC.SuppressFinalize(this); + TearDownGraph(); + + if (m_ImageHandlers != null) + { + foreach (ImageHandler ih in m_ImageHandlers) + { + ih.Dispose(); + } + m_ImageHandlers = null; + } + m_hwndVideo = null; + } + + #endregion + } +} diff --git a/Samples/Players/EVRPlayer/EVRPlayer-2008.sln b/Samples/Players/EVRPlayer/EVRPlayer-2008.sln new file mode 100644 index 0000000..3a6890e --- /dev/null +++ b/Samples/Players/EVRPlayer/EVRPlayer-2008.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EVRPlayer-2008", "EVRPlayer-2008.csproj", "{4C65947E-100E-4176-B893-C3067ED8DC11}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4C65947E-100E-4176-B893-C3067ED8DC11}.Debug|x86.ActiveCfg = Debug|x86 + {4C65947E-100E-4176-B893-C3067ED8DC11}.Debug|x86.Build.0 = Debug|x86 + {4C65947E-100E-4176-B893-C3067ED8DC11}.Release|x86.ActiveCfg = Release|x86 + {4C65947E-100E-4176-B893-C3067ED8DC11}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Players/EVRPlayer/EVRPlayer.csproj b/Samples/Players/EVRPlayer/EVRPlayer.csproj new file mode 100644 index 0000000..f2d80ef --- /dev/null +++ b/Samples/Players/EVRPlayer/EVRPlayer.csproj @@ -0,0 +1,133 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {4C65947E-100E-4176-B893-C3067ED8DC11} + WinExe + Properties + EVRPlayer + EVRPlayer + v3.5 + 512 + + + + + + + 3.5 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + bin\x86\Debug\ + DEBUG;TRACE + full + x86 + prompt + false + true + false + + + bin\x86\Release\ + TRACE + true + pdbonly + x86 + prompt + true + + + + + + + + + + + Form + + + Form1.cs + + + + + + Form1.cs + Designer + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + {b78c0f3b-071a-4fd2-829d-7a67e0f7bd1c} + MediaFoundation + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + \ No newline at end of file diff --git a/Samples/Players/EVRPlayer/Form1.Designer.cs b/Samples/Players/EVRPlayer/Form1.Designer.cs new file mode 100644 index 0000000..45cb654 --- /dev/null +++ b/Samples/Players/EVRPlayer/Form1.Designer.cs @@ -0,0 +1,283 @@ +namespace EVRPlayer +{ + partial class Form1 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.panVideoWin = new System.Windows.Forms.Panel(); + this.bnPlay = new System.Windows.Forms.Button(); + this.bnPause = new System.Windows.Forms.Button(); + this.bnStop = new System.Windows.Forms.Button(); + this.bnFrameStep = new System.Windows.Forms.Button(); + this.seekbar = new System.Windows.Forms.TrackBar(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.SubpicSize = new System.Windows.Forms.TrackBar(); + this.label1 = new System.Windows.Forms.Label(); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.openFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.subpictureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.evToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.timer1 = new System.Windows.Forms.Timer(this.components); + this.label2 = new System.Windows.Forms.Label(); + ((System.ComponentModel.ISupportInitialize)(this.seekbar)).BeginInit(); + this.groupBox1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.SubpicSize)).BeginInit(); + this.menuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // panVideoWin + // + this.panVideoWin.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.panVideoWin.Location = new System.Drawing.Point(5, 56); + this.panVideoWin.Name = "panVideoWin"; + this.panVideoWin.Size = new System.Drawing.Size(355, 242); + this.panVideoWin.TabIndex = 97; + this.panVideoWin.Paint += new System.Windows.Forms.PaintEventHandler(this.panVideoWin_Paint); + this.panVideoWin.MouseMove += new System.Windows.Forms.MouseEventHandler(this.panVideoWin_MouseMove); + this.panVideoWin.MouseDown += new System.Windows.Forms.MouseEventHandler(this.panVideoWin_MouseDown); + this.panVideoWin.MouseUp += new System.Windows.Forms.MouseEventHandler(this.panVideoWin_MouseUp); + // + // bnPlay + // + this.bnPlay.Enabled = false; + this.bnPlay.Location = new System.Drawing.Point(7, 308); + this.bnPlay.Name = "bnPlay"; + this.bnPlay.Size = new System.Drawing.Size(75, 23); + this.bnPlay.TabIndex = 1; + this.bnPlay.Text = "Play"; + this.bnPlay.UseVisualStyleBackColor = true; + this.bnPlay.Click += new System.EventHandler(this.bnPlay_Click); + // + // bnPause + // + this.bnPause.Enabled = false; + this.bnPause.Location = new System.Drawing.Point(98, 308); + this.bnPause.Name = "bnPause"; + this.bnPause.Size = new System.Drawing.Size(75, 23); + this.bnPause.TabIndex = 2; + this.bnPause.Text = "Pause"; + this.bnPause.UseVisualStyleBackColor = true; + this.bnPause.Click += new System.EventHandler(this.bnPause_Click); + // + // bnStop + // + this.bnStop.Enabled = false; + this.bnStop.Location = new System.Drawing.Point(189, 308); + this.bnStop.Name = "bnStop"; + this.bnStop.Size = new System.Drawing.Size(75, 23); + this.bnStop.TabIndex = 3; + this.bnStop.Text = "Stop"; + this.bnStop.UseVisualStyleBackColor = true; + this.bnStop.Click += new System.EventHandler(this.bnStop_Click); + // + // bnFrameStep + // + this.bnFrameStep.Enabled = false; + this.bnFrameStep.Location = new System.Drawing.Point(280, 308); + this.bnFrameStep.Name = "bnFrameStep"; + this.bnFrameStep.Size = new System.Drawing.Size(75, 23); + this.bnFrameStep.TabIndex = 4; + this.bnFrameStep.Text = "Step"; + this.bnFrameStep.UseVisualStyleBackColor = true; + this.bnFrameStep.Click += new System.EventHandler(this.bnStep_Click); + // + // seekbar + // + this.seekbar.Enabled = false; + this.seekbar.Location = new System.Drawing.Point(7, 337); + this.seekbar.Name = "seekbar"; + this.seekbar.Size = new System.Drawing.Size(350, 45); + this.seekbar.TabIndex = 5; + this.seekbar.TickStyle = System.Windows.Forms.TickStyle.None; + this.seekbar.MouseCaptureChanged += new System.EventHandler(this.seekbar_MouseCaptureChanged); + this.seekbar.Scroll += new System.EventHandler(this.seekbar_Scroll); + this.seekbar.MouseDown += new System.Windows.Forms.MouseEventHandler(this.seekbar_MouseDown); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.SubpicSize); + this.groupBox1.Controls.Add(this.label1); + this.groupBox1.Location = new System.Drawing.Point(7, 363); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(350, 77); + this.groupBox1.TabIndex = 99; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Subpicture stream"; + // + // SubpicSize + // + this.SubpicSize.Enabled = false; + this.SubpicSize.Location = new System.Drawing.Point(39, 22); + this.SubpicSize.Maximum = 100; + this.SubpicSize.Name = "SubpicSize"; + this.SubpicSize.Size = new System.Drawing.Size(305, 45); + this.SubpicSize.TabIndex = 6; + this.SubpicSize.TickFrequency = 10; + this.SubpicSize.Value = 65; + this.SubpicSize.Scroll += new System.EventHandler(this.SubpicSize_Scroll); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(5, 28); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(38, 13); + this.label1.TabIndex = 98; + this.label1.Text = "Size %"; + // + // menuStrip1 + // + this.menuStrip1.BackColor = System.Drawing.SystemColors.MenuBar; + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.fileToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.RenderMode = System.Windows.Forms.ToolStripRenderMode.System; + this.menuStrip1.Size = new System.Drawing.Size(364, 24); + this.menuStrip1.TabIndex = 0; + this.menuStrip1.Text = "menuStrip1"; + // + // fileToolStripMenuItem + // + this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.openFileToolStripMenuItem, + this.subpictureToolStripMenuItem, + this.evToolStripMenuItem, + this.toolStripSeparator1, + this.exitToolStripMenuItem}); + this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); + this.fileToolStripMenuItem.Text = "&File"; + // + // openFileToolStripMenuItem + // + this.openFileToolStripMenuItem.Name = "openFileToolStripMenuItem"; + this.openFileToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O))); + this.openFileToolStripMenuItem.Size = new System.Drawing.Size(167, 22); + this.openFileToolStripMenuItem.Text = "&Open File"; + this.openFileToolStripMenuItem.Click += new System.EventHandler(this.openFileToolStripMenuItem_Click); + // + // subpictureToolStripMenuItem + // + this.subpictureToolStripMenuItem.Name = "subpictureToolStripMenuItem"; + this.subpictureToolStripMenuItem.Size = new System.Drawing.Size(167, 22); + this.subpictureToolStripMenuItem.Text = "&Subpicture"; + this.subpictureToolStripMenuItem.Click += new System.EventHandler(this.subpictureToolStripMenuItem_Click); + // + // evToolStripMenuItem + // + this.evToolStripMenuItem.Name = "evToolStripMenuItem"; + this.evToolStripMenuItem.Size = new System.Drawing.Size(167, 22); + this.evToolStripMenuItem.Text = "&EVR Presenter"; + this.evToolStripMenuItem.Click += new System.EventHandler(this.evToolStripMenuItem_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(164, 6); + // + // exitToolStripMenuItem + // + this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; + this.exitToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Q))); + this.exitToolStripMenuItem.Size = new System.Drawing.Size(167, 22); + this.exitToolStripMenuItem.Text = "E&xit"; + this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); + // + // timer1 + // + this.timer1.Interval = 200; + this.timer1.Tick += new System.EventHandler(this.timer1_Tick); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(72, 35); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(220, 13); + this.label2.TabIndex = 96; + this.label2.Text = "Click and drag the box that has the clock in it"; + this.label2.Visible = false; + // + // Form1 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(364, 461); + this.Controls.Add(this.label2); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.seekbar); + this.Controls.Add(this.bnFrameStep); + this.Controls.Add(this.bnStop); + this.Controls.Add(this.bnPause); + this.Controls.Add(this.bnPlay); + this.Controls.Add(this.panVideoWin); + this.Controls.Add(this.menuStrip1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MainMenuStrip = this.menuStrip1; + this.MaximizeBox = false; + this.Name = "Form1"; + this.Text = "Form1"; + this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.Form1_FormClosed); + ((System.ComponentModel.ISupportInitialize)(this.seekbar)).EndInit(); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.SubpicSize)).EndInit(); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Panel panVideoWin; + private System.Windows.Forms.Button bnPlay; + private System.Windows.Forms.Button bnPause; + private System.Windows.Forms.Button bnStop; + private System.Windows.Forms.Button bnFrameStep; + private System.Windows.Forms.TrackBar seekbar; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.TrackBar SubpicSize; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem openFileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem subpictureToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem evToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; + private System.Windows.Forms.Timer timer1; + private System.Windows.Forms.Label label2; + } +} + diff --git a/Samples/Players/EVRPlayer/Form1.cs b/Samples/Players/EVRPlayer/Form1.cs new file mode 100644 index 0000000..62a6a96 --- /dev/null +++ b/Samples/Players/EVRPlayer/Form1.cs @@ -0,0 +1,423 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Diagnostics; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Threading; + +namespace EVRPlayer +{ + public partial class Form1 : Form, GraphEventCallback + { + #region Members + + const int FRAME_STEP_INCREMENT = 5; // How many frames to step, when frame-stepping. + const int ONE_MSEC = 10000; // The number of 100-ns in 1 msec + const int WM_GRAPH_EVENT = 0x8000 + 1; + + Guid m_PresenterCLSID = new Guid("DD1BE413-E999-47f1-A107-9BC1F3DCB6C7"); + + // The c++ sample EVRPresenter's CLSID + //Guid m_PresenterCLSID = new Guid(0x9707fc9c, 0x807b, 0x41e3, 0x98, 0xa8, 0x75, 0x17, 0x6f, 0x95, 0xa0, 0x62); + + DShowPlayer m_pPlayer; + PlaybackState m_state; + + bool m_bFrameStepping; // TRUE if a frame step is in progress. + bool m_bDrag; // TRUE if a drag is in progress + + #endregion + + public Form1() + { + InitializeComponent(); + + m_state = PlaybackState.Closed; + m_pPlayer = new DShowPlayer(panVideoWin, Handle, WM_GRAPH_EVENT); + m_bDrag = false; + } + + protected override void WndProc(ref Message m) + { + switch (m.Msg) + { + // A message arrived from the graph + case WM_GRAPH_EVENT: + { + m_pPlayer.HandleGraphEvent(this); + break; + } + default: + { + base.WndProc(ref m); + break; + } + } + } + + private void openFileToolStripMenuItem_Click(object sender, EventArgs e) + { + Invoker I = new Invoker(); + + // Show the File Open dialog. + DialogResult dr = I.Invoke(); + + if (dr == DialogResult.OK) + { + m_pPlayer.OpenFile(I.FileName(), Guid.Empty); + SubpicSize_Scroll(null, null); + + // Update the state of the UI. (Regardless of success/failure code) + UpdateUI(); + + // Invalidate the video window, in case there is an old video + // frame from the previous file and there is no video now. (eg, the + // new file is audio only, or we failed to open this file.) + panVideoWin.Invalidate(); + + // Update the seek bar to match the current state. + UpdateSeekBar(); + } + } + + private void subpictureToolStripMenuItem_Click(object sender, EventArgs e) + { + SubpicSize.Enabled = true; + m_pPlayer.OpenOverlay(Guid.Empty); + SubpicSize_Scroll(null, null); + + // Update the state of the UI. (Regardless of success/failure code) + UpdateUI(); + + // Invalidate the video window, in case there is an old video + // frame from the previous file and there is no video now. (eg, the + // new file is audio only, or we failed to open this file.) + panVideoWin.Invalidate(); + + // Update the seek bar to match the current state. + UpdateSeekBar(); + } + + private void evToolStripMenuItem_Click(object sender, EventArgs e) + { + Invoker I = new Invoker(); + + // Show the File Open dialog. + DialogResult dr = I.Invoke(); + + if (dr == DialogResult.OK) + { + m_pPlayer.OpenFile(I.FileName(), m_PresenterCLSID); + SubpicSize_Scroll(null, null); + + // Update the state of the UI. (Regardless of success/failure code) + UpdateUI(); + + // Invalidate the video window, in case there is an old video + // frame from the previous file and there is no video now. (eg, the + // new file is audio only, or we failed to open this file.) + panVideoWin.Invalidate(); + + // Update the seek bar to match the current state. + UpdateSeekBar(); + } + } + + private void exitToolStripMenuItem_Click(object sender, EventArgs e) + { + if (m_pPlayer != null) + { + m_pPlayer.Dispose(); + m_pPlayer = null; + } + Application.Exit(); + } + + private void bnPlay_Click(object sender, EventArgs e) + { + m_pPlayer.Play(); + + UpdateUI(); + } + + private void bnStop_Click(object sender, EventArgs e) + { + m_pPlayer.Stop(); + + // Seek back to the start. + if (m_pPlayer.CanSeek()) + { + m_pPlayer.SetPosition(0); + } + + UpdateUI(); + } + + private void bnPause_Click(object sender, EventArgs e) + { + m_pPlayer.Pause(); + + UpdateUI(); + } + + private void bnStep_Click(object sender, EventArgs e) + { + m_pPlayer.Step(FRAME_STEP_INCREMENT); + + m_bFrameStepping = true; + UpdateUI(); + } + + private void timer1_Tick(object sender, EventArgs e) + { + // If the player can seek, update the seek bar with the current position. + if (m_pPlayer.CanSeek()) + { + long timeNow; + + m_pPlayer.GetCurrentPosition(out timeNow); + seekbar.Value = (int)(timeNow / ONE_MSEC); + } + } + + private void Form1_FormClosed(object sender, FormClosedEventArgs e) + { + if (m_pPlayer != null) + { + m_pPlayer.Dispose(); + m_pPlayer = null; + } + } + + private void seekbar_Scroll(object sender, EventArgs e) + { + // Update the position continuously. + m_pPlayer.SetPosition(ONE_MSEC * seekbar.Value); + } + + private void seekbar_MouseCaptureChanged(object sender, EventArgs e) + { + if (m_state == PlaybackState.Stopped) + { + m_pPlayer.Stop(); + } + else if (m_state == PlaybackState.Running) + { + m_pPlayer.Play(); + } + } + + private void seekbar_MouseDown(object sender, MouseEventArgs e) + { + // Pause when the scroll action begins. + m_state = m_pPlayer.State(); + m_pPlayer.Pause(); + } + + private void SubpicSize_Scroll(object sender, EventArgs e) + { + // Scale the subpicture. + float fNewSize = (float)SubpicSize.Value / 100.0f; + + m_pPlayer.SetScale(fNewSize); + + } + + private void panVideoWin_MouseDown(object sender, MouseEventArgs e) + { + if (m_pPlayer.HasSubstream()) + { + // Test whether the user clicked on the substream image. + if (m_pPlayer.HitTest(new Point(e.X, e.Y))) + { + m_bDrag = true; + panVideoWin.Capture = true; + } + } + } + + private void panVideoWin_MouseUp(object sender, MouseEventArgs e) + { + if (m_bDrag) + { + panVideoWin.Capture = false; + m_bDrag = false; + } + } + + private void panVideoWin_MouseMove(object sender, MouseEventArgs e) + { + if (m_bDrag) + { + m_pPlayer.Track(new Point(e.X, e.Y)); + } + } + + private void UpdateUI() + { + bool bPlay = false; + bool bPause = false; + bool bStop = false; + bool bFrameStep = false; + + switch (m_pPlayer.State()) + { + case PlaybackState.Running: + bPause = true; + bStop = true; + bFrameStep = true; + break; + + case PlaybackState.Paused: + bPlay = true; + bStop = true; + bFrameStep = true; + break; + + case PlaybackState.Stopped: + bPlay = true; + bFrameStep = true; + break; + } + + bnPlay.Enabled = bPlay; + bnPause.Enabled = bPause; + bnStop.Enabled = bStop; + bnFrameStep.Enabled = (bFrameStep && !m_bFrameStepping); + + // Trackbar to resize the substream. + SubpicSize.Enabled = m_pPlayer.HasSubstream(); + label2.Visible = SubpicSize.Enabled; + } + + private void UpdateSeekBar() + { + // If the player can seek, set the seekbar range and start the time. + // Otherwise, disable the seekbar. + if (m_pPlayer.CanSeek()) + { + seekbar.Enabled = true; + + long rtDuration; + m_pPlayer.GetStopTime(out rtDuration); + + seekbar.Maximum = (int)(rtDuration / ONE_MSEC); + seekbar.LargeChange = seekbar.Maximum / 10; + + // Start the timer + timer1.Enabled = true; + } + else + { + seekbar.Enabled = false; + + // Stop the old timer, if any. + timer1.Enabled = false; + } + } + + private void NotifyError(string sMessage, int hrStatus) + { + MessageBox.Show(sMessage + " 0x" + hrStatus.ToString("x"), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + private void panVideoWin_Paint(object sender, PaintEventArgs e) + { + m_pPlayer.RepaintVideo(); + } + + #region GraphEventCallback Members + + public void OnGraphEvent(DirectShowLib.EventCode eventCode, IntPtr param1, IntPtr param2) + { + Debug.WriteLine(eventCode); + switch (eventCode) + { + case DirectShowLib.EventCode.Complete: + bnStop_Click(null, null); + break; + + case DirectShowLib.EventCode.StepComplete: + // Frame stepping has completed. + m_bFrameStepping = false; + UpdateUI(); + break; + + case DirectShowLib.EventCode.ErrorAbort: + NotifyError("An error occurred during playback.", param1.ToInt32()); + UpdateUI(); + break; + + default: + break; + } + } + + #endregion + } + + /// + /// Opens a specified FileOpenDialog box on an STA thread + /// + public class Invoker + { + private string m_FileName; + private DialogResult m_InvokeResult; + + // Constructor is passed the dialog to use + public Invoker() + { + m_InvokeResult = DialogResult.None; + m_FileName = null; + } + + // Start the thread and get the result + public DialogResult Invoke() + { + Thread thdInvokeThread; + + // No reason to waste a thread if we aren't MTA + if (Thread.CurrentThread.GetApartmentState() == ApartmentState.MTA) + { + thdInvokeThread = new Thread(new ThreadStart(InvokeMethod)); + thdInvokeThread.SetApartmentState(ApartmentState.STA); + + thdInvokeThread.Start(); + thdInvokeThread.Join(); + thdInvokeThread = null; + } + else + { + // If we are already STA, just invoke the method + InvokeMethod(); + } + + return m_InvokeResult; + } + + public string FileName() + { + return m_FileName; + } + + // The thread entry point + private void InvokeMethod() + { + OpenFileDialog ofDialog = new OpenFileDialog(); + + m_InvokeResult = ofDialog.ShowDialog(); + + if (m_InvokeResult == DialogResult.OK) + { + m_FileName = ofDialog.FileName; + } + } + } +} diff --git a/Samples/Players/EVRPlayer/Form1.resx b/Samples/Players/EVRPlayer/Form1.resx new file mode 100644 index 0000000..382f7cd --- /dev/null +++ b/Samples/Players/EVRPlayer/Form1.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 265, 17 + + \ No newline at end of file diff --git a/Samples/Players/EVRPlayer/Overlay.cs b/Samples/Players/EVRPlayer/Overlay.cs new file mode 100644 index 0000000..34b127c --- /dev/null +++ b/Samples/Players/EVRPlayer/Overlay.cs @@ -0,0 +1,941 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Diagnostics; +using System.Drawing; +using System.Drawing.Imaging; +using System.Runtime.InteropServices; +using System.Security; + +using DirectShowLib; +using MediaFoundation; +using GenericSampleSourceFilterClasses; + +namespace EVRPlayer +{ + /// + /// This abstract class serves as a wrapper for the calls and callbacks used by the + /// GSSF provider. It is intended to be generic, and should work for both video and + /// audio data. + /// + abstract internal class GSSFHandler : MediaFoundation.Misc.COMBase, IDisposable, IGenericSampleCB2 + { + #region Definitions + + /// + /// 100 ns - used by a number of DS methods + /// + protected const int UNIT = 10000000; + + [DllImport("NTDll.dll", ExactSpelling = true, EntryPoint = "RtlCompareMemory"), SuppressUnmanagedCodeSecurity] + protected static extern int CompareMemory(IntPtr Destination, IntPtr Source, [MarshalAs(UnmanagedType.U4)] int Length); + + #endregion + + /// + /// Number of callbacks that returned a positive result + /// + protected volatile int m_iFrameNumber; + /// + /// Current MediaType + /// + protected AMMediaType m_pmt; + + /// + /// Public constructor. Subclasses should call this in their own constructors + /// + public GSSFHandler() + { + m_iFrameNumber = 0; + } + + /// + /// Calls the GSSF to specify the media type. Must be called before pins try to connect. + /// + /// Pointer to the GSSF + abstract public void SetMediaType(IGenericSampleConfig2 psc); + + /// + /// Set the timestamps on samples. It is not always required that media samples have + /// timestamps, so this default implementation does not set one. To set a timestamp + /// on the samples, override this method in a child class. + /// + /// Pointer to the sample interface + /// HRESULT + virtual public int SetTimeStamps(IMediaSample pSample) + { + return S_Ok; + } + + /// + /// Release all member variables. Child classes that implement IDisposable should + /// call base.Dispose(); + /// + virtual public void Dispose() + { + GC.SuppressFinalize(this); + + if (m_pmt != null) + { + DsUtils.FreeAMMediaType(m_pmt); + m_pmt = null; + } + } + + #region IGenericSampleCB2 Members + + /// + /// 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. + /// This default implementation is based on CMediaType operator== (from the c++ baseclasses). + /// + /// The proposed alternative media type. Do NOT call DsUtils.FreeAMMediaType on this + /// S_Ok to accept the media type, E_Fail to decline + virtual public int CheckMediaType(AMMediaType amt) + { + if ( + (amt.majorType == m_pmt.majorType) && + (amt.subType == m_pmt.subType) && + (amt.formatType == m_pmt.formatType) && + (amt.formatSize == m_pmt.formatSize) && + ((amt.formatSize == 0) || + (amt.formatPtr != IntPtr.Zero && + m_pmt.formatPtr != IntPtr.Zero && + CompareMemory(amt.formatPtr, m_pmt.formatPtr, amt.formatSize) == amt.formatSize)) + ) + { + return S_Ok; + } + + return E_Fail; + } + /// + /// The callback from the GSSF to populate the sample. This class isn't intended + /// to be overridden. Child classes should instead implement PopulateSample, + /// which this method calls. + /// + /// The sample to populate + /// HRESULT + public int SampleCallback(IMediaSample pSample) + { + int hr; + IntPtr pData; + + try + { + // Get the buffer into which we will copy the data + hr = pSample.GetPointer(out pData); + if (hr >= 0) + { + // Find out the amount of space in the buffer + int cbData = pSample.GetSize(); + + lock (this) + { + hr = SetTimeStamps(pSample); + if (hr >= 0) + { + int iRead; + + // Populate the sample + hr = PopulateSample(pData, cbData, out iRead); + if (hr >= 0) + { + if (hr == S_Ok) // 1 == End of stream + { + // increment the frame number for next time + m_iFrameNumber++; + } + else + { + m_iFrameNumber = 0; + } + + pSample.SetActualDataLength(iRead); + } + } + } + } + } + finally + { + // Release our pointer the the media sample. THIS IS ESSENTIAL! If + // you don't do this, the graph will stop after about 2 samples. + Marshal.ReleaseComObject(pSample); + } + + return hr; + } + /// + /// Notifies us that the media type has changed. When CheckMediaType is called, you can't + /// assume that returning S_Ok means that the specified media type *will* be used. When + /// the two pins involved in the connection finally agree on a media type, that media + /// type will be passed to this method. + /// Also, if the media *samples* include a media type (see IMediaSample::GetMediaType on + /// MSDN), the new type is checked with CheckMediaType, then passed to MediaTypeChanged. + /// + /// The proposed alternative media type. You must eventually call DsUtils.FreeAMMediaType on this to avoid a leak + /// The return value is ignored. Declining a media type must occur in CheckMediaType + virtual public int OnMediaTypeChanged(AMMediaType pmt) + { + // Free the old value (if any) + if (m_pmt != null) + { + DsUtils.FreeAMMediaType(m_pmt); + } + m_pmt = pmt; + + return S_Ok; + } + + /// + /// Called when the GSSF OnThreadCreate method is called. See the docs for the baseclasses. + /// + /// HRESULT + virtual public int OnThreadCreate() + { + return S_Ok; + } + /// + /// Called when the GSSF OnThreadDestroy method is called. See the docs for the baseclasses. + /// + /// HRESULT + virtual public int OnThreadDestroy() + { + return S_Ok; + } + + /// + /// Called by the GSSF to determine whether we support seeking + /// + /// What seek operations we support + /// Total duration + /// HRESULT + virtual public int Startup(out AMSeekingSeekingCapabilities sc, out long lDuration) + { + sc = AMSeekingSeekingCapabilities.None; // By default, say we support nothing + lDuration = 0; // have no duration + + return E_NotImplemented; // and don't support seeking + } + + /// + /// Called by the GSSF to notify use that the start point has changed. See the + /// baseclasses for ChangeStart. + /// + /// New start time in 100ns units + /// HRESULT + virtual public int ChangeStart(long rtStart) + { + return E_NotImplemented; + } + + /// + /// Called by the GSSF to notify use that the start point has changed. See the + /// baseclasses for ChangeStop. + /// + /// New stop time in 100ns units + /// S_FALSE if a flush is needed, or an HRESULT + virtual public int ChangeStop(long rtStop) + { + return E_NotImplemented; + } + + /// + /// Called by the GSSF to get our current position. + /// + /// Our current position in 100ns units + /// HRESULT + virtual public int GetCurrentPosition(out long lPosition) + { + lPosition = 0; + + return E_NotImplemented; + } + + #endregion + + /// + /// This method must be implemented by child classes. It is called by SampleCallback + /// and performs the actual work of filling in the sample. + /// + /// Pointer to the buffer to fill + /// Size of the buffer + /// Returns the number of buffer bytes used + /// HRESULT for failure, S_Ok for success, or S_False for end of stream + abstract protected int PopulateSample(IntPtr ip, int iSize, out int iRead); + } + + /// + /// This class is a somewhat more specific implementation of GSSFHandler. It is intended to + /// work primarily with video streams. + /// + abstract internal class ImageHandler : GSSFHandler, IDisposable + { + // How many frames to return before returning End Of Stream + protected const int MAXFRAMES = 300; + + #region Member Variables + + /// Frames per second + protected int m_Fps; + /// Media Subtype + protected MediaFoundation.Misc.FourCC m_SubType; + /// Video width in pixels + protected int m_Width; + /// Video height in pixels + protected int m_Height; + /// Bits per pixel + protected short m_bpp; + + /// Bitmap's stride. May not always be (m_bpp * m_width) / 8 + protected int m_Stride; + + /// The bitmap into which the frame is drawn + protected Bitmap m_bitmapOverlay; + /// The pointer to the bitmaps's buffer + protected IntPtr m_pData; + /// The current stream time to write onto the sample + protected long m_rtSampleTime; + /// The current stream time to write onto the sample + protected long m_rtStopTime; + + #endregion + + /// + /// Public constructor. Subclasses should call this in their own constructors + /// + /// Frames per second; 30 = 30 FPS + /// Used to construct the AMMediaType and BmiHeader.Compression + /// Frame width in pixels + /// Frame height in pixels + /// Bits per pixel + public ImageHandler(int FPS, MediaFoundation.Misc.FourCC SubType, int width, int height, short bpp) + : base() + { + m_rtSampleTime = 0; + m_rtStopTime = MAXFRAMES * (UNIT / FPS); + + // The BYTES per pixel of the buffer in which we do our work. Since this buffer + // is ARGB, that's 32bpp / 8 + const int WORKINGBPP = (32 / 8); + + // Store the passed in parameters + m_Fps = FPS; + m_SubType = SubType; + m_Height = height; + m_Width = width; + m_bpp = bpp; + m_Stride = (width * bpp) / 8; // This is an estimate, and may be overwritten later + + // Create a buffer to do our drawing in. It is *much* easier to draw in a Format32bppArgb + // buffer than a YUYV buffer. So, we draw in ARGB, and translate to the appropriate format. + m_pData = Marshal.AllocCoTaskMem(m_Width * m_Height * WORKINGBPP); + m_bitmapOverlay = new Bitmap(m_Width, m_Height, m_Width * WORKINGBPP, PixelFormat.Format32bppArgb, m_pData); + } + + /// + /// This method calls the GSSF and specifies the media type to use. This + /// overridable method builds a generic AMMediaType based on the arguments + /// passed to the constructor. + /// + /// Interface pointer to the GSSF + public override void SetMediaType(IGenericSampleConfig2 psc) + { + VideoInfoHeader2 vih2 = new VideoInfoHeader2(); + + vih2.BmiHeader = new BitmapInfoHeader(); + vih2.SrcRect = new DsRect(0, 0, m_Width, m_Height); + vih2.TargetRect = new DsRect(0, 0, m_Width, m_Height); + + // Build a BitmapInfo struct using the parms from the file + vih2.BmiHeader.Size = Marshal.SizeOf(typeof(BitmapInfoHeader)); + vih2.BmiHeader.Width = m_Width; + vih2.BmiHeader.Height = m_Height; + vih2.BmiHeader.Planes = 1; + vih2.BmiHeader.BitCount = m_bpp; + vih2.BmiHeader.Compression = (int)m_SubType; + vih2.BmiHeader.ImageSize = ((vih2.BmiHeader.BitCount * vih2.BmiHeader.Width) / 8) * vih2.BmiHeader.Height; + vih2.BmiHeader.XPelsPerMeter = 0; + vih2.BmiHeader.YPelsPerMeter = 0; + vih2.BmiHeader.ClrUsed = 0; + vih2.BmiHeader.ClrImportant = 0; + vih2.BmiHeader.Height *= -1; // The bitmap is a top-down DIB + + vih2.BitRate = (int)(vih2.BmiHeader.ImageSize * 8 * m_Fps); + vih2.BitErrorRate = 0; + vih2.AvgTimePerFrame = UNIT / m_Fps; + vih2.InterlaceFlags = 0; + vih2.CopyProtectFlags = 0; + vih2.PictAspectRatioX = 4; + vih2.PictAspectRatioY = 3; + vih2.ControlFlags = 0; + vih2.Reserved2 = 0; + + // Free any previous media type + if (m_pmt != null) + { + DsUtils.FreeAMMediaType(m_pmt); + } + + m_pmt = new AMMediaType(); + m_pmt.majorType = MediaType.Video; + m_pmt.fixedSizeSamples = true; + m_pmt.temporalCompression = false; + m_pmt.formatType = FormatType.VideoInfo2; + m_pmt.sampleSize = vih2.BmiHeader.ImageSize; + + int iStride; + + if ((int)m_SubType == 3) // 3 == BI_BITFIELDS + { + Debug.Assert(vih2.BmiHeader.BitCount == 32); // 16bit uses a slightly different format + + m_pmt.subType = MediaSubType.ARGB32; // Can't use the compression type to compute the subtype + + m_pmt.formatSize = Marshal.SizeOf(vih2) + (3 * (m_bpp / 8)); // Make room for the bitfields + m_pmt.formatPtr = Marshal.AllocCoTaskMem(m_pmt.formatSize); + + if (m_bpp != 16) + { + vih2.BmiHeader.Size += 3 * sizeof(int); + + // One byte per color + Marshal.WriteInt32(m_pmt.formatPtr, 0xff); // Red + Marshal.WriteInt32(m_pmt.formatPtr, 4, 0xff00); // Green + Marshal.WriteInt32(m_pmt.formatPtr, 8, 0xff0000); // Blue + } + else + { + // Todo - 555, 565 + } + + iStride = (m_Width * m_bpp) / 8; + } + else + { + // Calculate the stride from the compression type + MFExtern.MFGetStrideForBitmapInfoHeader(vih2.BmiHeader.Compression, vih2.BmiHeader.Width, out iStride); + + m_pmt.subType = (Guid)m_SubType; + m_pmt.formatSize = Marshal.SizeOf(vih2); + m_pmt.formatPtr = Marshal.AllocCoTaskMem(m_pmt.formatSize); + } + + m_pmt.sampleSize = iStride * m_Height; + Marshal.StructureToPtr(vih2, m_pmt.formatPtr, false); + + int hr = psc.SetPinMediaType(m_pmt); + DsError.ThrowExceptionForHR(hr); + } + + /// + /// Notifies us that the media type has changed. When CheckMediaType is called, you can't + /// assume that returning S_Ok means that the specified media type *will* be used. When + /// the two pins involved in the connection finally agree on a media type, that media + /// type will be passed to this method. + /// Also, if the media *samples* include a media type (see IMediaSample::GetMediaType on + /// MSDN), the new type is checked with CheckMediaType, then passed to MediaTypeChanged. + /// + /// The proposed alternative media type. You must eventually call DsUtils.FreeAMMediaType on this to avoid a leak + /// The return value is ignored. Declining a media type must occur in CheckMediaType + override public int OnMediaTypeChanged(AMMediaType pmt) + { + // Let the parent do its bit + base.OnMediaTypeChanged(pmt); + + Debug.Assert(pmt.formatType == FormatType.VideoInfo2); + + // Overwrite the stride based on the new AMMediaType. This code is essential since + // sometimes (like when using the EVR), the stride is changed by sending a new + // AMMediaType on the samples. + + VideoInfoHeader2 vih2 = (VideoInfoHeader2)Marshal.PtrToStructure(m_pmt.formatPtr, typeof(VideoInfoHeader2)); + + // Compute the stride + if (vih2.BmiHeader.Compression == 3) + { + // It isn't possible for MFGetStrideForBitmapInfoHeader to handle straight RGB + // formats (they'd need to rest of the BMIHeader). Handle that as a special case + m_Stride = (m_Width * m_bpp) / 8; + } + else + { + MFExtern.MFGetStrideForBitmapInfoHeader((int)m_SubType, vih2.BmiHeader.Width, out m_Stride); + } + + return S_Ok; + } + + /// + /// Override OnThreadCreate to ensure sample times are set correctly + /// + /// HRESULT + public override int OnThreadCreate() + { + m_rtSampleTime = 0; + + return base.OnThreadCreate(); + } + + /// + /// 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. + /// + /// The proposed alternative media type. Do NOT call DsUtils.FreeAMMediaType on this + /// S_Ok to accept the media type, a negative value to decline + 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; + } + + /// + /// Calculate and populate the timestamps + /// + /// The IMediaSample to set the timestamps on + /// HRESULT + override public int SetTimeStamps(IMediaSample pSample) + { + // Time per frame + int tpf = (UNIT / m_Fps); + + DsLong rtStart = new DsLong(m_rtSampleTime); + m_rtSampleTime += tpf; + + DsLong rtStop = new DsLong(m_rtSampleTime); + + // Set the times into the sample + int hr = pSample.SetTime(rtStart, rtStop); + + // Set TRUE on every sample for uncompressed frames + if (hr >= 0) + { + hr = pSample.SetSyncPoint(true); + } + + return hr; + } + + /// + /// Called by the GSSF to determine whether we support seeking + /// + /// What seek operations we support + /// Total duration + /// HRESULT + public override int Startup(out AMSeekingSeekingCapabilities sc, out long lDuration) + { + sc = AMSeekingSeekingCapabilities.CanGetCurrentPos | + AMSeekingSeekingCapabilities.CanGetDuration | + AMSeekingSeekingCapabilities.CanSeekAbsolute | + AMSeekingSeekingCapabilities.CanSeekBackwards | + AMSeekingSeekingCapabilities.CanSeekForwards; + + lDuration = MAXFRAMES * (UNIT / m_Fps); + + return S_Ok; + } + + /// + /// Called by the GSSF to notify use that the start point has changed. See the + /// baseclasses for ChangeStart. + /// + /// New start time in 100ns units + /// HRESULT + public override int ChangeStart(long rtStart) + { + m_iFrameNumber = (int)(rtStart / (UNIT / m_Fps)); + m_rtSampleTime = 0; + + return S_Ok; + } + + /// + /// Called by the GSSF to notify use that the start point has changed. See the + /// baseclasses for ChangeStop. + /// + /// New stop time in 100ns units + /// S_FALSE if a flush is needed, or an HRESULT + public override int ChangeStop(long rtStop) + { + m_rtStopTime = rtStop; + + return S_Ok; + } + + /// + /// Called by the GSSF to get our current position. + /// + /// Our current position in 100ns units + /// HRESULT + public override int GetCurrentPosition(out long lPosition) + { + lPosition = m_iFrameNumber * (UNIT / m_Fps); + + return S_Ok; + } + + /// + /// Release the member variables + /// + override public void Dispose() + { + base.Dispose(); + if (m_bitmapOverlay != null) + { + Marshal.FreeCoTaskMem(m_pData); + m_pData = IntPtr.Zero; + + m_bitmapOverlay.Dispose(); + m_bitmapOverlay = null; + } + } + } + + /// + /// Class to provide a video stream. It paints the background various colors + /// and draws a piegraph section on top of it. + /// + internal class ImageFromPixels : ImageHandler, IDisposable + { + #region Member Variables + + /// Red + private int m_r; + /// Green + private int m_g; + /// Blue + private int m_b; + + #endregion + + /// + /// Constructor + /// + /// Frames per second; 30 = 30 FPS + /// Used to construct the AMMediaType and BmiHeader.Compression + /// Frame width in pixels + /// Frame height in pixels + /// Bits per pixel + public ImageFromPixels(int FPS, MediaFoundation.Misc.FourCC SubType, int width, int height, short bpp) + : base(FPS, SubType, width, height, bpp) + { + // Pick a random starting point for the RGB of the background + Random r = new Random(); + m_r = r.Next(256); + m_b = r.Next(256); + m_g = r.Next(256); + } + ~ImageFromPixels() + { + Dispose(); + } + + /// + /// Override of PopulateSample to fill in the sample data + /// + /// Pointer to the buffer to fill + /// Size of the buffer + /// Returns the number of buffer bytes used + /// HRESULT for failure, S_Ok for success, or S_False for end of stream + override protected int PopulateSample(IntPtr ip, int iSize, out int iRead) + { + int hr = S_Ok; + + // Send back MAXFRAMES frames, then end the stream + if (m_rtSampleTime < m_rtStopTime) + { + // It is *much* easier to draw in a Format32bppArgb buffer than a YUYV, NV12, etc buffer. So, + // we draw in ARGB, then translate it to the appropriate format. + + Graphics g; + Rectangle r1 = new Rectangle(0, 0, m_Width - 1, m_Height - 1); + + // Get a graphics handle. + g = Graphics.FromImage(m_bitmapOverlay); + + try + { + // Clear the entire box to the specified color + g.Clear(Color.FromArgb(255, m_r % 255, m_g % 255, m_b % 255)); + + // For testing purposes, sometimes it's useful to clear to a solid color + //g.Clear(Color.Red); + + // Draw a pie chart segment on the background, simply because we can + g.FillPie(Brushes.BlueViolet, r1, m_iFrameNumber, (m_iFrameNumber + 123) % 360); + } + finally + { + g.Dispose(); + } + + // Convert the RGB bitmap to the appropriate output format + iRead = ConvertImage.ToFormat((int)m_SubType, m_Width, m_Height, m_Stride, m_pData, ip); + Debug.Assert(iRead <= iSize); + + // Reset for the next call + m_r += 1; + m_g += 3; + m_b += 7; + } + else + { + hr = S_False; // End of stream + iRead = 0; + } + + return hr; + } + } + + /// + /// Class to provide a video stream. It creates a transparent box in which it prints the current time. + /// + internal class ImageFromText : ImageHandler, IDisposable + { + #region Member Variables + + /// The font used to write the text + private Font m_fontOverlay; + + #endregion + + /// + /// Constructor + /// + /// Frames per second; 30 = 30 FPS + /// Used to construct the AMMediaType and BmiHeader.Compression + /// Frame width in pixels + /// Frame height in pixels + /// Bits per pixel + public ImageFromText(int FPS, MediaFoundation.Misc.FourCC SubType, int width, int height, short bpp) + : base(FPS, SubType, width, height, bpp) + { + } + ~ImageFromText() + { + Dispose(); + } + + /// + /// Overrides parent class to compute font size for output string + /// + /// The proposed alternative media type. You must eventually call DsUtils.FreeAMMediaType on this to avoid a leak + /// HRESULT + public override int OnMediaTypeChanged(AMMediaType pmt) + { + int hr = base.OnMediaTypeChanged(pmt); + + int fSize = 9 * (m_Width / 64); + + if (m_fontOverlay != null) + { + // Release the old font + m_fontOverlay.Dispose(); + } + + m_fontOverlay = new Font("Times New Roman", fSize, FontStyle.Bold, GraphicsUnit.Point); + + return hr; + } + + /// + /// Override of PopulateSample to fill in the sample data + /// + /// Pointer to the buffer to fill + /// Size of the buffer + /// Returns the number of buffer bytes used + /// HRESULT for failure, S_Ok for success, or S_False for end of stream + override protected int PopulateSample(IntPtr ip, int iSize, out int iRead) + { + int hr = S_Ok; + + // Send back MAXFRAMES frames, then end the stream + if (m_rtSampleTime < m_rtStopTime) + { + // It is *much* easier to draw in a Format32bppArgb buffer than a YUYV buffer. So, + // we draw in ARGB, and translate to the appropriate format. + + Graphics g; + float sLeft; + float sTop; + SizeF d; + + // The string to print + string sString = DateTime.Now.ToString("h:mm:ss"); + sString = m_iFrameNumber.ToString(); + + // Get a graphics handle. We do the drawing on an ARGB32 bitmap, then + // convert the bitmap to the appropriate format (below) + g = Graphics.FromImage(m_bitmapOverlay); + + try + { + // Clear the entire box to transparent + g.Clear(Color.Transparent); + + // Prepare to put the specified string on the image + g.DrawRectangle(Pens.Blue, 0, 0, m_Width - 1, m_Height - 1); + g.DrawRectangle(Pens.Blue, 1, 1, m_Width - 3, m_Height - 3); + + // Print the string in the box + d = g.MeasureString(sString, m_fontOverlay); + + sLeft = (m_Width - d.Width) / 2; + sTop = (m_Height - d.Height) / 2; + + g.DrawString(sString, m_fontOverlay, Brushes.Red, sLeft, sTop, StringFormat.GenericTypographic); + } + finally + { + g.Dispose(); + } + + // Convert the RGB bitmap to the appropriate format + iRead = ConvertImage.ToFormat((int)m_SubType, m_Width, m_Height, m_Stride, m_pData, ip); + Debug.Assert(iRead <= iSize); + } + else + { + hr = S_False; // End of stream + iRead = 0; + } + + return hr; + } + + /// + /// Release all member variables. + /// + override public void Dispose() + { + if (m_fontOverlay != null) + { + m_fontOverlay.Dispose(); + m_fontOverlay = null; + } + base.Dispose(); + } + } +} diff --git a/Samples/Players/EVRPlayer/Program.cs b/Samples/Players/EVRPlayer/Program.cs new file mode 100644 index 0000000..f8b9a17 --- /dev/null +++ b/Samples/Players/EVRPlayer/Program.cs @@ -0,0 +1,26 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Windows.Forms; + +namespace EVRPlayer +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [MTAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new Form1()); + } + } +} diff --git a/Samples/Players/EVRPlayer/PushClasses2.cs b/Samples/Players/EVRPlayer/PushClasses2.cs new file mode 100644 index 0000000..5c0c50e --- /dev/null +++ b/Samples/Players/EVRPlayer/PushClasses2.cs @@ -0,0 +1,68 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +// This file has the c# declarations needed to call the GSSF2 filter. + +using System; +using System.Runtime.InteropServices; + +using DirectShowLib; + +namespace GenericSampleSourceFilterClasses +{ + [ComImport, Guid("E6409B54-52E6-40fb-B075-2AAF35EDF751")] + public class GenericSampleSourceFilter2 + { + } + + [ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), + Guid("37E2B3ED-5E24-4528-AEBA-20269A592E1E")] + public interface IGenericSampleCB2 + { + [PreserveSig] + int CheckMediaType([In, MarshalAs(UnmanagedType.LPStruct)] AMMediaType amt); + + [PreserveSig] + int OnMediaTypeChanged([In, MarshalAs(UnmanagedType.LPStruct)] AMMediaType amt); + + [PreserveSig] + int SampleCallback(IMediaSample pSample); + + #region Support for seeking + + [PreserveSig] + int OnThreadCreate(); + + [PreserveSig] + int OnThreadDestroy(); + + [PreserveSig] + int Startup(out AMSeekingSeekingCapabilities sc, out long lDuration); + + [PreserveSig] + int ChangeStart(long rtStart); + + [PreserveSig] + int ChangeStop(long rtStop); + + [PreserveSig] + int GetCurrentPosition(out long lPosition); + + #endregion + } + + [ComVisible(true), Guid("B8F15920-95BB-4305-A29C-6D96AD017815"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IGenericSampleConfig2 + { + [PreserveSig] + int SetPinMediaType([In, MarshalAs(UnmanagedType.LPStruct)] AMMediaType amt); + + [PreserveSig] + int SetBitmapCB(IGenericSampleCB2 pfn); + } +} diff --git a/Samples/Players/EVRPlayer/ReadMe.txt b/Samples/Players/EVRPlayer/ReadMe.txt new file mode 100644 index 0000000..d684fcb --- /dev/null +++ b/Samples/Players/EVRPlayer/ReadMe.txt @@ -0,0 +1,30 @@ +As with any code that is labeled "sample," you should be clear about what level of quality you are expecting. +While there are no bugs or gotchas in this code TO MY KNOWLEDGE, that doesn't mean there aren't any. You should +review the code yourself, and test it for your specific purposes. + +To use option 2, you must register the GSSF2 provider. + +To use option 3, you must register the EVRPresenter, which in turn requires the Hack project. The +EVRPresenter and Hack projects are part of MFNet, and can be found at http://MFNet.SourceForge.Net + + +This project is a c# translation of the c++ EVRPlayer sample that ships with the Windows SDK. + +It has 3 different operations + +1) Open File - This is just building your basic DirectShow graph. There isn't much here that's interesting + to long-time DirectShow users. It does show how to configure the number of input pins on the EVR. + +2) SubPicture - This one is more interesting. The EVR is able to perform overlays using up to 16 video + streams. However, in order to show how that works, you need to have something that generates multiple + video streams, and those streams must be in formats that the EVR is willing to mix (a short list). + The code here uses the GSSF2 to produce a YUY2 and a AYUV stream. It overlays the AYUV on top of the YUY2. + After you have chosen this menu option, hit play, then drag the box (the AYUV video) around the screen. And + use the "Size %" slider to shrink or grow this size of the window. The guts of the video generating are in + Overlay.cs (see ImageFromPixels.PopulateSample) and ConvertImage.cs. Pretty cool stuff. + +3) EVR Presenter - Here's were things get serious. While the code here isn't much different from Open File, it + instructs the EVR to use a presenter that we specify. Check out the code in the EVR Presenter project. Be + aware the in order to use the c# presenter, the caller must be MTA (see MTAThread). + + diff --git a/Samples/Players/EVRPlayer/properties/AssemblyInfo.cs b/Samples/Players/EVRPlayer/properties/AssemblyInfo.cs new file mode 100644 index 0000000..0653195 --- /dev/null +++ b/Samples/Players/EVRPlayer/properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("EVRPlayer")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("EVRPlayer")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2009")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("0d875aa3-ae49-475d-b3cf-74148ab872b3")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Samples/Players/EVRPlayer/properties/Resources.Designer.cs b/Samples/Players/EVRPlayer/properties/Resources.Designer.cs new file mode 100644 index 0000000..a1fad9d --- /dev/null +++ b/Samples/Players/EVRPlayer/properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace EVRPlayer.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EVRPlayer.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Samples/Players/EVRPlayer/properties/Resources.resx b/Samples/Players/EVRPlayer/properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/Samples/Players/EVRPlayer/properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Samples/Players/EVRPlayer/properties/Settings.Designer.cs b/Samples/Players/EVRPlayer/properties/Settings.Designer.cs new file mode 100644 index 0000000..f5c6607 --- /dev/null +++ b/Samples/Players/EVRPlayer/properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace EVRPlayer.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Samples/Players/EVRPlayer/properties/Settings.settings b/Samples/Players/EVRPlayer/properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Samples/Players/EVRPlayer/properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Samples/Players/GMFPlay/GMFPlay-2008.sln b/Samples/Players/GMFPlay/GMFPlay-2008.sln new file mode 100644 index 0000000..5d32460 --- /dev/null +++ b/Samples/Players/GMFPlay/GMFPlay-2008.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GMFPlay-2008", "GMFPlay\GMFPlay-2008.csproj", "{FE48353B-7945-400B-87B2-660BE9225083}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FE48353B-7945-400B-87B2-660BE9225083}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FE48353B-7945-400B-87B2-660BE9225083}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FE48353B-7945-400B-87B2-660BE9225083}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FE48353B-7945-400B-87B2-660BE9225083}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Players/GMFPlay/GMFPlay.sln b/Samples/Players/GMFPlay/GMFPlay.sln new file mode 100644 index 0000000..199ca9f --- /dev/null +++ b/Samples/Players/GMFPlay/GMFPlay.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GMFPlay", "GMFPlay\GMFPlay.csproj", "{FE48353B-7945-400B-87B2-660BE9225083}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FE48353B-7945-400B-87B2-660BE9225083}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FE48353B-7945-400B-87B2-660BE9225083}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FE48353B-7945-400B-87B2-660BE9225083}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FE48353B-7945-400B-87B2-660BE9225083}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Players/GMFPlay/GMFPlay/ClipPlayer.cs b/Samples/Players/GMFPlay/GMFPlay/ClipPlayer.cs new file mode 100644 index 0000000..d6c40ea --- /dev/null +++ b/Samples/Players/GMFPlay/GMFPlay/ClipPlayer.cs @@ -0,0 +1,920 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text; +using DirectShowLib; +using DirectShowLib.GDCL; +using System.Runtime.InteropServices; +using System.Diagnostics; + +namespace GMFPlay +{ + public class ClipPlayer : IDisposable + { + #region Constants + + private const int S_OK = 0; + private const int VFW_E_UNSUPPORTED_AUDIO = unchecked((int)0x8004025C); + private const int E_FAIL = unchecked((int)0x80004005); + private const int E_INVALIDARG = unchecked((int)0x80000003); + private const int VFW_S_STATE_INTERMEDIATE = unchecked((int)0x00040237); + + #endregion + + #region Member variables + + private ArrayList m_Clips; + private bool m_bLoop; + private long m_tDuration; + private long m_tStartPosition; + private bool m_bActive; + private IntPtr m_hwndApp; + private int m_msgEvent; + private int m_msgSegment; + private int m_pPlayNext; + private int m_itCurrent; + + private IGMFBridgeController m_pController; + private IGraphBuilder m_pRenderGraph; + private IBaseFilter m_pRenderGraphSourceFilter; + + #endregion + + public ClipPlayer(IntPtr hwnd, int msgSegment, int msgEvent) + { + m_bLoop = false; + m_tDuration = 0; + m_tStartPosition = 0; + m_bActive = false; + m_hwndApp = hwnd; + m_msgEvent = msgEvent; + m_msgSegment = msgSegment; + m_pPlayNext = -1; + + m_Clips = new ArrayList(5); + + m_pController = new GMFBridgeController() as IGMFBridgeController; + + m_pController.SetNotify(hwnd, msgSegment); + + // we use a video and an audio stream, + // options: + //don't allow compressed in source graphs, + //don't discard when not connected + m_pController.AddStream(true, eFormatType.Uncompressed, false); + m_pController.AddStream(false, eFormatType.Uncompressed, false); + + // increase buffering at the join, so that audio does not run out + m_pController.SetBufferMinimum(200); + + m_itCurrent = m_Clips.Count; + } + + public bool IsCued() + { + IMediaControl pMC = m_pRenderGraph as IMediaControl; + if (pMC != null) + { + FilterState fs; + int hr = pMC.GetState(0, out fs); + if (hr == VFW_S_STATE_INTERMEDIATE) + { + return false; + } + } + return true; + } + + public long TotalDuration() + { + return m_tDuration; + } + + public int AddClip(string path, out ClipEntry pClip) + { + int it = m_Clips.Count; + + pClip = new ClipEntry(); + m_Clips.Add(pClip); + + int hr = pClip.Create(m_pController, path); + + // if we expect both audio and video, then all clips + // must have both audio and video. + // If the first clip is video only, then switch + // to video-only automatically + if ((hr == VFW_E_UNSUPPORTED_AUDIO) && (m_Clips.Count == 1)) + { + // new controller, different options (only one video stream) + if (m_pController != null) + { + Marshal.ReleaseComObject(m_pController); + m_pController = null; + } + m_pController = new GMFBridgeController() as IGMFBridgeController; + m_pController.SetNotify(m_hwndApp, m_msgSegment); + m_pController.AddStream(true, eFormatType.Uncompressed, false); + m_pController.SetBufferMinimum(200); + + // try again + hr = pClip.Create(m_pController, path); + } + + if (hr >= 0) + { + pClip.SetStartPosition(m_tDuration); + m_tDuration += pClip.Duration(); + + // if this is the first clip, create the render graph + if (m_Clips.Count == 1) + { + m_pRenderGraph = new FilterGraph() as IGraphBuilder; + hr = m_pController.CreateRenderGraph(pClip.SinkFilter(), m_pRenderGraph, out m_pRenderGraphSourceFilter); + if (hr >= 0 && m_hwndApp != IntPtr.Zero) + { + IMediaEventEx pME = m_pRenderGraph as IMediaEventEx; + if (pME != null) + { + pME.SetNotifyWindow(m_hwndApp, m_msgEvent, IntPtr.Zero); + } + } + } + } + else + { + pClip.Dispose(); + m_Clips.RemoveAt(it); + } + + return hr; + } + + public int Play() + { + // make all graphs active + int hr = S_OK; + if (!m_bActive) + { + UpdateDuration(); + hr = Pause(); + } + + ClipEntry ce = (ClipEntry)m_Clips[m_itCurrent]; + if (ce.Graph() == null) + { + hr = E_FAIL; + } + + if (hr >= 0) + { + IMediaControl pMC = m_pRenderGraph as IMediaControl; + hr = pMC.Run(); + } + return hr; + } + + public int Pause() + { + // make all graphs active + if (!m_bActive) + { + // render graph first, or data may be discarded + IMediaControl pMC = m_pRenderGraph as IMediaControl; + pMC.Pause(); + + // seek all source graphs to correct start positions + SeekSourceGraphs(); + + // activate each graph + foreach(ClipEntry ce in m_Clips) + { + IMediaControl pMC2 = ce.Graph() as IMediaControl; + pMC2.Run(); + } + + m_bActive = true; + } + + IMediaControl pMC3 = m_pRenderGraph as IMediaControl; + if (pMC3 != null) + { + pMC3.Pause(); + } + return S_OK; + } + + public int Stop() + { + if (m_bActive) + { + // deactivate all graphs + IMediaControl pMC = m_pRenderGraph as IMediaControl; + if (pMC != null) + { + pMC.Stop(); + } + foreach(ClipEntry it in m_Clips) + { + it.Stop(); + } + m_bActive = false; + } + + // rewind on stop + m_itCurrent = m_Clips.Count; + m_tStartPosition = 0; + m_pPlayNext = -1; + return S_OK; + } + + public void OnEndOfSegment1() + { + if (m_itCurrent == m_Clips.Count) + { + // ? already at the end + return; + } + + int itOld = m_itCurrent; + + // locate next graph + if (m_pPlayNext < 0) + { + m_itCurrent++; + + if (m_itCurrent == m_Clips.Count) + { + if (!m_bLoop) + { + // no more clips, so allow EOS to propagate through + // render graph. We will receive EC_COMPLETE eventually. + m_pController.NoMoreSegments(); + + // disconnect graphs -- but we cannot do that until NoMoreSegments has + // sent the EndOfStream through the bridge + m_pController.BridgeGraphs(null, null); + return; + } + else + { + m_pController.BridgeGraphs(null, null); + m_itCurrent = 0; + } + } + } + else + { + m_itCurrent = m_pPlayNext; + m_pPlayNext = -1; + } + + // disconnect graphs before seeking the source graph + m_tStartPosition = 0; + + ClipEntry ce = (ClipEntry)m_Clips[m_itCurrent]; + + // looping to same graph? rewind now + if (m_itCurrent == itOld) + { + ce.Prime(0); + } + else + { + // need to rewind clip for next time round + // unless we are reusing it immediately (ie looping single clip) + // it's better to do this when not in use + ClipEntry ce3 = (ClipEntry)m_Clips[itOld]; + ce3.Prime(0); + } + + // now we are about to connect it, so as soon as data is delivered out of the graph it + // is no longer primed for re-use (it will need a new seek before using again) + ce.InUse(); + + // reconnect + m_pController.BridgeGraphs(ce.SinkFilter(), m_pRenderGraphSourceFilter); + } + + public void OnEndOfSegment() + { + if (m_itCurrent == m_Clips.Count) + { + // ? already at the end + return; + } + + int itOld = m_itCurrent; + + // locate next graph + m_itCurrent++; + if (m_pPlayNext >= 0) + { + // jump to specified clip + m_itCurrent = m_pPlayNext; + m_pPlayNext = -1; + } + + if (m_itCurrent == m_Clips.Count) + { + if (!m_bLoop) + { + // no more clips, so allow EOS to propagate through + // render graph. We will receive EC_COMPLETE eventually. + m_pController.NoMoreSegments(); + + // disconnect graphs -- but we cannot do that until NoMoreSegments has + // sent the EndOfStream through the bridge + m_pController.BridgeGraphs(null, null); + return; + } + + // disconnect graphs before seeking the source graph + m_pController.BridgeGraphs(null, null); + m_itCurrent = 0; + m_tStartPosition = 0; + } + + ClipEntry ce = (ClipEntry)m_Clips[m_itCurrent]; + + // has this graph been rewound? + ce.Prime(); + + // now we are about to connect it, so as soon as data is delivered out of the graph it + // is no longer primed for re-use (it will need a new seek before using again) + ce.InUse(); + + // reconnect + m_pController.BridgeGraphs(ce.SinkFilter(), m_pRenderGraphSourceFilter); + + if (m_bLoop && (m_itCurrent != itOld)) + { + ce = (ClipEntry)m_Clips[itOld]; + + // need to rewind clip for next time round + // unless we are reusing it immediately (ie looping single clip) + // it's better to do this when not in use + ce.Prime(0); + } + } + + public void OnEvent() + { + IMediaEventEx pME = m_pRenderGraph as IMediaEventEx; + if (pME != null) + { + EventCode lEvent; + IntPtr l1, l2; + while (pME.GetEvent(out lEvent, out l1, out l2, 0) == S_OK) + { + switch (lEvent) + { + case EventCode.Complete: + Stop(); + break; + case EventCode.VideoSizeChanged: + ResizeWindowToVideo(); + break; + } + pME.FreeEventParams(lEvent, l1, l2); + } + } + } + + public void ResizeWindowToVideo() + { + IVideoWindow pVW = m_pRenderGraph as IVideoWindow; + IBasicVideo pBV = m_pRenderGraph as IBasicVideo; + if ((pVW != null) && (pBV != null)) + { + // size of new video + int cx, cy; + pBV.GetVideoSize(out cx, out cy); + DsRect rcVideo = new DsRect(0, 0, cx, cy); + + // adjust from client size to window size + WindowStyle style; + pVW.get_WindowStyle(out style); + //AdjustWindowRect(rcVideo, style, false); + + // get current window top/left + int cxWindow, cyWindow; + DsRect rc = new DsRect(); + pVW.GetWindowPosition(out rc.left, out rc.top, out cxWindow, out cyWindow); + + // reposition video window with old top/left position and new size + pVW.SetWindowPosition(rc.left, rc.top, rcVideo.right - rcVideo.left, rcVideo.bottom - rcVideo.top); + } + } + + public long CurrentPosition() + { + if ((m_itCurrent == m_Clips.Count) || !m_bActive) + { + return m_tStartPosition; + } + double dTime = 0; + m_pController.GetSegmentTime(out dTime); + long tNow = (long)(dTime * 10000000); + + ClipEntry ce = (ClipEntry)m_Clips[m_itCurrent]; + + // this is relative to the start position within this particular clip. + // Did we start at the beginning of this clip? + if (m_tStartPosition > ce.GetStartPosition()) + { + // no, we started some distance into the clip + tNow += (m_tStartPosition - ce.GetStartPosition()); + } + // offset from start of this clip to start of entire sequence + tNow += ce.GetStartPosition(); + + if ((tNow < 0) && m_bLoop) + { + // current time is near end of previous loop + ce = (ClipEntry)m_Clips[m_Clips.Count-1]; + tNow += ce.GetStartPosition() + ce.Duration(); + } + return tNow; + } + + public int SeekSourceGraphs() + { + ClipEntry ce; + + // disconnect first + m_pController.BridgeGraphs(null, null); + + // now seek all graphs and activate them + + long tStartThis = 0; + int hr = E_INVALIDARG; + m_itCurrent = 0; + for(int x=0; x < m_Clips.Count; x++) + { + ce = (ClipEntry)m_Clips[x]; + // all clips at or after start: seek to correct position + if ((tStartThis + ce.Duration()) <= m_tStartPosition) + { + // whole clip is before beginning point - not required + // but must rewind if we are in loop mode + if (m_bLoop) + { + ce.Prime(0); + } + } + else + { + // included in clip -- set start position + long tOffset = 0; + if (m_tStartPosition >= tStartThis) + { + // starts someway in (this is first clip in sequence) + m_itCurrent = x; + tOffset = m_tStartPosition - tStartThis; + } + ce.Prime(tOffset); + } + + tStartThis += ce.Duration(); + } + + // bridge the correct graph + // note: once connected, this graph is no longer primed (it has output some data + // and will need rewinding before re-use) + ce = (ClipEntry)m_Clips[m_itCurrent]; + ce.InUse(); + hr = m_pController.BridgeGraphs(ce.SinkFilter(), m_pRenderGraphSourceFilter); + + return hr; + } + + public int SetPosition(long tStart) + { + m_tStartPosition = tStart; + IMediaControl pMC = m_pRenderGraph as IMediaControl; + if (pMC == null) + { + return E_FAIL; + } + FilterState fs; + pMC.GetState(0, out fs); + bool bRunning = false; + if (fs == FilterState.Running) + { + pMC.Pause(); + bRunning = true; + } + else if (fs == FilterState.Stopped) + { + // on going active, we'll seek all graphs + return S_OK; + } + + int hr = SeekSourceGraphs(); + + if (bRunning) + { + pMC.Run(); + } + return hr; + } + + public ClipEntry CurrentClip() + { + if (m_itCurrent == m_Clips.Count) + { + return null; + } + ClipEntry ce = (ClipEntry)m_Clips[m_itCurrent]; + return ce; + } + + public void UpdateDuration() + { + // loop through all clips setting position and calculating duration + m_tDuration = 0; + foreach (ClipEntry pClip in m_Clips) + { + pClip.SetStartPosition(m_tDuration); + m_tDuration += pClip.Duration(); + } + } + + public int SetClipLimits(ClipEntry pClip, long tStart, long tEnd) + { + long tDur = pClip.Duration(); + int hr = pClip.SetLimits(tStart, tEnd); + if (hr < 0 || (tDur == pClip.Duration())) + { + return hr; + } + + // this is called from the same message loop as the end-of-segment processing, so it's safe to + // access the current segment + if (pClip == CurrentClip()) + { + // send just the stop time to the graph + // in the hope that it is not too late + hr = pClip.SetStopTime(); + } + + // clip duration has changed: update start position of + // all subsequent clips (for current position slider UI) + + m_tDuration = 0; + bool bFound = false; + foreach (ClipEntry pThis in m_Clips) + { + if (pThis == pClip) + { + bFound = true; + m_tDuration = pClip.GetStartPosition() + pClip.Duration(); + } + else if (bFound) + { + // following clip: adjust + pClip.SetStartPosition(m_tDuration); + m_tDuration += pClip.Duration(); + } + } + return S_OK; + } + + public void SetLoop(bool bLoop) + { + m_bLoop = bLoop; + } + + public FilterState GetState() + { + FilterState state = FilterState.Stopped; + IMediaControl pMC = m_pRenderGraph as IMediaControl; + if (pMC != null) + { + pMC.GetState(0, out state); + } + return state; + } + + public ClipEntry GetClipByIndex(int idx) + { + ClipEntry ce; + if (idx >= 0 && idx < m_Clips.Count) + { + ce = (ClipEntry)m_Clips[idx]; + } + else + { + ce = null; + } + + return ce; + } + + public void PlayNext(int iClip) + { + // synchronised by windows message queue + m_pPlayNext = iClip; + } + + #region IDisposable Members + + public void Dispose() + { + GC.SuppressFinalize(this); + + Stop(); + + if (m_pController != null) + { + m_pController.BridgeGraphs(null, null); + Marshal.ReleaseComObject(m_pController); + m_pController = null; + } + + foreach(ClipEntry ce in m_Clips) + { + ce.Dispose(); + } + m_Clips.Clear(); + + if (m_pRenderGraph != null) + { + Marshal.ReleaseComObject(m_pRenderGraph); + m_pRenderGraph = null; + } + + if (m_pRenderGraphSourceFilter != null) + { + Marshal.ReleaseComObject(m_pRenderGraphSourceFilter); + m_pRenderGraphSourceFilter = null; + } + + } + + #endregion + } +} + + +// ---------- ClipEntry implementation ----------------- + +public class ClipEntry : IDisposable +{ + #region Constants + + private const int S_OK = 0; + private const int E_NOINTERFACE = unchecked((int)0x80000004); + + #endregion + + #region Member variables + + private long m_tOffset; + private long m_tStart; + private long m_tStop; + private bool m_bPrimed; + private string m_strName; + + private IFilterGraph m_pGraph; + private IBaseFilter m_pSinkFilter; + + #endregion + + public ClipEntry() + { + m_tOffset = 0; + m_tStart = 0; + m_tStop = 0; + m_bPrimed = false; + } + + public ClipEntry(ClipEntry r) + { + m_tOffset = r.m_tOffset; + m_pGraph = r.m_pGraph; + m_pSinkFilter = r.m_pSinkFilter; + m_strName = r.m_strName; + m_tStart = r.m_tStart; + m_tStop = r.m_tStop; + m_bPrimed = r.m_bPrimed; + } + + public IBaseFilter SinkFilter() + { + return m_pSinkFilter; + } + + public long GetStartPosition() + { + return m_tOffset; + } + + public void SetStartPosition(long tOffset) + { + m_tOffset = tOffset; + } + + public void GetLimits(out long ptStart, out long ptStop) + { + ptStart = m_tStart; + ptStop = m_tStop; + } + + public IFilterGraph Graph() + { + return m_pGraph; + } + + public string Name() + { + return m_strName; + } + + ClipEntry Copy(ClipEntry r) + { + m_tOffset = r.m_tOffset; + m_pGraph = r.m_pGraph; + m_pSinkFilter = r.m_pSinkFilter; + m_strName = r.m_strName; + m_tStart = r.m_tStart; + m_tStop = r.m_tStop; + m_bPrimed = r.m_bPrimed; + + return this; + } + + public int Create(IGMFBridgeController pController, string path) + { + m_bPrimed = false; + + m_pGraph = new FilterGraph() as IGraphBuilder; + int hr = pController.CreateSourceGraph(path, m_pGraph, out m_pSinkFilter); + + m_strName = path.Substring(path.LastIndexOf('\\')+1); + + if (hr < 0) + { + if (m_pGraph != null) + { + Marshal.ReleaseComObject(m_pGraph); + m_pGraph = null; + } + } + + return hr; + } + + public int SetLimits(long tStart, long tStop) + { + m_tStart = tStart; + m_tStop = tStop; + m_bPrimed = false; + return S_OK; + } + + public long Duration() + { + if (m_tStop == 0) + { + long tDur = 0; + IMediaSeeking pMS = m_pGraph as IMediaSeeking; + int hr = pMS.GetDuration(out tDur); + if (hr < 0) + { + return 0; + } + + return tDur - m_tStart; + } + return m_tStop - m_tStart; + } + + public long NativeDuration() + { + // native duration with no limits applied + long tDur = 0; + IMediaSeeking pMS = m_pGraph as IMediaSeeking; + int hr = pMS.GetDuration(out tDur); + return tDur; + } + + public long CurrentPosition() + { + // stream time in graph + IMediaSeeking pMS = m_pGraph as IMediaSeeking; + long tNow = 0; + pMS.GetCurrentPosition(out tNow); + return tNow + m_tStart; + } + + public int SetPosition(long tStart) + { + IMediaSeeking pSeek = m_pGraph as IMediaSeeking; + int hr = E_NOINTERFACE; + if (pSeek != null) + { + // input time is relative to clip start -- add on offset + // from start of media + tStart += m_tStart; + if (m_tStop == 0) + { + hr = pSeek.SetPositions( + tStart, + AMSeekingSeekingFlags.AbsolutePositioning, + null, + AMSeekingSeekingFlags.NoPositioning); + } else { + hr = pSeek.SetPositions( + tStart, + AMSeekingSeekingFlags.AbsolutePositioning, + m_tStop, + AMSeekingSeekingFlags.AbsolutePositioning); + } + } + return hr; + } + + public int SetStopTime() + { + // for limits change of active clip: pass the stop time to graph + + IMediaSeeking pSeek = m_pGraph as IMediaSeeking; + int hr = E_NOINTERFACE; + if (pSeek != null) + { + hr = pSeek.SetPositions( + null, + AMSeekingSeekingFlags.NoPositioning, + m_tStop, + AMSeekingSeekingFlags.AbsolutePositioning); + } + return hr; + } + + // in use: so no longer primed + public void InUse() + { + m_bPrimed = false; + } + + public void Prime() + { + Prime(0); + } + + public void Prime(long tStart) + { + if (!m_bPrimed) + { + SetPosition(tStart); + + IMediaControl pMC = Graph() as IMediaControl; + FilterState state; + pMC.GetState(0, out state); + if (state != FilterState.Running) + { + pMC.Run(); + } + m_bPrimed = true; + } + } + + public void Stop() + { + IMediaControl pMC = Graph() as IMediaControl; + pMC.Stop(); + m_bPrimed = false; + } + + #region IDisposable Members + + public void Dispose() + { + GC.SuppressFinalize(this); + + if (m_pGraph != null) + { + IMediaControl pMC = m_pGraph as IMediaControl; + pMC.Stop(); + + Marshal.ReleaseComObject(m_pGraph); + m_pGraph = null; + } + + if (m_pSinkFilter != null) + { + Marshal.ReleaseComObject(m_pSinkFilter); + m_pSinkFilter = null; + } + } + + #endregion +} diff --git a/Samples/Players/GMFPlay/GMFPlay/GMFBridge.cs b/Samples/Players/GMFPlay/GMFPlay/GMFBridge.cs new file mode 100644 index 0000000..a281aac --- /dev/null +++ b/Samples/Players/GMFPlay/GMFPlay/GMFBridge.cs @@ -0,0 +1,99 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +// These definitions are for use with the GMFBridge filter, which is available +// at http://www.gdcl.co.uk/. Please check out the information there for +// descriptions of how to use these interfaces. + +using System; +using System.Runtime.InteropServices; + +using DirectShowLib; + +namespace DirectShowLib.GDCL +{ + public enum eFormatType + { + Uncompressed, + MuxInputs, + Any, + } + + [ComImport, Guid("08E3287F-3A5C-47e9-8179-A9E9221A5CDE")] + public class GMFBridgeController + { + } + + [Guid("8C4D8054-FCBA-4783-865A-7E8B3C814011"), + InterfaceType(ComInterfaceType.InterfaceIsDual)] + public interface IGMFBridgeController + { + [PreserveSig] + int AddStream( + [In, MarshalAs(UnmanagedType.Bool)] bool bVideo, + [In] eFormatType AllowedTypes, + [In, MarshalAs(UnmanagedType.Bool)] bool bDiscardUnconnected + ); + + [PreserveSig] + int InsertSinkFilter( + [In] IFilterGraph pGraph, + out IBaseFilter ppFilter + ); + + [PreserveSig] + int InsertSourceFilter( + [In] IBaseFilter pUnkSourceGraphSinkFilter, + [In] IGraphBuilder pRenderGraph, + out IBaseFilter ppFilter + ); + + [PreserveSig] + int CreateSourceGraph( + [In, MarshalAs(UnmanagedType.BStr)] string strFile, + [In] IFilterGraph pGraph, + out IBaseFilter pSinkFilter + ); + + [PreserveSig] + int CreateRenderGraph( + [In] IBaseFilter pSourceGraphSinkFilter, + [In] IGraphBuilder pRenderGraph, + out IBaseFilter pRenderGraphSourceFilter + ); + + [PreserveSig] + int BridgeGraphs( + [In] IBaseFilter pSourceGraphSinkFilter, + [In] IBaseFilter pRenderGraphSourceFilter + ); + + [PreserveSig] + int SetNotify( + [In] IntPtr hwnd, + [In] int msg + ); + + [PreserveSig] + int SetBufferMinimum( + [In] int nMillisecs + ); + + [PreserveSig] + int GetSegmentTime( + out double pdSeconds + ); + + [PreserveSig] + int NoMoreSegments(); + + [PreserveSig] + int GetSegmentOffset( + out double pdOffset + ); + } +} diff --git a/Samples/Players/GMFPlay/GMFPlay/GMFPlay-2005.csproj b/Samples/Players/GMFPlay/GMFPlay/GMFPlay-2005.csproj new file mode 100644 index 0000000..64efd47 --- /dev/null +++ b/Samples/Players/GMFPlay/GMFPlay/GMFPlay-2005.csproj @@ -0,0 +1,94 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {FE48353B-7945-400B-87B2-660BE9225083} + WinExe + Properties + GMFPlay + GMFPlay + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\..\..\..\lib\DirectShowLib-2005.dll + + + + + + + + + + + + + Form + + + Limits.cs + + + Form + + + MainDlg.cs + + + + + Designer + Limits.cs + + + Designer + MainDlg.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + \ No newline at end of file diff --git a/Samples/Players/GMFPlay/GMFPlay/GMFPlay.csproj b/Samples/Players/GMFPlay/GMFPlay/GMFPlay.csproj new file mode 100644 index 0000000..877f00b --- /dev/null +++ b/Samples/Players/GMFPlay/GMFPlay/GMFPlay.csproj @@ -0,0 +1,131 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {FE48353B-7945-400B-87B2-660BE9225083} + WinExe + Properties + GMFPlay + GMFPlay + + + 3.5 + + + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + Form + + + Limits.cs + + + Form + + + MainDlg.cs + + + + + Designer + Limits.cs + + + Designer + MainDlg.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + \ No newline at end of file diff --git a/Samples/Players/GMFPlay/GMFPlay/Limits.Designer.cs b/Samples/Players/GMFPlay/GMFPlay/Limits.Designer.cs new file mode 100644 index 0000000..6a04033 --- /dev/null +++ b/Samples/Players/GMFPlay/GMFPlay/Limits.Designer.cs @@ -0,0 +1,139 @@ +namespace GMFPlay +{ + partial class fmLimits + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.tbStart = new System.Windows.Forms.TextBox(); + this.tbStop = new System.Windows.Forms.TextBox(); + this.bnOk = new System.Windows.Forms.Button(); + this.bnCancel = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(44, 30); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(135, 17); + this.label1.TabIndex = 0; + this.label1.Text = "Duration: 1 seconds"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(12, 93); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(68, 17); + this.label2.TabIndex = 1; + this.label2.Text = "Start time"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(13, 129); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(67, 17); + this.label3.TabIndex = 2; + this.label3.Text = "Stop time"; + // + // tbStart + // + this.tbStart.Location = new System.Drawing.Point(135, 93); + this.tbStart.MaxLength = 18; + this.tbStart.Name = "tbStart"; + this.tbStart.Size = new System.Drawing.Size(93, 22); + this.tbStart.TabIndex = 3; + // + // tbStop + // + this.tbStop.Location = new System.Drawing.Point(135, 126); + this.tbStop.MaxLength = 18; + this.tbStop.Name = "tbStop"; + this.tbStop.Size = new System.Drawing.Size(93, 22); + this.tbStop.TabIndex = 4; + // + // bnOk + // + this.bnOk.DialogResult = System.Windows.Forms.DialogResult.OK; + this.bnOk.Location = new System.Drawing.Point(65, 170); + this.bnOk.Name = "bnOk"; + this.bnOk.Size = new System.Drawing.Size(75, 33); + this.bnOk.TabIndex = 5; + this.bnOk.Text = "Ok"; + this.bnOk.UseVisualStyleBackColor = true; + this.bnOk.Click += new System.EventHandler(this.bnOk_Click); + // + // bnCancel + // + this.bnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.bnCancel.Location = new System.Drawing.Point(176, 170); + this.bnCancel.Name = "bnCancel"; + this.bnCancel.Size = new System.Drawing.Size(75, 33); + this.bnCancel.TabIndex = 6; + this.bnCancel.Text = "Cancel"; + this.bnCancel.UseVisualStyleBackColor = true; + this.bnCancel.Click += new System.EventHandler(this.bnCancel_Click); + // + // fmLimits + // + this.AcceptButton = this.bnOk; + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.bnCancel; + this.ClientSize = new System.Drawing.Size(399, 215); + this.Controls.Add(this.bnCancel); + this.Controls.Add(this.bnOk); + this.Controls.Add(this.tbStop); + this.Controls.Add(this.tbStart); + this.Controls.Add(this.label3); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "fmLimits"; + this.Text = "Set Clip Limits"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Button bnOk; + private System.Windows.Forms.Button bnCancel; + public System.Windows.Forms.TextBox tbStart; + public System.Windows.Forms.TextBox tbStop; + } +} \ No newline at end of file diff --git a/Samples/Players/GMFPlay/GMFPlay/Limits.cs b/Samples/Players/GMFPlay/GMFPlay/Limits.cs new file mode 100644 index 0000000..eb0788c --- /dev/null +++ b/Samples/Players/GMFPlay/GMFPlay/Limits.cs @@ -0,0 +1,36 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace GMFPlay +{ + public partial class fmLimits : Form + { + public fmLimits(long lDuration) + { + InitializeComponent(); + label1.Text = string.Format("Duration: {0} seconds", lDuration); + } + + private void bnOk_Click(object sender, EventArgs e) + { + Close(); + } + + private void bnCancel_Click(object sender, EventArgs e) + { + Close(); + } + } +} \ No newline at end of file diff --git a/Samples/Players/GMFPlay/GMFPlay/Limits.resx b/Samples/Players/GMFPlay/GMFPlay/Limits.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/Samples/Players/GMFPlay/GMFPlay/Limits.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Samples/Players/GMFPlay/GMFPlay/MainDlg.Designer.cs b/Samples/Players/GMFPlay/GMFPlay/MainDlg.Designer.cs new file mode 100644 index 0000000..670b926 --- /dev/null +++ b/Samples/Players/GMFPlay/GMFPlay/MainDlg.Designer.cs @@ -0,0 +1,189 @@ +namespace GMFPlay +{ + partial class MainDlg + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.bnClickedAdd = new System.Windows.Forms.Button(); + this.bnPlay = new System.Windows.Forms.Button(); + this.bnPause = new System.Windows.Forms.Button(); + this.bnStop = new System.Windows.Forms.Button(); + this.bnLimits = new System.Windows.Forms.Button(); + this.bnPlayNext = new System.Windows.Forms.Button(); + this.cbLoop = new System.Windows.Forms.CheckBox(); + this.trackBar1 = new System.Windows.Forms.TrackBar(); + this.listBox1 = new System.Windows.Forms.ListBox(); + this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + this.timer1 = new System.Windows.Forms.Timer(this.components); + ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).BeginInit(); + this.SuspendLayout(); + // + // bnClickedAdd + // + this.bnClickedAdd.Location = new System.Drawing.Point(407, 16); + this.bnClickedAdd.Name = "bnClickedAdd"; + this.bnClickedAdd.Size = new System.Drawing.Size(95, 29); + this.bnClickedAdd.TabIndex = 0; + this.bnClickedAdd.Text = "&Add Clip..."; + this.bnClickedAdd.UseVisualStyleBackColor = true; + this.bnClickedAdd.Click += new System.EventHandler(this.bnClickedAdd_Click); + // + // bnPlay + // + this.bnPlay.Location = new System.Drawing.Point(407, 52); + this.bnPlay.Name = "bnPlay"; + this.bnPlay.Size = new System.Drawing.Size(95, 29); + this.bnPlay.TabIndex = 1; + this.bnPlay.Text = "&Play"; + this.bnPlay.UseVisualStyleBackColor = true; + this.bnPlay.Click += new System.EventHandler(this.bnPlay_Click); + // + // bnPause + // + this.bnPause.Location = new System.Drawing.Point(407, 88); + this.bnPause.Name = "bnPause"; + this.bnPause.Size = new System.Drawing.Size(95, 29); + this.bnPause.TabIndex = 2; + this.bnPause.Text = "P&ause"; + this.bnPause.UseVisualStyleBackColor = true; + this.bnPause.Click += new System.EventHandler(this.bnPause_Click); + // + // bnStop + // + this.bnStop.Location = new System.Drawing.Point(407, 124); + this.bnStop.Name = "bnStop"; + this.bnStop.Size = new System.Drawing.Size(95, 29); + this.bnStop.TabIndex = 3; + this.bnStop.Text = "&Stop"; + this.bnStop.UseVisualStyleBackColor = true; + this.bnStop.Click += new System.EventHandler(this.bnStop_Click); + // + // bnLimits + // + this.bnLimits.Enabled = false; + this.bnLimits.Location = new System.Drawing.Point(407, 160); + this.bnLimits.Name = "bnLimits"; + this.bnLimits.Size = new System.Drawing.Size(95, 29); + this.bnLimits.TabIndex = 4; + this.bnLimits.Text = "&Limits"; + this.bnLimits.UseVisualStyleBackColor = true; + this.bnLimits.Click += new System.EventHandler(this.bnLimits_Click); + // + // bnPlayNext + // + this.bnPlayNext.Enabled = false; + this.bnPlayNext.Location = new System.Drawing.Point(407, 196); + this.bnPlayNext.Name = "bnPlayNext"; + this.bnPlayNext.Size = new System.Drawing.Size(95, 29); + this.bnPlayNext.TabIndex = 5; + this.bnPlayNext.Text = "Play &Next"; + this.bnPlayNext.UseVisualStyleBackColor = true; + this.bnPlayNext.Click += new System.EventHandler(this.bnPlayNext_Click); + // + // cbLoop + // + this.cbLoop.AutoSize = true; + this.cbLoop.Location = new System.Drawing.Point(413, 267); + this.cbLoop.Name = "cbLoop"; + this.cbLoop.Size = new System.Drawing.Size(62, 21); + this.cbLoop.TabIndex = 6; + this.cbLoop.Text = "Loop"; + this.cbLoop.UseVisualStyleBackColor = true; + this.cbLoop.CheckedChanged += new System.EventHandler(this.cbLoop_CheckedChanged); + // + // trackBar1 + // + this.trackBar1.Location = new System.Drawing.Point(12, 322); + this.trackBar1.Maximum = 1000; + this.trackBar1.Name = "trackBar1"; + this.trackBar1.Size = new System.Drawing.Size(490, 64); + this.trackBar1.TabIndex = 7; + this.trackBar1.TickStyle = System.Windows.Forms.TickStyle.None; + this.trackBar1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.trackBar1_MouseDown); + this.trackBar1.ValueChanged += new System.EventHandler(this.trackBar1_ValueChanged); + this.trackBar1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.trackBar1_MouseUp); + // + // listBox1 + // + this.listBox1.FormattingEnabled = true; + this.listBox1.ItemHeight = 16; + this.listBox1.Location = new System.Drawing.Point(12, 16); + this.listBox1.Name = "listBox1"; + this.listBox1.Size = new System.Drawing.Size(378, 276); + this.listBox1.TabIndex = 8; + this.listBox1.SelectedIndexChanged += new System.EventHandler(this.listBox1_SelectedIndexChanged); + // + // openFileDialog1 + // + this.openFileDialog1.FileName = "openFileDialog1"; + // + // timer1 + // + this.timer1.Interval = 200; + this.timer1.Tick += new System.EventHandler(this.timer1_Tick); + // + // MainDlg + // + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(523, 387); + this.Controls.Add(this.listBox1); + this.Controls.Add(this.trackBar1); + this.Controls.Add(this.cbLoop); + this.Controls.Add(this.bnPlayNext); + this.Controls.Add(this.bnLimits); + this.Controls.Add(this.bnStop); + this.Controls.Add(this.bnPause); + this.Controls.Add(this.bnPlay); + this.Controls.Add(this.bnClickedAdd); + this.MaximizeBox = false; + this.Name = "MainDlg"; + this.Text = "GMF Player Demo"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainDlg_FormClosing); + ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button bnClickedAdd; + private System.Windows.Forms.Button bnPlay; + private System.Windows.Forms.Button bnPause; + private System.Windows.Forms.Button bnStop; + private System.Windows.Forms.Button bnLimits; + private System.Windows.Forms.Button bnPlayNext; + private System.Windows.Forms.CheckBox cbLoop; + private System.Windows.Forms.TrackBar trackBar1; + private System.Windows.Forms.ListBox listBox1; + private System.Windows.Forms.OpenFileDialog openFileDialog1; + private System.Windows.Forms.Timer timer1; + } +} + diff --git a/Samples/Players/GMFPlay/GMFPlay/MainDlg.cs b/Samples/Players/GMFPlay/GMFPlay/MainDlg.cs new file mode 100644 index 0000000..2d5e5d0 --- /dev/null +++ b/Samples/Players/GMFPlay/GMFPlay/MainDlg.cs @@ -0,0 +1,286 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Diagnostics; +using DirectShowLib; + +namespace GMFPlay +{ + public partial class MainDlg : Form + { + #region Constants + + private const long NANOSECONDS = (1000000000); // 10 ^ 9 + private const long UNITS = (NANOSECONDS / 100); // 10 ^ 7 + private const int WM_USER = 0x8000; + private const int MSG_ENDOFSEGMENT = WM_USER + 100; + private const int MSG_DSEVENT = WM_USER + 101; + private const int TB_THUMBTRACK = 0; + private const int TB_ENDTRACK = 1; + private const int TB_THUMBPOSITION = 2; + + #endregion + + #region Member variables + + private ClipPlayer m_pPlayer; + private bool m_bTracking; + private FilterState m_State; + + #endregion + + public MainDlg() + { + InitializeComponent(); + + try + { + m_pPlayer = new ClipPlayer(this.Handle, MSG_ENDOFSEGMENT, MSG_DSEVENT); + m_bTracking = false; + m_State = FilterState.Stopped; + } + catch + { + MessageBox.Show("Please register GMFBridge.DLL with regsvr32"); + } + } + + protected override void WndProc(ref Message m) + { + switch (m.Msg) + { + case MSG_ENDOFSEGMENT: + OnEndOfSegment(); + break; + + case MSG_DSEVENT: + OnDSEvent(); + break; + + + // all other messages + default: + // unhandled window message + base.WndProc(ref m); + break; + } + } + + void OnEndOfSegment() + { + m_pPlayer.OnEndOfSegment(); + } + + void OnDSEvent() + { + m_pPlayer.OnEvent(); + } + + private void bnClickedAdd_Click(object sender, EventArgs e) + { + openFileDialog1.CheckFileExists = true; + openFileDialog1.ReadOnlyChecked = true; + + if (openFileDialog1.ShowDialog(this) == DialogResult.OK) + { + ClipEntry pClip; + int hr = m_pPlayer.AddClip(openFileDialog1.FileName, out pClip); + if (hr < 0) + { + MessageBox.Show("Cannot add clip: format not support", "Incompatible Clip"); + return; + } + + // duration, limits dlg -- set clip limits (in seconds) + string sDesc; + + fmLimits dlg = new fmLimits((pClip.Duration() + UNITS - 1) / UNITS); + dlg.tbStart.Text = "0"; + dlg.tbStop.Text = ""; + if (dlg.ShowDialog() == DialogResult.OK) + { + long tStart = int.Parse(dlg.tbStart.Text) * UNITS; + long tStop = pClip.Duration(); + if (dlg.tbStop.Text.Length > 0 && int.Parse(dlg.tbStop.Text) > 0) + { + tStop = int.Parse(dlg.tbStop.Text) * UNITS; + } + m_pPlayer.SetClipLimits(pClip, tStart, tStop); + + // append range to clip description text + sDesc = string.Format("{0} [{1}..{2}]", pClip.Name(), tStart / UNITS, tStop / UNITS); + int it = listBox1.Items.Add(sDesc); + listBox1.SelectedIndex = it; + } + } + } + + private void bnPlay_Click(object sender, EventArgs e) + { + m_pPlayer.Play(); + timer1.Enabled = true; + } + + private void bnPause_Click(object sender, EventArgs e) + { + m_pPlayer.Pause(); + } + + private void bnStop_Click(object sender, EventArgs e) + { + m_pPlayer.Stop(); + } + + private void bnLimits_Click(object sender, EventArgs e) + { + int idx = listBox1.SelectedIndex; + ClipEntry pClip = null; + if (idx != -1) + { + pClip = m_pPlayer.GetClipByIndex(idx); + } + + if (pClip != null) + { + // duration, limits dlg -- set clip limits (in seconds) + long lDur = ((pClip.NativeDuration() + UNITS - 1) / UNITS); + long tStart, tStop; + pClip.GetLimits(out tStart, out tStop); + long lStart = ((tStart + UNITS - 1) / UNITS); + long lStop = -1; + if (tStop != 0) + { + lStop = ((tStop + UNITS - 1) / UNITS); + + } + + fmLimits dlg = new fmLimits((pClip.Duration() + UNITS - 1) / UNITS); + dlg.tbStart.Text = lStart.ToString(); + dlg.tbStop.Text = lStop.ToString(); + if (dlg.ShowDialog() == DialogResult.OK) + { + long tStart2 = int.Parse(dlg.tbStart.Text) * UNITS; + long tStop2 = pClip.NativeDuration(); + if (int.Parse(dlg.tbStop.Text) > 0) + { + tStop2 = int.Parse(dlg.tbStop.Text) * UNITS; + } + m_pPlayer.SetClipLimits(pClip, tStart2, tStop2); + + string sDesc = string.Format("{0} [{1}..{2}]", pClip.Name(), tStart2 / UNITS, tStop2 / UNITS); + + int n = listBox1.SelectedIndex; + + listBox1.Items.RemoveAt(n); + listBox1.Items.Insert(n, sDesc); + } + } + } + + private void bnPlayNext_Click(object sender, EventArgs e) + { + int idx = listBox1.SelectedIndex; + + if (idx != -1) + { + m_pPlayer.PlayNext(idx); + } + } + + private void cbLoop_CheckedChanged(object sender, EventArgs e) + { + m_pPlayer.SetLoop(cbLoop.Checked); + } + + private void timer1_Tick(object sender, EventArgs e) + { + if (!m_bTracking) + { + long tDuration = m_pPlayer.TotalDuration(); + if (tDuration > 0) + { + long tNow = Math.Max(m_pPlayer.CurrentPosition(), 0); + tNow = Math.Min(tNow, tDuration); + trackBar1.Value = (int)(tNow * trackBar1.Maximum / tDuration); + } + } + } + + private void trackBar1_MouseDown(object sender, MouseEventArgs e) + { + // on mouse-down, pause the graph + if (!m_bTracking) + { + // stop/pause/run state of render graph + m_State = m_pPlayer.GetState(); + if (m_State == FilterState.Running) + { + m_pPlayer.Pause(); + } + m_bTracking = true; + } + } + + private void trackBar1_MouseUp(object sender, MouseEventArgs e) + { + int position = trackBar1.Value; + + // scale 0..1000 track bar range into total duration + long tSeek = position * m_pPlayer.TotalDuration() / trackBar1.Maximum; + m_pPlayer.SetPosition(tSeek); + + if (m_bTracking) + { + if (m_State == FilterState.Running) + { + m_pPlayer.Play(); + } + m_bTracking = false; + } + } + + private void trackBar1_ValueChanged(object sender, EventArgs e) + { + if (m_bTracking) + { + // scale 0..1000 track bar range into total duration + long tSeek = trackBar1.Value * m_pPlayer.TotalDuration() / trackBar1.Maximum; + m_pPlayer.SetPosition(tSeek); + Debug.WriteLine(string.Format("{0} {1} {2} {3}", trackBar1.Value, tSeek, m_pPlayer.CurrentPosition(), m_pPlayer.TotalDuration())); + } + } + + private void listBox1_SelectedIndexChanged(object sender, EventArgs e) + { + bool bEnable = false; + int idx = listBox1.SelectedIndex; + + if ((idx != -1) && (m_pPlayer.GetClipByIndex(idx) != null)) + { + bEnable = true; + } + + bnLimits.Enabled = bEnable; + bnPlayNext.Enabled = bEnable; + } + + private void MainDlg_FormClosing(object sender, FormClosingEventArgs e) + { + if (m_pPlayer != null) + { + m_pPlayer.Dispose(); + } + } + } +} \ No newline at end of file diff --git a/Samples/Players/GMFPlay/GMFPlay/MainDlg.resx b/Samples/Players/GMFPlay/GMFPlay/MainDlg.resx new file mode 100644 index 0000000..4fb69f8 --- /dev/null +++ b/Samples/Players/GMFPlay/GMFPlay/MainDlg.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 185, 17 + + \ No newline at end of file diff --git a/Samples/Players/GMFPlay/GMFPlay/Program.cs b/Samples/Players/GMFPlay/GMFPlay/Program.cs new file mode 100644 index 0000000..2ea1324 --- /dev/null +++ b/Samples/Players/GMFPlay/GMFPlay/Program.cs @@ -0,0 +1,27 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Windows.Forms; + +namespace GMFPlay +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new MainDlg()); + } + } +} \ No newline at end of file diff --git a/Samples/Players/GMFPlay/GMFPlay/Properties/AssemblyInfo.cs b/Samples/Players/GMFPlay/GMFPlay/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..133b31c --- /dev/null +++ b/Samples/Players/GMFPlay/GMFPlay/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("GMFPlay")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Personal Copy")] +[assembly: AssemblyProduct("GMFPlay")] +[assembly: AssemblyCopyright("Copyright © Personal Copy 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("24bd66e1-c133-4ccd-8563-8c2dcb3296bd")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Samples/Players/GMFPlay/GMFPlay/Properties/Resources.Designer.cs b/Samples/Players/GMFPlay/GMFPlay/Properties/Resources.Designer.cs new file mode 100644 index 0000000..790f9b8 --- /dev/null +++ b/Samples/Players/GMFPlay/GMFPlay/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace GMFPlay.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GMFPlay.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Samples/Players/GMFPlay/GMFPlay/Properties/Resources.resx b/Samples/Players/GMFPlay/GMFPlay/Properties/Resources.resx new file mode 100644 index 0000000..25a6121 --- /dev/null +++ b/Samples/Players/GMFPlay/GMFPlay/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Samples/Players/GMFPlay/GMFPlay/Properties/Settings.Designer.cs b/Samples/Players/GMFPlay/GMFPlay/Properties/Settings.Designer.cs new file mode 100644 index 0000000..d71c20b --- /dev/null +++ b/Samples/Players/GMFPlay/GMFPlay/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace GMFPlay.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Samples/Players/GMFPlay/GMFPlay/Properties/Settings.settings b/Samples/Players/GMFPlay/GMFPlay/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Samples/Players/GMFPlay/GMFPlay/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Samples/Players/GMFPlay/GMFPlay/readme.txt b/Samples/Players/GMFPlay/GMFPlay/readme.txt new file mode 100644 index 0000000..feb2ed2 --- /dev/null +++ b/Samples/Players/GMFPlay/GMFPlay/readme.txt @@ -0,0 +1,17 @@ +--------------------------------------------------------------------- +GMFPlay + +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + +--------------------------------------------------------------------- + +This sample shows how to play media files one after another without a +gap between them. + +This sample is a fairly direct translation of the GMFPlay sample from +http://www.gdcl.co.uk. You MUST download and install the GMFBridge DLL +from that website before this sample will run. + diff --git a/Samples/Players/PlayVB/AssemblyInfo.vb b/Samples/Players/PlayVB/AssemblyInfo.vb new file mode 100644 index 0000000..59e3a16 --- /dev/null +++ b/Samples/Players/PlayVB/AssemblyInfo.vb @@ -0,0 +1,39 @@ +'**************************************************************************** +'While the underlying libraries are covered by LGPL, this sample is released +'as public domain. It is distributed in the hope that it will be useful, but +'WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +'or FITNESS FOR A PARTICULAR PURPOSE. +'*****************************************************************************/ + +Imports System +Imports System.Reflection +Imports System.Runtime.InteropServices + +' General Information about an assembly is controlled through the following +' set of attributes. Change these attribute values to modify the information +' associated with an assembly. + +' Review the values of the assembly attributes + + + + + + + + + +'The following GUID is for the ID of the typelib if this project is exposed to COM + + +' Version information for an assembly consists of the following four values: +' +' Major Version +' Minor Version +' Build Number +' Revision +' +' You can specify all the values or you can default the Build and Revision Numbers +' by using the '*' as shown below: + + diff --git a/Samples/Players/PlayVB/Form1.resx b/Samples/Players/PlayVB/Form1.resx new file mode 100644 index 0000000..ae4e930 --- /dev/null +++ b/Samples/Players/PlayVB/Form1.resx @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + Assembly + + + Assembly + + + False + + + (Default) + + + False + + + False + + + 8, 8 + + + Form1 + + + True + + + 80 + + + True + + + Assembly + + \ No newline at end of file diff --git a/Samples/Players/PlayVB/Form1.vb b/Samples/Players/PlayVB/Form1.vb new file mode 100644 index 0000000..1edbcb9 --- /dev/null +++ b/Samples/Players/PlayVB/Form1.vb @@ -0,0 +1,103 @@ +'**************************************************************************** +'While the underlying libraries are covered by LGPL, this sample is released +'as public domain. It is distributed in the hope that it will be useful, but +'WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +'or FITNESS FOR A PARTICULAR PURPOSE. +'*****************************************************************************/ + +Imports DirectShowLib +Imports System.Runtime.InteropServices + +Public Class Form1 + Inherits System.Windows.Forms.Form + +#Region " Windows Form Designer generated code " + + Public Sub New() + MyBase.New() + + 'This call is required by the Windows Form Designer. + InitializeComponent() + + 'Add any initialization after the InitializeComponent() call + + End Sub + + 'Form overrides dispose to clean up the component list. + Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) + If disposing Then + If Not (components Is Nothing) Then + components.Dispose() + End If + End If + MyBase.Dispose(disposing) + End Sub + + 'Required by the Windows Form Designer + Private components As System.ComponentModel.IContainer + + 'NOTE: The following procedure is required by the Windows Form Designer + 'It can be modified using the Windows Form Designer. + 'Do not modify it using the code editor. + Friend WithEvents Button1 As System.Windows.Forms.Button + Private Sub InitializeComponent() + Me.Button1 = New System.Windows.Forms.Button + Me.SuspendLayout() + ' + 'Button1 + ' + Me.Button1.Location = New System.Drawing.Point(104, 80) + Me.Button1.Name = "Button1" + Me.Button1.TabIndex = 0 + Me.Button1.Text = "Play" + ' + 'Form1 + ' + Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13) + Me.ClientSize = New System.Drawing.Size(292, 262) + Me.Controls.Add(Me.Button1) + Me.Name = "Form1" + Me.Text = "Form1" + Me.ResumeLayout(False) + + End Sub + +#End Region + + Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click + Dim hr As Integer + Dim ev As EventCode + + Dim fg As FilterGraph + Dim ifg2 As IFilterGraph2 + Dim imc As IMediaControl + Dim ime As IMediaEvent + + ' Get a filtergraph object + fg = New FilterGraph + ifg2 = DirectCast(fg, IFilterGraph2) + + ' Get the IMediaControl interface from the fg object + imc = DirectCast(fg, IMediaControl) + + ' Get the IMediaEvent interface from the fg object + ime = DirectCast(fg, IMediaEvent) + + ' Build the graph + hr = ifg2.RenderFile("c:\1.avi", Nothing) + DsError.ThrowExceptionForHR(hr) + + ' Run the graph + hr = imc.Run() + DsError.ThrowExceptionForHR(hr) + + ' Wait for the entire file to finish playing + hr = ime.WaitForCompletion(-1, ev) + DsError.ThrowExceptionForHR(hr) + + ' Release the graph (and all its interfaces) + Marshal.ReleaseComObject(fg) + + End Sub + +End Class diff --git a/Samples/Players/PlayVB/PlayVB-2005.sln b/Samples/Players/PlayVB/PlayVB-2005.sln new file mode 100644 index 0000000..19f0fbd --- /dev/null +++ b/Samples/Players/PlayVB/PlayVB-2005.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "PlayVB-2005", "PlayVB-2005.vbproj", "{72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Players/PlayVB/PlayVB-2005.vbproj b/Samples/Players/PlayVB/PlayVB-2005.vbproj new file mode 100644 index 0000000..8358784 --- /dev/null +++ b/Samples/Players/PlayVB/PlayVB-2005.vbproj @@ -0,0 +1,119 @@ + + + Local + 8.0.50727 + 2.0 + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1} + Debug + AnyCPU + + + + + PlayVB + + + None + JScript + Grid + IE50 + false + WinExe + Binary + On + Off + PlayVB + PlayVB.Form1 + + + WindowsFormsWithCustomSubMain + + + + + bin\ + PlayVB.xml + 285212672 + + + + + true + true + true + false + false + false + false + 1 + 42016,42017,42018,42019,42032 + full + + + bin\ + PlayVB.xml + 285212672 + + + + + false + true + false + true + false + false + false + 1 + 42016,42017,42018,42019,42032 + none + + + + False + ..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Data + + + System.Drawing + + + System.Windows.Forms + + + System.XML + + + + + + + + + + + + + + Code + + + Form + + + Form1.vb + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Players/PlayVB/PlayVB-2008.sln b/Samples/Players/PlayVB/PlayVB-2008.sln new file mode 100644 index 0000000..1f9a93a --- /dev/null +++ b/Samples/Players/PlayVB/PlayVB-2008.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "PlayVB-2008", "PlayVB-2008.vbproj", "{72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Players/PlayVB/PlayVB.vbproj b/Samples/Players/PlayVB/PlayVB.vbproj new file mode 100644 index 0000000..c7f0f00 --- /dev/null +++ b/Samples/Players/PlayVB/PlayVB.vbproj @@ -0,0 +1,154 @@ + + + + Local + 8.0.50727 + 2.0 + {72D5AFCA-8989-4536-BA61-EEB1CD8A7FD1} + Debug + AnyCPU + + + + + PlayVB + + + None + JScript + Grid + IE50 + false + WinExe + Binary + On + Off + PlayVB + PlayVB.Form1 + + + WindowsFormsWithCustomSubMain + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\ + PlayVB.xml + 285212672 + + + + + true + true + true + false + false + false + false + 1 + 42016,42017,42018,42019,42032,42353,42354,42355 + full + + + bin\ + PlayVB.xml + 285212672 + + + + + false + true + false + true + false + false + false + 1 + 42016,42017,42018,42019,42032,42353,42354,42355 + none + + + + System + + + System.Data + + + System.Drawing + + + System.Windows.Forms + + + System.XML + + + + + + + + + + + + + + Code + + + Form + + + Form1.vb + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Players/PlayVB/readme.txt b/Samples/Players/PlayVB/readme.txt new file mode 100644 index 0000000..8b88bf3 --- /dev/null +++ b/Samples/Players/PlayVB/readme.txt @@ -0,0 +1 @@ +A *very* simple video file player in vb. It loads a file into a graph, plays it, and waits for it to finish. \ No newline at end of file diff --git a/Samples/Players/PlayWnd/AboutBox.cs b/Samples/Players/PlayWnd/AboutBox.cs new file mode 100644 index 0000000..7517592 --- /dev/null +++ b/Samples/Players/PlayWnd/AboutBox.cs @@ -0,0 +1,163 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Reflection; +using System.Windows.Forms; + +using DirectShowLib; + +namespace DirectShowLib.Sample +{ + internal class AboutBoxWnd : Form + { + public System.Windows.Forms.Label label1; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.LinkLabel linkLabel1; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label4; + private System.ComponentModel.Container components = null; + + public AboutBoxWnd() + { + InitializeComponent(); + + Type t = typeof(IGraphBuilder); + label3.Text += t.Assembly.GetName().Version; + } + + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if(components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Code généré par le Concepteur Windows Form + /// + /// Méthode requise pour la prise en charge du concepteur - ne modifiez pas + /// le contenu de cette méthode avec l'éditeur de code. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.button1 = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.linkLabel1 = new System.Windows.Forms.LinkLabel(); + this.label3 = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // label1 + // + this.label1.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label1.Location = new System.Drawing.Point(8, 8); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(272, 40); + this.label1.TabIndex = 1; + // + // button1 + // + this.button1.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.button1.Location = new System.Drawing.Point(288, 8); + this.button1.Name = "button1"; + this.button1.TabIndex = 0; + this.button1.Text = "OK"; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // label2 + // + this.label2.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label2.Location = new System.Drawing.Point(8, 64); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(160, 16); + this.label2.TabIndex = 2; + this.label2.Text = "Library source code release under"; + // + // linkLabel1 + // + this.linkLabel1.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.linkLabel1.Location = new System.Drawing.Point(184, 64); + this.linkLabel1.Name = "linkLabel1"; + this.linkLabel1.Size = new System.Drawing.Size(160, 16); + this.linkLabel1.TabIndex = 3; + this.linkLabel1.TabStop = true; + this.linkLabel1.Text = "Lesser General Public License"; + this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked); + // + // label3 + // + this.label3.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label3.Location = new System.Drawing.Point(8, 48); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(320, 16); + this.label3.TabIndex = 4; + this.label3.Text = "DirectShowLib Version : "; + // + // label4 + // + this.label4.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label4.Location = new System.Drawing.Point(8, 80); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(264, 16); + this.label4.TabIndex = 5; + this.label4.Text = "Sample source code release under Public Domain"; + // + // AboutBoxWnd + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(372, 104); + this.Controls.Add(this.label4); + this.Controls.Add(this.label3); + this.Controls.Add(this.linkLabel1); + this.Controls.Add(this.label2); + this.Controls.Add(this.button1); + this.Controls.Add(this.label1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "AboutBoxWnd"; + this.ShowInTaskbar = false; + this.Text = "AboutBox"; + this.ResumeLayout(false); + + } + #endregion + + private void button1_Click(object sender, System.EventArgs e) + { + this.Close(); + } + + private void linkLabel1_LinkClicked(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e) + { + System.Diagnostics.Process.Start("http://www.gnu.org/copyleft/lesser.txt"); + } + } + + public class AboutBox + { + public static void Show(string title, string text) + { + using (AboutBoxWnd form = new AboutBoxWnd()) + { + form.Text = title; + form.label1.Text = text; + form.ShowDialog(); + } + } + } +} diff --git a/Samples/Players/PlayWnd/AboutBox.resx b/Samples/Players/PlayWnd/AboutBox.resx new file mode 100644 index 0000000..4b1c550 --- /dev/null +++ b/Samples/Players/PlayWnd/AboutBox.resx @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + Private + + + Public + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + Private + + + False + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + (Default) + + + False + + + False + + + 8, 8 + + + True + + + AboutBoxWnd + + + 80 + + + True + + + Private + + \ No newline at end of file diff --git a/Samples/Players/PlayWnd/AssemblyInfo.cs b/Samples/Players/PlayWnd/AssemblyInfo.cs new file mode 100644 index 0000000..76201ae --- /dev/null +++ b/Samples/Players/PlayWnd/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// Les informations générales relatives à un assembly dépendent de +// l'ensemble d'attributs suivant. Pour modifier les informations +// associées à un assembly, changez les valeurs de ces attributs. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Les informations de version pour un assembly se composent des quatre valeurs suivantes : +// +// Version principale +// Version secondaire +// Numéro de build +// Révision +// +// Vous pouvez spécifier toutes les valeurs ou indiquer des numéros de révision et de build par défaut +// en utilisant '*', comme ci-dessous : + +[assembly: AssemblyVersion("1.0.*")] + +// +// Pour signer votre assembly, vous devez spécifier la clé à utiliser. Consultez +// la documentation Microsoft .NET Framework pour plus d'informations sur la signature d'un assembly. +// +// Utilisez les attributs ci-dessous pour contrôler la clé utilisée lors de la signature. +// +// Remarques : +// (*) Si aucune clé n'est spécifiée, l'assembly n'est pas signé. +// (*) KeyName fait référence à une clé installée dans le fournisseur de +// services cryptographiques (CSP) de votre ordinateur. KeyFile fait référence à un fichier qui contient +// une clé. +// (*) Si les valeurs de KeyFile et de KeyName sont spécifiées, le +// traitement suivant se produit : +// (1) Si KeyName se trouve dans le CSP, la clé est utilisée. +// (2) Si KeyName n'existe pas mais que KeyFile existe, la clé +// de KeyFile est installée dans le CSP et utilisée. +// (*) Pour créer KeyFile, vous pouvez utiliser l'utilitaire sn.exe (Strong Name, Nom fort). +// Lors de la spécification de KeyFile, son emplacement doit être +// relatif au répertoire de sortie du projet qui est +// %Project Directory%\obj\. Par exemple, si votre KeyFile se trouve +// dans le répertoire du projet, vous devez spécifier l'attribut +// AssemblyKeyFile sous la forme [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) DelaySign (signature différée) est une option avancée. Pour plus d'informations, consultez la +// documentation Microsoft .NET Framework. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/Players/PlayWnd/MainForm.cs b/Samples/Players/PlayWnd/MainForm.cs new file mode 100644 index 0000000..71bcd0a --- /dev/null +++ b/Samples/Players/PlayWnd/MainForm.cs @@ -0,0 +1,1216 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +using DirectShowLib; + +namespace DirectShowLib.Sample +{ + internal enum PlayState + { + Stopped, + Paused, + Running, + Init + }; + + internal enum MediaType + { + Audio, + Video + } + + public class MainForm : System.Windows.Forms.Form + { + private const int WMGraphNotify = 0x0400 + 13; + private const int VolumeFull = 0; + private const int VolumeSilence = -10000; + + private IGraphBuilder graphBuilder = null; + private IMediaControl mediaControl = null; + private IMediaEventEx mediaEventEx = null; + private IVideoWindow videoWindow = null; + private IBasicAudio basicAudio = null; + private IBasicVideo basicVideo = null; + private IMediaSeeking mediaSeeking = null; + private IMediaPosition mediaPosition = null; + private IVideoFrameStep frameStep = null; + + private string filename = string.Empty; + private bool isAudioOnly = false; + private bool isFullScreen = false; + private int currentVolume = VolumeFull; + private PlayState currentState = PlayState.Stopped; + private double currentPlaybackRate = 1.0; + + private IntPtr hDrain = IntPtr.Zero; + +#if DEBUG + private DsROTEntry rot = null; +#endif + + private System.Windows.Forms.MainMenu mainMenu1; + private System.Windows.Forms.MenuItem menuItem1; + private System.Windows.Forms.MenuItem menuItem4; + private System.Windows.Forms.MenuItem menuItem6; + private System.Windows.Forms.MenuItem menuItem10; + private System.Windows.Forms.MenuItem menuItem12; + private System.Windows.Forms.MenuItem menuItem17; + private System.Windows.Forms.MenuItem menuItem19; + private System.Windows.Forms.MenuItem menuItem22; + private System.Windows.Forms.MenuItem menuItem26; + private System.Windows.Forms.MenuItem menuFileOpenClip; + private System.Windows.Forms.MenuItem menuFileClose; + private System.Windows.Forms.MenuItem menuFileExit; + private System.Windows.Forms.MenuItem menuFilePause; + private System.Windows.Forms.MenuItem menuFileStop; + private System.Windows.Forms.MenuItem menuFileMute; + private System.Windows.Forms.MenuItem menuSingleStep; + private System.Windows.Forms.MenuItem menuFileSizeHalf; + private System.Windows.Forms.MenuItem menuFileSizeThreeQuarter; + private System.Windows.Forms.MenuItem menuFileSizeNormal; + private System.Windows.Forms.MenuItem menuFileSizeDouble; + private System.Windows.Forms.MenuItem menuFileFullScreen; + private System.Windows.Forms.MenuItem menuRateIncrease; + private System.Windows.Forms.MenuItem menuRateDecrease; + private System.Windows.Forms.MenuItem menuRateNormal; + private System.Windows.Forms.MenuItem menuRateHalf; + private System.Windows.Forms.MenuItem menuRateDouble; + private System.Windows.Forms.MenuItem menuHelpAbout; + private System.Windows.Forms.OpenFileDialog openFileDialog1; + + /// + /// Variable nécessaire au concepteur. + /// + private System.ComponentModel.Container components = null; + + public MainForm() + { + // + // Requis pour la prise en charge du Concepteur Windows Forms + // + InitializeComponent(); + + // + // TODO : ajoutez le code du constructeur après l'appel à InitializeComponent + // + } + + /// + /// Nettoyage des ressources utilisées. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if (components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + + #region Code généré par le Concepteur Windows Form + /// + /// Méthode requise pour la prise en charge du concepteur - ne modifiez pas + /// le contenu de cette méthode avec l'éditeur de code. + /// + private void InitializeComponent() + { + this.mainMenu1 = new System.Windows.Forms.MainMenu(); + this.menuItem1 = new System.Windows.Forms.MenuItem(); + this.menuFileOpenClip = new System.Windows.Forms.MenuItem(); + this.menuFileClose = new System.Windows.Forms.MenuItem(); + this.menuItem4 = new System.Windows.Forms.MenuItem(); + this.menuFileExit = new System.Windows.Forms.MenuItem(); + this.menuItem6 = new System.Windows.Forms.MenuItem(); + this.menuFilePause = new System.Windows.Forms.MenuItem(); + this.menuFileStop = new System.Windows.Forms.MenuItem(); + this.menuFileMute = new System.Windows.Forms.MenuItem(); + this.menuItem10 = new System.Windows.Forms.MenuItem(); + this.menuSingleStep = new System.Windows.Forms.MenuItem(); + this.menuItem12 = new System.Windows.Forms.MenuItem(); + this.menuFileSizeHalf = new System.Windows.Forms.MenuItem(); + this.menuFileSizeThreeQuarter = new System.Windows.Forms.MenuItem(); + this.menuFileSizeNormal = new System.Windows.Forms.MenuItem(); + this.menuFileSizeDouble = new System.Windows.Forms.MenuItem(); + this.menuItem17 = new System.Windows.Forms.MenuItem(); + this.menuFileFullScreen = new System.Windows.Forms.MenuItem(); + this.menuItem19 = new System.Windows.Forms.MenuItem(); + this.menuRateIncrease = new System.Windows.Forms.MenuItem(); + this.menuRateDecrease = new System.Windows.Forms.MenuItem(); + this.menuItem22 = new System.Windows.Forms.MenuItem(); + this.menuRateNormal = new System.Windows.Forms.MenuItem(); + this.menuRateHalf = new System.Windows.Forms.MenuItem(); + this.menuRateDouble = new System.Windows.Forms.MenuItem(); + this.menuItem26 = new System.Windows.Forms.MenuItem(); + this.menuHelpAbout = new System.Windows.Forms.MenuItem(); + this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + // + // mainMenu1 + // + this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuItem1, + this.menuItem6, + this.menuItem19, + this.menuItem26}); + // + // menuItem1 + // + this.menuItem1.Index = 0; + this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuFileOpenClip, + this.menuFileClose, + this.menuItem4, + this.menuFileExit}); + this.menuItem1.Text = "File"; + // + // menuFileOpenClip + // + this.menuFileOpenClip.Index = 0; + this.menuFileOpenClip.Text = "Open clip..."; + this.menuFileOpenClip.Click += new System.EventHandler(this.menuFileOpenClip_Click); + // + // menuFileClose + // + this.menuFileClose.Index = 1; + this.menuFileClose.Text = "Close clip"; + this.menuFileClose.Click += new System.EventHandler(this.menuFileClose_Click); + // + // menuItem4 + // + this.menuItem4.Index = 2; + this.menuItem4.Text = "-"; + // + // menuFileExit + // + this.menuFileExit.Index = 3; + this.menuFileExit.Text = "Exit"; + this.menuFileExit.Click += new System.EventHandler(this.menuFileExit_Click); + // + // menuItem6 + // + this.menuItem6.Index = 1; + this.menuItem6.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuFilePause, + this.menuFileStop, + this.menuFileMute, + this.menuItem10, + this.menuSingleStep, + this.menuItem12, + this.menuFileSizeHalf, + this.menuFileSizeThreeQuarter, + this.menuFileSizeNormal, + this.menuFileSizeDouble, + this.menuItem17, + this.menuFileFullScreen}); + this.menuItem6.Text = "Control"; + // + // menuFilePause + // + this.menuFilePause.Index = 0; + this.menuFilePause.Text = "Play/Pause"; + this.menuFilePause.Click += new System.EventHandler(this.menuFilePause_Click); + // + // menuFileStop + // + this.menuFileStop.Index = 1; + this.menuFileStop.Text = "Stop"; + this.menuFileStop.Click += new System.EventHandler(this.menuFileStop_Click); + // + // menuFileMute + // + this.menuFileMute.Index = 2; + this.menuFileMute.Text = "Mute/Unmute"; + this.menuFileMute.Click += new System.EventHandler(this.menuFileMute_Click); + // + // menuItem10 + // + this.menuItem10.Index = 3; + this.menuItem10.Text = "-"; + // + // menuSingleStep + // + this.menuSingleStep.Index = 4; + this.menuSingleStep.Text = "Single Frame Step"; + this.menuSingleStep.Click += new System.EventHandler(this.menuSingleStep_Click); + // + // menuItem12 + // + this.menuItem12.Index = 5; + this.menuItem12.Text = "-"; + // + // menuFileSizeHalf + // + this.menuFileSizeHalf.Index = 6; + this.menuFileSizeHalf.Text = "Half size (50%)"; + this.menuFileSizeHalf.Click += new System.EventHandler(this.menuFileSize_Click); + // + // menuFileSizeThreeQuarter + // + this.menuFileSizeThreeQuarter.Index = 7; + this.menuFileSizeThreeQuarter.Text = "Three-quarter size (75%)"; + this.menuFileSizeThreeQuarter.Click += new System.EventHandler(this.menuFileSize_Click); + // + // menuFileSizeNormal + // + this.menuFileSizeNormal.Index = 8; + this.menuFileSizeNormal.Text = "Normal size (100%)"; + this.menuFileSizeNormal.Click += new System.EventHandler(this.menuFileSize_Click); + // + // menuFileSizeDouble + // + this.menuFileSizeDouble.Index = 9; + this.menuFileSizeDouble.Text = "Double size (200%)"; + this.menuFileSizeDouble.Click += new System.EventHandler(this.menuFileSize_Click); + // + // menuItem17 + // + this.menuItem17.Index = 10; + this.menuItem17.Text = "-"; + // + // menuFileFullScreen + // + this.menuFileFullScreen.Index = 11; + this.menuFileFullScreen.Text = "Full Screen"; + this.menuFileFullScreen.Click += new System.EventHandler(this.menuFileFullScreen_Click); + // + // menuItem19 + // + this.menuItem19.Index = 2; + this.menuItem19.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuRateIncrease, + this.menuRateDecrease, + this.menuItem22, + this.menuRateNormal, + this.menuRateHalf, + this.menuRateDouble}); + this.menuItem19.Text = "Rate"; + // + // menuRateIncrease + // + this.menuRateIncrease.Index = 0; + this.menuRateIncrease.Text = "Increase Playback Rate"; + this.menuRateIncrease.Click += new System.EventHandler(this.menuRate_Click); + // + // menuRateDecrease + // + this.menuRateDecrease.Index = 1; + this.menuRateDecrease.Text = "Decrease Playback Rate"; + this.menuRateDecrease.Click += new System.EventHandler(this.menuRate_Click); + // + // menuItem22 + // + this.menuItem22.Index = 2; + this.menuItem22.Text = "-"; + // + // menuRateNormal + // + this.menuRateNormal.Index = 3; + this.menuRateNormal.Text = "Normal Playback Rate"; + this.menuRateNormal.Click += new System.EventHandler(this.menuRate_Click); + // + // menuRateHalf + // + this.menuRateHalf.Index = 4; + this.menuRateHalf.Text = "Half Playback Rate"; + this.menuRateHalf.Click += new System.EventHandler(this.menuRate_Click); + // + // menuRateDouble + // + this.menuRateDouble.Index = 5; + this.menuRateDouble.Text = "Double Playback Rate"; + this.menuRateDouble.Click += new System.EventHandler(this.menuRate_Click); + // + // menuItem26 + // + this.menuItem26.Index = 3; + this.menuItem26.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuHelpAbout}); + this.menuItem26.Text = "Help"; + // + // menuHelpAbout + // + this.menuHelpAbout.Index = 0; + this.menuHelpAbout.Text = "About"; + this.menuHelpAbout.Click += new System.EventHandler(this.menuHelpAbout_Click); + // + // openFileDialog1 + // + this.openFileDialog1.Filter = @"Video Files (*.avi; *.qt; *.mov; *.mpg; *.mpeg; *.m1v)|*.avi; *.qt; *.mov; *.mpg; *.mpeg; *.m1v|Audio files (*.wav; *.mpa; *.mp2; *.mp3; *.au; *.aif; *.aiff; *.snd)|*.wav; *.mpa; *.mp2; *.mp3; *.au; *.aif; *.aiff; *.snd|MIDI Files (*.mid, *.midi, *.rmi)|*.mid; *.midi; *.rmi|Image Files (*.jpg, *.bmp, *.gif, *.tga)|*.jpg; *.bmp; *.gif; *.tga|All Files (*.*)|*.*"; + // + // MainForm + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(240, 120); + this.Menu = this.mainMenu1; + this.Name = "MainForm"; + this.Text = "PlayWnd Media Player"; + this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MainForm_KeyDown); + this.Resize += new System.EventHandler(this.MainForm_Resize); + this.Closing += new System.ComponentModel.CancelEventHandler(this.MainForm_Closing); + this.Move += new System.EventHandler(this.MainForm_Move); + + } + #endregion + + /* + * Graph creation and destruction methods + */ + + private void OpenClip() + { + try + { + // If no filename specified by command line, show file open dialog + if (this.filename == string.Empty) + { + UpdateMainTitle(); + + this.filename = GetClipFileName(); + if (this.filename == string.Empty) + return; + } + + // Reset status variables + this.currentState = PlayState.Stopped; + this.currentVolume = VolumeFull; + + // Start playing the media file + PlayMovieInWindow(this.filename); + } + catch + { + CloseClip(); + } + } + + private void PlayMovieInWindow(string filename) + { + int hr = 0; + + if (filename == string.Empty) + return; + + this.graphBuilder = (IGraphBuilder) new FilterGraph(); + + // Have the graph builder construct its the appropriate graph automatically + hr = this.graphBuilder.RenderFile(filename, null); + DsError.ThrowExceptionForHR(hr); + + // QueryInterface for DirectShow interfaces + this.mediaControl = (IMediaControl) this.graphBuilder; + this.mediaEventEx = (IMediaEventEx) this.graphBuilder; + this.mediaSeeking = (IMediaSeeking) this.graphBuilder; + this.mediaPosition = (IMediaPosition) this.graphBuilder; + + // Query for video interfaces, which may not be relevant for audio files + this.videoWindow = this.graphBuilder as IVideoWindow; + this.basicVideo = this.graphBuilder as IBasicVideo; + + // Query for audio interfaces, which may not be relevant for video-only files + this.basicAudio = this.graphBuilder as IBasicAudio; + + // Is this an audio-only file (no video component)? + CheckVisibility(); + + // Have the graph signal event via window callbacks for performance + hr = this.mediaEventEx.SetNotifyWindow(this.Handle, WMGraphNotify, IntPtr.Zero); + DsError.ThrowExceptionForHR(hr); + + if (!this.isAudioOnly) + { + // Setup the video window + hr = this.videoWindow.put_Owner(this.Handle); + DsError.ThrowExceptionForHR(hr); + + hr = this.videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipSiblings | WindowStyle.ClipChildren); + DsError.ThrowExceptionForHR(hr); + + hr = InitVideoWindow(1, 1); + DsError.ThrowExceptionForHR(hr); + + GetFrameStepInterface(); + } + else + { + // Initialize the default player size and enable playback menu items + hr = InitPlayerWindow(); + DsError.ThrowExceptionForHR(hr); + + EnablePlaybackMenu(true, MediaType.Audio); + } + + // Complete window initialization + CheckSizeMenu(menuFileSizeNormal); + this.isFullScreen = false; + this.currentPlaybackRate = 1.0; + UpdateMainTitle(); + +#if DEBUG + rot = new DsROTEntry(this.graphBuilder); +#endif + + this.Focus(); + + // Run the graph to play the media file + hr = this.mediaControl.Run(); + DsError.ThrowExceptionForHR(hr); + + this.currentState=PlayState.Running; + } + + private void CloseClip() + { + int hr = 0; + + // Stop media playback + if(this.mediaControl != null) + hr = this.mediaControl.Stop(); + + // Clear global flags + this.currentState = PlayState.Stopped; + this.isAudioOnly = true; + this.isFullScreen = false; + + // Free DirectShow interfaces + CloseInterfaces(); + + // Clear file name to allow selection of new file with open dialog + this.filename = string.Empty; + + // No current media state + this.currentState = PlayState.Init; + + UpdateMainTitle(); + InitPlayerWindow(); + } + + private int InitVideoWindow(int nMultiplier, int nDivider) + { + int hr = 0; + int lHeight, lWidth; + + if (this.basicVideo == null) + return 0; + + // Read the default video size + hr = this.basicVideo.GetVideoSize(out lWidth, out lHeight); + if (hr == DsResults.E_NoInterface) + return 0; + + EnablePlaybackMenu(true, MediaType.Video); + + // Account for requests of normal, half, or double size + lWidth = lWidth * nMultiplier / nDivider; + lHeight = lHeight * nMultiplier / nDivider; + + this.ClientSize = new Size(lWidth, lHeight); + Application.DoEvents(); + + hr = this.videoWindow.SetWindowPosition(0, 0, lWidth, lHeight); + + return hr; + } + + private void MoveVideoWindow() + { + int hr = 0; + + // Track the movement of the container window and resize as needed + if (this.videoWindow != null) + { + hr = this.videoWindow.SetWindowPosition( + this.ClientRectangle.Left, + this.ClientRectangle.Top, + this.ClientRectangle.Width, + this.ClientRectangle.Height + ); + DsError.ThrowExceptionForHR(hr); + } + } + + private void CheckVisibility() + { + int hr = 0; + OABool lVisible; + + if ((this.videoWindow == null) || (this.basicVideo == null)) + { + // Audio-only files have no video interfaces. This might also + // be a file whose video component uses an unknown video codec. + this.isAudioOnly = true; + return; + } + else + { + // Clear the global flag + this.isAudioOnly = false; + } + + hr = this.videoWindow.get_Visible(out lVisible); + if (hr < 0) + { + // If this is an audio-only clip, get_Visible() won't work. + // + // Also, if this video is encoded with an unsupported codec, + // we won't see any video, although the audio will work if it is + // of a supported format. + if (hr == unchecked((int) 0x80004002)) //E_NOINTERFACE + { + this.isAudioOnly = true; + } + else + DsError.ThrowExceptionForHR(hr); + } + } + + // + // Some video renderers support stepping media frame by frame with the + // IVideoFrameStep interface. See the interface documentation for more + // details on frame stepping. + // + private bool GetFrameStepInterface() + { + int hr = 0; + + IVideoFrameStep frameStepTest = null; + + // Get the frame step interface, if supported + frameStepTest = (IVideoFrameStep) this.graphBuilder; + + // Check if this decoder can step + hr = frameStepTest.CanStep(0, null); + if (hr == 0) + { + this.frameStep = frameStepTest; + return true; + } + else + { + // BUG 1560263 found by husakm (thanks)... + // Marshal.ReleaseComObject(frameStepTest); + this.frameStep = null; + return false; + } + } + + private void CloseInterfaces() + { + int hr = 0; + + try + { + lock(this) + { + // Relinquish ownership (IMPORTANT!) after hiding video window + if (!this.isAudioOnly) + { + hr = this.videoWindow.put_Visible(OABool.False); + DsError.ThrowExceptionForHR(hr); + hr = this.videoWindow.put_Owner(IntPtr.Zero); + DsError.ThrowExceptionForHR(hr); + } + + if (this.mediaEventEx != null) + { + hr = this.mediaEventEx.SetNotifyWindow(IntPtr.Zero, 0, IntPtr.Zero); + DsError.ThrowExceptionForHR(hr); + } + +#if DEBUG + if (rot != null) + { + rot.Dispose(); + rot = null; + } +#endif + // Release and zero DirectShow interfaces + if (this.mediaEventEx != null) + this.mediaEventEx = null; + if (this.mediaSeeking != null) + this.mediaSeeking = null; + if (this.mediaPosition != null) + this.mediaPosition = null; + if (this.mediaControl != null) + this.mediaControl = null; + if (this.basicAudio != null) + this.basicAudio = null; + if (this.basicVideo != null) + this.basicVideo = null; + if (this.videoWindow != null) + this.videoWindow = null; + if (this.frameStep != null) + this.frameStep = null; + if (this.graphBuilder != null) + Marshal.ReleaseComObject(this.graphBuilder); this.graphBuilder = null; + + GC.Collect(); + } + } + catch + { + } + } + + /* + * Media Related methods + */ + + private void PauseClip() + { + if (this.mediaControl == null) + return; + + // Toggle play/pause behavior + if((this.currentState == PlayState.Paused) || (this.currentState == PlayState.Stopped)) + { + if (this.mediaControl.Run() >= 0) + this.currentState = PlayState.Running; + } + else + { + if (this.mediaControl.Pause() >= 0) + this.currentState = PlayState.Paused; + } + + UpdateMainTitle(); + } + + private void StopClip() + { + int hr = 0; + DsLong pos = new DsLong(0); + + if ((this.mediaControl == null) || (this.mediaSeeking == null)) + return; + + // Stop and reset postion to beginning + if((this.currentState == PlayState.Paused) || (this.currentState == PlayState.Running)) + { + hr = this.mediaControl.Stop(); + this.currentState = PlayState.Stopped; + + // Seek to the beginning + hr = this.mediaSeeking.SetPositions(pos, AMSeekingSeekingFlags.AbsolutePositioning, null, AMSeekingSeekingFlags.NoPositioning); + + // Display the first frame to indicate the reset condition + hr = this.mediaControl.Pause(); + } + UpdateMainTitle(); + } + + private int ToggleMute() + { + int hr = 0; + + if ((this.graphBuilder == null) || (this.basicAudio == null)) + return 0; + + // Read current volume + hr = this.basicAudio.get_Volume(out this.currentVolume); + if (hr == -1) //E_NOTIMPL + { + // Fail quietly if this is a video-only media file + return 0; + } + else if (hr < 0) + { + return hr; + } + + // Switch volume levels + if (this.currentVolume == VolumeFull) + this.currentVolume = VolumeSilence; + else + this.currentVolume = VolumeFull; + + // Set new volume + hr = this.basicAudio.put_Volume(this.currentVolume); + + UpdateMainTitle(); + return hr; + } + + private int ToggleFullScreen() + { + int hr = 0; + OABool lMode; + + // Don't bother with full-screen for audio-only files + if ((this.isAudioOnly) || (this.videoWindow == null)) + return 0; + + // Read current state + hr = this.videoWindow.get_FullScreenMode(out lMode); + DsError.ThrowExceptionForHR(hr); + + if (lMode == OABool.False) + { + // Save current message drain + hr = this.videoWindow.get_MessageDrain(out hDrain); + DsError.ThrowExceptionForHR(hr); + + // Set message drain to application main window + hr = this.videoWindow.put_MessageDrain(this.Handle); + DsError.ThrowExceptionForHR(hr); + + // Switch to full-screen mode + lMode = OABool.True; + hr = this.videoWindow.put_FullScreenMode(lMode); + DsError.ThrowExceptionForHR(hr); + this.isFullScreen = true; + } + else + { + // Switch back to windowed mode + lMode = OABool.False; + hr = this.videoWindow.put_FullScreenMode(lMode); + DsError.ThrowExceptionForHR(hr); + + // Undo change of message drain + hr = this.videoWindow.put_MessageDrain(hDrain); + DsError.ThrowExceptionForHR(hr); + + // Reset video window + hr = this.videoWindow.SetWindowForeground(OABool.True); + DsError.ThrowExceptionForHR(hr); + + // Reclaim keyboard focus for player application + //this.Focus(); + this.isFullScreen = false; + } + + return hr; + } + + private int StepOneFrame() + { + int hr = 0; + + // If the Frame Stepping interface exists, use it to step one frame + if (this.frameStep != null) + { + // The graph must be paused for frame stepping to work + if (this.currentState != PlayState.Paused) + PauseClip(); + + // Step the requested number of frames, if supported + hr = this.frameStep.Step(1, null); + } + + return hr; + } + + private int StepFrames(int nFramesToStep) + { + int hr = 0; + + // If the Frame Stepping interface exists, use it to step frames + if (this.frameStep != null) + { + // The renderer may not support frame stepping for more than one + // frame at a time, so check for support. S_OK indicates that the + // renderer can step nFramesToStep successfully. + hr = this.frameStep.CanStep(nFramesToStep, null); + if (hr == 0) + { + // The graph must be paused for frame stepping to work + if (this.currentState != PlayState.Paused) + PauseClip(); + + // Step the requested number of frames, if supported + hr = this.frameStep.Step(nFramesToStep, null); + } + } + + return hr; + } + + private int ModifyRate(double dRateAdjust) + { + int hr = 0; + double dRate; + + // If the IMediaPosition interface exists, use it to set rate + if ((this.mediaPosition != null) && (dRateAdjust != 0.0)) + { + hr = this.mediaPosition.get_Rate(out dRate); + if (hr == 0) + { + // Add current rate to adjustment value + double dNewRate = dRate + dRateAdjust; + hr = this.mediaPosition.put_Rate(dNewRate); + + // Save global rate + if (hr == 0) + { + this.currentPlaybackRate = dNewRate; + UpdateMainTitle(); + } + } + } + + return hr; + } + + private int SetRate(double rate) + { + int hr = 0; + + // If the IMediaPosition interface exists, use it to set rate + if (this.mediaPosition != null) + { + hr = this.mediaPosition.put_Rate(rate); + if (hr >= 0) + { + this.currentPlaybackRate = rate; + UpdateMainTitle(); + } + } + + return hr; + } + + private void HandleGraphEvent() + { + int hr = 0; + EventCode evCode; + IntPtr evParam1, evParam2; + + // Make sure that we don't access the media event interface + // after it has already been released. + if (this.mediaEventEx == null) + return; + + // Process all queued events + while(this.mediaEventEx.GetEvent(out evCode, out evParam1, out evParam2, 0) == 0) + { + // Free memory associated with callback, since we're not using it + hr = this.mediaEventEx.FreeEventParams(evCode, evParam1, evParam2); + + // If this is the end of the clip, reset to beginning + if(evCode == EventCode.Complete) + { + DsLong pos = new DsLong(0); + // Reset to first frame of movie + hr = this.mediaSeeking.SetPositions(pos, AMSeekingSeekingFlags.AbsolutePositioning, + null, AMSeekingSeekingFlags.NoPositioning); + if (hr < 0) + { + // Some custom filters (like the Windows CE MIDI filter) + // may not implement seeking interfaces (IMediaSeeking) + // to allow seeking to the start. In that case, just stop + // and restart for the same effect. This should not be + // necessary in most cases. + hr = this.mediaControl.Stop(); + hr = this.mediaControl.Run(); + } + } + } + } + + /* + * WinForm Related methods + */ + + protected override void WndProc(ref Message m) + { + switch (m.Msg) + { + case WMGraphNotify : + { + HandleGraphEvent(); + break; + } + } + + // Pass this message to the video window for notification of system changes + if (this.videoWindow != null) + this.videoWindow.NotifyOwnerMessage(m.HWnd, m.Msg, m.WParam, m.LParam); + + base.WndProc (ref m); + } + + private string GetClipFileName() + { + if (openFileDialog1.ShowDialog() == DialogResult.OK) + { + return openFileDialog1.FileName; + } + else + return string.Empty; + } + + private int InitPlayerWindow() + { + // Reset to a default size for audio and after closing a clip + this.ClientSize = new Size(240, 120); + + // Check the 'full size' menu item + CheckSizeMenu(menuFileSizeNormal); + EnablePlaybackMenu(false, MediaType.Audio); + + return 0; + } + + private void UpdateMainTitle() + { + // If no file is loaded, just show the application title + if (this.filename == string.Empty) + this.Text = "PlayWnd Media Player"; + else + { + string media = (isAudioOnly) ? "Audio" : "Video"; + string muted = (currentVolume == VolumeSilence) ? "Mute" : ""; + string paused = (currentState == PlayState.Paused) ? "Paused" : ""; + + this.Text = String.Format("{0} [{1}] {2}{3}", System.IO.Path.GetFileName(this.filename), media, muted, paused); + } + } + + private void CheckSizeMenu(MenuItem item) + { + menuFileSizeHalf.Checked = false; + menuFileSizeThreeQuarter.Checked = false; + menuFileSizeNormal.Checked = false; + menuFileSizeDouble.Checked = false; + + item.Checked = true; + } + + private void EnablePlaybackMenu(bool bEnable, MediaType nMediaType) + { + // Enable/disable menu items related to playback (pause, stop, mute) + menuFilePause.Enabled = bEnable; + menuFileStop.Enabled = bEnable; + menuFileMute.Enabled = bEnable; + menuRateIncrease.Enabled = bEnable; + menuRateDecrease.Enabled = bEnable; + menuRateNormal.Enabled = bEnable; + menuRateHalf.Enabled = bEnable; + menuRateDouble.Enabled = bEnable; + + // Enable/disable menu items related to video size + bool isVideo = (nMediaType == MediaType.Video) ? true : false; + + menuSingleStep.Enabled = isVideo; + menuFileSizeHalf.Enabled = isVideo; + menuFileSizeDouble.Enabled = isVideo; + menuFileSizeNormal.Enabled = isVideo; + menuFileSizeThreeQuarter.Enabled = isVideo; + menuFileFullScreen.Enabled = isVideo; + } + + private void MainForm_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) + { + switch(e.KeyCode) + { + case Keys.Space : + { + StepOneFrame(); + break; + } + case Keys.Left : + { + ModifyRate(-0.25); + break; + } + case Keys.Right : + { + ModifyRate(+0.25); + break; + } + case Keys.Down : + { + SetRate(1.0); + break; + } + case Keys.P : + { + PauseClip(); + break; + } + case Keys.S : + { + StopClip(); + break; + } + case Keys.M : + { + ToggleMute(); + break; + } + case Keys.F: + case Keys.Return: + { + ToggleFullScreen(); + break; + } + case Keys.H : + { + InitVideoWindow(1, 2); + CheckSizeMenu(menuFileSizeHalf); + break; + } + case Keys.N : + { + InitVideoWindow(1, 1); + CheckSizeMenu(menuFileSizeNormal); + break; + } + case Keys.D : + { + InitVideoWindow(2, 1); + CheckSizeMenu(menuFileSizeDouble); + break; + } + case Keys.T : + { + InitVideoWindow(3, 4); + CheckSizeMenu(menuFileSizeThreeQuarter); + break; + } + case Keys.Escape : + { + if (this.isFullScreen) + ToggleFullScreen(); + else + CloseClip(); + break; + } + case Keys.F12 | Keys.Q | Keys.X : + { + CloseClip(); + break; + } + } + } + + private void menuFileOpenClip_Click(object sender, System.EventArgs e) + { + // If we have ANY file open, close it and shut down DirectShow + if (this.currentState != PlayState.Init) + CloseClip(); + + // Open the new clip + OpenClip(); + } + + private void menuFileClose_Click(object sender, System.EventArgs e) + { + CloseClip(); + } + + private void menuFileExit_Click(object sender, System.EventArgs e) + { + CloseClip(); + this.Close(); + } + + private void menuFilePause_Click(object sender, System.EventArgs e) + { + PauseClip(); + } + + private void menuFileStop_Click(object sender, System.EventArgs e) + { + StopClip(); + } + + private void menuFileMute_Click(object sender, System.EventArgs e) + { + ToggleMute(); + } + + private void menuFileFullScreen_Click(object sender, System.EventArgs e) + { + ToggleFullScreen(); + } + + private void menuFileSize_Click(object sender, System.EventArgs e) + { + if (sender == menuFileSizeHalf) InitVideoWindow(1, 2); + if (sender == menuFileSizeNormal) InitVideoWindow(1, 1); + if (sender == menuFileSizeDouble) InitVideoWindow(2, 1); + if (sender == menuFileSizeThreeQuarter) InitVideoWindow(3, 4); + + CheckSizeMenu((MenuItem) sender); + } + + private void menuSingleStep_Click(object sender, System.EventArgs e) + { + StepOneFrame(); + } + + private void menuRate_Click(object sender, System.EventArgs e) + { + if (sender == menuRateDecrease) ModifyRate(-0.25); + if (sender == menuRateIncrease) ModifyRate(+0.25); + if (sender == menuRateNormal) SetRate(1.0); + if (sender == menuRateHalf) SetRate(0.5); + if (sender == menuRateDouble) SetRate(2.0); + } + + private void MainForm_Move(object sender, System.EventArgs e) + { + if (!this.isAudioOnly) + MoveVideoWindow(); + } + + private void MainForm_Resize(object sender, System.EventArgs e) + { + if (!this.isAudioOnly) + MoveVideoWindow(); + } + + private void MainForm_Closing(object sender, System.ComponentModel.CancelEventArgs e) + { + StopClip(); + CloseInterfaces(); + } + + private void menuHelpAbout_Click(object sender, System.EventArgs e) + { + string title = "About PlayWnd Media Player"; + string text = "DirectShow.Net PlayWindow Sample"; + + AboutBox.Show(title, text); + } + + /// + /// Main entry point + /// + [STAThread] + static void Main(string[] args) + { + // Enable XP style controls + Application.EnableVisualStyles(); + Application.DoEvents(); + + using(MainForm form = new MainForm()) + { + if (args.Length > 0) + form.filename = args[0]; + + form.Show(); + form.OpenClip(); + + Application.Run(form); + } + } + + } +} diff --git a/Samples/Players/PlayWnd/MainForm.resx b/Samples/Players/PlayWnd/MainForm.resx new file mode 100644 index 0000000..b5dc9de --- /dev/null +++ b/Samples/Players/PlayWnd/MainForm.resx @@ -0,0 +1,310 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Private + + + 17, 17 + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + 126, 17 + + + False + + + (Default) + + + False + + + False + + + MainForm + + + 8, 8 + + + True + + + 80 + + + True + + + Private + + \ No newline at end of file diff --git a/Samples/Players/PlayWnd/PlayWnd-2005.csproj b/Samples/Players/PlayWnd/PlayWnd-2005.csproj new file mode 100644 index 0000000..5d8a560 --- /dev/null +++ b/Samples/Players/PlayWnd/PlayWnd-2005.csproj @@ -0,0 +1,122 @@ + + + Local + 8.0.50727 + 2.0 + {20FBEEA4-92C2-409E-9448-219CE60C0041} + Debug + AnyCPU + + + + + PlayWnd + + + JScript + Grid + IE50 + false + WinExe + PlayWnd + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Data + + + System.Drawing + + + System.Windows.Forms + + + System.XML + + + + + Form + + + Code + + + Form + + + AboutBox.cs + + + MainForm.cs + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Players/PlayWnd/PlayWnd-2005.sln b/Samples/Players/PlayWnd/PlayWnd-2005.sln new file mode 100644 index 0000000..213d959 --- /dev/null +++ b/Samples/Players/PlayWnd/PlayWnd-2005.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlayWnd-2005", "PlayWnd-2005.csproj", "{20FBEEA4-92C2-409E-9448-219CE60C0041}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {20FBEEA4-92C2-409E-9448-219CE60C0041}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {20FBEEA4-92C2-409E-9448-219CE60C0041}.Debug|Any CPU.Build.0 = Debug|Any CPU + {20FBEEA4-92C2-409E-9448-219CE60C0041}.Release|Any CPU.ActiveCfg = Release|Any CPU + {20FBEEA4-92C2-409E-9448-219CE60C0041}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Players/PlayWnd/PlayWnd-2008.sln b/Samples/Players/PlayWnd/PlayWnd-2008.sln new file mode 100644 index 0000000..37fb0e5 --- /dev/null +++ b/Samples/Players/PlayWnd/PlayWnd-2008.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlayWnd-2008", "PlayWnd-2008.csproj", "{20FBEEA4-92C2-409E-9448-219CE60C0041}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {20FBEEA4-92C2-409E-9448-219CE60C0041}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {20FBEEA4-92C2-409E-9448-219CE60C0041}.Debug|Any CPU.Build.0 = Debug|Any CPU + {20FBEEA4-92C2-409E-9448-219CE60C0041}.Release|Any CPU.ActiveCfg = Release|Any CPU + {20FBEEA4-92C2-409E-9448-219CE60C0041}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Players/PlayWnd/PlayWnd.csproj b/Samples/Players/PlayWnd/PlayWnd.csproj new file mode 100644 index 0000000..ca37847 --- /dev/null +++ b/Samples/Players/PlayWnd/PlayWnd.csproj @@ -0,0 +1,154 @@ + + + + Local + 8.0.50727 + 2.0 + {20FBEEA4-92C2-409E-9448-219CE60C0041} + Debug + AnyCPU + + + + + PlayWnd + + + JScript + Grid + IE50 + false + WinExe + PlayWnd + OnBuildSuccess + + + + + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Data + + + System.Drawing + + + System.Windows.Forms + + + System.XML + + + + + Form + + + Code + + + Form + + + AboutBox.cs + + + MainForm.cs + + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Players/PlayWnd/playwnd.ico b/Samples/Players/PlayWnd/playwnd.ico new file mode 100644 index 0000000000000000000000000000000000000000..bc43c1b2085df668dffff26d80adcb0ef73f23a9 GIT binary patch literal 25214 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 literal 0 HcmV?d00001 diff --git a/Samples/SBE/DvrMsCutter/AssemblyInfo.cs b/Samples/SBE/DvrMsCutter/AssemblyInfo.cs new file mode 100644 index 0000000..76201ae --- /dev/null +++ b/Samples/SBE/DvrMsCutter/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// Les informations générales relatives à un assembly dépendent de +// l'ensemble d'attributs suivant. Pour modifier les informations +// associées à un assembly, changez les valeurs de ces attributs. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Les informations de version pour un assembly se composent des quatre valeurs suivantes : +// +// Version principale +// Version secondaire +// Numéro de build +// Révision +// +// Vous pouvez spécifier toutes les valeurs ou indiquer des numéros de révision et de build par défaut +// en utilisant '*', comme ci-dessous : + +[assembly: AssemblyVersion("1.0.*")] + +// +// Pour signer votre assembly, vous devez spécifier la clé à utiliser. Consultez +// la documentation Microsoft .NET Framework pour plus d'informations sur la signature d'un assembly. +// +// Utilisez les attributs ci-dessous pour contrôler la clé utilisée lors de la signature. +// +// Remarques : +// (*) Si aucune clé n'est spécifiée, l'assembly n'est pas signé. +// (*) KeyName fait référence à une clé installée dans le fournisseur de +// services cryptographiques (CSP) de votre ordinateur. KeyFile fait référence à un fichier qui contient +// une clé. +// (*) Si les valeurs de KeyFile et de KeyName sont spécifiées, le +// traitement suivant se produit : +// (1) Si KeyName se trouve dans le CSP, la clé est utilisée. +// (2) Si KeyName n'existe pas mais que KeyFile existe, la clé +// de KeyFile est installée dans le CSP et utilisée. +// (*) Pour créer KeyFile, vous pouvez utiliser l'utilitaire sn.exe (Strong Name, Nom fort). +// Lors de la spécification de KeyFile, son emplacement doit être +// relatif au répertoire de sortie du projet qui est +// %Project Directory%\obj\. Par exemple, si votre KeyFile se trouve +// dans le répertoire du projet, vous devez spécifier l'attribut +// AssemblyKeyFile sous la forme [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) DelaySign (signature différée) est une option avancée. Pour plus d'informations, consultez la +// documentation Microsoft .NET Framework. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/SBE/DvrMsCutter/DvrMsCutter-2005.csproj b/Samples/SBE/DvrMsCutter/DvrMsCutter-2005.csproj new file mode 100644 index 0000000..febc61a --- /dev/null +++ b/Samples/SBE/DvrMsCutter/DvrMsCutter-2005.csproj @@ -0,0 +1,110 @@ + + + Local + 8.0.50727 + 2.0 + {58BA266F-B6DF-4096-8816-6A97C0A343E7} + Debug + AnyCPU + App.ico + + + DvrMsCutter + + + JScript + Grid + IE50 + false + Exe + DirectShowLib.Sample + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\lib\DirectShowLib-2005.dll + + + System + + + System.Data + + + System.XML + + + + + + + Code + + + Code + + + Code + + + + + + + + + + \ No newline at end of file diff --git a/Samples/SBE/DvrMsCutter/DvrMsCutter-2005.sln b/Samples/SBE/DvrMsCutter/DvrMsCutter-2005.sln new file mode 100644 index 0000000..3c7df6c --- /dev/null +++ b/Samples/SBE/DvrMsCutter/DvrMsCutter-2005.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DvrMsCutter-2005", "DvrMsCutter-2005.csproj", "{58BA266F-B6DF-4096-8816-6A97C0A343E7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {58BA266F-B6DF-4096-8816-6A97C0A343E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {58BA266F-B6DF-4096-8816-6A97C0A343E7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {58BA266F-B6DF-4096-8816-6A97C0A343E7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {58BA266F-B6DF-4096-8816-6A97C0A343E7}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/SBE/DvrMsCutter/DvrMsCutter-2008.sln b/Samples/SBE/DvrMsCutter/DvrMsCutter-2008.sln new file mode 100644 index 0000000..1e12602 --- /dev/null +++ b/Samples/SBE/DvrMsCutter/DvrMsCutter-2008.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DvrMsCutter-2008", "DvrMsCutter-2008.csproj", "{58BA266F-B6DF-4096-8816-6A97C0A343E7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {58BA266F-B6DF-4096-8816-6A97C0A343E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {58BA266F-B6DF-4096-8816-6A97C0A343E7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {58BA266F-B6DF-4096-8816-6A97C0A343E7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {58BA266F-B6DF-4096-8816-6A97C0A343E7}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/SBE/DvrMsCutter/DvrMsCutter.csproj b/Samples/SBE/DvrMsCutter/DvrMsCutter.csproj new file mode 100644 index 0000000..089fb60 --- /dev/null +++ b/Samples/SBE/DvrMsCutter/DvrMsCutter.csproj @@ -0,0 +1,142 @@ + + + + Local + 8.0.50727 + 2.0 + {58BA266F-B6DF-4096-8816-6A97C0A343E7} + Debug + AnyCPU + App.ico + + + DvrMsCutter + + + JScript + Grid + IE50 + false + Exe + DirectShowLib.Sample + OnBuildSuccess + + + + + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Data + + + System.XML + + + + + + + Code + + + Code + + + Code + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + + + + + + \ No newline at end of file diff --git a/Samples/SBE/DvrMsCutter/SBECutter.cs b/Samples/SBE/DvrMsCutter/SBECutter.cs new file mode 100644 index 0000000..29cf71b --- /dev/null +++ b/Samples/SBE/DvrMsCutter/SBECutter.cs @@ -0,0 +1,58 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Runtime.InteropServices; + +using DirectShowLib.SBE; + +namespace DirectShowLib.Sample +{ + public class SBECutter : IDisposable + { + // SBE provide an utility object for cutting SBE files + IStreamBufferRecComp recComp; + + public SBECutter() + { + // Create this object + recComp = (IStreamBufferRecComp) new StreamBufferComposeRecording(); + } + + ~SBECutter() + { + Dispose(); + } + + public void Dispose() + { + // Realease it + if (recComp != null) + Marshal.ReleaseComObject(recComp); + + GC.SuppressFinalize(this); + } + + public void DoCut(string srcFile, string dstFile, TimeSpan start, TimeSpan stop) + { + int hr = 0; + + // Initialize a destination file with the same profil as source file + hr = recComp.Initialize(dstFile, srcFile); + DsError.ThrowExceptionForHR(hr); + + // Copy source file into destination file + hr = recComp.AppendEx(srcFile, start.Ticks, stop.Ticks); + DsError.ThrowExceptionForHR(hr); + + // Close destination file + hr = recComp.Close(); + DsError.ThrowExceptionForHR(hr); + } + + } +} diff --git a/Samples/SBE/DvrMsCutter/StartUp.cs b/Samples/SBE/DvrMsCutter/StartUp.cs new file mode 100644 index 0000000..d114d2c --- /dev/null +++ b/Samples/SBE/DvrMsCutter/StartUp.cs @@ -0,0 +1,68 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.IO; + +namespace DirectShowLib.Sample +{ + class StartUp + { + public static void ShowUsage() + { + Console.WriteLine(); + Console.WriteLine("Usage : DvrMsCutter.exe Source Destination StartTime EndTime"); + Console.WriteLine(); + Console.WriteLine("Source : must be an existing dvr-ms file"); + Console.WriteLine("Destination : the result dvr-ms file (warning : overwitten if already exist)"); + Console.WriteLine("StartTime : the start time the source file in this format : hh:mm:ss"); + Console.WriteLine("EndTime : the end time the source file in this format : hh:mm:ss"); + } + + private static TimeSpan ParseTime(string time) + { + string[] hhmmss = time.Split(new char[]{':'}); + + return new TimeSpan(Convert.ToInt32(hhmmss[0]), Convert.ToInt32(hhmmss[1]), Convert.ToInt32(hhmmss[2])); + } + + [STAThread] + static int Main(string[] args) + { + // Verify if enough arguments have been given... + if (args.Length != 4) + { + ShowUsage(); + return 1; + } + + // Parse arguments + string src = args[0]; + string dst = args[1]; + TimeSpan start = ParseTime(args[2]); + TimeSpan end = ParseTime(args[3]); + + // If source file doesn't exist, exit with an error + if (!File.Exists(src)) + { + Console.WriteLine(src + " doesn't exist"); + return 1; + } + + // If destination file exist, delete it + if (File.Exists(dst)) + File.Delete(dst); + + // Cut the file + SBECutter cutter = new SBECutter(); + cutter.DoCut(src, dst, start, end); + cutter.Dispose(); + + return 0; + } + } +} diff --git a/Samples/SBE/DvrMsCutter/readme.txt b/Samples/SBE/DvrMsCutter/readme.txt new file mode 100644 index 0000000..3b8a736 --- /dev/null +++ b/Samples/SBE/DvrMsCutter/readme.txt @@ -0,0 +1,10 @@ +This sample shows how to work with the dvr-ms files created when working with SBE. It produces +a command line utility that has the following options: + +Usage : DvrMsCutter.exe Source Destination StartTime EndTime + +Source : must be an existing dvr-ms file +Destination : the result dvr-ms file (warning : overwitten if already exist) +StartTime : the start time the source file in this format : hh:mm:ss +EndTime : the end time the source file in this format : hh:mm:ss + diff --git a/Samples/SBE/DvrMsCutter2/DvrMsCutter2-2005.csproj b/Samples/SBE/DvrMsCutter2/DvrMsCutter2-2005.csproj new file mode 100644 index 0000000..e954074 --- /dev/null +++ b/Samples/SBE/DvrMsCutter2/DvrMsCutter2-2005.csproj @@ -0,0 +1,53 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {2BB69C76-D153-48A0-95B9-710550D63986} + Exe + Properties + DirectShowLib.Sample + DvrMsCutter2 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\..\..\lib\DirectShowLib-2005.dll + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/SBE/DvrMsCutter2/DvrMsCutter2-2008.sln b/Samples/SBE/DvrMsCutter2/DvrMsCutter2-2008.sln new file mode 100644 index 0000000..1afd205 --- /dev/null +++ b/Samples/SBE/DvrMsCutter2/DvrMsCutter2-2008.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DvrMsCutter2-2008", "DvrMsCutter2-2008.csproj", "{2BB69C76-D153-48A0-95B9-710550D63986}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2BB69C76-D153-48A0-95B9-710550D63986}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2BB69C76-D153-48A0-95B9-710550D63986}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2BB69C76-D153-48A0-95B9-710550D63986}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2BB69C76-D153-48A0-95B9-710550D63986}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/SBE/DvrMsCutter2/DvrMsCutter2.csproj b/Samples/SBE/DvrMsCutter2/DvrMsCutter2.csproj new file mode 100644 index 0000000..577ac3c --- /dev/null +++ b/Samples/SBE/DvrMsCutter2/DvrMsCutter2.csproj @@ -0,0 +1,89 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {2BB69C76-D153-48A0-95B9-710550D63986} + Exe + Properties + DirectShowLib.Sample + DvrMsCutter2 + + + 3.5 + + + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + \ No newline at end of file diff --git a/Samples/SBE/DvrMsCutter2/DvrMsCutter2.sln b/Samples/SBE/DvrMsCutter2/DvrMsCutter2.sln new file mode 100644 index 0000000..889c99a --- /dev/null +++ b/Samples/SBE/DvrMsCutter2/DvrMsCutter2.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DvrMsCutter2", "DvrMsCutter2.csproj", "{2BB69C76-D153-48A0-95B9-710550D63986}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2BB69C76-D153-48A0-95B9-710550D63986}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2BB69C76-D153-48A0-95B9-710550D63986}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2BB69C76-D153-48A0-95B9-710550D63986}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2BB69C76-D153-48A0-95B9-710550D63986}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/SBE/DvrMsCutter2/Program.cs b/Samples/SBE/DvrMsCutter2/Program.cs new file mode 100644 index 0000000..cb549c2 --- /dev/null +++ b/Samples/SBE/DvrMsCutter2/Program.cs @@ -0,0 +1,107 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.IO; + +namespace DirectShowLib.Sample +{ + public struct Segment + { + public TimeSpan From; + public TimeSpan To; + } + + class Program + { + static string sourceFile, destinationFile; + static List segments; + + public static void ShowUsage() + { + Console.WriteLine(); + Console.WriteLine("Usage : DvrMsCutter.exe Source Destination Segment1 Segment2 ... SegmentN"); + Console.WriteLine(); + Console.WriteLine("Source : must be an existing dvr-ms file"); + Console.WriteLine("Destination : the result dvr-ms file (warning : overwitten if already exist)"); + Console.WriteLine("Segment : the start and the end of a segment in this format : hh:mm:ss-hh:mm:ss"); + } + + public static bool ParseParameters(string[] args) + { + if (args.Length < 3) + { + Console.WriteLine("Not enough parameters"); + ShowUsage(); + return false; + + } + + sourceFile = args[0]; + if (!File.Exists(sourceFile)) + throw new FileNotFoundException(); + + destinationFile = args[1]; + if (File.Exists(destinationFile)) + { + Console.WriteLine("Destionation file already exists. Press Y to continue."); + ConsoleKeyInfo keyInfo = Console.ReadKey(); + if (keyInfo.KeyChar != 'Y' && keyInfo.KeyChar != 'y') + { + return false; + } + } + + segments = new List(args.Length - 2); + + for (int i = 2; i < args.Length; i++) + { + string[] segmentBounds = args[i].Split(new char[] { '-' }); + if (segmentBounds.Length != 2) + { + Console.WriteLine("Invalid segment : " + args[i]); + return false; + } + + Segment segment = new Segment(); + segment.From = ParseTime(segmentBounds[0]); + segment.To = ParseTime(segmentBounds[1]); + segments.Add(segment); + } + + return true; + } + + private static TimeSpan ParseTime(string time) + { + string[] hhmmss = time.Split(new char[] { ':' }); + + if (hhmmss.Length != 3) + throw new ArgumentException(); + + return new TimeSpan(Convert.ToInt32(hhmmss[0]), Convert.ToInt32(hhmmss[1]), Convert.ToInt32(hhmmss[2])); + } + + static void Main(string[] args) + { + SBECutter2 cutter; + + if (ParseParameters(args)) + { + using (cutter = new SBECutter2(sourceFile, destinationFile)) + { + foreach (Segment segment in segments) + { + cutter.CopyThisSegment(segment.From, segment.To); + } + } + } + + } + } +} diff --git a/Samples/SBE/DvrMsCutter2/Properties/AssemblyInfo.cs b/Samples/SBE/DvrMsCutter2/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..c96bb55 --- /dev/null +++ b/Samples/SBE/DvrMsCutter2/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("DvrMsCutter2")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("DvrMsCutter2")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("93A17333-4729-4a75-922D-224E6870CBCC")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Samples/SBE/DvrMsCutter2/SBECutter2.cs b/Samples/SBE/DvrMsCutter2/SBECutter2.cs new file mode 100644 index 0000000..2602559 --- /dev/null +++ b/Samples/SBE/DvrMsCutter2/SBECutter2.cs @@ -0,0 +1,97 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Text; + +using DirectShowLib; +using DirectShowLib.SBE; + +namespace DirectShowLib.Sample +{ + public class SBECutter2 : IDisposable + { + IStreamBufferRecComp sbeRecComp; + string source, destionation; + + /// + /// This object is a managed wrapper around the SBE's RecComp object + /// + /// The source file to be cutted + /// The resulting file. Delet + /// Warning, if destFile already exists, the constructor delete it + /// Thrown if srcFile doesn't exists + /// Thrown if someting wrong append during the destination initialization + public SBECutter2(string srcFile, string destFile) + { + if (!File.Exists(srcFile)) + throw new FileNotFoundException(); + + if (File.Exists(destFile)) + File.Delete(destFile); + + sbeRecComp = (IStreamBufferRecComp) new StreamBufferComposeRecording(); + source = srcFile; + destionation = destFile; + + int hr = sbeRecComp.Initialize(destionation, source); + DsError.ThrowExceptionForHR(hr); + } + + ~SBECutter2() + { + Dispose(false); + } + + #region IDisposable Members + + /// + /// Close both files and release unmanged ressources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + #endregion + + /// + /// Close both files and release unmanged ressources if disposing is true. + /// + /// dispose unmanaged ressources or not + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + if (sbeRecComp != null) + { + sbeRecComp.Close(); + Marshal.ReleaseComObject(sbeRecComp); + } + } + } + + /// + /// Append a segment of the source file into the destination file + /// + /// start time of the segment + /// end time of the segment + /// Thrown if the fist paramter is superior to the second + /// Thrown if someting wrong append during the copy + public void CopyThisSegment(TimeSpan from, TimeSpan to) + { + if (from > to) + throw new ArgumentException(); + + int hr = sbeRecComp.AppendEx(source, from.Ticks, to.Ticks); + DsError.ThrowExceptionForHR(hr); + } + } +} diff --git a/Samples/SBE/DvrMsCutter2/readme.txt b/Samples/SBE/DvrMsCutter2/readme.txt new file mode 100644 index 0000000..eaecd0a --- /dev/null +++ b/Samples/SBE/DvrMsCutter2/readme.txt @@ -0,0 +1,15 @@ +This sample shows how to work with the dvr-ms files created when working with SBE. +It enhances the first DvrmsCutter by allowing the copy multiple segments of the source instead of just one. +Handy to remove advertisements from your favorite tv series... + +The main program is just a consumer of the SBECutter2 class that can be reuse in any other programs + +The sample consist in a command line utility that has the following options: + +Usage : DvrMsCutter.exe Source Destination Segment1 Segment2 ... SegmentN + +Source : must be an existing dvr-ms file +Destination : the result dvr-ms file (warning : overwritten if already exist) +Segment : the start and the end of a segment in this format : hh:mm:ss-hh:mm:ss + +The sample only work with .Net 2.0 but can easily adapted to an older framework version. diff --git a/Samples/VMR9/BitmapMixer/AboutBox.cs b/Samples/VMR9/BitmapMixer/AboutBox.cs new file mode 100644 index 0000000..7517592 --- /dev/null +++ b/Samples/VMR9/BitmapMixer/AboutBox.cs @@ -0,0 +1,163 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Reflection; +using System.Windows.Forms; + +using DirectShowLib; + +namespace DirectShowLib.Sample +{ + internal class AboutBoxWnd : Form + { + public System.Windows.Forms.Label label1; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.LinkLabel linkLabel1; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label4; + private System.ComponentModel.Container components = null; + + public AboutBoxWnd() + { + InitializeComponent(); + + Type t = typeof(IGraphBuilder); + label3.Text += t.Assembly.GetName().Version; + } + + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if(components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Code généré par le Concepteur Windows Form + /// + /// Méthode requise pour la prise en charge du concepteur - ne modifiez pas + /// le contenu de cette méthode avec l'éditeur de code. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.button1 = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.linkLabel1 = new System.Windows.Forms.LinkLabel(); + this.label3 = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // label1 + // + this.label1.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label1.Location = new System.Drawing.Point(8, 8); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(272, 40); + this.label1.TabIndex = 1; + // + // button1 + // + this.button1.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.button1.Location = new System.Drawing.Point(288, 8); + this.button1.Name = "button1"; + this.button1.TabIndex = 0; + this.button1.Text = "OK"; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // label2 + // + this.label2.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label2.Location = new System.Drawing.Point(8, 64); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(160, 16); + this.label2.TabIndex = 2; + this.label2.Text = "Library source code release under"; + // + // linkLabel1 + // + this.linkLabel1.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.linkLabel1.Location = new System.Drawing.Point(184, 64); + this.linkLabel1.Name = "linkLabel1"; + this.linkLabel1.Size = new System.Drawing.Size(160, 16); + this.linkLabel1.TabIndex = 3; + this.linkLabel1.TabStop = true; + this.linkLabel1.Text = "Lesser General Public License"; + this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked); + // + // label3 + // + this.label3.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label3.Location = new System.Drawing.Point(8, 48); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(320, 16); + this.label3.TabIndex = 4; + this.label3.Text = "DirectShowLib Version : "; + // + // label4 + // + this.label4.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label4.Location = new System.Drawing.Point(8, 80); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(264, 16); + this.label4.TabIndex = 5; + this.label4.Text = "Sample source code release under Public Domain"; + // + // AboutBoxWnd + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(372, 104); + this.Controls.Add(this.label4); + this.Controls.Add(this.label3); + this.Controls.Add(this.linkLabel1); + this.Controls.Add(this.label2); + this.Controls.Add(this.button1); + this.Controls.Add(this.label1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "AboutBoxWnd"; + this.ShowInTaskbar = false; + this.Text = "AboutBox"; + this.ResumeLayout(false); + + } + #endregion + + private void button1_Click(object sender, System.EventArgs e) + { + this.Close(); + } + + private void linkLabel1_LinkClicked(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e) + { + System.Diagnostics.Process.Start("http://www.gnu.org/copyleft/lesser.txt"); + } + } + + public class AboutBox + { + public static void Show(string title, string text) + { + using (AboutBoxWnd form = new AboutBoxWnd()) + { + form.Text = title; + form.label1.Text = text; + form.ShowDialog(); + } + } + } +} diff --git a/Samples/VMR9/BitmapMixer/AboutBox.resx b/Samples/VMR9/BitmapMixer/AboutBox.resx new file mode 100644 index 0000000..4b1c550 --- /dev/null +++ b/Samples/VMR9/BitmapMixer/AboutBox.resx @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + Private + + + Public + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + Private + + + False + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + (Default) + + + False + + + False + + + 8, 8 + + + True + + + AboutBoxWnd + + + 80 + + + True + + + Private + + \ No newline at end of file diff --git a/Samples/VMR9/BitmapMixer/App.ico b/Samples/VMR9/BitmapMixer/App.ico new file mode 100644 index 0000000000000000000000000000000000000000..3a5525fd794f7a7c5c8e6187f470ea3af38cd2b6 GIT binary patch literal 1078 zcmeHHJr05}7=1t!Hp3A*8IHkVf+j?-!eHY14Gtcw1Eb*_9>Bq^zETJ@GKj{_2j4$w zo9}xCh!8{T3=X##Skq>ikMjsvB|y%crWBM2iW(4pI}c%z6%lW!=~4v77#3{z!dmB1 z__&l)-{KUYR+|8|;wB^R|9ET$J@(@=#rd^=)qs85?vAy(PSF5CyNkus435LVkZ$rj zNw|JG-P7^hF<(;#o*Vk}5R#e|^13tBbQkeF?djULtvqyxd3<{9 literal 0 HcmV?d00001 diff --git a/Samples/VMR9/BitmapMixer/AssemblyInfo.cs b/Samples/VMR9/BitmapMixer/AssemblyInfo.cs new file mode 100644 index 0000000..76201ae --- /dev/null +++ b/Samples/VMR9/BitmapMixer/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// Les informations générales relatives à un assembly dépendent de +// l'ensemble d'attributs suivant. Pour modifier les informations +// associées à un assembly, changez les valeurs de ces attributs. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Les informations de version pour un assembly se composent des quatre valeurs suivantes : +// +// Version principale +// Version secondaire +// Numéro de build +// Révision +// +// Vous pouvez spécifier toutes les valeurs ou indiquer des numéros de révision et de build par défaut +// en utilisant '*', comme ci-dessous : + +[assembly: AssemblyVersion("1.0.*")] + +// +// Pour signer votre assembly, vous devez spécifier la clé à utiliser. Consultez +// la documentation Microsoft .NET Framework pour plus d'informations sur la signature d'un assembly. +// +// Utilisez les attributs ci-dessous pour contrôler la clé utilisée lors de la signature. +// +// Remarques : +// (*) Si aucune clé n'est spécifiée, l'assembly n'est pas signé. +// (*) KeyName fait référence à une clé installée dans le fournisseur de +// services cryptographiques (CSP) de votre ordinateur. KeyFile fait référence à un fichier qui contient +// une clé. +// (*) Si les valeurs de KeyFile et de KeyName sont spécifiées, le +// traitement suivant se produit : +// (1) Si KeyName se trouve dans le CSP, la clé est utilisée. +// (2) Si KeyName n'existe pas mais que KeyFile existe, la clé +// de KeyFile est installée dans le CSP et utilisée. +// (*) Pour créer KeyFile, vous pouvez utiliser l'utilitaire sn.exe (Strong Name, Nom fort). +// Lors de la spécification de KeyFile, son emplacement doit être +// relatif au répertoire de sortie du projet qui est +// %Project Directory%\obj\. Par exemple, si votre KeyFile se trouve +// dans le répertoire du projet, vous devez spécifier l'attribut +// AssemblyKeyFile sous la forme [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) DelaySign (signature différée) est une option avancée. Pour plus d'informations, consultez la +// documentation Microsoft .NET Framework. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/VMR9/BitmapMixer/BitmapGenerator.cs b/Samples/VMR9/BitmapMixer/BitmapGenerator.cs new file mode 100644 index 0000000..01f662b --- /dev/null +++ b/Samples/VMR9/BitmapMixer/BitmapGenerator.cs @@ -0,0 +1,128 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.Drawing.Text; + +namespace DirectShowLib.Sample +{ + public sealed class BitmapGenerator + { + public static Bitmap GenerateColorKeyBitmap(Color colorKey, bool useAntiAlias) + { + // Some drawing tools needed later + Pen blackBorder = new Pen(Color.Black, 2.0f); + Brush green = new SolidBrush(Color.Green); + Font font = new Font("Tahoma", 16); + Brush textColorKeyed = new SolidBrush(colorKey); + Brush textColor = new SolidBrush(Color.White); + + // Create a 256x256 RGB bitmap + Bitmap bmp = new Bitmap(256, 256, PixelFormat.Format24bppRgb); + Graphics g = Graphics.FromImage(bmp); + + // configure antialiased drawing or not + if (useAntiAlias) + { + g.SmoothingMode = SmoothingMode.AntiAlias; + g.TextRenderingHint = TextRenderingHint.AntiAlias; + } + else + { + g.SmoothingMode = SmoothingMode.None; + g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit; + } + + // Clear the bitmap with the color key + g.Clear(colorKey); + + // Draw a green circle with black border in the middle + g.FillEllipse(green, 50, 50, 155, 155); + g.DrawEllipse(blackBorder, 50, 50, 155, 155); + + // Draw some text in the cicle with the color key color + g.DrawString("Some text...", font, textColorKeyed, 70, 120); + + // Draw some text in white elsewhere in the bitmap + g.DrawString("Other text...", font, textColor, 10, 10); + g.DrawString("Text again...", font, textColor, 120, 220); + + // Release GDI+ objects + blackBorder.Dispose(); + green.Dispose(); + font.Dispose(); + textColor.Dispose(); + g.Dispose(); + + // return the bitmap + return bmp; + } + + public static Bitmap GenerateAlphaBitmap() + { + // Alpha values + int alpha25 = (int) (255 * 0.25f); // 25% opacity + int alpha50 = (int) (255 * 0.50f); // 50% opacity + int alpha75 = (int) (255 * 0.75f); // 75% opacity + int alpha100 = 255; // 100% opacity + + // Some drawing tools needed later + Pen blackBorder = new Pen(Color.Black, 2.0f); + Brush violet25 = new SolidBrush(Color.FromArgb(alpha25, Color.Violet)); + Brush red50 = new SolidBrush(Color.FromArgb(alpha50, Color.Red)); + Brush green75 = new SolidBrush(Color.FromArgb(alpha75, Color.Green)); + Brush blue100 = new SolidBrush(Color.FromArgb(alpha100, Color.Blue)); + Font font = new Font("Tahoma", 16); + Brush text100 = new SolidBrush(Color.FromArgb(255, Color.White)); + + // Create a 256x256 ARGB bitmap + Bitmap bmp = new Bitmap(256, 256, PixelFormat.Format32bppArgb); + Graphics g = Graphics.FromImage(bmp); + + // Do antialiased drawings + g.SmoothingMode = SmoothingMode.AntiAlias; + g.TextRenderingHint = TextRenderingHint.AntiAlias; + + // Clear the bitmap with complete transparency + g.Clear(Color.Transparent); + + // Draw serveral cicles with various Alpha values + g.FillEllipse(violet25, 9, 9, 110, 110); + g.DrawEllipse(blackBorder, 9, 9, 110, 110); + g.DrawString("25%", font, text100, 40, 50); + + g.FillEllipse(red50, 137, 9, 110, 110); + g.DrawEllipse(blackBorder, 137, 9, 110, 110); + g.DrawString("50%", font, text100, 170, 50); + + g.FillEllipse(green75, 9, 137, 110, 110); + g.DrawEllipse(blackBorder, 9, 137, 110, 110); + g.DrawString("75%", font, text100, 40, 180); + + g.FillEllipse(blue100, 137, 137, 110, 110); + g.DrawEllipse(blackBorder, 137, 137, 110, 110); + g.DrawString("100%", font, text100, 170, 180); + + // Release GDI+ objects + blackBorder.Dispose(); + violet25.Dispose(); + red50.Dispose(); + green75.Dispose(); + blue100.Dispose(); + font.Dispose(); + text100.Dispose(); + g.Dispose(); + + // return the bitmap + return bmp; + } + + } +} diff --git a/Samples/VMR9/BitmapMixer/BitmapMixer-2005.csproj b/Samples/VMR9/BitmapMixer/BitmapMixer-2005.csproj new file mode 100644 index 0000000..5a7c112 --- /dev/null +++ b/Samples/VMR9/BitmapMixer/BitmapMixer-2005.csproj @@ -0,0 +1,130 @@ + + + Local + 8.0.50727 + 2.0 + {4682D111-4503-448E-B5F4-93358502C229} + Debug + AnyCPU + App.ico + + + BitmapMixer + + + JScript + Grid + IE50 + false + WinExe + DirectShowLib.Sample + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\lib\DirectShowLib-2005.dll + + + + + System + + + System.Data + + + System.Drawing + + + System.Windows.Forms + + + System.XML + + + + + Form + + + Code + + + Code + + + Form + + + Code + + + AboutBox.cs + + + MainForm.cs + + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/VMR9/BitmapMixer/BitmapMixer-2005.sln b/Samples/VMR9/BitmapMixer/BitmapMixer-2005.sln new file mode 100644 index 0000000..1bfac2d --- /dev/null +++ b/Samples/VMR9/BitmapMixer/BitmapMixer-2005.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BitmapMixer-2005", "BitmapMixer-2005.csproj", "{4682D111-4503-448E-B5F4-93358502C229}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4682D111-4503-448E-B5F4-93358502C229}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/VMR9/BitmapMixer/BitmapMixer-2008.sln b/Samples/VMR9/BitmapMixer/BitmapMixer-2008.sln new file mode 100644 index 0000000..164e75e --- /dev/null +++ b/Samples/VMR9/BitmapMixer/BitmapMixer-2008.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BitmapMixer-2008", "BitmapMixer-2008.csproj", "{4682D111-4503-448E-B5F4-93358502C229}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4682D111-4503-448E-B5F4-93358502C229}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/VMR9/BitmapMixer/BitmapMixer.csproj b/Samples/VMR9/BitmapMixer/BitmapMixer.csproj new file mode 100644 index 0000000..3d4dba2 --- /dev/null +++ b/Samples/VMR9/BitmapMixer/BitmapMixer.csproj @@ -0,0 +1,162 @@ + + + + Local + 8.0.50727 + 2.0 + {4682D111-4503-448E-B5F4-93358502C229} + Debug + AnyCPU + App.ico + + + BitmapMixer + + + JScript + Grid + IE50 + false + WinExe + DirectShowLib.Sample + OnBuildSuccess + + + + + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + + + System + + + System.Data + + + System.Drawing + + + System.Windows.Forms + + + System.XML + + + + + Form + + + Code + + + Code + + + Form + + + Code + + + AboutBox.cs + + + MainForm.cs + + + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + + + + + + \ No newline at end of file diff --git a/Samples/VMR9/BitmapMixer/MainForm.cs b/Samples/VMR9/BitmapMixer/MainForm.cs new file mode 100644 index 0000000..434f9c1 --- /dev/null +++ b/Samples/VMR9/BitmapMixer/MainForm.cs @@ -0,0 +1,572 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Windows.Forms; +using System.Runtime.InteropServices; + +using DirectShowLib; + +using Microsoft.DirectX; +using Microsoft.DirectX.Direct3D; +using Microsoft.Win32; + +namespace DirectShowLib.Sample +{ + public class MainForm : System.Windows.Forms.Form + { + private System.Windows.Forms.MainMenu mainMenu; + private System.Windows.Forms.OpenFileDialog openFileDialog; + private System.Windows.Forms.MenuItem menuFile; + private System.Windows.Forms.MenuItem menuFileOpen; + private System.Windows.Forms.MenuItem menuFileClose; + private System.Windows.Forms.MenuItem menuItem1; + private System.Windows.Forms.MenuItem menuFileExit; + private System.Windows.Forms.MenuItem menuMixer; + private System.Windows.Forms.MenuItem menuHelp; + private System.Windows.Forms.MenuItem menuHelpAbout; + private System.Windows.Forms.MenuItem menuMixerEnable; + private System.Windows.Forms.MenuItem menuMixerGDI; + private System.Windows.Forms.MenuItem menuMixerD3D; + + private System.ComponentModel.Container components = null; + + private Color colorKey = Color.Violet; // The color use as ColorKey for GDI operations + private Bitmap colorKeyBitmap; // A RGB bitmap used for GDI operations. + private Bitmap alphaBitmap; // A ARGB bitmap used for Direct3D operations + + // Managed Direct3D magic number to retrieve unmanaged Direct3D interfaces + private const int DxMagicNumber = -759872593; + private Device device = null; // A Managed Direct3D device + private PresentParameters presentParams; + private Surface surface = null; // A Direct3D suface filled with alphaBitmap + private IntPtr unmanagedSurface; // A pointer on the unmanaged surface + + private IFilterGraph2 graphBuilder = null; + private IMediaControl mediaControl = null; + private IBaseFilter vmr9 = null; + private IVMRMixerBitmap9 mixerBitmap = null; + private IVMRWindowlessControl9 windowlessCtrl = null; + private bool handlersAdded = false; // Needed to remove delegates + + // Menus stuff + private bool mixerEnabled = true; + private bool usingGDI = true; + + public MainForm() + { + InitializeComponent(); + + // We paint the windows ourself + this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); + + // Get the colorkeyed bitmap without antialiasing + colorKeyBitmap = BitmapGenerator.GenerateColorKeyBitmap(colorKey, false); + // Get the bitmap with alpha transparency + alphaBitmap = BitmapGenerator.GenerateAlphaBitmap(); + + // Init Managed Direct3D + InitializeDirect3D(); + } + + /// + /// Nettoyage des ressources utilisées. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if (components != null) + { + components.Dispose(); + } + } + + // Clean-up DirectShow interfaces + CloseInterfaces(); + + // Dispose Managed Direct3D objects + surface.Dispose(); + device.Dispose(); + + base.Dispose( disposing ); + } + + #region Code généré par le Concepteur Windows Form + /// + /// Méthode requise pour la prise en charge du concepteur - ne modifiez pas + /// le contenu de cette méthode avec l'éditeur de code. + /// + private void InitializeComponent() + { + this.mainMenu = new System.Windows.Forms.MainMenu(); + this.menuFile = new System.Windows.Forms.MenuItem(); + this.menuFileOpen = new System.Windows.Forms.MenuItem(); + this.menuFileClose = new System.Windows.Forms.MenuItem(); + this.menuItem1 = new System.Windows.Forms.MenuItem(); + this.menuFileExit = new System.Windows.Forms.MenuItem(); + this.menuMixer = new System.Windows.Forms.MenuItem(); + this.menuMixerEnable = new System.Windows.Forms.MenuItem(); + this.menuMixerGDI = new System.Windows.Forms.MenuItem(); + this.menuMixerD3D = new System.Windows.Forms.MenuItem(); + this.menuHelp = new System.Windows.Forms.MenuItem(); + this.menuHelpAbout = new System.Windows.Forms.MenuItem(); + this.openFileDialog = new System.Windows.Forms.OpenFileDialog(); + // + // mainMenu + // + this.mainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuFile, + this.menuMixer, + this.menuHelp}); + // + // menuFile + // + this.menuFile.Index = 0; + this.menuFile.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuFileOpen, + this.menuFileClose, + this.menuItem1, + this.menuFileExit}); + this.menuFile.Text = "File"; + // + // menuFileOpen + // + this.menuFileOpen.Index = 0; + this.menuFileOpen.Text = "Open Clip..."; + this.menuFileOpen.Click += new System.EventHandler(this.menuFileOpen_Click); + // + // menuFileClose + // + this.menuFileClose.Index = 1; + this.menuFileClose.Text = "Close Clip"; + this.menuFileClose.Click += new System.EventHandler(this.menuFileClose_Click); + // + // menuItem1 + // + this.menuItem1.Index = 2; + this.menuItem1.Text = "-"; + // + // menuFileExit + // + this.menuFileExit.Index = 3; + this.menuFileExit.Text = "Exit"; + this.menuFileExit.Click += new System.EventHandler(this.menuFileExit_Click); + // + // menuMixer + // + this.menuMixer.Enabled = false; + this.menuMixer.Index = 1; + this.menuMixer.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuMixerEnable, + this.menuMixerGDI, + this.menuMixerD3D}); + this.menuMixer.Text = "Mixer"; + // + // menuMixerEnable + // + this.menuMixerEnable.Checked = true; + this.menuMixerEnable.Index = 0; + this.menuMixerEnable.Text = "Enable / Disable"; + this.menuMixerEnable.Click += new System.EventHandler(this.menuMixerEnable_Click); + // + // menuMixerGDI + // + this.menuMixerGDI.Checked = true; + this.menuMixerGDI.Index = 1; + this.menuMixerGDI.Text = "Using GDI"; + this.menuMixerGDI.Click += new System.EventHandler(this.menuMixerGDI_Click); + // + // menuMixerD3D + // + this.menuMixerD3D.Index = 2; + this.menuMixerD3D.Text = "Using Direct3D"; + this.menuMixerD3D.Click += new System.EventHandler(this.menuMixerD3D_Click); + // + // menuHelp + // + this.menuHelp.Index = 2; + this.menuHelp.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuHelpAbout}); + this.menuHelp.Text = "Help"; + // + // menuHelpAbout + // + this.menuHelpAbout.Index = 0; + this.menuHelpAbout.Text = "About Bitmap mixer..."; + this.menuHelpAbout.Click += new System.EventHandler(this.menuHelpAbout_Click); + // + // openFileDialog + // + this.openFileDialog.Filter = @"Video Files (*.avi; *.qt; *.mov; *.mpg; *.mpeg; *.m1v)|*.avi; *.qt; *.mov; *.mpg; *.mpeg; *.m1v|Audio files (*.wav; *.mpa; *.mp2; *.mp3; *.au; *.aif; *.aiff; *.snd)|*.wav; *.mpa; *.mp2; *.mp3; *.au; *.aif; *.aiff; *.snd|MIDI Files (*.mid, *.midi, *.rmi)|*.mid; *.midi; *.rmi|Image Files (*.jpg, *.bmp, *.gif, *.tga)|*.jpg; *.bmp; *.gif; *.tga|All Files (*.*)|*.*"; + // + // MainForm + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.BackColor = System.Drawing.Color.Black; + this.ClientSize = new System.Drawing.Size(640, 480); + this.Menu = this.mainMenu; + this.Name = "MainForm"; + this.Text = "Bitmap mixer"; + + } + #endregion + + private void InitializeDirect3D() + { + Device.IsUsingEventHandlers = false; + + // Basic Presentation Parameters... + presentParams = new PresentParameters(); + presentParams.Windowed = true; + presentParams.SwapEffect = SwapEffect.Discard; + + // Assume a hardware Direct3D device is available + // Add MultiThreaded to be safe. Each DirectShow filter runs in a separate thread... + device = new Device( + 0, + DeviceType.Hardware, + this, + CreateFlags.SoftwareVertexProcessing | CreateFlags.MultiThreaded, + presentParams + ); + + // Create a surface from our alpha bitmap + surface = new Surface(device, alphaBitmap, Pool.SystemMemory); + // Get the unmanaged pointer + unmanagedSurface = surface.GetObjectByValue(DxMagicNumber); + } + + private void CloseInterfaces() + { + if (mediaControl != null) + mediaControl.Stop(); + + if (handlersAdded) + RemoveHandlers(); + + if (vmr9 != null) + { + Marshal.ReleaseComObject(vmr9); + vmr9 = null; + windowlessCtrl = null; + mixerBitmap = null; + } + + if (graphBuilder != null) + { + Marshal.ReleaseComObject(graphBuilder); + graphBuilder = null; + mediaControl = null; + } + + menuMixer.Enabled = false; + } + + private void BuildGraph(string fileName) + { + int hr = 0; + + try + { + graphBuilder = (IFilterGraph2) new FilterGraph(); + mediaControl = (IMediaControl) graphBuilder; + + vmr9 = (IBaseFilter) new VideoMixingRenderer9(); + + ConfigureVMR9InWindowlessMode(); + + hr = graphBuilder.AddFilter(vmr9, "Video Mixing Renderer 9"); + DsError.ThrowExceptionForHR(hr); + + hr = graphBuilder.RenderFile(fileName, null); + DsError.ThrowExceptionForHR(hr); + + mixerBitmap = (IVMRMixerBitmap9) vmr9; + + menuMixer.Enabled = true; + mixerEnabled = true; + usingGDI = false; + UpdateMixerMenu(); + SetMixerSettings(); + } + catch(Exception e) + { + CloseInterfaces(); + MessageBox.Show("An error occured during the graph building : \r\n\r\n" + e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void ConfigureVMR9InWindowlessMode() + { + int hr = 0; + + IVMRFilterConfig9 filterConfig = (IVMRFilterConfig9) vmr9; + + // Not really needed for VMR9 but don't forget calling it with VMR7 + hr = filterConfig.SetNumberOfStreams(1); + DsError.ThrowExceptionForHR(hr); + + // Change VMR9 mode to Windowless + hr = filterConfig.SetRenderingMode(VMR9Mode.Windowless); + DsError.ThrowExceptionForHR(hr); + + windowlessCtrl = (IVMRWindowlessControl9) vmr9; + + // Set "Parent" window + hr = windowlessCtrl.SetVideoClippingWindow(this.Handle); + DsError.ThrowExceptionForHR(hr); + + // Set Aspect-Ratio + hr = windowlessCtrl.SetAspectRatioMode(VMR9AspectRatioMode.LetterBox); + DsError.ThrowExceptionForHR(hr); + + // Add delegates for Windowless operations + AddHandlers(); + + // Call the resize handler to configure the output size + MainForm_ResizeMove(null, null); + } + + private void SetMixerSettings() + { + int hr = 0; + VMR9AlphaBitmap alphaBmp; + + if (!mixerEnabled) // Did the user disable the bitmap ? + { + // Get current Alpha Bitmap Parameters + hr = mixerBitmap.GetAlphaBitmapParameters(out alphaBmp); + DsError.ThrowExceptionForHR(hr); + + // Disable them + alphaBmp.dwFlags = VMR9AlphaBitmapFlags.Disable; + + // Update the Alpha Bitmap Parameters + hr = mixerBitmap.UpdateAlphaBitmapParameters(ref alphaBmp); + DsError.ThrowExceptionForHR(hr); + + return; + } + + if (usingGDI) + { + // Old school GDI stuff... + Graphics g = Graphics.FromImage(colorKeyBitmap); + IntPtr hdc = g.GetHdc(); + IntPtr memDC = NativeMethodes.CreateCompatibleDC(hdc); + IntPtr hBitmap = colorKeyBitmap.GetHbitmap(); + NativeMethodes.SelectObject(memDC, hBitmap); + + // Set Alpha Bitmap Parameters for using a GDI DC + alphaBmp = new VMR9AlphaBitmap(); + alphaBmp.dwFlags = VMR9AlphaBitmapFlags.hDC | VMR9AlphaBitmapFlags.SrcColorKey | VMR9AlphaBitmapFlags.FilterMode; + alphaBmp.hdc = memDC; + alphaBmp.rSrc = new DsRect(0, 0, colorKeyBitmap.Size.Width, colorKeyBitmap.Size.Height); + alphaBmp.rDest = GetDestRectangle(); + alphaBmp.clrSrcKey = ColorTranslator.ToWin32(colorKey); + alphaBmp.dwFilterMode = VMRMixerPrefs.PointFiltering; + alphaBmp.fAlpha = 0.75f; + + // Set Alpha Bitmap Parameters + hr = mixerBitmap.SetAlphaBitmap(ref alphaBmp); + DsError.ThrowExceptionForHR(hr); + + // Release GDI handles + NativeMethodes.DeleteObject(hBitmap); + NativeMethodes.DeleteDC(memDC); + g.ReleaseHdc(hdc); + g.Dispose(); + } + else // Using a Direct3D surface + { + // Set Alpha Bitmap Parameters for using a Direct3D surface + alphaBmp = new VMR9AlphaBitmap(); + alphaBmp.dwFlags = VMR9AlphaBitmapFlags.EntireDDS; + alphaBmp.pDDS = unmanagedSurface; + alphaBmp.rDest = GetDestRectangle(); + alphaBmp.fAlpha = 1.0f; + // Note : Alpha values from the bitmap are cumulative with the fAlpha parameter. + // Example : texel alpha = 128 (50%) & fAlpha = 0.5f (50%) = effective alpha : 64 (25%) + + // Set Alpha Bitmap Parameters + hr = mixerBitmap.SetAlphaBitmap(ref alphaBmp); + DsError.ThrowExceptionForHR(hr); + } + } + + private NormalizedRect GetDestRectangle() + { + int hr = 0; + int width, height, arW, arH; + NormalizedRect rect = new NormalizedRect(); + + hr = windowlessCtrl.GetNativeVideoSize(out width, out height, out arW, out arH); + DsError.ThrowExceptionForHR(hr); + + // Position the bitmap in the middle of the video stream. + if (width >= height) + { + rect.top = 0.0f; + rect.left = (1.0f - ((float)height / (float)width)) / 2; + rect.bottom = 1.0f; + rect.right = rect.left + (float)height / (float)width; + } + else + { + rect.top = (1.0f - ((float)width / (float)height)) / 2; + rect.left = 0.0f; + rect.right = rect.top + (float)width / (float)height; + rect.bottom = 1.0f; + } + + return rect; + } + + private void UpdateMixerMenu() + { + // Just manage the Mixer menu... + menuMixerEnable.Checked = mixerEnabled; + + menuMixerGDI.Enabled = mixerEnabled; + menuMixerGDI.Checked = usingGDI; + menuMixerD3D.Enabled = mixerEnabled; + menuMixerD3D.Checked = !usingGDI; + } + + private void AddHandlers() + { + // Add handlers for VMR purpose + this.Paint += new PaintEventHandler(MainForm_Paint); // for WM_PAINT + this.Resize += new EventHandler(MainForm_ResizeMove); // for WM_SIZE + this.Move += new EventHandler(MainForm_ResizeMove); // for WM_MOVE + SystemEvents.DisplaySettingsChanged += new EventHandler(SystemEvents_DisplaySettingsChanged); // for WM_DISPLAYCHANGE + handlersAdded = true; + } + + private void RemoveHandlers() + { + // remove handlers when they are no more needed + handlersAdded = false; + this.Paint -= new PaintEventHandler(MainForm_Paint); + this.Resize -= new EventHandler(MainForm_ResizeMove); + this.Move -= new EventHandler(MainForm_ResizeMove); + SystemEvents.DisplaySettingsChanged -= new EventHandler(SystemEvents_DisplaySettingsChanged); + } + + private void RunGraph() + { + if (mediaControl != null) + { + int hr = mediaControl.Run(); + DsError.ThrowExceptionForHR(hr); + } + } + + private void StopGraph() + { + if (mediaControl != null) + { + int hr = mediaControl.Stop(); + DsError.ThrowExceptionForHR(hr); + } + } + + // Menus click handlers + private void menuFileOpen_Click(object sender, System.EventArgs e) + { + if (openFileDialog.ShowDialog() == DialogResult.OK) + { + CloseInterfaces(); + BuildGraph(openFileDialog.FileName); + RunGraph(); + } + } + + private void menuFileClose_Click(object sender, System.EventArgs e) + { + StopGraph(); + CloseInterfaces(); + this.Invalidate(); + } + + private void menuFileExit_Click(object sender, System.EventArgs e) + { + StopGraph(); + CloseInterfaces(); + this.Dispose(); + } + + private void MainForm_Paint(object sender, PaintEventArgs e) + { + if (windowlessCtrl != null) + { + IntPtr hdc = e.Graphics.GetHdc(); + int hr = windowlessCtrl.RepaintVideo(this.Handle, hdc); + e.Graphics.ReleaseHdc(hdc); + } + } + + private void MainForm_ResizeMove(object sender, EventArgs e) + { + if (windowlessCtrl != null) + { + int hr = windowlessCtrl.SetVideoPosition(null, DsRect.FromRectangle(this.ClientRectangle)); + } + } + + private void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e) + { + if (windowlessCtrl != null) + { + int hr = windowlessCtrl.DisplayModeChanged(); + } + } + + private void menuMixerEnable_Click(object sender, System.EventArgs e) + { + mixerEnabled = !mixerEnabled; + UpdateMixerMenu(); + SetMixerSettings(); + } + + private void menuMixerGDI_Click(object sender, System.EventArgs e) + { + usingGDI = true; + UpdateMixerMenu(); + SetMixerSettings(); + } + + private void menuMixerD3D_Click(object sender, System.EventArgs e) + { + usingGDI = false; + UpdateMixerMenu(); + SetMixerSettings(); + } + + private void menuHelpAbout_Click(object sender, System.EventArgs e) + { + string title = "About Bitmap mixer"; + string text = "DirectShow.Net VMR9 Bitmap mixer\r\nMake use of IVMRBitmapMixer9"; + + AboutBox.Show(title, text); + } + + [STAThread] + static void Main() + { + using (MainForm form = new MainForm()) + { + Application.Run(form); + } + } + + } +} diff --git a/Samples/VMR9/BitmapMixer/MainForm.resx b/Samples/VMR9/BitmapMixer/MainForm.resx new file mode 100644 index 0000000..ef00e70 --- /dev/null +++ b/Samples/VMR9/BitmapMixer/MainForm.resx @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Private + + + 17, 17 + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + 120, 17 + + + False + + + (Default) + + + False + + + False + + + 8, 8 + + + True + + + MainForm + + + 80 + + + True + + + Private + + \ No newline at end of file diff --git a/Samples/VMR9/BitmapMixer/NativeMethodes.cs b/Samples/VMR9/BitmapMixer/NativeMethodes.cs new file mode 100644 index 0000000..fc735c2 --- /dev/null +++ b/Samples/VMR9/BitmapMixer/NativeMethodes.cs @@ -0,0 +1,31 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Runtime.InteropServices; + +namespace DirectShowLib.Sample +{ + internal sealed class NativeMethodes + { + // Graphics.GetHdc() have several "bugs" detailed here : + // http://support.microsoft.com/default.aspx?scid=kb;en-us;311221 + // (see case 2) So we have to play with old school GDI... + [DllImport("gdi32.dll")] + public static extern IntPtr CreateCompatibleDC(IntPtr hdc); + + [DllImport("gdi32.dll")] + public static extern bool DeleteDC(IntPtr hdc); + + [DllImport("gdi32.dll")] + public static extern bool DeleteObject(IntPtr hObject); + + [DllImport("gdi32.dll")] + public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj); + + } +} diff --git a/Samples/VMR9/BitmapMixer/readme.txt b/Samples/VMR9/BitmapMixer/readme.txt new file mode 100644 index 0000000..db3d0db --- /dev/null +++ b/Samples/VMR9/BitmapMixer/readme.txt @@ -0,0 +1,30 @@ +--------------------------------------------------------------------- +BitmapMixer + +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + +--------------------------------------------------------------------- + +BitmapMixer is an example of how to draw things over a video using VMR9. + +This sample is mainly built around the IVMRMixerBitmap9 interface. This interface +accept bitmaps as a GDI Device Context or as a Direct3D Surface. The main advantage +of the Direct3D Surface is that it enables the use of true alpha transparency. GDI DC +don't support alpha bitmap and transparency is accomplished by using color keying. + +This sample dynamically generates bitmaps using GDI+. + +This sample uses the following DirectShow Interfaces : + + IFilterGraph2 + IMediaControl + IBaseFilter + IVMRWindowlessControl9 + IVMRFilterConfig9 + +This sample is not the translation of the DirectShow's BitmapMix sample. + +Managed DirectX must be installed to run this sample. \ No newline at end of file diff --git a/Samples/VMR9/VMR9Allocator/AboutBox.cs b/Samples/VMR9/VMR9Allocator/AboutBox.cs new file mode 100644 index 0000000..7517592 --- /dev/null +++ b/Samples/VMR9/VMR9Allocator/AboutBox.cs @@ -0,0 +1,163 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Reflection; +using System.Windows.Forms; + +using DirectShowLib; + +namespace DirectShowLib.Sample +{ + internal class AboutBoxWnd : Form + { + public System.Windows.Forms.Label label1; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.LinkLabel linkLabel1; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label4; + private System.ComponentModel.Container components = null; + + public AboutBoxWnd() + { + InitializeComponent(); + + Type t = typeof(IGraphBuilder); + label3.Text += t.Assembly.GetName().Version; + } + + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if(components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Code généré par le Concepteur Windows Form + /// + /// Méthode requise pour la prise en charge du concepteur - ne modifiez pas + /// le contenu de cette méthode avec l'éditeur de code. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.button1 = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.linkLabel1 = new System.Windows.Forms.LinkLabel(); + this.label3 = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // label1 + // + this.label1.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label1.Location = new System.Drawing.Point(8, 8); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(272, 40); + this.label1.TabIndex = 1; + // + // button1 + // + this.button1.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.button1.Location = new System.Drawing.Point(288, 8); + this.button1.Name = "button1"; + this.button1.TabIndex = 0; + this.button1.Text = "OK"; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // label2 + // + this.label2.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label2.Location = new System.Drawing.Point(8, 64); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(160, 16); + this.label2.TabIndex = 2; + this.label2.Text = "Library source code release under"; + // + // linkLabel1 + // + this.linkLabel1.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.linkLabel1.Location = new System.Drawing.Point(184, 64); + this.linkLabel1.Name = "linkLabel1"; + this.linkLabel1.Size = new System.Drawing.Size(160, 16); + this.linkLabel1.TabIndex = 3; + this.linkLabel1.TabStop = true; + this.linkLabel1.Text = "Lesser General Public License"; + this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked); + // + // label3 + // + this.label3.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label3.Location = new System.Drawing.Point(8, 48); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(320, 16); + this.label3.TabIndex = 4; + this.label3.Text = "DirectShowLib Version : "; + // + // label4 + // + this.label4.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label4.Location = new System.Drawing.Point(8, 80); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(264, 16); + this.label4.TabIndex = 5; + this.label4.Text = "Sample source code release under Public Domain"; + // + // AboutBoxWnd + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(372, 104); + this.Controls.Add(this.label4); + this.Controls.Add(this.label3); + this.Controls.Add(this.linkLabel1); + this.Controls.Add(this.label2); + this.Controls.Add(this.button1); + this.Controls.Add(this.label1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "AboutBoxWnd"; + this.ShowInTaskbar = false; + this.Text = "AboutBox"; + this.ResumeLayout(false); + + } + #endregion + + private void button1_Click(object sender, System.EventArgs e) + { + this.Close(); + } + + private void linkLabel1_LinkClicked(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e) + { + System.Diagnostics.Process.Start("http://www.gnu.org/copyleft/lesser.txt"); + } + } + + public class AboutBox + { + public static void Show(string title, string text) + { + using (AboutBoxWnd form = new AboutBoxWnd()) + { + form.Text = title; + form.label1.Text = text; + form.ShowDialog(); + } + } + } +} diff --git a/Samples/VMR9/VMR9Allocator/AboutBox.resx b/Samples/VMR9/VMR9Allocator/AboutBox.resx new file mode 100644 index 0000000..4b1c550 --- /dev/null +++ b/Samples/VMR9/VMR9Allocator/AboutBox.resx @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + Private + + + Public + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + Private + + + False + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + (Default) + + + False + + + False + + + 8, 8 + + + True + + + AboutBoxWnd + + + 80 + + + True + + + Private + + \ No newline at end of file diff --git a/Samples/VMR9/VMR9Allocator/Allocator.cs b/Samples/VMR9/VMR9Allocator/Allocator.cs new file mode 100644 index 0000000..b775139 --- /dev/null +++ b/Samples/VMR9/VMR9Allocator/Allocator.cs @@ -0,0 +1,452 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Collections; +using System.Drawing; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; + +using DirectShowLib; + +using Microsoft.DirectX; +using Microsoft.DirectX.Direct3D; + +namespace DirectShowLib.Sample +{ + [ComVisible(true)] + [ClassInterface(ClassInterfaceType.None)] + public class Allocator : IVMRSurfaceAllocator9, IVMRImagePresenter9, IDisposable + { + private const int E_FAIL = unchecked((int) 0x80004005); + private const int DxMagicNumber = -759872593; + + private Control parentControl; + + private PresentParameters presentParam; + private Device device = null; + private Surface renderTarget = null; + private AdapterInformation adapterInfo = null; + + private Hashtable textures = null; + private Hashtable surfaces = null; + private IntPtr[] unmanagedSurfaces = null; + private Texture privateTexture = null; + private Surface privateSurface = null; + + private IVMRSurfaceAllocatorNotify9 vmrSurfaceAllocatorNotify = null; + + private PlaneScene scene = null; + + public Allocator(Control control) + { + parentControl = control; + scene = new PlaneScene(); + + Device.IsUsingEventHandlers = false; + + CreateDevice(); + } + + ~Allocator() + { + Dispose(); + } + + private void CreateDevice() + { + adapterInfo = Manager.Adapters.Default; + + presentParam = new PresentParameters(); + presentParam.Windowed = true; + presentParam.PresentFlag = PresentFlag.Video; + presentParam.SwapEffect = SwapEffect.Copy; + presentParam.BackBufferFormat = adapterInfo.CurrentDisplayMode.Format; + + device = new Device( + 0, + DeviceType.Hardware, + parentControl, + CreateFlags.SoftwareVertexProcessing | CreateFlags.MultiThreaded, + presentParam + ); + + renderTarget = device.GetRenderTarget(0); + } + + private void DeleteSurfaces() + { + lock(this) + { + if (privateTexture != null) + { + privateTexture.Dispose(); + privateTexture = null; + } + + if (privateSurface != null) + { + privateSurface.Dispose(); + privateSurface = null; + } + + if (textures != null) + { + foreach (Texture tex in textures.Values) + { + tex.Dispose(); + } + textures = null; + } + + if (surfaces != null) + { + foreach (Surface surf in surfaces.Values) + { + surf.Dispose(); + } + surfaces = null; + } + } + } + + #region Membres de IVMRSurfaceAllocator9 + + public int InitializeDevice(IntPtr dwUserID, ref VMR9AllocationInfo lpAllocInfo, ref int lpNumBuffers) + { + int width = 1; + int height = 1; + float fTU = 1.0f; + float fTV = 1.0f; + + if (vmrSurfaceAllocatorNotify == null) + { + return E_FAIL; + } + + int hr = 0; + + try + { + IntPtr unmanagedDevice = device.GetObjectByValue(DxMagicNumber); + IntPtr hMonitor = Manager.GetAdapterMonitor(adapterInfo.Adapter); + + hr = vmrSurfaceAllocatorNotify.SetD3DDevice(unmanagedDevice, hMonitor); + DsError.ThrowExceptionForHR(hr); + + if (device.DeviceCaps.TextureCaps.SupportsPower2) + { + while (width < lpAllocInfo.dwWidth) + width = width << 1; + while (height < lpAllocInfo.dwHeight) + height = height << 1; + + fTU = (float)(lpAllocInfo.dwWidth) / (float)(width); + fTV = (float)(lpAllocInfo.dwHeight) / (float)(height); + scene.SetSrcRect(fTU, fTV); + + lpAllocInfo.dwWidth = width; + lpAllocInfo.dwHeight = height; + } + + // NOTE: + // we need to make sure that we create textures because + // surfaces can not be textured onto a primitive. + lpAllocInfo.dwFlags |= VMR9SurfaceAllocationFlags.TextureSurface; + + DeleteSurfaces(); + + unmanagedSurfaces = new IntPtr[lpNumBuffers]; + + hr = vmrSurfaceAllocatorNotify.AllocateSurfaceHelper(ref lpAllocInfo, ref lpNumBuffers, unmanagedSurfaces); + + // If we couldn't create a texture surface and + // the format is not an alpha format, + // then we probably cannot create a texture. + // So what we need to do is create a private texture + // and copy the decoded images onto it. + if (hr < 0) + { + DeleteSurfaces(); + + FourCC fcc = new FourCC("0000"); + + // is surface YUV ? + if (lpAllocInfo.Format > fcc.ToInt32()) + { + // create the private texture + privateTexture = new Texture( + device, + lpAllocInfo.dwWidth, + lpAllocInfo.dwHeight, + 1, + Usage.RenderTarget, + adapterInfo.CurrentDisplayMode.Format, + Pool.Default + ); + + privateSurface = privateTexture.GetSurfaceLevel(0); + } + + lpAllocInfo.dwFlags &= ~VMR9SurfaceAllocationFlags.TextureSurface; + lpAllocInfo.dwFlags |= VMR9SurfaceAllocationFlags.OffscreenSurface; + + unmanagedSurfaces = new IntPtr[lpNumBuffers]; + + hr = vmrSurfaceAllocatorNotify.AllocateSurfaceHelper(ref lpAllocInfo, ref lpNumBuffers, unmanagedSurfaces); + if (hr < 0) + return hr; + } + else + { + surfaces = new Hashtable(unmanagedSurfaces.Length); + textures = new Hashtable(unmanagedSurfaces.Length); + + for (int i = 0; i < lpNumBuffers; i++) + { + Surface surf = new Surface(unmanagedSurfaces[i]); + Texture text = (Texture) surf.GetContainer(new Guid("85C31227-3DE5-4f00-9B3A-F11AC38C18B5")); + surfaces.Add(unmanagedSurfaces[i], surf); + textures.Add(unmanagedSurfaces[i], text); + } + } + + return scene.Init(device); + } + catch(DirectXException e) + { + return e.ErrorCode; + } + catch + { + return E_FAIL; + } + } + + public int TerminateDevice(IntPtr dwID) + { + DeleteSurfaces(); + return 0; + } + + public int GetSurface(IntPtr dwUserID, int SurfaceIndex, int SurfaceFlags, out IntPtr lplpSurface) + { + lplpSurface = IntPtr.Zero; + + if (SurfaceIndex > unmanagedSurfaces.Length) + return E_FAIL; + + lock(this) + { + lplpSurface = unmanagedSurfaces[SurfaceIndex]; + Marshal.AddRef(lplpSurface); + return 0; + } + } + + public int AdviseNotify(IVMRSurfaceAllocatorNotify9 lpIVMRSurfAllocNotify) + { + lock(this) + { + vmrSurfaceAllocatorNotify = lpIVMRSurfAllocNotify; + + IntPtr unmanagedDevice = device.GetObjectByValue(DxMagicNumber); + IntPtr hMonitor = Manager.GetAdapterMonitor(Manager.Adapters.Default.Adapter); + + return vmrSurfaceAllocatorNotify.SetD3DDevice(unmanagedDevice, hMonitor); + } + } + + #endregion + + #region Membres de IVMRImagePresenter9 + + public int StartPresenting(IntPtr dwUserID) + { + lock(this) + { + if (device == null) + return E_FAIL; + + return 0; + } + } + + public int StopPresenting(IntPtr dwUserID) + { + return 0; + } + + public int PresentImage(IntPtr dwUserID, ref VMR9PresentationInfo lpPresInfo) + { + int hr = 0; + + lock(this) + { + try + { + // if we are in the middle of the display change + if(NeedToHandleDisplayChange()) + { + // NOTE: this piece of code is left as a user exercise. + // The D3DDevice here needs to be switched + // to the device that is using another adapter + } + + hr = PresentHelper(lpPresInfo); + + return hr; + } + catch (DirectXException e) + { + return e.ErrorCode; + } + catch + { + return E_FAIL; + } + } + } + + private int PresentHelper(VMR9PresentationInfo lpPresInfo) + { + int hr = 0; + + try + { + device.SetRenderTarget(0, renderTarget); + + if (privateTexture != null) + { + Marshal.AddRef(lpPresInfo.lpSurf); + using(Surface surface = new Surface(lpPresInfo.lpSurf)) + { + device.StretchRectangle( + surface, + new Rectangle(0, 0, surface.Description.Width, surface.Description.Height), + privateSurface, + new Rectangle(0, 0, privateSurface.Description.Width, privateSurface.Description.Height), + TextureFilter.None + ); + } + + hr = scene.DrawScene(device, privateTexture); + if (hr < 0) + return hr; + } + else + { + if (textures.ContainsKey(lpPresInfo.lpSurf)) + { + hr = scene.DrawScene(device, textures[lpPresInfo.lpSurf] as Texture); + if (hr < 0) + return hr; + } + else + hr = E_FAIL; + } + + device.Present(); + return 0; + } + catch (DirectXException e) + { + return e.ErrorCode; + } + catch + { + return E_FAIL; + } + } + + private bool NeedToHandleDisplayChange() + { + if (vmrSurfaceAllocatorNotify == null) + return false; + + IntPtr currentMonitor = Manager.GetAdapterMonitor(device.CreationParameters.AdapterOrdinal); + IntPtr defaultMonitor = Manager.GetAdapterMonitor(adapterInfo.Adapter); + + return currentMonitor != defaultMonitor; + } + + #endregion + + #region Membres de IDisposable + + public void Dispose() + { + DeleteSurfaces(); + scene.Dispose(); + device.Dispose(); + } + + #endregion + + } + + public class FourCC + { + private int fourCC = 0; + + public FourCC(string fcc) + { + if (fcc.Length != 4) + throw new ArgumentException(fcc + " is not a valid FourCC"); + + byte[] asc = Encoding.ASCII.GetBytes(fcc); + + this.fourCC = asc[0]; + this.fourCC |= asc[1] << 8; + this.fourCC |= asc[2] << 16; + this.fourCC |= asc[3] << 24; + } + + public FourCC(char a, char b, char c, char d) : this(new string(new char[] {a, b, c, d})) + {} + + public FourCC(int fcc) + { + this.fourCC = fcc; + } + + public int ToInt32() + { + return this.fourCC; + } + + public Guid ToMediaSubtype() + { + return new Guid(this.fourCC.ToString("X") + "-0000-0010-8000-00AA00389B71"); + } + + public static bool operator ==(FourCC fcc1, FourCC fcc2) + { + return fcc1.fourCC == fcc2.fourCC; + } + + public static bool operator !=(FourCC fcc1, FourCC fcc2) + { + return fcc1.fourCC != fcc2.fourCC; + } + + public override bool Equals(object obj) + { + if (!(obj is FourCC)) + return false; + + return (obj as FourCC).fourCC == this.fourCC; + } + + public override int GetHashCode() + { + return this.fourCC.GetHashCode(); + } + } +} diff --git a/Samples/VMR9/VMR9Allocator/AssemblyInfo.cs b/Samples/VMR9/VMR9Allocator/AssemblyInfo.cs new file mode 100644 index 0000000..76201ae --- /dev/null +++ b/Samples/VMR9/VMR9Allocator/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// Les informations générales relatives à un assembly dépendent de +// l'ensemble d'attributs suivant. Pour modifier les informations +// associées à un assembly, changez les valeurs de ces attributs. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Les informations de version pour un assembly se composent des quatre valeurs suivantes : +// +// Version principale +// Version secondaire +// Numéro de build +// Révision +// +// Vous pouvez spécifier toutes les valeurs ou indiquer des numéros de révision et de build par défaut +// en utilisant '*', comme ci-dessous : + +[assembly: AssemblyVersion("1.0.*")] + +// +// Pour signer votre assembly, vous devez spécifier la clé à utiliser. Consultez +// la documentation Microsoft .NET Framework pour plus d'informations sur la signature d'un assembly. +// +// Utilisez les attributs ci-dessous pour contrôler la clé utilisée lors de la signature. +// +// Remarques : +// (*) Si aucune clé n'est spécifiée, l'assembly n'est pas signé. +// (*) KeyName fait référence à une clé installée dans le fournisseur de +// services cryptographiques (CSP) de votre ordinateur. KeyFile fait référence à un fichier qui contient +// une clé. +// (*) Si les valeurs de KeyFile et de KeyName sont spécifiées, le +// traitement suivant se produit : +// (1) Si KeyName se trouve dans le CSP, la clé est utilisée. +// (2) Si KeyName n'existe pas mais que KeyFile existe, la clé +// de KeyFile est installée dans le CSP et utilisée. +// (*) Pour créer KeyFile, vous pouvez utiliser l'utilitaire sn.exe (Strong Name, Nom fort). +// Lors de la spécification de KeyFile, son emplacement doit être +// relatif au répertoire de sortie du projet qui est +// %Project Directory%\obj\. Par exemple, si votre KeyFile se trouve +// dans le répertoire du projet, vous devez spécifier l'attribut +// AssemblyKeyFile sous la forme [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) DelaySign (signature différée) est une option avancée. Pour plus d'informations, consultez la +// documentation Microsoft .NET Framework. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/VMR9/VMR9Allocator/MainForm.cs b/Samples/VMR9/VMR9Allocator/MainForm.cs new file mode 100644 index 0000000..e47f2fb --- /dev/null +++ b/Samples/VMR9/VMR9Allocator/MainForm.cs @@ -0,0 +1,321 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Windows.Forms; +using System.Data; +using System.Runtime.InteropServices; + +using DirectShowLib; + +namespace DirectShowLib.Sample +{ + public class MainForm : System.Windows.Forms.Form + { + private System.Windows.Forms.MenuItem menuItem5; + private System.Windows.Forms.MainMenu mainMenu; + private System.Windows.Forms.MenuItem menuFile; + private System.Windows.Forms.MenuItem menuFilePlayFile; + private System.Windows.Forms.MenuItem menuFileCloseFile; + private System.Windows.Forms.MenuItem menuFileExit; + private System.Windows.Forms.MenuItem menuHelp; + private System.Windows.Forms.MenuItem menuHelpAbout; + + private System.Windows.Forms.OpenFileDialog openFileDialog; + + private System.ComponentModel.Container components = null; + + private IGraphBuilder graph = null; + private IBaseFilter filter = null; + private IMediaControl mediaControl = null; + private Allocator allocator = null; + + private IntPtr userId = new IntPtr(unchecked((int)0xACDCACDC)); + + public MainForm() + { + InitializeComponent(); + } + + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if (components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Code généré par le Concepteur Windows Form + /// + /// Méthode requise pour la prise en charge du concepteur - ne modifiez pas + /// le contenu de cette méthode avec l'éditeur de code. + /// + private void InitializeComponent() + { + System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(MainForm)); + this.openFileDialog = new System.Windows.Forms.OpenFileDialog(); + this.mainMenu = new System.Windows.Forms.MainMenu(); + this.menuFile = new System.Windows.Forms.MenuItem(); + this.menuFilePlayFile = new System.Windows.Forms.MenuItem(); + this.menuFileCloseFile = new System.Windows.Forms.MenuItem(); + this.menuItem5 = new System.Windows.Forms.MenuItem(); + this.menuFileExit = new System.Windows.Forms.MenuItem(); + this.menuHelp = new System.Windows.Forms.MenuItem(); + this.menuHelpAbout = new System.Windows.Forms.MenuItem(); + // + // openFileDialog + // + this.openFileDialog.Filter = "Video Files (.ASF, .AVI, .MPG, .MPEG, .VOB, .QT, .WMV)|*.ASF;*.AVI;*.MPG;*.MPEG;*" + + ".VOB;*.QT;*.WMV|All Files (*.*)|*.*"; + this.openFileDialog.Title = "Select a video file to play..."; + // + // mainMenu + // + this.mainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuFile, + this.menuHelp}); + // + // menuFile + // + this.menuFile.Index = 0; + this.menuFile.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuFilePlayFile, + this.menuFileCloseFile, + this.menuItem5, + this.menuFileExit}); + this.menuFile.Text = "&File"; + // + // menuFilePlayFile + // + this.menuFilePlayFile.Index = 0; + this.menuFilePlayFile.Text = "&Play File..."; + this.menuFilePlayFile.Click += new System.EventHandler(this.menuFilePlayFile_Click); + // + // menuFileCloseFile + // + this.menuFileCloseFile.Index = 1; + this.menuFileCloseFile.Text = "&Close File"; + this.menuFileCloseFile.Click += new System.EventHandler(this.menuFileCloseFile_Click); + // + // menuItem5 + // + this.menuItem5.Index = 2; + this.menuItem5.Text = "-"; + // + // menuFileExit + // + this.menuFileExit.Index = 3; + this.menuFileExit.Text = "E&xit"; + this.menuFileExit.Click += new System.EventHandler(this.menuFileExit_Click); + // + // menuHelp + // + this.menuHelp.Index = 1; + this.menuHelp.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuHelpAbout}); + this.menuHelp.Text = "&Help"; + // + // menuHelpAbout + // + this.menuHelpAbout.Index = 0; + this.menuHelpAbout.Text = "&About VMR9Allocator.."; + this.menuHelpAbout.Click += new System.EventHandler(this.menuHelpAbout_Click); + // + // MainForm + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.BackColor = System.Drawing.Color.White; + this.ClientSize = new System.Drawing.Size(592, 466); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Menu = this.mainMenu; + this.Name = "MainForm"; + this.Text = "Plug-in Allocator-Presenter for VMR 9"; + this.Closing += new System.ComponentModel.CancelEventHandler(this.MainForm_Closing); + + } + #endregion + + [STAThread] + static void Main() + { + using(MainForm form1 = new MainForm()) + { + Application.Run(form1); + } + } + + private string GetMoviePath() + { + if (openFileDialog.ShowDialog(this) == DialogResult.OK) + { + return openFileDialog.FileName; + } + else + return string.Empty; + } + + private void CloseGraph() + { + FilterState state; + + if (mediaControl != null) + { + do + { + mediaControl.Stop(); + mediaControl.GetState(0, out state); + } while (state != FilterState.Stopped); + + mediaControl = null; + } + + if (allocator != null) + { + allocator.Dispose(); + allocator = null; + } + + if (filter != null) + { + Marshal.ReleaseComObject(filter); + filter = null; + } + + + if (graph != null) + { + RemoveAllFilters(); + + Marshal.ReleaseComObject(graph); + graph = null; + } + } + + public void RemoveAllFilters() + { + int hr = 0; + IEnumFilters enumFilters; + ArrayList filtersArray = new ArrayList(); + + hr = graph.EnumFilters(out enumFilters); + DsError.ThrowExceptionForHR(hr); + + IBaseFilter[] filters = new IBaseFilter[1]; + + while(enumFilters.Next(filters.Length, filters, IntPtr.Zero) == 0) + { + filtersArray.Add(filters[0]); + } + + foreach(IBaseFilter filter in filtersArray) + { + hr = graph.RemoveFilter(filter); + while (Marshal.ReleaseComObject(filter) > 0); + } + } + + private void StartGraph() + { + int hr = 0; + + CloseGraph(); + + string path = GetMoviePath(); + if (path == string.Empty) + return; + + try + { + graph = (IGraphBuilder) new FilterGraph(); + filter = (IBaseFilter) new VideoMixingRenderer9(); + + IVMRFilterConfig9 filterConfig = (IVMRFilterConfig9) filter; + + hr = filterConfig.SetRenderingMode(VMR9Mode.Renderless); + DsError.ThrowExceptionForHR(hr); + + hr = filterConfig.SetNumberOfStreams(2); + DsError.ThrowExceptionForHR(hr); + + SetAllocatorPresenter(); + + hr = graph.AddFilter(filter, "Video Mixing Renderer 9"); + DsError.ThrowExceptionForHR(hr); + + hr = graph.RenderFile(path, null); + DsError.ThrowExceptionForHR(hr); + + mediaControl = (IMediaControl) graph; + + hr = mediaControl.Run(); + DsError.ThrowExceptionForHR(hr); + } + catch + { + } + } + + private void SetAllocatorPresenter() + { + int hr = 0; + + IVMRSurfaceAllocatorNotify9 vmrSurfAllocNotify = (IVMRSurfaceAllocatorNotify9) filter; + + try + { + allocator = new Allocator(this); + + hr = vmrSurfAllocNotify.AdviseSurfaceAllocator(userId, allocator); + DsError.ThrowExceptionForHR(hr); + + hr = allocator.AdviseNotify(vmrSurfAllocNotify); + DsError.ThrowExceptionForHR(hr); + } + catch + { + allocator = null; + throw; + } + } + + private void menuFilePlayFile_Click(object sender, System.EventArgs e) + { + StartGraph(); + } + + private void menuFileCloseFile_Click(object sender, System.EventArgs e) + { + CloseGraph(); + this.Invalidate(); + } + + private void menuFileExit_Click(object sender, System.EventArgs e) + { + this.Close(); + } + + private void menuHelpAbout_Click(object sender, System.EventArgs e) + { + string title = "About VMR9 Allocator Sample"; + string text = "DirectShow.Net VMR9 Allocator Sample"; + + AboutBox.Show(title, text); + } + + private void MainForm_Closing(object sender, System.ComponentModel.CancelEventArgs e) + { + CloseGraph(); + } + } +} diff --git a/Samples/VMR9/VMR9Allocator/MainForm.resx b/Samples/VMR9/VMR9Allocator/MainForm.resx new file mode 100644 index 0000000..abd5f06 --- /dev/null +++ b/Samples/VMR9/VMR9Allocator/MainForm.resx @@ -0,0 +1,615 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Private + + + Private + + + 17, 17 + + + Private + + + 147, 17 + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + Private + + + False + + + MainForm + + + (Default) + + + False + + + False + + + 8, 8 + + + True + + + 80 + + + True + + + Private + + + + AAABAAkAMDAQAAAAAABoBgAAlgAAACAgEAAAAAAA6AIAAP4GAAAQEBAAAAAAACgBAADmCQAAMDAAAAEA + CACoDgAADgsAACAgAAABAAgAqAgAALYZAAAQEAAAAQAIAGgFAABeIgAAMDAAAAEAIACoJQAAxicAACAg + AAABACAAqBAAAG5NAAAQEAAAAQAgAGgEAAAWXgAAKAAAADAAAABgAAAAAQAEAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAIAAAICAAIAAAACAAIAAgIAAAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAAAA + AAD//wAA////AACAAADMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM + zMzMzMzMzMzMzMy2t7a2bMzMzMzMzMzMzMzMzMzMzMzMu7a3tnd2d2ZszMzMzMzMzMzMzMzMzMy7t7tr + a2dnZmZmbMzMzMzMzMzMzMzMzLu7e2tnZnZmZmZmZmzMzMzMzMzMzMzMy7u3u7e2tmdmZmZmZmbMzMzM + zMzMzMzMt7e7u3tra2Z2ZmZmZmZszMzMzMzMzMzLu7u7u7u7d7Z2ZmZmZmZmzMzMzMzMzMx7O7u7s3N7 + trd2tmZmZuZmbMzMzMzMzMu7u7uzNye7e2trZmd3ZmZmZszMzMzMzLO7u7MzqmZ3t7Z3ZrdyZmbmZmzM + zMzMy7u7s7MKqqZre2t2t3AqpmZmZmbMzMzMx7OzuzIqqqpnt7a3ZzIqamZm5mbMzMzMO7u7syKqqqpm + e3trYzKqqmZmZmZszMzMu7OzMiqqqqpqe7a2syKqqmpmZmZszMzLszszIiqqqqqmd7t7cCqqqqamZmZm + zMzHu7swAiKqqqqqZ3u3MCqqqqpqZmZmzMzLMzMzACIqKqqqZ7t7Aqqqqqqqd2ZmzMzLO7szMAIiqqqq + anszIqqqqqoid2ZmzMxzszOzMwAiIqqqpmMyKqqqqqIie2ZnbMy7O7OzszAAIiqqqqd6qqqqoiIzd2Zm + bMw3szs7OzMwAiKqqqqqqqqqIDN3tmZ2bMy7M7OzuzszACKqqqqqqqoiA3trZrZmvMxzOzOzs7O7MAIq + qqqqqqcjN7a3t2ZnfMw7M7Ozs7s7MwIqqqqqqqoje3t3a3d2fMx7OzM7O7O7MzAqqqqqqqpnt7e7trZ3 + fMy3MzOzuzuzswKqqqqqqqqme7tra2dnfMx7M7M7M7O7MwKqqqqqqqpqZ7u7u7a2vMx3szszs7OzMqqq + qqqqqqqmpnu7t7tnfMzLczM7OzswKqqqqqoqKqqqpme7u7e7zMzHOzOzMzMCqqqqqqIiKqqqpqZ7u7e2 + zMzLc7MzMzKqqqqqqiIAIiqqqmpnu7t7zMzMtzMzMCKqqqqqqgMwACIqqqqne7e8zMzMN7MzAiqqqqqq + ojMzACIqqqqnO3u8zMzMxzszACKqqqqqIDszMwIiqqIjO7vMzMzMy3MzAAIiqqqqA7O7MwAiIqIDu3vM + zMzMzHtzMwAioqqiM7s7szMCIiAzu7zMzMzMzMe3MwAiKqojM7O7O7MAIgO7u8zMzMzMzMx7MzAAIqID + O7OzuzMwAzO7vMzMzMzMzMzHdzMAAiIzszuzs7MzM7t7zMzMzMzMzMzMtzcwACMzOzM7OzuzM3u8zMzM + zMzMzMzMx7s3MDMzs7Ozs7Ozu7vMzMzMzMzMzMzMzHdzMzOzMzs7Ozs7t7zMzMzMzMzMzMzMzMy3d7cz + s7M7O3u3vMzMzMzMzMzMzMzMzMzMt3t7e3t7e7e8zMzMzMzMzMzMzMzMzMzMzMe3t7e3t8zMzMzMzMzM + zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz///////8AAP///////wAA///AH///AAD//AAB//8AAP/w + AAB//wAA/8AAAB//AAD/gAAAD/8AAP8AAAAH/wAA/gAAAAP/AAD8AAAAAf8AAPgAAAAA/wAA8AAAAAB/ + AADgAAAAAD8AAOAAAAAAPwAAwAAAAAAfAADAAAAAAB8AAIAAAAAADwAAgAAAAAAPAACAAAAAAA8AAIAA + AAAADwAAAAAAAAAHAAAAAAAAAAcAAAAAAAAABwAAAAAAAAAHAAAAAAAAAAcAAAAAAAAABwAAAAAAAAAH + AAAAAAAAAAcAAAAAAAAABwAAAAAAAAAHAACAAAAAAA8AAIAAAAAADwAAgAAAAAAPAADAAAAAAB8AAMAA + AAAAHwAA4AAAAAA/AADgAAAAAD8AAPAAAAAAfwAA+AAAAAD/AAD8AAAAAf8AAP4AAAAD/wAA/wAAAAf/ + AAD/gAAAD/8AAP/AAAAf/wAA//AAAH//AAD//AAB//8AAP//gA///wAA////////AAAoAAAAIAAAAEAA + AAABAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgIAAgAAAAIAAgACAgAAAwMDAAICA + gAAAAP8AAP8AAAD//wD/AAAAAAAAAP//AAD///8AAIAAAMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM + zMzMzMzMzMzMzMzLe2tmbMzMzMzMzMzMzMy3dnZ2ZmZmzMzMzMzMzMzHu7t3ZmZmZmzMzMzMzMzHu7u7 + t7a2ZmZmbMzMzMzMu7uzd3trZmZ2ZmbMzMzMy7uzMqZ7tnd3dmZmbMzMzMuzMCqma2t2cKpmZmzMzMy7 + MyKqqqe2tzKqpmZmzMzLszIqqqpmu3cKqqamZmzMyzMCIqqqpndzKqqqZmZszMszACIqqqprMKqqqqp2 + bMxzszACIiqqpzKqqqoidmbMOzszACIqqqqqqqqiA3ZmzLs7MzAAIqqqqqqiA3dmZsxzM7MzMAKqqqqq + I3trdmfMu7M7OzMAqqqqqqO3trdmzHMzs7MzAqqqqqqqe3t3a8x7OzszMqqqqqqqpme7trbMtzMzMCqq + qqqiqqqmZ7trzMtzMwKqqqqiAiKqqqZ7fMzHszAqqqqqoAAiqqqiu7zMw3MwIiqqqiMwAiqqI7e8zMy3 + MAIiqqIzMwIiIjO7zMzMx3MAIiogM7MAIiM7vMzMzMNzcAIiIzszMAIDu7zMzMzMdzMwIgM7OzMzO3vM + zMzMzMt3MwMzs7OzM7u8zMzMzMzMx3c3Mzs7O7e8zMzMzMzMzMw3e3t7e7e7zMzMzMzMzMzMzMN7e3t8 + zMzMzMzM////////////4B///wAD//4AAf/4AAB/8AAAP+AAAB/gAAAfwAAAD4AAAAeAAAAHgAAABwAA + AAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADgAAAB4AAAAeAAAAHwAAAD+AAAB/gAAAf8AAAP/gA + AH/+AAH//wAD///gH/8oAAAAEAAAACAAAAABAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + gAAAgIAAgAAAAIAAgACAgAAAwMDAAICAgAAAAP8AAP8AAAD//wD/AAAAAAAAAP//AAD///8AAIAAAMzM + zMzMzMzMzMzLZmbMzMzMy7e2ZmbMzMyzB3dndmzMyzKqe3CmZszDCqpnMqpmzLMyqqcKqqZsOzAqqqqi + dmwzszCqqie2bDMzMqqqZ7tsMzAqqqqme7zDAqqiAqqrzMcyqqMwojvMzHMqCzAjvMzMxzIzMzvMzMzM + xze7zMzM//+zMPg/a2vgD6pmwAfMzIADMyKAA6e2AAGqpgABzMwAATIqAAFmuwABqqaAA2zMgAMCIsAH + pnfgD6qq+D9szCgAAAAwAAAAYAAAAAEACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADWAAAA0QAAAM4A + AADNAAAAywAAAMgAAADGAAAAxQAAAMIAAADBAAAAvgAAALwAAAC6AAAAtwAAALUAAACzAAAAsAAAAK0A + AACpAAAApgAAAJwAAABzAAAAZwAAADwAAACiAQEAkgEBAN0CAgDAAgIAvQICAH0BAQBWAQEAzgMDAMMD + AwC/AwMAsAMDALQEBACGAwMA5wYGACUBAQDTBgYAxQYGAKQFBQDXBwcAuQcHAMAICABIAwMAMgICALQI + CACtCAgAoQcHAMcKCgD5Dg4AvgsLAOEODgDMDAwAmgoKANIPDwDFEREArQ8PAPoXFwDpFxcApBERANwY + GADJGRkA/iEhALcYGAD0IyMA1B4eAOQiIgBjDw8A7SUlABoEBAD9KioAlxkZAAwCAgClHR0A9SwsADMJ + CQDXJycAuSIiAMYoKAD+NDQAiRwcAPQ0NADnNDQA2jIyAP47OwCqKSkA9j09AP5CQgD+RkYA9ENDAP9J + SQC6NjYAyzw8AGYfHwA1EBAA/05OAPhNTQDlR0cA/1FRAKg3NwD/VVUAu0BAAEkZGQCKMDAA/1paAPZX + VwD2WloA/15eAMhLSwC3RUUA/2FhAG4qKgC/TEwA/2ZmALFHRwDoX18A9mZmALVLSwD/bGwAtk5OAMxZ + WQDmZWUAr01NAKBHRwD/cnIAt1JSADMXFwD2c3MA/3h4ACkUFAD/fX0A/4GBAOl3dwD/hoYA+oODAPaG + hgD/jY0AqF1dAGY5OQD/k5MA5oaGAMVzcwD/mZkA8JOTAP+engD/oqIA+6GhAKNpaQCEVVUA/6amAMuF + hQD/rKwA8KamAP+ysgD0q6sA/7a2APuzswD/ubkA+bW1AP++vgDgqakA/8LCAP/FxQD/yckA6Lm5AP/O + zgCOc3MA/M3NAOzCwgDDq6sAMy0tAAD+/gAA/f0AAPv7AAD5+QAA9/cAAPT0AADx8QAA7+8AAO3tAADp + 6QAA5uYAAOTkAADg4AAA398AANraAADT0wAAyckAAI6OAAB9fQABzs4AAcbGAAHCwgABuroAAbS0AAGt + rQABpKQAAZubAAGHhwAC+fkAAvf3AAF1dQAD//8AA/v7AAX19QAG//8ABubmAAJSUgAJ//8ADP//AAnA + wAAIj48ABmhoAAMxMQAQ8/MAEf7+AAqBgQAGSUkAFv7+AA+qqgAW6+sADH5+AAQoKAAWysoAHf7+ABzX + 1wAo/v4AJujoADT//wAt19cAMuLiADf29gA7/v4ABhgYAEf9/QBU/v4AUPDwAD2wsAAYREQAFj09ABAs + LABO1NQAZPDwAGr29gB29fUAPHx8AC9dXQBarq4Ac93dAIC+vgBDYmIAltTUAIeYmAAAAAAA//////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////XGRqcHh+hIeK//// + //////////////////////////////////////////9ISFZaZGpzfoKEh4qNjZCSk/////////////// + ////////////////////////QEBIVlxmc36Eh4qNkJKSk5eXl5mZ//////////////////////////// + /////0xCSEhRWWFteIKHipCSk5mZm5ubm5ubm5v/////////////////////////////QkJMTFFRVllk + anN+hIqNkpmbnaGhoaGfn52d//////////////////////////9GRkxMTEhASFNYWmRteIKHjZKXm6Gj + pKSko6Gfn////////////////////////0ZGRkJCOzszPENVU1lhanN+hYqQl5uho6WlpaSjoZ////// + ////////////////REREPDwzMzMqPWllVVZcZnB4goeKkJecoqaqqaelpKGf//////////////////9E + Pjw8NSUlJRAe/PmoXlhaZG1zfoSHipGYqKirpqmnpaShn////////////////04+PjUlJSUBJKzU5e77 + lWNZYWpzeIKFiY+W+O/7q6qpp6WjoZ3/////////////TkM+NRoaGgQV8MCx4uz0+3JbYWZweH6Ehous + 397u/auqqaeloZ+b////////////Qz44KhoaBB3xw7Kt3Obt+otjWmRqc3iBeozww8rq9f2rqqmnpJ+b + //////////9OQzgnAAAEJPDCtLCt2eTs9P5uW1xkanN7fYDHubDk7fb9q6qppaGdm/////////9DPzYf + AgsW8MS6s7Ct0uLm7fqVY1lcZmx6cfLDtq/c5u32/auqpKOdmf///////1A/OSgHEhbxvsO8t7KuzNnk + 7PT+blhZXGNlgMu8tK/S4urt9v2rpqGfmZf//////1A/MigMGRfr1sfEwLizr8/i5u37i1RRWF5f8cK3 + sq6t0+Lm7PT7q6afmZP//////1A/LBsNGR5H68vHxcG7tbDT5Oz0/mdMVFdg1ru0sK6urrDO3uj5/qKg + mZL//////085LBsKESQeR+vWvsbDvLax2ebt+n1QT0Xww7WxsLCytLe7wd33qKKemZL/////UE9BKxwJ + Cg8ZHiZK27/HxMC3sOLq7v5pX/C9tbGwsbO3u8HH1vGMj5qbmZKN////UE9BKwwKCAcLFBUXSuDWvsXA + ts3k6vPv7+Gyrq+wsrfAxcjxgIyLjpSZl5CK////UE9BIw0LCQcFBxAkHiZK277Eu7PT5OTk4tnPra2v + tsDI8oBxfXqGiI2Tk42H////XU86Ig8NCggFAgIHExUXStHHvbev09zc2dPSz9LQxNaDX2VudXZ+goeQ + ko2E////XU86IhAODAoHBAEAAQ0dLkrLw7myrdLT0s/S09nh+GhpXmNrbXBzeISKkIqC////XU86EREP + DQsIBQIBAAARFibXxrmyrq3MzMzP2eLn92leW1xhZGZqbX6Fiod+////Z1c6EhIRDwwKBwQBAAAEGRfg + xrexrq2tra3P2eLp85ZeWFlZWlxcZHCCh4V4////b109KRMREA4MCQYDAQADGS7WwLOwra2trq2t0+Lm + 7vuLVFFRVlZWWWZ4hYJz////b11LMRMTERANCwgFAgIOHtvBtbGvra6vsbGwrtnk7PX7ckhISEhRUVpw + fnhw////b2dXPSkTEhEPDQoICRIX38CzsK+urrCztri3tLDc5u31+15AQEBASFZmc3Bw/////29XPTEY + ExIRDw0OGWDFt7Kvrq2tsLO6vcK9u7ax3Obt9ftvOzM7O1Fcamb//////29lSz0UGBMSERgW8MKzr6+t + ra2usrvG1svHw8C4sdzm7fX6lTwzM0hWYWT//////29vVz0xFBQUHS3WvLKvrq2tra2xt8bxSuvRyMW9 + uLHc5uzt+qhDM0BRWWT///////93ZUs3GR0eg9bBt7Kvra2tra+zvfEXLSZK28jFvbix2eTq7vlpPkhR + Vv////////90b1dJJB4m0cfCu7Wwra2trrG61S0UFBUuStvIxb24ssnY4/dSPkxWWv//////////d2VX + Uh4m4L/Gwru1sK2usLXFYBIEBREVF0rRyMW9urfA2i06PExW////////////dHdlSUUuSuC/xsK7tbCw + tL3xGQUBAQMQHRdK277FwcLfTRk+RlNi/////////////3d0ZVJFLkrgy8bCu7W0u9YWCgQCAQEDDh0X + StG+x9ZNJDg8TFj///////////////95dGVSRS5K17/Gwru7xhcTCQcFBAMBAw4VLuvW1k0kNjxGU/// + ////////////////f3RlUkUuSte/xsPF8R0OCwoIBwUEAwUTFi5HTR0yPkRU//////////////////// + /393ZVJFTUrXy77bHhMPDQwKCQgHBQQJFBUWJDQ+RFT///////////////////////9/eWVpX2BH8tsX + GRIRDw4NCwoJBwYFITA6OUNEVP//////////////////////////eXl0aXFoYC0dGBMSERAPDQwLCiAo + Mjk/Q05V/////////////////////////////3d/fH1pcVJLPTowMDAvLys0NDk/P05OVVX///////// + ////////////////////////d398dGVlV1dPQUFBQU9PUFBQUFVV//////////////////////////// + //////////90eX95b2dnZ11dXV5eXl5eXv////////////////////////////////////////////9v + cnJycnJubm5eXv////////////////////////////////////////////////////////////////// + ////////////////////////////////AAD///////8AAP//wB///wAA//wAAf//AAD/8AAAf/8AAP/A + AAAf/wAA/4AAAA//AAD/AAAAB/8AAP4AAAAD/wAA/AAAAAH/AAD4AAAAAP8AAPAAAAAAfwAA4AAAAAA/ + AADgAAAAAD8AAMAAAAAAHwAAwAAAAAAfAACAAAAAAA8AAIAAAAAADwAAgAAAAAAPAACAAAAAAA8AAAAA + AAAABwAAAAAAAAAHAAAAAAAAAAcAAAAAAAAABwAAAAAAAAAHAAAAAAAAAAcAAAAAAAAABwAAAAAAAAAH + AAAAAAAAAAcAAAAAAAAABwAAgAAAAAAPAACAAAAAAA8AAIAAAAAADwAAwAAAAAAfAADAAAAAAB8AAOAA + AAAAPwAA4AAAAAA/AADwAAAAAH8AAPgAAAAA/wAA/AAAAAH/AAD+AAAAA/8AAP8AAAAH/wAA/4AAAA// + AAD/wAAAH/8AAP/wAAB//wAA//wAAf//AAD//4AP//8AAP///////wAAKAAAACAAAABAAAAAAQAIAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAC9AAAAuwAAALkAAAC2AAAAswAAALEAAAClAAAAowAAAKEA + AACcAAAAkQAAAG0AAABpAAAAZAAAAF0AAABYAAAANgAAADAAAAAqAAAAIgAAABMAAAAHAAAAhgEBAL8C + AgC8AgIAqAICAKECAgBPAQEAQgEBALsDAwCyAwMArQMDAH0CAgC3BAQAiwMDALMFBQC8BwcA3AkJAKUH + BwBVBAQAzgsLALwKCgCqCQkAOwMDAOgNDQAPAQEAXQcHAJcMDACgDg4AvBISAPkaGgDNFhYAWwoKAOcb + GwC2FhYA2hwcAKsXFwDDGxsAuxwcALUbGwDKICAA8ycnAJMZGQBFDAwA0yYmAOUtLQC2JCQA/TQ0APAy + MgDGLCwA+Do6AKwoKAD/PDwA1TMzAP8+PgDpOjoA/0REAPBAQADIOTkAwDc3AP9KSgC3NTUATRcXANdC + QgD/T08A+E1NAM1AQAAqDQ0A5khIACYMDADxTU0Avj09AKw5OQCVMTEA/1VVAMFCQgC6QUEAsT4+AP9b + WwDISUkAvkZGALFCQgBpJycAzU1NAAgDAwD/YmIANBQUAOhcXAD/ZmYAu0tLAPhnZwD/a2sAs0xMALxR + UQD/cnIAkUFBAHk2NgCkS0sA/3Z2AJtISAC2VVUAzmNjAP98fADodXUASyYmAP+EhAD2gYEAqFlZABYM + DAD/jIwAm1hYAGc7OwD+k5MAqmNjANJ9fQD/mpoA/56eAP+iogD/qKgA/6qqAN6WlgD/ra0A+6qqAP+w + sABzUVEA/7i4AOurqwD/u7sA/729APK3twCFZWUA/8PDAL6RkQD/ysoA16urAPXExAD3ysoAwqamAMyx + sQAhHR0AKScnAB0cHAAA//8AAP39AAD7+wAA+PgAAPb2AAD19QAA8/MAAPHxAADv7wAA7e0AAOrqAADm + 5gAA5OQAAOPjAADh4QAA398AAN3dAADY2AAA19cAAM3NAADLywAAx8cAAMPDAADBwQAAtbUAALCwAACt + rQAAqakAAKamAACjowAAlZUAAJKSAABmZgAAZGQAAY2NAAGCggACvLwAA/7+AAPs7AADwsIAApycAAT8 + /AAEtLQABK6uAAJcXAAEl5cAB/n5AAf09AAG2NgABaKiAASRkQADbGwACPX1AAR4eAAJ/v4ADv//AAZm + ZgAQ+voACpycABT//wALiooAFfT0ABz9/QAe6OgAI/39AAk6OgAs/f0ALu7uACKurgAz/f0AHo+PADz8 + /AA86+sAPNXVAEn9/QBG7+8AInBwAFL+/gA2oaEAVPX1AF/9/QAECgoAYOTkAFzT0wBr8fEAaM7OAGO8 + vABx1dUAgN7eAHzIyACQ5eUAfpeXAAAAAAD///////////////////////////////////////////// + //////////////////////////////////////////////////////9janB3foKFiP////////////// + /////////////0lJUWNzfoWIiouMjI6Q//////////////////////9ERERJUWNwe4KJjpKUlZSS//// + //////////////9FPj4zMzZKTlVqc36IjJSYmpiVlP//////////////QjY2LSkwdf5XTV9te4KFjZmb + nJqYlP///////////0I2LSYfHOfr9YBOX213f4eR8fienZqYlP//////////OCYZIWvH3Ojz/GhVanN8 + g6HT6vufnZqV/////////zgpGx3ftqrZ5fD3hltjb3p91a3j8/2fnZiS//////9BNCAc1ry3r6bh6vP8 + aF9sdKK3q9rq8/2fnJKQ/////z0yIxPPwby3rqbj7feDWWR90LCqpOHq8vuelo7/////PSoXERbDwr24 + sajl8PliXqK0rKmoqcni7P6bjP///0Y6KgkNExbExb+6s9Lo7pF9yqioqa2zts3pl5OMif//RjolBAoO + ExbPxsC5sNzl5uLZo6WpsLrGoISHj4uF//9GOyIDBAoMERX02Lu0qdrh3trZzK7Uon10en+JioL//1A8 + JAQCAwcXDxMWxbWrpNna2t7g71NeaGxvd4KIfv//XEMgBgQBAAMJDRTktaqlo8jZ3uPsdVRWX19qe4V3 + //9lQysgBgMBAAkQgb2tqKamqKjR4er2dk5LTVVwfnP//2VSORogBgYLHd20q6emp6ywsq7S5fD6gFdF + SWNzbf//YWE5JwcHIRLOrKempaars7rHuLLX6PD3/GZFUWpj////bkgxFxBay7OrpqSkqLDL5Ma/urHR + 5e3y+UZLVf////9uYj8o5MW8tq+opaaruIEUFtbAuK+o4OLxQ0RL/////2JxXlMu1sG8tq+pqa/fEA0T + 9Ma+uLS01DU4RE3//////3F2Z1gWw8G8t7Kx1B0ICA8Vz8K+u9UdMj5H/////////3l4Z1hpw8G9usdY + CwACFxEWw8LYLCs2Rf//////////Ynl4Z1hpw8LA2A4FAAAHDBMu5CwnOEVO////////////Znl4Z2uB + z9sRCwQBAAIKDBwvMThCTP//////////////Znl2dX1rQCEaHyIZGB4rMTxBQkz///////////////// + /3GAeHReSDw3NzI6Oj1GSkr//////////////////////11xeXJuZWBcT1dXV0pK//////////////// + ////////////XGVlZGRkV0//////////////////////////////4B///wAD//4AAf/4AAB/8AAAP+AA + AB/gAAAfwAAAD4AAAAeAAAAHgAAABwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADgAAAB4AA + AAeAAAAHwAAAD+AAAB/gAAAf8AAAP/gAAH/+AAH//wAD///gH/8oAAAAEAAAACAAAAABAAgAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAvAAAALsAAAC6AAAAsgAAALEAAACwAAAArQAAAKcAAACfAAAAkwAAAH4A + AABtAAAAPAAAAKgEBAChBQUAYAMDADsCAgBVBAQAOwMDAKIMDAC0Dg4Avg8PANEWFgBoCwsA5xoaALsV + FQDFGBgAsxYWADwICACoFxcAgBISAPYuLgDfKSkA4y0tAJwfHwCyJCQAzy0tAOAxMQDzNzcA8zk5APA5 + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgAJGRkYLISEhHxwcHEB+FxeKtB4exd8o + KOr/ODj//0VF//9QUP//W1v//2Zm//9wcP//eHj//39///+Ghv//jIz//5GR//+Wlv//mZn/2YaG7aNo + aNJZOjquAAAAfwAAAF8AAAA7AAAAGwAAAAgAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8BZmZmBT09PRUwMDA1jB4eiMQa + Gs/0Hh75/ysr//86Ov//SEj//1ZW//9lZf//cXH//319//+Ghv//jo7//5OT//+Zmf//nZ3//6Cg//+k + pP//pqb//6en//+oqP/0oqL5tHl53F9BQbMAAAB9AAAAVgAAAC0AAAAQAAAAAwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////Af///wGSkpIHSkpKH3Qp + KV66Hx++6yEh9fsmJv/9Li7//zU1//9DQ///T0///11d//9tbf//enr//4aG//+Pj///l5f//56e//+k + pP//qqr//66u//+wsP//s7P//7Oz//+zs///s7P//7Oz/+6np/ahcXHUNCYmngICAmwAAAA8AAAAFwAA + AAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wH///8B////AoCA + gAhEREQimyQkhNAgINz0JSX/9y0t//kvL//8MjL//zQ0//86Ov//RET//1BQ//9aWv//aGj//3R0//9/ + f///ior//5aW//+goP//qqr//7Ky//+3t///vLz//76+//++vv//vb3//7u7//+5uf//t7f/y5GR52VJ + SbcCAgJ5BAQERwAAABoAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wH///8DqqqqCU5OTiSsJSWW3CIi7O8lJf/yKir/9Ssr//cqKv/7KCj//iUl//0nJ//4MTH/9zk5//1F + Rf//UVH//19f//9ra///eHj//4WF//+Skv//np7//6mp//+zs///vLz//8LC///Fxf//xsb//8XF///C + wv//vr7//7u7/+KkpPKAXFzDAgICgAAAAEoAAAAaAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////Af///wOzs7MKWlpaIrAkJJrfISHz7CUl/+4kJP/wIiL/9B4e//YaGv/5FRX/+BER/+sS + Ev/WICD/3C0t//Q1Nf/+QkL//05O//9bW///Z2f//3V1//+Bgf//jY3//5ub//+mpv//srL//7y8//7D + w//9yMj//svL///Kyv//x8f//8LC//++vv/ura33iGNjxwQEBIAAAABGAAAAFwAAAAMAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8B////A9XV1QZsbGwariYmkNseHvPnISH/6SAg/+saGv/tFRX/8Q8P//UM + DP/xCQn/1QcH/6EPD/+KLS3/qzk5/983N//7PT3//0lJ//9WVv//YmL//2xs//94eP//hIT//4+P//+a + mv/9paX/9Kur/+Wrq//js7P/7sLC//vMzP/+zs7//8nJ///ExP//v7//7q2t94FeXsMCAgJ5AAAAPAAA + ABAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAD///8C////Bo6OjhKoLCxz0iAg6uIbG//kGhr/5hUV/+gP + D//sCQn/7QQE/+MEBP+vAQH/WAcH/0NiYv9anJz/iG5u/8dAQP/1PT3//0ZG//9SUv//Xl7//2ho//9z + c///fHz//4aG//2QkP/wk5P/y4WF/5Rqav+QgYH/u56e/+a+vv/7zs7//8/P///Ly///xMT//76+/+Ol + pfJnSkq3AgICbAAAAC0AAAAIAAAAAAAAAAAAAAAAAAAAAP///wH///8Ev7+/DJg8PEPGISHU3Rsb/98V + Ff/hDg7/4wkJ/+YFBf/kAwP/0AEB/4MBAf8qNTX/CcDA/ybo6P9L6ur/ccDA/6NkZP/hQkL//END//9P + T///Wlr//2Rk//9ubv//eXn//4KC//aGhv/Penr/f09P/zdXV/8/u7v/esXF/7mqqv/pwcH//M7O///P + z///ysr//8PD//+9vf/LkpLnNicnngMDA1cAAAAbAAAAAwAAAAAAAAAAAAAAAP///wL///8HgICAFrch + IajZHR3/2hYW/9sNDf/dBgb/4AIC/98CAv/LAQH/cAAA/x5AQP8Dzc3/APf3/x7///9C/f3/Y/Hx/4S5 + uf/DTk7/9END//5MTP//VVX//2Bg//9qav//c3P//Hx8/+d6ev+eWVn/PCQk/w9/f/8X5ub/VvLy/4vZ + 2f/CsLD/68PD//zOzv//zs7//8jI///AwP//uLj/oXJy1AYGBn8AAAA7AAAACwAAAAAAAAAAAAAAAP// + /wTMzMwKqykpYc0eHvHVFhb/1g4O/9gGBv/aAgL/3AAA/8sAAP9+AAD/GkBA/wO8vP8A8/P/AP7+/xb/ + //81////Vf///3Lh4f+oXl7/5kRE//xGRv//UFD//1pa//9kZP//bW3/9nNz/8lmZv9kNjb/EUdH/wK5 + uf8C9/f/Ov7+/2v39/+X1NT/xrCw/+zDw//9zs7//8zM///Fxf//u7v/7qio92NGRrQDAwNgAAAAHgAA + AAIAAAAAAAAAAP///wZxcXESuyEht9EaGv/RERH/0wYG/9QBAf/XAQH/ywAA/4kAAP8YRkb/AsPD/wDv + 7/8A+fn/AP7+/xD///8o////Rv///2Px8f+JmZn/x01N//RDQ///Skr//1NT//9cXP/8ZWX/5mVl/5tJ + Sf8vGBj/A5ub/wHh4f8A+fn/Jf///0////91+Pj/mdXV/8awsP/swsL//MvL///IyP//v7///7W1/7d+ + ft0GBgaBAAAAOgAAAAoAAAAAAAAAAP///weqJiZVyR0d9MwVFf/ODAz/zgMD/84AAP+7AAD/awAA/xdD + Q/8CsrL/AN/f/wDw8P8A+fn/AP7+/wn///8c////Nv///1X9/f9y39//o2pq/+NDQ//8Q0P//0tL//9U + VP/2Wlr/y1JS/2cuLv8TKyv/ALy8/wDp6f8A+vr/FP///zX///9X////efPz/5vW1v/JsLD/7sLC//zH + x///wcH//7a2//SmpvldPz+vAwMDVwAAABYAAAAAAAAAALOzswq3IyOfyhwc/8kREf/JBwf/xQEB/6kA + AP9hAAD/Ez4+/wKNjf8AuLj/ANHR/wDm5v8A9PT/APz8/wL///8R////KP///0X///9j8vL/ipWV/8xH + R//2PDz//0FB//1JSf/pTEz/oTo6/zQVFf8FeHj/ANbW/wDv7/8A+/v/CP///x////84////V////3X1 + 9f+Zzs7/x6ys/+u9vf/8wMD//ri4//+srP+mbW3TBwcHcQYGBikAAAADAAAAAIVHRxm9ISHaxhkZ/8UM + DP/EBQX/ugAA/40AAP9BAAD/DB0d/wFqav8AnJz/ALa2/wDPz/8A4+P/APLy/wD7+/8G////G////zb/ + //9V+fn/dsLC/6lcXP/kOzv//Tc3//c+Pv/MOTn/aCEh/xI9Pf8Bv7//AObm/wD09P8A/Pz/Af///w3/ + //8a/v7/L/39/0n5+f9o7u7/j8TE/8Ojo//tt7f//Li4//+urv/bjIztFxISiwQEBD4AAAAKAAAAAKgk + JFXFIyP/wxcX/8EJCf/AAgL/twAA/5QAAP9UAAD/GgAA/wMfH/8AcnL/AJaW/wCvr/8Ax8f/ANzc/wDs + 7P8A+Pj/C/7+/yb///9G/f3/Ze3t/4WoqP/DQUH/7i8v/+cwMP+hJyf/OA8P/wZubv8A29v/AO/v/wD4 + +P8A/Pz/AP39/wD8/P8A+fn/BfX1/xXv7/8y4uL/XLq6/5qTk//drKz/+bW1//+trf//n5//ZD8/sQYG + BlEAAAASAAAAALIlJYnCISH/vhQU/74HB/+/AgL/vgAA/60AAP+FAAD/TwAA/xsAAP8DFxf/AGdn/wCM + jP8Apqb/AL29/wDT0/8A6Oj/APf3/xP+/v8z////Uv39/23c3P+eTk7/xyws/7YjI/9dEhL/E0RE/wG4 + uP8A7e3/APb2/wD5+f8A+fn/APX1/wDv7/8A5ub/ANra/wPGxv8Pqqr/N319/41sbP/epKT/+7Oz//+s + rP//np7/mFtbygoKCmIAAAAZAAAAALcoKLG/ISH/uxMT/7sHB/+9AgL/wAAA/78AAP+yAAD/jwAA/1sA + AP8nAAD/CAIC/wFHR/8Afn7/AJub/wC0tP8Az8//AObm/wD5+f8d/v7/Pf///1X09P9wjo7/gjs7/2Qg + IP8gSkr/AsvL/wDt7f8A9/f/APj4/wD39/8A8fH/AOfn/wDZ2f8Ax8f/AZub/whfX/8fOjr/Xjw8/7h5 + ef/wpqb//rGx//+qqv//nZ3/vG1t3RAQEG8AAAAgAAAAALcpKdG8IiL/uRMT/7gGBv+5AQH/vgAA/8MA + AP/EAAD/uwAA/54AAP9uAAD/PAAA/xIAAP8CKyv/AGVl/wCPj/8Ar6//AM/P/wDp6f8D+/v/Jf7+/z39 + /f9I3d3/R7Cw/zGmpv8Sy8v/APX1/wD8/P8A+/v/APn5/wDz8/8A5+f/ANDQ/wCtrf8DhIT/Ej09/zYb + G/9vODj/smFh/+aGhv/7oaH//6ur//+np///mpr/13Z26w8PD3gAAAAlAAAAALksLOe6IyP/thIS/7QE + BP+2AQH/uwAA/8AAAP/FAAD/yQAA/8UAAP+xAAD/iQAA/1cAAP8pAAD/CgAA/wFHR/8Ajo7/ALa2/wDY + 2P8A8PD/DP39/yP///8u/f3/LPj4/yD4+P8R/f3/Bf///wD///8A////APv7/wDq6v8AzMz/BISE/xIt + Lf8xFRX/ZCsr/55HR//MX1//63Nz//qDg///lpb//6Oj//+jo///lpb/63t79RQUFIAGBgYpAAAAALsx + Mfe3IiL/shAQ/7EDA/+zAQH/uAAA/70AAP/CAAD/yAAA/84AAP/OAAD/xAAA/6YAAP91AAD/OQAA/wwA + AP8BUVH/AJub/wDIyP8A5+f/APr6/w3///8Y////Gf///xP///8N////CP///wf///8I////Bubm/wKx + sf8MYWH/KxUV/2IiIv+bOjr/yU9P/+hfX//2Zmb//HBw//94eP//iYn//5mZ//+dnf//kpL/+Hx8+xUV + FYQGBgYrAAAAALs0NP60IiL/rw4O/64DA/+wAAD/tQAA/7oAAP+/AAD/xQAA/8sAAP/RAAD/1QAA/9IA + AP+2AAD/egAA/zEAAP8HDAz/AHd3/wC6uv8A4OD/APX1/wD///8J////C////wr///8H////CP///w3/ + //8T/f3/GsnJ/yZiYv9KGRn/iSgo/8Y+Pv/nTU3/9ldX//xdXf//YGD//2Rk//9tbf//fX3//46O//+X + l///jIz//nh4/xgYGIEGBgYpAAAAALo4OPezJSX/rA8P/6sCAv+tAAD/sgAA/7cAAP+8AAD/wgAA/8gA + AP/OAAD/0wAA/9gAAP/UAAD/rgAA/2gAAP8fAAD/AzU1/wChof8A4OD/APT0/wD9/f8B////A////wP/ + //8E////B////xD///8d/f3/LdfX/0h9ff+FMDD/zTc3//NDQ//9S0v//09P//9SUv//VVX//1hY//9e + Xv//cHD//4OD//+QkP//hob/+G5u/BkZGXsHBwcmAAAAALg+PuizKyv/qhIS/6gCAv+qAAD/rgAA/7MA + AP+5AAD/vgAA/8QAAP/KAAD/0AAA/9YAAP/aAAD/ygAA/5MAAP86AAD/CCUl/wCgoP8A5eX/APb2/wD9 + /f8A////AP///wD///8B////Bv///xD///8h////N/b2/1PKyv+IWlr/zz4+//k9Pf//QED//0ND//9G + Rv//SEj//0pK//9QUP//YmL//3h4//+IiP//gID/7GJi9RsbG3IICAghAAAAALZBQdOzMDD/qRUV/6UE + BP+nAQH/qwAA/7AAAP+1AAD/ugAA/8AAAP/GAAD/zAAA/9IAAP/XAAD/zQAA/5UAAP8xAAD/BWpq/wDM + zP8A8PD/APn5/wD+/v8A/v7/AP///wD9/f8A/v7/Af7+/wv///8d////N////1Ly8v9zvr7/qVtb/+g6 + Ov//NDT//zc3//86Ov//Ozv//z4+//9CQv//VVX//2tr//+AgP//eHj/3FdX6R4eHmcKCgoaAAAAALRD + Q7S0ODj/qhwc/6QICP+lAgL/pwAA/6wAAP+xAAD/tgAA/7wAAP/CAAD/yAAA/84AAP/OAAD/tAAA/1EA + AP8PTEz/AcfH/wDt7f8A9/f/APv7/wD+/v8A/f3/APv7/wD39/8A9vb/APj4/wD8/P8R/v7/Kv///0f9 + /f9k9fX/hL+//71PT//6Kir//yoq//8rK///Li7//zAw//82Nv//R0f//2Ji//91df//bm7/xUxM2iMj + I1gAAAASAAAAALFBQYq2QED/rCcn/6QPD/+jBQX/pAAA/6gAAP+tAAD/sgAA/7cAAP+9AAD/wgAA/8EA + AP+oAAD/QQAA/wx/f/8B0ND/APHx/wD4+P8A+/v/AP39/wD9/f8A+Pj/APHx/wDp6f8A5OT/AObm/wDu + 7v8A+fn/FP7+/zH///9P////bPX1/4y6uv/OQED/+x4e//8dHf//Hx///yIi//8oKP//PDz//1VV//9m + Zv//YGD/qkJCwykpKUUAAAAKAAAAALE9PU+3R0f/rS8v/6MVFf+hCAj/oQEB/6QAAP+pAAD/rQAA/7MA + AP+3AAD/tQAA/44AAP8wDw//Bqys/wDn5/8A9fX/APr6/wD8/P8A/v7/AP7+/wD5+f8A8PD/AN/f/wDL + y/8Aw8P/AMjI/wDX1/8A6Oj/APf3/xb9/f80////Uv///2719f+Ltrb/vkZG//UVFf//EBD//xUV//8b + G///MTH//0hI//9bW///Vlb/iDw8nzU1NTBAQEAEAAAAALEzMwqzRUXZsDo6/6YfH/+gDQ3/ngEB/6EA + AP+kAAD/qQAA/6sAAP+iAAD/agAA/xtDQ/8DwsL/APDw/wD6+v8A+/v/AP7+/wD+/v8A/v7/APz8/wD0 + 9P8A29v/AaWl/wFtbf8Ac3P/AJ6e/wC3t/8Azs7/AOTk/wD39/8W/v7/Nf///1H///9p9/f/f9jY/6Rt + bf/qERH//wcH//8REf//Jyf//z4+//9OTv/jSUntSzw8ak1NTR7///8B////AQAAAACwQkKbtEVF/6kq + Kv+hFBT/nQUF/5wAAP+dAAD/mAAA/4AAAP9DAAD/D2pq/wHR0f8A8/P/APv7/wD9/f8A/v7/AP///wD/ + //8A/v7/APf3/wDl5f8CoqL/Cj8//xAFBf8HERH/AVBQ/wCHh/8Ara3/AMrK/wDk5P8A9/f/Fv7+/zH/ + //9L////Xv39/27f3/+LfHz/0Rwc//oPD///IiL//zU1//9BQf+/Pz/MRkZGSWlpaRH///8B////AQAA + AACuPT1LtktL8602Nv+kHx//mgoK/5EBAf9+AAD/UgAA/yYSEv8Jb2//AcbG/wDn5/8A9fX/APv7/wD+ + /v8A////AP///wD+/v8A+/v/APHx/wHJyf8TQUH/PAAA/0oAAP8qAAD/CgEB/wFISP8AiIj/AKur/wDI + yP8A5OT/APb2/xD9/f8n/v7/Ofv7/0bv7/9XtbX/kDQ0/94aGv/6KSn//Tc3//U4OPmVQUGWXV1dLL+/ + vwgAAAAAAAAAAAAAAAAAAAAAsUZGr7JDQ/+nLS3/mxQU/4IGBv9bAQH/JQIC/wdRUf8BmJj/AMHB/wDZ + 2f8A7Oz/APj4/wD+/v8A////AP///wD9/f8A9vb/AN/f/wiPj/9MAAD/lwAA/5sAAP9wAAD/NAAA/wsA + AP8BR0f/AImJ/wCrq/8AyMj/AOTk/wD09P8C+fn/EPPz/xzX1/81e3v/iRkZ/9wbG//3Kyv/+zg4/8w5 + OdVYWFhRi4uLFv///wQAAAAAAAAAAAAAAAAAAAAArT4+UrNLS+6uPT3/nyUl/4MQEP9VBgb/IQEB/wUh + If8Aenr/AKWl/wDCwv8A29v/AO3t/wD4+P8A/v7/AP39/wD5+f8A6+v/BKqq/zMREf+pAAD/ywAA/8gA + AP+sAAD/dwAA/zcAAP8KAAD/AVFR/wCIiP8ArKz/AMnJ/wDf3/8A5ub/Ac7O/wqBgf9JBwf/sA8P/+kd + Hf/3Ly//7TY29p9CQpR0dHQus7OzCv///wMAAAAAAAAAAAAAAAAAAAAAAAAAAK9FRZu0Skr/qDY2/5Ie + Hv9sDg7/NgMD/w8AAP8CKir/AH19/wClpf8AwsL/ANzc/wDt7f8A+Pj/APn5/wDv7/8Bycn/HTs7/5UA + AP/JAAD/0gAA/9MAAP/MAAD/sQAA/3oAAP86AAD/DAAA/wFKSv8AjIz/AK+v/wDFxf8AwcH/CHx8/zUJ + Cf+SBgb/2RMT//AlJf/1MzP/wjw8xGtra0WmpqYX////BP///wEAAAAAAAAAAAAAAAAAAAAAAAAAAKo5 + OSiwSUnKsUhI/6UzM/+MHh7/YwwM/zMEBP8PAQH/Aisr/wB1df8ApaX/AMLC/wDb2/8A6+v/AO7u/wDa + 2v8Oamr/ZgAA/74AAP/LAAD/zgAA/9AAAP/RAAD/zQAA/7QAAP99AAD/PQAA/wsAAP8AWVn/AJCQ/wCe + nv8Ia2v/MwkJ/4kDA//QDQ3/6hwc//AsLP/UODjgjlJSa5WVlSTo6OgL////Av///wEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACtPz9ZtE9P47FHR/+kMzP/ihwc/2MODv8yBQX/DgEB/wMuLv8Afn7/AKam/wDB + wf8A19f/ANra/wSlpf88AAD/pQAA/8EAAP/FAAD/yAAA/8sAAP/NAAD/0AAA/80AAP+0AAD/dwAA/zEA + AP8GFBT/AmNj/wZhYf8wCwv/hAQE/8oLC//kGBj/7CYm/90xMe6pRESNi4uLLtLS0hH///8F////AQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr0REdLRQUO+xSEj/ozIy/4kcHP9hDg7/MAQE/w0B + Af8CMDD/AH9//wCkpP8Aubn/Aa6u/xo8PP9+AAD/tQAA/7wAAP+/AAD/wgAA/8UAAP/IAAD/ywAA/80A + AP/JAAD/pwAA/2YAAP8tAAD/GggI/zIGBv9/AwP/xgoK/+AWFv/nJSX/4S8v9LQ8PJ6MjIwz3NzcFv// + /wr///8DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALBHR361U1PwskpK/6Q1 + Nf+NIiL/YxER/zMICP8QBAT/AzEx/wB0dP8Bj4//Dk1N/1sAAP+lAAD/swAA/7cAAP+6AAD/vQAA/8AA + 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 + yf+AAU3/wANP/+AHYf8= + + + \ No newline at end of file diff --git a/Samples/VMR9/VMR9Allocator/PlaneScene.cs b/Samples/VMR9/VMR9Allocator/PlaneScene.cs new file mode 100644 index 0000000..1db94cd --- /dev/null +++ b/Samples/VMR9/VMR9Allocator/PlaneScene.cs @@ -0,0 +1,193 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +using Microsoft.DirectX; +using Microsoft.DirectX.Direct3D; + +namespace DirectShowLib.Sample +{ + public class PlaneScene : IDisposable + { + private const int E_FAIL = unchecked((int) 0x80004005); + + private CustomVertex.PositionColoredTextured[] vertices; + private VertexBuffer vertexBuffer = null; + + private int time = 0; + + public PlaneScene() + { + vertices = new CustomVertex.PositionColoredTextured[4]; + + vertices[0].Position = new Vector3(-1.0f, 1.0f, 0.0f); // top left + vertices[1].Position = new Vector3(-1.0f, -1.0f, 0.0f); // bottom left + vertices[2].Position = new Vector3( 1.0f, 1.0f, 0.0f); // top right + vertices[3].Position = new Vector3( 1.0f, -1.0f, 0.0f); // bottom right + + vertices[0].Color = unchecked((int)0xffffffff); // low left + vertices[1].Color = unchecked((int)0xff0000ff); // high left + vertices[2].Color = unchecked((int)0xffffffff); // low right + vertices[3].Color = unchecked((int)0xff0000ff); // high right + + vertices[0].Tu = 0.0f; vertices[0].Tv = 0.0f; // low left + vertices[1].Tu = 0.0f; vertices[1].Tv = 1.0f; // high left + vertices[2].Tu = 1.0f; vertices[2].Tv = 0.0f; // low right + vertices[3].Tu = 1.0f; vertices[3].Tv = 1.0f; // high right + } + + ~PlaneScene() + { + Dispose(); + } + + #region Membres de IDisposable + + public void Dispose() + { + if (vertexBuffer != null) + { + vertexBuffer.Dispose(); + vertexBuffer = null; + } + } + + #endregion + + [DllImport("kernel32.dll")] + private static extern int GetTickCount(); + + public int Init(Device d3dDev) + { + try + { + d3dDev.RenderState.CullMode = Cull.None; + d3dDev.RenderState.Lighting = false; + + d3dDev.RenderState.AlphaBlendEnable = true; + d3dDev.RenderState.SourceBlend = Blend.SourceAlpha; + d3dDev.RenderState.DestinationBlend = Blend.InvSourceAlpha; + d3dDev.RenderState.AlphaTestEnable = true; + d3dDev.RenderState.ReferenceAlpha = 0x10; + d3dDev.RenderState.AlphaFunction = Compare.Greater; + + d3dDev.SamplerState[0].AddressU = TextureAddress.Clamp; + d3dDev.SamplerState[0].AddressV = TextureAddress.Clamp; + d3dDev.SamplerState[0].MagFilter = TextureFilter.Linear; + d3dDev.SamplerState[0].MinFilter = TextureFilter.Linear; + d3dDev.SamplerState[0].MipFilter = TextureFilter.Linear; + + vertexBuffer = new VertexBuffer( + typeof(CustomVertex.PositionColoredTextured), + 4, + d3dDev, + Usage.WriteOnly, + CustomVertex.PositionColoredTextured.Format, + Pool.Managed + ); + + Surface backBuffer = d3dDev.GetBackBuffer(0, 0, BackBufferType.Mono); + SurfaceDescription backBufferDesc = backBuffer.Description; + + float aspect = (float)backBufferDesc.Width / (float)backBufferDesc.Height; + Matrix matProj = Matrix.PerspectiveFovLH((float)Math.PI / 4, aspect, 1.0f, 100.0f); + d3dDev.SetTransform(TransformType.Projection, matProj); + + Vector3 from = new Vector3(1.0f, 1.0f, -3.0f); + Vector3 at = new Vector3(0.0f, 0.0f, 0.0f); + Vector3 up = new Vector3(0.0f, 1.0f, 0.0f); + Matrix matView = Matrix.LookAtLH(from, at, up); + d3dDev.SetTransform(TransformType.View, matView); + + time = GetTickCount(); + + backBuffer.Dispose(); + } + catch(DirectXException e) + { + return e.ErrorCode; + } + catch + { + return E_FAIL; + } + + return 0; + } + + public int DrawScene(Device d3dDev, Texture texture) + { + if (vertexBuffer == null) + return E_FAIL; + + // get the difference in time + int currentTime = GetTickCount(); + double difference = time - currentTime ; + + // figure out the rotation of the plane + float x = (float) (-Math.Cos(difference / 2000.0)); + float y = (float) (Math.Cos(difference / 2000.0)); + float z = (float) (Math.Sin(difference / 2000.0)); + + // update the two rotating vertices with the new position + vertices[0].Position = new Vector3(x, y, z); + vertices[3].Position = new Vector3(-x, -y, -z); + + // Adjust the color so the blue is always on the bottom. + // As the corner approaches the bottom, get rid of all the other + // colors besides blue + int mask0 = (int) (255 * (( y + 1.0) / 2.0)); + int mask3 = (int) (255 * (( -y + 1.0 ) / 2.0)); + vertices[0].Color = unchecked((int) 0xff0000ff | (mask0 << 16) | (mask0 << 8)); + vertices[3].Color = unchecked((int) 0xff0000ff | (mask3 << 16) | (mask3 << 8)); + + try + { + // write the new vertex information into the buffer + vertexBuffer.SetData(vertices, 0, LockFlags.None); + + // clear the scene so we don't have any articats left + d3dDev.Clear(ClearFlags.Target, 0x00ffffff, 1.0f, 0); + + d3dDev.BeginScene(); + d3dDev.SetTexture(0, texture); + + d3dDev.SetTextureStageState(0, TextureStageStates.AlphaOperation, (int)TextureOperation.Modulate); + d3dDev.SetTextureStageState(0, TextureStageStates.AlphaArgument1, (int)TextureArgument.TextureColor); + d3dDev.SetTextureStageState(0, TextureStageStates.AlphaArgument2, (int)TextureArgument.Diffuse); + d3dDev.SetTextureStageState(0, TextureStageStates.ColorArgument1, (int)TextureArgument.TextureColor); + + d3dDev.SetStreamSource(0, vertexBuffer, 0); + d3dDev.VertexFormat = CustomVertex.PositionColoredTextured.Format; + d3dDev.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2); + d3dDev.SetTexture(0, null); + d3dDev.EndScene(); + } + catch(DirectXException e) + { + return e.ErrorCode; + } + catch + { + return E_FAIL; + } + + return 0; + } + + public void SetSrcRect(float fTU, float fTV) + { + vertices[0].Tu = 0.0f; vertices[0].Tv = 0.0f; // low left + vertices[1].Tu = 0.0f; vertices[1].Tv = fTV; // high left + vertices[2].Tu = fTU; vertices[2].Tv = 0.0f; // low right + vertices[3].Tu = fTU; vertices[3].Tv = fTV; // high right + } + } +} diff --git a/Samples/VMR9/VMR9Allocator/VMR9Allocator-2005.csproj b/Samples/VMR9/VMR9Allocator/VMR9Allocator-2005.csproj new file mode 100644 index 0000000..8dc5c57 --- /dev/null +++ b/Samples/VMR9/VMR9Allocator/VMR9Allocator-2005.csproj @@ -0,0 +1,129 @@ + + + Local + 8.0.50727 + 2.0 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1} + Debug + AnyCPU + directx.ico + + + VMR9Allocator + + + JScript + Grid + IE50 + false + WinExe + DirectShowLib.Samples + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\lib\DirectShowLib-2005.dll + + + + + System + + + System.Data + + + System.Drawing + + + System.Windows.Forms + + + System.XML + + + + + Form + + + Code + + + Code + + + Form + + + Code + + + AboutBox.cs + + + MainForm.cs + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/VMR9/VMR9Allocator/VMR9Allocator-2005.sln b/Samples/VMR9/VMR9Allocator/VMR9Allocator-2005.sln new file mode 100644 index 0000000..44994ef --- /dev/null +++ b/Samples/VMR9/VMR9Allocator/VMR9Allocator-2005.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VMR9Allocator-2005", "VMR9Allocator-2005.csproj", "{B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/VMR9/VMR9Allocator/VMR9Allocator-2008.sln b/Samples/VMR9/VMR9Allocator/VMR9Allocator-2008.sln new file mode 100644 index 0000000..1be76cc --- /dev/null +++ b/Samples/VMR9/VMR9Allocator/VMR9Allocator-2008.sln @@ -0,0 +1,42 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VMR9Allocator-2008", "VMR9Allocator-2008.csproj", "{B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DirectShowLib-2008", "..\..\..\src\DirectShowLib-2008.csproj", "{CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Debug|x64.ActiveCfg = Debug|x64 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Debug|x64.Build.0 = Debug|x64 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Debug|x86.ActiveCfg = Debug|x86 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Debug|x86.Build.0 = Debug|x86 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Release|Any CPU.Build.0 = Release|Any CPU + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Release|x64.ActiveCfg = Release|x64 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Release|x64.Build.0 = Release|x64 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Release|x86.ActiveCfg = Release|x86 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1}.Release|x86.Build.0 = Release|x86 + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Debug|x64.ActiveCfg = Debug|x64 + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Debug|x64.Build.0 = Debug|x64 + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Debug|x86.ActiveCfg = Debug|x86 + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Release|Any CPU.Build.0 = Release|Any CPU + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Release|x64.ActiveCfg = Release|Any CPU + {CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}.Release|x86.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/VMR9/VMR9Allocator/VMR9Allocator.csproj b/Samples/VMR9/VMR9Allocator/VMR9Allocator.csproj new file mode 100644 index 0000000..5c2b59a --- /dev/null +++ b/Samples/VMR9/VMR9Allocator/VMR9Allocator.csproj @@ -0,0 +1,217 @@ + + + + true + bin\x86\Debug\ + TRACE;DEBUG;USING_NET20 + 285212672 + 4096 + full + x86 + prompt + + + bin\x86\Release\ + TRACE;USING_NET20 + 285212672 + true + 4096 + x86 + prompt + + + Local + 9.0.21022 + 2.0 + {B3D9A91A-8F19-45DA-93FF-4C6248AFD6D1} + Debug + AnyCPU + directx.ico + + + VMR9Allocator + + + JScript + Grid + IE50 + false + WinExe + DirectShowLib.Samples + OnBuildSuccess + + + + + + + 3.5 + false + v3.5 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + true + bin\x64\Debug\ + TRACE;DEBUG;USING_NET20 + 285212672 + 4096 + full + x64 + prompt + + + bin\x64\Release\ + TRACE;USING_NET20 + 285212672 + true + 4096 + x64 + prompt + + + + + + System + + + 3.5 + + + System.Data + + + System.Drawing + + + System.Windows.Forms + + + System.XML + + + + + Form + + + Code + + + Code + + + Form + + + Code + + + AboutBox.cs + + + MainForm.cs + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + False + .NET Framework 3.5 SP1 + false + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + + + + + + \ No newline at end of file diff --git a/Samples/VMR9/VMR9Allocator/directx.ico b/Samples/VMR9/VMR9Allocator/directx.ico new file mode 100644 index 0000000000000000000000000000000000000000..bc43c1b2085df668dffff26d80adcb0ef73f23a9 GIT binary patch literal 25214 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 8; + } + + return System.Text.Encoding.ASCII.GetString(chars); + } + + #region Members of IVMRSurfaceAllocator9 + + public int InitializeDevice(IntPtr dwUserID, ref VMR9AllocationInfo lpAllocInfo, ref int lpNumBuffers) + { + int hr = 0; + + Debug.WriteLine(string.Format("{0}x{1} : {2} / {3} / 0x{4:x}", lpAllocInfo.dwWidth, lpAllocInfo.dwHeight, FourCCToStr(lpAllocInfo.Format), lpAllocInfo.Pool, lpAllocInfo.dwFlags)); + + // The allocator sometime call this method with invalid pool value (4 for me). Don't ask me why! + // If the pool is invalid, return an error now to avoid an exception later in the code. + if ((lpAllocInfo.Pool < 0) || (lpAllocInfo.Pool > 3)) + return D3DERR_INVALIDCALL; + + // if format is YUV ? (note : 0x30303030 = " ") + if (lpAllocInfo.Format > 0x30303030) + { + // Check if the hardware support format conversion from this YUV format to the RGB desktop format + if (!Manager.CheckDeviceFormatConversion(creationParameters.AdapterOrdinal, creationParameters.DeviceType, (Format)lpAllocInfo.Format, adapterInfo.CurrentDisplayMode.Format)) + { + // If not, refuse this format! + // The VMR9 will propose other formats supported by the downstream filter output pin. + return D3DERR_INVALIDCALL; + } + } + + try + { + IntPtr unmanagedDevice = device.GetObjectByValue(DxMagicNumber); + IntPtr hMonitor = Manager.GetAdapterMonitor(adapterInfo.Adapter); + + // Give our Direct3D device to the VMR9 filter + hr = vmrSurfaceAllocatorNotify.SetD3DDevice(unmanagedDevice, hMonitor); + DsError.ThrowExceptionForHR(hr); + + videoSize = new Size(lpAllocInfo.dwWidth, lpAllocInfo.dwHeight); + + int width = 1; + int height = 1; + + // If hardware require textures to power of two sized + if (device.DeviceCaps.TextureCaps.SupportsPower2) + { + // Compute the ideal size + while (width < lpAllocInfo.dwWidth) + width = width << 1; + while (height < lpAllocInfo.dwHeight) + height = height << 1; + + // notify this change to the VMR9 filter + lpAllocInfo.dwWidth = width; + lpAllocInfo.dwHeight = height; + } + + textureSize = new Size(lpAllocInfo.dwWidth, lpAllocInfo.dwHeight); + + // Just in case + DeleteSurfaces(); + + // if format is YUV ? + if (lpAllocInfo.Format > 0x30303030) + { + // An offscreen surface must be created + lpAllocInfo.dwFlags |= VMR9SurfaceAllocationFlags.OffscreenSurface; + + // Create it + videoSurface = device.CreateOffscreenPlainSurface(lpAllocInfo.dwWidth, lpAllocInfo.dwHeight, (Format)lpAllocInfo.Format, (Pool)lpAllocInfo.Pool); + + // And get it unmanaged pointer + unmanagedSurface = videoSurface.GetObjectByValue(DxMagicNumber); + + // Then create a private texture for the client application + privateTexture = new Texture( + device, + lpAllocInfo.dwWidth, + lpAllocInfo.dwHeight, + 1, + Usage.RenderTarget, + adapterInfo.CurrentDisplayMode.Format, + Pool.Default + ); + + // Get the MipMap surface 0 for the copy (see PresentImage) + privateSurface = privateTexture.GetSurfaceLevel(0); + + // This code path need a surface copy + needCopy = true; + } + else + { + // in RGB pixel format + lpAllocInfo.dwFlags |= VMR9SurfaceAllocationFlags.TextureSurface; + + // Simply create a texture + privateTexture = new Texture( + device, + lpAllocInfo.dwWidth, + lpAllocInfo.dwHeight, + 1, + Usage.RenderTarget, + adapterInfo.CurrentDisplayMode.Format, + Pool.Default + ); + + // And get the MipMap surface 0 for the VMR9 filter + privateSurface = privateTexture.GetSurfaceLevel(0); + unmanagedSurface = privateSurface.GetObjectByValue(DxMagicNumber); + + // This code path don't need a surface copy. + // The client appllication use the same texture the VMR9 filter use. + needCopy = false; + } + + // This allocator only support 1 buffer. + // Notify the VMR9 filter + lpNumBuffers = 1; + } + + catch(DirectXException e) + { + // A Direct3D error can occure : Notify it to the VMR9 filter + return e.ErrorCode; + } + catch + { + // Or else, notify a more general error + return E_FAIL; + } + + // This allocation is a success + return 0; + } + + public int TerminateDevice(IntPtr dwID) + { + DeleteSurfaces(); + return 0; + } + + public int GetSurface(IntPtr dwUserID, int SurfaceIndex, int SurfaceFlags, out IntPtr lplpSurface) + { + lplpSurface = IntPtr.Zero; + + // If the filter ask for an invalid buffer index, return an error. + if (SurfaceIndex >= 1) + return E_FAIL; + + lock(this) + { + // IVMRSurfaceAllocator9.GetSurface documentation state that the caller release the returned + // interface so we must increment its reference count. + lplpSurface = unmanagedSurface; + Marshal.AddRef(lplpSurface); + return 0; + } + } + + public int AdviseNotify(IVMRSurfaceAllocatorNotify9 lpIVMRSurfAllocNotify) + { + lock (this) + { + vmrSurfaceAllocatorNotify = lpIVMRSurfAllocNotify; + + // Give our Direct3D device to the VMR9 filter + IntPtr unmanagedDevice = device.GetObjectByValue(DxMagicNumber); + IntPtr hMonitor = Manager.GetAdapterMonitor(Manager.Adapters.Default.Adapter); + + return vmrSurfaceAllocatorNotify.SetD3DDevice(unmanagedDevice, hMonitor); + } + } + + #endregion + + #region Membres de IVMRImagePresenter9 + + public int StartPresenting(IntPtr dwUserID) + { + lock (this) + { + if (device == null) + return E_FAIL; + + return 0; + } + } + + public int StopPresenting(IntPtr dwUserID) + { + return 0; + } + + public int PresentImage(IntPtr dwUserID, ref VMR9PresentationInfo lpPresInfo) + { + lock (this) + { + try + { + // If YUV mixing is activated, a surface copy is needed + if (needCopy) + { + // Use StretchRectangle to do the Pixel Format conversion + device.StretchRectangle( + videoSurface, + new Rectangle(Point.Empty, videoSize), + privateSurface, + new Rectangle(Point.Empty, videoSize), + TextureFilter.None + ); + } + } + catch(DirectXException e) + { + // A Direct3D error can occure : Notify it to the VMR9 filter + return e.ErrorCode; + } + catch + { + // Or else, notify a more general error + return E_FAIL; + } + + // This presentation is a success + return 0; + } + } + #endregion + + } +} diff --git a/Samples/VMR9/VMR9Allocator2/App.ico b/Samples/VMR9/VMR9Allocator2/App.ico new file mode 100644 index 0000000000000000000000000000000000000000..3a5525fd794f7a7c5c8e6187f470ea3af38cd2b6 GIT binary patch literal 1078 zcmeHHJr05}7=1t!Hp3A*8IHkVf+j?-!eHY14Gtcw1Eb*_9>Bq^zETJ@GKj{_2j4$w zo9}xCh!8{T3=X##Skq>ikMjsvB|y%crWBM2iW(4pI}c%z6%lW!=~4v77#3{z!dmB1 z__&l)-{KUYR+|8|;wB^R|9ET$J@(@=#rd^=)qs85?vAy(PSF5CyNkus435LVkZ$rj zNw|JG-P7^hF<(;#o*Vk}5R#e|^13tBbQkeF?djULtvqyxd3<{9 literal 0 HcmV?d00001 diff --git a/Samples/VMR9/VMR9Allocator2/AssemblyInfo.cs b/Samples/VMR9/VMR9Allocator2/AssemblyInfo.cs new file mode 100644 index 0000000..76201ae --- /dev/null +++ b/Samples/VMR9/VMR9Allocator2/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// Les informations générales relatives à un assembly dépendent de +// l'ensemble d'attributs suivant. Pour modifier les informations +// associées à un assembly, changez les valeurs de ces attributs. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Les informations de version pour un assembly se composent des quatre valeurs suivantes : +// +// Version principale +// Version secondaire +// Numéro de build +// Révision +// +// Vous pouvez spécifier toutes les valeurs ou indiquer des numéros de révision et de build par défaut +// en utilisant '*', comme ci-dessous : + +[assembly: AssemblyVersion("1.0.*")] + +// +// Pour signer votre assembly, vous devez spécifier la clé à utiliser. Consultez +// la documentation Microsoft .NET Framework pour plus d'informations sur la signature d'un assembly. +// +// Utilisez les attributs ci-dessous pour contrôler la clé utilisée lors de la signature. +// +// Remarques : +// (*) Si aucune clé n'est spécifiée, l'assembly n'est pas signé. +// (*) KeyName fait référence à une clé installée dans le fournisseur de +// services cryptographiques (CSP) de votre ordinateur. KeyFile fait référence à un fichier qui contient +// une clé. +// (*) Si les valeurs de KeyFile et de KeyName sont spécifiées, le +// traitement suivant se produit : +// (1) Si KeyName se trouve dans le CSP, la clé est utilisée. +// (2) Si KeyName n'existe pas mais que KeyFile existe, la clé +// de KeyFile est installée dans le CSP et utilisée. +// (*) Pour créer KeyFile, vous pouvez utiliser l'utilitaire sn.exe (Strong Name, Nom fort). +// Lors de la spécification de KeyFile, son emplacement doit être +// relatif au répertoire de sortie du projet qui est +// %Project Directory%\obj\. Par exemple, si votre KeyFile se trouve +// dans le répertoire du projet, vous devez spécifier l'attribut +// AssemblyKeyFile sous la forme [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) DelaySign (signature différée) est une option avancée. Pour plus d'informations, consultez la +// documentation Microsoft .NET Framework. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/VMR9/VMR9Allocator2/ConfigForm.Designer.cs b/Samples/VMR9/VMR9Allocator2/ConfigForm.Designer.cs new file mode 100644 index 0000000..cfd7685 --- /dev/null +++ b/Samples/VMR9/VMR9Allocator2/ConfigForm.Designer.cs @@ -0,0 +1,190 @@ +namespace DirectShowLib.Sample +{ + partial class ConfigForm + { + /// + /// Variable nécessaire au concepteur. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Nettoyage des ressources utilisées. + /// + /// true si les ressources managées doivent être supprimées ; sinon, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Code généré par le Concepteur Windows Form + + /// + /// Méthode requise pour la prise en charge du concepteur - ne modifiez pas + /// le contenu de cette méthode avec l'éditeur de code. + /// + private void InitializeComponent() + { + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.rbWindowed = new System.Windows.Forms.RadioButton(); + this.rbFullScreen = new System.Windows.Forms.RadioButton(); + this.cbDisplayModes = new System.Windows.Forms.ComboBox(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.rbNoMixing = new System.Windows.Forms.RadioButton(); + this.rbYUVMixing = new System.Windows.Forms.RadioButton(); + this.rbRGBMixing = new System.Windows.Forms.RadioButton(); + this.btOK = new System.Windows.Forms.Button(); + this.btCancel = new System.Windows.Forms.Button(); + this.groupBox1.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.cbDisplayModes); + this.groupBox1.Controls.Add(this.rbFullScreen); + this.groupBox1.Controls.Add(this.rbWindowed); + this.groupBox1.Location = new System.Drawing.Point(12, 12); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(276, 78); + this.groupBox1.TabIndex = 0; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Direct3D window behaviour"; + // + // rbWindowed + // + this.rbWindowed.AutoSize = true; + this.rbWindowed.Checked = true; + this.rbWindowed.Location = new System.Drawing.Point(6, 19); + this.rbWindowed.Name = "rbWindowed"; + this.rbWindowed.Size = new System.Drawing.Size(76, 17); + this.rbWindowed.TabIndex = 0; + this.rbWindowed.TabStop = true; + this.rbWindowed.Text = "Windowed"; + this.rbWindowed.UseVisualStyleBackColor = true; + this.rbWindowed.CheckedChanged += new System.EventHandler(this.rbWindowed_CheckedChanged); + // + // rbFullScreen + // + this.rbFullScreen.AutoSize = true; + this.rbFullScreen.Location = new System.Drawing.Point(6, 42); + this.rbFullScreen.Name = "rbFullScreen"; + this.rbFullScreen.Size = new System.Drawing.Size(78, 17); + this.rbFullScreen.TabIndex = 1; + this.rbFullScreen.Text = "Full Screen"; + this.rbFullScreen.UseVisualStyleBackColor = true; + this.rbFullScreen.CheckedChanged += new System.EventHandler(this.rbFullScreen_CheckedChanged); + // + // cbDisplayModes + // + this.cbDisplayModes.Enabled = false; + this.cbDisplayModes.FormattingEnabled = true; + this.cbDisplayModes.Location = new System.Drawing.Point(90, 42); + this.cbDisplayModes.Name = "cbDisplayModes"; + this.cbDisplayModes.Size = new System.Drawing.Size(172, 21); + this.cbDisplayModes.TabIndex = 2; + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.rbRGBMixing); + this.groupBox2.Controls.Add(this.rbYUVMixing); + this.groupBox2.Controls.Add(this.rbNoMixing); + this.groupBox2.Location = new System.Drawing.Point(12, 97); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(276, 93); + this.groupBox2.TabIndex = 1; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "VMR9 mixing configuration"; + // + // rbNoMixing + // + this.rbNoMixing.AutoSize = true; + this.rbNoMixing.Checked = true; + this.rbNoMixing.Location = new System.Drawing.Point(7, 20); + this.rbNoMixing.Name = "rbNoMixing"; + this.rbNoMixing.Size = new System.Drawing.Size(102, 17); + this.rbNoMixing.TabIndex = 0; + this.rbNoMixing.TabStop = true; + this.rbNoMixing.Text = "Don\'t use mixing"; + this.rbNoMixing.UseVisualStyleBackColor = true; + // + // rbYUVMixing + // + this.rbYUVMixing.AutoSize = true; + this.rbYUVMixing.Location = new System.Drawing.Point(6, 44); + this.rbYUVMixing.Name = "rbYUVMixing"; + this.rbYUVMixing.Size = new System.Drawing.Size(101, 17); + this.rbYUVMixing.TabIndex = 1; + this.rbYUVMixing.Text = "Use YUV mixing"; + this.rbYUVMixing.UseVisualStyleBackColor = true; + // + // rbRGBMixing + // + this.rbRGBMixing.AutoSize = true; + this.rbRGBMixing.Location = new System.Drawing.Point(7, 68); + this.rbRGBMixing.Name = "rbRGBMixing"; + this.rbRGBMixing.Size = new System.Drawing.Size(102, 17); + this.rbRGBMixing.TabIndex = 2; + this.rbRGBMixing.Text = "Use RGB mixing"; + this.rbRGBMixing.UseVisualStyleBackColor = true; + // + // btOK + // + this.btOK.Location = new System.Drawing.Point(12, 196); + this.btOK.Name = "btOK"; + this.btOK.Size = new System.Drawing.Size(75, 23); + this.btOK.TabIndex = 2; + this.btOK.Text = "&OK"; + this.btOK.UseVisualStyleBackColor = true; + this.btOK.Click += new System.EventHandler(this.btOK_Click); + // + // btCancel + // + this.btCancel.Location = new System.Drawing.Point(93, 196); + this.btCancel.Name = "btCancel"; + this.btCancel.Size = new System.Drawing.Size(75, 23); + this.btCancel.TabIndex = 3; + this.btCancel.Text = "&Cancel"; + this.btCancel.UseVisualStyleBackColor = true; + this.btCancel.Click += new System.EventHandler(this.btCancel_Click); + // + // ConfigForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(300, 227); + this.Controls.Add(this.btCancel); + this.Controls.Add(this.btOK); + this.Controls.Add(this.groupBox2); + this.Controls.Add(this.groupBox1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "ConfigForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Configuration Form"; + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.RadioButton rbWindowed; + private System.Windows.Forms.ComboBox cbDisplayModes; + private System.Windows.Forms.RadioButton rbFullScreen; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.RadioButton rbRGBMixing; + private System.Windows.Forms.RadioButton rbYUVMixing; + private System.Windows.Forms.RadioButton rbNoMixing; + private System.Windows.Forms.Button btOK; + private System.Windows.Forms.Button btCancel; + } +} \ No newline at end of file diff --git a/Samples/VMR9/VMR9Allocator2/ConfigForm.cs b/Samples/VMR9/VMR9Allocator2/ConfigForm.cs new file mode 100644 index 0000000..e313ab3 --- /dev/null +++ b/Samples/VMR9/VMR9Allocator2/ConfigForm.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +using Microsoft.DirectX.Direct3D; + +namespace DirectShowLib.Sample +{ + /// + /// Helper struture to pass selected preferences + /// + public struct Configuration + { + public bool IsWindowed; + public DisplayMode Mode; + public bool IsUsingMixing; + public bool UseYUVMixing; + } + + /// + /// Helper Structure to display video modes in the combo + /// + public struct Mode + { + public DisplayMode mode; + + public Mode(DisplayMode mode) + { + this.mode = mode; + } + + public override string ToString() + { + return string.Format("{0} x {1} : {2} @ {3}Hz", mode.Width, mode.Height, mode.Format, mode.RefreshRate); + } + } + + public partial class ConfigForm : Form + { + public Configuration config = new Configuration(); + + public ConfigForm() + { + InitializeComponent(); + + FillComboWithDisplayModes(); + } + + private void FillComboWithDisplayModes() + { + foreach (DisplayMode displayMode in Manager.Adapters.Default.SupportedDisplayModes) + { + cbDisplayModes.Items.Add(new Mode(displayMode)); + } + } + + private void rbWindowed_CheckedChanged(object sender, EventArgs e) + { + cbDisplayModes.Enabled = false; + } + + private void rbFullScreen_CheckedChanged(object sender, EventArgs e) + { + cbDisplayModes.Enabled = true; + } + + private void btOK_Click(object sender, EventArgs e) + { + config.IsWindowed = rbWindowed.Checked; + if (rbFullScreen.Checked) + { + config.Mode = ((Mode)cbDisplayModes.SelectedItem).mode; + } + config.IsUsingMixing = !rbNoMixing.Checked; + config.UseYUVMixing = rbYUVMixing.Checked; + + this.DialogResult = DialogResult.OK; + this.Close(); + } + + private void btCancel_Click(object sender, EventArgs e) + { + this.DialogResult = DialogResult.Cancel; + this.Close(); + } + } +} \ No newline at end of file diff --git a/Samples/VMR9/VMR9Allocator2/ConfigForm.resx b/Samples/VMR9/VMR9Allocator2/ConfigForm.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/Samples/VMR9/VMR9Allocator2/ConfigForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Samples/VMR9/VMR9Allocator2/MainForm.cs b/Samples/VMR9/VMR9Allocator2/MainForm.cs new file mode 100644 index 0000000..2039a29 --- /dev/null +++ b/Samples/VMR9/VMR9Allocator2/MainForm.cs @@ -0,0 +1,438 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Diagnostics; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Windows.Forms; +using System.Runtime.InteropServices; + +using Microsoft.DirectX; +using Microsoft.DirectX.Direct3D; + +using DirectShowLib; + +namespace DirectShowLib.Sample +{ + public class MainForm : System.Windows.Forms.Form + { + // Managed Direct3D Device + private Device device = null; + private PresentParameters presentParams = null; + + // Managed Direct3D Resources + private Surface renderTarget; + private VertexBuffer vertexBuffer = null; + private CustomVertex.TransformedTextured[] vertices = new CustomVertex.TransformedTextured[4]; + + // The configuration retrieve from the conf form + private Configuration config; + + // The window default size and backbuffer fixed size + private Size displaySize = new Size(1024, 768); + + // DirectShow objects + private IFilterGraph2 graphBuilder; + private DsROTEntry rot; + private IBaseFilter vmr9; + private Allocator allocator; + + private const int WM_PAINT = 0x000F; + private const int WM_GRAPHNOTIFY = 0x4000 + 123; + + public MainForm() + { + InitializeComponent(); + + // The form is completly opaque and drawn by ourself + this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.Opaque, true); + } + + public MainForm(Configuration config) : this() + { + this.config = config; + } + + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + Shutdown(); + } + + base.Dispose( disposing ); + } + + #region Code généré par le Concepteur Windows Form + /// + /// Méthode requise pour la prise en charge du concepteur - ne modifiez pas + /// le contenu de cette méthode avec l'éditeur de code. + /// + private void InitializeComponent() + { + // + // MainForm + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = displaySize; + this.Name = "MainForm"; + this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MainForm_KeyDown); + + } + #endregion + + private void MainForm_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) + { + switch(e.KeyCode) + { + // Press Escape to quit + case Keys.Escape: + { + this.Close(); + break; + } + } + } + + // Init the Managed Direct3D Device + public void InitializeGraphics() + { + presentParams = new PresentParameters(); + + if (config.IsWindowed) + { + // We want a windowed device + presentParams.Windowed = true; + + // Enable Z-Buffer + // This is not really needed in this sample but real applications generaly use it + presentParams.EnableAutoDepthStencil = true; + presentParams.AutoDepthStencilFormat = DepthFormat.D16; + + // Hint to the Device Driver : This is a video playing application + presentParams.PresentFlag = PresentFlag.Video; + + // How to swap backbuffer in front and how many frames per screen refresh + presentParams.SwapEffect = SwapEffect.Copy; + presentParams.PresentationInterval = PresentInterval.One; + } + else + { + // We want a fullscreen device + presentParams.Windowed = false; + + // One backbuffer should be enough + presentParams.BackBufferCount = 2; + presentParams.BackBufferWidth = config.Mode.Width; + presentParams.BackBufferHeight = config.Mode.Height; + presentParams.BackBufferFormat = config.Mode.Format; + presentParams.FullScreenRefreshRateInHz = config.Mode.RefreshRate; + + // Enable Z-Buffer + // This is not really needed in this sample but real applications generaly use it + presentParams.EnableAutoDepthStencil = true; + presentParams.AutoDepthStencilFormat = DepthFormat.D16; + + // Hint to the Device Driver : This is a video playing application + presentParams.PresentFlag = PresentFlag.Video; + + // How to swap backbuffer in front and how many frames per screen refresh + presentParams.SwapEffect = SwapEffect.Discard; + presentParams.PresentationInterval = PresentInterval.One; + + displaySize = new Size(config.Mode.Width, config.Mode.Height); + } + + // Disable Managed Direct3D events + Device.IsUsingEventHandlers = false; + + // Create the device + device = new Device( + Manager.Adapters.Default.Adapter, + DeviceType.Hardware, + this, + CreateFlags.SoftwareVertexProcessing | CreateFlags.MultiThreaded, + presentParams + ); + + AllocateResources(); + InitializeDevice(); + } + + private void AllocateResources() + { + // Retrieve the render tatget (the backbuffer) + renderTarget = device.GetRenderTarget(0); + + // Alloc a Vertex buffer to draw the video (4 vertices -> a Quad) + vertexBuffer = new VertexBuffer( + typeof(CustomVertex.TransformedTextured), + 4, + device, + Usage.Dynamic | Usage.WriteOnly, + CustomVertex.TransformedTextured.Format, + Pool.Default + ); + } + + private void InitializeDevice() + { + FilterCaps filterCaps = device.DeviceCaps.TextureFilterCaps; + + // If the hardware support it, apply a bilinear filtering + if (filterCaps.SupportsMagnifyLinear && filterCaps.SupportsMinifyLinear) + { + device.SamplerState[0].MinFilter = TextureFilter.Linear; + device.SamplerState[0].MagFilter = TextureFilter.Linear; + } + else + { + device.SamplerState[0].MinFilter = TextureFilter.Point; + device.SamplerState[0].MagFilter = TextureFilter.Point; + } + } + + public void InitVMR9(string filename) + { + int hr = 0; + + // Create a DirectShow FilterGraph + graphBuilder = (IFilterGraph2) new FilterGraph(); + + // Add it in ROT for debug purpose + rot = new DsROTEntry(graphBuilder); + + // Add a notification handler (see WndProc) + hr = (graphBuilder as IMediaEventEx).SetNotifyWindow(this.Handle, WM_GRAPHNOTIFY, IntPtr.Zero); + DsError.ThrowExceptionForHR(hr); + + // Create a VMR9 object + vmr9 = (IBaseFilter) new VideoMixingRenderer9(); + + IVMRFilterConfig9 filterConfig = (IVMRFilterConfig9) vmr9; + + // We want the Renderless mode! + hr = filterConfig.SetRenderingMode(VMR9Mode.Renderless); + DsError.ThrowExceptionForHR(hr); + + // Create the Allocator / Presenter object + allocator = new Allocator(device); + + IVMRSurfaceAllocatorNotify9 vmrSurfAllocNotify = (IVMRSurfaceAllocatorNotify9) vmr9; + + // Notify the VMR9 filter about our allocator + hr = vmrSurfAllocNotify.AdviseSurfaceAllocator(IntPtr.Zero, allocator); + DsError.ThrowExceptionForHR(hr); + + // Notify our allocator about the VMR9 filter + hr = allocator.AdviseNotify(vmrSurfAllocNotify); + DsError.ThrowExceptionForHR(hr); + + if (config.IsUsingMixing) + { + // One stream is enough for this sample + // This line also load the mixing componant + hr = filterConfig.SetNumberOfStreams(1); + DsError.ThrowExceptionForHR(hr); + + IVMRMixerControl9 mixerControl = (IVMRMixerControl9) vmr9; + + // Select the mixer mode : YUV or RGB + if (config.UseYUVMixing) + { + hr = mixerControl.SetMixingPrefs(VMR9MixerPrefs.RenderTargetYUV | VMR9MixerPrefs.NoDecimation | VMR9MixerPrefs.ARAdjustXorY | VMR9MixerPrefs.BiLinearFiltering); + } + else + { + hr = mixerControl.SetMixingPrefs(VMR9MixerPrefs.RenderTargetRGB | VMR9MixerPrefs.NoDecimation | VMR9MixerPrefs.ARAdjustXorY | VMR9MixerPrefs.BiLinearFiltering); + } + DsError.ThrowExceptionForHR(hr); + + Debug.WriteLine("Using VMR9 mixing mode"); + } + + // Add the filter to the graph + hr = graphBuilder.AddFilter(vmr9, "Video Mixing Renderer 9"); + DsError.ThrowExceptionForHR(hr); + + // Render the file + hr = graphBuilder.RenderFile(filename, null); + DsError.ThrowExceptionForHR(hr); + + // Run the graph + hr = (graphBuilder as IMediaControl).Run(); + DsError.ThrowExceptionForHR(hr); + } + + private void Shutdown() + { + int hr = 0; + + // Remove the ROT entry + if (rot != null) + rot.Dispose(); + + if (graphBuilder != null) + { + // Stop DirectShow notifications + hr = (graphBuilder as IMediaEventEx).SetNotifyWindow(IntPtr.Zero, 0, IntPtr.Zero); + + // Stop the graph + hr = (graphBuilder as IMediaControl).StopWhenReady(); + hr = (graphBuilder as IMediaControl).Stop(); + + // Dispose the allocator + allocator.Dispose(); + + // Release DirectShow objects + Marshal.ReleaseComObject(vmr9); + Marshal.ReleaseComObject(graphBuilder); + graphBuilder = null; + + FreeResources(); + + // Free the Managed Direct3D device + device.Dispose(); + } + } + + private void FreeResources() + { + // Free Managed Direct3D resources + renderTarget.Dispose(); + vertexBuffer.Dispose(); + } + + // + private void UpdateEnvironment() + { + Size vmrTexSize = allocator.TextureSize; + Size vmrVidSize = allocator.VideoSize; + RectangleF videoClientRectangle = Rectangle.Empty; + + if (vmrVidSize.Width >= vmrVidSize.Height) + { + // Compute the video aspect-ratio for a landscape proportioned image + float videoAR = (float)vmrVidSize.Height / (float)vmrVidSize.Width; + + videoClientRectangle.X = 0.0f; + videoClientRectangle.Width = (float) displaySize.Width; + videoClientRectangle.Height = (float) displaySize.Width * videoAR; + videoClientRectangle.Y = ((float) displaySize.Height - videoClientRectangle.Height) / 2; + } + else + { + // Compute the video aspect-ratio for a portrait proportioned image + float videoAR = (float)vmrVidSize.Width / (float)vmrVidSize.Height; + + videoClientRectangle.Y = 0.0f; + videoClientRectangle.Width = (float) displaySize.Height * videoAR; + videoClientRectangle.Height = (float) displaySize.Height; + videoClientRectangle.X = ((float) displaySize.Width - videoClientRectangle.Width) / 2; + } + + // The Quad is built using a triangle fan of 2 triangles : 0,1,2 and 0, 2, 3 + // 0 *-------------------* 1 + // |\ | + // | \ | + // | \ | + // | \ | + // | \ | + // | \ | + // | \| + // 3 *-------------------* 2 + + vertices[0].X = videoClientRectangle.X; + vertices[0].Y = videoClientRectangle.Y; + vertices[1].X = videoClientRectangle.Width; + vertices[1].Y = videoClientRectangle.Y; + vertices[2].X = videoClientRectangle.Width; + vertices[2].Y = videoClientRectangle.Height + videoClientRectangle.Y; + vertices[3].X = videoClientRectangle.X; + vertices[3].Y = videoClientRectangle.Height + videoClientRectangle.Y; + + // See the allocator source to see why the texture size is not necessary the video size + vertices[0].Tu = 0.0f; + vertices[0].Tv = 0.0f; + vertices[1].Tu = (float) vmrVidSize.Width / (float) vmrTexSize.Width; + vertices[1].Tv = 0.0f; + vertices[2].Tu = (float) vmrVidSize.Width / (float) vmrTexSize.Width; + vertices[2].Tv = (float) vmrVidSize.Height / (float) vmrTexSize.Height; + vertices[3].Tu = 0.0f; + vertices[3].Tv = (float) vmrVidSize.Height / (float) vmrTexSize.Height; + + // Fill the vertex buffer + vertexBuffer.SetData(vertices, 0, LockFlags.Discard); + } + + private void RenderEnvironment() + { + // Set the Render Target (the VMR9 change it) + device.SetRenderTarget(0, renderTarget); + + // Clear it + device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.LimeGreen, 1.0f, 0); + + device.BeginScene(); + + // Attach the vertex buffer to the Direct3D Device + device.SetStreamSource(0, vertexBuffer, 0); + device.VertexFormat = CustomVertex.TransformedTextured.Format; + + // Set the allocator texture as active texture + device.SetTexture(0, allocator.Texture); + + // Draw the Quad + device.DrawPrimitives(PrimitiveType.TriangleFan, 0, 2); + + device.EndScene(); + + device.SetTexture(0, null); + + // Show what we draw + device.Present(); + + // A "Device Lost" exception can occure. This sample don't manage it... + } + + protected override void WndProc(ref Message m) + { + switch (m.Msg) + { + case WM_PAINT: + { + UpdateEnvironment(); + RenderEnvironment(); + NativeMethods.InvalidateRect(this.Handle, IntPtr.Zero, 0); + return; + } + + case WM_GRAPHNOTIFY: + { + IMediaEventEx eventEx = (IMediaEventEx)graphBuilder; + + EventCode evCode; + IntPtr param1, param2; + + while (eventEx.GetEvent(out evCode, out param1, out param2, 0) == 0) + { + eventEx.FreeEventParams(evCode, param1, param2); + + Debug.WriteLine(string.Format("### Event : {0} Param1 : {1} Param2 {2}", evCode.ToString(), param1.ToString(), param2.ToString())); + } + + break; + } + } + + base.WndProc (ref m); + } + + } +} diff --git a/Samples/VMR9/VMR9Allocator2/MainForm.resx b/Samples/VMR9/VMR9Allocator2/MainForm.resx new file mode 100644 index 0000000..3f337e0 --- /dev/null +++ b/Samples/VMR9/VMR9Allocator2/MainForm.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/Samples/VMR9/VMR9Allocator2/NativeMethods.cs b/Samples/VMR9/VMR9Allocator2/NativeMethods.cs new file mode 100644 index 0000000..5523c0f --- /dev/null +++ b/Samples/VMR9/VMR9Allocator2/NativeMethods.cs @@ -0,0 +1,24 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +namespace DirectShowLib.Sample +{ + [System.Security.SuppressUnmanagedCodeSecurity] + internal sealed class NativeMethods + { + [DllImport("user32.dll")] + public static extern int InvalidateRect( + IntPtr hwnd, + IntPtr rect, + int erase + ); + } +} diff --git a/Samples/VMR9/VMR9Allocator2/StartUp.cs b/Samples/VMR9/VMR9Allocator2/StartUp.cs new file mode 100644 index 0000000..f9ac7b6 --- /dev/null +++ b/Samples/VMR9/VMR9Allocator2/StartUp.cs @@ -0,0 +1,66 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Windows.Forms; +using System.Threading; + +namespace DirectShowLib.Sample +{ + public class StartUp + { + public static string filename; + public static Configuration config; + + [STAThread] + static void Main() + { + DialogResult result; + + Application.EnableVisualStyles(); + + using (ConfigForm form = new ConfigForm()) + { + result = form.ShowDialog(); + config = form.config; + } + + if (result == DialogResult.OK) + { + OpenFileDialog openDialog = new OpenFileDialog(); + + if (openDialog.ShowDialog() == DialogResult.OK) + { + filename = openDialog.FileName; + + Thread initThread = new Thread(new ThreadStart(StartUp.ApplicationLaunch)); +#if USING_NET20 + initThread.SetApartmentState(ApartmentState.MTA); +#else + initThread.ApartmentState = ApartmentState.MTA; +#endif + initThread.Start(); + } + } + } + + static void ApplicationLaunch() + { + Application.DoEvents(); + + using (MainForm form = new MainForm(config)) + { + form.Show(); + + form.InitializeGraphics(); + form.InitVMR9(StartUp.filename); + form.Focus(); + Application.Run(form); + } + } + } +} diff --git a/Samples/VMR9/VMR9Allocator2/VMR9Allocator2-2005.csproj b/Samples/VMR9/VMR9Allocator2/VMR9Allocator2-2005.csproj new file mode 100644 index 0000000..4b1a372 --- /dev/null +++ b/Samples/VMR9/VMR9Allocator2/VMR9Allocator2-2005.csproj @@ -0,0 +1,134 @@ + + + Local + 8.0.50727 + 2.0 + {16A0709D-4952-4801-9C3C-3607940121B6} + Debug + AnyCPU + App.ico + + + VMR9Allocator2 + + + JScript + Grid + IE50 + false + WinExe + DirectShowLib.Sample + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\lib\DirectShowLib-2005.dll + + + + + System + + + + System.Drawing + + + System.Windows.Forms + + + + + + Code + + + Code + + + Form + + + ConfigForm.cs + + + Form + + + Code + + + Code + + + + + Designer + ConfigForm.cs + + + MainForm.cs + Designer + + + + + + + + + + \ No newline at end of file diff --git a/Samples/VMR9/VMR9Allocator2/VMR9Allocator2-2005.sln b/Samples/VMR9/VMR9Allocator2/VMR9Allocator2-2005.sln new file mode 100644 index 0000000..2b27a86 --- /dev/null +++ b/Samples/VMR9/VMR9Allocator2/VMR9Allocator2-2005.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VMR9Allocator2-2005", "VMR9Allocator2-2005.csproj", "{16A0709D-4952-4801-9C3C-3607940121B6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {16A0709D-4952-4801-9C3C-3607940121B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {16A0709D-4952-4801-9C3C-3607940121B6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {16A0709D-4952-4801-9C3C-3607940121B6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {16A0709D-4952-4801-9C3C-3607940121B6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/VMR9/VMR9Allocator2/VMR9Allocator2-2008.sln b/Samples/VMR9/VMR9Allocator2/VMR9Allocator2-2008.sln new file mode 100644 index 0000000..754355b --- /dev/null +++ b/Samples/VMR9/VMR9Allocator2/VMR9Allocator2-2008.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VMR9Allocator2-2008", "VMR9Allocator2-2008.csproj", "{16A0709D-4952-4801-9C3C-3607940121B6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {16A0709D-4952-4801-9C3C-3607940121B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {16A0709D-4952-4801-9C3C-3607940121B6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {16A0709D-4952-4801-9C3C-3607940121B6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {16A0709D-4952-4801-9C3C-3607940121B6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/VMR9/VMR9Allocator2/VMR9Allocator2.csproj b/Samples/VMR9/VMR9Allocator2/VMR9Allocator2.csproj new file mode 100644 index 0000000..578b796 --- /dev/null +++ b/Samples/VMR9/VMR9Allocator2/VMR9Allocator2.csproj @@ -0,0 +1,166 @@ + + + + Local + 8.0.50727 + 2.0 + {16A0709D-4952-4801-9C3C-3607940121B6} + Debug + AnyCPU + App.ico + + + VMR9Allocator2 + + + JScript + Grid + IE50 + false + WinExe + DirectShowLib.Sample + OnBuildSuccess + + + + + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + + + System + + + + System.Drawing + + + System.Windows.Forms + + + + + + Code + + + Code + + + Form + + + ConfigForm.cs + + + Form + + + Code + + + Code + + + + + Designer + ConfigForm.cs + + + MainForm.cs + Designer + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + + + + + + \ No newline at end of file diff --git a/Samples/VMR9/VMR9Allocator2/readme.txt b/Samples/VMR9/VMR9Allocator2/readme.txt new file mode 100644 index 0000000..a873465 --- /dev/null +++ b/Samples/VMR9/VMR9Allocator2/readme.txt @@ -0,0 +1,76 @@ +--------------------------------------------------------------------- +VMR9Allocator2 (second try) + +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + +--------------------------------------------------------------------- + +This sample is an alternative to the DirectShow VMR9Allocator program. +Minimal knowledge in Managed Direct3D is required to understand this sample! + +The original VMR9Allocator has some drawbacks. + +1) The render loop is in the PresentImage method. Most real-life Direct3D +applications handle the render loop themselves and some developers found that it's +difficult to use VMR9Allocator in an existing engine. + +2) The InitializeDevice method uses IVMRSurfaceAllocatorNotify9.AllocateSurfaceHelper +to allocate the VMR9 surface. This method works well in C++ but in the managed world, +you have to deal with unmanaged surfaces and create the managed representation +of this surface. All those complications make the source more complicated. + +What this sample is and what it is not! + +The purpose of this sample is to illustrate how an allocator / presenter can be +rewriten to just provide a texture to a client application. In this version, the +presenter draws nothing! + +In this sample, the A/P part is almost complete but has some limitations: + - Only one pin connected to the VMR9 filter + - Direct3D errors are not checked. + - In a real-life application, D3D resources should be handled by the 3D + engine's resources manager to aid in "Device Lost" situations. + +The sample's Managed Direct3D engine is reduced to the minimal. This part absolutely +doesn't have production quality. It doesn't handle Direct3D exceptions and resize +events (You are warned). + +What's wrong with AllocateSurfaceHelper? + +Nothing but its use is not necessary if you don't want it. + +The VMR9 filter calls the InitializeDevice method once for each media type +supported by the down-stream filter. So if you don't like the first one +(or more likely because your hardware don't like it) it's perfectly valid to +refuse it! + +VMR9Allocator2 allocates a managed surface then retrieves its unmanaged pointer +so source code is less tainted by unmanaged code pieces and it is also more +readable. + +Why are YUV and RGB media types handled differently? + +This is a common hardware limitation. Most video boards (even the latest ones) +don't allow building a 3D texture from an YUV off screen surface. So YUV surfaces +must be converted to an RGB surface before being used in a 3D engine. + +YUV to RGB conversions are generally very fast on DirectX 9 class hardware. +During my tests I found that with my Geforce FX 5900, YUV rendering is as fast +as RGB rendering even with the extra copy... + +This sample uses the following DirectShow Interfaces: + + IGraphBuilder + IBaseFilter + IMediaControl + IMediaEventEx + IVMRFilterConfig9 + IVMRMixerControl9 + IVMRSurfaceAllocatorNotify9 + IVMRSurfaceAllocator9 + IVMRImagePresenter9 + +Managed DirectX must be installed to run this sample. diff --git a/Samples/VMR9/VMR9Compositor/AboutBox.resx b/Samples/VMR9/VMR9Compositor/AboutBox.resx new file mode 100644 index 0000000..4b1c550 --- /dev/null +++ b/Samples/VMR9/VMR9Compositor/AboutBox.resx @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + Private + + + Public + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + Private + + + False + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + (Default) + + + False + + + False + + + 8, 8 + + + True + + + AboutBoxWnd + + + 80 + + + True + + + Private + + \ No newline at end of file diff --git a/Samples/VMR9/VMR9Compositor/Aboutbox.cs b/Samples/VMR9/VMR9Compositor/Aboutbox.cs new file mode 100644 index 0000000..7517592 --- /dev/null +++ b/Samples/VMR9/VMR9Compositor/Aboutbox.cs @@ -0,0 +1,163 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Reflection; +using System.Windows.Forms; + +using DirectShowLib; + +namespace DirectShowLib.Sample +{ + internal class AboutBoxWnd : Form + { + public System.Windows.Forms.Label label1; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.LinkLabel linkLabel1; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label4; + private System.ComponentModel.Container components = null; + + public AboutBoxWnd() + { + InitializeComponent(); + + Type t = typeof(IGraphBuilder); + label3.Text += t.Assembly.GetName().Version; + } + + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if(components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Code généré par le Concepteur Windows Form + /// + /// Méthode requise pour la prise en charge du concepteur - ne modifiez pas + /// le contenu de cette méthode avec l'éditeur de code. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.button1 = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.linkLabel1 = new System.Windows.Forms.LinkLabel(); + this.label3 = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // label1 + // + this.label1.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label1.Location = new System.Drawing.Point(8, 8); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(272, 40); + this.label1.TabIndex = 1; + // + // button1 + // + this.button1.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.button1.Location = new System.Drawing.Point(288, 8); + this.button1.Name = "button1"; + this.button1.TabIndex = 0; + this.button1.Text = "OK"; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // label2 + // + this.label2.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label2.Location = new System.Drawing.Point(8, 64); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(160, 16); + this.label2.TabIndex = 2; + this.label2.Text = "Library source code release under"; + // + // linkLabel1 + // + this.linkLabel1.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.linkLabel1.Location = new System.Drawing.Point(184, 64); + this.linkLabel1.Name = "linkLabel1"; + this.linkLabel1.Size = new System.Drawing.Size(160, 16); + this.linkLabel1.TabIndex = 3; + this.linkLabel1.TabStop = true; + this.linkLabel1.Text = "Lesser General Public License"; + this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked); + // + // label3 + // + this.label3.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label3.Location = new System.Drawing.Point(8, 48); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(320, 16); + this.label3.TabIndex = 4; + this.label3.Text = "DirectShowLib Version : "; + // + // label4 + // + this.label4.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label4.Location = new System.Drawing.Point(8, 80); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(264, 16); + this.label4.TabIndex = 5; + this.label4.Text = "Sample source code release under Public Domain"; + // + // AboutBoxWnd + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(372, 104); + this.Controls.Add(this.label4); + this.Controls.Add(this.label3); + this.Controls.Add(this.linkLabel1); + this.Controls.Add(this.label2); + this.Controls.Add(this.button1); + this.Controls.Add(this.label1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "AboutBoxWnd"; + this.ShowInTaskbar = false; + this.Text = "AboutBox"; + this.ResumeLayout(false); + + } + #endregion + + private void button1_Click(object sender, System.EventArgs e) + { + this.Close(); + } + + private void linkLabel1_LinkClicked(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e) + { + System.Diagnostics.Process.Start("http://www.gnu.org/copyleft/lesser.txt"); + } + } + + public class AboutBox + { + public static void Show(string title, string text) + { + using (AboutBoxWnd form = new AboutBoxWnd()) + { + form.Text = title; + form.label1.Text = text; + form.ShowDialog(); + } + } + } +} diff --git a/Samples/VMR9/VMR9Compositor/Compositor.cs b/Samples/VMR9/VMR9Compositor/Compositor.cs new file mode 100644 index 0000000..62cbfe9 --- /dev/null +++ b/Samples/VMR9/VMR9Compositor/Compositor.cs @@ -0,0 +1,244 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; + +using Microsoft.DirectX; +using Microsoft.DirectX.Direct3D; +using Direct3D = Microsoft.DirectX.Direct3D; + +using DirectShowLib; + +namespace DirectShowLib.Sample +{ + public class Compositor : IVMRImageCompositor9, IDisposable + { + private IntPtr unmanagedDevice; + private Device device; + private Sprite sprite; + private Direct3D.Font d3dFont; + private Texture spiderTex; + private Vector3 spiderPos = new Vector3(0.0f, 0.0f, 0.5f); + private Point spiderMove = new Point(+1, +1); + private Size spiderSize; + + private System.Drawing.Font gdiFont; + + + public Compositor() + { + Device.IsUsingEventHandlers = false; + } + + #region IVMRImageCompositor9 Membres + + public int CompositeImage(IntPtr pD3DDevice, IntPtr pddsRenderTarget, AMMediaType pmtRenderTarget, long rtStart, long rtEnd, int dwClrBkGnd, VMR9VideoStreamInfo[] pVideoStreamInfo, int cStreams) + { + try + { + // Just in case the filter call CompositeImage before InitCompositionDevice (this sometime occure) + if (unmanagedDevice != pD3DDevice) + { + SetManagedDevice(pD3DDevice); + } + + // Create a managed Direct3D surface (the Render Target) from the unmanaged pointer. + // The constructor don't call IUnknown.AddRef but the "destructor" seem to call IUnknown.Release + // Direct3D seem to be happier with that according to the DirectX log + Marshal.AddRef(pddsRenderTarget); + Surface renderTarget = new Surface(pddsRenderTarget); + SurfaceDescription renderTargetDesc = renderTarget.Description; + Rectangle renderTargetRect = new Rectangle(0, 0, renderTargetDesc.Width, renderTargetDesc.Height); + + // Same thing for the first video surface + // WARNING : This Compositor sample only use the video provided to the first pin. + Marshal.AddRef(pVideoStreamInfo[0].pddsVideoSurface); + Surface surface = new Surface(pVideoStreamInfo[0].pddsVideoSurface); + SurfaceDescription surfaceDesc = surface.Description; + Rectangle surfaceRect = new Rectangle(0, 0, surfaceDesc.Width, surfaceDesc.Height); + + // Get the current time (to write it over the video later) + TimeSpan timeStart = TimeSpan.FromTicks(rtStart); + + // Set the device's render target (this doesn't seem to be needed) + device.SetRenderTarget(0, renderTarget); + + // Copy the whole video surface into the render target + // it's a de facto surface cleaning... + device.StretchRectangle(surface, surfaceRect, renderTarget, renderTargetRect, TextureFilter.None); + + // sprite's methods need to be called between device.BeginScene and device.EndScene + device.BeginScene(); + + // Init the sprite engine for AlphaBlending operations + sprite.Begin(SpriteFlags.AlphaBlend | SpriteFlags.DoNotSaveState); + + // Write the current video time (using the sprite)... + d3dFont.DrawText(sprite, timeStart.ToString(), Point.Empty, Color.White); + + // Compute the spider moves + if (spiderPos.X == 0) spiderMove.X = +1; + if (spiderPos.X + spiderSize.Width > renderTargetDesc.Width) spiderMove.X = -1; + + spiderPos.X += spiderMove.X; + + if (spiderPos.Y == 0) spiderMove.Y = +1; + if (spiderPos.Y + spiderSize.Height > renderTargetDesc.Height) spiderMove.Y = -1; + + spiderPos.Y += spiderMove.Y; + + // Draw the spider + // sprite.Draw2D(spiderTex, Rectangle.Empty, Rectangle.Empty, spiderPos, -1); + // Draw2D seem buggy. Many thanks to Hitbox for finding that ! + // https://sourceforge.net/forum/message.php?msg_id=4528466 + sprite.Draw(spiderTex, Vector3.Empty, spiderPos, -1); + + // End the spite engine (drawings take place here) + sprite.Flush(); + sprite.End(); + + // End the sceen. + device.EndScene(); + + // No Present requiered because the rendering is on a render target... + // device.Present(); + + // Dispose the managed surface + surface.Dispose(); + surface = null; + + // and the managed render target + renderTarget.Dispose(); + renderTarget = null; + } + catch(Exception e) + { + Debug.WriteLine(e.ToString()); + } + + // return a success to the filter + return 0; + } + + public int InitCompositionDevice(IntPtr pD3DDevice) + { + try + { + // Init the compositor with this unamanaged device + if (unmanagedDevice != pD3DDevice) + { + SetManagedDevice(pD3DDevice); + } + } + catch (Exception e) + { + Debug.WriteLine(e.ToString()); + } + + // return a success to the filter + return 0; + } + + public int SetStreamMediaType(int dwStrmID, AMMediaType pmt, bool fTexture) + { + // This method is called many times with pmt == null + if (pmt == null) + return 0; + + // This sample don't use this method... but return a success + return 0; + } + + public int TermCompositionDevice(IntPtr pD3DDevice) + { + try + { + // Free the resources each time this method is called + unmanagedDevice = IntPtr.Zero; + FreeResources(); + } + catch (Exception e) + { + Debug.WriteLine(e.ToString()); + } + + // return a success to the filter + return 0; + } + + #endregion + + #region IDisposable Membres + + public void Dispose() + { + // free resources + FreeResources(); + } + + #endregion + + private void FreeResources() + { + if (d3dFont != null) + { + d3dFont.Dispose(); + d3dFont = null; + } + + if (sprite != null) + { + sprite.Dispose(); + sprite = null; + } + + if (device != null) + { + device.Dispose(); + device = null; + } + + if (gdiFont != null) + { + gdiFont.Dispose(); + gdiFont = null; + } + } + + private void SetManagedDevice(IntPtr unmanagedDevice) + { + // Start by freeing everything + FreeResources(); + + // Create a managed Device from the unmanaged pointer + // The constructor don't call IUnknown.AddRef but the "destructor" seem to call IUnknown.Release + // Direct3D seem to be happier with that according to the DirectX log + Marshal.AddRef(unmanagedDevice); + this.unmanagedDevice = unmanagedDevice; + device = new Device(unmanagedDevice); + + // Create helper objects to draw over the video + sprite = new Sprite(device); + gdiFont = new System.Drawing.Font("Tahoma", 15); + d3dFont = new Direct3D.Font(device, gdiFont); + + // Load a bitmap (the spider) from embedded resources. This is a png file with alpha transparency + using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("DirectShowLib.Sample.redspider.png")) + { + spiderTex = TextureLoader.FromStream(device, stream, D3DX.Default, D3DX.Default, D3DX.Default, D3DX.Default, Usage.None, Format.A8R8G8B8, Pool.Default, Filter.None, Filter.None, 0); + SurfaceDescription spiderDesc = spiderTex.GetLevelDescription(0); + spiderSize = new Size(spiderDesc.Width, spiderDesc.Height); + } + } + + } +} diff --git a/Samples/VMR9/VMR9Compositor/MainForm.Designer.cs b/Samples/VMR9/VMR9Compositor/MainForm.Designer.cs new file mode 100644 index 0000000..f9e7b6b --- /dev/null +++ b/Samples/VMR9/VMR9Compositor/MainForm.Designer.cs @@ -0,0 +1,143 @@ +namespace DirectShowLib.Sample +{ + partial class MainForm + { + /// + /// Variable nécessaire au concepteur. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Nettoyage des ressources utilisées. + /// + /// true si les ressources managées doivent être supprimées ; sinon, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Code généré par le Concepteur Windows Form + + /// + /// Méthode requise pour la prise en charge du concepteur - ne modifiez pas + /// le contenu de cette méthode avec l'éditeur de code. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.menuFile = new System.Windows.Forms.ToolStripMenuItem(); + this.menuFileOpen = new System.Windows.Forms.ToolStripMenuItem(); + this.menuFileClose = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.menuFileQuit = new System.Windows.Forms.ToolStripMenuItem(); + this.menuAbout = new System.Windows.Forms.ToolStripMenuItem(); + this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + this.renderingPanel = new System.Windows.Forms.Panel(); + this.menuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuFile, + this.menuAbout}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(640, 24); + this.menuStrip1.TabIndex = 0; + this.menuStrip1.Text = "menuStrip1"; + // + // menuFile + // + this.menuFile.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuFileOpen, + this.menuFileClose, + this.toolStripSeparator1, + this.menuFileQuit}); + this.menuFile.Name = "menuFile"; + this.menuFile.Size = new System.Drawing.Size(35, 20); + this.menuFile.Text = "&File"; + this.menuFile.TextDirection = System.Windows.Forms.ToolStripTextDirection.Horizontal; + // + // menuFileOpen + // + this.menuFileOpen.Name = "menuFileOpen"; + this.menuFileOpen.Size = new System.Drawing.Size(111, 22); + this.menuFileOpen.Text = "&Open"; + this.menuFileOpen.Click += new System.EventHandler(this.menuFileOpen_Click); + // + // menuFileClose + // + this.menuFileClose.Name = "menuFileClose"; + this.menuFileClose.Size = new System.Drawing.Size(152, 22); + this.menuFileClose.Text = "&Close"; + this.menuFileClose.Click += new System.EventHandler(this.menuFileClose_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(108, 6); + // + // menuFileQuit + // + this.menuFileQuit.Name = "menuFileQuit"; + this.menuFileQuit.Size = new System.Drawing.Size(111, 22); + this.menuFileQuit.Text = "&Quit"; + this.menuFileQuit.Click += new System.EventHandler(this.menuFileQuit_Click); + // + // menuAbout + // + this.menuAbout.Name = "menuAbout"; + this.menuAbout.Size = new System.Drawing.Size(48, 20); + this.menuAbout.Text = "&About"; + this.menuAbout.Click += new System.EventHandler(this.menuAbout_Click); + // + // openFileDialog1 + // + this.openFileDialog1.Filter = resources.GetString("openFileDialog1.Filter"); + // + // renderingPanel + // + this.renderingPanel.Dock = System.Windows.Forms.DockStyle.Fill; + this.renderingPanel.Location = new System.Drawing.Point(0, 24); + this.renderingPanel.Name = "renderingPanel"; + this.renderingPanel.Size = new System.Drawing.Size(640, 456); + this.renderingPanel.TabIndex = 1; + // + // MainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(640, 480); + this.Controls.Add(this.renderingPanel); + this.Controls.Add(this.menuStrip1); + this.MainMenuStrip = this.menuStrip1; + this.Name = "MainForm"; + this.Text = "VMR9 Compositor"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem menuFile; + private System.Windows.Forms.ToolStripMenuItem menuFileOpen; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripMenuItem menuFileQuit; + private System.Windows.Forms.ToolStripMenuItem menuFileClose; + private System.Windows.Forms.OpenFileDialog openFileDialog1; + private System.Windows.Forms.ToolStripMenuItem menuAbout; + private System.Windows.Forms.Panel renderingPanel; + } +} + diff --git a/Samples/VMR9/VMR9Compositor/MainForm.cs b/Samples/VMR9/VMR9Compositor/MainForm.cs new file mode 100644 index 0000000..6f21281 --- /dev/null +++ b/Samples/VMR9/VMR9Compositor/MainForm.cs @@ -0,0 +1,236 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +using Microsoft.Win32; + +using DirectShowLib; + +namespace DirectShowLib.Sample +{ + public partial class MainForm : Form + { + private IFilterGraph2 graphBuilder; + private DsROTEntry rot; + private IMediaControl mediaControl; + + private IBaseFilter vmr9; + private IVMRWindowlessControl9 windowlessCtrl; + + private Compositor compositor; + + public MainForm() + { + InitializeComponent(); + } + + private void BuildGraph(string filename) + { + int hr = 0; + + try + { + graphBuilder = (IFilterGraph2)new FilterGraph(); + mediaControl = (IMediaControl)graphBuilder; + + rot = new DsROTEntry(graphBuilder); + + vmr9 = (IBaseFilter)new VideoMixingRenderer9(); + + ConfigureVMR9InWindowlessMode(); + + hr = graphBuilder.AddFilter(vmr9, "Video Mixing Renderer 9"); + DsError.ThrowExceptionForHR(hr); + + hr = graphBuilder.RenderFile(filename, null); + DsError.ThrowExceptionForHR(hr); + + RunGraph(); + } + catch (Exception e) + { + CloseInterfaces(); + MessageBox.Show("An error occured during the graph building : \r\n\r\n" + e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void ConfigureVMR9InWindowlessMode() + { + int hr = 0; + + IVMRFilterConfig9 filterConfig = (IVMRFilterConfig9)vmr9; + + // Must be called before calling SetImageCompositor + hr = filterConfig.SetNumberOfStreams(1); + DsError.ThrowExceptionForHR(hr); + + // Create an instance of the Compositor + compositor = new Compositor(); + + // Configure the filter with the Compositor + hr = filterConfig.SetImageCompositor(compositor); + DsError.ThrowExceptionForHR(hr); + + // Change VMR9 mode to Windowless + hr = filterConfig.SetRenderingMode(VMR9Mode.Windowless); + DsError.ThrowExceptionForHR(hr); + + windowlessCtrl = (IVMRWindowlessControl9)vmr9; + + // Set rendering window + hr = windowlessCtrl.SetVideoClippingWindow(renderingPanel.Handle); + DsError.ThrowExceptionForHR(hr); + + // Set Aspect-Ratio + hr = windowlessCtrl.SetAspectRatioMode(VMR9AspectRatioMode.LetterBox); + DsError.ThrowExceptionForHR(hr); + + // Add delegates for Windowless operations + AddHandlers(); + + // Call the resize handler to configure the output size + MainForm_ResizeMove(null, null); + } + + private void CloseInterfaces() + { + if (mediaControl != null) + mediaControl.Stop(); + + if (rot != null) + { + rot.Dispose(); + rot = null; + } + + RemoveHandlers(); + + if (compositor != null) + { + compositor.Dispose(); + compositor = null; + } + + if (vmr9 != null) + { + Marshal.ReleaseComObject(vmr9); + vmr9 = null; + windowlessCtrl = null; + } + + if (graphBuilder != null) + { + Marshal.ReleaseComObject(graphBuilder); + graphBuilder = null; + mediaControl = null; + } + + } + + private void RunGraph() + { + if (mediaControl != null) + { + int hr = mediaControl.Run(); + DsError.ThrowExceptionForHR(hr); + } + } + + private void StopGraph() + { + if (mediaControl != null) + { + int hr = mediaControl.Stop(); + DsError.ThrowExceptionForHR(hr); + } + } + + private void AddHandlers() + { + // Add handlers for VMR purpose + renderingPanel.Paint += new PaintEventHandler(MainForm_Paint); // for WM_PAINT + renderingPanel.Resize += new EventHandler(MainForm_ResizeMove); // for WM_SIZE + renderingPanel.Move += new EventHandler(MainForm_ResizeMove); // for WM_MOVE + SystemEvents.DisplaySettingsChanged += new EventHandler(SystemEvents_DisplaySettingsChanged); // for WM_DISPLAYCHANGE + } + + private void RemoveHandlers() + { + // remove handlers when they are no more needed + renderingPanel.Paint -= new PaintEventHandler(MainForm_Paint); + renderingPanel.Resize -= new EventHandler(MainForm_ResizeMove); + renderingPanel.Move -= new EventHandler(MainForm_ResizeMove); + SystemEvents.DisplaySettingsChanged -= new EventHandler(SystemEvents_DisplaySettingsChanged); + } + + private void MainForm_Paint(object sender, PaintEventArgs e) + { + if (windowlessCtrl != null) + { + IntPtr hdc = e.Graphics.GetHdc(); + int hr = windowlessCtrl.RepaintVideo(renderingPanel.Handle, hdc); + e.Graphics.ReleaseHdc(hdc); + } + } + + private void MainForm_ResizeMove(object sender, EventArgs e) + { + if (windowlessCtrl != null) + { + int hr = windowlessCtrl.SetVideoPosition(null, DsRect.FromRectangle(renderingPanel.ClientRectangle)); + } + } + + private void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e) + { + if (windowlessCtrl != null) + { + int hr = windowlessCtrl.DisplayModeChanged(); + } + } + + private void menuFileQuit_Click(object sender, EventArgs e) + { + CloseInterfaces(); + this.Close(); + } + + private void menuFileOpen_Click(object sender, EventArgs e) + { + if (openFileDialog1.ShowDialog() == DialogResult.OK) + { + CloseInterfaces(); + BuildGraph(openFileDialog1.FileName); + } + } + + private void menuFileClose_Click(object sender, EventArgs e) + { + CloseInterfaces(); + } + + private void MainForm_FormClosing(object sender, FormClosingEventArgs e) + { + CloseInterfaces(); + } + + private void menuAbout_Click(object sender, EventArgs e) + { + string title = "About VMR9 Compositor Sample"; + string text = "DirectShow.Net VMR9 Compositor Sample"; + + AboutBox.Show(title, text); + } + + } +} \ No newline at end of file diff --git a/Samples/VMR9/VMR9Compositor/MainForm.resx b/Samples/VMR9/VMR9Compositor/MainForm.resx new file mode 100644 index 0000000..21b0466 --- /dev/null +++ b/Samples/VMR9/VMR9Compositor/MainForm.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 126, 17 + + + Video Files (*.avi; *.qt; *.mov; *.mpg; *.mpeg; *.m1v; *.wmv)|*.avi; *.qt; *.mov; *.mpg; *.mpeg; *.m1v; *.wmv|Audio files (*.wav; *.mpa; *.mp2; *.mp3; *.au; *.aif; *.aiff; *.snd)|*.wav; *.mpa; *.mp2; *.mp3; *.au; *.aif; *.aiff; *.snd|MIDI Files (*.mid, *.midi, *.rmi)|*.mid; *.midi; *.rmi|Image Files (*.jpg, *.bmp, *.gif, *.tga)|*.jpg; *.bmp; *.gif; *.tga|All Files (*.*)|*.* + + \ No newline at end of file diff --git a/Samples/VMR9/VMR9Compositor/Program.cs b/Samples/VMR9/VMR9Compositor/Program.cs new file mode 100644 index 0000000..2e805df --- /dev/null +++ b/Samples/VMR9/VMR9Compositor/Program.cs @@ -0,0 +1,30 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Windows.Forms; + +namespace DirectShowLib.Sample +{ + static class Program + { + /// + /// Point d'entrée principal de l'application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + using (MainForm form = new MainForm()) + { + Application.Run(form); + } + } + } +} \ No newline at end of file diff --git a/Samples/VMR9/VMR9Compositor/Properties/AssemblyInfo.cs b/Samples/VMR9/VMR9Compositor/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..290a7cf --- /dev/null +++ b/Samples/VMR9/VMR9Compositor/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Les informations générales relatives à un assembly dépendent de +// l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations +// associées à un assembly. +[assembly: AssemblyTitle("Vmr9Compositor")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Vmr9Compositor")] +[assembly: AssemblyCopyright("Copyright © 2006")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly +// aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de +// COM, affectez la valeur true à l'attribut ComVisible sur ce type. +[assembly: ComVisible(false)] + +// Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM +[assembly: Guid("bc8a12b1-f648-41dd-8034-3fc4a5d3dd24")] + +// Les informations de version pour un assembly se composent des quatre valeurs suivantes : +// +// Version principale +// Version secondaire +// Numéro de build +// Révision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Samples/VMR9/VMR9Compositor/Properties/Resources.Designer.cs b/Samples/VMR9/VMR9Compositor/Properties/Resources.Designer.cs new file mode 100644 index 0000000..6b472fd --- /dev/null +++ b/Samples/VMR9/VMR9Compositor/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace DirectShowLib.Sample.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DirectShowLib.Sample.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Samples/VMR9/VMR9Compositor/Properties/Resources.resx b/Samples/VMR9/VMR9Compositor/Properties/Resources.resx new file mode 100644 index 0000000..04e2214 --- /dev/null +++ b/Samples/VMR9/VMR9Compositor/Properties/Resources.resx @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + \ No newline at end of file diff --git a/Samples/VMR9/VMR9Compositor/Properties/Settings.Designer.cs b/Samples/VMR9/VMR9Compositor/Properties/Settings.Designer.cs new file mode 100644 index 0000000..7ca5893 --- /dev/null +++ b/Samples/VMR9/VMR9Compositor/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace DirectShowLib.Sample.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Samples/VMR9/VMR9Compositor/Properties/Settings.settings b/Samples/VMR9/VMR9Compositor/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Samples/VMR9/VMR9Compositor/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Samples/VMR9/VMR9Compositor/Vmr9Compositor.csproj b/Samples/VMR9/VMR9Compositor/Vmr9Compositor.csproj new file mode 100644 index 0000000..9c5f01b --- /dev/null +++ b/Samples/VMR9/VMR9Compositor/Vmr9Compositor.csproj @@ -0,0 +1,137 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {88B15C8B-9377-4CCB-AA9B-4C3F9D923713} + WinExe + Properties + DirectShowLib.Sample + Vmr9Compositor + v2.0 + + + + + 2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + Form + + + + Form + + + MainForm.cs + + + + + Designer + MainForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + Aboutbox.cs + Designer + + + Always + + + + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + \ No newline at end of file diff --git a/Samples/VMR9/VMR9Compositor/Vmr9Compositor.sln b/Samples/VMR9/VMR9Compositor/Vmr9Compositor.sln new file mode 100644 index 0000000..faad023 --- /dev/null +++ b/Samples/VMR9/VMR9Compositor/Vmr9Compositor.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vmr9Compositor", "Vmr9Compositor.csproj", "{88B15C8B-9377-4CCB-AA9B-4C3F9D923713}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {88B15C8B-9377-4CCB-AA9B-4C3F9D923713}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {88B15C8B-9377-4CCB-AA9B-4C3F9D923713}.Debug|Any CPU.Build.0 = Debug|Any CPU + {88B15C8B-9377-4CCB-AA9B-4C3F9D923713}.Release|Any CPU.ActiveCfg = Release|Any CPU + {88B15C8B-9377-4CCB-AA9B-4C3F9D923713}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/VMR9/VMR9Compositor/readme.txt b/Samples/VMR9/VMR9Compositor/readme.txt new file mode 100644 index 0000000..d1ebd2d --- /dev/null +++ b/Samples/VMR9/VMR9Compositor/readme.txt @@ -0,0 +1,24 @@ +--------------------------------------------------------------------- +VMR9Compositor + +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + +--------------------------------------------------------------------- + +This sample is a demonstration of the poorly documented VMR9 custom compositor feature. + +The main feature of this sample is an implementation of the IVMRImageCompositor9 interface. +This interface is documented here : http://windowssdk.msdn.microsoft.com/en-us/library/ms787035.aspx + +The purpose of the compositor object in the VMR9 filter is to composite multiple images coming from the input pins into one image that is next send to the Allocator/Presenter object. + +As for most things related to the VMR9 filter, this sample make extensive use of the Managed DirectX. Basic knowledge is required to fully understand this sample. + +This custom Compositor object from this sample just composite the images coming from the first pin but it also demonstrate how to add text or a moving watermark over the video. It can provide similar fonctionnality than the Bitmap Mixer sample. + +This sample use a classic windowless configuration to display the composited video into a panel. + +Finally, i want to thanks Daniel for his tutorial that greatly inspirated this sample : http://www.a2ii.com/tech/directx/tutorialDS10.htm (Daniel : Check how i have resolve the ref count problem) diff --git a/Samples/VMR9/VMR9Compositor/redspider.png b/Samples/VMR9/VMR9Compositor/redspider.png new file mode 100644 index 0000000000000000000000000000000000000000..18e3d77f7dd137ff6dda402f2044ea425b78dae6 GIT binary patch literal 1859 zcmV-J2fX-+P)o@<6X_eW!pypDJK; zmiHprcx3tONOpBc5RR7b1u#|1CzfX;>0GdUZ24>ew_K#Vs3X7%FWZmXmR|*+^Crdq z9>W2aeluwo_%eWNfqiIae6oVCT23rq^I)oo0j@^UTSIv#z9_I|Q;56Li^>mJevJw) zcyLRIIgY5ijFktuiyquKVw%yT0K7_CcEsbPeZ*`=*1v^v-%2wAOu59ysn`y9j)D(8 zmYI)L%_`t%&{hg4n@GYrzI%W*mo%nUN&-mP{nc= zyTaA;P##C)&YDf`CGtM6cxLmz-V!jK5k!dDhxS*x2zNan)UjK0;9z_^*QVd z$_hDPFrv{hNvm%t1jrQuS`y}IZFbm!ONu)CLnJ;r+vkUtnV{k z5^!~fb8bptYP~F^!pp8Mh8rSHhP@=%vBYq}jhRxw0b9(gkdS;(a%Xz5SxU3G7HcW! z#}J|w<32Cg!*_N~d*V|!?ejiF$!8AzAhT)O$BUN5z87+W&jG8BmfFA;A0oIi?%iz* zts9HCQBRrZ9)fK;w2R}{3RfP5&-A!Lz2^B)9Yb9JT6xpxQr(PT9k7QC&(K=hG&m;x zWBEf{!9NQ-0G$A7CyWEGxfqmW>E{6~TCgudh0mLGISnItk)th`4PKb^Tp$}0vT3e@ zpYIy?)CV^GP*UU`K?f)tR3#OLPt{&rPC7zoK!tv>{M4~REJV2-fX7dD%NMc2U7Y}T zL4SZFEdPuS*)1YO(*+>JCQQ1=1{FW;g^!k6ChazlEw7j4Y%xqpdMU?OCwIY7HkWNi+Rv9=I$#s!3<$a)^P5*R6xchi zb%5mUCOYQ~!SWVfQp!?C5|hVM-A62Hr#()8sdYdic-ocQA2QsiLRKzj@)B#)``Uj~%~BQ%PH%oph$9Q61orFXj0)$8WBB zIUVrObcWh_LD4hzohM1&g@}Uq`&|Ar;k}FOJFHnAs2osA4;SvTpC<%GPuX|gRU`wo z#NX%g*M;}^j?u$Xo@;wa=V>f(MZnUzex8-px|{`SOdg%yb_9DW4msi-Lg%I^E+b#C zpCutQT53!VELe)(7I}s5Q=;avqqxl(gUZY0J78Zj4~|9pyI)w*IU`7R^zl zI|z@MoGS$z;6GuTL=dbGh6NnW#jC6gE=3&YtUTaHm>hZs@ws5faMHex30|2CoeO+L zovGViulq*pB;Dj#^OT<@wq1{2d7>z5y;%=EQ-)TchV=wC+Y;Eys&gdzX{002ovPDHLkV1g@aU>E=Z literal 0 HcmV?d00001 diff --git a/Samples/VMR9/VMR9Snapper/App.ico b/Samples/VMR9/VMR9Snapper/App.ico new file mode 100644 index 0000000000000000000000000000000000000000..3a5525fd794f7a7c5c8e6187f470ea3af38cd2b6 GIT binary patch literal 1078 zcmeHHJr05}7=1t!Hp3A*8IHkVf+j?-!eHY14Gtcw1Eb*_9>Bq^zETJ@GKj{_2j4$w zo9}xCh!8{T3=X##Skq>ikMjsvB|y%crWBM2iW(4pI}c%z6%lW!=~4v77#3{z!dmB1 z__&l)-{KUYR+|8|;wB^R|9ET$J@(@=#rd^=)qs85?vAy(PSF5CyNkus435LVkZ$rj zNw|JG-P7^hF<(;#o*Vk}5R#e|^13tBbQkeF?djULtvqyxd3<{9 literal 0 HcmV?d00001 diff --git a/Samples/VMR9/VMR9Snapper/AssemblyInfo.cs b/Samples/VMR9/VMR9Snapper/AssemblyInfo.cs new file mode 100644 index 0000000..76201ae --- /dev/null +++ b/Samples/VMR9/VMR9Snapper/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// Les informations générales relatives à un assembly dépendent de +// l'ensemble d'attributs suivant. Pour modifier les informations +// associées à un assembly, changez les valeurs de ces attributs. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Les informations de version pour un assembly se composent des quatre valeurs suivantes : +// +// Version principale +// Version secondaire +// Numéro de build +// Révision +// +// Vous pouvez spécifier toutes les valeurs ou indiquer des numéros de révision et de build par défaut +// en utilisant '*', comme ci-dessous : + +[assembly: AssemblyVersion("1.0.*")] + +// +// Pour signer votre assembly, vous devez spécifier la clé à utiliser. Consultez +// la documentation Microsoft .NET Framework pour plus d'informations sur la signature d'un assembly. +// +// Utilisez les attributs ci-dessous pour contrôler la clé utilisée lors de la signature. +// +// Remarques : +// (*) Si aucune clé n'est spécifiée, l'assembly n'est pas signé. +// (*) KeyName fait référence à une clé installée dans le fournisseur de +// services cryptographiques (CSP) de votre ordinateur. KeyFile fait référence à un fichier qui contient +// une clé. +// (*) Si les valeurs de KeyFile et de KeyName sont spécifiées, le +// traitement suivant se produit : +// (1) Si KeyName se trouve dans le CSP, la clé est utilisée. +// (2) Si KeyName n'existe pas mais que KeyFile existe, la clé +// de KeyFile est installée dans le CSP et utilisée. +// (*) Pour créer KeyFile, vous pouvez utiliser l'utilitaire sn.exe (Strong Name, Nom fort). +// Lors de la spécification de KeyFile, son emplacement doit être +// relatif au répertoire de sortie du projet qui est +// %Project Directory%\obj\. Par exemple, si votre KeyFile se trouve +// dans le répertoire du projet, vous devez spécifier l'attribut +// AssemblyKeyFile sous la forme [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) DelaySign (signature différée) est une option avancée. Pour plus d'informations, consultez la +// documentation Microsoft .NET Framework. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Samples/VMR9/VMR9Snapper/MainForm.cs b/Samples/VMR9/VMR9Snapper/MainForm.cs new file mode 100644 index 0000000..27e1fc0 --- /dev/null +++ b/Samples/VMR9/VMR9Snapper/MainForm.cs @@ -0,0 +1,529 @@ +/**************************************************************************** +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +*****************************************************************************/ + +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Windows.Forms; +using System.Runtime.InteropServices; + +using DirectShowLib; + +using Microsoft.Win32; + +namespace DirectShowLib.Sample +{ + public class MainForm : System.Windows.Forms.Form + { + private System.Windows.Forms.MainMenu mainMenu; + private System.Windows.Forms.OpenFileDialog openFileDialog; + private System.Windows.Forms.MenuItem menuFile; + private System.Windows.Forms.MenuItem menuFileOpen; + private System.Windows.Forms.MenuItem menuFileClose; + private System.Windows.Forms.MenuItem menuItem1; + private System.Windows.Forms.MenuItem menuFileExit; + private IContainer components; + + // DirectShow stuff + private IFilterGraph2 graphBuilder = null; + private IMediaControl mediaControl = null; + private IBaseFilter vmr9 = null; + private IVMRWindowlessControl9 windowlessCtrl = null; + private bool handlersAdded = false; + private SaveFileDialog saveFileDialog; + private TableLayoutPanel tableLayoutPanelMain; + private TableLayoutPanel tableLayoutPanelButtons; + private Button btnSnap; + private Button btnOpen; + private Button btnPlay; + private Button btnPause; + private Panel panel1; // Needed to remove delegates + + // Menus stuff + private MenuItem menuSnap; + + public MainForm() + { + InitializeComponent(); + + // We paint the windows ourself + this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); + + this.saveFileDialog.DefaultExt = ".jpg"; + this.saveFileDialog.AddExtension = true; + this.saveFileDialog.CheckPathExists = true; + this.saveFileDialog.Filter += "Jpeg files (*.jpg)|*.jpg"; + } + + /// + /// Nettoyage des ressources utilisées. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if (components != null) + { + components.Dispose(); + } + } + + // Clean-up DirectShow interfaces + CloseInterfaces(); + + base.Dispose( disposing ); + } + + #region Code généré par le Concepteur Windows Form + /// + /// Méthode requise pour la prise en charge du concepteur - ne modifiez pas + /// le contenu de cette méthode avec l'éditeur de code. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); + this.mainMenu = new System.Windows.Forms.MainMenu(this.components); + this.menuFile = new System.Windows.Forms.MenuItem(); + this.menuFileOpen = new System.Windows.Forms.MenuItem(); + this.menuSnap = new System.Windows.Forms.MenuItem(); + this.menuFileClose = new System.Windows.Forms.MenuItem(); + this.menuItem1 = new System.Windows.Forms.MenuItem(); + this.menuFileExit = new System.Windows.Forms.MenuItem(); + this.openFileDialog = new System.Windows.Forms.OpenFileDialog(); + this.saveFileDialog = new System.Windows.Forms.SaveFileDialog(); + this.tableLayoutPanelMain = new System.Windows.Forms.TableLayoutPanel(); + this.tableLayoutPanelButtons = new System.Windows.Forms.TableLayoutPanel(); + this.btnSnap = new System.Windows.Forms.Button(); + this.btnOpen = new System.Windows.Forms.Button(); + this.btnPause = new System.Windows.Forms.Button(); + this.btnPlay = new System.Windows.Forms.Button(); + this.panel1 = new System.Windows.Forms.Panel(); + this.tableLayoutPanelMain.SuspendLayout(); + this.tableLayoutPanelButtons.SuspendLayout(); + this.SuspendLayout(); + // + // mainMenu + // + this.mainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuFile}); + // + // menuFile + // + this.menuFile.Index = 0; + this.menuFile.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.menuFileOpen, + this.menuSnap, + this.menuFileClose, + this.menuItem1, + this.menuFileExit}); + this.menuFile.Text = "File"; + // + // menuFileOpen + // + this.menuFileOpen.Index = 0; + this.menuFileOpen.Text = "Open Clip..."; + this.menuFileOpen.Click += new System.EventHandler(this.menuFileOpen_Click); + // + // menuSnap + // + this.menuSnap.Index = 1; + this.menuSnap.Text = "Save image..."; + this.menuSnap.Click += new System.EventHandler(this.menuSnap_Click); + // + // menuFileClose + // + this.menuFileClose.Index = 2; + this.menuFileClose.Text = "Close Clip"; + this.menuFileClose.Click += new System.EventHandler(this.menuFileClose_Click); + // + // menuItem1 + // + this.menuItem1.Index = 3; + this.menuItem1.Text = "-"; + // + // menuFileExit + // + this.menuFileExit.Index = 4; + this.menuFileExit.Text = "Exit"; + this.menuFileExit.Click += new System.EventHandler(this.menuFileExit_Click); + // + // openFileDialog + // + this.openFileDialog.Filter = resources.GetString("openFileDialog.Filter"); + // + // tableLayoutPanelMain + // + this.tableLayoutPanelMain.ColumnCount = 1; + this.tableLayoutPanelMain.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanelMain.Controls.Add(this.tableLayoutPanelButtons, 0, 1); + this.tableLayoutPanelMain.Controls.Add(this.panel1, 0, 0); + this.tableLayoutPanelMain.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanelMain.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanelMain.Name = "tableLayoutPanelMain"; + this.tableLayoutPanelMain.RowCount = 2; + this.tableLayoutPanelMain.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 92.10526F)); + this.tableLayoutPanelMain.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 7.894737F)); + this.tableLayoutPanelMain.Size = new System.Drawing.Size(640, 480); + this.tableLayoutPanelMain.TabIndex = 0; + // + // tableLayoutPanelButtons + // + this.tableLayoutPanelButtons.ColumnCount = 4; + this.tableLayoutPanelButtons.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F)); + this.tableLayoutPanelButtons.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F)); + this.tableLayoutPanelButtons.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F)); + this.tableLayoutPanelButtons.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F)); + this.tableLayoutPanelButtons.Controls.Add(this.btnPlay, 0, 0); + this.tableLayoutPanelButtons.Controls.Add(this.btnSnap, 3, 0); + this.tableLayoutPanelButtons.Controls.Add(this.btnOpen, 2, 0); + this.tableLayoutPanelButtons.Controls.Add(this.btnPause, 1, 0); + this.tableLayoutPanelButtons.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanelButtons.Location = new System.Drawing.Point(3, 445); + this.tableLayoutPanelButtons.Name = "tableLayoutPanelButtons"; + this.tableLayoutPanelButtons.RowCount = 1; + this.tableLayoutPanelButtons.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanelButtons.Size = new System.Drawing.Size(634, 32); + this.tableLayoutPanelButtons.TabIndex = 0; + // + // btnSnap + // + this.btnSnap.BackColor = System.Drawing.Color.Transparent; + this.btnSnap.Dock = System.Windows.Forms.DockStyle.Fill; + this.btnSnap.Location = new System.Drawing.Point(477, 3); + this.btnSnap.Name = "btnSnap"; + this.btnSnap.Size = new System.Drawing.Size(154, 26); + this.btnSnap.TabIndex = 0; + this.btnSnap.Text = "Save image ..."; + this.btnSnap.UseVisualStyleBackColor = false; + this.btnSnap.Click += new System.EventHandler(this.btnSnap_Click); + // + // btnOpen + // + this.btnOpen.BackColor = System.Drawing.Color.Transparent; + this.btnOpen.Dock = System.Windows.Forms.DockStyle.Fill; + this.btnOpen.Location = new System.Drawing.Point(319, 3); + this.btnOpen.Name = "btnOpen"; + this.btnOpen.Size = new System.Drawing.Size(152, 26); + this.btnOpen.TabIndex = 1; + this.btnOpen.Text = "Open..."; + this.btnOpen.UseVisualStyleBackColor = false; + this.btnOpen.Click += new System.EventHandler(this.btnOpen_Click); + // + // btnPause + // + this.btnPause.BackColor = System.Drawing.Color.Transparent; + this.btnPause.Dock = System.Windows.Forms.DockStyle.Fill; + this.btnPause.Location = new System.Drawing.Point(161, 3); + this.btnPause.Name = "btnPause"; + this.btnPause.Size = new System.Drawing.Size(152, 26); + this.btnPause.TabIndex = 2; + this.btnPause.Text = "Pause"; + this.btnPause.UseVisualStyleBackColor = false; + this.btnPause.Click += new System.EventHandler(this.btnPause_Click); + // + // btnPlay + // + this.btnPlay.BackColor = System.Drawing.Color.Transparent; + this.btnPlay.Dock = System.Windows.Forms.DockStyle.Fill; + this.btnPlay.Location = new System.Drawing.Point(3, 3); + this.btnPlay.Name = "btnPlay"; + this.btnPlay.Size = new System.Drawing.Size(152, 26); + this.btnPlay.TabIndex = 3; + this.btnPlay.Text = "Play"; + this.btnPlay.UseVisualStyleBackColor = false; + this.btnPlay.Click += new System.EventHandler(this.btnPlay_Click); + // + // panel1 + // + this.panel1.BackColor = System.Drawing.SystemColors.ControlDarkDark; + this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel1.Location = new System.Drawing.Point(3, 3); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(634, 436); + this.panel1.TabIndex = 1; + // + // MainForm + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224))))); + this.ClientSize = new System.Drawing.Size(640, 480); + this.Controls.Add(this.tableLayoutPanelMain); + this.Menu = this.mainMenu; + this.Name = "MainForm"; + this.Text = "VMR Snapper"; + this.tableLayoutPanelMain.ResumeLayout(false); + this.tableLayoutPanelButtons.ResumeLayout(false); + this.ResumeLayout(false); + + } + #endregion + + private void CloseInterfaces() + { + if (mediaControl != null) + mediaControl.Stop(); + + if (handlersAdded) + RemoveHandlers(); + + if (vmr9 != null) + { + Marshal.ReleaseComObject(vmr9); + vmr9 = null; + windowlessCtrl = null; + } + + if (graphBuilder != null) + { + Marshal.ReleaseComObject(graphBuilder); + graphBuilder = null; + mediaControl = null; + } + + } + + private void BuildGraph(string fileName) + { + int hr = 0; + + try + { + graphBuilder = (IFilterGraph2) new FilterGraph(); + mediaControl = (IMediaControl) graphBuilder; + + vmr9 = (IBaseFilter) new VideoMixingRenderer9(); + + ConfigureVMR9InWindowlessMode(); + + hr = graphBuilder.AddFilter(vmr9, "Video Mixing Renderer 9"); + DsError.ThrowExceptionForHR(hr); + + hr = graphBuilder.RenderFile(fileName, null); + DsError.ThrowExceptionForHR(hr); + } + catch(Exception e) + { + CloseInterfaces(); + MessageBox.Show("An error occured during the graph building : \r\n\r\n" + e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void ConfigureVMR9InWindowlessMode() + { + int hr = 0; + + IVMRFilterConfig9 filterConfig = (IVMRFilterConfig9) vmr9; + + // Not really needed for VMR9 but don't forget calling it with VMR7 + hr = filterConfig.SetNumberOfStreams(1); + DsError.ThrowExceptionForHR(hr); + + // Change VMR9 mode to Windowless + hr = filterConfig.SetRenderingMode(VMR9Mode.Windowless); + DsError.ThrowExceptionForHR(hr); + + windowlessCtrl = (IVMRWindowlessControl9) vmr9; + + // Set "Parent" window + hr = windowlessCtrl.SetVideoClippingWindow(this.panel1.Handle); + DsError.ThrowExceptionForHR(hr); + + // Set Aspect-Ratio + hr = windowlessCtrl.SetAspectRatioMode(VMR9AspectRatioMode.LetterBox); + DsError.ThrowExceptionForHR(hr); + + // Add delegates for Windowless operations + AddHandlers(); + + // Call the resize handler to configure the output size + MainForm_ResizeMove(null, null); + } + + private void AddHandlers() + { + // Add handlers for VMR purpose + this.Paint += new PaintEventHandler(MainForm_Paint); // for WM_PAINT + this.Resize += new EventHandler(MainForm_ResizeMove); // for WM_SIZE + this.Move += new EventHandler(MainForm_ResizeMove); // for WM_MOVE + SystemEvents.DisplaySettingsChanged += new EventHandler(SystemEvents_DisplaySettingsChanged); // for WM_DISPLAYCHANGE + handlersAdded = true; + } + + private void RemoveHandlers() + { + // remove handlers when they are no more needed + handlersAdded = false; + this.Paint -= new PaintEventHandler(MainForm_Paint); + this.Resize -= new EventHandler(MainForm_ResizeMove); + this.Move -= new EventHandler(MainForm_ResizeMove); + SystemEvents.DisplaySettingsChanged -= new EventHandler(SystemEvents_DisplaySettingsChanged); + } + + private void RunGraph() + { + if (mediaControl != null) + { + int hr = mediaControl.Run(); + DsError.ThrowExceptionForHR(hr); + } + } + + private void StopGraph() + { + if (mediaControl != null) + { + int hr = mediaControl.Stop(); + DsError.ThrowExceptionForHR(hr); + } + } + + // Menus click handlers + private void menuFileOpen_Click(object sender, System.EventArgs e) + { + openFile(); + } + + private void openFile() + { + if (openFileDialog.ShowDialog() == DialogResult.OK) + { + CloseInterfaces(); + BuildGraph(openFileDialog.FileName); + RunGraph(); + } + } + + private void menuFileClose_Click(object sender, System.EventArgs e) + { + StopGraph(); + CloseInterfaces(); + this.Invalidate(); + } + + private void menuFileExit_Click(object sender, System.EventArgs e) + { + StopGraph(); + CloseInterfaces(); + this.Dispose(); + } + + private void MainForm_Paint(object sender, PaintEventArgs e) + { + if (windowlessCtrl != null) + { + IntPtr hdc = e.Graphics.GetHdc(); + int hr = windowlessCtrl.RepaintVideo(this.panel1.Handle, hdc); + e.Graphics.ReleaseHdc(hdc); + } + } + + private void MainForm_ResizeMove(object sender, EventArgs e) + { + if (windowlessCtrl != null) + { + int hr = windowlessCtrl.SetVideoPosition(null, DsRect.FromRectangle(this.panel1.ClientRectangle)); + } + } + + private void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e) + { + if (windowlessCtrl != null) + { + int hr = windowlessCtrl.DisplayModeChanged(); + } + } + + [STAThread] + static void Main() + { + using (MainForm form = new MainForm()) + { + Application.Run(form); + } + } + + private void menuSnap_Click(object sender, EventArgs e) + { + snapImage(); + + } + + private void snapImage() + { + if (windowlessCtrl != null) + { + IntPtr currentImage = IntPtr.Zero; + Bitmap bmp = null; + + try + { + int hr = windowlessCtrl.GetCurrentImage(out currentImage); + DsError.ThrowExceptionForHR(hr); + + if (currentImage != IntPtr.Zero) + { + BitmapInfoHeader structure = new BitmapInfoHeader(); + Marshal.PtrToStructure(currentImage, structure); + + bmp = new Bitmap(structure.Width, structure.Height, (structure.BitCount / 8) * structure.Width, System.Drawing.Imaging.PixelFormat.Format32bppArgb, new IntPtr(currentImage.ToInt64() + 40)); + bmp.RotateFlip(RotateFlipType.RotateNoneFlipY); + + if (saveFileDialog.ShowDialog() == DialogResult.OK) + { + bmp.Save(saveFileDialog.FileName.ToString(), System.Drawing.Imaging.ImageFormat.Jpeg); + } + } + } + catch (Exception anyException) + { + MessageBox.Show("Failed getting image: " + anyException.Message); + } + finally + { + if (bmp != null) + { + bmp.Dispose(); + } + + Marshal.FreeCoTaskMem(currentImage); + } + } + } + + private void btnPlay_Click(object sender, EventArgs e) + { + RunGraph(); + } + + private void btnPause_Click(object sender, EventArgs e) + { + pause(); + } + + private void pause() + { + if (mediaControl != null) + { + int hr = mediaControl.Pause(); + DsError.ThrowExceptionForHR(hr); + } + } + + private void btnOpen_Click(object sender, EventArgs e) + { + openFile(); + } + + private void btnSnap_Click(object sender, EventArgs e) + { + snapImage(); + } + + } +} diff --git a/Samples/VMR9/VMR9Snapper/MainForm.resx b/Samples/VMR9/VMR9Snapper/MainForm.resx new file mode 100644 index 0000000..38fbe36 --- /dev/null +++ b/Samples/VMR9/VMR9Snapper/MainForm.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 120, 17 + + + Video Files (*.avi; *.qt; *.mov; *.mpg; *.mpeg; *.m1v)|*.avi; *.qt; *.mov; *.mpg; *.mpeg; *.m1v|Audio files (*.wav; *.mpa; *.mp2; *.mp3; *.au; *.aif; *.aiff; *.snd)|*.wav; *.mpa; *.mp2; *.mp3; *.au; *.aif; *.aiff; *.snd|MIDI Files (*.mid, *.midi, *.rmi)|*.mid; *.midi; *.rmi|Image Files (*.jpg, *.bmp, *.gif, *.tga)|*.jpg; *.bmp; *.gif; *.tga|All Files (*.*)|*.* + + + 258, 17 + + \ No newline at end of file diff --git a/Samples/VMR9/VMR9Snapper/VMR9Snapper-2005.csproj b/Samples/VMR9/VMR9Snapper/VMR9Snapper-2005.csproj new file mode 100644 index 0000000..ba4d548 --- /dev/null +++ b/Samples/VMR9/VMR9Snapper/VMR9Snapper-2005.csproj @@ -0,0 +1,118 @@ + + + Local + 8.0.50727 + 2.0 + {4682D111-4503-448E-B5F4-93358502C229} + Debug + AnyCPU + App.ico + + + BitmapMixer + + + JScript + Grid + IE50 + false + WinExe + DirectShowLib.Sample + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\lib\DirectShowLib-2005.dll + + + + + System + + + System.Data + + + System.Drawing + + + System.Windows.Forms + + + System.XML + + + + + Code + + + Form + + + MainForm.cs + + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/VMR9/VMR9Snapper/VMR9Snapper-2005.sln b/Samples/VMR9/VMR9Snapper/VMR9Snapper-2005.sln new file mode 100644 index 0000000..fe23bc3 --- /dev/null +++ b/Samples/VMR9/VMR9Snapper/VMR9Snapper-2005.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VMR9Snapper-2005", "VMR9Snapper-2005.csproj", "{4682D111-4503-448E-B5F4-93358502C229}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4682D111-4503-448E-B5F4-93358502C229}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/VMR9/VMR9Snapper/VMR9Snapper-2008.sln b/Samples/VMR9/VMR9Snapper/VMR9Snapper-2008.sln new file mode 100644 index 0000000..87369d8 --- /dev/null +++ b/Samples/VMR9/VMR9Snapper/VMR9Snapper-2008.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VMR9Snapper-2008", "VMR9Snapper-2008.csproj", "{4682D111-4503-448E-B5F4-93358502C229}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4682D111-4503-448E-B5F4-93358502C229}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4682D111-4503-448E-B5F4-93358502C229}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/VMR9/VMR9Snapper/VMR9Snapper.csproj b/Samples/VMR9/VMR9Snapper/VMR9Snapper.csproj new file mode 100644 index 0000000..bc940ba --- /dev/null +++ b/Samples/VMR9/VMR9Snapper/VMR9Snapper.csproj @@ -0,0 +1,150 @@ + + + + Local + 8.0.50727 + 2.0 + {19113520-FF5B-4713-8CC6-3704817F1F48} + Debug + AnyCPU + App.ico + + + BitmapMixer + + + JScript + Grid + IE50 + false + WinExe + DirectShowLib.Sample + OnBuildSuccess + + + + + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;USING_NET20 + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE;USING_NET20 + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + + + System + + + System.Data + + + System.Drawing + + + System.Windows.Forms + + + System.XML + + + + + Code + + + Form + + + MainForm.cs + + + + + + + {ce009bfa-5ef6-4153-b2a1-2fa79698a9ae} + DirectShowLib + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + + + + + + + + \ No newline at end of file diff --git a/Samples/VMR9/VMR9Snapper/readme.txt b/Samples/VMR9/VMR9Snapper/readme.txt new file mode 100644 index 0000000..5c30352 --- /dev/null +++ b/Samples/VMR9/VMR9Snapper/readme.txt @@ -0,0 +1,21 @@ +--------------------------------------------------------------------- +VmrSnapper + +While the underlying libraries are covered by LGPL, this sample is released +as public domain. It is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. + +--------------------------------------------------------------------- + +VmrSnapper is an example of how to get a Bitmap from a video using VMR9. + +This sample uses the following DirectShow Interfaces : + + IFilterGraph2 + IMediaControl + IBaseFilter + IVMRWindowlessControl9 + IVMRFilterConfig9 + +This sample is based on the BitmapMixer sample. \ No newline at end of file diff --git a/Samples/lisezmoi-samples.txt b/Samples/lisezmoi-samples.txt new file mode 100644 index 0000000..0d85b20 --- /dev/null +++ b/Samples/lisezmoi-samples.txt @@ -0,0 +1,207 @@ +Programmes d'exemples pour DirectShowLib 2010-02-21 + +http://SourceForgeNet.SourceForge.net + +Cette archive contient une sélection de programmes d'exemples. Ces programmes étaient +dans le passé inclus avec la bibliothèque DirectShowLib mais avec la version 1.4 ils +ont été dissociés de celle-ci. + +Nous avons supprimé le support de vs2003 dans cette version. vs2005 est supporté depuis +deux ans mais il n'est plus installé par aucuns des développeurs. + +Nous avons ajoutés deux exemples depuis la précédente version : + + BlackList + EVRPlayer + +Voir les descriptions ci-dessous. + +Ces programmes ne doivent pas être considérés comme des applications de qualité +commerciale. Ils ont juste pour but d'illustrer comment utiliser une ou un groupe de +fonctionnalités particulières de DirectShow. Vous êtes libre de les améliorer ou de les +utiliser en partie dans votre code. Chaque exemple a (au moins) un fichier "readme"; Si +vous chercher des informations sur un des ces programmes, ils sont toujours un bon +endroit où commencer. + +Aussi, bien que DirectShowLib soit publiée sous licence LGPL, ces exemples sont dans le +domaine public; Utilisez-les comme bon vous semble. Tous ces programmes nécessitent la +bibliothèque DirectShowLib qui n'est pas incluse dans cette archive. + +Les gens qui ont écrit ces exemples trainent souvent la +http://sourceforge.net/forum/forum.php?forum_id=460697. Si vous avez des questions, +des commentaires ou juste envie de remercier ceux qui ont passé du temps à créer tout ça, +n'hésitez pas à y faire un tour. + +D'ailleurs, si vous avez des programmes d'exemples qui vous sembles avoir une valeur +pédagogique (ou si vous voulez en écrire), c'est aussi un bon endroit ou commencer. + +===================================================================================== + +Ceci est liste actuelle des programmes d'exemples acompagné d'une courte description. +Reportez vous au fichier readme.txt de chaque exemple pour plus de détails. + +Samples\BDA\DTViewer +-------------------- +Utilise BDA pour afficher de la télévision digitale dans un Form Windows. + + +Samples\Capture\CapWMV +---------------------- +Capturer depuis un périphérique d'acquisition vidéo vers des fichiers WMV. + + +Samples\Capture\DxLogo +---------------------- +Une application démontrant comment superposez un logo sur un flux de données. Elle +utilise un périphérique de capture comme source vidéo, et extrait le résultat dans un +fichier. + + +Samples\Capture\DxLogoVB +------------------------ +Il s'agit du même exemple que DxLogo mais écrit en Visual Basic. En dehors des problèmes +liés à la conversion de C# vers VB, ce n'est qu'un exercice trivial. + + +Samples\Capture\DxPropPages +--------------------------- +Démontre comment ajouter des filtres de compression vidéo à une capture vidéo, et +comment invoquer les pages de propriétés de périphériques de capture et de compresseurs +vidéo. + + +Samples\Capture\DxSnap +---------------------- +Utilise DirectShow pour prendre des instantanées de la "Still pin" d'un périphérique de +capture. Notez que MS encourage l'utilisation de WIA pour cela, mais si vous souhaitez +le faire avec DirectShow et C#, voici comment. + + +Samples\Capture\DxTuner +----------------------- +Montre comment capturer depuis des tuners TV, ainsi que comment changer de chaine. + + +Samples\Capture\PlayCap +----------------------- +Une traduction du programme PlayCap de DirectShow pour montrer à quoi cela peut +ressembler en C#. +Cette application crée une fenêtre de prévisualisation pour le premier périphérique de +capture vidéo localisé sur le système de l'utilisateur (s'il y'en a un). Elle démontre +par un exemple simple comment utiliser les interfaces ICaptureGraphBuilder2 et +ICreateDevEnum pour construire un graphe de capture. + + +Samples\DMO\DMOFlip +------------------ +Un objet DMO pouvant être utilisé dans un graph DirectShow. Cet objet DMO permet de +d'inverser la vidéo sur les axes X ou Y (ou les deux). Un fichier d'aide en anglais +(IMediaObjectImpl.chm) est fourni pour monter comment écrire un objet DMO soi-même. + + +Samples\DMO\DMOSplit +-------------------- +Un objet DMO qui sépare un signal audio stéréo en deux flux mono. + + +Samples\Editing\DESCombine +-------------------------- +Une bibliothèque de classe qui utilise DirectShow Editing Services pour combiner des +fichiers audio et vidéo (ou des parties de fichiers) en un seul fichier de sortie. Un +fichier d'aide en anglais (DESCombine.chm) est fournis pour utiliser cette classe. + + +Samples\Editing\DxScan +---------------------- +Une application qui scanne un fichier à la recherche de trames noires. + + +Samples\Misc\BlackList +---------------------- +Cet exemple illustre comment utiliser l'interface IAMGraphBuilderCallback pour rejeter +certains filtres durant la création d'un graph. Vous pouvez adapter cet exemple pour vos +besoins si vous savez que certains filtres sont connus pour endommager votre application. + + +Samples\Misc\DxWebCam +--------------------- +Le programme de WebCam du pauvre. Cette application s'exécute en tant que service Win32. +Il prend la sortie d'un graphe de capture, le convertie en flux de fichiers JPEG et +l'envoie via TCP/IP à une application cliente. + + +Samples\Misc\GSSF +----------------- +Une façon d'implémenter un filtre source en C#. Si vous avez des échantillons (par +exemple des trames vidéo provenant de fichiers bitmap) que vous voulez utiliser comme source +dans un graph, ce filtre vous montrera comment. + + +Samples\Misc\Toolkit +-------------------- +Un ensemble d'utilitaires pratiques. + + +Samples\Players\DvdPlay +----------------------- +Un exemple basique montrant comment lire des DVD avec DirectShow. + + +Samples\Players\DxPlay +---------------------- +Une application démontrant comment lire des fichiers multimédia (AVI, WMV, etc.) et +prendre des instantanés. + + +Samples\Players\DxText +---------------------- +Une application démontrant comment superposez un texte sur un flux de données. Le flux +est lu depuis un fichier avi. + + +Samples\Players\EVRPlayer +------------------------- +Ce projet est une taduction en c# de l'exemple c++ EVRPlayer fournis avec le Windows SDK. Il montre +comment utiliser le filtre EVR dans DirectShow. + + +Samples\Players\GMFPlay +----------------------- +Un exmple qui montre comment utliser l'indispensable filtre de Geraint, le GMFBridge filter, pour jouer une +serie de fichier multimedia l'un après l'autre. + + +Samples\Players\PlayVB +---------------------- +Un "player" simple en VB. + + +Samples\Players\PlayWnd +----------------------- +Une traduction du programme PlayWnd de DirectShow pour montrer à quoi cela peut +ressembler en C#. +PlayWnd est un lecteur multimédia avec une interface utilisateur minimale. + + +Samples\SBE\DvrMsCutter +----------------------- +Cet exemple extrait un morceau de fichier dvr-ms dans un autre fichier dvr-ms. + + +Samples\VMR9\BitMapMixer +------------------------ +BitmapMixer est un exemple démontrant comment dessiner des choses diverses par-dessus +une vidéo en utilisant VMR9. + + +Samples\VMR9\VMR9Allocator +-------------------------- +Une traduction du programme VMR9Allocator de DirectShow pour monter à quoi cela peut +ressembler en c#. + + +Samples\VMR9\VMR9Allocator2 +--------------------------- +Une alternative au programme VMR9Allocator de DirectShow. + + diff --git a/Samples/readme-samples.txt b/Samples/readme-samples.txt new file mode 100644 index 0000000..29fa9ad --- /dev/null +++ b/Samples/readme-samples.txt @@ -0,0 +1,229 @@ +DirectShowLib Samples 2010-02-21 + +http://DirectShowNet.SourceForge.net + +This package contains a selection of samples. These samples were formerly bundled +with the DirectShowLib library, but as of version 1.4, they have been split out to +this separate package. + +We have removed the build files for vs2003 in this release. vs2005 has been available +(for free!) for 2 years now. Besides, no one on our dev team still has it installed. + +We have added two samples since the last release: + + BlackList + EVRPlayer + +See the descriptions below. + +These samples should not be considered commercial quality applications. They are just +intended to illustrate how to use some particular feature, or group of features in +DirectShow. Feel free to polish them into applications of your own, or extract +sections to use in your own code. Each sample has (at least one) readme file. +Several samples also have help files (.chm files). If you are looking for info +regarding a sample, those are always a good place to start. + +Also, while DirectShowLib is licensed under LGPL, these samples are public domain. +Use them as you like. Every one of these samples needs the DirectShowLib library +which is not included in this package. Get the latest version from the SourceForge +website. + +The people who wrote these samples usually hang out in +http://sourceforge.net/forum/forum.php?forum_id=460697. If you have questions, +comments, or just want to say thanks to the people who have taken the time to +create these, feel free to stop by. + +Also, if you have samples you think would be useful (or would like to write some), +that would be the place to get started. + +===================================================================================== + +This is the current list of samples along with a short description. See the +readme.txt in the individual samples for more details. + + +Samples\BDA\DTViewer +-------------------- +Use BDA to display Digital TV into a Windows Form. + + +Samples\Capture\CapWMV +---------------------- +Capture from video capture devices to WMV files. + + +Samples\Capture\DxLogo +---------------------- +A sample application showing how to superimpose a logo on a data stream. It uses a +capture device for the video source, and outputs the result to a file. + + +Samples\Capture\DxLogoVB +------------------------ +This is precisely the same sample as DxLogo, except that it's written in Visual +Basic. Other than the tediousness of converting C# to VB, this was a trivial +exercise. + + +Samples\Capture\DxPropPages +--------------------------- +Show how to add compression filters to video capture, and show how to invoke the +property pages for capture devices, and video compressors. + + +Samples\Capture\DxSnap +---------------------- +Use DirectShow to take snapshots from the Still pin of a capture device. Note +the MS encourages you to use WIA for this, but if you want to do in with +DirectShow and C#, here's how. + + +Samples\Capture\DxTuner +----------------------- +Shows how to capture from TV Tuners, including how to change channels. + + +Samples\Capture\PlayCap +----------------------- +A translation of the DirectShow PlayCap program to show how this would appear in +c#. This application creates a preview window for the first video capture device +that it locates on the user's system (if any). It demonstrates a simple example of +using the ICaptureGraphBuilder2 and ICreateDevEnum interfaces to build a capture graph. + + +Samples\DMO\DMOFlip +------------------- +A DMO that can be used in a Directshow FilterGraph. This DMO allows video to be +flipped on the X or Y axis (or both). There is a help file (IMediaObjectImpl.chm) +showing how to write a DMO of your own. + + +Samples\DMO\DMOSplit +-------------------- +A DMO that splits a stereo audio signal into two mono streams. + + +Samples\Editing\DESCombine +-------------------------- +A class library that uses DirectShow Editing Services to combine video and audio +files (or pieces of files) into a single output file. A help file (DESCombine.chm) +is provided for using the class. + + +Samples\Editing\DESCombineLib\DESCombineVB +------------------------------------------ +Showing how to use the DESCombine sample (above) in VB. + + +Samples\Editing\DxScan +---------------------- +A sample application scanning a media file looking for black frames. + + +Samples\Misc\BlackList +---------------------- +This sample illustrate how to use the IAMGraphBuilderCallback interface to +reject some filters during the graph creation. You can adapt this sample for +your uses if some filters are known to break your application. + + +Samples\Misc\DxWebCam +--------------------- +A poor man's web cam program. This application runs as a Win32 Service. It +takes the output of a capture graph, turns it into a stream of JPEG files, and +sends it thru TCP/IP to a client application. + + +Samples\Misc\GMFPreview +----------------------- +A sample showing how to use Geraint's indispensible GMFBridge tool to allow part +of a graph to be stopped while another part keeps running. This is useful to allow +preview windows to keep running while you start/stop capturing to disk. + + +Samples\Misc\GSSF +----------------- +A way to implement a source filter in c#. If you have samples (for example video +frames from bitmap files) that you want to use as a source in a graph, this filter +will show you how. + + +Samples\Misc\Toolkit +-------------------- +A collection of useful utilities. + + +Samples\Players\DvdPlay +----------------------- +A bare-bones sample showing how to play DVDs with DirectShow. + + +Samples\Players\DxPlay +---------------------- +A sample application showing how to play media files (AVI, WMV, etc) and +capture snapshots. + + +Samples\Players\DxText +---------------------- +A sample application showing how to superimpose text strings on a datastream. +The stream is read from an avi file. + + +Samples\Players\EVRPlayer +------------------------- +This project is a c# translation of the c++ EVRPlayer sample that ships with the Windows SDK. It shows +how to use the EVR renderer from DirectShow. + + +Samples\Players\GMFPlay +----------------------- +A sample showing how to use Geraint's indispensible GMFBridge filter to play a collection +of media files one after another. + + +Samples\Players\PlayVB +---------------------- +A simple player in VB. + + +Samples\Players\PlayWnd +----------------------- +A translation of the DirectShow PlayWnd program to show how this would appear in C#. PlayWnd +is a simple media player application with a minimal user interface. + + +Samples\SBE\DvrMsCutter +----------------------- +This sample extracts a segment of a dvr-ms file into another dvr-ms file. + + +Samples\SBE\DvrMsCutter2 +------------------------ +This sample extracts multiple segments of a dvr-ms file into another dvr-ms file. + + +Samples\VMR9\BitMapMixer +------------------------ +BitmapMixer is an example of how to draw things over a video using VMR9. + + +Samples\VMR9\VMR9Allocator +-------------------------- +A translation of the DirectShow VMR9Allocator program to show how this would appear in c#. + + +Samples\VMR9\VMR9Compositor +--------------------------- +This sample shows how to use the VMR9 custom compositor feature. + + +Samples\VMR9\VMR9Allocator2 +--------------------------- +An alternative to the DirectShow VMR9Allocator program. + + +Samples\VMR9\vMR9Snapper +------------------------ +This sample shows how to capture bitmaps from VMR9. +