Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stream disconnect when scene changes from total darkness abruptly #4

Open
dustinkerstein opened this issue Nov 15, 2020 · 6 comments
Open

Comments

@dustinkerstein
Copy link

First of all, thanks for this awesome demo. It's working perfectly 99% of the time.

A minor issue, though definitely a snag for my usage, is when the scene changes from total darkness (ie. taking lens cap off) the stream will disconnect with the error:

Error received while reading the MJPEG.

Any ideas on why this could be happening? Are you able to replicate? Thanks!

@DanielArnett
Copy link
Owner

DanielArnett commented Nov 15, 2020 via email

@dustinkerstein
Copy link
Author

Yeah, that sound good. It's happening somewhere in OnGetResponse which already has a try, catch. I can definitely add some more, but do you have any inclination as to which part inside that chunk of code I should debug first? Thanks for the quick reply!

@dustinkerstein
Copy link
Author

Here's that chunk of code for reference:

private void OnGetResponse(IAsyncResult asyncResult)
    {
        responseReceived = true;
        //Debug.Log("OnGetResponse");
        byte[] imageBuffer = new byte[1024 * 1024];

        //Debug.Log("Starting request");
        // get the response
        HttpWebRequest req = (HttpWebRequest)asyncResult.AsyncState;

        try
        {
            //Debug.Log("OnGetResponse try entered.");
            HttpWebResponse resp = (HttpWebResponse)req.EndGetResponse(asyncResult);
            //Debug.Log("response received");
            // find our magic boundary value
            string contentType = resp.Headers["Content-Type"];
            if (!string.IsNullOrEmpty(contentType) && !contentType.Contains("="))
            {
                Debug.Log("MJPEG Exception thrown");
                throw new Exception("Invalid content-type header.  The camera is likely not returning a proper MJPEG stream.");
            }

            string boundary = resp.Headers["Content-Type"].Split('=')[1].Replace("\"", "");
            byte[] boundaryBytes = Encoding.UTF8.GetBytes(boundary.StartsWith("--") ? boundary : "--" + boundary);

            Stream s = resp.GetResponseStream();
            BinaryReader br = new BinaryReader(s);

            _streamActive = true;
            byte[] buff = br.ReadBytes(_chunkSize);

            while (_streamActive)
            {
                // find the JPEG header
                int imageStart = FindBytes(buff, JpegHeader);// buff.Find(JpegHeader);

                if (imageStart != -1)
                {
                    // copy the start of the JPEG image to the imageBuffer
                    int size = buff.Length - imageStart;
                    Array.Copy(buff, imageStart, imageBuffer, 0, size);

                    while (true)
                    {
                        buff = br.ReadBytes(_chunkSize);

                        // Find the end of the jpeg
                        int imageEnd = FindBytes(buff, boundaryBytes);
                        if (imageEnd != -1)
                        {
                            // copy the remainder of the JPEG to the imageBuffer
                            Array.Copy(buff, 0, imageBuffer, size, imageEnd);
                            size += imageEnd;

                            // Copy the latest frame into `CurrentFrame`
                            byte[] frame = new byte[size];
                            Array.Copy(imageBuffer, 0, frame, 0, size);
                            CurrentFrame = frame;

                            // tell whoever's listening that we have a frame to draw
                            if (FrameReady != null)
                                FrameReady(this, new FrameReadyEventArgs());
                            // copy the leftover data to the start
                            Array.Copy(buff, imageEnd, buff, 0, buff.Length - imageEnd);

                            // fill the remainder of the buffer with new data and start over
                            byte[] temp = br.ReadBytes(imageEnd);

                            Array.Copy(temp, 0, buff, buff.Length - imageEnd, temp.Length);
                            break;
                        }

                        // copy all of the data to the imageBuffer
                        Array.Copy(buff, 0, imageBuffer, size, buff.Length);
                        size += buff.Length;

                        if (!_streamActive)
                        {
                            //Debug.Log("CLOSING");
                            resp.Close();
                            break;
                        }
                    }
                }
            }
            resp.Close();
        }
        catch (Exception ex)
        {
            if (Error != null)
                _context.Post(delegate { Error(this, new ErrorEventArgs() { Message = ex.Message }); }, null);

            return;
        }
    }
}

@DanielArnett
Copy link
Owner

DanielArnett commented Nov 15, 2020 via email

@dustinkerstein
Copy link
Author

It looks like it's happening here:

Array.Copy(buff, 0, imageBuffer, size, buff.Length);

But none of the variables are zero/null as when I Debug.Log("size: " + size + " imageBuffer length: " + imageBuffer.Length + " buff.Length: " + buff.Length) before that line I get:

size: 1048515 imageBuffer length: 1048576 buff.Length: 4096

I'll try a little more debug now.

@dustinkerstein
Copy link
Author

Ah, the buffer size was too small based on the 4096 offset. I increased the buffer to byte[] imageBuffer = new byte[2048 * 2048] and it seems to have resolved this issue. Let me know if you see a better way to address that. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants