예제 #1
0
        public virtual void Initialize(DeviceManager deviceManager)
        {
            lock (lockObject)
            {
                // Startup MediaManager
                MediaManager.Startup();

                // Setup multithread on the Direct3D11 device
                var multithread = deviceManager.DeviceDirect3D.QueryInterface <SharpDX.Direct3D.DeviceMultithread>();
                multithread.SetMultithreadProtected(true);

                // Create a DXGI Device Manager
                dxgiDeviceManager = new DXGIDeviceManager();
                dxgiDeviceManager.ResetDevice(deviceManager.DeviceDirect3D);

                // Setup Media Engine attributes
                var attributes = new MediaEngineAttributes
                {
                    DxgiManager       = dxgiDeviceManager,
                    VideoOutputFormat = (int)SharpDX.DXGI.Format.B8G8R8A8_UNorm
                };

                using (var factory = new MediaEngineClassFactory())
                    mediaEngine = new MediaEngine(factory, attributes, MediaEngineCreateFlags.WaitForStableState, OnMediaEngineEvent);
                mediaEngineEx = mediaEngine.QueryInterface <MediaEngineEx>();
            }
        }
        public CapturePlayer(Device device)
        {
            using (var manager = new DXGIDeviceManager())
            {
                manager.ResetDevice(device);

                captureEngineAttributes.Set(CaptureEngineAttributeKeys.D3DManager, manager);
            }
        }
예제 #3
0
 private void newDXDeviceForVideo()
 {
     SharpDX.Utilities.Dispose(ref dxman);
     dxman = new DXGIDeviceManager();
     using (var dxdevice = new DXDevice(SharpDX.Direct3D.DriverType.Hardware, DeviceCreationFlags.BgraSupport | DeviceCreationFlags.VideoSupport))
     {
         using (var mt = dxdevice.QueryInterface <DeviceMultithread>())
             mt.SetMultithreadProtected(true);
         dxman.ResetDevice(dxdevice);
     }
 }
예제 #4
0
        private void SetupMediaFoundation()
        {
            using var mediaEngineAttributes = new MediaEngineAttributes()
                  {
                      // _SRGB doesn't work :/ Getting invalid argument exception later in TransferVideoFrame
                      AudioCategory     = SharpDX.Multimedia.AudioStreamCategory.GameMedia,
                      AudioEndpointRole = SharpDX.Multimedia.AudioEndpointRole.Multimedia,
                      VideoOutputFormat = (int)SharpDX.DXGI.Format.B8G8R8A8_UNorm
                  };

            //var graphicsDevice = renderDrawContextHandle.Resource.GraphicsDevice;
            var device = ResourceManager.Instance().Device;

            //var device = SharpDXInterop.GetNativeDevice(graphicsDevice) as Device;
            if (device != null)
            {
                // Add multi thread protection on device (MF is multi-threaded)
                using var deviceMultithread = device.QueryInterface <DeviceMultithread>();
                deviceMultithread.SetMultithreadProtected(true);

                // Reset device
                using var manager = new DXGIDeviceManager();
                manager.ResetDevice(device);
                mediaEngineAttributes.DxgiManager = manager;
            }

            // using var classFactory = new MediaEngineClassFactory();
            // try
            // {
            //
            //     _engine = new MediaEngine(classFactory, mediaEngineAttributes);
            //     _engine.PlaybackEvent += Engine_PlaybackEvent;
            // }
            // catch (SharpDXException e)
            // {
            //     Log.Error("Failed to setup MediaEngine: " + e.Message);
            // }

            // Setup Media Engine attributes
            // Create a DXGI Device Manager
            dxgiDeviceManager = new DXGIDeviceManager();
            dxgiDeviceManager.ResetDevice(device);
            var attributes = new MediaEngineAttributes
            {
                DxgiManager       = dxgiDeviceManager,
                VideoOutputFormat = (int)SharpDX.DXGI.Format.B8G8R8A8_UNorm
            };

            MediaManager.Startup();
            using (var factory = new MediaEngineClassFactory())
                _engine = new MediaEngine(factory, attributes, MediaEngineCreateFlags.WaitForStableState, Engine_PlaybackEvent);
        }
