3333import javax .imageio .ImageIO ;
3434import java .awt .image .BufferedImage ;
3535import java .io .ByteArrayInputStream ;
36+ import java .io .DataInputStream ;
37+ import java .io .EOFException ;
3638import java .io .IOException ;
37- import java .io .InputStream ;
3839import java .net .MalformedURLException ;
3940import java .net .URL ;
4041import java .net .URLConnection ;
41- import java .util .List ;
42- import java .util .Map ;
42+ import java .util .concurrent .TimeUnit ;
4343
4444import static org .bytedeco .javacpp .opencv_core .*;
4545import static org .bytedeco .javacpp .opencv_imgcodecs .cvDecodeImage ;
@@ -69,37 +69,31 @@ public static void tryLoad() throws Exception {
6969 }
7070 }
7171
72- private URL url ;
72+ private final URL url ;
73+ private final int connectionTimeout ;
74+ private final int readTimeout ;
7375
7476 private URLConnection connection ;
75- private InputStream input ;
77+ private DataInputStream input ;
7678 private byte [] pixelBuffer = new byte [1024 ];
77- private Map <String , List <String >> headerfields ;
78- private String boundryKey ;
7979 private IplImage decoded = null ;
8080 private FrameConverter <IplImage > converter = new OpenCVFrameConverter .ToIplImage ();
8181
82- public IPCameraFrameGrabber (String urlstr ) throws MalformedURLException {
82+ public IPCameraFrameGrabber (String urlstr , int connectionTimeout , int readTimeout , TimeUnit unit ) throws MalformedURLException {
83+ super ();
8384 url = new URL (urlstr );
85+ this .connectionTimeout = Math .toIntExact (TimeUnit .MILLISECONDS .convert (connectionTimeout , unit ));
86+ this .readTimeout = Math .toIntExact (TimeUnit .MILLISECONDS .convert (readTimeout , unit ));
8487 }
8588
8689 @ Override
8790 public void start () throws Exception {
8891
8992 try {
9093 connection = url .openConnection ();
91- headerfields = connection .getHeaderFields ();
92- if (headerfields .containsKey ("Content-Type" )) {
93- List <String > ct = headerfields .get ("Content-Type" );
94- for (int i = 0 ; i < ct .size (); ++i ) {
95- String key = ct .get (i );
96- int j = key .indexOf ("boundary=" );
97- if (j != -1 ) {
98- boundryKey = key .substring (j + 9 ); // FIXME << fragile
99- }
100- }
101- }
102- input = connection .getInputStream ();
94+ connection .setConnectTimeout (connectionTimeout );
95+ connection .setReadTimeout (readTimeout );
96+ input = new DataInputStream (connection .getInputStream ());
10397 } catch (IOException e ) {
10498 // Make sure we rethrow the IO exception https://github.com/bytedeco/javacv/pull/300
10599 throw new Exception (e .getMessage (), e );
@@ -169,9 +163,9 @@ byte[] readImage() throws IOException {
169163 }
170164 }
171165 // find embedded jpeg in stream
172- String subheader = sb .toString ();
166+ final String subheader = sb .toString ();
173167 //log.debug(subheader);
174- int contentLength = - 1 ;
168+
175169 // if (boundryKey == null)
176170 // {
177171 // Yay! - server was nice and sent content length
@@ -180,18 +174,17 @@ byte[] readImage() throws IOException {
180174
181175 if (c0 < 0 ) {
182176 //log.info("no content length returning null");
183- return null ;
177+ throw new EOFException ( "The camera stream ended unexpectedly" ) ;
184178 }
185179
186180 c0 += 16 ;
187- contentLength = Integer .parseInt (subheader .substring (c0 , c1 ).trim ());
181+ final int contentLength = Integer .parseInt (subheader .substring (c0 , c1 ).trim ());
188182 //log.debug("Content-Length: " + contentLength);
189183
190184 // adaptive size - careful - don't want a 2G jpeg
191185 ensureBufferCapacity (contentLength );
192186
193- while (input .available () < contentLength ) ;
194- input .read (pixelBuffer , 0 , contentLength );
187+ input .readFully (pixelBuffer , 0 , contentLength );
195188 input .read ();// \r
196189 input .read ();// \n
197190 input .read ();// \r
0 commit comments