コード例 #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>();
            }
        }
コード例 #2
0
        public CapturePlayer(Device device)
        {
            using (var manager = new DXGIDeviceManager())
            {
                manager.ResetDevice(device);

                captureEngineAttributes.Set(CaptureEngineAttributeKeys.D3DManager, manager);
            }
        }
コード例 #3
0
        /// <inheritdoc />
        /// <summary>
        ///   Begins encoding the video.
        /// </summary>
        /// <param name="frameSize">Frame size.</param>
        /// <param name="stream">Output stream.</param>
        public void Initialize(Size frameSize, Stream stream)
        {
            MediaFactory.Startup(MediaFactory.Version, NoSocket);

            using (var attrs = new MediaAttributes()) {
                attrs.Set(TranscodeAttributeKeys.TranscodeContainertype, ContainerType);
                attrs.Set(SinkWriterAttributeKeys.ReadwriteEnableHardwareTransforms, 1);
                attrs.Set(SinkWriterAttributeKeys.DisableThrottling, 1);
                attrs.Set(SinkWriterAttributeKeys.LowLatency, true);

                if (SurfacePointer != IntPtr.Zero)
                {
                    // get the source surface
                    this.surface = new Texture2D(SurfacePointer);

                    // create and bind a DXGI device manager
                    this.dxgiManager = new DXGIDeviceManager();
                    this.dxgiManager.ResetDevice(this.surface.Device);

                    attrs.Set(SinkWriterAttributeKeys.D3DManager, this.dxgiManager);
                }

                // create byte stream and sink writer
                this.byteStream = new ByteStream(stream);
                this.sinkWriter = MediaFactory.CreateSinkWriterFromURL(null, this.byteStream.NativePointer, attrs);

                // create output media type
                using (var outMediaType = new MediaType()) {
                    outMediaType.Set(MediaTypeAttributeKeys.MajorType, MediaTypeGuids.Video);
                    outMediaType.Set(MediaTypeAttributeKeys.Subtype, VideoFormat);
                    outMediaType.Set(MediaTypeAttributeKeys.AvgBitrate, BitRate);
                    outMediaType.Set(MediaTypeAttributeKeys.InterlaceMode, (int)VideoInterlaceMode.Progressive);
                    outMediaType.Set(MediaTypeAttributeKeys.FrameSize,
                                     ((long)frameSize.Width << 32) | (uint)frameSize.Height);
                    outMediaType.Set(MediaTypeAttributeKeys.FrameRate, ((long)FrameRate << 32) | 1);
                    outMediaType.Set(MediaTypeAttributeKeys.PixelAspectRatio, (1 << 32) | (uint)1);

                    this.sinkWriter.AddStream(outMediaType, out this.streamIdx);
                }

                // create input media type
                using (var inMediaType = new MediaType()) {
                    inMediaType.Set(MediaTypeAttributeKeys.MajorType, MediaTypeGuids.Video);
                    inMediaType.Set(MediaTypeAttributeKeys.Subtype, VideoFormatGuids.Rgb32);
                    inMediaType.Set(MediaTypeAttributeKeys.InterlaceMode, (int)VideoInterlaceMode.Progressive);
                    inMediaType.Set(MediaTypeAttributeKeys.FrameSize,
                                    ((long)frameSize.Width << 32) | (uint)frameSize.Height);
                    inMediaType.Set(MediaTypeAttributeKeys.FrameRate, ((long)FrameRate << 32) | 1);
                    inMediaType.Set(MediaTypeAttributeKeys.PixelAspectRatio, (1 << 32) | (uint)1);

                    this.sinkWriter.SetInputMediaType(this.streamIdx, inMediaType, null);
                    this.sinkWriter.BeginWriting();
                }
            }
        }
コード例 #4
0
        /// <inheritdoc />
        /// <summary>
        ///   Releases resources.
        /// </summary>
        public void Dispose()
        {
            this.byteStream?.Dispose();
            this.sinkWriter?.Dispose();
            this.dxgiManager?.Dispose();
            MediaFactory.Shutdown();

            this.sinkWriter  = null;
            this.byteStream  = null;
            this.dxgiManager = null;
        }
コード例 #5
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);
     }
 }
コード例 #6
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);
        }
コード例 #7
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);
        }
コード例 #8
0
ファイル: Program.cs プロジェクト: ukod/LiveScreenWallpaper
            /// <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);
            }
コード例 #9
0
ファイル: VideoSystem.Direct3D.cs プロジェクト: Aggror/Stride
        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();
        }
