Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(272)

Side by Side Diff: media/filters/audio_decoder_unittest.cc

Issue 1740313002: Added unit test from MediaCodecPlayerAndroid (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@spitzer-aad-test
Patch Set: Skipped tests if MediaCodec is needed but not available on device Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/filters/android/media_codec_audio_decoder.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 #include <stdint.h> 6 #include <stdint.h>
7 7
8 #include <deque>
9 #include <vector> 8 #include <vector>
10 9
11 #include "base/bind.h" 10 #include "base/bind.h"
12 #include "base/format_macros.h" 11 #include "base/format_macros.h"
13 #include "base/macros.h" 12 #include "base/macros.h"
14 #include "base/md5.h" 13 #include "base/md5.h"
15 #include "base/message_loop/message_loop.h" 14 #include "base/message_loop/message_loop.h"
16 #include "base/run_loop.h" 15 #include "base/run_loop.h"
17 #include "base/strings/stringprintf.h" 16 #include "base/strings/stringprintf.h"
18 #include "base/sys_byteorder.h" 17 #include "base/sys_byteorder.h"
18 #include "base/threading/platform_thread.h"
19 #include "build/build_config.h" 19 #include "build/build_config.h"
20 #include "media/base/audio_buffer.h" 20 #include "media/base/audio_buffer.h"
21 #include "media/base/audio_bus.h" 21 #include "media/base/audio_bus.h"
22 #include "media/base/audio_hash.h" 22 #include "media/base/audio_hash.h"
23 #include "media/base/decoder_buffer.h" 23 #include "media/base/decoder_buffer.h"
24 #include "media/base/media_util.h" 24 #include "media/base/media_util.h"
25 #include "media/base/test_data_util.h" 25 #include "media/base/test_data_util.h"
26 #include "media/base/test_helpers.h" 26 #include "media/base/test_helpers.h"
27 #include "media/base/timestamp_constants.h" 27 #include "media/base/timestamp_constants.h"
28 #include "media/ffmpeg/ffmpeg_common.h" 28 #include "media/ffmpeg/ffmpeg_common.h"
29 #include "media/filters/audio_file_reader.h" 29 #include "media/filters/audio_file_reader.h"
30 #include "media/filters/ffmpeg_audio_decoder.h" 30 #include "media/filters/ffmpeg_audio_decoder.h"
31 #include "media/filters/in_memory_url_protocol.h" 31 #include "media/filters/in_memory_url_protocol.h"
32 #include "media/filters/opus_audio_decoder.h" 32 #include "media/filters/opus_audio_decoder.h"
33 #include "testing/gtest/include/gtest/gtest.h" 33 #include "testing/gtest/include/gtest/gtest.h"
34 34
35 #if defined(OS_ANDROID)
36 #include "base/android/build_info.h"
37 #include "media/base/android/media_codec_util.h"
38 #include "media/filters/android/media_codec_audio_decoder.h"
39
40 // Helper macro to skip the test if MediaCodec is not available.
41 #define SKIP_TEST_IF_NO_MEDIA_CODEC() \
42 do { \
43 if (GetParam().decoder_type == MEDIA_CODEC) { \
44 if (!MediaCodecUtil::IsMediaCodecAvailable()) { \
45 VLOG(0) << "Could not run test - no MediaCodec on device."; \
46 return; \
47 } \
48 if (GetParam().codec == kCodecOpus && \
49 base::android::BuildInfo::GetInstance()->sdk_int() < 21) { \
50 VLOG(0) << "Could not run test - Opus is not supported"; \
51 return; \
52 } \
53 } \
54 } while (0)
55 #else
56 #define SKIP_TEST_IF_NO_MEDIA_CODEC() \
57 do { \
58 } while (0)
59 #endif // !defined(OS_ANDROID)
60
35 namespace media { 61 namespace media {
36 62
37 // The number of packets to read and then decode from each file. 63 // The number of packets to read and then decode from each file.
38 static const size_t kDecodeRuns = 3; 64 static const size_t kDecodeRuns = 3;
39 static const uint8_t kOpusExtraData[] = { 65 static const uint8_t kOpusExtraData[] = {
40 0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64, 0x01, 0x02, 66 0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64, 0x01, 0x02,
41 // The next two bytes represent the codec delay. 67 // The next two bytes represent the codec delay.
42 0x00, 0x00, 0x80, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00}; 68 0x00, 0x00, 0x80, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00};
43 69
44 enum AudioDecoderType { 70 enum AudioDecoderType {
45 FFMPEG, 71 FFMPEG,
46 OPUS, 72 OPUS,
73 #if defined(OS_ANDROID)
74 MEDIA_CODEC,
75 #endif
47 }; 76 };
48 77
49 struct DecodedBufferExpectations { 78 struct DecodedBufferExpectations {
50 const int64_t timestamp; 79 const int64_t timestamp;
51 const int64_t duration; 80 const int64_t duration;
52 const char* hash; 81 const char* hash;
53 }; 82 };
54 83
55 struct DecoderTestData { 84 struct DecoderTestData {
56 const AudioDecoderType decoder_type; 85 const AudioDecoderType decoder_type;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 last_decode_status_(AudioDecoder::kDecodeError) { 135 last_decode_status_(AudioDecoder::kDecodeError) {
107 switch (GetParam().decoder_type) { 136 switch (GetParam().decoder_type) {
108 case FFMPEG: 137 case FFMPEG:
109 decoder_.reset(new FFmpegAudioDecoder(message_loop_.task_runner(), 138 decoder_.reset(new FFmpegAudioDecoder(message_loop_.task_runner(),
110 new MediaLog())); 139 new MediaLog()));
111 break; 140 break;
112 case OPUS: 141 case OPUS:
113 decoder_.reset( 142 decoder_.reset(
114 new OpusAudioDecoder(message_loop_.task_runner())); 143 new OpusAudioDecoder(message_loop_.task_runner()));
115 break; 144 break;
145 #if defined(OS_ANDROID)
146 case MEDIA_CODEC:
147 decoder_.reset(new MediaCodecAudioDecoder(message_loop_.task_runner()));
148 break;
149 #endif
116 } 150 }
117 } 151 }
118 152
119 virtual ~AudioDecoderTest() { 153 virtual ~AudioDecoderTest() {
120 EXPECT_FALSE(pending_decode_); 154 EXPECT_FALSE(pending_decode_);
121 EXPECT_FALSE(pending_reset_); 155 EXPECT_FALSE(pending_reset_);
122 } 156 }
123 157
124 protected: 158 protected:
125 void DecodeBuffer(const scoped_refptr<DecoderBuffer>& buffer) { 159 void DecodeBuffer(const scoped_refptr<DecoderBuffer>& buffer) {
126 ASSERT_FALSE(pending_decode_); 160 ASSERT_FALSE(pending_decode_);
127 pending_decode_ = true; 161 pending_decode_ = true;
128 last_decode_status_ = AudioDecoder::kDecodeError; 162 last_decode_status_ = AudioDecoder::kDecodeError;
163
164 base::RunLoop run_loop;
129 decoder_->Decode( 165 decoder_->Decode(
130 buffer, 166 buffer, base::Bind(&AudioDecoderTest::DecodeFinished,
131 base::Bind(&AudioDecoderTest::DecodeFinished, base::Unretained(this))); 167 base::Unretained(this), run_loop.QuitClosure()));
132 base::RunLoop().RunUntilIdle(); 168 run_loop.Run();
133 ASSERT_FALSE(pending_decode_); 169 ASSERT_FALSE(pending_decode_);
134 } 170 }
135 171
136 void SendEndOfStream() { 172 void SendEndOfStream() {
137 DecodeBuffer(DecoderBuffer::CreateEOSBuffer()); 173 DecodeBuffer(DecoderBuffer::CreateEOSBuffer());
138 } 174 }
139 175
140 void Initialize() { 176 void Initialize() {
141 // Load the test data file. 177 // Load the test data file.
142 data_ = ReadTestDataFile(GetParam().filename); 178 data_ = ReadTestDataFile(GetParam().filename);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 Reset(); 254 Reset();
219 decoded_audio_.clear(); 255 decoded_audio_.clear();
220 ASSERT_TRUE(reader_->SeekForTesting(seek_time)); 256 ASSERT_TRUE(reader_->SeekForTesting(seek_time));
221 } 257 }
222 258
223 void OnDecoderOutput(const scoped_refptr<AudioBuffer>& buffer) { 259 void OnDecoderOutput(const scoped_refptr<AudioBuffer>& buffer) {
224 EXPECT_FALSE(buffer->end_of_stream()); 260 EXPECT_FALSE(buffer->end_of_stream());
225 decoded_audio_.push_back(buffer); 261 decoded_audio_.push_back(buffer);
226 } 262 }
227 263
228 void DecodeFinished(AudioDecoder::Status status) { 264 void DecodeFinished(const base::Closure& quit_closure,
265 AudioDecoder::Status status) {
229 EXPECT_TRUE(pending_decode_); 266 EXPECT_TRUE(pending_decode_);
230 EXPECT_FALSE(pending_reset_); 267 EXPECT_FALSE(pending_reset_);
231 pending_decode_ = false; 268 pending_decode_ = false;
232 last_decode_status_ = status; 269 last_decode_status_ = status;
270 quit_closure.Run();
233 } 271 }
234 272
235 void ResetFinished() { 273 void ResetFinished() {
236 EXPECT_TRUE(pending_reset_); 274 EXPECT_TRUE(pending_reset_);
237 EXPECT_FALSE(pending_decode_); 275 EXPECT_FALSE(pending_decode_);
238 pending_reset_ = false; 276 pending_reset_ = false;
239 } 277 }
240 278
241 // Generates an MD5 hash of the audio signal. Should not be used for checks 279 // Generates an MD5 hash of the audio signal. Should not be used for checks
242 // across platforms as audio varies slightly across platforms. 280 // across platforms as audio varies slightly across platforms.
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 std::deque<scoped_refptr<AudioBuffer> > decoded_audio_; 352 std::deque<scoped_refptr<AudioBuffer> > decoded_audio_;
315 base::TimeDelta start_timestamp_; 353 base::TimeDelta start_timestamp_;
316 354
317 DISALLOW_COPY_AND_ASSIGN(AudioDecoderTest); 355 DISALLOW_COPY_AND_ASSIGN(AudioDecoderTest);
318 }; 356 };
319 357
320 class OpusAudioDecoderBehavioralTest : public AudioDecoderTest {}; 358 class OpusAudioDecoderBehavioralTest : public AudioDecoderTest {};
321 class FFmpegAudioDecoderBehavioralTest : public AudioDecoderTest {}; 359 class FFmpegAudioDecoderBehavioralTest : public AudioDecoderTest {};
322 360
323 TEST_P(AudioDecoderTest, Initialize) { 361 TEST_P(AudioDecoderTest, Initialize) {
362 SKIP_TEST_IF_NO_MEDIA_CODEC();
324 ASSERT_NO_FATAL_FAILURE(Initialize()); 363 ASSERT_NO_FATAL_FAILURE(Initialize());
325 } 364 }
326 365
327 // Verifies decode audio as well as the Decode() -> Reset() sequence. 366 // Verifies decode audio as well as the Decode() -> Reset() sequence.
328 TEST_P(AudioDecoderTest, ProduceAudioSamples) { 367 TEST_P(AudioDecoderTest, ProduceAudioSamples) {
368 SKIP_TEST_IF_NO_MEDIA_CODEC();
329 ASSERT_NO_FATAL_FAILURE(Initialize()); 369 ASSERT_NO_FATAL_FAILURE(Initialize());
330 370
331 // Run the test multiple times with a seek back to the beginning in between. 371 // Run the test multiple times with a seek back to the beginning in between.
332 std::vector<std::string> decoded_audio_md5_hashes; 372 std::vector<std::string> decoded_audio_md5_hashes;
333 for (int i = 0; i < 2; ++i) { 373 for (int i = 0; i < 2; ++i) {
334 for (size_t j = 0; j < kDecodeRuns; ++j) { 374 // Run decoder until we get at least |kDecodeRuns| output buffers.
335 do { 375 // Keeping Decode() in a loop seems to be the simplest way to guarantee that
336 Decode(); 376 // the predefined number of output buffers are produced without draining
337 ASSERT_EQ(last_decode_status(), AudioDecoder::kOk); 377 // (i.e. decoding EOS).
338 // Some codecs have a multiple buffer delay and require an extra 378 do {
339 // Decode() step to extract the desired number of output buffers. 379 Decode();
340 } while (j == 0 && decoded_audio_size() == 0); 380 ASSERT_EQ(last_decode_status(), AudioDecoder::kOk);
381 } while (decoded_audio_size() < kDecodeRuns);
341 382
342 // On the first pass record the exact MD5 hash for each decoded buffer. 383 // With MediaCodecAudioDecoder the output buffers might appear after
343 if (i == 0) 384 // some delay. Since we keep decoding in a loop, the number of output
385 // buffers when they eventually appear might exceed |kDecodeRuns|.
386 ASSERT_LE(kDecodeRuns, decoded_audio_size());
387
388 // On the first pass record the exact MD5 hash for each decoded buffer.
389 if (i == 0) {
390 for (size_t j = 0; j < kDecodeRuns; ++j)
344 decoded_audio_md5_hashes.push_back(GetDecodedAudioMD5(j)); 391 decoded_audio_md5_hashes.push_back(GetDecodedAudioMD5(j));
345 } 392 }
346 393
347 ASSERT_EQ(kDecodeRuns, decoded_audio_size());
348
349 // On the first pass verify the basic audio hash and sample info. On the 394 // On the first pass verify the basic audio hash and sample info. On the
350 // second, verify the exact MD5 sum for each packet. It shouldn't change. 395 // second, verify the exact MD5 sum for each packet. It shouldn't change.
351 for (size_t j = 0; j < kDecodeRuns; ++j) { 396 for (size_t j = 0; j < kDecodeRuns; ++j) {
352 SCOPED_TRACE(base::StringPrintf("i = %d, j = %" PRIuS, i, j)); 397 SCOPED_TRACE(base::StringPrintf("i = %d, j = %" PRIuS, i, j));
353 ExpectDecodedAudio(j, i == 0 ? "" : decoded_audio_md5_hashes[j]); 398 ExpectDecodedAudio(j, i == 0 ? "" : decoded_audio_md5_hashes[j]);
354 } 399 }
355 400
356 SendEndOfStream(); 401 SendEndOfStream();
357 ASSERT_EQ(kDecodeRuns, decoded_audio_size());
358 402
359 // Seek back to the beginning. Calls Reset() on the decoder. 403 // Seek back to the beginning. Calls Reset() on the decoder.
360 Seek(start_timestamp()); 404 Seek(start_timestamp());
361 } 405 }
362 } 406 }
363 407
364 TEST_P(AudioDecoderTest, Decode) { 408 TEST_P(AudioDecoderTest, Decode) {
409 SKIP_TEST_IF_NO_MEDIA_CODEC();
365 ASSERT_NO_FATAL_FAILURE(Initialize()); 410 ASSERT_NO_FATAL_FAILURE(Initialize());
366 Decode(); 411 Decode();
367 EXPECT_EQ(AudioDecoder::kOk, last_decode_status()); 412 EXPECT_EQ(AudioDecoder::kOk, last_decode_status());
368 } 413 }
369 414
370 TEST_P(AudioDecoderTest, Reset) { 415 TEST_P(AudioDecoderTest, Reset) {
416 SKIP_TEST_IF_NO_MEDIA_CODEC();
371 ASSERT_NO_FATAL_FAILURE(Initialize()); 417 ASSERT_NO_FATAL_FAILURE(Initialize());
372 Reset(); 418 Reset();
373 } 419 }
374 420
375 TEST_P(AudioDecoderTest, NoTimestamp) { 421 TEST_P(AudioDecoderTest, NoTimestamp) {
422 SKIP_TEST_IF_NO_MEDIA_CODEC();
376 ASSERT_NO_FATAL_FAILURE(Initialize()); 423 ASSERT_NO_FATAL_FAILURE(Initialize());
377 scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(0)); 424 scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(0));
378 buffer->set_timestamp(kNoTimestamp()); 425 buffer->set_timestamp(kNoTimestamp());
379 DecodeBuffer(buffer); 426 DecodeBuffer(buffer);
380 EXPECT_EQ(AudioDecoder::kDecodeError, last_decode_status()); 427 EXPECT_EQ(AudioDecoder::kDecodeError, last_decode_status());
381 } 428 }
382 429
383 TEST_P(OpusAudioDecoderBehavioralTest, InitializeWithNoCodecDelay) { 430 TEST_P(OpusAudioDecoderBehavioralTest, InitializeWithNoCodecDelay) {
384 ASSERT_EQ(GetParam().decoder_type, OPUS); 431 ASSERT_EQ(GetParam().decoder_type, OPUS);
385 std::vector<uint8_t> extra_data( 432 std::vector<uint8_t> extra_data(
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 {OPUS, kUnknownAudioCodec, "", NULL, 0, 0, CHANNEL_LAYOUT_NONE}, 495 {OPUS, kUnknownAudioCodec, "", NULL, 0, 0, CHANNEL_LAYOUT_NONE},
449 }; 496 };
450 497
451 INSTANTIATE_TEST_CASE_P(OpusAudioDecoderTest, 498 INSTANTIATE_TEST_CASE_P(OpusAudioDecoderTest,
452 AudioDecoderTest, 499 AudioDecoderTest,
453 testing::ValuesIn(kOpusTests)); 500 testing::ValuesIn(kOpusTests));
454 INSTANTIATE_TEST_CASE_P(OpusAudioDecoderBehavioralTest, 501 INSTANTIATE_TEST_CASE_P(OpusAudioDecoderBehavioralTest,
455 OpusAudioDecoderBehavioralTest, 502 OpusAudioDecoderBehavioralTest,
456 testing::ValuesIn(kOpusBehavioralTest)); 503 testing::ValuesIn(kOpusBehavioralTest));
457 504
505 #if defined(OS_ANDROID)
506
507 const DecoderTestData kMediaCodecTests[] = {
508 {MEDIA_CODEC, kCodecOpus, "bear-opus.ogg", kBearOpusExpectations, 24, 48000,
509 CHANNEL_LAYOUT_STEREO},
510 };
511
512 INSTANTIATE_TEST_CASE_P(MediaCodecAudioDecoderTest,
513 AudioDecoderTest,
514 testing::ValuesIn(kMediaCodecTests));
515
516 #else // !defined(OS_ANDROID)
517
458 // Disable all FFmpeg decoder tests on Android. http://crbug.com/570762. 518 // Disable all FFmpeg decoder tests on Android. http://crbug.com/570762.
459 #if !defined(OS_ANDROID)
460 519
461 #if defined(USE_PROPRIETARY_CODECS) 520 #if defined(USE_PROPRIETARY_CODECS)
462 const DecodedBufferExpectations kSfxMp3Expectations[] = { 521 const DecodedBufferExpectations kSfxMp3Expectations[] = {
463 {0, 1065, "2.81,3.99,4.53,4.10,3.08,2.46,"}, 522 {0, 1065, "2.81,3.99,4.53,4.10,3.08,2.46,"},
464 {1065, 26122, "-3.81,-4.14,-3.90,-3.36,-3.03,-3.23,"}, 523 {1065, 26122, "-3.81,-4.14,-3.90,-3.36,-3.03,-3.23,"},
465 {27188, 26122, "4.24,3.95,4.22,4.78,5.13,4.93,"}, 524 {27188, 26122, "4.24,3.95,4.22,4.78,5.13,4.93,"},
466 }; 525 };
467 526
468 const DecodedBufferExpectations kSfxAdtsExpectations[] = { 527 const DecodedBufferExpectations kSfxAdtsExpectations[] = {
469 {0, 23219, "-1.90,-1.53,-0.15,1.28,1.23,-0.33,"}, 528 {0, 23219, "-1.90,-1.53,-0.15,1.28,1.23,-0.33,"},
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 INSTANTIATE_TEST_CASE_P(FFmpegAudioDecoderTest, 594 INSTANTIATE_TEST_CASE_P(FFmpegAudioDecoderTest,
536 AudioDecoderTest, 595 AudioDecoderTest,
537 testing::ValuesIn(kFFmpegTests)); 596 testing::ValuesIn(kFFmpegTests));
538 INSTANTIATE_TEST_CASE_P(FFmpegAudioDecoderBehavioralTest, 597 INSTANTIATE_TEST_CASE_P(FFmpegAudioDecoderBehavioralTest,
539 FFmpegAudioDecoderBehavioralTest, 598 FFmpegAudioDecoderBehavioralTest,
540 testing::ValuesIn(kFFmpegBehavioralTest)); 599 testing::ValuesIn(kFFmpegBehavioralTest));
541 600
542 #endif // !defined(OS_ANDROID) 601 #endif // !defined(OS_ANDROID)
543 602
544 } // namespace media 603 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/android/media_codec_audio_decoder.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698