ardupilot/Tools/ArdupilotMegaPlanner/Utilities/CaptureMJPEG.cs
Michael Oborne a5bd3c67c6 Mission Planner 1.2.10
add useritems to HUD
change hdop scale
fix posible follow me bug (, vs .)
fix posible friendly params bug (, vs .)
tweak flightdata log playback timming
fix gridv2 bug. if no waypoint had been done, the grid wold fail
tweak some mission upload potential issues
add ability to get param list from a log (from startup)
add ability to get the first wp list in a log, if wps where received in that log.
tweak video capture library timing
2012-08-30 20:51:29 +08:00

211 lines
5.9 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);
// 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";
while (line.Length > 2)
{
line = ReadLine(br);
if (line.StartsWith("--")) {
mpheader = line;
break;
}
}
}
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();
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;
}
}
}