Skip to content

Commit

Permalink
major update to support CameraViewPlus for #295 #297 #111 and others
Browse files Browse the repository at this point in the history
- uses the https://github.com/siralam/CameraViewPlus library to make the camera usage more reliable, and support Camera2
- integrates RenderScript support to move to better performance on some image conversion functions
- improves display and performance of detection display overlay
  • Loading branch information
n8fr8 committed Jul 3, 2018
1 parent 3a8b2e6 commit e0ecdc6
Show file tree
Hide file tree
Showing 10 changed files with 320 additions and 388 deletions.
15 changes: 13 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,15 @@ android {
}
multiDexEnabled true
vectorDrawables.useSupportLibrary = true
renderscriptTargetApi 16
renderscriptSupportModeEnabled true

ndk {
abiFilters "armeabi", "armeabi-v7a", "x86"
}
}


buildTypes {
release {
minifyEnabled false
Expand All @@ -100,10 +107,12 @@ android {
}

dependencies {
//noinspection GradleCompatible
implementation 'com.android.support:support-v4:27.1.1'
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:design:27.1.1'
implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation 'com.github.guardianproject:signal-cli-android:-SNAPSHOT'
implementation 'com.github.satyan:sugar:1.5'
implementation 'com.squareup.picasso:picasso:2.71828'
Expand All @@ -113,7 +122,7 @@ dependencies {
implementation 'com.nanohttpd:nanohttpd-webserver:2.2.0'
implementation 'me.angrybyte.picker:picker:1.3.1'
implementation 'com.github.stfalcon:frescoimageviewer:0.5.0'
implementation 'com.facebook.fresco:fresco:1.8.1'
implementation 'com.facebook.fresco:fresco:1.9.0'
implementation 'com.github.derlio.waveform:library:1.0.1'
implementation 'org.firezenk:audiowaves:1.1@aar'
implementation 'com.maxproj.simplewaveform:app:1.0.0'
Expand All @@ -123,5 +132,7 @@ dependencies {
implementation('com.mikepenz:aboutlibraries:6.0.2@aar') {
transitive = true
}
implementation 'com.asksira.android:cameraviewplus:0.9.4'
implementation 'com.github.halilozercan:BetterVideoPlayer:1.1.0'
implementation 'io.github.silvaren:easyrs:0.5.3'
}
12 changes: 12 additions & 0 deletions src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
android:name=".MonitorActivity"
android:configChanges="orientation|screenSize"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:launchMode="singleTop" />
<activity
android:name=".ui.VideoPlayerActivity"
Expand Down Expand Up @@ -111,6 +112,17 @@
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
</intent-filter>
</receiver>

<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="org.havenapp.main.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_paths" />
</provider>

</application>

</manifest>
25 changes: 18 additions & 7 deletions src/main/java/org/havenapp/main/HavenApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import android.util.Log;

import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.imagepipeline.core.ImagePipelineConfig;
import com.facebook.imagepipeline.decoder.SimpleProgressiveJpegConfig;
import com.orm.SugarContext;

import java.io.IOException;
Expand All @@ -44,26 +46,35 @@ public class HavenApp extends MultiDexApplication {
public void onCreate() {
super.onCreate();

SugarContext.init(this);

mPrefs = new PreferenceManager(this);

Fresco.initialize(this);
SugarContext.init(this);
ImagePipelineConfig config = ImagePipelineConfig.newBuilder(this)
.setProgressiveJpegConfig(new SimpleProgressiveJpegConfig())
.setResizeAndRotateEnabledForNetwork(true)
.setDownsampleEnabled(true)
.build();

Fresco.initialize(this,config);

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);

if (mPrefs.getRemoteAccessActive())
startServer();

}


public void startServer ()
{
if (mOnionServer == null || (!mOnionServer.isAlive()))
{
try {
mOnionServer = new WebServer(this, mPrefs.getRemoteAccessCredential());
} catch (IOException ioe) {
Log.e("OnioNServer", "unable to start onion server", ioe);
if ( mPrefs.getRemoteAccessCredential() != null) {
try {
mOnionServer = new WebServer(this, mPrefs.getRemoteAccessCredential());
} catch (IOException ioe) {
Log.e("OnioNServer", "unable to start onion server", ioe);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.os.Handler;
import android.support.v8.renderscript.RenderScript;
import android.util.Log;

import org.havenapp.main.sensors.motion.IMotionDetector;
Expand All @@ -24,14 +25,16 @@
import java.util.ArrayList;
import java.util.List;

import io.github.silvaren.easyrs.tools.Nv21Image;

/**
* Task doing all image processing in backgrounds,
* has a collection of listeners to notify in after having processed
* the image
* @author marco
*
*/
public class MotionAsyncTask extends Thread {
public class MotionDetector {

// Input data

Expand All @@ -44,14 +47,14 @@ public class MotionAsyncTask extends Thread {
private int motionSensitivity;

// Output data

private Bitmap lastBitmap;
private Bitmap newBitmap;
private Bitmap rawBitmap;

private boolean hasChanged;

private IMotionDetector detector;


private RenderScript renderScript;


public interface MotionListener {
public void onProcess(Bitmap oldBitmap,
Bitmap newBitmap,
Expand All @@ -63,89 +66,88 @@ public void addListener(MotionListener listener) {
listeners.add(listener);
}

public MotionAsyncTask(
public MotionDetector(
RenderScript renderScript,
byte[] rawOldPic,
byte[] rawNewPic,
int width,
int height,
Handler updateHandler,
int motionSensitivity) {
this.renderScript = renderScript;
this.rawOldPic = rawOldPic;
this.rawNewPic = rawNewPic;
this.width = width;
this.height = height;
this.handler = updateHandler;
this.motionSensitivity = motionSensitivity;

}
detector = new LuminanceMotionDetector();

}

public void setMotionSensitivity (int motionSensitivity)
{
this.motionSensitivity = motionSensitivity;
detector.setThreshold(motionSensitivity);
}

@Override
public void run() {
public void detect() {
int[] newPicLuma = ImageCodec.N21toLuma(rawNewPic, width, height);
if (rawOldPic == null) {
newBitmap = ImageCodec.lumaToBitmapGreyscale(newPicLuma, width, height);
lastBitmap = newBitmap;
} else {
if (rawOldPic != null) {

int[] oldPicLuma = ImageCodec.N21toLuma(rawOldPic, width, height);
detector = new LuminanceMotionDetector();
detector.setThreshold(motionSensitivity);
List<Integer> changedPixels =
List<Integer> changedPixels =
detector.detectMotion(oldPicLuma, newPicLuma, width, height);
hasChanged = false;

int[] newPic = ImageCodec.lumaToGreyscale(newPicLuma, width, height);

if (changedPixels != null) {
hasChanged = true;
for (int changedPixel : changedPixels) {
newPic[changedPixel] = Color.YELLOW;
}
}

lastBitmap = ImageCodec.lumaToBitmapGreyscale(oldPicLuma, width, height);
newBitmap = Bitmap.createBitmap(newPic, width, height, Bitmap.Config.RGB_565);
}


if (hasChanged) {
YuvImage image = new YuvImage(rawNewPic, ImageFormat.NV21, width, height, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compressToJpeg(
new Rect(0, 0, image.getWidth(), image.getHeight()), 90,
baos);

byte[] imageBytes = baos.toByteArray();
rawBitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
// Setting post rotate to 90
Matrix mtx = new Matrix();
mtx.postRotate(-90);
// Rotating Bitmap
rawBitmap = Bitmap.createBitmap(rawBitmap, 0, 0, width, height, mtx, true);
}
else
{
rawBitmap = null;


Bitmap lastBitmap = ImageCodec.lumaToBitmapGreyscale(oldPicLuma, width, height);

for (int i = 0; i < newPic.length; i++)
newPic[i] = Color.TRANSPARENT;

for (int changedPixel : changedPixels) {
newPic[changedPixel] = Color.YELLOW;
}


Matrix mtx = new Matrix();
mtx.postRotate(-90);
mtx.postScale(-1, 1, width/2,height/2);

Bitmap newBitmap
= Bitmap.createBitmap(Bitmap.createBitmap(newPic, width, height, Bitmap.Config.ARGB_4444), 0, 0, width, height, mtx, true);

Bitmap rawBitmap = Bitmap.createBitmap(Nv21Image.nv21ToBitmap(renderScript, rawNewPic, width, height),0,0,width,height,mtx,true);

Log.i("MotionDetector", "Finished processing, sending results");
handler.post(() -> {
for (MotionListener listener : listeners) {
Log.i("MotionDetector", "Updating back view");
listener.onProcess(
lastBitmap,
newBitmap,
rawBitmap,
hasChanged);
}

});
}

}

Log.i("MotionAsyncTask", "Finished processing, sending results");
handler.post(new Runnable() {

public void run() {
for (MotionListener listener : listeners) {
Log.i("MotionAsyncTask", "Updating back view");
listener.onProcess(
lastBitmap,
newBitmap,
rawBitmap,
hasChanged);
}

}
});


}


Expand Down
Loading

0 comments on commit e0ecdc6

Please sign in to comment.