/// <summary> /// Parse the MJPG stream. This should only return in the case of an /// exception accuring. /// </summary> /// <exception cref="System.ApplicationException">Thrown when /// there is a problem with the handling of the stream. See the /// string description for more information.</exception> //private void getFrames() private void getFrames(object sender, DoWorkEventArgs ev) { BackgroundWorker bw = sender as BackgroundWorker; string strHeader = "--myboundary\r\nContent-Type: image/jpeg\r\nContent-Length: "; byte[] headerBuffer = new byte[strHeader.Length]; string strHeaderBuffer = ""; int bytesRead = 0; // Set the URL to request //string strRequest = this.camParams.MjpgParameterString(); string strRequest = AxisParameters.MjpgParameterString(this.cameraConfig); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(strRequest); // set the username and password if (this.cameraConfig.User != null && this.cameraConfig.Password != null) { request.Credentials = new NetworkCredential( this.cameraConfig.User, this.cameraConfig.Password ); } this.doInfo(this, new ScallopInfoEventArgs("Trying Axis camera with URL " + request.RequestUri.ToString())); HttpWebResponse streamResponse = (HttpWebResponse)request.GetResponse(); this.doInfo(this, new ScallopInfoEventArgs("Server responded with : " + streamResponse.StatusDescription)); using (BufferedStream mjpgStream = new BufferedStream(streamResponse.GetResponseStream())) { this.streaming = true; this.doOpened(this, EventArgs.Empty); while (true) { int contentLen = 0; string aLine = ""; if (bw.CancellationPending == true) { mjpgStream.Close(); ev.Cancel = true; return; } /* * HTTP/1.0 200 OK\r\n * Content-Type: multipart/x-mixed-replace;boundary=myboundary\r\n * \r\n * --myboundary\r\n * Content-Type: image/jpeg\r\n * Content-Length: 15656\r\n * \r\n * <JPEG image data>\r\n * --myboundary\r\n * Content-Type: image/jpeg\r\n * Content-Length: 14978\r\n * \r\n * <JPEG image data>\r\n * --myboundary\r\n * Content-Type: image/jpeg\r\n * Content-Length: 15136\r\n * \r\n * <JPEG image data>\r\n * --myboundary\r\n * . * . * .*/ bytesRead = 0; // Read --myboundary and Content-Type while ((bytesRead += mjpgStream.Read(headerBuffer, bytesRead, headerBuffer.Length - bytesRead)) < headerBuffer.Length) { // No op } strHeaderBuffer = System.Text.Encoding.UTF8.GetString(headerBuffer); if (!strHeaderBuffer.Equals(strHeader)) { throw new ScallopException("MJPEG header not found"); } aLine = readMjpgLine(mjpgStream); contentLen = int.Parse(aLine); aLine = readMjpgLine(mjpgStream); if (!String.IsNullOrEmpty(aLine)) // empty line { throw new ScallopException("Blank line not found"); } // buffer for MJPG frame data byte[] frameBuffer = new byte[contentLen]; bytesRead = 0; // read up to contentLen of data to frameBuffer while ((bytesRead += mjpgStream.Read(frameBuffer, bytesRead, contentLen - bytesRead)) < contentLen) { // No op } aLine = readMjpgLine(mjpgStream); switch (this.cameraConfig.FrameFormat) { case AxisCameraConfigTypeFrameFormat.Jpeg: this.doData(this, new ScallopSensorDataEventArgs(frameBuffer, "New frame")); break; case AxisCameraConfigTypeFrameFormat.SystemDrawingBitmap: using (MemoryStream pixelStream = new MemoryStream(frameBuffer)) { Bitmap streamBitmap = new Bitmap(pixelStream); Bitmap bmp = streamBitmap.Clone() as Bitmap; if (bmp != null) { this.doData(this, new ScallopSensorDataEventArgs(bmp, "New frame")); } streamBitmap.Dispose(); } break; case AxisCameraConfigTypeFrameFormat.SystemWindowsMediaImagingBitmapSource: JpegBitmapDecoder decoder = new JpegBitmapDecoder(new MemoryStream(frameBuffer), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); if (decoder.Frames[0] != null) { this.doData(this, new ScallopSensorDataEventArgs(decoder.Frames[0] as BitmapSource, "New frame")); } break; } } } }
/// <summary> /// Parse the MJPG stream. This should only return in the case of an /// exception accuring. /// </summary> /// <exception cref="System.ApplicationException">Thrown when /// there is a problem with the handling of the stream. See the /// string description for more information.</exception> //private void getFrames() private void getFrames(object sender, DoWorkEventArgs ev) { BackgroundWorker bw = sender as BackgroundWorker; string delimiter = "--myboundary"; // Set the URL to request //string strRequest = this.camParams.MjpgParameterString(); string strRequest = AxisParameters.MjpgParameterString(this.cameraConfig); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(strRequest); // set the username and password if (this.cameraConfig.User != null && this.cameraConfig.Password != null) { request.Credentials = new NetworkCredential( this.cameraConfig.User, this.cameraConfig.Password ); } this.doInfo(this, new ScallopInfoEventArgs("Trying Axis camera with URL " + request.RequestUri.ToString())); HttpWebResponse streamResponse = (HttpWebResponse)request.GetResponse(); this.doInfo(this, new ScallopInfoEventArgs("Server responded with : " + streamResponse.StatusDescription)); using (BufferedStream mjpgStream = new BufferedStream(streamResponse.GetResponseStream())) { // find the first boundary while (!(readMjpgLine(mjpgStream).Equals(delimiter))) { /* NO-OP */ } this.streaming = true; this.doOpened(this, EventArgs.Empty); while (true) { int contentLen = 0; string aLine; if (bw.CancellationPending == true) { mjpgStream.Close(); ev.Cancel = true; return; } aLine = readMjpgLine(mjpgStream); if (!aLine.StartsWith("Content-Type: image/jpeg")) { throw new ScallopException("Content-Type not found"); } aLine = readMjpgLine(mjpgStream); if (aLine.StartsWith("Content-Length:")) { contentLen = int.Parse(aLine.Substring(15)); } else { throw new ScallopException("Content-Length not found"); } aLine = readMjpgLine(mjpgStream); if (!String.IsNullOrEmpty(aLine)) // empty line { throw new ScallopException("Blank line not found"); } // buffer for MJPG frame data byte[] frameBuffer = new byte[contentLen]; int tmp = 0; // read up to contentLen of data to frameBuffer while ((tmp += mjpgStream.Read(frameBuffer, tmp, contentLen - tmp)) < contentLen) { // No op } aLine = readMjpgLine(mjpgStream); while (!aLine.StartsWith(delimiter)) { aLine = readMjpgLine(mjpgStream); } switch (this.cameraConfig.FrameFormat) { case AxisCameraConfigTypeFrameFormat.Jpeg: this.doData(this, new ScallopSensorDataEventArgs(frameBuffer, "New frame")); break; case AxisCameraConfigTypeFrameFormat.SystemDrawingBitmap: using (MemoryStream pixelStream = new MemoryStream(frameBuffer)) { Bitmap streamBitmap = new Bitmap(pixelStream); Bitmap bmp = streamBitmap.Clone() as Bitmap; if (bmp != null) { this.doData(this, new ScallopSensorDataEventArgs(bmp, "New frame")); } streamBitmap.Dispose(); } break; case AxisCameraConfigTypeFrameFormat.SystemWindowsMediaImagingBitmapSource: JpegBitmapDecoder decoder = new JpegBitmapDecoder(new MemoryStream(frameBuffer), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); if (decoder.Frames[0] != null) { this.doData(this, new ScallopSensorDataEventArgs(decoder.Frames[0] as BitmapSource, "New frame")); } break; } } } }