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 {
 | 
			
		||||
    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 imageHeight = 240;
 | 
			
		||||
    MainActivity activity;
 | 
			
		||||
    private final SurfaceHolder holder;
 | 
			
		||||
    private final Bitmap bitmap;
 | 
			
		||||
    private final Paint paint;
 | 
			
		||||
    private AudioRecord audio;
 | 
			
		||||
    private final AudioRecord audio;
 | 
			
		||||
    private final int audioSource = MediaRecorder.AudioSource.MIC;
 | 
			
		||||
    private final int channelConfig = AudioFormat.CHANNEL_IN_MONO;
 | 
			
		||||
    private final int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
 | 
			
		||||
| 
						 | 
				
			
			@ -76,15 +76,11 @@ public class ImageView extends SurfaceView implements SurfaceHolder.Callback {
 | 
			
		|||
    private final Thread thread = new Thread() {
 | 
			
		||||
        @Override
 | 
			
		||||
        public void run() {
 | 
			
		||||
            //noinspection InfiniteLoopStatement
 | 
			
		||||
            while (true) {
 | 
			
		||||
                synchronized (this) {
 | 
			
		||||
                    while (cantTouchThis || takeABreak) {
 | 
			
		||||
                        try {
 | 
			
		||||
                            wait();
 | 
			
		||||
                        } catch (InterruptedException ignored) {
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    if (quitThread)
 | 
			
		||||
                        return;
 | 
			
		||||
                    if (!cantTouchThis && !takeABreak) {
 | 
			
		||||
                        Canvas canvas = null;
 | 
			
		||||
                        try {
 | 
			
		||||
                            canvas = holder.lockCanvas(null);
 | 
			
		||||
| 
						 | 
				
			
			@ -93,9 +89,10 @@ public class ImageView extends SurfaceView implements SurfaceHolder.Callback {
 | 
			
		|||
                            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 framesPerSecond = Math.max(1, sampleRate / bufferSizeInSamples);
 | 
			
		||||
        audioBuffer = new short[framesPerSecond * bufferSizeInSamples];
 | 
			
		||||
        audio = new AudioRecord(audioSource, sampleRate, channelConfig, audioFormat, audioBuffer.length * 2);
 | 
			
		||||
        audio.startRecording();
 | 
			
		||||
 | 
			
		||||
        int maxHorizontalLength = 3 * sampleRate;
 | 
			
		||||
        currentMode = new int[1];
 | 
			
		||||
| 
						 | 
				
			
			@ -140,76 +139,24 @@ public class ImageView extends SurfaceView implements SurfaceHolder.Callback {
 | 
			
		|||
 | 
			
		||||
        thread.start();
 | 
			
		||||
    }
 | 
			
		||||
    void softer_image() {
 | 
			
		||||
        synchronized (thread) {
 | 
			
		||||
            rsDecoder.invoke_incr_blur();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    void sharper_image() {
 | 
			
		||||
        synchronized (thread) {
 | 
			
		||||
            rsDecoder.invoke_decr_blur();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    void debug_sync() {
 | 
			
		||||
        synchronized (thread) {
 | 
			
		||||
            rsDecoder.invoke_debug_sync();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    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 softer_image() { 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 debug_both() { rsDecoder.invoke_debug_both(); }
 | 
			
		||||
    void robot36_mode() { rsDecoder.invoke_robot36_mode(); }
 | 
			
		||||
    void robot72_mode() { rsDecoder.invoke_robot72_mode(); }
 | 
			
		||||
    void martin1_mode() { rsDecoder.invoke_martin1_mode(); }
 | 
			
		||||
    void martin2_mode() { rsDecoder.invoke_martin2_mode(); }
 | 
			
		||||
    void scottie1_mode() { rsDecoder.invoke_scottie1_mode(); }
 | 
			
		||||
    void scottie2_mode() { rsDecoder.invoke_scottie2_mode(); }
 | 
			
		||||
    void scottieDX_mode() { rsDecoder.invoke_scottieDX_mode(); }
 | 
			
		||||
    void wrasseSC2_180_mode() { rsDecoder.invoke_wrasseSC2_180_mode(); }
 | 
			
		||||
 | 
			
		||||
    void updateTitle(int id) { activity.updateTitle(activity.getString(id)); }
 | 
			
		||||
    void switch_mode(int mode)
 | 
			
		||||
    {
 | 
			
		||||
        synchronized (thread) {
 | 
			
		||||
        switch (mode) {
 | 
			
		||||
            case mode_debug:
 | 
			
		||||
                imageWidth = bitmap.getWidth();
 | 
			
		||||
| 
						 | 
				
			
			@ -260,26 +207,22 @@ public class ImageView extends SurfaceView implements SurfaceHolder.Callback {
 | 
			
		|||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    }
 | 
			
		||||
    void pause() {
 | 
			
		||||
        synchronized (thread) {
 | 
			
		||||
            takeABreak = true;
 | 
			
		||||
            if (audio != null) {
 | 
			
		||||
                audio.stop();
 | 
			
		||||
                audio.release();
 | 
			
		||||
                audio = null;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    void resume() {
 | 
			
		||||
        synchronized (thread) {
 | 
			
		||||
            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) {
 | 
			
		||||
        synchronized (thread) {
 | 
			
		||||
| 
						 | 
				
			
			@ -291,13 +234,11 @@ public class ImageView extends SurfaceView implements SurfaceHolder.Callback {
 | 
			
		|||
        synchronized (thread) {
 | 
			
		||||
            cantTouchThis = false;
 | 
			
		||||
        }
 | 
			
		||||
        resume();
 | 
			
		||||
    }
 | 
			
		||||
    public void surfaceDestroyed(SurfaceHolder holder) {
 | 
			
		||||
        synchronized (thread) {
 | 
			
		||||
            cantTouchThis = true;
 | 
			
		||||
        }
 | 
			
		||||
        pause();
 | 
			
		||||
    }
 | 
			
		||||
    void drawBitmap(Canvas canvas) {
 | 
			
		||||
        float sx, sy, px, py;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -85,6 +85,24 @@ public class MainActivity extends Activity {
 | 
			
		|||
        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
 | 
			
		||||
    public boolean onCreateOptionsMenu(Menu menu) {
 | 
			
		||||
        // 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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @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_height = height;
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < width * height; ++i)
 | 
			
		||||
        pixel_buffer[i] = 0;
 | 
			
		||||
 | 
			
		||||
    vpos = 0;
 | 
			
		||||
    prev_hpos = hpos = 0;
 | 
			
		||||
    sync_counter = 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue