1 package net.osdn.gokigen.gr2control.camera.utils;
3 import android.util.Log;
5 import java.io.ByteArrayOutputStream;
6 import java.io.EOFException;
7 import java.io.InputStream;
8 import java.net.HttpURLConnection;
11 public class SimpleLiveviewSlicer
13 private static final String TAG = SimpleLiveviewSlicer.class.getSimpleName();
14 public static final class Payload
16 // jpeg data container
17 final byte[] jpegData;
19 // padding data container
20 final byte[] paddingData;
25 private Payload(byte[] jpeg, byte[] padding)
28 this.paddingData = padding;
30 public byte[] getJpegData()
36 private static final int CONNECTION_TIMEOUT = 2000; // [msec]
37 private HttpURLConnection mHttpConn;
38 private InputStream mInputStream;
40 public void open(String liveviewUrl)
44 if ((mInputStream != null)||(mHttpConn != null))
46 Log.v(TAG, "Slicer is already open.");
50 final URL urlObj = new URL(liveviewUrl);
51 mHttpConn = (HttpURLConnection) urlObj.openConnection();
52 mHttpConn.setRequestMethod("GET");
53 mHttpConn.setConnectTimeout(CONNECTION_TIMEOUT);
55 if (mHttpConn.getResponseCode() == HttpURLConnection.HTTP_OK)
57 mInputStream = mHttpConn.getInputStream();
70 if (mInputStream != null)
82 if (mHttpConn != null)
84 mHttpConn.disconnect();
94 public Payload nextPayload()
96 Payload payload = null;
99 while ((mInputStream != null)&&(payload == null))
102 int readLength = 1 + 1 + 2 + 4;
103 byte[] commonHeader = readBytes(mInputStream, readLength);
104 if ((commonHeader == null)||(commonHeader.length != readLength))
106 Log.v(TAG, "Cannot read stream for common header.");
110 if (commonHeader[0] != (byte) 0xFF)
112 Log.v(TAG, "Unexpected data format. (Start byte)");
116 switch (commonHeader[1])
119 // This is information header for streaming. skip this packet.
120 readLength = 4 + 3 + 1 + 2 + 118 + 4 + 4 + 24;
121 //commonHeader = null;
122 readBytes(mInputStream, readLength);
127 payload = readPayload();
143 private Payload readPayload()
147 if (mInputStream != null)
150 int readLength = 4 + 3 + 1 + 4 + 1 + 115;
151 byte[] payloadHeader = readBytes(mInputStream, readLength);
152 if ((payloadHeader == null)||(payloadHeader.length != readLength))
154 throw new EOFException("Cannot read stream for payload header.");
156 if (payloadHeader[0] != (byte) 0x24 || payloadHeader[1] != (byte) 0x35
157 || payloadHeader[2] != (byte) 0x68
158 || payloadHeader[3] != (byte) 0x79)
160 throw new EOFException("Unexpected data format. (Start code)");
162 int jpegSize = bytesToInt(payloadHeader, 4, 3);
163 int paddingSize = bytesToInt(payloadHeader, 7, 1);
166 byte[] jpegData = readBytes(mInputStream, jpegSize);
167 byte[] paddingData = readBytes(mInputStream, paddingSize);
169 return (new Payload(jpegData, paddingData));
172 catch (EOFException eo)
174 eo.printStackTrace();
184 private static int bytesToInt(byte[] byteData, int startIndex, int count)
189 for (int i = startIndex; i < startIndex + count; i++)
191 ret = (ret << 8) | (byteData[i] & 0xff);
201 private static byte[] readBytes(InputStream in, int length)
206 ByteArrayOutputStream tmpByteArray = new ByteArrayOutputStream();
207 byte[] buffer = new byte[1024];
210 int trialReadlen = Math.min(buffer.length, length - tmpByteArray.size());
211 int readlen = in.read(buffer, 0, trialReadlen);
216 tmpByteArray.write(buffer, 0, readlen);
217 if (length <= tmpByteArray.size())
222 ret = tmpByteArray.toByteArray();
223 tmpByteArray.close();
234 * 先頭のjpegマーカーが出てくるまで読み飛ばす
237 private void skipJpegMarkStart(InputStream stream)
240 int[] startmarker = { 0x0d, 0x0a, 0x0d, 0x0a, 0xff, 0xd8 };
245 int data = stream.read();
246 if (data == startmarker[searchIndex])
249 if (searchIndex >= startmarker.length)
267 public Payload nextPayloadForMotionJpeg()
270 int[] endmarker = { 0xff, 0xd9, 0x0d, 0x0a, 0x0d, 0x0a };
271 Payload payload = null;
274 while ((mInputStream != null)&&(payload == null))
276 skipJpegMarkStart(mInputStream);
277 ByteArrayOutputStream tmpByteArray = new ByteArrayOutputStream();
279 tmpByteArray.write(0xff);
280 tmpByteArray.write(0xd8);
285 // 1byteづつの読み込み... 本当は複数バイト読み出しで処理したい
286 int data = mInputStream.read();
287 tmpByteArray.write(data);
288 if (data == endmarker[searchIndex])
291 if (searchIndex >= endmarker.length)
303 Log.v(TAG, "INPUT STREAM EXCEPTION : " + e.getLocalizedMessage());
304 // e.printStackTrace();
308 payload = new Payload(tmpByteArray.toByteArray(), null);