Пример #1
0
  /** Creates instances of CameraTextureRender and SurfaceTexture. */
  public SurfaceTextureManager() {

    textureRender = new CameraTextureRender();
    textureRender.surfaceCreated();

    logger.debug("textureID=" + textureRender.getTextureId());
    surfaceTexture = new SurfaceTexture(textureRender.getTextureId());

    surfaceTexture.setOnFrameAvailableListener(this);
  }
Пример #2
0
 @Override
 public void onFrameAvailable(SurfaceTexture st) {
   logger.trace("new frame available");
   synchronized (frameSyncObject) {
     if (frameAvailable) {
       throw new RuntimeException("frameAvailable already set, frame could be dropped");
     }
     frameAvailable = true;
     frameSyncObject.notifyAll();
   }
 }
Пример #3
0
/**
 * Manages a SurfaceTexture. Creates SurfaceTexture and CameraTextureRender objects, and provides
 * functions that wait for frames and render them to the current EGL surface.
 *
 * <p>The SurfaceTexture can be passed to Camera.setPreviewTexture() to receive camera output.
 */
public class SurfaceTextureManager implements SurfaceTexture.OnFrameAvailableListener {
  /** The logger */
  private static final Logger logger = Logger.getLogger(SurfaceTextureManager.class);

  private SurfaceTexture surfaceTexture;

  private CameraTextureRender textureRender;

  /** guards frameAvailable */
  private final Object frameSyncObject = new Object();

  private boolean frameAvailable;

  /** Creates instances of CameraTextureRender and SurfaceTexture. */
  public SurfaceTextureManager() {

    textureRender = new CameraTextureRender();
    textureRender.surfaceCreated();

    logger.debug("textureID=" + textureRender.getTextureId());
    surfaceTexture = new SurfaceTexture(textureRender.getTextureId());

    surfaceTexture.setOnFrameAvailableListener(this);
  }

  @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
  public void release() {
    if (textureRender != null) {
      textureRender.release();
      textureRender = null;
    }
    if (surfaceTexture != null) {
      surfaceTexture.release();
      surfaceTexture = null;
    }
  }

  /** Returns the SurfaceTexture. */
  public SurfaceTexture getSurfaceTexture() {
    return surfaceTexture;
  }

  /**
   * Latches the next buffer into the texture. Must be called from the thread that created the
   * OutputSurface object.
   */
  public void awaitNewImage() {
    final int TIMEOUT_MS = 2500;

    synchronized (frameSyncObject) {
      while (!frameAvailable) {
        try {
          // Wait for onFrameAvailable() to signal us. Use a timeout
          // to avoid stalling the test if it doesn't arrive.
          frameSyncObject.wait(TIMEOUT_MS);
          if (!frameAvailable) {
            // TODO: if "spurious wakeup", continue while loop
            throw new RuntimeException("Camera frame wait timed out");
          }
        } catch (InterruptedException ie) {
          // shouldn't happen
          throw new RuntimeException(ie);
        }
      }
      frameAvailable = false;
    }

    // Latch the data.
    textureRender.checkGlError("before updateTexImage");
    surfaceTexture.updateTexImage();
  }

  /** Draws the data from SurfaceTexture onto the current EGL surface. */
  public void drawImage() {
    textureRender.drawFrame(surfaceTexture);
  }

  @Override
  public void onFrameAvailable(SurfaceTexture st) {
    logger.trace("new frame available");
    synchronized (frameSyncObject) {
      if (frameAvailable) {
        throw new RuntimeException("frameAvailable already set, frame could be dropped");
      }
      frameAvailable = true;
      frameSyncObject.notifyAll();
    }
  }
}