// Worker thread private void WorkerThread( ) { // buffer to read stream byte[] buffer = new byte[bufSize]; // JPEG magic number byte[] jpegMagic = new byte[] { 0xFF, 0xD8, 0xFF }; int jpegMagicLength = 3; ASCIIEncoding encoding = new ASCIIEncoding( ); while (!stopEvent.WaitOne(0, false)) { // reset reload event reloadEvent.Reset( ); // HTTP web request HttpWebRequest request = null; // web responce WebResponse response = null; // stream for MJPEG downloading Stream stream = null; // boundary betweeen images (string and binary versions) byte[] boundary = null; string boudaryStr = null; // length of boundary int boundaryLen; // flag signaling if boundary was checked or not bool boundaryIsChecked = false; // read amounts and positions int read, todo = 0, total = 0, pos = 0, align = 1; int start = 0, stop = 0; // align // 1 = searching for image start // 2 = searching for image end try { // create request request = (HttpWebRequest)WebRequest.Create(source); // set user agent if (userAgent != null) { request.UserAgent = userAgent; } // set proxy if (proxy != null) { request.Proxy = proxy; } // set timeout value for the request request.Timeout = requestTimeout; // set login and password if ((login != null) && (password != null) && (login != string.Empty)) { request.Credentials = new NetworkCredential(login, password); } // set connection group name if (useSeparateConnectionGroup) { request.ConnectionGroupName = GetHashCode( ).ToString( ); } // force basic authentication through extra headers if required if (forceBasicAuthentication) { string authInfo = string.Format("{0}:{1}", login, password); authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo)); request.Headers["Authorization"] = "Basic " + authInfo; } // get response response = request.GetResponse( ); // check content type string contentType = response.ContentType; string[] contentTypeArray = contentType.Split('/'); // "application/octet-stream" if ((contentTypeArray[0] == "application") && (contentTypeArray[1] == "octet-stream")) { boundaryLen = 0; boundary = new byte[0]; } else if ((contentTypeArray[0] == "multipart") && (contentType.Contains("mixed"))) { // get boundary int boundaryIndex = contentType.IndexOf("boundary", 0); if (boundaryIndex != -1) { boundaryIndex = contentType.IndexOf("=", boundaryIndex + 8); } if (boundaryIndex == -1) { // try same scenario as with octet-stream, i.e. without boundaries boundaryLen = 0; boundary = new byte[0]; } else { boudaryStr = contentType.Substring(boundaryIndex + 1); // remove spaces and double quotes, which may be added by some IP cameras boudaryStr = boudaryStr.Trim(' ', '"'); boundary = encoding.GetBytes(boudaryStr); boundaryLen = boundary.Length; boundaryIsChecked = false; } } else { throw new Exception("Invalid content type."); } // get response stream stream = response.GetResponseStream( ); stream.ReadTimeout = requestTimeout; // loop while ((!stopEvent.WaitOne(0, false)) && (!reloadEvent.WaitOne(0, false))) { // check total read if (total > bufSize - readSize) { total = pos = todo = 0; } // read next portion from stream if ((read = stream.Read(buffer, total, readSize)) == 0) { throw new ApplicationException( ); } total += read; todo += read; // increment received bytes counter bytesReceived += read; // do we need to check boundary ? if ((boundaryLen != 0) && (!boundaryIsChecked)) { // some IP cameras, like AirLink, claim that boundary is "myboundary", // when it is really "--myboundary". this needs to be corrected. pos = ByteArrayUtils.Find(buffer, boundary, 0, todo); // continue reading if boudary was not found if (pos == -1) { continue; } for (int i = pos - 1; i >= 0; i--) { byte ch = buffer[i]; if ((ch == (byte)'\n') || (ch == (byte)'\r')) { break; } boudaryStr = (char)ch + boudaryStr; } boundary = encoding.GetBytes(boudaryStr); boundaryLen = boundary.Length; boundaryIsChecked = true; } // search for image start if ((align == 1) && (todo >= jpegMagicLength)) { start = ByteArrayUtils.Find(buffer, jpegMagic, pos, todo); if (start != -1) { // found JPEG start pos = start + jpegMagicLength; todo = total - pos; align = 2; } else { // delimiter not found todo = jpegMagicLength - 1; pos = total - todo; } } // search for image end ( boundaryLen can be 0, so need extra check ) while ((align == 2) && (todo != 0) && (todo >= boundaryLen)) { stop = ByteArrayUtils.Find(buffer, (boundaryLen != 0) ? boundary : jpegMagic, pos, todo); if (stop != -1) { pos = stop; todo = total - pos; // increment frames counter framesReceived++; // image at stop if ((NewFrame != null) && (!stopEvent.WaitOne(0, false))) { Bitmap bitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(buffer, start, stop - start)); // notify client NewFrame(this, new NewFrameEventArgs(bitmap)); // release the image bitmap.Dispose( ); bitmap = null; } // shift array pos = stop + boundaryLen; todo = total - pos; Array.Copy(buffer, pos, buffer, 0, todo); total = todo; pos = 0; align = 1; } else { // boundary not found if (boundaryLen != 0) { todo = boundaryLen - 1; pos = total - todo; } else { todo = 0; pos = total; } } } } } catch (ApplicationException) { // do nothing for Application Exception, which we raised on our own // wait for a while before the next try Thread.Sleep(250); } catch (ThreadAbortException) { break; } catch (Exception exception) { // provide information to clients if (VideoSourceError != null) { VideoSourceError(this, new VideoSourceErrorEventArgs(exception.Message)); } // wait for a while before the next try Thread.Sleep(250); } finally { // abort request if (request != null) { request.Abort( ); request = null; } // close response stream if (stream != null) { stream.Close( ); stream = null; } // close response if (response != null) { response.Close( ); response = null; } } // need to stop ? if (stopEvent.WaitOne(0, false)) { break; } } if (PlayingFinished != null) { PlayingFinished(this, ReasonToFinishPlaying.StoppedByUser); } }
// Worker thread private void WorkerThread( ) { // buffer to read stream byte[] buffer = new byte[bufSize]; // JPEG magic number byte[] jpegMagic = new byte[] { 0xFF, 0xD8, 0xFF }; int jpegMagicLength = 3; while (true) { // reset reload event reloadEvent.Reset( ); // HTTP web request HttpWebRequest request = null; // web responce WebResponse response = null; // stream for MJPEG downloading Stream stream = null; // boundary betweeen images byte[] boundary = null; // length of boundary int boundaryLen; // read amounts and positions int read, todo = 0, total = 0, pos = 0, align = 1; int start = 0, stop = 0; // align // 1 = searching for image start // 2 = searching for image end try { // create request request = (HttpWebRequest)WebRequest.Create(source); // set user agent if (userAgent != null) { request.UserAgent = userAgent; } // set timeout value for the request request.Timeout = requestTimeout; // set login and password if ((login != null) && (password != null) && (login != string.Empty)) { request.Credentials = new NetworkCredential(login, password); } // set connection group name if (useSeparateConnectionGroup) { request.ConnectionGroupName = GetHashCode( ).ToString( ); } // get response response = request.GetResponse( ); // check content type string contentType = response.ContentType; string[] contentTypeArray = contentType.Split('/'); if (!((contentTypeArray[0] == "multipart") && (contentType.Contains("mixed")))) { // provide information to clients if (VideoSourceError != null) { VideoSourceError(this, new VideoSourceErrorEventArgs("Invalid content type")); } request.Abort( ); request = null; response.Close( ); response = null; // need to stop ? if (stopEvent.WaitOne(0, true)) { break; } continue; } // get boundary ASCIIEncoding encoding = new ASCIIEncoding( ); string boudaryStr = contentType.Substring(contentType.IndexOf("boundary=", 0) + 9); boundary = encoding.GetBytes(boudaryStr); boundaryLen = boundary.Length; bool boundaryIsChecked = false; // get response stream stream = response.GetResponseStream( ); // loop while ((!stopEvent.WaitOne(0, true)) && (!reloadEvent.WaitOne(0, true))) { // check total read if (total > bufSize - readSize) { total = pos = todo = 0; } // read next portion from stream if ((read = stream.Read(buffer, total, readSize)) == 0) { throw new ApplicationException( ); } total += read; todo += read; // increment received bytes counter bytesReceived += read; // do we need to check boundary ? if (!boundaryIsChecked) { // some IP cameras, like AirLink, claim that boundary is "myboundary", // when it is really "--myboundary". this needs to be corrected. pos = ByteArrayUtils.Find(buffer, boundary, 0, todo); // continue reading if boudary was not found if (pos == -1) { continue; } for (int i = pos - 1; i >= 0; i--) { byte ch = buffer[i]; if ((ch == (byte)'\n') || (ch == (byte)'\r')) { break; } boudaryStr = (char)ch + boudaryStr; } boundary = encoding.GetBytes(boudaryStr); boundaryLen = boundary.Length; boundaryIsChecked = true; } // search for image start if (align == 1) { start = ByteArrayUtils.Find(buffer, jpegMagic, pos, todo); if (start != -1) { // found JPEG start pos = start; todo = total - pos; align = 2; } else { // delimiter not found todo = jpegMagicLength - 1; pos = total - todo; } } // search for image end while ((align == 2) && (todo >= boundaryLen)) { stop = ByteArrayUtils.Find(buffer, boundary, pos, todo); if (stop != -1) { pos = stop; todo = total - pos; // increment frames counter framesReceived++; // image at stop if ((NewFrame != null) && (!stopEvent.WaitOne(0, true))) { Bitmap bitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(buffer, start, stop - start)); // notify client NewFrame(this, new NewFrameEventArgs(bitmap)); // release the image bitmap.Dispose( ); bitmap = null; } // shift array pos = stop + boundaryLen; todo = total - pos; Array.Copy(buffer, pos, buffer, 0, todo); total = todo; pos = 0; align = 1; } else { // boundary not found todo = boundaryLen - 1; pos = total - todo; } } } } catch (WebException exception) { // provide information to clients if (VideoSourceError != null) { VideoSourceError(this, new VideoSourceErrorEventArgs(exception.Message)); } // wait for a while before the next try Thread.Sleep(250); } catch (ApplicationException) { // wait for a while before the next try Thread.Sleep(250); } catch (Exception) { } finally { // abort request if (request != null) { request.Abort( ); request = null; } // close response stream if (stream != null) { stream.Close( ); stream = null; } // close response if (response != null) { response.Close( ); response = null; } } // need to stop ? if (stopEvent.WaitOne(0, true)) { break; } } if (PlayingFinished != null) { PlayingFinished(this, ReasonToFinishPlaying.StoppedByUser); } }
private void WorkerThread() { byte[] buffer = new byte[0x80000]; byte[] needle = new byte[] { 0xff, 0xd8, 0xff }; int num = 3; do { this.reloadEvent.Reset(); HttpWebRequest request = null; WebResponse response = null; Stream responseStream = null; byte[] bytes = null; int sourceLength = 0; int offset = 0; int startIndex = 0; int num7 = 1; int index = 0; int num9 = 0; try { request = (HttpWebRequest)WebRequest.Create(this.source); if (this.userAgent != null) { request.UserAgent = this.userAgent; } request.Timeout = this.requestTimeout; if (((this.login != null) && (this.password != null)) && (this.login != string.Empty)) { request.Credentials = new NetworkCredential(this.login, this.password); } if (this.useSeparateConnectionGroup) { request.ConnectionGroupName = this.GetHashCode().ToString(); } response = request.GetResponse(); string contentType = response.ContentType; if ((contentType.Split(new char[] { '/' })[0] != "multipart") || !contentType.Contains("mixed")) { if (this.VideoSourceError != null) { this.VideoSourceError(this, new VideoSourceErrorEventArgs("Invalid content type")); } throw new ApplicationException(); } int num10 = contentType.IndexOf("boundary", 0); if (num10 != -1) { num10 = contentType.IndexOf("=", (int)(num10 + 8)); } if (num10 == -1) { if (this.VideoSourceError != null) { this.VideoSourceError(this, new VideoSourceErrorEventArgs("Invalid content type")); } throw new ApplicationException(); } string s = contentType.Substring(num10 + 1).Trim(new char[] { ' ', '"' }); ASCIIEncoding encoding = new ASCIIEncoding(); bytes = encoding.GetBytes(s); int length = bytes.Length; bool flag = false; responseStream = response.GetResponseStream(); while (!this.stopEvent.WaitOne(0, true) && !this.reloadEvent.WaitOne(0, true)) { if (offset > 0x7fc00) { offset = startIndex = sourceLength = 0; } int num3 = responseStream.Read(buffer, offset, 0x400); if (num3 == 0) { throw new ApplicationException(); } offset += num3; sourceLength += num3; this.bytesReceived += num3; if (flag) { goto Label_028A; } startIndex = ByteArrayUtils.Find(buffer, bytes, 0, sourceLength); if (startIndex == -1) { continue; } for (int i = startIndex - 1; i >= 0; i--) { byte num12 = buffer[i]; switch (num12) { case 10: case 13: goto Label_0276; } s = ((char)num12) + s; } Label_0276: bytes = encoding.GetBytes(s); length = bytes.Length; flag = true; Label_028A: if (num7 == 1) { index = ByteArrayUtils.Find(buffer, needle, startIndex, sourceLength); if (index != -1) { startIndex = index; sourceLength = offset - startIndex; num7 = 2; } else { sourceLength = num - 1; startIndex = offset - sourceLength; } } while ((num7 == 2) && (sourceLength >= length)) { num9 = ByteArrayUtils.Find(buffer, bytes, startIndex, sourceLength); if (num9 != -1) { startIndex = num9; sourceLength = offset - startIndex; this.framesReceived++; if ((this.NewFrame != null) && !this.stopEvent.WaitOne(0, true)) { Bitmap frame = (Bitmap)Image.FromStream(new MemoryStream(buffer, index, num9 - index)); this.NewFrame(this, new NewFrameEventArgs(frame)); frame.Dispose(); frame = null; } startIndex = num9 + length; sourceLength = offset - startIndex; Array.Copy(buffer, startIndex, buffer, 0, sourceLength); offset = sourceLength; startIndex = 0; num7 = 1; } else { sourceLength = length - 1; startIndex = offset - sourceLength; } } } } catch (WebException exception) { if (this.VideoSourceError != null) { this.VideoSourceError(this, new VideoSourceErrorEventArgs(exception.Message)); } Thread.Sleep(250); } catch (ApplicationException) { Thread.Sleep(250); } catch (Exception) { } finally { if (request != null) { request.Abort(); request = null; } if (responseStream != null) { responseStream.Close(); responseStream = null; } if (response != null) { response.Close(); response = null; } } }while (!this.stopEvent.WaitOne(0, true)); if (this.PlayingFinished != null) { this.PlayingFinished(this, ReasonToFinishPlaying.StoppedByUser); } }
private void WorkerThread() { byte[] array = new byte[1048576]; byte[] array2 = new byte[3] { 255, 216, 255 }; int num = 3; ASCIIEncoding aSCIIEncoding = new ASCIIEncoding(); while (!stopEvent.WaitOne(0, exitContext: false)) { reloadEvent.Reset(); HttpWebRequest httpWebRequest = null; WebResponse webResponse = null; Stream stream = null; byte[] array3 = null; string text = null; bool flag = false; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 1; int num6 = 0; int num7 = 0; try { httpWebRequest = (HttpWebRequest)WebRequest.Create(source); if (userAgent != null) { httpWebRequest.UserAgent = userAgent; } if (proxy != null) { httpWebRequest.Proxy = proxy; } httpWebRequest.Timeout = requestTimeout; if (login != null && password != null && login != string.Empty) { httpWebRequest.Credentials = new NetworkCredential(login, password); } if (useSeparateConnectionGroup) { httpWebRequest.ConnectionGroupName = GetHashCode().ToString(); } if (forceBasicAuthentication) { string s = $"{login}:{password}"; s = Convert.ToBase64String(Encoding.Default.GetBytes(s)); httpWebRequest.Headers["Authorization"] = "Basic " + s; } webResponse = httpWebRequest.GetResponse(); string contentType = webResponse.ContentType; string[] array4 = contentType.Split('/'); int num8; if (array4[0] == "application" && array4[1] == "octet-stream") { num8 = 0; array3 = new byte[0]; } else { if (!(array4[0] == "multipart") || !contentType.Contains("mixed")) { throw new Exception("Invalid content type."); } int num9 = contentType.IndexOf("boundary", 0); if (num9 != -1) { num9 = contentType.IndexOf("=", num9 + 8); } if (num9 == -1) { num8 = 0; array3 = new byte[0]; } else { text = contentType.Substring(num9 + 1); text = text.Trim(' ', '"'); array3 = aSCIIEncoding.GetBytes(text); num8 = array3.Length; flag = false; } } stream = webResponse.GetResponseStream(); stream.ReadTimeout = requestTimeout; while (!stopEvent.WaitOne(0, exitContext: false) && !reloadEvent.WaitOne(0, exitContext: false)) { if (num3 > 1047552) { num3 = (num4 = (num2 = 0)); } int num10; if ((num10 = stream.Read(array, num3, 1024)) == 0) { throw new ApplicationException(); } num3 += num10; num2 += num10; bytesReceived += num10; if (num8 != 0 && !flag) { num4 = ByteArrayUtils.Find(array, array3, 0, num2); if (num4 == -1) { continue; } for (int num11 = num4 - 1; num11 >= 0; num11--) { byte b = array[num11]; if (b == 10 || b == 13) { break; } text = (char)b + text; } array3 = aSCIIEncoding.GetBytes(text); num8 = array3.Length; flag = true; } if (num5 == 1 && num2 >= num) { num6 = ByteArrayUtils.Find(array, array2, num4, num2); if (num6 != -1) { num4 = num6 + num; num2 = num3 - num4; num5 = 2; } else { num2 = num - 1; num4 = num3 - num2; } } while (num5 == 2 && num2 != 0 && num2 >= num8) { num7 = ByteArrayUtils.Find(array, (num8 != 0) ? array3 : array2, num4, num2); if (num7 != -1) { num4 = num7; num2 = num3 - num4; framesReceived++; if (this.NewFrame != null && !stopEvent.WaitOne(0, exitContext: false)) { Bitmap bitmap = (Bitmap)Image.FromStream(new MemoryStream(array, num6, num7 - num6)); this.NewFrame(this, new NewFrameEventArgs(bitmap)); bitmap.Dispose(); bitmap = null; } num4 = num7 + num8; num2 = num3 - num4; Array.Copy(array, num4, array, 0, num2); num3 = num2; num4 = 0; num5 = 1; } else if (num8 != 0) { num2 = num8 - 1; num4 = num3 - num2; } else { num2 = 0; num4 = num3; } } } } catch (ApplicationException) { Thread.Sleep(250); } catch (ThreadAbortException) { break; } catch (Exception ex3) { if (this.VideoSourceError != null) { this.VideoSourceError(this, new VideoSourceErrorEventArgs(ex3.Message)); } Thread.Sleep(250); } finally { if (httpWebRequest != null) { httpWebRequest.Abort(); httpWebRequest = null; } if (stream != null) { stream.Close(); stream = null; } if (webResponse != null) { webResponse.Close(); webResponse = null; } } if (stopEvent.WaitOne(0, exitContext: false)) { break; } } if (this.PlayingFinished != null) { this.PlayingFinished(this, ReasonToFinishPlaying.StoppedByUser); } }