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 "media/filters/pipeline_integration_test_base.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_vector.h" 9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "media/base/clock.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/media_log.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/audio_renderer_impl.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/chunk_demuxer.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/ffmpeg_audio_decoder.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/ffmpeg_demuxer.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/ffmpeg_video_decoder.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/file_data_source.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/filters/opus_audio_decoder.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/filters/vpx_video_decoder.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::AnyNumber; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::AtMost; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kNullVideoHash[] = "d41d8cd98f00b204e9800998ecf8427e"; 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kNullAudioHash[] = "0.00,0.00,0.00,0.00,0.00,0.00,"; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PipelineIntegrationTestBase::PipelineIntegrationTestBase() 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : hashing_enabled_(false), 303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) clockless_playback_(false), 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pipeline_(new Pipeline(message_loop_.message_loop_proxy(), 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new MediaLog())), 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ended_(false), 34b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) pipeline_status_(PIPELINE_OK), 350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) last_video_frame_format_(VideoFrame::UNKNOWN) { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::MD5Init(&md5_context_); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*this, OnSetOpaque(true)).Times(AnyNumber()); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PipelineIntegrationTestBase::~PipelineIntegrationTestBase() { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pipeline_->IsRunning()) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Stop(); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PipelineIntegrationTestBase::OnStatusCallback( 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PipelineStatus status) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pipeline_status_ = status; 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PipelineIntegrationTestBase::OnStatusCallbackChecked( 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PipelineStatus expected_status, 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PipelineStatus status) { 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(expected_status, status); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnStatusCallback(status); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PipelineStatusCB PipelineIntegrationTestBase::QuitOnStatusCB( 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PipelineStatus expected_status) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::Bind(&PipelineIntegrationTestBase::OnStatusCallbackChecked, 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this), 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_status); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PipelineIntegrationTestBase::DemuxerNeedKeyCB( 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& type, 69424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const std::vector<uint8>& init_data) { 70424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(!init_data.empty()); 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(!need_key_cb_.is_null()); 724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) need_key_cb_.Run(type, init_data); 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PipelineIntegrationTestBase::OnEnded() { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!ended_); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ended_ = true; 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pipeline_status_ = PIPELINE_OK; 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PipelineIntegrationTestBase::WaitUntilOnEnded() { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ended_) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (pipeline_status_ == PIPELINE_OK); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_.Run(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ended_); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ended_ && (pipeline_status_ == PIPELINE_OK); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PipelineStatus PipelineIntegrationTestBase::WaitUntilEndedOrError() { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ended_ || pipeline_status_ != PIPELINE_OK) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pipeline_status_; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_.Run(); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pipeline_status_; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PipelineIntegrationTestBase::OnError(PipelineStatus status) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(status, PIPELINE_OK); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pipeline_status_ = status; 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PipelineIntegrationTestBase::Start(const base::FilePath& file_path, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PipelineStatus expected_status) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*this, OnBufferingState(Pipeline::kHaveMetadata)) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(AtMost(1)); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*this, OnBufferingState(Pipeline::kPrerollCompleted)) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(AtMost(1)); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pipeline_->Start( 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateFilterCollection(file_path, NULL), 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PipelineIntegrationTestBase::OnEnded, base::Unretained(this)), 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PipelineIntegrationTestBase::OnError, base::Unretained(this)), 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuitOnStatusCB(expected_status), 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PipelineIntegrationTestBase::OnBufferingState, 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this)), 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Closure()); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_.Run(); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (pipeline_status_ == PIPELINE_OK); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PipelineIntegrationTestBase::Start(const base::FilePath& file_path, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PipelineStatus expected_status, 1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) kTestType test_type) { 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) hashing_enabled_ = test_type == kHashed; 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) clockless_playback_ = test_type == kClockless; 126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (clockless_playback_) { 127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) pipeline_->SetClockForTesting(new Clock(&dummy_clock_)); 128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Start(file_path, expected_status); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PipelineIntegrationTestBase::Start(const base::FilePath& file_path) { 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Start(file_path, NULL); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PipelineIntegrationTestBase::Start(const base::FilePath& file_path, 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Decryptor* decryptor) { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*this, OnBufferingState(Pipeline::kHaveMetadata)) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(AtMost(1)); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*this, OnBufferingState(Pipeline::kPrerollCompleted)) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(AtMost(1)); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pipeline_->Start( 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateFilterCollection(file_path, decryptor), 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PipelineIntegrationTestBase::OnEnded, base::Unretained(this)), 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PipelineIntegrationTestBase::OnError, base::Unretained(this)), 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PipelineIntegrationTestBase::OnStatusCallback, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this)), 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PipelineIntegrationTestBase::OnBufferingState, 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this)), 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Closure()); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_.Run(); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (pipeline_status_ == PIPELINE_OK); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PipelineIntegrationTestBase::Play() { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pipeline_->SetPlaybackRate(1); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PipelineIntegrationTestBase::Pause() { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pipeline_->SetPlaybackRate(0); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PipelineIntegrationTestBase::Seek(base::TimeDelta seek_time) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ended_ = false; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*this, OnBufferingState(Pipeline::kPrerollCompleted)); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pipeline_->Seek(seek_time, QuitOnStatusCB(PIPELINE_OK)); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_.Run(); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (pipeline_status_ == PIPELINE_OK); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PipelineIntegrationTestBase::Stop() { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(pipeline_->IsRunning()); 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pipeline_->Stop(base::MessageLoop::QuitClosure()); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_.Run(); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PipelineIntegrationTestBase::QuitAfterCurrentTimeTask( 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeDelta& quit_time) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pipeline_->GetMediaTime() >= quit_time || 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pipeline_status_ != PIPELINE_OK) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_.Quit(); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_.PostDelayedTask( 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PipelineIntegrationTestBase::QuitAfterCurrentTimeTask, 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this), quit_time), 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(10)); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PipelineIntegrationTestBase::WaitUntilCurrentTimeIsAfter( 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeDelta& wait_time) { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(pipeline_->IsRunning()); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(pipeline_->GetPlaybackRate(), 0); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(wait_time <= pipeline_->GetMediaDuration()); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_.PostDelayedTask( 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PipelineIntegrationTestBase::QuitAfterCurrentTimeTask, 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this), 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_time), 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(10)); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_.Run(); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (pipeline_status_ == PIPELINE_OK); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<FilterCollection> 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PipelineIntegrationTestBase::CreateFilterCollection( 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& file_path, 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Decryptor* decryptor) { 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FileDataSource* file_data_source = new FileDataSource(); 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK(file_data_source->Initialize(file_path)); 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) data_source_.reset(file_data_source); 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 217424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Demuxer::NeedKeyCB need_key_cb = base::Bind( 218a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) &PipelineIntegrationTestBase::DemuxerNeedKeyCB, base::Unretained(this)); 219a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_ptr<Demuxer> demuxer( 220a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) new FFmpegDemuxer(message_loop_.message_loop_proxy(), 221a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) data_source_.get(), 222a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) need_key_cb, 223a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) new MediaLog())); 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return CreateFilterCollection(demuxer.Pass(), decryptor); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<FilterCollection> 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PipelineIntegrationTestBase::CreateFilterCollection( 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<Demuxer> demuxer, 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Decryptor* decryptor) { 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) demuxer_ = demuxer.Pass(); 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<FilterCollection> collection(new FilterCollection()); 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) collection->SetDemuxer(demuxer_.get()); 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ScopedVector<VideoDecoder> video_decoders; 237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) video_decoders.push_back( 238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new VpxVideoDecoder(message_loop_.message_loop_proxy())); 239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) video_decoders.push_back( 240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new FFmpegVideoDecoder(message_loop_.message_loop_proxy())); 2413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Disable frame dropping if hashing is enabled. 243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<VideoRenderer> renderer(new VideoRendererImpl( 244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) message_loop_.message_loop_proxy(), 245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) video_decoders.Pass(), 246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&PipelineIntegrationTestBase::SetDecryptor, 247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Unretained(this), 248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) decryptor), 249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&PipelineIntegrationTestBase::OnVideoRendererPaint, 250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Unretained(this)), 251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&PipelineIntegrationTestBase::OnSetOpaque, 252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Unretained(this)), 253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) false)); 254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) collection->SetVideoRenderer(renderer.Pass()); 255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!clockless_playback_) { 2573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) audio_sink_ = new NullAudioSink(message_loop_.message_loop_proxy()); 2583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 2593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) clockless_audio_sink_ = new ClocklessAudioSink(); 2603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedVector<AudioDecoder> audio_decoders; 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) audio_decoders.push_back( 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new FFmpegAudioDecoder(message_loop_.message_loop_proxy())); 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) audio_decoders.push_back( 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new OpusAudioDecoder(message_loop_.message_loop_proxy())); 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AudioRendererImpl* audio_renderer_impl = new AudioRendererImpl( 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_.message_loop_proxy(), 2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) (clockless_playback_) 2713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ? static_cast<AudioRendererSink*>(clockless_audio_sink_.get()) 2723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : audio_sink_.get(), 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) audio_decoders.Pass(), 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&PipelineIntegrationTestBase::SetDecryptor, 275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Unretained(this), 276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) decryptor)); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Disable underflow if hashing is enabled. 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (hashing_enabled_) { 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) audio_sink_->StartAudioHashForTesting(); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) audio_renderer_impl->DisableUnderflowForTesting(); 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AudioRenderer> audio_renderer(audio_renderer_impl); 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) collection->SetAudioRenderer(audio_renderer.Pass()); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return collection.Pass(); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PipelineIntegrationTestBase::SetDecryptor( 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Decryptor* decryptor, 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DecryptorReadyCB& decryptor_ready_cb) { 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decryptor_ready_cb.Run(decryptor); 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PipelineIntegrationTestBase::OnVideoRendererPaint( 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const scoped_refptr<VideoFrame>& frame) { 296b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) last_video_frame_format_ = frame->format(); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!hashing_enabled_) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame->HashFrameForTesting(&md5_context_); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string PipelineIntegrationTestBase::GetVideoHash() { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(hashing_enabled_); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::MD5Digest digest; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::MD5Final(&digest, &md5_context_); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::MD5DigestToBase16(digest); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string PipelineIntegrationTestBase::GetAudioHash() { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(hashing_enabled_); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return audio_sink_->GetAudioHashForTesting(); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)base::TimeDelta PipelineIntegrationTestBase::GetAudioTime() { 3153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(clockless_playback_); 3163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return clockless_audio_sink_->render_time(); 3173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 319a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::TimeTicks DummyTickClock::NowTicks() { 320a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) now_ += base::TimeDelta::FromSeconds(60); 321a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return now_; 322a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 323a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 325