pipeline_integration_test_base.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  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. #ifndef MEDIA_TEST_PIPELINE_INTEGRATION_TEST_BASE_H_
  5. #define MEDIA_TEST_PIPELINE_INTEGRATION_TEST_BASE_H_
  6. #include <stdint.h>
  7. #include <memory>
  8. #include "base/callback_forward.h"
  9. #include "base/hash/md5.h"
  10. #include "base/run_loop.h"
  11. #include "base/test/scoped_run_loop_timeout.h"
  12. #include "base/test/task_environment.h"
  13. #include "base/time/time.h"
  14. #include "media/audio/clockless_audio_sink.h"
  15. #include "media/audio/null_audio_sink.h"
  16. #include "media/base/demuxer.h"
  17. #include "media/base/mock_media_log.h"
  18. #include "media/base/null_video_sink.h"
  19. #include "media/base/pipeline_impl.h"
  20. #include "media/base/pipeline_status.h"
  21. #include "media/base/text_track.h"
  22. #include "media/base/text_track_config.h"
  23. #include "media/base/video_frame.h"
  24. #include "media/renderers/audio_renderer_impl.h"
  25. #include "media/renderers/video_renderer_impl.h"
  26. #include "testing/gmock/include/gmock/gmock.h"
  27. using ::testing::NiceMock;
  28. namespace base {
  29. class RunLoop;
  30. }
  31. namespace media {
  32. class FakeEncryptedMedia;
  33. class TestMediaSource;
  34. // Empty MD5 hash string. Used to verify empty video tracks.
  35. extern const char kNullVideoHash[];
  36. // Empty hash string. Used to verify empty audio tracks.
  37. extern const char kNullAudioHash[];
  38. // Integration tests for Pipeline. Real demuxers, real decoders, and
  39. // base renderer implementations are used to verify pipeline functionality. The
  40. // renderers used in these tests rely heavily on the AudioRendererBase &
  41. // VideoRendererImpl implementations which contain a majority of the code used
  42. // in the real AudioRendererImpl & PaintCanvasVideoRenderer implementations used
  43. // in the browser. The renderers in this test don't actually write data to a
  44. // display or audio device. Both of these devices are simulated since they have
  45. // little effect on verifying pipeline behavior and allow tests to run faster
  46. // than real-time.
  47. class PipelineIntegrationTestBase : public Pipeline::Client {
  48. public:
  49. PipelineIntegrationTestBase();
  50. PipelineIntegrationTestBase(const PipelineIntegrationTestBase&) = delete;
  51. PipelineIntegrationTestBase& operator=(const PipelineIntegrationTestBase&) =
  52. delete;
  53. virtual ~PipelineIntegrationTestBase();
  54. // Test types for advanced testing and benchmarking (e.g., underflow is
  55. // disabled to ensure consistent hashes). May be combined using the bitwise
  56. // or operator (and as such must have values that are powers of two).
  57. enum TestTypeFlags {
  58. kNormal = 0,
  59. kHashed = 1,
  60. kNoClockless = 2,
  61. kExpectDemuxerFailure = 4,
  62. kUnreliableDuration = 8,
  63. kWebAudio = 16,
  64. kMonoOutput = 32,
  65. kFuzzing = 64,
  66. };
  67. // Setup method to intialize various state according to flags.
  68. void ParseTestTypeFlags(uint8_t flags);
  69. // Starts the pipeline with a file specified by |filename|, optionally with a
  70. // CdmContext or a |test_type|, returning the final status code after it has
  71. // started. |filename| points at a test file located under media/test/data/.
  72. PipelineStatus Start(const std::string& filename);
  73. PipelineStatus Start(const std::string& filename, CdmContext* cdm_context);
  74. PipelineStatus Start(
  75. const std::string& filename,
  76. uint8_t test_type,
  77. CreateVideoDecodersCB prepend_video_decoders_cb = CreateVideoDecodersCB(),
  78. CreateAudioDecodersCB prepend_audio_decoders_cb =
  79. CreateAudioDecodersCB());
  80. // Starts the pipeline with |data| (with |size| bytes). The |data| will be
  81. // valid throughtout the lifetime of this test.
  82. PipelineStatus Start(const uint8_t* data, size_t size, uint8_t test_type);
  83. void Play();
  84. void Pause();
  85. bool Seek(base::TimeDelta seek_time);
  86. bool Suspend();
  87. bool Resume(base::TimeDelta seek_time);
  88. void Stop();
  89. // Fails the test with |status|.
  90. void FailTest(PipelineStatus status);
  91. bool WaitUntilCurrentTimeIsAfter(const base::TimeDelta& wait_time);
  92. bool WaitUntilOnEnded();
  93. PipelineStatus WaitUntilEndedOrError();
  94. // Returns the MD5 hash of all video frames seen. Should only be called once
  95. // after playback completes. First time hashes should be generated with
  96. // --video-threads=1 to ensure correctness. Pipeline must have been started
  97. // with hashing enabled.
  98. std::string GetVideoHash();
  99. // Returns the hash of all audio frames seen. Should only be called once
  100. // after playback completes. Pipeline must have been started with hashing
  101. // enabled.
  102. std::string GetAudioHash();
  103. // Reset video hash to restart hashing from scratch (e.g. after a seek or
  104. // after disabling a media track).
  105. void ResetVideoHash();
  106. // Returns the time taken to render the complete audio file.
  107. // Pipeline must have been started with clockless playback enabled.
  108. base::TimeDelta GetAudioTime();
  109. // Sets a callback to handle EME "encrypted" event. Must be called to test
  110. // potentially encrypted media.
  111. void set_encrypted_media_init_data_cb(
  112. const Demuxer::EncryptedMediaInitDataCB& encrypted_media_init_data_cb) {
  113. encrypted_media_init_data_cb_ = encrypted_media_init_data_cb;
  114. }
  115. // Saves a test callback, ownership of which will be transferred to the next
  116. // AudioRendererImpl created by CreateDefaultRenderer().
  117. void set_audio_play_delay_cb(AudioRendererImpl::PlayDelayCBForTesting cb) {
  118. audio_play_delay_cb_ = std::move(cb);
  119. }
  120. std::unique_ptr<Renderer> CreateRenderer(
  121. absl::optional<RendererType> renderer_type);
  122. protected:
  123. NiceMock<MockMediaLog> media_log_;
  124. base::test::TaskEnvironment task_environment_;
  125. base::MD5Context md5_context_;
  126. bool hashing_enabled_;
  127. bool clockless_playback_;
  128. bool webaudio_attached_;
  129. bool mono_output_;
  130. bool fuzzing_;
  131. #if defined(ADDRESS_SANITIZER) || defined(UNDEFINED_SANITIZER)
  132. // TODO(https://crbug.com/924030): ASAN causes Run() timeouts to be reached.
  133. const base::test::ScopedDisableRunLoopTimeout disable_run_timeout_;
  134. #endif
  135. std::unique_ptr<Demuxer> demuxer_;
  136. std::unique_ptr<DataSource> data_source_;
  137. std::unique_ptr<PipelineImpl> pipeline_;
  138. scoped_refptr<NullAudioSink> audio_sink_;
  139. scoped_refptr<ClocklessAudioSink> clockless_audio_sink_;
  140. std::unique_ptr<NullVideoSink> video_sink_;
  141. bool ended_;
  142. PipelineStatus pipeline_status_;
  143. Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb_;
  144. VideoPixelFormat last_video_frame_format_;
  145. gfx::ColorSpace last_video_frame_color_space_;
  146. PipelineMetadata metadata_;
  147. scoped_refptr<VideoFrame> last_frame_;
  148. base::TimeDelta current_duration_;
  149. AudioRendererImpl::PlayDelayCBForTesting audio_play_delay_cb_;
  150. // By default RendererImpl will be created using CreateDefaultRenderer(). But
  151. // if |create_renderer_cb_| is set, it'll be used to create the Renderer
  152. // instead.
  153. using CreateRendererCB = base::RepeatingCallback<std::unique_ptr<Renderer>(
  154. absl::optional<RendererType> renderer_type)>;
  155. CreateRendererCB create_renderer_cb_;
  156. std::unique_ptr<Renderer> CreateDefaultRenderer(
  157. absl::optional<RendererType> renderer_type);
  158. // Sets |create_renderer_cb_| which will be used to wrap the Renderer created
  159. // by CreateDefaultRenderer().
  160. void SetCreateRendererCB(CreateRendererCB create_renderer_cb);
  161. PipelineStatus StartInternal(
  162. std::unique_ptr<DataSource> data_source,
  163. CdmContext* cdm_context,
  164. uint8_t test_type,
  165. CreateVideoDecodersCB prepend_video_decoders_cb = CreateVideoDecodersCB(),
  166. CreateAudioDecodersCB prepend_audio_decoders_cb =
  167. CreateAudioDecodersCB());
  168. PipelineStatus StartWithFile(
  169. const std::string& filename,
  170. CdmContext* cdm_context,
  171. uint8_t test_type,
  172. CreateVideoDecodersCB prepend_video_decoders_cb = CreateVideoDecodersCB(),
  173. CreateAudioDecodersCB prepend_audio_decoders_cb =
  174. CreateAudioDecodersCB());
  175. PipelineStatus StartPipelineWithMediaSource(TestMediaSource* source);
  176. PipelineStatus StartPipelineWithEncryptedMedia(
  177. TestMediaSource* source,
  178. FakeEncryptedMedia* encrypted_media);
  179. PipelineStatus StartPipelineWithMediaSource(
  180. TestMediaSource* source,
  181. uint8_t test_type,
  182. FakeEncryptedMedia* encrypted_media);
  183. PipelineStatus StartPipelineWithMediaSource(
  184. TestMediaSource* source,
  185. uint8_t test_type,
  186. CreateAudioDecodersCB prepend_audio_decoders_cb);
  187. void OnSeeked(base::TimeDelta seek_time, PipelineStatus status);
  188. void OnStatusCallback(const base::RepeatingClosure& quit_run_loop_closure,
  189. PipelineStatus status);
  190. void DemuxerEncryptedMediaInitDataCB(EmeInitDataType type,
  191. const std::vector<uint8_t>& init_data);
  192. void DemuxerMediaTracksUpdatedCB(std::unique_ptr<MediaTracks> tracks);
  193. void QuitAfterCurrentTimeTask(base::TimeDelta quit_time,
  194. base::OnceClosure quit_closure);
  195. // Creates Demuxer and sets |demuxer_|.
  196. void CreateDemuxer(std::unique_ptr<DataSource> data_source);
  197. void OnVideoFramePaint(scoped_refptr<VideoFrame> frame);
  198. void CheckDuration();
  199. // Return the media start time from |demuxer_|.
  200. base::TimeDelta GetStartTime();
  201. MOCK_METHOD1(DecryptorAttached, void(bool));
  202. // Pipeline::Client overrides.
  203. void OnError(PipelineStatus status) override;
  204. void OnFallback(PipelineStatus status) override;
  205. void OnEnded() override;
  206. MOCK_METHOD1(OnMetadata, void(const PipelineMetadata&));
  207. MOCK_METHOD2(OnBufferingStateChange,
  208. void(BufferingState, BufferingStateChangeReason));
  209. MOCK_METHOD0(OnDurationChange, void());
  210. MOCK_METHOD2(OnAddTextTrack,
  211. void(const TextTrackConfig& config, AddTextTrackDoneCB done_cb));
  212. MOCK_METHOD1(OnWaiting, void(WaitingReason));
  213. MOCK_METHOD1(OnVideoNaturalSizeChange, void(const gfx::Size&));
  214. MOCK_METHOD1(OnVideoConfigChange, void(const VideoDecoderConfig&));
  215. MOCK_METHOD1(OnAudioConfigChange, void(const AudioDecoderConfig&));
  216. MOCK_METHOD1(OnVideoOpacityChange, void(bool));
  217. MOCK_METHOD1(OnVideoFrameRateChange, void(absl::optional<int>));
  218. MOCK_METHOD0(OnVideoAverageKeyframeDistanceUpdate, void());
  219. MOCK_METHOD1(OnAudioPipelineInfoChange, void(const AudioPipelineInfo&));
  220. MOCK_METHOD1(OnVideoPipelineInfoChange, void(const VideoPipelineInfo&));
  221. MOCK_METHOD1(OnRemotePlayStateChange, void(MediaStatus::State state));
  222. private:
  223. // Runs |run_loop| until it is explicitly Quit() by some part of the calling
  224. // test fixture or when an error occurs (by setting |on_error_closure_|). The
  225. // |task_environment_| is RunUntilIdle() after the RunLoop finishes
  226. // running, before returning to the caller.
  227. void RunUntilQuitOrError(base::RunLoop* run_loop);
  228. // Configures |on_ended_closure_| to quit |run_loop| and then calls
  229. // RunUntilQuitOrError() on it.
  230. void RunUntilQuitOrEndedOrError(base::RunLoop* run_loop);
  231. CreateVideoDecodersCB prepend_video_decoders_cb_;
  232. CreateAudioDecodersCB prepend_audio_decoders_cb_;
  233. base::OnceClosure on_ended_closure_;
  234. base::OnceClosure on_error_closure_;
  235. };
  236. } // namespace media
  237. #endif // MEDIA_TEST_PIPELINE_INTEGRATION_TEST_BASE_H_