예제 #5
0
        MediaAttributes GetSinkWriterAttributes(Device Device)
        {
            var attr = new MediaAttributes(6);

            attr.Set(SinkWriterAttributeKeys.ReadwriteEnableHardwareTransforms, 1);
            attr.Set(SinkWriterAttributeKeys.ReadwriteDisableConverters, 0);
            attr.Set(TranscodeAttributeKeys.TranscodeContainertype, TranscodeContainerTypeGuids.Mpeg4);
            attr.Set(SinkWriterAttributeKeys.LowLatency, true);

            var devMan = new DXGIDeviceManager();

            devMan.ResetDevice(Device);
            attr.Set(SinkWriterAttributeKeys.D3DManager, devMan);

            return(attr);
        }
예제 #6
0
        public override void Initialize()
        {
            base.Initialize();

            var graphicsDevice = Services.GetService <IGame>().GraphicsDevice;

            DxgiDeviceManager = new DXGIDeviceManager();
            DxgiDeviceManager.ResetDevice(graphicsDevice.NativeDevice);

            //Add multi thread protection on device
            var mt = graphicsDevice.NativeDevice.QueryInterface <DeviceMultithread>();

            mt.SetMultithreadProtected(true);

            MediaManager.Startup();
        }
예제 #7
0
            /// <summary>
            /// Creates device with necessary flags for video processing
            /// </summary>
            /// <param name="manager">DXGI Manager, used to create media engine</param>
            /// <returns>Device with video support</returns>
            internal static DXDevice CreateDeviceForVideo(out DXGIDeviceManager manager)
            {
                //Device need bgra and video support
                var device = new DXDevice(SharpDX.Direct3D.DriverType.Hardware, DeviceCreationFlags.BgraSupport | DeviceCreationFlags.VideoSupport);

                //Add multi thread protection on device
                DeviceMultithread mt = device.QueryInterface <DeviceMultithread>();

                mt.SetMultithreadProtected(true);

                //Reset device
                manager = new DXGIDeviceManager();
                manager.ResetDevice(device);

                return(device);
            }
예제 #8
0
        private void PlatformInitialize()
        {
            MediaManager.Startup();

            _devManager = new DXGIDeviceManager();
            _devManager.ResetDevice(Game.Instance.GraphicsDevice._d3dDevice);

            using (var factory = new MediaEngineClassFactory())
                using (var attributes = new MediaEngineAttributes
                {
                    VideoOutputFormat = (int)SharpDX.DXGI.Format.B8G8R8A8_UNorm,
                    DxgiManager = _devManager
                })
                {
                    _mediaEngine = new MediaEngine(factory, attributes, MediaEngineCreateFlags.None, OnMediaEngineEvent);
                }
        }
예제 #9
0
        public StreamPlayer(Device device, int fps)
        {
            Device = device.QueryInterface <SharpDX.Direct3D11.Device>();
            using (var manager = new DXGIDeviceManager())
                using (var factory = new MediaEngineClassFactory())
                    using (var attributes = new MediaEngineAttributes(2))
                    {
                        manager.ResetDevice(device);
                        attributes.DxgiManager       = manager;
                        attributes.VideoOutputFormat = (int)Format.B8G8R8A8_UNorm;
                        var baseEngine = new MediaEngine(factory, attributes, playbackCallback: OnEngineEvent);
                        engine = baseEngine.QueryInterface <MediaEngineEx>();
                    }

            frameTime = TimeSpan.FromSeconds(1.0 / fps);
            SetCurrentState(StreamPlayerState.NoSource);
        }
예제 #10
0
        public VideoPlayer(NodeContext nodeContext)
        {
            renderDrawContextHandle = nodeContext.GetGameProvider()
                                      .Bind(g => RenderContext.GetShared(g.Services).GetThreadContext())
                                      .GetHandle() ?? throw new ServiceNotFoundException(typeof(IResourceProvider <Game>));

            colorSpaceConverter = new ColorSpaceConverter(renderDrawContextHandle.Resource);

            // Initialize MediaFoundation
            MediaManagerService.Initialize();

            using var mediaEngineAttributes = new MediaEngineAttributes()
                  {
                      // _SRGB doesn't work :/ Getting invalid argument exception later in TransferVideoFrame
                      AudioCategory     = SharpDX.Multimedia.AudioStreamCategory.GameMedia,
                      AudioEndpointRole = SharpDX.Multimedia.AudioEndpointRole.Multimedia,
                      VideoOutputFormat = (int)SharpDX.DXGI.Format.B8G8R8A8_UNorm
                  };

            var graphicsDevice = renderDrawContextHandle.Resource.GraphicsDevice;
            var device         = SharpDXInterop.GetNativeDevice(graphicsDevice) as Device;

            if (device != null)
            {
                // Add multi thread protection on device (MF is multi-threaded)
                using var deviceMultithread = device.QueryInterface <DeviceMultithread>();
                deviceMultithread.SetMultithreadProtected(true);


                // Reset device
                using var manager = new DXGIDeviceManager();
                manager.ResetDevice(device);
                mediaEngineAttributes.DxgiManager = manager;
            }

            using var classFactory = new MediaEngineClassFactory();
            engine = new MediaEngine(classFactory, mediaEngineAttributes);
            engine.PlaybackEvent += Engine_PlaybackEvent;
        }
