using System; using System.Collections.Generic; using System.Net.Sockets; using System.Net; using System.Text; using System.Threading; using nRTP; using System.Windows.Forms; using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Reflection; using UTIL; namespace UDPLIB { public class Data { public static string Ver = "1.1.2.264"; protected static string IPAddr = "192.168.1.2"; protected static Int32 LocalPort = 5004; protected static Int32 RemotePort = 5006; #if DEBUG public static string Conf = "Debug"; #else public static string Conf = "Release"; #endif } public class UDPreceive : Data { //Int32 localPort = 5004; //Int32 remotePort = 5006; Thread UDPreceiveThread = null; // Thread processFrameThread = null; Thread sendFrameThread = null; // Thread processDataFrameThread = null; Stopwatch fpstimer; private volatile bool listening = false; UInt16 iwidth = 0; UInt16 iheight = 0; List udata50 = new List(); List udata51 = new List(); UInt32 cnt_frames = 0; Res2 rrr2 = new Res2(); // класс ресурсов на замену Res #region Прием данных public UDPreceive(Int32 localPortUDP) { LocalPort = localPortUDP; for (int i = 0; i < 2500; i++) { udata50.Add(new Byte[0]); udata51.Add(new Byte[0]); } fpstimer = new Stopwatch(); UDPreceiveThread = new Thread(new ThreadStart(UDPReceive7)); listening = true; UDPreceiveThread.Start(); cnt_frames = 0; } public UDPreceive() { for (int i = 0; i < 2500; i++) { udata50.Add(new Byte[0]); udata51.Add(new Byte[0]); } fpstimer = new Stopwatch(); UDPreceiveThread = new Thread(new ThreadStart(UDPReceive7)); listening = true; UDPreceiveThread.Start(); cnt_frames = 0; } public void Stop() { listening = false; cnt_frames = 0; } public Boolean IsAlive { get { if (UDPreceiveThread == null || !UDPreceiveThread.IsAlive) return false; else return true; } } void UDPReceive7() { UdpClient receiver = null; IPEndPoint endPoint = null; EndPoint remoteIp = null; DialogResult res = DialogResult.OK; try { // receiver = new UdpClient(localPort); receiver = new UdpClient(LocalPort); endPoint = new IPEndPoint(IPAddress.Any, LocalPort); remoteIp = new IPEndPoint(IPAddress.Any, 0); } catch (Exception ee) { res = MessageBox.Show("Порт " + LocalPort.ToString() + " используется како-то программой. \r\n" + "Прием видео невозможен. Перезапустите программу.", "Ошибка!!!", MessageBoxButtons.OK, MessageBoxIcon.Error); System.Diagnostics.Process.GetCurrentProcess().Kill(); return; } Int32 numrow = 0; Int32 numlist = 0; Int32 prevnumrow = 0; Byte[] imgarr = new Byte[1]; Byte[] blackline = null; fpstimer.Start(); while (listening) { try { UInt32 packetsize = 0; UInt32 ssrc = 0; if (receiver.Available == 0) continue; byte[] data = receiver.Receive(ref endPoint); numrow = BitConverter.ToUInt16(data, 16); packetsize = (UInt32)data.Length; ssrc = BitConverter.ToUInt32(data, 8); prevnumrow = numrow; if (ssrc == 12345678) { switch (numlist) { case 0: udata50[numrow] = data; break; case 1: udata51[numrow] = data; break; } } if (numrow == 0 && ssrc == 12345678) // Packet 0 { //iwidth = BitConverter.ToUInt16(data, 20); //iheight = BitConverter.ToUInt16(data, 22); blackline = new Byte[iwidth * 3 + 20]; RTP.DataH0 = data; RTP.GetDataH0(); //Res.Iwidth = iwidth; //Res.Iheight = iheight; //Res.AzUpr = BitConverter.ToSingle(data, 24); //Res.ElUpr = BitConverter.ToSingle(data, 28); //Res.Course = BitConverter.ToInt16(data, 32); //Res.Roll = BitConverter.ToInt16(data, 34); //Res.Pitch = BitConverter.ToInt16(data, 36); iwidth = RTP.SD_Width; iheight = RTP.SD_Height; Res.Iwidth = RTP.SD_Width; Res.Iheight = RTP.SD_Height; Res.AzUpr = RTP.SD_AzUpr; Res.ElUpr = RTP.SD_ElUpr; Res.Course = RTP.SD_Course; Res.Roll = RTP.SD_Roll; Res.Pitch = RTP.SD_Pitch; Res.Shirota = RTP.SD_Shirota; Res.Dolgota = RTP.SD_Dolgota; Res.Vysota = RTP.SD_Vysota; Res.rejim_oes = RTP.SD_rejim_oes; Res.zahvat = RTP.SD_zahvat; Res.color = RTP.SD_color; rrr2.Iwidth = RTP.SD_Width; rrr2.Iheight = RTP.SD_Height; rrr2.AzUpr = RTP.SD_AzUpr; rrr2.ElUpr = RTP.SD_ElUpr; rrr2.Course = RTP.SD_Course; rrr2.Roll = RTP.SD_Roll; rrr2.Pitch = RTP.SD_Pitch; rrr2.Shirota = RTP.SD_Shirota; rrr2.Dolgota = RTP.SD_Dolgota; rrr2.Vysota = RTP.SD_Vysota; rrr2.rejim_oes = RTP.SD_rejim_oes; rrr2.zahvat = RTP.SD_zahvat; rrr2.color = RTP.SD_color; } if (data[1] == 0xC7 && iheight != 0 && iwidth != 0) { switch (numlist) { case 0: { Thread sendFrame0 = new Thread(new ParameterizedThreadStart(processFrame7)); sendFrame0.Start(new thrdata(0, iwidth, iheight)); sendFrame0.IsBackground = true; } numlist = 1; break; case 1: { Thread sendFrame1 = new Thread(new ParameterizedThreadStart(processFrame7)); sendFrame1.Start(new thrdata(1, iwidth, iheight)); sendFrame1.IsBackground = true; } numlist = 0; break; } } } catch (Exception ee) { using (StreamWriter sw = new StreamWriter(System.IO.File.OpenWrite("udplib.log"))) { sw.WriteLine($"{DateTime.Now.ToString("HH:mm:ss:fff ")} Error dll recv\r\n{ee.Message}"); } } } receiver.Close(); } void processFrame7(object obj) { try { thrdata arr = obj as thrdata; List udata = new List(); ushort prevnumrow = 0, numrow = 0; UInt32 cnt_frame = 0; int iwi = 0; int ihe = 0; switch (arr.arr) { case 0: udata.AddRange(udata50); break; case 1: udata.AddRange(udata51); break; } iwi = BitConverter.ToUInt16(udata[0], 20); ihe = BitConverter.ToUInt16(udata[0], 22); Bitmap img = new Bitmap(iwi, ihe, System.Drawing.Imaging.PixelFormat.Format24bppRgb); Rectangle rect = new Rectangle(0, 0, iwi, ihe); unsafe { BitmapData bmpData = img.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, img.PixelFormat); byte* curpos = ((Byte*)bmpData.Scan0); prevnumrow = numrow; cnt_frame++; int dd = 0; int ff = 0; try { for (int h = 1; h < ihe + 1; h++) { dd = h; for (int w = 20; w < iwi * 3 + 20; w += 3) { ff = w; if (udata[h].Length < (iwi * 3 + 20)) { curpos += 3; break; } *(curpos++) = udata[h][w + 2]; *(curpos++) = udata[h][w + 1]; *(curpos++) = udata[h][w + 0]; } } } catch (Exception ee) { Console.WriteLine($"!!! {ee.Message} {dd} {ff} {udata[dd].Length}"); return; } udata.Clear(); img.UnlockBits(bmpData); } Res.Clearimg = (Bitmap)img.Clone(); Res.Bmp = img; rrr2.Clearimg = (Bitmap)img.Clone(); rrr2.Bmp = img; fpstimer.Stop(); // Res.Fps = gk.filtered(1000F / fpstimer.ElapsedMilliseconds); Res.Fps = 1000F / fpstimer.ElapsedMilliseconds; Res.Frames = cnt_frames++; rrr2.Fps = 1000F / fpstimer.ElapsedMilliseconds; rrr2.Frames = cnt_frames++; // Res.Fps = 1000F / fpstimer.ElapsedMilliseconds; fpstimer.Reset(); fpstimer.Start(); CallBack.Event_newimg_Handler2(rrr2); } catch (Exception) { using (StreamWriter sw = new StreamWriter(System.IO.File.OpenWrite("udplib.log"))) { sw.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff ") + "Error lib process"); } } } #endregion } public class UDPTransmit : Data { UdpClient transmitter = null; IPEndPoint endPoint = null; UInt16 pntX = 0; UInt16 pntY = 0; UInt16 pntlx = 0; UInt16 pntly = 0; //public UDPTransmit(String IPaddr, Int32 remotePortUDP, Point p) //{ // transmitter = new UdpClient(); // endPoint = new IPEndPoint(IPAddress.Parse(IPaddr), remotePortUDP); // pnt = p; // pnt.X = Util.minmax((ushort)64, (ushort)576, (ushort)pnt.X); // pnt.Y = Util.minmax((ushort)64, (ushort)416, (ushort)pnt.Y); // Bitmap crop = Res.Clearimg.Clone(new Rectangle(pnt.X - 64, pnt.Y - 64, 128, 128), PixelFormat.Format24bppRgb); // Res.Crop = crop; // Thread UDPtransmitThread = new Thread(new ThreadStart(UDPtransmitFrame)); // UDPtransmitThread.Start(); //} public UDPTransmit(String IPaddr, Int32 remotePortUDP, (UInt16, UInt16, UInt16, UInt16) p) { transmitter = new UdpClient(); endPoint = new IPEndPoint(IPAddress.Parse(IPaddr), remotePortUDP); pntX = p.Item1; // X координата pntY = p.Item2; // Y координата pntlx = p.Item3; // ширина эталона pntly = p.Item4; // высота эталона Res.Crop = Res.Clearimg.Clone(new Rectangle(pntX - pntlx / 2, pntY - pntly / 2, pntlx, pntly), PixelFormat.Format24bppRgb); Thread UDPtransmitThread = new Thread(new ThreadStart(UDPtransmitFrame)); UDPtransmitThread.Start(); } public UDPTransmit((UInt16, UInt16, UInt16, UInt16) p) { transmitter = new UdpClient(); endPoint = new IPEndPoint(IPAddress.Parse(IPAddr), RemotePort); pntX = p.Item1; // X координата pntY = p.Item2; // Y координата pntlx = p.Item3; // ширина эталона pntly = p.Item4; // высота эталона Res.Crop = Res.Clearimg.Clone(new Rectangle(pntX - pntlx / 2, pntY - pntly / 2, pntlx, pntly), PixelFormat.Format24bppRgb); Thread UDPtransmitThread = new Thread(new ThreadStart(UDPtransmitFrame)); UDPtransmitThread.Start(); } public UDPTransmit(String IPaddr, Int32 remotePortUDP, Bitmap crop) { transmitter = new UdpClient(); endPoint = new IPEndPoint(IPAddress.Parse(IPaddr), remotePortUDP); Res.Crop = crop; Thread UDPtransmitThread = new Thread(new ThreadStart(UDPtransmitFrame)); UDPtransmitThread.Start(); } void UDPtransmitFrame() { transmitter.Connect(endPoint); // RTPMsgHeader RTPet.MH_VerPXCC = 2; RTPet.MH_MPT = 0xC6; RTPet.SeqCounter = 0; //! RTPet.MH_Timestamp = (uint)DateTimeOffset.Now.ToUnixTimeSeconds(); //! RTPet.MH_PT = 99; RTPet.MH_M = 0; RTPet.MH_SSRC = 12345678; RTPet.MH_DataLen = (UInt16)(RTPet.DataH0.Length - RTPet.DataH1.Length); RTPet.MH_RowNumber = 0; RTPet.MH_Offset = 0; // RTPVideoSupplementalData RTPet.SD_Width = (ushort)Res.Crop.Width; RTPet.SD_Height = (ushort)Res.Crop.Height; RTPet.SD_AzUpr = RTP.SD_AzUpr; RTPet.SD_ElUpr = RTP.SD_ElUpr; RTPet.SD_Shirota = RTP.SD_Shirota; RTPet.SD_Dolgota = RTP.SD_Dolgota; RTPet.SD_Vysota = RTP.SD_Vysota; RTPet.SD_Course = RTP.SD_Course; RTPet.SD_Roll = RTP.SD_Roll; RTPet.SD_Pitch = RTP.SD_Pitch; RTPet.SD_X = pntX; RTPet.SD_Y = pntY; RTPet.SD_lx = (Byte)pntlx; RTPet.SD_ly = (Byte)pntly; RTPet.SD_rejim_oes = RTP.SD_rejim_oes; RTPet.SD_color = RTP.SD_color; RTPet.MakeDataH0(); transmitter.Send(RTPet.DataH0, RTPet.DataH0.Length); Byte[] dataudp = new Byte[20 + RTPet.SD_Width * 3]; Byte[] dataimg = new Byte[RTPet.SD_Width * 3]; for (int i = 0; i < RTPet.SD_Height; i++) { // RTPMsgHeader RTPet.MH_VerPXCC = 2; if (i == RTPet.SD_Height - 1) { RTPet.MH_PT = 99; RTPet.MH_M = 1; } else { RTPet.MH_PT = 99; RTPet.MH_M = 0; } ++RTPet.SeqCounter; RTPet.MH_RowNumber = (ushort)(i + 1); RTPet.MH_DataLen = (ushort)(RTPet.SD_Width * 3); RTPet.MakeDataH1(); uint ccc = 0; try { for (int j = 0; j < RTPet.SD_Width; j++) { Color c = Res.Crop.GetPixel(j, i); dataimg[ccc++] = c.B; dataimg[ccc++] = c.G; dataimg[ccc++] = c.R; } } catch (Exception ee) { Console.WriteLine(ee.Message); Console.WriteLine("Error 4 getpixel"); return; } Array.Copy(RTPet.DataH1, dataudp, RTPet.DataH1.Length); Array.Copy(dataimg, 0, dataudp, RTPet.DataH1.Length, dataimg.Length); transmitter.Send(dataudp, dataudp.Length); } transmitter.Close(); CallBack.Event_crop_transmitted_Handler(); } } public class UDPTransmitSim : Data { UdpClient transmitter = null; IPEndPoint endPoint = null; Point pnt; Int32 sizeX = 0; Int32 sizeY = 0; Int32 delayMS = 0; public Bitmap img = null; // Resources.che1; volatile Boolean flag = false; Thread UDPtransmitThread = null; Stopwatch fpstmr; private UInt32 cnt_frame = 0; float fps = 0; public UDPTransmitSim(String ipaddr, Int32 remotePortUDP, Int32 sizeX, Int32 sizeY, Int32 delayMS) { transmitter = new UdpClient(); endPoint = new IPEndPoint(IPAddress.Parse(ipaddr), remotePortUDP); this.sizeX = sizeX; this.sizeY = sizeY; this.delayMS = delayMS; img = new Bitmap(Res.Sim, new Size(sizeX, sizeY)); UDPtransmitThread = new Thread(new ThreadStart(UDPtransmitFrame)); UDPtransmitThread.Start(); Start(); fpstmr = new Stopwatch(); } public UDPTransmitSim(Int32 sizeX, Int32 sizeY, Int32 delayMS) { transmitter = new UdpClient(); endPoint = new IPEndPoint(IPAddress.Parse(IPAddr), RemotePort); this.sizeX = sizeX; this.sizeY = sizeY; this.delayMS = delayMS; img = new Bitmap(Res.Sim, new Size(sizeX, sizeY)); UDPtransmitThread = new Thread(new ThreadStart(UDPtransmitFrame)); UDPtransmitThread.Start(); Start(); fpstmr = new Stopwatch(); } public UDPTransmitSim(String IPaddr, Int32 remotePortUDP, Int32 delayMS, Bitmap i) { transmitter = new UdpClient(); endPoint = new IPEndPoint(IPAddress.Parse(IPaddr), remotePortUDP); sizeX = i.Width; sizeY = i.Height; this.delayMS = delayMS; img = new Bitmap(i); UDPtransmitThread = new Thread(new ThreadStart(UDPtransmitFrame)); UDPtransmitThread.Start(); Start(); fpstmr = new Stopwatch(); } public void Start() { flag = true; } public void Stop() { flag = false; } void UDPtransmitFrame() { transmitter.Connect(endPoint); Res.Frames = 0; //cnt_frame = 0; while (flag) { fpstmr.Start(); // RTPMsgHeader RTP.MH_VerPXCC = 2; RTP.MH_MPT = 0xC6; RTP.SeqCounter = 0; //! RTP.MH_Timestamp = (uint)DateTimeOffset.Now.ToUnixTimeSeconds(); //! RTP.MH_PT = 99; RTP.MH_M = 0; RTP.MH_SSRC = 12345678; RTP.MH_DataLen = (UInt16)(RTP.DataH0.Length - RTP.DataH1.Length); RTP.MH_RowNumber = 0; RTP.MH_Offset = 0; // RTPVideoSupplementalData RTP.SD_Width = (UInt16)sizeX; RTP.SD_Height = (UInt16)sizeY; RTP.SD_AzUpr = 0; RTP.SD_ElUpr = 0; RTP.SD_Shirota = Res.Shirota; RTP.SD_Dolgota = Res.Dolgota; RTP.SD_Vysota = Res.Vysota; RTP.SD_Course = Res.Course; RTP.SD_Roll = Res.Roll; RTP.SD_Pitch = Res.Pitch; //RTP.SD_X = pntX; //RTP.SD_Y = pntY; //RTP.SD_lx = (Byte)pntlx; //RTP.SD_ly = (Byte)pntly; RTP.SD_rejim_oes = Res.rejim_oes; RTP.SD_color = Res.color; RTP.SD_zahvat = Res.zahvat; // Console.WriteLine($"{RTP.SD_rejim_oes} {RTP.SD_zahvat} {RTP.SD_color} {RTP.SD_Status} {Res.status}"); //Console.WriteLine($"{RTP.SD_color} {RTP.SD_zahvat} {RTP.SD_rejim_oes} {RTP.SD_Status}"); RTP.MakeDataH0(); transmitter.Send(RTP.DataH0, RTP.DataH0.Length); Byte[] dataudp = new Byte[20 + RTP.SD_Width * 3]; Byte[] dataimg = new Byte[RTP.SD_Width * 3]; for (int i = 0; i < sizeY; i++) { // RTPMsgHeader RTP.MH_VerPXCC = 2; if (i == (sizeY - 1)) { RTP.MH_PT = 99; RTP.MH_M = 1; } else { RTP.MH_PT = 99; RTP.MH_M = 0; } ++RTP.SeqCounter; RTP.MH_RowNumber = (ushort)(i + 1); RTP.MH_DataLen = (ushort)(RTP.SD_Width * 3); RTP.MakeDataH1(); uint ccc = 0; try { for (int j = 0; j < sizeX; j++) { Color c = img.GetPixel(j, i); dataimg[ccc++] = c.R; dataimg[ccc++] = c.G; dataimg[ccc++] = c.B; } } catch (Exception ee) { Console.WriteLine(ee.Message); Console.WriteLine("Error 4 getpixel"); return; } Array.Copy(RTP.DataH1, dataudp, RTP.DataH1.Length); Array.Copy(dataimg, 0, dataudp, RTP.DataH1.Length, dataimg.Length); transmitter.Send(dataudp, dataudp.Length); } Res.Frames++; // transmitter.Close(); fpstmr.Stop(); fps = 1000F / fpstmr.ElapsedMilliseconds; Res.Fps = fps; fpstmr.Reset(); cnt_frame++; CallBack.Event_transmitted_Handler(); Thread.Sleep(delayMS); } Res.Frames = 0; Res.Fps = 0; CallBack.Event_transmitted_Handler(); transmitter.Close(); transmitter.Dispose(); } public void Dispose() { if (img != null) { UDPtransmitThread.Abort(); img.Dispose(); } flag = false; } } class thrdata { public uint arr; public uint iw; public uint ih; public thrdata(uint a, uint w, uint h) { arr = a; iw = w; ih = h; } } public static class Res { public static Bitmap Bmp { set; get; } public static Bitmap Sim { set; get; } public static Bitmap Crop { set; get; } public static Bitmap Clearimg { set; get; } public static UInt16 Iwidth { set; get; } public static UInt16 Iheight { set; get; } public static UInt32 Frames { set; get; } public static float Fps { set; get; } public static float AzUpr { set; get; } public static float ElUpr { set; get; } public static Int16 Course { set; get; } public static Int16 Roll { set; get; } public static Int16 Pitch { set; get; } public static Int32 Shirota { set; get; } public static Int32 Dolgota { set; get; } public static Int32 Vysota { set; get; } public static UInt16 X { set; get; } public static UInt16 Y { set; get; } public static Byte lx { set; get; } public static Byte ly { set; get; } public static Byte rejim_oes { set; get; } // Режим ОЭС: «0» – Обзор, «1» – АС public static Byte zahvat { set; get; } // Захват: «0» – отсутствие захвата, «1» – наличие захвата public static Byte color { set; get; } // Цвет изображения: «1» – цветное, «0» – монохромное public static String Version { get => Data.Ver; } public static String Configuration { get => Data.Conf; } public static Boolean status_rs { set; get; } public static Boolean status_eth { set; get; } public static float Az { set; get; } public static float El { set; get; } //public static Byte status //{ // get // { // status = 0; // status |= (Byte)(rejim_oes << 0); // status |= (Byte)(zahvat << 1); // status |= (Byte)(color << 2); // return status; // } // set // { // status = value; // rejim_oes = (Byte)((value >> 0) & 0x01); // zahvat = (Byte)((value >> 1) & 0x01); // color = (Byte)((value >> 2) & 0x01); // } //} } public class Res2 { public Bitmap Bmp; public Bitmap Crop; public Bitmap Clearimg; public UInt16 Iwidth; public UInt16 Iheight; public UInt32 Frames; public float Fps; public float AzUpr; public float ElUpr; public Int32 Shirota; public Int32 Dolgota; public Int32 Vysota; public Int16 Course; public Int16 Roll; public Int16 Pitch; public UInt16 X; public UInt16 Y; public Byte lx; public Byte ly; public Byte rejim_oes; // Режим ОЭС: «0» – Обзор, «1» – АС public Byte zahvat; // Захват: «0» – отсутствие захвата, «1» – налачие захвата public Byte color; // Цвет изображения: «1» – цветное, «0» – монохромное public String Version { get => Data.Ver; } public String Configuration { get => Data.Conf; } public Boolean status_rs { set; get; } public Boolean status_eth { set; get; } } public static class CallBack { public delegate void Event_newimg(); public static Event_newimg Event_newimg_Handler; public delegate void Event_crop_transmitted(); public static Event_crop_transmitted Event_crop_transmitted_Handler; public delegate void Event_newimg2(Res2 data); public static Event_newimg2 Event_newimg_Handler2; public delegate void Event_transmitted(); public static Event_transmitted Event_transmitted_Handler; } }