예제 #1
0
        public void StartLocalVideo(VideoMode videoMode)
        {
            if (_localVideoSamplingTask != null && !_localVideoSamplingTask.IsCompleted && _localVideoSamplingCancelTokenSource != null)
            {
                _localVideoSamplingCancelTokenSource.Cancel();
            }

            var videoSampler = new MFVideoSampler();

            videoSampler.Init(videoMode.DeviceIndex, VideoSubTypesEnum.RGB24, videoMode.Width, videoMode.Height);
            //videoSampler.InitFromFile();
            //_audioChannel = new AudioChannel();

            _localVideoSamplingCancelTokenSource = new CancellationTokenSource();
            var cancellationToken = _localVideoSamplingCancelTokenSource.Token;

            _localVideoSamplingTask = Task.Factory.StartNew(() =>
            {
                Thread.CurrentThread.Name = "vidsampler_" + videoMode.DeviceIndex + "_" + videoMode.Width + "_" + videoMode.Height;

                var vpxEncoder = new VPXEncoder();
                vpxEncoder.InitEncoder(Convert.ToUInt32(videoMode.Width), Convert.ToUInt32(videoMode.Height));

                // var videoSampler = new MFVideoSampler();
                //videoSampler.Init(videoMode.DeviceIndex, videoMode.Width, videoMode.Height);
                // videoSampler.InitFromFile();

                while (!_stop && !cancellationToken.IsCancellationRequested)
                {
                    byte[] videoSample = null;
                    int result         = videoSampler.GetSample(ref videoSample);

                    if (result == NAudio.MediaFoundation.MediaFoundationErrors.MF_E_HW_MFT_FAILED_START_STREAMING)
                    {
                        logger.Warn("A sample could not be acquired from the local webcam. Check that it is not already in use.");
                        OnLocalVideoError("A sample could not be acquired from the local webcam. Check that it is not already in use.");
                        break;
                    }
                    else if (result != 0)
                    {
                        logger.Warn("A sample could not be acquired from the local webcam. Check that it is not already in use. Error code: " + result);
                        OnLocalVideoError("A sample could not be acquired from the local webcam. Check that it is not already in use. Error code: " + result);
                        break;
                    }
                    else if (videoSample != null)
                    {
                        // This event sends the raw bitmap to the WPF UI.
                        if (OnLocalVideoSampleReady != null)
                        {
                            OnLocalVideoSampleReady(videoSample, videoSampler.Width, videoSampler.Height);
                        }

                        // This event encodes the sample and forwards it to the RTP manager for network transmission.
                        if (_rtpManager != null)
                        {
                            IntPtr rawSamplePtr = Marshal.AllocHGlobal(videoSample.Length);
                            Marshal.Copy(videoSample, 0, rawSamplePtr, videoSample.Length);

                            byte[] yuv = null;

                            unsafe
                            {
                                _imageConverter.ConvertRGBtoYUV((byte *)rawSamplePtr, VideoSubTypesEnum.RGB24, Convert.ToInt32(videoMode.Width), Convert.ToInt32(videoMode.Height), VideoSubTypesEnum.I420, ref yuv);
                                //_imageConverter.ConvertToI420((byte*)rawSamplePtr, VideoSubTypesEnum.RGB24, Convert.ToInt32(videoMode.Width), Convert.ToInt32(videoMode.Height), ref yuv);
                            }

                            Marshal.FreeHGlobal(rawSamplePtr);

                            IntPtr yuvPtr = Marshal.AllocHGlobal(yuv.Length);
                            Marshal.Copy(yuv, 0, yuvPtr, yuv.Length);

                            byte[] encodedBuffer = null;

                            unsafe
                            {
                                vpxEncoder.Encode((byte *)yuvPtr, yuv.Length, _encodingSample++, ref encodedBuffer);
                            }

                            Marshal.FreeHGlobal(yuvPtr);

                            //if(encodedBuffer )
                            _rtpManager.LocalVideoSampleReady(encodedBuffer);
                        }
                    }
                }

                videoSampler.Stop();
                vpxEncoder.Dispose();
            }, cancellationToken);

            _localAudioSamplingTask = Task.Factory.StartNew(() =>
            {
                Thread.CurrentThread.Name = "audsampler_" + videoMode.DeviceIndex;

                while (!_stop && !cancellationToken.IsCancellationRequested)
                {
                    byte[] audioSample = null;
                    int result         = videoSampler.GetAudioSample(ref audioSample);

                    if (result == NAudio.MediaFoundation.MediaFoundationErrors.MF_E_HW_MFT_FAILED_START_STREAMING)
                    {
                        logger.Warn("An audio sample could not be acquired from the local source. Check that it is not already in use.");
                        //OnLocalVideoError("A sample could not be acquired from the local webcam. Check that it is not already in use.");
                        break;
                    }
                    else if (result != 0)
                    {
                        logger.Warn("An audio sample could not be acquired from the local source. Check that it is not already in use. Error code: " + result);
                        //OnLocalVideoError("A sample could not be acquired from the local webcam. Check that it is not already in use. Error code: " + result);
                        break;
                    }
                    else if (audioSample != null)
                    {
                        if (_audioChannel != null)
                        {
                            _audioChannel.AudioSampleReceived(audioSample, 0);
                        }
                    }
                }
            }, cancellationToken);
        }
