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; } }
public void Setup(int deviceIndex = 0) { logger.Debug("VideoCaptureSource::Setup()"); Activate[] activates = null; using (var attributes = new MediaAttributes()) { MediaFactory.CreateAttributes(attributes, 1); attributes.Set(CaptureDeviceAttributeKeys.SourceType, CaptureDeviceAttributeKeys.SourceTypeVideoCapture.Guid); activates = MediaFactory.EnumDeviceSources(attributes); } if (activates == null || activates.Length == 0) { logger.Error("SourceTypeVideoCapture not found"); Console.ReadKey(); } foreach (var activate in activates) { Console.WriteLine("---------------------------------------------"); var friendlyName = activate.Get(CaptureDeviceAttributeKeys.FriendlyName); var isHwSource = activate.Get(CaptureDeviceAttributeKeys.SourceTypeVidcapHwSource); //var maxBuffers = activate.Get(CaptureDeviceAttributeKeys.SourceTypeVidcapMaxBuffers); var symbolicLink = activate.Get(CaptureDeviceAttributeKeys.SourceTypeVidcapSymbolicLink); logger.Info("FriendlyName " + friendlyName + "\r\n" + "isHwSource " + isHwSource + "\r\n" + //"maxBuffers " + maxBuffers + "symbolicLink " + symbolicLink); } var currentActivator = activates[deviceIndex]; mediaSource = currentActivator.ActivateObject <MediaSource>(); foreach (var a in activates) { a.Dispose(); } using (var mediaAttributes = new MediaAttributes(IntPtr.Zero)) { MediaFactory.CreateAttributes(mediaAttributes, 2); mediaAttributes.Set(SourceReaderAttributeKeys.EnableVideoProcessing, 1); //var devMan = new DXGIDeviceManager(); //devMan.ResetDevice(device); //mediaAttributes.Set(SourceReaderAttributeKeys.D3DManager, devMan); //MediaFactory.CreateSourceReaderFromMediaSource(mediaSource, mediaAttributes, sourceReader); sourceReader = new SourceReader(mediaSource, mediaAttributes); } Console.WriteLine("------------------CurrentMediaType-------------------"); var mediaType = sourceReader.GetCurrentMediaType(SourceReaderIndex.FirstVideoStream); Console.WriteLine(MfTool.LogMediaType(mediaType)); var frameSize = MfTool.GetFrameSize(mediaType); var subtype = mediaType.Get(MediaTypeAttributeKeys.Subtype); mediaType?.Dispose(); //Device device = null; int adapterIndex = 0; using (var dxgiFactory = new SharpDX.DXGI.Factory1()) { var adapter = dxgiFactory.Adapters1[adapterIndex]; device = new Device(adapter, //DeviceCreationFlags.Debug | DeviceCreationFlags.VideoSupport | DeviceCreationFlags.BgraSupport); using (var multiThread = device.QueryInterface <SharpDX.Direct3D11.Multithread>()) { multiThread.SetMultithreadProtected(true); } } SharedTexture = new Texture2D(device, new Texture2DDescription { CpuAccessFlags = CpuAccessFlags.None, BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource, Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm, Width = frameSize.Width, Height = frameSize.Height, MipLevels = 1, ArraySize = 1, SampleDescription = { Count = 1, Quality = 0 }, Usage = ResourceUsage.Default, //OptionFlags = ResourceOptionFlags.GdiCompatible//ResourceOptionFlags.None, OptionFlags = ResourceOptionFlags.Shared, }); texture = new Texture2D(device, new Texture2DDescription { CpuAccessFlags = CpuAccessFlags.Read, BindFlags = BindFlags.None, Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm, Width = frameSize.Width, Height = frameSize.Height, MipLevels = 1, ArraySize = 1, SampleDescription = { Count = 1, Quality = 0 }, Usage = ResourceUsage.Staging, OptionFlags = ResourceOptionFlags.None, }); processor = new MfVideoProcessor(null); var inProcArgs = new MfVideoArgs { Width = frameSize.Width, Height = frameSize.Height, // Format = VideoFormatGuids.Rgb24, Format = subtype,//VideoFormatGuids.NV12, }; var outProcArgs = new MfVideoArgs { Width = frameSize.Width, Height = frameSize.Height, Format = VideoFormatGuids.Argb32, //Format = VideoFormatGuids.Rgb32,//VideoFormatGuids.Argb32, }; processor.Setup(inProcArgs, outProcArgs); //processor.SetMirror(VideoProcessorMirror.MirrorHorizontal); processor.SetMirror(VideoProcessorMirror.MirrorVertical); }
//public IntPtr hWnd = IntPtr.Zero; public void Setup(VideoEncoderSettings inputPars, VideoEncoderSettings outputPars, NetworkSettings networkPars) { logger.Debug("ScreenReceiver::Setup(...)"); var inputArgs = new MfVideoArgs { Width = inputPars.Resolution.Width, Height = inputPars.Resolution.Height, FrameRate = MfTool.PackToLong(inputPars.FrameRate), }; var outputArgs = new MfVideoArgs { Width = outputPars.Resolution.Width, Height = outputPars.Resolution.Height, FrameRate = MfTool.PackToLong(outputPars.FrameRate), }; int adapterIndex = 0; using (var dxgiFactory = new SharpDX.DXGI.Factory1()) { using (var adapter = dxgiFactory.GetAdapter1(adapterIndex)) { device = new Device(adapter, //DeviceCreationFlags.Debug | DeviceCreationFlags.VideoSupport | DeviceCreationFlags.BgraSupport); using (var multiThread = device.QueryInterface <SharpDX.Direct3D11.Multithread>()) { multiThread.SetMultithreadProtected(true); } } } sharedTexture = new Texture2D(device, new Texture2DDescription { CpuAccessFlags = CpuAccessFlags.None, BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource, Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm, Width = outputArgs.Width, //640,//texture.Description.Width, Height = outputArgs.Height, //480,//texture.Description.Height, MipLevels = 1, ArraySize = 1, SampleDescription = { Count = 1, Quality = 0 }, Usage = ResourceUsage.Default, //OptionFlags = ResourceOptionFlags.GdiCompatible//ResourceOptionFlags.None, OptionFlags = ResourceOptionFlags.Shared, }); //ImageProvider = new D3DImageProvider(dispatcher); //decoder = new DXVADecoder(IntPtr.Zero); decoder = new MfH264Decoder(device); decoder.Setup(inputArgs); var decoderType = decoder.OutputMediaType; var decFormat = decoderType.Get(MediaTypeAttributeKeys.Subtype); var decFrameSize = MfTool.GetFrameSize(decoderType); processor = new MfVideoProcessor(device); var inProcArgs = new MfVideoArgs { Width = decFrameSize.Width, Height = decFrameSize.Height, Format = decFormat, }; var outProcArgs = new MfVideoArgs { Width = outputArgs.Width, Height = outputArgs.Height, Format = VideoFormatGuids.Argb32, }; processor.Setup(inProcArgs, outProcArgs); h264Session = new H264Session(); if (networkPars.TransportMode == TransportMode.Tcp) { rtpReceiver = new RtpTcpReceiver(h264Session); } else if (networkPars.TransportMode == TransportMode.Udp) { rtpReceiver = new RtpUdpReceiver(h264Session); } else { throw new Exception("networkPars.TransportMode"); } h264Session.SSRC = networkPars.SSRC; rtpReceiver.Open(networkPars); rtpReceiver.RtpPacketReceived += RtpReceiver_RtpPacketReceived; }
public void Open(VideoEncoderSettings encoderSettings) { logger.Debug("VideoEncoder::Setup(...)"); //var hwContext = videoSource.hwContext; // var hwDevice = hwContext.Device3D11; var hwBuffer = videoSource.SharedTexture; var hwDescr = hwBuffer.Description; var srcSize = new Size(hwDescr.Width, hwDescr.Height); var srcFormat = MfTool.GetVideoFormatGuidFromDXGIFormat(hwDescr.Format); var destSize = encoderSettings.Resolution; //new Size(destParams.Width, destParams.Height); var adapterId = videoSource.AdapterId; using (var adapter = DxTool.FindAdapter1(adapterId)) { var descr = adapter.Description; int adapterVenId = descr.VendorId; logger.Info("Adapter: " + descr.Description + " " + adapterVenId); var flags = DeviceCreationFlags.VideoSupport | DeviceCreationFlags.BgraSupport; //DeviceCreationFlags.Debug; device = new SharpDX.Direct3D11.Device(adapter, flags); using (var multiThread = device.QueryInterface <SharpDX.Direct3D11.Multithread>()) { multiThread.SetMultithreadProtected(true); } } var profile = MfTool.GetMfH264Profile(encoderSettings.Profile); var bitrateMode = MfTool.GetMfBitrateMode(encoderSettings.BitrateMode); var aspectRatio = encoderSettings.AspectRatio; var encArgs = new MfVideoArgs { Width = destSize.Width, //srcSize.Width, Height = destSize.Height, //srcSize.Height, Format = VideoFormatGuids.NV12, //VideoFormatGuids.Argb32, FrameRate = MfTool.PackToLong(encoderSettings.FrameRate), MaxBitrate = encoderSettings.MaxBitrate * 1000, //kbps->bps AvgBitrate = encoderSettings.Bitrate * 1000, LowLatency = encoderSettings.LowLatency, AdapterId = videoSource.AdapterId, Profile = profile, BitrateMode = bitrateMode, GopSize = encoderSettings.GOPSize, Quality = encoderSettings.Quality, EncoderId = encoderSettings.EncoderId, AspectRatio = MfTool.PackToLong(aspectRatio) }; processor = new MfVideoProcessor(device); var inProcArgs = new MfVideoArgs { Width = srcSize.Width, Height = srcSize.Height, Format = srcFormat, //SharpDX.MediaFoundation.VideoFormatGuids.Argb32, }; var outProcArgs = new MfVideoArgs { Width = encArgs.Width, Height = encArgs.Height, Format = encArgs.Format, //VideoFormatGuids.NV12,//.Argb32, }; processor.Setup(inProcArgs, outProcArgs); bufTexture = new Texture2D(device, new Texture2DDescription { // Format = Format.NV12, Format = hwDescr.Format, //SharpDX.DXGI.Format.B8G8R8A8_UNorm, Width = srcSize.Width, Height = srcSize.Height, MipLevels = 1, ArraySize = 1, SampleDescription = { Count = 1 }, }); processor?.Start(); var encoderName = encoderSettings.EncoderId; if (encoderName == "libx264" || encoderName == "h264_nvenc") { encoder = new MfFFMpegVideoEncoder(); } else { encoder = new MfH264EncoderEx(device); } encoder.Setup(encArgs); encoder.DataEncoded += Encoder_DataEncoded; ////encoder.DataReady += MfEncoder_DataReady; encoder.Start(); }
public void Setup(MfVideoArgs args) { logger.Debug("MfEncoderAsync::Setup(...)"); 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 { var adapterId = args.AdapterId; using (var adapter = FindAdapter(adapterId)) { var descr = adapter.Description; int adapterVenId = descr.VendorId; long adapterLuid = descr.Luid; logger.Info("Adapter: " + descr.Description + " " + adapterVenId); if (device == null) { var flags = DeviceCreationFlags.VideoSupport | DeviceCreationFlags.BgraSupport; //DeviceCreationFlags.Debug; device = new SharpDX.Direct3D11.Device(adapter, flags); using (var multiThread = device.QueryInterface <SharpDX.Direct3D11.Multithread>()) { multiThread.SetMultithreadProtected(true); } } SetupSampleBuffer(args); encoder = FindEncoder(adapterVenId); syncMode = false; //encoder = new Transform(ClsId.MSH264EncoderMFT); //syncMode = true; } if (encoder == null) { throw new NotSupportedException("Hardware encode acceleration is not available on this platform."); } SetupEncoder(args); } catch (Exception ex) { logger.Error(ex); Close(); throw; } }
public void Setup(VideoEncoderSettings settings, IntPtr hwnd) { logger.Debug("D3D9RendererSink::Setup()"); this.hWnd = hwnd; this.EncoderSettings = settings; var avgTimePerFrame = MfTool.FrameRateToAverageTimePerFrame(EncoderSettings.FrameRate); this.EncoderSettings.AverageTimePerFrame = avgTimePerFrame; MediaFactory.CreatePresentationClock(out presentationClock); PresentationTimeSource timeSource = null; try { MediaFactory.CreateSystemTimeSource(out timeSource); presentationClock.TimeSource = timeSource; } finally { timeSource?.Dispose(); } videoRenderer = new MfVideoRenderer(); //TODO: нужно настраивать когда декодер пришлет свой формат videoRenderer.Setup(new VideoRendererArgs { hWnd = hWnd, FourCC = new SharpDX.Multimedia.FourCC("NV12"), //FourCC = 0x59565955, //"UYVY", Resolution = settings.Resolution, // //Resolution = new System.Drawing.Size(1920, 1088), FrameRate = settings.FrameRate, //new Tuple<int, int>(settings.FrameRate, 1), }); videoRenderer.RendererStarted += VideoRenderer_RendererStarted; videoRenderer.RendererStopped += VideoRenderer_RendererStopped; videoRenderer.SetPresentationClock(presentationClock); videoRenderer.Resize(new System.Drawing.Rectangle(0, 0, 100, 100)); SharpDX.MediaFoundation.DirectX.Direct3DDeviceManager d3dManager = null; if (EncoderSettings.UseHardware) { d3dManager = videoRenderer.D3DDeviceManager; } decoder = new MfH264Dxva2Decoder(d3dManager); var inputArgs = new MfVideoArgs { Width = EncoderSettings.Resolution.Width, Height = EncoderSettings.Resolution.Height, FrameRate = MfTool.PackToLong(EncoderSettings.FrameRate), LowLatency = EncoderSettings.LowLatency, }; decoder.Setup(inputArgs); }
private void SetupEncoder(MfVideoArgs args) { logger.Debug("SetupEncoder(...)"); var frameRate = args.FrameRate; var width = args.Width; var height = args.Height; int avgBitrate = args.AvgBitrate; int maxBitrate = args.MaxBitrate; int mpegProfile = (int)args.Profile; //if (width % 2 != 0) //{// должно быть четным... // width++; //} //if (height % 2 != 0) //{ // height++; //} //var inputFormat = VideoFormatGuids.Argb32; var inputFormat = args.Format; //VideoFormatGuids.NV12; logger.Info("Encoder input params: " + width + "x" + height + " fps=" + frameRate + " {" + inputFormat + "}"); using (var attr = encoder.Attributes) { // TODO: // log pref 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.AVEncMPVDefaultBPictureCount, 0); 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(CodecApiPropertyKeys.AVEncMPVDefaultBPictureCount, 0); 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); }
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; } }
public void Start1() { var flags = DeviceCreationFlags.VideoSupport | DeviceCreationFlags.BgraSupport | DeviceCreationFlags.Debug; var device = new SharpDX.Direct3D11.Device(SharpDX.Direct3D.DriverType.Hardware, flags); using (var multiThread = device.QueryInterface <SharpDX.Direct3D11.Multithread>()) { multiThread.SetMultithreadProtected(true); } System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(@"D:\Temp\4.bmp"); Texture2D rgbTexture = DxTool.GetTexture(bmp, device); var bufTexture = new Texture2D(device, new Texture2DDescription { // Format = Format.NV12, Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm, Width = 1920, Height = 1080, MipLevels = 1, ArraySize = 1, SampleDescription = { Count = 1 }, }); device.ImmediateContext.CopyResource(rgbTexture, bufTexture); var processor = new MfVideoProcessor(device); var inProcArgs = new MfVideoArgs { Width = 1920, Height = 1080, Format = SharpDX.MediaFoundation.VideoFormatGuids.Argb32, }; var outProcArgs = new MfVideoArgs { Width = 1920, Height = 1080, Format = SharpDX.MediaFoundation.VideoFormatGuids.NV12, //.Argb32, }; processor.Setup(inProcArgs, outProcArgs); processor.Start(); var rgbSample = MediaFactory.CreateVideoSampleFromSurface(null); // Create the media buffer from the texture MediaFactory.CreateDXGISurfaceBuffer(typeof(Texture2D).GUID, bufTexture, 0, false, out var mediaBuffer); using (var buffer2D = mediaBuffer.QueryInterface <Buffer2D>()) { mediaBuffer.CurrentLength = buffer2D.ContiguousLength; } rgbSample.AddBuffer(mediaBuffer); rgbSample.SampleTime = 0; rgbSample.SampleDuration = 0; var result = processor.ProcessSample(rgbSample, out var nv12Sample); Task.Run(() => { Stopwatch sw = new Stopwatch(); int fps = 60; int interval = (int)(1000.0 / fps); int _count = 1; long globalTime = 0; while (true) { if (result) { globalTime += sw.ElapsedMilliseconds; sw.Restart(); nv12Sample.SampleTime = MfTool.SecToMfTicks((globalTime / 1000.0)); nv12Sample.SampleDuration = MfTool.SecToMfTicks(((int)interval / 1000.0)); //sample.SampleTime = MfTool.SecToMfTicks((globalTime / 1000.0)); //sample.SampleDuration = MfTool.SecToMfTicks(((int)interval / 1000.0)); SampleReady?.Invoke(nv12Sample); var msec = sw.ElapsedMilliseconds; var delay = interval - msec; if (delay < 0) { delay = 1; } // var delay = 1; Thread.Sleep((int)delay); var elapsedMilliseconds = sw.ElapsedMilliseconds; globalTime += elapsedMilliseconds; _count++; } //nv12Sample?.Dispose(); //Thread.Sleep(30); } }); }
public void Start() { if (running) { return; } //var testSeqDir = @"D:\testBMP\"; //var di = new DirectoryInfo(testSeqDir); //var files = di.GetFiles().Take(60); //foreach (var f in files) //{ // var bytes = File.ReadAllBytes(f.FullName); // testBitmapSequence.Add(bytes); //} var testFile5 = @".\TestBmp\1920x1080_bmdFormat10BitYUV.raw"; var testFile2 = @".\TestBmp\1920x1080_bmdFormat8BitYUV.raw"; var testFile3 = @".\TestBmp\1920x1080_Argb32.raw"; var testArgb = File.ReadAllBytes(testFile3); //var canvaspng = @".\TestBmp\canvas.png"; var testBytes = File.ReadAllBytes(testFile2); var testBytes5 = File.ReadAllBytes(testFile5); //var fourCC = new FourCC("V210"); var V210FourCC = new FourCC(0x30313256); var UYVYFourCC = new FourCC(0x59565955); var NV12FourCC = new FourCC("NV12"); // var format = VideoFormatGuids.FromFourCC(v210FourCC); // var format = VideoFormatGuids.FromFourCC(UYVYFourCC); //var format = VideoFormatGuids.FromFourCC(NV12FourCC); //VideoFormatGuids.NV12; var format = VideoFormatGuids.Argb32; var sampleArgs = new MfVideoArgs { Width = 1920, Height = 1080, Format = format, //VideoFormatGuids.Uyvy, //VideoFormatGuids.NV12,//MFVideoFormat_v210, }; var producerTask = Task.Run(() => { running = true; Stopwatch sw = new Stopwatch(); int fps = 30; int interval = (int)(1000.0 / fps); int _count = 1; long globalTime = 0; Bitmap bmp = new Bitmap(1920, 1080, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var g = Graphics.FromImage(bmp); g.DrawString(DateTime.Now.ToString("HH:mm:ss.fff"), new System.Drawing.Font(FontFamily.GenericMonospace, 120), Brushes.Yellow, 0f, 0f); var data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat); var size = data.Stride * data.Height; var sample = MediaFactory.CreateSample(); var mb = MediaFactory.CreateMemoryBuffer(size); var pBuffer = mb.Lock(out int cbMaxLen, out int cbCurLen); Kernel32.CopyMemory(pBuffer, data.Scan0, (uint)size); //Marshal.Copy(testArgb, 0, pBuffer, testArgb.Length); mb.CurrentLength = size; mb.Unlock(); sample.AddBuffer(mb); bmp.UnlockBits(data); g.Dispose(); Random rnd = new Random(); Stopwatch timer = Stopwatch.StartNew(); while (running) { if (paused) { Thread.Sleep(100); continue; } UpdateSample(bmp, mb); globalTime += sw.ElapsedMilliseconds; sw.Restart(); var _rndOffset = 0; //rnd.Next(-16, 16); //if (_count%2 == 0) //{ // _rndOffset = 66; //} //globalTime += _rndOffset; var time = timer.ElapsedMilliseconds + _rndOffset; sample.SampleTime = MfTool.SecToMfTicks((time / 1000.0)); //sample.SampleTime = MfTool.SecToMfTicks((globalTime / 1000.0) ); sample.SampleDuration = MfTool.SecToMfTicks((interval / 1000.0)); //sample.SampleTime = MfTool.SecToMfTicks((globalTime / 1000.0)); //sample.SampleDuration = MfTool.SecToMfTicks(((int)interval / 1000.0)); SampleReady?.Invoke(sample); var msec = sw.ElapsedMilliseconds; var delay = interval - msec; if (delay < 0) { delay = 1; } //Console.WriteLine(delay); // var delay = 1; Thread.Sleep((int)delay); //var elapsedMilliseconds = sw.ElapsedMilliseconds; //sw.Restart(); //globalTime += elapsedMilliseconds; _count++; //Console.WriteLine(globalTime/1000.0 + " " + _count + " " + delay); //Console.SetCursorPosition(0, Console.CursorTop - 1); } sample?.Dispose(); mb.Dispose(); bmp.Dispose(); }); }
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); }