import androidx.preference.PreferenceManager
import net.osdn.gokigen.a01d.camera.ILiveViewControl
import net.osdn.gokigen.a01d.camera.fujix.wrapper.command.IFujiXCommunication
-import net.osdn.gokigen.a01d.camera.utils.SimpleLogDumper
import net.osdn.gokigen.a01d.liveview.liveviewlistener.CameraLiveViewListenerImpl
import net.osdn.gokigen.a01d.liveview.liveviewlistener.ILiveViewListener
import net.osdn.gokigen.a01d.preference.IPreferencePropertyAccessor
import java.io.ByteArrayOutputStream
import java.net.Socket
-import java.util.*
class FujiXLiveViewControl(activity: Activity, private val ipAddress: String, private val portNumber: Int) : ILiveViewControl, IFujiXCommunication
{
- private val TAG = toString()
+ private val classTag = toString()
private val liveViewListener = CameraLiveViewListenerImpl()
private var waitMs = 0
private var isStart = false
e.printStackTrace()
waitMs = 100
}
- Log.v(TAG, " LOOP WAIT : $waitMs ms")
+ Log.v(classTag, " LOOP WAIT : $waitMs ms")
}
override fun startLiveView()
if (isStart)
{
// すでに受信スレッド動作中なので抜ける
- Log.v(TAG, " LiveView IS ALREADY STARTED")
+ Log.v(classTag, " LiveView IS ALREADY STARTED")
return
}
isStart = true
}
catch (e: Exception)
{
- Log.v(TAG, " IP : $ipAddress port : $portNumber")
+ Log.v(classTag, " IP : $ipAddress port : $portNumber")
e.printStackTrace()
}
}.start()
{
if (logcat)
{
- Log.v(TAG, message)
+ Log.v(classTag, message)
}
}
- private fun dump_bytes(header : String, byteArray: ByteArray, size : Int = 24)
- {
- if (logcat)
- {
- SimpleLogDumper.dump_bytes(header, byteArray.copyOf(size))
- }
- }
-
- private fun startReceiveAlter(socket: Socket)
- {
- var errorCount = 0
- val isr = socket.getInputStream()
- val byteArray = ByteArray(BUFFER_SIZE + 32)
-
- while (isStart)
- {
- try
- {
- var findJpeg = false
- var length_bytes: Int
- var read_bytes = isr.read(byteArray, 0, BUFFER_SIZE)
- if (read_bytes > DATA_HEADER_OFFSET)
- {
- // メッセージボディの先頭にあるメッセージ長分は読み込む
- length_bytes = (byteArray[3].toInt() and 0xff shl 24) + (byteArray[2].toInt() and 0xff shl 16) + (byteArray[1].toInt() and 0xff shl 8) + (byteArray[0].toInt() and 0xff)
- if (byteArray[18] == 0xff.toByte() && byteArray[19] == 0xd8.toByte())
- {
- findJpeg = true
- while (read_bytes < length_bytes && read_bytes < BUFFER_SIZE && length_bytes <= BUFFER_SIZE)
- {
- val append_bytes = isr.read(byteArray, read_bytes, length_bytes - read_bytes)
- logcat("READ AGAIN : $append_bytes [$read_bytes]")
- if (append_bytes < 0)
- {
- break
- }
- read_bytes = read_bytes + append_bytes
- }
- logcat("READ BYTES : " + read_bytes + " (" + length_bytes + " bytes, " + waitMs + "ms)")
- }
- else
- {
- // ウェイトを短めに入れてマーカーを拾うまで待つ
- Thread.sleep(waitMs / 4.toLong())
- logcat(" --- wait LiveView ---")
- continue
- }
- }
-
- // 先頭データをダンプする
- dump_bytes("[LV]", byteArray)
- if (findJpeg)
- {
- liveViewListener.onUpdateLiveView(Arrays.copyOfRange(byteArray, DATA_HEADER_OFFSET, read_bytes - DATA_HEADER_OFFSET), null)
- errorCount = 0
- }
- Thread.sleep(waitMs.toLong())
- }
- catch (e: Exception)
- {
- e.printStackTrace()
- errorCount++
- }
-
- if (errorCount > ERROR_LIMIT)
- {
- // エラーが連続でたくさん出たらループをストップ(ライブビューを停止)させる
- isStart = false
- }
- }
-
- try
- {
- isr.close()
- socket.close()
- }
- catch (e: Exception)
- {
- e.printStackTrace()
- }
- }
-
- private fun findJpegStartTag(byteArray : ByteArray, arraySize : Int) : Int
+ private fun findJpegTag(byteArray : ByteArray, arraySize : Int, charTag : Byte) : Int
{
var index = 0
while (index < arraySize)
{
- val value1 = byteArray.get(index)
- if (value1 == 0xff.toByte())
- {
- if (byteArray.get(index + 1) == 0xd8.toByte())
- {
- return (index)
- }
- }
- index++
- }
- return (-1)
- }
-
- private fun findJpegFinishTag(byteArray : ByteArray, arraySize : Int) : Int
- {
- var index = 0
-
- while (index < arraySize)
- {
- val value1 = byteArray.get(index)
+ val value1 = byteArray[index]
if (value1 == 0xff.toByte())
{
- if (byteArray.get(index + 1) == 0xd9.toByte())
+ if (byteArray[index + 1] == charTag)
{
return (index)
}
if (!findJpeg)
{
- val startPosition = findJpegStartTag(byteArray, readBytes)
+ val startPosition = findJpegTag(byteArray, readBytes, 0xd8.toByte())
if (startPosition < 0)
{
Thread.sleep(waitMs / 4.toLong())
continue
}
+ // JPEGのスタートタグが見つかっていた場合
findJpeg = true
if (startPosition < readBytes)
{
}
}
- // JPEGã\81®ã\82¹ã\82¿ã\83¼ã\83\88ã\82¿ã\82°ã\81\8cè¦\8bã\81¤ã\81\8bã\81£ã\81¦ã\81\84ã\81\9få ´å\90\88...
- val endPosition = findJpegFinishTag(byteArray, readBytes)
+ // JPEGã\81®ã\82¨ã\83³ã\83\89ã\82¿ã\82°ã\82\92æ\8e¢ã\81\99
+ val endPosition = findJpegTag(byteArray, readBytes, 0xd9.toByte())
if (endPosition < 0)
{
// エンドマーカーがなかった...全部streamに流しておく
companion object
{
- private const val DATA_HEADER_OFFSET = 18
private const val BUFFER_SIZE = 2048 * 1280
private const val ERROR_LIMIT = 30
}
+++ /dev/null
-package net.osdn.gokigen.a01d.camera.fujix.wrapper.liveview;
-
-import android.app.Activity;
-import android.content.SharedPreferences;
-import android.util.Log;
-import androidx.annotation.NonNull;
-import androidx.preference.PreferenceManager;
-
-import net.osdn.gokigen.a01d.camera.ILiveViewControl;
-import net.osdn.gokigen.a01d.camera.fujix.wrapper.command.IFujiXCommunication;
-import net.osdn.gokigen.a01d.liveview.liveviewlistener.CameraLiveViewListenerImpl;
-import net.osdn.gokigen.a01d.liveview.liveviewlistener.ILiveViewListener;
-
-import java.io.InputStream;
-import java.net.Socket;
-import java.util.Arrays;
-
-import static net.osdn.gokigen.a01d.preference.IPreferencePropertyAccessor.FUJIX_LIVEVIEW_WAIT;
-import static net.osdn.gokigen.a01d.preference.IPreferencePropertyAccessor.FUJIX_LIVEVIEW_WAIT_DEFAULT_VALUE;
-
-
-public class FujiXLiveViewControlAlternate implements ILiveViewControl, IFujiXCommunication
-{
- private final String TAG = toString();
- private final String ipAddress;
- private final int portNumber;
- private final CameraLiveViewListenerImpl liveViewListener;
- private int waitMs = 0;
- private static final int DATA_HEADER_OFFSET = 18;
- private static final int BUFFER_SIZE = 2048 * 1280;
- private static final int ERROR_LIMIT = 30;
- private boolean isStart = false;
- private boolean logcat = true;
-
- public FujiXLiveViewControlAlternate(@NonNull Activity activity, String ip, int portNumber)
- {
- this.ipAddress = ip;
- this.portNumber = portNumber;
- liveViewListener = new CameraLiveViewListenerImpl();
-
- try
- {
- SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
- String waitMsStr = preferences.getString(FUJIX_LIVEVIEW_WAIT, FUJIX_LIVEVIEW_WAIT_DEFAULT_VALUE);
- logcat("waitMS : " + waitMsStr);
- if (waitMsStr != null)
- {
- int wait = Integer.parseInt(waitMsStr);
- if ((wait >= 20) && (wait <= 800))
- {
- waitMs = wait;
- }
- }
- }
- catch (Exception e)
- {
- e.printStackTrace();
- waitMs = 100;
- }
- Log.v(TAG, "LOOP WAIT : " + waitMs + " ms");
- }
-
- @Override
- public void startLiveView()
- {
- if (isStart)
- {
- // すでに受信スレッド動作中なので抜ける
- Log.v(TAG, " LiveView IS ALREADY STARTED");
- return;
- }
- isStart = true;
- Thread thread = new Thread(new Runnable()
- {
- @Override
- public void run()
- {
- try
- {
- Socket socket = new Socket(ipAddress, portNumber);
- startReceive(socket);
- }
- catch (Exception e)
- {
- Log.v(TAG, " IP : " + ipAddress + " port : " + portNumber);
- e.printStackTrace();
- }
- }
- });
- try
- {
- thread.start();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-
- @Override
- public void stopLiveView()
- {
- isStart = false;
- }
-
- private void startReceive(Socket socket)
- {
- String lvHeader = "[LV]";
- int lvHeaderDumpBytes = 24;
-
- int errorCount = 0;
- InputStream isr;
- byte[] byteArray;
- try
- {
- isr = socket.getInputStream();
- byteArray = new byte[BUFFER_SIZE + 32];
- }
- catch (Exception e)
- {
- e.printStackTrace();
- Log.v(TAG, "===== startReceive() aborted.");
- return;
- }
- while (isStart)
- {
- try
- {
- boolean findJpeg = false;
- int length_bytes;
- int read_bytes = isr.read(byteArray, 0, BUFFER_SIZE);
-
- // 先頭データ(48バイト分)をダンプ
- dump_bytes("[lv]", byteArray, 48);
-
- if (read_bytes > DATA_HEADER_OFFSET)
- {
- // メッセージボディの先頭にあるメッセージ長分は読み込む
- length_bytes = ((((int) byteArray[3]) & 0xff) << 24) + ((((int) byteArray[2]) & 0xff) << 16) + ((((int) byteArray[1]) & 0xff) << 8) + (((int) byteArray[0]) & 0xff);
- if ((byteArray[18] == (byte)0xff)&&(byteArray[19] == (byte)0xd8))
- {
- findJpeg = true;
- while ((read_bytes < length_bytes) && (read_bytes < BUFFER_SIZE) && (length_bytes <= BUFFER_SIZE))
- {
- int append_bytes = isr.read(byteArray, read_bytes, length_bytes - read_bytes);
- logcat("READ AGAIN : " + append_bytes + " [" + read_bytes + "]");
- if (append_bytes < 0)
- {
- break;
- }
- read_bytes = read_bytes + append_bytes;
- }
- logcat("READ BYTES : " + read_bytes + " (" + length_bytes + " bytes, " + waitMs + "ms)");
- }
- else
- {
- // ウェイトを短めに入れてマーカーを拾うまで待つ
- Thread.sleep(waitMs/4);
- logcat(" --- wait LiveView ---");
- continue;
- }
- }
-
- // 先頭データ(24バイト分)をダンプ
- dump_bytes(lvHeader, byteArray, lvHeaderDumpBytes);
-
- if (findJpeg)
- {
- liveViewListener.onUpdateLiveView(Arrays.copyOfRange(byteArray, DATA_HEADER_OFFSET, read_bytes - DATA_HEADER_OFFSET), null);
- errorCount = 0;
- }
- Thread.sleep(waitMs);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- errorCount++;
- }
- if (errorCount > ERROR_LIMIT)
- {
- // エラーが連続でたくさん出たらループをストップさせる
- isStart = false;
- }
- }
- try
- {
- isr.close();
- socket.close();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-
-
- @Override
- public void updateDigitalZoom()
- {
-
- }
-
- @Override
- public void updateMagnifyingLiveViewScale(boolean isChangeScale)
- {
-
- }
-
- @Override
- public float getMagnifyingLiveViewScale()
- {
- return (1.0f);
- }
-
- @Override
- public void changeLiveViewSize(String size)
- {
-
- }
-
- @Override
- public float getDigitalZoomScale()
- {
- return (1.0f);
- }
-
- public ILiveViewListener getLiveViewListener()
- {
- return (liveViewListener);
- }
-
- @Override
- public boolean connect()
- {
- return (true);
- }
-
- @Override
- public void disconnect()
- {
- isStart = false;
- }
-
- /**
- * デバッグ用:ログにバイト列を出力する
- *
- */
- private void dump_bytes(String header, byte[] data, int dumpBytes)
- {
- if (!logcat)
- {
- // ログ出力しないモードだった
- return;
- }
-
- int index = 0;
- StringBuffer message;
- if (dumpBytes <= 0)
- {
- dumpBytes = 24;
- }
- message = new StringBuffer();
- for (int point = 0; point < dumpBytes; point++)
- {
- byte item = data[point];
- index++;
- message.append(String.format("%02x ", item));
- if (index >= 8)
- {
- Log.v(TAG, header + " " + message);
- index = 0;
- message = new StringBuffer();
- }
- }
- if (index != 0)
- {
- Log.v(TAG, header + " " + message);
- }
- System.gc();
- }
-
- private void logcat(String message)
- {
- if (logcat)
- {
- Log.v(TAG, message);
- }
- }
-}