private void FinalizeSample(Sample encodedSample) { using (var buffer = encodedSample.ConvertToContiguousBuffer()) { var ptr = buffer.Lock(out int cbMaxLength, out int cbCurrentLength); try { if (cbCurrentLength > 0) { var sampleTime = encodedSample.SampleTime; var timeSec = MfTool.MfTicksToSec(sampleTime); DataEncoded?.Invoke(ptr, cbCurrentLength, timeSec); //byte[] buf = new byte[cbCurrentLength]; //Marshal.Copy(ptr, buf, 0, buf.Length); //OnDataReady(buf); } } finally { buffer.Unlock(); } } }
private static void ProcessSample(Sample sample) { var sampleTime = sample.SampleTime; var sampltDuration = sample.SampleDuration; //Console.WriteLine("SampleTime " + sampleTime + " SampleDuration " + sample.SampleDuration + " SampleFlags " + sample.SampleFlags); using (var mb = sample.ConvertToContiguousBuffer()) { try { using (var attrs = sample.QueryInterface <MediaAttributes>()) { var log = MfTool.LogMediaAttributes(attrs); Console.WriteLine(">>>>>>>>>>>>>>>>>>>>>>>>>>>>> " + log); } var pData = mb.Lock(out var maxLen, out var currLen); //var fileName = "Nv12_1280x720_" + MfTool.MfTicksToSec(sampleTime).ToString("0.00") + ".raw"; //var path = @"d:\TEMP\Test\"; //var fileFullName = Path.Combine(path, fileName); //TestTools.WriteFile(pData, currLen, fileFullName); } finally { mb.Unlock(); } } }
//private static void NewMethod1() //{ // 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(null); // 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 msEncoder = new MfH264EncoderMS(); // var encArgs = new MfVideoArgs // { // Width = 1920, // Height = 1080, // FrameRate = 30, // Format = SharpDX.MediaFoundation.VideoFormatGuids.NV12, // }; // msEncoder.Setup(encArgs); // msEncoder.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); // var ffEncoder = new H264Encoder(); // ffEncoder.Setup(new VideoEncoderSettings // { // Width = encArgs.Width, // Height = encArgs.Height, // FrameRate = 30, // }); // while (true) // { // rgbSample.SampleTime = 0; // rgbSample.SampleDuration = 0; // var result = processor.ProcessSample(rgbSample, out var nv12Sampel); // if (result) // { // using (var buffer = nv12Sampel.ConvertToContiguousBuffer()) // { // var ptr = buffer.Lock(out var maxLen, out var curLen); // ffEncoder.Encode(ptr, curLen, 0); // buffer.Unlock(); // } // //result = msEncoder.ProcessSample(nv12Sampel, out var outputSample); // //if (result) // //{ // //} // } // nv12Sampel?.Dispose(); // Thread.Sleep(300); // } // //Console.ReadKey(); // //Console.WriteLine("-------------------------------"); // //return; //} private static void NewMethod() { Guid CColorConvertDMO = new Guid("98230571-0087-4204-b020-3282538e57d3"); Guid VideoProcessorMFT = new Guid("88753B26-5B24-49BD-B2E7-0C445C78C982"); Guid NVidiaH264EncoderMFT = new Guid("60F44560-5A20-4857-BFEF-D29773CB8040"); Guid IntelQSVH264EncoderMFT = new Guid("4BE8D3C0-0515-4A37-AD55-E4BAE19AF471"); //ArrayList inputTypes = new ArrayList(); //ArrayList outputTypes = new ArrayList(); //MFInt inputTypesNum = new MFInt(); //MFInt outputTypesNum = new MFInt(); //IntPtr ip = IntPtr.Zero; var result = MfApi.MFTGetInfo(CColorConvertDMO, out string pszName, out IntPtr ppInputTypes, out uint inputTypesNum, out IntPtr ppOutputTypes, out uint outputTypesNum, out IntPtr ppAttributes); if (result == MediaToolkit.NativeAPIs.HResult.S_OK) { MediaAttributes mediaAttributes = new MediaAttributes(ppAttributes); Console.WriteLine(MfTool.LogMediaAttributes(mediaAttributes)); Console.WriteLine("InputTypes-------------------------------------"); MarshalHelper.PtrToArray(ppInputTypes, (int)inputTypesNum, out MFTRegisterTypeInfo[] inputTypes); foreach (var type in inputTypes) { var majorType = type.guidMajorType; var subType = type.guidSubtype; //Console.WriteLine(MfTool.GetMediaTypeName(majorType)); Console.WriteLine(MfTool.GetMediaTypeName(subType)); } Console.WriteLine(""); Console.WriteLine("OutputTypes-------------------------------------"); MarshalHelper.PtrToArray(ppOutputTypes, (int)outputTypesNum, out MFTRegisterTypeInfo[] outputTypes); foreach (var type in outputTypes) { var majorType = type.guidMajorType; var subType = type.guidSubtype; //Console.WriteLine(MfTool.GetMediaTypeName(majorType)); Console.WriteLine(MfTool.GetMediaTypeName(subType)); } } Console.WriteLine("Press any key to exit..."); Console.ReadKey(); return; }
private static void LogSourceTypes(SourceReader sourceReader) { int streamIndex = 0; while (true) { bool invalidStreamNumber = false; int _streamIndex = -1; for (int mediaIndex = 0; ; mediaIndex++) { try { var nativeMediaType = sourceReader.GetNativeMediaType(streamIndex, mediaIndex); if (_streamIndex != streamIndex) { _streamIndex = streamIndex; Console.WriteLine("====================== StreamIndex#" + streamIndex + "====================="); } Console.WriteLine(MfTool.LogMediaType(nativeMediaType)); nativeMediaType?.Dispose(); } catch (SharpDX.SharpDXException ex) { if (ex.ResultCode == SharpDX.MediaFoundation.ResultCode.NoMoreTypes) { Console.WriteLine(""); break; } else if (ex.ResultCode == SharpDX.MediaFoundation.ResultCode.InvalidStreamNumber) { invalidStreamNumber = true; break; } else { throw; } } } if (invalidStreamNumber) { break; } streamIndex++; } }
public void Setup(MfVideoArgs args) { encoder = new FFmpegLib.H264Encoder(); VideoEncoderSettings settings = new VideoEncoderSettings { EncoderId = "libx264", FrameRate = MfTool.LongToInts(args.FrameRate), Width = args.Width, Height = args.Height, }; encoder.Setup(settings); encoder.DataEncoded += Encoder_DataEncoded; }
private void SetupSampleBuffer(MfVideoArgs args) { logger.Debug("SetupSampleBuffer(...)"); int width = args.Width; int height = args.Height; //if (width % 2 != 0) //{// должно быть четным... // width++; //} //if (height % 2 != 0) //{ // height++; //} Format format = MfTool.GetDXGIFormatFromVideoFormatGuid(args.Format); if (format == Format.Unknown) { throw new NotSupportedException("Format not suppored " + args.Format); } var _descr = new Texture2DDescription { Format = format, Width = width, Height = height, MipLevels = 1, ArraySize = 1, SampleDescription = { Count = 1 }, }; bufTexture = new Texture2D(device, _descr); MediaBuffer mediaBuffer = null; try { MediaFactory.CreateDXGISurfaceBuffer(typeof(Texture2D).GUID, bufTexture, 0, false, out mediaBuffer); bufSample = MediaFactory.CreateSample(); bufSample.AddBuffer(mediaBuffer); } finally { mediaBuffer?.Dispose(); } }
public Sample GetSample() { var g = Graphics.FromImage(bmp); g.DrawImage(_bmp, 0, 0); var currentTime = sampleCount * sampleDuration; var text = DateTime.Now.ToString("HH:mm:ss.fff") + " " + currentTime; var font = new System.Drawing.Font(FontFamily.GenericMonospace, 120); var textSize = g.MeasureString(text, font); g.FillRectangle(Brushes.Black, 0f, 0f, textSize.Width, textSize.Height); g.DrawString(text, font, 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); mb.Dispose(); sample.SampleDuration = 0; //MfTool.SecToMfTicks( sampleDuration); sample.SampleTime = MfTool.SecToMfTicks(currentTime); bmp.UnlockBits(data); g.Dispose(); sampleCount++; return(sample); }
private void buttonStart_Click(object sender, EventArgs e) { logger.Debug("buttonStart_Click(...)"); if (videoRenderer != null) { var time = MfTool.SecToMfTicks((globalTime / 1000.0)); logger.Debug("renderer.Start(...) " + time); stopwatch.Start(); presentationClock.Start(0); //videoRenderer.Start(time); sampleSource.Start(); // sampleSource.Start1(); } }
public static void EnumerateCaptureSources() { 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) { Console.WriteLine("SourceTypeVideoCapture not found"); return; } 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); Console.WriteLine("FriendlyName " + friendlyName + "\r\n" + "isHwSource " + isHwSource + "\r\n" + //"maxBuffers " + maxBuffers + "symbolicLink " + symbolicLink); var mediaSource = _activate.ActivateObject <MediaSource>(); var log = MfTool.LogMediaSource(mediaSource); Console.WriteLine(log); mediaSource?.Dispose(); _activate?.Dispose(); } }
private void Decode(byte[] nal, double time) { try { var encodedSample = MediaFactory.CreateSample(); try { using (MediaBuffer mb = MediaFactory.CreateMemoryBuffer(nal.Length)) { var dest = mb.Lock(out int cbMaxLength, out int cbCurrentLength); //logger.Debug(sampleCount + " Marshal.Copy(...) " + nal.Length); Marshal.Copy(nal, 0, dest, nal.Length); mb.CurrentLength = nal.Length; mb.Unlock(); encodedSample.AddBuffer(mb); if (!double.IsNaN(time)) { var sampleTime = MfTool.SecToMfTicks(time); //(long)(time * 10_000_000); encodedSample.SampleTime = sampleTime; } } var res = decoder.ProcessSample(encodedSample, OnSampleDecoded); if (!res) { //... } } finally { encodedSample?.Dispose(); } } catch (Exception ex) { logger.Error(ex); } }
public bool EncodeSample(Sample inputSample, out Sample outputSample) { bool Result = false; outputSample = null; if (inputSample == null) { return(false); } encoder.ProcessInput(0, inputSample, 0); //if (processor.OutputStatus == (int)MftOutputStatusFlags.MftOutputStatusSampleReady) { encoder.GetOutputStreamInfo(0, out TOutputStreamInformation streamInfo); MftOutputStreamInformationFlags flags = (MftOutputStreamInformationFlags)streamInfo.DwFlags; bool createSample = !flags.HasFlag(MftOutputStreamInformationFlags.MftOutputStreamProvidesSamples); if (createSample) { outputSample = MediaFactory.CreateSample(); outputSample.SampleTime = inputSample.SampleTime; outputSample.SampleDuration = inputSample.SampleDuration; outputSample.SampleFlags = inputSample.SampleFlags; using (var mediaBuffer = MediaFactory.CreateMemoryBuffer(streamInfo.CbSize)) { outputSample.AddBuffer(mediaBuffer); } } TOutputDataBuffer[] outputDataBuffer = new TOutputDataBuffer[1]; var data = new TOutputDataBuffer { DwStatus = 0, DwStreamID = 0, PSample = outputSample, PEvents = null, }; outputDataBuffer[0] = data; var res = encoder.TryProcessOutput(TransformProcessOutputFlags.None, outputDataBuffer, out TransformProcessOutputStatus status); if (res == SharpDX.Result.Ok) { if (outputSample == null) { outputSample = outputDataBuffer[0].PSample; } Debug.Assert(outputSample != null, "res.Success && outputSample != null"); Result = true; } else if (res == SharpDX.MediaFoundation.ResultCode.TransformNeedMoreInput) { logger.Warn(res.ToString() + " TransformNeedMoreInput"); Result = true; } else if (res == SharpDX.MediaFoundation.ResultCode.TransformStreamChange) { logger.Warn(res.ToString() + " TransformStreamChange"); MediaType newOutputType = null; try { encoder.TryGetOutputAvailableType(outputStreamId, 0, out newOutputType); encoder.SetOutputType(outputStreamId, newOutputType, 0); if (OutputMediaType != null) { OutputMediaType.Dispose(); OutputMediaType = null; } OutputMediaType = newOutputType; logger.Info("============== NEW OUTPUT TYPE=================="); logger.Info(MfTool.LogMediaType(OutputMediaType)); } finally { newOutputType?.Dispose(); newOutputType = null; } } else { res.CheckError(); } } return(Result); }
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); }
private void ProcessOutput() { if (stopping) { logger.Warn("ProcessOutput() stopping..."); } if (closing) { logger.Warn("ProcessOutput() closing..."); return; } encoder.GetOutputStreamInfo(0, out TOutputStreamInformation streamInfo); MftOutputStreamInformationFlags flags = (MftOutputStreamInformationFlags)streamInfo.DwFlags; bool createSample = !flags.HasFlag(MftOutputStreamInformationFlags.MftOutputStreamProvidesSamples); // Create output sample Sample outputSample = null; try { if (createSample) { Debug.Assert(streamInfo.CbSize > 0, "streamInfo.CbSize > 0"); outputSample = MediaFactory.CreateSample(); using (var mediaBuffer = MediaFactory.CreateMemoryBuffer(streamInfo.CbSize)) { outputSample.AddBuffer(mediaBuffer); } } TOutputDataBuffer[] outputDataBuffer = new TOutputDataBuffer[1]; var data = new TOutputDataBuffer { DwStatus = 0, DwStreamID = 0, PSample = outputSample, PEvents = null, }; outputDataBuffer[0] = data; var res = encoder.TryProcessOutput(TransformProcessOutputFlags.None, outputDataBuffer, out TransformProcessOutputStatus status); if (res == SharpDX.Result.Ok) { if (outputSample == null) { outputSample = outputDataBuffer[0].PSample; } Debug.Assert(outputSample != null, "res.Success && outputSample != null"); FinalizeSample(outputSample); // SampleReady?.Invoke(outputSample); } else if (res == SharpDX.MediaFoundation.ResultCode.TransformNeedMoreInput) { //logger.Debug(res.ToString() + " TransformNeedMoreInput"); //Result = true; } else if (res == SharpDX.MediaFoundation.ResultCode.TransformStreamChange) {// не должны приходить для энкодера... // но приходят для Intel MFT !!! logger.Warn(res.ToString() + " TransformStreamChange"); MediaType newOutputType = null; try { encoder.TryGetOutputAvailableType(outputStreamId, 0, out newOutputType); encoder.SetOutputType(outputStreamId, newOutputType, 0); if (OutputMediaType != null) { OutputMediaType.Dispose(); OutputMediaType = null; } OutputMediaType = newOutputType; logger.Info("============== NEW OUTPUT TYPE=================="); logger.Info(MfTool.LogMediaType(OutputMediaType)); } finally { newOutputType?.Dispose(); newOutputType = null; } } else { res.CheckError(); } } finally { if (outputSample != null) { outputSample.Dispose(); outputSample = null; } } }
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(); }
private Transform FindEncoder(int adapterVenId) { logger.Debug("FindEncoder(...) " + adapterVenId); Transform preferTransform = null; var transformFlags = TransformEnumFlag.All | // TransformEnumFlag.All | TransformEnumFlag.SortAndFilter; var outputType = new TRegisterTypeInformation { GuidMajorType = MediaTypeGuids.Video, GuidSubtype = VideoFormatGuids.H264 // GuidSubtype = VideoFormatGuids.Hevc }; //int vendorId = 0; //using (var dxgiDevice = device.QueryInterface<SharpDX.DXGI.Device>()) //{ // var adapter = dxgiDevice.Adapter; // vendorId = adapter.Description.VendorId; //} var activates = MediaFactory.FindTransform(TransformCategoryGuids.VideoEncoder, transformFlags, null, outputType); try { Activate preferActivate = null; foreach (var activate in activates) { var actLog = MfTool.LogMediaAttributes(activate); logger.Debug("\r\nActivator:\r\n-----------------\r\n" + actLog); string name = activate.Get(TransformAttributeKeys.MftFriendlyNameAttribute); Guid clsid = activate.Get(TransformAttributeKeys.MftTransformClsidAttribute); TransformEnumFlag flags = (TransformEnumFlag)activate.Get(TransformAttributeKeys.TransformFlagsAttribute); bool isAsync = !(flags.HasFlag(TransformEnumFlag.Syncmft)); isAsync |= (flags.HasFlag(TransformEnumFlag.Asyncmft)); bool isHardware = flags.HasFlag(TransformEnumFlag.Hardware); if (isHardware) { string venIdStr = activate.Get(TransformAttributeKeys.MftEnumHardwareVendorIdAttribute); if (MfTool.TryGetVendorId(venIdStr, out int activatorVendId)) { if (activatorVendId == adapterVenId) { preferActivate = activate; syncMode = false; } } } else { //TODO:... } //var _flags = Enum.GetValues(typeof(TransformEnumFlag)) // .Cast<TransformEnumFlag>() // .Where(m => (m != TransformEnumFlag.None && flags.HasFlag(m))); //var transformInfo = name + " " + clsid.ToString() + " " + string.Join("|", _flags); //logger.Info(transformInfo); //logger.Debug(MfTool.LogMediaAttributes(activator)); //var HardwareUrl = activator.Get(TransformAttributeKeys.MftEnumHardwareUrlAttribute); //logger.Info(HardwareUrl); //var TransformAsync = activator.Get(TransformAttributeKeys.TransformAsync); //logger.Info(TransformAsync); //logger.Info("-------------------------------------"); } // preferEncoder = transformActivators[0].ActivateObject<Transform>(); if (preferActivate != null) { preferTransform = preferActivate.ActivateObject <Transform>(); } } finally { foreach (var activator in activates) { activator.Dispose(); } } return(preferTransform); }
private void OnSampleDecoded(Sample sample) { if (sample == null) { return; } try { //using (var buffer = sample.ConvertToContiguousBuffer()) //{ // MediaFactory.GetService(buffer, MediaServiceKeys.Buffer, IID.D3D9Surface, out var pSurf); // var surf = new SharpDX.Direct3D9.Surface(pSurf); // var descr = surf.Description; // logger.Debug(descr.Format); //} var sampleTime = sample.SampleTime; //sampleTime += presentationAdjust; if (prevSampleTime == 0) { prevSampleTime = sampleTime; } //_sampleTime += 33333; var timeDiff = (sampleTime - prevSampleTime); //if (timeDiff < 0) //{ // logger.Warn("Not monotonic time: " + string.Join(" ", sampleTime, prevSampleTime, timeDiff)); //} //else if (timeDiff > MfTool.SecToMfTicks(0.033)) //{ // //logger.Warn("Large time gap: " + string.Join(" ", sampleTime, prevSampleTime, timeDiff)); // var _delay = MfTool.MfTicksToSec(timeDiff - MfTool.SecToMfTicks(0.033)) * 1000; // //logger.Warn("Large time gap: " + string.Join(" ", sampleTime, prevSampleTime, timeDiff, _delay)); // Thread.Sleep((int)_delay); //} unwrappedSampleTime += timeDiff; sample.SampleTime = unwrappedSampleTime; var avgTimePerFrame = EncoderSettings.AverageTimePerFrame; sample.SampleDuration = avgTimePerFrame; // MfTool.SecToMfTicks(0.033); var presentationTime = presentationClock.Time; if (!EncoderSettings.LowLatency) { var delta = unwrappedSampleTime - presentationTime; //var avgDuration = MfTool.SecToMfTicks(0.033); if (delta < 0) { //logger.Warn("delta: " + string.Join(" ", delta)); } else if (delta > avgTimePerFrame) { //logger.Warn("Large time gap: " + string.Join(" ", sampleTime, prevSampleTime, timeDiff)); var _delay = MfTool.MfTicksToSec(delta - avgTimePerFrame) * 1000; logger.Warn("Large time gap: " + string.Join(" ", sampleTime, prevSampleTime, timeDiff, _delay)); Thread.Sleep((int)_delay); } } sample.SampleTime = 0; sample.SampleDuration = 0; if (EncoderSettings.UseHardware) { videoRenderer.ProcessDxva2Sample(sample); } else { videoRenderer.ProcessSample(sample); } prevSampleTime = sampleTime; //logger.Debug(sampleTime + " " + prevSampleTime + " " + (sampleTime - prevSampleTime)); } finally { sample.Dispose(); sample = null; } }
private void buttonSetup_Click(object sender, EventArgs e) { logger.Debug("buttonSetup_Click(...)"); if (presentationClock != null) { presentationClock.Dispose(); presentationClock = null; } MediaFactory.CreatePresentationClock(out presentationClock); PresentationTimeSource timeSource = null; try { MediaFactory.CreateSystemTimeSource(out timeSource); presentationClock.TimeSource = timeSource; } finally { timeSource?.Dispose(); } videoForm = new VideoForm { BackColor = Color.Black, //ClientSize = new Size(sampleArgs.Width, sampleArgs.Height), StartPosition = FormStartPosition.CenterScreen, }; videoRenderer = new MfVideoRenderer(); videoRenderer.RendererStarted += Renderer_RendererStarted; videoRenderer.RendererStopped += Renderer_RendererStopped; videoForm.Paint += (o, a) => { videoRenderer.Repaint(); }; videoForm.SizeChanged += (o, a) => { var rect = videoForm.ClientRectangle; //Console.WriteLine(rect); videoRenderer.Resize(rect); }; videoForm.Visible = true; videoRenderer.Setup(new VideoRendererArgs { hWnd = videoForm.Handle, // FourCC = new FourCC("NV12"), //FourCC = 0x59565955, //"UYVY", FourCC = new FourCC((int)Format.A8R8G8B8), Resolution = new Size(1920, 1080), FrameRate = new Tuple <int, int>(30, 1), }); videoRenderer.SetPresentationClock(presentationClock); videoRenderer.RendererStopped += () => { videoRenderer.Close(); GC.Collect(); }; videoRenderer.Resize(videoForm.ClientRectangle); sampleSource = new SampleSource(); bool isFirstTimestamp = true; long timeAdjust = 0; sampleSource.SampleReady += (sample) => { if (isFirstTimestamp) { var _sampleTime = sample.SampleTime; var presetnationTime = presentationClock.Time; var stopwatchTime = MfTool.SecToMfTicks(stopwatch.ElapsedMilliseconds / 1000.0); timeAdjust = presetnationTime - _sampleTime; //stopwatchTime; Console.WriteLine(presetnationTime + " - " + _sampleTime + " = " + timeAdjust); isFirstTimestamp = false; } //var sampleTime = sample.SampleTime; //var presetnationTime = presentationClock.Time; //var diff = sampleTime - presetnationTime; //Console.WriteLine(MfTool.MfTicksToSec(sampleTime) + " " + MfTool.MfTicksToSec(presetnationTime) + " " + MfTool.MfTicksToSec(diff)); //var stopwatchTime = MfTool.SecToMfTicks(stopwatch.ElapsedMilliseconds / 1000.0); //var diff2 = stopwatchTime - presetnationTime; //Console.WriteLine (MfTool.MfTicksToSec(stopwatchTime) + " " + MfTool.MfTicksToSec(presetnationTime) + " " + MfTool.MfTicksToSec(diff2)); var sampleTime = sample.SampleTime; sample.SampleTime = sampleTime + timeAdjust; //sample.SampleDuration = 0; videoRenderer?.ProcessSample(sample); //sample?.Dispose(); }; }
private void ProcessSample(Sample sample) { if (State != CaptureState.Capturing) { return; } Sample outputSample = null; try { var res = processor.ProcessSample(sample, out outputSample); if (res) { // Console.WriteLine("outputSample!=null" + (outputSample != null)); var mediaBuffer = outputSample.ConvertToContiguousBuffer(); try { var pBuffer = mediaBuffer.Lock(out int cbMaxLengthRef, out int cbCurrentLengthRef); var immediateContext = device.ImmediateContext; var dataBox = immediateContext.MapSubresource(stagingTexture, 0, MapMode.Read, MapFlags.None); Kernel32.CopyMemory(dataBox.DataPointer, pBuffer, (uint)cbCurrentLengthRef); immediateContext.UnmapSubresource(stagingTexture, 0); immediateContext.CopyResource(stagingTexture, SharedTexture); immediateContext.Flush(); OnBufferUpdated(); //var time = (double)(sample.SampleTime) / 10_000_000; var time = MfTool.MfTicksToSec(sample.SampleTime); captureStats.UpdateFrameStats(time, cbCurrentLengthRef); mediaBuffer.Unlock(); } finally { mediaBuffer?.Dispose(); } } } catch (Exception ex) { logger.Error(ex); } finally { if (outputSample != null) { outputSample.Dispose(); outputSample = null; } } }
public bool ProcessSample(Sample inputSample, Action <Sample> OnSampleDecoded, Action <MediaType> OnMediaTypeChanged = null) { bool Result = false; if (inputSample == null) { return(false); } decoder.ProcessInput(0, inputSample, 0); //if (decoder.OutputStatus == (int)MftOutputStatusFlags.MftOutputStatusSampleReady) { decoder.GetOutputStreamInfo(0, out TOutputStreamInformation streamInfo); MftOutputStreamInformationFlags flags = (MftOutputStreamInformationFlags)streamInfo.DwFlags; bool createSample = !flags.HasFlag(MftOutputStreamInformationFlags.MftOutputStreamProvidesSamples); do { Sample pSample = null; // Create output sample if (createSample) { pSample = MediaFactory.CreateSample(); pSample.SampleTime = inputSample.SampleTime; pSample.SampleDuration = inputSample.SampleDuration; pSample.SampleFlags = inputSample.SampleFlags; //logger.Debug("CreateSample: " + inputSample.SampleTime); using (var mediaBuffer = MediaFactory.CreateMemoryBuffer(streamInfo.CbSize)) { pSample.AddBuffer(mediaBuffer); } } TOutputDataBuffer[] outputBuffers = new TOutputDataBuffer[1]; var outputBuffer = new TOutputDataBuffer { DwStatus = 0, DwStreamID = 0, PSample = pSample, PEvents = null, }; outputBuffers[0] = outputBuffer; var res = decoder.TryProcessOutput(TransformProcessOutputFlags.None, outputBuffers, out TransformProcessOutputStatus status); //logger.Info("TryProcessOutput(...) " + res + " " + outputDataBuffer[0].DwStatus); if (res == SharpDX.Result.Ok) { var buf = outputBuffers[0]; var outputSample = buf.PSample; var pEvents = buf.PEvents; if (pEvents != null) { var eventsCount = pEvents.ElementCount; Debug.Assert(eventsCount == 0, "eventsCount == 0"); if (eventsCount > 0) { for (int i = 0; i < eventsCount; i++) { var e = pEvents.GetElement(i); if (e != null) { e.Dispose(); e = null; } } } } Debug.Assert(outputSample != null, "res.Success && outputSample != null"); OnSampleDecoded?.Invoke(outputSample); Result = true; //continue; } else if (res == SharpDX.MediaFoundation.ResultCode.TransformNeedMoreInput) { //logger.Info("-------------------------"); if (pSample != null) { pSample.Dispose(); pSample = null; } Result = true; break; } else if (res == SharpDX.MediaFoundation.ResultCode.TransformStreamChange) { logger.Warn(res.ToString() + " TransformStreamChange"); MediaType newOutputType = null; try { decoder.TryGetOutputAvailableType(outputStreamId, 0, out newOutputType); decoder.SetOutputType(outputStreamId, newOutputType, 0); if (OutputMediaType != null) { OutputMediaType.Dispose(); OutputMediaType = null; } OutputMediaType = newOutputType; logger.Info("============== NEW OUTPUT TYPE=================="); logger.Info(MfTool.LogMediaType(OutputMediaType)); OnMediaTypeChanged?.Invoke(OutputMediaType); } finally { //newOutputType?.Dispose(); //newOutputType = null; } } else { res.CheckError(); Result = false; break; } }while (true); } return(Result); }
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 = 10; int interval = (int)(1000.0 / fps); int _count = 1; long globalTime = 0; Bitmap _bmp = new Bitmap(@"D:\Temp\4.bmp"); Bitmap bmp = new Bitmap(1920, 1080, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var g = Graphics.FromImage(bmp); g.DrawImage(_bmp, 0, 0); var text = DateTime.Now.ToString("HH:mm:ss.fff"); var font = new System.Drawing.Font(FontFamily.GenericMonospace, 120); var textSize = g.MeasureString(text, font); g.FillRectangle(Brushes.Black, 0f, 0f, textSize.Width, textSize.Height); g.DrawString(text, font, 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(); }); }
private void buttonSetup_Click(object sender, EventArgs e) { logger.Debug("buttonSetup_Click(...)"); sourceVideoFile = textBox1.Text; videoForm = new VideoForm { BackColor = Color.Black, //ClientSize = new Size(sampleArgs.Width, sampleArgs.Height), StartPosition = FormStartPosition.CenterScreen, }; videoForm.Visible = true; if (presentationClock != null) { presentationClock.Dispose(); presentationClock = null; } MediaFactory.CreatePresentationClock(out presentationClock); PresentationTimeSource timeSource = null; try { MediaFactory.CreateSystemTimeSource(out timeSource); presentationClock.TimeSource = timeSource; } finally { timeSource?.Dispose(); } videoRenderer = new MfVideoRendererEx(); videoRenderer.Init(videoForm.Handle, presentationClock); int sinkRequestSample = 0; int count = 0; fileSource = new VideoFileSource(); fileSource.Setup(sourceVideoFile, videoRenderer.D3DDeviceManager); //videoRenderer.Prerolled += () => //{ // presentationClock.Start(MfTool.SecToMfTicks(1)); //}; fileSource.SampleReady += (flags, sample) => { var _flags = (SourceReaderFlags)flags; if (_flags == SourceReaderFlags.StreamTick) { } else if (_flags == SourceReaderFlags.Currentmediatypechanged) { var newMediaType = fileSource.GetCurrentMediaType(); //var log = MfTool.LogMediaType(newMediaType); //Console.WriteLine("================Currentmediatypechanged======================"); //Console.WriteLine(log); videoRenderer?.SetMediaType(newMediaType); newMediaType.Dispose(); } if (sample != null) { var presentationTime = presentationClock.Time; var sampleTime = sample.SampleTime; var diff = sampleTime - presentationTime; if (diff > 0) { var delay = (int)(MfTool.MfTicksToSec(diff) * 1000); Console.WriteLine("Delay " + delay); Thread.Sleep(delay); } sample.SampleTime = 0; sample.SampleDuration = 0; //videoRenderer.ProcessDxva2Sample(sample); videoRenderer._ProcessDxva2Sample(sample); //videoRenderer.ProcessSample(sample); sample.Dispose(); count++; } }; fileSource.SourceStopped += () => { Console.WriteLine("fileSource.SourceStopped()"); fileSource.Close(); }; var srcMediaType = fileSource.GetCurrentMediaType(); var subType = srcMediaType.Get(MediaTypeAttributeKeys.Subtype); var frameSize = srcMediaType.Get(MediaTypeAttributeKeys.FrameSize); var frameRate = srcMediaType.Get(MediaTypeAttributeKeys.FrameRate); using (var mediaType = new SharpDX.MediaFoundation.MediaType()) { mediaType.Set(MediaTypeAttributeKeys.MajorType, MediaTypeGuids.Video); mediaType.Set(MediaTypeAttributeKeys.Subtype, VideoFormatGuids.NV12); // mediaType.Set(MediaTypeAttributeKeys.FrameSize, frameSize); mediaType.Set(MediaTypeAttributeKeys.InterlaceMode, 2); mediaType.Set(MediaTypeAttributeKeys.AllSamplesIndependent, 1); mediaType.Set(MediaTypeAttributeKeys.FrameRate, frameRate); videoRenderer.SetMediaType(mediaType); } videoRenderer.RequestSample += () => { //if (presentationClock != null) //{ // presentationClock.GetState(0, out var clockState); // if(clockState == ClockState.Running) // { // //fileSource.NextSample(); // } //} fileSource.NextSample(); sinkRequestSample++; }; videoRenderer.RendererStopped += () => { videoRenderer.Close(); GC.Collect(); }; videoRenderer.Resize(videoForm.ClientRectangle); videoForm.Paint += (o, a) => { videoRenderer.Repaint(); }; videoForm.SizeChanged += (o, a) => { var rect = videoForm.ClientRectangle; //Console.WriteLine(rect); videoRenderer.Resize(rect); }; }
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 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); }
//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 Setup(string fileName, Direct3DDeviceManager devMan = null) { logger.Debug("VideoFileSource::Setup()"); // using (var sourceResolver = new SourceResolver()) { var unkObj = sourceResolver.CreateObjectFromURL(fileName, SourceResolverFlags.MediaSource); var guid = typeof(MediaSource).GUID; unkObj.QueryInterface(ref guid, out var pUnk); mediaSource = new MediaSource(pUnk); } using (var mediaAttributes = new MediaAttributes(IntPtr.Zero)) { MediaFactory.CreateAttributes(mediaAttributes, 5); //mediaAttributes.Set(SourceReaderAttributeKeys.EnableVideoProcessing, 1); if (devMan != null) { //mediaAttributes.Set(SourceReaderAttributeKeys.DisableDxva, 0); mediaAttributes.Set(SourceReaderAttributeKeys.D3DManager, devMan); } //mediaAttributes.Set(CodecApiPropertyKeys.AVLowLatencyMode, false); sourceReader = new SourceReader(mediaSource, mediaAttributes); } var charact = mediaSource.Characteristics; Console.WriteLine(MfTool.LogEnumFlags((MediaSourceCharacteristics)charact)); Console.WriteLine("------------------CurrentMediaType-------------------"); int videoStreamIndex = (int)SourceReaderIndex.FirstVideoStream; using (var currentMediaType = sourceReader.GetCurrentMediaType(videoStreamIndex)) { Console.WriteLine(MfTool.LogMediaType(currentMediaType)); var frameSize = currentMediaType.Get(MediaTypeAttributeKeys.FrameSize); var frameRate = currentMediaType.Get(MediaTypeAttributeKeys.FrameRate); OutputMediaType = new MediaType(); OutputMediaType.Set(MediaTypeAttributeKeys.MajorType, MediaTypeGuids.Video); OutputMediaType.Set(MediaTypeAttributeKeys.Subtype, VideoFormatGuids.NV12); // VideoFormatGuids.Yv12); OutputMediaType.Set(MediaTypeAttributeKeys.FrameSize, frameSize); OutputMediaType.Set(MediaTypeAttributeKeys.FrameRate, frameRate); OutputMediaType.Set(MediaTypeAttributeKeys.InterlaceMode, (int)VideoInterlaceMode.Progressive); OutputMediaType.Set(MediaTypeAttributeKeys.AllSamplesIndependent, 1); sourceReader.SetCurrentMediaType(videoStreamIndex, OutputMediaType); Console.WriteLine("------------------NEW MediaType-------------------"); Console.WriteLine(MfTool.LogMediaType(OutputMediaType)); } }
static void Main(string[] args) { MediaToolkitManager.Startup(); 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); } var featureLevel = _device.FeatureLevel; using (var dxgiDevice = _device.QueryInterface <SharpDX.DXGI.Device>()) { using (var adapter = dxgiDevice.Adapter) { var descr = adapter.Description; Console.WriteLine(string.Join(" ", descr.Description)); } } Console.WriteLine(DxTool.LogDxInfo()); Console.ReadKey(); return; // NewMethod1(); ////DxTool.FindAdapter1(4313); var videoEncoders = MfTool.FindVideoEncoders(); foreach (var enc in videoEncoders) { Console.WriteLine(enc.ToString()); } foreach (var enc in videoEncoders) { if (enc.Format == VideoCodingFormat.H264 && enc.Activatable) { Console.WriteLine(enc.Name + " " + enc.ClsId + " isHardware: " + enc.IsHardware); } } Console.ReadKey(); Console.WriteLine("-------------------------------"); return; //NewMethod(); //return; //MarshalHelper.ToArray(ppOutputTypes, (int)inputTypesNum, out MFTRegisterTypeInfo[] outputTypes); //MediaAttributes mediaAttributes = new MediaAttributes(ppAttributes); //Console.WriteLine(MfTool.LogMediaAttributes(mediaAttributes)); //Guid VideoProcessorMFT = new Guid("88753B26-5B24-49BD-B2E7-0C445C78C982"); //SharpDX.MediaFoundation.MediaFactory.TGetInfo(VideoProcessorMFT, IntPtr.Zero, // null, out int cInputTypesRef, // null, out int cOutputTypesRef, // out SharpDX.MediaFoundation.MediaAttributes attrs); //var transformFlags = TransformEnumFlag.All | // TransformEnumFlag.All | // TransformEnumFlag.SortAndFilter; //var outputType = new TRegisterTypeInformation //{ // GuidMajorType = MediaTypeGuids.Video, // GuidSubtype = VideoFormatGuids.H264 // // GuidSubtype = VideoFormatGuids.Hevc //}; //var category = SharpDX.MediaFoundation.TransformCategoryGuids.VideoDecoder; //MediaAttributes mediaAttributes = new MediaAttributes(); //Activate[] activates = new Activate[1024]; //SharpDX.MediaFoundation.MediaFactory.TEnum2(category, (int)transformFlags, null, outputType, mediaAttributes, activates, out int activatesNum); 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); } //var descr = new SharpDX.Direct3D11.Texture2DDescription //{ // Width = 1920, // Height = 1080, // MipLevels = 1, // ArraySize = 1, // SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), // Usage = SharpDX.Direct3D11.ResourceUsage.Default, // Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm, // BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource, // CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None, // OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None, //}; //var texture = new SharpDX.Direct3D11.Texture2D(device, descr); var bmp = new System.Drawing.Bitmap(@"D:\Temp\4.bmp"); var texture = DxTool.GetTexture(bmp, device); //Texture2D stagingTexture = null; //try //{ // // Create Staging texture CPU-accessible // stagingTexture = new Texture2D(device, // new Texture2DDescription // { // CpuAccessFlags = CpuAccessFlags.Read, // BindFlags = BindFlags.None, // Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm, // Width = 1920, // Height = 1080, // MipLevels = 1, // ArraySize = 1, // SampleDescription = { Count = 1, Quality = 0 }, // Usage = ResourceUsage.Staging, // OptionFlags = ResourceOptionFlags.None, // }); // device.ImmediateContext.CopyResource(texture, stagingTexture); // device.ImmediateContext.Flush(); // //var destBmp = new System.Drawing.Bitmap(1920, 1080, System.Drawing.Imaging.PixelFormat.Format32bppArgb); // System.Drawing.Bitmap destBmp = null; // int count = 10; // byte[] bytes = null; // while (count-- > 0) // { // DxTool.TextureToBitmap(stagingTexture, ref destBmp); // bytes = DxTool.GetTextureBytes(stagingTexture); // Thread.Sleep(10); // } // File.WriteAllBytes("d:\\test_argb32.raw", bytes); // destBmp.Save("d:\\test.bmp"); // destBmp.Dispose(); //} //finally //{ // stagingTexture?.Dispose(); //} //texture.Dispose(); //device.Dispose(); //bmp.Dispose(); //var report = SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects(); //Console.WriteLine(report); //Console.ReadKey(); //return; //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); //} do { // var videoSource = new ScreenSource(); // ScreenCaptureDeviceDescription captureParams = new ScreenCaptureDeviceDescription // { // CaptureRegion = new System.Drawing.Rectangle(0, 0, 1920, 1080), // Resolution = new System.Drawing.Size(1920, 1080), // }; // captureParams.CaptureType = VideoCaptureType.DXGIDeskDupl; // captureParams.Fps = 10; // captureParams.CaptureMouse = true; // videoSource.Setup(captureParams); // VideoEncoderSettings encodingParams = new VideoEncoderSettings // { // //Width = destSize.Width, // options.Width, // //Height = destSize.Height, // options.Height, // Resolution = new System.Drawing.Size(1920, 1080), // FrameRate = 10, // }; // //var videoEncoder = new VideoEncoder(videoSource); // //videoEncoder.Open(encodingParams); // var hwBuffer = videoSource.SharedTexture; // var hwDevice = hwBuffer.Device; // using (var dxgiDevice = hwDevice.QueryInterface<SharpDX.DXGI.Device>()) // { // using (var adapter = dxgiDevice.Adapter) // { // var adapterLuid = adapter.Description.Luid; // } // } //// hwDevice.Dispose(); // // Marshal.Release(hwDevice.NativePointer); // //ComObject comObject = new ComObject(); // //comObject. //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); //} var encoder = new MfH264Encoder(null); encoder.Setup(new MfVideoArgs { Width = 1920, Height = 1080, FrameRate = 30, Format = SharpDX.MediaFoundation.VideoFormatGuids.Argb32, }); var encDevice = encoder.device; var bufTexture = new Texture2D(encDevice, new Texture2DDescription { // Format = Format.NV12, Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm, Width = 1920, Height = 1080, MipLevels = 1, ArraySize = 1, SampleDescription = { Count = 1 }, }); //var processor = new MfVideoProcessor(encDevice); //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(); encoder.Start(); int count = 3; while (count-- > 0) { //encDevice.ImmediateContext.CopyResource(texture, bufTexture); //encoder.WriteTexture(texture); Thread.Sleep(100); Console.WriteLine("Try next " + count); } encoder.Stop(); //processor.Stop(); //processor.Close(); bufTexture.Dispose(); texture.Dispose(); // videoEncoder.Close(); //videoSource.Close(); //hwDevice.Dispose(); //Console.WriteLine(MfTool.GetActiveObjectsReport()); Thread.Sleep(300); //encoder.Close(); GC.Collect(); Console.WriteLine("----------------------------------------\r\n" + MfTool.GetActiveObjectsReport()); Console.WriteLine("Spacebar to next..."); var key = Console.ReadKey(); if (key.Key == ConsoleKey.Spacebar) { continue; } else { break; } } while (true); Console.WriteLine("Any key to exit..."); Console.ReadKey(); MediaToolkitManager.Shutdown(); }
public void Setup(object pars) { logger.Debug("VideoCaptureSource::Setup()"); if (State != CaptureState.Closed) { throw new InvalidOperationException("Invalid capture state " + State); } UvcDevice captureParams = pars as UvcDevice; var deviceId = captureParams.DeviceId; try { int adapterIndex = 0; using (var dxgiFactory = new SharpDX.DXGI.Factory1()) { using (var adapter = dxgiFactory.GetAdapter1(adapterIndex)) { var deviceCreationFlags = //DeviceCreationFlags.Debug | DeviceCreationFlags.VideoSupport | DeviceCreationFlags.BgraSupport; device = new Device(adapter, deviceCreationFlags); using (var multiThread = device.QueryInterface <SharpDX.Direct3D11.Multithread>()) { multiThread.SetMultithreadProtected(true); } } } sourceReader = CreateSourceReaderByDeviceId(deviceId); if (sourceReader == null) { throw new Exception("Unable to create media source reader " + deviceId); } var mediaType = sourceReader.GetCurrentMediaType(SourceReaderIndex.FirstVideoStream); logger.Debug("------------------CurrentMediaType-------------------"); logger.Debug(MfTool.LogMediaType(mediaType)); srcSize = MfTool.GetFrameSize(mediaType); var destSize = captureParams.Resolution; if (destSize.IsEmpty) { destSize = srcSize; } var subtype = mediaType.Get(MediaTypeAttributeKeys.Subtype); mediaType?.Dispose(); SharedTexture = new Texture2D(device, new Texture2DDescription { CpuAccessFlags = CpuAccessFlags.None, BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource, Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm, Width = destSize.Width, Height = destSize.Height, MipLevels = 1, ArraySize = 1, SampleDescription = { Count = 1, Quality = 0 }, Usage = ResourceUsage.Default, OptionFlags = ResourceOptionFlags.Shared, }); stagingTexture = new Texture2D(device, new Texture2DDescription { CpuAccessFlags = CpuAccessFlags.Read, //BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource, BindFlags = BindFlags.None, Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm, Width = destSize.Width, Height = destSize.Height, MipLevels = 1, ArraySize = 1, SampleDescription = { Count = 1, Quality = 0 }, Usage = ResourceUsage.Staging, OptionFlags = ResourceOptionFlags.None, }); processor = new MfVideoProcessor(null); var intupArgs = new MfVideoArgs { Width = srcSize.Width, Height = srcSize.Height, Format = subtype,//VideoFormatGuids.NV12, }; var outputArgs = new MfVideoArgs { Width = destSize.Width, Height = destSize.Height, Format = VideoFormatGuids.Argb32, }; processor.Setup(intupArgs, outputArgs); processor.SetMirror(VideoProcessorMirror.MirrorVertical); state = CaptureState.Initialized; } catch (Exception ex) { logger.Error(ex); LastError = ex; errorCode = (int)SharedTypes.ErrorCode.NotInitialized; CleanUp(); 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 Setup(MfVideoArgs inputArgs) { logger.Debug("MfH264Dxva2Decoder::Setup(...)"); var width = inputArgs.Width; var height = inputArgs.Height; var inputFormat = VideoFormatGuids.H264; var frameRate = inputArgs.FrameRate; LowLatency = inputArgs.LowLatency; try { var transformFlags = //TransformEnumFlag.Hardware | TransformEnumFlag.SortAndFilter; var inputType = new TRegisterTypeInformation { GuidMajorType = MediaTypeGuids.Video, GuidSubtype = VideoFormatGuids.H264 }; var transformActivators = MediaFactory.FindTransform(TransformCategoryGuids.VideoDecoder, transformFlags, inputType, null); try { foreach (var activator in transformActivators) { //bool isHardware = flags.HasFlag(TransformEnumFlag.Hardware); //bool isAsync = flags.HasFlag(TransformEnumFlag.Asyncmft); string name = activator.Get(TransformAttributeKeys.MftFriendlyNameAttribute); Guid clsid = activator.Get(TransformAttributeKeys.MftTransformClsidAttribute); TransformEnumFlag flags = (TransformEnumFlag)activator.Get(TransformAttributeKeys.TransformFlagsAttribute); bool isAsync = !(flags.HasFlag(TransformEnumFlag.Syncmft)); isAsync |= !!(flags.HasFlag(TransformEnumFlag.Asyncmft)); bool isHardware = !!(flags.HasFlag(TransformEnumFlag.Hardware)); var _flags = Enum.GetValues(typeof(TransformEnumFlag)) .Cast <TransformEnumFlag>() .Where(m => (m != TransformEnumFlag.None && flags.HasFlag(m))); var transformInfo = name + " " + clsid.ToString() + " " + string.Join("|", _flags); logger.Info(transformInfo); //encoder = activator.ActivateObject<Transform>(); //break; //var HardwareUrl = activator.Get(TransformAttributeKeys.MftEnumHardwareUrlAttribute); //logger.Info(HardwareUrl); //var TransformAsync = activator.Get(TransformAttributeKeys.TransformAsync); //logger.Info(TransformAsync); //logger.Info("-------------------------------------"); } } finally { decoder = transformActivators[0].ActivateObject <Transform>(); foreach (var activator in transformActivators) { activator.Dispose(); } } using (var attr = decoder.Attributes) { bool d3dAware = attr.Get(TransformAttributeKeys.D3DAware); if (d3dAware) { if (d3dDeviceManager != null) { decoder.ProcessMessage(TMessageType.SetD3DManager, d3dDeviceManager.NativePointer); } else { attr.Set(TransformAttributeKeys.D3DAware, false); } } attr.Set(SinkWriterAttributeKeys.LowLatency, LowLatency); //attr.Set(MFAttributeKeys.MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT, 1); } int inputStreamCount = -1; int outputStreamsCount = -1; decoder.GetStreamCount(out inputStreamCount, out outputStreamsCount); int[] inputStreamIDs = new int[inputStreamCount]; int[] outputStreamIDs = new int[outputStreamsCount]; bool res = decoder.TryGetStreamIDs(inputStreamIDs, outputStreamIDs); if (res) { inputStreamId = inputStreamIDs[0]; outputStreamId = outputStreamIDs[0]; } else { inputStreamId = 0; outputStreamId = 0; } for (int i = 0; ; i++) { try { decoder.GetInputAvailableType(0, i, out MediaType mediaType); if (mediaType == null) { logger.Warn("NoMoreType"); break; } var formatId = mediaType.Get(MediaTypeAttributeKeys.Subtype); if (formatId == inputFormat) { logger.Debug("inputFormat " + inputFormat); InputMediaType = mediaType; break; } mediaType.Dispose(); mediaType = null; } catch (SharpDX.SharpDXException ex) { if (ex.ResultCode != SharpDX.MediaFoundation.ResultCode.NoMoreTypes) { throw; } } } if (InputMediaType == null) { logger.Warn("Unsuported format: " + MfTool.GetMediaTypeName(inputFormat)); return; } InputMediaType.Set(MediaTypeAttributeKeys.MajorType, MediaTypeGuids.Video); InputMediaType.Set(MediaTypeAttributeKeys.Subtype, VideoFormatGuids.H264); InputMediaType.Set(MediaTypeAttributeKeys.FrameSize, MfTool.PackToLong(width, height)); InputMediaType.Set(MediaTypeAttributeKeys.FrameRate, frameRate); // InputMediaType.Set(MediaTypeAttributeKeys.PixelAspectRatio, MfTool.PackToLong(1, 1)); InputMediaType.Set(MediaTypeAttributeKeys.InterlaceMode, (int)VideoInterlaceMode.Progressive); InputMediaType.Set(MediaTypeAttributeKeys.AllSamplesIndependent, 1); decoder.SetInputType(inputStreamId, InputMediaType, 0); logger.Info("============== INPUT TYPE=================="); logger.Info(MfTool.LogMediaType(InputMediaType)); OutputMediaType = new MediaType(); OutputMediaType.Set(MediaTypeAttributeKeys.MajorType, MediaTypeGuids.Video); OutputMediaType.Set(MediaTypeAttributeKeys.Subtype, VideoFormatGuids.NV12); //OutputMediaType.Set(MediaTypeAttributeKeys.AvgBitrate, 30000000); OutputMediaType.Set(MediaTypeAttributeKeys.InterlaceMode, (int)VideoInterlaceMode.Progressive); OutputMediaType.Set(MediaTypeAttributeKeys.FrameSize, MfTool.PackToLong(width, height)); OutputMediaType.Set(MediaTypeAttributeKeys.FrameRate, frameRate); OutputMediaType.Set(MediaTypeAttributeKeys.AllSamplesIndependent, 1); decoder.SetOutputType(outputStreamId, OutputMediaType, 0); logger.Info("============== OUTPUT TYPE=================="); logger.Info(MfTool.LogMediaType(OutputMediaType)); } catch (Exception ex) { logger.Error(ex); Close(); throw; } }
public void ProcessData(byte[] data, double time) { try { var encodedSample = MediaFactory.CreateSample(); try { using (MediaBuffer mb = MediaFactory.CreateMemoryBuffer(data.Length)) { try { var dest = mb.Lock(out int cbMaxLength, out int cbCurrentLength); Marshal.Copy(data, 0, dest, data.Length); mb.CurrentLength = data.Length; } finally { mb.Unlock(); } encodedSample.AddBuffer(mb); } if (!double.IsNaN(time) && time > 0) { // может глючить рендерер если метки будут кривые!! // TODO: сделать валидацию вр.меток до декодера и после... var sampleTime = MfTool.SecToMfTicks(time); if (presentationAdjust == long.MaxValue) { var presentaionTime = presentationClock.Time; presentationAdjust = presentaionTime - sampleTime; } encodedSample.SampleTime = sampleTime; // + presentationAdjust; encodedSample.SampleDuration = 0; // MfTool.SecToMfTicks(0.033); //logger.Debug(">>>>>>>>>>> " + sampleTime); } else { encodedSample.SampleTime = 0; encodedSample.SampleDuration = 0; } //logger.Debug("ProcessData " + time); var res = decoder.ProcessSample(encodedSample, OnSampleDecoded, OnMediaTypeChanged); if (!res) { logger.Debug("decoder.ProcessSample() " + res); //... } } finally { encodedSample?.Dispose(); } } catch (Exception ex) { logger.Error(ex); } }