OPC(Olympus Air)用望遠鏡アプリ。
Revisión | 78867656d1c8b75b4f292510bc8936b953ff949e (tree) |
---|---|
Tiempo | 2020-12-19 10:40:35 |
Autor | MRSa <mrsa@myad...> |
Commiter | MRSa |
Canonのライブビュー通信安定性を向上させる。
@@ -68,6 +68,7 @@ public class CanonInterfaceProvider implements IPtpIpInterfaceProvider, IDisplay | ||
68 | 68 | this.activity = context; |
69 | 69 | |
70 | 70 | String ipAddress; |
71 | + int delayMs = 30; | |
71 | 72 | try |
72 | 73 | { |
73 | 74 | SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); |
@@ -76,6 +77,22 @@ public class CanonInterfaceProvider implements IPtpIpInterfaceProvider, IDisplay | ||
76 | 77 | { |
77 | 78 | ipAddress = "192.168.0.1"; |
78 | 79 | } |
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 | + } | |
79 | 96 | } |
80 | 97 | catch (Exception e) |
81 | 98 | { |
@@ -84,7 +101,7 @@ public class CanonInterfaceProvider implements IPtpIpInterfaceProvider, IDisplay | ||
84 | 101 | } |
85 | 102 | Log.v(TAG, " Canon IP : " + ipAddress); |
86 | 103 | commandPublisher = new PtpIpCommandPublisher(ipAddress, CONTROL_PORT, false, false); |
87 | - liveViewControl = new CanonLiveViewControl(context, this, 10); // | |
104 | + liveViewControl = new CanonLiveViewControl(context, this, delayMs); // | |
88 | 105 | asyncReceiver = new PtpIpAsyncResponseReceiver(ipAddress, ASYNC_RESPONSE_PORT); |
89 | 106 | statusChecker = new CanonStatusChecker(context, commandPublisher, ipAddress, EVENT_PORT); |
90 | 107 | canonConnection = new CanonConnection(context, provider, this, statusChecker); |
@@ -29,7 +29,7 @@ public class CanonCameraConnectSequence implements Runnable, IPtpIpCommandCallba | ||
29 | 29 | private final IPtpIpInterfaceProvider interfaceProvider; |
30 | 30 | private final IPtpIpCommandPublisher commandIssuer; |
31 | 31 | private final CanonStatusChecker statusChecker; |
32 | - private boolean isDumpLog = false; | |
32 | + private final boolean isDumpLog = false; | |
33 | 33 | |
34 | 34 | CanonCameraConnectSequence(@NonNull Activity context, @NonNull ICameraStatusReceiver statusReceiver, @NonNull final ICameraConnection cameraConnection, @NonNull IPtpIpInterfaceProvider interfaceProvider, @NonNull CanonStatusChecker statusChecker) |
35 | 35 | { |
@@ -157,7 +157,8 @@ public class CanonCameraConnectSequence implements Runnable, IPtpIpCommandCallba | ||
157 | 157 | case SEQ_GET_EVENT1: |
158 | 158 | Log.v(TAG, " SEQ_GET_EVENT1 "); |
159 | 159 | 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)); | |
161 | 162 | break; |
162 | 163 | |
163 | 164 | case SEQ_DEVICE_INFORMATION: |
@@ -207,9 +208,29 @@ public class CanonCameraConnectSequence implements Runnable, IPtpIpCommandCallba | ||
207 | 208 | case SEQ_SET_DEVICE_PROPERTY_3: |
208 | 209 | Log.v(TAG, " SEQ_SET_DEVICE_PROPERTY_3 "); |
209 | 210 | 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)); | |
210 | 212 | commandIssuer.enqueueCommand(new CanonSetDevicePropertyValue(this, SEQ_DEVICE_PROPERTY_FINISHED, isDumpLog, 0, 300, 0xd1b0, 0x08)); |
211 | 213 | break; |
212 | 214 | |
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 | + | |
213 | 234 | case SEQ_DEVICE_PROPERTY_FINISHED: |
214 | 235 | Log.v(TAG, " SEQ_DEVICE_PROPERTY_FINISHED "); |
215 | 236 | interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.connect_connect_finished), false, false, 0); |
@@ -9,7 +9,7 @@ import net.osdn.gokigen.a01d.camera.ILiveViewControl; | ||
9 | 9 | import net.osdn.gokigen.a01d.camera.ptpip.IPtpIpInterfaceProvider; |
10 | 10 | import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommandPublisher; |
11 | 11 | 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; | |
13 | 13 | import net.osdn.gokigen.a01d.camera.ptpip.wrapper.liveview.IPtpIpLiveViewImageCallback; |
14 | 14 | import net.osdn.gokigen.a01d.liveview.liveviewlistener.IImageDataReceiver; |
15 | 15 | import net.osdn.gokigen.a01d.liveview.liveviewlistener.ILiveViewListener; |
@@ -24,7 +24,8 @@ public class CanonLiveViewControl implements ILiveViewControl, ILiveViewListener | ||
24 | 24 | private final String TAG = this.toString(); |
25 | 25 | private final IPtpIpCommandPublisher commandIssuer; |
26 | 26 | private final int delayMs; |
27 | - private CanonLiveViewImageReceiver imageReceiver; | |
27 | + //private CanonLiveViewImageReceiver imageReceiver; | |
28 | + private final CanonLiveViewImageReceiver imageReceiver; | |
28 | 29 | private IImageDataReceiver dataReceiver = null; |
29 | 30 | private boolean liveViewIsReceiving = false; |
30 | 31 | private boolean commandIssued = false; |
@@ -33,7 +34,9 @@ public class CanonLiveViewControl implements ILiveViewControl, ILiveViewListener | ||
33 | 34 | { |
34 | 35 | this.commandIssuer = interfaceProvider.getCommandPublisher(); |
35 | 36 | this.delayMs = delayMs; |
37 | + //this.imageReceiver = new CanonLiveViewImageReceiver(this); | |
36 | 38 | this.imageReceiver = new CanonLiveViewImageReceiver(this); |
39 | + Log.v(TAG, " -=-=-=-=-=- CanonLiveViewControl : delay " + delayMs + " ms"); | |
37 | 40 | } |
38 | 41 | |
39 | 42 | public ILiveViewListener getLiveViewListener() |
@@ -65,7 +68,7 @@ public class CanonLiveViewControl implements ILiveViewControl, ILiveViewListener | ||
65 | 68 | if (!commandIssued) |
66 | 69 | { |
67 | 70 | 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)); | |
69 | 72 | } |
70 | 73 | try |
71 | 74 | { |
@@ -152,7 +155,7 @@ public class CanonLiveViewControl implements ILiveViewControl, ILiveViewListener | ||
152 | 155 | { |
153 | 156 | if ((dataReceiver != null)&&(data != null)) |
154 | 157 | { |
155 | - //Log.v(TAG, " ---+++--- RECEIVED LV IMAGE ---+++--- : " + data.length + " bytes."); | |
158 | + Log.v(TAG, " ---+++--- RECEIVED LV IMAGE ---+++--- : " + data.length + " bytes."); | |
156 | 159 | //dataReceiver.setImageData(data, metadata); |
157 | 160 | if (data.length > 8) |
158 | 161 | { |
@@ -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 | -} |
@@ -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 |
@@ -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 | +} |
@@ -29,6 +29,7 @@ public interface IPtpIpMessages | ||
29 | 29 | int SEQ_GET_DEVICE_PROP1 = 24; |
30 | 30 | int SEQ_GET_DEVICE_PROP2 = 25; |
31 | 31 | int SEQ_GET_CAMERASTATUS = 26; |
32 | + int SEQ_SET_REMOTE_SHOOTING_MODE = 27; | |
32 | 33 | |
33 | 34 | int GET_STORAGE_ID = 101; |
34 | 35 | int GET_STORAGE_INFO = 102; |
@@ -198,7 +198,11 @@ class PtpIpCommandPublisher(private val ipAddress : String, private val portNumb | ||
198 | 198 | isHold = true |
199 | 199 | holdId = command.holdId |
200 | 200 | } |
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 | + } | |
202 | 206 | return (commandQueue.offer(command)) |
203 | 207 | } |
204 | 208 | catch (e: Exception) |
@@ -120,6 +120,9 @@ public interface IPreferencePropertyAccessor | ||
120 | 120 | String CANON_HOST_IP = "canon_host_ip"; |
121 | 121 | String CANON_HOST_IP_DEFAULT_VALUE = "192.168.0.1"; |
122 | 122 | |
123 | + String CANON_LIVEVIEW_WAIT = "canon_liveview_wait"; | |
124 | + String CANON_LIVEVIEW_WAIT_DEFAULT_VALUE = "25"; | |
125 | + | |
123 | 126 | /* |
124 | 127 | int CHOICE_SPLASH_SCREEN = 10; |
125 | 128 |
@@ -136,6 +136,9 @@ public class CanonPreferenceFragment extends PreferenceFragmentCompat implements | ||
136 | 136 | if (!items.containsKey(IPreferencePropertyAccessor.CANON_HOST_IP)) { |
137 | 137 | editor.putString(IPreferencePropertyAccessor.CANON_HOST_IP, IPreferencePropertyAccessor.CANON_HOST_IP_DEFAULT_VALUE); |
138 | 138 | } |
139 | + if (!items.containsKey(IPreferencePropertyAccessor.CANON_LIVEVIEW_WAIT)) { | |
140 | + editor.putString(IPreferencePropertyAccessor.CANON_LIVEVIEW_WAIT, IPreferencePropertyAccessor.CANON_LIVEVIEW_WAIT_DEFAULT_VALUE); | |
141 | + } | |
139 | 142 | editor.apply(); |
140 | 143 | } |
141 | 144 | catch (Exception e) |
@@ -304,6 +307,7 @@ public class CanonPreferenceFragment extends PreferenceFragmentCompat implements | ||
304 | 307 | * @param key Preference(データ)のキー |
305 | 308 | * @param defaultValue Preferenceのデフォルト値 |
306 | 309 | */ |
310 | + @SuppressWarnings("SameParameterValue") | |
307 | 311 | private void setBooleanPreference(String pref_key, String key, boolean defaultValue) |
308 | 312 | { |
309 | 313 | try |
@@ -343,4 +343,7 @@ | ||
343 | 343 | <string name="pref_canon_host_ip">カメラIPアドレス</string> |
344 | 344 | <string name="pref_summary_canon_host_ip">通常、変更は不要です (初期値:192.168.0.1)</string> |
345 | 345 | |
346 | + <string name="pref_canon_liveview_wait">LV画像受信待ち間隔(default: 25)</string> | |
347 | + <string name="pref_summary_canon_liveview_wait">ライブビュー画像受信間隔を指定します</string> | |
348 | + | |
346 | 349 | </resources> |
@@ -348,4 +348,7 @@ | ||
348 | 348 | <string name="pref_canon_host_ip">Camera IP Address</string> |
349 | 349 | <string name="pref_summary_canon_host_ip">default: 192.168.0.1 </string> |
350 | 350 | |
351 | + <string name="pref_canon_liveview_wait">Liveview receive wait (default: 25)</string> | |
352 | + <string name="pref_summary_canon_liveview_wait"> </string> | |
353 | + | |
351 | 354 | </resources> |
@@ -53,6 +53,13 @@ | ||
53 | 53 | android:title="@string/pref_canon_host_ip" |
54 | 54 | android:defaultValue="192.168.0.1" |
55 | 55 | 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 | + | |
56 | 63 | <!-- |
57 | 64 | <CheckBoxPreference |
58 | 65 | android:key="capture_both_camera_and_live_view" |