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/media_keys.h" 15#include "media/base/pipeline.h" 16#include "media/base/text_track.h" 17#include "media/base/text_track_config.h" 18#include "media/base/video_frame.h" 19#include "media/filters/video_renderer_impl.h" 20#include "testing/gmock/include/gmock/gmock.h" 21 22namespace base { 23class FilePath; 24} 25 26namespace media { 27 28class Decryptor; 29 30// Empty MD5 hash string. Used to verify empty video tracks. 31extern const char kNullVideoHash[]; 32 33// Empty hash string. Used to verify empty audio tracks. 34extern const char kNullAudioHash[]; 35 36// Dummy tick clock which advances extremely quickly (1 minute every time 37// NowTicks() is called). 38class DummyTickClock : public base::TickClock { 39 public: 40 DummyTickClock() : now_() {} 41 virtual ~DummyTickClock() {} 42 virtual base::TimeTicks NowTicks() OVERRIDE; 43 private: 44 base::TimeTicks now_; 45}; 46 47// Integration tests for Pipeline. Real demuxers, real decoders, and 48// base renderer implementations are used to verify pipeline functionality. The 49// renderers used in these tests rely heavily on the AudioRendererBase & 50// VideoRendererImpl implementations which contain a majority of the code used 51// in the real AudioRendererImpl & SkCanvasVideoRenderer implementations used in 52// the browser. The renderers in this test don't actually write data to a 53// display or audio device. Both of these devices are simulated since they have 54// little effect on verifying pipeline behavior and allow tests to run faster 55// than real-time. 56class PipelineIntegrationTestBase { 57 public: 58 PipelineIntegrationTestBase(); 59 virtual ~PipelineIntegrationTestBase(); 60 61 bool WaitUntilOnEnded(); 62 PipelineStatus WaitUntilEndedOrError(); 63 bool Start(const base::FilePath& file_path, PipelineStatus expected_status); 64 // Enable playback with audio and video hashing enabled, or clockless 65 // playback (audio only). Frame dropping and audio underflow will be disabled 66 // if hashing enabled to ensure consistent hashes. 67 enum kTestType { kHashed, kClockless }; 68 bool Start(const base::FilePath& file_path, 69 PipelineStatus expected_status, 70 kTestType test_type); 71 // Initialize the pipeline and ignore any status updates. Useful for testing 72 // invalid audio/video clips which don't have deterministic results. 73 bool Start(const base::FilePath& file_path); 74 bool Start(const base::FilePath& file_path, Decryptor* decryptor); 75 76 void Play(); 77 void Pause(); 78 bool Seek(base::TimeDelta seek_time); 79 void Stop(); 80 bool WaitUntilCurrentTimeIsAfter(const base::TimeDelta& wait_time); 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 AudioHardwareConfig hardware_config_; 113 PipelineMetadata metadata_; 114 115 void OnStatusCallbackChecked(PipelineStatus expected_status, 116 PipelineStatus status); 117 void OnStatusCallback(PipelineStatus status); 118 PipelineStatusCB QuitOnStatusCB(PipelineStatus expected_status); 119 void DemuxerNeedKeyCB(const std::string& type, 120 const std::vector<uint8>& init_data); 121 void set_need_key_cb(const Demuxer::NeedKeyCB& need_key_cb) { 122 need_key_cb_ = need_key_cb; 123 } 124 125 void OnEnded(); 126 void OnError(PipelineStatus status); 127 void QuitAfterCurrentTimeTask(const base::TimeDelta& quit_time); 128 129 // Creates Demuxer and sets |demuxer_|. 130 void CreateDemuxer(const base::FilePath& file_path); 131 132 // Creates and returns a Renderer. 133 scoped_ptr<Renderer> CreateRenderer(Decryptor* decryptor); 134 135 void SetDecryptor(Decryptor* decryptor, 136 const DecryptorReadyCB& decryptor_ready_cb); 137 void OnVideoRendererPaint(const scoped_refptr<VideoFrame>& frame); 138 139 MOCK_METHOD1(OnMetadata, void(PipelineMetadata)); 140 MOCK_METHOD1(OnBufferingStateChanged, void(BufferingState)); 141 MOCK_METHOD1(DecryptorAttached, void(bool)); 142 MOCK_METHOD2(OnAddTextTrack, 143 void(const TextTrackConfig& config, 144 const AddTextTrackDoneCB& done_cb)); 145}; 146 147} // namespace media 148 149#endif // MEDIA_FILTERS_PIPELINE_INTEGRATION_TEST_BASE_H_ 150