1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef MEDIA_FILTERS_PIPELINE_INTEGRATION_TEST_BASE_H_ 6#define MEDIA_FILTERS_PIPELINE_INTEGRATION_TEST_BASE_H_ 7 8#include "base/md5.h" 9#include "base/message_loop/message_loop.h" 10#include "media/audio/clockless_audio_sink.h" 11#include "media/audio/null_audio_sink.h" 12#include "media/base/demuxer.h" 13#include "media/base/filter_collection.h" 14#include "media/base/media_keys.h" 15#include "media/base/pipeline.h" 16#include "media/base/video_frame.h" 17#include "media/filters/video_renderer_impl.h" 18#include "testing/gmock/include/gmock/gmock.h" 19 20namespace base { 21class FilePath; 22} 23 24namespace media { 25 26class Decryptor; 27 28// Empty MD5 hash string. Used to verify empty video tracks. 29extern const char kNullVideoHash[]; 30 31// Empty hash string. Used to verify empty audio tracks. 32extern const char kNullAudioHash[]; 33 34// Dummy tick clock which advances extremely quickly (1 minute every time 35// NowTicks() is called). 36class DummyTickClock : public base::TickClock { 37 public: 38 DummyTickClock() : now_() {} 39 virtual ~DummyTickClock() {} 40 virtual base::TimeTicks NowTicks() OVERRIDE; 41 private: 42 base::TimeTicks now_; 43}; 44 45// Integration tests for Pipeline. Real demuxers, real decoders, and 46// base renderer implementations are used to verify pipeline functionality. The 47// renderers used in these tests rely heavily on the AudioRendererBase & 48// VideoRendererImpl implementations which contain a majority of the code used 49// in the real AudioRendererImpl & SkCanvasVideoRenderer implementations used in 50// the browser. The renderers in this test don't actually write data to a 51// display or audio device. Both of these devices are simulated since they have 52// little effect on verifying pipeline behavior and allow tests to run faster 53// than real-time. 54class PipelineIntegrationTestBase { 55 public: 56 PipelineIntegrationTestBase(); 57 virtual ~PipelineIntegrationTestBase(); 58 59 bool WaitUntilOnEnded(); 60 PipelineStatus WaitUntilEndedOrError(); 61 bool Start(const base::FilePath& file_path, PipelineStatus expected_status); 62 // Enable playback with audio and video hashing enabled, or clockless 63 // playback (audio only). Frame dropping and audio underflow will be disabled 64 // if hashing enabled to ensure consistent hashes. 65 enum kTestType { kHashed, kClockless }; 66 bool Start(const base::FilePath& file_path, 67 PipelineStatus expected_status, 68 kTestType test_type); 69 // Initialize the pipeline and ignore any status updates. Useful for testing 70 // invalid audio/video clips which don't have deterministic results. 71 bool Start(const base::FilePath& file_path); 72 bool Start(const base::FilePath& file_path, Decryptor* decryptor); 73 74 void Play(); 75 void Pause(); 76 bool Seek(base::TimeDelta seek_time); 77 void Stop(); 78 bool WaitUntilCurrentTimeIsAfter(const base::TimeDelta& wait_time); 79 scoped_ptr<FilterCollection> CreateFilterCollection( 80 const base::FilePath& file_path, Decryptor* decryptor); 81 82 // Returns the MD5 hash of all video frames seen. Should only be called once 83 // after playback completes. First time hashes should be generated with 84 // --video-threads=1 to ensure correctness. Pipeline must have been started 85 // with hashing enabled. 86 std::string GetVideoHash(); 87 88 // Returns the hash of all audio frames seen. Should only be called once 89 // after playback completes. Pipeline must have been started with hashing 90 // enabled. 91 std::string GetAudioHash(); 92 93 // Returns the time taken to render the complete audio file. 94 // Pipeline must have been started with clockless playback enabled. 95 base::TimeDelta GetAudioTime(); 96 97 protected: 98 base::MessageLoop message_loop_; 99 base::MD5Context md5_context_; 100 bool hashing_enabled_; 101 bool clockless_playback_; 102 scoped_ptr<Demuxer> demuxer_; 103 scoped_ptr<DataSource> data_source_; 104 scoped_ptr<Pipeline> pipeline_; 105 scoped_refptr<NullAudioSink> audio_sink_; 106 scoped_refptr<ClocklessAudioSink> clockless_audio_sink_; 107 bool ended_; 108 PipelineStatus pipeline_status_; 109 Demuxer::NeedKeyCB need_key_cb_; 110 VideoFrame::Format last_video_frame_format_; 111 DummyTickClock dummy_clock_; 112 113 void OnStatusCallbackChecked(PipelineStatus expected_status, 114 PipelineStatus status); 115 void OnStatusCallback(PipelineStatus status); 116 PipelineStatusCB QuitOnStatusCB(PipelineStatus expected_status); 117 void DemuxerNeedKeyCB(const std::string& type, 118 const std::vector<uint8>& init_data); 119 void set_need_key_cb(const Demuxer::NeedKeyCB& need_key_cb) { 120 need_key_cb_ = need_key_cb; 121 } 122 123 void OnEnded(); 124 void OnError(PipelineStatus status); 125 void QuitAfterCurrentTimeTask(const base::TimeDelta& quit_time); 126 scoped_ptr<FilterCollection> CreateFilterCollection( 127 scoped_ptr<Demuxer> demuxer, Decryptor* decryptor); 128 129 void SetDecryptor(Decryptor* decryptor, 130 const DecryptorReadyCB& decryptor_ready_cb); 131 void OnVideoRendererPaint(const scoped_refptr<VideoFrame>& frame); 132 133 MOCK_METHOD1(OnSetOpaque, void(bool)); 134 MOCK_METHOD1(OnBufferingState, void(Pipeline::BufferingState)); 135}; 136 137} // namespace media 138 139#endif // MEDIA_FILTERS_PIPELINE_INTEGRATION_TEST_BASE_H_ 140