// The ShowBitmap now devided into 2 methods, for MIPSDK 2014 private void ShowBitmap(BitmapData bitmapData) { // Next 15 lines new for MIPSDK 2014 if (_currentTimeInformation != null && _currentTimeInformation.PreviousTime < bitmapData.DateTime && _currentTimeInformation.NextTime > bitmapData.DateTime) { Debug.WriteLine("----> Duplicate bitmap at " + bitmapData.DateTime); // this should only happen a few times during startup return; } _currentTimeInformation = new PlaybackTimeInformationData() { Item = _selectedItem.FQID, CurrentTime = bitmapData.DateTime, NextTime = bitmapData.NextDateTime, PreviousTime = bitmapData.PreviousDateTime }; _requestInProgress = true; if (InvokeRequired) { Invoke(new ShowBitmapDelegate(ShowBitmap2), bitmapData); } else { ShowBitmap2(bitmapData); } }
private void ShowBitmap2(BitmapData bitmapData) { { if (bitmapData.DateTime != _currentShownTime || _redisplay) { _redisplay = false; // The following code does these functions: // Get a IntPtr to the start of the GBR bitmap // Transform via sample transformation (To be replaced with your C++ code) // Create a Bitmap with the result // Create a new Bitmap scaled to visible area on screen // Assign new Bitmap into PictureBox // Dispose first Bitmap // // The transformation is therefore done on the original image, but if the transformation is // keeping to the same size, then this would be much more effective if the resize was done first, // and the transformation afterwards. // Scaling can be done by setting the Width and Height on the int width = bitmapData.GetPlaneWidth(0); int height = bitmapData.GetPlaneHeight(0); int stride = bitmapData.GetPlaneStride(0); // When using RGB / BGR bitmaps, they have all bytes continues in memory. The PlanePointer(0) is used for all planes: IntPtr plane0 = bitmapData.GetPlanePointer(0); //IntPtr newPlane0 = transform.Perform(plane0, width * height * 3); // Make the sample transformation / color change IntPtr newPlane0 = _transform.Perform(plane0, stride, width, height); // Make the sample transformation / color change Image myImage = new Bitmap(width, height, stride, PixelFormat.Format24bppRgb, newPlane0); if (pictureBox.Width != 0 && pictureBox.Height != 0) // Ignore when window is not visible { // We need to resize to the displayed area pictureBox.Image = new Bitmap(myImage, pictureBox.Width, pictureBox.Height); myImage.Dispose(); // ---- bitmapData.Dispose(); Need to be disposed on the calling thread _transform.Release(newPlane0); //textBoxTime.Text = bitmapData.DateTime.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss.fff"); } } _currentShownTime = bitmapData.DateTime; Debug.WriteLine("Image time: " + bitmapData.DateTime.ToLocalTime().ToString("HH.mm.ss.fff") + ", Mode=" + _mode); } _requestInProgress = false; }
// The ShowBitmap now devided into 2 methods, for MIPSDK 2014 private void ShowBitmap(BitmapData bitmapData) { // Next 15 lines new for MIPSDK 2014 if (_currentTimeInformation != null && _currentTimeInformation.PreviousTime < bitmapData.DateTime && _currentTimeInformation.NextTime > bitmapData.DateTime) { Debug.WriteLine("----> Duplicate bitmap at " + bitmapData.DateTime); // this should only happen a few times during startup if (Selected) { EnvironmentManager.Instance.SendMessage(new Message( MessageId.SmartClient.PlaybackTimeInformation, _currentTimeInformation), null, _viewItemManager.FQID); } return; } // Set here to avoid race-condition. And we should use some locking to ensure thread-safety. _nextToFetchTime = bitmapData.DateTime; _currentTimeInformation = new PlaybackTimeInformationData { Item = _selectedItem.FQID, CurrentTime = bitmapData.DateTime, NextTime = bitmapData.NextDateTime, PreviousTime = bitmapData.PreviousDateTime }; if (Selected) { EnvironmentManager.Instance.SendMessage(new Message( MessageId.SmartClient.PlaybackTimeInformation, _currentTimeInformation), null, _viewItemManager.FQID); } _requestInProgress = true; if (InvokeRequired) { Invoke(new ShowBitmapDelegate(ShowBitmap2), bitmapData); } else { ShowBitmap2(bitmapData); } }
private void BitmapFetchThread() { bool errorRecovery = false; try { while (!_stop) { try { if (_stopPlayback) { if (_bitmapVideoSource != null) { _bitmapVideoSource.Close(); } _bitmapVideoSource = null; _nextCommand = MyPlayCommand.None; _nextToFetchTime = DateTime.MinValue; } if (_bitmapVideoSourceNext != null) { lock (_bitmapVideoSourceNextLock) { if (_bitmapVideoSource != null) { _bitmapVideoSource.Close(); } _bitmapVideoSource = _bitmapVideoSourceNext; _bitmapVideoSourceNext = null; } _bitmapVideoSource.Init(); ShowError(""); // Clear messages errorRecovery = false; } if (_bitmapVideoSource != null && _setResolution) { _bitmapVideoSource.Width = _newWidth; _bitmapVideoSource.Height = _newHeight; _bitmapVideoSource.SetWidthHeight(); _setResolution = false; } } catch (Exception ex) { if (ex is CommunicationMIPException) { ShowError("Connection lost to server ..."); } else { ShowError(ex.Message); } errorRecovery = true; _bitmapVideoSourceNext = _bitmapVideoSource; _bitmapVideoSource = null; _nextCommand = MyPlayCommand.None; _nextToFetchTime = DateTime.MinValue; } if (errorRecovery) { Thread.Sleep(3000); continue; } if (Selected && _nextCommand != MyPlayCommand.None && _bitmapVideoSource != null && !_requestInProgress) { try { BitmapData bitmapData = null; switch (_nextCommand) { case MyPlayCommand.Start: bitmapData = _bitmapVideoSource.GetBegin(); break; case MyPlayCommand.End: bitmapData = _bitmapVideoSource.GetEnd(); break; case MyPlayCommand.PrevSequence: bitmapData = _bitmapVideoSource.GetPreviousSequence(); break; case MyPlayCommand.NextSequence: bitmapData = _bitmapVideoSource.GetNextSequence(); break; case MyPlayCommand.PrevFrame: bitmapData = _bitmapVideoSource.GetPrevious(); break; case MyPlayCommand.NextFrame: bitmapData = _bitmapVideoSource.GetNext() as BitmapData; break; } if (bitmapData != null) { ShowBitmap(bitmapData); // Lets get the Smart Client to show this time, (This will issue a new set time command, but is same again (that we ignore)) EnvironmentManager.Instance.PostMessage( new Message(MessageId.SmartClient.PlaybackCommand, new PlaybackCommandData { Command = PlaybackData.Goto, DateTime = bitmapData.DateTime })); bitmapData.Dispose(); } } catch (Exception ex) { if (ex is CommunicationMIPException) { ShowError("Connection lost to server ..."); } else { ShowError(ex.Message); } errorRecovery = true; _bitmapVideoSourceNext = _bitmapVideoSource; _bitmapVideoSource = null; continue; } _nextCommand = MyPlayCommand.None; } if (_nextToFetchTime != DateTime.MinValue && (_nextToFetchTime != _currentShownTime || _redisplay) && _bitmapVideoSource != null && !_requestInProgress) { DateTime time = _nextToFetchTime; DateTime utcTime = time.Kind == DateTimeKind.Local ? time.ToUniversalTime() : time; // Next 4 lines new for MIPSDK 2014 bool willResultInSameFrame = _currentTimeInformation != null && _currentTimeInformation.NextTime > utcTime && _currentTimeInformation.PreviousTime < utcTime; // Lets validate if we are just asking for the same frame _nextToFetchTime = DateTime.MinValue; if (!willResultInSameFrame) { try { if (_mode == PlaybackPlayModeData.Stop) { _bitmapVideoSource.GoTo(utcTime, PlaybackPlayModeData.Reverse); } var bitmapData = _bitmapVideoSource.GetAtOrBefore(utcTime) as BitmapData; // For MIPSDK 2014 if (bitmapData != null && bitmapData.IsPreviousAvailable == false) { if (utcTime - TimeSpan.FromMilliseconds(10) < bitmapData.DateTime) { bitmapData.PreviousDateTime = utcTime - TimeSpan.FromMilliseconds(10); } else { bitmapData.PreviousDateTime = bitmapData.DateTime; } } if (bitmapData != null) { ShowBitmap(bitmapData); bitmapData.Dispose(); } } catch (Exception ex) { if (ex is CommunicationMIPException) { ShowError("Connection lost to server ..."); } else { ShowError(ex.Message); } errorRecovery = true; _bitmapVideoSourceNext = _bitmapVideoSource; _bitmapVideoSource = null; } } } Thread.Sleep(10); } } catch (Exception ex) { EnvironmentManager.Instance.ExceptionHandler("RGBVideoEnhancement.PlaybackThread", ex); } if (_bitmapVideoSource != null) { _bitmapVideoSource.Close(); _bitmapVideoSource = null; } _fetchThread = null; }
private void ShowBitmap2(BitmapData bitmapData) { { if (bitmapData.DateTime != _currentShownTime || _redisplay) { _redisplay = false; // The following code does these functions: // Get a IntPtr to the start of the GBR bitmap // Transform via sample transformation (To be replaced with your C++ code) // Create a Bitmap with the result // Create a new Bitmap scaled to visible area on screen // Assign new Bitmap into PictureBox // Dispose first Bitmap // // The transformation is therefore done on the original image, but if the transformation is // keeping to the same size, then this would be much more effective if the resize was done first, // and the transformation afterwards. // Scaling can be done by setting the Width and Height on the int width = bitmapData.GetPlaneWidth(0); int height = bitmapData.GetPlaneHeight(0); int stride = bitmapData.GetPlaneStride(0); // When using RGB / BGR bitmaps, they have all bytes continues in memory. The PlanePointer(0) is used for all planes: IntPtr plane0 = bitmapData.GetPlanePointer(0); IntPtr newPlane0 = transform.Perform(plane0, stride, width, height); // Make the sample transformation / color change Image myImage = new Bitmap(width, height, stride, PixelFormat.Format24bppRgb, newPlane0); // We need to resize to the displayed area pictureBox.Image = new Bitmap(myImage, pictureBox.Width, pictureBox.Height); myImage.Dispose(); // ---- bitmapData.Dispose(); transform.Release(newPlane0); textBoxTime.Text = bitmapData.DateTime.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss.fff"); // Inform the PlybackController of the time information - so skipping can be done correctly //Update 2016 EnvironmentManager.Instance.SendMessage(new VideoOS.Platform.Messaging.Message(MessageId.SmartClient.PlaybackTimeInformation, new PlaybackTimeInformationData() { Item = _selectedItem.FQID, CurrentTime = bitmapData.DateTime, PreviousTime = bitmapData.PreviousDateTime, NextTime = bitmapData.NextDateTime })); if (_mode == PlaybackPlayModeData.Stop) { //Update 2016 EnvironmentManager.Instance.SendMessage(new VideoOS.Platform.Messaging.Message(MessageId.SmartClient.PlaybackCommand, new PlaybackCommandData() { Command = PlaybackData.Goto, DateTime = bitmapData.DateTime })); } _currentShownTime = bitmapData.DateTime; Debug.WriteLine("Image time: " + bitmapData.DateTime.ToLocalTime().ToString("HH.mm.ss.fff") + ", Mode=" + _mode); } _requestInProgress = false; } }
private void BitmapFetchThread() { bool errorRecovery = false; BitmapVideoSource _bitmapVideoSource = null; while (!_stop) { if (_performCloseVideoSource) { if (_bitmapVideoSource != null) { _bitmapVideoSource.Close(); _bitmapVideoSource = null; } _performCloseVideoSource = false; } if (_newlySelectedItem != null) { _selectedItem = _newlySelectedItem; _bitmapVideoSource = new BitmapVideoSource(_selectedItem); _bitmapVideoSource.Width = pictureBox.Width; _bitmapVideoSource.Height = pictureBox.Height; _bitmapVideoSource.SetKeepAspectRatio(true, true); try { _bitmapVideoSource.Init(); BitmapData bitmapData = _bitmapVideoSource.GetAtOrBefore(DateTime.Now) as BitmapData; if (bitmapData != null) { ShowBitmap(bitmapData); } else { ShowError(""); // Clear any error messages } _newlySelectedItem = null; errorRecovery = false; BeginInvoke(new MethodInvoker(delegate() { groupBoxPlayback.Enabled = true; })); } catch (Exception ex) { if (ex is CommunicationMIPException) { ShowError("Connection lost to server ..."); } else { ShowError(ex.Message); } errorRecovery = true; _bitmapVideoSource = null; _newlySelectedItem = _selectedItem; // Redo the Initialization } } if (errorRecovery || _bitmapVideoSource == null) { if (this.IsHandleCreated) { BeginInvoke(new MethodInvoker(delegate() { groupBoxPlayback.Enabled = false; })); } if (_mode != PlaybackData.PlayStop) { buttonStop_Click(null, null); } Thread.Sleep(3000); continue; } if (_performReSize) { _bitmapVideoSource.Width = _reSizeWidth; _bitmapVideoSource.Height = _reSizeHeight; _bitmapVideoSource.SetWidthHeight(); if (_mode == PlaybackPlayModeData.Stop) { _nextToFetchTime = _currentShownTime; _redisplay = true; } } if (_nextCommand != MyPlayCommand.None && _requestInProgress == false) { try { BitmapData bitmapData = null; switch (_nextCommand) { case MyPlayCommand.Start: bitmapData = _bitmapVideoSource.GetBegin(); break; case MyPlayCommand.End: bitmapData = _bitmapVideoSource.GetEnd(); break; case MyPlayCommand.PrevSequence: bitmapData = _bitmapVideoSource.GetPreviousSequence(); break; case MyPlayCommand.NextSequence: bitmapData = _bitmapVideoSource.GetNextSequence(); break; case MyPlayCommand.PrevFrame: bitmapData = _bitmapVideoSource.GetPrevious(); break; case MyPlayCommand.NextFrame: bitmapData = _bitmapVideoSource.GetNext() as BitmapData; break; } if (bitmapData != null) { ShowBitmap(bitmapData); bitmapData.Dispose(); } } catch (Exception ex) { if (ex is CommunicationMIPException) { ShowError("Connection lost to server ..."); } else { ShowError(ex.Message); } errorRecovery = true; _bitmapVideoSource = null; _newlySelectedItem = _selectedItem; // Redo the Initialization _nextCommand = MyPlayCommand.None; Thread.Sleep(3000); continue; } _nextCommand = MyPlayCommand.None; } if (_nextToFetchTime != DateTime.MinValue && _requestInProgress == false) { Debug.WriteLine("NextToFetch = " + _nextToFetchTime.ToString()); DateTime time = _nextToFetchTime; DateTime localTime = time.Kind == DateTimeKind.Local ? time : time.ToLocalTime(); DateTime utcTime = time.Kind == DateTimeKind.Local ? time.ToUniversalTime() : time; // Next 10 lines new for MIPSDK 2014 bool willResultInSameFrame = false; // Lets validate if we are just asking for the same frame if (_currentTimeInformation != null) { if (_mode == PlaybackPlayModeData.Forward && _currentTimeInformation.NextTime > utcTime) { willResultInSameFrame = true; } if (_mode == PlaybackPlayModeData.Reverse && _currentTimeInformation.PreviousTime < utcTime) { willResultInSameFrame = true; } } _nextToFetchTime = DateTime.MinValue; if (willResultInSameFrame) { // Same frame -> Ignore request } else { try { BeginInvoke( new MethodInvoker(delegate() { textBoxAsked.Text = localTime.ToString("yyyy-MM-dd HH:mm:ss.fff"); })); BitmapData bitmapData = null; switch (_mode) { case PlaybackPlayModeData.Stop: bitmapData = _bitmapVideoSource.GetAtOrBefore(utcTime) as BitmapData; // Next 2 lines new for MIPSDK 2014 if (bitmapData != null && bitmapData.IsPreviousAvailable == false) { bitmapData.PreviousDateTime = bitmapData.DateTime - TimeSpan.FromMilliseconds(10); } break; case PlaybackPlayModeData.Forward: _bitmapVideoSource.GoTo(utcTime, _mode); bitmapData = _bitmapVideoSource.GetNext() as BitmapData; // Next 2 lines new for MIPSDK 2014 if (bitmapData != null && bitmapData.IsPreviousAvailable == false) { if (utcTime - TimeSpan.FromMilliseconds(10) < bitmapData.DateTime) { bitmapData.PreviousDateTime = utcTime - TimeSpan.FromMilliseconds(10); } else { bitmapData.PreviousDateTime = bitmapData.DateTime; } } break; case PlaybackPlayModeData.Reverse: _bitmapVideoSource.GoTo(utcTime, _mode); bitmapData = _bitmapVideoSource.GetPrevious(); // Next 2 lines new for MIPSDK 2014 if (bitmapData != null && bitmapData.IsPreviousAvailable == false) { bitmapData.PreviousDateTime = bitmapData.DateTime - TimeSpan.FromMilliseconds(10); } break; } if (bitmapData != null) { ShowBitmap(bitmapData); bitmapData.Dispose(); } } catch (Exception ex) { if (ex is CommunicationMIPException) { ShowError("Connection lost to server ..."); } else { ShowError(ex.Message); } errorRecovery = true; _bitmapVideoSource = null; _nextCommand = MyPlayCommand.None; _newlySelectedItem = _selectedItem; // Redo the Initialization } } } } _fetchThread = null; }