예제 #11
0
        public virtual void Initialize(DeviceManager devices)
        {
            // Startup MediaManager
            MediaManager.Startup();

            // Create a DXGI Device Manager
            dxgiDeviceManager = new DXGIDeviceManager();
            dxgiDeviceManager.ResetDevice(devices.DeviceDirect3D);

            // Setup Media Engine attributes
            var attributes = new MediaEngineAttributes
            {
                DxgiManager       = dxgiDeviceManager,
                VideoOutputFormat = (int)SharpDX.DXGI.Format.B8G8R8A8_UNorm
            };

            using (var factory = new MediaEngineClassFactory())
                using (var mediaEngine = new MediaEngine(factory, attributes, MediaEngineCreateflags.None))
                    mediaEngineEx = mediaEngine.QueryInterface <MediaEngineEx>();

            // Register for playback notification from MediaEngine
            mediaEngineEx.PlaybackEvent += MediaEngineExOnPlaybackEvent;
        }
예제 #12
0
        public MfColorConverter(int Width, int Height, Device Device)
        {
            var transforms = MediaFactory.FindTransform(TransformCategoryGuids.VideoProcessor, TransformEnumFlag.All);

            _colorConverter = transforms[0].ActivateObject <Transform>();

            _deviceMan = new DXGIDeviceManager();
            _deviceMan.ResetDevice(Device);

            _colorConverter.ProcessMessage(TMessageType.SetD3DManager, _deviceMan.NativePointer);

            using (var mediaTypeIn = new MediaType())
            {
                mediaTypeIn.Set(MediaTypeAttributeKeys.MajorType, MediaTypeGuids.Video);
                mediaTypeIn.Set(MediaTypeAttributeKeys.Subtype, VideoFormatGuids.Rgb32);
                mediaTypeIn.Set(MediaTypeAttributeKeys.FrameSize, MfWriter.PackLong(Width, Height));
                mediaTypeIn.Set(MediaTypeAttributeKeys.DefaultStride, Width * 4);
                mediaTypeIn.Set(MediaTypeAttributeKeys.FixedSizeSamples, 1);
                mediaTypeIn.Set(MediaTypeAttributeKeys.SampleSize, Width * Height * 4);

                _colorConverter.SetInputType(0, mediaTypeIn, 0);
            }

            var outputStride     = Width * 12 / 8;
            var outputSampleSize = Height * outputStride;

            using (var mediaTypeOut = new MediaType())
            {
                mediaTypeOut.Set(MediaTypeAttributeKeys.MajorType, MediaTypeGuids.Video);
                mediaTypeOut.Set(MediaTypeAttributeKeys.Subtype, VideoFormatGuids.NV12);
                mediaTypeOut.Set(MediaTypeAttributeKeys.FrameSize, MfWriter.PackLong(Width, Height));
                mediaTypeOut.Set(MediaTypeAttributeKeys.DefaultStride, outputStride);
                mediaTypeOut.Set(MediaTypeAttributeKeys.FixedSizeSamples, 1);
                mediaTypeOut.Set(MediaTypeAttributeKeys.SampleSize, outputSampleSize);

                _colorConverter.SetOutputType(0, mediaTypeOut, 0);
            }

            _colorConverter.ProcessMessage(TMessageType.NotifyBeginStreaming, IntPtr.Zero);

            _copyTexture = new Texture2D(Device, new Texture2DDescription
            {
                CpuAccessFlags    = CpuAccessFlags.None,
                BindFlags         = BindFlags.RenderTarget | BindFlags.ShaderResource,
                Format            = Format.B8G8R8A8_UNorm,
                Width             = Width,
                Height            = Height,
                OptionFlags       = ResourceOptionFlags.None,
                MipLevels         = 1,
                ArraySize         = 1,
                SampleDescription = { Count = 1, Quality = 0 },
                Usage             = ResourceUsage.Default
            });

            _inputSample = MediaFactory.CreateVideoSampleFromSurface(null);

            // Create the media buffer from the texture
            MediaFactory.CreateDXGISurfaceBuffer(typeof(Texture2D).GUID, _copyTexture, 0, false, out var inputBuffer);

            using (var buffer2D = inputBuffer.QueryInterface <Buffer2D>())
                inputBuffer.CurrentLength = buffer2D.ContiguousLength;

            // Attach the created buffer to the sample
            _inputSample.AddBuffer(inputBuffer);
        }
