using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Windows;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

namespace CSharpPlayerDemo
{
    public partial class Form1 : Form
    {
        private Panel[] m_panDisPlay;//播放画面数组
        private CLS_PlaySDK m_PlayHelper;//播放器操作接口对象
        private CLS_Players m_Players;//播放器对象，存储了所有播放器的实例的信息，个数、ID、速度、音频等等
        //处理文件播放完毕
        private delegatePlayEndFun m_ReadEnd;
        private delegate void dePlayEndClient(int _iID);

        private int m_iBMPNum;
        private SDK_VERSION m_SdkVer;
        public const long MAX_SIZE = 2147483647;
        public const int MAX_READBUFFER = 102400;
        public const int  RET_BUFFER_FULL = -11;  //Stream VoD PutData buffer满
        public const int RET_FRAMELIST_FULL=-12;	 //Stream VoD帧缓冲满
        public const int RET_VODPLAY_OVER=-13;	 //VoDPlayer播放完毕
        public const int RET_FILEREAD_OVER=-14;	 //文件读写完毕
        public const int RET_FRAMELIST_FEW=-15;  //VoD缓冲帧数太少

        public const int RET_FRAMELIST_WILL_BE_FULL=-16;		//	即将满
        public const int RET_FRAMELIST_WILL_BE_EMPTY=-17;		//	即将空
        public const int RET_BUFFER_WILL_BE_FULL=-18;		//	即将满
        public const int RET_BUFFER_WILL_BE_EMPTY = -19;		//	即将空

        public const int WM_USER = 0x0400;
        public const int MSG_PLAYSDKM4 = WM_USER + 0x01FF;//回放器库消息的默认值

        public const int LPARAM_VOD_STREAM_END = 6;//VOD文件流播放完毕

        //自定义消息
        private const int WM_CUSTOMMSG = 0x1000;
        //控制画“橡皮筋”标志
        private bool m_bDrawing = false;
        //预先创建PEN防止影响效率
        private Pen m_PenDrawZoom = new Pen(Color.Gray, 2);
        //被电子放大的矩形
        private RECT m_rcZoom;
        private int m_iEZoom = -1;
        //显示电子放大效果的窗口
        //private List<ZoomIn> m_lstFormZoomIn = null;
        private ZoomIn m_FormZoomIn = null;
        private ZoomIn m_OldFormZoomIn = null;

        private void m_PlayEndFun(int _iID)
        {
            //Trace.WriteLine(_iID.ToString());
            //子线程内访问FORM窗体元素使用invoke方法实现
            if (this.InvokeRequired)
            {
                //代理,有参代理
                dePlayEndClient dePEC = new dePlayEndClient(m_PlayEndFun);
                for (int i = 0; i<4 ; i++)
                {
                    if(m_Players.m_iArrID[i] == _iID)
                    {
                        m_panDisPlay[i].Invoke(dePEC, _iID);
                        break;  
                    }
                }
                
            }
            else
            {
                //向主线程发送消息
                m_PlayHelper.m_MyPostMessage(this.Handle, WM_CUSTOMMSG, 0, _iID);
                //MyPostMsg(this.Handle, WM_CUSTOMMSG, 0, _iID);
            }       
        }

        //文件发送关闭消息处理函数
        private void m_OnPlayEnd(Int32 _iID)
        {
            //m_panDisPlay[_iID].Invalidate();
            //m_Players.m_iArrID[_iID] = -1;
            for (int i = 0; i < 4;i++ )
            {
                if (m_Players.m_iArrID[i]==_iID)
                {
                    m_PlayHelper.m_Stop(m_Players.m_iArrID[i]);
                    int iRetDelP = 0;
                    iRetDelP = m_PlayHelper.m_DeletePlayer(m_Players.m_iArrID[i]);
                    //Trace.WriteLine(iRetDelP.ToString());
                    m_panDisPlay[i].Invalidate();
                    m_Players.m_iArrID[i] = -1;
                }
            }
        }

