예제 #1
0
        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();
                }
            }
        }
예제 #2
0
        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();
                }
            }
        }
예제 #3
0
        //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;
        }
예제 #4
0
        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++;
            }
        }
예제 #5
0
        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;
        }
예제 #6
0
        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();
            }
        }
예제 #7
0
            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);
            }
예제 #8
0
        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();
            }
        }
예제 #9
0
        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();
            }
        }
예제 #10
0
        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);
            }
        }
예제 #11
0
        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);
        }
예제 #12
0
        private void SetupEncoder(MfVideoArgs args)
        {
            logger.Debug("SetupEncoder(...)");


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

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

            long pixelAspectRatio = args.AspectRatio;

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

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

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


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

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

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

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

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


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

                var attrLog = MfTool.LogMediaAttributes(attr);

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


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

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

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

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


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

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

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

                mediaType.Set(MediaTypeAttributeKeys.PixelAspectRatio, pixelAspectRatio);

                encoder.SetOutputType(outputStreamId, mediaType, 0);

                OutputMediaType = mediaType;

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

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

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

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

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

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

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

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

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

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

            var mediaLog = MfTool.LogMediaType(InputMediaType);

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


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



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

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


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

            //var codecApi = (NativeAPIs.DShow.ICodecAPI)Marshal.GetObjectForIUnknown(pUnk);
            ////var code = codecApi.GetParameterRange(CodecApiPropertyKeys.AVEncMPVDefaultBPictureCount.Guid, out var valMin, out var valMax, out var sDelta);
            //var code = codecApi.GetValue(CodecApiPropertyKeys.AVEncMPVDefaultBPictureCount.Guid, out var val);
        }
예제 #13
0
        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;
                }
            }
        }
예제 #14
0
        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();
        }
예제 #15
0
        private Transform FindEncoder(int adapterVenId)
        {
            logger.Debug("FindEncoder(...) " + adapterVenId);


            Transform preferTransform = null;

            var transformFlags = TransformEnumFlag.All | // TransformEnumFlag.All |
                                 TransformEnumFlag.SortAndFilter;

            var outputType = new TRegisterTypeInformation
            {
                GuidMajorType = MediaTypeGuids.Video,
                GuidSubtype   = VideoFormatGuids.H264
                                // GuidSubtype = VideoFormatGuids.Hevc
            };

            //int vendorId = 0;
            //using (var dxgiDevice = device.QueryInterface<SharpDX.DXGI.Device>())
            //{
            //    var adapter = dxgiDevice.Adapter;
            //    vendorId = adapter.Description.VendorId;
            //}


            var activates = MediaFactory.FindTransform(TransformCategoryGuids.VideoEncoder, transformFlags, null, outputType);

            try
            {
                Activate preferActivate = null;
                foreach (var activate in activates)
                {
                    var actLog = MfTool.LogMediaAttributes(activate);

                    logger.Debug("\r\nActivator:\r\n-----------------\r\n" + actLog);

                    string            name  = activate.Get(TransformAttributeKeys.MftFriendlyNameAttribute);
                    Guid              clsid = activate.Get(TransformAttributeKeys.MftTransformClsidAttribute);
                    TransformEnumFlag flags = (TransformEnumFlag)activate.Get(TransformAttributeKeys.TransformFlagsAttribute);

                    bool isAsync = !(flags.HasFlag(TransformEnumFlag.Syncmft));
                    isAsync |= (flags.HasFlag(TransformEnumFlag.Asyncmft));
                    bool isHardware = flags.HasFlag(TransformEnumFlag.Hardware);


                    if (isHardware)
                    {
                        string venIdStr = activate.Get(TransformAttributeKeys.MftEnumHardwareVendorIdAttribute);

                        if (MfTool.TryGetVendorId(venIdStr, out int activatorVendId))
                        {
                            if (activatorVendId == adapterVenId)
                            {
                                preferActivate = activate;
                                syncMode       = false;
                            }
                        }
                    }
                    else
                    {
                        //TODO:...
                    }


                    //var _flags = Enum.GetValues(typeof(TransformEnumFlag))
                    //             .Cast<TransformEnumFlag>()
                    //             .Where(m => (m != TransformEnumFlag.None && flags.HasFlag(m)));

                    //var transformInfo = name + " " + clsid.ToString() + " " + string.Join("|", _flags);

                    //logger.Info(transformInfo);

                    //logger.Debug(MfTool.LogMediaAttributes(activator));

                    //var HardwareUrl = activator.Get(TransformAttributeKeys.MftEnumHardwareUrlAttribute);
                    //logger.Info(HardwareUrl);

                    //var TransformAsync = activator.Get(TransformAttributeKeys.TransformAsync);
                    //logger.Info(TransformAsync);
                    //logger.Info("-------------------------------------");
                }

                // preferEncoder = transformActivators[0].ActivateObject<Transform>();

                if (preferActivate != null)
                {
                    preferTransform = preferActivate.ActivateObject <Transform>();
                }
            }
            finally
            {
                foreach (var activator in activates)
                {
                    activator.Dispose();
                }
            }

            return(preferTransform);
        }
