override protected Frame.Video FrameBufferPrepare() { Frame.Video oRetVal = new Frame.Video(sName); IntPtr pBuffer; (new Logger("DeckLinkFake", sName)).WriteNotice("!!!!!:" + stArea.nWidth + ":" + stArea.nHeight + ":" + stArea.nWidth * 4 + ":" + "BGRA"); if (_pFakePointer == IntPtr.Zero) { _pFakePointer = Marshal.AllocHGlobal(_nVideoBytesQty); } pBuffer = _pFakePointer; if (IntPtr.Zero != pBuffer) { lock (_ahFramesBuffersBinds) { _ahFramesBuffersBinds.Add(oRetVal, pBuffer); } oRetVal.oFrameBytes = pBuffer; (new Logger("DeckLinkFake", sName)).WriteNotice("new decklink video frame was created. [count=" + _ahFramesBuffersBinds.Count + "]"); } else { (new Logger("DeckLinkFake", sName)).WriteError(new Exception("CREATE VIDEOFRAME RETURNED NULL!")); } return(oRetVal); }
byte[] GetVideoFrame() { // см внимательно ScheduledFrameCompleted в деклинке!! Frame.Video cV = _AjaFramesVideoBuffer.Dequeue(); _AjaFramesVideoToDispose.Enqueue(cV); return(cV.aFrameBytes.aBytes); }
override protected Frame.Video FrameBufferPrepare() { if (_ePixelFormat != AjaInterop.NTV2FrameBufferFormat.NTV2_FBF_ARGB && _ePixelFormat != AjaInterop.NTV2FrameBufferFormat.NTV2_FBF_ABGR) { throw new Exception("not supported pixel format [" + _ePixelFormat + "][expected=" + AjaInterop.NTV2FrameBufferFormat.NTV2_FBF_ARGB + "]"); } Frame.Video cRetVal = new Frame.Video(sName); cRetVal.oFrameBytes = new Bytes() { aBytes = new byte[_nVideoBytesQty], nID = -1 }; // if problems - look at ntv2player.cc: mVideoBufferSize = GetVideoWriteSize (mVideoFormat, mPixelFormat, mVancEnabled, mWideVanc); return(cRetVal); }
override protected bool FrameSchedule() { Frame.Video cFrameVideo; _dtLastTimeFrameScheduleCalled = DateTime.Now; int nLogCount = 0; #region video if (NextFrameAttached) { try { while (Preferences.nQueueDeviceLength > _cXNARender._aqDisplayQueue.Count) { if (null == (cFrameVideo = VideoFrameGet()) || null == cFrameVideo.aFrameBytes) { (new Logger()).WriteDebug("got null instead of frame"); break; } lock (_cXNARender._aqDisplayQueue) { //_GlobalMeter = Stopwatch.StartNew(); _cXNARender._aqDisplayQueue.Enqueue(_cXNARender.TextureCreate(cFrameVideo.aFrameBytes, _stArea.nWidth, _stArea.nHeight)); //UNDONE if (null != _cFrameVideoPrevious) { FrameBufferReleased(_cFrameVideoPrevious); } _cFrameVideoPrevious = cFrameVideo; //_GlobalMeter.Stop(); //_nGlobalTexture += _GlobalMeter.ElapsedMilliseconds; //if (_GlobalMeter.ElapsedMilliseconds < _nTextureMin) _nTextureMin = _GlobalMeter.ElapsedMilliseconds; //if (_GlobalMeter.ElapsedMilliseconds > _nTextureMax) _nTextureMax = _GlobalMeter.ElapsedMilliseconds; //if (_nGlobalIndex == 100) //{ // (new Logger()).WriteNotice("!!!!!!!!!!! 100 TextureCreate = " + _nGlobalTexture / 100 + " ms (" + _nTextureMin + "," + _nTextureMax + ")]"); // _nGlobalIndex = -1; // _nGlobalTexture = 0; // _nTextureMin = long.MaxValue; // _nTextureMax = 0; //} //_nGlobalIndex++; } AudioFrameGet(); break; } if (!nStarted && _cXNARender._aqDisplayQueue.Count > 0) { nStarted = true; } if (nStarted) { nLogCount++; if (_cXNARender._aqDisplayQueue.Count < Preferences.nQueueDeviceLength / 2) { (new Logger()).WriteNotice("device queue is less than " + Preferences.nQueueDeviceLength / 2 + " (" + _cXNARender._aqDisplayQueue.Count + ") dev buffer:" + base._nBufferFrameCount + " internal buffer:(" + _aq__PROBA__AudioFrames.Count + ", " + _aq__PROBA__VideoFrames.Count + ")"); } else if (nLogCount > 200) { nLogCount = 0; (new Logger()).WriteNotice("device queue:(" + _cXNARender._aqDisplayQueue.Count + ") dev buffer:" + base._nBufferFrameCount + " internal buffer:(" + _aq__PROBA__AudioFrames.Count + ", " + _aq__PROBA__VideoFrames.Count + ")"); } } } catch (Exception ex) { (new Logger()).WriteError(ex); } } #endregion return(true); }
override protected Frame.Video FrameBufferPrepare() { Frame.Video cRetVal = new Frame.Video(); cRetVal.oFrameBytes = new byte[_stArea.nWidth * _stArea.nHeight * 4]; //UNDONE * 4 //1b return(cRetVal); }
protected Frame.Video VideoFrameGet() { Frame.Video cRetVal; if (1 < _aq__PROBA__AudioFrames.Count - _aq__PROBA__VideoFrames.Count) { //_cFrameVideoLast.nReferences++; //_aq__PROBA__VideoFrames.Enqueue(_cFrameVideoLast); //КАК Я И ГОВОРИЛ, БАГ ИМЕННО ИЗ-ЗА ЭТОЙ КОНСТРУКЦИИ =)) МЫ ОДИН И ТОТ ЖЕ НОРМАЛЬНЫЙ КАДР ХУЯЧИМ ДВА РАЗА ИЗ-ЗА ЭТОГО IF'А if (250 < BalanceBeemTimeCounter) { ulong nID = _aq__PROBA__AudioFrames.Dequeue().nID; (new Logger()).WriteWarning("BALANCE-BEEM. SYNC CORRECTED BY DROPPING __AUDIO__ FRAME! [audio_frame_id=" + nID + "][ticks=" + DateTime.Now.Ticks + "]"); } else if (0 == BalanceBeemTimeCounter) (new Logger()).WriteNotice("balance-beem started [ticks=" + DateTime.Now.Ticks + "]"); BalanceBeemTimeCounter++; } else if (0 < BalanceBeemTimeCounter) { BalanceBeemTimeCounter = 0; (new Logger()).WriteNotice("balance-beem ended [ticks=" + DateTime.Now.Ticks + "]"); } if (0 < _aq__PROBA__VideoFrames.Count) { cRetVal = _aq__PROBA__VideoFrames.Dequeue(); _cBugCatcherOnVideoFrameReturn.Enqueue(cRetVal, "first return:_aq__PROBA__VideoFrames:" + _aq__PROBA__VideoFrames.Count + ":_aq__PROBA__AudioFrames:" + _aq__PROBA__AudioFrames.Count); // bug return cRetVal; } cRetVal = _cFrameVideoLast; Frame cFrame = NextFrame(); _cBugCatcherOnFrameGet.Enqueue(cFrame, "video recieve:_aq__PROBA__VideoFrames:" + _aq__PROBA__VideoFrames.Count + ":_aq__PROBA__AudioFrames:" + _aq__PROBA__AudioFrames.Count); if (null != cFrame) { if (null == cFrame.cVideo.oFrameBytes) { _cFrameVideoLast.nReferences++; (new Logger()).WriteDebug2("BYTES FROM BTL IS NULL 2 - repeat the last [id=" + _cFrameVideoLast.nID + "][ref=" + _cFrameVideoLast.nReferences + "]"); } else if (cFrame.cVideo.oFrameBytes is byte[] && 1 > cFrame.cVideo.aFrameBytes.Length) cRetVal = _cFrameVideoLast = _cVideoFrameEmpty; //получили признак необходимости очистить экран else cRetVal = _cFrameVideoLast = cFrame.cVideo; if (null != cFrame.cAudio && null != cFrame.cAudio.aFrameBytes) _aq__PROBA__AudioFrames.Enqueue(cFrame.cAudio); else _aq__PROBA__AudioFrames.Enqueue(_cFrameAudioEmpty); } else { _cFrameVideoLast.nReferences++; (new Logger()).WriteDebug2("FRAME FROM BTL IS NULL 2 - repeat the last [id=" + _cFrameVideoLast.nID + "][ref=" + _cFrameVideoLast.nReferences + "]"); _aq__PROBA__AudioFrames.Enqueue(_cFrameAudioEmpty); } _cBugCatcherOnVideoFrameReturn.Enqueue(cRetVal, "last return:_aq__PROBA__VideoFrames:" + _aq__PROBA__VideoFrames.Count + ":_aq__PROBA__AudioFrames:" + _aq__PROBA__AudioFrames.Count); // bug return cRetVal; }
protected Frame.Audio AudioFrameGet() { if (0 < _aq__PROBA__AudioFrames.Count) return _aq__PROBA__AudioFrames.Dequeue(); Frame.Audio cRetVal = _cFrameAudioEmpty; Frame cFrame = NextFrame(); _cBugCatcherOnFrameGet.Enqueue(cFrame, "audio recieve:_aq__PROBA__VideoFrames:" + _aq__PROBA__VideoFrames.Count + ":_aq__PROBA__AudioFrames:" + _aq__PROBA__AudioFrames.Count); if (null != cFrame) { if (null == cFrame.cVideo.oFrameBytes) { _cFrameVideoLast.nReferences++; (new Logger()).WriteDebug2("BYTES FROM BTL IS NULL 1 - repeat the last [id=" + _cFrameVideoLast.nID + "][ref=" + _cFrameVideoLast.nReferences + "]"); } else if (cFrame.cVideo.oFrameBytes is byte[] && 1 > cFrame.cVideo.aFrameBytes.Length) _cFrameVideoLast = _cVideoFrameEmpty; //получили признак необходимости очистить экран else _cFrameVideoLast = cFrame.cVideo; _aq__PROBA__VideoFrames.Enqueue(_cFrameVideoLast); if (null != cFrame.cAudio && null != cFrame.cAudio.aFrameBytes) cRetVal = cFrame.cAudio; else (new Logger()).WriteNotice("Got null audio frame from BTL! [audio_frame_is_null = " + (cFrame.cAudio == null ? "true]" : "false][bytes_is_null = " + (cFrame.cAudio.aFrameBytes == null ? "true" : "false") + "]")); } else { _aq__PROBA__VideoFrames.Enqueue(_cFrameVideoLast); _cFrameVideoLast.nReferences++; // пока не разобрались с набегающим рассинхроном - теряем кадрик! (new Logger()).WriteDebug2("FRAME FROM BTL IS NULL 1 - repeat the last [id=" + _cFrameVideoLast.nID + "][ref=" + _cFrameVideoLast.nReferences + "]"); } // пока не разобрались с набегающим рассинхроном - теряем кадрик! if (2 < _aq__PROBA__VideoFrames.Count) { if (250 < BalanceBeemTimeCounter) { Frame.Video cVF = _aq__PROBA__VideoFrames.Dequeue(); FrameBufferReleased(cVF); // возврат в конвейер (new Logger()).WriteWarning("BALANCE-BEEM. SYNC CORRECTED BY DROPPING __VIDEO__ FRAME! [video_frame_id=" + cVF.nID + "][ticks=" + DateTime.Now.Ticks + "]"); } else if (0 == BalanceBeemTimeCounter) (new Logger()).WriteNotice("balance-beem started [ticks=" + DateTime.Now.Ticks + "]"); BalanceBeemTimeCounter++; } else if (0 < BalanceBeemTimeCounter) { BalanceBeemTimeCounter = 0; (new Logger()).WriteNotice("balance-beem ended [ticks=" + DateTime.Now.Ticks + "]"); } return cRetVal; }
public BugCatcher(Frame.Video cEmpty) { Info cInfo = new Info { cFrame = new Frame() { cVideo = cEmpty }, sInfo = "empty frame" }; aLastNFrames.Add(cInfo); aLastNFrames.Add(cInfo); aLastNFrames.Add(cInfo); aLastNFrames.Add(cInfo); _cEmptyVideoFrame = cEmpty; }
virtual public void TurnOn() { if (Preferences.bAudio) { _cFrameAudioEmpty = new Frame.Audio(); _cFrameAudioEmpty.aFrameBytes = new byte[Preferences.nAudioBytesPerFrame]; } if (!Preferences.bDeviceInput) { _cVideoFrameEmpty = FrameBufferPrepare(); if (_cVideoFrameEmpty.oFrameBytes is IntPtr) { uint nBlack = 0x0; for (int nIndx = 0; nIndx < _stArea.nWidth * _stArea.nHeight * 4; nIndx += 4) Marshal.WriteInt32(_cVideoFrameEmpty.pFrameBytes, nIndx, (Int32)nBlack); //pixel format } _cFrameVideoLast = _cVideoFrameEmpty; while (Preferences.nQueueBaetylusLength + 2 > _aFrames.Count) AddNewFrameToConveyor("! from TurnOn !"); _cThread = new System.Threading.Thread(FrameScheduleWorker); _cThread.Priority = System.Threading.ThreadPriority.Highest; _cThread.Start(); _cBugCatcherOnFrameGet = new BugCatcher(_cVideoFrameEmpty); // bug _cBugCatcherOnVideoFrameReturn = new BugCatcher(_cVideoFrameEmpty); // bug _cBugCatcherOnVideoFramePrepare = new BugCatcher(_cVideoFrameEmpty); // bug _cBugCatcherScheduleFrame = new BugCatcher(_cVideoFrameEmpty); // bug //System.Threading.ThreadPool.QueueUserWorkItem(FrameScheduleWorker); } }
override protected Frame.Video FrameBufferPrepare() { IDeckLinkMutableVideoFrame cVideoFrame; Frame.Video oRetVal = new Frame.Video(); IntPtr pBuffer; (new Logger()).WriteNotice("!!!!!:" + stArea.nWidth + ":" + stArea.nHeight + ":" + stArea.nWidth * 4 + ":" + Preferences.ePixelFormat); _iDLOutput.CreateVideoFrame(stArea.nWidth, stArea.nHeight, stArea.nWidth * 4, Preferences.ePixelFormat, _BMDFrameFlags.bmdFrameFlagDefault, out cVideoFrame); _nFrameBufSize = stArea.nWidth * stArea.nHeight * 4; cVideoFrame.GetBytes(out pBuffer); if (IntPtr.Zero != pBuffer) { lock (_ahFramesBuffersBinds) { if (_ahFramesBuffersBinds.Values.Contains(cVideoFrame)) // проверить было ли вообще такое!!!! (new Logger()).WriteError(new Exception("TRYING TO INSERT FRAME [type = IDeckLinkMutableVideoFrame] INTO _ahFramesBuffersBinds, THAT ALREADY EXISTS THERE!")); _ahFramesBuffersBinds.Add(oRetVal, cVideoFrame); } oRetVal.oFrameBytes = pBuffer; (new Logger()).WriteNotice("new decklink video frame was created. [count=" + _ahFramesBuffersBinds.Count + "]"); } else (new Logger()).WriteError(new Exception("CREATE VIDEOFRAME RETURNED NULL!")); return oRetVal; }