        private void m_ChangePutSpeed(eSpeedType _speedType)
        {
            int iStreamSpeed = 0;
            iStreamSpeed = (int)numericUpDown1.Value;
            if (eSpeedType.SPEED_DEC==_speedType)
            {
                iStreamSpeed += 50;
            }
            else if (eSpeedType.SPEED_ADD==_speedType)
            {
                iStreamSpeed -= 100;
            }
            if (iStreamSpeed <= 0)
            {
                iStreamSpeed = 20;
            }
            if (iStreamSpeed>(int)numericUpDown1.Maximum)
            {
                iStreamSpeed = 200;
            }
            timerGetData.Interval = iStreamSpeed;
            numericUpDown1.Value = iStreamSpeed;
        }

        private int CheckFileSize(string _strFileName)
        {  
            FileStream fs = null;
            try
            {
                fs = File.Open(_strFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                if (fs.Length > MAX_SIZE)
                {
                    return -2;
                }
            }
            catch
            {
            }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                }
            }
            
            return 0;
        }

        private int SwapIfBig(ref Int32 _iFir, ref Int32 _iSec)
        {
            if (_iFir > _iSec)
            {
                Int32 iTemp = _iFir;
                _iFir = _iSec;
                _iSec = iTemp;
            }
            return 0;
        }

        private int UI_Update_FrameInfo(int _iIndex)
        {
            int iBegin = 0;
            int iEnd = 0;
            if (m_PlayHelper.m_GetBeginEnd(m_Players.m_iArrID[_iIndex], ref iBegin, ref iEnd) == 0)
            {
                tbFirFrmNo.Text = iBegin.ToString();
                tbLastFrmNo.Text = iEnd.ToString();
            }

            return 0;
        }

        private int PanelRectToVideoRect(int _iIndex, ref RECT _rcRcct)
        {

            int iVideoWith = 0;
            int iVideoHeight = 0;
            int iFrameRate = 0;
            m_PlayHelper.m_GetVideoParam(m_Players.m_iArrID[_iIndex], ref iVideoWith, ref iVideoHeight, ref iFrameRate);


            int iPanelWidth = m_panDisPlay[_iIndex].Width;
            int iPanelHeight = m_panDisPlay[_iIndex].Height;

            _rcRcct.left = (int)((double)_rcRcct.left / iPanelWidth * iVideoWith);
            _rcRcct.right = (int)((double)_rcRcct.right / iPanelWidth * iVideoWith);
            _rcRcct.top = (int)((double)_rcRcct.top / iPanelHeight * iVideoHeight);
            _rcRcct.bottom = (int)((double)_rcRcct.bottom / iPanelHeight * iVideoHeight);

            return 0;
        }

        public Form1()
        {
            InitializeComponent();

            //将4个panel赋值给控制数组，您可以增加更多的panel
            m_panDisPlay = new Panel[4];
            m_panDisPlay[0] = panel1;
            m_panDisPlay[1] = panel2;
            m_panDisPlay[2] = panel3;
            m_panDisPlay[3] = panel4;

            //初始化
            m_PlayHelper = new CLS_PlaySDK();
            //播放实例句柄
            m_Players = new CLS_Players(4);
            //BMP图计数
            m_iBMPNum = 0;
            //文件播放完毕委托创建
            m_ReadEnd = new delegatePlayEndFun(m_PlayEndFun);
            //SDK版本信息
            m_SdkVer = new SDK_VERSION();

            //开启双缓存
            this.DoubleBuffered = true;

            m_PlayHelper.m_TC_RegisterEventMsg(this.Handle, MSG_PLAYSDKM4);

            //Control.CheckForIllegalCrossThreadCalls = false;

            //m_FormZoomIn = new ZoomIn();
            //m_lstFormZoomIn = new List<ZoomIn>(10);
        }

        private void panelMouseClick(object sender, MouseEventArgs e)
        {
            Panel panTemp = sender as Panel;
            tbSelNo.Text = panTemp.Tag.ToString();
            int iIndex = Convert.ToInt32(tbSelNo.Text);
            if (m_Players.m_iAudioArr[iIndex]==0)
            {
                button6.Text = "AudioStop";
            }
            else
            {
                button6.Text = "AudioOpen";
            }

            UI_Update_FrameInfo(iIndex);
        }