예제 #2
0
        private void SampleWebCam(MFVideoSampler videoSampler, VideoMode videoMode, CancellationTokenSource cts)
        {
            try
            {
                Thread.CurrentThread.Name = "vidsampler_" + videoMode.DeviceIndex + "_" + videoMode.Width + "_" + videoMode.Height;

                var vpxEncoder = new VPXEncoder();
                // TODO: The last parameter passed to the vpx encoder init needs to be the frame stride not the width.
                vpxEncoder.InitEncoder(Convert.ToUInt32(videoMode.Width), Convert.ToUInt32(videoMode.Height), Convert.ToUInt32(videoMode.Width));

                // var videoSampler = new MFVideoSampler();
                //videoSampler.Init(videoMode.DeviceIndex, videoMode.Width, videoMode.Height);
                // videoSampler.InitFromFile();

                while (!_stop && !cts.IsCancellationRequested)
                {
                    byte[] videoSample = null;
                    var    sample      = videoSampler.GetSample(ref videoSample);

                    //if (result == NAudio.MediaFoundation.MediaFoundationErrors.MF_E_HW_MFT_FAILED_START_STREAMING)
                    //{
                    //    logger.Warn("A sample could not be acquired from the local webcam. Check that it is not already in use.");
                    //    OnLocalVideoError("A sample could not be acquired from the local webcam. Check that it is not already in use.");
                    //    break;
                    //}
                    //else if (result != 0)
                    //{
                    //    logger.Warn("A sample could not be acquired from the local webcam. Check that it is not already in use. Error code: " + result);
                    //    OnLocalVideoError("A sample could not be acquired from the local webcam. Check that it is not already in use. Error code: " + result);
                    //    break;
                    //}
                    //else
                    if (sample?.HasVideoSample == true)
                    {
                        // This event sends the raw bitmap to the WPF UI.
                        OnLocalVideoSampleReady?.Invoke(videoSample, videoSampler.Width, videoSampler.Height);

                        // This event encodes the sample and forwards it to the RTP manager for network transmission.
                        if (_rtpManager != null)
                        {
                            IntPtr rawSamplePtr = Marshal.AllocHGlobal(videoSample.Length);
                            Marshal.Copy(videoSample, 0, rawSamplePtr, videoSample.Length);

                            byte[] yuv = null;

                            unsafe
                            {
                                // TODO: using width instead of stride.
                                _imageConverter.ConvertRGBtoYUV((byte *)rawSamplePtr, VideoSubTypesEnum.RGB24, Convert.ToInt32(videoMode.Width), Convert.ToInt32(videoMode.Height), Convert.ToInt32(videoMode.Width), VideoSubTypesEnum.I420, ref yuv);
                                //_imageConverter.ConvertToI420((byte*)rawSamplePtr, VideoSubTypesEnum.RGB24, Convert.ToInt32(videoMode.Width), Convert.ToInt32(videoMode.Height), ref yuv);
                            }

                            Marshal.FreeHGlobal(rawSamplePtr);

                            IntPtr yuvPtr = Marshal.AllocHGlobal(yuv.Length);
                            Marshal.Copy(yuv, 0, yuvPtr, yuv.Length);

                            byte[] encodedBuffer = null;

                            unsafe
                            {
                                vpxEncoder.Encode((byte *)yuvPtr, yuv.Length, _encodingSample++, ref encodedBuffer);
                            }

                            Marshal.FreeHGlobal(yuvPtr);

                            //if(encodedBuffer )
                            _rtpManager.LocalVideoSampleReady(encodedBuffer);
                        }
                    }
                }

                videoSampler.Stop();
                vpxEncoder.Dispose();
            }
            catch (Exception excp)
            {
                logger.Error($"Exception SampleWebCam. {excp.Message}");
            }
        }
예제 #3
0
        public void StartLocalVideo(VideoMode videoMode)
        {
            if (_localVideoSamplingTask != null && !_localVideoSamplingTask.IsCompleted && _localVideoSamplingCancelTokenSource != null)
            {
                _localVideoSamplingCancelTokenSource.Cancel();
            }

            var videoSampler = new MFVideoSampler();
            videoSampler.Init(videoMode.DeviceIndex, videoMode.Width, videoMode.Height);
            //videoSampler.InitFromFile();
            //_audioChannel = new AudioChannel();

            _localVideoSamplingCancelTokenSource = new CancellationTokenSource();
            var cancellationToken = _localVideoSamplingCancelTokenSource.Token;

            _localVideoSamplingTask = Task.Factory.StartNew(() =>
            {
                Thread.CurrentThread.Name = "vidsampler_" + videoMode.DeviceIndex + "_" + videoMode.Width + "_" + videoMode.Height;

                var vpxEncoder = new VPXEncoder();
                vpxEncoder.InitEncoder(Convert.ToUInt32(videoMode.Width), Convert.ToUInt32(videoMode.Height));

               // var videoSampler = new MFVideoSampler();
                //videoSampler.Init(videoMode.DeviceIndex, videoMode.Width, videoMode.Height);
               // videoSampler.InitFromFile();

                while (!_stop && !cancellationToken.IsCancellationRequested)
                {
                    byte[] videoSample = null;
                    int result = videoSampler.GetSample(ref videoSample);

                    if (result == NAudio.MediaFoundation.MediaFoundationErrors.MF_E_HW_MFT_FAILED_START_STREAMING)
                    {
                        logger.Warn("A sample could not be acquired from the local webcam. Check that it is not already in use.");
                        OnLocalVideoError("A sample could not be acquired from the local webcam. Check that it is not already in use.");
                        break;
                    }
                    else if (result != 0)
                    {
                        logger.Warn("A sample could not be acquired from the local webcam. Check that it is not already in use. Error code: " + result);
                        OnLocalVideoError("A sample could not be acquired from the local webcam. Check that it is not already in use. Error code: " + result);
                        break;
                    }
                    else if (videoSample != null)
                    {
                        // This event sends the raw bitmap to the WPF UI.
                        if (OnLocalVideoSampleReady != null)
                        {
                            OnLocalVideoSampleReady(videoSample, videoSampler.Width, videoSampler.Height);
                        }

                        // This event encodes the sample and forwards it to the RTP manager for network transmission.
                        if (_rtpManager != null)
                        {
                            IntPtr rawSamplePtr = Marshal.AllocHGlobal(videoSample.Length);
                            Marshal.Copy(videoSample, 0, rawSamplePtr, videoSample.Length);

                            byte[] yuv = null;

                            unsafe
                            {
                                _imageConverter.ConvertRGBtoYUV((byte*)rawSamplePtr, Convert.ToInt32(videoMode.Width), Convert.ToInt32(videoMode.Height), ref yuv);
                            }

                            Marshal.FreeHGlobal(rawSamplePtr);

                            IntPtr yuvPtr = Marshal.AllocHGlobal(yuv.Length);
                            Marshal.Copy(yuv, 0, yuvPtr, yuv.Length);

                            byte[] encodedBuffer = null;

                            unsafe
                            {
                                vpxEncoder.Encode((byte*)yuvPtr, yuv.Length, _encodingSample++, ref encodedBuffer);
                            }

                            Marshal.FreeHGlobal(yuvPtr);

                            _rtpManager.LocalVideoSampleReady(encodedBuffer);
                        }
                    }
                }

                videoSampler.Stop();
                vpxEncoder.Dispose();
            }, cancellationToken);

            _localAudioSamplingTask = Task.Factory.StartNew(() =>
            {
                Thread.CurrentThread.Name = "audsampler_" + videoMode.DeviceIndex;

                while (!_stop && !cancellationToken.IsCancellationRequested)
                {
                    byte[] audioSample = null;
                    int result = videoSampler.GetAudioSample(ref audioSample);

                    if (result == NAudio.MediaFoundation.MediaFoundationErrors.MF_E_HW_MFT_FAILED_START_STREAMING)
                    {
                        logger.Warn("An audio sample could not be acquired from the local source. Check that it is not already in use.");
                        //OnLocalVideoError("A sample could not be acquired from the local webcam. Check that it is not already in use.");
                        break;
                    }
                    else if (result != 0)
                    {
                        logger.Warn("An audio sample could not be acquired from the local source. Check that it is not already in use. Error code: " + result);
                        //OnLocalVideoError("A sample could not be acquired from the local webcam. Check that it is not already in use. Error code: " + result);
                        break;
                    }
                    else if (audioSample != null)
                    {
                        if (_audioChannel != null)
                        {
                            _audioChannel.AudioSampleReceived(audioSample, 0);
                        }
                    }
                }
            }, cancellationToken);
        }