示例#1
0
        public Preferences(string sData)
        {
            XmlDocument cXmlDocument = new XmlDocument();
            cXmlDocument.LoadXml(sData);
            XmlNode cXmlNode = cXmlDocument.NodeGet("data");

            XmlNode cNodeChild = cXmlNode.NodeGet("playlist");
            _bCuda = cNodeChild.AttributeGet<bool>("cuda");
            _nLayer = cNodeChild.AttributeGet<ushort>("layer");
            cNodeChild = cNodeChild.NodeGet("area");
            _stArea = new Area(
                    cNodeChild.AttributeGet<short>("left"),
                    cNodeChild.AttributeGet<short>("top"),
                    cNodeChild.AttributeGet<ushort>("width"),
                    cNodeChild.AttributeGet<ushort>("height")
                );
        }
示例#2
0
		internal EffectVideo(EffectType eType)
			: base(eType)
		{
			try
			{
				bCUDA = Preferences.bCUDA;
				nFrameCurrent = 0;
				stArea = new Area(0, 0, 0, 0);
				nMaxOpacity = 255;
				nInDissolve = 0;
				nOutDissolve = 0;
			}
			catch
			{
				Fail();
				throw;
			}
		}
示例#3
0
        public Preferences(string sData)
        {
            XmlDocument cXmlDocument = new XmlDocument();
            cXmlDocument.LoadXml(sData);
            XmlNode cXmlNode = cXmlDocument.NodeGet("data");
            sRequest = cXmlNode.AttributeValueGet("request");
            nTemplate = cXmlNode.AttributeGet<byte>("template");
            sValue = cXmlNode.AttributeValueGet("value", false);
            _nCheckInterval = cXmlNode.AttributeGet<int>("interval");

            XmlNode cNodeChild = cXmlNode.NodeGet("roll");
            _eDirection = cNodeChild.AttributeGet<btl.Roll.Direction>("direction");
            _nSpeed = cNodeChild.AttributeGet<float>("speed");
            _bRollCuda = cNodeChild.AttributeGet<bool>("cuda");
            _nLayer = cNodeChild.AttributeGet<ushort>("layer");
            _nQueueLength = cNodeChild.AttributeGet<byte>("queue");
			if (int.MaxValue == (_nPause = cNodeChild.AttributeGet<int>("pause", false)))
				_nPause = 0;
            cNodeChild = cNodeChild.NodeGet("area");
            _stArea = new Area(
                    cNodeChild.AttributeGet<short>("left"),
                    cNodeChild.AttributeGet<short>("top"),
                    cNodeChild.AttributeGet<ushort>("width"),
                    cNodeChild.AttributeGet<ushort>("height")
                );
            _aItems = cXmlNode.NodesGet("item").Select(o => Item.Parse(o)).ToList();
        }
示例#4
0
        public Baetylus()
        {
            (new Logger()).WriteDebug3("in");
            lock (_cSyncRoot)
            {
                if (1 > _nReferencesQty)
                {
                    (new Logger()).WriteDebug4("baetylus:constructor:init");
                    _aqContainerActions = new Queue<Dictionary<IEffect, ContainerAction>>();

                    _aEffects = new List<IEffect>();
                    _stFullFrameArea = cBoard.stArea;
					_aqBufferFrame = new ThreadBufferQueue<Device.Frame>(Preferences.nQueueBaetylusLength, true, false);
					_aqPixelsMapsDisposed = new Queue<PixelsMap>();
                    _bNeedEffectsReorder = false;
					_cThreadWorker = new System.Threading.Thread(Worker);
					_cThreadWorker.IsBackground = true;
					_cThreadWorker.Priority = System.Threading.ThreadPriority.AboveNormal;
					_cThreadWorker.Start();
					_bDoWritingFrames = false;
					_aqWritingFrames = new Queue<byte[]>();
					_cThreadWritingFramesWorker = new System.Threading.Thread(WritingFramesWorker);
					_cThreadWritingFramesWorker.IsBackground = true;
					_cThreadWritingFramesWorker.Priority = System.Threading.ThreadPriority.Normal;
					_cThreadWritingFramesWorker.Start();

					cBoard.NextFrame += new NextFrameCallback(OnNextFrame);
                    cBoard.TurnOn();
                }
                _nReferencesQty++;
            }
            (new Logger()).WriteDebug4("return [refqty:" + _nReferencesQty + "]");
        }