        private void panelMouseDoubleClick(object sender, MouseEventArgs e)
        {
            Panel panTemp = sender as Panel;
            tbSelNo.Text = panTemp.Tag.ToString();
            int iIndex = Convert.ToInt32(tbSelNo.Text);

            if (m_panDisPlay[iIndex].Width <= 720)
            {
                m_panDisPlay[iIndex].Left=2;
                m_panDisPlay[iIndex].Top=2;               
                m_panDisPlay[iIndex].Width=722;
                m_panDisPlay[iIndex].Height=572;

                for(int i=0;i<4;i++)
                {
                    if (i != iIndex)
                    {
                        m_panDisPlay[i].Left = (i % 2) * 362 + 2;
                        m_panDisPlay[i].Top = (i / 2) * 287 + 2;
                        m_panDisPlay[i].Width = 360;
                        m_panDisPlay[i].Height = 285;
                    }
                }
                //MessageBox.Show(top.ToString() +" "+ left.ToString() +" "+ width.ToString() +" "+ heigt.ToString());
            }
            else
            {
                m_panDisPlay[iIndex].Left = (iIndex % 2) * 362 + 2;
                m_panDisPlay[iIndex].Top = (iIndex / 2) * 287 + 2;
                m_panDisPlay[iIndex].Width = 360;
                m_panDisPlay[iIndex].Height = 285;
            }
            m_panDisPlay[iIndex].BringToFront();
            RECT rcDraw = new RECT();
            m_PlayHelper.m_SetPlayRect(m_Players.m_iArrID[iIndex], ref rcDraw);
        }

        private void panelMouseDown(object sender,MouseEventArgs e)
        {
            if (e.Button!=MouseButtons.Right)
            {
                return;
            }

            Panel panTemp = sender as Panel;
            tbSelNo.Text = panTemp.Tag.ToString();
            int iIndex = Convert.ToInt32(tbSelNo.Text);

            m_bDrawing = true;
            m_rcZoom.left = e.X;
            m_rcZoom.top = e.Y;

            //m_EZoom();
        }

        private void panelMouseUp(object sender,MouseEventArgs e)
        {
            if (e.Button!=MouseButtons.Right)
            {
                return;
            }

            m_bDrawing = false;
            int iIndex = Convert.ToInt32(tbSelNo.Text);


            int iPanelWidth = m_panDisPlay[iIndex].Width;
            int iPanelHeight = m_panDisPlay[iIndex].Height;

            m_rcZoom.right = Math.Max(Math.Min(iPanelWidth, e.X), 0);
            m_rcZoom.bottom = Math.Max(Math.Min(iPanelHeight, e.Y), 0);

            SwapIfBig(ref m_rcZoom.left, ref m_rcZoom.right);
            SwapIfBig(ref m_rcZoom.top, ref m_rcZoom.bottom);

            RECT rctZero = new RECT();
            m_PlayHelper.m_DrawRect(m_Players.m_iArrID[iIndex], ref rctZero, 1);

            m_EZoom(iIndex, ref m_rcZoom); 
        }

        private void panelMouseMove(object sender,MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Right)
            {
                return;
            }

            int iIndex = Convert.ToInt32(tbSelNo.Text);

            m_rcZoom.right = e.X;
            m_rcZoom.bottom = e.Y;

