--- /dev/null
+package net.osdn.gokigen.a01d.camera.fujix.operation;
+
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import net.osdn.gokigen.a01d.camera.ICaptureControl;
+import net.osdn.gokigen.a01d.camera.fujix.wrapper.command.IFujiXCommandCallback;
+import net.osdn.gokigen.a01d.camera.fujix.wrapper.command.IFujiXCommandIssuer;
+import net.osdn.gokigen.a01d.camera.fujix.wrapper.command.messages.CaptureCommand;
+import net.osdn.gokigen.a01d.liveview.IAutoFocusFrameDisplay;
+
+public class FujiXCaptureControl implements ICaptureControl, IFujiXCommandCallback
+{
+ private final String TAG = this.toString();
+ private final IFujiXCommandIssuer issuer;
+ private final IAutoFocusFrameDisplay frameDisplay;
+
+
+ public FujiXCaptureControl(@NonNull IFujiXCommandIssuer issuer, IAutoFocusFrameDisplay frameDisplay)
+ {
+ this.issuer = issuer;
+ this.frameDisplay = frameDisplay;
+
+ }
+
+ @Override
+ public void doCapture(int kind)
+ {
+ try
+ {
+ issuer.enqueueCommand(new CaptureCommand(this));
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void receivedMessage(int id, byte[] rx_body)
+ {
+ Log.v(TAG, "Response Received.");
+ frameDisplay.hideFocusFrame();
+ }
+}
--- /dev/null
+package net.osdn.gokigen.a01d.camera.fujix.operation;
+
+import android.app.Activity;
+import android.content.SharedPreferences;
+import android.graphics.PointF;
+import android.graphics.RectF;
+import android.util.Log;
+import android.view.MotionEvent;
+
+import androidx.annotation.NonNull;
+import androidx.preference.PreferenceManager;
+
+import net.osdn.gokigen.a01d.camera.IFocusingControl;
+import net.osdn.gokigen.a01d.camera.fujix.wrapper.command.IFujiXCommandCallback;
+import net.osdn.gokigen.a01d.camera.fujix.wrapper.command.IFujiXCommandIssuer;
+import net.osdn.gokigen.a01d.camera.fujix.wrapper.command.messages.FocusLock;
+import net.osdn.gokigen.a01d.camera.fujix.wrapper.command.messages.FocusUnlock;
+import net.osdn.gokigen.a01d.liveview.IAutoFocusFrameDisplay;
+import net.osdn.gokigen.a01d.liveview.IIndicatorControl;
+import net.osdn.gokigen.a01d.preference.IPreferencePropertyAccessor;
+
+public class FujiXFocusingControl implements IFocusingControl, IFujiXCommandCallback
+{
+ private final String TAG = this.toString();
+
+ public static final int FOCUS_LOCK = 0;
+ public static final int FOCUS_UNLOCK = 1;
+
+ private float maxPointLimitWidth;
+ private float maxPointLimitHeight;
+
+ private final IFujiXCommandIssuer issuer;
+ private final IAutoFocusFrameDisplay frameDisplayer;
+ private final IIndicatorControl indicator;
+ private RectF preFocusFrameRect = null;
+
+
+ public FujiXFocusingControl(@NonNull Activity activity, @NonNull IFujiXCommandIssuer issuer, @NonNull final IAutoFocusFrameDisplay frameDisplayer, @NonNull final IIndicatorControl indicator)
+ {
+ this.issuer = issuer;
+ this.frameDisplayer = frameDisplayer;
+ this.indicator = indicator;
+ try
+ {
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
+ String focusPoint = preferences.getString(IPreferencePropertyAccessor.FUJIX_FOCUS_XY, IPreferencePropertyAccessor.FUJIX_FOCUS_XY_DEFAULT_VALUE);
+ String[] focus = focusPoint.split(",");
+ if (focus.length == 2)
+ {
+ maxPointLimitWidth = Integer.parseInt(focus[0]);
+ maxPointLimitHeight = Integer.parseInt(focus[1]);
+ }
+ else
+ {
+ maxPointLimitWidth = 7.0f;
+ maxPointLimitHeight = 7.0f;
+ }
+ Log.v(TAG, "FOCUS RESOLUTION : " + maxPointLimitWidth + "," + maxPointLimitHeight);
+
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ maxPointLimitWidth = 7.0f;
+ maxPointLimitHeight = 7.0f;
+ }
+ }
+
+ @Override
+ public boolean driveAutoFocus(final MotionEvent motionEvent)
+ {
+ Log.v(TAG, "driveAutoFocus()");
+ if (motionEvent.getAction() != MotionEvent.ACTION_DOWN)
+ {
+ return (false);
+ }
+ Thread thread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try
+ {
+ PointF point = frameDisplayer.getPointWithEvent(motionEvent);
+ if (point != null)
+ {
+ preFocusFrameRect = getPreFocusFrameRect(point);
+ showFocusFrame(preFocusFrameRect, IAutoFocusFrameDisplay.FocusFrameStatus.Running, 0.0);
+ if (frameDisplayer.isContainsPoint(point))
+ {
+ lockAutoFocus(point);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ });
+ try
+ {
+ thread.start();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ return (false);
+ }
+
+ @Override
+ public void unlockAutoFocus()
+ {
+ try
+ {
+ issuer.enqueueCommand(new FocusUnlock(this));
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void halfPressShutter(boolean isPressed)
+ {
+ lockAutoFocus(new PointF(0.5f, 0.5f));
+ }
+
+ private void lockAutoFocus(PointF point)
+ {
+ try
+ {
+ byte x = (byte) (0x000000ff & ((int)(Math.round(point.x) * maxPointLimitWidth) + 1));
+ byte y = (byte) (0x000000ff & ((int)(Math.round(point.y) * maxPointLimitHeight) + 1));
+ issuer.enqueueCommand(new FocusLock(x, y, this));
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ *
+ *
+ */
+ private RectF getPreFocusFrameRect(@NonNull PointF point)
+ {
+ float imageWidth = frameDisplayer.getContentSizeWidth();
+ float imageHeight = frameDisplayer.getContentSizeHeight();
+
+ // Display a provisional focus frame at the touched point.
+ float focusWidth = 0.125f; // 0.125 is rough estimate.
+ float focusHeight = 0.125f;
+ if (imageWidth > imageHeight)
+ {
+ focusHeight *= (imageWidth / imageHeight);
+ }
+ else
+ {
+ focusHeight *= (imageHeight / imageWidth);
+ }
+ return (new RectF(point.x - focusWidth / 2.0f, point.y - focusHeight / 2.0f,
+ point.x + focusWidth / 2.0f, point.y + focusHeight / 2.0f));
+ }
+
+ /**
+ *
+ *
+ */
+ private void showFocusFrame(RectF rect, IAutoFocusFrameDisplay.FocusFrameStatus status, double duration)
+ {
+ frameDisplayer.showFocusFrame(rect, status, duration);
+ indicator.onAfLockUpdate(IAutoFocusFrameDisplay.FocusFrameStatus.Focused == status);
+ }
+
+ /**
+ *
+ *
+ */
+ private void hideFocusFrame()
+ {
+ frameDisplayer.hideFocusFrame();
+ indicator.onAfLockUpdate(false);
+ }
+
+
+ @Override
+ public void receivedMessage(int id, byte[] rx_body)
+ {
+ if (id == FOCUS_LOCK)
+ {
+ Log.v(TAG, "FOCUS LOCKED");
+ if (preFocusFrameRect != null)
+ {
+ showFocusFrame(preFocusFrameRect, IAutoFocusFrameDisplay.FocusFrameStatus.Focused, 1.0); // いったん1秒だけ表示
+ }
+ }
+ else // if (id == FOCUS_UNLOCK)
+ {
+ Log.v(TAG, "FOCUS UNLOCKED");
+ hideFocusFrame();
+
+ }
+ preFocusFrameRect = null;
+ }
+}
package net.osdn.gokigen.a01d.camera.fujix.wrapper;
import android.app.Activity;
+import android.util.Log;
import androidx.annotation.NonNull;
import net.osdn.gokigen.a01d.camera.ILiveViewControl;
import net.osdn.gokigen.a01d.camera.IZoomLensControl;
import net.osdn.gokigen.a01d.camera.fujix.IFujiXInterfaceProvider;
+import net.osdn.gokigen.a01d.camera.fujix.operation.FujiXCaptureControl;
+import net.osdn.gokigen.a01d.camera.fujix.operation.FujiXFocusingControl;
import net.osdn.gokigen.a01d.camera.fujix.operation.FujiXZoomControl;
import net.osdn.gokigen.a01d.camera.fujix.wrapper.command.FujiXAsyncResponseReceiver;
import net.osdn.gokigen.a01d.camera.fujix.wrapper.command.FujiXCommandIssuer;
import net.osdn.gokigen.a01d.camera.fujix.wrapper.command.IFujiXCommunication;
import net.osdn.gokigen.a01d.camera.fujix.wrapper.connection.FujiXConnection;
import net.osdn.gokigen.a01d.camera.fujix.wrapper.liveview.FujiXLiveViewControl;
+import net.osdn.gokigen.a01d.camera.ricohgr2.operation.RicohGr2CameraCaptureControl;
+import net.osdn.gokigen.a01d.camera.ricohgr2.operation.RicohGr2CameraFocusControl;
import net.osdn.gokigen.a01d.liveview.IAutoFocusFrameDisplay;
import net.osdn.gokigen.a01d.liveview.IIndicatorControl;
import net.osdn.gokigen.a01d.liveview.liveviewlistener.ILiveViewListener;
private FujiXLiveViewControl liveViewControl;
private FujiXAsyncResponseReceiver asyncReceiver;
private FujiXZoomControl zoomControl;
+ private FujiXCaptureControl captureControl;
+ private FujiXFocusingControl focusingControl;
public FujiXInterfaceProvider(@NonNull Activity context, @NonNull ICameraStatusReceiver provider)
@Override
public void injectDisplay(IAutoFocusFrameDisplay frameDisplayer, IIndicatorControl indicator, IFocusingModeNotify focusingModeNotify)
{
-
+ Log.v(TAG, "injectDisplay()");
+ captureControl = new FujiXCaptureControl(commandIssuer, frameDisplayer);
+ focusingControl = new FujiXFocusingControl(activity, commandIssuer, frameDisplayer, indicator);
}
@Override
@Override
public IFocusingControl getFocusingControl()
{
- return null;
+ return (focusingControl);
}
@Override
@Override
public ICaptureControl getCaptureControl()
{
- return null;
+ return (captureControl);
}
@Override
public IDisplayInjector getDisplayInjector()
{
- return null;
+ return (this);
}
@Override
--- /dev/null
+package net.osdn.gokigen.a01d.camera.fujix.wrapper.command.messages;
+
+import androidx.annotation.NonNull;
+
+import net.osdn.gokigen.a01d.camera.fujix.wrapper.command.IFujiXCommandCallback;
+import net.osdn.gokigen.a01d.camera.fujix.wrapper.connection.FujiXCameraConnectSequence;
+
+public class CaptureCommand extends FujiXCommandBase
+{
+ private final IFujiXCommandCallback callback;
+
+ public CaptureCommand(@NonNull IFujiXCommandCallback callback)
+ {
+ this.callback = callback;
+ }
+
+ @Override
+ public IFujiXCommandCallback responseCallback()
+ {
+ return (callback);
+ }
+
+ @Override
+ public int getId()
+ {
+ return (0);
+ }
+
+ @Override
+ public byte[] commandBody()
+ {
+ return (new byte[] {
+
+ // message_header.index : uint16 (0: terminate, 2: two_part_message, 1: other)
+ (byte)0x01, (byte)0x00,
+
+ // message_header.type : shutter (0x100e)
+ (byte)0x0e, (byte)0x10,
+
+ // sequence number
+ (byte)0x0B, (byte)0x00, (byte)0x00, (byte)0x00,
+
+ // data ...
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ });
+ }
+}
--- /dev/null
+package net.osdn.gokigen.a01d.camera.fujix.wrapper.command.messages;
+
+import androidx.annotation.NonNull;
+
+import net.osdn.gokigen.a01d.camera.fujix.wrapper.command.IFujiXCommandCallback;
+import net.osdn.gokigen.a01d.camera.fujix.wrapper.connection.FujiXCameraConnectSequence;
+
+import static net.osdn.gokigen.a01d.camera.fujix.operation.FujiXFocusingControl.FOCUS_LOCK;
+
+public class FocusLock extends FujiXCommandBase
+{
+ private final IFujiXCommandCallback callback;
+ private final byte pointX;
+ private final byte pointY;
+
+ public FocusLock(byte pointX, byte pointY, @NonNull IFujiXCommandCallback callback)
+ {
+ this.pointX = pointX;
+ this.pointY = pointY;
+ this.callback = callback;
+ }
+
+ @Override
+ public IFujiXCommandCallback responseCallback()
+ {
+ return (callback);
+ }
+
+ @Override
+ public int getId()
+ {
+ return (FOCUS_LOCK);
+ }
+
+ @Override
+ public byte[] commandBody()
+ {
+ return (new byte[] {
+
+ // message_header.index : uint16 (0: terminate, 2: two_part_message, 1: other)
+ (byte)0x01, (byte)0x00,
+
+ // message_header.type : focus_point (0x9026)
+ (byte)0x26, (byte)0x90,
+
+ // sequence number
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+
+ // data ...
+ pointY, pointX, (byte)0x02, (byte)0x03,
+ });
+ }
+}
--- /dev/null
+package net.osdn.gokigen.a01d.camera.fujix.wrapper.command.messages;
+
+import androidx.annotation.NonNull;
+
+import net.osdn.gokigen.a01d.camera.fujix.wrapper.command.IFujiXCommandCallback;
+import net.osdn.gokigen.a01d.camera.fujix.wrapper.connection.FujiXCameraConnectSequence;
+
+import static net.osdn.gokigen.a01d.camera.fujix.operation.FujiXFocusingControl.FOCUS_UNLOCK;
+
+public class FocusUnlock extends FujiXCommandBase
+{
+ private final IFujiXCommandCallback callback;
+
+ public FocusUnlock(@NonNull IFujiXCommandCallback callback)
+ {
+ this.callback = callback;
+ }
+
+ @Override
+ public IFujiXCommandCallback responseCallback()
+ {
+ return (callback);
+ }
+
+ @Override
+ public int getId()
+ {
+ return (FOCUS_UNLOCK);
+ }
+
+ @Override
+ public byte[] commandBody()
+ {
+ return (new byte[] {
+
+ // message_header.index : uint16 (0: terminate, 2: two_part_message, 1: other)
+ (byte)0x01, (byte)0x00,
+
+ // message_header.type : focus_unlock (0x9027)
+ (byte)0x27, (byte)0x90,
+
+ // message_id (0~1づつ繰り上がる...
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ });
+ }
+}
private final String ipAddress;
private final int portNumber;
private final CameraLiveViewListenerImpl liveViewListener;
- private int waitMs = 80;
+ private int waitMs = 100;
private static final int DATA_HEADER_OFFSET = 18;
private static final int BUFFER_SIZE = 1280 * 1024 + 8;
private static final int ERROR_LIMIT = 30;
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
String waitMsStr = preferences.getString(FUJIX_LIVEVIEW_WAIT, FUJIX_LIVEVIEW_WAIT_DEFAULT_VALUE);
int wait = Integer.parseInt(waitMsStr);
- if ((wait >= 10)&&(wait <= 800))
+ if ((wait >= 20)&&(wait <= 800))
{
waitMs = wait;
}
catch (Exception e)
{
e.printStackTrace();
- waitMs = 80;
+ waitMs = 100;
}
Log.v(TAG, "LOOP WAIT : " + waitMs + " ms");
}
{
int read_bytes = isr.read(byteArray, 0, BUFFER_SIZE);
liveViewListener.onUpdateLiveView(Arrays.copyOfRange(byteArray, DATA_HEADER_OFFSET, read_bytes - DATA_HEADER_OFFSET), null);
+ //liveViewListener.onUpdateLiveView(Arrays.copyOfRange(byteArray, 0, read_bytes), null);
Thread.sleep(waitMs);
errorCount = 0;
}
--- /dev/null
+package net.osdn.gokigen.a01d.camera.fujix.wrapper.status;
+
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import net.osdn.gokigen.a01d.camera.ICameraStatus;
+import net.osdn.gokigen.a01d.camera.ICameraStatusWatcher;
+import net.osdn.gokigen.a01d.camera.fujix.wrapper.command.IFujiXCommand;
+import net.osdn.gokigen.a01d.camera.fujix.wrapper.command.IFujiXCommandCallback;
+import net.osdn.gokigen.a01d.camera.fujix.wrapper.command.IFujiXCommandIssuer;
+import net.osdn.gokigen.a01d.camera.fujix.wrapper.command.messages.StatusRequestReceive;
+import net.osdn.gokigen.a01d.liveview.ICameraStatusUpdateNotify;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FujiXStatusChecker implements IFujiXCommandCallback, ICameraStatusWatcher, ICameraStatus
+{
+ private final String TAG = toString();
+ private static final int STATUS_MESSAGE_HEADER_SIZE = 14;
+ private final int sleepMs;
+ private final IFujiXCommandIssuer issuer;
+ private ICameraStatusUpdateNotify notifier = null;
+ private FujiXStatusHolder statusHolder;
+ private boolean whileFetching = false;
+
+ public FujiXStatusChecker(@NonNull IFujiXCommandIssuer issuer, int sleepMs)
+ {
+ this.issuer = issuer;
+ this.statusHolder = new FujiXStatusHolder();
+ this.sleepMs = sleepMs;
+ }
+
+ @Override
+ public void receivedMessage(int id, byte[] data)
+ {
+ try
+ {
+ if (data.length < STATUS_MESSAGE_HEADER_SIZE)
+ {
+ Log.v(TAG, "received status length is short. (" + data.length + " bytes.)");
+ return;
+ }
+
+ int nofStatus = (data[13] * 256) + data[12];
+ int statusCount = 0;
+ int index = STATUS_MESSAGE_HEADER_SIZE;
+ while ((statusCount < nofStatus)&&(index < data.length))
+ {
+ int dataId = ((((int)data[index + 1]) & 0xff) * 256) + (((int) data[index]) & 0xff);
+ statusHolder.updateValue(notifier, dataId, data[index + 2], data[index + 3], data[index +4], data[index + 5]);
+ index = index + 6;
+ statusCount++;
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public List<String> getStatusList(String key)
+ {
+ try
+ {
+ if (statusHolder == null)
+ {
+ return (new ArrayList<>());
+ }
+ String listKey = key + "List";
+ return (statusHolder.getAvailableItemList(key));
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ return (new ArrayList<>());
+ }
+
+ @Override
+ public String getStatus(String key)
+ {
+ try
+ {
+ if (statusHolder == null)
+ {
+ return ("");
+ }
+ return (statusHolder.getItemStatus(key));
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ return ("");
+ }
+
+ @Override
+ public void setStatus(String key, String value)
+ {
+ try
+ {
+ Log.v(TAG, "setStatus(" + key + ", " + value + ")");
+
+ // ここで設定を行う。
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void startStatusWatch(@NonNull ICameraStatusUpdateNotify notifier)
+ {
+ Log.v(TAG, "startStatusWatch()");
+ if (whileFetching)
+ {
+ Log.v(TAG, "startStatusWatch() already starting.");
+ return;
+ }
+ try
+ {
+ this.notifier = notifier;
+ whileFetching = true;
+ final IFujiXCommand command = new StatusRequestReceive(this);
+ Thread thread = new Thread(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ Log.d(TAG, "Start status watch.");
+ while (whileFetching)
+ {
+ try
+ {
+ issuer.enqueueCommand(command);
+ Thread.sleep(sleepMs);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ Log.v(TAG, "STATUS WATCH STOPPED.");
+ }
+ });
+ thread.start();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void stopStatusWatch()
+ {
+ Log.v(TAG, "stoptStatusWatch()");
+ whileFetching = false;
+ this.notifier = null;
+ }
+}
--- /dev/null
+package net.osdn.gokigen.a01d.camera.fujix.wrapper.status;
+
+import android.util.Log;
+import android.util.SparseIntArray;
+
+import net.osdn.gokigen.a01d.liveview.ICameraStatusUpdateNotify;
+
+import java.util.ArrayList;
+import java.util.List;
+
+class FujiXStatusHolder
+{
+ private final String TAG = toString();
+ private SparseIntArray statusHolder;
+
+ FujiXStatusHolder()
+ {
+ statusHolder = new SparseIntArray();
+ statusHolder.clear();
+ }
+
+ void updateValue(ICameraStatusUpdateNotify notifier, int id, byte data0, byte data1, byte data2, byte data3)
+ {
+ try
+ {
+ int value = ((((int) data3) & 0xff) << 24) + ((((int) data2) & 0xff) << 16) + ((((int) data1) & 0xff) << 8) + (((int) data0) & 0xff);
+ int currentValue = statusHolder.get(id, -1);
+ statusHolder.put(id, value);
+ if (currentValue != value)
+ {
+ updateDetected(notifier, id, currentValue, value);
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+
+ }
+
+ private void updateDetected(ICameraStatusUpdateNotify notifier, int id, int previous, int current)
+ {
+ Log.v(TAG, "updateDetected(" + id + " " + previous + " -> " + current + " )");
+ }
+
+ List<String> getAvailableItemList(String listKey)
+ {
+ return (new ArrayList<>());
+ }
+
+ String getItemStatus(String key)
+ {
+ return ("");
+ }
+
+}