示例#5
0
		private DisCom.LayerInfo Intersect(Area stBase)  //v: Даёт размерность, ширину, высоту кропа и относительные координаты его лев верх угла от бэка и от фора и ширину кропа.
		{                                         //в целях оптимизации убраны все проверки, т.к. они уже были в FramesMerge...
			DisCom.LayerInfo cRetVal = new DisCom.LayerInfo();
			cRetVal.nShiftPosition = _nShiftPosition;
			cRetVal.bShiftVertical = _bShiftVertical;
			Area stCrop = _stArea.CropOnBase(stBase);
			cRetVal.nWidth = stArea.nWidth;
			cRetVal.nCropWidth = stCrop.nWidth;
			cRetVal.nCropHeight = stCrop.nHeight;
			cRetVal.nCropLeft = stCrop.nLeft - stBase.nLeft; //отступ кропа слева COL
			int nBGIndxStart = (stCrop.nTop - stBase.nTop) * stBase.nWidth + cRetVal.nCropLeft; //BGIndxStart=COT*BW+COL;
			//формула вычисления FI=BI+M*(FW-BW)-(FOT*FW+FOL); M=(int)(BI/BW);
			cRetVal.nWidthDiff = _stArea.nWidth - stBase.nWidth; //5/ константа 1 - (FW-BW) 
			cRetVal.nForegroundStart = (_stArea.nTop - stBase.nTop) * _stArea.nWidth + _stArea.nLeft - stBase.nLeft; //6/ константа 2 - (FOT*FW+FOL)
			cRetVal.nBackgroundStart = nBGIndxStart; //7/  начальный индекс по BG
			cRetVal.nBackgroundStop = nBGIndxStart + (stCrop.nHeight - 1) * stBase.nWidth + stCrop.nWidth - 1;//8/ конечный индекс по BG
			cRetVal.nCropRight = cRetVal.nCropLeft + stCrop.nWidth - 1; //10/ константа COL+CW-1
			cRetVal.nAlphaConstant = nAlphaConstant; //11/ константная альфа
            cRetVal.nAlphaType = (byte)eAlpha;
			cRetVal.nShiftTotal = _nShiftTotal;
			cRetVal.nTop = stArea.nTop;
			cRetVal.nLeft = stArea.nLeft;

			if (null != _cShiftOffset)
			{
				cRetVal.nOffsetLeft = _cShiftOffset.nLeft;
				cRetVal.nOffsetTop = _cShiftOffset.nTop & 1;


				if (stBase.nTop > _stArea.nTop && ((stBase.nTop - _stArea.nTop) & 1) == 1)
					cRetVal.nOffsetTop = ~cRetVal.nOffsetTop;
			}			



			return cRetVal;
		}
示例#6
0
		public Area CropOnBase(Area stBase)  //Valikoo. Возвращает обрезанную область если она вышла за рамки образца stBase
		{
			Area stRetVal = new Area();
			stRetVal.nLeft = stBase.nLeft > nLeft ? stBase.nLeft : nLeft;
			stRetVal.nTop = stBase.nTop > nTop ? stBase.nTop : nTop;
			stRetVal.nRight = stBase.nRight > nRight ? nRight : stBase.nRight;
			stRetVal.nBottom = stBase.nBottom > nBottom ? nBottom : stBase.nBottom;
			if (0 == stRetVal.nWidth || 0 == stRetVal.nHeight)
			{
				stRetVal.nWidth = 0;
				stRetVal.nHeight = 0;
			}
			return stRetVal;
		}
