Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / media / cast / audio_sender / audio_encoder_unittest.cc
1 // Copyright 2013 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 <sstream>
6 #include <string>
7
8 #include "base/bind.h"
9 #include "base/bind_helpers.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "media/base/audio_bus.h"
12 #include "media/base/media.h"
13 #include "media/cast/audio_sender/audio_encoder.h"
14 #include "media/cast/cast_config.h"
15 #include "media/cast/cast_environment.h"
16 #include "media/cast/test/fake_single_thread_task_runner.h"
17 #include "media/cast/test/utility/audio_utility.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 namespace media {
21 namespace cast {
22
23 static const int64 kStartMillisecond = GG_INT64_C(12345678900000);
24
25 namespace {
26
27 class TestEncodedAudioFrameReceiver {
28  public:
29   explicit TestEncodedAudioFrameReceiver(transport::AudioCodec codec)
30       : codec_(codec), frames_received_(0) {}
31   virtual ~TestEncodedAudioFrameReceiver() {}
32
33   int frames_received() const { return frames_received_; }
34
35   void SetRecordedTimeLowerBound(const base::TimeTicks& t) { lower_bound_ = t; }
36
37   void SetRecordedTimeUpperBound(const base::TimeTicks& t) { upper_bound_ = t; }
38
39   void FrameEncoded(scoped_ptr<transport::EncodedAudioFrame> encoded_frame,
40                     const base::TimeTicks& recorded_time) {
41     EXPECT_EQ(codec_, encoded_frame->codec);
42     EXPECT_EQ(static_cast<uint8>(frames_received_ & 0xff),
43               encoded_frame->frame_id);
44     EXPECT_LT(0u, encoded_frame->rtp_timestamp);
45     EXPECT_TRUE(!encoded_frame->data.empty());
46
47     EXPECT_LE(lower_bound_, recorded_time);
48     lower_bound_ = recorded_time;
49     EXPECT_GT(upper_bound_, recorded_time);
50
51     ++frames_received_;
52   }
53
54  private:
55   const transport::AudioCodec codec_;
56   int frames_received_;
57   base::TimeTicks lower_bound_;
58   base::TimeTicks upper_bound_;
59
60   DISALLOW_COPY_AND_ASSIGN(TestEncodedAudioFrameReceiver);
61 };
62
63 struct TestScenario {
64   const int64* durations_in_ms;
65   size_t num_durations;
66
67   TestScenario(const int64* d, size_t n)
68       : durations_in_ms(d), num_durations(n) {}
69
70   std::string ToString() const {
71     std::ostringstream out;
72     for (size_t i = 0; i < num_durations; ++i) {
73       if (i > 0)
74         out << ", ";
75       out << durations_in_ms[i];
76     }
77     return out.str();
78   }
79 };
80
81 }  // namespace
82
83 class AudioEncoderTest : public ::testing::TestWithParam<TestScenario> {
84  public:
85   AudioEncoderTest() {
86     InitializeMediaLibraryForTesting();
87     testing_clock_ = new base::SimpleTestTickClock();
88     testing_clock_->Advance(
89         base::TimeDelta::FromMilliseconds(kStartMillisecond));
90   }
91
92   virtual void SetUp() {
93     task_runner_ = new test::FakeSingleThreadTaskRunner(testing_clock_);
94     cast_environment_ =
95         new CastEnvironment(scoped_ptr<base::TickClock>(testing_clock_).Pass(),
96                             task_runner_,
97                             task_runner_,
98                             task_runner_,
99                             task_runner_,
100                             task_runner_,
101                             task_runner_,
102                             GetDefaultCastSenderLoggingConfig());
103   }
104
105   virtual ~AudioEncoderTest() {}
106
107   void RunTestForCodec(transport::AudioCodec codec) {
108     const TestScenario& scenario = GetParam();
109     SCOPED_TRACE(::testing::Message() << "Durations: " << scenario.ToString());
110
111     CreateObjectsForCodec(codec);
112
113     receiver_->SetRecordedTimeLowerBound(testing_clock_->NowTicks());
114     for (size_t i = 0; i < scenario.num_durations; ++i) {
115       const base::TimeDelta duration =
116           base::TimeDelta::FromMilliseconds(scenario.durations_in_ms[i]);
117       receiver_->SetRecordedTimeUpperBound(testing_clock_->NowTicks() +
118                                            duration);
119
120       const scoped_ptr<AudioBus> bus(
121           audio_bus_factory_->NextAudioBus(duration));
122
123       const int last_count = release_callback_count_;
124       audio_encoder_->InsertAudio(
125           bus.get(),
126           testing_clock_->NowTicks(),
127           base::Bind(&AudioEncoderTest::IncrementReleaseCallbackCounter,
128                      base::Unretained(this)));
129       task_runner_->RunTasks();
130       EXPECT_EQ(1, release_callback_count_ - last_count)
131           << "Release callback was not invoked once.";
132
133       testing_clock_->Advance(duration);
134     }
135
136     DVLOG(1) << "Received " << receiver_->frames_received()
137              << " frames for this test run: " << scenario.ToString();
138   }
139
140  private:
141   void CreateObjectsForCodec(transport::AudioCodec codec) {
142     AudioSenderConfig audio_config;
143     audio_config.codec = codec;
144     audio_config.use_external_encoder = false;
145     audio_config.frequency = kDefaultAudioSamplingRate;
146     audio_config.channels = 2;
147     audio_config.bitrate = kDefaultAudioEncoderBitrate;
148     audio_config.rtp_config.payload_type = 127;
149
150     audio_bus_factory_.reset(
151         new TestAudioBusFactory(audio_config.channels,
152                                 audio_config.frequency,
153                                 TestAudioBusFactory::kMiddleANoteFreq,
154                                 0.5f));
155
156     receiver_.reset(new TestEncodedAudioFrameReceiver(codec));
157
158     audio_encoder_ = new AudioEncoder(
159         cast_environment_,
160         audio_config,
161         base::Bind(&TestEncodedAudioFrameReceiver::FrameEncoded,
162                    base::Unretained(receiver_.get())));
163     release_callback_count_ = 0;
164   }
165
166   void IncrementReleaseCallbackCounter() { ++release_callback_count_; }
167
168   base::SimpleTestTickClock* testing_clock_;  // Owned by CastEnvironment.
169   scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_;
170   scoped_ptr<TestAudioBusFactory> audio_bus_factory_;
171   scoped_ptr<TestEncodedAudioFrameReceiver> receiver_;
172   scoped_refptr<AudioEncoder> audio_encoder_;
173   scoped_refptr<CastEnvironment> cast_environment_;
174   int release_callback_count_;
175
176   DISALLOW_COPY_AND_ASSIGN(AudioEncoderTest);
177 };
178
179 TEST_P(AudioEncoderTest, EncodeOpus) { RunTestForCodec(transport::kOpus); }
180
181 TEST_P(AudioEncoderTest, EncodePcm16) { RunTestForCodec(transport::kPcm16); }
182
183 static const int64 kOneCall_3Millis[] = {3};
184 static const int64 kOneCall_10Millis[] = {10};
185 static const int64 kOneCall_13Millis[] = {13};
186 static const int64 kOneCall_20Millis[] = {20};
187
188 static const int64 kTwoCalls_3Millis[] = {3, 3};
189 static const int64 kTwoCalls_10Millis[] = {10, 10};
190 static const int64 kTwoCalls_Mixed1[] = {3, 10};
191 static const int64 kTwoCalls_Mixed2[] = {10, 3};
192 static const int64 kTwoCalls_Mixed3[] = {3, 17};
193 static const int64 kTwoCalls_Mixed4[] = {17, 3};
194
195 static const int64 kManyCalls_3Millis[] = {3, 3, 3, 3, 3, 3, 3, 3,
196                                            3, 3, 3, 3, 3, 3, 3};
197 static const int64 kManyCalls_10Millis[] = {10, 10, 10, 10, 10, 10, 10, 10,
198                                             10, 10, 10, 10, 10, 10, 10};
199 static const int64 kManyCalls_Mixed1[] = {3,  10, 3,  10, 3,  10, 3,  10, 3,
200                                           10, 3,  10, 3,  10, 3,  10, 3,  10};
201 static const int64 kManyCalls_Mixed2[] = {10, 3, 10, 3, 10, 3, 10, 3, 10, 3,
202                                           10, 3, 10, 3, 10, 3, 10, 3, 10, 3};
203 static const int64 kManyCalls_Mixed3[] = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8,
204                                           9, 7, 9, 3, 2, 3, 8, 4, 6, 2, 6, 4};
205 static const int64 kManyCalls_Mixed4[] = {31, 4, 15, 9,  26, 53, 5,  8, 9,
206                                           7,  9, 32, 38, 4,  62, 64, 3};
207 static const int64 kManyCalls_Mixed5[] = {3, 14, 15, 9, 26, 53, 58, 9, 7,
208                                           9, 3,  23, 8, 4,  6,  2,  6, 43};
209
210 INSTANTIATE_TEST_CASE_P(
211     AudioEncoderTestScenarios,
212     AudioEncoderTest,
213     ::testing::Values(
214         TestScenario(kOneCall_3Millis, arraysize(kOneCall_3Millis)),
215         TestScenario(kOneCall_10Millis, arraysize(kOneCall_10Millis)),
216         TestScenario(kOneCall_13Millis, arraysize(kOneCall_13Millis)),
217         TestScenario(kOneCall_20Millis, arraysize(kOneCall_20Millis)),
218         TestScenario(kTwoCalls_3Millis, arraysize(kTwoCalls_3Millis)),
219         TestScenario(kTwoCalls_10Millis, arraysize(kTwoCalls_10Millis)),
220         TestScenario(kTwoCalls_Mixed1, arraysize(kTwoCalls_Mixed1)),
221         TestScenario(kTwoCalls_Mixed2, arraysize(kTwoCalls_Mixed2)),
222         TestScenario(kTwoCalls_Mixed3, arraysize(kTwoCalls_Mixed3)),
223         TestScenario(kTwoCalls_Mixed4, arraysize(kTwoCalls_Mixed4)),
224         TestScenario(kManyCalls_3Millis, arraysize(kManyCalls_3Millis)),
225         TestScenario(kManyCalls_10Millis, arraysize(kManyCalls_10Millis)),
226         TestScenario(kManyCalls_Mixed1, arraysize(kManyCalls_Mixed1)),
227         TestScenario(kManyCalls_Mixed2, arraysize(kManyCalls_Mixed2)),
228         TestScenario(kManyCalls_Mixed3, arraysize(kManyCalls_Mixed3)),
229         TestScenario(kManyCalls_Mixed4, arraysize(kManyCalls_Mixed4)),
230         TestScenario(kManyCalls_Mixed5, arraysize(kManyCalls_Mixed5))));
231
232 }  // namespace cast
233 }  // namespace media