pipeline_integration_test_base.cc revision 3551c9c881056c480085172ff9840cab31610854
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"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/media_log.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/audio_renderer_impl.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/chunk_demuxer.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/ffmpeg_audio_decoder.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/ffmpeg_demuxer.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/ffmpeg_video_decoder.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/file_data_source.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/filters/opus_audio_decoder.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/filters/vpx_video_decoder.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::AnyNumber;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::AtMost;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kNullVideoHash[] = "d41d8cd98f00b204e9800998ecf8427e";
2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kNullAudioHash[] = "0.00,0.00,0.00,0.00,0.00,0.00,";
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PipelineIntegrationTestBase::PipelineIntegrationTestBase()
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : hashing_enabled_(false),
293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      clockless_playback_(false),
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pipeline_(new Pipeline(message_loop_.message_loop_proxy(),
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             new MediaLog())),
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ended_(false),
33b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      pipeline_status_(PIPELINE_OK),
34b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      last_video_frame_format_(VideoFrame::INVALID) {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::MD5Init(&md5_context_);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, OnSetOpaque(true)).Times(AnyNumber());
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PipelineIntegrationTestBase::~PipelineIntegrationTestBase() {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!pipeline_->IsRunning())
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Stop();
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PipelineIntegrationTestBase::OnStatusCallback(
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PipelineStatus status) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pipeline_status_ = status;
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PipelineIntegrationTestBase::OnStatusCallbackChecked(
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PipelineStatus expected_status,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PipelineStatus status) {
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(expected_status, status);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnStatusCallback(status);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PipelineStatusCB PipelineIntegrationTestBase::QuitOnStatusCB(
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PipelineStatus expected_status) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base::Bind(&PipelineIntegrationTestBase::OnStatusCallbackChecked,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    base::Unretained(this),
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    expected_status);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PipelineIntegrationTestBase::DemuxerNeedKeyCB(
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& type,
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<uint8[]> init_data,
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int init_data_size) {
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(init_data.get());
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_GT(init_data_size, 0);
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(!need_key_cb_.is_null());
737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  need_key_cb_.Run(std::string(), type, init_data.Pass(), init_data_size);
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PipelineIntegrationTestBase::OnEnded() {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!ended_);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ended_ = true;
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pipeline_status_ = PIPELINE_OK;
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PipelineIntegrationTestBase::WaitUntilOnEnded() {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ended_)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (pipeline_status_ == PIPELINE_OK);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop_.Run();
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ended_);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ended_ && (pipeline_status_ == PIPELINE_OK);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PipelineStatus PipelineIntegrationTestBase::WaitUntilEndedOrError() {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ended_ || pipeline_status_ != PIPELINE_OK)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return pipeline_status_;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop_.Run();
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pipeline_status_;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PipelineIntegrationTestBase::OnError(PipelineStatus status) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(status, PIPELINE_OK);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pipeline_status_ = status;
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PipelineIntegrationTestBase::Start(const base::FilePath& file_path,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        PipelineStatus expected_status) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, OnBufferingState(Pipeline::kHaveMetadata))
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(AtMost(1));
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, OnBufferingState(Pipeline::kPrerollCompleted))
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(AtMost(1));
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pipeline_->Start(
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateFilterCollection(file_path, NULL),
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&PipelineIntegrationTestBase::OnEnded, base::Unretained(this)),
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&PipelineIntegrationTestBase::OnError, base::Unretained(this)),
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      QuitOnStatusCB(expected_status),
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&PipelineIntegrationTestBase::OnBufferingState,
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(this)),
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Closure());
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop_.Run();
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (pipeline_status_ == PIPELINE_OK);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PipelineIntegrationTestBase::Start(const base::FilePath& file_path,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        PipelineStatus expected_status,
1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        kTestType test_type) {
1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  hashing_enabled_ = test_type == kHashed;
1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  clockless_playback_ = test_type == kClockless;
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return Start(file_path, expected_status);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PipelineIntegrationTestBase::Start(const base::FilePath& file_path) {
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return Start(file_path, NULL);
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PipelineIntegrationTestBase::Start(const base::FilePath& file_path,
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        Decryptor* decryptor) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, OnBufferingState(Pipeline::kHaveMetadata))
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(AtMost(1));
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, OnBufferingState(Pipeline::kPrerollCompleted))
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(AtMost(1));
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pipeline_->Start(
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateFilterCollection(file_path, decryptor),
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&PipelineIntegrationTestBase::OnEnded, base::Unretained(this)),
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&PipelineIntegrationTestBase::OnError, base::Unretained(this)),
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&PipelineIntegrationTestBase::OnStatusCallback,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)),
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&PipelineIntegrationTestBase::OnBufferingState,
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(this)),
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Closure());
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop_.Run();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (pipeline_status_ == PIPELINE_OK);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PipelineIntegrationTestBase::Play() {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pipeline_->SetPlaybackRate(1);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PipelineIntegrationTestBase::Pause() {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pipeline_->SetPlaybackRate(0);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PipelineIntegrationTestBase::Seek(base::TimeDelta seek_time) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ended_ = false;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, OnBufferingState(Pipeline::kPrerollCompleted));
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pipeline_->Seek(seek_time, QuitOnStatusCB(PIPELINE_OK));
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop_.Run();
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (pipeline_status_ == PIPELINE_OK);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PipelineIntegrationTestBase::Stop() {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(pipeline_->IsRunning());
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pipeline_->Stop(base::MessageLoop::QuitClosure());
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop_.Run();
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PipelineIntegrationTestBase::QuitAfterCurrentTimeTask(
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::TimeDelta& quit_time) {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pipeline_->GetMediaTime() >= quit_time ||
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pipeline_status_ != PIPELINE_OK) {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_loop_.Quit();
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop_.PostDelayedTask(
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&PipelineIntegrationTestBase::QuitAfterCurrentTimeTask,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this), quit_time),
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(10));
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PipelineIntegrationTestBase::WaitUntilCurrentTimeIsAfter(
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::TimeDelta& wait_time) {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(pipeline_->IsRunning());
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GT(pipeline_->GetPlaybackRate(), 0);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(wait_time <= pipeline_->GetMediaDuration());
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop_.PostDelayedTask(
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&PipelineIntegrationTestBase::QuitAfterCurrentTimeTask,
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this),
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 wait_time),
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(10));
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop_.Run();
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (pipeline_status_ == PIPELINE_OK);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<FilterCollection>
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PipelineIntegrationTestBase::CreateFilterCollection(
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& file_path,
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Decryptor* decryptor) {
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FileDataSource* file_data_source = new FileDataSource();
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK(file_data_source->Initialize(file_path));
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  data_source_.reset(file_data_source);
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
215a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  media::FFmpegNeedKeyCB need_key_cb = base::Bind(
216a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      &PipelineIntegrationTestBase::DemuxerNeedKeyCB, base::Unretained(this));
217a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_ptr<Demuxer> demuxer(
218a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      new FFmpegDemuxer(message_loop_.message_loop_proxy(),
219a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                        data_source_.get(),
220a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                        need_key_cb,
221a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                        new MediaLog()));
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return CreateFilterCollection(demuxer.Pass(), decryptor);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<FilterCollection>
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PipelineIntegrationTestBase::CreateFilterCollection(
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<Demuxer> demuxer,
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Decryptor* decryptor) {
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  demuxer_ = demuxer.Pass();
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<FilterCollection> collection(new FilterCollection());
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  collection->SetDemuxer(demuxer_.get());
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!clockless_playback_) {
2353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ScopedVector<VideoDecoder> video_decoders;
2363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    video_decoders.push_back(
2373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        new VpxVideoDecoder(message_loop_.message_loop_proxy()));
2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    video_decoders.push_back(
2393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        new FFmpegVideoDecoder(message_loop_.message_loop_proxy()));
2403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Disable frame dropping if hashing is enabled.
2423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    scoped_ptr<VideoRenderer> renderer(new VideoRendererBase(
2433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        message_loop_.message_loop_proxy(),
2443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        video_decoders.Pass(),
2453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        base::Bind(&PipelineIntegrationTestBase::SetDecryptor,
2463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   base::Unretained(this),
2473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   decryptor),
2483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        base::Bind(&PipelineIntegrationTestBase::OnVideoRendererPaint,
2493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   base::Unretained(this)),
2503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        base::Bind(&PipelineIntegrationTestBase::OnSetOpaque,
2513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   base::Unretained(this)),
2523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        !hashing_enabled_));
2533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    collection->SetVideoRenderer(renderer.Pass());
2543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    audio_sink_ = new NullAudioSink(message_loop_.message_loop_proxy());
2563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else {
2573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // audio only for clockless_playback_
2583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    clockless_audio_sink_ = new ClocklessAudioSink();
2593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<AudioDecoder> audio_decoders;
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  audio_decoders.push_back(
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FFmpegAudioDecoder(message_loop_.message_loop_proxy()));
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  audio_decoders.push_back(
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new OpusAudioDecoder(message_loop_.message_loop_proxy()));
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AudioRendererImpl* audio_renderer_impl = new AudioRendererImpl(
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      message_loop_.message_loop_proxy(),
2693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      (clockless_playback_)
2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          ? static_cast<AudioRendererSink*>(clockless_audio_sink_.get())
2713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          : audio_sink_.get(),
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      audio_decoders.Pass(),
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&PipelineIntegrationTestBase::SetDecryptor,
274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                 base::Unretained(this),
275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                 decryptor),
276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      true);
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)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
320