示例#7
0
        public Composite(ushort nDimensionTargetMax, Type enType) 
            :this()
        {
            switch (enType)
            {
                case Type.Vertical:
					_nWidth = nDimensionTargetMax;
                    _aLines = new List<Line>();
                    enType = Type.Vertical;
                    break;
                case Type.Horizontal:                 //это конструктор горизонтальный. TODO. ДОДЕЛАТЬ ДОБАВЛЕНИЕ !!!!!!!!!  
					_nHeight = nDimensionTargetMax;
                    _aColumns = new List<Column>();
                    enType = Type.Horizontal;
                    break;
                case Type.Fixed:
					_nHeight = _nWidth = nDimensionTargetMax;
                    stArea = new Area(0, 0, _nWidth, _nHeight);
                    enType = Type.Fixed;
                    break;
                default:
                    break;
            }
            
        }
示例#8
0
		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;
			}
		}
示例#9
0
		public PixelsMap(Area stArea, Format ePixelFormat)
			: this(true, stArea, ePixelFormat)
		{
		}
示例#10
0
        private DisCom.LayerInfo Intersect(Area stBase)            //v: Даёт размерность, ширину, высоту кропа и относительные координаты его лев верх угла от бэка и от фора и ширину кропа.
        {                                                          //в целях оптимизации убраны все проверки, т.к. они уже были в FramesMerge...
            DisCom.LayerInfo cRetVal = new DisCom.LayerInfo();
            Area             stCrop  = _stArea.CropOnBase(stBase); // если кроп нулевой, то w == h == 0

            if (stCrop.nWidth == 0)                                //не пересеклись
            {
                cRetVal.nCropTopLineInBG    = -1;
                cRetVal.nCropBottomLineInBG = -1;
            }
            else
            {
                cRetVal.nWidth_4     = 4 * stArea.nWidth;
                cRetVal.nCropWidth_4 = 4 * stCrop.nWidth;
                int nCropLeft = stCrop.nLeft - stBase.nLeft;                                //отступ кропа слева COL
                cRetVal.nCropLeft_4 = 4 * nCropLeft;
                int nBGIndxStart = (stCrop.nTop - stBase.nTop) * stBase.nWidth + nCropLeft; //BGIndxStart=COT*BW+COL;   начальный индекс по бг
                //формула вычисления FI=BI+M*(FW-BW)-(FOT*FW+FOL); M=(int)(BI/BW);
                cRetVal.nAlphaConstant      = nAlphaConstant;                               //11/ константная альфа
                cRetVal.nAlphaType          = (byte)eAlpha;
                cRetVal.nTop                = stArea.nTop;
                cRetVal.nLeft_4             = 4 * stArea.nLeft;
                cRetVal.nCropTopLineInBG    = nBGIndxStart / stBase.nWidth;
                cRetVal.nCropBottomLineInBG = cRetVal.nCropTopLineInBG + stCrop.nHeight - 1;

                int   nFloorX = (int)Math.Floor(_stPosition.X);
                int   nFloorY = (int)Math.Floor(_stPosition.Y);
                float nShift  = _stPosition.X - nFloorX;                  // т.е. всегда теперь 0 <= S < 1
                if ((cRetVal.nShiftPositionByteX = (byte)Math.Abs(255 * nShift)) == 255)
                {
                    cRetVal.nShiftPositionByteX = 254;
                }
                nShift = _stPosition.Y - nFloorY;
                if ((cRetVal.nShiftPositionByteY = (byte)Math.Abs(255 * nShift)) == 255)
                {
                    cRetVal.nShiftPositionByteY = 254;
                }

                cRetVal.nShiftTotalX = _nShiftTotalX;
                if (0 < Math.Abs(_nShiftTotalX))                 // то делаем поля
                {
                    int nFloorHalfX = (int)Math.Floor(_stHalfPosition.X);
                    int nFloorHalfY = (int)Math.Floor(_stHalfPosition.Y);
                    nShift = _stHalfPosition.X - nFloorHalfX;
                    cRetVal.nHalfPathShiftPositionByteX = nShift == 0 ? (byte)0 : (byte)Math.Abs(255 * nShift);
                    nShift = _stHalfPosition.Y - nFloorHalfY;
                    cRetVal.nHalfPathShiftPositionByteY = nShift == 0 ? (byte)0 : (byte)Math.Abs(255 * nShift);                      // (для диагональных смещений с полями)
                    //   знак узнаем из nDeltaPxX_4
                    cRetVal.nHalfDeltaPxX_4 = (nFloorX - nFloorHalfX) * 4;
                    cRetVal.nHalfDeltaPxY_4 = (nFloorY - nFloorHalfY) * 4;

                    if (null != _cShiftOffset)
                    {
                        cRetVal.nOffsetTop = _cShiftOffset.nTop & 1;

                        if (stBase.nTop > _stArea.nTop && ((stBase.nTop - _stArea.nTop) & 1) == 1)
                        {
                            cRetVal.nOffsetTop = ~cRetVal.nOffsetTop;
                        }
                    }
                }
            }
            return(cRetVal);
        }
