| 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 "content/browser/renderer_host/media/video_capture_device_client.h" | 5 #include "content/browser/renderer_host/media/video_capture_device_client.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 const media::VideoCaptureFormat kFrameFormat( | 80 const media::VideoCaptureFormat kFrameFormat( |
| 81 gfx::Size(10, 10), 30.0f /*frame_rate*/, | 81 gfx::Size(10, 10), 30.0f /*frame_rate*/, |
| 82 media::PIXEL_FORMAT_I420, | 82 media::PIXEL_FORMAT_I420, |
| 83 media::PIXEL_STORAGE_CPU); | 83 media::PIXEL_STORAGE_CPU); |
| 84 DCHECK(device_client_.get()); | 84 DCHECK(device_client_.get()); |
| 85 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); | 85 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); |
| 86 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) | 86 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) |
| 87 .Times(1); | 87 .Times(1); |
| 88 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, | 88 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, |
| 89 kFrameFormat, 0 /*clockwise rotation*/, | 89 kFrameFormat, 0 /*clockwise rotation*/, |
| 90 base::TimeTicks()); | 90 base::TimeTicks(), base::TimeDelta()); |
| 91 base::RunLoop().RunUntilIdle(); | 91 base::RunLoop().RunUntilIdle(); |
| 92 Mock::VerifyAndClearExpectations(controller_.get()); | 92 Mock::VerifyAndClearExpectations(controller_.get()); |
| 93 } | 93 } |
| 94 | 94 |
| 95 // Tests that we don't try to pass on frames with an invalid frame format. | 95 // Tests that we don't try to pass on frames with an invalid frame format. |
| 96 TEST_F(VideoCaptureDeviceClientTest, FailsSilentlyGivenInvalidFrameFormat) { | 96 TEST_F(VideoCaptureDeviceClientTest, FailsSilentlyGivenInvalidFrameFormat) { |
| 97 const size_t kScratchpadSizeInBytes = 400; | 97 const size_t kScratchpadSizeInBytes = 400; |
| 98 unsigned char data[kScratchpadSizeInBytes] = {}; | 98 unsigned char data[kScratchpadSizeInBytes] = {}; |
| 99 // kFrameFormat is invalid in a number of ways. | 99 // kFrameFormat is invalid in a number of ways. |
| 100 const media::VideoCaptureFormat kFrameFormat( | 100 const media::VideoCaptureFormat kFrameFormat( |
| 101 gfx::Size(media::limits::kMaxDimension + 1, media::limits::kMaxDimension), | 101 gfx::Size(media::limits::kMaxDimension + 1, media::limits::kMaxDimension), |
| 102 media::limits::kMaxFramesPerSecond + 1, | 102 media::limits::kMaxFramesPerSecond + 1, |
| 103 media::VideoPixelFormat::PIXEL_FORMAT_I420, | 103 media::VideoPixelFormat::PIXEL_FORMAT_I420, |
| 104 media::VideoPixelStorage::PIXEL_STORAGE_CPU); | 104 media::VideoPixelStorage::PIXEL_STORAGE_CPU); |
| 105 DCHECK(device_client_.get()); | 105 DCHECK(device_client_.get()); |
| 106 // Expect the the call to fail silently inside the VideoCaptureDeviceClient. | 106 // Expect the the call to fail silently inside the VideoCaptureDeviceClient. |
| 107 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); | 107 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); |
| 108 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) | 108 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) |
| 109 .Times(0); | 109 .Times(0); |
| 110 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, | 110 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, |
| 111 kFrameFormat, 0 /*clockwise rotation*/, | 111 kFrameFormat, 0 /*clockwise rotation*/, |
| 112 base::TimeTicks()); | 112 base::TimeTicks(), base::TimeDelta()); |
| 113 base::RunLoop().RunUntilIdle(); | 113 base::RunLoop().RunUntilIdle(); |
| 114 Mock::VerifyAndClearExpectations(controller_.get()); | 114 Mock::VerifyAndClearExpectations(controller_.get()); |
| 115 } | 115 } |
| 116 | 116 |
| 117 // Tests that we fail silently if no available buffers to use. | 117 // Tests that we fail silently if no available buffers to use. |
| 118 TEST_F(VideoCaptureDeviceClientTest, DropsFrameIfNoBuffer) { | 118 TEST_F(VideoCaptureDeviceClientTest, DropsFrameIfNoBuffer) { |
| 119 const size_t kScratchpadSizeInBytes = 400; | 119 const size_t kScratchpadSizeInBytes = 400; |
| 120 unsigned char data[kScratchpadSizeInBytes] = {}; | 120 unsigned char data[kScratchpadSizeInBytes] = {}; |
| 121 const media::VideoCaptureFormat kFrameFormat( | 121 const media::VideoCaptureFormat kFrameFormat( |
| 122 gfx::Size(10, 10), 30.0f /*frame_rate*/, | 122 gfx::Size(10, 10), 30.0f /*frame_rate*/, |
| 123 media::PIXEL_FORMAT_I420, | 123 media::PIXEL_FORMAT_I420, |
| 124 media::PIXEL_STORAGE_CPU); | 124 media::PIXEL_STORAGE_CPU); |
| 125 // We expect the second frame to be silently dropped, so these should | 125 // We expect the second frame to be silently dropped, so these should |
| 126 // only be called once despite the two frames. | 126 // only be called once despite the two frames. |
| 127 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); | 127 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); |
| 128 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) | 128 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) |
| 129 .Times(1); | 129 .Times(1); |
| 130 // Pass two frames. The second will be dropped. | 130 // Pass two frames. The second will be dropped. |
| 131 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, | 131 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, |
| 132 kFrameFormat, 0 /*clockwise rotation*/, | 132 kFrameFormat, 0 /*clockwise rotation*/, |
| 133 base::TimeTicks()); | 133 base::TimeTicks(), base::TimeDelta()); |
| 134 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, | 134 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, |
| 135 kFrameFormat, 0 /*clockwise rotation*/, | 135 kFrameFormat, 0 /*clockwise rotation*/, |
| 136 base::TimeTicks()); | 136 base::TimeTicks(), base::TimeDelta()); |
| 137 base::RunLoop().RunUntilIdle(); | 137 base::RunLoop().RunUntilIdle(); |
| 138 Mock::VerifyAndClearExpectations(controller_.get()); | 138 Mock::VerifyAndClearExpectations(controller_.get()); |
| 139 } | 139 } |
| 140 | 140 |
| 141 // Tests that buffer-based capture API accepts some memory-backed pixel formats. | 141 // Tests that buffer-based capture API accepts some memory-backed pixel formats. |
| 142 TEST_F(VideoCaptureDeviceClientTest, DataCaptureGoodPixelFormats) { | 142 TEST_F(VideoCaptureDeviceClientTest, DataCaptureGoodPixelFormats) { |
| 143 // The usual ReserveOutputBuffer() -> OnIncomingCapturedVideoFrame() cannot | 143 // The usual ReserveOutputBuffer() -> OnIncomingCapturedVideoFrame() cannot |
| 144 // be used since it does not accept all pixel formats. The memory backed | 144 // be used since it does not accept all pixel formats. The memory backed |
| 145 // buffer OnIncomingCapturedData() is used instead, with a dummy scratchpad | 145 // buffer OnIncomingCapturedData() is used instead, with a dummy scratchpad |
| 146 // buffer. | 146 // buffer. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 171 }; | 171 }; |
| 172 | 172 |
| 173 for (media::VideoPixelFormat format : kSupportedFormats) { | 173 for (media::VideoPixelFormat format : kSupportedFormats) { |
| 174 params.requested_format.pixel_format = format; | 174 params.requested_format.pixel_format = format; |
| 175 | 175 |
| 176 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); | 176 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); |
| 177 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) | 177 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) |
| 178 .Times(1); | 178 .Times(1); |
| 179 device_client_->OnIncomingCapturedData( | 179 device_client_->OnIncomingCapturedData( |
| 180 data, params.requested_format.ImageAllocationSize(), | 180 data, params.requested_format.ImageAllocationSize(), |
| 181 params.requested_format, 0 /* clockwise_rotation */, base::TimeTicks()); | 181 params.requested_format, 0 /* clockwise_rotation */, base::TimeTicks(), |
| 182 base::TimeDelta()); |
| 182 base::RunLoop().RunUntilIdle(); | 183 base::RunLoop().RunUntilIdle(); |
| 183 Mock::VerifyAndClearExpectations(controller_.get()); | 184 Mock::VerifyAndClearExpectations(controller_.get()); |
| 184 } | 185 } |
| 185 } | 186 } |
| 186 | 187 |
| 187 // Test that we receive the expected resolution for a given captured frame | 188 // Test that we receive the expected resolution for a given captured frame |
| 188 // resolution and rotation. Odd resolutions are also cropped. | 189 // resolution and rotation. Odd resolutions are also cropped. |
| 189 TEST_F(VideoCaptureDeviceClientTest, CheckRotationsAndCrops) { | 190 TEST_F(VideoCaptureDeviceClientTest, CheckRotationsAndCrops) { |
| 190 const struct SizeAndRotation { | 191 const struct SizeAndRotation { |
| 191 gfx::Size input_resolution; | 192 gfx::Size input_resolution; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 216 << "Scratchpad is too small to hold the largest pixel format (ARGB)."; | 217 << "Scratchpad is too small to hold the largest pixel format (ARGB)."; |
| 217 params.requested_format = | 218 params.requested_format = |
| 218 media::VideoCaptureFormat(size_and_rotation.input_resolution, 30.0f, | 219 media::VideoCaptureFormat(size_and_rotation.input_resolution, 30.0f, |
| 219 media::PIXEL_FORMAT_ARGB); | 220 media::PIXEL_FORMAT_ARGB); |
| 220 gfx::Size coded_size; | 221 gfx::Size coded_size; |
| 221 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) | 222 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) |
| 222 .Times(1) | 223 .Times(1) |
| 223 .WillOnce(SaveArg<0>(&coded_size)); | 224 .WillOnce(SaveArg<0>(&coded_size)); |
| 224 device_client_->OnIncomingCapturedData( | 225 device_client_->OnIncomingCapturedData( |
| 225 data, params.requested_format.ImageAllocationSize(), | 226 data, params.requested_format.ImageAllocationSize(), |
| 226 params.requested_format, size_and_rotation.rotation, base::TimeTicks()); | 227 params.requested_format, size_and_rotation.rotation, base::TimeTicks(), |
| 228 base::TimeDelta()); |
| 227 base::RunLoop().RunUntilIdle(); | 229 base::RunLoop().RunUntilIdle(); |
| 228 | 230 |
| 229 EXPECT_EQ(coded_size.width(), size_and_rotation.output_resolution.width()); | 231 EXPECT_EQ(coded_size.width(), size_and_rotation.output_resolution.width()); |
| 230 EXPECT_EQ(coded_size.height(), | 232 EXPECT_EQ(coded_size.height(), |
| 231 size_and_rotation.output_resolution.height()); | 233 size_and_rotation.output_resolution.height()); |
| 232 | 234 |
| 233 Mock::VerifyAndClearExpectations(controller_.get()); | 235 Mock::VerifyAndClearExpectations(controller_.get()); |
| 234 } | 236 } |
| 235 } | 237 } |
| 236 | 238 |
| 237 } // namespace content | 239 } // namespace content |
| OLD | NEW |