예제 #13
0
        private void SetupEncoder(MfVideoArgs args)
        {
            logger.Debug("SetupEncoder(...)");


            var width  = args.Width;
            var height = args.Height;

            var frameRate   = args.FrameRate;
            int avgBitrate  = args.AvgBitrate;
            int maxBitrate  = args.MaxBitrate;
            int mpegProfile = (int)args.Profile;

            long pixelAspectRatio = args.AspectRatio;

            //var inputFormat = VideoFormatGuids.Argb32;//VideoFormatGuids.NV12;
            var inputFormat = args.Format;

            logger.Info("Encoder input params: " + width + "x" + height + " fps=" + frameRate + " {" + inputFormat + "}");
            using (var attr = encoder.Attributes)
            {
                // TODO:
                // log pref

                try
                {
                    syncMode = !(attr.Get(TransformAttributeKeys.TransformAsync) == 1);
                }
                catch (SharpDX.SharpDXException ex)
                {
                    syncMode = true;
                }


                if (!syncMode)
                {
                    //var transformAsync = (attr.Get(TransformAttributeKeys.TransformAsync) == 1);
                    //if (transformAsync)
                    //{
                    attr.Set(TransformAttributeKeys.TransformAsyncUnlock, 1);
                    attr.Set(TransformAttributeKeys.MftSupportDynamicFormatChange, true);

                    bool d3d11Aware = attr.Get(TransformAttributeKeys.D3D11Aware);
                    if (d3d11Aware)
                    {
                        using (var devMan = new DXGIDeviceManager())
                        {
                            devMan.ResetDevice(device);
                            encoder.ProcessMessage(TMessageType.SetD3DManager, devMan.NativePointer);
                        }
                    }
                    //}
                }

                attr.Set(CodecApiPropertyKeys.AVLowLatencyMode, args.LowLatency);
                attr.Set(CodecApiPropertyKeys.AVEncCommonRateControlMode, args.BitrateMode);
                attr.Set(CodecApiPropertyKeys.AVEncCommonQuality, args.Quality);

                attr.Set(CodecApiPropertyKeys.AVEncMPVGOPSize, args.GopSize);

                // отключаем B-фреймы
                attr.Set(CodecApiPropertyKeys.AVEncMPVDefaultBPictureCount, 0);


                //attr.Set(CodecApiPropertyKeys.AVEncNumWorkerThreads, 4);

                var attrLog = MfTool.LogMediaAttributes(attr);

                logger.Debug("\r\nMFT:\r\n-----------------\r\n" + attrLog);
            }


            int inputStreamCount   = -1;
            int outputStreamsCount = -1;

            encoder.GetStreamCount(out inputStreamCount, out outputStreamsCount);
            int[] inputStreamIDs  = new int[inputStreamCount];
            int[] outputStreamIDs = new int[outputStreamsCount];

            bool res = encoder.TryGetStreamIDs(inputStreamIDs, outputStreamIDs);

            if (res)
            {
                inputStreamId  = inputStreamIDs[0];
                outputStreamId = outputStreamIDs[0];
            }
            else
            {
                inputStreamId  = 0;
                outputStreamId = 0;
            }


            for (int i = 0; ; i++)
            {
                if (!encoder.TryGetOutputAvailableType(outputStreamId, i, out MediaType mediaType))
                {
                    //
                    logger.Warn("NoMoreOutputTypes");
                    break;
                }
                //var log = MfTool.LogMediaType(mediaType);
                //logger.Warn(log);

                mediaType.Set(MediaTypeAttributeKeys.InterlaceMode, (int)VideoInterlaceMode.Progressive);
                mediaType.Set(MediaTypeAttributeKeys.FrameSize, MfTool.PackToLong(width, height));
                mediaType.Set(MediaTypeAttributeKeys.FrameRate, frameRate);
                mediaType.Set(MediaTypeAttributeKeys.AllSamplesIndependent, 1);

                mediaType.Set(MediaTypeAttributeKeys.Mpeg2Profile, mpegProfile);
                mediaType.Set(MediaTypeAttributeKeys.AvgBitrate, avgBitrate);
                mediaType.Set(CodecApiPropertyKeys.AVEncCommonMaxBitRate, maxBitrate);

                mediaType.Set(MediaTypeAttributeKeys.PixelAspectRatio, pixelAspectRatio);

                encoder.SetOutputType(outputStreamId, mediaType, 0);

                OutputMediaType = mediaType;

                var _mediaLog = MfTool.LogMediaType(mediaType);
                logger.Debug("\r\nOutputMediaType:\r\n-----------------\r\n" + _mediaLog);

                //logger.Debug("\r\n" + i + ". AvailableOutputMediaType:\r\n-----------------\r\n" + mediaLog);
                //mediaType.Dispose();
                //mediaType = null;
                break;
            }

            if (OutputMediaType == null)
            {
                //...
            }

            for (int i = 0; ; i++)
            {
                try
                {
                    encoder.GetInputAvailableType(0, i, out MediaType availableType);

                    //var log = MfTool.LogMediaType(availableType);
                    //logger.Debug("\r\n" + i + ". AvalibleInputMediaType:\r\n-----------------\r\n" + log);

                    var formatId = availableType.Get(MediaTypeAttributeKeys.Subtype);
                    if (formatId == inputFormat)
                    {
                        InputMediaType = availableType;
                        availableType  = null;
                        //logger.Debug("inputFormat " + inputFormat);
                        break;
                    }

                    if (availableType != null)
                    {
                        availableType.Dispose();
                        availableType = null;
                    }
                }
                catch (SharpDX.SharpDXException ex)
                {
                    if (ex.ResultCode != SharpDX.MediaFoundation.ResultCode.NoMoreTypes)
                    {
                        throw;
                    }
                    break;
                }
            }

            if (InputMediaType == null)
            {
                throw new FormatException("Unsuported input format: " + MfTool.GetMediaTypeName(inputFormat));
            }

            //InputMediaType.Set(MediaTypeAttributeKeys.MajorType, MediaTypeGuids.Video);
            //InputMediaType.Set(MediaTypeAttributeKeys.Subtype, VideoFormatGuids.NV12);
            InputMediaType.Set(MediaTypeAttributeKeys.FrameSize, MfTool.PackToLong(width, height));
            InputMediaType.Set(MediaTypeAttributeKeys.FrameRate, frameRate);

            InputMediaType.Set(MediaTypeAttributeKeys.InterlaceMode, (int)VideoInterlaceMode.Progressive);
            InputMediaType.Set(MediaTypeAttributeKeys.AllSamplesIndependent, 1);
            encoder.SetInputType(inputStreamId, InputMediaType, 0);

            var mediaLog = MfTool.LogMediaType(InputMediaType);

            logger.Debug("\r\nInputMediaType:\r\n-----------------\r\n" + mediaLog);


            if (!syncMode)
            {
                mediaEventGenerator         = encoder.QueryInterface <MediaEventGenerator>();
                eventHandler                = new MediaEventHandler(mediaEventGenerator);
                eventHandler.EventReceived += HandleMediaEvent;
            }



            //encoder.GetInputStreamInfo(0, out TInputStreamInformation inputStreamInfo);
            //var inputInfoFlags = (MftInputStreamInformationFlags)inputStreamInfo.DwFlags;
            //logger.Debug(MfTool.LogEnumFlags(inputInfoFlags));

            //encoder.GetOutputStreamInfo(0, out TOutputStreamInformation outputStreamInfo);
            //var outputInfoFlags = (MftOutputStreamInformationFlags)outputStreamInfo.DwFlags;
            //logger.Debug(MfTool.LogEnumFlags(outputInfoFlags));


            //var guid = new Guid("901db4c7-31ce-41a2-85dc-8fa0bf41b8da");
            //encoder.QueryInterface(guid, out var pUnk);

            //var codecApi = (NativeAPIs.DShow.ICodecAPI)Marshal.GetObjectForIUnknown(pUnk);
            ////var code = codecApi.GetParameterRange(CodecApiPropertyKeys.AVEncMPVDefaultBPictureCount.Guid, out var valMin, out var valMax, out var sDelta);
            //var code = codecApi.GetValue(CodecApiPropertyKeys.AVEncMPVDefaultBPictureCount.Guid, out var val);
        }
