diff --git a/res/layout/activity_cam.xml b/res/layout/activity_cam.xml
index 3c9f70f..7aad758 100644
--- a/res/layout/activity_cam.xml
+++ b/res/layout/activity_cam.xml
@@ -10,4 +10,11 @@
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".CamActivity" >
-
+
+
+
+
\ No newline at end of file
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 31826e1..1558306 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -10,7 +10,7 @@
Comenzar streaming de video
CamActivity
Dirección IP de NxtAR
- La dirección IP no es válida
+ No se encontró un servidor válido
Rellene el campo de dirección IP
Esta app requiere WiFi
¿Encender el WiFi?
@@ -18,7 +18,7 @@
Encender
El radio del WiFi está encendido
Esta app no puede funcionar sin wifi, cerrando.
- Este dispositivo no soporta Bluetooth
+ Este dispositivo no soporta Bluetooth
Esta app no puede funcionar sin Bluetooth, cerrando
Ícono de lente
Conectar con el robot
diff --git a/res/values/strings.xml b/res/values/strings.xml
index deb1f95..4e72cee 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -10,7 +10,7 @@
Connect with NxtAR
Start video streaming
NxtAR IP Address
- Invalid IP address
+ No proper server found
Fill out the IP address field
This app requires WiFi
Turn on the WiFi?
diff --git a/src/ve/ucv/ciens/ccg/nxtcam/CamActivity.java b/src/ve/ucv/ciens/ccg/nxtcam/CamActivity.java
index 47369bc..3e47c80 100644
--- a/src/ve/ucv/ciens/ccg/nxtcam/CamActivity.java
+++ b/src/ve/ucv/ciens/ccg/nxtcam/CamActivity.java
@@ -2,6 +2,7 @@ package ve.ucv.ciens.ccg.nxtcam;
import ve.ucv.ciens.ccg.nxtcam.camera.CameraPreview;
import ve.ucv.ciens.ccg.nxtcam.network.ImageTransferThread;
+import ve.ucv.ciens.ccg.nxtcam.network.LCPThread;
import ve.ucv.ciens.ccg.nxtcam.utils.Logger;
import android.app.Activity;
import android.content.Intent;
@@ -12,16 +13,18 @@ import android.support.v4.app.NavUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.WindowManager;
+import android.widget.FrameLayout;
import android.widget.Toast;
public class CamActivity extends Activity{
private final String TAG = "NXTCAM_CAM";
- private final String CLASS_NAME = MainActivity.class.getSimpleName();
-
+ private final String CLASS_NAME = CamActivity.class.getSimpleName();
+
private Camera hwCamera;
private CameraPreview cPreview;
private CameraSetupTask camSetupTask;
private ImageTransferThread imThread;
+ private LCPThread botThread;
private String serverIp;
/*******************
@@ -31,12 +34,11 @@ public class CamActivity extends Activity{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
-
- cPreview = new CameraPreview(this, hwCamera);
- setContentView(cPreview);
-
+ setContentView(R.layout.activity_cam);
+
Intent intent = getIntent();
serverIp = intent.getStringExtra("address");
+ imThread = new ImageTransferThread(serverIp);
}
@Override
@@ -69,20 +71,28 @@ public class CamActivity extends Activity{
camSetupTask = new CameraSetupTask();
camSetupTask.execute();
-
- imThread = new ImageTransferThread(serverIp);
- imThread.start();
+
+ // imThread.start();
}
@Override
public void onPause(){
super.onPause();
- // TODO: Disconnect and destroy the imThread object.
-
- cPreview.removePreviewCallback();
- cPreview.setCamera(null);
- releaseCamera();
+ // TODO: pause the imThread and botThread objects.
+
+ if(cPreview != null){
+ cPreview.removePreviewCallback();
+ cPreview.setCamera(null);
+ releaseCamera();
+ }
+ }
+
+ @Override
+ public void onDestroy(){
+ super.onDestroy();
+ // TODO: Destroy the network threads.
+ imThread = null;
}
/******************
@@ -90,7 +100,11 @@ public class CamActivity extends Activity{
******************/
public void startCameraPreview(){
if(hwCamera != null){
+ Logger.log_d(TAG, CLASS_NAME + ".startCameraPreview() :: Setting camera.");
+ cPreview = new CameraPreview(this, hwCamera);
cPreview.setCamera(hwCamera);
+ ((FrameLayout)findViewById(R.id.previewLayout)).addView(cPreview);
+ Logger.log_d(TAG, CLASS_NAME + ".startCameraPreview() :: Camera and content view set.");
}else{
Logger.log_wtf(TAG, CLASS_NAME + ".startCameraPreview() :: CAMERA IS NULL!");
System.exit(1);
@@ -110,6 +124,7 @@ public class CamActivity extends Activity{
@Override
protected Camera doInBackground(Void... params) {
Camera cam = null;
+ Logger.log_d(TAG, CLASS_NAME + ".doInBackground() :: Opening the camera.");
try{
cam = Camera.open(0);
}catch(Exception e){
@@ -121,7 +136,7 @@ public class CamActivity extends Activity{
@Override
protected void onPostExecute(Camera result) {
super.onPostExecute(result);
-
+
hwCamera = result;
if(result != null){
Logger.log_d(TAG, CLASS_NAME + ".onPostExecute() :: Camera successfully opened");
diff --git a/src/ve/ucv/ciens/ccg/nxtcam/MainActivity.java b/src/ve/ucv/ciens/ccg/nxtcam/MainActivity.java
index 80a6dbb..3d57f54 100644
--- a/src/ve/ucv/ciens/ccg/nxtcam/MainActivity.java
+++ b/src/ve/ucv/ciens/ccg/nxtcam/MainActivity.java
@@ -334,11 +334,6 @@ public class MainActivity extends Activity implements WifiOnDialogListener, Conn
Logger.log_d(TAG, CLASS_NAME + ".doInBackground() :: Packet payload is\n" + received);
if(received.compareTo("NxtAR server here!") == 0)
done = true;
- Socket client1, client2;
- client1 = new Socket(packet.getAddress(), ProjectConstants.SERVER_TCP_PORT_1);
- client1.close();
- client2 = new Socket(packet.getAddress(), ProjectConstants.SERVER_TCP_PORT_2);
- client2.close();
}
result = true;
}catch(IOException io){
@@ -367,10 +362,10 @@ public class MainActivity extends Activity implements WifiOnDialogListener, Conn
if(packet != null){
showToast(R.string.serv_connected, Toast.LENGTH_SHORT);
- // startCamActivity(result, packet.getAddress().getHostAddress());
+ startCamActivity(result, packet.getAddress().getHostAddress());
}else{
showToast(R.string.serv_fail, Toast.LENGTH_SHORT);
- // startCamActivity(false, null);
+ startCamActivity(false, null);
}
}
}
diff --git a/src/ve/ucv/ciens/ccg/nxtcam/camera/CameraImageMonitor.java b/src/ve/ucv/ciens/ccg/nxtcam/camera/CameraImageMonitor.java
index 4637344..51a094a 100644
--- a/src/ve/ucv/ciens/ccg/nxtcam/camera/CameraImageMonitor.java
+++ b/src/ve/ucv/ciens/ccg/nxtcam/camera/CameraImageMonitor.java
@@ -7,10 +7,12 @@ public class CameraImageMonitor{
private final String CLASS_NAME = CameraImageMonitor.class.getSimpleName();
private byte[] image;
- private boolean imgChanged;
+ private boolean imgProduced;
+ private boolean imgConsumed;
private CameraImageMonitor(){
- imgChanged = false;
+ imgProduced = false;
+ imgConsumed = false;
}
private static class SingletonHolder{
@@ -22,33 +24,40 @@ public class CameraImageMonitor{
}
public void setImageData(byte[] image){
- Logger.log_d(TAG, CLASS_NAME + ".setImageData() :: Copying new image.");
- synchronized(image){
- this.image = new byte[image.length];
- System.arraycopy(image, 0, this.image, 0, image.length);
- imgChanged = true;
- image.notifyAll();
+ if(imgConsumed){
+ Logger.log_d(TAG, CLASS_NAME + ".setImageData() :: Copying new image.");
+ synchronized(this.image){
+ //this.image = new byte[image.length];
+ //System.arraycopy(image, 0, this.image, 0, image.length);
+ this.image = image;
+ imgProduced = true;
+ imgConsumed = false;
+ this.image.notifyAll();
+ }
+ Logger.log_d(TAG, CLASS_NAME + ".setImageData() :: Data copy finished.");
+ }else{
+ Logger.log_d(TAG, CLASS_NAME + ".setImageData() :: Old image still valid, ignoring new image.");
}
- Logger.log_d(TAG, CLASS_NAME + ".setImageData() :: Data copy finished.");
}
public byte[] getImageData(){
byte[] returnImg;
Logger.log_d(TAG, CLASS_NAME + ".getImageData() :: Entry point.");
synchronized(image){
- while(!imgChanged){
- Logger.log_d(TAG, CLASS_NAME + ".getImageData() :: Waiting for new data.");
- try{ image.wait(); }catch(InterruptedException ie){}
+ while(!imgProduced){
+ Logger.log_d(TAG, CLASS_NAME + ".getImageData() :: Waiting for new image.");
+ try{ image.wait(); }catch(InterruptedException ie){ }
}
- Logger.log_d(TAG, CLASS_NAME + ".getImageData() :: Retrieving new data.");
- returnImg = image.clone();
- imgChanged = false;
+ Logger.log_d(TAG, CLASS_NAME + ".getImageData() :: Retrieving new image.");
+ returnImg = image;
+ imgProduced = false;
+ imgConsumed = true;
}
- Logger.log_d(TAG, CLASS_NAME + ".getImageData() :: New data retreived.");
+ Logger.log_d(TAG, CLASS_NAME + ".getImageData() :: New image retrieved.");
return returnImg;
}
public synchronized boolean hasChanged(){
- return imgChanged;
+ return imgProduced;
}
}
diff --git a/src/ve/ucv/ciens/ccg/nxtcam/camera/CameraPreview.java b/src/ve/ucv/ciens/ccg/nxtcam/camera/CameraPreview.java
index 93fb5cb..a97ccd3 100644
--- a/src/ve/ucv/ciens/ccg/nxtcam/camera/CameraPreview.java
+++ b/src/ve/ucv/ciens/ccg/nxtcam/camera/CameraPreview.java
@@ -13,85 +13,83 @@ import android.os.Build;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
-import android.view.View;
-import android.view.ViewGroup;
/** A basic Camera preview class */
@SuppressLint("ViewConstructor")
-public class CameraPreview extends ViewGroup implements SurfaceHolder.Callback, Camera.PreviewCallback {
+public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback {
private final String TAG = "SURFVIEW";
private final String CLASS_NAME = CameraPreview.class.getSimpleName();
- private Size mPreviewSize;
- private List mSupportedPreviewSizes;
- private CameraImageMonitor camMonitor;
+ private CameraImageMonitor imgMonitor;
private Activity parentActivity;
- private SurfaceView mSurfaceView;
- private SurfaceHolder mHolder;
- private Camera mCamera;
+ private SurfaceHolder holder;
+ private Camera camera;
@SuppressWarnings("deprecation")
public CameraPreview(Context context, Camera camera){
super(context);
parentActivity = (Activity)context;
- mSurfaceView = new SurfaceView(context);
- mHolder = mSurfaceView.getHolder();
- mHolder.addCallback(this);
+ // surfaceView = new SurfaceView(context);
+ holder = getHolder();
+ holder.addCallback(this);
if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.HONEYCOMB)
- mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
+ holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void setCamera(Camera camera){
- mCamera = camera;
- if(mCamera != null){
- camMonitor = CameraImageMonitor.getInstance();
- mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
+ this.camera = camera;
+ if(this.camera != null){
+ Logger.log_d(TAG, CLASS_NAME + ".setCamera() :: Setting camera.");
+ imgMonitor = CameraImageMonitor.getInstance();
requestLayout();
+ Logger.log_d(TAG, CLASS_NAME + ".setCamera() :: Camera set.");
}
}
public void surfaceCreated(SurfaceHolder holder){
// The Surface has been created, now tell the camera where to draw the preview.
+ Logger.log_d(TAG, CLASS_NAME + ".surfaceCreated() :: Creating surface view.");
try {
- if(mCamera != null){
- mCamera.setPreviewDisplay(holder);
- }
+ if(camera != null)
+ camera.setPreviewDisplay(holder);
} catch (IOException e) {
- Logger.log_d(TAG, "Error setting camera preview: " + e.getMessage());
+ Logger.log_e(TAG, CLASS_NAME + ".surfaceCreated() :: Error creating camera: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder){
- if(mCamera != null){
- mCamera.stopPreview();
- }
+ if(camera != null)
+ camera.stopPreview();
}
- public void surfaceChanged(SurfaceHolder holder, int format, int w, int h){
- if(mHolder.getSurface() == null){
+ public void surfaceChanged(SurfaceHolder tmpHolder, int format, int w, int h){
+ int result;
+ int rotation;
+ int degrees = 0;
+ Camera.Parameters camParams;
+
+ Logger.log_d(TAG, CLASS_NAME + ".surfaceChanged() :: Method started.");
+ if(this.holder.getSurface() == null || camera == null){
+ Logger.log_d(TAG, CLASS_NAME + ".surfaceChanged() :: Holder and/or camera are null.");
return;
}
- try{
- mCamera.stopPreview();
- }catch (Exception e){ }
+ try{ camera.stopPreview(); }catch (Exception e){ }
requestLayout();
- Camera.Parameters camParams = mCamera.getParameters();
- /*Size optimal = getOptimalPreviewSize(camParams.getSupportedPreviewSizes(), w, h);
- if(ProjectConstants.DEBUG)
- Log.d(TAG, CLASS_NAME + ".surfaceChanged() :: Preview size set at (" + optimal.width + ", " + optimal.height + ")");*/
- camParams.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
- mCamera.setParameters(camParams);
+ camParams = camera.getParameters();
+ Size optimal = getOptimalPreviewSize(camParams.getSupportedPreviewSizes(), w, h);
+ Logger.log_d(TAG, CLASS_NAME + ".surfaceChanged() :: Preview size set at (" + optimal.width + ", " + optimal.height + ")");
+ camParams.setPreviewSize(optimal.width, optimal.height);
+ camera.setParameters(camParams);
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(0, info);
- int rotation = parentActivity.getWindowManager().getDefaultDisplay().getRotation();
+ rotation = parentActivity.getWindowManager().getDefaultDisplay().getRotation();
- int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0: degrees = 0; break;
case Surface.ROTATION_90: degrees = 90; break;
@@ -99,41 +97,41 @@ public class CameraPreview extends ViewGroup implements SurfaceHolder.Callback,
case Surface.ROTATION_270: degrees = 270; break;
}
- int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
- mCamera.setDisplayOrientation(result);
-
- mCamera.setPreviewCallback(this);
+ camera.setDisplayOrientation(result);
+ camera.setPreviewCallback(this);
try {
- mCamera.setPreviewDisplay(mHolder);
- mCamera.startPreview();
-
+ camera.setPreviewDisplay(this.holder);
+ camera.startPreview();
}catch (Exception e){
- Logger.log_d(TAG, CLASS_NAME + ".surfaceChanged() :: Error starting camera preview: " + e.getMessage());
+ Logger.log_e(TAG, CLASS_NAME + ".surfaceChanged() :: Error starting camera preview: " + e.getMessage());
}
}
@Override
public void onPreviewFrame(byte[] data, Camera camera){
Logger.log_d(TAG, CLASS_NAME + ".onPreviewFrame() :: Preview received");
- Logger.log_d(TAG, CLASS_NAME + ".onPreviewFrame() :: Frame has" + (camMonitor.hasChanged() ? "" : " not") + " changed.");
- if(!camMonitor.hasChanged())
- camMonitor.setImageData(data);
+ Logger.log_d(TAG, CLASS_NAME + ".onPreviewFrame() :: Frame has" + (imgMonitor.hasChanged() ? "" : " not") + " changed.");
+ if(!imgMonitor.hasChanged())
+ imgMonitor.setImageData(data);
}
public void removePreviewCallback(){
- mCamera.setPreviewCallback(null);
+ if(camera != null)
+ camera.setPreviewCallback(null);
}
private Size getOptimalPreviewSize(List sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) w / h;
+
+ Logger.log_d(TAG, CLASS_NAME + ".getOptimalPreviewSize() :: Method started.");
if (sizes == null) return null;
Size optimalSize = null;
@@ -161,45 +159,9 @@ public class CameraPreview extends ViewGroup implements SurfaceHolder.Callback,
}
}
}
+ Logger.log_d(TAG, CLASS_NAME + ".getOptimalPreviewSize() :: Method ended.");
+ Logger.log_d(TAG, CLASS_NAME + ".getOptimalPreviewSize() :: Optimal size is: (" + Integer.toString(optimalSize.width) +
+ ", " + Integer.toString(optimalSize.height) + ")");
return optimalSize;
}
-
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- if (changed && getChildCount() > 0) {
- final View child = getChildAt(0);
-
- final int width = r - l;
- final int height = b - t;
-
- int previewWidth = width;
- int previewHeight = height;
- if (mPreviewSize != null) {
- previewWidth = mPreviewSize.width;
- previewHeight = mPreviewSize.height;
- }
-
- // Center the child SurfaceView within the parent.
- if (width * previewHeight > height * previewWidth) {
- final int scaledChildWidth = previewWidth * height / previewHeight;
- child.layout((width - scaledChildWidth) / 2, 0,
- (width + scaledChildWidth) / 2, height);
- } else {
- final int scaledChildHeight = previewHeight * width / previewWidth;
- child.layout(0, (height - scaledChildHeight) / 2,
- width, (height + scaledChildHeight) / 2);
- }
- }
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
- final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
- setMeasuredDimension(width, height);
-
- if (mSupportedPreviewSizes != null) {
- mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
- }
- }
}