kopia lustrzana https://github.com/xdsopl/robot36
WIP: experimental async decoding
it will continue decoding in background. to stop decoder, you must exit application. also removed some unneeded synchronizations to make it more responsive.pull/6/head
rodzic
bb183cb80e
commit
60b8c48d9b
|
@ -34,14 +34,14 @@ import android.support.v8.renderscript.RenderScript;
|
||||||
|
|
||||||
public class ImageView extends SurfaceView implements SurfaceHolder.Callback {
|
public class ImageView extends SurfaceView implements SurfaceHolder.Callback {
|
||||||
private int canvasWidth = -1, canvasHeight = -1;
|
private int canvasWidth = -1, canvasHeight = -1;
|
||||||
private boolean takeABreak = true, cantTouchThis = true;
|
private boolean takeABreak = true, cantTouchThis = true, quitThread = false;
|
||||||
private int imageWidth = 320;
|
private int imageWidth = 320;
|
||||||
private int imageHeight = 240;
|
private int imageHeight = 240;
|
||||||
MainActivity activity;
|
MainActivity activity;
|
||||||
private final SurfaceHolder holder;
|
private final SurfaceHolder holder;
|
||||||
private final Bitmap bitmap;
|
private final Bitmap bitmap;
|
||||||
private final Paint paint;
|
private final Paint paint;
|
||||||
private AudioRecord audio;
|
private final AudioRecord audio;
|
||||||
private final int audioSource = MediaRecorder.AudioSource.MIC;
|
private final int audioSource = MediaRecorder.AudioSource.MIC;
|
||||||
private final int channelConfig = AudioFormat.CHANNEL_IN_MONO;
|
private final int channelConfig = AudioFormat.CHANNEL_IN_MONO;
|
||||||
private final int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
|
private final int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
|
||||||
|
@ -76,25 +76,22 @@ public class ImageView extends SurfaceView implements SurfaceHolder.Callback {
|
||||||
private final Thread thread = new Thread() {
|
private final Thread thread = new Thread() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
//noinspection InfiniteLoopStatement
|
|
||||||
while (true) {
|
while (true) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
while (cantTouchThis || takeABreak) {
|
if (quitThread)
|
||||||
|
return;
|
||||||
|
if (!cantTouchThis && !takeABreak) {
|
||||||
|
Canvas canvas = null;
|
||||||
try {
|
try {
|
||||||
wait();
|
canvas = holder.lockCanvas(null);
|
||||||
} catch (InterruptedException ignored) {
|
drawBitmap(canvas);
|
||||||
|
} finally {
|
||||||
|
if (canvas != null)
|
||||||
|
holder.unlockCanvasAndPost(canvas);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Canvas canvas = null;
|
|
||||||
try {
|
|
||||||
canvas = holder.lockCanvas(null);
|
|
||||||
drawBitmap(canvas);
|
|
||||||
} finally {
|
|
||||||
if (canvas != null)
|
|
||||||
holder.unlockCanvasAndPost(canvas);
|
|
||||||
}
|
|
||||||
decode();
|
|
||||||
}
|
}
|
||||||
|
decode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -112,6 +109,8 @@ public class ImageView extends SurfaceView implements SurfaceHolder.Callback {
|
||||||
int bufferSizeInSamples = bufferSizeInBytes / 2;
|
int bufferSizeInSamples = bufferSizeInBytes / 2;
|
||||||
int framesPerSecond = Math.max(1, sampleRate / bufferSizeInSamples);
|
int framesPerSecond = Math.max(1, sampleRate / bufferSizeInSamples);
|
||||||
audioBuffer = new short[framesPerSecond * bufferSizeInSamples];
|
audioBuffer = new short[framesPerSecond * bufferSizeInSamples];
|
||||||
|
audio = new AudioRecord(audioSource, sampleRate, channelConfig, audioFormat, audioBuffer.length * 2);
|
||||||
|
audio.startRecording();
|
||||||
|
|
||||||
int maxHorizontalLength = 3 * sampleRate;
|
int maxHorizontalLength = 3 * sampleRate;
|
||||||
currentMode = new int[1];
|
currentMode = new int[1];
|
||||||
|
@ -140,147 +139,91 @@ public class ImageView extends SurfaceView implements SurfaceHolder.Callback {
|
||||||
|
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
void softer_image() {
|
|
||||||
synchronized (thread) {
|
void softer_image() { rsDecoder.invoke_incr_blur(); }
|
||||||
rsDecoder.invoke_incr_blur();
|
void sharper_image() { rsDecoder.invoke_decr_blur(); }
|
||||||
}
|
void debug_sync() { rsDecoder.invoke_debug_sync(); }
|
||||||
}
|
void debug_image() { rsDecoder.invoke_debug_image(); }
|
||||||
void sharper_image() {
|
void debug_both() { rsDecoder.invoke_debug_both(); }
|
||||||
synchronized (thread) {
|
void robot36_mode() { rsDecoder.invoke_robot36_mode(); }
|
||||||
rsDecoder.invoke_decr_blur();
|
void robot72_mode() { rsDecoder.invoke_robot72_mode(); }
|
||||||
}
|
void martin1_mode() { rsDecoder.invoke_martin1_mode(); }
|
||||||
}
|
void martin2_mode() { rsDecoder.invoke_martin2_mode(); }
|
||||||
void debug_sync() {
|
void scottie1_mode() { rsDecoder.invoke_scottie1_mode(); }
|
||||||
synchronized (thread) {
|
void scottie2_mode() { rsDecoder.invoke_scottie2_mode(); }
|
||||||
rsDecoder.invoke_debug_sync();
|
void scottieDX_mode() { rsDecoder.invoke_scottieDX_mode(); }
|
||||||
}
|
void wrasseSC2_180_mode() { rsDecoder.invoke_wrasseSC2_180_mode(); }
|
||||||
}
|
|
||||||
void debug_image() {
|
|
||||||
synchronized (thread) {
|
|
||||||
rsDecoder.invoke_debug_image();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void debug_both() {
|
|
||||||
synchronized (thread) {
|
|
||||||
rsDecoder.invoke_debug_both();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void robot36_mode() {
|
|
||||||
synchronized (thread) {
|
|
||||||
rsDecoder.invoke_robot36_mode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void robot72_mode() {
|
|
||||||
synchronized (thread) {
|
|
||||||
rsDecoder.invoke_robot72_mode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void martin1_mode() {
|
|
||||||
synchronized (thread) {
|
|
||||||
rsDecoder.invoke_martin1_mode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void martin2_mode() {
|
|
||||||
synchronized (thread) {
|
|
||||||
rsDecoder.invoke_martin2_mode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void scottie1_mode() {
|
|
||||||
synchronized (thread) {
|
|
||||||
rsDecoder.invoke_scottie1_mode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void scottie2_mode() {
|
|
||||||
synchronized (thread) {
|
|
||||||
rsDecoder.invoke_scottie2_mode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void scottieDX_mode() {
|
|
||||||
synchronized (thread) {
|
|
||||||
rsDecoder.invoke_scottieDX_mode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void wrasseSC2_180_mode() {
|
|
||||||
synchronized (thread) {
|
|
||||||
rsDecoder.invoke_wrasseSC2_180_mode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateTitle(int id) { activity.updateTitle(activity.getString(id)); }
|
void updateTitle(int id) { activity.updateTitle(activity.getString(id)); }
|
||||||
void switch_mode(int mode)
|
void switch_mode(int mode)
|
||||||
{
|
{
|
||||||
synchronized (thread) {
|
switch (mode) {
|
||||||
switch (mode) {
|
case mode_debug:
|
||||||
case mode_debug:
|
imageWidth = bitmap.getWidth();
|
||||||
imageWidth = bitmap.getWidth();
|
imageHeight = bitmap.getHeight();
|
||||||
imageHeight = bitmap.getHeight();
|
updateTitle(R.string.action_debug_mode);
|
||||||
updateTitle(R.string.action_debug_mode);
|
break;
|
||||||
break;
|
case mode_robot36:
|
||||||
case mode_robot36:
|
imageWidth = 320;
|
||||||
imageWidth = 320;
|
imageHeight = 240;
|
||||||
imageHeight = 240;
|
updateTitle(R.string.action_robot36_mode);
|
||||||
updateTitle(R.string.action_robot36_mode);
|
break;
|
||||||
break;
|
case mode_robot72:
|
||||||
case mode_robot72:
|
imageWidth = 320;
|
||||||
imageWidth = 320;
|
imageHeight = 240;
|
||||||
imageHeight = 240;
|
updateTitle(R.string.action_robot72_mode);
|
||||||
updateTitle(R.string.action_robot72_mode);
|
break;
|
||||||
break;
|
case mode_martin1:
|
||||||
case mode_martin1:
|
imageWidth = 320;
|
||||||
imageWidth = 320;
|
imageHeight = 256;
|
||||||
imageHeight = 256;
|
updateTitle(R.string.action_martin1_mode);
|
||||||
updateTitle(R.string.action_martin1_mode);
|
break;
|
||||||
break;
|
case mode_martin2:
|
||||||
case mode_martin2:
|
imageWidth = 320;
|
||||||
imageWidth = 320;
|
imageHeight = 256;
|
||||||
imageHeight = 256;
|
updateTitle(R.string.action_martin2_mode);
|
||||||
updateTitle(R.string.action_martin2_mode);
|
break;
|
||||||
break;
|
case mode_scottie1:
|
||||||
case mode_scottie1:
|
imageWidth = 320;
|
||||||
imageWidth = 320;
|
imageHeight = 256;
|
||||||
imageHeight = 256;
|
updateTitle(R.string.action_scottie1_mode);
|
||||||
updateTitle(R.string.action_scottie1_mode);
|
break;
|
||||||
break;
|
case mode_scottie2:
|
||||||
case mode_scottie2:
|
imageWidth = 320;
|
||||||
imageWidth = 320;
|
imageHeight = 256;
|
||||||
imageHeight = 256;
|
updateTitle(R.string.action_scottie2_mode);
|
||||||
updateTitle(R.string.action_scottie2_mode);
|
break;
|
||||||
break;
|
case mode_scottieDX:
|
||||||
case mode_scottieDX:
|
imageWidth = 320;
|
||||||
imageWidth = 320;
|
imageHeight = 256;
|
||||||
imageHeight = 256;
|
updateTitle(R.string.action_scottieDX_mode);
|
||||||
updateTitle(R.string.action_scottieDX_mode);
|
break;
|
||||||
break;
|
case mode_wrasseSC2_180:
|
||||||
case mode_wrasseSC2_180:
|
imageWidth = 320;
|
||||||
imageWidth = 320;
|
imageHeight = 256;
|
||||||
imageHeight = 256;
|
updateTitle(R.string.action_wrasseSC2_180_mode);
|
||||||
updateTitle(R.string.action_wrasseSC2_180_mode);
|
break;
|
||||||
break;
|
default:
|
||||||
default:
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void pause() {
|
void pause() {
|
||||||
synchronized (thread) {
|
synchronized (thread) {
|
||||||
takeABreak = true;
|
takeABreak = true;
|
||||||
if (audio != null) {
|
|
||||||
audio.stop();
|
|
||||||
audio.release();
|
|
||||||
audio = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void resume() {
|
void resume() {
|
||||||
synchronized (thread) {
|
synchronized (thread) {
|
||||||
takeABreak = false;
|
takeABreak = false;
|
||||||
if (audio == null) {
|
|
||||||
audio = new AudioRecord(audioSource, sampleRate, channelConfig, audioFormat, audioBuffer.length * 2);
|
|
||||||
audio.startRecording();
|
|
||||||
}
|
|
||||||
thread.notify();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void destroy() {
|
||||||
|
synchronized (thread) {
|
||||||
|
quitThread = true;
|
||||||
|
}
|
||||||
|
audio.stop();
|
||||||
|
audio.release();
|
||||||
|
}
|
||||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||||
synchronized (thread) {
|
synchronized (thread) {
|
||||||
canvasWidth = width;
|
canvasWidth = width;
|
||||||
|
@ -291,13 +234,11 @@ public class ImageView extends SurfaceView implements SurfaceHolder.Callback {
|
||||||
synchronized (thread) {
|
synchronized (thread) {
|
||||||
cantTouchThis = false;
|
cantTouchThis = false;
|
||||||
}
|
}
|
||||||
resume();
|
|
||||||
}
|
}
|
||||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||||
synchronized (thread) {
|
synchronized (thread) {
|
||||||
cantTouchThis = true;
|
cantTouchThis = true;
|
||||||
}
|
}
|
||||||
pause();
|
|
||||||
}
|
}
|
||||||
void drawBitmap(Canvas canvas) {
|
void drawBitmap(Canvas canvas) {
|
||||||
float sx, sy, px, py;
|
float sx, sy, px, py;
|
||||||
|
|
|
@ -85,6 +85,24 @@ public class MainActivity extends Activity {
|
||||||
view.activity = this;
|
view.activity = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy () {
|
||||||
|
view.destroy();
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
view.pause();
|
||||||
|
super.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
view.resume();
|
||||||
|
super.onResume();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
// Inflate the menu; this adds items to the action bar if it is present.
|
// Inflate the menu; this adds items to the action bar if it is present.
|
||||||
|
@ -144,16 +162,4 @@ public class MainActivity extends Activity {
|
||||||
|
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPause() {
|
|
||||||
view.pause();
|
|
||||||
super.onPause();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
view.resume();
|
|
||||||
super.onResume();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,9 @@ void initialize(float rate, int length, int width, int height)
|
||||||
maximum_width = width;
|
maximum_width = width;
|
||||||
maximum_height = height;
|
maximum_height = height;
|
||||||
|
|
||||||
|
for (int i = 0; i < width * height; ++i)
|
||||||
|
pixel_buffer[i] = 0;
|
||||||
|
|
||||||
vpos = 0;
|
vpos = 0;
|
||||||
prev_hpos = hpos = 0;
|
prev_hpos = hpos = 0;
|
||||||
sync_counter = 0;
|
sync_counter = 0;
|
||||||
|
|
Ładowanie…
Reference in New Issue