示例#11
0
		private Area AreaResize(int nImageWidth, int nImageHeight, int nCanvasWidth, int nCanvasHeight, float nPixelAspectRatio)
		{
			Area stRetVal;
			nImageWidth = (int)Math.Round(((double)nImageWidth) * nPixelAspectRatio, 0);
			int nCrop;
			if (nImageWidth * nCanvasHeight > nImageHeight * nCanvasWidth)
			{
				nCrop = (int)Math.Round((double)(nImageHeight * nCanvasWidth) / (double)nImageWidth, 0);
				stRetVal = new Area(0, (short)Math.Round((double)(nCanvasHeight - nCrop) / 2, 0), (ushort)nCanvasWidth, (ushort)nCrop);
				_cFile.stDimensionsResized = new Size(nCanvasWidth, nCrop);
			}
			else
			{
				nCrop = (int)Math.Round((double)(nImageWidth * nCanvasHeight) / (double)nImageHeight, 0);
				stRetVal = new Area((short)Math.Round((double)(nCanvasWidth - nCrop) / 2, 0), 0, (ushort)nCrop, (ushort)nCanvasHeight);
				_cFile.stDimensionsResized = new Size(nCrop, nCanvasHeight);
			}
			return stRetVal;
		}
示例#12
0
 public PixelsMap(MergingMethod stMergingMethod, Area stArea, Format ePixelFormat)
     : this(stMergingMethod, stArea, ePixelFormat, false)
 {
 }
