Resetting to invalid mark&java.lang.NegativeArraySizeException: -1
Hi i am new at android and i have to stream ip cam. I am getting these errors after i entered my credentials.
java.io.IOException: Resetting to invalid mark
at java.io.BufferedInputStream.reset(BufferedInputStream.java:437)
at java.io.FilterInputStream.reset(FilterInputStream.java:226)
at com.github.niqdev.mjpeg.MjpegInputStreamDefault.readMjpegFrame(MjpegInputStreamDefault.java:76)
at com.github.niqdev.mjpeg.MjpegViewDefault$MjpegViewThread.run(MjpegViewDefault.java:129)
and this
java.lang.NegativeArraySizeException: -1
at com.github.niqdev.mjpeg.MjpegInputStreamDefault.readMjpegFrame(MjpegInputStreamDefault.java:69)
at com.github.niqdev.mjpeg.MjpegViewDefault$MjpegViewThread.run(MjpegViewDefault.java:129)
If you want i can write my credentials. Thanks in advance.
Hi, are you using the code in the sample app? Did you try with the app on the Play Store? Thanks
I did both. I did try sample in Android Studio and i got those errors. The camera what i use is Mobotix IP Camera and the url is http://plazacam.studentaffairs.duke.edu/mjpg/video.mjpg, it is type MJPEG and i entered credentials. I did debug and i ve seen in MjpegInputStreamDefault.class, when the headerLen variable equals -1, these errors appear.
Interesting, so could you please checkout old tags of the app and test the sample code or just downgrade the library with old versions, I wouldn't that with the latest changes we have introduced some regressions. Let me know if you find a version that work, thanks.
@erdemnayir Do you still have the problem? Did you try with older versions?
Unfortunately, I tried all versions, but I got the same errors.
Can you give me please more details of how reproduce the error?
Hi, so for sure you should open the stream in this way
.credential("deneme1", "deneme0002")
.open("http://85.99.109.4:5005/control/faststream.jpg?stream=full", TIMEOUT)
but apparently I have another error with that URL then
com.github.niqdev.ipcam E/MjpegViewDefault: encountered exception during render
java.io.IOException: Mark has been invalidated.
at java.io.BufferedInputStream.reset(BufferedInputStream.java:336)
at java.io.FilterInputStream.reset(FilterInputStream.java:134)
at com.github.niqdev.mjpeg.MjpegInputStreamDefault.readMjpegFrame(MjpegInputStreamDefault.java:76)
at com.github.niqdev.mjpeg.MjpegViewDefault$MjpegViewThread.run(MjpegViewDefault.java:129)
com.github.niqdev.ipcam E/AndroidRuntime: FATAL EXCEPTION: Thread-217
Process: com.github.niqdev.ipcam, PID: 18311
java.lang.NegativeArraySizeException: -1
at com.github.niqdev.mjpeg.MjpegInputStreamDefault.readMjpegFrame(MjpegInputStreamDefault.java:69)
at com.github.niqdev.mjpeg.MjpegViewDefault$MjpegViewThread.run(MjpegViewDefault.java:129)
so maybe there is another parameter to add in the URL or a different path to retrieve the stream in the proper format
Yes, i did like that. I did try so many times and with different types.
I used this then it worked and i think you can fix with this;
package com.nagikho.ipcammjpegsample;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
public class MjpegInputStream extends DataInputStream {
private static final String TAG = "MjpegInputStream";
private final byte[] SOI_MARKER = {(byte) 0xFF, (byte) 0xD8};
private final byte[] EOF_MARKER = {(byte) 0xFF, (byte) 0xD9};
private int mContentLength = -1;
byte[] CONTENT_LENGTH_BYTES;
byte[] CONTENT_END_BYTES;
private final static int HEADER_MAX_LENGTH = 100;
private final static int FRAME_MAX_LENGTH = 200000 + HEADER_MAX_LENGTH;
private final String CONTENT_LENGTH = "Content-length:";
private final String CONTENT_END = "\r\n";
private final static byte[] gFrameData = new byte[FRAME_MAX_LENGTH];
private final static byte[] gHeader = new byte[HEADER_MAX_LENGTH];
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
public MjpegInputStream(InputStream in) {
super(new BufferedInputStream(in, FRAME_MAX_LENGTH));
bitmapOptions.inSampleSize = 1;
bitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;
bitmapOptions.inPreferQualityOverSpeed = false;
bitmapOptions.inPurgeable = true;
try {
CONTENT_LENGTH_BYTES = CONTENT_LENGTH.getBytes("UTF-8");
CONTENT_END_BYTES = CONTENT_END.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
private int getEndOfSeqeunce(DataInputStream in, byte[] sequence) throws IOException {
int seqIndex = 0;
byte c;
for (int i = 0; i < FRAME_MAX_LENGTH; i++) {
c = (byte) in.readUnsignedByte();
if (c == sequence[seqIndex]) {
seqIndex++;
if (seqIndex == sequence.length) {
return i + 1;
}
} else {
seqIndex = 0;
}
}
return -1;
}
private int getStartOfSequence(DataInputStream in, byte[] sequence) throws IOException {
int end = getEndOfSeqeunce(in, sequence);
return (end < 0) ? (-1) : (end - sequence.length);
}
private int parseContentLength(byte[] headerBytes, int length) throws IOException, NumberFormatException {
int begin = findPattern(headerBytes, length, CONTENT_LENGTH_BYTES, 0);
int end = findPattern(headerBytes, length, CONTENT_END_BYTES, begin) - CONTENT_END_BYTES.length;
// converting string to int
int number = 0;
int radix = 1;
for (int i = end - 1; i >= begin; --i) {
if (headerBytes[i] > 47 && headerBytes[i] < 58) {
number += (headerBytes[i] - 48) * radix;
radix *= 10;
}
}
return number;
}
private int findPattern(byte[] buffer, int bufferLen, byte[] pattern, int offset) {
int seqIndex = 0;
for (int i = offset; i < bufferLen; ++i) {
if (buffer[i] == pattern[seqIndex]) {
++seqIndex;
if (seqIndex == pattern.length) {
return i + 1;
}
} else {
seqIndex = 0;
}
}
return -1;
}
public Bitmap readMjpegFrame() throws IOException {
mark(FRAME_MAX_LENGTH);
int headerLen = getStartOfSequence(this, SOI_MARKER);
if (headerLen < 0)
return null;
reset();
readFully(gHeader, 0, headerLen);
try {
mContentLength = parseContentLength(gHeader, headerLen);
} catch (NumberFormatException nfe) {
nfe.getStackTrace();
mContentLength = getEndOfSeqeunce(this, EOF_MARKER);
}
readFully(gFrameData, 0, mContentLength);
Bitmap bm = BitmapFactory.decodeByteArray(gFrameData, 0, mContentLength, bitmapOptions);
bitmapOptions.inBitmap = bm;
return bm;
}
}
@erdemnayir if it works and probably could help also someone else, would be nice if you can make a pull request with your changes. If you think it make more sense you could create another stream type with your solution since this library is just a wrapper and could be used with
stream:type="stream_default OR stream_native OR YOUR_STREAM_NAME"
If your frame size is larger than ~40,000 you will have this problem.