/ocr/ocrservice/src/com/googlecode/eyesfree/opticflow/ProcessingThread.java
Java | 159 lines | 95 code | 31 blank | 33 comment | 9 complexity | c60eec80a85d646da0d01d7e1eacbcad MD5 | raw file
1/* 2 * Copyright (C) 2011 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17package com.googlecode.eyesfree.opticflow; 18 19import android.os.Handler; 20import android.os.Looper; 21import android.os.Message; 22 23import com.googlecode.eyesfree.env.Stopwatch; 24 25import java.util.Vector; 26 27/** 28 * This is the thread where the actual work gets done. Uses the Android 29 * Looper/Handler paradigm to receive frames from the UI thread. 30 * 31 * Modified by Alan Viverette from Andrew Harp's original source. 32 * 33 * @author Andrew Harp 34 * @author alanv@google.com (Alan Viverette) 35 */ 36public class ProcessingThread extends Thread { 37 private static final int STOP_CODE = -1; 38 39 private final Vector<FrameProcessor> previewProcessors; 40 41 private Handler processingHandler; 42 43 private volatile boolean isProcessing; 44 45 private final Stopwatch stopwatch; 46 47 private final String name; 48 49 private final FrameLooper previewLooper; 50 51 private final int delay; 52 53 private final int priority; 54 55 public ProcessingThread( 56 final FrameLooper previewLooper, final int level, final int delay, final int priority) { 57 this.previewLooper = previewLooper; 58 this.delay = delay; 59 this.priority = priority; 60 61 this.isProcessing = false; 62 this.stopwatch = new Stopwatch(); 63 this.previewProcessors = new Vector<FrameProcessor>(); 64 this.name = "FrameProcessingThread" + level; 65 66 stopwatch.start(); 67 68 setName(name); 69 } 70 71 protected void kill() { 72 processingHandler.sendEmptyMessage(STOP_CODE); 73 processingHandler = null; 74 } 75 76 protected void sendFrame(final TimestampedFrame previewFrame) { 77 final Message message = new Message(); 78 message.obj = previewFrame; 79 // TODO(mrcasey): Figure out when this is null... it doesn't seem like 80 // it should be. 81 if (processingHandler != null) { 82 processingHandler.sendMessage(message); 83 } 84 } 85 86 protected boolean isReady() { 87 return !isProcessing && stopwatch.getElapsedMilliseconds() >= delay; 88 } 89 90 protected void preprocess(final TimestampedFrame previewFrame) { 91 previewFrame.threadStart(); 92 93 isProcessing = true; 94 for (final FrameProcessor processor : previewProcessors) { 95 synchronized (processor) { 96 processor.preprocessFrame(previewFrame); 97 } 98 } 99 } 100 101 /** 102 * Processes the frame in a the processing thread. 103 */ 104 protected void processFrame(final TimestampedFrame frame) { 105 stopwatch.reset(); 106 107 final Vector<FrameProcessor> processors = getProcessors(); 108 109 // This is where the frame handling happens. 110 for (final FrameProcessor processor : processors) { 111 synchronized (processor) { 112 if (!processor.isInitialized()) { 113 // Initialize any processors that have been added lately. 114 processor.init(frame.getSize()); 115 } 116 117 processor.processFrame(frame); 118 } 119 } 120 121 frame.threadDone(); 122 previewLooper.doneProcessing(frame); 123 isProcessing = false; 124 } 125 126 @Override 127 public void run() { 128 setPriority(priority); 129 Looper.prepare(); 130 processingHandler = new Handler() { 131 @Override 132 public void handleMessage(final Message msg) { 133 // Stop the loop if stopLoop has been called (and cleared 134 // processingHandler). 135 if (processingHandler == null) { 136 final Vector<FrameProcessor> processors = getProcessors(); 137 for (final FrameProcessor processor : processors) { 138 synchronized (processor) { 139 processor.shutdown(); 140 } 141 } 142 Looper.myLooper().quit(); 143 return; 144 } 145 146 processFrame((TimestampedFrame) msg.obj); 147 } 148 }; 149 Looper.loop(); 150 } 151 152 public void addProcessor(final FrameProcessor handler) { 153 previewProcessors.add(handler); 154 } 155 156 public Vector<FrameProcessor> getProcessors() { 157 return new Vector<FrameProcessor>(previewProcessors); 158 } 159}