示例#13
0
文件: Video.cs 项目: ratsil/bethe.btl
        override public void Prepare()
        {
			try
			{
				float nK;
				ushort nNewSize;
				short nHalfDelta;

				(new Logger()).WriteDebug2("video prepare [old area:" + stArea.nWidth + "  " + stArea.nHeight + "]");
				(new Logger()).WriteDebug2("video prepare [file area:" + _cFile.stArea.nWidth + "  " + _cFile.stArea.nHeight + "]");
				(new Logger()).WriteDebug2("video prepare [file w h:" + _cFile.nWidthOriginal + "  " + _cFile.nHeightOriginal + "]");
				//DNF
				FitIn eFitIn = FitIn.Crop; // типа из настроек пришло ))
				if (_cFile.nHeightOriginal != stArea.nHeight || _cFile.nWidthOriginal != stArea.nWidth) // если видео не совпало с контейнером
				{
					if (_cFile.nHeightOriginal == 576 && _cFile.nWidthOriginal == 720) // if video format is PAL = 768x576 in square pixels   рассмотрим частный случай, т.к. он восновном и будет только.
					{
						if (eFitIn == FitIn.Crop)
						{
							nK = (float)stArea.nWidth / 768; // коэффициент    (делаем правильно именно дл¤ пала с учетом аспекта пиксел¤ у пала)
							nNewSize = (ushort)Math.Round(nK * _cFile.nHeightOriginal); // нова¤ высота при раст¤гивании по ширине
							nHalfDelta = (short)Math.Round(((float)(stArea.nHeight - nNewSize) / 2));
							stArea = new Area(0, nHalfDelta, stArea.nWidth, nNewSize);
							//stArea = new Area(0, -180, 1920, 1440);  должно быть так, если правильно посчитано будет...
						}
					}
					else  // if video is not container's size and not PAL
					{
						if (eFitIn == FitIn.Crop)
						{
							if (_cFile.nWidthOriginal > _cFile.nHeightOriginal)
							{
								nK = (float)stArea.nWidth / _cFile.nWidthOriginal; // коэффициент
								nNewSize = (ushort)Math.Round(nK * _cFile.nHeightOriginal); // нова¤ высота при раст¤гивании по ширине
								nHalfDelta = (short)Math.Round((float)(stArea.nHeight - nNewSize) / 2);
								stArea = new Area(0, nHalfDelta, stArea.nWidth, nNewSize);
							}
							else
							{
								nK = (float)stArea.nHeight / _cFile.nHeightOriginal; // коэффициент
								nNewSize = (ushort)Math.Round(nK * _cFile.nWidthOriginal); // нова¤ высота при раст¤гивании по ширине
								nHalfDelta = (short)Math.Round((float)(stArea.nWidth - nNewSize) / 2);
								stArea = new Area(nHalfDelta, 0, nNewSize, stArea.nHeight);
							}
						}
					}
				}
				//DNF
				(new Logger()).WriteDebug2("video prepare [new area:" + stArea.nWidth + "  " + stArea.nHeight + "]");

				_cFile.stArea = stArea;
				_cFile.Open(bCUDA);
				if (ulong.MaxValue == nDuration)
					nDuration = _cFile.nFramesTotal - nFrameStart;
				(new Logger()).WriteDebug2("video prepared [video_hc:" + GetHashCode() + "][file_hc:" + _cFile.GetHashCode() + "]");
				base.Prepare();
			}
			catch
			{
				Fail();
				throw;
			}
        }
示例#14
0
        static public Area SumOfAreas(Area a1, Area a2)
        {
            Area aRetVal = new Area();
			aRetVal.nLeft = 0; // a1.nLeft < a2.nLeft ? a1.nLeft : a2.nLeft;
			aRetVal.nTop = 0; // a1.nTop < a2.nTop ? a1.nTop : a2.nTop;
            aRetVal.nWidth = a1.nRight < a2.nRight ? (ushort)(a2.nRight - aRetVal.nLeft + 1) : (ushort)(a1.nRight - aRetVal.nLeft + 1);
			aRetVal.nWidth += a1.nLeft < 0 || a2.nLeft < 0 ? (ushort)0 : (ushort)Math.Min(a1.nLeft, a2.nLeft);
            aRetVal.nHeight = a1.nBottom < a2.nBottom ? (ushort)(a2.nBottom - aRetVal.nTop + 1) : (ushort)(a1.nBottom - aRetVal.nTop + 1);
			aRetVal.nHeight += a1.nTop <= 0 || a2.nTop <= 0 ? (ushort)0 : (ushort)Math.Min(a1.nTop, a2.nTop);
            return aRetVal;
        }
示例#15
0
		protected void AreaSet(Area stArea)
		{
			if (null != _cEffect)
				((shared.EffectVideo)_cEffect).stArea = stArea;
			this.stArea = stArea;
		}
