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); }
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}"); } }
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); }