override public PixelsMap FrameNext() // если население композита тексты и они не менялись, то можно ничего не менять вообще! (оптимизация чата и подобных) // сделал { _cPixelsMap = _cPMDuo.Switch(nPixelsMapSyncIndex); if (null == _cPixelsMap) { return(null); } _bChanged = false; base.FrameNext(); PixelsMap cPM = null; List <PixelsMap> aPMs = new List <PixelsMap>(); Dictionary <Effect, PixelsMap> ahEffects_PMs = new Dictionary <Effect, PixelsMap>(); IVideo iVideo = null; foreach (Effect cEffect in _aEffects) { if (null == cEffect || !(cEffect is IVideo) || (EffectStatus.Running != cEffect.eStatus)) { continue; } iVideo = (IVideo)cEffect; iVideo.nPixelsMapSyncIndex = nPixelsMapSyncIndex; cPM = iVideo.FrameNext(); if (null == cPM) { continue; } aPMs.Add(cPM); if (!_bChanged && (!(iVideo is Text) || ((Text)iVideo).dtChanged > _dtLastChange)) { _bChanged = true; } } if (_bChanged && 0 < aPMs.Count) // когда == 0 - это пустышка и не надо для нее делать pixelsmap // || _bMergedChanges { //_bMergedChanges = _bChanged; _dtLastChange = DateTime.Now; _cPixelsMap.Merge(aPMs); Baetylus.PixelsMapDispose(aPMs.ToArray()); } _cPixelsMap.nAlphaConstant = nCurrentOpacity; if (null != cMask) { _cPixelsMap.eAlpha = cMask.eMaskType; } _cPixelsMap.Move(stArea.nLeft, stArea.nTop); if (nFrameCurrent >= nDuration) { base.Stop(); } return(_cPixelsMap); }
public PixelsMap FrameNextVideo() { cTimings.TotalRenew(); try { _cPixelsMap = _cPMDuo.cCurrent; _cPixelsMap.Move(stPixelArea.nLeft, stPixelArea.nTop); // были проблемы в транзишене. т.к. PM многоразовый, то кто-то его мог мувнуть (плейлист) и на место не класть. ffmpeg.net.Frame cFrame = _cFile.FrameNextVideoGet(); //_cFormatVideo, cTimings.Restart("ffmpeg_framenext"); if (null != cFrame) { int nOffset = 0; int nOffsetBot = 0; int nLine = _cFormatVideo.nWidth * _cFormatVideo.nBitsPerPixel / 8; int nBotDiff = _cFormatVideo.nHeight - (stContainerArea.nHeight - stArea.nTop); if (720 == _cFormatVideo.nWidth && 576 == _cFormatVideo.nHeight) // инверсия полей нужна только на sd { nOffset = nLine; } if (stArea.nTop < 0) { nOffset += (-stArea.nTop) * nLine; } if (nBotDiff > 0) { nOffsetBot = nBotDiff * nLine; } _cPixelsMap.CopyIn(cFrame.pBytes + nOffset, cFrame.nLength - nOffset - nOffsetBot); // сдвигаем фрейм на строчку вверх (это если не HD, а PAL) cTimings.Restart("copy_in"); cFrame.Dispose(); cTimings.Restart("dispose"); //GC.Collect(1, GCCollectionMode.Force_d); // худший вариант был //GC.Collect(GC.MaxGeneration, GCCollectionMode.Optimized); // этот лучший был ------- уехало в байтилус ------- //GC.Collect(GC.MaxGeneration, GCCollectionMode.Force_d); // гипотеза (ТАК и оказалось!!!!) - т.к. сборка спонтанная высвобождает сразу много мусора и и лочит этим copyin и вышибает пробки у БлэкМэджика //cTimings.Restart("GCcollect. " + System.Runtime.GCSettings.LatencyMode + "."); nFrameCurrentVideo++; } else if (bEOF) { return(null); } cTimings.Stop("framenext", "eof_getting", 20); ffmpeg.net.File.Input.nBTLCurrentBuffer = Baetylus.nCurrentDeviceBufferCount; return(_cPixelsMap); } catch (Exception ex) { (new Logger()).WriteError(ex); _cFile.Close(); } return(null); }
override public PixelsMap FrameNext() { base.FrameNext(); base.Action(); try { _cPixelsMap = _cPMDuo.Switch(nPixelsMapSyncIndex); _cTimings.TotalRenew(); if (null == _cPixelsMap) { _cPixelsMap = new PixelsMap(stMergingMethod, new Area(0, 0, stArea.nWidth, stArea.nHeight), PixelsMap.Format.ARGB32); _cPixelsMap.bKeepAlive = false; // на одни раз _cPixelsMap.nIndexTriple = nPixelsMapSyncIndex; _cPixelsMap.Allocate(); _cTimings.Restart("newpm"); } _cPixelsMap.Move(0, 0); _cTimings.Restart("move1"); _cFile.VideoFrameNext(_cPixelsMap); _cTimings.Restart("frnext"); if (_cFile.bEOF) { base.Stop(); return(null); } _cPixelsMap.Move(stArea.nLeft, stArea.nTop); _cTimings.Restart("move2"); Advance(); _cTimings.Stop("frnext", "advance", 30); } catch (Exception ex) { (new Logger()).WriteError(ex); } if (nFrameCurrent >= nDuration) { base.Stop(); } if (null != _cPixelsMap) { _cPixelsMap.nAlphaConstant = nCurrentOpacity; if (null != cMask) { _cPixelsMap.eAlpha = cMask.eMaskType; } } return(_cPixelsMap); }
override public PixelsMap FrameNext() { lock (_cSyncRoot) { base.FrameNext(); if (nFrameCurrent >= nDuration) { base.Stop(); } _cPixelsMap = _cPMDuo.Switch(nPixelsMapSyncIndex); if (null == _cPixelsMap) { _cPixelsMap = new PixelsMap(stMergingMethod, stArea, PixelsMap.Format.ARGB32); _cPixelsMap.bKeepAlive = false; // на одни раз _cPixelsMap.nIndexTriple = nPixelsMapSyncIndex; _cPixelsMap.Allocate(); } if (null != _cPixelsMap) { if (!_aPMGotDrawCurrent.Contains(_cPixelsMap.nID)) { _dtChanged = DateTime.Now; _aPMGotDrawCurrent.Add(_cPixelsMap.nID); _cPixelsMap.CopyIn(_aDrawCurrent.aBytes); } if (_cPixelsMap.nAlphaConstant != nCurrentOpacity) { _dtChanged = DateTime.Now; _cPixelsMap.nAlphaConstant = nCurrentOpacity; } if (null != cMask && _cPixelsMap.eAlpha != cMask.eMaskType) { _dtChanged = DateTime.Now; _cPixelsMap.eAlpha = cMask.eMaskType; } if (_cPixelsMap.stArea.nLeft != stArea.nLeft || _cPixelsMap.stArea.nTop != stArea.nTop) { _dtChanged = DateTime.Now; _cPixelsMap.Move(stArea.nLeft, stArea.nTop); } } return(_cPixelsMap); } }
override public void Prepare() { lock (_aEffects) try { if (EffectStatus.Idle != ((IEffect)this).eStatus) { return; } if (stMergingMethod.eDeviceType == MergingDevice.DisCom) { PixelsMap.DisComInit(); } foreach (Effect cEffect in _aEffects) { if (EffectStatus.Idle == cEffect.eStatus) { ((IVideo)cEffect).stMergingMethod = this.stMergingMethod; cEffect.Prepare(); } } if (null != _cPMDuo && stArea != _cPMDuo.cFirst.stArea) { Baetylus.PixelsMapDispose(_cPMDuo, true); _cPMDuo = null; } if (null == _cPMDuo) { _cPMDuo = new PixelsMap.Triple(this.stMergingMethod, this.stArea, PixelsMap.Format.ARGB32, true, Baetylus.PixelsMapDispose); if (1 > _cPMDuo.cFirst.nLength) { (new Logger()).WriteNotice("1 > __cPixelsMap.nLength. composite.prepare"); } _cPMDuo.Allocate(); } _cPMDuo.RenewFirstTime(); nPixelsMapSyncIndex = byte.MaxValue; base.Prepare(); } catch (Exception ex) { (new Logger()).WriteError(ex); } }
override public void Prepare() { base.Prepare(); if (0 == nDuration) { nDuration = 1; } if (stMergingMethod.eDeviceType == MergingDevice.DisCom) { PixelsMap.DisComInit(); } 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 != _cPMDuo && stArea != _cPMDuo.cFirst.stArea) { Baetylus.PixelsMapDispose(_cPMDuo, true); _cPMDuo = null; } if (null == _cPMDuo) { //_cPixelsMap = new PixelsMap(stMergingMethod, stArea, PixelsMap.Format.ARGB32); _cPMDuo = new PixelsMap.Triple(new MergingMethod(stMergingMethod.eDeviceType, 0), stArea, PixelsMap.Format.ARGB32, true, Baetylus.PixelsMapDispose); //MergingDevice.DisCom if (1 > _cPMDuo.cFirst.nLength) { (new Logger()).WriteNotice("1 > _cPixelsMap.nLength. transition.prepare"); } _cPMDuo.Allocate(); } _cPMDuo.RenewFirstTime(); nPixelsMapSyncIndex = byte.MaxValue; } }
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 PixelsMap FrameNextVideo() { cTimings.TotalRenew(); if (null == _cFile.cPMDuo.Switch(nPixelsMapSyncIndex)) { return(null); } PixelsMap cRetVal = _cFile.FrameNextVideo(); cTimings.Restart("file_nextframe"); ulong nDuration = this.nDuration; nDuration = nDuration < _cFile.nFramesTotal ? nDuration : _cFile.nFramesTotal; if ((null == cRetVal && _cFile.bEOF) || (nFrameCurrentVideo >= nDuration && (nFrameCurrentAudio >= nDuration || nFrameCurrentAudio == 0))) { if (_cFile.bEOF && (nFrameCurrentVideo != nDuration || nFrameCurrentAudio != nDuration)) { (new Logger()).WriteWarning("video has been stopped abnormal [hc:" + nID + "] [duration: " + nDuration + "] [current_video: " + _cFile.nFrameCurrentVideo + "] [current_audio: " + _cFile.nFrameCurrentAudio + "][cRetVal=" + (cRetVal == null ? "null" : "NOT null") + "][EOF=" + _cFile.bEOF + "]"); } (new Logger()).WriteDebug3("FrameNextVideo(): video stopped [hc:" + nID + "]" + "[frames total:" + _cFile.nFramesTotal + "]" + "[nFrameCurrentVideo:" + _cFile.nFrameCurrentVideo + "]" + "[nFrameCurrentAudio:" + _cFile.nFrameCurrentAudio + "][cRetVal=" + (cRetVal == null ? "null" : "NOT null") + "][eof: " + _cFile.bEOF + "]"); Stop(); } (new Logger()).WriteDebug4("video returns a frame [hc:" + nID + "]"); cTimings.Stop("video:framenext > 40ms", "eof_getting and dur_getting", 40); if (null != cRetVal) { cRetVal.nAlphaConstant = nCurrentOpacity; if (null != cMask) { cRetVal.eAlpha = cMask.eMaskType; } } 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) { _cTimings.TotalRenew(); if (null == _cCache) { BitmapDataSet(_aFiles[nFrameCurrent]); cPixelsMap.CopyIn(_cBitmapData.Scan0, _cBitmapData.Stride * _cBitmapData.Height); _cBitmap.UnlockBits(_cBitmapData); _cBitmap.Dispose(); _cTimings.Restart("copyin1"); } else { if (0 <= nQueueLength) { if (0 == nQueueLength && 0 < (ulong)_aFiles.Length - nFrameCurrent) { (new Logger()).WriteWarning("animation queue length is empty - will just return!![" + nQueueLength + "][total=" + nFramesTotal + "][cur=" + nFrameCurrent + "][" + _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 + "][total=" + nFramesTotal + "][cur=" + nFrameCurrent + "][" + _sFolder + "]"); } } if (0 == nQueueLength || (int)nFrameCurrent >= _cCache.Count) { bEOF = true; return; } lock (_oCacheLock) { cPixelsMap.CopyIn(_cCache[(int)nFrameCurrent].aBytes, false, true); if (-1 < _nQueueLength) { _nQueueLength--; } } _cTimings.Stop("frnext", "lock and copyin2", 40); } } nFrameCurrent++; } else { bEOF = true; } } catch (Exception ex) { (new Logger()).WriteError("[" + _aFiles[nFrameCurrent] + "][" + _sFolder + "]", ex); bEOF = true; } }
override public PixelsMap FrameNextVideo() { if (!(_cEffectSource is IVideo) && !(_cEffectTarget is IVideo)) { return(null); } if (nDuration == _nFramesCounterVideo) { return(null); } _nFramesCounterVideo++; List <PixelsMap> aFrames = new List <PixelsMap>(); PixelsMap cFrame; Dictionary <PixelsMap, byte> nAlphaConstantOld = new Dictionary <PixelsMap, byte>(); float nProgress = (float)_nFramesCounterVideo / (float)nDuration; bool bIfLayersHave255Alpha = true; IVideo iVideo; if (_cEffectSource is IVideo) { iVideo = (IVideo)_cEffectSource; iVideo.nPixelsMapSyncIndex = nPixelsMapSyncIndex; if (null != (cFrame = iVideo.FrameNext())) { if (cFrame.nAlphaConstant < 255) { bIfLayersHave255Alpha = false; } nAlphaConstantOld.Add(cFrame, cFrame.nAlphaConstant); //if(null != iVideo.iMask) // { // aFrames.Add(iVideo.iMask.FrameNext()); // aFrames[aFrames.Count - 1].eAlpha = DisCom.Alpha.mask; // } aFrames.Add(TransitionVideoFrame(cFrame, eTransitionTypeVideo, nProgress)); } } if (_cEffectTarget is IVideo) { if (0.5 == nProgress) // избегаем коллизии ровной середины { nProgress = 0.501F; } iVideo = (IVideo)_cEffectTarget; iVideo.nPixelsMapSyncIndex = nPixelsMapSyncIndex; if (null != (cFrame = iVideo.FrameNext())) { if (cFrame.nAlphaConstant < 255) { bIfLayersHave255Alpha = false; } nAlphaConstantOld.Add(cFrame, cFrame.nAlphaConstant); //if (null != iVideo.iMask) //{ // aFrames.Add(iVideo.iMask.FrameNext()); // aFrames[aFrames.Count - 1].eAlpha = DisCom.Alpha.mask; //} aFrames.Add(TransitionVideoFrame(cFrame, eTransitionTypeVideo, 1 - nProgress)); } } if (2 == aFrames.Count && aFrames[0].stArea == aFrames[1].stArea && bIfLayersHave255Alpha) { aFrames[0].nAlphaConstant = byte.MaxValue; } //PixelsMap cRetVal = PixelsMap.Merge(stArea, aFrames); //EMERGENCY:l тут мы, между прочим, для каждого кадра делаем пикселсмэп, а это очень неэффективно... // И не надо отправлять в мердж, если эффект только один (уход в черное) - просто меняем ему конст альфу PixelsMap cRetVal = _cPMDuo.Switch(nPixelsMapSyncIndex); if (cRetVal == null) { return(null); } cRetVal.Merge(aFrames); if (null != cRetVal && null != cMask) { cRetVal.eAlpha = cMask.eMaskType; } foreach (PixelsMap cPM in aFrames) { if (nAlphaConstantOld.ContainsKey(cPM)) { cPM.nAlphaConstant = nAlphaConstantOld[cPM]; } Baetylus.PixelsMapDispose(cPM); } if (EffectStatus.Running != _cEffectTarget.eStatus || (nDuration == _nFramesCounterVideo && (_nFramesCounterVideo == _nFramesCounterAudio || (!(_cEffectSource is IAudio) && !(_cEffectTarget is IAudio)) ) ) ) { Stop(); } return(cRetVal); }