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 20 namespace base { 21 class FilePath; 22 } 23 24 namespace media { 25 26 class Decryptor; 27 28 // Empty MD5 hash string. Used to verify empty video tracks. 29 extern const char kNullVideoHash[]; 30 31 // Empty hash string. Used to verify empty audio tracks. 32 extern const char kNullAudioHash[]; 33 34 // Dummy tick clock which advances extremely quickly (1 minute every time 35 // NowTicks() is called). 36 class DummyTickClock : public base::TickClock { 37 public: DummyTickClock()38 DummyTickClock() : now_() {} ~DummyTickClock()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. 54 class 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); set_need_key_cb(const Demuxer::NeedKeyCB & need_key_cb)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