Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "media/capture/video/chromeos/stream_buffer_manager.h" | |
| 6 | |
| 7 #include "base/run_loop.h" | |
| 8 #include "base/test/scoped_task_environment.h" | |
| 9 #include "base/threading/thread.h" | |
| 10 #include "base/threading/thread_task_runner_handle.h" | |
| 11 #include "media/capture/video/chromeos/camera_device_context.h" | |
| 12 #include "media/capture/video/chromeos/camera_device_delegate.h" | |
| 13 #include "media/capture/video/chromeos/mock_video_capture_client.h" | |
| 14 #include "media/capture/video/chromeos/mojo/arc_camera3.mojom.h" | |
| 15 #include "testing/gmock/include/gmock/gmock.h" | |
| 16 #include "testing/gtest/include/gtest/gtest.h" | |
| 17 | |
| 18 using testing::_; | |
| 19 using testing::A; | |
| 20 using testing::AtLeast; | |
| 21 using testing::Invoke; | |
| 22 using testing::InvokeWithoutArgs; | |
| 23 | |
| 24 namespace media { | |
| 25 | |
| 26 namespace { | |
| 27 | |
| 28 class MockStreamCaptureInterface : public StreamCaptureInterface { | |
| 29 public: | |
| 30 void RegisterBuffer(uint64_t buffer_id, | |
| 31 arc::mojom::Camera3DeviceOps::BufferType type, | |
| 32 std::vector<mojo::ScopedHandle> fds, | |
| 33 uint32_t drm_format, | |
| 34 arc::mojom::HalPixelFormat hal_pixel_format, | |
| 35 uint32_t width, | |
| 36 uint32_t height, | |
| 37 std::vector<uint32_t> strides, | |
| 38 std::vector<uint32_t> offsets, | |
| 39 base::OnceCallback<void(int32_t)> callback) { | |
| 40 DoRegisterBuffer(buffer_id, type, fds, drm_format, hal_pixel_format, width, | |
| 41 height, strides, offsets, callback); | |
| 42 } | |
| 43 MOCK_METHOD10(DoRegisterBuffer, | |
| 44 void(uint64_t buffer_id, | |
| 45 arc::mojom::Camera3DeviceOps::BufferType type, | |
| 46 std::vector<mojo::ScopedHandle>& fds, | |
| 47 uint32_t drm_format, | |
| 48 arc::mojom::HalPixelFormat hal_pixel_format, | |
| 49 uint32_t width, | |
| 50 uint32_t height, | |
| 51 const std::vector<uint32_t>& strides, | |
| 52 const std::vector<uint32_t>& offsets, | |
| 53 base::OnceCallback<void(int32_t)>& callback)); | |
| 54 | |
| 55 void ProcessCaptureRequest(arc::mojom::Camera3CaptureRequestPtr request, | |
| 56 base::OnceCallback<void(int32_t)> callback) { | |
| 57 DoProcessCaptureRequest(request, callback); | |
| 58 } | |
| 59 MOCK_METHOD2(DoProcessCaptureRequest, | |
| 60 void(arc::mojom::Camera3CaptureRequestPtr& request, | |
| 61 base::OnceCallback<void(int32_t)>& callback)); | |
| 62 }; | |
| 63 | |
| 64 const VideoCaptureFormat kDefaultCaptureFormat(gfx::Size(1280, 720), | |
| 65 30.0, | |
| 66 PIXEL_FORMAT_NV12); | |
| 67 | |
| 68 } // namespace | |
| 69 | |
| 70 class StreamBufferManagerTest : public ::testing::Test { | |
| 71 public: | |
| 72 void SetUp() override { | |
| 73 quit_ = false; | |
| 74 arc::mojom::Camera3CallbackOpsRequest callback_ops_request = | |
| 75 mojo::MakeRequest(&mock_callback_ops_); | |
| 76 std::unique_ptr<VideoCaptureDevice::Client> mock_client( | |
| 77 new unittest_internal::MockVideoCaptureClient()); | |
| 78 device_context_.reset(new CameraDeviceContext(std::move(mock_client))); | |
|
chfremer
2017/06/08 21:58:38
nit: Not sure what the style guide says here, but
jcliang
2017/06/09 05:16:01
Done.
| |
| 79 | |
| 80 stream_buffer_manager_ = new StreamBufferManager( | |
| 81 std::move(callback_ops_request), | |
| 82 std::unique_ptr<StreamCaptureInterface>( | |
| 83 new MockStreamCaptureInterface()), | |
|
chfremer
2017/06/08 21:58:38
base::MakeUnique<>
jcliang
2017/06/09 05:16:01
Done.
| |
| 84 device_context_.get(), base::ThreadTaskRunnerHandle::Get()); | |
| 85 } | |
| 86 | |
| 87 void TearDown() override { | |
| 88 while (!stream_buffer_manager_->HasOneRef()) { | |
| 89 base::PlatformThread::YieldCurrentThread(); | |
| 90 } | |
|
chfremer
2017/06/08 21:58:38
I still don't think that this is a clean solution.
jcliang
2017/06/09 05:16:01
This pattern in the unit test is mainly to make su
chfremer
2017/06/09 17:53:18
Wouldn't it be possible to add a method to StreamB
| |
| 91 stream_buffer_manager_ = nullptr; | |
| 92 } | |
| 93 | |
| 94 void DoLoop() { | |
| 95 run_loop_.reset(new base::RunLoop()); | |
| 96 run_loop_->Run(); | |
| 97 } | |
| 98 | |
| 99 void QuitCaptureLoop() { | |
| 100 quit_ = true; | |
| 101 if (run_loop_) { | |
| 102 run_loop_->Quit(); | |
| 103 } | |
| 104 } | |
| 105 | |
| 106 void RegisterBuffer(uint64_t buffer_id, | |
| 107 arc::mojom::Camera3DeviceOps::BufferType type, | |
| 108 std::vector<mojo::ScopedHandle>& fds, | |
| 109 uint32_t drm_format, | |
| 110 arc::mojom::HalPixelFormat hal_pixel_format, | |
| 111 uint32_t width, | |
| 112 uint32_t height, | |
| 113 const std::vector<uint32_t>& strides, | |
| 114 const std::vector<uint32_t>& offsets, | |
| 115 base::OnceCallback<void(int32_t)>& callback) { | |
| 116 if (quit_) { | |
| 117 return; | |
| 118 } | |
| 119 std::move(callback).Run(0); | |
| 120 } | |
| 121 | |
| 122 void ProcessCaptureRequest(arc::mojom::Camera3CaptureRequestPtr& request, | |
| 123 base::OnceCallback<void(int32_t)>& callback) { | |
| 124 if (quit_) { | |
| 125 return; | |
| 126 } | |
| 127 std::move(callback).Run(0); | |
| 128 mock_callback_ops_->Notify(PrepareShutterNotifyMessage( | |
| 129 request->frame_number, base::TimeTicks::Now().ToInternalValue())); | |
| 130 mock_callback_ops_->ProcessCaptureResult(PrepareCapturedResult( | |
| 131 request->frame_number, arc::mojom::CameraMetadata::New(), 1, | |
| 132 std::move(request->output_buffers))); | |
| 133 } | |
| 134 | |
| 135 MockStreamCaptureInterface* GetMockCaptureInterface() { | |
| 136 EXPECT_NE(nullptr, stream_buffer_manager_.get()); | |
| 137 return reinterpret_cast<MockStreamCaptureInterface*>( | |
| 138 stream_buffer_manager_->capture_interface_.get()); | |
| 139 } | |
| 140 | |
| 141 unittest_internal::MockVideoCaptureClient* GetMockVideoCaptureClient() { | |
| 142 EXPECT_NE(nullptr, device_context_); | |
| 143 return reinterpret_cast<unittest_internal::MockVideoCaptureClient*>( | |
| 144 device_context_->client_.get()); | |
| 145 } | |
| 146 | |
| 147 std::map<uint32_t, StreamBufferManager::CaptureResult>& GetPartialResults() { | |
| 148 EXPECT_NE(nullptr, stream_buffer_manager_.get()); | |
| 149 return stream_buffer_manager_->partial_results_; | |
| 150 } | |
| 151 | |
| 152 arc::mojom::Camera3StreamPtr PrepareCaptureStream(uint32_t max_buffers) { | |
| 153 auto stream = arc::mojom::Camera3Stream::New(); | |
| 154 stream->id = 0; | |
| 155 stream->stream_type = arc::mojom::Camera3StreamType::CAMERA3_STREAM_OUTPUT; | |
| 156 stream->width = kDefaultCaptureFormat.frame_size.width(); | |
| 157 stream->height = kDefaultCaptureFormat.frame_size.height(); | |
| 158 stream->format = arc::mojom::HalPixelFormat::HAL_PIXEL_FORMAT_YCbCr_420_888; | |
| 159 stream->usage = 0; | |
| 160 stream->max_buffers = max_buffers; | |
| 161 stream->data_space = 0; | |
| 162 stream->rotation = | |
| 163 arc::mojom::Camera3StreamRotation::CAMERA3_STREAM_ROTATION_0; | |
| 164 return stream; | |
| 165 } | |
| 166 | |
| 167 arc::mojom::Camera3NotifyMsgPtr PrepareErrorNotifyMessage( | |
| 168 uint32_t frame_number, | |
| 169 arc::mojom::Camera3ErrorMsgCode error_code) { | |
| 170 auto error_msg = arc::mojom::Camera3ErrorMsg::New(); | |
| 171 error_msg->frame_number = frame_number; | |
| 172 // There is only the preview stream. | |
| 173 error_msg->error_stream_id = 1; | |
| 174 error_msg->error_code = error_code; | |
| 175 auto notify_msg = arc::mojom::Camera3NotifyMsg::New(); | |
| 176 notify_msg->message = arc::mojom::Camera3NotifyMsgMessage::New(); | |
| 177 notify_msg->type = arc::mojom::Camera3MsgType::CAMERA3_MSG_ERROR; | |
| 178 notify_msg->message->set_error(std::move(error_msg)); | |
| 179 return notify_msg; | |
| 180 } | |
| 181 | |
| 182 arc::mojom::Camera3NotifyMsgPtr PrepareShutterNotifyMessage( | |
| 183 uint32_t frame_number, | |
| 184 uint64_t timestamp) { | |
| 185 auto shutter_msg = arc::mojom::Camera3ShutterMsg::New(); | |
| 186 shutter_msg->frame_number = frame_number; | |
| 187 shutter_msg->timestamp = timestamp; | |
| 188 auto notify_msg = arc::mojom::Camera3NotifyMsg::New(); | |
| 189 notify_msg->message = arc::mojom::Camera3NotifyMsgMessage::New(); | |
| 190 notify_msg->type = arc::mojom::Camera3MsgType::CAMERA3_MSG_SHUTTER; | |
| 191 notify_msg->message->set_shutter(std::move(shutter_msg)); | |
| 192 return notify_msg; | |
| 193 } | |
| 194 | |
| 195 arc::mojom::Camera3CaptureResultPtr PrepareCapturedResult( | |
| 196 uint32_t frame_number, | |
| 197 arc::mojom::CameraMetadataPtr result_metadata, | |
| 198 uint32_t partial_result, | |
| 199 std::vector<arc::mojom::Camera3StreamBufferPtr> output_buffers) { | |
| 200 auto result = arc::mojom::Camera3CaptureResult::New(); | |
| 201 result->frame_number = frame_number; | |
| 202 result->result = std::move(result_metadata); | |
| 203 if (output_buffers.size()) { | |
| 204 result->output_buffers = std::move(output_buffers); | |
| 205 } | |
| 206 result->partial_result = partial_result; | |
| 207 return result; | |
| 208 } | |
| 209 | |
| 210 protected: | |
| 211 scoped_refptr<StreamBufferManager> stream_buffer_manager_; | |
| 212 arc::mojom::Camera3CallbackOpsPtr mock_callback_ops_; | |
| 213 std::unique_ptr<CameraDeviceContext> device_context_; | |
| 214 arc::mojom::Camera3StreamPtr stream; | |
| 215 | |
| 216 private: | |
| 217 std::unique_ptr<base::RunLoop> run_loop_; | |
| 218 bool quit_; | |
| 219 base::test::ScopedTaskEnvironment scoped_test_environment_; | |
| 220 }; | |
| 221 | |
| 222 // A basic sanity test to capture one frame with the capture loop. | |
| 223 TEST_F(StreamBufferManagerTest, SimpleCaptureTest) { | |
| 224 GetMockVideoCaptureClient()->SetFrameCb(base::BindOnce( | |
| 225 &StreamBufferManagerTest::QuitCaptureLoop, base::Unretained(this))); | |
| 226 EXPECT_CALL(*GetMockCaptureInterface(), | |
| 227 DoRegisterBuffer(0, arc::mojom::Camera3DeviceOps::BufferType::SHM, | |
| 228 _, _, _, _, _, _, _, _)) | |
| 229 .Times(AtLeast(1)) | |
| 230 .WillOnce(Invoke(this, &StreamBufferManagerTest::RegisterBuffer)); | |
| 231 EXPECT_CALL(*GetMockCaptureInterface(), DoProcessCaptureRequest(_, _)) | |
| 232 .Times(1) | |
| 233 .WillOnce(Invoke(this, &StreamBufferManagerTest::ProcessCaptureRequest)); | |
| 234 | |
| 235 stream_buffer_manager_->SetUpStreamAndBuffers( | |
| 236 kDefaultCaptureFormat, /* partial_result_count */ 1, | |
| 237 PrepareCaptureStream(/* max_buffers */ 1)); | |
| 238 stream_buffer_manager_->StartCapture(arc::mojom::CameraMetadata::New()); | |
| 239 | |
| 240 // Wait until a captured frame is received by MockVideoCaptureClient. | |
| 241 DoLoop(); | |
| 242 } | |
| 243 | |
| 244 // Test that the StreamBufferManager submits a captured result only after all | |
| 245 // partial metadata are received. | |
| 246 TEST_F(StreamBufferManagerTest, PartialResultTest) { | |
| 247 GetMockVideoCaptureClient()->SetFrameCb(base::BindOnce( | |
| 248 [](StreamBufferManagerTest* test) { | |
| 249 EXPECT_EQ(1u, test->GetPartialResults().size()); | |
| 250 // Make sure all the three partial metadata are received before the | |
| 251 // captured result is submitted. | |
| 252 EXPECT_EQ( | |
| 253 3u, test->GetPartialResults()[0].partial_metadata_received.size()); | |
| 254 test->QuitCaptureLoop(); | |
| 255 }, | |
| 256 base::Unretained(this))); | |
| 257 EXPECT_CALL(*GetMockCaptureInterface(), | |
| 258 DoRegisterBuffer(0, arc::mojom::Camera3DeviceOps::BufferType::SHM, | |
| 259 _, _, _, _, _, _, _, _)) | |
| 260 .Times(AtLeast(1)) | |
| 261 .WillOnce(Invoke(this, &StreamBufferManagerTest::RegisterBuffer)); | |
| 262 EXPECT_CALL(*GetMockCaptureInterface(), DoProcessCaptureRequest(_, _)) | |
| 263 .Times(1) | |
| 264 .WillOnce(Invoke([this](arc::mojom::Camera3CaptureRequestPtr& request, | |
| 265 base::OnceCallback<void(int32_t)>& callback) { | |
| 266 std::move(callback).Run(0); | |
| 267 mock_callback_ops_->Notify(PrepareShutterNotifyMessage( | |
| 268 request->frame_number, base::TimeTicks::Now().ToInternalValue())); | |
| 269 mock_callback_ops_->ProcessCaptureResult(PrepareCapturedResult( | |
| 270 request->frame_number, arc::mojom::CameraMetadata::New(), 1, | |
| 271 std::move(request->output_buffers))); | |
| 272 | |
| 273 mock_callback_ops_->ProcessCaptureResult(PrepareCapturedResult( | |
| 274 request->frame_number, arc::mojom::CameraMetadata::New(), 2, | |
| 275 std::vector<arc::mojom::Camera3StreamBufferPtr>())); | |
| 276 | |
| 277 mock_callback_ops_->ProcessCaptureResult(PrepareCapturedResult( | |
| 278 request->frame_number, arc::mojom::CameraMetadata::New(), 3, | |
| 279 std::vector<arc::mojom::Camera3StreamBufferPtr>())); | |
| 280 })); | |
| 281 | |
| 282 stream_buffer_manager_->SetUpStreamAndBuffers( | |
| 283 kDefaultCaptureFormat, /* partial_result_count */ 3, | |
| 284 PrepareCaptureStream(/* max_buffers */ 1)); | |
| 285 stream_buffer_manager_->StartCapture(arc::mojom::CameraMetadata::New()); | |
| 286 | |
| 287 // Wait until a captured frame is received by MockVideoCaptureClient. | |
| 288 DoLoop(); | |
| 289 } | |
| 290 | |
| 291 // Test that the capture loop is stopped and no frame is submitted when a device | |
| 292 // error happens. | |
| 293 TEST_F(StreamBufferManagerTest, DeviceErrorTest) { | |
| 294 GetMockVideoCaptureClient()->SetFrameCb(base::BindOnce( | |
| 295 [](StreamBufferManagerTest* test) { | |
| 296 ADD_FAILURE() << "No frame should be submitted"; | |
| 297 test->QuitCaptureLoop(); | |
| 298 }, | |
| 299 base::Unretained(this))); | |
| 300 EXPECT_CALL(*GetMockVideoCaptureClient(), OnError(_, _)) | |
| 301 .Times(1) | |
| 302 .WillOnce( | |
| 303 InvokeWithoutArgs(this, &StreamBufferManagerTest::QuitCaptureLoop)); | |
| 304 EXPECT_CALL(*GetMockCaptureInterface(), | |
| 305 DoRegisterBuffer(0, arc::mojom::Camera3DeviceOps::BufferType::SHM, | |
| 306 _, _, _, _, _, _, _, _)) | |
| 307 .Times(1) | |
| 308 .WillOnce(Invoke(this, &StreamBufferManagerTest::RegisterBuffer)); | |
| 309 EXPECT_CALL(*GetMockCaptureInterface(), DoProcessCaptureRequest(_, _)) | |
| 310 .Times(1) | |
| 311 .WillOnce(Invoke([this](arc::mojom::Camera3CaptureRequestPtr& request, | |
| 312 base::OnceCallback<void(int32_t)>& callback) { | |
| 313 std::move(callback).Run(0); | |
| 314 mock_callback_ops_->Notify(PrepareErrorNotifyMessage( | |
| 315 request->frame_number, | |
| 316 arc::mojom::Camera3ErrorMsgCode::CAMERA3_MSG_ERROR_DEVICE)); | |
|
chfremer
2017/06/08 21:58:38
Out of curiosity, does the order of running |callb
jcliang
2017/06/09 05:16:01
It shouldn't matter in this case. I believe device
| |
| 317 })); | |
| 318 | |
| 319 stream_buffer_manager_->SetUpStreamAndBuffers( | |
| 320 kDefaultCaptureFormat, /* partial_result_count */ 1, | |
| 321 PrepareCaptureStream(/* max_buffers */ 1)); | |
| 322 stream_buffer_manager_->StartCapture(arc::mojom::CameraMetadata::New()); | |
| 323 | |
| 324 // Wait until the MockVideoCaptureClient is deleted. | |
| 325 DoLoop(); | |
| 326 } | |
| 327 | |
| 328 // Test that upon request error the erroneous frame is dropped, and the capture | |
| 329 // loop continues. | |
| 330 TEST_F(StreamBufferManagerTest, RequestErrorTest) { | |
| 331 GetMockVideoCaptureClient()->SetFrameCb(base::BindOnce( | |
| 332 [](StreamBufferManagerTest* test) { | |
| 333 // Frame 0 should be dropped, and the frame callback should be called | |
| 334 // with frame 1. | |
| 335 EXPECT_EQ(test->GetPartialResults().end(), | |
| 336 test->GetPartialResults().find(0)); | |
| 337 EXPECT_NE(test->GetPartialResults().end(), | |
| 338 test->GetPartialResults().find(1)); | |
| 339 test->QuitCaptureLoop(); | |
| 340 }, | |
| 341 base::Unretained(this))); | |
| 342 EXPECT_CALL(*GetMockCaptureInterface(), | |
| 343 DoRegisterBuffer(0, arc::mojom::Camera3DeviceOps::BufferType::SHM, | |
| 344 _, _, _, _, _, _, _, _)) | |
| 345 .Times(AtLeast(2)) | |
| 346 .WillOnce(Invoke(this, &StreamBufferManagerTest::RegisterBuffer)) | |
| 347 .WillOnce(Invoke(this, &StreamBufferManagerTest::RegisterBuffer)); | |
| 348 EXPECT_CALL(*GetMockCaptureInterface(), DoProcessCaptureRequest(_, _)) | |
| 349 .Times(2) | |
| 350 .WillOnce(Invoke([this](arc::mojom::Camera3CaptureRequestPtr& request, | |
| 351 base::OnceCallback<void(int32_t)>& callback) { | |
| 352 std::move(callback).Run(0); | |
| 353 mock_callback_ops_->Notify(PrepareErrorNotifyMessage( | |
| 354 request->frame_number, | |
| 355 arc::mojom::Camera3ErrorMsgCode::CAMERA3_MSG_ERROR_REQUEST)); | |
| 356 request->output_buffers[0]->status = | |
| 357 arc::mojom::Camera3BufferStatus::CAMERA3_BUFFER_STATUS_ERROR; | |
| 358 mock_callback_ops_->ProcessCaptureResult(PrepareCapturedResult( | |
| 359 request->frame_number, arc::mojom::CameraMetadata::New(), 1, | |
| 360 std::move(request->output_buffers))); | |
| 361 })) | |
| 362 .WillOnce(Invoke(this, &StreamBufferManagerTest::ProcessCaptureRequest)); | |
| 363 | |
| 364 stream_buffer_manager_->SetUpStreamAndBuffers( | |
| 365 kDefaultCaptureFormat, /* partial_result_count */ 1, | |
| 366 PrepareCaptureStream(/* max_buffers */ 1)); | |
| 367 stream_buffer_manager_->StartCapture(arc::mojom::CameraMetadata::New()); | |
| 368 | |
| 369 // Wait until the MockVideoCaptureClient is deleted. | |
| 370 DoLoop(); | |
| 371 } | |
| 372 | |
| 373 // Test that upon result error the captured buffer is submitted despite of the | |
| 374 // missing result metadata, and the capture loop continues. | |
| 375 TEST_F(StreamBufferManagerTest, ResultErrorTest) { | |
| 376 GetMockVideoCaptureClient()->SetFrameCb(base::BindOnce( | |
| 377 [](StreamBufferManagerTest* test) { | |
| 378 // Frame 0 should be submitted. | |
| 379 EXPECT_NE(test->GetPartialResults().end(), | |
| 380 test->GetPartialResults().find(0)); | |
| 381 test->QuitCaptureLoop(); | |
| 382 }, | |
| 383 base::Unretained(this))); | |
| 384 EXPECT_CALL(*GetMockCaptureInterface(), | |
| 385 DoRegisterBuffer(0, arc::mojom::Camera3DeviceOps::BufferType::SHM, | |
| 386 _, _, _, _, _, _, _, _)) | |
| 387 .Times(AtLeast(1)) | |
| 388 .WillOnce(Invoke(this, &StreamBufferManagerTest::RegisterBuffer)); | |
| 389 EXPECT_CALL(*GetMockCaptureInterface(), DoProcessCaptureRequest(_, _)) | |
| 390 .Times(1) | |
| 391 .WillOnce(Invoke([this](arc::mojom::Camera3CaptureRequestPtr& request, | |
| 392 base::OnceCallback<void(int32_t)>& callback) { | |
| 393 std::move(callback).Run(0); | |
| 394 mock_callback_ops_->Notify(PrepareShutterNotifyMessage( | |
| 395 request->frame_number, base::TimeTicks::Now().ToInternalValue())); | |
| 396 mock_callback_ops_->ProcessCaptureResult(PrepareCapturedResult( | |
| 397 request->frame_number, arc::mojom::CameraMetadata::New(), 1, | |
| 398 std::move(request->output_buffers))); | |
| 399 // Send a result error notify without sending the second partial result. | |
| 400 // StreamBufferManager should submit the buffer when it receives the | |
| 401 // result error. | |
| 402 mock_callback_ops_->Notify(PrepareErrorNotifyMessage( | |
| 403 request->frame_number, | |
| 404 arc::mojom::Camera3ErrorMsgCode::CAMERA3_MSG_ERROR_RESULT)); | |
| 405 })) | |
| 406 .WillOnce(Invoke(this, &StreamBufferManagerTest::ProcessCaptureRequest)); | |
| 407 | |
| 408 stream_buffer_manager_->SetUpStreamAndBuffers( | |
| 409 kDefaultCaptureFormat, /* partial_result_count */ 2, | |
| 410 PrepareCaptureStream(/* max_buffers */ 1)); | |
| 411 stream_buffer_manager_->StartCapture(arc::mojom::CameraMetadata::New()); | |
| 412 | |
| 413 // Wait until the MockVideoCaptureClient is deleted. | |
| 414 DoLoop(); | |
| 415 } | |
| 416 | |
| 417 // Test that upon buffer error the erroneous buffer is dropped, and the capture | |
| 418 // loop continues. | |
| 419 TEST_F(StreamBufferManagerTest, BufferErrorTest) { | |
| 420 GetMockVideoCaptureClient()->SetFrameCb(base::BindOnce( | |
| 421 [](StreamBufferManagerTest* test) { | |
| 422 // Frame 0 should be dropped, and the frame callback should be called | |
| 423 // with frame 1. | |
| 424 EXPECT_EQ(test->GetPartialResults().end(), | |
| 425 test->GetPartialResults().find(0)); | |
| 426 EXPECT_NE(test->GetPartialResults().end(), | |
| 427 test->GetPartialResults().find(1)); | |
| 428 test->QuitCaptureLoop(); | |
| 429 }, | |
| 430 base::Unretained(this))); | |
| 431 EXPECT_CALL(*GetMockCaptureInterface(), | |
| 432 DoRegisterBuffer(0, arc::mojom::Camera3DeviceOps::BufferType::SHM, | |
| 433 _, _, _, _, _, _, _, _)) | |
| 434 .Times(AtLeast(2)) | |
| 435 .WillOnce(Invoke(this, &StreamBufferManagerTest::RegisterBuffer)) | |
| 436 .WillOnce(Invoke(this, &StreamBufferManagerTest::RegisterBuffer)); | |
| 437 EXPECT_CALL(*GetMockCaptureInterface(), DoProcessCaptureRequest(_, _)) | |
| 438 .Times(2) | |
| 439 .WillOnce(Invoke([this](arc::mojom::Camera3CaptureRequestPtr& request, | |
| 440 base::OnceCallback<void(int32_t)>& callback) { | |
| 441 std::move(callback).Run(0); | |
| 442 mock_callback_ops_->Notify(PrepareShutterNotifyMessage( | |
| 443 request->frame_number, base::TimeTicks::Now().ToInternalValue())); | |
| 444 mock_callback_ops_->Notify(PrepareErrorNotifyMessage( | |
| 445 request->frame_number, | |
| 446 arc::mojom::Camera3ErrorMsgCode::CAMERA3_MSG_ERROR_BUFFER)); | |
| 447 request->output_buffers[0]->status = | |
| 448 arc::mojom::Camera3BufferStatus::CAMERA3_BUFFER_STATUS_ERROR; | |
| 449 mock_callback_ops_->ProcessCaptureResult(PrepareCapturedResult( | |
| 450 request->frame_number, arc::mojom::CameraMetadata::New(), 1, | |
| 451 std::move(request->output_buffers))); | |
| 452 })) | |
| 453 .WillOnce(Invoke(this, &StreamBufferManagerTest::ProcessCaptureRequest)); | |
| 454 | |
| 455 stream_buffer_manager_->SetUpStreamAndBuffers( | |
| 456 kDefaultCaptureFormat, /* partial_result_count */ 1, | |
| 457 PrepareCaptureStream(/* max_buffers */ 1)); | |
| 458 stream_buffer_manager_->StartCapture(arc::mojom::CameraMetadata::New()); | |
| 459 | |
| 460 // Wait until the MockVideoCaptureClient is deleted. | |
| 461 DoLoop(); | |
| 462 } | |
| 463 | |
| 464 } // namespace media | |
| OLD | NEW |