コード例 #1
0
        private void AddTransforms(IEnumerable <Activate> effects, string type)
        {
            foreach (var mft in effects)
            {
                int attributeCount = mft.Count;
                var sb             = new StringBuilder();
                sb.AppendFormat(type);
                sb.AppendLine();
                for (int n = 0; n < attributeCount; n++)
                {
                    Guid   key;
                    var    value        = mft.GetByIndex(n, out key);
                    string propertyName = FieldDescriptionHelper.Describe(typeof(MediaFoundationAttributes), key);
                    if (key == TransformAttributeKeys.MftInputTypesAttributes.Guid || key == TransformAttributeKeys.MftOutputTypesAttributes.Guid)
                    {
                        byte[] blob  = (byte[])value;
                        var    count = blob.Length / 32;
                        var    types = new TRegisterTypeInformation[count];

                        for (int j = 0; j < count; j++)
                        {
                            types[j].GuidMajorType = new Guid(blob.Skip(j * 32).Take(16).ToArray());
                            types[j].GuidSubtype   = new Guid(blob.Skip(j * 32 + 16).Take(16).ToArray());
                        }

                        sb.AppendFormat("{0}: {1} items:", propertyName, types.Length);
                        sb.AppendLine();
                        foreach (var t in types)
                        {
                            sb.AppendFormat("    {0}-{1}",
                                            FieldDescriptionHelper.Describe(typeof(MediaTypes), t.GuidMajorType),
                                            FieldDescriptionHelper.Describe(typeof(AudioSubtypes), t.GuidSubtype));
                            sb.AppendLine();
                        }
                    }
                    else if (key == TransformAttributeKeys.TransformCategoryAttribute.Guid)
                    {
                        sb.AppendFormat("{0}: {1}", propertyName, FieldDescriptionHelper.Describe(typeof(MediaFoundationTransformCategories), (Guid)value));
                        sb.AppendLine();
                    }
                    else if (value is byte[])
                    {
                        var b = (byte[])value;
                        sb.AppendFormat("{0}: Blob of {1} bytes", propertyName, b.Length);
                        sb.AppendLine();
                    }
                    else
                    {
                        sb.AppendFormat("{0}: {1}", propertyName, value);
                        sb.AppendLine();
                    }
                }
                Transforms.Add(sb.ToString());
            }
        }
コード例 #2
0
ファイル: H264Encoder.cs プロジェクト: ouarlone/DesktopPortal
        public static IEnumerable <H264Encoder> Enumerate(TransformEnumFlag flags)
        {
            var output = new TRegisterTypeInformation();

            output.GuidMajorType = MediaTypeGuids.Video;
            output.GuidSubtype   = VideoFormatGuids.FromFourCC(new FourCC("H264"));
            foreach (var activate in MediaFactory.FindTransform(TransformCategoryGuids.VideoEncoder, flags, null, output))
            {
                yield return(new H264Encoder(activate));
            }
        }
コード例 #3
0
ファイル: MediaFactory.cs プロジェクト: rbwhitaker/SharpDX
        /// <summary>
        /// Gets a list of Microsoft Media Foundation transforms (MFTs) that match specified search criteria. This function extends the <strong><see cref="SharpDX.MediaFoundation.MediaFactory.TEnum"/></strong> function.
        /// </summary>
        /// <param name="guidCategory">A GUID that specifies the category of MFTs to enumerate. For a list of MFT categories, see <strong><see cref="SharpDX.MediaFoundation.TransformCategoryGuids"/></strong>.</param>
        /// <param name="enumFlags">The bitwise OR of zero or more flags from the <strong><see cref="SharpDX.MediaFoundation.TransformEnumFlag"/></strong> enumeration.</param>
        /// <param name="inputTypeRef">A pointer to an <strong><see cref="SharpDX.MediaFoundation.TRegisterTypeInformation"/></strong> structure that specifies an input media type to match.<para>This parameter can be NULL. If NULL, all input types are matched.</para></param>
        /// <param name="outputTypeRef">A pointer to an <strong><see cref="SharpDX.MediaFoundation.TRegisterTypeInformation"/></strong> structure that specifies an output media type to match.<para>This parameter can be NULL. If NULL, all output types are matched.</para></param>
        /// <returns>Returnss an array of <strong><see cref="SharpDX.MediaFoundation.Activate"/></strong> objects. Each object represents an activation object for an MFT that matches the search criteria. The function allocates the memory for the array. The caller must release the pointers and call the Dispose for each element in the array.</returns>
        /// <msdn-id>dd388652</msdn-id>	
        /// <unmanaged>HRESULT MFTEnumEx([In] GUID guidCategory,[In] unsigned int Flags,[In, Optional] const MFT_REGISTER_TYPE_INFO* pInputType,[In, Optional] const MFT_REGISTER_TYPE_INFO* pOutputType,[Out, Buffer] IMFActivate*** pppMFTActivate,[Out] unsigned int* pnumMFTActivate)</unmanaged>	
        /// <unmanaged-short>MFTEnumEx</unmanaged-short>	
        public static Activate[] FindTransform(Guid guidCategory, TransformEnumFlag enumFlags, TRegisterTypeInformation? inputTypeRef = null, TRegisterTypeInformation? outputTypeRef = null)
        {
            IntPtr pActivatesArr;
            int pNumActivates;
            TEnumEx(guidCategory, (int)enumFlags, inputTypeRef, outputTypeRef, out pActivatesArr, out pNumActivates);

            var activates = new Activate[pNumActivates];
            unsafe
            {
                var ptr = (IntPtr*)(pActivatesArr);
                for (int i = 0; i < pNumActivates; i++)
                {
                    activates[i] = new Activate(ptr[i]);
                }
            }
            Marshal.FreeCoTaskMem(pActivatesArr);

            return activates;
        }
コード例 #4
0
        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;
            }
        }
コード例 #5
0
        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);
        }