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