예제 #1
0
        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));
            }
        }
예제 #2
0
        /// <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;
        }
예제 #3
0
        /// <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>Returns 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);
        }