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

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: Created 4 years, 10 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
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 "media/filters/android/media_codec_audio_decoder.h"
37 #endif
38
35 namespace media { 39 namespace media {
36 40
37 // The number of packets to read and then decode from each file. 41 // The number of packets to read and then decode from each file.
38 static const size_t kDecodeRuns = 3; 42 static const size_t kDecodeRuns = 3;
39 static const uint8_t kOpusExtraData[] = { 43 static const uint8_t kOpusExtraData[] = {
40 0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64, 0x01, 0x02, 44 0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64, 0x01, 0x02,
41 // The next two bytes represent the codec delay. 45 // The next two bytes represent the codec delay.
42 0x00, 0x00, 0x80, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00}; 46 0x00, 0x00, 0x80, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00};
43 47
44 enum AudioDecoderType { 48 enum AudioDecoderType {
45 FFMPEG, 49 FFMPEG,
46 OPUS, 50 OPUS,
51 #if defined(OS_ANDROID)
52 MEDIA_CODEC,
53 #endif
47 }; 54 };
48 55
49 struct DecodedBufferExpectations { 56 struct DecodedBufferExpectations {
50 const int64_t timestamp; 57 const int64_t timestamp;
51 const int64_t duration; 58 const int64_t duration;
52 const char* hash; 59 const char* hash;
53 }; 60 };
54 61
55 struct DecoderTestData { 62 struct DecoderTestData {
56 const AudioDecoderType decoder_type; 63 const AudioDecoderType decoder_type;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 last_decode_status_(AudioDecoder::kDecodeError) { 113 last_decode_status_(AudioDecoder::kDecodeError) {
107 switch (GetParam().decoder_type) { 114 switch (GetParam().decoder_type) {
108 case FFMPEG: 115 case FFMPEG:
109 decoder_.reset(new FFmpegAudioDecoder(message_loop_.task_runner(), 116 decoder_.reset(new FFmpegAudioDecoder(message_loop_.task_runner(),
110 new MediaLog())); 117 new MediaLog()));
111 break; 118 break;
112 case OPUS: 119 case OPUS:
113 decoder_.reset( 120 decoder_.reset(
114 new OpusAudioDecoder(message_loop_.task_runner())); 121 new OpusAudioDecoder(message_loop_.task_runner()));
115 break; 122 break;
123 #if defined(OS_ANDROID)
124 case MEDIA_CODEC:
125 decoder_.reset(new MediaCodecAudioDecoder(message_loop_.task_runner()));
126 break;
127 #endif
116 } 128 }
117 } 129 }
118 130
119 virtual ~AudioDecoderTest() { 131 virtual ~AudioDecoderTest() {
120 EXPECT_FALSE(pending_decode_); 132 EXPECT_FALSE(pending_decode_);
121 EXPECT_FALSE(pending_reset_); 133 EXPECT_FALSE(pending_reset_);
122 } 134 }
123 135
124 protected: 136 protected:
125 void DecodeBuffer(const scoped_refptr<DecoderBuffer>& buffer) { 137 void DecodeBuffer(const scoped_refptr<DecoderBuffer>& buffer) {
126 ASSERT_FALSE(pending_decode_); 138 ASSERT_FALSE(pending_decode_);
127 pending_decode_ = true; 139 pending_decode_ = true;
128 last_decode_status_ = AudioDecoder::kDecodeError; 140 last_decode_status_ = AudioDecoder::kDecodeError;
129 decoder_->Decode( 141 decoder_->Decode(
130 buffer, 142 buffer,
131 base::Bind(&AudioDecoderTest::DecodeFinished, base::Unretained(this))); 143 base::Bind(&AudioDecoderTest::DecodeFinished, base::Unretained(this)));
132 base::RunLoop().RunUntilIdle(); 144 WaitForDecodeResponse();
133 ASSERT_FALSE(pending_decode_); 145 ASSERT_FALSE(pending_decode_);
134 } 146 }
135 147
148 void WaitForDecodeResponse() {
liberato (no reviews please) 2016/02/29 17:08:57 "do work for 100msec" seems flaky. i see that the
Tima Vaisburd 2016/02/29 21:01:03 I think that mocking MediaCodec is a good idea, as
liberato (no reviews please) 2016/03/01 22:20:39 i was thinking about a very simple MediaCodec mock
Tima Vaisburd 2016/03/01 23:35:33 Even if the MediaCodec returns the output buffer i
liberato (no reviews please) 2016/03/02 15:02:01 flakiness: a delay of 100msec seems like something
149 const base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(100);
150 const base::TimeDelta sleep_time = base::TimeDelta::FromMilliseconds(10);
151
152 for (int i = 0; i < timeout / sleep_time; ++i) {
liberato (no reviews please) 2016/02/29 17:08:57 not sure if ::Sleep guarantees not to wake up earl
Tima Vaisburd 2016/02/29 21:01:03 Yes, I was not sure whether to use the Sleep(), or
liberato (no reviews please) 2016/03/02 15:02:01 i think that i like dale's suggestion better than
153 base::RunLoop().RunUntilIdle();
154 if (!pending_decode_)
155 break;
156 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
157 }
158 }
159
136 void SendEndOfStream() { 160 void SendEndOfStream() {
137 DecodeBuffer(DecoderBuffer::CreateEOSBuffer()); 161 DecodeBuffer(DecoderBuffer::CreateEOSBuffer());
138 } 162 }
139 163
140 void Initialize() { 164 void Initialize() {
141 // Load the test data file. 165 // Load the test data file.
142 data_ = ReadTestDataFile(GetParam().filename); 166 data_ = ReadTestDataFile(GetParam().filename);
143 protocol_.reset( 167 protocol_.reset(
144 new InMemoryUrlProtocol(data_->data(), data_->data_size(), false)); 168 new InMemoryUrlProtocol(data_->data(), data_->data_size(), false));
145 reader_.reset(new AudioFileReader(protocol_.get())); 169 reader_.reset(new AudioFileReader(protocol_.get()));
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 ASSERT_NO_FATAL_FAILURE(Initialize()); 348 ASSERT_NO_FATAL_FAILURE(Initialize());
325 } 349 }
326 350
327 // Verifies decode audio as well as the Decode() -> Reset() sequence. 351 // Verifies decode audio as well as the Decode() -> Reset() sequence.
328 TEST_P(AudioDecoderTest, ProduceAudioSamples) { 352 TEST_P(AudioDecoderTest, ProduceAudioSamples) {
329 ASSERT_NO_FATAL_FAILURE(Initialize()); 353 ASSERT_NO_FATAL_FAILURE(Initialize());
330 354
331 // Run the test multiple times with a seek back to the beginning in between. 355 // Run the test multiple times with a seek back to the beginning in between.
332 std::vector<std::string> decoded_audio_md5_hashes; 356 std::vector<std::string> decoded_audio_md5_hashes;
333 for (int i = 0; i < 2; ++i) { 357 for (int i = 0; i < 2; ++i) {
334 for (size_t j = 0; j < kDecodeRuns; ++j) { 358 // Run decoder until we get at least |kDecodeRuns| output buffers.
335 do { 359 do {
336 Decode(); 360 Decode();
337 ASSERT_EQ(last_decode_status(), AudioDecoder::kOk); 361 ASSERT_EQ(last_decode_status(), AudioDecoder::kOk);
338 // Some codecs have a multiple buffer delay and require an extra 362 } while (decoded_audio_size() < kDecodeRuns);
liberato (no reviews please) 2016/02/29 17:08:57 why did this change? does MediaCodec have a varia
Tima Vaisburd 2016/02/29 21:01:03 I think first. See below.
339 // Decode() step to extract the desired number of output buffers.
340 } while (j == 0 && decoded_audio_size() == 0);
341 363
342 // On the first pass record the exact MD5 hash for each decoded buffer. 364 // On the first pass record the exact MD5 hash for each decoded buffer.
343 if (i == 0) 365 if (i == 0) {
366 for (size_t j = 0; j < kDecodeRuns; ++j)
344 decoded_audio_md5_hashes.push_back(GetDecodedAudioMD5(j)); 367 decoded_audio_md5_hashes.push_back(GetDecodedAudioMD5(j));
345 } 368 }
346 369
347 ASSERT_EQ(kDecodeRuns, decoded_audio_size()); 370 ASSERT_LE(kDecodeRuns, decoded_audio_size());
liberato (no reviews please) 2016/02/29 17:08:57 why can't we guarantee EQ here? is it because one
Tima Vaisburd 2016/02/29 21:01:03 As far as I understand, this is the consequence of
liberato (no reviews please) 2016/03/01 22:20:39 i don't think eq is important, but it's probably w
Tima Vaisburd 2016/03/01 23:35:33 I went a little deeper to see why we cannot ASSERT
348 371
349 // On the first pass verify the basic audio hash and sample info. On the 372 // 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. 373 // second, verify the exact MD5 sum for each packet. It shouldn't change.
351 for (size_t j = 0; j < kDecodeRuns; ++j) { 374 for (size_t j = 0; j < kDecodeRuns; ++j) {
352 SCOPED_TRACE(base::StringPrintf("i = %d, j = %" PRIuS, i, j)); 375 SCOPED_TRACE(base::StringPrintf("i = %d, j = %" PRIuS, i, j));
353 ExpectDecodedAudio(j, i == 0 ? "" : decoded_audio_md5_hashes[j]); 376 ExpectDecodedAudio(j, i == 0 ? "" : decoded_audio_md5_hashes[j]);
354 } 377 }
355 378
356 SendEndOfStream(); 379 SendEndOfStream();
357 ASSERT_EQ(kDecodeRuns, decoded_audio_size());
358 380
359 // Seek back to the beginning. Calls Reset() on the decoder. 381 // Seek back to the beginning. Calls Reset() on the decoder.
360 Seek(start_timestamp()); 382 Seek(start_timestamp());
361 } 383 }
362 } 384 }
363 385
364 TEST_P(AudioDecoderTest, Decode) { 386 TEST_P(AudioDecoderTest, Decode) {
365 ASSERT_NO_FATAL_FAILURE(Initialize()); 387 ASSERT_NO_FATAL_FAILURE(Initialize());
366 Decode(); 388 Decode();
367 EXPECT_EQ(AudioDecoder::kOk, last_decode_status()); 389 EXPECT_EQ(AudioDecoder::kOk, last_decode_status());
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 {OPUS, kUnknownAudioCodec, "", NULL, 0, 0, CHANNEL_LAYOUT_NONE}, 470 {OPUS, kUnknownAudioCodec, "", NULL, 0, 0, CHANNEL_LAYOUT_NONE},
449 }; 471 };
450 472
451 INSTANTIATE_TEST_CASE_P(OpusAudioDecoderTest, 473 INSTANTIATE_TEST_CASE_P(OpusAudioDecoderTest,
452 AudioDecoderTest, 474 AudioDecoderTest,
453 testing::ValuesIn(kOpusTests)); 475 testing::ValuesIn(kOpusTests));
454 INSTANTIATE_TEST_CASE_P(OpusAudioDecoderBehavioralTest, 476 INSTANTIATE_TEST_CASE_P(OpusAudioDecoderBehavioralTest,
455 OpusAudioDecoderBehavioralTest, 477 OpusAudioDecoderBehavioralTest,
456 testing::ValuesIn(kOpusBehavioralTest)); 478 testing::ValuesIn(kOpusBehavioralTest));
457 479
480 #if defined(OS_ANDROID)
481
482 const DecoderTestData kMediaCodecTests[] = {
483 {MEDIA_CODEC, kCodecOpus, "bear-opus.ogg", kBearOpusExpectations, 24, 48000,
484 CHANNEL_LAYOUT_STEREO},
485 };
486
487 INSTANTIATE_TEST_CASE_P(MediaCodecAudioDecoderTest,
488 AudioDecoderTest,
489 testing::ValuesIn(kMediaCodecTests));
490
491 #else // !defined(OS_ANDROID)
492
458 // Disable all FFmpeg decoder tests on Android. http://crbug.com/570762. 493 // Disable all FFmpeg decoder tests on Android. http://crbug.com/570762.
459 #if !defined(OS_ANDROID)
460 494
461 #if defined(USE_PROPRIETARY_CODECS) 495 #if defined(USE_PROPRIETARY_CODECS)
462 const DecodedBufferExpectations kSfxMp3Expectations[] = { 496 const DecodedBufferExpectations kSfxMp3Expectations[] = {
463 {0, 1065, "2.81,3.99,4.53,4.10,3.08,2.46,"}, 497 {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,"}, 498 {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,"}, 499 {27188, 26122, "4.24,3.95,4.22,4.78,5.13,4.93,"},
466 }; 500 };
467 501
468 const DecodedBufferExpectations kSfxAdtsExpectations[] = { 502 const DecodedBufferExpectations kSfxAdtsExpectations[] = {
469 {0, 23219, "-1.90,-1.53,-0.15,1.28,1.23,-0.33,"}, 503 {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, 569 INSTANTIATE_TEST_CASE_P(FFmpegAudioDecoderTest,
536 AudioDecoderTest, 570 AudioDecoderTest,
537 testing::ValuesIn(kFFmpegTests)); 571 testing::ValuesIn(kFFmpegTests));
538 INSTANTIATE_TEST_CASE_P(FFmpegAudioDecoderBehavioralTest, 572 INSTANTIATE_TEST_CASE_P(FFmpegAudioDecoderBehavioralTest,
539 FFmpegAudioDecoderBehavioralTest, 573 FFmpegAudioDecoderBehavioralTest,
540 testing::ValuesIn(kFFmpegBehavioralTest)); 574 testing::ValuesIn(kFFmpegBehavioralTest));
541 575
542 #endif // !defined(OS_ANDROID) 576 #endif // !defined(OS_ANDROID)
543 577
544 } // namespace media 578 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698