Index: media/test/pipeline_integration_test_base.h |
diff --git a/media/test/pipeline_integration_test_base.h b/media/test/pipeline_integration_test_base.h |
index a39eb3ffe447318ba17792f5ec5b53639cd1b4a5..9bac11f5d00143bbce476eb55886979c0d34fe3c 100644 |
--- a/media/test/pipeline_integration_test_base.h |
+++ b/media/test/pipeline_integration_test_base.h |
@@ -13,6 +13,8 @@ |
#include "base/test/scoped_task_scheduler.h" |
#include "media/audio/clockless_audio_sink.h" |
#include "media/audio/null_audio_sink.h" |
+#include "media/base/cdm_context.h" |
+#include "media/base/content_decryption_module.h" |
#include "media/base/demuxer.h" |
#include "media/base/null_video_sink.h" |
#include "media/base/pipeline_impl.h" |
@@ -20,12 +22,13 @@ |
#include "media/base/text_track.h" |
#include "media/base/text_track_config.h" |
#include "media/base/video_frame.h" |
+#include "media/filters/chunk_demuxer.h" |
#include "media/renderers/video_renderer_impl.h" |
#include "testing/gmock/include/gmock/gmock.h" |
namespace media { |
-class CdmContext; |
+class AesDecryptor; |
// Empty MD5 hash string. Used to verify empty video tracks. |
extern const char kNullVideoHash[]; |
@@ -33,6 +36,9 @@ extern const char kNullVideoHash[]; |
// Empty hash string. Used to verify empty audio tracks. |
extern const char kNullAudioHash[]; |
+// Indicates that the whole file should be appended. |
+extern const size_t kAppendWholeFile; |
+ |
// Dummy tick clock which advances extremely quickly (1 minute every time |
// NowTicks() is called). |
class DummyTickClock : public base::TickClock { |
@@ -45,6 +51,129 @@ class DummyTickClock : public base::TickClock { |
base::TimeTicks now_; |
}; |
+class PipelineTestRendererFactory { |
+ public: |
+ virtual ~PipelineTestRendererFactory() {} |
+ // Creates and returns a Renderer. |
+ virtual std::unique_ptr<Renderer> CreateRenderer( |
+ CreateVideoDecodersCB prepend_video_decoders_cb = CreateVideoDecodersCB(), |
+ CreateAudioDecodersCB prepend_audio_decoders_cb = |
+ CreateAudioDecodersCB()) = 0; |
+}; |
+ |
+// Helper class that emulates calls made on the ChunkDemuxer by the |
DaleCurtis
2017/04/20 18:24:51
Should be extracted to a mock_media_source.{h,cc}
xjz
2017/04/20 21:26:10
Done.
|
+// Media Source API. |
+class MockMediaSource { |
+ public: |
+ MockMediaSource(const std::string& filename, |
+ const std::string& mimetype, |
+ size_t initial_append_size); |
+ ~MockMediaSource(); |
+ |
+ std::unique_ptr<Demuxer> GetDemuxer(); |
+ void set_encrypted_media_init_data_cb( |
+ const Demuxer::EncryptedMediaInitDataCB& encrypted_media_init_data_cb); |
+ void set_demuxer_failure_cb(const PipelineStatusCB& demuxer_failure_cb); |
+ void Seek(base::TimeDelta seek_time, |
+ size_t new_position, |
+ size_t seek_append_size); |
+ void Seek(base::TimeDelta seek_time); |
+ void AppendData(size_t size); |
+ bool AppendAtTime(base::TimeDelta timestamp_offset, |
+ const uint8_t* pData, |
+ int size); |
+ void AppendAtTimeWithWindow(base::TimeDelta timestamp_offset, |
+ base::TimeDelta append_window_start, |
+ base::TimeDelta append_window_end, |
+ const uint8_t* pData, |
+ int size); |
+ void SetMemoryLimits(size_t limit_bytes); |
+ void EvictCodedFrames(base::TimeDelta currentMediaTime, size_t newDataSize); |
+ void RemoveRange(base::TimeDelta start, base::TimeDelta end); |
+ void EndOfStream(); |
+ void Shutdown(); |
+ void DemuxerOpened(); |
+ void DemuxerOpenedTask(); |
+ ChunkDemuxer::Status AddId(); |
+ void OnEncryptedMediaInitData(EmeInitDataType init_data_type, |
+ const std::vector<uint8_t>& init_data); |
+ base::TimeDelta last_timestamp_offset() const; |
+ void InitSegmentReceived(std::unique_ptr<MediaTracks> tracks); |
+ MOCK_METHOD1(InitSegmentReceivedMock, void(std::unique_ptr<MediaTracks>&)); |
+ |
+ private: |
+ MediaLog media_log_; |
+ scoped_refptr<DecoderBuffer> file_data_; |
+ size_t current_position_; |
+ size_t initial_append_size_; |
+ std::string mimetype_; |
+ ChunkDemuxer* chunk_demuxer_; |
+ std::unique_ptr<Demuxer> owned_chunk_demuxer_; |
+ PipelineStatusCB demuxer_failure_cb_; |
+ Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb_; |
+ base::TimeDelta last_timestamp_offset_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(MockMediaSource); |
+}; |
+ |
+// Note: Tests using this class only exercise the DecryptingDemuxerStream path. |
DaleCurtis
2017/04/20 18:24:51
Ditto.
xjz
2017/04/20 21:26:10
Done.
|
+// They do not exercise the Decrypting{Audio|Video}Decoder path. |
+class FakeEncryptedMedia { |
+ public: |
+ // Defines the behavior of the "app" that responds to EME events. |
+ class AppBase { |
+ public: |
+ virtual ~AppBase() {} |
+ |
+ virtual void OnSessionMessage( |
+ const std::string& session_id, |
+ ContentDecryptionModule::MessageType message_type, |
+ const std::vector<uint8_t>& message, |
+ AesDecryptor* decryptor) = 0; |
+ |
+ virtual void OnSessionClosed(const std::string& session_id) = 0; |
+ |
+ virtual void OnSessionKeysChange(const std::string& session_id, |
+ bool has_additional_usable_key, |
+ CdmKeysInfo keys_info) = 0; |
+ |
+ virtual void OnEncryptedMediaInitData(EmeInitDataType init_data_type, |
+ const std::vector<uint8_t>& init_data, |
+ AesDecryptor* decryptor) = 0; |
+ }; |
+ |
+ FakeEncryptedMedia(AppBase* app); |
+ ~FakeEncryptedMedia(); |
+ CdmContext* GetCdmContext(); |
+ // Callbacks for firing session events. Delegate to |app_|. |
+ void OnSessionMessage(const std::string& session_id, |
+ ContentDecryptionModule::MessageType message_type, |
+ const std::vector<uint8_t>& message); |
+ void OnSessionClosed(const std::string& session_id); |
+ void OnSessionKeysChange(const std::string& session_id, |
+ bool has_additional_usable_key, |
+ CdmKeysInfo keys_info); |
+ void OnEncryptedMediaInitData(EmeInitDataType init_data_type, |
+ const std::vector<uint8_t>& init_data); |
+ |
+ private: |
+ class TestCdmContext : public CdmContext { |
+ public: |
+ TestCdmContext(Decryptor* decryptor); |
+ Decryptor* GetDecryptor() final; |
+ int GetCdmId() const final; |
+ |
+ private: |
+ Decryptor* decryptor_; |
+ }; |
+ |
+ scoped_refptr<AesDecryptor> decryptor_; |
+ TestCdmContext cdm_context_; |
+ std::unique_ptr<AppBase> app_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(FakeEncryptedMedia); |
+}; |
+ |
// Integration tests for Pipeline. Real demuxers, real decoders, and |
// base renderer implementations are used to verify pipeline functionality. The |
// renderers used in these tests rely heavily on the AudioRendererBase & |
@@ -126,6 +255,10 @@ class PipelineIntegrationTestBase : public Pipeline::Client { |
encrypted_media_init_data_cb_ = encrypted_media_init_data_cb; |
} |
+ std::unique_ptr<Renderer> CreateRenderer( |
+ CreateVideoDecodersCB prepend_video_decoders_cb, |
+ CreateAudioDecodersCB prepend_audio_decoders_cb); |
+ |
protected: |
MediaLog media_log_; |
base::MessageLoop message_loop_; |
@@ -150,6 +283,7 @@ class PipelineIntegrationTestBase : public Pipeline::Client { |
PipelineMetadata metadata_; |
scoped_refptr<VideoFrame> last_frame_; |
base::TimeDelta current_duration_; |
+ std::unique_ptr<PipelineTestRendererFactory> renderer_factory_; |
PipelineStatus StartInternal( |
std::unique_ptr<DataSource> data_source, |
@@ -167,6 +301,15 @@ class PipelineIntegrationTestBase : public Pipeline::Client { |
CreateAudioDecodersCB prepend_audio_decoders_cb = |
CreateAudioDecodersCB()); |
+ PipelineStatus StartPipelineWithMediaSource(MockMediaSource* source); |
+ PipelineStatus StartPipelineWithEncryptedMedia( |
+ MockMediaSource* source, |
+ FakeEncryptedMedia* encrypted_media); |
+ PipelineStatus StartPipelineWithMediaSource( |
+ MockMediaSource* source, |
+ uint8_t test_type, |
+ FakeEncryptedMedia* encrypted_media); |
+ |
void OnSeeked(base::TimeDelta seek_time, PipelineStatus status); |
void OnStatusCallback(PipelineStatus status); |
void DemuxerEncryptedMediaInitDataCB(EmeInitDataType type, |
@@ -179,12 +322,6 @@ class PipelineIntegrationTestBase : public Pipeline::Client { |
// Creates Demuxer and sets |demuxer_|. |
void CreateDemuxer(std::unique_ptr<DataSource> data_source); |
- // Creates and returns a Renderer. |
- virtual std::unique_ptr<Renderer> CreateRenderer( |
- CreateVideoDecodersCB prepend_video_decoders_cb = CreateVideoDecodersCB(), |
- CreateAudioDecodersCB prepend_audio_decoders_cb = |
- CreateAudioDecodersCB()); |
- |
void OnVideoFramePaint(const scoped_refptr<VideoFrame>& frame); |
void CheckDuration(); |
@@ -192,6 +329,14 @@ class PipelineIntegrationTestBase : public Pipeline::Client { |
// Return the media start time from |demuxer_|. |
base::TimeDelta GetStartTime(); |
+ bool TestSeekDuringRead(const std::string& filename, |
DaleCurtis
2017/04/20 18:24:51
This should be on the normal PIT since you can dro
xjz
2017/04/20 21:26:10
Done.
|
+ const std::string& mimetype, |
+ int initial_append_size, |
+ base::TimeDelta start_seek_time, |
+ base::TimeDelta seek_time, |
+ int seek_file_position, |
+ int seek_append_size); |
+ |
MOCK_METHOD1(DecryptorAttached, void(bool)); |
// Pipeline::Client overrides. |
void OnError(PipelineStatus status) override; |
@@ -206,6 +351,9 @@ class PipelineIntegrationTestBase : public Pipeline::Client { |
MOCK_METHOD1(OnVideoNaturalSizeChange, void(const gfx::Size&)); |
MOCK_METHOD1(OnVideoOpacityChange, void(bool)); |
MOCK_METHOD0(OnVideoAverageKeyframeDistanceUpdate, void()); |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(PipelineIntegrationTestBase); |
}; |
} // namespace media |