Commit 5a07fa8e authored by Ricky Liang's avatar Ricky Liang Committed by Commit Bot

[CrOS] video_capture: pre-rotate frames for non-zero sensor orientation

There are some devices with camera sensors of non-zero physical
orientation.  For these devices, we still have to rotate the camera
frames to compensate for the sensor orientation if we disable
pre-rotation in the video capture stack.  Otherwise, the video
recorded in the camera app will have wrong orientation because we
don't rotate the frames at all on the video stack.

Bug: 990682
Test: Manually on Nocturne
Change-Id: Iba471e318f6d15770491b5677769e5d6c5d1c241
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2335849
Commit-Queue: Ricky Liang <jcliang@chromium.org>
Reviewed-by: default avatarWei Lee <wtlee@chromium.org>
Cr-Commit-Position: refs/heads/master@{#795406}
parent 4b95a898
...@@ -60,8 +60,8 @@ void CameraDeviceContext::SubmitCapturedGpuMemoryBuffer( ...@@ -60,8 +60,8 @@ void CameraDeviceContext::SubmitCapturedGpuMemoryBuffer(
base::TimeTicks reference_time, base::TimeTicks reference_time,
base::TimeDelta timestamp) { base::TimeDelta timestamp) {
client_->OnIncomingCapturedGfxBuffer(buffer, frame_format, client_->OnIncomingCapturedGfxBuffer(buffer, frame_format,
GetCameraFrameOrientation(), GetCameraFrameRotation(), reference_time,
reference_time, timestamp); timestamp);
} }
void CameraDeviceContext::SetSensorOrientation(int sensor_orientation) { void CameraDeviceContext::SetSensorOrientation(int sensor_orientation) {
...@@ -78,10 +78,19 @@ void CameraDeviceContext::SetScreenRotation(int screen_rotation) { ...@@ -78,10 +78,19 @@ void CameraDeviceContext::SetScreenRotation(int screen_rotation) {
screen_rotation_ = screen_rotation; screen_rotation_ = screen_rotation;
} }
int CameraDeviceContext::GetCameraFrameOrientation() { int CameraDeviceContext::GetCameraFrameRotation() {
return (sensor_orientation_ + screen_rotation_) % 360; return (sensor_orientation_ + screen_rotation_) % 360;
} }
int CameraDeviceContext::GetRotationForDisplay() {
return screen_rotation_;
}
int CameraDeviceContext::GetRotationFromSensorOrientation() {
// We need to rotate the frame back to 0 degree.
return (360 - sensor_orientation_);
}
bool CameraDeviceContext::ReserveVideoCaptureBufferFromPool( bool CameraDeviceContext::ReserveVideoCaptureBufferFromPool(
gfx::Size size, gfx::Size size,
VideoPixelFormat format, VideoPixelFormat format,
......
...@@ -134,7 +134,17 @@ class CAPTURE_EXPORT CameraDeviceContext { ...@@ -134,7 +134,17 @@ class CAPTURE_EXPORT CameraDeviceContext {
void SetScreenRotation(int screen_rotation); void SetScreenRotation(int screen_rotation);
int GetCameraFrameOrientation(); // Gets the accumulated rotation that the camera frame needs to be rotated
// to match the display orientation. This includes the sensor orientation and
// the screen rotation.
int GetCameraFrameRotation();
// Gets the rotation needed to match the camera frame to the display, assuming
// the camera frame has 0 degree orientation.
int GetRotationForDisplay();
// Gets the rotation needed to get the camera frame to 0 degree orientation.
int GetRotationFromSensorOrientation();
// Reserves a video capture buffer from the buffer pool provided by the video // Reserves a video capture buffer from the buffer pool provided by the video
// |client_|. Returns true if the operation succeeds; false otherwise. // |client_|. Returns true if the operation succeeds; false otherwise.
......
...@@ -1070,7 +1070,7 @@ bool CameraDeviceDelegate::SetPointsOfInterest( ...@@ -1070,7 +1070,7 @@ bool CameraDeviceDelegate::SetPointsOfInterest(
// Handle rotation, still in normalized square space. // Handle rotation, still in normalized square space.
std::tie(x, y) = [&]() -> std::pair<double, double> { std::tie(x, y) = [&]() -> std::pair<double, double> {
switch (device_context_->GetCameraFrameOrientation()) { switch (device_context_->GetCameraFrameRotation()) {
case 0: case 0:
return {x, y}; return {x, y};
case 90: case 90:
......
...@@ -319,7 +319,7 @@ void RequestManager::PrepareCaptureRequest() { ...@@ -319,7 +319,7 @@ void RequestManager::PrepareCaptureRequest() {
pending_result.input_buffer_id = input_buffer_id; pending_result.input_buffer_id = input_buffer_id;
pending_result.reprocess_effect = reprocess_effect; pending_result.reprocess_effect = reprocess_effect;
pending_result.still_capture_callback = std::move(callback); pending_result.still_capture_callback = std::move(callback);
pending_result.orientation = device_context_->GetCameraFrameOrientation(); pending_result.orientation = device_context_->GetCameraFrameRotation();
// For reprocess supported devices, bind the ReprocessTaskQueue with this // For reprocess supported devices, bind the ReprocessTaskQueue with this
// frame number. Once the shot result is returned, we will rebind the // frame number. Once the shot result is returned, we will rebind the
...@@ -441,7 +441,7 @@ bool RequestManager::TryPrepareOneShotRequest( ...@@ -441,7 +441,7 @@ bool RequestManager::TryPrepareOneShotRequest(
take_photo_callback_queue_.pop(); take_photo_callback_queue_.pop();
*settings = std::move(take_photo_settings_queue_.front()); *settings = std::move(take_photo_settings_queue_.front());
SetJpegOrientation(settings, device_context_->GetCameraFrameOrientation()); SetJpegOrientation(settings, device_context_->GetCameraFrameRotation());
} }
SetZeroShutterLag(settings, true); SetZeroShutterLag(settings, true);
take_photo_settings_queue_.pop(); take_photo_settings_queue_.pop();
...@@ -832,8 +832,7 @@ void RequestManager::SubmitCapturedPreviewBuffer(uint32_t frame_number, ...@@ -832,8 +832,7 @@ void RequestManager::SubmitCapturedPreviewBuffer(uint32_t frame_number,
VideoCaptureFormat format; VideoCaptureFormat format;
base::Optional<VideoCaptureDevice::Client::Buffer> buffer = base::Optional<VideoCaptureDevice::Client::Buffer> buffer =
stream_buffer_manager_->AcquireBufferForClientById( stream_buffer_manager_->AcquireBufferForClientById(
StreamType::kPreviewOutput, buffer_ipc_id, StreamType::kPreviewOutput, buffer_ipc_id, &format);
device_context_->GetCameraFrameOrientation(), &format);
CHECK(buffer); CHECK(buffer);
// TODO: Figure out the right color space for the camera frame. We may need // TODO: Figure out the right color space for the camera frame. We may need
...@@ -859,7 +858,7 @@ void RequestManager::SubmitCapturedPreviewBuffer(uint32_t frame_number, ...@@ -859,7 +858,7 @@ void RequestManager::SubmitCapturedPreviewBuffer(uint32_t frame_number,
return VideoRotation::VIDEO_ROTATION_0; return VideoRotation::VIDEO_ROTATION_0;
}; };
metadata.rotation = metadata.rotation =
translate_rotation(device_context_->GetCameraFrameOrientation()); translate_rotation(device_context_->GetRotationForDisplay());
} else { } else {
// All frames are pre-rotated to the display orientation. // All frames are pre-rotated to the display orientation.
metadata.rotation = VideoRotation::VIDEO_ROTATION_0; metadata.rotation = VideoRotation::VIDEO_ROTATION_0;
......
...@@ -67,7 +67,6 @@ gfx::GpuMemoryBuffer* StreamBufferManager::GetGpuMemoryBufferById( ...@@ -67,7 +67,6 @@ gfx::GpuMemoryBuffer* StreamBufferManager::GetGpuMemoryBufferById(
base::Optional<StreamBufferManager::Buffer> base::Optional<StreamBufferManager::Buffer>
StreamBufferManager::AcquireBufferForClientById(StreamType stream_type, StreamBufferManager::AcquireBufferForClientById(StreamType stream_type,
uint64_t buffer_ipc_id, uint64_t buffer_ipc_id,
int rotation,
VideoCaptureFormat* format) { VideoCaptureFormat* format) {
DCHECK(stream_context_.count(stream_type)); DCHECK(stream_context_.count(stream_type));
auto& stream_context = stream_context_[stream_type]; auto& stream_context = stream_context_[stream_type];
...@@ -83,9 +82,14 @@ StreamBufferManager::AcquireBufferForClientById(StreamType stream_type, ...@@ -83,9 +82,14 @@ StreamBufferManager::AcquireBufferForClientById(StreamType stream_type,
// We only support NV12 at the moment. // We only support NV12 at the moment.
DCHECK_EQ(format->pixel_format, PIXEL_FORMAT_NV12); DCHECK_EQ(format->pixel_format, PIXEL_FORMAT_NV12);
int rotation = device_context_->GetCameraFrameRotation();
if (base::FeatureList::IsEnabled( if (base::FeatureList::IsEnabled(
features::kDisableCameraFrameRotationAtSource)) { features::kDisableCameraFrameRotationAtSource)) {
return std::move(buffer_pair.vcd_buffer); // For a device that don't have the camera sensor installed to match the
// device's natural orientation, we have to fix the sensor orientation here.
// Otherwise the recorded video in Chrome camera app would have wrong
// orientation because we no longer rotate the frames for the video encoder.
rotation = device_context_->GetRotationFromSensorOrientation();
} }
if (rotation == 0) { if (rotation == 0) {
......
...@@ -69,7 +69,6 @@ class CAPTURE_EXPORT StreamBufferManager final { ...@@ -69,7 +69,6 @@ class CAPTURE_EXPORT StreamBufferManager final {
// camera frame rotation for good. // camera frame rotation for good.
base::Optional<Buffer> AcquireBufferForClientById(StreamType stream_type, base::Optional<Buffer> AcquireBufferForClientById(StreamType stream_type,
uint64_t buffer_ipc_id, uint64_t buffer_ipc_id,
int rotation,
VideoCaptureFormat* format); VideoCaptureFormat* format);
VideoCaptureFormat GetStreamCaptureFormat(StreamType stream_type); VideoCaptureFormat GetStreamCaptureFormat(StreamType stream_type);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment