3

I have got custom view that extends SurfaceView and implements Camera.PreviewCallback. I am using this view as a camera preview. There is also implemented functionality captureing video frames to buffer and streaming them.

When orientation of device is changed, I call setRotation() with appropriate argument.

Camera.Parameters parameters = svVideo.getCamera().getParameters();
parameters.setRotation(rotation);
svVideo.getCamera().setParameters(parameters);

But sadly, there is no change in orientation of frames captured in onPreviewFrame() callback. What I am trying to achieve is that if I rotate streaming device, video stream sent to other device will be rotated accordingly.

I also tried to take some photos with changed rotation as described. setRotation() affects only rotation of pictures taken with front-facing camera (which is weird), photos from back facing camera are not affected at all.

My question is: How could I get properly rotated frames usable for streaming or rotate them in callback by myself?

Here is my onPreviewFrame method:

@Override
public void onPreviewFrame(final byte[] frame, final Camera camera) {
    final long now = System.nanoTime();
    if (outq.remainingCapacity() >= 2 && (now - this.frame) >= 1000000000 / fps) { //Don't encode more then we can handle, and also not more then FPS.
        queueFrameForEncoding(frame, now);
    }
    getEncodedFrames();
    camera.addCallbackBuffer(frame); //Recycle buffer
}
Komoi
  • 43
  • 8
  • It looks like there is no chance to receive frames rotated correctly in callback so I have to do this manually. I will try proposed solutions from http://stackoverflow.com/questions/14167976/rotate-an-yuv-byte-array-on-android – Komoi Jul 22 '15 at 12:13
  • 1
    Alternatively, send the preview to a TextureView and apply a rotation matrix to that instead. That way the hardware does all the work. – fadden Jul 22 '15 at 18:01

1 Answers1

3
byte[] rotatedData = new byte[imgToDecode.length]; 
    for (int y = 0; y < imgHeight; y++) {
        for (int x = 0; x < imgWidth; x++)
            rotatedData[x * imgHeight + imgHeight - y - 1] = imgToDecode[x + y * imgWidth];
    }

Also after rotation you should swap width and height

int buffer = height;
height = width;
width = buffer;
Ufkoku
  • 2,384
  • 20
  • 44
  • Thank you for answer. It will indeed rotate image data, but there is probably some metadata header which will mess the result. Now, It produces greenish stream, but I will try to improve it to rotate only frame data itself. – Komoi Jul 22 '15 at 11:36