OSDN Git Service

デグレ? があった個所を修正。(OPCのプロパティリスト表示)
[gokigen/A01d.git] / app / src / main / java / net / osdn / gokigen / a01d / camera / fujix / wrapper / liveview / FujiXLiveViewControlAlternate.java
1 package net.osdn.gokigen.a01d.camera.fujix.wrapper.liveview;
2
3 import android.app.Activity;
4 import android.content.SharedPreferences;
5 import android.util.Log;
6 import androidx.annotation.NonNull;
7 import androidx.preference.PreferenceManager;
8
9 import net.osdn.gokigen.a01d.camera.ILiveViewControl;
10 import net.osdn.gokigen.a01d.camera.fujix.wrapper.command.IFujiXCommunication;
11 import net.osdn.gokigen.a01d.liveview.liveviewlistener.CameraLiveViewListenerImpl;
12 import net.osdn.gokigen.a01d.liveview.liveviewlistener.ILiveViewListener;
13
14 import java.io.InputStream;
15 import java.net.Socket;
16 import java.util.Arrays;
17
18 import static net.osdn.gokigen.a01d.preference.IPreferencePropertyAccessor.FUJIX_LIVEVIEW_WAIT;
19 import static net.osdn.gokigen.a01d.preference.IPreferencePropertyAccessor.FUJIX_LIVEVIEW_WAIT_DEFAULT_VALUE;
20
21
22 public class FujiXLiveViewControlAlternate implements ILiveViewControl, IFujiXCommunication
23 {
24     private final String TAG = toString();
25     private final String ipAddress;
26     private final int portNumber;
27     private final CameraLiveViewListenerImpl liveViewListener;
28     private int waitMs = 0;
29     private static final int DATA_HEADER_OFFSET = 18;
30     private static final int BUFFER_SIZE = 2048 * 1280;
31     private static final int ERROR_LIMIT = 30;
32     private boolean isStart = false;
33     private boolean logcat = true;
34
35     public FujiXLiveViewControlAlternate(@NonNull Activity activity, String ip, int portNumber)
36     {
37         this.ipAddress = ip;
38         this.portNumber = portNumber;
39         liveViewListener = new CameraLiveViewListenerImpl();
40
41         try
42         {
43             SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
44             String waitMsStr = preferences.getString(FUJIX_LIVEVIEW_WAIT, FUJIX_LIVEVIEW_WAIT_DEFAULT_VALUE);
45             logcat("waitMS : " + waitMsStr);
46             if (waitMsStr != null)
47             {
48                 int wait = Integer.parseInt(waitMsStr);
49                 if ((wait >= 20) && (wait <= 800))
50                 {
51                     waitMs = wait;
52                 }
53             }
54         }
55         catch (Exception e)
56         {
57             e.printStackTrace();
58             waitMs = 100;
59         }
60         Log.v(TAG, "LOOP WAIT : " + waitMs + " ms");
61     }
62
63     @Override
64     public void startLiveView()
65     {
66         if (isStart)
67         {
68             // すでに受信スレッド動作中なので抜ける
69             Log.v(TAG, " LiveView IS ALREADY STARTED");
70             return;
71         }
72         isStart = true;
73         Thread thread = new Thread(new Runnable()
74         {
75             @Override
76             public void run()
77             {
78                 try
79                 {
80                     Socket socket = new Socket(ipAddress, portNumber);
81                     startReceive(socket);
82                 }
83                 catch (Exception e)
84                 {
85                     Log.v(TAG, " IP : " + ipAddress + " port : " + portNumber);
86                     e.printStackTrace();
87                 }
88             }
89         });
90         try
91         {
92             thread.start();
93         }
94         catch (Exception e)
95         {
96             e.printStackTrace();
97         }
98     }
99
100     @Override
101     public void stopLiveView()
102     {
103         isStart = false;
104     }
105
106     private void startReceive(Socket socket)
107     {
108         String lvHeader = "[LV]";
109         int lvHeaderDumpBytes = 24;
110
111         int errorCount = 0;
112         InputStream isr;
113         byte[] byteArray;
114         try
115         {
116             isr = socket.getInputStream();
117             byteArray = new byte[BUFFER_SIZE + 32];
118         }
119         catch (Exception e)
120         {
121             e.printStackTrace();
122             Log.v(TAG, "===== startReceive() aborted.");
123             return;
124         }
125         while (isStart)
126         {
127             try
128             {
129                 boolean findJpeg = false;
130                 int length_bytes;
131                 int read_bytes = isr.read(byteArray, 0, BUFFER_SIZE);
132
133                 // 先頭データ(48バイト分)をダンプ
134                 dump_bytes("[lv]", byteArray, 48);
135
136                 if (read_bytes > DATA_HEADER_OFFSET)
137                 {
138                     // メッセージボディの先頭にあるメッセージ長分は読み込む
139                     length_bytes = ((((int) byteArray[3]) & 0xff) << 24) + ((((int) byteArray[2]) & 0xff) << 16) + ((((int) byteArray[1]) & 0xff) << 8) + (((int) byteArray[0]) & 0xff);
140                     if ((byteArray[18] == (byte)0xff)&&(byteArray[19] == (byte)0xd8))
141                     {
142                         findJpeg = true;
143                         while ((read_bytes < length_bytes) && (read_bytes < BUFFER_SIZE) && (length_bytes <= BUFFER_SIZE))
144                         {
145                             int append_bytes = isr.read(byteArray, read_bytes, length_bytes - read_bytes);
146                             logcat("READ AGAIN : " + append_bytes + " [" + read_bytes + "]");
147                             if (append_bytes < 0)
148                             {
149                                 break;
150                             }
151                             read_bytes = read_bytes + append_bytes;
152                         }
153                         logcat("READ BYTES : " + read_bytes + "  (" + length_bytes + " bytes, " + waitMs + "ms)");
154                     }
155                     else
156                     {
157                         // ウェイトを短めに入れてマーカーを拾うまで待つ
158                         Thread.sleep(waitMs/4);
159                         logcat(" --- wait LiveView ---");
160                         continue;
161                     }
162                 }
163
164                 // 先頭データ(24バイト分)をダンプ
165                 dump_bytes(lvHeader, byteArray, lvHeaderDumpBytes);
166
167                 if (findJpeg)
168                 {
169                     liveViewListener.onUpdateLiveView(Arrays.copyOfRange(byteArray, DATA_HEADER_OFFSET, read_bytes - DATA_HEADER_OFFSET), null);
170                     errorCount = 0;
171                 }
172                 Thread.sleep(waitMs);
173             }
174             catch (Exception e)
175             {
176                 e.printStackTrace();
177                 errorCount++;
178             }
179             if (errorCount > ERROR_LIMIT)
180             {
181                 // エラーが連続でたくさん出たらループをストップさせる
182                 isStart = false;
183             }
184         }
185         try
186         {
187             isr.close();
188             socket.close();
189         }
190         catch (Exception e)
191         {
192             e.printStackTrace();
193         }
194     }
195
196
197     @Override
198     public void updateDigitalZoom()
199     {
200
201     }
202
203     @Override
204     public void updateMagnifyingLiveViewScale(boolean isChangeScale)
205     {
206
207     }
208
209     @Override
210     public float getMagnifyingLiveViewScale()
211     {
212         return (1.0f);
213     }
214
215     @Override
216     public void changeLiveViewSize(String size)
217     {
218
219     }
220
221     @Override
222     public float getDigitalZoomScale()
223     {
224         return (1.0f);
225     }
226
227     public ILiveViewListener getLiveViewListener()
228     {
229         return (liveViewListener);
230     }
231
232     @Override
233     public boolean connect()
234     {
235         return (true);
236     }
237
238     @Override
239     public void disconnect()
240     {
241         isStart = false;
242     }
243
244     /**
245      *   デバッグ用:ログにバイト列を出力する
246      *
247      */
248     private void dump_bytes(String header, byte[] data, int dumpBytes)
249     {
250         if (!logcat)
251         {
252             // ログ出力しないモードだった
253             return;
254         }
255
256         int index = 0;
257         StringBuffer message;
258         if (dumpBytes <= 0)
259         {
260             dumpBytes = 24;
261         }
262         message = new StringBuffer();
263         for (int point = 0; point < dumpBytes; point++)
264         {
265             byte item = data[point];
266             index++;
267             message.append(String.format("%02x ", item));
268             if (index >= 8)
269             {
270                 Log.v(TAG, header + " " + message);
271                 index = 0;
272                 message = new StringBuffer();
273             }
274         }
275         if (index != 0)
276         {
277             Log.v(TAG, header + " " + message);
278         }
279         System.gc();
280     }
281
282     private void logcat(String message)
283     {
284         if (logcat)
285         {
286             Log.v(TAG, message);
287         }
288     }
289 }