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