            if (m_bDrawing)
            {
                RECT rcInVideo = new RECT();
                rcInVideo.left = m_rcZoom.left;
                rcInVideo.top = m_rcZoom.top;
                rcInVideo.right = m_rcZoom.right;
                rcInVideo.bottom = m_rcZoom.bottom;

                SwapIfBig(ref rcInVideo.left, ref rcInVideo.right);
                SwapIfBig(ref rcInVideo.top, ref rcInVideo.bottom);

                PanelRectToVideoRect(iIndex, ref rcInVideo);
                m_PlayHelper.m_DrawRect(m_Players.m_iArrID[iIndex], ref rcInVideo, 1);
            }
        }

        private int m_EZoom(int _iIndex, ref RECT _rcEZoom)
        {
            if( _iIndex < 0 || _iIndex > 3 || _rcEZoom.left == _rcEZoom.right || _rcEZoom.top == _rcEZoom.bottom || m_Players.m_iArrID[_iIndex] == -1)
            {
                 return -1;
            }

            if (_rcEZoom.left < 0 || _rcEZoom.top < 0 || _rcEZoom.right < 0 || _rcEZoom.bottom < 0)
            {
                MessageBox.Show("Check the height/width");
                 return -1;
            }          

            RECT rcInVideo = new RECT();
            rcInVideo.left = _rcEZoom.left;
            rcInVideo.top = _rcEZoom.top;
            rcInVideo.right = _rcEZoom.right;
            rcInVideo.bottom = _rcEZoom.bottom;

            PanelRectToVideoRect(_iIndex, ref rcInVideo);

            if (m_iEZoom!=-1)
            {
                m_PlayHelper.m_RemoveEZoom(m_Players.m_iArrID[_iIndex], m_iEZoom);
            }

            
            if (m_FormZoomIn!=null)
            {
                m_OldFormZoomIn = m_FormZoomIn;
                m_OldFormZoomIn.Close();
                m_iEZoom = -1;
            }
            
            m_FormZoomIn = new ZoomIn();
            m_FormZoomIn.Show();

            RECT rcShow = new RECT();
            m_iEZoom = m_PlayHelper.m_AddEZoom(m_Players.m_iArrID[_iIndex], m_FormZoomIn.Handle, ref rcShow, 1);
            
            int iRet = m_PlayHelper.m_SetEZoom(m_Players.m_iArrID[_iIndex], m_iEZoom, rcInVideo);

            return 1;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //初始化players
            m_Players.InitPlayers();
            //为m_panDisPlay添加处理函数
            for (int i = 0; i < 4; i++)
            {
                m_panDisPlay[i].MouseClick += new MouseEventHandler(panelMouseClick);
                m_panDisPlay[i].MouseDoubleClick+=new MouseEventHandler(panelMouseDoubleClick);
                m_panDisPlay[i].MouseDown += new MouseEventHandler(panelMouseDown);
                m_panDisPlay[i].MouseMove+=new MouseEventHandler(panelMouseMove);
                m_panDisPlay[i].MouseUp+=new MouseEventHandler(panelMouseUp);
            }

            int er;
            if ((er = m_PlayHelper.m_CreateSystem(new IntPtr(0))) != 0)
            {
                string strMsg = "Initial failed! error=" + er.ToString();
                string strCapt = "Error";
                MessageBoxButtons bnMsg = MessageBoxButtons.OKCancel;
                MessageBox.Show(strMsg, strCapt, bnMsg);
                return;
            }

            m_PlayHelper.m_StartMonitorCPU();
            //int iRetPlayEnd = 0;
            m_PlayHelper.m_RegisterNotifyPlayToEnd(m_ReadEnd);
            //Trace.WriteLine(iRetPlayEnd.ToString());
            //m_PlayHelper.m_GetVersion(ref m_SdkVer);

        }

        private void m_FormOpenFile(object sender, EventArgs e)
        {
            String strFileName = "";
            RECT rcDraw = new RECT();

            //获得选中的Panel索引
            int iIndex = Convert.ToInt32(tbSelNo.Text);
            DialogResult drRet = openFileDialog.ShowDialog();
            if (DialogResult.OK == drRet)
            {
                strFileName = openFileDialog.FileName;
                if (strFileName == "")
                {
                    MessageBox.Show("File name is empty!", "Error");
                    return;
                }
                if (!File.Exists(strFileName))
                {
                    MessageBox.Show("File not found!", "Error");
                    return;
                }
                int checkResult = CheckFileSize(strFileName);
                if (checkResult == -2)
                {
                    MessageBox.Show("Big file (>2G) is not supported!", "Error");
                }
                }
            else
            {
                return;
            }
            if (m_Players.m_iArrID[iIndex] != -1)
            {
                m_Players.m_iSpeed[iIndex] = 0;
                m_PlayHelper.m_Stop(m_Players.m_iArrID[iIndex]);
                m_PlayHelper.m_DeletePlayer(m_Players.m_iArrID[iIndex]);

                if (m_Players.m_fsArr[iIndex]!=null)
                {
                    m_Players.m_fsArr[iIndex].Close();
                    m_Players.m_fsArr[iIndex] = null;
                }

                m_Players.m_iArrID[iIndex] = -1;
                m_panDisPlay[iIndex].Invalidate();
            }

            int iBuffSz = 0;
            m_Players.m_iArrID[iIndex] = m_PlayHelper.m_CreatePlayerFromFile(m_panDisPlay[iIndex].Handle,
                strFileName, iBuffSz);
            if (m_Players.m_iArrID[iIndex] < 0)
            {
                MessageBox.Show("Incorrect file format!", "Error");
                return;
            }
            m_PlayHelper.m_SetPlayRect(m_Players.m_iArrID[iIndex], ref rcDraw);

            int iBegin = 0;
            int iEnd = 0;
            if (m_PlayHelper.m_GetBeginEnd(m_Players.m_iArrID[iIndex],ref iBegin,ref iEnd)==0)
            {
                tbFirFrmNo.Text = iBegin.ToString();
                tbLastFrmNo.Text = iEnd.ToString();
            }
            m_PlayHelper.m_Play(m_Players.m_iArrID[iIndex]);
            button6.Text = "AudioOpen";
            m_Players.m_iAudioArr[iIndex] = -1;

            if (!timerSetTB.Enabled)
            {
                timerSetTB.Start();
            }            
        }

        private void m_FormOpenStream(object sender, EventArgs e)
        {
            String strFileName = "";
            RECT rcDraw = new RECT();

            //获得选中的Panel索引
            int iIndex = Convert.ToInt32(tbSelNo.Text);
            DialogResult drRet = openFileDialog.ShowDialog();
            if (DialogResult.OK == drRet)
            {
                strFileName = openFileDialog.FileName;
                if (strFileName == "")
                {
                    MessageBox.Show("File name is empty!", "Error");
                    return;
                }
                if (!File.Exists(strFileName))
                {
                    MessageBox.Show("File not found!", "Error");
                    return;
                }
                int checkResult = CheckFileSize(strFileName);
                if (checkResult == -2)
                {
                    MessageBox.Show("Big file (>2G) is not supported!", "Error");
                }
                }
            else
            {
                return;
            }       
            if (m_Players.m_iArrID[iIndex] != -1)
            {
                m_Players.m_iSpeed[iIndex] = 0;
                m_PlayHelper.m_Stop(m_Players.m_iArrID[iIndex]);
                m_PlayHelper.m_DeletePlayer(m_Players.m_iArrID[iIndex]);

                if (m_Players.m_fsArr[iIndex] != null)
                {
                    m_Players.m_fsArr[iIndex].Close();
                    m_Players.m_fsArr[iIndex] = null;
                }

                m_Players.m_iArrID[iIndex] = -1;
                if (timerSetTB.Enabled)
                {
                    timerSetTB.Stop();
                }                
                m_panDisPlay[iIndex].Invalidate();
            }

            Byte[] cHeadInfo = new Byte[88];
            try
            {
                m_Players.m_fsArr[iIndex] = new FileStream(strFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                m_Players.m_fsArr[iIndex].Seek(0, SeekOrigin.Begin);
                m_Players.m_fsArr[iIndex].Read(cHeadInfo, 0, cHeadInfo.Length);
                m_Players.m_iArrID[iIndex] = m_PlayHelper.m_CreatePlayerFromVoD(m_panDisPlay[iIndex].Handle,
                    cHeadInfo, cHeadInfo.Length);

                if (m_Players.m_iArrID[iIndex] < 0)
                {
                    MessageBox.Show("Incorrect file format!", "Error");
                    return;
                }
                m_PlayHelper.m_SetPlayRect(m_Players.m_iArrID[iIndex], ref rcDraw);

                m_PlayHelper.m_Play(m_Players.m_iArrID[iIndex]);
                button6.Text = "AudioOpen";
                m_Players.m_iAudioArr[iIndex] = -1;
                timerGetData.Start();

                if (!timerSetTB.Enabled)
                {
                    timerSetTB.Start();
                }

            }
            catch
            {
            }
        }

        private void m_FormPlay(object sender, EventArgs e)
        {
            int iIndex = Convert.ToInt32(tbSelNo.Text);
            m_PlayHelper.m_Play(m_Players.m_iArrID[iIndex]);

            m_Players.m_iSpeed[iIndex] = 0;
        }

        private void m_FormPause(object sender, EventArgs e)
        {
            int iIndex = Convert.ToInt32(tbSelNo.Text);
            m_PlayHelper.m_Pause(m_Players.m_iArrID[iIndex]);

            m_Players.m_iSpeed[iIndex] = 0;
        }

        private void m_FormForwardStep(object sender, EventArgs e)
        {
            int iIndex = Convert.ToInt32(tbSelNo.Text);
            m_PlayHelper.m_StepForward(m_Players.m_iArrID[iIndex]);

            m_Players.m_iSpeed[iIndex] = 0;
        }

        private void m_FormBackStep(object sender, EventArgs e)
        {
            int iIndex = Convert.ToInt32(tbSelNo.Text);
            m_PlayHelper.m_StepBackward(m_Players.m_iArrID[iIndex]);

            m_Players.m_iSpeed[iIndex] = 0;
        }

        private void m_FormToEnd(object sender, EventArgs e)
        {
            int iIndex = Convert.ToInt32(tbSelNo.Text);
            m_PlayHelper.m_GoEnd(m_Players.m_iArrID[iIndex]);

            m_Players.m_iSpeed[iIndex] = 0;
        }

        private void m_FormToHome(object sender, EventArgs e)
        {
            int iIndex = Convert.ToInt32(tbSelNo.Text);
            m_PlayHelper.m_GoBegin(m_Players.m_iArrID[iIndex]);

            m_Players.m_iSpeed[iIndex] = 0;
        }

        private void m_FormMakeFaster(object sender, EventArgs e)
        {
            int iIndex = Convert.ToInt32(tbSelNo.Text);

            m_Players.m_iSpeed[iIndex]++;
            if (m_Players.m_iSpeed[iIndex] <= 0)
            {
                m_Players.m_iSpeed[iIndex] = 1;
            }
            else if (m_Players.m_iSpeed[iIndex] >= 4)
            {
                m_Players.m_iSpeed[iIndex] = 4;
            }

            m_PlayHelper.m_FastForward(m_Players.m_iArrID[iIndex], m_Players.m_iSpeed[iIndex]);
        }

        private void m_FormMakeSlower(object sender, EventArgs e)
        {
            int iIndex = Convert.ToInt32(tbSelNo.Text);

            m_Players.m_iSpeed[iIndex]--;
            if (m_Players.m_iSpeed[iIndex] >= 0)
            {
                m_Players.m_iSpeed[iIndex] = -1;
            }
            else if (m_Players.m_iSpeed[iIndex] <= -4)
            {
                m_Players.m_iSpeed[iIndex] = -4;
            }
            m_PlayHelper.m_SlowForward(m_Players.m_iArrID[iIndex], Math.Abs(m_Players.m_iSpeed[iIndex]));
        }

        private void m_FormBackSearch(object sender, EventArgs e)
        {
            int iIndex = Convert.ToInt32(tbSelNo.Text);
            m_PlayHelper.m_FastBackward(m_Players.m_iArrID[iIndex]);
        }

        private void m_FormPlayerClose(object sender, EventArgs e)
        {
            int iIndex = Convert.ToInt32(tbSelNo.Text);
            m_Players.m_iSpeed[iIndex] = 0;
            m_PlayHelper.m_Stop(m_Players.m_iArrID[iIndex]);
            m_PlayHelper.m_DeletePlayer(m_Players.m_iArrID[iIndex]);
            m_Players.m_iArrID[iIndex] = -1;

            if (m_Players.m_fsArr[iIndex]!=null)
            {
                m_Players.m_fsArr[iIndex].Close();
                m_Players.m_fsArr[iIndex] = null;
            }
            m_panDisPlay[iIndex].Invalidate();

            for (int i = 0; i < 4;i++ )
            {
                if (m_Players.m_iArrID[i]!=-1)
                {
                    return;
                }
            }

            timerGetData.Stop();
        }

        private void m_FormCapYUV(object sender, EventArgs e)
        {
            int iIndex = Convert.ToInt32(tbSelNo.Text);
            if (m_Players.m_iArrID[iIndex]<0)
            {
                MessageBox.Show("Can't capture when no playing!");
                return;
            }

            string strFileName = "";
            saveFileDialog.CreatePrompt = true;
            DialogResult drRet = saveFileDialog.ShowDialog();
            if (DialogResult.OK==drRet)
            {
                if (saveFileDialog.FileName=="")
                {
                    MessageBox.Show("File name is empty!");
                    return;
                }
                strFileName = saveFileDialog.FileName;
                FileStream fs = new FileStream(strFileName, FileMode.OpenOrCreate,FileAccess.Write, FileShare.None);
                int iSize = 0;
                int iWidth = 0;
	            int iHeight = 0;
                int iFrameRate = 0;
                int iRet = m_PlayHelper.m_GetVideoParam(m_Players.m_iArrID[iIndex], ref iWidth, ref iHeight, ref iFrameRate);
                if(iRet < 0)
                {
                    MessageBox.Show("Can't capture for no playing!");
                    return;
                }

	            if (iWidth/iHeight >= 2)
	            {
		            iHeight *= 2;
	            } 
	            else if(iHeight/iWidth >= 2)
	            {
		            iWidth *= 2;
	            }

                Byte[] dataP=new Byte[iWidth*iHeight*2];
                iSize = m_PlayHelper.m_CapturePic(m_Players.m_iArrID[iIndex], dataP);
                Byte[] buff = new Byte[iWidth*iHeight*2];
                Array.Copy(buff, dataP, iSize);
                fs.Write(buff, 0, iSize);
                fs.Close();
            }

        }

        private void FormCapBmp(object sender, EventArgs e)
        {
            int iIndex = Convert.ToInt32(tbSelNo.Text);
            if (m_Players.m_iArrID[iIndex] < 0)
            {
                MessageBox.Show("Can't capture when no playing!");
                return;
            }
            
            string strPath = "C:\\capture\\";
            if (!Directory.Exists(strPath))
            {
                try
                {
                    Directory.CreateDirectory(strPath);  
                }
                catch
                {
                    return;
                }
                
            }

            DateTime dtNow = DateTime.Now;
            string strtmIn = dtNow.Year.ToString() + dtNow.Month.ToString() + dtNow.Day.ToString() +
                dtNow.Hour.ToString() + dtNow.Minute.ToString() + dtNow.Second.ToString();
            string strFileName = strPath+strtmIn+m_iBMPNum.ToString() + ".bmp";
            m_iBMPNum++;
            int iCapRet = 0;
            if ((iCapRet = m_PlayHelper.m_CaptureBmpPic(m_Players.m_iArrID[iIndex], strFileName)) < 0)
            {
                MessageBox.Show("Parameter error");
                return;
            }
        }

        private void FormAdOpen(object sender, EventArgs e)
        {
            int iIndex = Convert.ToInt32(tbSelNo.Text);
            if (m_Players.m_iArrID[iIndex]==-1)
            {
                return;
            }
            if (button6.Text == "AudioOpen")
            {
                for (int i = 0; i < 4;i++ )
                {
                    m_PlayHelper.m_StopAudio(m_Players.m_iArrID[i]);
                    m_Players.m_iAudioArr[i] = -1;
                }
                m_PlayHelper.m_PlayAudio(m_Players.m_iArrID[iIndex]);
                m_Players.m_iAudioArr[iIndex] = 0;
                button6.Text = "AudioStop";
            }
            else
            {
                m_PlayHelper.m_StopAudio(m_Players.m_iArrID[iIndex]);
                m_Players.m_iAudioArr[iIndex] = -1;
                button6.Text = "AudioOpen";
            }
        }

        private void OnTMRSetTB(object sender, EventArgs e)
        {
            int iIndex = Convert.ToInt32(tbSelNo.Text);
            int iPlayingNum=m_PlayHelper.m_GetPlayingFrameNum(m_Players.m_iArrID[iIndex]);
            int iFrameCount=m_PlayHelper.m_GetFrameCount(m_Players.m_iArrID[iIndex]);
            int tbPos=0;
            if (iFrameCount>0)
            {
                tbPos = (iPlayingNum * 100) / iFrameCount;
                this.Text = iPlayingNum.ToString() + "/" + iFrameCount.ToString();
            }
            else
            {
                string strSDKVersion = "PlayDemo ";
                this.Text = strSDKVersion;
            }
            
            if(tbPos>100)
            {
                tbPos = 100;
            }
                
            tbPlayCtrl.Value = tbPos;
        }

        private void OnTMRGetData(object sender, EventArgs e)
        {
            //Trace.WriteLine(timerGetData.Interval);
            long lCurCount = 0;
            int iReadCount = 0;
            for (int i = 0; i < 4;i++ )
            {
                if (m_Players.m_iArrID[i] != -1&&m_Players.m_fsArr[i] != null)
                {
                    //m_Players.m_fsArr[i].Seek(0, SeekOrigin.Current);
                    lCurCount = m_Players.m_fsArr[i].Position;
                    iReadCount = m_Players.m_fsArr[i].Read(m_Players.m_fileDataBuff[i], 0, MAX_READBUFFER);

                    if (iReadCount==0)
                    {
                        if (m_Players.m_fsArr[i] != null)
                        {
                            m_Players.m_fsArr[i].Close();
                            m_Players.m_fsArr[i] = null;
                        }
                        m_PlayHelper.m_SetVoDPlayerOver(m_Players.m_iArrID[i]);
                        continue;
                    }

                    int iInputRet = m_PlayHelper.m_PutStreamToPlayer(m_Players.m_iArrID[i], m_Players.m_fileDataBuff[i], iReadCount);

                    //Trace.WriteLine(iInputRet);
                    if (iInputRet == RET_BUFFER_WILL_BE_FULL || iInputRet == RET_FRAMELIST_WILL_BE_FULL)
                    {
                        if (numericUpDown1.Value!=numericUpDown1.Maximum)
                        {
                            //m_PlayHelper.m_SetCleanVoDBuffer(m_Players.m_iArrID[i]);
                            m_ChangePutSpeed(eSpeedType.SPEED_DEC);
                        }                       
                    }
                    else if (iInputRet == RET_BUFFER_WILL_BE_EMPTY || iInputRet == RET_FRAMELIST_WILL_BE_EMPTY || iInputRet == RET_FRAMELIST_FEW)
                    {
                        if (numericUpDown1.Value!=numericUpDown1.Minimum)
                        {
                            m_ChangePutSpeed(eSpeedType.SPEED_ADD);
                        }
                    }
                    else if (iInputRet == RET_FRAMELIST_FULL || iInputRet == RET_BUFFER_FULL)
                    {
                        m_Players.m_fsArr[i].Seek(lCurCount, SeekOrigin.Begin);
                    }
                }
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (timerGetData.Enabled)
            {
                timerGetData.Stop();
            }
            if (timerSetTB.Enabled)
            {
                timerSetTB.Stop();
            }
            for (int i = 0; i < 4; i++ )
            {
                if (m_Players.m_iArrID[i]!=-1)
                {
                    m_PlayHelper.m_DeletePlayer(m_Players.m_iArrID[i]);
                }
            }

            if (m_FormZoomIn!=null)
            {
                m_FormZoomIn.Close();
            }

            m_PlayHelper.m_StopMonitorCPU();
            m_PlayHelper.m_DeleteSystem();
        }

        private void tbPlayCtrl_Scroll(object sender, EventArgs e)
        {
            int iIndex = Convert.ToInt32(tbSelNo.Text);
            int iSeekFrm = (tbPlayCtrl.Value * m_PlayHelper.m_GetFrameCount(m_Players.m_iArrID[iIndex])) / 100;
            m_PlayHelper.m_Seek(m_Players.m_iArrID[iIndex], iSeekFrm);
        }

        private void m_SeekTo(object sender, EventArgs e)
        {
            if (SeekFrameNo.Text=="")
            {
                MessageBox.Show("Please input your seek No.");
                return;
            }
            int iIndex = Convert.ToInt32(tbSelNo.Text);
            int iSeekFrm = Convert.ToInt32(SeekFrameNo.Text);
            int iBegin = 0;
            int iEnd = 0;

            if (m_PlayHelper.m_GetBeginEnd(m_Players.m_iArrID[iIndex], ref iBegin, ref iEnd) != 0)
            {
                return;
            }

            if (iSeekFrm<iBegin||iSeekFrm>iEnd)
            {
                MessageBox.Show("Out of range!");
                return;
            }

            m_PlayHelper.m_Seek(m_Players.m_iArrID[iIndex], iSeekFrm);
            m_Players.m_iSpeed[iIndex] = 0;
        }

        //重载消息循环
        protected override void DefWndProc(ref Message m)
        {
            int iID=0;
            switch(m.Msg)
            {
                case WM_CUSTOMMSG:
                    iID=(int)m.LParam;
                    m_OnPlayEnd(iID);
                    break;
                case MSG_PLAYSDKM4:
                    iID = (int)m.WParam;
                    int iMsgId = (int)m.LParam;
                    if (LPARAM_VOD_STREAM_END == iMsgId)
                    {
                        m_OnPlayEnd(iID);
                    }
                    break;
            }
            base.DefWndProc(ref m);
        }
    }
}
