ardupilot/Tools/ArdupilotMegaPlanner/Utilities/CaptureMJPEG.cs
Michael Oborne 25bcfdd1e7 Mission Planner 1.2.12
add arduino chip detect
fix apm2,2.5 dialog test
add write timeout. this will stop planner hangs on bad serial devices.
change quickview decimal places to 0.00
fix map clicking issue.
fix wind direction wrapping
add airspeed use
modify firmware screen from Marooned
major flightdata tab change.
add save/load polygon from file
add some error handling dialogs
2012-09-20 07:37:36 +08:00

219 lines
6.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Drawing;
using System.Threading;
using log4net;
namespace ArdupilotMega.Utilities
{
public class CaptureMJPEG
{
private static readonly ILog log =
LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
static Thread asyncthread;
static bool running = false;
public static string URL = @"http://127.0.0.1:56781/map.jpg";
public static event EventHandler OnNewImage;
static DateTime lastimage = DateTime.Now;
static int fps = 0;
public static void runAsync()
{
while (asyncthread != null && asyncthread.IsAlive)
{
running = false;
}
asyncthread = new Thread(new ThreadStart(getUrl))
{
IsBackground = true,
Priority = ThreadPriority.BelowNormal,
Name = "mjpg stream reader"
};
asyncthread.Start();
}
public static void Stop()
{
running = false;
}
public static string ReadLine(BinaryReader br)
{
StringBuilder sb = new StringBuilder();
while (true) {
byte by = br.ReadByte();
sb.Append((char)by);
if (by == '\n')
break;
}
sb = sb.Replace("\r\n", "");
return sb.ToString();
}
static void getUrl()
{
running = true;
Bitmap frame = new Bitmap(640, 480);
try
{
// Create a request using a URL that can receive a post.
WebRequest request = HttpWebRequest.Create(URL);
// Set the Method property of the request to POST.
request.Method = "GET";
((HttpWebRequest)request).AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
request.Headers.Add("Accept-Encoding", "gzip,deflate");
// Get the response.
WebResponse response = request.GetResponse();
// Display the status.
log.Debug(((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
Stream dataStream = response.GetResponseStream();
BinaryReader br = new BinaryReader(dataStream);
// get boundary header
string mpheader = response.Headers["Content-Type"];
if (mpheader.IndexOf("boundary=") == -1)
{
ReadLine(br); // this is a blank line
string line = "proxyline";
do
{
line = ReadLine(br);
if (line.StartsWith("--"))
{
mpheader = line;
break;
}
} while (line.Length > 2);
}
else
{
int startboundary = mpheader.IndexOf("boundary=") + 9;
int endboundary = mpheader.Length;
mpheader = mpheader.Substring(startboundary, endboundary - startboundary);
}
dataStream.ReadTimeout = 30000; // 30 seconds
br.BaseStream.ReadTimeout = 30000;
while (running)
{
try
{
// get the multipart start header
int length = int.Parse(getHeader(br)["Content-Length"]);
// read boundary header
if (length > 0)
{
byte[] buf1 = new byte[length];
dataStream.ReadTimeout = 3000;
int offset = 0;
int len = 0;
while ((len = br.Read(buf1, offset, length)) > 0)
{
offset += len;
length -= len;
}
/*
BinaryWriter sw = new BinaryWriter(File.OpenWrite("test.jpg"));
sw.Write(buf1,0,buf1.Length);
sw.Close();
*/
try
{
frame = new Bitmap(new MemoryStream(buf1));
}
catch { }
fps++;
if (lastimage.Second != DateTime.Now.Second)
{
Console.WriteLine("MJPEG " + fps);
fps = 0;
lastimage = DateTime.Now;
}
if (OnNewImage != null)
OnNewImage(frame, new EventArgs());
}
// blank line at end of data
ReadLine(br);
}
catch (Exception ex) { log.Info(ex); break; }
}
// clear last image
if (OnNewImage != null)
OnNewImage(null, new EventArgs());
dataStream.Close();
response.Close();
}
catch (Exception ex) { log.Error(ex); }
running = false;
}
static void getUrlRTSP()
{
}
static Dictionary<string, string> getHeader(BinaryReader stream)
{
Dictionary<string, string> answer = new Dictionary<string, string>();
string line;
do
{
line = ReadLine(stream);
string[] items = line.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
if (items.Length == 2)
answer.Add(items[0].Trim(), items[1].Trim());
} while (line != "");
return answer;
}
}
}