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

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

Issue 2642823004: media: Fix MediaCodecAudioDecoder reinitialization (Closed)
Patch Set: Android macro fix Created 3 years, 11 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 <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 17 matching lines...) Expand all
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 "testing/gtest/include/gtest/gtest.h" 32 #include "testing/gtest/include/gtest/gtest.h"
33 33
34 #if defined(OS_ANDROID) 34 #if defined(OS_ANDROID)
35 #include "base/android/build_info.h" 35 #include "base/android/build_info.h"
36 #include "media/base/android/media_codec_util.h" 36 #include "media/base/android/media_codec_util.h"
37 #include "media/filters/android/media_codec_audio_decoder.h" 37 #include "media/filters/android/media_codec_audio_decoder.h"
38 #endif
38 39
39 #if defined(USE_PROPRIETARY_CODECS) 40 #if defined(USE_PROPRIETARY_CODECS)
40 #include "media/formats/mpeg/adts_stream_parser.h" 41 #include "media/formats/mpeg/adts_stream_parser.h"
41 #endif 42 #endif
42 43
43 // Helper macro to skip the test if MediaCodec is not available. 44 using testing::Combine;
44 #define SKIP_TEST_IF_NO_MEDIA_CODEC() \ 45 using testing::TestWithParam;
45 do { \ 46 using testing::Values;
46 if (GetParam().decoder_type == MEDIA_CODEC) { \ 47 using testing::ValuesIn;
47 if (!MediaCodecUtil::IsMediaCodecAvailable()) { \
48 VLOG(0) << "Could not run test - no MediaCodec on device."; \
49 return; \
50 } \
51 if (GetParam().codec == kCodecOpus && \
52 base::android::BuildInfo::GetInstance()->sdk_int() < 21) { \
53 VLOG(0) << "Could not run test - Opus is not supported"; \
54 return; \
55 } \
56 } \
57 } while (0)
58 #else
59 #define SKIP_TEST_IF_NO_MEDIA_CODEC() \
60 do { \
61 } while (0)
62 #endif // !defined(OS_ANDROID)
63 48
64 namespace media { 49 namespace media {
65 50
51 namespace {
52
53 #define SKIP_TEST_IF_NOT_SUPPORTED() \
54 do { \
55 if (!IsSupported()) \
56 return; \
57 } while (0)
58
66 // The number of packets to read and then decode from each file. 59 // The number of packets to read and then decode from each file.
67 static const size_t kDecodeRuns = 3; 60 const size_t kDecodeRuns = 3;
68 61
69 enum AudioDecoderType { 62 enum AudioDecoderType {
70 FFMPEG, 63 FFMPEG,
71 #if defined(OS_ANDROID) 64 #if defined(OS_ANDROID)
72 MEDIA_CODEC, 65 MEDIA_CODEC,
73 #endif 66 #endif
74 }; 67 };
75 68
76 struct DecodedBufferExpectations { 69 struct DecodedBufferExpectations {
77 const int64_t timestamp; 70 int64_t timestamp;
78 const int64_t duration; 71 int64_t duration;
79 const char* hash; 72 const char* hash;
80 }; 73 };
81 74
82 struct DecoderTestData { 75 struct TestParams {
83 const AudioDecoderType decoder_type; 76 AudioCodec codec;
84 const AudioCodec codec;
85 const char* filename; 77 const char* filename;
86 const DecodedBufferExpectations* expectations; 78 const DecodedBufferExpectations* expectations;
87 const int first_packet_pts; 79 int first_packet_pts;
88 const int samples_per_second; 80 int samples_per_second;
89 const ChannelLayout channel_layout; 81 ChannelLayout channel_layout;
90 }; 82 };
91 83
92 // Tells gtest how to print our DecoderTestData structure. 84 // Tells gtest how to print our TestParams structure.
93 std::ostream& operator<<(std::ostream& os, const DecoderTestData& data) { 85 std::ostream& operator<<(std::ostream& os, const TestParams& params) {
94 return os << data.filename; 86 return os << params.filename;
95 } 87 }
96 88
97 // Marks negative timestamp buffers for discard or transfers FFmpeg's built in 89 // Marks negative timestamp buffers for discard or transfers FFmpeg's built in
98 // discard metadata in favor of setting DiscardPadding on the DecoderBuffer. 90 // discard metadata in favor of setting DiscardPadding on the DecoderBuffer.
99 // Allows better testing of AudioDiscardHelper usage. 91 // Allows better testing of AudioDiscardHelper usage.
100 static void SetDiscardPadding(AVPacket* packet, 92 void SetDiscardPadding(AVPacket* packet,
101 const scoped_refptr<DecoderBuffer> buffer, 93 const scoped_refptr<DecoderBuffer> buffer,
102 double samples_per_second) { 94 double samples_per_second) {
103 // Discard negative timestamps. 95 // Discard negative timestamps.
104 if (buffer->timestamp() + buffer->duration() < base::TimeDelta()) { 96 if (buffer->timestamp() + buffer->duration() < base::TimeDelta()) {
105 buffer->set_discard_padding( 97 buffer->set_discard_padding(
106 std::make_pair(kInfiniteDuration, base::TimeDelta())); 98 std::make_pair(kInfiniteDuration, base::TimeDelta()));
107 return; 99 return;
108 } 100 }
109 if (buffer->timestamp() < base::TimeDelta()) { 101 if (buffer->timestamp() < base::TimeDelta()) {
110 buffer->set_discard_padding( 102 buffer->set_discard_padding(
111 std::make_pair(-buffer->timestamp(), base::TimeDelta())); 103 std::make_pair(-buffer->timestamp(), base::TimeDelta()));
112 return; 104 return;
113 } 105 }
114 106
115 // If the timestamp is positive, try to use FFmpeg's discard data. 107 // If the timestamp is positive, try to use FFmpeg's discard data.
116 int skip_samples_size = 0; 108 int skip_samples_size = 0;
117 const uint32_t* skip_samples_ptr = 109 const uint32_t* skip_samples_ptr =
118 reinterpret_cast<const uint32_t*>(av_packet_get_side_data( 110 reinterpret_cast<const uint32_t*>(av_packet_get_side_data(
119 packet, AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size)); 111 packet, AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
120 if (skip_samples_size < 4) 112 if (skip_samples_size < 4)
121 return; 113 return;
122 buffer->set_discard_padding(std::make_pair( 114 buffer->set_discard_padding(std::make_pair(
123 base::TimeDelta::FromSecondsD(base::ByteSwapToLE32(*skip_samples_ptr) / 115 base::TimeDelta::FromSecondsD(base::ByteSwapToLE32(*skip_samples_ptr) /
124 samples_per_second), 116 samples_per_second),
125 base::TimeDelta())); 117 base::TimeDelta()));
126 } 118 }
127 119
128 class AudioDecoderTest : public testing::TestWithParam<DecoderTestData> { 120 } // namespace
121
122 class AudioDecoderTest
123 : public TestWithParam<std::tuple<AudioDecoderType, TestParams>> {
129 public: 124 public:
130 AudioDecoderTest() 125 AudioDecoderTest()
131 : pending_decode_(false), 126 : decoder_type_(std::get<0>(GetParam())),
127 params_(std::get<1>(GetParam())),
128 pending_decode_(false),
132 pending_reset_(false), 129 pending_reset_(false),
133 last_decode_status_(DecodeStatus::DECODE_ERROR) { 130 last_decode_status_(DecodeStatus::DECODE_ERROR) {
134 switch (GetParam().decoder_type) { 131 switch (decoder_type_) {
135 case FFMPEG: 132 case FFMPEG:
136 decoder_.reset(new FFmpegAudioDecoder(message_loop_.task_runner(), 133 decoder_.reset(new FFmpegAudioDecoder(message_loop_.task_runner(),
137 new MediaLog())); 134 new MediaLog()));
138 break; 135 break;
139 #if defined(OS_ANDROID) 136 #if defined(OS_ANDROID)
140 case MEDIA_CODEC: 137 case MEDIA_CODEC:
141 decoder_.reset(new MediaCodecAudioDecoder(message_loop_.task_runner())); 138 decoder_.reset(new MediaCodecAudioDecoder(message_loop_.task_runner()));
142 break; 139 break;
143 #endif 140 #endif
144 } 141 }
145 } 142 }
146 143
147 virtual ~AudioDecoderTest() { 144 virtual ~AudioDecoderTest() {
148 EXPECT_FALSE(pending_decode_); 145 EXPECT_FALSE(pending_decode_);
149 EXPECT_FALSE(pending_reset_); 146 EXPECT_FALSE(pending_reset_);
150 } 147 }
151 148
152 protected: 149 protected:
150 bool IsSupported() const {
151 #if defined(OS_ANDROID)
DaleCurtis 2017/01/19 18:09:29 Could probably use mime_util_internal for this if
152 if (decoder_type_ == MEDIA_CODEC) {
153 if (!MediaCodecUtil::IsMediaCodecAvailable()) {
154 VLOG(0) << "Could not run test - no MediaCodec on device.";
155 return false;
156 }
157 if (params_.codec == kCodecOpus &&
158 base::android::BuildInfo::GetInstance()->sdk_int() < 21) {
159 VLOG(0) << "Could not run test - Opus is not supported";
160 return false;
161 }
162 }
163 #endif
164 return true;
165 }
166
153 void DecodeBuffer(const scoped_refptr<DecoderBuffer>& buffer) { 167 void DecodeBuffer(const scoped_refptr<DecoderBuffer>& buffer) {
154 ASSERT_FALSE(pending_decode_); 168 ASSERT_FALSE(pending_decode_);
155 pending_decode_ = true; 169 pending_decode_ = true;
156 last_decode_status_ = DecodeStatus::DECODE_ERROR; 170 last_decode_status_ = DecodeStatus::DECODE_ERROR;
157 171
158 base::RunLoop run_loop; 172 base::RunLoop run_loop;
159 decoder_->Decode( 173 decoder_->Decode(
160 buffer, base::Bind(&AudioDecoderTest::DecodeFinished, 174 buffer, base::Bind(&AudioDecoderTest::DecodeFinished,
161 base::Unretained(this), run_loop.QuitClosure())); 175 base::Unretained(this), run_loop.QuitClosure()));
162 run_loop.Run(); 176 run_loop.Run();
163 ASSERT_FALSE(pending_decode_); 177 ASSERT_FALSE(pending_decode_);
164 } 178 }
165 179
166 void SendEndOfStream() { DecodeBuffer(DecoderBuffer::CreateEOSBuffer()); } 180 void SendEndOfStream() { DecodeBuffer(DecoderBuffer::CreateEOSBuffer()); }
167 181
182 // Set the TestParams explicitly. Can be use to reinitialize the decoder with
183 // different TestParams.
184 void set_params(const TestParams& params) { params_ = params; }
185
168 void Initialize() { 186 void Initialize() {
169 // Load the test data file. 187 // Load the test data file.
170 data_ = ReadTestDataFile(GetParam().filename); 188 data_ = ReadTestDataFile(params_.filename);
171 protocol_.reset( 189 protocol_.reset(
172 new InMemoryUrlProtocol(data_->data(), data_->data_size(), false)); 190 new InMemoryUrlProtocol(data_->data(), data_->data_size(), false));
173 reader_.reset(new AudioFileReader(protocol_.get())); 191 reader_.reset(new AudioFileReader(protocol_.get()));
174 ASSERT_TRUE(reader_->OpenDemuxerForTesting()); 192 ASSERT_TRUE(reader_->OpenDemuxerForTesting());
175 193
176 // Load the first packet and check its timestamp. 194 // Load the first packet and check its timestamp.
177 AVPacket packet; 195 AVPacket packet;
178 ASSERT_TRUE(reader_->ReadPacketForTesting(&packet)); 196 ASSERT_TRUE(reader_->ReadPacketForTesting(&packet));
179 EXPECT_EQ(GetParam().first_packet_pts, packet.pts); 197 EXPECT_EQ(params_.first_packet_pts, packet.pts);
180 start_timestamp_ = ConvertFromTimeBase( 198 start_timestamp_ = ConvertFromTimeBase(
181 reader_->GetAVStreamForTesting()->time_base, packet.pts); 199 reader_->GetAVStreamForTesting()->time_base, packet.pts);
182 200
183 // Seek back to the beginning. 201 // Seek back to the beginning.
184 ASSERT_TRUE(reader_->SeekForTesting(start_timestamp_)); 202 ASSERT_TRUE(reader_->SeekForTesting(start_timestamp_));
185 203
186 AudioDecoderConfig config; 204 AudioDecoderConfig config;
187 ASSERT_TRUE(AVCodecContextToAudioDecoderConfig( 205 ASSERT_TRUE(AVCodecContextToAudioDecoderConfig(
188 reader_->codec_context_for_testing(), Unencrypted(), &config)); 206 reader_->codec_context_for_testing(), Unencrypted(), &config));
189 207
190 #if defined(OS_ANDROID) && defined(USE_PROPRIETARY_CODECS) 208 #if defined(OS_ANDROID) && defined(USE_PROPRIETARY_CODECS)
191 // MEDIA_CODEC type requires config->extra_data() for AAC codec. For ADTS 209 // MEDIA_CODEC type requires config->extra_data() for AAC codec. For ADTS
192 // streams we need to extract it with a separate procedure. 210 // streams we need to extract it with a separate procedure.
193 if (GetParam().decoder_type == MEDIA_CODEC && 211 if (decoder_type_ == MEDIA_CODEC && params_.codec == kCodecAAC &&
194 GetParam().codec == kCodecAAC && config.extra_data().empty()) { 212 config.extra_data().empty()) {
195 int sample_rate; 213 int sample_rate;
196 ChannelLayout channel_layout; 214 ChannelLayout channel_layout;
197 std::vector<uint8_t> extra_data; 215 std::vector<uint8_t> extra_data;
198 ASSERT_GT(ADTSStreamParser().ParseFrameHeader( 216 ASSERT_GT(ADTSStreamParser().ParseFrameHeader(
199 packet.data, packet.size, nullptr, &sample_rate, 217 packet.data, packet.size, nullptr, &sample_rate,
200 &channel_layout, nullptr, nullptr, &extra_data), 218 &channel_layout, nullptr, nullptr, &extra_data),
201 0); 219 0);
202 config.Initialize(kCodecAAC, kSampleFormatS16, channel_layout, 220 config.Initialize(kCodecAAC, kSampleFormatS16, channel_layout,
203 sample_rate, extra_data, Unencrypted(), 221 sample_rate, extra_data, Unencrypted(),
204 base::TimeDelta(), 0); 222 base::TimeDelta(), 0);
205 ASSERT_FALSE(config.extra_data().empty()); 223 ASSERT_FALSE(config.extra_data().empty());
206 } 224 }
207 #endif 225 #endif
208 226
209 av_packet_unref(&packet); 227 av_packet_unref(&packet);
210 228
211 EXPECT_EQ(GetParam().codec, config.codec()); 229 EXPECT_EQ(params_.codec, config.codec());
212 EXPECT_EQ(GetParam().samples_per_second, config.samples_per_second()); 230 EXPECT_EQ(params_.samples_per_second, config.samples_per_second());
213 EXPECT_EQ(GetParam().channel_layout, config.channel_layout()); 231 EXPECT_EQ(params_.channel_layout, config.channel_layout());
214 232
215 InitializeDecoder(config); 233 InitializeDecoder(config);
216 } 234 }
217 235
218 void InitializeDecoder(const AudioDecoderConfig& config) { 236 void InitializeDecoder(const AudioDecoderConfig& config) {
219 InitializeDecoderWithResult(config, true); 237 InitializeDecoderWithResult(config, true);
220 } 238 }
221 239
222 void InitializeDecoderWithResult(const AudioDecoderConfig& config, 240 void InitializeDecoderWithResult(const AudioDecoderConfig& config,
223 bool success) { 241 bool success) {
(...skipping 14 matching lines...) Expand all
238 DecoderBuffer::CopyFrom(packet.data, packet.size); 256 DecoderBuffer::CopyFrom(packet.data, packet.size);
239 buffer->set_timestamp(ConvertFromTimeBase( 257 buffer->set_timestamp(ConvertFromTimeBase(
240 reader_->GetAVStreamForTesting()->time_base, packet.pts)); 258 reader_->GetAVStreamForTesting()->time_base, packet.pts));
241 buffer->set_duration(ConvertFromTimeBase( 259 buffer->set_duration(ConvertFromTimeBase(
242 reader_->GetAVStreamForTesting()->time_base, packet.duration)); 260 reader_->GetAVStreamForTesting()->time_base, packet.duration));
243 if (packet.flags & AV_PKT_FLAG_KEY) 261 if (packet.flags & AV_PKT_FLAG_KEY)
244 buffer->set_is_key_frame(true); 262 buffer->set_is_key_frame(true);
245 263
246 // Don't set discard padding for Opus, it already has discard behavior set 264 // Don't set discard padding for Opus, it already has discard behavior set
247 // based on the codec delay in the AudioDecoderConfig. 265 // based on the codec delay in the AudioDecoderConfig.
248 if (GetParam().decoder_type == FFMPEG && GetParam().codec != kCodecOpus) 266 if (decoder_type_ == FFMPEG && params_.codec != kCodecOpus)
249 SetDiscardPadding(&packet, buffer, GetParam().samples_per_second); 267 SetDiscardPadding(&packet, buffer, params_.samples_per_second);
250 268
251 // DecodeBuffer() shouldn't need the original packet since it uses the copy. 269 // DecodeBuffer() shouldn't need the original packet since it uses the copy.
252 av_packet_unref(&packet); 270 av_packet_unref(&packet);
253 DecodeBuffer(buffer); 271 DecodeBuffer(buffer);
254 } 272 }
255 273
256 void Reset() { 274 void Reset() {
257 ASSERT_FALSE(pending_reset_); 275 ASSERT_FALSE(pending_reset_);
258 pending_reset_ = true; 276 pending_reset_ = true;
259 decoder_->Reset( 277 decoder_->Reset(
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 base::MD5Digest digest; 326 base::MD5Digest digest;
309 base::MD5Final(&digest, &context); 327 base::MD5Final(&digest, &context);
310 return base::MD5DigestToBase16(digest); 328 return base::MD5DigestToBase16(digest);
311 } 329 }
312 330
313 // Android MediaCodec returns wrong timestamps (shifted one frame forward) 331 // Android MediaCodec returns wrong timestamps (shifted one frame forward)
314 // for AAC before Android L. Skip the timestamp check in this situation. 332 // for AAC before Android L. Skip the timestamp check in this situation.
315 bool SkipBufferTimestampCheck() const { 333 bool SkipBufferTimestampCheck() const {
316 #if defined(OS_ANDROID) 334 #if defined(OS_ANDROID)
317 return (base::android::BuildInfo::GetInstance()->sdk_int() < 21) && 335 return (base::android::BuildInfo::GetInstance()->sdk_int() < 21) &&
318 GetParam().decoder_type == MEDIA_CODEC && 336 decoder_type_ == MEDIA_CODEC && params_.codec == kCodecAAC;
319 GetParam().codec == kCodecAAC;
320 #else 337 #else
321 return false; 338 return false;
322 #endif 339 #endif
323 } 340 }
324 341
325 void ExpectDecodedAudio(size_t i, const std::string& exact_hash) { 342 void ExpectDecodedAudio(size_t i, const std::string& exact_hash) {
326 CHECK_LT(i, decoded_audio_.size()); 343 CHECK_LT(i, decoded_audio_.size());
327 const scoped_refptr<AudioBuffer>& buffer = decoded_audio_[i]; 344 const scoped_refptr<AudioBuffer>& buffer = decoded_audio_[i];
328 345
329 const DecodedBufferExpectations& sample_info = GetParam().expectations[i]; 346 const DecodedBufferExpectations& sample_info = params_.expectations[i];
330 347
331 // Android MediaCodec returns wrong timestamps (shifted one frame forward) 348 // Android MediaCodec returns wrong timestamps (shifted one frame forward)
332 // for AAC before Android L. Ignore sample_info.timestamp in this situation. 349 // for AAC before Android L. Ignore sample_info.timestamp in this situation.
333 if (!SkipBufferTimestampCheck()) 350 if (!SkipBufferTimestampCheck())
334 EXPECT_EQ(sample_info.timestamp, buffer->timestamp().InMicroseconds()); 351 EXPECT_EQ(sample_info.timestamp, buffer->timestamp().InMicroseconds());
335 EXPECT_EQ(sample_info.duration, buffer->duration().InMicroseconds()); 352 EXPECT_EQ(sample_info.duration, buffer->duration().InMicroseconds());
336 EXPECT_FALSE(buffer->end_of_stream()); 353 EXPECT_FALSE(buffer->end_of_stream());
337 354
338 std::unique_ptr<AudioBus> output = 355 std::unique_ptr<AudioBus> output =
339 AudioBus::Create(buffer->channel_count(), buffer->frame_count()); 356 AudioBus::Create(buffer->channel_count(), buffer->frame_count());
(...skipping 17 matching lines...) Expand all
357 } 374 }
358 375
359 size_t decoded_audio_size() const { return decoded_audio_.size(); } 376 size_t decoded_audio_size() const { return decoded_audio_.size(); }
360 base::TimeDelta start_timestamp() const { return start_timestamp_; } 377 base::TimeDelta start_timestamp() const { return start_timestamp_; }
361 const scoped_refptr<AudioBuffer>& decoded_audio(size_t i) { 378 const scoped_refptr<AudioBuffer>& decoded_audio(size_t i) {
362 return decoded_audio_[i]; 379 return decoded_audio_[i];
363 } 380 }
364 DecodeStatus last_decode_status() const { return last_decode_status_; } 381 DecodeStatus last_decode_status() const { return last_decode_status_; }
365 382
366 private: 383 private:
384 const AudioDecoderType decoder_type_;
385
386 // Current TestParams used to initialize the test and decoder. The initial
387 // valie is std::get<1>(GetParam()). Could be overridden by set_param() so
388 // that the decoder can be reinitialized with different parameters.
389 TestParams params_;
390
367 base::MessageLoop message_loop_; 391 base::MessageLoop message_loop_;
392
368 scoped_refptr<DecoderBuffer> data_; 393 scoped_refptr<DecoderBuffer> data_;
369 std::unique_ptr<InMemoryUrlProtocol> protocol_; 394 std::unique_ptr<InMemoryUrlProtocol> protocol_;
370 std::unique_ptr<AudioFileReader> reader_; 395 std::unique_ptr<AudioFileReader> reader_;
371 396
372 std::unique_ptr<AudioDecoder> decoder_; 397 std::unique_ptr<AudioDecoder> decoder_;
373 bool pending_decode_; 398 bool pending_decode_;
374 bool pending_reset_; 399 bool pending_reset_;
375 DecodeStatus last_decode_status_; 400 DecodeStatus last_decode_status_;
376 401
377 std::deque<scoped_refptr<AudioBuffer> > decoded_audio_; 402 std::deque<scoped_refptr<AudioBuffer> > decoded_audio_;
378 base::TimeDelta start_timestamp_; 403 base::TimeDelta start_timestamp_;
379 404
380 DISALLOW_COPY_AND_ASSIGN(AudioDecoderTest); 405 DISALLOW_COPY_AND_ASSIGN(AudioDecoderTest);
381 }; 406 };
382 407
383 TEST_P(AudioDecoderTest, Initialize) {
384 SKIP_TEST_IF_NO_MEDIA_CODEC();
385 ASSERT_NO_FATAL_FAILURE(Initialize());
386 }
387
388 // Verifies decode audio as well as the Decode() -> Reset() sequence.
389 TEST_P(AudioDecoderTest, ProduceAudioSamples) {
390 SKIP_TEST_IF_NO_MEDIA_CODEC();
391 ASSERT_NO_FATAL_FAILURE(Initialize());
392
393 // Run the test multiple times with a seek back to the beginning in between.
394 std::vector<std::string> decoded_audio_md5_hashes;
395 for (int i = 0; i < 2; ++i) {
396 // Run decoder until we get at least |kDecodeRuns| output buffers.
397 // Keeping Decode() in a loop seems to be the simplest way to guarantee that
398 // the predefined number of output buffers are produced without draining
399 // (i.e. decoding EOS).
400 do {
401 Decode();
402 ASSERT_EQ(last_decode_status(), DecodeStatus::OK);
403 } while (decoded_audio_size() < kDecodeRuns);
404
405 // With MediaCodecAudioDecoder the output buffers might appear after
406 // some delay. Since we keep decoding in a loop, the number of output
407 // buffers when they eventually appear might exceed |kDecodeRuns|.
408 ASSERT_LE(kDecodeRuns, decoded_audio_size());
409
410 // On the first pass record the exact MD5 hash for each decoded buffer.
411 if (i == 0) {
412 for (size_t j = 0; j < kDecodeRuns; ++j)
413 decoded_audio_md5_hashes.push_back(GetDecodedAudioMD5(j));
414 }
415
416 // On the first pass verify the basic audio hash and sample info. On the
417 // second, verify the exact MD5 sum for each packet. It shouldn't change.
418 for (size_t j = 0; j < kDecodeRuns; ++j) {
419 SCOPED_TRACE(base::StringPrintf("i = %d, j = %" PRIuS, i, j));
420 ExpectDecodedAudio(j, i == 0 ? "" : decoded_audio_md5_hashes[j]);
421 }
422
423 SendEndOfStream();
424
425 // Seek back to the beginning. Calls Reset() on the decoder.
426 Seek(start_timestamp());
427 }
428 }
429
430 TEST_P(AudioDecoderTest, Decode) {
431 SKIP_TEST_IF_NO_MEDIA_CODEC();
432 ASSERT_NO_FATAL_FAILURE(Initialize());
433 Decode();
434 EXPECT_EQ(DecodeStatus::OK, last_decode_status());
435 }
436
437 TEST_P(AudioDecoderTest, Reset) {
438 SKIP_TEST_IF_NO_MEDIA_CODEC();
439 ASSERT_NO_FATAL_FAILURE(Initialize());
440 Reset();
441 }
442
443 TEST_P(AudioDecoderTest, NoTimestamp) {
444 SKIP_TEST_IF_NO_MEDIA_CODEC();
445 ASSERT_NO_FATAL_FAILURE(Initialize());
446 scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(0));
447 buffer->set_timestamp(kNoTimestamp);
448 DecodeBuffer(buffer);
449 EXPECT_EQ(DecodeStatus::DECODE_ERROR, last_decode_status());
450 }
451
452 const DecodedBufferExpectations kBearOpusExpectations[] = { 408 const DecodedBufferExpectations kBearOpusExpectations[] = {
453 {500, 3500, "-0.26,0.87,1.36,0.84,-0.30,-1.22,"}, 409 {500, 3500, "-0.26,0.87,1.36,0.84,-0.30,-1.22,"},
454 {4000, 10000, "0.09,0.23,0.21,0.03,-0.17,-0.24,"}, 410 {4000, 10000, "0.09,0.23,0.21,0.03,-0.17,-0.24,"},
455 {14000, 10000, "0.10,0.24,0.23,0.04,-0.14,-0.23,"}, 411 {14000, 10000, "0.10,0.24,0.23,0.04,-0.14,-0.23,"},
456 }; 412 };
457 413
414 // Test params to test decoder reinitialization. Choose opus because it is
415 // supported on all platforms we test on.
416 const TestParams kReinitializeTestParams = {
417 kCodecOpus, "bear-opus.ogg", kBearOpusExpectations,
418 24, 48000, CHANNEL_LAYOUT_STEREO};
419
458 #if defined(OS_ANDROID) 420 #if defined(OS_ANDROID)
459 #if defined(USE_PROPRIETARY_CODECS) 421 #if defined(USE_PROPRIETARY_CODECS)
460 const DecodedBufferExpectations kSfxAdtsMcExpectations[] = { 422 const DecodedBufferExpectations kSfxAdtsMcExpectations[] = {
461 {0, 23219, "-1.80,-1.49,-0.23,1.11,1.54,-0.11,"}, 423 {0, 23219, "-1.80,-1.49,-0.23,1.11,1.54,-0.11,"},
462 {23219, 23219, "-1.90,-1.53,-0.15,1.28,1.23,-0.33,"}, 424 {23219, 23219, "-1.90,-1.53,-0.15,1.28,1.23,-0.33,"},
463 {46439, 23219, "0.54,0.88,2.19,3.54,3.24,1.63,"}, 425 {46439, 23219, "0.54,0.88,2.19,3.54,3.24,1.63,"},
464 }; 426 };
465 427
466 const DecodedBufferExpectations kHeAacMcExpectations[] = { 428 const DecodedBufferExpectations kHeAacMcExpectations[] = {
467 {0, 42666, "-1.76,-0.12,1.72,1.45,0.10,-1.32,"}, 429 {0, 42666, "-1.76,-0.12,1.72,1.45,0.10,-1.32,"},
468 {42666, 42666, "-1.78,-0.13,1.70,1.44,0.09,-1.32,"}, 430 {42666, 42666, "-1.78,-0.13,1.70,1.44,0.09,-1.32,"},
469 {85333, 42666, "-1.78,-0.13,1.70,1.44,0.08,-1.33,"}, 431 {85333, 42666, "-1.78,-0.13,1.70,1.44,0.08,-1.33,"},
470 }; 432 };
471 #endif 433 #endif // defined(USE_PROPRIETARY_CODECS)
472 434
473 const DecoderTestData kMediaCodecTests[] = { 435 const TestParams kMediaCodecTestParams[] = {
474 {MEDIA_CODEC, kCodecOpus, "bear-opus.ogg", kBearOpusExpectations, 24, 48000, 436 {kCodecOpus, "bear-opus.ogg", kBearOpusExpectations, 24, 48000,
475 CHANNEL_LAYOUT_STEREO}, 437 CHANNEL_LAYOUT_STEREO},
476 #if defined(USE_PROPRIETARY_CODECS) 438 #if defined(USE_PROPRIETARY_CODECS)
477 {MEDIA_CODEC, kCodecAAC, "sfx.adts", kSfxAdtsMcExpectations, 0, 44100, 439 {kCodecAAC, "sfx.adts", kSfxAdtsMcExpectations, 0, 44100,
478 CHANNEL_LAYOUT_MONO}, 440 CHANNEL_LAYOUT_MONO},
479 {MEDIA_CODEC, kCodecAAC, "bear-audio-implicit-he-aac-v2.aac", 441 {kCodecAAC, "bear-audio-implicit-he-aac-v2.aac", kHeAacMcExpectations, 0,
480 kHeAacMcExpectations, 0, 24000, CHANNEL_LAYOUT_MONO}, 442 24000, CHANNEL_LAYOUT_MONO},
481 #endif 443 #endif // defined(USE_PROPRIETARY_CODECS)
482 }; 444 };
483 445
484 INSTANTIATE_TEST_CASE_P(MediaCodec,
485 AudioDecoderTest,
486 testing::ValuesIn(kMediaCodecTests));
487 #endif // defined(OS_ANDROID) 446 #endif // defined(OS_ANDROID)
488 447
489 #if defined(USE_PROPRIETARY_CODECS) 448 #if defined(USE_PROPRIETARY_CODECS)
490 const DecodedBufferExpectations kSfxMp3Expectations[] = { 449 const DecodedBufferExpectations kSfxMp3Expectations[] = {
491 {0, 1065, "2.81,3.99,4.53,4.10,3.08,2.46,"}, 450 {0, 1065, "2.81,3.99,4.53,4.10,3.08,2.46,"},
492 {1065, 26122, "-3.81,-4.14,-3.90,-3.36,-3.03,-3.23,"}, 451 {1065, 26122, "-3.81,-4.14,-3.90,-3.36,-3.03,-3.23,"},
493 {27188, 26122, "4.24,3.95,4.22,4.78,5.13,4.93,"}, 452 {27188, 26122, "4.24,3.95,4.22,4.78,5.13,4.93,"},
494 }; 453 };
495 454
496 const DecodedBufferExpectations kSfxAdtsExpectations[] = { 455 const DecodedBufferExpectations kSfxAdtsExpectations[] = {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 {33500, 20000, "-3.44,-3.34,-3.57,-4.11,-4.74,-5.13,"}, 496 {33500, 20000, "-3.44,-3.34,-3.57,-4.11,-4.74,-5.13,"},
538 }; 497 };
539 #else 498 #else
540 const DecodedBufferExpectations kSfxOpusExpectations[] = { 499 const DecodedBufferExpectations kSfxOpusExpectations[] = {
541 {0, 13500, "-2.70,-1.41,-0.78,-1.27,-2.56,-3.73,"}, 500 {0, 13500, "-2.70,-1.41,-0.78,-1.27,-2.56,-3.73,"},
542 {13500, 20000, "5.48,5.93,6.04,5.83,5.54,5.45,"}, 501 {13500, 20000, "5.48,5.93,6.04,5.83,5.54,5.45,"},
543 {33500, 20000, "-3.45,-3.35,-3.57,-4.12,-4.74,-5.14,"}, 502 {33500, 20000, "-3.45,-3.35,-3.57,-4.12,-4.74,-5.14,"},
544 }; 503 };
545 #endif 504 #endif
546 505
547 const DecoderTestData kFFmpegTests[] = { 506 const TestParams kFFmpegTestParams[] = {
548 #if defined(USE_PROPRIETARY_CODECS) 507 #if defined(USE_PROPRIETARY_CODECS)
549 {FFMPEG, kCodecMP3, "sfx.mp3", kSfxMp3Expectations, 0, 44100, 508 {kCodecMP3, "sfx.mp3", kSfxMp3Expectations, 0, 44100, CHANNEL_LAYOUT_MONO},
550 CHANNEL_LAYOUT_MONO}, 509 {kCodecAAC, "sfx.adts", kSfxAdtsExpectations, 0, 44100,
551 {FFMPEG, kCodecAAC, "sfx.adts", kSfxAdtsExpectations, 0, 44100,
552 CHANNEL_LAYOUT_MONO}, 510 CHANNEL_LAYOUT_MONO},
553 #endif 511 #endif
554 {FFMPEG, kCodecFLAC, "sfx.flac", kSfxFlacExpectations, 0, 44100, 512 {kCodecFLAC, "sfx.flac", kSfxFlacExpectations, 0, 44100,
555 CHANNEL_LAYOUT_MONO}, 513 CHANNEL_LAYOUT_MONO},
556 {FFMPEG, kCodecPCM, "sfx_f32le.wav", kSfxWaveExpectations, 0, 44100, 514 {kCodecPCM, "sfx_f32le.wav", kSfxWaveExpectations, 0, 44100,
557 CHANNEL_LAYOUT_MONO}, 515 CHANNEL_LAYOUT_MONO},
558 {FFMPEG, kCodecPCM, "4ch.wav", kFourChannelWaveExpectations, 0, 44100, 516 {kCodecPCM, "4ch.wav", kFourChannelWaveExpectations, 0, 44100,
559 CHANNEL_LAYOUT_QUAD}, 517 CHANNEL_LAYOUT_QUAD},
560 {FFMPEG, kCodecVorbis, "sfx.ogg", kSfxOggExpectations, 0, 44100, 518 {kCodecVorbis, "sfx.ogg", kSfxOggExpectations, 0, 44100,
561 CHANNEL_LAYOUT_MONO}, 519 CHANNEL_LAYOUT_MONO},
562 // Note: bear.ogv is incorrectly muxed such that valid samples are given 520 // Note: bear.ogv is incorrectly muxed such that valid samples are given
563 // negative timestamps, this marks them for discard per the ogg vorbis spec. 521 // negative timestamps, this marks them for discard per the ogg vorbis spec.
564 {FFMPEG, kCodecVorbis, "bear.ogv", kBearOgvExpectations, -704, 44100, 522 {kCodecVorbis, "bear.ogv", kBearOgvExpectations, -704, 44100,
565 CHANNEL_LAYOUT_STEREO}, 523 CHANNEL_LAYOUT_STEREO},
566 {FFMPEG, kCodecOpus, "sfx-opus.ogg", kSfxOpusExpectations, -312, 48000, 524 {kCodecOpus, "sfx-opus.ogg", kSfxOpusExpectations, -312, 48000,
567 CHANNEL_LAYOUT_MONO}, 525 CHANNEL_LAYOUT_MONO},
568 {FFMPEG, kCodecOpus, "bear-opus.ogg", kBearOpusExpectations, 24, 48000, 526 {kCodecOpus, "bear-opus.ogg", kBearOpusExpectations, 24, 48000,
569 CHANNEL_LAYOUT_STEREO}, 527 CHANNEL_LAYOUT_STEREO},
570 }; 528 };
571 529
530 TEST_P(AudioDecoderTest, Initialize) {
531 SKIP_TEST_IF_NOT_SUPPORTED();
532 ASSERT_NO_FATAL_FAILURE(Initialize());
533 }
534
535 TEST_P(AudioDecoderTest, Reinitialize) {
536 SKIP_TEST_IF_NOT_SUPPORTED();
537 ASSERT_NO_FATAL_FAILURE(Initialize());
538 Decode();
539 Reset();
540
541 // Use a different TestParams to reinitialize the decoder.
542 set_params(kReinitializeTestParams);
543
544 SKIP_TEST_IF_NOT_SUPPORTED();
545 ASSERT_NO_FATAL_FAILURE(Initialize());
546 Decode();
547 Reset();
548 }
549
550 // Verifies decode audio as well as the Decode() -> Reset() sequence.
551 TEST_P(AudioDecoderTest, ProduceAudioSamples) {
552 SKIP_TEST_IF_NOT_SUPPORTED();
553 ASSERT_NO_FATAL_FAILURE(Initialize());
554
555 // Run the test multiple times with a seek back to the beginning in between.
556 std::vector<std::string> decoded_audio_md5_hashes;
557 for (int i = 0; i < 2; ++i) {
558 // Run decoder until we get at least |kDecodeRuns| output buffers.
559 // Keeping Decode() in a loop seems to be the simplest way to guarantee that
560 // the predefined number of output buffers are produced without draining
561 // (i.e. decoding EOS).
562 do {
563 Decode();
564 ASSERT_EQ(last_decode_status(), DecodeStatus::OK);
565 } while (decoded_audio_size() < kDecodeRuns);
566
567 // With MediaCodecAudioDecoder the output buffers might appear after
568 // some delay. Since we keep decoding in a loop, the number of output
569 // buffers when they eventually appear might exceed |kDecodeRuns|.
570 ASSERT_LE(kDecodeRuns, decoded_audio_size());
571
572 // On the first pass record the exact MD5 hash for each decoded buffer.
573 if (i == 0) {
574 for (size_t j = 0; j < kDecodeRuns; ++j)
575 decoded_audio_md5_hashes.push_back(GetDecodedAudioMD5(j));
576 }
577
578 // On the first pass verify the basic audio hash and sample info. On the
579 // second, verify the exact MD5 sum for each packet. It shouldn't change.
580 for (size_t j = 0; j < kDecodeRuns; ++j) {
581 SCOPED_TRACE(base::StringPrintf("i = %d, j = %" PRIuS, i, j));
582 ExpectDecodedAudio(j, i == 0 ? "" : decoded_audio_md5_hashes[j]);
583 }
584
585 SendEndOfStream();
586
587 // Seek back to the beginning. Calls Reset() on the decoder.
588 Seek(start_timestamp());
589 }
590 }
591
592 TEST_P(AudioDecoderTest, Decode) {
593 SKIP_TEST_IF_NOT_SUPPORTED();
594 ASSERT_NO_FATAL_FAILURE(Initialize());
595 Decode();
596 EXPECT_EQ(DecodeStatus::OK, last_decode_status());
597 }
598
599 TEST_P(AudioDecoderTest, Reset) {
600 SKIP_TEST_IF_NOT_SUPPORTED();
601 ASSERT_NO_FATAL_FAILURE(Initialize());
602 Reset();
603 }
604
605 TEST_P(AudioDecoderTest, NoTimestamp) {
606 SKIP_TEST_IF_NOT_SUPPORTED();
607 ASSERT_NO_FATAL_FAILURE(Initialize());
608 scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(0));
609 buffer->set_timestamp(kNoTimestamp);
610 DecodeBuffer(buffer);
611 EXPECT_EQ(DecodeStatus::DECODE_ERROR, last_decode_status());
612 }
613
572 INSTANTIATE_TEST_CASE_P(FFmpeg, 614 INSTANTIATE_TEST_CASE_P(FFmpeg,
573 AudioDecoderTest, 615 AudioDecoderTest,
574 testing::ValuesIn(kFFmpegTests)); 616 Combine(Values(FFMPEG), ValuesIn(kFFmpegTestParams)));
617
618 #if defined(OS_ANDROID)
619 INSTANTIATE_TEST_CASE_P(MediaCodec,
620 AudioDecoderTest,
621 Combine(Values(MEDIA_CODEC),
622 ValuesIn(kMediaCodecTestParams)));
623 #endif // defined(OS_ANDROID)
575 624
576 } // namespace media 625 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698