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 "media/base/android/sdk_media_codec_bridge.h" | |
6 | |
7 #include <stddef.h> | 5 #include <stddef.h> |
8 #include <stdint.h> | 6 #include <stdint.h> |
9 | 7 |
10 #include <memory> | 8 #include <memory> |
11 #include <string> | 9 #include <string> |
12 | 10 |
13 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "media/base/android/media_codec_bridge_impl.h" |
14 #include "media/base/android/media_codec_util.h" | 13 #include "media/base/android/media_codec_util.h" |
15 #include "media/base/decoder_buffer.h" | 14 #include "media/base/decoder_buffer.h" |
16 #include "media/base/test_data_util.h" | 15 #include "media/base/test_data_util.h" |
17 #include "testing/gmock/include/gmock/gmock.h" | 16 #include "testing/gmock/include/gmock/gmock.h" |
18 | 17 |
19 namespace { | 18 namespace { |
20 | 19 |
21 // The first frame of | 20 // The first frame of |
22 // http://www.html5rocks.com/en/tutorials/audio/quick/test.mp3 | 21 // http://www.html5rocks.com/en/tutorials/audio/quick/test.mp3 |
23 unsigned char test_mp3[] = { | 22 unsigned char test_mp3[] = { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 0x4c, 0x22, 0x17, 0xc5, 0x25, 0x23, 0xed, 0x78, 0xf5, 0x41, 0xd1, 0xe9, | 89 0x4c, 0x22, 0x17, 0xc5, 0x25, 0x23, 0xed, 0x78, 0xf5, 0x41, 0xd1, 0xe9, |
91 0x8a, 0xb3, 0x52, 0xd1, 0x3d, 0x79, 0x81, 0x4d, 0x31, 0x24, 0xf9, 0x38, | 90 0x8a, 0xb3, 0x52, 0xd1, 0x3d, 0x79, 0x81, 0x4d, 0x31, 0x24, 0xf9, 0x38, |
92 0x96, 0xbc, 0xf4, 0x8c, 0x25, 0xe9, 0xf2, 0x73, 0x94, 0x85, 0xc2, 0x61, | 91 0x96, 0xbc, 0xf4, 0x8c, 0x25, 0xe9, 0xf2, 0x73, 0x94, 0x85, 0xc2, 0x61, |
93 0x6a, 0x34, 0x68, 0x65, 0x78, 0x87, 0xa6, 0x4f}; | 92 0x6a, 0x34, 0x68, 0x65, 0x78, 0x87, 0xa6, 0x4f}; |
94 static const size_t kDecodedAudioLengthInBytes = 9216u; | 93 static const size_t kDecodedAudioLengthInBytes = 9216u; |
95 | 94 |
96 } // namespace | 95 } // namespace |
97 | 96 |
98 namespace media { | 97 namespace media { |
99 | 98 |
100 // Helper macro to skip the test if MediaCodecBridge isn't available. | 99 #define SKIP_TEST_IF_MEDIA_CODEC_IS_NOT_AVAILABLE() \ |
101 #define SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE() \ | |
102 do { \ | 100 do { \ |
103 if (!MediaCodecUtil::IsMediaCodecAvailable()) { \ | 101 if (!MediaCodecUtil::IsMediaCodecAvailable()) { \ |
104 VLOG(0) << "Could not run test - not supported on device."; \ | 102 VLOG(0) << "Could not run test - not supported on device."; \ |
105 return; \ | 103 return; \ |
106 } \ | 104 } \ |
107 } while (0) | 105 } while (0) |
108 | 106 |
109 static const int kPresentationTimeBase = 100; | 107 static const int kPresentationTimeBase = 100; |
110 static const int kMaxInputPts = kPresentationTimeBase + 2; | 108 static const int kMaxInputPts = kPresentationTimeBase + 2; |
111 | 109 |
(...skipping 29 matching lines...) Expand all Loading... |
141 if (status == MEDIA_CODEC_OK && output_buf_index > 0) { | 139 if (status == MEDIA_CODEC_OK && output_buf_index > 0) { |
142 media_codec->ReleaseOutputBuffer(output_buf_index, false); | 140 media_codec->ReleaseOutputBuffer(output_buf_index, false); |
143 } | 141 } |
144 // Output time stamp should not be smaller than old timestamp. | 142 // Output time stamp should not be smaller than old timestamp. |
145 ASSERT_TRUE(new_timestamp >= timestamp); | 143 ASSERT_TRUE(new_timestamp >= timestamp); |
146 input_pts += base::TimeDelta::FromMicroseconds(33000); | 144 input_pts += base::TimeDelta::FromMicroseconds(33000); |
147 timestamp = new_timestamp; | 145 timestamp = new_timestamp; |
148 } | 146 } |
149 } | 147 } |
150 | 148 |
151 TEST(SdkMediaCodecBridgeTest, Initialize) { | 149 TEST(MediaCodecBridgeTest, Initialize) { |
152 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | 150 SKIP_TEST_IF_MEDIA_CODEC_IS_NOT_AVAILABLE(); |
153 | 151 |
154 std::unique_ptr<media::MediaCodecBridge> media_codec; | 152 std::unique_ptr<media::MediaCodecBridge> media_codec; |
155 media_codec.reset(VideoCodecBridge::CreateDecoder( | 153 media_codec.reset(VideoCodecBridge::CreateDecoder( |
156 kCodecH264, false, gfx::Size(640, 480), nullptr, nullptr, | 154 kCodecH264, false, gfx::Size(640, 480), nullptr, nullptr, |
157 std::vector<uint8_t>(), std::vector<uint8_t>())); | 155 std::vector<uint8_t>(), std::vector<uint8_t>())); |
158 } | 156 } |
159 | 157 |
160 TEST(SdkMediaCodecBridgeTest, DoNormal) { | 158 TEST(MediaCodecBridgeTest, DoNormal) { |
161 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | 159 SKIP_TEST_IF_MEDIA_CODEC_IS_NOT_AVAILABLE(); |
162 | 160 |
163 std::unique_ptr<media::AudioCodecBridge> media_codec; | 161 std::unique_ptr<media::AudioCodecBridge> media_codec; |
164 media_codec.reset(AudioCodecBridge::Create(kCodecMP3)); | 162 media_codec.reset(AudioCodecBridge::Create(kCodecMP3)); |
165 | 163 |
166 ASSERT_TRUE(media_codec->ConfigureAndStart(kCodecMP3, 44100, 2, nullptr, 0, 0, | 164 ASSERT_TRUE(media_codec->ConfigureAndStart(kCodecMP3, 44100, 2, nullptr, 0, 0, |
167 0, nullptr)); | 165 0, nullptr)); |
168 | 166 |
169 int input_buf_index = -1; | 167 int input_buf_index = -1; |
170 MediaCodecStatus status = | 168 MediaCodecStatus status = |
171 media_codec->DequeueInputBuffer(InfiniteTimeOut(), &input_buf_index); | 169 media_codec->DequeueInputBuffer(InfiniteTimeOut(), &input_buf_index); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 break; | 207 break; |
210 } | 208 } |
211 ASSERT_GE(output_buf_index, 0); | 209 ASSERT_GE(output_buf_index, 0); |
212 EXPECT_LE(1u, size); | 210 EXPECT_LE(1u, size); |
213 total_size += size; | 211 total_size += size; |
214 } | 212 } |
215 EXPECT_EQ(kDecodedAudioLengthInBytes, total_size); | 213 EXPECT_EQ(kDecodedAudioLengthInBytes, total_size); |
216 ASSERT_LE(input_pts, kMaxInputPts); | 214 ASSERT_LE(input_pts, kMaxInputPts); |
217 } | 215 } |
218 | 216 |
219 TEST(SdkMediaCodecBridgeTest, InvalidVorbisHeader) { | 217 TEST(MediaCodecBridgeTest, InvalidVorbisHeader) { |
220 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | 218 SKIP_TEST_IF_MEDIA_CODEC_IS_NOT_AVAILABLE(); |
221 | 219 |
222 std::unique_ptr<media::AudioCodecBridge> media_codec; | 220 std::unique_ptr<media::AudioCodecBridge> media_codec; |
223 media_codec.reset(AudioCodecBridge::Create(kCodecVorbis)); | 221 media_codec.reset(AudioCodecBridge::Create(kCodecVorbis)); |
224 | 222 |
225 // The first byte of the header is not 0x02. | 223 // The first byte of the header is not 0x02. |
226 uint8_t invalid_first_byte[] = {0x00, 0xff, 0xff, 0xff, 0xff}; | 224 uint8_t invalid_first_byte[] = {0x00, 0xff, 0xff, 0xff, 0xff}; |
227 EXPECT_FALSE(media_codec->ConfigureAndStart( | 225 EXPECT_FALSE(media_codec->ConfigureAndStart( |
228 kCodecVorbis, 44100, 2, invalid_first_byte, sizeof(invalid_first_byte), 0, | 226 kCodecVorbis, 44100, 2, invalid_first_byte, sizeof(invalid_first_byte), 0, |
229 0, nullptr)); | 227 0, nullptr)); |
230 | 228 |
231 // Size of the header does not match with the data we passed in. | 229 // Size of the header does not match with the data we passed in. |
232 uint8_t invalid_size[] = {0x02, 0x01, 0xff, 0x01, 0xff}; | 230 uint8_t invalid_size[] = {0x02, 0x01, 0xff, 0x01, 0xff}; |
233 EXPECT_FALSE( | 231 EXPECT_FALSE( |
234 media_codec->ConfigureAndStart(kCodecVorbis, 44100, 2, invalid_size, | 232 media_codec->ConfigureAndStart(kCodecVorbis, 44100, 2, invalid_size, |
235 sizeof(invalid_size), 0, 0, nullptr)); | 233 sizeof(invalid_size), 0, 0, nullptr)); |
236 | 234 |
237 // Size of the header is too large. | 235 // Size of the header is too large. |
238 size_t large_size = 8 * 1024 * 1024 + 2; | 236 size_t large_size = 8 * 1024 * 1024 + 2; |
239 uint8_t* very_large_header = new uint8_t[large_size]; | 237 uint8_t* very_large_header = new uint8_t[large_size]; |
240 very_large_header[0] = 0x02; | 238 very_large_header[0] = 0x02; |
241 for (size_t i = 1; i < large_size - 1; ++i) | 239 for (size_t i = 1; i < large_size - 1; ++i) |
242 very_large_header[i] = 0xff; | 240 very_large_header[i] = 0xff; |
243 very_large_header[large_size - 1] = 0xfe; | 241 very_large_header[large_size - 1] = 0xfe; |
244 EXPECT_FALSE(media_codec->ConfigureAndStart( | 242 EXPECT_FALSE(media_codec->ConfigureAndStart( |
245 kCodecVorbis, 44100, 2, very_large_header, 0x80000000, 0, 0, nullptr)); | 243 kCodecVorbis, 44100, 2, very_large_header, 0x80000000, 0, 0, nullptr)); |
246 delete[] very_large_header; | 244 delete[] very_large_header; |
247 } | 245 } |
248 | 246 |
249 TEST(SdkMediaCodecBridgeTest, InvalidOpusHeader) { | 247 TEST(MediaCodecBridgeTest, InvalidOpusHeader) { |
250 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | 248 SKIP_TEST_IF_MEDIA_CODEC_IS_NOT_AVAILABLE(); |
251 | 249 |
252 std::unique_ptr<media::AudioCodecBridge> media_codec; | 250 std::unique_ptr<media::AudioCodecBridge> media_codec; |
253 media_codec.reset(AudioCodecBridge::Create(kCodecOpus)); | 251 media_codec.reset(AudioCodecBridge::Create(kCodecOpus)); |
254 if (!media_codec) | 252 if (!media_codec) |
255 return; | 253 return; |
256 | 254 |
257 uint8_t dummy_extra_data[] = {0, 0}; | 255 uint8_t dummy_extra_data[] = {0, 0}; |
258 | 256 |
259 // Extra Data is NULL. | 257 // Extra Data is NULL. |
260 EXPECT_FALSE(media_codec->ConfigureAndStart(kCodecOpus, 48000, 2, nullptr, 0, | 258 EXPECT_FALSE(media_codec->ConfigureAndStart(kCodecOpus, 48000, 2, nullptr, 0, |
261 -1, 0, nullptr)); | 259 -1, 0, nullptr)); |
262 | 260 |
263 // Codec Delay is < 0. | 261 // Codec Delay is < 0. |
264 EXPECT_FALSE( | 262 EXPECT_FALSE( |
265 media_codec->ConfigureAndStart(kCodecOpus, 48000, 2, dummy_extra_data, | 263 media_codec->ConfigureAndStart(kCodecOpus, 48000, 2, dummy_extra_data, |
266 sizeof(dummy_extra_data), -1, 0, nullptr)); | 264 sizeof(dummy_extra_data), -1, 0, nullptr)); |
267 | 265 |
268 // Seek Preroll is < 0. | 266 // Seek Preroll is < 0. |
269 EXPECT_FALSE( | 267 EXPECT_FALSE( |
270 media_codec->ConfigureAndStart(kCodecOpus, 48000, 2, dummy_extra_data, | 268 media_codec->ConfigureAndStart(kCodecOpus, 48000, 2, dummy_extra_data, |
271 sizeof(dummy_extra_data), 0, -1, nullptr)); | 269 sizeof(dummy_extra_data), 0, -1, nullptr)); |
272 } | 270 } |
273 | 271 |
274 TEST(SdkMediaCodecBridgeTest, PresentationTimestampsDoNotDecrease) { | 272 TEST(MediaCodecBridgeTest, PresentationTimestampsDoNotDecrease) { |
275 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED(); | 273 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED(); |
276 | 274 |
277 std::unique_ptr<VideoCodecBridge> media_codec(VideoCodecBridge::CreateDecoder( | 275 std::unique_ptr<VideoCodecBridge> media_codec(VideoCodecBridge::CreateDecoder( |
278 kCodecVP8, false, gfx::Size(320, 240), nullptr, nullptr, | 276 kCodecVP8, false, gfx::Size(320, 240), nullptr, nullptr, |
279 std::vector<uint8_t>(), std::vector<uint8_t>())); | 277 std::vector<uint8_t>(), std::vector<uint8_t>())); |
280 EXPECT_TRUE(media_codec.get()); | 278 EXPECT_TRUE(media_codec.get()); |
281 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("vp8-I-frame-320x240"); | 279 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("vp8-I-frame-320x240"); |
282 DecodeMediaFrame(media_codec.get(), buffer->data(), buffer->data_size(), | 280 DecodeMediaFrame(media_codec.get(), buffer->data(), buffer->data_size(), |
283 base::TimeDelta(), base::TimeDelta()); | 281 base::TimeDelta(), base::TimeDelta()); |
284 | 282 |
285 // Simulate a seek to 10 seconds, and each chunk has 2 I-frames. | 283 // Simulate a seek to 10 seconds, and each chunk has 2 I-frames. |
286 std::vector<uint8_t> chunk(buffer->data(), | 284 std::vector<uint8_t> chunk(buffer->data(), |
287 buffer->data() + buffer->data_size()); | 285 buffer->data() + buffer->data_size()); |
288 chunk.insert(chunk.end(), buffer->data(), | 286 chunk.insert(chunk.end(), buffer->data(), |
289 buffer->data() + buffer->data_size()); | 287 buffer->data() + buffer->data_size()); |
290 media_codec->Flush(); | 288 media_codec->Flush(); |
291 DecodeMediaFrame(media_codec.get(), &chunk[0], chunk.size(), | 289 DecodeMediaFrame(media_codec.get(), &chunk[0], chunk.size(), |
292 base::TimeDelta::FromMicroseconds(10000000), | 290 base::TimeDelta::FromMicroseconds(10000000), |
293 base::TimeDelta::FromMicroseconds(9900000)); | 291 base::TimeDelta::FromMicroseconds(9900000)); |
294 | 292 |
295 // Simulate a seek to 5 seconds. | 293 // Simulate a seek to 5 seconds. |
296 media_codec->Flush(); | 294 media_codec->Flush(); |
297 DecodeMediaFrame(media_codec.get(), &chunk[0], chunk.size(), | 295 DecodeMediaFrame(media_codec.get(), &chunk[0], chunk.size(), |
298 base::TimeDelta::FromMicroseconds(5000000), | 296 base::TimeDelta::FromMicroseconds(5000000), |
299 base::TimeDelta::FromMicroseconds(4900000)); | 297 base::TimeDelta::FromMicroseconds(4900000)); |
300 } | 298 } |
301 | 299 |
302 TEST(SdkMediaCodecBridgeTest, CreateUnsupportedCodec) { | 300 TEST(MediaCodecBridgeTest, CreateUnsupportedCodec) { |
303 EXPECT_EQ(nullptr, AudioCodecBridge::Create(kUnknownAudioCodec)); | 301 EXPECT_EQ(nullptr, AudioCodecBridge::Create(kUnknownAudioCodec)); |
304 EXPECT_EQ(nullptr, | 302 EXPECT_EQ(nullptr, |
305 VideoCodecBridge::CreateDecoder( | 303 VideoCodecBridge::CreateDecoder( |
306 kUnknownVideoCodec, false, gfx::Size(320, 240), nullptr, | 304 kUnknownVideoCodec, false, gfx::Size(320, 240), nullptr, |
307 nullptr, std::vector<uint8_t>(), std::vector<uint8_t>())); | 305 nullptr, std::vector<uint8_t>(), std::vector<uint8_t>())); |
308 } | 306 } |
309 | 307 |
310 } // namespace media | 308 } // namespace media |
OLD | NEW |