public void Setup(MfVideoArgs inputArgs) { logger.Debug("MfH264Dxva2Decoder::Setup(...)"); var width = inputArgs.Width; var height = inputArgs.Height; var inputFormat = VideoFormatGuids.H264; var frameRate = inputArgs.FrameRate; LowLatency = inputArgs.LowLatency; try { var transformFlags = //TransformEnumFlag.Hardware | TransformEnumFlag.SortAndFilter; var inputType = new TRegisterTypeInformation { GuidMajorType = MediaTypeGuids.Video, GuidSubtype = VideoFormatGuids.H264 }; var transformActivators = MediaFactory.FindTransform(TransformCategoryGuids.VideoDecoder, transformFlags, inputType, null); try { foreach (var activator in transformActivators) { //bool isHardware = flags.HasFlag(TransformEnumFlag.Hardware); //bool isAsync = flags.HasFlag(TransformEnumFlag.Asyncmft); string name = activator.Get(TransformAttributeKeys.MftFriendlyNameAttribute); Guid clsid = activator.Get(TransformAttributeKeys.MftTransformClsidAttribute); TransformEnumFlag flags = (TransformEnumFlag)activator.Get(TransformAttributeKeys.TransformFlagsAttribute); bool isAsync = !(flags.HasFlag(TransformEnumFlag.Syncmft)); isAsync |= !!(flags.HasFlag(TransformEnumFlag.Asyncmft)); bool isHardware = !!(flags.HasFlag(TransformEnumFlag.Hardware)); var _flags = Enum.GetValues(typeof(TransformEnumFlag)) .Cast <TransformEnumFlag>() .Where(m => (m != TransformEnumFlag.None && flags.HasFlag(m))); var transformInfo = name + " " + clsid.ToString() + " " + string.Join("|", _flags); logger.Info(transformInfo); //encoder = activator.ActivateObject<Transform>(); //break; //var HardwareUrl = activator.Get(TransformAttributeKeys.MftEnumHardwareUrlAttribute); //logger.Info(HardwareUrl); //var TransformAsync = activator.Get(TransformAttributeKeys.TransformAsync); //logger.Info(TransformAsync); //logger.Info("-------------------------------------"); } } finally { decoder = transformActivators[0].ActivateObject <Transform>(); foreach (var activator in transformActivators) { activator.Dispose(); } } using (var attr = decoder.Attributes) { bool d3dAware = attr.Get(TransformAttributeKeys.D3DAware); if (d3dAware) { if (d3dDeviceManager != null) { decoder.ProcessMessage(TMessageType.SetD3DManager, d3dDeviceManager.NativePointer); } else { attr.Set(TransformAttributeKeys.D3DAware, false); } } attr.Set(SinkWriterAttributeKeys.LowLatency, LowLatency); //attr.Set(MFAttributeKeys.MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT, 1); } int inputStreamCount = -1; int outputStreamsCount = -1; decoder.GetStreamCount(out inputStreamCount, out outputStreamsCount); int[] inputStreamIDs = new int[inputStreamCount]; int[] outputStreamIDs = new int[outputStreamsCount]; bool res = decoder.TryGetStreamIDs(inputStreamIDs, outputStreamIDs); if (res) { inputStreamId = inputStreamIDs[0]; outputStreamId = outputStreamIDs[0]; } else { inputStreamId = 0; outputStreamId = 0; } for (int i = 0; ; i++) { try { decoder.GetInputAvailableType(0, i, out MediaType mediaType); if (mediaType == null) { logger.Warn("NoMoreType"); break; } var formatId = mediaType.Get(MediaTypeAttributeKeys.Subtype); if (formatId == inputFormat) { logger.Debug("inputFormat " + inputFormat); InputMediaType = mediaType; break; } mediaType.Dispose(); mediaType = null; } catch (SharpDX.SharpDXException ex) { if (ex.ResultCode != SharpDX.MediaFoundation.ResultCode.NoMoreTypes) { throw; } } } if (InputMediaType == null) { logger.Warn("Unsuported format: " + MfTool.GetMediaTypeName(inputFormat)); return; } InputMediaType.Set(MediaTypeAttributeKeys.MajorType, MediaTypeGuids.Video); InputMediaType.Set(MediaTypeAttributeKeys.Subtype, VideoFormatGuids.H264); InputMediaType.Set(MediaTypeAttributeKeys.FrameSize, MfTool.PackToLong(width, height)); InputMediaType.Set(MediaTypeAttributeKeys.FrameRate, frameRate); // InputMediaType.Set(MediaTypeAttributeKeys.PixelAspectRatio, MfTool.PackToLong(1, 1)); InputMediaType.Set(MediaTypeAttributeKeys.InterlaceMode, (int)VideoInterlaceMode.Progressive); InputMediaType.Set(MediaTypeAttributeKeys.AllSamplesIndependent, 1); decoder.SetInputType(inputStreamId, InputMediaType, 0); logger.Info("============== INPUT TYPE=================="); logger.Info(MfTool.LogMediaType(InputMediaType)); OutputMediaType = new MediaType(); OutputMediaType.Set(MediaTypeAttributeKeys.MajorType, MediaTypeGuids.Video); OutputMediaType.Set(MediaTypeAttributeKeys.Subtype, VideoFormatGuids.NV12); //OutputMediaType.Set(MediaTypeAttributeKeys.AvgBitrate, 30000000); OutputMediaType.Set(MediaTypeAttributeKeys.InterlaceMode, (int)VideoInterlaceMode.Progressive); OutputMediaType.Set(MediaTypeAttributeKeys.FrameSize, MfTool.PackToLong(width, height)); OutputMediaType.Set(MediaTypeAttributeKeys.FrameRate, frameRate); OutputMediaType.Set(MediaTypeAttributeKeys.AllSamplesIndependent, 1); decoder.SetOutputType(outputStreamId, OutputMediaType, 0); logger.Info("============== OUTPUT TYPE=================="); logger.Info(MfTool.LogMediaType(OutputMediaType)); } catch (Exception ex) { logger.Error(ex); Close(); throw; } }
private Transform FindEncoder(int adapterVenId) { logger.Debug("FindEncoder(...) " + adapterVenId); Transform preferTransform = null; var transformFlags = TransformEnumFlag.All | // TransformEnumFlag.All | TransformEnumFlag.SortAndFilter; var outputType = new TRegisterTypeInformation { GuidMajorType = MediaTypeGuids.Video, GuidSubtype = VideoFormatGuids.H264 // GuidSubtype = VideoFormatGuids.Hevc }; //int vendorId = 0; //using (var dxgiDevice = device.QueryInterface<SharpDX.DXGI.Device>()) //{ // var adapter = dxgiDevice.Adapter; // vendorId = adapter.Description.VendorId; //} var activates = MediaFactory.FindTransform(TransformCategoryGuids.VideoEncoder, transformFlags, null, outputType); try { Activate preferActivate = null; foreach (var activate in activates) { var actLog = MfTool.LogMediaAttributes(activate); logger.Debug("\r\nActivator:\r\n-----------------\r\n" + actLog); string name = activate.Get(TransformAttributeKeys.MftFriendlyNameAttribute); Guid clsid = activate.Get(TransformAttributeKeys.MftTransformClsidAttribute); TransformEnumFlag flags = (TransformEnumFlag)activate.Get(TransformAttributeKeys.TransformFlagsAttribute); bool isAsync = !(flags.HasFlag(TransformEnumFlag.Syncmft)); isAsync |= (flags.HasFlag(TransformEnumFlag.Asyncmft)); bool isHardware = flags.HasFlag(TransformEnumFlag.Hardware); if (isHardware) { string venIdStr = activate.Get(TransformAttributeKeys.MftEnumHardwareVendorIdAttribute); if (MfTool.TryGetVendorId(venIdStr, out int activatorVendId)) { if (activatorVendId == adapterVenId) { preferActivate = activate; syncMode = false; } } } else { //TODO:... } //var _flags = Enum.GetValues(typeof(TransformEnumFlag)) // .Cast<TransformEnumFlag>() // .Where(m => (m != TransformEnumFlag.None && flags.HasFlag(m))); //var transformInfo = name + " " + clsid.ToString() + " " + string.Join("|", _flags); //logger.Info(transformInfo); //logger.Debug(MfTool.LogMediaAttributes(activator)); //var HardwareUrl = activator.Get(TransformAttributeKeys.MftEnumHardwareUrlAttribute); //logger.Info(HardwareUrl); //var TransformAsync = activator.Get(TransformAttributeKeys.TransformAsync); //logger.Info(TransformAsync); //logger.Info("-------------------------------------"); } // preferEncoder = transformActivators[0].ActivateObject<Transform>(); if (preferActivate != null) { preferTransform = preferActivate.ActivateObject <Transform>(); } } finally { foreach (var activator in activates) { activator.Dispose(); } } return(preferTransform); }