diff options
-rw-r--r-- | content/common/gpu/media/video_encode_accelerator_unittest.cc | 35 | ||||
-rw-r--r-- | media/BUILD.gn | 2 | ||||
-rw-r--r-- | media/cast/BUILD.gn | 2 | ||||
-rw-r--r-- | media/cast/cast_testing.gypi | 4 | ||||
-rw-r--r-- | media/cast/sender/external_video_encoder_unittest.cc | 17 | ||||
-rw-r--r-- | media/cast/sender/video_sender_unittest.cc | 15 | ||||
-rw-r--r-- | media/media.gyp | 2 | ||||
-rw-r--r-- | media/video/fake_video_encode_accelerator.cc (renamed from media/cast/test/fake_video_encode_accelerator.cc) | 107 | ||||
-rw-r--r-- | media/video/fake_video_encode_accelerator.h (renamed from media/cast/test/fake_video_encode_accelerator.h) | 54 |
9 files changed, 144 insertions, 94 deletions
diff --git a/content/common/gpu/media/video_encode_accelerator_unittest.cc b/content/common/gpu/media/video_encode_accelerator_unittest.cc index e56b03b..63f10c1 100644 --- a/content/common/gpu/media/video_encode_accelerator_unittest.cc +++ b/content/common/gpu/media/video_encode_accelerator_unittest.cc @@ -20,6 +20,7 @@ #include "media/base/bitstream_buffer.h" #include "media/base/test_data_util.h" #include "media/filters/h264_parser.h" +#include "media/video/fake_video_encode_accelerator.h" #include "media/video/video_encode_accelerator.h" #include "testing/gtest/include/gtest/gtest.h" @@ -101,6 +102,11 @@ const unsigned int kMinFramesForBitrateTests = 300; // Bitrate is only forced for tests that test bitrate. const char* g_default_in_filename = "bear_320x192_40frames.yuv"; const char* g_default_in_parameters = ":320:192:1:out.h264:200000"; + +// Enabled by including a --fake_encoder flag to the command line invoking the +// test. +bool g_fake_encoder = false; + // Environment to store test stream data for all test cases. class VideoEncodeAcceleratorTestEnvironment; VideoEncodeAcceleratorTestEnvironment* g_env; @@ -488,7 +494,9 @@ scoped_ptr<StreamValidator> StreamValidator::Create( const FrameFoundCallback& frame_cb) { scoped_ptr<StreamValidator> validator; - if (IsH264(profile)) { + if (g_fake_encoder) { + validator.reset(NULL); + } else if (IsH264(profile)) { validator.reset(new H264Validator(frame_cb)); } else if (IsVP8(profile)) { validator.reset(new VP8Validator(frame_cb)); @@ -529,6 +537,7 @@ class VEAClient : public VideoEncodeAccelerator::Client { private: bool has_encoder() { return encoder_.get(); } + scoped_ptr<media::VideoEncodeAccelerator> CreateFakeVEA(); scoped_ptr<media::VideoEncodeAccelerator> CreateV4L2VEA(); scoped_ptr<media::VideoEncodeAccelerator> CreateVaapiVEA(); @@ -716,7 +725,8 @@ VEAClient::VEAClient(TestStream* test_stream, test_stream_->requested_profile, base::Bind(&VEAClient::HandleEncodedFrame, base::Unretained(this))); - CHECK(validator_.get()); + + CHECK(g_fake_encoder || validator_.get()); if (save_to_file_) { CHECK(!test_stream_->out_filename.empty()); @@ -734,6 +744,17 @@ VEAClient::VEAClient(TestStream* test_stream, VEAClient::~VEAClient() { CHECK(!has_encoder()); } +scoped_ptr<media::VideoEncodeAccelerator> VEAClient::CreateFakeVEA() { + scoped_ptr<media::VideoEncodeAccelerator> encoder; + if (g_fake_encoder) { + encoder.reset( + new media::FakeVideoEncodeAccelerator( + scoped_refptr<base::SingleThreadTaskRunner>( + base::MessageLoopProxy::current()))); + } + return encoder.Pass(); +} + scoped_ptr<media::VideoEncodeAccelerator> VEAClient::CreateV4L2VEA() { scoped_ptr<media::VideoEncodeAccelerator> encoder; #if defined(OS_CHROMEOS) && (defined(ARCH_CPU_ARMEL) || \ @@ -758,6 +779,7 @@ void VEAClient::CreateEncoder() { CHECK(!has_encoder()); scoped_ptr<media::VideoEncodeAccelerator> encoders[] = { + CreateFakeVEA(), CreateV4L2VEA(), CreateVaapiVEA() }; @@ -911,7 +933,11 @@ void VEAClient::BitstreamBufferReady(int32 bitstream_buffer_id, const uint8* stream_ptr = static_cast<const uint8*>(shm->memory()); if (payload_size > 0) { - validator_->ProcessStreamBuffer(stream_ptr, payload_size); + if (validator_) { + validator_->ProcessStreamBuffer(stream_ptr, payload_size); + } else { + HandleEncodedFrame(key_frame); + } if (save_to_file_) { if (IsVP8(test_stream_->requested_profile)) @@ -1352,6 +1378,9 @@ int main(int argc, char** argv) { if (it->first == "num_frames_to_encode") { std::string input(it->second.begin(), it->second.end()); CHECK(base::StringToInt(input, &content::g_num_frames_to_encode)); + } + if (it->first == "fake_encoder") { + content::g_fake_encoder = true; continue; } if (it->first == "run_at_fps") { diff --git a/media/BUILD.gn b/media/BUILD.gn index 688c6a7..4a8c1d9 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -226,6 +226,8 @@ component("media") { "video/capture/win/video_capture_device_mf_win.h", "video/capture/win/video_capture_device_win.cc", "video/capture/win/video_capture_device_win.h", + "video/fake_video_encode_accelerator.cc", + "video/fake_video_encode_accelerator.h", "video/h264_poc.cc", "video/h264_poc.h", "video/picture.cc", diff --git a/media/cast/BUILD.gn b/media/cast/BUILD.gn index 632b334..c10a990 100644 --- a/media/cast/BUILD.gn +++ b/media/cast/BUILD.gn @@ -301,8 +301,6 @@ test("cast_unittests") { "test/end2end_unittest.cc", "test/fake_receiver_time_offset_estimator.cc", "test/fake_receiver_time_offset_estimator.h", - "test/fake_video_encode_accelerator.cc", - "test/fake_video_encode_accelerator.h", "test/utility/audio_utility_unittest.cc", "test/utility/barcode_unittest.cc", ] diff --git a/media/cast/cast_testing.gypi b/media/cast/cast_testing.gypi index 6a554e0..12199b5 100644 --- a/media/cast/cast_testing.gypi +++ b/media/cast/cast_testing.gypi @@ -123,8 +123,6 @@ 'test/fake_receiver_time_offset_estimator.h', 'test/fake_single_thread_task_runner.cc', 'test/fake_single_thread_task_runner.h', - 'test/fake_video_encode_accelerator.cc', - 'test/fake_video_encode_accelerator.h', 'test/utility/audio_utility_unittest.cc', 'test/utility/barcode_unittest.cc', ], # source @@ -149,8 +147,6 @@ 'test/cast_benchmarks.cc', 'test/fake_single_thread_task_runner.cc', 'test/fake_single_thread_task_runner.h', - 'test/fake_video_encode_accelerator.cc', - 'test/fake_video_encode_accelerator.h', 'test/utility/test_util.cc', 'test/utility/test_util.h', ], # source diff --git a/media/cast/sender/external_video_encoder_unittest.cc b/media/cast/sender/external_video_encoder_unittest.cc index e48066d..6cc1911 100644 --- a/media/cast/sender/external_video_encoder_unittest.cc +++ b/media/cast/sender/external_video_encoder_unittest.cc @@ -12,8 +12,8 @@ #include "media/cast/cast_environment.h" #include "media/cast/sender/external_video_encoder.h" #include "media/cast/test/fake_single_thread_task_runner.h" -#include "media/cast/test/fake_video_encode_accelerator.h" #include "media/cast/test/utility/video_utility.h" +#include "media/video/fake_video_encode_accelerator.h" #include "testing/gmock/include/gmock/gmock.h" namespace media { @@ -133,8 +133,7 @@ class ExternalVideoEncoderTest : public ::testing::Test { task_runner_, task_runner_); - fake_vea_ = new test::FakeVideoEncodeAccelerator(task_runner_, - &stored_bitrates_); + fake_vea_ = new media::FakeVideoEncodeAccelerator(task_runner_); scoped_ptr<VideoEncodeAccelerator> fake_vea(fake_vea_); VEAFactory vea_factory(task_runner_, fake_vea.Pass()); video_encoder_.reset(new ExternalVideoEncoder( @@ -156,8 +155,7 @@ class ExternalVideoEncoderTest : public ::testing::Test { } base::SimpleTestTickClock* testing_clock_; // Owned by CastEnvironment. - test::FakeVideoEncodeAccelerator* fake_vea_; // Owned by video_encoder_. - std::vector<uint32> stored_bitrates_; + media::FakeVideoEncodeAccelerator* fake_vea_; // Owned by video_encoder_. scoped_refptr<TestVideoEncoderCallback> test_video_encoder_callback_; VideoSenderConfig video_config_; scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; @@ -194,12 +192,12 @@ TEST_F(ExternalVideoEncoderTest, EncodePattern30fpsRunningOutOfAck) { video_frame_, testing_clock_->NowTicks(), frame_encoded_callback)); task_runner_->RunTasks(); } + ASSERT_EQ(1u, fake_vea_->stored_bitrates().size()); + EXPECT_EQ(2000u, fake_vea_->stored_bitrates()[0]); + // We need to run the task to cleanup the GPU instance. video_encoder_.reset(NULL); task_runner_->RunTasks(); - - ASSERT_EQ(1u, stored_bitrates_.size()); - EXPECT_EQ(2000u, stored_bitrates_[0]); } TEST_F(ExternalVideoEncoderTest, StreamHeader) { @@ -238,9 +236,8 @@ TEST(ExternalVideoEncoderEarlyDestroyTest, DestroyBeforeVEACreatedCallback) { task_runner, task_runner)); - std::vector<uint32> stored_bitrates; scoped_ptr<VideoEncodeAccelerator> fake_vea( - new test::FakeVideoEncodeAccelerator(task_runner, &stored_bitrates)); + new media::FakeVideoEncodeAccelerator(task_runner)); VEAFactory vea_factory(task_runner, fake_vea.Pass()); scoped_ptr<ExternalVideoEncoder> video_encoder(new ExternalVideoEncoder( diff --git a/media/cast/sender/video_sender_unittest.cc b/media/cast/sender/video_sender_unittest.cc index ab9ac4c..5c207d5 100644 --- a/media/cast/sender/video_sender_unittest.cc +++ b/media/cast/sender/video_sender_unittest.cc @@ -18,9 +18,9 @@ #include "media/cast/sender/video_frame_factory.h" #include "media/cast/sender/video_sender.h" #include "media/cast/test/fake_single_thread_task_runner.h" -#include "media/cast/test/fake_video_encode_accelerator.h" #include "media/cast/test/utility/default_config.h" #include "media/cast/test/utility/video_utility.h" +#include "media/video/fake_video_encode_accelerator.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -133,7 +133,8 @@ class PeerVideoSender : public VideoSender { class VideoSenderTest : public ::testing::Test { protected: - VideoSenderTest() { + VideoSenderTest() + : stored_bitrates_(NULL) { testing_clock_ = new base::SimpleTestTickClock(); testing_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks()); task_runner_ = new test::FakeSingleThreadTaskRunner(testing_clock_); @@ -191,9 +192,9 @@ class VideoSenderTest : public ::testing::Test { CastInitializationStatus status = STATUS_VIDEO_UNINITIALIZED; if (external) { - test::FakeVideoEncodeAccelerator* fake_vea = - new test::FakeVideoEncodeAccelerator( - task_runner_, &stored_bitrates_); + media::FakeVideoEncodeAccelerator* fake_vea = + new media::FakeVideoEncodeAccelerator(task_runner_); + stored_bitrates_ = &fake_vea->stored_bitrates(); fake_vea->SetWillInitializationSucceed(expect_init_success); scoped_ptr<VideoEncodeAccelerator> fake_vea_owner(fake_vea); video_sender_.reset( @@ -253,7 +254,7 @@ class VideoSenderTest : public ::testing::Test { scoped_ptr<CastTransportSenderImpl> transport_sender_; scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; scoped_ptr<PeerVideoSender> video_sender_; - std::vector<uint32> stored_bitrates_; + const std::vector<uint32>* stored_bitrates_; // Owned by |video_sender_|. scoped_refptr<CastEnvironment> cast_environment_; int last_pixel_value_; base::TimeTicks first_frame_timestamp_; @@ -288,7 +289,7 @@ TEST_F(VideoSenderTest, ExternalEncoder) { // Fixed bitrate is used for external encoder. Bitrate is only once // to the encoder. - EXPECT_EQ(1u, stored_bitrates_.size()); + EXPECT_EQ(1u, stored_bitrates_->size()); video_sender_.reset(NULL); task_runner_->RunTasks(); } diff --git a/media/media.gyp b/media/media.gyp index d785ecb..6fe8230 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -574,6 +574,8 @@ 'video/capture/win/video_capture_device_mf_win.h', 'video/capture/win/video_capture_device_win.cc', 'video/capture/win/video_capture_device_win.h', + 'video/fake_video_encode_accelerator.cc', + 'video/fake_video_encode_accelerator.h', 'video/h264_poc.cc', 'video/h264_poc.h', 'video/picture.cc', diff --git a/media/cast/test/fake_video_encode_accelerator.cc b/media/video/fake_video_encode_accelerator.cc index 23a6fb3..4ca7a23 100644 --- a/media/cast/test/fake_video_encode_accelerator.cc +++ b/media/video/fake_video_encode_accelerator.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "media/cast/test/fake_video_encode_accelerator.h" +#include "media/video/fake_video_encode_accelerator.h" #include "base/bind.h" #include "base/location.h" @@ -10,23 +10,17 @@ #include "base/single_thread_task_runner.h" namespace media { -namespace cast { -namespace test { static const unsigned int kMinimumInputCount = 1; static const size_t kMinimumOutputBufferSize = 123456; FakeVideoEncodeAccelerator::FakeVideoEncodeAccelerator( - const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, - std::vector<uint32>* stored_bitrates) + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) : task_runner_(task_runner), - stored_bitrates_(stored_bitrates), - client_(NULL), - first_(true), will_initialization_succeed_(true), - weak_this_factory_(this) { - DCHECK(stored_bitrates_); -} + client_(NULL), + next_frame_is_first_frame_(true), + weak_this_factory_(this) {} FakeVideoEncodeAccelerator::~FakeVideoEncodeAccelerator() { weak_this_factory_.InvalidateWeakPtrs(); @@ -34,22 +28,33 @@ FakeVideoEncodeAccelerator::~FakeVideoEncodeAccelerator() { std::vector<VideoEncodeAccelerator::SupportedProfile> FakeVideoEncodeAccelerator::GetSupportedProfiles() { - return std::vector<VideoEncodeAccelerator::SupportedProfile>(); + std::vector<VideoEncodeAccelerator::SupportedProfile> profiles; + SupportedProfile profile; + profile.max_resolution.SetSize(1920, 1088); + profile.max_framerate_numerator = 30; + profile.max_framerate_denominator = 1; + + profile.profile = media::H264PROFILE_MAIN; + profiles.push_back(profile); + profile.profile = media::VP8PROFILE_ANY; + profiles.push_back(profile); + return profiles; } bool FakeVideoEncodeAccelerator::Initialize( - media::VideoFrame::Format input_format, + VideoFrame::Format input_format, const gfx::Size& input_visible_size, VideoCodecProfile output_profile, uint32 initial_bitrate, Client* client) { - if (!will_initialization_succeed_) + if (!will_initialization_succeed_) { return false; - client_ = client; - if (output_profile != media::VP8PROFILE_ANY && - output_profile != media::H264PROFILE_MAIN) { + } + if (output_profile == VIDEO_CODEC_PROFILE_UNKNOWN || + output_profile > VIDEO_CODEC_PROFILE_MAX) { return false; } + client_ = client; task_runner_->PostTask( FROM_HERE, base::Bind(&FakeVideoEncodeAccelerator::DoRequireBitstreamBuffers, @@ -60,45 +65,41 @@ bool FakeVideoEncodeAccelerator::Initialize( return true; } -void FakeVideoEncodeAccelerator::Encode(const scoped_refptr<VideoFrame>& frame, - bool force_keyframe) { +void FakeVideoEncodeAccelerator::Encode( + const scoped_refptr<VideoFrame>& frame, + bool force_keyframe) { DCHECK(client_); - DCHECK(!available_buffer_ids_.empty()); - - // Fake that we have encoded the frame; resulting in using the full output - // buffer. - int32 id = available_buffer_ids_.front(); - available_buffer_ids_.pop_front(); - - bool is_key_fame = force_keyframe; - if (first_) { - is_key_fame = true; - first_ = false; - } - task_runner_->PostTask( - FROM_HERE, - base::Bind(&FakeVideoEncodeAccelerator::DoBitstreamBufferReady, - weak_this_factory_.GetWeakPtr(), - id, - kMinimumOutputBufferSize, - is_key_fame)); + queued_frames_.push(force_keyframe); + EncodeTask(); } void FakeVideoEncodeAccelerator::UseOutputBitstreamBuffer( const BitstreamBuffer& buffer) { - available_buffer_ids_.push_back(buffer.id()); + available_buffers_.push_back(buffer); + EncodeTask(); } void FakeVideoEncodeAccelerator::RequestEncodingParametersChange( uint32 bitrate, uint32 framerate) { - stored_bitrates_->push_back(bitrate); + stored_bitrates_.push_back(bitrate); } void FakeVideoEncodeAccelerator::Destroy() { delete this; } void FakeVideoEncodeAccelerator::SendDummyFrameForTesting(bool key_frame) { - DoBitstreamBufferReady(0, 23, key_frame); + task_runner_->PostTask( + FROM_HERE, + base::Bind(&FakeVideoEncodeAccelerator::DoBitstreamBufferReady, + weak_this_factory_.GetWeakPtr(), + 0, + 23, + key_frame)); +} + +void FakeVideoEncodeAccelerator::SetWillInitializationSucceed( + bool will_initialization_succeed) { + will_initialization_succeed_ = will_initialization_succeed; } void FakeVideoEncodeAccelerator::DoRequireBitstreamBuffers( @@ -109,13 +110,31 @@ void FakeVideoEncodeAccelerator::DoRequireBitstreamBuffers( input_count, input_coded_size, output_buffer_size); } +void FakeVideoEncodeAccelerator::EncodeTask() { + while (!queued_frames_.empty() && !available_buffers_.empty()) { + bool force_key_frame = queued_frames_.front(); + queued_frames_.pop(); + int32 bitstream_buffer_id = available_buffers_.front().id(); + available_buffers_.pop_front(); + bool key_frame = next_frame_is_first_frame_ || force_key_frame; + next_frame_is_first_frame_ = false; + task_runner_->PostTask( + FROM_HERE, + base::Bind(&FakeVideoEncodeAccelerator::DoBitstreamBufferReady, + weak_this_factory_.GetWeakPtr(), + bitstream_buffer_id, + kMinimumOutputBufferSize, + key_frame)); + } +} + void FakeVideoEncodeAccelerator::DoBitstreamBufferReady( int32 bitstream_buffer_id, size_t payload_size, bool key_frame) const { - client_->BitstreamBufferReady(bitstream_buffer_id, payload_size, key_frame); + client_->BitstreamBufferReady(bitstream_buffer_id, + payload_size, + key_frame); } -} // namespace test -} // namespace cast } // namespace media diff --git a/media/cast/test/fake_video_encode_accelerator.h b/media/video/fake_video_encode_accelerator.h index 65cc36c..6c7c348 100644 --- a/media/cast/test/fake_video_encode_accelerator.h +++ b/media/video/fake_video_encode_accelerator.h @@ -2,78 +2,84 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef MEDIA_CAST_TEST_FAKE_MOCK_VIDEO_ENCODE_ACCELERATOR_H_ -#define MEDIA_CAST_TEST_FAKE_MOCK_VIDEO_ENCODE_ACCELERATOR_H_ - -#include "media/video/video_encode_accelerator.h" +#ifndef MEDIA_VIDEO_FAKE_VIDEO_ENCODE_ACCELERATOR_H_ +#define MEDIA_VIDEO_FAKE_VIDEO_ENCODE_ACCELERATOR_H_ #include <list> +#include <queue> #include <vector> #include "base/memory/weak_ptr.h" #include "media/base/bitstream_buffer.h" +#include "media/base/media_export.h" +#include "media/video/video_encode_accelerator.h" namespace base { + class SingleThreadTaskRunner; + } // namespace base namespace media { -namespace cast { -namespace test { -class FakeVideoEncodeAccelerator : public VideoEncodeAccelerator { +class MEDIA_EXPORT FakeVideoEncodeAccelerator : public VideoEncodeAccelerator { public: explicit FakeVideoEncodeAccelerator( - const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, - std::vector<uint32>* stored_bitrates); + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner); ~FakeVideoEncodeAccelerator() override; std::vector<VideoEncodeAccelerator::SupportedProfile> GetSupportedProfiles() override; - bool Initialize(media::VideoFrame::Format input_format, + bool Initialize(VideoFrame::Format input_format, const gfx::Size& input_visible_size, VideoCodecProfile output_profile, uint32 initial_bitrate, Client* client) override; - void Encode(const scoped_refptr<VideoFrame>& frame, bool force_keyframe) override; - void UseOutputBitstreamBuffer(const BitstreamBuffer& buffer) override; - void RequestEncodingParametersChange(uint32 bitrate, uint32 framerate) override; - void Destroy() override; - void SendDummyFrameForTesting(bool key_frame); - void SetWillInitializationSucceed(bool will_initialization_succeed) { - will_initialization_succeed_ = will_initialization_succeed; + const std::vector<uint32>& stored_bitrates() const { + return stored_bitrates_; } + void SendDummyFrameForTesting(bool key_frame); + void SetWillInitializationSucceed(bool will_initialization_succeed); private: void DoRequireBitstreamBuffers(unsigned int input_count, const gfx::Size& input_coded_size, size_t output_buffer_size) const; + void EncodeTask(); void DoBitstreamBufferReady(int32 bitstream_buffer_id, size_t payload_size, bool key_frame) const; + // Our original (constructor) calling message loop used for all tasks. const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - std::vector<uint32>* const stored_bitrates_; - VideoEncodeAccelerator::Client* client_; - bool first_; + std::vector<uint32> stored_bitrates_; bool will_initialization_succeed_; - std::list<int32> available_buffer_ids_; + VideoEncodeAccelerator::Client* client_; + + // Keeps track of if the current frame is the first encoded frame. This + // is used to force a fake key frame for the first encoded frame. + bool next_frame_is_first_frame_; + + // A queue containing the necessary data for incoming frames. The boolean + // represent whether the queued frame should force a key frame. + std::queue<bool> queued_frames_; + + // A list of buffers available for putting fake encoded frames in. + std::list<BitstreamBuffer> available_buffers_; base::WeakPtrFactory<FakeVideoEncodeAccelerator> weak_this_factory_; DISALLOW_COPY_AND_ASSIGN(FakeVideoEncodeAccelerator); }; -} // namespace test -} // namespace cast } // namespace media -#endif // MEDIA_CAST_TEST_FAKE_MOCK_VIDEO_ENCODE_ACCELERATOR_H_ +#endif // MEDIA_VIDEO_FAKE_VIDEO_ENCODE_ACCELERATOR_H_ |