1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h"
10 #include "base/strings/stringprintf.h"
11 #include "media/base/audio_buffer.h"
12 #include "media/base/decoder_buffer.h"
13 #include "media/base/mock_filters.h"
14 #include "media/base/test_data_util.h"
15 #include "media/base/test_helpers.h"
16 #include "media/ffmpeg/ffmpeg_common.h"
17 #include "media/filters/ffmpeg_audio_decoder.h"
18 #include "media/filters/ffmpeg_glue.h"
19 #include "testing/gtest/include/gtest/gtest.h"
22 using ::testing::StrictMock;
26 class FFmpegAudioDecoderTest : public testing::Test {
28 FFmpegAudioDecoderTest()
29 : decoder_(new FFmpegAudioDecoder(message_loop_.message_loop_proxy(),
31 pending_decode_(false),
32 pending_reset_(false) {
33 FFmpegGlue::InitializeFFmpeg();
35 vorbis_extradata_ = ReadTestDataFile("vorbis-extradata");
37 // Refer to media/test/data/README for details on vorbis test data.
38 for (int i = 0; i < 4; ++i) {
39 scoped_refptr<DecoderBuffer> buffer =
40 ReadTestDataFile(base::StringPrintf("vorbis-packet-%d", i));
43 buffer->set_timestamp(base::TimeDelta());
45 buffer->set_timestamp(base::TimeDelta::FromMicroseconds(2902));
48 buffer->set_duration(base::TimeDelta());
49 encoded_audio_.push_back(buffer);
52 // Push in an EOS buffer.
53 encoded_audio_.push_back(DecoderBuffer::CreateEOSBuffer());
58 virtual ~FFmpegAudioDecoderTest() {
59 EXPECT_FALSE(pending_decode_);
60 EXPECT_FALSE(pending_reset_);
64 AudioDecoderConfig config(kCodecVorbis,
65 kSampleFormatPlanarF32,
66 CHANNEL_LAYOUT_STEREO,
68 vorbis_extradata_->data(),
69 vorbis_extradata_->data_size(),
70 false); // Not encrypted.
71 decoder_->Initialize(config,
72 NewExpectedStatusCB(PIPELINE_OK));
73 base::RunLoop().RunUntilIdle();
76 void SatisfyPendingDecode() {
77 base::RunLoop().RunUntilIdle();
81 pending_decode_ = true;
82 scoped_refptr<DecoderBuffer> buffer(encoded_audio_.front());
83 encoded_audio_.pop_front();
84 decoder_->Decode(buffer,
85 base::Bind(&FFmpegAudioDecoderTest::DecodeFinished,
86 base::Unretained(this)));
87 base::RunLoop().RunUntilIdle();
91 pending_reset_ = true;
92 decoder_->Reset(base::Bind(
93 &FFmpegAudioDecoderTest::ResetFinished, base::Unretained(this)));
94 base::RunLoop().RunUntilIdle();
99 base::RunLoop().RunUntilIdle();
102 void DecodeFinished(AudioDecoder::Status status,
103 const scoped_refptr<AudioBuffer>& buffer) {
104 EXPECT_TRUE(pending_decode_);
105 pending_decode_ = false;
107 if (status == AudioDecoder::kNotEnoughData) {
108 EXPECT_TRUE(buffer.get() == NULL);
113 decoded_audio_.push_back(buffer);
115 // If we hit a NULL buffer or have a pending reset, we expect an abort.
116 if (buffer.get() == NULL || pending_reset_) {
117 EXPECT_TRUE(buffer.get() == NULL);
118 EXPECT_EQ(status, AudioDecoder::kAborted);
122 EXPECT_EQ(status, AudioDecoder::kOk);
125 void ResetFinished() {
126 EXPECT_TRUE(pending_reset_);
127 // Reset should always finish after Decode.
128 EXPECT_FALSE(pending_decode_);
130 pending_reset_ = false;
133 void ExpectDecodedAudio(size_t i, int64 timestamp, int64 duration) {
134 EXPECT_LT(i, decoded_audio_.size());
135 EXPECT_EQ(timestamp, decoded_audio_[i]->timestamp().InMicroseconds());
136 EXPECT_EQ(duration, decoded_audio_[i]->duration().InMicroseconds());
137 EXPECT_FALSE(decoded_audio_[i]->end_of_stream());
140 void ExpectEndOfStream(size_t i) {
141 EXPECT_LT(i, decoded_audio_.size());
142 EXPECT_TRUE(decoded_audio_[i]->end_of_stream());
145 base::MessageLoop message_loop_;
146 scoped_ptr<FFmpegAudioDecoder> decoder_;
147 bool pending_decode_;
150 scoped_refptr<DecoderBuffer> vorbis_extradata_;
152 std::deque<scoped_refptr<DecoderBuffer> > encoded_audio_;
153 std::deque<scoped_refptr<AudioBuffer> > decoded_audio_;
156 TEST_F(FFmpegAudioDecoderTest, Initialize) {
157 AudioDecoderConfig config(kCodecVorbis,
158 kSampleFormatPlanarF32,
159 CHANNEL_LAYOUT_STEREO,
161 vorbis_extradata_->data(),
162 vorbis_extradata_->data_size(),
163 false); // Not encrypted.
167 TEST_F(FFmpegAudioDecoderTest, ProduceAudioSamples) {
168 // Vorbis requires N+1 packets to produce audio data for N packets.
170 // This will should result in the demuxer receiving three reads for two
171 // requests to produce audio samples.
176 ASSERT_EQ(3u, decoded_audio_.size());
177 ExpectDecodedAudio(0, 0, 2902);
178 ExpectDecodedAudio(1, 2902, 13061);
179 ExpectDecodedAudio(2, 15963, 23219);
181 // Call one more time to trigger EOS.
183 ASSERT_EQ(4u, decoded_audio_.size());
184 ExpectEndOfStream(3);
188 TEST_F(FFmpegAudioDecoderTest, DecodeAbort) {
189 encoded_audio_.clear();
190 encoded_audio_.push_back(NULL);
193 EXPECT_EQ(decoded_audio_.size(), 1u);
194 EXPECT_TRUE(decoded_audio_[0].get() == NULL);
198 TEST_F(FFmpegAudioDecoderTest, PendingDecode_Stop) {
201 SatisfyPendingDecode();
204 TEST_F(FFmpegAudioDecoderTest, PendingDecode_Reset) {
207 SatisfyPendingDecode();
211 TEST_F(FFmpegAudioDecoderTest, PendingDecode_ResetStop) {
215 SatisfyPendingDecode();