コード例 #10
0
        private void RecreateResources(IVisualContainerElement root, out RenderContext context)
        {
            _dxgiFactory?.Dispose();
            _swapChain?.Dispose();
            _direct3DDevice?.Dispose();
            _directWriteFactory?.Dispose();

            CreateSwapChainAndDevice(out _swapChainDescription, out _swapChain, out _direct3DDevice);
            _dxgiDevice  = _direct3DDevice.QueryInterface <SharpDX.DXGI.Device>();
            _dxgiFactory = _swapChain.GetParent <Factory>();

            // Video (EVR) initialization.
            var multithread = _direct3DDevice.QueryInterface <DeviceMultithread>();

            multithread.SetMultithreadProtected(true);
            if (_dxgiDeviceManager == null)
            {
                try {
                    _dxgiDeviceManager = new DXGIDeviceManager();
                } catch (System.EntryPointNotFoundException) {
                    // Windows 7
                }
            }
            _dxgiDeviceManager?.ResetDevice(_direct3DDevice);

            _directWriteFactory = new SharpDX.DirectWrite.Factory();

            context        = new RenderContext(this, new Size(_swapChainDescription.ModeDescription.Width, _swapChainDescription.ModeDescription.Height));
            _renderContext = context;

            root.OnLayout();

            root.OnGotContext(context);

            _isSizeChanged = false;

            ++_controlResizeCounter;
            if (_controlResizeCounter == StartupControlResizeCount)
            {
                // WTF...
                // Look into MediaEngine and DXGIDeviceManager?
                Game.Window.Invoke(new Action(() => Game.Window.RaiseStageReady(EventArgs.Empty)));

                root.OnStageReady(context);
            }
        }
コード例 #11
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);
        }
コード例 #12
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);
                }
        }
コード例 #13
0
ファイル: Video.cs プロジェクト: limyz/DTXMania2
        public Video(DXGIDeviceManager deviceManager, DeviceContext d2dDeviceContext, VariablePath ファイルパス, double 再生速度 = 1.0)
            : this()
        {
            using var _ = new LogBlock(Log.現在のメソッド名);

            this.再生速度 = 再生速度;
            try
            {
                this._VideoSource = new MediaFoundationFileVideoSource(deviceManager, d2dDeviceContext, ファイルパス, 再生速度);
            }
            catch
            {
                Log.WARNING($"動画のデコードに失敗しました。[{ファイルパス.変数付きパス}");
                this._VideoSource = null;
                return;
            }

            this._ファイルから生成した = true;
        }
コード例 #14
0
        /// <inheritdoc />
        /// <summary>
        ///   Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources
        /// </summary>
        public override void Dispose()
        {
            try {
                this.sinkWriter.Finalize();
            } catch (SharpDXException exception) when(exception.ResultCode.Code == MF_E_SINK_NO_SAMPLES_PROCESSED)
            {
                this.byteStream.Length = 0;
            }

            this.byteStream?.Dispose();
            this.sinkWriter?.Dispose();
            this.dxgiManager?.Dispose();

            MediaFactory.Shutdown();

            this.sinkWriter  = null;
            this.byteStream  = null;
            this.dxgiManager = null;
        }
コード例 #15
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;
        }
コード例 #16
0
ファイル: MediaPlayer.cs プロジェクト: Makzz90/VKClient_re
 public void Initialize(SharpDXContext context)
 {
     lock (this.lockObject)
     {
         this.sharpDxContext = context;
         MediaManager.Startup(false);
         this.multithread = this.sharpDxContext.D3DContext.QueryInterface <DeviceMultithread>();
         this.multithread.SetMultithreadProtected((Bool)true);
         this.dxgiDeviceManager = new DXGIDeviceManager();
         this.dxgiDeviceManager.ResetDevice((ComObject)this.sharpDxContext.D3DDevice);
         this.attributes = new MediaEngineAttributes(0)
         {
             DxgiManager       = this.dxgiDeviceManager,
             VideoOutputFormat = 87
         };
         using (MediaEngineClassFactory resource_0 = new MediaEngineClassFactory())
             this.mediaEngine = new MediaEngine(resource_0, this.attributes, MediaEngineCreateFlags.None, new MediaEngineNotifyDelegate(this.OnMediaEngineEvent));
         this.mediaEngineEx        = this.mediaEngine.QueryInterface <MediaEngineEx>();
         this.mediaEngine.Loop     = (Bool)true;
         this.mediaEngine.AutoPlay = (Bool)true;
     }
 }
