• R/O
  • HTTP
  • SSH
  • HTTPS

A01d: Commit

OPC(Olympus Air)用望遠鏡アプリ。


Commit MetaInfo

Revisión78867656d1c8b75b4f292510bc8936b953ff949e (tree)
Tiempo2020-12-19 10:40:35
AutorMRSa <mrsa@myad...>
CommiterMRSa

Log Message

Canonのライブビュー通信安定性を向上させる。

Cambiar Resumen

Diferencia incremental

--- a/app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/CanonInterfaceProvider.java
+++ b/app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/CanonInterfaceProvider.java
@@ -68,6 +68,7 @@ public class CanonInterfaceProvider implements IPtpIpInterfaceProvider, IDisplay
6868 this.activity = context;
6969
7070 String ipAddress;
71+ int delayMs = 30;
7172 try
7273 {
7374 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
@@ -76,6 +77,22 @@ public class CanonInterfaceProvider implements IPtpIpInterfaceProvider, IDisplay
7677 {
7778 ipAddress = "192.168.0.1";
7879 }
80+ try
81+ {
82+ String delayMsStr = preferences.getString(IPreferencePropertyAccessor.CANON_LIVEVIEW_WAIT, IPreferencePropertyAccessor.CANON_LIVEVIEW_WAIT_DEFAULT_VALUE);
83+ if (delayMsStr != null)
84+ {
85+ delayMs = Integer.parseInt(delayMsStr);
86+ }
87+ if (delayMs < 10)
88+ {
89+ delayMs = 10;
90+ }
91+ }
92+ catch (Exception e)
93+ {
94+ e.printStackTrace();
95+ }
7996 }
8097 catch (Exception e)
8198 {
@@ -84,7 +101,7 @@ public class CanonInterfaceProvider implements IPtpIpInterfaceProvider, IDisplay
84101 }
85102 Log.v(TAG, " Canon IP : " + ipAddress);
86103 commandPublisher = new PtpIpCommandPublisher(ipAddress, CONTROL_PORT, false, false);
87- liveViewControl = new CanonLiveViewControl(context, this, 10); //
104+ liveViewControl = new CanonLiveViewControl(context, this, delayMs); //
88105 asyncReceiver = new PtpIpAsyncResponseReceiver(ipAddress, ASYNC_RESPONSE_PORT);
89106 statusChecker = new CanonStatusChecker(context, commandPublisher, ipAddress, EVENT_PORT);
90107 canonConnection = new CanonConnection(context, provider, this, statusChecker);
--- a/app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/connection/CanonCameraConnectSequence.java
+++ b/app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/connection/CanonCameraConnectSequence.java
@@ -29,7 +29,7 @@ public class CanonCameraConnectSequence implements Runnable, IPtpIpCommandCallba
2929 private final IPtpIpInterfaceProvider interfaceProvider;
3030 private final IPtpIpCommandPublisher commandIssuer;
3131 private final CanonStatusChecker statusChecker;
32- private boolean isDumpLog = false;
32+ private final boolean isDumpLog = false;
3333
3434 CanonCameraConnectSequence(@NonNull Activity context, @NonNull ICameraStatusReceiver statusReceiver, @NonNull final ICameraConnection cameraConnection, @NonNull IPtpIpInterfaceProvider interfaceProvider, @NonNull CanonStatusChecker statusChecker)
3535 {
@@ -157,7 +157,8 @@ public class CanonCameraConnectSequence implements Runnable, IPtpIpCommandCallba
157157 case SEQ_GET_EVENT1:
158158 Log.v(TAG, " SEQ_GET_EVENT1 ");
159159 interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.canon_connect_connecting7), false, false, 0);
160- commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_DEVICE_INFORMATION, isDumpLog, 0, 0x1001));
160+ //commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_DEVICE_INFORMATION, isDumpLog, 0, 0x1001));
161+ commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_SET_REMOTE_SHOOTING_MODE, isDumpLog, 0, 0x1001));
161162 break;
162163
163164 case SEQ_DEVICE_INFORMATION:
@@ -207,9 +208,29 @@ public class CanonCameraConnectSequence implements Runnable, IPtpIpCommandCallba
207208 case SEQ_SET_DEVICE_PROPERTY_3:
208209 Log.v(TAG, " SEQ_SET_DEVICE_PROPERTY_3 ");
209210 interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.canon_connect_connecting12), false, false, 0);
211+ //commandIssuer.enqueueCommand(new CanonSetDevicePropertyValue(this, SEQ_SET_REMOTE_SHOOTING_MODE, isDumpLog, 0, 300, 0xd1b0, 0x08));
210212 commandIssuer.enqueueCommand(new CanonSetDevicePropertyValue(this, SEQ_DEVICE_PROPERTY_FINISHED, isDumpLog, 0, 300, 0xd1b0, 0x08));
211213 break;
212214
215+ case SEQ_SET_REMOTE_SHOOTING_MODE:
216+ Log.v(TAG, " SEQ_SET_REMOTE_SHOOTING_MODE ");
217+ interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.canon_connect_connecting12), false, false, 0);
218+ try
219+ {
220+ // ちょっと(250ms)待つ
221+ Thread.sleep(250);
222+
223+ // コマンド発行
224+ //commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_DEVICE_PROPERTY_FINISHED, isDumpLog, 0, 0x9086, 4, 0x00000001));
225+ commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_DEVICE_INFORMATION, isDumpLog, 0, 0x9086, 4, 0x00000001));
226+
227+ }
228+ catch (Exception e)
229+ {
230+ e.printStackTrace();
231+ }
232+ break;
233+
213234 case SEQ_DEVICE_PROPERTY_FINISHED:
214235 Log.v(TAG, " SEQ_DEVICE_PROPERTY_FINISHED ");
215236 interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.connect_connect_finished), false, false, 0);
--- a/app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/liveview/CanonLiveViewControl.java
+++ b/app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/liveview/CanonLiveViewControl.java
@@ -9,7 +9,7 @@ import net.osdn.gokigen.a01d.camera.ILiveViewControl;
99 import net.osdn.gokigen.a01d.camera.ptpip.IPtpIpInterfaceProvider;
1010 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommandPublisher;
1111 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommunication;
12-import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.messages.PtpIpCommandGeneric;
12+import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.messages.PtpIpCommandGenericWithRetry;
1313 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.liveview.IPtpIpLiveViewImageCallback;
1414 import net.osdn.gokigen.a01d.liveview.liveviewlistener.IImageDataReceiver;
1515 import net.osdn.gokigen.a01d.liveview.liveviewlistener.ILiveViewListener;
@@ -24,7 +24,8 @@ public class CanonLiveViewControl implements ILiveViewControl, ILiveViewListener
2424 private final String TAG = this.toString();
2525 private final IPtpIpCommandPublisher commandIssuer;
2626 private final int delayMs;
27- private CanonLiveViewImageReceiver imageReceiver;
27+ //private CanonLiveViewImageReceiver imageReceiver;
28+ private final CanonLiveViewImageReceiver imageReceiver;
2829 private IImageDataReceiver dataReceiver = null;
2930 private boolean liveViewIsReceiving = false;
3031 private boolean commandIssued = false;
@@ -33,7 +34,9 @@ public class CanonLiveViewControl implements ILiveViewControl, ILiveViewListener
3334 {
3435 this.commandIssuer = interfaceProvider.getCommandPublisher();
3536 this.delayMs = delayMs;
37+ //this.imageReceiver = new CanonLiveViewImageReceiver(this);
3638 this.imageReceiver = new CanonLiveViewImageReceiver(this);
39+ Log.v(TAG, " -=-=-=-=-=- CanonLiveViewControl : delay " + delayMs + " ms");
3740 }
3841
3942 public ILiveViewListener getLiveViewListener()
@@ -65,7 +68,7 @@ public class CanonLiveViewControl implements ILiveViewControl, ILiveViewListener
6568 if (!commandIssued)
6669 {
6770 commandIssued = true;
68- commandIssuer.enqueueCommand(new PtpIpCommandGeneric(imageReceiver, SEQ_GET_VIEWFRAME, 20, false, 0, 0x9153, 12, 0x00200000, 0x01, 0x00, 0x00));
71+ commandIssuer.enqueueCommand(new PtpIpCommandGenericWithRetry(imageReceiver, SEQ_GET_VIEWFRAME, delayMs, 2000, false, false, 0, 0x9153, 12, 0x00200000, 0x01, 0x00, 0x00));
6972 }
7073 try
7174 {
@@ -152,7 +155,7 @@ public class CanonLiveViewControl implements ILiveViewControl, ILiveViewListener
152155 {
153156 if ((dataReceiver != null)&&(data != null))
154157 {
155- //Log.v(TAG, " ---+++--- RECEIVED LV IMAGE ---+++--- : " + data.length + " bytes.");
158+ Log.v(TAG, " ---+++--- RECEIVED LV IMAGE ---+++--- : " + data.length + " bytes.");
156159 //dataReceiver.setImageData(data, metadata);
157160 if (data.length > 8)
158161 {
--- a/app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/liveview/CanonLiveViewImageReceiver.java
+++ /dev/null
@@ -1,143 +0,0 @@
1-package net.osdn.gokigen.a01d.camera.canon.wrapper.liveview;
2-
3-import android.util.Log;
4-
5-import androidx.annotation.NonNull;
6-import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommandCallback;
7-import net.osdn.gokigen.a01d.camera.ptpip.wrapper.liveview.IPtpIpLiveViewImageCallback;
8-
9-import java.io.ByteArrayOutputStream;
10-
11-public class CanonLiveViewImageReceiver implements IPtpIpCommandCallback
12-{
13- private final String TAG = toString();
14-
15- private IPtpIpLiveViewImageCallback callback;
16-
17- private int received_total_bytes = 0;
18- private int received_remain_bytes = 0;
19-
20- private int target_image_size = 0;
21- private boolean receivedFirstData = false;
22- private ByteArrayOutputStream byteStream;
23-
24- CanonLiveViewImageReceiver(@NonNull IPtpIpLiveViewImageCallback callback)
25- {
26- this.callback = callback;
27- byteStream = new ByteArrayOutputStream();
28- }
29-
30- @Override
31- public void receivedMessage(int id, byte[] rx_body)
32- {
33- try
34- {
35- // end of receive sequence.
36- //byte [] thumbnail = byteStream.toByteArray();
37- //Log.v(TAG, " TransferComplete() RECEIVED : " + id + " size : " + target_image_size + " (" + thumbnail.length + ")");
38- //SimpleLogDumper.dump_bytes(" [xxxxx]", Arrays.copyOfRange(thumbnail, 0, (64)));
39- //SimpleLogDumper.dump_bytes(" [zzzzz]", Arrays.copyOfRange(thumbnail, (thumbnail.length - 64), (thumbnail.length)));
40- callback.onCompleted(byteStream.toByteArray(), null);
41- receivedFirstData = false;
42- received_remain_bytes = 0;
43- received_total_bytes = 0;
44- target_image_size = 0;
45-
46- byteStream.reset();
47- }
48- catch (Exception e)
49- {
50- e.printStackTrace();
51- {
52- callback.onErrorOccurred(e);
53- }
54- }
55- }
56-
57- @Override
58- public void onReceiveProgress(final int currentBytes, final int totalBytes, byte[] rx_body)
59- {
60- // Log.v(TAG, " onReceiveProgress() " + currentBytes + "/" + totalBytes);
61-
62- // 受信したデータから、通信のヘッダ部分を削除する
63- cutHeader(rx_body);
64- }
65-
66- private void cutHeader(byte[] rx_body)
67- {
68- if (rx_body == null)
69- {
70- return;
71- }
72- int length = rx_body.length;
73- int data_position = 0;
74- if (!receivedFirstData)
75- {
76- // データを最初に読んだとき。ヘッダ部分を読み飛ばす
77- receivedFirstData = true;
78- data_position = (int) rx_body[0] & (0xff);
79- //Log.v(TAG, " FIRST DATA POS. : " + data_position);
80- //SimpleLogDumper.dump_bytes(" [sssss]", Arrays.copyOfRange(rx_body, 0, (64)));
81- }
82- else if (received_remain_bytes > 0)
83- {
84- // データの読み込みが途中だった場合...
85- if (length < received_remain_bytes)
86- {
87- // 全部コピーする、足りないバイト数は残す
88- received_remain_bytes = received_remain_bytes - length;
89- received_total_bytes = received_total_bytes + rx_body.length;
90- byteStream.write(rx_body, 0, rx_body.length);
91- return;
92- }
93- else
94- {
95- byteStream.write(rx_body, data_position, received_remain_bytes);
96- data_position = received_remain_bytes;
97- received_remain_bytes = 0;
98- }
99- }
100-
101- while (data_position <= (length - 12)) {
102- int body_size = (rx_body[data_position] & 0xff) + ((rx_body[data_position + 1] & 0xff) << 8) +
103- ((rx_body[data_position + 2] & 0xff) << 16) + ((rx_body[data_position + 3] & 0xff) << 24);
104- if (body_size <= 12) {
105- Log.v(TAG, " --- BODY SIZE IS SMALL : " + data_position + " (" + body_size + ") [" + received_remain_bytes + "] " + rx_body.length + " (" + target_image_size + ")");
106- //int startpos = (data_position > 48) ? (data_position - 48) : 0;
107- //SimpleLogDumper.dump_bytes(" [xxx]", Arrays.copyOfRange(rx_body, startpos, (data_position + 48)));
108- break;
109- }
110-
111- // 受信データ(のヘッダ部分)をダンプする
112- //Log.v(TAG, " RX DATA : " + data_position + " (" + body_size + ") [" + received_remain_bytes + "] (" + received_total_bytes + ")");
113- //SimpleLogDumper.dump_bytes(" [zzz] " + data_position + ": ", Arrays.copyOfRange(rx_body, data_position, (data_position + 48)));
114-
115- if ((data_position + body_size) > length) {
116- // データがすべてバッファ内になかったときは、バッファすべてコピーして残ったサイズを記憶しておく。
117- int copysize = (length - ((data_position + 12)));
118- byteStream.write(rx_body, (data_position + 12), copysize);
119- received_remain_bytes = body_size - copysize - 12; // マイナス12は、ヘッダ分
120- received_total_bytes = received_total_bytes + copysize;
121- //Log.v(TAG, " ----- copy : " + (data_position + 12) + " " + copysize + " remain : " + received_remain_bytes + " body size : " + body_size);
122- break;
123- }
124- try {
125- byteStream.write(rx_body, (data_position + 12), (body_size - 12));
126- data_position = data_position + body_size;
127- received_total_bytes = received_total_bytes + 12;
128- //Log.v(TAG, " --- COPY : " + (data_position + 12) + " " + (body_size - 12) + " remain : " + received_remain_bytes);
129-
130- } catch (Exception e) {
131- Log.v(TAG, " pos : " + data_position + " size : " + body_size + " length : " + length);
132- e.printStackTrace();
133- }
134- }
135- }
136-
137- @Override
138- public boolean isReceiveMulti()
139- {
140- return (true);
141- }
142-
143-}
--- /dev/null
+++ b/app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/liveview/CanonLiveViewImageReceiver.kt
@@ -0,0 +1,168 @@
1+package net.osdn.gokigen.a01d.camera.canon.wrapper.liveview
2+
3+import android.util.Log
4+import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommandCallback
5+import net.osdn.gokigen.a01d.camera.ptpip.wrapper.liveview.IPtpIpLiveViewImageCallback
6+import net.osdn.gokigen.a01d.camera.utils.SimpleLogDumper
7+import java.io.ByteArrayOutputStream
8+import java.util.*
9+
10+class CanonLiveViewImageReceiver(val callback: IPtpIpLiveViewImageCallback) : IPtpIpCommandCallback
11+{
12+ private val isDumpLog = false
13+ private val byteStream = ByteArrayOutputStream()
14+
15+ private var receivedTotalBytes = 0
16+ private var receivedRemainBytes = 0
17+ private var receivedFirstData = false
18+
19+ override fun receivedMessage(id: Int, rx_body: ByteArray?)
20+ {
21+ if (rx_body == null)
22+ {
23+ Log.v(TAG, " CanonLiveViewReceiver: MSG BODY IS NULL. (ID:$id)")
24+ callback.onCompleted(rx_body, null)
25+ return
26+ }
27+ receivedMultiMessage(id, rx_body)
28+ }
29+
30+ override fun onReceiveProgress(currentBytes: Int, totalBytes: Int, rx_body: ByteArray?)
31+ {
32+ if (rx_body == null)
33+ {
34+ Log.v(TAG, " CanonLiveViewReceiver: MSG BODY is NULL. ($currentBytes/$totalBytes)")
35+ callback.onCompleted(rx_body, null)
36+ return
37+ }
38+ if (isDumpLog)
39+ {
40+ Log.v(TAG, " CanonLiveViewReceiver::onReceiveProgress() $currentBytes/$totalBytes [size: ${rx_body.size}]")
41+ }
42+ parseReceivedBody(rx_body)
43+ }
44+
45+
46+ private fun parseReceivedBody(rx_body: ByteArray)
47+ {
48+ try
49+ {
50+ val length = rx_body.size
51+ var dataPosition = 0
52+ if (!receivedFirstData)
53+ {
54+ // データを最初に読んだとき。ヘッダ部分を読み飛ばす
55+ receivedFirstData = true
56+ dataPosition = rx_body[0].toUByte().toInt()
57+ if (isDumpLog)
58+ {
59+ Log.v(TAG, " FIRST DATA POS. : $dataPosition len: $length ")
60+ SimpleLogDumper.dump_bytes(" [1stData]", rx_body.copyOfRange(0, (32)))
61+ }
62+ }
63+ else
64+ {
65+ // 2回目以降の受信データ
66+ if (receivedRemainBytes > 0)
67+ {
68+ // データの読み込みが途中だった場合...
69+ if (length < receivedRemainBytes)
70+ {
71+ // 全部コピーする、足りないバイト数は残す
72+ receivedRemainBytes -= length
73+ receivedTotalBytes += rx_body.size
74+ byteStream.write(rx_body, 0, rx_body.size)
75+ return
76+ }
77+ else
78+ {
79+ byteStream.write(rx_body, dataPosition, receivedRemainBytes)
80+ dataPosition = receivedRemainBytes
81+ receivedRemainBytes = 0
82+ }
83+ }
84+ }
85+ while (dataPosition <= length - 12)
86+ {
87+ val body_size = (rx_body[dataPosition].toUByte()).toInt() + ((rx_body[dataPosition + 1].toUByte()).toInt() * 256) + ((rx_body[dataPosition + 2].toUByte()).toInt() * 256 * 256) + ((rx_body[dataPosition + 3].toUByte()).toInt() * 256 * 256 * 256)
88+ //Log.v(TAG, " <> body_size : ${body_size} [$dataPosition] ($length) aa: ${rx_body[dataPosition].toUByte().toInt()} ${rx_body[dataPosition + 1].toUByte().toInt()} + ${rx_body[dataPosition + 2].toUByte().toInt()}")
89+ if (body_size <= 12)
90+ {
91+ Log.v(TAG, " ----- BODY SIZE IS SMALL : " + dataPosition + " (" + body_size + ") [" + receivedRemainBytes + "] " + rx_body.size + " ")
92+ break
93+ }
94+
95+ //Log.v(TAG, " RX DATA : " + dataPosition + " (" + body_size + ") [" + receivedRemainBytes + "] (" + receivedTotalBytes + ")");
96+ if (dataPosition + body_size > length)
97+ {
98+ // データがすべてバッファ内になかったときは、バッファすべてコピーして残ったサイズを記憶しておく。
99+ val copysize = length - (dataPosition + 12)
100+ byteStream.write(rx_body, dataPosition + 12, copysize)
101+ receivedRemainBytes = body_size - copysize - 12 // マイナス12は、ヘッダ分
102+ receivedTotalBytes += copysize
103+ //Log.v(TAG, " ----- copy : " + (data_position + (12)) + " " + copysize + " remain : " + received_remain_bytes + " body size : " + body_size);
104+ break
105+ }
106+ try
107+ {
108+ byteStream.write(rx_body, dataPosition + 12, body_size - 12)
109+ dataPosition += body_size
110+ receivedTotalBytes += 12
111+ //Log.v(TAG, " --- COPY : " + (data_position + 12) + " " + (body_size - (12)) + " remain : " + received_remain_bytes);
112+ }
113+ catch (e: Exception)
114+ {
115+ Log.v(TAG, " pos : $dataPosition size : $body_size length : $length")
116+ e.printStackTrace()
117+ }
118+ }
119+ }
120+ catch (e : Exception)
121+ {
122+ e.printStackTrace()
123+ }
124+ }
125+
126+
127+ private fun receivedMultiMessage(id: Int, rx_body: ByteArray)
128+ {
129+ try
130+ {
131+ byteStream.write(rx_body, 0, rx_body.size)
132+ if (isDumpLog)
133+ {
134+ val thumbNail = byteStream.toByteArray()
135+ var dumpLength = thumbNail.size
136+ if (dumpLength > 256)
137+ {
138+ dumpLength = 256
139+ }
140+ SimpleLogDumper.dump_bytes(" [--ID:$id(>)--]", Arrays.copyOfRange(thumbNail, 0, dumpLength))
141+ SimpleLogDumper.dump_bytes(" [-ID:$id(<)-]", Arrays.copyOfRange(thumbNail, thumbNail.size - dumpLength, thumbNail.size))
142+ }
143+ callback.onCompleted(byteStream.toByteArray(), null)
144+ receivedFirstData = false
145+ receivedRemainBytes = 0
146+ receivedTotalBytes = 0
147+ byteStream.reset()
148+ }
149+ catch (e: Exception)
150+ {
151+ e.printStackTrace()
152+ callback.onErrorOccurred(e)
153+ }
154+ }
155+
156+
157+
158+ override fun isReceiveMulti(): Boolean
159+ {
160+ return (true)
161+ }
162+
163+ companion object
164+ {
165+ private val TAG = "CanonLiveViewReceiver"
166+ }
167+
168+}
\ No newline at end of file
--- /dev/null
+++ b/app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/liveview/CanonLiveViewImageReceiverPrev.java
@@ -0,0 +1,166 @@
1+package net.osdn.gokigen.a01d.camera.canon.wrapper.liveview;
2+
3+import android.util.Log;
4+
5+import androidx.annotation.NonNull;
6+import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommandCallback;
7+import net.osdn.gokigen.a01d.camera.ptpip.wrapper.liveview.IPtpIpLiveViewImageCallback;
8+import net.osdn.gokigen.a01d.camera.utils.SimpleLogDumper;
9+
10+import java.io.ByteArrayOutputStream;
11+import java.util.Arrays;
12+
13+public class CanonLiveViewImageReceiverPrev implements IPtpIpCommandCallback
14+{
15+ private final String TAG = toString();
16+
17+ private final IPtpIpLiveViewImageCallback callback;
18+
19+ private int received_total_bytes = 0;
20+ private int received_remain_bytes = 0;
21+
22+ private int target_image_size = 0;
23+ private boolean receivedFirstData = false;
24+ private final ByteArrayOutputStream byteStream;
25+
26+ CanonLiveViewImageReceiverPrev(@NonNull IPtpIpLiveViewImageCallback callback)
27+ {
28+ this.callback = callback;
29+ byteStream = new ByteArrayOutputStream();
30+ }
31+
32+ @Override
33+ public void receivedMessage(int id, byte[] rx_body)
34+ {
35+ try
36+ {
37+ // end of receive sequence.
38+ if (rx_body != null)
39+ {
40+ byteStream.write(rx_body, 0, rx_body.length);
41+ }
42+ byte [] thumbnail = byteStream.toByteArray();
43+ Log.v(TAG, " TransferComplete() RECEIVED : " + id + " size : " + target_image_size + " (" + thumbnail.length + ")");
44+ int dump_length = 96;
45+ if (thumbnail.length > dump_length)
46+ {
47+ SimpleLogDumper.dump_bytes(" [xxx(head)xxx]", Arrays.copyOfRange(thumbnail, 0, (dump_length)));
48+ SimpleLogDumper.dump_bytes(" [zz(bottom)zz]", Arrays.copyOfRange(thumbnail, (thumbnail.length - dump_length), (thumbnail.length)));
49+ }
50+ callback.onCompleted(byteStream.toByteArray(), null);
51+ receivedFirstData = false;
52+ received_remain_bytes = 0;
53+ received_total_bytes = 0;
54+ target_image_size = 0;
55+ byteStream.reset();
56+ }
57+ catch (Exception e)
58+ {
59+ e.printStackTrace();
60+ {
61+ callback.onErrorOccurred(e);
62+ }
63+ }
64+ }
65+
66+ @Override
67+ public void onReceiveProgress(final int currentBytes, final int totalBytes, byte[] rx_body)
68+ {
69+ Log.v(TAG, " onReceiveProgress() " + currentBytes + "/" + totalBytes);
70+
71+ // 受信したデータから、通信のヘッダ部分を削除する
72+ cutHeader(rx_body);
73+ }
74+
75+ private void cutHeader(byte[] rx_body)
76+ {
77+ if (rx_body == null)
78+ {
79+ return;
80+ }
81+ try
82+ {
83+ int length = rx_body.length;
84+ int data_position = 0;
85+ if (!receivedFirstData)
86+ {
87+ // データを最初に読んだとき。ヘッダ部分を読み飛ばす
88+ receivedFirstData = true;
89+ data_position = (int) rx_body[0] & (0xff);
90+ Log.v(TAG, " FIRST DATA POS. : " + data_position + " [size : " + rx_body.length + "]");
91+ //SimpleLogDumper.dump_bytes(" [sssss]", Arrays.copyOfRange(rx_body, 0, (96)));
92+ }
93+ else if (received_remain_bytes > 0)
94+ {
95+ // データの読み込みが途中だった場合...
96+ if (length < received_remain_bytes)
97+ {
98+ // 全部コピーする、足りないバイト数は残す
99+ received_remain_bytes = received_remain_bytes - length;
100+ received_total_bytes = received_total_bytes + rx_body.length;
101+ byteStream.write(rx_body, 0, rx_body.length);
102+ return;
103+ }
104+ else
105+ {
106+ byteStream.write(rx_body, data_position, received_remain_bytes);
107+ data_position = received_remain_bytes;
108+ received_remain_bytes = 0;
109+ }
110+ }
111+
112+ while (data_position <= (length - 12))
113+ {
114+ int body_size = (rx_body[data_position] & 0xff) + ((rx_body[data_position + 1] & 0xff) << 8) +
115+ ((rx_body[data_position + 2] & 0xff) << 16) + ((rx_body[data_position + 3] & 0xff) << 24);
116+ if (body_size <= 12)
117+ {
118+ Log.v(TAG, " --- BODY SIZE IS SMALL : " + data_position + " (" + body_size + ") [" + received_remain_bytes + "] " + rx_body.length + " (" + target_image_size + ")");
119+ //int startpos = (data_position > 48) ? (data_position - 48) : 0;
120+ //SimpleLogDumper.dump_bytes(" [xxx]", Arrays.copyOfRange(rx_body, startpos, (data_position + 48)));
121+ break;
122+ }
123+
124+ // 受信データ(のヘッダ部分)をダンプする
125+ Log.v(TAG, " RX DATA : " + data_position + " (" + body_size + ") [" + received_remain_bytes + "] (" + received_total_bytes + ")");
126+ //SimpleLogDumper.dump_bytes(" [zzz] " + data_position + ": ", Arrays.copyOfRange(rx_body, data_position, (data_position + 48)));
127+
128+ if ((data_position + body_size) > length)
129+ {
130+ // データがすべてバッファ内になかったときは、バッファすべてコピーして残ったサイズを記憶しておく。
131+ int copysize = (length - ((data_position + 12)));
132+ byteStream.write(rx_body, (data_position + 12), copysize);
133+ received_remain_bytes = body_size - copysize - 12; // マイナス12は、ヘッダ分
134+ received_total_bytes = received_total_bytes + copysize;
135+ Log.v(TAG, " ----- copy : " + (data_position + 12) + " " + copysize + " remain : " + received_remain_bytes + " body size : " + body_size);
136+ break;
137+ }
138+ try
139+ {
140+ byteStream.write(rx_body, (data_position + 12), (body_size - 12));
141+ data_position = data_position + body_size;
142+ received_total_bytes = received_total_bytes + 12;
143+ Log.v(TAG, " --- COPY : " + (data_position + 12) + " " + (body_size - 12) + " remain : " + received_remain_bytes);
144+
145+ }
146+ catch (Exception e)
147+ {
148+ Log.v(TAG, " pos : " + data_position + " size : " + body_size + " length : " + length);
149+ e.printStackTrace();
150+ }
151+ }
152+ }
153+ catch (Exception e)
154+ {
155+ e.printStackTrace();
156+ }
157+
158+ }
159+
160+ @Override
161+ public boolean isReceiveMulti()
162+ {
163+ return (true);
164+ }
165+
166+}
--- a/app/src/main/java/net/osdn/gokigen/a01d/camera/ptpip/wrapper/command/IPtpIpMessages.java
+++ b/app/src/main/java/net/osdn/gokigen/a01d/camera/ptpip/wrapper/command/IPtpIpMessages.java
@@ -29,6 +29,7 @@ public interface IPtpIpMessages
2929 int SEQ_GET_DEVICE_PROP1 = 24;
3030 int SEQ_GET_DEVICE_PROP2 = 25;
3131 int SEQ_GET_CAMERASTATUS = 26;
32+ int SEQ_SET_REMOTE_SHOOTING_MODE = 27;
3233
3334 int GET_STORAGE_ID = 101;
3435 int GET_STORAGE_INFO = 102;
--- a/app/src/main/java/net/osdn/gokigen/a01d/camera/ptpip/wrapper/command/PtpIpCommandPublisher.kt
+++ b/app/src/main/java/net/osdn/gokigen/a01d/camera/ptpip/wrapper/command/PtpIpCommandPublisher.kt
@@ -198,7 +198,11 @@ class PtpIpCommandPublisher(private val ipAddress : String, private val portNumb
198198 isHold = true
199199 holdId = command.holdId
200200 }
201- Log.v(TAG, "Enqueue [ID: " + command.getId() + "] size: " + commandQueue.size);
201+ if (commandQueue.size > 1)
202+ {
203+ // たまっているときだけログを吐く
204+ Log.v(TAG, "Enqueue [ID: " + command.getId() + "] size: " + commandQueue.size)
205+ }
202206 return (commandQueue.offer(command))
203207 }
204208 catch (e: Exception)
--- a/app/src/main/java/net/osdn/gokigen/a01d/preference/IPreferencePropertyAccessor.java
+++ b/app/src/main/java/net/osdn/gokigen/a01d/preference/IPreferencePropertyAccessor.java
@@ -120,6 +120,9 @@ public interface IPreferencePropertyAccessor
120120 String CANON_HOST_IP = "canon_host_ip";
121121 String CANON_HOST_IP_DEFAULT_VALUE = "192.168.0.1";
122122
123+ String CANON_LIVEVIEW_WAIT = "canon_liveview_wait";
124+ String CANON_LIVEVIEW_WAIT_DEFAULT_VALUE = "25";
125+
123126 /*
124127 int CHOICE_SPLASH_SCREEN = 10;
125128
--- a/app/src/main/java/net/osdn/gokigen/a01d/preference/canon/CanonPreferenceFragment.java
+++ b/app/src/main/java/net/osdn/gokigen/a01d/preference/canon/CanonPreferenceFragment.java
@@ -136,6 +136,9 @@ public class CanonPreferenceFragment extends PreferenceFragmentCompat implements
136136 if (!items.containsKey(IPreferencePropertyAccessor.CANON_HOST_IP)) {
137137 editor.putString(IPreferencePropertyAccessor.CANON_HOST_IP, IPreferencePropertyAccessor.CANON_HOST_IP_DEFAULT_VALUE);
138138 }
139+ if (!items.containsKey(IPreferencePropertyAccessor.CANON_LIVEVIEW_WAIT)) {
140+ editor.putString(IPreferencePropertyAccessor.CANON_LIVEVIEW_WAIT, IPreferencePropertyAccessor.CANON_LIVEVIEW_WAIT_DEFAULT_VALUE);
141+ }
139142 editor.apply();
140143 }
141144 catch (Exception e)
@@ -304,6 +307,7 @@ public class CanonPreferenceFragment extends PreferenceFragmentCompat implements
304307 * @param key Preference(データ)のキー
305308 * @param defaultValue Preferenceのデフォルト値
306309 */
310+ @SuppressWarnings("SameParameterValue")
307311 private void setBooleanPreference(String pref_key, String key, boolean defaultValue)
308312 {
309313 try
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -343,4 +343,7 @@
343343 <string name="pref_canon_host_ip">カメラIPアドレス</string>
344344 <string name="pref_summary_canon_host_ip">通常、変更は不要です (初期値:192.168.0.1)</string>
345345
346+ <string name="pref_canon_liveview_wait">LV画像受信待ち間隔(default: 25)</string>
347+ <string name="pref_summary_canon_liveview_wait">ライブビュー画像受信間隔を指定します</string>
348+
346349 </resources>
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -348,4 +348,7 @@
348348 <string name="pref_canon_host_ip">Camera IP Address</string>
349349 <string name="pref_summary_canon_host_ip">default: 192.168.0.1 </string>
350350
351+ <string name="pref_canon_liveview_wait">Liveview receive wait (default: 25)</string>
352+ <string name="pref_summary_canon_liveview_wait"> </string>
353+
351354 </resources>
--- a/app/src/main/res/xml/preferences_canon.xml
+++ b/app/src/main/res/xml/preferences_canon.xml
@@ -53,6 +53,13 @@
5353 android:title="@string/pref_canon_host_ip"
5454 android:defaultValue="192.168.0.1"
5555 android:summary="@string/pref_summary_canon_host_ip" />
56+
57+ <EditTextPreference
58+ android:key="canon_liveview_wait"
59+ android:title="@string/pref_canon_liveview_wait"
60+ android:defaultValue="25"
61+ android:summary="@string/pref_summary_canon_liveview_wait" />
62+
5663 <!--
5764 <CheckBoxPreference
5865 android:key="capture_both_camera_and_live_view"
Show on old repository browser