15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback_helpers.h"
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/run_loop.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "media/base/audio_buffer_converter.h"
10effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "media/base/audio_hardware_config.h"
110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "media/base/audio_splicer.h"
128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "media/base/fake_audio_renderer_sink.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/gmock_callback_support.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/mock_filters.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/test_helpers.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/audio_renderer_impl.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::base::TimeDelta;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::_;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::Return;
22f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using ::testing::SaveArg;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace {
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Since AudioBufferConverter is used due to different input/output sample
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// rates, define some helper types to differentiate between the two.
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)struct InputFrames {
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  explicit InputFrames(int value) : value(value) {}
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int value;
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)struct OutputFrames {
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  explicit OutputFrames(int value) : value(value) {}
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int value;
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Constants to specify the type of audio data used.
437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstatic AudioCodec kCodec = kCodecVorbis;
447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstatic SampleFormat kSampleFormat = kSampleFormatPlanarF32;
457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstatic ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO;
46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochstatic int kChannelCount = 2;
477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstatic int kChannels = ChannelLayoutToChannelCount(kChannelLayout);
487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use a different output sample rate so the AudioBufferConverter is invoked.
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static int kInputSamplesPerSecond = 5000;
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static int kOutputSamplesPerSecond = 10000;
52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ACTION_P(EnterPendingDecoderInitStateAction, test) {
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  test->EnterPendingDecoderInitState(arg1);
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AudioRendererImplTest : public ::testing::Test {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Give the decoder some non-garbage media properties.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AudioRendererImplTest()
61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      : hardware_config_(AudioParameters(), AudioParameters()),
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        demuxer_stream_(DemuxerStream::AUDIO),
630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        decoder_(new MockAudioDecoder()),
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        ended_(false) {
657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    AudioDecoderConfig audio_config(kCodec,
667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                    kSampleFormat,
677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                    kChannelLayout,
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    kInputSamplesPerSecond,
697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                    NULL,
707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                    0,
717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                    false);
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    demuxer_stream_.set_audio_decoder_config(audio_config);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Used to save callbacks and run them at a later time.
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_CALL(*decoder_, Decode(_, _))
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        .WillRepeatedly(Invoke(this, &AudioRendererImplTest::DecodeDecoder));
77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_CALL(*decoder_, Reset(_))
78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .WillRepeatedly(Invoke(this, &AudioRendererImplTest::ResetDecoder));
79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Mock out demuxer reads.
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_CALL(demuxer_stream_, Read(_)).WillRepeatedly(
82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        RunCallback<0>(DemuxerStream::kOk,
83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                       scoped_refptr<DecoderBuffer>(new DecoderBuffer(0))));
840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    EXPECT_CALL(demuxer_stream_, SupportsConfigChanges())
850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        .WillRepeatedly(Return(true));
860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    AudioParameters out_params(AudioParameters::AUDIO_PCM_LOW_LATENCY,
870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                               kChannelLayout,
880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                               kOutputSamplesPerSecond,
890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                               SampleFormatToBytesPerChannel(kSampleFormat) * 8,
900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                               512);
91effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    hardware_config_.UpdateOutputConfig(out_params);
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedVector<AudioDecoder> decoders;
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    decoders.push_back(decoder_);
948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    sink_ = new FakeAudioRendererSink();
95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    renderer_.reset(new AudioRendererImpl(message_loop_.message_loop_proxy(),
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                          sink_.get(),
97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                          decoders.Pass(),
98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                          SetDecryptorReadyCB(),
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                          hardware_config_,
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                          new MediaLog()));
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~AudioRendererImplTest() {
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SCOPED_TRACE("~AudioRendererImplTest()");
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ExpectUnsupportedAudioDecoder() {
108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_CALL(*decoder_, Initialize(_, _, _))
109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        .WillOnce(DoAll(SaveArg<2>(&output_cb_),
110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                        RunCallback<1>(DECODER_ERROR_NOT_SUPPORTED)));
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD1(OnStatistics, void(const PipelineStatistics&));
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MOCK_METHOD1(OnBufferingStateChange, void(BufferingState));
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD1(OnError, void(PipelineStatus));
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
117e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  void InitializeRenderer(const PipelineStatusCB& pipeline_status_cb) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    renderer_->Initialize(
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        &demuxer_stream_,
120e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        pipeline_status_cb,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AudioRendererImplTest::OnStatistics,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)),
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::Bind(&AudioRendererImplTest::OnBufferingStateChange,
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   base::Unretained(this)),
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::Bind(&AudioRendererImplTest::OnEnded,
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   base::Unretained(this)),
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AudioRendererImplTest::OnError,
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)));
129e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
130e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
131e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  void Initialize() {
132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_CALL(*decoder_, Initialize(_, _, _))
133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        .WillOnce(DoAll(SaveArg<2>(&output_cb_),
134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                        RunCallback<1>(PIPELINE_OK)));
135e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    InitializeWithStatus(PIPELINE_OK);
136e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    next_timestamp_.reset(new AudioTimestampHelper(kInputSamplesPerSecond));
138e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
139e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
140e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  void InitializeWithStatus(PipelineStatus expected) {
141e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    SCOPED_TRACE(base::StringPrintf("InitializeWithStatus(%d)", expected));
142e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
143e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    WaitableMessageLoopEvent event;
144e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    InitializeRenderer(event.GetPipelineStatusCB());
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event.RunAndWaitForStatus(expected);
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We should have no reads.
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_TRUE(decode_cb_.is_null());
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void InitializeAndDestroy() {
152f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_CALL(*decoder_, Initialize(_, _, _))
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        .WillOnce(RunCallback<1>(PIPELINE_OK));
154e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    WaitableMessageLoopEvent event;
156e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    InitializeRenderer(event.GetPipelineStatusCB());
157e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Destroy the |renderer_| before we let the MessageLoop run, this simulates
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // an interleaving in which we end up destroying the |renderer_| while the
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // OnDecoderSelected callback is in flight.
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    renderer_.reset();
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    event.RunAndWaitForStatus(PIPELINE_ERROR_ABORT);
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void InitializeAndDestroyDuringDecoderInit() {
166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_CALL(*decoder_, Initialize(_, _, _))
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        .WillOnce(EnterPendingDecoderInitStateAction(this));
168e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    WaitableMessageLoopEvent event;
170e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    InitializeRenderer(event.GetPipelineStatusCB());
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(!init_decoder_cb_.is_null());
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    renderer_.reset();
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    event.RunAndWaitForStatus(PIPELINE_ERROR_ABORT);
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void EnterPendingDecoderInitState(PipelineStatusCB cb) {
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    init_decoder_cb_ = cb;
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void FlushDuringPendingRead() {
183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SCOPED_TRACE("FlushDuringPendingRead()");
184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    WaitableMessageLoopEvent flush_event;
185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    renderer_->Flush(flush_event.GetClosure());
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    SatisfyPendingRead(InputFrames(256));
187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    flush_event.RunAndWait();
188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_FALSE(IsReadPending());
190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Preroll() {
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Preroll(0, PIPELINE_OK);
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Preroll(int timestamp_ms, PipelineStatus expected) {
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SCOPED_TRACE(base::StringPrintf("Preroll(%d, %d)", timestamp_ms, expected));
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TimeDelta timestamp = TimeDelta::FromMilliseconds(timestamp_ms);
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    next_timestamp_->SetBaseTimestamp(timestamp);
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Fill entire buffer to complete prerolling.
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    renderer_->SetMediaTime(timestamp);
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    renderer_->StartPlaying();
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WaitForPendingRead();
206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeliverRemainingAudio();
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void StartTicking() {
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    renderer_->StartTicking();
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    renderer_->SetPlaybackRate(1.0f);
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void StopTicking() { renderer_->StopTicking(); }
216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool IsReadPending() const {
218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return !decode_cb_.is_null();
219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void WaitForPendingRead() {
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SCOPED_TRACE("WaitForPendingRead()");
223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!decode_cb_.is_null())
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(wait_for_pending_decode_cb_.is_null());
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WaitableMessageLoopEvent event;
229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    wait_for_pending_decode_cb_ = event.GetClosure();
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event.RunAndWait();
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(!decode_cb_.is_null());
233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(wait_for_pending_decode_cb_.is_null());
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Delivers decoded frames to |renderer_|.
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void SatisfyPendingRead(InputFrames frames) {
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    CHECK_GT(frames.value, 0);
239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CHECK(!decode_cb_.is_null());
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_refptr<AudioBuffer> buffer =
242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        MakeAudioBuffer<float>(kSampleFormat,
24323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                               kChannelLayout,
244effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                               kChannelCount,
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               kInputSamplesPerSecond,
246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                               1.0f,
247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                               0.0f,
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               frames.value,
249010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                               next_timestamp_->GetTimestamp());
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    next_timestamp_->AddFrames(frames.value);
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DeliverBuffer(AudioDecoder::kOk, buffer);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DeliverEndOfStream() {
2566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    DCHECK(!decode_cb_.is_null());
2576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // Return EOS buffer to trigger EOS frame.
2596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EXPECT_CALL(demuxer_stream_, Read(_))
2606d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        .WillOnce(RunCallback<0>(DemuxerStream::kOk,
2616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                 DecoderBuffer::CreateEOSBuffer()));
2626d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // Satify pending |decode_cb_| to trigger a new DemuxerStream::Read().
2646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    message_loop_.PostTask(
2656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        FROM_HERE,
2666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        base::Bind(base::ResetAndReturn(&decode_cb_), AudioDecoder::kOk));
2676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    WaitForPendingRead();
2696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    message_loop_.PostTask(
2716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        FROM_HERE,
2726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        base::Bind(base::ResetAndReturn(&decode_cb_), AudioDecoder::kOk));
2736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::RunLoop().RunUntilIdle();
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Delivers frames until |renderer_|'s internal buffer is full and no longer
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // has pending reads.
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DeliverRemainingAudio() {
2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    while (frames_remaining_in_buffer().value > 0) {
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      SatisfyPendingRead(InputFrames(256));
2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Attempts to consume |requested_frames| frames from |renderer_|'s internal
286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // buffer. Returns true if and only if all of |requested_frames| were able
287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // to be consumed.
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool ConsumeBufferedData(OutputFrames requested_frames) {
2897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_ptr<AudioBus> bus =
2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        AudioBus::Create(kChannels, requested_frames.value);
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int frames_read = 0;
292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    EXPECT_TRUE(sink_->Render(bus.get(), 0, &frames_read));
2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return frames_read == requested_frames.value;
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OutputFrames frames_buffered() {
2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return OutputFrames(renderer_->algorithm_->frames_buffered());
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OutputFrames buffer_capacity() {
3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return OutputFrames(renderer_->algorithm_->QueueCapacity());
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OutputFrames frames_remaining_in_buffer() {
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This can happen if too much data was delivered, in which case the buffer
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // will accept the data but not increase capacity.
3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (frames_buffered().value > buffer_capacity().value) {
3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return OutputFrames(0);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return OutputFrames(buffer_capacity().value - frames_buffered().value);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void force_config_change() {
3140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    renderer_->OnConfigChange();
3150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
3160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  InputFrames converter_input_frames_left() const {
3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return InputFrames(
3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        renderer_->buffer_converter_->input_frames_left_for_testing());
3200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
3210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  bool splicer_has_next_buffer() const {
3230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return renderer_->splicer_->HasNextBuffer();
3240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
3250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeDelta CurrentMediaTime() {
3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return renderer_->CurrentMediaTime();
3280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
3290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
330116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool ended() const { return ended_; }
331116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fixture members.
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop_;
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<AudioRendererImpl> renderer_;
3358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<FakeAudioRendererSink> sink_;
336effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  AudioHardwareConfig hardware_config_;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void DecodeDecoder(const scoped_refptr<DecoderBuffer>& buffer,
340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     const AudioDecoder::DecodeCB& decode_cb) {
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(scherkus): Make this a DCHECK after threading semantics are fixed.
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (base::MessageLoop::current() != &message_loop_) {
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      message_loop_.PostTask(FROM_HERE, base::Bind(
344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          &AudioRendererImplTest::DecodeDecoder,
345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          base::Unretained(this), buffer, decode_cb));
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
349a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CHECK(decode_cb_.is_null()) << "Overlapping decodes are not permitted";
350a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    decode_cb_ = decode_cb;
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Wake up WaitForPendingRead() if needed.
353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!wait_for_pending_decode_cb_.is_null())
354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::ResetAndReturn(&wait_for_pending_decode_cb_).Run();
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
357a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void ResetDecoder(const base::Closure& reset_cb) {
358f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (!decode_cb_.is_null()) {
359f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // |reset_cb| will be called in DeliverBuffer(), after the decoder is
360f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // flushed.
361f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      reset_cb_ = reset_cb;
362f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return;
363f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    message_loop_.PostTask(FROM_HERE, reset_cb);
366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void DeliverBuffer(AudioDecoder::Status status,
3697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                     const scoped_refptr<AudioBuffer>& buffer) {
370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CHECK(!decode_cb_.is_null());
3711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (buffer.get() && !buffer->end_of_stream())
372f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      output_cb_.Run(buffer);
373f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    base::ResetAndReturn(&decode_cb_).Run(status);
374f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
375f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (!reset_cb_.is_null())
376f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::ResetAndReturn(&reset_cb_).Run();
377f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
3785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::RunLoop().RunUntilIdle();
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void OnEnded() {
382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CHECK(!ended_);
383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ended_ = true;
384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockDemuxerStream demuxer_stream_;
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockAudioDecoder* decoder_;
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Used for satisfying reads.
390f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  AudioDecoder::OutputCB output_cb_;
391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AudioDecoder::DecodeCB decode_cb_;
392f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::Closure reset_cb_;
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<AudioTimestampHelper> next_timestamp_;
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Run during DecodeDecoder() to unblock WaitForPendingRead().
396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::Closure wait_for_pending_decode_cb_;
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PipelineStatusCB init_decoder_cb_;
399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool ended_;
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AudioRendererImplTest);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererImplTest, Initialize_Successful) {
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize();
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererImplTest, Initialize_DecoderInitFailure) {
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectUnsupportedAudioDecoder();
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitializeWithStatus(DECODER_ERROR_NOT_SUPPORTED);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererImplTest, Preroll) {
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize();
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Preroll();
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(AudioRendererImplTest, StartTicking) {
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize();
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Preroll();
4215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  StartTicking();
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Drain internal buffer, we should have a pending read.
424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPendingRead();
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererImplTest, EndOfStream) {
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize();
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Preroll();
4315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  StartTicking();
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Drain internal buffer, we should have a pending read.
434116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPendingRead();
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
437116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Forcefully trigger underflow.
4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(ConsumeBufferedData(OutputFrames(1)));
439116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
440a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
441116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Fulfill the read with an end-of-stream buffer. Doing so should change our
442116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // buffering state so playback resumes.
443116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
444f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DeliverEndOfStream();
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
446116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Consume all remaining data. We shouldn't have signal ended yet.
447116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
4485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::RunLoop().RunUntilIdle();
449116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_FALSE(ended());
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
451116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Ended should trigger on next render call.
4525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(ConsumeBufferedData(OutputFrames(1)));
4535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::RunLoop().RunUntilIdle();
454116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(ended());
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
457116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(AudioRendererImplTest, Underflow) {
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize();
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Preroll();
4605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  StartTicking();
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Drain internal buffer, we should have a pending read.
463116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPendingRead();
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
466116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Verify the next FillBuffer() call triggers a buffering state change
467116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // update.
468116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
4695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(ConsumeBufferedData(OutputFrames(1)));
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
471116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Verify we're still not getting audio data.
4725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(0, frames_buffered().value);
4735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(ConsumeBufferedData(OutputFrames(1)));
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Deliver enough data to have enough for buffering.
476116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeliverRemainingAudio();
478116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
479116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Verify we're getting audio data.
4805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(ConsumeBufferedData(OutputFrames(1)));
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
483116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(AudioRendererImplTest, Underflow_CapacityResetsAfterFlush) {
4848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  Initialize();
4858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  Preroll();
4865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  StartTicking();
4878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Drain internal buffer, we should have a pending read.
489116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
4908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  WaitForPendingRead();
4918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Verify the next FillBuffer() call triggers the underflow callback
4938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // since the decoder hasn't delivered any data after it was drained.
4945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OutputFrames initial_capacity = buffer_capacity();
495116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
4965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(ConsumeBufferedData(OutputFrames(1)));
4978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
498116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Verify that the buffer capacity increased as a result of underflowing.
4995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_GT(buffer_capacity().value, initial_capacity.value);
5008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
501116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Verify that the buffer capacity is restored to the |initial_capacity|.
502116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FlushDuringPendingRead();
5035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(buffer_capacity().value, initial_capacity.value);
5048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
5058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
506116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(AudioRendererImplTest, Underflow_Flush) {
507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Initialize();
508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Preroll();
5095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  StartTicking();
510f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
511116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Force underflow.
512116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  WaitForPendingRead();
514116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
5155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(ConsumeBufferedData(OutputFrames(1)));
516116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  WaitForPendingRead();
5175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  StopTicking();
518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
519116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // We shouldn't expect another buffering state change when flushing.
520116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FlushDuringPendingRead();
521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
522f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
523a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(AudioRendererImplTest, PendingRead_Flush) {
524a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Initialize();
525a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
526a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Preroll();
5275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  StartTicking();
528a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
529a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Partially drain internal buffer so we get a pending read.
5305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(ConsumeBufferedData(OutputFrames(256)));
531a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  WaitForPendingRead();
532a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  StopTicking();
534a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
535a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(IsReadPending());
536a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
537116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Flush and expect to be notified that we have nothing.
538116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
539116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FlushDuringPendingRead();
540a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Preroll again to a different timestamp and verify it completed normally.
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Preroll(1000, PIPELINE_OK);
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(AudioRendererImplTest, PendingRead_Destroy) {
5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Initialize();
5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Preroll();
5495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  StartTicking();
5505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Partially drain internal buffer so we get a pending read.
5525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(ConsumeBufferedData(OutputFrames(256)));
5535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WaitForPendingRead();
5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  StopTicking();
5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(IsReadPending());
5585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  renderer_.reset();
5605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(AudioRendererImplTest, PendingFlush_Destroy) {
5635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Initialize();
5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Preroll();
5665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  StartTicking();
5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Partially drain internal buffer so we get a pending read.
5695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(ConsumeBufferedData(OutputFrames(256)));
5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WaitForPendingRead();
5715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  StopTicking();
5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(IsReadPending());
5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Start flushing.
5775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WaitableMessageLoopEvent flush_event;
5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  renderer_->Flush(flush_event.GetClosure());
5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
580116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
5815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SatisfyPendingRead(InputFrames(256));
5825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  renderer_.reset();
5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(AudioRendererImplTest, InitializeThenDestroy) {
5875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  InitializeAndDestroy();
5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(AudioRendererImplTest, InitializeThenDestroyDuringDecoderInit) {
5915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  InitializeAndDestroyDuringDecoderInit();
5925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5940529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_F(AudioRendererImplTest, ConfigChangeDrainsConverter) {
5950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  Initialize();
5960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  Preroll();
5975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  StartTicking();
5980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Drain internal buffer, we should have a pending read.
600116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
6010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  WaitForPendingRead();
6020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
6030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Deliver a little bit of data.  Use an odd data size to ensure there is data
6040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // left in the AudioBufferConverter.  Ensure no buffers are in the splicer.
6055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SatisfyPendingRead(InputFrames(2053));
6060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_FALSE(splicer_has_next_buffer());
6075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_GT(converter_input_frames_left().value, 0);
6080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
6090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Force a config change and then ensure all buffered data has been put into
6100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // the splicer.
6110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  force_config_change();
6120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(splicer_has_next_buffer());
6135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(0, converter_input_frames_left().value);
6140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
6150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
6160529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_F(AudioRendererImplTest, TimeUpdatesOnFirstBuffer) {
6170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  Initialize();
6180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  Preroll();
6195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  StartTicking();
6200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
6210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  AudioTimestampHelper timestamp_helper(kOutputSamplesPerSecond);
6221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  timestamp_helper.SetBaseTimestamp(base::TimeDelta());
6230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
6241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Time should be the starting timestamp as nothing's been consumed yet.
6251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(timestamp_helper.GetTimestamp(), CurrentMediaTime());
6261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Consume some audio data.
6285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OutputFrames frames_to_consume(frames_buffered().value / 2);
629116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(ConsumeBufferedData(frames_to_consume));
6300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  WaitForPendingRead();
6310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
6321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Time shouldn't change just yet because we've only sent the initial audio
6331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // data to the hardware.
6341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(timestamp_helper.GetTimestamp(), CurrentMediaTime());
6350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
6361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Consume some more audio data.
637cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  frames_to_consume = frames_buffered();
638116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(ConsumeBufferedData(frames_to_consume));
639cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
6401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now time should change now that the audio hardware has called back.
6416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  timestamp_helper.AddFrames(frames_to_consume.value);
6421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(timestamp_helper.GetTimestamp(), CurrentMediaTime());
6430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
6440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
645010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TEST_F(AudioRendererImplTest, ImmediateEndOfStream) {
646010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Initialize();
647010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  {
648010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    SCOPED_TRACE("Preroll()");
6495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    renderer_->StartPlaying();
650010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    WaitForPendingRead();
651116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
652010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    DeliverEndOfStream();
653010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
6545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  StartTicking();
655010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
656010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Read a single frame. We shouldn't be able to satisfy it.
657116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_FALSE(ended());
6585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(ConsumeBufferedData(OutputFrames(1)));
6595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::RunLoop().RunUntilIdle();
660116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(ended());
661010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
662010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
6630de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)TEST_F(AudioRendererImplTest, OnRenderErrorCausesDecodeError) {
6640de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  Initialize();
6650de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  Preroll();
6665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  StartTicking();
6670de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
6680de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  EXPECT_CALL(*this, OnError(PIPELINE_ERROR_DECODE));
6690de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  sink_->OnRenderError();
6705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::RunLoop().RunUntilIdle();
6710de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)}
6720de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
673cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Test for AudioRendererImpl calling Pause()/Play() on the sink when the
674cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// playback rate is set to zero and non-zero.
675cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(AudioRendererImplTest, SetPlaybackRate) {
676cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Initialize();
677cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Preroll();
678cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
679cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Rendering hasn't started. Sink should always be paused.
680cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state());
681cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  renderer_->SetPlaybackRate(0.0f);
682cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state());
683cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  renderer_->SetPlaybackRate(1.0f);
684cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state());
685cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
686cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Rendering has started with non-zero rate. Rate changes will affect sink
687cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // state.
6885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  renderer_->StartTicking();
689cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(FakeAudioRendererSink::kPlaying, sink_->state());
690cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  renderer_->SetPlaybackRate(0.0f);
691cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state());
692cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  renderer_->SetPlaybackRate(1.0f);
693cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(FakeAudioRendererSink::kPlaying, sink_->state());
694cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
695cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Rendering has stopped. Sink should be paused.
6965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  renderer_->StopTicking();
697cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state());
698cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
699cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Start rendering with zero playback rate. Sink should be paused until
700cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // non-zero rate is set.
701cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  renderer_->SetPlaybackRate(0.0f);
7025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  renderer_->StartTicking();
703cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state());
704cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  renderer_->SetPlaybackRate(1.0f);
705cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(FakeAudioRendererSink::kPlaying, sink_->state());
706cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
707cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
709