示例#16
0
		public PixelsMap(bool bIsCUDA, Area stArea, Format ePixelFormat)
		{
			_dt = DateTime.Now;
			_bTemp = false;
			_bProcessing = false;
			_bDisposed = false;
			_cSyncRoot = new object();
			if (bCUDA = bIsCUDA && 1 > Preferences.nCUDAVersion)
				throw new Exception("There is no CUDA version in preferences");
#else
		public PixelsMap()
			:this(false, new Area(0, 0, 1, 1), Format.BGRA32)
		{
		}
示例#17
0
		public EffectVideo()
			: base()
		{
			cDock = new Dock(Dock.Corner.upper_left, new Dock.Offset(0, 0));
			bOpacity = true;
			stArea = Area.stEmpty;
		}
示例#18
0
		public PixelsMap(bool bCUDA, Area stArea, Format ePixelFormat)
		{
#endif
			_nID = 0;
			nAlphaConstant = byte.MaxValue;
			bBackgroundClear = false;
			bKeepAlive = false;
			_cException = null;
			_nBytesQty = 0;
			_ePixelFormat = ePixelFormat;
			_stArea = stArea;
			_nBytesQty = (uint)(_stArea.nWidth * _stArea.nHeight * Math.Abs((int)((int)ePixelFormat / 100)) / 8);
			_nShiftPosition = 0;
			_cSyncRoot = new object();
		}
示例#19
0
        public Area Dock(Area stBase, Dock cDock)
		{
			Area stRetVal = this;
			if (null != cDock)
			{
				switch (cDock.eCorner)
				{
					case helpers.Dock.Corner.upper_left:
						stRetVal.nLeft = 0;
						stRetVal.nTop = 0;
						break;
					case helpers.Dock.Corner.upper_right:
						stRetVal.nLeft = (short)(stBase.nWidth - nWidth);
						stRetVal.nTop = 0;
						break;
					case helpers.Dock.Corner.bottom_left:
						stRetVal.nLeft = 0;
						stRetVal.nTop = (short)(stBase.nHeight - nHeight);
						break;
					case helpers.Dock.Corner.bottom_right:
						stRetVal.nLeft = (short)(stBase.nWidth - nWidth);
						stRetVal.nTop = (short)(stBase.nHeight - nHeight);
						break;
					case helpers.Dock.Corner.center:
						stRetVal.nLeft = (short)Math.Round((float)stBase.nWidth / 2 - (float)nWidth / 2);
						stRetVal.nTop = (short)Math.Round((float)stBase.nHeight / 2 - (float)nHeight / 2);
						break;
				}
				stRetVal.nLeft += cDock.cOffset.nLeft;
				stRetVal.nTop += cDock.cOffset.nTop;
			}
			return stRetVal;
		}
示例#20
0
		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;
		}
示例#21
0
 public Composite(ushort nWidth, ushort nHeight) //это конструктор для пустышки или константного размера
     : this()
 {
     stArea = new Area(0, 0, nWidth, nHeight);
     _nWidth = nWidth;
     _nHeight = nHeight;
     _eType = Type.Fixed;
 }