예제 #16
0
        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;
            }
        }
예제 #17
0
        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();
            };
        }
예제 #18
0
        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;
                }
            }
        }
예제 #19
0
        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);
        }
예제 #20
0
            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();
                });
            }
예제 #21
0
        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);
            };
        }
예제 #22
0
        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);
        }
예제 #23
0
        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);
        }
예제 #24
0
        //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;
        }
예제 #25
0
        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));
            }
        }
예제 #26
0
        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();
        }
예제 #27
0
        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;
            }
        }
예제 #28
0
            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);
                    }
                });
            }
예제 #29
0
        public void Setup(MfVideoArgs inputArgs)
        {
            logger.Debug("MfH264Dxva2Decoder::Setup(...)");

            var width       = inputArgs.Width;
            var height      = inputArgs.Height;
            var inputFormat = VideoFormatGuids.H264;
            var frameRate   = inputArgs.FrameRate;

            LowLatency = inputArgs.LowLatency;

            try
            {
                var transformFlags = //TransformEnumFlag.Hardware |
                                     TransformEnumFlag.SortAndFilter;
                var inputType = new TRegisterTypeInformation
                {
                    GuidMajorType = MediaTypeGuids.Video,
                    GuidSubtype   = VideoFormatGuids.H264
                };

                var transformActivators = MediaFactory.FindTransform(TransformCategoryGuids.VideoDecoder, transformFlags, inputType, null);
                try
                {
                    foreach (var activator in transformActivators)
                    {
                        //bool isHardware = flags.HasFlag(TransformEnumFlag.Hardware);
                        //bool isAsync = flags.HasFlag(TransformEnumFlag.Asyncmft);

                        string            name  = activator.Get(TransformAttributeKeys.MftFriendlyNameAttribute);
                        Guid              clsid = activator.Get(TransformAttributeKeys.MftTransformClsidAttribute);
                        TransformEnumFlag flags = (TransformEnumFlag)activator.Get(TransformAttributeKeys.TransformFlagsAttribute);


                        bool isAsync = !(flags.HasFlag(TransformEnumFlag.Syncmft));
                        isAsync |= !!(flags.HasFlag(TransformEnumFlag.Asyncmft));
                        bool isHardware = !!(flags.HasFlag(TransformEnumFlag.Hardware));


                        var _flags = Enum.GetValues(typeof(TransformEnumFlag))
                                     .Cast <TransformEnumFlag>()
                                     .Where(m => (m != TransformEnumFlag.None && flags.HasFlag(m)));

                        var transformInfo = name + " " + clsid.ToString() + " " + string.Join("|", _flags);

                        logger.Info(transformInfo);

                        //encoder = activator.ActivateObject<Transform>();
                        //break;

                        //var HardwareUrl = activator.Get(TransformAttributeKeys.MftEnumHardwareUrlAttribute);
                        //logger.Info(HardwareUrl);

                        //var TransformAsync = activator.Get(TransformAttributeKeys.TransformAsync);
                        //logger.Info(TransformAsync);
                        //logger.Info("-------------------------------------");
                    }
                }
                finally
                {
                    decoder = transformActivators[0].ActivateObject <Transform>();

                    foreach (var activator in transformActivators)
                    {
                        activator.Dispose();
                    }
                }


                using (var attr = decoder.Attributes)
                {
                    bool d3dAware = attr.Get(TransformAttributeKeys.D3DAware);
                    if (d3dAware)
                    {
                        if (d3dDeviceManager != null)
                        {
                            decoder.ProcessMessage(TMessageType.SetD3DManager, d3dDeviceManager.NativePointer);
                        }
                        else
                        {
                            attr.Set(TransformAttributeKeys.D3DAware, false);
                        }
                    }

                    attr.Set(SinkWriterAttributeKeys.LowLatency, LowLatency);

                    //attr.Set(MFAttributeKeys.MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT, 1);
                }


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

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



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

                        if (mediaType == null)
                        {
                            logger.Warn("NoMoreType");
                            break;
                        }

                        var formatId = mediaType.Get(MediaTypeAttributeKeys.Subtype);
                        if (formatId == inputFormat)
                        {
                            logger.Debug("inputFormat " + inputFormat);

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

                if (InputMediaType == null)
                {
                    logger.Warn("Unsuported format: " + MfTool.GetMediaTypeName(inputFormat));
                    return;
                }

                InputMediaType.Set(MediaTypeAttributeKeys.MajorType, MediaTypeGuids.Video);
                InputMediaType.Set(MediaTypeAttributeKeys.Subtype, VideoFormatGuids.H264);
                InputMediaType.Set(MediaTypeAttributeKeys.FrameSize, MfTool.PackToLong(width, height));
                InputMediaType.Set(MediaTypeAttributeKeys.FrameRate, frameRate);
                // InputMediaType.Set(MediaTypeAttributeKeys.PixelAspectRatio, MfTool.PackToLong(1, 1));
                InputMediaType.Set(MediaTypeAttributeKeys.InterlaceMode, (int)VideoInterlaceMode.Progressive);
                InputMediaType.Set(MediaTypeAttributeKeys.AllSamplesIndependent, 1);

                decoder.SetInputType(inputStreamId, InputMediaType, 0);

                logger.Info("============== INPUT TYPE==================");
                logger.Info(MfTool.LogMediaType(InputMediaType));



                OutputMediaType = new MediaType();
                OutputMediaType.Set(MediaTypeAttributeKeys.MajorType, MediaTypeGuids.Video);
                OutputMediaType.Set(MediaTypeAttributeKeys.Subtype, VideoFormatGuids.NV12);
                //OutputMediaType.Set(MediaTypeAttributeKeys.AvgBitrate, 30000000);
                OutputMediaType.Set(MediaTypeAttributeKeys.InterlaceMode, (int)VideoInterlaceMode.Progressive);
                OutputMediaType.Set(MediaTypeAttributeKeys.FrameSize, MfTool.PackToLong(width, height));
                OutputMediaType.Set(MediaTypeAttributeKeys.FrameRate, frameRate);
                OutputMediaType.Set(MediaTypeAttributeKeys.AllSamplesIndependent, 1);

                decoder.SetOutputType(outputStreamId, OutputMediaType, 0);

                logger.Info("============== OUTPUT TYPE==================");
                logger.Info(MfTool.LogMediaType(OutputMediaType));
            }
            catch (Exception ex)
            {
                logger.Error(ex);

                Close();
                throw;
            }
        }
예제 #30
0
        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);
            }
        }