0

Why following code have performance issue, the frame from camera is not smooth.

public class VideoCaptureAndroid implements PreviewCallback, Callback{
  private Integer deviceRotation = Integer.MAX_VALUE;

  public VideoCaptureAndroid(Context context, int id, long native_capturer) {
    deviceRotationNotifier = new OrientationEventListener(context, SensorManager.SENSOR_DELAY_NORMAL) {
      public void onOrientationChanged(int orientation) {
        if (orientation == ORIENTATION_UNKNOWN) {
          Log.d(TAG, "The device rotation angle is unknown.");
          return;
        }

        synchronized(deviceRotation) {
          if (deviceRotation != orientation) {
            deviceRotation = orientation;
          }
        }
      }
    };

    Exchanger<Handler> handlerExchanger = new Exchanger<Handler>();
    cameraThread = new CameraThread(handlerExchanger);
    cameraThread.start();
  }

  public synchronized void onPreviewFrame(byte[] data, Camera callbackCamera) {

    int frameRotation = info.orientation;
    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
       frameRotation = (info.orientation - deviceRotation + 360) % 360;
    } else if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
       frameRotation = (info.orientation + deviceRotation) % 360;
    }
    onFrame(data, data.length, native_capturer, frameRotation);
    camera.addCallbackBuffer(data);
  }

  }

Seems if I comment out the following code, the frame are smooth, and no performance issues. But I didn't using synchronized in onPreviewFrame to access the deviceRotation, why it will be impacted by onOrientationChanged?

if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
   frameRotation = (info.orientation - deviceRotation + 360) % 360;
} else if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
   frameRotation = (info.orientation + deviceRotation) % 360;
}
Gray
  • 115,027
  • 24
  • 293
  • 354
ZijingWu
  • 3,350
  • 3
  • 25
  • 40
  • Have you tried [Code Review](http://codereview.stackexchange.com/)? – Joseph Wood Jul 11 '16 at 13:25
  • Actually, I'm the reviwer. It our team members code. – ZijingWu Jul 11 '16 at 13:27
  • @JosephWood This would be considered off-topic for Code Review. Read what is on-topic over there to understand why. – syb0rg Jul 11 '16 at 13:27
  • @syb0rg, my mistake. I was under the impression that if your code works and you are simply looking for improvements (i.e. performance) then Code Review was the place to go. I'm still (and always) learning. – Joseph Wood Jul 11 '16 at 13:34
  • 1
    @JosephWood He's not looking for performance improvements though, he is asking why a specific snippet of code (when removed) greatly improves performance. That is not something a review would likely answer. – syb0rg Jul 11 '16 at 13:36
  • 2
    @JosephWood Simple Checklist: Does the code already work as intended? Is the code included in the question? Is it the full, unaltered code? Does the OP want **general, non-specific** feedback about any/all aspects of their code? The quintessential CR question goes "Here is my code that does X, how could I have done it better?". – Kaz Jul 11 '16 at 13:40
  • 1
    @Zak and syb0rg, thanks for insight. – Joseph Wood Jul 11 '16 at 13:44
  • addCallbackbuffer I find suspicious, but that is an uninformed guess. – Joop Eggen Jul 11 '16 at 13:45
  • 1
    Unsure about the performance problems but synchronizing on `deviceRotation` is a bug. Only final objects should be used. when the `deviceRotation` is changed, threats will be locking on different things. – Gray Aug 01 '16 at 19:58

1 Answers1

0

The code you have indicated is most likely not the problem. Modulo operations are slow, but doing a single one each frame is not going to have a huge impact. The frameRotation value is being passed to onFrame() which we can only assume is applying a matrix or other transform to rotate the data. This is an expensive operation and most likely involves the use of one or more temporary buffers (or Bitmap objects), which uses the heap and is also slow. I'm assuming that info.orientation being passed unaltered to onFrame() will result in no adjustment to the frame. Hence, the removal of the 2 lines you have indicated will result in no heavy processing in onFrame(), which is why the jitter disappears.

You can track this down better using traceview or systrace to confirm.

Larry Schiefer
  • 15,687
  • 2
  • 27
  • 33