Loading services/camera/libcameraservice/api2/CameraDeviceClient.cpp +80 −0 Original line number Diff line number Diff line Loading @@ -360,6 +360,26 @@ status_t CameraDeviceClient::createStream(int width, int height, int format, ALOGV("%s: Camera %d: Successfully created a new stream ID %d", __FUNCTION__, mCameraId, streamId); /** * Set the stream transform flags to automatically * rotate the camera stream for preview use cases. */ int32_t transform = 0; res = getRotationTransformLocked(&transform); if (res != OK) { // Error logged by getRotationTransformLocked. return res; } res = mDevice->setStreamTransform(streamId, transform); if (res != OK) { ALOGE("%s: Failed to set stream transform (stream id %d)", __FUNCTION__, streamId); return res; } return streamId; } Loading Loading @@ -560,4 +580,64 @@ bool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) { return true; } status_t CameraDeviceClient::getRotationTransformLocked(int32_t* transform) { ALOGV("%s: begin", __FUNCTION__); if (transform == NULL) { ALOGW("%s: null transform", __FUNCTION__); return BAD_VALUE; } *transform = 0; const CameraMetadata& staticInfo = mDevice->info(); camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_SENSOR_ORIENTATION); if (entry.count == 0) { ALOGE("%s: Camera %d: Can't find android.sensor.orientation in " "static metadata!", __FUNCTION__, mCameraId); return INVALID_OPERATION; } int32_t& flags = *transform; int orientation = entry.data.i32[0]; switch (orientation) { case 0: flags = 0; break; case 90: flags = NATIVE_WINDOW_TRANSFORM_ROT_90; break; case 180: flags = NATIVE_WINDOW_TRANSFORM_ROT_180; break; case 270: flags = NATIVE_WINDOW_TRANSFORM_ROT_270; break; default: ALOGE("%s: Invalid HAL android.sensor.orientation value: %d", __FUNCTION__, orientation); return INVALID_OPERATION; } /** * This magic flag makes surfaceflinger un-rotate the buffers * to counter the extra global device UI rotation whenever the user * physically rotates the device. * * By doing this, the camera buffer always ends up aligned * with the physical camera for a "see through" effect. * * In essence, the buffer only gets rotated during preview use-cases. * The user is still responsible to re-create streams of the proper * aspect ratio, or the preview will end up looking non-uniformly * stretched. */ flags |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; ALOGV("%s: final transform = 0x%x", __FUNCTION__, flags); return OK; } } // namespace android services/camera/libcameraservice/api2/CameraDeviceClient.h +3 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,9 @@ protected: const CameraMetadata& frame); virtual void detachDevice(); // Calculate the ANativeWindow transform from android.sensor.orientation status_t getRotationTransformLocked(/*out*/int32_t* transform); private: /** ICameraDeviceUser interface-related private members */ Loading Loading
services/camera/libcameraservice/api2/CameraDeviceClient.cpp +80 −0 Original line number Diff line number Diff line Loading @@ -360,6 +360,26 @@ status_t CameraDeviceClient::createStream(int width, int height, int format, ALOGV("%s: Camera %d: Successfully created a new stream ID %d", __FUNCTION__, mCameraId, streamId); /** * Set the stream transform flags to automatically * rotate the camera stream for preview use cases. */ int32_t transform = 0; res = getRotationTransformLocked(&transform); if (res != OK) { // Error logged by getRotationTransformLocked. return res; } res = mDevice->setStreamTransform(streamId, transform); if (res != OK) { ALOGE("%s: Failed to set stream transform (stream id %d)", __FUNCTION__, streamId); return res; } return streamId; } Loading Loading @@ -560,4 +580,64 @@ bool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) { return true; } status_t CameraDeviceClient::getRotationTransformLocked(int32_t* transform) { ALOGV("%s: begin", __FUNCTION__); if (transform == NULL) { ALOGW("%s: null transform", __FUNCTION__); return BAD_VALUE; } *transform = 0; const CameraMetadata& staticInfo = mDevice->info(); camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_SENSOR_ORIENTATION); if (entry.count == 0) { ALOGE("%s: Camera %d: Can't find android.sensor.orientation in " "static metadata!", __FUNCTION__, mCameraId); return INVALID_OPERATION; } int32_t& flags = *transform; int orientation = entry.data.i32[0]; switch (orientation) { case 0: flags = 0; break; case 90: flags = NATIVE_WINDOW_TRANSFORM_ROT_90; break; case 180: flags = NATIVE_WINDOW_TRANSFORM_ROT_180; break; case 270: flags = NATIVE_WINDOW_TRANSFORM_ROT_270; break; default: ALOGE("%s: Invalid HAL android.sensor.orientation value: %d", __FUNCTION__, orientation); return INVALID_OPERATION; } /** * This magic flag makes surfaceflinger un-rotate the buffers * to counter the extra global device UI rotation whenever the user * physically rotates the device. * * By doing this, the camera buffer always ends up aligned * with the physical camera for a "see through" effect. * * In essence, the buffer only gets rotated during preview use-cases. * The user is still responsible to re-create streams of the proper * aspect ratio, or the preview will end up looking non-uniformly * stretched. */ flags |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; ALOGV("%s: final transform = 0x%x", __FUNCTION__, flags); return OK; } } // namespace android
services/camera/libcameraservice/api2/CameraDeviceClient.h +3 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,9 @@ protected: const CameraMetadata& frame); virtual void detachDevice(); // Calculate the ANativeWindow transform from android.sensor.orientation status_t getRotationTransformLocked(/*out*/int32_t* transform); private: /** ICameraDeviceUser interface-related private members */ Loading