コード例 #17
0
        public static MediaFoundationStreamingSources CreateFromFile(DXGIDeviceManager dxgiDeviceManager, VariablePath ファイルパス, WaveFormat soundDeviceFormat)
        {
            var sources = new MediaFoundationStreamingSources();

            #region " ファイルから SourceReaderEx を生成する。"
            //----------------
            using (var ビデオ属性 = new MediaAttributes())
            {
                // DXVAに対応しているGPUの場合には、それをデコードに利用するよう指定する。
                ビデオ属性.Set(SourceReaderAttributeKeys.D3DManager, dxgiDeviceManager);

                // 追加のビデオプロセッシングを有効にする。
                ビデオ属性.Set(SourceReaderAttributeKeys.EnableAdvancedVideoProcessing, true);    // 真偽値が bool だったり

                // 追加のビデオプロセッシングを有効にしたら、こちらは無効に。
                ビデオ属性.Set(SinkWriterAttributeKeys.ReadwriteDisableConverters, 0);             // int だったり

                // 属性を使って、SourceReaderEx を生成。
                using (var sourceReader = new SourceReader(ファイルパス.数なしパス, ビデオ属性))        // パスは URI 扱い
                    sources._SourceReaderEx = sourceReader.QueryInterface <SourceReaderEx>();
            }
            //----------------
            #endregion

            #region " WaveFormat を生成。"
            //----------------
            sources._Audioのフォーマット = new WaveFormat(
                soundDeviceFormat.SampleRate,
                32,
                soundDeviceFormat.Channels,
                AudioEncoding.IeeeFloat);
            //----------------
            #endregion

            sources._SourceReaderEx生成後の初期化();

            return(sources);
        }
コード例 #18
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;
        }
コード例 #19
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);
        }
コード例 #20
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;
            }
        }
コード例 #21
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;
            }
        }
コード例 #22
0
        /// <summary>
        /// Configures the Direct3D device, and stores handles to it and the device context.
        /// </summary>
        private void CreateDeviceResources()
        {
            this.DisposeDeviceAndContext();

            // This flag adds support for surfaces with a different color channel ordering
            // than the API default. It is required for compatibility with Direct2D.
            DeviceCreationFlags creationFlags = DeviceCreationFlags.BgraSupport;

#if DEBUG
            // If the project is in a debug build, enable debugging via SDK Layers with this flag.
            creationFlags |= DeviceCreationFlags.Debug;
#endif

            // This array defines the set of DirectX hardware feature levels this app will support.
            // Note the ordering should be preserved.
            // Note that MixedReality supports feature level 11.1. The MixedReality emulator is also capable
            // of running on graphics cards starting with feature level 10.0.
            FeatureLevel[] featureLevels =
            {
                FeatureLevel.Level_12_1,
                FeatureLevel.Level_12_0,
                FeatureLevel.Level_11_1,
                FeatureLevel.Level_11_0,
                FeatureLevel.Level_10_1,
                FeatureLevel.Level_10_0
            };

            // Create the Direct3D 11 API device object and a corresponding context.
            try
            {
                if (this.dxgiAdapter != null)
                {
                    using (var device = new Device(this.dxgiAdapter, creationFlags, featureLevels))
                    {
                        // Store pointers to the Direct3D 11.1 API device.
                        this.d3dDevice = this.ToDispose(device.QueryInterface <Device3>());
                    }
                }
                else
                {
                    using (var device = new Device(DriverType.Hardware, creationFlags, featureLevels))
                    {
                        // Store a pointer to the Direct3D device.
                        this.d3dDevice = this.ToDispose(device.QueryInterface <Device3>());
                    }
                }
            }
            catch
            {
                // If the initialization fails, fall back to the WARP device.
                // For more information on WARP, see:
                // http://go.microsoft.com/fwlink/?LinkId=286690
                using (var device = new Device(DriverType.Warp, creationFlags, featureLevels))
                {
                    this.d3dDevice = this.ToDispose(device.QueryInterface <Device3>());
                }
            }

            // Cache the feature level of the device that was created.
            this.d3dFeatureLevel = this.d3dDevice.FeatureLevel;

            // Store a pointer to the Direct3D immediate context.
            this.d3dContext = this.ToDispose(this.d3dDevice.ImmediateContext3);

            // Acquire the DXGI interface for the Direct3D device.
            using (var dxgiDevice = this.d3dDevice.QueryInterface <SharpDX.DXGI.Device3>())
            {
                // Wrap the native device using a WinRT interop object.
                IntPtr pUnknown;
                uint   hr = InteropStatics.CreateDirect3D11DeviceFromDXGIDevice(dxgiDevice.NativePointer, out pUnknown);
                if (hr == 0)
                {
                    this.d3dInteropDevice = (IDirect3DDevice)Marshal.GetObjectForIUnknown(pUnknown);
                    Marshal.Release(pUnknown);
                }

                // Store a pointer to the DXGI adapter.
                // This is for the case of no preferred DXGI adapter, or fallback to WARP.
                this.dxgiAdapter = this.ToDispose(dxgiDevice.Adapter.QueryInterface <SharpDX.DXGI.Adapter3>());
            }

            // Check for device support for the optional feature that allows setting the render target array index from the vertex shader stage.
            var options = this.d3dDevice.CheckD3D113Features3();
            if (options.VPAndRTArrayIndexFromAnyShaderFeedingRasterizer)
            {
                this.d3dDeviceSupportsVprt = true;
            }

            // Startup MediaManager
            MediaManager.Startup();

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

            // Create a DXGI Device Manager
            this.dxgiDeviceManager = new SharpDX.MediaFoundation.DXGIDeviceManager();
            this.dxgiDeviceManager.ResetDevice(this.d3dDevice);
        }
