PageRenderTime 22ms CodeModel.GetById 12ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 0ms

/ocr/ocrservice/src/com/googlecode/eyesfree/opticflow/ProcessingThread.java

http://eyes-free.googlecode.com/
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}