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