예제 #14
0
        public void Setup(MfVideoArgs inputArgs)
        {
            logger.Debug("MfH264Decoder::Setup(...)");


            var frameRate = inputArgs.FrameRate;

            frameDuration = MfTool.TicksPerSecond / frameRate;

            var width   = inputArgs.Width;
            var height  = inputArgs.Height;
            var bufSize = width * height * 4;

            var inputFormat = VideoFormatGuids.H264;

            try
            {
                //device = new Device(adapter, DeviceCreationFlags.BgraSupport);
                if (device == null)
                {
                    using (var dxgiFactory = new SharpDX.DXGI.Factory1())
                    {
                        using (var adapter = dxgiFactory.GetAdapter1(0))
                        {
                            device = new Device(adapter,
                                                //DeviceCreationFlags.Debug |
                                                DeviceCreationFlags.VideoSupport |
                                                DeviceCreationFlags.BgraSupport);

                            using (var multiThread = device.QueryInterface <SharpDX.Direct3D11.Multithread>())
                            {
                                multiThread.SetMultithreadProtected(true);
                            }
                        }
                    }
                }


                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);

                    bool d3d11Aware = attr.Get(TransformAttributeKeys.D3D11Aware);
                    if (d3d11Aware)
                    {
                        using (DXGIDeviceManager devMan = new DXGIDeviceManager())
                        {
                            devMan.ResetDevice(device);
                            decoder.ProcessMessage(TMessageType.SetD3DManager, devMan.NativePointer);
                        }
                    }

                    attr.Set(SinkWriterAttributeKeys.LowLatency, true);

                    //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));



                //MediaType outputMediaType = null;
                //for (int i = 0; ; i++)
                //{
                //    res = decoder.TryGetOutputAvailableType(outputStreamId, i, out outputMediaType);

                //    if (!res)
                //    {
                //        break;
                //    }

                //    //outputMediaType.Set(MediaTypeAttributeKeys.AvgBitrate, 30000000);

                //    outputMediaType.Set(MediaTypeAttributeKeys.FrameSize, MfTool.PackToLong(width, height));
                //    outputMediaType.Set(MediaTypeAttributeKeys.FrameRate, MfTool.PackToLong(frameRate, 1));

                //    //outputMediaType.Set(MediaTypeAttributeKeys.InterlaceMode, (int)VideoInterlaceMode.Progressive);
                //    //outputMediaType.Set(MediaTypeAttributeKeys.AllSamplesIndependent, 1);

                //    decoder.SetOutputType(outputStreamId, outputMediaType, 0);


                //    outputMediaType.Dispose();
                //    outputMediaType = null;
                //    break;
                //}

                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;
            }
        }
