public Command(ID eID, PixelsMap cPM) { try { this.eID = eID; this.cPM = cPM; ahParameters = new Dictionary <Type, object>(); cMRE = new System.Threading.ManualResetEvent(false); } catch (Exception ex) { (new Logger("CUDA")).WriteError(ex); } }
public Triple(MergingMethod stMergingMethod, Area stArea, Format ePixelFormat, bool bKeepAlive, AddToDisposeBTL dAddToDisposeBTL) { _dAddToDisposeBTL = dAddToDisposeBTL; _bFirstTime = true; _stMergingMethod = stMergingMethod; _oLock = new object(); aPMs = new PixelsMap[_nMaxTripleIndex]; for (int nI = 0; nI < aPMs.Length; nI++) { aPMs[nI] = new PixelsMap(stMergingMethod, stArea, ePixelFormat); aPMs[nI].bKeepAlive = bKeepAlive; aPMs[nI]._nIndexTriple = (byte)nI; } _nCurrentPM = 0; }
static public PixelsMap Merge(Area stBase, List <PixelsMap> aPMs) { if ( 1 == aPMs.Count && 0 == aPMs[0]._nShiftTotalX && // не надо поля делать stBase == aPMs[0].stArea && byte.MaxValue == aPMs[0].nAlphaConstant && aPMs[0]._stPosition.X == (float)Math.Floor(aPMs[0]._stPosition.X) && // надеюсь это редко будет вообще проверяться.... aPMs[0]._stPosition.Y == (float)Math.Floor(aPMs[0]._stPosition.Y) ) { return(aPMs[0]); } #if CUDA PixelsMap cRetVal = new PixelsMap(aPMs[0].stMergingMethod, stBase, Format.ARGB32); cRetVal._bTemp = true; Command cCmd = null; if (aPMs[0].stMergingMethod.eDeviceType > 0) { //cRetVal._nBytesQty = (uint)(stBase.nWidth * stBase.nHeight * 4); //UNDONE нужно определять кол-во байт по ePixelFormat //FIXED cCmd = new Command(Command.ID.Allocate, cRetVal); _ahMergingHash_CommandsQueue[aPMs[0].stMergingMethod.nHash].Enqueue(cCmd); } else { cRetVal.Allocate(); } #else PixelsMap cRetVal = new PixelsMap(MergingDevice.DisCom, 0, stBase, Format.ARGB32); cRetVal._bTemp = true; cRetVal.Allocate(); #endif cRetVal.Merge(aPMs); return(cRetVal); }
override public void Prepare() { try { bool bCUDAEffects = bCUDA; foreach (Item cItem in _aEffects) { if (EffectStatus.Idle == cItem.iEffect.eStatus) cItem.iEffect.Prepare(); if (!cItem.iVideo.bCUDA) bCUDAEffects = false; } if (null != _cPixelsMap && stArea != _cPixelsMap.stArea) { _cPixelsMap.Dispose(true); _cPixelsMap = null; } if (null == _cPixelsMap) { _cPixelsMap = new PixelsMap(bCUDAEffects, stArea, PixelsMap.Format.ARGB32); _cPixelsMap.bKeepAlive = true; if (1 > _cPixelsMap.nLength) (new Logger()).WriteNotice("1 > _cPixelsMap.nLength. roll.prepare"); _cPixelsMap.Allocate(); } if (bCUDA && !bCUDAEffects) { if (null != _cCUDAPixelsMap && stArea != _cCUDAPixelsMap.stArea) { _cCUDAPixelsMap.Dispose(true); _cCUDAPixelsMap = null; } if (null == _cCUDAPixelsMap) { _cCUDAPixelsMap = new PixelsMap(true, stArea, PixelsMap.Format.ARGB32); _cCUDAPixelsMap.bKeepAlive = true; } } base.Prepare(); } catch (Exception ex) { (new Logger()).WriteError(ex); } }
public void EffectAdd(IVideo iVideo, float nSpeed, Keyframe[] aKeyframes, bool bSticky, uint nStartDelay) { IEffect iEffect = (IEffect)iVideo; iEffect.Prepared += OnEffectPrepared; iEffect.Started += OnEffectStarted; iEffect.Stopped += OnEffectStopped; iEffect.Failed += OnEffectFailed; Area stEffectArea = ((IVideo)iVideo).stArea; Point stEffectPosition = new Point(); if (stArea.nWidth == 0 && stArea.nHeight == 0) { Area stAreaNew = stArea; stAreaNew.nWidth = stEffectArea.nWidth; stAreaNew.nHeight = stEffectArea.nHeight; stArea = stAreaNew; } if (EffectStatus.Idle < ((IEffect)this).eStatus) iEffect.Prepare(); lock (_aEffects) { if (0 < _aEffects.Count && _aEffects[0].iVideo.bCUDA != iVideo.bCUDA) throw new Exception("некорректна¤ среда вычислений"); //TODO LANG if (1 > _aEffects.Count && null != _cPixelsMap && iVideo.bCUDA != _cPixelsMap.bCUDA) { _cPixelsMap.Dispose(true); _cPixelsMap = new PixelsMap(iVideo.bCUDA, stArea, PixelsMap.Format.ARGB32); _cPixelsMap.bKeepAlive = true; if (1 > _cPixelsMap.nLength) (new Logger()).WriteNotice("1 > _cPixelsMap.nLength. roll.effectadd"); _cPixelsMap.Allocate(); } if (eDirection == Direction.Up) { stEffectPosition.X = 0; stEffectPosition.Y = stArea.nHeight; } else if (eDirection == Direction.Down) { stEffectPosition.X = 0; stEffectPosition.Y = - stEffectArea.nHeight; } else if (eDirection == Direction.Right) { stEffectPosition.X = - stEffectArea.nWidth; stEffectPosition.Y = 0; } else if (eDirection == Direction.Left) { stEffectPosition.X = stArea.nWidth; stEffectPosition.Y = 0; } _aEffects.Add(new Item(iVideo, stEffectPosition, nSpeed, aKeyframes, bSticky, nStartDelay)); } (new Logger()).WriteDebug2("roll_effect_add: [pos=" + stEffectPosition + "] [speed=" + nSpeed + "] [keyframes=" + aKeyframes + "] [sticky=" + bSticky + "]"); OnEffectAdded((Effect)iVideo); }
public Command(ID eID, PixelsMap cPM) { try { this.eID = eID; this.cPM = cPM; ahParameters = new Dictionary<Type, object>(); cMRE = new System.Threading.ManualResetEvent(false); } catch (Exception ex) { (new Logger()).WriteError(ex); } }
static public PixelsMap Merge(Area stBase, List<PixelsMap> aPMs) { if (1 == aPMs.Count && 0 == aPMs[0]._nShiftPosition && stBase == aPMs[0].stArea && byte.MaxValue == aPMs[0].nAlphaConstant) return aPMs[0]; #if CUDA PixelsMap cRetVal = new PixelsMap(aPMs[0].bCUDA, stBase, Format.ARGB32); cRetVal._bTemp = true; Command cCmd = null; if (aPMs[0].bCUDA) { //cRetVal._nBytesQty = (uint)(stBase.nWidth * stBase.nHeight * 4); //UNDONE нужно определять кол-во байт по ePixelFormat //FIXED cCmd = new Command(Command.ID.Allocate, cRetVal); _aqCommands.Enqueue(cCmd); } else cRetVal.Allocate(); #else PixelsMap cRetVal = new PixelsMap(false, stBase, Format.ARGB32); cRetVal._bTemp = true; cRetVal.Allocate(); #endif cRetVal.Merge(aPMs); return cRetVal; }
override public void Prepare() { try { if (EffectStatus.Idle != ((IEffect)this).eStatus) return; if (bResize && Area.stEmpty != stArea) { stArea = AreaResize(_cFile.stDimensions.Width, _cFile.stDimensions.Height, stArea.nWidth, stArea.nHeight, nPixelAspectRatio); _cFile.stDimensionsResized = new Size(stArea.nWidth, stArea.nHeight); } else if (bResize && Area.stEmpty == stArea) { stArea = AreaResize(_cFile.stDimensions.Width, _cFile.stDimensions.Height, _cFile.stDimensions.Width, _cFile.stDimensions.Height, nPixelAspectRatio); _cFile.stDimensionsResized = new Size(stArea.nWidth, stArea.nHeight); stArea = new Area(0, 0, stArea.nWidth, stArea.nHeight); } else stArea = new Area(stArea.nLeft, stArea.nTop, (ushort)_cFile.stDimensions.Width, (ushort)_cFile.stDimensions.Height); if (null == _cPixelsMap) { _cFile.Open(); if (bKeepAlive) _cFile.Cache(); //#if DEBUG else _cFile.DynamicQueueStart(); //DNF //#endif _cPixelsMap = new PixelsMap(bCUDA, new Area(0, 0, stArea.nWidth, stArea.nHeight), PixelsMap.Format.ARGB32); _cPixelsMap.bKeepAlive = true; if (1 > _cPixelsMap.nLength) (new Logger()).WriteNotice("1 > _cPixelMap.nLength. animation.prepare"); _cPixelsMap.Allocate(); nDuration = nFramesTotal; } else { nFrameCurrentPhysical = 0; //это если препаре делают после стопа. nLoopCurrent = 0; } base.Prepare(); } catch (Exception ex) { (new Logger()).WriteError(ex); (new Logger()).WriteWarning("[bKeepAlive = " + (null == _cPixelsMap ? "null" : "" + _cPixelsMap.bKeepAlive) + "][nDuration = " + nDuration + "]"); throw; } }
static internal void PixelsMapDispose(PixelsMap cPixelsMap) { PixelsMapDispose(cPixelsMap, false); }
public DisCom() { PixelsMap.DisComInit(); _cMREDone = new ManualResetEvent(false); oLock = new object(); }
public void Open(bool bCUDA) { // TODO нужно выцепл¤ть размеры кадра из видео. _bClosed = false; if (null == _cFile) { _cFile = new ffmpeg.net.File.Input(_sFile, nFrameStart); } (new Logger()).WriteDebug("[video_file " + GetHashCode() + "][ffmpeg_file " + _cFile.GetHashCode() + "]"); Area stDeviceArea = Baetylus.Helper.cBoard.stArea; _cFormatVideo = new ffmpeg.net.Format.Video(stArea.nWidth, stArea.nHeight, ffmpeg.net.PixelFormat.AV_PIX_FMT_BGRA); _cPixelsMap = new PixelsMap(bCUDA, stArea, PixelsMap.Format.BGRA32); _cPixelsMap.bBackgroundClear = true; _cPixelsMap.bKeepAlive = true; ffmpeg.net.AVSampleFormat eAVSampleFormat; switch (Preferences.nAudioBitDepth) { case 32: eAVSampleFormat = ffmpeg.net.AVSampleFormat.AV_SAMPLE_FMT_S32; break; case 16: default: eAVSampleFormat = ffmpeg.net.AVSampleFormat.AV_SAMPLE_FMT_S16; break; } int nAudioChannelsQty = Preferences.nAudioChannelsQty; switch (Preferences.nAudioChannelsQty) { case 8: nAudioChannelsQty = 2; break; } _cFormatAudio = new ffmpeg.net.Format.Audio((int)Preferences.nAudioSamplesRate, nAudioChannelsQty, eAVSampleFormat); nFramesTotal = _cFile.nFramesQty; //_cFile.Prepare(nDuration); _cFile.Prepare(_cFormatVideo, _cFormatAudio); }
private PixelsMap TransitionVideoFrame(PixelsMap cFrame,TypeVideo eTransitionType, float nProgress) { if (0 > cFrame.nAlphaConstant) cFrame.nAlphaConstant = 255; // = 250 switch (eTransitionType) { case TypeVideo.cut: if (nProgress > 0.5) cFrame.nAlphaConstant = 0; break; case TypeVideo.dissolve: cFrame.nAlphaConstant = (byte)((float)cFrame.nAlphaConstant - (float)cFrame.nAlphaConstant * nProgress + 0.5); break; //default: } return cFrame; }
override public void Prepare() { base.Prepare(); if (0 == nDuration) nDuration = 1; if (EffectStatus.Idle == _cEffectSource.eStatus || EffectStatus.Stopped == _cEffectSource.eStatus) _cEffectSource.Prepare(); if (EffectStatus.Idle == _cEffectTarget.eStatus || EffectStatus.Stopped == _cEffectTarget.eStatus) _cEffectTarget.Prepare(); if (_cEffectSource is IVideo && _cEffectTarget is IVideo) { stArea = SumOfAreas(((IVideo)_cEffectSource).stArea, ((IVideo)_cEffectTarget).stArea); if (null != _cPixelsMap && stArea != _cPixelsMap.stArea) { _cPixelsMap.Dispose(true); _cPixelsMap = null; } if (null == _cPixelsMap) { _cPixelsMap = new PixelsMap(bCUDA, stArea, PixelsMap.Format.ARGB32); _cPixelsMap.bKeepAlive = true; if (1 > _cPixelsMap.nLength) (new Logger()).WriteNotice("1 > _cPixelsMap.nLength. transition.prepare"); _cPixelsMap.Allocate(); } } }
private void Worker(object cState) { LinkedList<LoggerMessage> aLoggerMessages = new LinkedList<LoggerMessage>(); Logger cLogger; Device.Frame.Audio cFrameAudio = null; Device.Frame.Video cFrameVideo = null; IVideo iVideoEffect = null; PixelsMap cBackground = new PixelsMap(Preferences.bCUDA, _stFullFrameArea, PixelsMap.Format.ARGB32); cBackground.eAlpha = (null == Preferences.cDownStreamKeyer ? DisCom.Alpha.none : DisCom.Alpha.normal); cBackground.Allocate(); cBackground.bKeepAlive = true; PixelsMap cFrame = null; byte[] aFrameBufferAudio = null, aBytesAudio = null; List<PixelsMap> aFrames = new List<PixelsMap>(); Dictionary<IEffect, ContainerAction> ahMoveInfo = null; int nIndx, nLogIndx = 0; bool bIsStarted = false; #region timings Stopwatch cStopwatchEffect = null, cStopwatch = null; double nTotalFrameDuration, nTotalFrameDurationMax = 0; string sMessage; LinkedList<TimingInfo> aTimings = new LinkedList<TimingInfo>(); #endregion List<IVideo> aOpacityEffects = new List<IVideo>(); Dictionary<IAudio,byte[]> ahAudioEffects; Dictionary<IEffect, ulong> ahEffectsDelays = new Dictionary<IEffect, ulong>(); AudioChannelMapping[] aAudioChannelMappings = null; uint nSampleBytesQty = Preferences.nAudioByteDepth; uint nChannelSamplesQty = Preferences.nAudioSamplesPerFrame; uint nChannelBytesQty = Preferences.nAudioSamplesPerFrame * Preferences.nAudioByteDepth; byte nChannelsQty = 0; byte[] aChannels; int nSource, nDestination; bool bVideoFrame = false; bool bWroteNotice = false; bool bWroteWarning = false; IAudio iAudioEffect; _nFrameBufSize = _stFullFrameArea.nWidth * _stFullFrameArea.nHeight * 4; while (null != _aEffects) { try { long nStart0 = DateTime.Now.Ticks; // ------------------------------- cStopwatchEffect = Stopwatch.StartNew(); aFrames.Clear(); aOpacityEffects.Clear(); aFrameBufferAudio = null; iVideoEffect = null; ahAudioEffects = new Dictionary<IAudio, byte[]>(); aAudioChannelMappings = null; sPLLogs = ""; sMessage = ""; aTimings.Clear(); //if (DateTime.Now > dtLastTime.AddMinutes(1)) //EMERGENCY если воскрешать то выкинуть DateTime... отталкиватьс¤ можно от кол-ва прошедших итераций //{ // dtLastTime = DateTime.Now; // string sDebug = "worker: _aEffects.Count = " + _aEffects.Count + ", <br>\t_aEffects ="; // foreach (IEffect cEff in _aEffects) // { // sDebug += "<br>\t\t[" + _aEffects.IndexOf(cEff) + "]\ttype = " + cEff.eType + "\tstatus = " + cEff.eStatus; // } // sDebug += "<br>\t\tqueues: [v:" + _aqBufferVideo.nCount + "][a:" + _aqBufferAudio.nCount + "]"; // aqLoggerMessages.Enqueue(new LoggerMessage(Logger.Level.notice, sDebug); //} if (1 > _aEffects.Count && (bVideoFrame || Preferences.bClearScreenOnEmpty)) //добавл¤ем в очередь признак необходимости очистить экран, иначе девайс будет повтор¤ть предыдущий кадр до потери сознани¤ { if (!bWroteNotice) { (new Logger()).WriteNotice("вставл¤ем черное поле..."); bWroteNotice = true; } _aqBufferFrame.Enqueue(new Device.Frame() { cAudio = null, cVideo = new Device.Frame.Video() { oFrameBytes = new byte[0] } }); bVideoFrame = false; } else { bWroteNotice = false; } if (new TimeSpan(DateTime.Now.Ticks - nStart0).TotalMilliseconds >= Preferences.nFrameDuration) (new Logger()).WriteDebug2("PART-01: [dur = " + new TimeSpan(DateTime.Now.Ticks - nStart0).TotalMilliseconds.ToString() + "ms]"); // --------------------------------- #region audio & video processing for (nIndx = _aEffects.Count - 1; 0 <= nIndx; nIndx--) { nStart0 = DateTime.Now.Ticks; // ------------------------------- try { if (!bIsStarted) bIsStarted = true; if (null == _aEffects[nIndx]) { (new Logger()).WriteError("effect can't be null"); continue; } if (!(_aEffects[nIndx] is IVideo) && !(_aEffects[nIndx] is IAudio)) continue; if (EffectStatus.Running != _aEffects[nIndx].eStatus) continue; if (0 < _aEffects[nIndx].nDelay) { if (!ahEffectsDelays.ContainsKey(_aEffects[nIndx])) ahEffectsDelays.Add(_aEffects[nIndx], _aEffects[nIndx].nDelay); if (0 < ahEffectsDelays[_aEffects[nIndx]]) { ahEffectsDelays[_aEffects[nIndx]]--; continue; } } if (new TimeSpan(DateTime.Now.Ticks - nStart0).TotalMilliseconds >= Preferences.nFrameDuration) (new Logger()).WriteDebug2("PART-02-1: [dur = " + new TimeSpan(DateTime.Now.Ticks - nStart0).TotalMilliseconds.ToString() + "ms]"); // --------------------------------- nStart0 = DateTime.Now.Ticks; // ------------------------------- bVideoFrame = true; iAudioEffect = null; cFrame = null; if (_aEffects[nIndx] is IVideo) { iVideoEffect = (IVideo)_aEffects[nIndx]; if (1 > aOpacityEffects.Count(row => row.stArea >= iVideoEffect.stArea)) { if (iVideoEffect.bOpacity) aOpacityEffects.Add(iVideoEffect); cStopwatch = Stopwatch.StartNew(); cFrame = iVideoEffect.FrameNext(); cStopwatch.Stop(); aTimings.AddLast(new TimingInfo(TimingInfo.Type.VideoEffectFrameNext, cStopwatch.Elapsed.TotalMilliseconds, iVideoEffect)); if (null != cFrame) { aFrames.Insert(0, cFrame); if (null != iVideoEffect.iMask) { aFrames.Insert(0, iVideoEffect.iMask.FrameNext()); aFrames[0].eAlpha = DisCom.Alpha.mask; } } else bVideoFrame = false; } else iVideoEffect.Skip(); } if (new TimeSpan(DateTime.Now.Ticks - nStart0).TotalMilliseconds >= Preferences.nFrameDuration) (new Logger()).WriteDebug2("PART-02-2: [dur = " + new TimeSpan(DateTime.Now.Ticks - nStart0).TotalMilliseconds.ToString() + "ms]"); // --------------------------------- nStart0 = DateTime.Now.Ticks; // ------------------------------- if (_aEffects[nIndx] is IAudio) { iAudioEffect = (IAudio)_aEffects[nIndx]; if (null == (aChannels = iAudioEffect.aChannels) || 0 < aChannels.Length) //см. комменты в IAudio ahAudioEffects.Add(iAudioEffect, iAudioEffect.FrameNext()); else iAudioEffect.Skip(); } if (new TimeSpan(DateTime.Now.Ticks - nStart0).TotalMilliseconds >= Preferences.nFrameDuration) (new Logger()).WriteDebug2("PART-02-3: [dur = " + new TimeSpan(DateTime.Now.Ticks - nStart0).TotalMilliseconds.ToString() + "ms]"); // --------------------------------- nStart0 = DateTime.Now.Ticks; // ------------------------------- if (null != iAudioEffect && ahAudioEffects.ContainsKey(iAudioEffect)) { if (null == ahAudioEffects[iAudioEffect] && aFrames.Contains(cFrame)) { aFrames.Remove(cFrame); PixelsMapDispose(cFrame); if (null != iVideoEffect.iMask) { PixelsMapDispose(aFrames[0]); aFrames.RemoveAt(0); } } if (!bVideoFrame) ahAudioEffects.Remove(iAudioEffect); } if (new TimeSpan(DateTime.Now.Ticks - nStart0).TotalMilliseconds >= Preferences.nFrameDuration) (new Logger()).WriteDebug2("PART-02-4: [dur = " + new TimeSpan(DateTime.Now.Ticks - nStart0).TotalMilliseconds.ToString() + "ms]"); // --------------------------------- nStart0 = DateTime.Now.Ticks; // ------------------------------- } catch (Exception ex) { (new Logger()).WriteError(ex); } if (new TimeSpan(DateTime.Now.Ticks - nStart0).TotalMilliseconds >= Preferences.nFrameDuration) (new Logger()).WriteDebug2("PART-02-5: [dur = " + new TimeSpan(DateTime.Now.Ticks - nStart0).TotalMilliseconds.ToString() + "ms]"); // --------------------------------- } #region audio mappings nStart0 = DateTime.Now.Ticks; // ------------------------------- if (0 < ahAudioEffects.Count) { foreach (IAudio iAudio in ahAudioEffects.Keys) { cStopwatch = Stopwatch.StartNew(); if (null == (aBytesAudio = ahAudioEffects[iAudio])) { cStopwatch.Stop(); aTimings.AddLast(new TimingInfo(TimingInfo.Type.AudioEffectSampleNext, cStopwatch.Elapsed.TotalMilliseconds, iAudio)); continue; } nChannelsQty = (byte)(aBytesAudio.Length / nChannelBytesQty); aChannels = iAudio.aChannels; if (null == aChannels) { aChannels = new byte[nChannelsQty]; for (byte nChannel = 0; nChannelsQty > nChannel; nChannel++) aChannels[nChannel] = nChannel; } if (null == aAudioChannelMappings) { if (Preferences.nAudioChannelsQty == aChannels.Length) { aFrameBufferAudio = aBytesAudio; cStopwatch.Stop(); aTimings.AddLast(new TimingInfo(TimingInfo.Type.AudioEffectSampleNext, cStopwatch.Elapsed.TotalMilliseconds, iAudio)); break; } else aAudioChannelMappings = new AudioChannelMapping[Preferences.nAudioChannelsQty]; } for (byte nChannel = 0; aChannels.Length > nChannel; nChannel++) { if (aChannels[nChannel] < aAudioChannelMappings.Length && null == aAudioChannelMappings[aChannels[nChannel]]) { aAudioChannelMappings[aChannels[nChannel]] = new AudioChannelMapping(); aAudioChannelMappings[aChannels[nChannel]].aBuffer = aBytesAudio; aAudioChannelMappings[aChannels[nChannel]].nBufferChannel = nChannel; aAudioChannelMappings[aChannels[nChannel]].nBufferChannelsQty = (byte)aChannels.Length; } } cStopwatch.Stop(); aTimings.AddLast(new TimingInfo(TimingInfo.Type.AudioEffectSampleNext, cStopwatch.Elapsed.TotalMilliseconds, iAudio)); } if (null != aAudioChannelMappings) { cStopwatch = Stopwatch.StartNew(); aFrameBufferAudio = new byte[Preferences.nAudioChannelsQty * nChannelBytesQty]; for (int nChannel = 0; aAudioChannelMappings.Length > nChannel; nChannel++) { if (null == aAudioChannelMappings[nChannel]) continue; for (int nSampleIndx = 0; nChannelSamplesQty > nSampleIndx; nSampleIndx++) { nSource = (int)(((nSampleIndx * aAudioChannelMappings[nChannel].nBufferChannelsQty) + aAudioChannelMappings[nChannel].nBufferChannel) * nSampleBytesQty); nDestination = (int)(((nSampleIndx * aAudioChannelMappings.Length) + nChannel) * nSampleBytesQty); for (int nByte = 0; nSampleBytesQty > nByte; nByte++) aFrameBufferAudio[nDestination + nByte] = aAudioChannelMappings[nChannel].aBuffer[nSource + nByte]; } } cStopwatch.Stop(); aTimings.AddLast(new TimingInfo(TimingInfo.Type.AudioChannelMappings, cStopwatch.Elapsed.TotalMilliseconds)); } } if (new TimeSpan(DateTime.Now.Ticks - nStart0).TotalMilliseconds >= Preferences.nFrameDuration) (new Logger()).WriteDebug2("PART-03: [dur = " + new TimeSpan(DateTime.Now.Ticks - nStart0).TotalMilliseconds.ToString() + "ms]"); // --------------------------------- #endregion audio mappings #endregion #region container actions cStopwatch = Stopwatch.StartNew(); lock (_aqContainerActions) { // очистка от стопов. пока тут. еще можно ее сделать у тех кто стопит, но это не всегда возможно (( Dictionary<IEffect, ContainerAction> ahToRemove = new Dictionary<IEffect, ContainerAction>(); foreach (IEffect cEffect in _aEffects.Where(row => EffectStatus.Stopped == row.eStatus || EffectStatus.Error == row.eStatus).ToArray()) ahToRemove.Add(cEffect, ContainerAction.Remove); if (0 < ahToRemove.Count) _aqContainerActions.Enqueue(ahToRemove); if (0 < _aqContainerActions.Count) { if (null == _aEffects) throw new NullReferenceException("internal error: array of effects is null"); while (0 < _aqContainerActions.Count) { ahMoveInfo = _aqContainerActions.Dequeue(); //nActionID = _aqActionsIDs.Dequeue(); //OnActionIsFinished(nActionID); if (null == ahMoveInfo) throw new NullReferenceException("move info can't be null"); foreach (IEffect cEffect in ahMoveInfo.Keys) { if (null == cEffect) throw new NullReferenceException("effect can't be null"); switch (ahMoveInfo[cEffect]) { case ContainerAction.Add: if (!_aEffects.Contains(cEffect)) { (new Logger()).WriteDebug3("ContainerAction.Add"); _aEffects.Add(cEffect); cEffect.iContainer = (IContainer)Helper.cBaetylus; } else throw new Exception("this container already has specified effect"); break; case ContainerAction.Remove: if (_aEffects.Contains(cEffect)) _aEffects.Remove(cEffect); if (ahEffectsDelays.ContainsKey(cEffect)) ahEffectsDelays.Remove(cEffect); break; default: throw new NotImplementedException("unknown container action"); } } } _bNeedEffectsReorder = true; } if (_bNeedEffectsReorder) { IEffect cEffect = null; for (ushort nOutterIndx = 0; _aEffects.Count > nOutterIndx; nOutterIndx++) { for (ushort nInnerIndx = (ushort)(nOutterIndx + 1); _aEffects.Count > nInnerIndx; nInnerIndx++) { if (_aEffects[nOutterIndx].nLayer > _aEffects[nInnerIndx].nLayer) { aLoggerMessages.AddLast(new LoggerMessage(Logger.Level.debug3, "effects reordered: " + _aEffects[nOutterIndx].eType.ToString() + "[" + _aEffects[nOutterIndx].GetHashCode() + "] has layer " + _aEffects[nOutterIndx].nLayer + " and " + _aEffects[nInnerIndx].eType.ToString() + "[" + _aEffects[nInnerIndx].GetHashCode() + "] has layer " + _aEffects[nInnerIndx].nLayer)); cEffect = _aEffects[nOutterIndx]; _aEffects[nOutterIndx] = _aEffects[nInnerIndx]; _aEffects[nInnerIndx] = cEffect; } } } _bNeedEffectsReorder = false; } } cStopwatch.Stop(); aTimings.AddLast(new TimingInfo(TimingInfo.Type.ContainerActions, cStopwatch.Elapsed.TotalMilliseconds)); #endregion #region merging nStart0 = DateTime.Now.Ticks; // ------------------------------- if ((null == iVideoEffect && 1 > ahAudioEffects.Count) || (null != iVideoEffect && 1 > aFrames.Count) || (0 < ahAudioEffects.Count && null == aFrameBufferAudio)) //(1 > aFrames.Count && null == aFrameBufferAudio) || { if (bIsStarted && !bWroteWarning) { (new Logger()).WriteWarning("we're sleeping [aFrames.Count = " + aFrames.Count + "] [aFrameBufferAudio is null = " + aFrameBufferAudio.IsNullOrEmpty() + "] [aAudioEffects.Count = " + ahAudioEffects.Count + "]"); bWroteWarning = true; } System.Threading.Thread.Sleep(10); continue; //sMessage = ":got null video:"; } bWroteWarning = false; if (null != iVideoEffect) { cStopwatch = Stopwatch.StartNew(); if ((null == cFrameVideo || null == cFrameVideo.oFrameBytes) && null == (cFrameVideo = _cBoardCurrent.FrameBufferGet())) { (new Logger()).WriteError(new Exception("FATAL ERROR")); break; } cStopwatch.Stop(); aTimings.AddLast(new TimingInfo(TimingInfo.Type.FrameBufferGet, cStopwatch.Elapsed.TotalMilliseconds)); if (1 < aFrames.Count || _stFullFrameArea != aFrames[0].stArea) { cStopwatch = Stopwatch.StartNew(); cBackground.Merge(aFrames); cFrame = cBackground; cStopwatch.Stop(); aTimings.AddLast(new TimingInfo(TimingInfo.Type.Merge, cStopwatch.Elapsed.TotalMilliseconds)); (new Logger()).WriteDebug4("merge: " + cStopwatch.Elapsed.TotalMilliseconds); } else { cFrame = aFrames[0]; PixelsMapDispose(cFrame); } //if (400 == nTMPCount) // ================= SLEEP TEST =========================== // System.Threading.Thread.Sleep(10000); //nTMPCount++; cStopwatch = Stopwatch.StartNew(); if (cFrameVideo.oFrameBytes is IntPtr) cFrame.CopyOut((IntPtr)cFrameVideo.oFrameBytes); else if (cFrameVideo.oFrameBytes is byte[]) cFrame.CopyOut((byte[])cFrameVideo.oFrameBytes); cStopwatch.Stop(); aTimings.AddLast(new TimingInfo(TimingInfo.Type.CopyOut, cStopwatch.Elapsed.TotalMilliseconds)); } else cFrameVideo = new Device.Frame.Video(); cFrameAudio = new Device.Frame.Audio(); cFrameAudio.aFrameBytes = aFrameBufferAudio; if (0 < sMessage.Length) aLoggerMessages.AddLast(new LoggerMessage(Logger.Level.notice, sMessage)); //закомментил, т.к. мне кажетс¤ dispose этих pixelsmap'ов совершенно лишний - они и так диспоз¤тс¤ в merge. //cStopwatch = Stopwatch.StartNew(); foreach (PixelsMap cPM in aFrames) PixelsMapDispose(cPM); //cStopwatch.Stop(); //aTimings.AddLast(new TimingInfo(TimingInfo.Type.PixelsMapsQueuedForDispose, cStopwatch.Elapsed.TotalMilliseconds)); if (PixelsMap.bMemoryStarvation || Preferences.nQueueBaetylusLength == (_aqBufferFrame.nCount + 1)) { // nDoingStart = DateTime.Now.Ticks; // GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); // nDoingDur = DateTime.Now.Ticks - nDoingStart; // nGCCollectCallsQty++; // if (20 < (new TimeSpan(nDoingDur)).TotalMilliseconds) // aqLoggerMessages.Enqueue(new LoggerMessage(Logger.Level.notice, "Baetylus:Worker:GC.Collect():[dur=" + (new TimeSpan(nDoingDur)).TotalMilliseconds.ToString() + "ms]")); //} cStopwatch = Stopwatch.StartNew(); lock (_aqPixelsMapsDisposed) while (0 < _aqPixelsMapsDisposed.Count && (PixelsMap.bMemoryStarvation || Preferences.nQueueBaetylusLength == (_aqBufferFrame.nCount + 1))) _aqPixelsMapsDisposed.Dequeue().Dispose(); cStopwatch.Stop(); aTimings.AddLast(new TimingInfo(TimingInfo.Type.PixelsMapsDispose, cStopwatch.Elapsed.TotalMilliseconds)); } if (new TimeSpan(DateTime.Now.Ticks - nStart0).TotalMilliseconds >= Preferences.nFrameDuration) (new Logger()).WriteDebug2("PART-04: [dur = " + new TimeSpan(DateTime.Now.Ticks - nStart0).TotalMilliseconds.ToString() + "ms]"); // --------------------------------- #endregion #region logging nStart0 = DateTime.Now.Ticks; // ------------------------------- cStopwatchEffect.Stop(); nTotalFrameDuration = cStopwatchEffect.Elapsed.TotalMilliseconds; if (nTotalFrameDuration > nTotalFrameDurationMax) nTotalFrameDurationMax = nTotalFrameDuration; if (nLogIndx == 5000) { aLoggerMessages.AddLast(new LoggerMessage(Logger.Level.notice, "«а последние 5000 кадров максимальное врем¤ выполнени¤ эффектов в одном кадре составило " + nTotalFrameDurationMax.ToString() + " ms")); //[nGCCollectCallsQty=" + nGCCollectCallsQty + "]"); nLogIndx = 0; nTotalFrameDurationMax = 0; //nGCCollectCallsQty = 0; } if (Logger.bDebug && nTotalFrameDuration > Preferences.nFrameDuration) { sMessage = "¬Ќ»ћјЌ»≈! ƒлительность выполнени¤ эффектов дл¤ этого кадра превысила порог: [" + Preferences.nFrameDuration + " ms][dur:" + nTotalFrameDuration.ToString() + " ms]<br>\t"; foreach (TimingInfo cTI in aTimings) { if (null == cTI.o || !(cTI.o is IEffect)) sMessage += "[" + cTI.eType.ToString() + ":" + cTI.nValue + "ms]"; } sMessage += "<br>—ѕ»—ќ Ё‘‘≈ “ќ¬: [count=" + _aEffects.Count + "]<br>"; foreach (IEffect iEffect in _aEffects) { sMessage += "\t[type:" + iEffect.eType + "][status:" + iEffect.eStatus + "][dur:" + iEffect.nDuration + "][layer:" + iEffect.nLayer + "][hash:" + iEffect.GetHashCode() + "]"; foreach (TimingInfo cTI in aTimings) { if (null != cTI.o && iEffect == cTI.o) sMessage += "[" + cTI.eType.ToString() + ":" + cTI.nValue + "ms]"; } sMessage += "<br>"; } if(0 < sPLLogs.Length) sMessage += "\t\t" + sPLLogs; aLoggerMessages.AddLast(new LoggerMessage(Logger.Level.notice, sMessage)); } nLogIndx++; if (0 < aLoggerMessages.Count) { cLogger = new Logger(); foreach (LoggerMessage cLM in aLoggerMessages) cLogger.Write(cLM.dt, cLM.eLevel, cLM.sMessage); aLoggerMessages.Clear(); } if (new TimeSpan(DateTime.Now.Ticks - nStart0).TotalMilliseconds >= Preferences.nFrameDuration) (new Logger()).WriteDebug2("PART-05: [dur = " + new TimeSpan(DateTime.Now.Ticks - nStart0).TotalMilliseconds.ToString() + "ms]"); // --------------------------------- #endregion //if (200 == nCount++) // System.Threading.Thread.Sleep(8000); Device.Frame cFrameResult = new Device.Frame() { cAudio = cFrameAudio, cVideo = cFrameVideo }; // bug if (null == _cBugCatcher) _cBugCatcher = new Device.BugCatcher(((Device)_cBoardCurrent)._cVideoFrameEmpty); _cBugCatcher.Enqueue(cFrameResult, "baetylus:_aqBufferFrame:" + _aqBufferFrame.nCount); _aqBufferFrame.Enqueue(cFrameResult); if (cFrameResult.cAudio == null || cFrameResult.cAudio.aFrameBytes == null) (new Logger()).WriteNotice("Sent null audio frame! [audio_frame_is_null = " + (cFrameResult.cAudio == null ? "true]" : "false][bytes_is_null = " + (cFrameResult.cAudio.aFrameBytes == null ? "true" : "false") + "]")); if (_bDoWritingFrames) { if (null != cFrameVideo) { byte[] aBytes = new byte[_nFrameBufSize]; System.Runtime.InteropServices.Marshal.Copy(cFrameVideo.pFrameBytes, aBytes, 0, (int)_nFrameBufSize); lock (_aqWritingFrames) _aqWritingFrames.Enqueue(aBytes); } } cFrameAudio = null; cFrameVideo = null; } catch (Exception ex) { (new Logger()).WriteError(ex); } } }
static internal void PixelsMapDispose(PixelsMap cPixelsMap, bool bForce) { if (bForce) cPixelsMap.bKeepAlive = false; lock (_aqPixelsMapsDisposed) if (1 > _aqPixelsMapsDisposed.Count(row => row == cPixelsMap)) _aqPixelsMapsDisposed.Enqueue(cPixelsMap); }
override public void Stop() { try { if (null != _cCUDAPixelsMap) { _cCUDAPixelsMap.Dispose(true); _cCUDAPixelsMap = null; } } catch (Exception ex) { (new Logger()).WriteError(ex); } base.Stop(); }
//System.Diagnostics.Stopwatch cStopwatch = null; //System.Diagnostics.Stopwatch cSW_while = null; //System.Diagnostics.Stopwatch cSW_lock = null; override public PixelsMap FrameNext() { _nSpeed = _nSpeedNew; PixelsMap cRetVal = null; base.FrameNext(); bool bHaveSpaceForNextEffect = true; int nEffectIndex = 0; PixelsMap cPM = null; IVideo iVideo; List<PixelsMap> aPMs = new List<PixelsMap>(); // cSW_lock = System.Diagnostics.Stopwatch.StartNew(); lock (_aEffects) { //cSW_while = System.Diagnostics.Stopwatch.StartNew(); while (bHaveSpaceForNextEffect && nEffectIndex < _aEffects.Count) { //cStopwatch = System.Diagnostics.Stopwatch.StartNew(); if (_aEffects[nEffectIndex].nStartDelay > 0) { _aEffects[nEffectIndex].nStartDelay--; bHaveSpaceForNextEffect = false; nEffectIndex++; continue; } if (!_aEffects[nEffectIndex].bMoved) { if (float.MaxValue > _aEffects[nEffectIndex].nSpeed && float.MinValue < _aEffects[nEffectIndex].nSpeed) _aSpeeds.Add(_aEffects[nEffectIndex].nSpeed); if (null != EffectIsOnScreen) EffectIsOnScreen(this, (Effect)_aEffects[nEffectIndex].iVideo); _aEffects[nEffectIndex].bMoved = true; } bHaveSpaceForNextEffect = MoveEffect(nEffectIndex); if (IsEffectInRollArea(nEffectIndex) && EffectStatus.Stopped != _aEffects[nEffectIndex].cEffect.eStatus) { if (EffectStatus.Preparing == _aEffects[nEffectIndex].iEffect.eStatus) _aEffects[nEffectIndex].iEffect.Start(null); if (EffectStatus.Running != _aEffects[nEffectIndex].iEffect.eStatus) throw new Exception("Ёффект не может быть не Prepare в ROLL.FrameNext()"); cPM = (iVideo = (IVideo)_aEffects[nEffectIndex].iVideo).FrameNext(); if (null == cPM) continue; short nLeftNewPos = (short)Math.Floor(_aEffects[nEffectIndex].stPosition.X); short nTopNewPos = (short)Math.Floor(_aEffects[nEffectIndex].stPosition.Y); cPM.Move((short)(nLeftNewPos), (short)(nTopNewPos)); if (Direction.Up == eDirection) cPM.Shift(true, - (_aEffects[nEffectIndex].stPosition.Y - nTopNewPos), new Dock.Offset(0, 0), 0); //true >0 <=1 else if (Direction.Left == eDirection) { Dock.Offset cOffset = ((IVideo)_aEffects[nEffectIndex].cEffect).OffsetAbsoluteGet(); cPM.Shift(false, -(_aEffects[nEffectIndex].stPosition.X - nLeftNewPos), cOffset, _aEffects[nEffectIndex].stPosition.X - _aEffects[nEffectIndex].stPositionPrevious.X); // если <0 ,то значит влево шло - это дл¤ куды инфа - если идеально совпадЄт, то =0 и отрабатывать не нужно будет } if (null != iVideo.iMask) { aPMs.Add(iVideo.iMask.FrameNext()); aPMs[aPMs.Count - 1].eAlpha = DisCom.Alpha.mask; } aPMs.Add(cPM); } else { if (float.MaxValue > _aEffects[nEffectIndex].nSpeed && float.MinValue < _aEffects[nEffectIndex].nSpeed) _aSpeeds.RemoveAt(0); if (null != EffectIsOffScreen) EffectIsOffScreen(this, _aEffects[nEffectIndex].cEffect); _aEffects.RemoveAt(nEffectIndex--); GC.Collect(GC.MaxGeneration, GCCollectionMode.Optimized); } //cStopwatch.Stop(); //(new Logger()).WriteNotice(" ======TIMING: roll: while: nEffectIndex=" + nEffectIndex + " type=" + _aEffects[nEffectIndex].iEffect.eType + " ms=" + cStopwatch.Elapsed.TotalMilliseconds); nEffectIndex++; } //cSW_while.Stop(); //(new Logger()).WriteNotice(" ======TIMING: roll: complited while: ms=" + cSW_while.Elapsed.TotalMilliseconds); } //cSW_lock.Stop(); //(new Logger()).WriteNotice(" ======TIMING: roll: lock: ms=" + cSW_lock.Elapsed.TotalMilliseconds); if (0 < aPMs.Count) { _cPixelsMap.eAlpha = (bOpacity ? DisCom.Alpha.none : DisCom.Alpha.normal); _cPixelsMap.Merge(aPMs); cRetVal = _cPixelsMap; Baetylus.PixelsMapDispose(aPMs.ToArray()); //if (true) //{ // Bitmap bmp; // BitmapData bd; // bmp = new Bitmap((int)stArea.nWidth, stArea.nHeight); // bd = bmp.LockBits(new Rectangle(0, 0, stArea.nWidth, stArea.nHeight), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); // cRetVal.CopyOut(bd.Scan0); // bmp.UnlockBits(bd); // bmp.Save(@"c:\___TMP\" + (nDebug++).ToString("0000") + ".png"); // bmp.Dispose(); //} if (bCUDA && !cRetVal.bCUDA) { if (null != _cCUDAPixelsMap && stArea != _cCUDAPixelsMap.stArea) { _cCUDAPixelsMap.Dispose(true); _cCUDAPixelsMap = null; } if (null == _cCUDAPixelsMap) { _cCUDAPixelsMap = new PixelsMap(true, stArea, PixelsMap.Format.ARGB32); _cCUDAPixelsMap.bKeepAlive = true; } _cCUDAPixelsMap.CopyIn(cRetVal.CopyOut()); cRetVal = _cCUDAPixelsMap; } } if (0 == _aEffects.Count && bStopOnEmpty && EffectStatus.Stopped != this.eStatus) Stop(); if (null != cRetVal) cRetVal.nAlphaConstant = nCurrentOpacity; return cRetVal; }
public void VideoFrameNext(PixelsMap cPixelsMap) { try { if (null == _aFiles) throw new Exception("_aFiles is null in Animation.cs"); //UNDONE if (nFrameCurrent < (ulong)_aFiles.Length) { if (null != cPixelsMap) { if (null == _aCache) { BitmapDataSet(_aFiles[nFrameCurrent]); cPixelsMap.CopyIn(_cBitmapData.Scan0, _cBitmapData.Stride * _cBitmapData.Height); _cBitmap.UnlockBits(_cBitmapData); _cBitmap.Dispose(); // GC.Collect(); } else { if (0 <= nQueueLength) { if (0 == nQueueLength && 0 < (ulong)_aFiles.Length - nFrameCurrent) (new Logger()).WriteWarning("animation queue length is empty!![" + nQueueLength + "][" + _sFolder + "]"); else if (3 > nQueueLength && 3 <= (ulong)_aFiles.Length - nFrameCurrent) (new Logger()).WriteNotice("animation queue length is less than 3! [" + nQueueLength + "][" + _sFolder + "]"); else if ((Preferences.nQueueAnimationLength / 2 > nQueueLength) && (Preferences.nQueueAnimationLength / 2) <= _aFiles.Length - (int)nFrameCurrent) (new Logger()).WriteDebug3("animation queue length [" + nQueueLength + "][" + _sFolder + "]"); } while (nQueueLength == 0) System.Threading.Thread.Sleep(10); lock (_aCache) { cPixelsMap.CopyIn(_aCache[(int)nFrameCurrent]); if (-1 < _nQueueLength) _nQueueLength--; } } } nFrameCurrent++; } else bEOF = true; } catch (Exception ex) { (new Logger()).WriteError("[" + _aFiles[nFrameCurrent] + "][" + _sFolder + "]", ex); bEOF = true; } }
override public void Prepare() { lock (_aEffects) try { if (EffectStatus.Idle != ((IEffect)this).eStatus) return; foreach (Effect cEffect in _aEffects) if (EffectStatus.Idle == cEffect.eStatus) cEffect.Prepare(); _cPixelsMap = new PixelsMap(this.bCUDA, this.stArea, PixelsMap.Format.ARGB32); _cPixelsMap.bKeepAlive = true; if (1 > _cPixelsMap.nLength) (new Logger()).WriteNotice("1 > _cPixelMap.nLength. composite.prepare"); _cPixelsMap.Allocate(); base.Prepare(); } catch (Exception ex) { (new Logger()).WriteError(ex); } }
static internal void PixelsMapDispose(PixelsMap[] aPixelsMaps) { foreach (PixelsMap cPixelsMap in aPixelsMaps) PixelsMapDispose(cPixelsMap, false); }