/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. package com.googlecode.eyesfree.opticflow;
  17. import android.os.Handler;
  18. import android.os.Looper;
  19. import android.os.Message;
  20. import com.googlecode.eyesfree.env.Stopwatch;
  21. import java.util.Vector;
  22. /**
  23. * This is the thread where the actual work gets done. Uses the Android
  24. * Looper/Handler paradigm to receive frames from the UI thread.
  25. *
  26. * Modified by Alan Viverette from Andrew Harp's original source.
  27. *
  28. * @author Andrew Harp
  29. * @author alanv@google.com (Alan Viverette)
  30. */
  31. public class ProcessingThread extends Thread {
  32. private static final int STOP_CODE = -1;
  33. private final Vector<FrameProcessor> previewProcessors;
  34. private Handler processingHandler;
  35. private volatile boolean isProcessing;
  36. private final Stopwatch stopwatch;
  37. private final String name;
  38. private final FrameLooper previewLooper;
  39. private final int delay;
  40. private final int priority;
  41. public ProcessingThread(
  42. final FrameLooper previewLooper, final int level, final int delay, final int priority) {
  43. this.previewLooper = previewLooper;
  44. this.delay = delay;
  45. this.priority = priority;
  46. this.isProcessing = false;
  47. this.stopwatch = new Stopwatch();
  48. this.previewProcessors = new Vector<FrameProcessor>();
  49. this.name = "FrameProcessingThread" + level;
  50. stopwatch.start();
  51. setName(name);
  52. }
  53. protected void kill() {
  54. processingHandler.sendEmptyMessage(STOP_CODE);
  55. processingHandler = null;
  56. }
  57. protected void sendFrame(final TimestampedFrame previewFrame) {
  58. final Message message = new Message();
  59. message.obj = previewFrame;
  60. // TODO(mrcasey): Figure out when this is null... it doesn't seem like
  61. // it should be.
  62. if (processingHandler != null) {
  63. processingHandler.sendMessage(message);
  64. }
  65. }
  66. protected boolean isReady() {
  67. return !isProcessing && stopwatch.getElapsedMilliseconds() >= delay;
  68. }
  69. protected void preprocess(final TimestampedFrame previewFrame) {
  70. previewFrame.threadStart();
  71. isProcessing = true;
  72. for (final FrameProcessor processor : previewProcessors) {
  73. synchronized (processor) {
  74. processor.preprocessFrame(previewFrame);
  75. }
  76. }
  77. }
  78. /**
  79. * Processes the frame in a the processing thread.
  80. */
  81. protected void processFrame(final TimestampedFrame frame) {
  82. stopwatch.reset();
  83. final Vector<FrameProcessor> processors = getProcessors();
  84. // This is where the frame handling happens.
  85. for (final FrameProcessor processor : processors) {
  86. synchronized (processor) {
  87. if (!processor.isInitialized()) {
  88. // Initialize any processors that have been added lately.
  89. processor.init(frame.getSize());
  90. }
  91. processor.processFrame(frame);
  92. }
  93. }
  94. frame.threadDone();
  95. previewLooper.doneProcessing(frame);
  96. isProcessing = false;
  97. }
  98. @Override
  99. public void run() {
  100. setPriority(priority);
  101. Looper.prepare();
  102. processingHandler = new Handler() {
  103. @Override
  104. public void handleMessage(final Message msg) {
  105. // Stop the loop if stopLoop has been called (and cleared
  106. // processingHandler).
  107. if (processingHandler == null) {
  108. final Vector<FrameProcessor> processors = getProcessors();
  109. for (final FrameProcessor processor : processors) {
  110. synchronized (processor) {
  111. processor.shutdown();
  112. }
  113. }
  114. Looper.myLooper().quit();
  115. return;
  116. }
  117. processFrame((TimestampedFrame) msg.obj);
  118. }
  119. };
  120. Looper.loop();
  121. }
  122. public void addProcessor(final FrameProcessor handler) {
  123. previewProcessors.add(handler);
  124. }
  125. public Vector<FrameProcessor> getProcessors() {
  126. return new Vector<FrameProcessor>(previewProcessors);
  127. }
  128. }