예제 #15
0
        public void Setup(string fileName, MfVideoArgs Args)
        {
            logger.Debug("MfWriter::Init(...)");

            var inputFormat = VideoFormatGuids.NV12;

            //  var inputFormat = VideoFormatGuids.Rgb32; // VideoFormatGuids.NV12


            frameDuration = 10_000_000 / Args.FrameRate;

            var width   = Args.Width;
            var height  = Args.Height;
            var bufSize = width * height * 4;


            try
            {
                using (var attr = new MediaAttributes(6))
                {
                    attr.Set(SinkWriterAttributeKeys.ReadwriteEnableHardwareTransforms, 1);
                    attr.Set(SinkWriterAttributeKeys.ReadwriteDisableConverters, 0);
                    attr.Set(TranscodeAttributeKeys.TranscodeContainertype, TranscodeContainerTypeGuids.Mpeg4);
                    attr.Set(SinkWriterAttributeKeys.LowLatency, true);
                    attr.Set(SinkWriterAttributeKeys.DisableThrottling, 1);

                    using (var devMan = new DXGIDeviceManager())
                    {
                        devMan.ResetDevice(device);
                        attr.Set(SinkWriterAttributeKeys.D3DManager, devMan);
                    }

                    sinkWriter = MediaFactory.CreateSinkWriterFromURL(fileName, null, attr);
                }

                using (var outputMediaType = new MediaType())
                {
                    outputMediaType.Set(MediaTypeAttributeKeys.MajorType, MediaTypeGuids.Video);
                    outputMediaType.Set(MediaTypeAttributeKeys.Subtype, VideoFormatGuids.H264);
                    outputMediaType.Set(MediaTypeAttributeKeys.AvgBitrate, 8_000_000);
                    outputMediaType.Set(MediaTypeAttributeKeys.InterlaceMode, (int)VideoInterlaceMode.Progressive);
                    outputMediaType.Set(MediaTypeAttributeKeys.FrameSize, MfTool.PackToLong(width, height));
                    outputMediaType.Set(MediaTypeAttributeKeys.FrameRate, Args.FrameRate);
                    outputMediaType.Set(MediaTypeAttributeKeys.PixelAspectRatio, MfTool.PackToLong(1, 1));


                    sinkWriter.AddStream(outputMediaType, out videoStreamIndex);

                    Debug.WriteLine("mediaTypeOut " + videoStreamIndex);
                }


                using (var inputMediaType = new MediaType())
                {
                    inputMediaType.Set(MediaTypeAttributeKeys.MajorType, MediaTypeGuids.Video);
                    inputMediaType.Set(MediaTypeAttributeKeys.Subtype, inputFormat);
                    inputMediaType.Set(MediaTypeAttributeKeys.InterlaceMode, (int)VideoInterlaceMode.Progressive);
                    inputMediaType.Set(MediaTypeAttributeKeys.FrameSize, MfTool.PackToLong(width, height));
                    inputMediaType.Set(MediaTypeAttributeKeys.FrameRate, Args.FrameRate);
                    inputMediaType.Set(MediaTypeAttributeKeys.PixelAspectRatio, MfTool.PackToLong(1, 1));

                    inputMediaType.Set(MediaTypeAttributeKeys.AllSamplesIndependent, 1);

                    using (var encoderParams = new MediaAttributes(2))
                    {
                        encoderParams.Set(CodecApiPropertyKeys.AVEncCommonRateControlMode, RateControlMode.Quality);
                        encoderParams.Set(CodecApiPropertyKeys.AVEncCommonQuality, Args.Quality);

                        sinkWriter.SetInputMediaType(0, inputMediaType, encoderParams);
                    }
                }

                bufTexture = new Texture2D(device, new Texture2DDescription
                {
                    CpuAccessFlags    = CpuAccessFlags.Read,
                    BindFlags         = BindFlags.None,
                    Format            = Format.B8G8R8A8_UNorm,
                    Width             = width,
                    Height            = height,
                    OptionFlags       = ResourceOptionFlags.None,
                    MipLevels         = 1,
                    ArraySize         = 1,
                    SampleDescription = { Count = 1, Quality = 0 },
                    Usage             = ResourceUsage.Staging
                });

                videoSample = MediaFactory.CreateVideoSampleFromSurface(null);

                // Create the media buffer from the texture
                MediaFactory.CreateDXGISurfaceBuffer(typeof(Texture2D).GUID, bufTexture, 0, false, out mediaBuffer);

                using (var buffer2D = mediaBuffer.QueryInterface <Buffer2D>())
                {
                    mediaBuffer.CurrentLength = buffer2D.ContiguousLength;
                }

                // Attach the created buffer to the sample
                videoSample.AddBuffer(mediaBuffer);
            }
            catch (Exception ex)
            {
                logger.Error(ex);

                Close();
                throw;
            }
        }
