| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stddef.h> | 5 #include <stddef.h> |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" |
| 8 #include "base/macros.h" | 9 #include "base/macros.h" |
| 9 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
| 11 #include "base/single_thread_task_runner.h" | 12 #include "base/single_thread_task_runner.h" |
| 12 #include "base/thread_task_runner_handle.h" | 13 #include "base/thread_task_runner_handle.h" |
| 13 #include "build/build_config.h" | 14 #include "build/build_config.h" |
| 14 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h" | 15 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h" |
| 15 #include "content/browser/renderer_host/media/video_capture_controller.h" | 16 #include "content/browser/renderer_host/media/video_capture_controller.h" |
| 16 #include "content/browser/renderer_host/media/video_capture_device_client.h" | 17 #include "content/browser/renderer_host/media/video_capture_device_client.h" |
| 17 #include "content/public/test/test_browser_thread_bundle.h" | 18 #include "content/public/test/test_browser_thread_bundle.h" |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 // A small test for reference and to verify VideoCaptureDeviceClient is | 73 // A small test for reference and to verify VideoCaptureDeviceClient is |
| 73 // minimally functional. | 74 // minimally functional. |
| 74 TEST_F(VideoCaptureDeviceClientTest, Minimal) { | 75 TEST_F(VideoCaptureDeviceClientTest, Minimal) { |
| 75 const size_t kScratchpadSizeInBytes = 400; | 76 const size_t kScratchpadSizeInBytes = 400; |
| 76 unsigned char data[kScratchpadSizeInBytes] = {}; | 77 unsigned char data[kScratchpadSizeInBytes] = {}; |
| 77 const media::VideoCaptureFormat kFrameFormat( | 78 const media::VideoCaptureFormat kFrameFormat( |
| 78 gfx::Size(10, 10), 30.0f /*frame_rate*/, | 79 gfx::Size(10, 10), 30.0f /*frame_rate*/, |
| 79 media::PIXEL_FORMAT_I420, | 80 media::PIXEL_FORMAT_I420, |
| 80 media::PIXEL_STORAGE_CPU); | 81 media::PIXEL_STORAGE_CPU); |
| 81 DCHECK(device_client_.get()); | 82 DCHECK(device_client_.get()); |
| 83 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); |
| 82 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) | 84 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) |
| 83 .Times(1); | 85 .Times(1); |
| 84 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, | 86 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, |
| 85 kFrameFormat, 0 /*clockwise rotation*/, | 87 kFrameFormat, 0 /*clockwise rotation*/, |
| 86 base::TimeTicks()); | 88 base::TimeTicks()); |
| 87 base::RunLoop().RunUntilIdle(); | 89 base::RunLoop().RunUntilIdle(); |
| 88 Mock::VerifyAndClearExpectations(controller_.get()); | 90 Mock::VerifyAndClearExpectations(controller_.get()); |
| 89 } | 91 } |
| 90 | 92 |
| 91 // Tests that we don't try to pass on frames with an invalid frame format. | 93 // Tests that we don't try to pass on frames with an invalid frame format. |
| 92 TEST_F(VideoCaptureDeviceClientTest, FailsSilentlyGivenInvalidFrameFormat) { | 94 TEST_F(VideoCaptureDeviceClientTest, FailsSilentlyGivenInvalidFrameFormat) { |
| 93 const size_t kScratchpadSizeInBytes = 400; | 95 const size_t kScratchpadSizeInBytes = 400; |
| 94 unsigned char data[kScratchpadSizeInBytes] = {}; | 96 unsigned char data[kScratchpadSizeInBytes] = {}; |
| 95 // kFrameFormat is invalid in a number of ways. | 97 // kFrameFormat is invalid in a number of ways. |
| 96 const media::VideoCaptureFormat kFrameFormat( | 98 const media::VideoCaptureFormat kFrameFormat( |
| 97 gfx::Size(media::limits::kMaxDimension + 1, media::limits::kMaxDimension), | 99 gfx::Size(media::limits::kMaxDimension + 1, media::limits::kMaxDimension), |
| 98 media::limits::kMaxFramesPerSecond + 1, | 100 media::limits::kMaxFramesPerSecond + 1, |
| 99 media::VideoPixelFormat::PIXEL_FORMAT_I420, | 101 media::VideoPixelFormat::PIXEL_FORMAT_I420, |
| 100 media::VideoPixelStorage::PIXEL_STORAGE_CPU); | 102 media::VideoPixelStorage::PIXEL_STORAGE_CPU); |
| 101 DCHECK(device_client_.get()); | 103 DCHECK(device_client_.get()); |
| 102 // Expect the the call to fail silently inside the VideoCaptureDeviceClient. | 104 // Expect the the call to fail silently inside the VideoCaptureDeviceClient. |
| 105 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); |
| 103 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) | 106 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) |
| 104 .Times(0); | 107 .Times(0); |
| 105 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, | 108 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, |
| 106 kFrameFormat, 0 /*clockwise rotation*/, | 109 kFrameFormat, 0 /*clockwise rotation*/, |
| 107 base::TimeTicks()); | 110 base::TimeTicks()); |
| 108 base::RunLoop().RunUntilIdle(); | 111 base::RunLoop().RunUntilIdle(); |
| 109 Mock::VerifyAndClearExpectations(controller_.get()); | 112 Mock::VerifyAndClearExpectations(controller_.get()); |
| 110 } | 113 } |
| 111 | 114 |
| 112 // Tests that we fail silently if no available buffers to use. | 115 // Tests that we fail silently if no available buffers to use. |
| 113 TEST_F(VideoCaptureDeviceClientTest, DropsFrameIfNoBuffer) { | 116 TEST_F(VideoCaptureDeviceClientTest, DropsFrameIfNoBuffer) { |
| 114 const size_t kScratchpadSizeInBytes = 400; | 117 const size_t kScratchpadSizeInBytes = 400; |
| 115 unsigned char data[kScratchpadSizeInBytes] = {}; | 118 unsigned char data[kScratchpadSizeInBytes] = {}; |
| 116 const media::VideoCaptureFormat kFrameFormat( | 119 const media::VideoCaptureFormat kFrameFormat( |
| 117 gfx::Size(10, 10), 30.0f /*frame_rate*/, | 120 gfx::Size(10, 10), 30.0f /*frame_rate*/, |
| 118 media::PIXEL_FORMAT_I420, | 121 media::PIXEL_FORMAT_I420, |
| 119 media::PIXEL_STORAGE_CPU); | 122 media::PIXEL_STORAGE_CPU); |
| 120 // We expect the second frame to be silently dropped, so these should | 123 // We expect the second frame to be silently dropped, so these should |
| 121 // only be called once despite the two frames. | 124 // only be called once despite the two frames. |
| 125 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); |
| 122 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) | 126 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) |
| 123 .Times(1); | 127 .Times(1); |
| 124 // Pass two frames. The second will be dropped. | 128 // Pass two frames. The second will be dropped. |
| 125 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, | 129 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, |
| 126 kFrameFormat, 0 /*clockwise rotation*/, | 130 kFrameFormat, 0 /*clockwise rotation*/, |
| 127 base::TimeTicks()); | 131 base::TimeTicks()); |
| 128 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, | 132 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, |
| 129 kFrameFormat, 0 /*clockwise rotation*/, | 133 kFrameFormat, 0 /*clockwise rotation*/, |
| 130 base::TimeTicks()); | 134 base::TimeTicks()); |
| 131 base::RunLoop().RunUntilIdle(); | 135 base::RunLoop().RunUntilIdle(); |
| 132 Mock::VerifyAndClearExpectations(controller_.get()); | 136 Mock::VerifyAndClearExpectations(controller_.get()); |
| 133 } | 137 } |
| 134 | 138 |
| 135 // Tests that buffer-based capture API accepts all memory-backed pixel formats. | 139 // Tests that buffer-based capture API accepts some memory-backed pixel formats. |
| 136 TEST_F(VideoCaptureDeviceClientTest, DataCaptureInEachVideoFormatInSequence) { | 140 TEST_F(VideoCaptureDeviceClientTest, DataCaptureGoodPixelFormats) { |
| 137 // The usual ReserveOutputBuffer() -> OnIncomingCapturedVideoFrame() cannot | 141 // The usual ReserveOutputBuffer() -> OnIncomingCapturedVideoFrame() cannot |
| 138 // be used since it does not accept all pixel formats. The memory backed | 142 // be used since it does not accept all pixel formats. The memory backed |
| 139 // buffer OnIncomingCapturedData() is used instead, with a dummy scratchpad | 143 // buffer OnIncomingCapturedData() is used instead, with a dummy scratchpad |
| 140 // buffer. | 144 // buffer. |
| 141 const size_t kScratchpadSizeInBytes = 400; | 145 const size_t kScratchpadSizeInBytes = 400; |
| 142 unsigned char data[kScratchpadSizeInBytes] = {}; | 146 unsigned char data[kScratchpadSizeInBytes] = {}; |
| 143 const gfx::Size capture_resolution(10, 10); | 147 const gfx::Size kCaptureResolution(10, 10); |
| 144 ASSERT_GE(kScratchpadSizeInBytes, capture_resolution.GetArea() * 4u) | 148 ASSERT_GE(kScratchpadSizeInBytes, kCaptureResolution.GetArea() * 4u) |
| 145 << "Scratchpad is too small to hold the largest pixel format (ARGB)."; | 149 << "Scratchpad is too small to hold the largest pixel format (ARGB)."; |
| 146 | 150 |
| 147 for (int format = 0; format < media::PIXEL_FORMAT_MAX; | 151 media::VideoCaptureParams params; |
| 148 ++format) { | 152 params.requested_format = media::VideoCaptureFormat( |
| 149 // Conversion from some formats are unsupported. | 153 kCaptureResolution, 30.0f, media::PIXEL_FORMAT_UNKNOWN); |
| 150 if (format == media::PIXEL_FORMAT_UNKNOWN || | 154 |
| 151 format == media::PIXEL_FORMAT_YV16 || | 155 // Only use the VideoPixelFormats that we know supported. Do not add |
| 152 format == media::PIXEL_FORMAT_YV12A || | 156 // PIXEL_FORMAT_MJPEG since it would need a real JPEG header. |
| 153 format == media::PIXEL_FORMAT_YV24 || | 157 const media::VideoPixelFormat kSupportedFormats[] = { |
| 154 format == media::PIXEL_FORMAT_ARGB || | 158 media::PIXEL_FORMAT_I420, |
| 155 format == media::PIXEL_FORMAT_XRGB || | 159 media::PIXEL_FORMAT_YV12, |
| 156 format == media::PIXEL_FORMAT_MJPEG || | 160 media::PIXEL_FORMAT_NV12, |
| 157 format == media::PIXEL_FORMAT_MT21 || | 161 media::PIXEL_FORMAT_NV21, |
| 158 format == media::PIXEL_FORMAT_YUV420P9 || | 162 media::PIXEL_FORMAT_YUY2, |
| 159 format == media::PIXEL_FORMAT_YUV420P10 || | 163 media::PIXEL_FORMAT_UYVY, |
| 160 format == media::PIXEL_FORMAT_YUV422P9 || | 164 #if defined(OS_WIN) || defined(OS_LINUX) |
| 161 format == media::PIXEL_FORMAT_YUV422P10 || | 165 media::PIXEL_FORMAT_RGB24, |
| 162 format == media::PIXEL_FORMAT_YUV444P9 || | |
| 163 format == media::PIXEL_FORMAT_YUV444P10) { | |
| 164 continue; | |
| 165 } | |
| 166 #if !defined(OS_LINUX) && !defined(OS_WIN) | |
| 167 if (format == media::PIXEL_FORMAT_RGB24) { | |
| 168 continue; | |
| 169 } | |
| 170 #endif | 166 #endif |
| 171 media::VideoCaptureParams params; | 167 media::PIXEL_FORMAT_RGB32, |
| 172 params.requested_format = media::VideoCaptureFormat( | 168 media::PIXEL_FORMAT_ARGB |
| 173 capture_resolution, 30.0f, media::VideoPixelFormat(format)); | 169 }; |
| 170 |
| 171 for (media::VideoPixelFormat format : kSupportedFormats) { |
| 172 params.requested_format.pixel_format = format; |
| 173 |
| 174 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); |
| 174 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) | 175 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) |
| 175 .Times(1); | 176 .Times(1); |
| 176 device_client_->OnIncomingCapturedData( | 177 device_client_->OnIncomingCapturedData( |
| 177 data, params.requested_format.ImageAllocationSize(), | 178 data, params.requested_format.ImageAllocationSize(), |
| 178 params.requested_format, 0 /* clockwise_rotation */, base::TimeTicks()); | 179 params.requested_format, 0 /* clockwise_rotation */, base::TimeTicks()); |
| 179 base::RunLoop().RunUntilIdle(); | 180 base::RunLoop().RunUntilIdle(); |
| 180 Mock::VerifyAndClearExpectations(controller_.get()); | 181 Mock::VerifyAndClearExpectations(controller_.get()); |
| 181 } | 182 } |
| 182 } | 183 } |
| 183 | 184 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 197 {{7, 4}, 180, {6, 4}}, | 198 {{7, 4}, 180, {6, 4}}, |
| 198 {{7, 4}, 270, {4, 6}}}; | 199 {{7, 4}, 270, {4, 6}}}; |
| 199 | 200 |
| 200 // The usual ReserveOutputBuffer() -> OnIncomingCapturedVideoFrame() cannot | 201 // The usual ReserveOutputBuffer() -> OnIncomingCapturedVideoFrame() cannot |
| 201 // be used since it does not resolve rotations or crops. The memory backed | 202 // be used since it does not resolve rotations or crops. The memory backed |
| 202 // buffer OnIncomingCapturedData() is used instead, with a dummy scratchpad | 203 // buffer OnIncomingCapturedData() is used instead, with a dummy scratchpad |
| 203 // buffer. | 204 // buffer. |
| 204 const size_t kScratchpadSizeInBytes = 400; | 205 const size_t kScratchpadSizeInBytes = 400; |
| 205 unsigned char data[kScratchpadSizeInBytes] = {}; | 206 unsigned char data[kScratchpadSizeInBytes] = {}; |
| 206 | 207 |
| 208 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); |
| 209 |
| 207 media::VideoCaptureParams params; | 210 media::VideoCaptureParams params; |
| 208 for (const auto& size_and_rotation : kSizeAndRotations) { | 211 for (const auto& size_and_rotation : kSizeAndRotations) { |
| 209 ASSERT_GE(kScratchpadSizeInBytes, | 212 ASSERT_GE(kScratchpadSizeInBytes, |
| 210 size_and_rotation.input_resolution.GetArea() * 4u) | 213 size_and_rotation.input_resolution.GetArea() * 4u) |
| 211 << "Scratchpad is too small to hold the largest pixel format (ARGB)."; | 214 << "Scratchpad is too small to hold the largest pixel format (ARGB)."; |
| 212 params.requested_format = | 215 params.requested_format = |
| 213 media::VideoCaptureFormat(size_and_rotation.input_resolution, 30.0f, | 216 media::VideoCaptureFormat(size_and_rotation.input_resolution, 30.0f, |
| 214 media::PIXEL_FORMAT_ARGB); | 217 media::PIXEL_FORMAT_ARGB); |
| 215 gfx::Size coded_size; | 218 gfx::Size coded_size; |
| 216 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) | 219 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) |
| 217 .Times(1) | 220 .Times(1) |
| 218 .WillOnce(SaveArg<0>(&coded_size)); | 221 .WillOnce(SaveArg<0>(&coded_size)); |
| 219 device_client_->OnIncomingCapturedData( | 222 device_client_->OnIncomingCapturedData( |
| 220 data, params.requested_format.ImageAllocationSize(), | 223 data, params.requested_format.ImageAllocationSize(), |
| 221 params.requested_format, size_and_rotation.rotation, base::TimeTicks()); | 224 params.requested_format, size_and_rotation.rotation, base::TimeTicks()); |
| 222 base::RunLoop().RunUntilIdle(); | 225 base::RunLoop().RunUntilIdle(); |
| 223 | 226 |
| 224 EXPECT_EQ(coded_size.width(), size_and_rotation.output_resolution.width()); | 227 EXPECT_EQ(coded_size.width(), size_and_rotation.output_resolution.width()); |
| 225 EXPECT_EQ(coded_size.height(), | 228 EXPECT_EQ(coded_size.height(), |
| 226 size_and_rotation.output_resolution.height()); | 229 size_and_rotation.output_resolution.height()); |
| 227 | 230 |
| 228 Mock::VerifyAndClearExpectations(controller_.get()); | 231 Mock::VerifyAndClearExpectations(controller_.get()); |
| 229 } | 232 } |
| 230 } | 233 } |
| 231 | 234 |
| 232 } // namespace content | 235 } // namespace content |
| OLD | NEW |