/**
   * 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();
  }