Commit 33bdfbd0 authored by Sergey Ulanov's avatar Sergey Ulanov Committed by Commit Bot

[Fuchsia] rotate frame in video capturer based on the camera orientation.

fuchsia.camera3 API provides camera application to clients, which are
expected to rotate the image when presenting it on the screen. Updated
VideoCaptureDeviceFuchsia to watch camera orientation and apply
corresponding transformation to the video frames.

Bug: 866669
Change-Id: I05ea0a3d4a59975ae0ed111c949b434fb6482b95
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2189619
Commit-Queue: Sergey Ulanov <sergeyu@chromium.org>
Reviewed-by: default avatarKevin Marshall <kmarshall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#768552}
parent 701cae5d
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/time/time.h" #include "base/time/time.h"
#include "media/base/video_types.h" #include "media/base/video_types.h"
#include "third_party/libyuv/include/libyuv/convert.h" #include "third_party/libyuv/include/libyuv/convert.h"
#include "third_party/libyuv/include/libyuv/video_common.h"
#include "ui/gfx/buffer_format_util.h" #include "ui/gfx/buffer_format_util.h"
namespace media { namespace media {
...@@ -21,71 +22,68 @@ size_t RoundUp(size_t value, size_t alignment) { ...@@ -21,71 +22,68 @@ size_t RoundUp(size_t value, size_t alignment) {
return ((value + alignment - 1) / alignment) * alignment; return ((value + alignment - 1) / alignment) * alignment;
} }
void CopyAndConvertFrame( libyuv::FourCC GetFourccForPixelFormat(
base::span<const uint8_t> src_span, fuchsia::sysmem::PixelFormatType src_pixel_format) {
fuchsia::sysmem::PixelFormatType src_pixel_format,
size_t src_stride_y,
size_t src_coded_height,
std::unique_ptr<VideoCaptureBufferHandle> output_handle,
gfx::Size output_size) {
const uint8_t* src_y = src_span.data();
size_t src_y_plane_size = src_stride_y * src_coded_height;
// Calculate offsets and strides for the output buffer.
uint8_t* dst_y = output_handle->data();
int dst_stride_y = output_size.width();
size_t dst_y_plane_size = output_size.width() * output_size.height();
uint8_t* dst_u = dst_y + dst_y_plane_size;
int dst_stride_u = output_size.width() / 2;
uint8_t* dst_v = dst_u + dst_y_plane_size / 4;
int dst_stride_v = output_size.width() / 2;
// Check that the output fits in the buffer.
const uint8_t* dst_end = dst_v + dst_y_plane_size / 4;
CHECK_LE(dst_end, output_handle->data() + output_handle->mapped_size());
switch (src_pixel_format) { switch (src_pixel_format) {
case fuchsia::sysmem::PixelFormatType::I420:
return libyuv::FourCC::FOURCC_I420;
case fuchsia::sysmem::PixelFormatType::YV12: case fuchsia::sysmem::PixelFormatType::YV12:
case fuchsia::sysmem::PixelFormatType::I420: { return libyuv::FourCC::FOURCC_YV12;
const uint8_t* src_u = src_y + src_y_plane_size; case fuchsia::sysmem::PixelFormatType::NV12:
int src_stride_u = src_stride_y / 2; return libyuv::FourCC::FOURCC_NV12;
size_t src_u_plane_size = src_stride_u * src_coded_height / 2; default:
const uint8_t* src_v = src_u + src_u_plane_size; NOTREACHED();
int src_stride_v = src_stride_y / 2; return libyuv::FourCC::FOURCC_I420;
if (src_pixel_format == fuchsia::sysmem::PixelFormatType::YV12) {
// Swap U and V planes to account for different plane order in YV12.
std::swap(src_u, src_v);
} }
}
size_t src_v_plane_size = src_stride_v * src_coded_height / 2; libyuv::RotationMode CameraOrientationToLibyuvRotation(
const uint8_t* src_end = src_v + src_v_plane_size; fuchsia::camera3::Orientation orientation,
CHECK_LE(src_end, src_span.data() + src_span.size()); bool* flip_y) {
switch (orientation) {
libyuv::I420Copy(src_y, src_stride_y, src_u, src_stride_u, src_v, case fuchsia::camera3::Orientation::UP:
src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u, *flip_y = false;
dst_v, dst_stride_v, output_size.width(), return libyuv::RotationMode::kRotate0;
output_size.height());
break; case fuchsia::camera3::Orientation::DOWN:
*flip_y = false;
return libyuv::RotationMode::kRotate180;
case fuchsia::camera3::Orientation::LEFT:
*flip_y = false;
return libyuv::RotationMode::kRotate270;
case fuchsia::camera3::Orientation::RIGHT:
*flip_y = false;
return libyuv::RotationMode::kRotate90;
case fuchsia::camera3::Orientation::UP_FLIPPED:
*flip_y = true;
return libyuv::RotationMode::kRotate180;
case fuchsia::camera3::Orientation::DOWN_FLIPPED:
*flip_y = true;
return libyuv::RotationMode::kRotate0;
case fuchsia::camera3::Orientation::LEFT_FLIPPED:
*flip_y = true;
return libyuv::RotationMode::kRotate90;
case fuchsia::camera3::Orientation::RIGHT_FLIPPED:
*flip_y = true;
return libyuv::RotationMode::kRotate270;
} }
}
case fuchsia::sysmem::PixelFormatType::NV12: { gfx::Size RotateSize(gfx::Size size, libyuv::RotationMode rotation) {
const uint8_t* src_uv = src_y + src_stride_y * src_coded_height; switch (rotation) {
int src_stride_uv = src_stride_y; case libyuv::RotationMode::kRotate0:
case libyuv::RotationMode::kRotate180:
int src_uv_plane_size = src_stride_uv * src_coded_height / 2; return size;
const uint8_t* src_end = src_uv + src_uv_plane_size;
CHECK_LE(src_end, src_span.data() + src_span.size());
libyuv::NV12ToI420(src_y, src_stride_y, src_uv, src_stride_uv, dst_y,
dst_stride_y, dst_u, dst_stride_u, dst_v, dst_stride_v,
output_size.width(), output_size.height());
break;
}
default: case libyuv::RotationMode::kRotate90:
NOTREACHED(); case libyuv::RotationMode::kRotate270:
return gfx::Size(size.height(), size.width());
} }
} }
...@@ -150,6 +148,7 @@ void VideoCaptureDeviceFuchsia::AllocateAndStart( ...@@ -150,6 +148,7 @@ void VideoCaptureDeviceFuchsia::AllocateAndStart(
fit::bind_member(this, &VideoCaptureDeviceFuchsia::OnStreamError)); fit::bind_member(this, &VideoCaptureDeviceFuchsia::OnStreamError));
WatchResolution(); WatchResolution();
WatchOrientation();
// Call SetBufferCollection() with a new buffer collection token to indicate // Call SetBufferCollection() with a new buffer collection token to indicate
// that we are interested in buffer collection negotiation. The collection // that we are interested in buffer collection negotiation. The collection
...@@ -213,6 +212,21 @@ void VideoCaptureDeviceFuchsia::OnWatchResolutionResult( ...@@ -213,6 +212,21 @@ void VideoCaptureDeviceFuchsia::OnWatchResolutionResult(
WatchResolution(); WatchResolution();
} }
void VideoCaptureDeviceFuchsia::WatchOrientation() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
stream_->WatchOrientation(fit::bind_member(
this, &VideoCaptureDeviceFuchsia::OnWatchOrientationResult));
}
void VideoCaptureDeviceFuchsia::OnWatchOrientationResult(
fuchsia::camera3::Orientation orientation) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
orientation_ = orientation;
WatchOrientation();
}
void VideoCaptureDeviceFuchsia::WatchBufferCollection() { void VideoCaptureDeviceFuchsia::WatchBufferCollection() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
...@@ -333,9 +347,16 @@ void VideoCaptureDeviceFuchsia::ProcessNewFrame( ...@@ -333,9 +347,16 @@ void VideoCaptureDeviceFuchsia::ProcessNewFrame(
sysmem_buffer_format.bytes_per_row_divisor); sysmem_buffer_format.bytes_per_row_divisor);
gfx::Size visible_size = gfx::Size visible_size =
frame_size_.value_or(gfx::Size(src_coded_width, src_coded_height)); frame_size_.value_or(gfx::Size(src_coded_width, src_coded_height));
gfx::Size output_size((visible_size.width() + 1) & ~1, gfx::Size nonrotated_output_size((visible_size.width() + 1) & ~1,
(visible_size.height() + 1) & ~1); (visible_size.height() + 1) & ~1);
bool flip_y;
libyuv::RotationMode rotation =
CameraOrientationToLibyuvRotation(orientation_, &flip_y);
gfx::Size output_size = RotateSize(nonrotated_output_size, rotation);
visible_size = RotateSize(visible_size, rotation);
base::TimeTicks reference_time = base::TimeTicks reference_time =
base::TimeTicks::FromZxTime(frame_info.timestamp); base::TimeTicks::FromZxTime(frame_info.timestamp);
base::TimeDelta timestamp = base::TimeDelta timestamp =
...@@ -375,11 +396,36 @@ void VideoCaptureDeviceFuchsia::ProcessNewFrame( ...@@ -375,11 +396,36 @@ void VideoCaptureDeviceFuchsia::ProcessNewFrame(
return; return;
} }
auto src_pixel_format = buffer_reader_->buffer_settings() std::unique_ptr<VideoCaptureBufferHandle> output_handle =
.image_format_constraints.pixel_format.type; buffer.handle_provider->GetHandleForInProcessAccess();
CopyAndConvertFrame(src_span, src_pixel_format, src_stride, src_coded_height,
buffer.handle_provider->GetHandleForInProcessAccess(), // Calculate offsets and strides for the output buffer.
output_size); uint8_t* dst_y = output_handle->data();
int dst_stride_y = output_size.width();
size_t dst_y_plane_size = output_size.width() * output_size.height();
uint8_t* dst_u = dst_y + dst_y_plane_size;
int dst_stride_u = output_size.width() / 2;
uint8_t* dst_v = dst_u + dst_y_plane_size / 4;
int dst_stride_v = output_size.width() / 2;
// Check that the output fits in the buffer.
const uint8_t* dst_end = dst_v + dst_y_plane_size / 4;
CHECK_LE(dst_end, output_handle->data() + output_handle->mapped_size());
// Vertical flip is indicated to ConvertToI420() by negating src_height.
int flipped_src_height = static_cast<int>(src_coded_height);
if (flip_y)
flipped_src_height = -flipped_src_height;
auto four_cc =
GetFourccForPixelFormat(buffer_reader_->buffer_settings()
.image_format_constraints.pixel_format.type);
libyuv::ConvertToI420(src_span.data(), src_span.size(), dst_y, dst_stride_y,
dst_u, dst_stride_u, dst_v, dst_stride_v,
/*crop_x=*/0, /*crop_y=*/0, src_stride,
flipped_src_height, nonrotated_output_size.width(),
nonrotated_output_size.height(), rotation, four_cc);
client_->OnIncomingCapturedBufferExt( client_->OnIncomingCapturedBufferExt(
std::move(buffer), capture_format, gfx::ColorSpace(), reference_time, std::move(buffer), capture_format, gfx::ColorSpace(), reference_time,
......
...@@ -60,6 +60,12 @@ class CAPTURE_EXPORT VideoCaptureDeviceFuchsia : public VideoCaptureDevice { ...@@ -60,6 +60,12 @@ class CAPTURE_EXPORT VideoCaptureDeviceFuchsia : public VideoCaptureDevice {
// Callback for WatchResolution(). // Callback for WatchResolution().
void OnWatchResolutionResult(fuchsia::math::Size frame_size); void OnWatchResolutionResult(fuchsia::math::Size frame_size);
// Watches for orientation updates and updates |orientation_| accordingly.
void WatchOrientation();
// Callback for WatchOrientation().
void OnWatchOrientationResult(fuchsia::camera3::Orientation orientation);
// Watches for sysmem buffer collection updates from the camera. // Watches for sysmem buffer collection updates from the camera.
void WatchBufferCollection(); void WatchBufferCollection();
...@@ -95,6 +101,8 @@ class CAPTURE_EXPORT VideoCaptureDeviceFuchsia : public VideoCaptureDevice { ...@@ -95,6 +101,8 @@ class CAPTURE_EXPORT VideoCaptureDeviceFuchsia : public VideoCaptureDevice {
std::unique_ptr<SysmemBufferReader> buffer_reader_; std::unique_ptr<SysmemBufferReader> buffer_reader_;
base::Optional<gfx::Size> frame_size_; base::Optional<gfx::Size> frame_size_;
fuchsia::camera3::Orientation orientation_ =
fuchsia::camera3::Orientation::UP;
base::TimeTicks start_time_; base::TimeTicks start_time_;
......
...@@ -256,6 +256,37 @@ TEST_F(VideoCaptureDeviceFuchsiaTest, MultipleFrames) { ...@@ -256,6 +256,37 @@ TEST_F(VideoCaptureDeviceFuchsiaTest, MultipleFrames) {
} }
} }
TEST_F(VideoCaptureDeviceFuchsiaTest, FrameRotation) {
const gfx::Size kResolution(4, 2);
fake_stream_.SetFakeResolution(kResolution);
StartCapturer();
EXPECT_TRUE(fake_stream_.WaitBuffersAllocated());
for (int i = static_cast<int>(fuchsia::camera3::Orientation::UP);
i <= static_cast<int>(fuchsia::camera3::Orientation::RIGHT_FLIPPED);
++i) {
SCOPED_TRACE(testing::Message() << "Orientation " << i);
auto orientation = static_cast<fuchsia::camera3::Orientation>(i);
ASSERT_TRUE(fake_stream_.WaitFreeBuffer());
fake_stream_.SetFakeOrientation(orientation);
fake_stream_.ProduceFrame(base::TimeTicks::Now(), i);
client_->WaitFrame();
gfx::Size expected_size = kResolution;
if (orientation == fuchsia::camera3::Orientation::LEFT ||
orientation == fuchsia::camera3::Orientation::LEFT_FLIPPED ||
orientation == fuchsia::camera3::Orientation::RIGHT ||
orientation == fuchsia::camera3::Orientation::RIGHT_FLIPPED) {
expected_size = gfx::Size(expected_size.height(), expected_size.width());
}
ValidateReceivedFrame(client_->received_frames().back(), expected_size, i);
}
}
TEST_F(VideoCaptureDeviceFuchsiaTest, FrameDimensionsNotDivisibleBy2) { TEST_F(VideoCaptureDeviceFuchsiaTest, FrameDimensionsNotDivisibleBy2) {
const gfx::Size kOddResolution(21, 7); const gfx::Size kOddResolution(21, 7);
fake_stream_.SetFakeResolution(kOddResolution); fake_stream_.SetFakeResolution(kOddResolution);
......
...@@ -25,11 +25,62 @@ uint8_t GetTestFrameValue(gfx::Size size, int x, int y, uint8_t salt) { ...@@ -25,11 +25,62 @@ uint8_t GetTestFrameValue(gfx::Size size, int x, int y, uint8_t salt) {
return static_cast<uint8_t>(y + x * size.height() + salt); return static_cast<uint8_t>(y + x * size.height() + salt);
} }
// Fills one plane of a test frame. |data| points at the location of the pixel
// (0, 0). |orientation| specifies frame orientation transformation that will be
// applied on the receiving end, so this function applies _reverse_ of the
// |orientation| transformation.
void FillPlane(uint8_t* data, void FillPlane(uint8_t* data,
gfx::Size size, gfx::Size size,
size_t x_step, int x_step,
size_t y_step, int y_step,
fuchsia::camera3::Orientation orientation,
uint8_t salt) { uint8_t salt) {
// First flip X axis for flipped orientation.
if (orientation == fuchsia::camera3::Orientation::UP_FLIPPED ||
orientation == fuchsia::camera3::Orientation::DOWN_FLIPPED ||
orientation == fuchsia::camera3::Orientation::RIGHT_FLIPPED ||
orientation == fuchsia::camera3::Orientation::LEFT_FLIPPED) {
// Move the origin to the top right corner and flip the X axis.
data += (size.width() - 1) * x_step;
x_step = -x_step;
}
switch (orientation) {
case fuchsia::camera3::Orientation::UP:
case fuchsia::camera3::Orientation::UP_FLIPPED:
break;
case fuchsia::camera3::Orientation::DOWN:
case fuchsia::camera3::Orientation::DOWN_FLIPPED:
// Move |data| to point to the bottom right corner and reverse direction
// of both axes.
data += (size.width() - 1) * x_step + (size.height() - 1) * y_step;
x_step = -x_step;
y_step = -y_step;
break;
case fuchsia::camera3::Orientation::LEFT:
case fuchsia::camera3::Orientation::LEFT_FLIPPED:
// Rotate 90 degrees clockwise by moving |data| to point to the right top
// corner, swapping the axes and reversing direction of the Y axis.
data += (size.width() - 1) * x_step;
size = gfx::Size(size.height(), size.width());
std::swap(x_step, y_step);
y_step = -y_step;
break;
case fuchsia::camera3::Orientation::RIGHT:
case fuchsia::camera3::Orientation::RIGHT_FLIPPED:
// Rotate 90 degrees counter-clockwise by moving |data| to point to the
// bottom left corner, swapping the axes and reversing direction of the X
// axis.
data += (size.height() - 1) * y_step;
size = gfx::Size(size.height(), size.width());
std::swap(x_step, y_step);
x_step = -x_step;
break;
}
for (int y = 0; y < size.height(); ++y) { for (int y = 0; y < size.height(); ++y) {
for (int x = 0; x < size.width(); ++x) { for (int x = 0; x < size.width(); ++x) {
data[x * x_step + y * y_step] = GetTestFrameValue(size, x, y, salt); data[x * x_step + y * y_step] = GetTestFrameValue(size, x, y, salt);
...@@ -111,6 +162,13 @@ void FakeCameraStream::SetFakeResolution(gfx::Size resolution) { ...@@ -111,6 +162,13 @@ void FakeCameraStream::SetFakeResolution(gfx::Size resolution) {
SendResolution(); SendResolution();
} }
void FakeCameraStream::SetFakeOrientation(
fuchsia::camera3::Orientation orientation) {
orientation_ = orientation;
orientation_update_ = orientation;
SendOrientation();
}
bool FakeCameraStream::WaitBuffersAllocated() { bool FakeCameraStream::WaitBuffersAllocated() {
EXPECT_FALSE(wait_buffers_allocated_run_loop_); EXPECT_FALSE(wait_buffers_allocated_run_loop_);
...@@ -158,16 +216,16 @@ void FakeCameraStream::ProduceFrame(base::TimeTicks timestamp, uint8_t salt) { ...@@ -158,16 +216,16 @@ void FakeCameraStream::ProduceFrame(base::TimeTicks timestamp, uint8_t salt) {
// Fill Y plane. // Fill Y plane.
uint8_t* y_plane = reinterpret_cast<uint8_t*>(buffer->mapping.memory()); uint8_t* y_plane = reinterpret_cast<uint8_t*>(buffer->mapping.memory());
size_t stride = kMaxFrameSize.width(); size_t stride = kMaxFrameSize.width();
FillPlane(y_plane, coded_size, /*x_step=*/1, /*y_step=*/stride, FillPlane(y_plane, coded_size, /*x_step=*/1, /*y_step=*/stride, orientation_,
salt + kYPlaneSalt); salt + kYPlaneSalt);
// Fill UV plane. // Fill UV plane.
gfx::Size uv_size(coded_size.width() / 2, coded_size.height() / 2); gfx::Size uv_size(coded_size.width() / 2, coded_size.height() / 2);
uint8_t* uv_plane = y_plane + kMaxFrameSize.width() * kMaxFrameSize.height(); uint8_t* uv_plane = y_plane + kMaxFrameSize.width() * kMaxFrameSize.height();
FillPlane(uv_plane, uv_size, /*x_step=*/2, /*y_step=*/stride, FillPlane(uv_plane, uv_size, /*x_step=*/2, /*y_step=*/stride, orientation_,
salt + kUPlaneSalt); salt + kUPlaneSalt);
FillPlane(uv_plane + 1, uv_size, /*x_step=*/2, /*y_step=*/stride, FillPlane(uv_plane + 1, uv_size, /*x_step=*/2, /*y_step=*/stride,
salt + kVPlaneSalt); orientation_, salt + kVPlaneSalt);
// Create FrameInfo. // Create FrameInfo.
fuchsia::camera3::FrameInfo frame; fuchsia::camera3::FrameInfo frame;
...@@ -194,6 +252,12 @@ void FakeCameraStream::WatchResolution(WatchResolutionCallback callback) { ...@@ -194,6 +252,12 @@ void FakeCameraStream::WatchResolution(WatchResolutionCallback callback) {
SendResolution(); SendResolution();
} }
void FakeCameraStream::WatchOrientation(WatchOrientationCallback callback) {
EXPECT_FALSE(watch_orientation_callback_);
watch_orientation_callback_ = std::move(callback);
SendOrientation();
}
void FakeCameraStream::SetBufferCollection( void FakeCameraStream::SetBufferCollection(
fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken> fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>
token_handle) { token_handle) {
...@@ -327,6 +391,14 @@ void FakeCameraStream::SendResolution() { ...@@ -327,6 +391,14 @@ void FakeCameraStream::SendResolution() {
resolution_update_.reset(); resolution_update_.reset();
} }
void FakeCameraStream::SendOrientation() {
if (!watch_orientation_callback_ || !orientation_update_)
return;
watch_orientation_callback_(orientation_update_.value());
watch_orientation_callback_ = {};
orientation_update_.reset();
}
void FakeCameraStream::SendBufferCollection() { void FakeCameraStream::SendBufferCollection() {
if (!watch_buffer_collection_callback_ || !new_buffer_collection_token_) if (!watch_buffer_collection_callback_ || !new_buffer_collection_token_)
return; return;
......
...@@ -39,6 +39,7 @@ class FakeCameraStream : public fuchsia::camera3::testing::Stream_TestBase, ...@@ -39,6 +39,7 @@ class FakeCameraStream : public fuchsia::camera3::testing::Stream_TestBase,
void Bind(fidl::InterfaceRequest<fuchsia::camera3::Stream> request); void Bind(fidl::InterfaceRequest<fuchsia::camera3::Stream> request);
void SetFakeResolution(gfx::Size resolution); void SetFakeResolution(gfx::Size resolution);
void SetFakeOrientation(fuchsia::camera3::Orientation orientation);
// Waits for the buffer collection to be allocated. Returns true if the buffer // Waits for the buffer collection to be allocated. Returns true if the buffer
// collection was allocated successfully. // collection was allocated successfully.
...@@ -55,6 +56,7 @@ class FakeCameraStream : public fuchsia::camera3::testing::Stream_TestBase, ...@@ -55,6 +56,7 @@ class FakeCameraStream : public fuchsia::camera3::testing::Stream_TestBase,
// fuchsia::camera3::Stream implementation. // fuchsia::camera3::Stream implementation.
void WatchResolution(WatchResolutionCallback callback) final; void WatchResolution(WatchResolutionCallback callback) final;
void WatchOrientation(WatchOrientationCallback callback) final;
void SetBufferCollection( void SetBufferCollection(
fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken> fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>
token_handle) final; token_handle) final;
...@@ -74,6 +76,10 @@ class FakeCameraStream : public fuchsia::camera3::testing::Stream_TestBase, ...@@ -74,6 +76,10 @@ class FakeCameraStream : public fuchsia::camera3::testing::Stream_TestBase,
// resolution has been updated. // resolution has been updated.
void SendResolution(); void SendResolution();
// Calls callback for the pending WatchOrientation() if the call is pending
// and orientation has been updated.
void SendOrientation();
// Calls callback for the pending WatchBufferCollection() if we have a new // Calls callback for the pending WatchBufferCollection() if we have a new
// token and the call is pending. // token and the call is pending.
void SendBufferCollection(); void SendBufferCollection();
...@@ -89,11 +95,17 @@ class FakeCameraStream : public fuchsia::camera3::testing::Stream_TestBase, ...@@ -89,11 +95,17 @@ class FakeCameraStream : public fuchsia::camera3::testing::Stream_TestBase,
fidl::Binding<fuchsia::camera3::Stream> binding_; fidl::Binding<fuchsia::camera3::Stream> binding_;
gfx::Size resolution_ = kDefaultFrameSize; gfx::Size resolution_ = kDefaultFrameSize;
fuchsia::camera3::Orientation orientation_ =
fuchsia::camera3::Orientation::UP;
base::Optional<fuchsia::math::Size> resolution_update_ = fuchsia::math::Size{ base::Optional<fuchsia::math::Size> resolution_update_ = fuchsia::math::Size{
kDefaultFrameSize.width(), kDefaultFrameSize.height()}; kDefaultFrameSize.width(), kDefaultFrameSize.height()};
WatchResolutionCallback watch_resolution_callback_; WatchResolutionCallback watch_resolution_callback_;
base::Optional<fuchsia::camera3::Orientation> orientation_update_ =
fuchsia::camera3::Orientation::UP;
WatchOrientationCallback watch_orientation_callback_;
base::Optional<fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>> base::Optional<fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>>
new_buffer_collection_token_; new_buffer_collection_token_;
WatchBufferCollectionCallback watch_buffer_collection_callback_; WatchBufferCollectionCallback watch_buffer_collection_callback_;
......
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