This is a variation on a question often asked hereabouts but I don't see this exact situation, so I'll throw it out there.
I have an onPreviewFrame callback set up. This gets a byte[] with NV21 data in it. We h.264 encode it and send it out as a video stream. On the other side, we see the video skewed, either 90 or 270 degrees, depending on the phone.
So the question is, how to rotate the data, not just the preview image? Camera.Parameters.setRotation only affects taking the picture, not video. Camera.setDisplayOrientation specifically says it only affects the displaying preview, not the frame bytes:
This does not affect the order of byte array passed in onPreviewFrame(byte[], Camera), JPEG pictures, or recorded videos.
So is there a way, at any API level, to change the orientation of the byte array? Failing that, can you even rotate the NV21 (YVU) format that this come in, or do I need to RGB it first?
For back-facing cameras, the sensor image buffer is rotated clockwise. The expression deviceOrientationDegrees * sign + 360 converts device rotation from counterclockwise to clockwise for back-facing cameras (for example, converting 270 degrees counterclockwise to 90 degrees clockwise).
PreviewView is a subclass of FrameLayout . To display the camera feed, it uses either a SurfaceView or TextureView , provides a preview surface to the camera when it's ready, tries to keep it valid as long as the camera is using it, and when released prematurely, provides a new surface if the camera is still in use.
Turns out you do need to rotate each frame yourself before sending it off. We ended up using libyuv, which has a very convenient function that both rotates and converts it - libyuv::ConvertToI420
https://code.google.com/p/libyuv/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With