示例#22
0
		private Decklink(IDeckLink cDevice)
		{
			(new Logger()).WriteDebug3("in");
			try
			{
				nAudioQueueLength = nAudioQueueLengthPrevious = 0;
				nBTLAudioQueueLengthPrevious = nBTLVideoQueueLengthPrevious = nVideoQueueLengthPrevious = 0;
				_iDLDevice = cDevice;
				if(Preferences.bDeviceInput)
					_iDLInput = (IDeckLinkInput)_iDLDevice;
				else
					_iDLOutput = (IDeckLinkOutput)_iDLDevice;

				IDeckLinkDisplayModeIterator cDisplayModeIterator;
				IDeckLinkDisplayMode cNextDLDisplayMode;
				string sDisplayModeName = "";

				string sMessage = "decklink supported modes:<br>";
				if (Preferences.bDeviceInput)
				{
					_iDLInputDisplayMode = null;
					_iDLInput.GetDisplayModeIterator(out cDisplayModeIterator);
					while (true)
					{
						cDisplayModeIterator.Next(out cNextDLDisplayMode);
						if (cNextDLDisplayMode == null)
							break;
						cNextDLDisplayMode.GetName(out sDisplayModeName);
						if (null == _iDLInputDisplayMode && sDisplayModeName.ToLower().Contains(Preferences.sVideoFormat))
						{
							sMessage += "selected:";
							_iDLInputDisplayMode = cNextDLDisplayMode;
						}
						else
							sMessage += "\t";
						sMessage += sDisplayModeName + "<br>";
					}
					(new Logger()).WriteNotice(sMessage);
					if (null == _iDLInputDisplayMode)
						throw new Exception("can't find " + Preferences.sVideoFormat + " mode within specified device for input");
				}
				else
				{
					_nFramesAudioDropped = 0;
					_iDLOutputDisplayMode = null;
					_iDLOutput.GetDisplayModeIterator(out cDisplayModeIterator);
					while (true)
					{

						cDisplayModeIterator.Next(out cNextDLDisplayMode);
						if (cNextDLDisplayMode == null)
							break;
						cNextDLDisplayMode.GetName(out sDisplayModeName);
						if (null == _iDLOutputDisplayMode && sDisplayModeName.ToLower().Contains(Preferences.sVideoFormat))
						{
							sMessage += "selected:";
							_iDLOutputDisplayMode = cNextDLDisplayMode;
						}
						else
							sMessage += "\t";
						sMessage += sDisplayModeName + "<br>";
					}
					(new Logger()).WriteNotice(sMessage);
					if (null == _iDLOutputDisplayMode)
						throw new Exception("can't find " + Preferences.sVideoFormat + " mode within specified device for output");
					stArea = new Area(0, 0, (ushort)_iDLOutputDisplayMode.GetWidth(), (ushort)_iDLOutputDisplayMode.GetHeight());

					long nFrameDuration, nFrameTimescale;
					_iDLOutputDisplayMode.GetFrameRate(out nFrameDuration, out nFrameTimescale);
					_nFPS = (ushort)((nFrameTimescale + (nFrameDuration - 1)) / nFrameDuration); //до ближайшего целого - взято из примера деклинка

					_bDoWritingFrames = false;
					_aqWritingFrames = new Queue<byte[]>();
					_cThreadWritingFramesWorker = new System.Threading.Thread(WritingFramesWorker);
					_cThreadWritingFramesWorker.IsBackground = true;
					_cThreadWritingFramesWorker.Priority = System.Threading.ThreadPriority.Normal;
					_cThreadWritingFramesWorker.Start();

					if (Preferences.bAudio)
					{
						switch (Preferences.nAudioBitDepth)
						{
							case 32:
								_eAudioSampleDepth = _BMDAudioSampleType.bmdAudioSampleType32bitInteger;
								break;
							case 16:
							default:
								_eAudioSampleDepth = _BMDAudioSampleType.bmdAudioSampleType16bitInteger;
								break;
						}
						switch (Preferences.nAudioSamplesRate)
						{
							case 48000:
								_eAudioSampleRate = _BMDAudioSampleRate.bmdAudioSampleRate48kHz;
								break;
							default:
								throw new Exception("unsupported audio sample rate [" + Preferences.nAudioSamplesRate + "]");
						}
						//_pAudioSamplesBuffer = Marshal.AllocCoTaskMem((int)_nAudioFrameSize_InBytes);
						_cAudioBuffer = new AudioBuffer();
						_nAudioBufferCapacity_InSamples = Preferences.nAudioSamplesPerFrame * Preferences.nQueueDeviceLength;
						//for (int nIndx = 0; _nAudioFrameSize_InBytes > nIndx; nIndx++)
						//    Marshal.WriteByte(_pAudioSamplesBuffer, nIndx, 0);

						_nTimescale = (ushort)_eAudioSampleRate;
						_nFrameDuration = (ushort)(_nTimescale / _nFPS);
					}
					if (null != Preferences.cDownStreamKeyer)
						_iDeckLinkKeyer = (IDeckLinkKeyer)_iDLDevice;
				}
			}
			catch (Exception ex)
			{
				(new Logger()).WriteError(ex);
				throw;
			}
			(new Logger()).WriteDebug4("return");
		}