예제 #16
0
        public bool Setup(MfVideoArgs inputArgs, MfVideoArgs outputArgs)
        {
            logger.Debug("MfProcessor::Setup(...)");

            //Debug.Assert(device != null, "device != null");

            //var winVersion = Environment.OSVersion.Version;
            //bool isCompatibleOSVersion = (winVersion.Major >= 6 && winVersion.Minor >= 2);

            //if (!isCompatibleOSVersion)
            //{
            //    throw new NotSupportedException("Windows versions earlier than 8 are not supported.");
            //}

            try
            {
                processor = new Transform(ClsId.VideoProcessorMFT);
                // processor = new Transform(CLSID.CColorConvertDMO);
                //processor = new Transform(CLSID.MJPEGDecoderMFT);

                if (device != null)
                {
                    using (var attr = processor.Attributes)
                    {
                        bool d3d11Aware = attr.Get(TransformAttributeKeys.D3D11Aware);
                        if (d3d11Aware)
                        {
                            using (DXGIDeviceManager devMan = new DXGIDeviceManager())
                            {
                                devMan.ResetDevice(device);

                                processor.ProcessMessage(TMessageType.SetD3DManager, devMan.NativePointer);
                            }
                        }
                    }
                }

                int inputStreamCount   = -1;
                int outputStreamsCount = -1;
                processor.GetStreamCount(out inputStreamCount, out outputStreamsCount);
                int[] inputStreamIDs  = new int[inputStreamCount];
                int[] outputStreamIDs = new int[outputStreamsCount];

                if (processor.TryGetStreamIDs(inputStreamIDs, outputStreamIDs))
                {
                    inputStreamId  = inputStreamIDs[0];
                    outputStreamId = outputStreamIDs[0];
                }
                else
                {
                    inputStreamId  = 0;
                    outputStreamId = 0;
                }

                InputMediaType = new MediaType();

                InputMediaType.Set(MediaTypeAttributeKeys.MajorType, MediaTypeGuids.Video);
                InputMediaType.Set(MediaTypeAttributeKeys.Subtype, inputArgs.Format); //VideoFormatGuids.NV12

                InputMediaType.Set(MediaTypeAttributeKeys.FrameSize, MfTool.PackToLong(inputArgs.Width, inputArgs.Height));
                // InputMediaType.Set(MediaTypeAttributeKeys.FrameRate, MfTool.PackToLong(30, 1));

                // InputMediaType.Set(MediaTypeAttributeKeys.AllSamplesIndependent, 1);
                //InputMediaType.Set(MediaTypeAttributeKeys.FrameSize, bufSize);
                //InputMediaType.Set(MediaTypeAttributeKeys.FixedSizeSamples, 1);
                //InputMediaType.Set(MediaTypeAttributeKeys.FrameRate, PackLong(30, 1));

                logger.Debug("VideoProcessor::SetInputType\r\n" + MfTool.LogMediaType(InputMediaType));
                processor.SetInputType(inputStreamId, InputMediaType, 0);


                try
                {
                    for (int i = 0; ; i++)
                    {
                        var res = processor.TryGetOutputAvailableType(0, i, out MediaType mediaType);
                        if (!res)
                        {
                            logger.Warn("NoMoreTypes");
                            break;
                        }


                        var subType = mediaType.Get(MediaTypeAttributeKeys.Subtype);

                        logger.Debug(MfTool.GetMediaTypeName(subType, true));
                        if (subType == outputArgs.Format) //VideoFormatGuids.Argb32)//Argb32)//YUY2)//NV12)
                        {
                            OutputMediaType = mediaType;
                            break;
                        }
                        mediaType.Dispose();
                    }
                }
                catch (SharpDX.SharpDXException ex)
                {
                    if (ex.ResultCode != SharpDX.MediaFoundation.ResultCode.NoMoreTypes)
                    {
                        throw;
                    }
                }

                if (OutputMediaType == null)
                {
                    logger.Warn("Format not supported: " + MfTool.GetMediaTypeName(outputArgs.Format, true));
                    return(false);
                }


                //OutputMediaType.Set(MediaTypeAttributeKeys.MajorType, MediaTypeGuids.Video);
                //OutputMediaType.Set(MediaTypeAttributeKeys.Subtype, VideoFormatGuids.Rgb24);

                OutputMediaType.Set(MediaTypeAttributeKeys.FrameSize, MfTool.PackToLong(outputArgs.Width, outputArgs.Height));
                // OutputMediaType.Set(MediaTypeAttributeKeys.PixelAspectRatio, MfTool.PackToLong(1, 1));

                //OutputMediaType.Set(MediaTypeAttributeKeys.FrameSize, MfTool.PackToLong(outputArgs.Width, outputArgs.Height));

                //OutputMediaType.Set(MediaTypeAttributeKeys.AllSamplesIndependent, 1);
                //OutputMediaType.Set(MediaTypeAttributeKeys.FixedSizeSamples, 1);

                logger.Debug("VideoProcessor::SetOutputType\r\n" + MfTool.LogMediaType(OutputMediaType));
                processor.SetOutputType(outputStreamId, OutputMediaType, 0);
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                Close();

                throw;
            }

            return(true);
        }