コード例 #23
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);
        }
コード例 #24
0
 /// <inheritdoc />
 /// <summary>
 ///   Binds a DXGI device to the video codec
 /// </summary>
 /// <param name="device">DXGI device object</param>
 public void BindDevice(Device device)
 {
     this.dxgiManager = new DXGIDeviceManager();
     this.dxgiManager.ResetDevice(device);
 }
コード例 #25
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);
        }
コード例 #26
0
        // 生成と終了


        public MediaFoundationFileVideoSource(DXGIDeviceManager deviceManager, DeviceContext d2dDeviceContext, VariablePath ファイルパス, double 再生速度 = 1.0)
        {
            using var _ = new LogBlock(Log.現在のメソッド名);

            this._D2DDeviceContext = d2dDeviceContext;

            this.再生速度 = Math.Clamp(再生速度, min: 0.01, max: 10.0);

            #region " フレームキューを生成。"
            //----------------
            // キューサイズは3フレームとする。
            this._FrameQueue = new BlockingQueue <VideoFrame>(3);
            //----------------
            #endregion

            #region " ファイルから SourceReaderEx を生成する。"
            //----------------
            using (var ビデオ属性 = new MediaAttributes())
            {
                // DXVAに対応しているGPUの場合には、それをデコードに利用するよう指定する。
                ビデオ属性.Set(SourceReaderAttributeKeys.D3DManager, deviceManager);

                // 追加のビデオプロセッシングを有効にする。
                ビデオ属性.Set(SourceReaderAttributeKeys.EnableAdvancedVideoProcessing, true);    // 真偽値が bool だったり

                // 追加のビデオプロセッシングを有効にしたら、こちらは無効に。
                ビデオ属性.Set(SinkWriterAttributeKeys.ReadwriteDisableConverters, 0);             // int だったり

                // 属性を使って、SourceReaderEx を生成。
                using var sourceReader = new SourceReader(ファイルパス.数なしパス, ビデオ属性);       // パスは URI 扱い
                this._SourceReaderEx   = sourceReader.QueryInterface <SourceReaderEx>();
            }

            // 最初のビデオストリームだけを選択。
            this._SourceReaderEx.SetStreamSelection(SourceReaderIndex.AllStreams, false);
            this._SourceReaderEx.SetStreamSelection(SourceReaderIndex.FirstVideoStream, true);
            //----------------
            #endregion

            #region " ビデオの長さ(総演奏時間)を取得する。"
            //----------------
            {
                var mediaSourceDuration = this._SourceReaderEx.GetPresentationAttribute(SourceReaderIndex.MediaSource, PresentationDescriptionAttributeKeys.Duration);
                this.総演奏時間sec = (long)(mediaSourceDuration / this.再生速度 / 10_000_000.0);
            }
            //----------------
            #endregion

            #region " デコーダを選択し、完全メディアタイプを取得する。"
            //----------------
            // 部分メディアタイプを設定する。
            using (var 部分MediaType = new MediaType())
            {
                // フォーマットは ARGB32 で固定とする。(SourceReaderEx を使わない場合、H264 では ARGB32 が選べないので注意。)
                部分MediaType.Set(MediaTypeAttributeKeys.MajorType, MediaTypeGuids.Video);
                部分MediaType.Set(MediaTypeAttributeKeys.Subtype, VideoFormatGuids.Argb32);

                // 部分メディアタイプを SourceReaderEx にセットする。SourceReaderEx は、必要なデコーダをロードするだろう。
                this._SourceReaderEx.SetCurrentMediaType(SourceReaderIndex.FirstVideoStream, 部分MediaType);
            }

            // 完成されたメディアタイプを取得する。
            this._MediaType = this._SourceReaderEx.GetCurrentMediaType(SourceReaderIndex.FirstVideoStream);
            //----------------
            #endregion

            #region " ビデオのフレームサイズを取得する。(動画の途中でのサイズ変更は考慮しない。)"
            //----------------
            long packedFrameSize = this._MediaType.Get(MediaTypeAttributeKeys.FrameSize);
            this.フレームサイズ = new Size2F((packedFrameSize >> 32) & 0xFFFFFFFF, (packedFrameSize) & 0xFFFFFFFF);
            //----------------
            #endregion

            this._デコードキャンセル  = new CancellationTokenSource();
            this._デコード起動完了通知 = new ManualResetEventSlim(false);
            this._一時停止解除通知   = new ManualResetEventSlim(true);
        }