Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / media / filters / ffmpeg_audio_decoder_unittest.cc
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.
4
5 #include <deque>
6
7 #include "base/bind.h"
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"
20
21 using ::testing::_;
22 using ::testing::StrictMock;
23
24 namespace media {
25
26 class FFmpegAudioDecoderTest : public testing::Test {
27  public:
28   FFmpegAudioDecoderTest()
29       : decoder_(new FFmpegAudioDecoder(message_loop_.message_loop_proxy(),
30                                         LogCB())),
31         pending_decode_(false),
32         pending_reset_(false) {
33     FFmpegGlue::InitializeFFmpeg();
34
35     vorbis_extradata_ = ReadTestDataFile("vorbis-extradata");
36
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));
41
42       if (i < 3) {
43         buffer->set_timestamp(base::TimeDelta());
44       } else {
45         buffer->set_timestamp(base::TimeDelta::FromMicroseconds(2902));
46       }
47
48       buffer->set_duration(base::TimeDelta());
49       encoded_audio_.push_back(buffer);
50     }
51
52     // Push in an EOS buffer.
53     encoded_audio_.push_back(DecoderBuffer::CreateEOSBuffer());
54
55     Initialize();
56   }
57
58   virtual ~FFmpegAudioDecoderTest() {
59     EXPECT_FALSE(pending_decode_);
60     EXPECT_FALSE(pending_reset_);
61   }
62
63   void Initialize() {
64     AudioDecoderConfig config(kCodecVorbis,
65                               kSampleFormatPlanarF32,
66                               CHANNEL_LAYOUT_STEREO,
67                               44100,
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();
74   }
75
76   void SatisfyPendingDecode() {
77     base::RunLoop().RunUntilIdle();
78   }
79
80   void Decode() {
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();
88   }
89
90   void Reset() {
91     pending_reset_ = true;
92     decoder_->Reset(base::Bind(
93         &FFmpegAudioDecoderTest::ResetFinished, base::Unretained(this)));
94     base::RunLoop().RunUntilIdle();
95   }
96
97   void Stop() {
98     decoder_->Stop();
99     base::RunLoop().RunUntilIdle();
100   }
101
102   void DecodeFinished(AudioDecoder::Status status,
103                       const scoped_refptr<AudioBuffer>& buffer) {
104     EXPECT_TRUE(pending_decode_);
105     pending_decode_ = false;
106
107     if (status == AudioDecoder::kNotEnoughData) {
108       EXPECT_TRUE(buffer.get() == NULL);
109       Decode();
110       return;
111     }
112
113     decoded_audio_.push_back(buffer);
114
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);
119       return;
120     }
121
122     EXPECT_EQ(status, AudioDecoder::kOk);
123   }
124
125   void ResetFinished() {
126     EXPECT_TRUE(pending_reset_);
127     // Reset should always finish after Decode.
128     EXPECT_FALSE(pending_decode_);
129
130     pending_reset_ = false;
131   }
132
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());
138   }
139
140   void ExpectEndOfStream(size_t i) {
141     EXPECT_LT(i, decoded_audio_.size());
142     EXPECT_TRUE(decoded_audio_[i]->end_of_stream());
143   }
144
145   base::MessageLoop message_loop_;
146   scoped_ptr<FFmpegAudioDecoder> decoder_;
147   bool pending_decode_;
148   bool pending_reset_;
149
150   scoped_refptr<DecoderBuffer> vorbis_extradata_;
151
152   std::deque<scoped_refptr<DecoderBuffer> > encoded_audio_;
153   std::deque<scoped_refptr<AudioBuffer> > decoded_audio_;
154 };
155
156 TEST_F(FFmpegAudioDecoderTest, Initialize) {
157   AudioDecoderConfig config(kCodecVorbis,
158                             kSampleFormatPlanarF32,
159                             CHANNEL_LAYOUT_STEREO,
160                             44100,
161                             vorbis_extradata_->data(),
162                             vorbis_extradata_->data_size(),
163                             false);  // Not encrypted.
164   Stop();
165 }
166
167 TEST_F(FFmpegAudioDecoderTest, ProduceAudioSamples) {
168   // Vorbis requires N+1 packets to produce audio data for N packets.
169   //
170   // This will should result in the demuxer receiving three reads for two
171   // requests to produce audio samples.
172   Decode();
173   Decode();
174   Decode();
175
176   ASSERT_EQ(3u, decoded_audio_.size());
177   ExpectDecodedAudio(0, 0, 2902);
178   ExpectDecodedAudio(1, 2902, 13061);
179   ExpectDecodedAudio(2, 15963, 23219);
180
181   // Call one more time to trigger EOS.
182   Decode();
183   ASSERT_EQ(4u, decoded_audio_.size());
184   ExpectEndOfStream(3);
185   Stop();
186 }
187
188 TEST_F(FFmpegAudioDecoderTest, DecodeAbort) {
189   encoded_audio_.clear();
190   encoded_audio_.push_back(NULL);
191   Decode();
192
193   EXPECT_EQ(decoded_audio_.size(), 1u);
194   EXPECT_TRUE(decoded_audio_[0].get() ==  NULL);
195   Stop();
196 }
197
198 TEST_F(FFmpegAudioDecoderTest, PendingDecode_Stop) {
199   Decode();
200   Stop();
201   SatisfyPendingDecode();
202 }
203
204 TEST_F(FFmpegAudioDecoderTest, PendingDecode_Reset) {
205   Decode();
206   Reset();
207   SatisfyPendingDecode();
208   Stop();
209 }
210
211 TEST_F(FFmpegAudioDecoderTest, PendingDecode_ResetStop) {
212   Decode();
213   Reset();
214   Stop();
215   SatisfyPendingDecode();
216 }
217
218 }  // namespace media