diff options
-rw-r--r-- | media/base/mock_ffmpeg.cc | 41 | ||||
-rw-r--r-- | media/base/mock_ffmpeg.h | 8 | ||||
-rw-r--r-- | media/base/mock_filters.h | 51 | ||||
-rw-r--r-- | media/base/mock_media_filters.h | 656 | ||||
-rw-r--r-- | media/base/pipeline_impl_unittest.cc | 248 | ||||
-rw-r--r-- | media/base/video_frame_impl_unittest.cc | 50 | ||||
-rw-r--r-- | media/filters/ffmpeg_glue_unittest.cc | 441 | ||||
-rw-r--r-- | media/filters/test_video_decoder.h | 80 | ||||
-rw-r--r-- | media/filters/test_video_renderer.h | 67 | ||||
-rw-r--r-- | media/media.gyp | 3 |
10 files changed, 519 insertions, 1126 deletions
diff --git a/media/base/mock_ffmpeg.cc b/media/base/mock_ffmpeg.cc index 054f996..562aff2 100644 --- a/media/base/mock_ffmpeg.cc +++ b/media/base/mock_ffmpeg.cc @@ -7,12 +7,36 @@ #include "base/logging.h" #include "media/filters/ffmpeg_common.h" +using ::testing::_; +using ::testing::AtMost; +using ::testing::DoAll; +using ::testing::Return; +using ::testing::SaveArg; + namespace media { MockFFmpeg* MockFFmpeg::instance_ = NULL; +URLProtocol* MockFFmpeg::protocol_ = NULL; MockFFmpeg::MockFFmpeg() : outstanding_packets_(0) { + // If we haven't assigned our static copy of URLProtocol, set up expectations + // to catch the URLProtocol registered when the singleton instance of + // FFmpegGlue is created. + // + // TODO(scherkus): this feels gross and I need to think of a way to better + // inject/mock singletons. + if (!protocol_) { + EXPECT_CALL(*this, AVCodecInit()) + .Times(AtMost(1)) + .WillOnce(Return()); + EXPECT_CALL(*this, AVRegisterProtocol(_)) + .Times(AtMost(1)) + .WillOnce(DoAll(SaveArg<0>(&protocol_), Return(0))); + EXPECT_CALL(*this, AVRegisterAll()) + .Times(AtMost(1)) + .WillOnce(Return()); + } } MockFFmpeg::~MockFFmpeg() { @@ -40,6 +64,11 @@ MockFFmpeg* MockFFmpeg::get() { } // static +URLProtocol* MockFFmpeg::protocol() { + return protocol_; +} + +// static void MockFFmpeg::DestructPacket(AVPacket* packet) { delete [] packet->data; packet->data = NULL; @@ -49,6 +78,18 @@ void MockFFmpeg::DestructPacket(AVPacket* packet) { // FFmpeg stubs that delegate to the FFmpegMock instance. extern "C" { +void avcodec_init() { + media::MockFFmpeg::get()->AVCodecInit(); +} + +int av_register_protocol(URLProtocol* protocol) { + return media::MockFFmpeg::get()->AVRegisterProtocol(protocol); +} + +void av_register_all() { + media::MockFFmpeg::get()->AVRegisterAll(); +} + AVCodec* avcodec_find_decoder(enum CodecID id) { return media::MockFFmpeg::get()->AVCodecFindDecoder(id); } diff --git a/media/base/mock_ffmpeg.h b/media/base/mock_ffmpeg.h index 3afdef9..4ba38fc 100644 --- a/media/base/mock_ffmpeg.h +++ b/media/base/mock_ffmpeg.h @@ -16,6 +16,10 @@ class MockFFmpeg { MockFFmpeg(); virtual ~MockFFmpeg(); + MOCK_METHOD0(AVCodecInit, void()); + MOCK_METHOD1(AVRegisterProtocol, int(URLProtocol* protocol)); + MOCK_METHOD0(AVRegisterAll, void()); + MOCK_METHOD1(AVCodecFindDecoder, AVCodec*(enum CodecID id)); MOCK_METHOD2(AVCodecOpen, int(AVCodecContext* avctx, AVCodec* codec)); MOCK_METHOD1(AVCodecClose, int(AVCodecContext* avctx)); @@ -51,6 +55,9 @@ class MockFFmpeg { static void set(MockFFmpeg* instance); static MockFFmpeg* get(); + // Returns the URLProtocol registered by the FFmpegGlue singleton. + static URLProtocol* protocol(); + // AVPacket destructor for packets allocated by av_new_packet(). static void DestructPacket(AVPacket* packet); @@ -60,6 +67,7 @@ class MockFFmpeg { private: static MockFFmpeg* instance_; + static URLProtocol* protocol_; // Tracks the number of packets allocated by calls to av_read_frame() and // av_free_packet(). We crash the unit test if this is not zero at time of diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h index bef46a7..bffba6f 100644 --- a/media/base/mock_filters.h +++ b/media/base/mock_filters.h @@ -19,6 +19,27 @@ namespace media { +// Use this template to test for object destruction by setting expectations on +// the method OnDestroy(). +// +// TODO(scherkus): not sure about the naming... perhaps contribute this back +// to gmock itself! +template<class MockClass> +class Destroyable : public MockClass { + public: + Destroyable() {} + + MOCK_METHOD0(OnDestroy, void()); + + protected: + virtual ~Destroyable() { + OnDestroy(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(Destroyable); +}; + class MockDataSource : public DataSource { public: MockDataSource() {} @@ -71,6 +92,12 @@ class MockDemuxerStream : public DemuxerStream { public: MockDemuxerStream() {} + // Sets the mime type of this object's media format, which is usually checked + // to determine the type of decoder to create. + explicit MockDemuxerStream(const std::string& mime_type) { + media_format_.SetAsString(MediaFormat::kMimeType, mime_type); + } + // DemuxerStream implementation. const MediaFormat& media_format() { return media_format_; } MOCK_METHOD1(Read, void(Callback1<Buffer*>::Type* read_callback)); @@ -175,7 +202,8 @@ class MockAudioRenderer : public AudioRenderer { class MockFilterFactory : public FilterFactory { public: MockFilterFactory() - : data_source_(new MockDataSource()), + : creation_successful_(true), + data_source_(new MockDataSource()), demuxer_(new MockDemuxer()), video_decoder_(new MockVideoDecoder()), audio_decoder_(new MockAudioDecoder()), @@ -185,6 +213,11 @@ class MockFilterFactory : public FilterFactory { virtual ~MockFilterFactory() {} + // Controls whether the Create() method is successful or not. + void set_creation_successful(bool creation_successful) { + creation_successful_ = creation_successful; + } + // Mock accessors. MockDataSource* data_source() const { return data_source_; } MockDemuxer* demuxer() const { return demuxer_; } @@ -195,6 +228,10 @@ class MockFilterFactory : public FilterFactory { protected: MediaFilter* Create(FilterType filter_type, const MediaFormat& media_format) { + if (!creation_successful_) { + return NULL; + } + switch (filter_type) { case FILTER_DATA_SOURCE: return data_source_; @@ -215,6 +252,7 @@ class MockFilterFactory : public FilterFactory { } private: + bool creation_successful_; scoped_refptr<MockDataSource> data_source_; scoped_refptr<MockDemuxer> demuxer_; scoped_refptr<MockVideoDecoder> video_decoder_; @@ -225,6 +263,17 @@ class MockFilterFactory : public FilterFactory { DISALLOW_COPY_AND_ASSIGN(MockFilterFactory); }; +// Helper gmock action that calls InitializationComplete() on behalf of the +// provided filter. +ACTION_P(InitializationComplete, filter) { + filter->host()->InitializationComplete(); +} + +// Helper gmock action that calls Error() on behalf of the provided filter. +ACTION_P2(Error, filter, error) { + filter->host()->Error(error); +} + } // namespace media #endif // MEDIA_BASE_MOCK_FILTERS_H_ diff --git a/media/base/mock_media_filters.h b/media/base/mock_media_filters.h deleted file mode 100644 index 698815f..0000000 --- a/media/base/mock_media_filters.h +++ /dev/null @@ -1,656 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this -// source code is governed by a BSD-style license that can be found in the -// LICENSE file. -// -// TODO(ajwong): This whole file is deprecated in favor or gmock style mocks. -// The deprecated classes have been moved into the old_mocks to avoid colliding -// with the newer mock classes. Once all the unittests have been migrated, this -// should be deleted. - -#ifndef MEDIA_BASE_MOCK_MEDIA_FILTERS_H_ -#define MEDIA_BASE_MOCK_MEDIA_FILTERS_H_ - -#include <string> - -#include "base/scoped_ptr.h" -#include "base/waitable_event.h" -#include "media/base/buffers.h" -#include "media/base/factory.h" -#include "media/base/filter_host.h" -#include "media/base/filters.h" -#include "media/base/media_format.h" -#include "media/base/pipeline.h" -#include "media/base/video_frame_impl.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace media { - -namespace old_mocks { - -// Behaviors for MockDataSource filter. -enum MockDataSourceBehavior { - MOCK_DATA_SOURCE_NORMAL_INIT, - MOCK_DATA_SOURCE_NEVER_INIT, - MOCK_DATA_SOURCE_URL_ERROR_IN_INIT, - MOCK_DATA_SOURCE_INIT_RETURN_FALSE, -}; - - -// This class is used by all of the mock filters to change the configuration -// of the desired pipeline. The test using this must ensure that the lifetime -// of the object is at least as long as the lifetime of the filters, as this -// is typically allocated on the stack. -struct MockFilterConfig { - MockFilterConfig() - : create_filter(true), - data_source_behavior(MOCK_DATA_SOURCE_NORMAL_INIT), - data_source_value('!'), - has_video(true), - video_width(1280u), - video_height(720u), - video_surface_format(VideoSurface::YV12), - has_audio(true), - compressed_audio_mime_type(mime_type::kAACAudio), - uncompressed_audio_mime_type(mime_type::kUncompressedAudio), - compressed_video_mime_type(mime_type::kH264AnnexB), - uncompressed_video_mime_type(mime_type::kUncompressedVideo), - frame_duration(base::TimeDelta::FromMicroseconds(33333)), - media_duration(base::TimeDelta::FromSeconds(5)), - media_total_bytes(media_duration.InMilliseconds() * 250) { - } - - bool create_filter; - MockDataSourceBehavior data_source_behavior; - char data_source_value; - bool has_video; - size_t video_width; - size_t video_height; - VideoSurface::Format video_surface_format; - bool has_audio; - std::string compressed_audio_mime_type; - std::string uncompressed_audio_mime_type; - std::string compressed_video_mime_type; - std::string uncompressed_video_mime_type; - base::TimeDelta frame_duration; - base::TimeDelta media_duration; - int64 media_total_bytes; -}; - - -class MockDataSource : public DataSource { - public: - explicit MockDataSource(const MockFilterConfig* config) - : config_(config), - position_(0), - deleted_(NULL) { - } - - MockDataSource(const MockFilterConfig* config, bool* deleted) - : config_(config), - position_(0), - deleted_(deleted) { - EXPECT_TRUE(deleted); - EXPECT_FALSE(*deleted); - } - - // Implementation of MediaFilter. - virtual void Stop() {} - - virtual void Seek(base::TimeDelta time) { - seek_time_ = time; - } - - // Implementation of DataSource. - virtual bool Initialize(const std::string& url) { - media_format_.SetAsString(MediaFormat::kMimeType, - mime_type::kApplicationOctetStream); - media_format_.SetAsString(MediaFormat::kURL, url); - host()->SetTotalBytes(config_->media_total_bytes); - switch (config_->data_source_behavior) { - case MOCK_DATA_SOURCE_NORMAL_INIT: - host()->InitializationComplete(); - return true; - case MOCK_DATA_SOURCE_NEVER_INIT: - return true; - case MOCK_DATA_SOURCE_URL_ERROR_IN_INIT: - host()->Error(PIPELINE_ERROR_URL_NOT_FOUND); - return false; - case MOCK_DATA_SOURCE_INIT_RETURN_FALSE: - return false; - default: - NOTREACHED(); - return false; - } - } - - virtual const MediaFormat& media_format() { - return media_format_; - } - - virtual size_t Read(uint8* data, size_t size) { - size_t read = static_cast<size_t>(config_->media_total_bytes - position_); - if (size < read) { - read = size; - } - memset(data, config_->data_source_value, read); - return read; - } - - virtual bool GetPosition(int64* position_out) { - *position_out = position_; - return true; - } - - virtual bool SetPosition(int64 position) { - if (position < 0u || position > config_->media_total_bytes) { - return false; - } - position_ = position; - return true; - } - - virtual bool GetSize(int64* size_out) { - if (config_->media_total_bytes >= 0) { - *size_out = config_->media_total_bytes; - return true; - } - return false; - } - - virtual bool IsSeekable() { - return true; - } - - // Mock accessors. - int64 position() const { return position_; } - const base::TimeDelta& seek_time() const { return seek_time_; } - - private: - virtual ~MockDataSource() { - if (deleted_) { - *deleted_ = true; - } - } - - const MockFilterConfig* config_; - int64 position_; - MediaFormat media_format_; - base::TimeDelta seek_time_; - - // Set to true inside the destructor. Used in FFmpegGlue unit tests for - // testing proper reference counting. - bool* deleted_; - - DISALLOW_COPY_AND_ASSIGN(MockDataSource); -}; - - -class MockDemuxerStream : public DemuxerStream { - public: - MockDemuxerStream(const MockFilterConfig* config, bool is_audio) { - if (is_audio) { - media_format_.SetAsString(MediaFormat::kMimeType, - config->compressed_audio_mime_type); - } else { - media_format_.SetAsString(MediaFormat::kMimeType, - config->compressed_video_mime_type); - media_format_.SetAsInteger(MediaFormat::kWidth, config->video_width); - media_format_.SetAsInteger(MediaFormat::kHeight, config->video_height); - } - } - - // Implementation of DemuxerStream. - virtual const MediaFormat& media_format() { - return media_format_; - } - - virtual void Read(Callback1<Buffer*>::Type* read_callback) { - NOTREACHED(); // TODO(ralphl): fix me!! - } - - private: - virtual ~MockDemuxerStream() {} - - MediaFormat media_format_; - - DISALLOW_COPY_AND_ASSIGN(MockDemuxerStream); -}; - - -class MockDemuxer : public Demuxer { - public: - explicit MockDemuxer(const MockFilterConfig* config) - : config_(config), - mock_audio_stream_(new MockDemuxerStream(config, true)), - mock_video_stream_(new MockDemuxerStream(config, false)) { - } - - // Implementation of MediaFilter. - virtual void Stop() {} - - virtual void Seek(base::TimeDelta time) { - seek_time_ = time; - } - - // Implementation of Demuxer. - virtual bool Initialize(DataSource* data_source) { - host()->InitializationComplete(); - return true; - } - - virtual size_t GetNumberOfStreams() { - size_t num_streams = 0; - if (config_->has_audio) { - ++num_streams; - } - if (config_->has_video) { - ++num_streams; - } - return num_streams; - } - - virtual scoped_refptr<DemuxerStream> GetStream(int stream_id) { - switch (stream_id) { - case 0: - if (config_->has_audio) { - return mock_audio_stream_; - } else if (config_->has_video) { - return mock_video_stream_; - } - break; - case 1: - if (config_->has_audio && config_->has_video) { - return mock_video_stream_; - } - break; - } - ADD_FAILURE(); - return NULL; - } - - // Mock accessors. - const base::TimeDelta& seek_time() const { return seek_time_; } - - private: - virtual ~MockDemuxer() {} - - const MockFilterConfig* config_; - scoped_refptr<DemuxerStream> mock_audio_stream_; - scoped_refptr<DemuxerStream> mock_video_stream_; - base::TimeDelta seek_time_; - - DISALLOW_COPY_AND_ASSIGN(MockDemuxer); -}; - - -class MockAudioDecoder : public AudioDecoder { - public: - explicit MockAudioDecoder(const MockFilterConfig* config) { - media_format_.SetAsString(MediaFormat::kMimeType, - config->uncompressed_audio_mime_type); - } - - // Implementation of MediaFilter. - virtual void Stop() {} - - virtual void Seek(base::TimeDelta time) { - seek_time_ = time; - } - - // Implementation of AudioDecoder. - virtual bool Initialize(DemuxerStream* stream) { - host()->InitializationComplete(); - return true; - } - - virtual const MediaFormat& media_format() { - return media_format_; - } - - virtual void Read(Callback1<Buffer*>::Type* callback) { - // TODO(ralphl): implement mock read. - NOTREACHED(); - } - - // Mock accessors. - const base::TimeDelta& seek_time() const { return seek_time_; } - - private: - virtual ~MockAudioDecoder() {} - - MediaFormat media_format_; - base::TimeDelta seek_time_; - - DISALLOW_COPY_AND_ASSIGN(MockAudioDecoder); -}; - - -class MockAudioRenderer : public AudioRenderer { - public: - explicit MockAudioRenderer(const MockFilterConfig* config) {} - - // Implementation of MediaFilter. - virtual void Stop() {} - - virtual void Seek(base::TimeDelta time) { - seek_time_ = time; - } - - // Implementation of AudioRenderer. - virtual bool Initialize(AudioDecoder* decoder) { - host()->InitializationComplete(); - return true; - } - - virtual void SetVolume(float volume) {} - - // Mock accessors. - const base::TimeDelta& seek_time() const { return seek_time_; } - - private: - virtual ~MockAudioRenderer() {} - - base::TimeDelta seek_time_; - - DISALLOW_COPY_AND_ASSIGN(MockAudioRenderer); -}; - - -class MockVideoDecoder : public VideoDecoder { - public: - // Helper function that initializes a YV12 frame with white and black scan - // lines based on the |white_to_black| parameter. If 0, then the entire - // frame will be black, if 1 then the entire frame will be white. - static void InitializeYV12Frame(VideoFrame* frame, double white_to_black) { - VideoSurface surface; - if (!frame->Lock(&surface)) { - ADD_FAILURE(); - } else { - EXPECT_EQ(surface.format, VideoSurface::YV12); - size_t first_black_row = static_cast<size_t>(surface.height * - white_to_black); - uint8* y_plane = surface.data[VideoSurface::kYPlane]; - for (size_t row = 0; row < surface.height; ++row) { - int color = (row < first_black_row) ? 0xFF : 0x00; - memset(y_plane, color, surface.width); - y_plane += surface.strides[VideoSurface::kYPlane]; - } - uint8* u_plane = surface.data[VideoSurface::kUPlane]; - uint8* v_plane = surface.data[VideoSurface::kVPlane]; - for (size_t row = 0; row < surface.height; row += 2) { - memset(u_plane, 0x80, surface.width / 2); - memset(v_plane, 0x80, surface.width / 2); - u_plane += surface.strides[VideoSurface::kUPlane]; - v_plane += surface.strides[VideoSurface::kVPlane]; - } - frame->Unlock(); - } - } - - explicit MockVideoDecoder(const MockFilterConfig* config) - : config_(config) { - media_format_.SetAsString(MediaFormat::kMimeType, - config->uncompressed_video_mime_type); - media_format_.SetAsInteger(MediaFormat::kWidth, config->video_width); - media_format_.SetAsInteger(MediaFormat::kHeight, config->video_height); - } - - // Implementation of MediaFilter. - virtual void Stop() {} - - virtual void Seek(base::TimeDelta time) { - seek_time_ = time; - } - - // Implementation of VideoDecoder. - virtual bool Initialize(DemuxerStream* stream) { - host()->InitializationComplete(); - return true; - } - - virtual const MediaFormat& media_format() { - return media_format_; - } - - virtual void Read(Callback1<VideoFrame*>::Type* callback) { - DoRead(callback); - } - - // Mock accessors. - const base::TimeDelta& seek_time() const { return seek_time_; } - - private: - virtual ~MockVideoDecoder() {} - - void DoRead(Callback1<VideoFrame*>::Type* callback) { - scoped_ptr<Callback1<VideoFrame*>::Type> scoped_callback(callback); - if (mock_frame_time_ < config_->media_duration) { - // TODO(ralphl): Mock video decoder only works with YV12. Implement other - // formats as needed. - EXPECT_EQ(config_->video_surface_format, VideoSurface::YV12); - scoped_refptr<VideoFrame> frame; - VideoFrameImpl::CreateFrame(config_->video_surface_format, - config_->video_width, - config_->video_height, - mock_frame_time_, - config_->frame_duration, - &frame); - if (!frame) { - host()->Error(PIPELINE_ERROR_OUT_OF_MEMORY); - ADD_FAILURE(); - } else { - mock_frame_time_ += config_->frame_duration; - if (mock_frame_time_ >= config_->media_duration) { - VideoFrameImpl::CreateEmptyFrame(&frame); - } else { - InitializeYV12Frame(frame, (mock_frame_time_.InSecondsF() / - config_->media_duration.InSecondsF())); - } - callback->Run(frame); - } - } - } - - MediaFormat media_format_; - base::TimeDelta mock_frame_time_; - base::TimeDelta seek_time_; - const MockFilterConfig* config_; - - DISALLOW_COPY_AND_ASSIGN(MockVideoDecoder); -}; - - -class MockVideoRenderer : public VideoRenderer { - public: - explicit MockVideoRenderer(const MockFilterConfig* config) - : config_(config) { - } - - // Implementation of MediaFilter. - virtual void Stop() {} - - virtual void Seek(base::TimeDelta time) { - seek_time_ = time; - } - - // Implementation of VideoRenderer. - virtual bool Initialize(VideoDecoder* decoder) { - host()->SetVideoSize(config_->video_width, config_->video_height); - host()->InitializationComplete(); - return true; - } - - // Mock accessors. - const base::TimeDelta& seek_time() const { return seek_time_; } - - private: - virtual ~MockVideoRenderer() {} - - base::TimeDelta seek_time_; - const MockFilterConfig* config_; - - DISALLOW_COPY_AND_ASSIGN(MockVideoRenderer); -}; - - -// FilterFactory capable of creating each mock filter type. Only one instance -// of each filter type can exist at any time. Filters can be inspected for -// expectations using the accessors, which may return NULL if the filter was -// never created (i.e., streams containing no video). -class MockFilterFactory : public FilterFactory { - public: - explicit MockFilterFactory(const MockFilterConfig* config) - : config_(config) { - } - - // Mock accessors. - MockDataSource* data_source() const { return data_source_; } - MockDemuxer* demuxer() const { return demuxer_; } - MockAudioDecoder* audio_decoder() const { return audio_decoder_; } - MockVideoDecoder* video_decoder() const { return video_decoder_; } - MockAudioRenderer* audio_renderer() const { return audio_renderer_; } - MockVideoRenderer* video_renderer() const { return video_renderer_; } - - protected: - MediaFilter* Create(FilterType filter_type, const MediaFormat& media_format) { - if (!config_->create_filter) - return NULL; - - switch (filter_type) { - case FILTER_DATA_SOURCE: - DCHECK(!data_source_); - data_source_ = new MockDataSource(config_); - return data_source_; - - case FILTER_DEMUXER: - DCHECK(!demuxer_); - demuxer_ = new MockDemuxer(config_); - return demuxer_; - - case FILTER_AUDIO_DECODER: - DCHECK(!audio_decoder_); - audio_decoder_ = new MockAudioDecoder(config_); - return audio_decoder_; - - case FILTER_VIDEO_DECODER: - DCHECK(!video_decoder_); - video_decoder_ = new MockVideoDecoder(config_); - return video_decoder_; - - case FILTER_AUDIO_RENDERER: - DCHECK(!audio_renderer_); - audio_renderer_ = new MockAudioRenderer(config_); - return audio_renderer_; - - case FILTER_VIDEO_RENDERER: - DCHECK(!video_renderer_); - video_renderer_ = new MockVideoRenderer(config_); - return video_renderer_; - - default: - NOTREACHED(); - } - return NULL; - } - - private: - const MockFilterConfig* config_; - scoped_refptr<MockDataSource> data_source_; - scoped_refptr<MockDemuxer> demuxer_; - scoped_refptr<MockAudioDecoder> audio_decoder_; - scoped_refptr<MockVideoDecoder> video_decoder_; - scoped_refptr<MockAudioRenderer> audio_renderer_; - scoped_refptr<MockVideoRenderer> video_renderer_; - - DISALLOW_COPY_AND_ASSIGN(MockFilterFactory); -}; - -// A simple class that waits for a pipeline to be started and checks some -// basic initialization values. The Start() method will not return until -// either a pre-determined amount of time has passed or the pipeline calls the -// InitCallback() callback. A typical use would be: -// Pipeline p; -// FilterFactoryCollection f; -// f->AddFactory(a); -// f->AddFactory(b); -// ... -// InitializationHelper h; -// h.Start(&p, f, uri); -// -// If the test is expecting to produce an error use would be: -// h.Start(&p, f, uri, PIPELINE_ERROR_REQUIRED_FILTER_MISSING) -// -// If the test expects the pipeline to hang during initialization (a filter -// never calls FilterHost::InitializationComplete()) then the use would be: -// h.Start(&p, f, uri, PIPELINE_OK, true); -// -// TODO(scherkus): Keep refactoring tests until we can remove this entirely. -class InitializationHelper { - public: - InitializationHelper() - : event_(true, false), - callback_success_status_(false), - waiting_for_callback_(false) {} - - // If callback has been called, then returns the boolean passed by the - // pipeline to the callback. - bool callback_success_status() { return callback_success_status_; } - - // Returns true if Start has been called, but the pipeline has not yet - // called the initialization complete callback. - bool waiting_for_callback() { return waiting_for_callback_; } - - // Starts the pipeline, providing an initialization callback that points - // to this object. - void Start(Pipeline* pipeline, - FilterFactory* filter_factory, - const std::string& uri, - PipelineError expect_error = PIPELINE_OK, - bool expect_hang = false) { - // For tests that we expect to hang in initialization, we want to - // wait a short time. If a hang is not expected, then wait long enough - // to make sure that the filters have time to initalize. 1/2 second if - // we expect to hang, and 3 seconds if we expect success. - base::TimeDelta max_wait = base::TimeDelta::FromMilliseconds(expect_hang ? - 500 : 3000); - EXPECT_FALSE(waiting_for_callback_); - waiting_for_callback_ = true; - callback_success_status_ = false; - event_.Reset(); - pipeline->Start(filter_factory, uri, - NewCallback(this, &InitializationHelper::InitCallback)); - bool signaled = event_.TimedWait(max_wait); - if (expect_hang) { - EXPECT_FALSE(signaled); - EXPECT_FALSE(pipeline->IsInitialized()); - EXPECT_TRUE(waiting_for_callback_); - } else { - EXPECT_TRUE(signaled); - EXPECT_FALSE(waiting_for_callback_); - EXPECT_EQ(pipeline->GetError(), expect_error); - EXPECT_EQ(callback_success_status_, (expect_error == PIPELINE_OK)); - EXPECT_EQ(pipeline->IsInitialized(), (expect_error == PIPELINE_OK)); - } - } - - private: - void InitCallback(bool success) { - EXPECT_TRUE(waiting_for_callback_); - EXPECT_FALSE(event_.IsSignaled()); - waiting_for_callback_ = false; - callback_success_status_ = success; - event_.Signal(); - } - - base::WaitableEvent event_; - bool callback_success_status_; - bool waiting_for_callback_; - - DISALLOW_COPY_AND_ASSIGN(InitializationHelper); -}; - -} // namespace old_mocks - -} // namespace media - -#endif // MEDIA_BASE_MOCK_MEDIA_FILTERS_H_ diff --git a/media/base/pipeline_impl_unittest.cc b/media/base/pipeline_impl_unittest.cc index 56aa246..4183126 100644 --- a/media/base/pipeline_impl_unittest.cc +++ b/media/base/pipeline_impl_unittest.cc @@ -10,34 +10,38 @@ #include "media/base/filters.h" #include "media/base/factory.h" #include "media/base/filter_host.h" -#include "media/base/mock_media_filters.h" +#include "media/base/mock_filters.h" #include "testing/gtest/include/gtest/gtest.h" -namespace { +using ::testing::DoAll; +using ::testing::Return; +using ::testing::StrictMock; -class PipelineImplTest : public testing::Test { - protected: +namespace media { + +typedef std::vector<MockDemuxerStream*> MockDemuxerStreamVector; + +class PipelineImplTest : public ::testing::Test { + public: PipelineImplTest() - : initialize_result_(false), + : mocks_(new MockFilterFactory()), + initialize_result_(false), seek_result_(false), initialize_event_(false, false), seek_event_(false, false) { } - virtual ~PipelineImplTest() {} - - virtual void TearDown() { + virtual ~PipelineImplTest() { // Force the pipeline to shut down its thread. pipeline_.Stop(); } + protected: // Called by tests after they have finished setting up MockFilterConfig. // Initializes the pipeline and returns true if the initialization callback // was executed, false otherwise. bool InitializeAndWait() { - DCHECK(!filters_); - filters_ = new media::old_mocks::MockFilterFactory(&config_); - pipeline_.Start(filters_, "", + pipeline_.Start(mocks_, "", NewCallback(this, &PipelineImplTest::OnInitialize)); return initialize_event_.TimedWait(base::TimeDelta::FromMilliseconds(500)); } @@ -49,10 +53,66 @@ class PipelineImplTest : public testing::Test { return seek_event_.TimedWait(base::TimeDelta::FromMilliseconds(500)); } + // Sets up expectations to allow the data source to initialize. + void InitializeDataSource() { + EXPECT_CALL(*mocks_->data_source(), Initialize("")) + .WillOnce(DoAll(InitializationComplete(mocks_->data_source()), + Return(true))); + EXPECT_CALL(*mocks_->data_source(), Stop()); + } + + // Sets up expectations to allow the demuxer to initialize. + void InitializeDemuxer(MockDemuxerStreamVector* streams) { + EXPECT_CALL(*mocks_->demuxer(), Initialize(mocks_->data_source())) + .WillOnce(DoAll(InitializationComplete(mocks_->demuxer()), + Return(true))); + EXPECT_CALL(*mocks_->demuxer(), GetNumberOfStreams()) + .WillRepeatedly(Return(streams->size())); + EXPECT_CALL(*mocks_->demuxer(), Stop()); + + // Configure the demuxer to return the streams. + for (size_t i = 0; i < streams->size(); ++i) { + scoped_refptr<DemuxerStream> stream = (*streams)[i]; + EXPECT_CALL(*mocks_->demuxer(), GetStream(i)) + .WillRepeatedly(Return(stream)); + } + } + + // Sets up expectations to allow the video decoder to initialize. + void InitializeVideoDecoder(MockDemuxerStream* stream) { + EXPECT_CALL(*mocks_->video_decoder(), Initialize(stream)) + .WillOnce(DoAll(InitializationComplete(mocks_->video_decoder()), + Return(true))); + EXPECT_CALL(*mocks_->video_decoder(), Stop()); + } + + // Sets up expectations to allow the audio decoder to initialize. + void InitializeAudioDecoder(MockDemuxerStream* stream) { + EXPECT_CALL(*mocks_->audio_decoder(), Initialize(stream)) + .WillOnce(DoAll(InitializationComplete(mocks_->audio_decoder()), + Return(true))); + EXPECT_CALL(*mocks_->audio_decoder(), Stop()); + } + + // Sets up expectations to allow the video renderer to initialize. + void InitializeVideoRenderer() { + EXPECT_CALL(*mocks_->video_renderer(), Initialize(mocks_->video_decoder())) + .WillOnce(DoAll(InitializationComplete(mocks_->video_renderer()), + Return(true))); + EXPECT_CALL(*mocks_->video_renderer(), Stop()); + } + + // Sets up expectations to allow the audio renderer to initialize. + void InitializeAudioRenderer() { + EXPECT_CALL(*mocks_->audio_renderer(), Initialize(mocks_->audio_decoder())) + .WillOnce(DoAll(InitializationComplete(mocks_->audio_renderer()), + Return(true))); + EXPECT_CALL(*mocks_->audio_renderer(), Stop()); + } + // Fixture members. media::PipelineImpl pipeline_; - scoped_refptr<media::old_mocks::MockFilterFactory> filters_; - media::old_mocks::MockFilterConfig config_; + scoped_refptr<media::MockFilterFactory> mocks_; bool initialize_result_; bool seek_result_; @@ -75,7 +135,9 @@ class PipelineImplTest : public testing::Test { }; TEST_F(PipelineImplTest, NeverInitializes) { - config_.data_source_behavior = media::old_mocks::MOCK_DATA_SOURCE_NEVER_INIT; + EXPECT_CALL(*mocks_->data_source(), Initialize("")) + .WillOnce(Return(true)); + EXPECT_CALL(*mocks_->data_source(), Stop()); // This test hangs during initialization by never calling // InitializationComplete(). Make sure we tear down the pipeline properly. @@ -86,7 +148,7 @@ TEST_F(PipelineImplTest, NeverInitializes) { } TEST_F(PipelineImplTest, RequiredFilterMissing) { - config_.create_filter = false; + mocks_->set_creation_successful(false); ASSERT_TRUE(InitializeAndWait()); EXPECT_FALSE(initialize_result_); @@ -96,8 +158,11 @@ TEST_F(PipelineImplTest, RequiredFilterMissing) { } TEST_F(PipelineImplTest, URLNotFound) { - config_.data_source_behavior = - media::old_mocks::MOCK_DATA_SOURCE_URL_ERROR_IN_INIT; + EXPECT_CALL(*mocks_->data_source(), Initialize("")) + .WillOnce(DoAll(Error(mocks_->data_source(), + PIPELINE_ERROR_URL_NOT_FOUND), + Return(false))); + EXPECT_CALL(*mocks_->data_source(), Stop()); ASSERT_TRUE(InitializeAndWait()); EXPECT_FALSE(initialize_result_); @@ -106,117 +171,128 @@ TEST_F(PipelineImplTest, URLNotFound) { } TEST_F(PipelineImplTest, NoStreams) { - config_.has_audio = false; - config_.has_video = false; + MockDemuxerStreamVector streams; + InitializeDataSource(); + InitializeDemuxer(&streams); ASSERT_TRUE(InitializeAndWait()); EXPECT_FALSE(initialize_result_); EXPECT_FALSE(pipeline_.IsInitialized()); EXPECT_EQ(media::PIPELINE_ERROR_COULD_NOT_RENDER, pipeline_.GetError()); - - EXPECT_FALSE(filters_->audio_decoder()); - EXPECT_FALSE(filters_->audio_renderer()); - EXPECT_FALSE(filters_->video_decoder()); - EXPECT_FALSE(filters_->video_renderer()); } TEST_F(PipelineImplTest, AudioStream) { - config_.has_video = false; + scoped_refptr<StrictMock<MockDemuxerStream> > stream = + new StrictMock<MockDemuxerStream>("audio/x-foo"); + MockDemuxerStreamVector streams; + streams.push_back(stream); + + InitializeDataSource(); + InitializeDemuxer(&streams); + InitializeAudioDecoder(stream); + InitializeAudioRenderer(); ASSERT_TRUE(InitializeAndWait()); EXPECT_TRUE(initialize_result_); EXPECT_TRUE(pipeline_.IsInitialized()); EXPECT_EQ(media::PIPELINE_OK, pipeline_.GetError()); - - size_t width, height; - pipeline_.GetVideoSize(&width, &height); - EXPECT_EQ(0u, width); - EXPECT_EQ(0u, height); EXPECT_TRUE(pipeline_.IsRendered(media::mime_type::kMajorTypeAudio)); EXPECT_FALSE(pipeline_.IsRendered(media::mime_type::kMajorTypeVideo)); - - EXPECT_TRUE(filters_->audio_decoder()); - EXPECT_TRUE(filters_->audio_renderer()); - EXPECT_FALSE(filters_->video_decoder()); - EXPECT_FALSE(filters_->video_renderer()); } TEST_F(PipelineImplTest, VideoStream) { - config_.has_audio = false; + scoped_refptr<StrictMock<MockDemuxerStream> > stream = + new StrictMock<MockDemuxerStream>("video/x-foo"); + MockDemuxerStreamVector streams; + streams.push_back(stream); + + InitializeDataSource(); + InitializeDemuxer(&streams); + InitializeVideoDecoder(stream); + InitializeVideoRenderer(); ASSERT_TRUE(InitializeAndWait()); EXPECT_TRUE(initialize_result_); EXPECT_TRUE(pipeline_.IsInitialized()); EXPECT_EQ(media::PIPELINE_OK, pipeline_.GetError()); - - size_t width, height; - pipeline_.GetVideoSize(&width, &height); - EXPECT_EQ(config_.video_width, width); - EXPECT_EQ(config_.video_height, height); EXPECT_FALSE(pipeline_.IsRendered(media::mime_type::kMajorTypeAudio)); EXPECT_TRUE(pipeline_.IsRendered(media::mime_type::kMajorTypeVideo)); - - EXPECT_FALSE(filters_->audio_decoder()); - EXPECT_FALSE(filters_->audio_renderer()); - EXPECT_TRUE(filters_->video_decoder()); - EXPECT_TRUE(filters_->video_renderer()); } TEST_F(PipelineImplTest, AudioVideoStream) { + scoped_refptr<StrictMock<MockDemuxerStream> > audio_stream = + new StrictMock<MockDemuxerStream>("audio/x-foo"); + scoped_refptr<StrictMock<MockDemuxerStream> > video_stream = + new StrictMock<MockDemuxerStream>("video/x-foo"); + MockDemuxerStreamVector streams; + streams.push_back(audio_stream); + streams.push_back(video_stream); + + InitializeDataSource(); + InitializeDemuxer(&streams); + InitializeAudioDecoder(audio_stream); + InitializeAudioRenderer(); + InitializeVideoDecoder(video_stream); + InitializeVideoRenderer(); + ASSERT_TRUE(InitializeAndWait()); EXPECT_TRUE(initialize_result_); EXPECT_TRUE(pipeline_.IsInitialized()); EXPECT_EQ(media::PIPELINE_OK, pipeline_.GetError()); - - size_t width, height; - pipeline_.GetVideoSize(&width, &height); - EXPECT_EQ(config_.video_width, width); - EXPECT_EQ(config_.video_height, height); EXPECT_TRUE(pipeline_.IsRendered(media::mime_type::kMajorTypeAudio)); EXPECT_TRUE(pipeline_.IsRendered(media::mime_type::kMajorTypeVideo)); - - EXPECT_TRUE(filters_->audio_decoder()); - EXPECT_TRUE(filters_->audio_renderer()); - EXPECT_TRUE(filters_->video_decoder()); - EXPECT_TRUE(filters_->video_renderer()); } TEST_F(PipelineImplTest, Seek) { - ASSERT_TRUE(InitializeAndWait()); - - // Seek and verify callback returned true. + scoped_refptr<StrictMock<MockDemuxerStream> > audio_stream = + new StrictMock<MockDemuxerStream>("audio/x-foo"); + scoped_refptr<StrictMock<MockDemuxerStream> > video_stream = + new StrictMock<MockDemuxerStream>("video/x-foo"); + MockDemuxerStreamVector streams; + streams.push_back(audio_stream); + streams.push_back(video_stream); + + InitializeDataSource(); + InitializeDemuxer(&streams); + InitializeAudioDecoder(audio_stream); + InitializeAudioRenderer(); + InitializeVideoDecoder(video_stream); + InitializeVideoRenderer(); + + // Every filter should receive a call to Seek(). base::TimeDelta expected = base::TimeDelta::FromSeconds(2000); + EXPECT_CALL(*mocks_->data_source(), Seek(expected)); + EXPECT_CALL(*mocks_->demuxer(), Seek(expected)); + EXPECT_CALL(*mocks_->audio_decoder(), Seek(expected)); + EXPECT_CALL(*mocks_->audio_renderer(), Seek(expected)); + EXPECT_CALL(*mocks_->video_decoder(), Seek(expected)); + EXPECT_CALL(*mocks_->video_renderer(), Seek(expected)); + + // Initialize then seek! + ASSERT_TRUE(InitializeAndWait()); EXPECT_TRUE(SeekAndWait(expected)); EXPECT_TRUE(seek_result_); - - // Verify every filter received the seek. - // TODO(scherkus): implement whatever it takes so I can use EXPECT_EQ with - // base::TimeDelta. - EXPECT_TRUE(expected == filters_->data_source()->seek_time()); - EXPECT_TRUE(expected == filters_->demuxer()->seek_time()); - EXPECT_TRUE(expected == filters_->audio_decoder()->seek_time()); - EXPECT_TRUE(expected == filters_->audio_renderer()->seek_time()); - EXPECT_TRUE(expected == filters_->video_decoder()->seek_time()); - EXPECT_TRUE(expected == filters_->video_renderer()->seek_time()); } -// Try to execute Start()/Stop() on the Pipeline many times and very fast. This -// test is trying to simulate the situation where the pipeline can get dead -// locked very easily by quickly calling Start()/Stop(). -TEST_F(PipelineImplTest, StressTestPipelineStartStop) { - media::old_mocks::MockFilterConfig config; - const int kTimes = 1000; - for (int i = 0; i < kTimes; ++i) { - scoped_refptr<media::old_mocks::MockFilterFactory> factory = - new media::old_mocks::MockFilterFactory(&config); - media::PipelineImpl pipeline; - pipeline.Start(factory.get(), "", NULL); - pipeline.Stop(); - } +TEST_F(PipelineImplTest, SetVolume) { + scoped_refptr<StrictMock<MockDemuxerStream> > audio_stream = + new StrictMock<MockDemuxerStream>("audio/x-foo"); + MockDemuxerStreamVector streams; + streams.push_back(audio_stream); + + InitializeDataSource(); + InitializeDemuxer(&streams); + InitializeAudioDecoder(audio_stream); + InitializeAudioRenderer(); + + // The audio renderer should receive a call to SetVolume(). + float expected = 0.5f; + EXPECT_CALL(*mocks_->audio_renderer(), SetVolume(expected)); + + // Initialize then set volume! + ASSERT_TRUE(InitializeAndWait()); + pipeline_.SetVolume(expected); } -// TODO(ralphl): Add a unit test that makes sure that the mock audio filter -// is actually called on a SetVolume() call to the pipeline. I almost checked -// in code that broke this, but all unit tests were passing. +} // namespace media -} // namespace diff --git a/media/base/video_frame_impl_unittest.cc b/media/base/video_frame_impl_unittest.cc index a6a1a6a..eeec716 100644 --- a/media/base/video_frame_impl_unittest.cc +++ b/media/base/video_frame_impl_unittest.cc @@ -3,15 +3,40 @@ // found in the LICENSE file. #include "media/base/buffers.h" -#include "media/base/mock_media_filters.h" +#include "media/base/mock_filters.h" #include "media/base/video_frame_impl.h" #include "media/base/yuv_convert.h" #include "testing/gtest/include/gtest/gtest.h" -using media::VideoFrameImpl; -using media::VideoSurface; +namespace media { -namespace { +// Helper function that initializes a YV12 frame with white and black scan +// lines based on the |white_to_black| parameter. If 0, then the entire +// frame will be black, if 1 then the entire frame will be white. +void InitializeYV12Frame(VideoFrame* frame, double white_to_black) { + VideoSurface surface; + if (!frame->Lock(&surface)) { + ADD_FAILURE(); + return; + } + EXPECT_EQ(surface.format, VideoSurface::YV12); + size_t first_black_row = static_cast<size_t>(surface.height * white_to_black); + uint8* y_plane = surface.data[VideoSurface::kYPlane]; + for (size_t row = 0; row < surface.height; ++row) { + int color = (row < first_black_row) ? 0xFF : 0x00; + memset(y_plane, color, surface.width); + y_plane += surface.strides[VideoSurface::kYPlane]; + } + uint8* u_plane = surface.data[VideoSurface::kUPlane]; + uint8* v_plane = surface.data[VideoSurface::kVPlane]; + for (size_t row = 0; row < surface.height; row += 2) { + memset(u_plane, 0x80, surface.width / 2); + memset(v_plane, 0x80, surface.width / 2); + u_plane += surface.strides[VideoSurface::kUPlane]; + v_plane += surface.strides[VideoSurface::kVPlane]; + } + frame->Unlock(); +} // Given a |yv12_frame| this method converts the YV12 frame to RGBA and // makes sure that all the pixels of the RBG frame equal |expect_rgb_color|. @@ -65,10 +90,7 @@ void ExpectFrameColor(media::VideoFrame* yv12_frame, uint32 expect_rgb_color) { yv12_frame->Unlock(); } -} // namespace - - -TEST(VideoFrameImpl, Basic) { +TEST(VideoFrameImpl, CreateFrame) { const size_t kWidth = 64; const size_t kHeight = 48; const base::TimeDelta kTimestampA = base::TimeDelta::FromMicroseconds(1337); @@ -78,8 +100,8 @@ TEST(VideoFrameImpl, Basic) { // Create a YV12 Video Frame. scoped_refptr<media::VideoFrame> frame; - media::VideoFrameImpl::CreateFrame(media::VideoSurface::YV12, kWidth, kHeight, - kTimestampA, kDurationA, &frame); + VideoFrameImpl::CreateFrame(media::VideoSurface::YV12, kWidth, kHeight, + kTimestampA, kDurationA, &frame); ASSERT_TRUE(frame); // Test StreamSample implementation. @@ -98,12 +120,14 @@ TEST(VideoFrameImpl, Basic) { EXPECT_FALSE(frame->IsDiscontinuous()); // Test VideoFrame implementation. - media::old_mocks::MockVideoDecoder::InitializeYV12Frame(frame, 0.0f); + InitializeYV12Frame(frame, 0.0f); ExpectFrameColor(frame, 0xFF000000); - media::old_mocks::MockVideoDecoder::InitializeYV12Frame(frame, 1.0f); + InitializeYV12Frame(frame, 1.0f); ExpectFrameColor(frame, 0xFFFFFFFF); // Test an empty frame. - media::VideoFrameImpl::CreateEmptyFrame(&frame); + VideoFrameImpl::CreateEmptyFrame(&frame); EXPECT_TRUE(frame->IsEndOfStream()); } + +} // namespace media diff --git a/media/filters/ffmpeg_glue_unittest.cc b/media/filters/ffmpeg_glue_unittest.cc index 993fb31..9f60868 100644 --- a/media/filters/ffmpeg_glue_unittest.cc +++ b/media/filters/ffmpeg_glue_unittest.cc @@ -2,65 +2,81 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "media/base/filters.h" -#include "media/base/mock_media_filters.h" +#include "media/base/mock_ffmpeg.h" +#include "media/base/mock_filters.h" #include "media/filters/ffmpeg_common.h" #include "media/filters/ffmpeg_glue.h" #include "testing/gtest/include/gtest/gtest.h" -// FFmpeg mocks to remove dependency on having the DLLs present. -extern "C" { -static bool g_avcodec_init = false; -static URLProtocol* g_protocol = NULL; -static bool g_av_register_all = false; - -void avcodec_init() { - EXPECT_FALSE(g_avcodec_init); - g_avcodec_init = true; -} - -int av_register_protocol(URLProtocol* protocol) { - EXPECT_FALSE(g_protocol); - g_protocol = protocol; - return 0; -} - -void av_register_all() { - EXPECT_FALSE(g_av_register_all); - g_av_register_all = true; -} -} // extern "C" - -TEST(FFmpegGlueTest, InitializeFFmpeg) { +using ::testing::_; +using ::testing::DoAll; +using ::testing::InSequence; +using ::testing::Return; +using ::testing::SetArgumentPointee; +using ::testing::StrictMock; + +namespace media { + +class FFmpegGlueTest : public ::testing::Test { + public: + FFmpegGlueTest() { + MockFFmpeg::set(&mock_ffmpeg_); + } + + virtual ~FFmpegGlueTest() { + MockFFmpeg::set(NULL); + } + + // Helper to open a URLContext pointing to the given mocked data source. + // Callers are expected to close the context at the end of their test. + virtual void OpenContext(MockDataSource* data_source, URLContext* context) { + // IsSeekable() is called when opening. + EXPECT_CALL(*data_source, IsSeekable()).WillOnce(Return(false)); + + // Add the data source to the glue layer and open a context. + std::string key = FFmpegGlue::get()->AddDataSource(data_source); + memset(context, 0, sizeof(*context)); + EXPECT_EQ(0, protocol_->url_open(context, key.c_str(), 0)); + FFmpegGlue::get()->RemoveDataSource(data_source); + } + + protected: + // Fixture members. + MockFFmpeg mock_ffmpeg_; + static URLProtocol* protocol_; + + private: + DISALLOW_COPY_AND_ASSIGN(FFmpegGlueTest); +}; + +URLProtocol* FFmpegGlueTest::protocol_ = NULL; + +TEST_F(FFmpegGlueTest, InitializeFFmpeg) { // Singleton should initialize FFmpeg. - media::FFmpegGlue* glue = media::FFmpegGlue::get(); + FFmpegGlue* glue = FFmpegGlue::get(); EXPECT_TRUE(glue); - EXPECT_TRUE(g_avcodec_init); - EXPECT_TRUE(g_protocol); - EXPECT_TRUE(g_av_register_all); + + // Assign our static copy of URLProtocol for the rest of the tests. + protocol_ = MockFFmpeg::protocol(); // Make sure URLProtocol was filled out correctly. - EXPECT_STREQ("http", g_protocol->name); - EXPECT_TRUE(g_protocol->url_close); - EXPECT_TRUE(g_protocol->url_open); - EXPECT_TRUE(g_protocol->url_read); - EXPECT_TRUE(g_protocol->url_seek); - EXPECT_TRUE(g_protocol->url_write); + EXPECT_STREQ("http", protocol_->name); + EXPECT_TRUE(protocol_->url_close); + EXPECT_TRUE(protocol_->url_open); + EXPECT_TRUE(protocol_->url_read); + EXPECT_TRUE(protocol_->url_seek); + EXPECT_TRUE(protocol_->url_write); } -TEST(FFmpegGlueTest, AddRemoveGetDataSource) { +TEST_F(FFmpegGlueTest, AddRemoveGetDataSource) { // Prepare testing data. - media::FFmpegGlue* glue = media::FFmpegGlue::get(); + FFmpegGlue* glue = FFmpegGlue::get(); // Create our data sources and add them to the glue layer. - bool deleted_a = false; - bool deleted_b = false; - media::old_mocks::MockFilterConfig config_a; - media::old_mocks::MockFilterConfig config_b; - scoped_refptr<media::old_mocks::MockDataSource> data_source_a - = new media::old_mocks::MockDataSource(&config_a, &deleted_a); - scoped_refptr<media::old_mocks::MockDataSource> data_source_b - = new media::old_mocks::MockDataSource(&config_b, &deleted_b); + scoped_refptr<StrictMock<Destroyable<MockDataSource> > > data_source_a + = new StrictMock<Destroyable<MockDataSource> >(); + scoped_refptr<StrictMock<Destroyable<MockDataSource> > > data_source_b + = new StrictMock<Destroyable<MockDataSource> >(); // Make sure the keys are unique. std::string key_a = glue->AddDataSource(data_source_a); @@ -70,8 +86,8 @@ TEST(FFmpegGlueTest, AddRemoveGetDataSource) { EXPECT_NE(key_a, key_b); // Our keys should return our data sources. - scoped_refptr<media::DataSource> data_source_c; - scoped_refptr<media::DataSource> data_source_d; + scoped_refptr<DataSource> data_source_c; + scoped_refptr<DataSource> data_source_d; glue->GetDataSource(key_a, &data_source_c); glue->GetDataSource(key_b, &data_source_d); EXPECT_EQ(data_source_a, data_source_c); @@ -84,8 +100,13 @@ TEST(FFmpegGlueTest, AddRemoveGetDataSource) { glue->GetDataSource(key_a2, &data_source_c); EXPECT_EQ(data_source_a, data_source_c); - // Removes the data sources and then releases our references. They should be - // deleted. + // Removes the data sources then releases our references. They should be + // destroyed. + InSequence s; + EXPECT_CALL(*data_source_a, OnDestroy()); + EXPECT_CALL(*data_source_b, OnDestroy()); + EXPECT_CALL(mock_ffmpeg_, CheckPoint(0)); + glue->RemoveDataSource(data_source_a); glue->GetDataSource(key_a, &data_source_c); EXPECT_FALSE(data_source_c); @@ -94,23 +115,21 @@ TEST(FFmpegGlueTest, AddRemoveGetDataSource) { glue->RemoveDataSource(data_source_b); glue->GetDataSource(key_b, &data_source_d); EXPECT_FALSE(data_source_d); - EXPECT_FALSE(deleted_a); - EXPECT_FALSE(deleted_b); data_source_a = NULL; data_source_b = NULL; - EXPECT_TRUE(deleted_a); - EXPECT_TRUE(deleted_b); + + // Data sources should be deleted by this point. + mock_ffmpeg_.CheckPoint(0); } -TEST(FFmpegGlueTest, OpenClose) { +TEST_F(FFmpegGlueTest, OpenClose) { // Prepare testing data. - media::FFmpegGlue* glue = media::FFmpegGlue::get(); + FFmpegGlue* glue = FFmpegGlue::get(); // Create our data source and add them to the glue layer. - bool deleted = false; - media::old_mocks::MockFilterConfig config; - scoped_refptr<media::old_mocks::MockDataSource> data_source - = new media::old_mocks::MockDataSource(&config, &deleted); + scoped_refptr<StrictMock<Destroyable<MockDataSource> > > data_source + = new StrictMock<Destroyable<MockDataSource> >(); + EXPECT_CALL(*data_source, IsSeekable()).WillOnce(Return(false)); std::string key = glue->AddDataSource(data_source); // Prepare FFmpeg URLContext structure. @@ -118,192 +137,174 @@ TEST(FFmpegGlueTest, OpenClose) { memset(&context, 0, sizeof(context)); // Test opening a URLContext with a data source that doesn't exist. - EXPECT_EQ(AVERROR_IO, g_protocol->url_open(&context, "foobar", 0)); + EXPECT_EQ(AVERROR_IO, protocol_->url_open(&context, "foobar", 0)); // Test opening a URLContext with our data source. - EXPECT_EQ(0, g_protocol->url_open(&context, key.c_str(), 0)); + EXPECT_EQ(0, protocol_->url_open(&context, key.c_str(), 0)); EXPECT_EQ(URL_RDONLY, context.flags); EXPECT_EQ(data_source, context.priv_data); - EXPECT_FALSE(context.is_streamed); + EXPECT_TRUE(context.is_streamed); + + // We're going to remove references one by one until the last reference is + // held by FFmpeg. Once we close the URLContext, the data source should be + // destroyed. + InSequence s; + EXPECT_CALL(mock_ffmpeg_, CheckPoint(0)); + EXPECT_CALL(mock_ffmpeg_, CheckPoint(1)); + EXPECT_CALL(*data_source, OnDestroy()); + EXPECT_CALL(mock_ffmpeg_, CheckPoint(2)); // Remove the data source from the glue layer, releasing a reference. glue->RemoveDataSource(data_source); - EXPECT_FALSE(deleted); + mock_ffmpeg_.CheckPoint(0); // Remove our own reference -- URLContext should maintain a reference. data_source = NULL; - EXPECT_FALSE(deleted); + mock_ffmpeg_.CheckPoint(1); // Close the URLContext, which should release the final reference. - EXPECT_EQ(0, g_protocol->url_close(&context)); - EXPECT_TRUE(deleted); + EXPECT_EQ(0, protocol_->url_close(&context)); + mock_ffmpeg_.CheckPoint(2); } -TEST(FFmpegGlueTest, ReadingWriting) { - // Prepare testing data. - media::FFmpegGlue* glue = media::FFmpegGlue::get(); - const size_t kBufferSize = 16; - unsigned char buffer[kBufferSize]; - - // Configure MockDataSource to be 8 characters long and fill reads with - // periods. Therefore our expected string should be a character of 8 periods. - const int kExpectedSize = 8; - media::old_mocks::MockFilterConfig config; - config.media_total_bytes = kExpectedSize; - config.data_source_value = '.'; - const char kExpected[] = "........"; - COMPILE_ASSERT(kExpectedSize == (arraysize(kExpected) - 1), string_length); - - // Create our data source and add them to the glue layer. - bool deleted = false; - scoped_refptr<media::old_mocks::MockDataSource> data_source - = new media::old_mocks::MockDataSource(&config, &deleted); - std::string key = glue->AddDataSource(data_source); - - // Open our data source and then remove it from the glue layer. +TEST_F(FFmpegGlueTest, Write) { + scoped_refptr<StrictMock<MockDataSource> > data_source + = new StrictMock<MockDataSource>(); URLContext context; - memset(&context, 0, sizeof(context)); - EXPECT_EQ(0, g_protocol->url_open(&context, key.c_str(), 0)); - glue->RemoveDataSource(data_source); - EXPECT_FALSE(deleted); - - // Writing should always fail. - EXPECT_EQ(AVERROR_IO, g_protocol->url_write(&context, NULL, 0)); - EXPECT_EQ(AVERROR_IO, g_protocol->url_write(&context, buffer, 0)); - EXPECT_EQ(AVERROR_IO, g_protocol->url_write(&context, buffer, -1)); - EXPECT_EQ(AVERROR_IO, g_protocol->url_write(&context, buffer, kBufferSize)); - EXPECT_EQ(0, data_source->position()); - - // Reading should return same amount of bytes if <= kExpectedSize. - EXPECT_EQ(0, g_protocol->url_read(&context, buffer, 0)); - EXPECT_EQ(kExpectedSize / 2, - g_protocol->url_read(&context, buffer, kExpectedSize / 2)); - EXPECT_EQ(kExpectedSize, - g_protocol->url_read(&context, buffer, kExpectedSize)); - buffer[kExpectedSize] = '\0'; - EXPECT_STREQ(kExpected, reinterpret_cast<char*>(buffer)); - - // Test reading more than kExpectedSize for simulating EOF. - EXPECT_EQ(kExpectedSize, g_protocol->url_read(&context, buffer, kBufferSize)); - buffer[kExpectedSize] = '\0'; - EXPECT_STREQ(kExpected, reinterpret_cast<char*>(buffer)); - - // Close our data source. - EXPECT_EQ(0, g_protocol->url_close(&context)); - EXPECT_FALSE(deleted); - - // Remove our own reference, which should release the final reference. - data_source = NULL; - EXPECT_TRUE(deleted); -} + OpenContext(data_source, &context); -TEST(FFmpegGlueTest, Seeking) { - // Prepare testing data. - media::FFmpegGlue* glue = media::FFmpegGlue::get(); - const int64 kSize = 32; + const int kBufferSize = 16; + uint8 buffer[kBufferSize]; - // Create our data source and add them to the glue layer. - bool deleted = false; - media::old_mocks::MockFilterConfig config; - config.media_total_bytes = kSize; - scoped_refptr<media::old_mocks::MockDataSource> data_source - = new media::old_mocks::MockDataSource(&config, &deleted); - std::string key = glue->AddDataSource(data_source); + // Writing should always fail and never call the data source. + EXPECT_EQ(AVERROR_IO, protocol_->url_write(&context, NULL, 0)); + EXPECT_EQ(AVERROR_IO, protocol_->url_write(&context, buffer, 0)); + EXPECT_EQ(AVERROR_IO, protocol_->url_write(&context, buffer, kBufferSize)); - // Open our data source and then remove it from the glue layer. - URLContext context; - memset(&context, 0, sizeof(context)); - EXPECT_EQ(0, g_protocol->url_open(&context, key.c_str(), 0)); - glue->RemoveDataSource(data_source); - EXPECT_FALSE(deleted); - - // Test SEEK_SET operations. - config.media_total_bytes = -1; - EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, 0, SEEK_SET)); - - config.media_total_bytes = kSize; - EXPECT_TRUE(data_source->SetPosition(0)); - EXPECT_EQ(0, g_protocol->url_seek(&context, 0, SEEK_SET)); - EXPECT_TRUE(data_source->SetPosition(5)); - EXPECT_EQ(0, g_protocol->url_seek(&context, 0, SEEK_SET)); - EXPECT_EQ(0, data_source->position()); - EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, -5, SEEK_SET)); - EXPECT_EQ(0, data_source->position()); - EXPECT_EQ(kSize, g_protocol->url_seek(&context, kSize, SEEK_SET)); - EXPECT_EQ(kSize, data_source->position()); - EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, kSize+1, SEEK_SET)); - EXPECT_EQ(kSize, data_source->position()); - - // Test SEEK_CUR operations. - config.media_total_bytes = -1; - EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, 0, SEEK_CUR)); - - config.media_total_bytes = kSize; - EXPECT_TRUE(data_source->SetPosition(0)); - EXPECT_EQ(0, g_protocol->url_seek(&context, 0, SEEK_CUR)); - EXPECT_TRUE(data_source->SetPosition(5)); - EXPECT_EQ(5, g_protocol->url_seek(&context, 0, SEEK_CUR)); - EXPECT_EQ(0, g_protocol->url_seek(&context, -5, SEEK_CUR)); - EXPECT_EQ(0, data_source->position()); - EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, -1, SEEK_CUR)); - EXPECT_EQ(kSize, g_protocol->url_seek(&context, kSize, SEEK_CUR)); - EXPECT_EQ(kSize, data_source->position()); - EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, 1, SEEK_CUR)); - EXPECT_EQ(kSize, data_source->position()); - - // Test SEEK_END operations. - config.media_total_bytes = -1; - EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, 0, SEEK_END)); - - config.media_total_bytes = kSize; - EXPECT_TRUE(data_source->SetPosition(0)); - EXPECT_EQ(kSize, g_protocol->url_seek(&context, 0, SEEK_END)); - EXPECT_EQ(kSize, data_source->position()); - EXPECT_EQ(kSize-5, g_protocol->url_seek(&context, -5, SEEK_END)); - EXPECT_EQ(kSize-5, data_source->position()); - EXPECT_EQ(0, g_protocol->url_seek(&context, -kSize, SEEK_END)); - EXPECT_EQ(0, data_source->position()); - EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, 1, SEEK_END)); - EXPECT_EQ(0, data_source->position()); - - // Test AVSEEK_SIZE operation. - config.media_total_bytes = -1; - EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, 0, AVSEEK_SIZE)); - - config.media_total_bytes = kSize; - EXPECT_TRUE(data_source->SetPosition(0)); - EXPECT_EQ(kSize, g_protocol->url_seek(&context, 0, AVSEEK_SIZE)); - - // Close our data source. - EXPECT_EQ(0, g_protocol->url_close(&context)); - EXPECT_FALSE(deleted); - - // Remove our own reference, which should release the final reference. - data_source = NULL; - EXPECT_TRUE(deleted); + // Destroy the data source. + protocol_->url_close(&context); } -TEST(FFmpegGlueTest, Destructor) { - // Prepare testing data. - media::FFmpegGlue* glue = media::FFmpegGlue::get(); +TEST_F(FFmpegGlueTest, Read) { + scoped_refptr<StrictMock<MockDataSource> > data_source + = new StrictMock<MockDataSource>(); + URLContext context; + OpenContext(data_source, &context); + + const int kBufferSize = 16; + uint8 buffer[kBufferSize]; + + // Reads are for the most part straight-through calls to Read(). + InSequence s; + EXPECT_CALL(*data_source, Read(buffer, 0)) + .WillOnce(Return(0)); + EXPECT_CALL(*data_source, Read(buffer, kBufferSize)) + .WillOnce(Return(kBufferSize)); + EXPECT_CALL(*data_source, Read(buffer, kBufferSize)) + .WillOnce(Return(DataSource::kReadError)); + + EXPECT_EQ(0, protocol_->url_read(&context, buffer, 0)); + EXPECT_EQ(kBufferSize, protocol_->url_read(&context, buffer, kBufferSize)); + EXPECT_EQ(AVERROR_IO, protocol_->url_read(&context, buffer, kBufferSize)); + + // Destroy the data source. + protocol_->url_close(&context); +} - // We use a static bool since ~FFmpegGlue() will set it to true sometime - // after this function exits. - static bool deleted = false; +TEST_F(FFmpegGlueTest, Seek) { + scoped_refptr<StrictMock<MockDataSource> > data_source + = new StrictMock<MockDataSource>(); + URLContext context; + OpenContext(data_source, &context); + + // SEEK_SET should be a straight-through call to SetPosition(), which when + // successful will return the result from GetPosition(). + InSequence s; + EXPECT_CALL(*data_source, SetPosition(-16)) + .WillOnce(Return(false)); + + EXPECT_CALL(*data_source, SetPosition(16)) + .WillOnce(Return(true)); + EXPECT_CALL(*data_source, GetPosition(_)) + .WillOnce(DoAll(SetArgumentPointee<0>(8), Return(true))); + + EXPECT_EQ(AVERROR_IO, protocol_->url_seek(&context, -16, SEEK_SET)); + EXPECT_EQ(8, protocol_->url_seek(&context, 16, SEEK_SET)); + + // SEEK_CUR should call GetPosition() first, and if it succeeds add the offset + // to the result then call SetPosition()+GetPosition(). + EXPECT_CALL(*data_source, GetPosition(_)) + .WillOnce(Return(false)); + + EXPECT_CALL(*data_source, GetPosition(_)) + .WillOnce(DoAll(SetArgumentPointee<0>(8), Return(true))); + EXPECT_CALL(*data_source, SetPosition(16)) + .WillOnce(Return(false)); + + EXPECT_CALL(*data_source, GetPosition(_)) + .WillOnce(DoAll(SetArgumentPointee<0>(8), Return(true))); + EXPECT_CALL(*data_source, SetPosition(16)) + .WillOnce(Return(true)); + EXPECT_CALL(*data_source, GetPosition(_)) + .WillOnce(DoAll(SetArgumentPointee<0>(16), Return(true))); + + EXPECT_EQ(AVERROR_IO, protocol_->url_seek(&context, 8, SEEK_CUR)); + EXPECT_EQ(AVERROR_IO, protocol_->url_seek(&context, 8, SEEK_CUR)); + EXPECT_EQ(16, protocol_->url_seek(&context, 8, SEEK_CUR)); + + // SEEK_END should call GetSize() first, and if it succeeds add the offset + // to the result then call SetPosition()+GetPosition(). + EXPECT_CALL(*data_source, GetSize(_)) + .WillOnce(Return(false)); + + EXPECT_CALL(*data_source, GetSize(_)) + .WillOnce(DoAll(SetArgumentPointee<0>(16), Return(true))); + EXPECT_CALL(*data_source, SetPosition(8)) + .WillOnce(Return(false)); + + EXPECT_CALL(*data_source, GetSize(_)) + .WillOnce(DoAll(SetArgumentPointee<0>(16), Return(true))); + EXPECT_CALL(*data_source, SetPosition(8)) + .WillOnce(Return(true)); + EXPECT_CALL(*data_source, GetPosition(_)) + .WillOnce(DoAll(SetArgumentPointee<0>(8), Return(true))); + + EXPECT_EQ(AVERROR_IO, protocol_->url_seek(&context, -8, SEEK_END)); + EXPECT_EQ(AVERROR_IO, protocol_->url_seek(&context, -8, SEEK_END)); + EXPECT_EQ(8, protocol_->url_seek(&context, -8, SEEK_END)); + + // AVSEEK_SIZE should be a straight-through call to GetSize(). + EXPECT_CALL(*data_source, GetSize(_)) + .WillOnce(Return(false)); + + EXPECT_CALL(*data_source, GetSize(_)) + .WillOnce(DoAll(SetArgumentPointee<0>(16), Return(true))); + + EXPECT_EQ(AVERROR_IO, protocol_->url_seek(&context, 0, AVSEEK_SIZE)); + EXPECT_EQ(16, protocol_->url_seek(&context, 0, AVSEEK_SIZE)); + + // Destroy the data source. + protocol_->url_close(&context); +} +TEST_F(FFmpegGlueTest, Destroy) { // Create our data source and add them to the glue layer. - media::old_mocks::MockFilterConfig config; - scoped_refptr<media::old_mocks::MockDataSource> data_source - = new media::old_mocks::MockDataSource(&config, &deleted); - std::string key = glue->AddDataSource(data_source); + scoped_refptr<StrictMock<Destroyable<MockDataSource> > > data_source + = new StrictMock<Destroyable<MockDataSource> >(); + std::string key = FFmpegGlue::get()->AddDataSource(data_source); - // Remove our own reference. + // We should expect the data source to get destroyed when the unit test + // exits. + InSequence s; + EXPECT_CALL(mock_ffmpeg_, CheckPoint(0)); + EXPECT_CALL(*data_source, OnDestroy()); + + // Remove our own reference, we shouldn't be destroyed yet. data_source = NULL; - EXPECT_FALSE(deleted); + mock_ffmpeg_.CheckPoint(0); // ~FFmpegGlue() will be called when this unit test finishes execution. By // leaving something inside FFmpegGlue's map we get to test our cleanup code. - // - // MockDataSource will be holding onto a bad MockFilterConfig pointer at this - // point but since no one is calling it everything will be ok. } + +} // namespace media diff --git a/media/filters/test_video_decoder.h b/media/filters/test_video_decoder.h deleted file mode 100644 index bb82c36..0000000 --- a/media/filters/test_video_decoder.h +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this -// source code is governed by a BSD-style license that can be found in the -// LICENSE file. -// - -#ifndef MEDIA_FILTERS_TEST_VIDEO_DECODER_H_ -#define MEDIA_FILTERS_TEST_VIDEO_DECODER_H_ - -#include <string> - -#include "media/base/buffers.h" -#include "media/base/factory.h" -#include "media/base/filters.h" -#include "media/base/mock_media_filters.h" -#include "media/base/video_frame_impl.h" -#include "media/filters/decoder_base.h" - -namespace media { - -class TestVideoDecoder : public DecoderBase<VideoDecoder, VideoFrame> { - public: - TestVideoDecoder() - : video_width_(0), - video_height_(0) { - } - - bool OnInitialize(DemuxerStream* demuxer_stream) { - const MediaFormat& media_format = demuxer_stream->media_format(); - std::string mime_type; - int width, height; - if (media_format.GetAsString(MediaFormat::kMimeType, &mime_type) && - mime_type.compare(mime_type::kH264AnnexB) == 0 && - media_format.GetAsInteger(MediaFormat::kWidth, &width) && - media_format.GetAsInteger(MediaFormat::kHeight, &height)) { - video_width_ = width; - video_height_ = height; - media_format_.SetAsString(MediaFormat::kMimeType, - mime_type::kUncompressedVideo); - media_format_.SetAsInteger(MediaFormat::kWidth, width); - media_format_.SetAsInteger(MediaFormat::kHeight, height); - return true; - } - return false; - } - - void OnDecode(Buffer* buffer) { - scoped_refptr<VideoFrame> frame; - VideoFrameImpl::CreateFrame(VideoSurface::YV12, - video_width_, - video_height_, - buffer->GetTimestamp(), - buffer->GetDuration(), - &frame); - if (frame) { - old_mocks::MockVideoDecoder::InitializeYV12Frame(frame, 0.5f); - EnqueueResult(frame); - } else { - host_->Error(PIPELINE_ERROR_OUT_OF_MEMORY); - } - } - - static bool IsMediaFormatSupported(const MediaFormat& media_format) { - std::string mime_type; - return (media_format.GetAsString(MediaFormat::kMimeType, &mime_type) && - mime_type == mime_type::kH264AnnexB); - } - - private: - friend class scoped_refptr<TestVideoDecoder>; - virtual ~TestVideoDecoder() {} - - size_t video_width_; - size_t video_height_; - - DISALLOW_COPY_AND_ASSIGN(TestVideoDecoder); -}; - -} // namespace - -#endif // MEDIA_FILTERS_TEST_VIDEO_DECODER_H_ diff --git a/media/filters/test_video_renderer.h b/media/filters/test_video_renderer.h deleted file mode 100644 index f9535f2..0000000 --- a/media/filters/test_video_renderer.h +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this -// source code is governed by a BSD-style license that can be found in the -// LICENSE file. -// -// Simple test class used by unit tests. Tests create the filter on the test's -// thread and then use InstanceFilterFactory to force the test's instance to -// be returned to the pipeline. - -#ifndef MEDIA_FILTERS_TEST_VIDEO_RENDERER_H_ -#define MEDIA_FILTERS_TEST_VIDEO_RENDERER_H_ - -#include "media/base/buffers.h" -#include "media/base/factory.h" -#include "media/base/filters.h" -#include "media/filters/video_renderer_base.h" - -namespace media { - -class TestVideoRenderer : public VideoRendererBase { - public: - TestVideoRenderer() - : last_frame_(NULL), - paint_called_(0), - unique_frames_(0) { - } - - virtual bool OnInitialize(size_t width, size_t height) { return true; } - - virtual void OnPaintNeeded() { - ++paint_called_; - scoped_refptr<VideoFrame> frame; - GetCurrentFrame(&frame); - if (frame.get()) { - VideoSurface video_surface; - EXPECT_TRUE(frame->Lock(&video_surface)); - frame->Unlock(); - if (frame != last_frame_) { - ++unique_frames_; - last_frame_ = frame; - last_timestamp_ = frame->GetTimestamp(); - } - } - } - - size_t unique_frames() { return unique_frames_; } - size_t paint_called() { return paint_called_; } - base::TimeDelta last_timestamp() { return last_timestamp_; } - - static bool IsMediaFormatSupported(const MediaFormat& format) { - return VideoRendererBase::IsMediaFormatSupported(format); - } - - private: - friend class scoped_refptr<TestVideoRenderer>; - virtual ~TestVideoRenderer() {} - - VideoFrame* last_frame_; - size_t paint_called_; - size_t unique_frames_; - base::TimeDelta last_timestamp_; - - DISALLOW_COPY_AND_ASSIGN(TestVideoRenderer); -}; - -} // namespace - -#endif // MEDIA_FILTERS_TEST_VIDEO_RENDERER_H_ diff --git a/media/media.gyp b/media/media.gyp index aaa009f..3b15e80 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -101,8 +101,6 @@ 'filters/file_data_source.h', 'filters/null_audio_renderer.cc', 'filters/null_audio_renderer.h', - 'filters/test_video_decoder.h', - 'filters/test_video_renderer.h', 'filters/video_renderer_base.cc', 'filters/video_renderer_base.h', ], @@ -158,7 +156,6 @@ 'base/mock_ffmpeg.h', 'base/mock_filter_host.h', 'base/mock_filters.h', - 'base/mock_media_filters.h', 'base/mock_reader.h', 'base/pipeline_impl_unittest.cc', 'base/run_all_unittests.cc', |