15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef MEDIA_FILTERS_PIPELINE_INTEGRATION_TEST_BASE_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MEDIA_FILTERS_PIPELINE_INTEGRATION_TEST_BASE_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/md5.h"
9ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "media/audio/clockless_audio_sink.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/audio/null_audio_sink.h"
12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "media/base/audio_hardware_config.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "media/base/demuxer.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "media/base/media_keys.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/pipeline.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/base/text_track.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/base/text_track_config.h"
18b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "media/base/video_frame.h"
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "media/filters/video_renderer_impl.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace base {
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FilePath;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Decryptor;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Empty MD5 hash string.  Used to verify empty video tracks.
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)extern const char kNullVideoHash[];
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Empty hash string.  Used to verify empty audio tracks.
3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)extern const char kNullAudioHash[];
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Dummy tick clock which advances extremely quickly (1 minute every time
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// NowTicks() is called).
38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class DummyTickClock : public base::TickClock {
39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public:
40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DummyTickClock() : now_() {}
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual ~DummyTickClock() {}
42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual base::TimeTicks NowTicks() OVERRIDE;
43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private:
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::TimeTicks now_;
45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Integration tests for Pipeline. Real demuxers, real decoders, and
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// base renderer implementations are used to verify pipeline functionality. The
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// renderers used in these tests rely heavily on the AudioRendererBase &
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// VideoRendererImpl implementations which contain a majority of the code used
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the real AudioRendererImpl & SkCanvasVideoRenderer implementations used in
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the browser. The renderers in this test don't actually write data to a
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// display or audio device. Both of these devices are simulated since they have
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// little effect on verifying pipeline behavior and allow tests to run faster
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// than real-time.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PipelineIntegrationTestBase {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PipelineIntegrationTestBase();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~PipelineIntegrationTestBase();
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool WaitUntilOnEnded();
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PipelineStatus WaitUntilEndedOrError();
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool Start(const base::FilePath& file_path, PipelineStatus expected_status);
643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Enable playback with audio and video hashing enabled, or clockless
653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // playback (audio only). Frame dropping and audio underflow will be disabled
663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // if hashing enabled to ensure consistent hashes.
673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  enum kTestType { kHashed, kClockless };
683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool Start(const base::FilePath& file_path,
693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)             PipelineStatus expected_status,
703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)             kTestType test_type);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initialize the pipeline and ignore any status updates.  Useful for testing
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // invalid audio/video clips which don't have deterministic results.
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool Start(const base::FilePath& file_path);
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool Start(const base::FilePath& file_path, Decryptor* decryptor);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Play();
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Pause();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Seek(base::TimeDelta seek_time);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Stop();
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool WaitUntilCurrentTimeIsAfter(const base::TimeDelta& wait_time);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the MD5 hash of all video frames seen.  Should only be called once
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // after playback completes.  First time hashes should be generated with
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // --video-threads=1 to ensure correctness.  Pipeline must have been started
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // with hashing enabled.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string GetVideoHash();
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns the hash of all audio frames seen.  Should only be called once
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // after playback completes.  Pipeline must have been started with hashing
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // enabled.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string GetAudioHash();
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Returns the time taken to render the complete audio file.
943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Pipeline must have been started with clockless playback enabled.
953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::TimeDelta GetAudioTime();
963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop_;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::MD5Context md5_context_;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool hashing_enabled_;
1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool clockless_playback_;
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<Demuxer> demuxer_;
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<DataSource> data_source_;
104b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_ptr<Pipeline> pipeline_;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<NullAudioSink> audio_sink_;
1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<ClocklessAudioSink> clockless_audio_sink_;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ended_;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PipelineStatus pipeline_status_;
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Demuxer::NeedKeyCB need_key_cb_;
110b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  VideoFrame::Format last_video_frame_format_;
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DummyTickClock dummy_clock_;
112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  AudioHardwareConfig hardware_config_;
1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  PipelineMetadata metadata_;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnStatusCallbackChecked(PipelineStatus expected_status,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               PipelineStatus status);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnStatusCallback(PipelineStatus status);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PipelineStatusCB QuitOnStatusCB(PipelineStatus expected_status);
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void DemuxerNeedKeyCB(const std::string& type,
120424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                        const std::vector<uint8>& init_data);
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void set_need_key_cb(const Demuxer::NeedKeyCB& need_key_cb) {
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    need_key_cb_ = need_key_cb;
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnEnded();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnError(PipelineStatus status);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void QuitAfterCurrentTimeTask(const base::TimeDelta& quit_time);
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Creates Demuxer and sets |demuxer_|.
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void CreateDemuxer(const base::FilePath& file_path);
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Creates and returns a Renderer.
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<Renderer> CreateRenderer(Decryptor* decryptor);
1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetDecryptor(Decryptor* decryptor,
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    const DecryptorReadyCB& decryptor_ready_cb);
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnVideoRendererPaint(const scoped_refptr<VideoFrame>& frame);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MOCK_METHOD1(OnMetadata, void(PipelineMetadata));
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MOCK_METHOD1(OnBufferingStateChanged, void(BufferingState));
1416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  MOCK_METHOD1(DecryptorAttached, void(bool));
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_METHOD2(OnAddTextTrack,
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               void(const TextTrackConfig& config,
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    const AddTextTrackDoneCB& done_cb));
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // MEDIA_FILTERS_PIPELINE_INTEGRATION_TEST_BASE_H_
150