From 8e885990aed58a26ae1b27dd7547536393879a7c Mon Sep 17 00:00:00 2001 From: "buildbot@webrtc.org" Date: Mon, 4 Aug 2014 23:56:14 +0000 Subject: [PATCH] (Auto)update libjingle 72566057-> 72591796 git-svn-id: http://webrtc.googlecode.com/svn/trunk@6824 4adac7df-926f-26a2-2b94-8c16560cd09d --- talk/libjingle.gyp | 5 +- talk/libjingle_tests.gyp | 1 - talk/media/base/fakevideocapturer.h | 6 - talk/media/base/mutedvideocapturer.cc | 137 +- .../mutedvideocapturer.h} | 45 +- .../media/base/mutedvideocapturer_unittest.cc | 96 ++ talk/media/base/videoadapter_unittest.cc | 1285 ----------------- talk/media/base/videocapturer.cc | 23 +- talk/media/base/videocapturer.h | 8 - talk/media/base/videocapturer_unittest.cc | 45 +- talk/media/base/videoengine_unittest.h | 20 +- talk/media/base/videoframefactory.h | 52 - talk/media/webrtc/webrtcvideocapturer.cc | 3 - talk/media/webrtc/webrtcvideoframefactory.h | 45 - 14 files changed, 292 insertions(+), 1479 deletions(-) rename talk/media/{webrtc/webrtcvideoframefactory.cc => base/mutedvideocapturer.h} (61%) create mode 100755 talk/media/base/mutedvideocapturer_unittest.cc delete mode 100755 talk/media/base/videoadapter_unittest.cc delete mode 100755 talk/media/base/videoframefactory.h delete mode 100755 talk/media/webrtc/webrtcvideoframefactory.h diff --git a/talk/libjingle.gyp b/talk/libjingle.gyp index f14854cfb..8ad4c110d 100755 --- a/talk/libjingle.gyp +++ b/talk/libjingle.gyp @@ -489,6 +489,8 @@ 'media/base/mediacommon.h', 'media/base/mediaengine.cc', 'media/base/mediaengine.h', + 'media/base/mutedvideocapturer.cc', + 'media/base/mutedvideocapturer.h', 'media/base/rtpdataengine.cc', 'media/base/rtpdataengine.h', 'media/base/rtpdump.cc', @@ -506,7 +508,6 @@ 'media/base/videocommon.h', 'media/base/videoframe.cc', 'media/base/videoframe.h', - 'media/base/videoframefactory.h', 'media/base/videoprocessor.h', 'media/base/videorenderer.h', 'media/base/voiceprocessor.h', @@ -542,8 +543,6 @@ 'media/webrtc/webrtcvideoengine2.h', 'media/webrtc/webrtcvideoframe.cc', 'media/webrtc/webrtcvideoframe.h', - 'media/webrtc/webrtcvideoframefactory.cc', - 'media/webrtc/webrtcvideoframefactory.h', 'media/webrtc/webrtcvie.h', 'media/webrtc/webrtcvoe.h', 'media/webrtc/webrtcvoiceengine.cc', diff --git a/talk/libjingle_tests.gyp b/talk/libjingle_tests.gyp index 76f22eaca..9a00fed70 100755 --- a/talk/libjingle_tests.gyp +++ b/talk/libjingle_tests.gyp @@ -148,7 +148,6 @@ 'media/base/streamparams_unittest.cc', 'media/base/testutils.cc', 'media/base/testutils.h', - 'media/base/videoadapter_unittest.cc', 'media/base/videocapturer_unittest.cc', 'media/base/videocommon_unittest.cc', 'media/base/videoengine_unittest.h', diff --git a/talk/media/base/fakevideocapturer.h b/talk/media/base/fakevideocapturer.h index b61ac5dd7..089151fc2 100644 --- a/talk/media/base/fakevideocapturer.h +++ b/talk/media/base/fakevideocapturer.h @@ -36,9 +36,6 @@ #include "talk/media/base/videocapturer.h" #include "talk/media/base/videocommon.h" #include "talk/media/base/videoframe.h" -#ifdef HAVE_WEBRTC_VIDEO -#include "talk/media/webrtc/webrtcvideoframefactory.h" -#endif namespace cricket { @@ -50,9 +47,6 @@ class FakeVideoCapturer : public cricket::VideoCapturer { initial_unix_timestamp_(time(NULL) * rtc::kNumNanosecsPerSec), next_timestamp_(rtc::kNumNanosecsPerMillisec), is_screencast_(false) { -#ifdef HAVE_WEBRTC_VIDEO - set_frame_factory(new cricket::WebRtcVideoFrameFactory()); -#endif // Default supported formats. Use ResetSupportedFormats to over write. std::vector formats; formats.push_back(cricket::VideoFormat(1280, 720, diff --git a/talk/media/base/mutedvideocapturer.cc b/talk/media/base/mutedvideocapturer.cc index f122c30f4..6ff60a061 100644 --- a/talk/media/base/mutedvideocapturer.cc +++ b/talk/media/base/mutedvideocapturer.cc @@ -1,2 +1,135 @@ -// TODO(pthatcher): Delete this file. Pulse won't work without it for -// some reason. +/* + * libjingle + * Copyright 2012 Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "webrtc/base/logging.h" +#include "webrtc/base/thread.h" +#include "talk/media/base/mutedvideocapturer.h" +#include "talk/media/base/videoframe.h" + +#if defined(HAVE_WEBRTC_VIDEO) +#include "talk/media/webrtc/webrtcvideoframe.h" +#endif // HAVE_WEBRTC_VIDEO + + +namespace cricket { + +const char MutedVideoCapturer::kCapturerId[] = "muted_camera"; + +class MutedFramesGenerator : public rtc::MessageHandler { + public: + explicit MutedFramesGenerator(const VideoFormat& format); + virtual ~MutedFramesGenerator(); + + // Called every |interval| ms. From |format|.interval given in the + // constructor. + sigslot::signal1 SignalFrame; + + protected: + virtual void OnMessage(rtc::Message* message); + + private: + rtc::Thread capture_thread_; + rtc::scoped_ptr muted_frame_; + const VideoFormat format_; + const int interval_; + uint32 create_time_; +}; + +MutedFramesGenerator::MutedFramesGenerator(const VideoFormat& format) + : format_(format), + interval_(static_cast(format.interval / + rtc::kNumNanosecsPerMillisec)), + create_time_(rtc::Time()) { + capture_thread_.Start(); + capture_thread_.PostDelayed(interval_, this); +} + +MutedFramesGenerator::~MutedFramesGenerator() { capture_thread_.Clear(this); } + +void MutedFramesGenerator::OnMessage(rtc::Message* message) { + // Queue a new frame as soon as possible to minimize drift. + capture_thread_.PostDelayed(interval_, this); + if (!muted_frame_) { +#if defined(HAVE_WEBRTC_VIDEO) +#define VIDEO_FRAME_NAME WebRtcVideoFrame +#endif +#if defined(VIDEO_FRAME_NAME) + muted_frame_.reset(new VIDEO_FRAME_NAME()); +#else + return; +#endif + } + uint32 current_timestamp = rtc::Time(); + // Delta between create time and current time will be correct even if there is + // a wraparound since they are unsigned integers. + uint32 elapsed_time = current_timestamp - create_time_; + if (!muted_frame_->InitToBlack(format_.width, format_.height, 1, 1, + elapsed_time, current_timestamp)) { + LOG(LS_ERROR) << "Failed to create a black frame."; + } + SignalFrame(muted_frame_.get()); +} + +MutedVideoCapturer::MutedVideoCapturer() { SetId(kCapturerId); } + +MutedVideoCapturer::~MutedVideoCapturer() { Stop(); } + +bool MutedVideoCapturer::GetBestCaptureFormat(const VideoFormat& desired, + VideoFormat* best_format) { + *best_format = desired; + return true; +} + +CaptureState MutedVideoCapturer::Start(const VideoFormat& capture_format) { + if (frame_generator_.get()) { + return CS_RUNNING; + } + frame_generator_.reset(new MutedFramesGenerator(capture_format)); + frame_generator_->SignalFrame + .connect(this, &MutedVideoCapturer::OnMutedFrame); + SetCaptureFormat(&capture_format); + return CS_RUNNING; +} + +void MutedVideoCapturer::Stop() { + frame_generator_.reset(); + SetCaptureFormat(NULL); +} + +bool MutedVideoCapturer::IsRunning() { return frame_generator_.get() != NULL; } + +bool MutedVideoCapturer::GetPreferredFourccs(std::vector* fourccs) { + fourccs->clear(); + fourccs->push_back(cricket::FOURCC_I420); + return true; +} + +void MutedVideoCapturer::OnMutedFrame(VideoFrame* muted_frame) { + SignalVideoFrame(this, muted_frame); +} + +} // namespace cricket diff --git a/talk/media/webrtc/webrtcvideoframefactory.cc b/talk/media/base/mutedvideocapturer.h similarity index 61% rename from talk/media/webrtc/webrtcvideoframefactory.cc rename to talk/media/base/mutedvideocapturer.h index 07b66636d..11512bcb6 100755 --- a/talk/media/webrtc/webrtcvideoframefactory.cc +++ b/talk/media/base/mutedvideocapturer.h @@ -1,6 +1,6 @@ /* * libjingle - * Copyright 2014 Google Inc. + * Copyright 2012 Google Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -25,23 +25,36 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "talk/media/webrtc/webrtcvideoframe.h" -#include "talk/media/webrtc/webrtcvideoframefactory.h" -#include "webrtc/base/logging.h" +#ifndef TALK_MEDIA_BASE_MUTEDVIDEOCAPTURER_H_ +#define TALK_MEDIA_BASE_MUTEDVIDEOCAPTURER_H_ + +#include "webrtc/base/thread.h" +#include "talk/media/base/videocapturer.h" namespace cricket { -VideoFrame* WebRtcVideoFrameFactory::CreateAliasedFrame( - const CapturedFrame* aliased_frame, int width, int height) const { - // TODO(pthatcher): Move Alias logic into the VideoFrameFactory and - // out of the VideoFrame. - rtc::scoped_ptr frame(new WebRtcVideoFrame()); - if (!frame->Alias(aliased_frame, width, height)) { - LOG(LS_ERROR) << - "Failed to create WebRtcVideoFrame in CreateAliasedFrame."; - return NULL; - } - return frame.release(); -} +class MutedFramesGenerator; + +class MutedVideoCapturer : public VideoCapturer { + public: + static const char kCapturerId[]; + + MutedVideoCapturer(); + virtual ~MutedVideoCapturer(); + virtual bool GetBestCaptureFormat(const VideoFormat& desired, + VideoFormat* best_format); + virtual CaptureState Start(const VideoFormat& capture_format); + virtual void Stop(); + virtual bool IsRunning(); + virtual bool IsScreencast() const { return false; } + virtual bool GetPreferredFourccs(std::vector* fourccs); + + protected: + void OnMutedFrame(VideoFrame* muted_frame); + + rtc::scoped_ptr frame_generator_; +}; } // namespace cricket + +#endif // TALK_MEDIA_BASE_MUTEDVIDEOCAPTURER_H_ diff --git a/talk/media/base/mutedvideocapturer_unittest.cc b/talk/media/base/mutedvideocapturer_unittest.cc new file mode 100755 index 000000000..739874fd9 --- /dev/null +++ b/talk/media/base/mutedvideocapturer_unittest.cc @@ -0,0 +1,96 @@ +/* + * libjingle + * Copyright 2012 Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "talk/media/base/mutedvideocapturer.h" + +#include "webrtc/base/gunit.h" +#include "talk/media/base/videoframe.h" + +class MutedVideoCapturerTest : public sigslot::has_slots<>, + public testing::Test { + protected: + void SetUp() { + frames_received_ = 0; + capturer_.SignalVideoFrame + .connect(this, &MutedVideoCapturerTest::OnVideoFrame); + } + void OnVideoFrame(cricket::VideoCapturer* capturer, + const cricket::VideoFrame* muted_frame) { + EXPECT_EQ(capturer, &capturer_); + ++frames_received_; + received_width_ = muted_frame->GetWidth(); + received_height_ = muted_frame->GetHeight(); + } + int frames_received() { return frames_received_; } + bool ReceivedCorrectFormat() { + return (received_width_ == capturer_.GetCaptureFormat()->width) && + (received_height_ == capturer_.GetCaptureFormat()->height); + } + + cricket::MutedVideoCapturer capturer_; + int frames_received_; + cricket::VideoFormat capture_format_; + int received_width_; + int received_height_; +}; + +TEST_F(MutedVideoCapturerTest, GetBestCaptureFormat) { + cricket::VideoFormat format(640, 360, cricket::VideoFormat::FpsToInterval(30), + cricket::FOURCC_I420); + cricket::VideoFormat best_format; + EXPECT_TRUE(capturer_.GetBestCaptureFormat(format, &best_format)); + EXPECT_EQ(format.width, best_format.width); + EXPECT_EQ(format.height, best_format.height); + EXPECT_EQ(format.interval, best_format.interval); + EXPECT_EQ(format.fourcc, best_format.fourcc); +} + +TEST_F(MutedVideoCapturerTest, IsScreencast) { + EXPECT_FALSE(capturer_.IsScreencast()); +} + +TEST_F(MutedVideoCapturerTest, GetPreferredFourccs) { + std::vector fourccs; + EXPECT_TRUE(capturer_.GetPreferredFourccs(&fourccs)); + EXPECT_EQ(fourccs.size(), 1u); + EXPECT_TRUE(capturer_.GetPreferredFourccs(&fourccs)); + EXPECT_EQ(fourccs.size(), 1u); + EXPECT_EQ(fourccs[0], cricket::FOURCC_I420); +} + +TEST_F(MutedVideoCapturerTest, Capturing) { + cricket::VideoFormat format(640, 360, cricket::VideoFormat::FpsToInterval(30), + cricket::FOURCC_I420); + EXPECT_EQ(capturer_.Start(format), cricket::CS_RUNNING); + EXPECT_EQ(capturer_.Start(format), cricket::CS_RUNNING); + EXPECT_TRUE(capturer_.IsRunning()); + // 100 ms should be enough to receive 3 frames at FPS of 30. + EXPECT_EQ_WAIT(frames_received(), 1, 100); + EXPECT_TRUE(ReceivedCorrectFormat()); + capturer_.Stop(); + EXPECT_FALSE(capturer_.IsRunning()); +} diff --git a/talk/media/base/videoadapter_unittest.cc b/talk/media/base/videoadapter_unittest.cc deleted file mode 100755 index df4125d8c..000000000 --- a/talk/media/base/videoadapter_unittest.cc +++ /dev/null @@ -1,1285 +0,0 @@ -/* - * libjingle - * Copyright 2010 Google Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// If we don't have a WebRtcVideoFrame, just skip all of these tests. -#if defined(HAVE_WEBRTC_VIDEO) -#include // For INT_MAX -#include -#include - -#include "webrtc/base/gunit.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/sigslot.h" -#include "talk/media/base/mediachannel.h" -#include "talk/media/base/testutils.h" -#include "talk/media/base/videoadapter.h" -#include "talk/media/devices/filevideocapturer.h" -#include "talk/media/webrtc/webrtcvideoframe.h" - -namespace cricket { - -namespace { - static const uint32 kWaitTimeout = 3000U; // 3 seconds. - static const uint32 kShortWaitTimeout = 1000U; // 1 second. - void UpdateCpuLoad(CoordinatedVideoAdapter* adapter, - int current_cpus, int max_cpus, float process_load, float system_load) { - adapter->set_cpu_load_min_samples(1); - adapter->OnCpuLoadUpdated(current_cpus, max_cpus, - process_load, system_load); - } -} - -class VideoAdapterTest : public testing::Test { - public: - virtual void SetUp() { - capturer_.reset(new FileVideoCapturer); - EXPECT_TRUE(capturer_->Init(GetTestFilePath( - "captured-320x240-2s-48.frames"))); - capture_format_ = capturer_->GetSupportedFormats()->at(0); - capture_format_.interval = VideoFormat::FpsToInterval(50); - adapter_.reset(new VideoAdapter()); - adapter_->SetInputFormat(capture_format_); - - listener_.reset(new VideoCapturerListener(adapter_.get())); - capturer_->SignalFrameCaptured.connect( - listener_.get(), &VideoCapturerListener::OnFrameCaptured); - } - - void VerifyAdaptedResolution(int width, int height) { - EXPECT_TRUE(NULL != listener_->adapted_frame()); - EXPECT_EQ(static_cast(width), - listener_->adapted_frame()->GetWidth()); - EXPECT_EQ(static_cast(height), - listener_->adapted_frame()->GetHeight()); - } - - protected: - class VideoCapturerListener: public sigslot::has_slots<> { - public: - explicit VideoCapturerListener(VideoAdapter* adapter) - : video_adapter_(adapter), - adapted_frame_(NULL), - copied_output_frame_(), - captured_frames_(0), - dropped_frames_(0), - last_adapt_was_no_op_(false) { - } - - void OnFrameCaptured(VideoCapturer* capturer, - const CapturedFrame* captured_frame) { - WebRtcVideoFrame temp_i420; - EXPECT_TRUE(temp_i420.Init(captured_frame, - captured_frame->width, abs(captured_frame->height))); - VideoFrame* out_frame = NULL; - EXPECT_TRUE(video_adapter_->AdaptFrame(&temp_i420, &out_frame)); - if (out_frame) { - if (out_frame == &temp_i420) { - last_adapt_was_no_op_ = true; - copied_output_frame_.reset(temp_i420.Copy()); - adapted_frame_ = copied_output_frame_.get(); - } else { - last_adapt_was_no_op_ = false; - adapted_frame_ = out_frame; - copied_output_frame_.reset(); - } - } else { - ++dropped_frames_; - } - ++captured_frames_; - } - - const VideoFrame* adapted_frame() const { return adapted_frame_; } - int captured_frames() const { return captured_frames_; } - int dropped_frames() const { return dropped_frames_; } - bool last_adapt_was_no_op() const { return last_adapt_was_no_op_; } - - private: - VideoAdapter* video_adapter_; - const VideoFrame* adapted_frame_; - rtc::scoped_ptr copied_output_frame_; - int captured_frames_; - int dropped_frames_; - bool last_adapt_was_no_op_; - }; - - class CpuAdapterListener: public sigslot::has_slots<> { - public: - CpuAdapterListener() : received_cpu_signal_(false) {} - void OnCpuAdaptationSignalled() { received_cpu_signal_ = true; } - bool received_cpu_signal() { return received_cpu_signal_; } - private: - bool received_cpu_signal_; - }; - - rtc::scoped_ptr capturer_; - rtc::scoped_ptr adapter_; - rtc::scoped_ptr listener_; - VideoFormat capture_format_; -}; - - -// Test adapter remembers exact pixel count -TEST_F(VideoAdapterTest, AdaptNumPixels) { - adapter_->SetOutputNumPixels(123456); - EXPECT_EQ(123456, adapter_->GetOutputNumPixels()); -} - -// Test adapter is constructed but not activated. Expect no frame drop and no -// resolution change. -TEST_F(VideoAdapterTest, AdaptInactive) { - // Output resolution is not set. - EXPECT_EQ(INT_MAX, adapter_->GetOutputNumPixels()); - - // Call Adapter with some frames. - EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); - EXPECT_TRUE_WAIT(!capturer_->IsRunning() || - listener_->captured_frames() >= 10, kWaitTimeout); - - // Verify no frame drop and no resolution change. - EXPECT_GE(listener_->captured_frames(), 10); - EXPECT_EQ(0, listener_->dropped_frames()); - VerifyAdaptedResolution(capture_format_.width, capture_format_.height); -} - -// Do not adapt the frame rate or the resolution. Expect no frame drop and no -// resolution change. -TEST_F(VideoAdapterTest, AdaptNothing) { - adapter_->SetOutputFormat(capture_format_); - EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); - EXPECT_TRUE_WAIT(!capturer_->IsRunning() || - listener_->captured_frames() >= 10, kWaitTimeout); - - // Verify no frame drop and no resolution change. - EXPECT_GE(listener_->captured_frames(), 10); - EXPECT_EQ(0, listener_->dropped_frames()); - VerifyAdaptedResolution(capture_format_.width, capture_format_.height); - EXPECT_TRUE(listener_->last_adapt_was_no_op()); -} - -TEST_F(VideoAdapterTest, AdaptZeroInterval) { - VideoFormat format = capturer_->GetSupportedFormats()->at(0); - format.interval = 0; - adapter_->SetInputFormat(format); - adapter_->SetOutputFormat(format); - EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); - EXPECT_TRUE_WAIT(!capturer_->IsRunning() || - listener_->captured_frames() >= 10, kWaitTimeout); - - // Verify no crash and that frames aren't dropped. - EXPECT_GE(listener_->captured_frames(), 10); - EXPECT_EQ(0, listener_->dropped_frames()); - VerifyAdaptedResolution(capture_format_.width, capture_format_.height); -} - -// Adapt the frame rate to be half of the capture rate at the beginning. Expect -// the number of dropped frames to be half of the number the captured frames. -TEST_F(VideoAdapterTest, AdaptFramerate) { - VideoFormat request_format = capture_format_; - request_format.interval *= 2; - adapter_->SetOutputFormat(request_format); - EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); - EXPECT_TRUE_WAIT(!capturer_->IsRunning() || - listener_->captured_frames() >= 10, kWaitTimeout); - - // Verify frame drop and no resolution change. - EXPECT_GE(listener_->captured_frames(), 10); - EXPECT_EQ(listener_->captured_frames() / 2, listener_->dropped_frames()); - VerifyAdaptedResolution(capture_format_.width, capture_format_.height); -} - -// Adapt the frame rate to be half of the capture rate at the beginning. Expect -// the number of dropped frames to be half of the number the captured frames. -TEST_F(VideoAdapterTest, AdaptFramerateVariable) { - VideoFormat request_format = capture_format_; - request_format.interval = request_format.interval * 3 / 2; - adapter_->SetOutputFormat(request_format); - EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); - EXPECT_TRUE_WAIT(!capturer_->IsRunning() || - listener_->captured_frames() >= 30, kWaitTimeout); - - // Verify frame drop and no resolution change. - EXPECT_GE(listener_->captured_frames(), 30); - // Verify 2 / 3 kept (20) and 1 / 3 dropped (10). - EXPECT_EQ(listener_->captured_frames() * 1 / 3, listener_->dropped_frames()); - VerifyAdaptedResolution(capture_format_.width, capture_format_.height); -} - -// Adapt the frame rate to be half of the capture rate after capturing no less -// than 10 frames. Expect no frame dropped before adaptation and frame dropped -// after adaptation. -TEST_F(VideoAdapterTest, AdaptFramerateOntheFly) { - VideoFormat request_format = capture_format_; - adapter_->SetOutputFormat(request_format); - EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); - EXPECT_TRUE_WAIT(!capturer_->IsRunning() || - listener_->captured_frames() >= 10, kWaitTimeout); - - // Verify no frame drop before adaptation. - EXPECT_EQ(0, listener_->dropped_frames()); - - // Adapat the frame rate. - request_format.interval *= 2; - adapter_->SetOutputFormat(request_format); - - EXPECT_TRUE_WAIT(!capturer_->IsRunning() || - listener_->captured_frames() >= 20, kWaitTimeout); - - // Verify frame drop after adaptation. - EXPECT_GT(listener_->dropped_frames(), 0); -} - -// Adapt the frame resolution to be a quarter of the capture resolution at the -// beginning. Expect resolution change. -TEST_F(VideoAdapterTest, AdaptResolution) { - VideoFormat request_format = capture_format_; - request_format.width /= 2; - request_format.height /= 2; - adapter_->SetOutputFormat(request_format); - EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); - EXPECT_TRUE_WAIT(!capturer_->IsRunning() || - listener_->captured_frames() >= 10, kWaitTimeout); - - // Verify no frame drop and resolution change. - EXPECT_EQ(0, listener_->dropped_frames()); - VerifyAdaptedResolution(request_format.width, request_format.height); -} - -// Adapt the frame resolution to half width. Expect resolution change. -TEST_F(VideoAdapterTest, AdaptResolutionNarrow) { - VideoFormat request_format = capture_format_; - request_format.width /= 2; - adapter_->set_scale_third(true); - adapter_->SetOutputFormat(request_format); - EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); - EXPECT_TRUE_WAIT(!capturer_->IsRunning() || - listener_->captured_frames() >= 10, kWaitTimeout); - - // Verify resolution change. - VerifyAdaptedResolution(213, 160); -} - -// Adapt the frame resolution to half height. Expect resolution change. -TEST_F(VideoAdapterTest, AdaptResolutionWide) { - VideoFormat request_format = capture_format_; - request_format.height /= 2; - adapter_->set_scale_third(true); - adapter_->SetOutputFormat(request_format); - EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); - EXPECT_TRUE_WAIT(!capturer_->IsRunning() || - listener_->captured_frames() >= 10, kWaitTimeout); - - // Verify resolution change. - VerifyAdaptedResolution(213, 160); -} - -// Adapt the frame resolution to be a quarter of the capture resolution after -// capturing no less than 10 frames. Expect no resolution change before -// adaptation and resolution change after adaptation. -TEST_F(VideoAdapterTest, AdaptResolutionOnTheFly) { - VideoFormat request_format = capture_format_; - adapter_->SetOutputFormat(request_format); - EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); - EXPECT_TRUE_WAIT(!capturer_->IsRunning() || - listener_->captured_frames() >= 10, kWaitTimeout); - - // Verify no resolution change before adaptation. - VerifyAdaptedResolution(request_format.width, request_format.height); - - // Adapt the frame resolution. - request_format.width /= 2; - request_format.height /= 2; - adapter_->SetOutputFormat(request_format); - EXPECT_TRUE_WAIT(!capturer_->IsRunning() || - listener_->captured_frames() >= 20, kWaitTimeout); - - - // Verify resolution change after adaptation. - VerifyAdaptedResolution(request_format.width, request_format.height); -} - -// Black the output frame. -TEST_F(VideoAdapterTest, BlackOutput) { - adapter_->SetOutputFormat(capture_format_); - EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); - EXPECT_TRUE_WAIT(!capturer_->IsRunning() || - listener_->captured_frames() >= 10, kWaitTimeout); - // Verify that the output frame is not black. - EXPECT_NE(16, *listener_->adapted_frame()->GetYPlane()); - EXPECT_NE(128, *listener_->adapted_frame()->GetUPlane()); - EXPECT_NE(128, *listener_->adapted_frame()->GetVPlane()); - - adapter_->SetBlackOutput(true); - EXPECT_TRUE_WAIT(!capturer_->IsRunning() || - listener_->captured_frames() >= 20, kWaitTimeout); - // Verify that the output frame is black. - EXPECT_EQ(16, *listener_->adapted_frame()->GetYPlane()); - EXPECT_EQ(128, *listener_->adapted_frame()->GetUPlane()); - EXPECT_EQ(128, *listener_->adapted_frame()->GetVPlane()); - - // Verify that the elapsed time and timestamp of the black frame increase. - int64 elapsed_time = listener_->adapted_frame()->GetElapsedTime(); - int64 timestamp = listener_->adapted_frame()->GetTimeStamp(); - EXPECT_TRUE_WAIT(!capturer_->IsRunning() || - listener_->captured_frames() >= 22, kWaitTimeout); - EXPECT_GT(listener_->adapted_frame()->GetElapsedTime(), elapsed_time); - EXPECT_GT(listener_->adapted_frame()->GetTimeStamp(), timestamp); - - // Change the output size - VideoFormat request_format = capture_format_; - request_format.width /= 2; - request_format.height /= 2; - adapter_->SetOutputFormat(request_format); - - EXPECT_TRUE_WAIT(!capturer_->IsRunning() || - listener_->captured_frames() >= 40, kWaitTimeout); - // Verify resolution change after adaptation. - VerifyAdaptedResolution(request_format.width, request_format.height); - // Verify that the output frame is black. - EXPECT_EQ(16, *listener_->adapted_frame()->GetYPlane()); - EXPECT_EQ(128, *listener_->adapted_frame()->GetUPlane()); - EXPECT_EQ(128, *listener_->adapted_frame()->GetVPlane()); -} - -// Drop all frames. -TEST_F(VideoAdapterTest, DropAllFrames) { - VideoFormat format; // with resolution 0x0. - adapter_->SetOutputFormat(format); - EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); - EXPECT_TRUE_WAIT(!capturer_->IsRunning() || - listener_->captured_frames() >= 10, kWaitTimeout); - - // Verify all frames are dropped. - EXPECT_GE(listener_->captured_frames(), 10); - EXPECT_EQ(listener_->captured_frames(), listener_->dropped_frames()); -} - -TEST(CoordinatedVideoAdapterTest, TestCoordinatedWithoutCpuAdaptation) { - CoordinatedVideoAdapter adapter; - adapter.set_cpu_adaptation(false); - - VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), FOURCC_I420); - adapter.SetInputFormat(format); - adapter.set_scale_third(true); - EXPECT_EQ(format, adapter.input_format()); - EXPECT_TRUE(adapter.output_format().IsSize0x0()); - - // Server format request 640x400. - format.height = 400; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(640, adapter.output_format().width); - EXPECT_EQ(400, adapter.output_format().height); - - // Server format request 1280x720, higher than input. Adapt nothing. - format.width = 1280; - format.height = 720; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(640, adapter.output_format().width); - EXPECT_EQ(400, adapter.output_format().height); - - // Cpu load is high, but cpu adaptation is disabled. Adapt nothing. - adapter.OnCpuLoadUpdated(1, 1, 0.99f, 0.99f); - EXPECT_EQ(640, adapter.output_format().width); - EXPECT_EQ(400, adapter.output_format().height); - - // Encoder resolution request: downgrade with different size. Adapt nothing. - adapter.OnEncoderResolutionRequest(320, 200, - CoordinatedVideoAdapter::DOWNGRADE); - EXPECT_EQ(640, adapter.output_format().width); - EXPECT_EQ(400, adapter.output_format().height); - - // Encoder resolution request: downgrade. - adapter.OnEncoderResolutionRequest(640, 400, - CoordinatedVideoAdapter::DOWNGRADE); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); - - // Encoder resolution request: downgrade. But GD off. Adapt nothing. - adapter.set_gd_adaptation(false); - adapter.OnEncoderResolutionRequest(480, 300, - CoordinatedVideoAdapter::DOWNGRADE); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); - adapter.set_gd_adaptation(true); - - // Encoder resolution request: downgrade. - adapter.OnEncoderResolutionRequest(480, 300, - CoordinatedVideoAdapter::DOWNGRADE); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Encoder resolution request: keep. Adapt nothing. - adapter.OnEncoderResolutionRequest(320, 200, - CoordinatedVideoAdapter::KEEP); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Encoder resolution request: upgrade. - adapter.OnEncoderResolutionRequest(320, 200, - CoordinatedVideoAdapter::UPGRADE); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); - - // Server format request 0x0. - format.width = 0; - format.height = 0; - adapter.OnOutputFormatRequest(format); - EXPECT_TRUE(adapter.output_format().IsSize0x0()); - - // Server format request 320x200. - format.width = 320; - format.height = 200; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Server format request 160x100. But view disabled. Adapt nothing. - adapter.set_view_adaptation(false); - format.width = 160; - format.height = 100; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - adapter.set_view_adaptation(true); - - // Enable View Switch. Expect adapt down. - adapter.set_view_switch(true); - format.width = 160; - format.height = 100; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(160, adapter.output_format().width); - EXPECT_EQ(100, adapter.output_format().height); - - // Encoder resolution request: upgrade. Adapt nothing. - adapter.OnEncoderResolutionRequest(160, 100, - CoordinatedVideoAdapter::UPGRADE); - EXPECT_EQ(160, adapter.output_format().width); - EXPECT_EQ(100, adapter.output_format().height); - - // Request View of 2 / 3. Expect adapt down. - adapter.set_view_switch(true); - format.width = (640 * 2 + 1) / 3; - format.height = (400 * 2 + 1) / 3; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ((640 * 2 + 1) / 3, adapter.output_format().width); - EXPECT_EQ((400 * 2 + 1) / 3, adapter.output_format().height); - - - // Request View of 3 / 8. Expect adapt down. - adapter.set_view_switch(true); - format.width = 640 * 3 / 8; - format.height = 400 * 3 / 8; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(640 * 3 / 8, adapter.output_format().width); - EXPECT_EQ(400 * 3 / 8, adapter.output_format().height); - - // View Switch back up. Expect adapt. - format.width = 320; - format.height = 200; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - adapter.set_view_switch(false); - - // Encoder resolution request: upgrade. Constrained by server request. - adapter.OnEncoderResolutionRequest(320, 200, - CoordinatedVideoAdapter::UPGRADE); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Server format request 480x300. - format.width = 480; - format.height = 300; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); -} - -TEST(CoordinatedVideoAdapterTest, TestCoordinatedWithCpuAdaptation) { - CoordinatedVideoAdapter adapter; - adapter.set_cpu_adaptation(true); - EXPECT_FALSE(adapter.cpu_smoothing()); - VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), FOURCC_I420); - adapter.SetInputFormat(format); - - // Server format request 640x400. - format.height = 400; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(640, adapter.output_format().width); - EXPECT_EQ(400, adapter.output_format().height); - - // Process load is medium, but system load is high. Downgrade. - UpdateCpuLoad(&adapter, 1, 1, 0.55f, 0.98f); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); - - // CPU high, but cpu adaptation disabled. Adapt nothing. - adapter.set_cpu_adaptation(false); - adapter.OnCpuLoadUpdated(1, 1, 0.55f, 0.98f); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); - adapter.set_cpu_adaptation(true); - - // System load is high, but time has not elaspsed. Adapt nothing. - adapter.set_cpu_load_min_samples(2); - adapter.OnCpuLoadUpdated(1, 1, 0.55f, 0.98f); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); - - // Process load is medium, but system load is high. Downgrade. - UpdateCpuLoad(&adapter, 1, 1, 0.55f, 0.98f); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Test reason for adapting is CPU. - EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU, - adapter.adapt_reason()); - - // Server format request 320x200. Same as CPU. Do nothing. - format.width = 320; - format.height = 200; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Test reason for adapting is CPU and VIEW. - EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU + - CoordinatedVideoAdapter::ADAPTREASON_VIEW, - adapter.adapt_reason()); - - // Process load and system load are normal. Adapt nothing. - UpdateCpuLoad(&adapter, 1, 1, 0.5f, 0.8f); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Process load and system load are low, but view is still low. Adapt nothing. - UpdateCpuLoad(&adapter, 1, 1, 0.2f, 0.3f); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Test reason for adapting is VIEW. - EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_VIEW, - adapter.adapt_reason()); - - // Server format request 640x400. Cpu is still low. Upgrade. - format.width = 640; - format.height = 400; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); - - // Test reason for adapting is CPU. - EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU, - adapter.adapt_reason()); - - // Encoder resolution request: downgrade. - adapter.OnEncoderResolutionRequest(480, 300, - CoordinatedVideoAdapter::DOWNGRADE); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Test reason for adapting is BANDWIDTH. - EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_BANDWIDTH, - adapter.adapt_reason()); - - // Process load and system load are low. Constrained by GD. Adapt nothing - adapter.OnCpuLoadUpdated(1, 1, 0.2f, 0.3f); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Encoder resolution request: upgrade. - adapter.OnEncoderResolutionRequest(320, 200, - CoordinatedVideoAdapter::UPGRADE); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); - - // Encoder resolution request: upgrade. Constrained by CPU. - adapter.OnEncoderResolutionRequest(480, 300, - CoordinatedVideoAdapter::UPGRADE); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); - - // Server format request 640x400. Constrained by CPU. - format.width = 640; - format.height = 400; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); -} - -TEST(CoordinatedVideoAdapterTest, TestCoordinatedWithCpuRequest) { - CoordinatedVideoAdapter adapter; - adapter.set_cpu_adaptation(true); - EXPECT_FALSE(adapter.cpu_smoothing()); - VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), FOURCC_I420); - adapter.SetInputFormat(format); - - // Server format request 640x400. - format.height = 400; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(640, adapter.output_format().width); - EXPECT_EQ(400, adapter.output_format().height); - - // CPU resolution request: downgrade. Adapt down. - adapter.OnCpuResolutionRequest(CoordinatedVideoAdapter::DOWNGRADE); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); - - // CPU resolution request: keep. Do nothing. - adapter.OnCpuResolutionRequest(CoordinatedVideoAdapter::KEEP); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); - - // CPU resolution request: downgrade, but cpu adaptation disabled. - // Adapt nothing. - adapter.set_cpu_adaptation(false); - adapter.OnCpuResolutionRequest(CoordinatedVideoAdapter::DOWNGRADE); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); - - // CPU resolution request: downgrade. Adapt down. - adapter.set_cpu_adaptation(true); - adapter.OnCpuResolutionRequest(CoordinatedVideoAdapter::DOWNGRADE); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Test reason for adapting is CPU. - EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU, - adapter.adapt_reason()); - - // CPU resolution request: downgrade, but already at minimum. Do nothing. - adapter.OnCpuResolutionRequest(CoordinatedVideoAdapter::DOWNGRADE); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Server format request 320x200. Same as CPU. Do nothing. - format.width = 320; - format.height = 200; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Test reason for adapting is CPU and VIEW. - EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU + - CoordinatedVideoAdapter::ADAPTREASON_VIEW, - adapter.adapt_reason()); - - // CPU resolution request: upgrade, but view request still low. Do nothing. - adapter.OnCpuResolutionRequest(CoordinatedVideoAdapter::UPGRADE); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Test reason for adapting is VIEW. - EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_VIEW, - adapter.adapt_reason()); - - // Server format request 640x400. Cpu is still low. Upgrade. - format.width = 640; - format.height = 400; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); - - // Test reason for adapting is CPU. - EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU, - adapter.adapt_reason()); - - // Encoder resolution request: downgrade. - adapter.OnEncoderResolutionRequest(480, 300, - CoordinatedVideoAdapter::DOWNGRADE); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Test reason for adapting is BANDWIDTH. - EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_BANDWIDTH, - adapter.adapt_reason()); - - // Process load and system load are low. Constrained by GD. Adapt nothing - adapter.OnCpuLoadUpdated(1, 1, 0.2f, 0.3f); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Encoder resolution request: upgrade. - adapter.OnEncoderResolutionRequest(320, 200, - CoordinatedVideoAdapter::UPGRADE); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); - - // Encoder resolution request: upgrade. Constrained by CPU. - adapter.OnEncoderResolutionRequest(480, 300, - CoordinatedVideoAdapter::UPGRADE); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); - - // Server format request 640x400. Constrained by CPU. - format.width = 640; - format.height = 400; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); -} - -TEST(CoordinatedVideoAdapterTest, TestViewRequestPlusCameraSwitch) { - CoordinatedVideoAdapter adapter; - adapter.set_view_switch(true); - - // Start at HD. - VideoFormat format(1280, 720, VideoFormat::FpsToInterval(30), FOURCC_I420); - adapter.SetInputFormat(format); - EXPECT_EQ(format, adapter.input_format()); - EXPECT_TRUE(adapter.output_format().IsSize0x0()); - - // View request for VGA. - format.width = 640; - format.height = 360; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(640, adapter.output_format().width); - EXPECT_EQ(360, adapter.output_format().height); - EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_VIEW, adapter.adapt_reason()); - - // Now, the camera reopens at VGA. - // Both the frame and the output format should be 640x360. - WebRtcVideoFrame in_frame; - in_frame.InitToBlack(640, 360, 1, 1, 33, 33); - VideoFrame* out_frame; - adapter.AdaptFrame(&in_frame, &out_frame); - EXPECT_EQ(640u, out_frame->GetWidth()); - EXPECT_EQ(360u, out_frame->GetHeight()); - // At this point, the view is no longer adapted, since the input has resized - // small enough to fit the last view request. - EXPECT_EQ(0, adapter.adapt_reason()); - - // And another view request comes in for 640x360, which should have no - // real impact. - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(640, adapter.output_format().width); - EXPECT_EQ(360, adapter.output_format().height); - EXPECT_EQ(0, adapter.adapt_reason()); -} - -TEST(CoordinatedVideoAdapterTest, TestVGAWidth) { - CoordinatedVideoAdapter adapter; - adapter.set_view_switch(true); - - // Start at 640x480, for cameras that don't support 640x360. - VideoFormat format(640, 480, VideoFormat::FpsToInterval(30), FOURCC_I420); - adapter.SetInputFormat(format); - EXPECT_EQ(format, adapter.input_format()); - EXPECT_TRUE(adapter.output_format().IsSize0x0()); - - // Output format is 640x360, though. - format.width = 640; - format.height = 360; - adapter.SetOutputFormat(format); - - // And also a view request comes for 640x360. - adapter.OnOutputFormatRequest(format); - // At this point, we have to adapt down to something lower. - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(360, adapter.output_format().height); - - // But if frames come in at 640x360, we shouldn't adapt them down. - // Fake a 640x360 frame. - WebRtcVideoFrame in_frame; - in_frame.InitToBlack(640, 360, 1, 1, 33, 33); - VideoFrame* out_frame; - adapter.AdaptFrame(&in_frame, &out_frame); - - EXPECT_EQ(640u, out_frame->GetWidth()); - EXPECT_EQ(360u, out_frame->GetHeight()); - - // Similarly, no-op adapt requests for other reasons shouldn't change - // adaptation state (before a previous bug, the previous EXPECTs would - // fail and the following would succeed, as the no-op CPU request would - // fix the adaptation state). - adapter.set_cpu_adaptation(true); - UpdateCpuLoad(&adapter, 1, 1, 0.7f, 0.7f); - adapter.AdaptFrame(&in_frame, &out_frame); - - EXPECT_EQ(640u, out_frame->GetWidth()); - EXPECT_EQ(360u, out_frame->GetHeight()); -} - -// When adapting resolution for CPU or GD, the quantity of pixels that the -// request is based on is reduced to half or double, and then an actual -// resolution is snapped to, rounding to the closest actual resolution. -// This works well for some tolerance to 3/4, odd widths and aspect ratios -// that dont exactly match, but is not best behavior for ViewRequests which -// need to be be strictly respected to avoid going over the resolution budget -// given to the codec - 854x480 total pixels. -// ViewRequest must find a lower resolution. -TEST(CoordinatedVideoAdapterTest, TestCoordinatedViewRequestDown) { - CoordinatedVideoAdapter adapter; - adapter.set_cpu_adaptation(false); - - VideoFormat format(960, 540, VideoFormat::FpsToInterval(30), FOURCC_I420); - adapter.SetInputFormat(format); - adapter.set_scale_third(true); - EXPECT_EQ(format, adapter.input_format()); - EXPECT_TRUE(adapter.output_format().IsSize0x0()); - - // Server format request 640x400. Expect HVGA. - format.width = 640; - format.height = 400; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(640, adapter.output_format().width); - EXPECT_EQ(360, adapter.output_format().height); - - // Test reason for adapting is VIEW. - EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_VIEW, adapter.adapt_reason()); -} - -// Test that we downgrade video for cpu up to two times. -TEST(CoordinatedVideoAdapterTest, TestCpuDowngradeTimes) { - CoordinatedVideoAdapter adapter; - adapter.set_cpu_adaptation(true); - EXPECT_FALSE(adapter.cpu_smoothing()); - VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), FOURCC_I420); - adapter.SetInputFormat(format); - - // Server format request 640x400. - format.height = 400; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(640, adapter.output_format().width); - EXPECT_EQ(400, adapter.output_format().height); - - // Process load and system load are low. Do not change the cpu desired format - // and do not adapt. - adapter.OnCpuLoadUpdated(1, 1, 0.2f, 0.3f); - EXPECT_EQ(640, adapter.output_format().width); - EXPECT_EQ(400, adapter.output_format().height); - - // System load is high. Downgrade. - UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); - - // System load is high. Downgrade again. - UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // System load is still high. Do not downgrade any more. - UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Process load and system load are low. Upgrade. - UpdateCpuLoad(&adapter, 1, 1, 0.2f, 0.3f); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); - - // System load is high. Downgrade. - UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // System load is still high. Do not downgrade any more. - UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); -} - -// Test that we respect CPU adapter threshold values. -TEST(CoordinatedVideoAdapterTest, TestAdapterCpuThreshold) { - CoordinatedVideoAdapter adapter; - adapter.set_cpu_adaptation(true); - EXPECT_FALSE(adapter.cpu_smoothing()); - VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), FOURCC_I420); - adapter.SetInputFormat(format); - - // Server format request 640x400. - format.height = 400; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(640, adapter.output_format().width); - EXPECT_EQ(400, adapter.output_format().height); - - // Process load and system load are low. Do not change the cpu desired format - // and do not adapt. - adapter.OnCpuLoadUpdated(1, 1, 0.2f, 0.3f); - EXPECT_EQ(640, adapter.output_format().width); - EXPECT_EQ(400, adapter.output_format().height); - - // System load is high. Downgrade. - UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); - - // Test reason for adapting is CPU. - EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU, adapter.adapt_reason()); - - // System load is high. Normally downgrade but threshold is high. Do nothing. - adapter.set_high_system_threshold(0.98f); // Set threshold high. - UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); - - // System load is medium. Normally do nothing, threshold is low. Adapt down. - adapter.set_high_system_threshold(0.75f); // Set threshold low. - UpdateCpuLoad(&adapter, 1, 1, 0.8f, 0.8f); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); -} - - -// Test that for an upgrade cpu request, we actually upgrade the desired format; -// for a downgrade request, we downgrade from the output format. -TEST(CoordinatedVideoAdapterTest, TestRealCpuUpgrade) { - CoordinatedVideoAdapter adapter; - adapter.set_cpu_adaptation(true); - adapter.set_cpu_smoothing(true); - VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), FOURCC_I420); - adapter.SetInputFormat(format); - - // Server format request 640x400. - format.width = 640; - format.height = 400; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(640, adapter.output_format().width); - EXPECT_EQ(400, adapter.output_format().height); - - // Process load and system load are low. Do not change the cpu desired format - // and do not adapt. - UpdateCpuLoad(&adapter, 1, 1, 0.2f, 0.3f); - EXPECT_EQ(640, adapter.output_format().width); - EXPECT_EQ(400, adapter.output_format().height); - - // Server format request 320x200. - format.width = 320; - format.height = 200; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Process load and system load are low. Do not change the cpu desired format - // and do not adapt. - UpdateCpuLoad(&adapter, 1, 1, 0.2f, 0.3f); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Server format request 640x400. Set to 640x400 immediately. - format.width = 640; - format.height = 400; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(640, adapter.output_format().width); - EXPECT_EQ(400, adapter.output_format().height); - - // Server format request 320x200. - format.width = 320; - format.height = 200; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Process load is high, but system is not. Do not change the cpu desired - // format and do not adapt. - for (size_t i = 0; i < 10; ++i) { - UpdateCpuLoad(&adapter, 1, 1, 0.75f, 0.8f); - } - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); -} - -// Test that for an upgrade encoder request, we actually upgrade the desired -// format; for a downgrade request, we downgrade from the output format. -TEST(CoordinatedVideoAdapterTest, TestRealEncoderUpgrade) { - CoordinatedVideoAdapter adapter; - adapter.set_cpu_adaptation(true); - adapter.set_cpu_smoothing(true); - VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), FOURCC_I420); - adapter.SetInputFormat(format); - - // Server format request 640x400. - format.width = 640; - format.height = 400; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(640, adapter.output_format().width); - EXPECT_EQ(400, adapter.output_format().height); - - // Encoder resolution request. Do not change the encoder desired format and - // do not adapt. - adapter.OnEncoderResolutionRequest(640, 400, - CoordinatedVideoAdapter::UPGRADE); - EXPECT_EQ(640, adapter.output_format().width); - EXPECT_EQ(400, adapter.output_format().height); - - // Server format request 320x200. - format.width = 320; - format.height = 200; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Encoder resolution request. Do not change the encoder desired format and - // do not adapt. - adapter.OnEncoderResolutionRequest(320, 200, - CoordinatedVideoAdapter::UPGRADE); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Server format request 640x400. Set to 640x400 immediately. - format.width = 640; - format.height = 400; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(300, adapter.output_format().height); - - // Test reason for adapting is BANDWIDTH. - EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_BANDWIDTH, - adapter.adapt_reason()); - - // Server format request 320x200. - format.width = 320; - format.height = 200; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(200, adapter.output_format().height); - - // Encoder resolution request. Downgrade from 320x200. - adapter.OnEncoderResolutionRequest(320, 200, - CoordinatedVideoAdapter::DOWNGRADE); - EXPECT_EQ(240, adapter.output_format().width); - EXPECT_EQ(150, adapter.output_format().height); -} - -TEST(CoordinatedVideoAdapterTest, TestNormalizeOutputFormat) { - CoordinatedVideoAdapter adapter; - // The input format is 640x360 and the output is limited to 16:9. - VideoFormat format(640, 360, VideoFormat::FpsToInterval(30), FOURCC_I420); - adapter.SetInputFormat(format); - - format.width = 320; - format.height = 180; - format.interval = VideoFormat::FpsToInterval(15); - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(180, adapter.output_format().height); - EXPECT_EQ(VideoFormat::FpsToInterval(15), adapter.output_format().interval); - - format.width = 320; - format.height = 200; - format.interval = VideoFormat::FpsToInterval(40); - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(180, adapter.output_format().height); - EXPECT_EQ(VideoFormat::FpsToInterval(30), adapter.output_format().interval); - - // Test reason for adapting is VIEW. Should work even with normalization. - EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_VIEW, - adapter.adapt_reason()); - - format.width = 320; - format.height = 240; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(180, adapter.output_format().height); - - // The input format is 640x480 and the output will be 4:3. - format.width = 640; - format.height = 480; - adapter.SetInputFormat(format); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(240, adapter.output_format().height); - - format.width = 320; - format.height = 240; - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(240, adapter.output_format().height); - - // The input format is initialized after the output. At that time, the output - // height is adjusted. - format.width = 0; - format.height = 0; - adapter.SetInputFormat(format); - - format.width = 320; - format.height = 240; - format.interval = VideoFormat::FpsToInterval(30); - adapter.OnOutputFormatRequest(format); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(240, adapter.output_format().height); - EXPECT_EQ(VideoFormat::FpsToInterval(30), adapter.output_format().interval); - - format.width = 640; - format.height = 480; - format.interval = VideoFormat::FpsToInterval(15); - adapter.SetInputFormat(format); - EXPECT_EQ(320, adapter.output_format().width); - EXPECT_EQ(240, adapter.output_format().height); - EXPECT_EQ(VideoFormat::FpsToInterval(15), adapter.output_format().interval); -} - -// Test that we downgrade video for cpu up to two times. -TEST_F(VideoAdapterTest, CpuDowngradeAndSignal) { - CoordinatedVideoAdapter adapter; - CpuAdapterListener cpu_listener; - adapter.SignalCpuAdaptationUnable.connect( - &cpu_listener, &CpuAdapterListener::OnCpuAdaptationSignalled); - - adapter.set_cpu_adaptation(true); - EXPECT_FALSE(adapter.cpu_smoothing()); - VideoFormat format(640, 360, VideoFormat::FpsToInterval(30), FOURCC_I420); - adapter.SetInputFormat(format); - adapter.OnOutputFormatRequest(format); - - // System load is high. Downgrade. - UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); - - // System load is high. Downgrade again. - UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); - - // System load is still high. Do not downgrade any more. Ensure we have not - // signalled until after the cpu warning though. - EXPECT_TRUE(!cpu_listener.received_cpu_signal()); - UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); - EXPECT_TRUE_WAIT(cpu_listener.received_cpu_signal(), kWaitTimeout); -} - -// Test that we downgrade video for cpu up to two times. -TEST_F(VideoAdapterTest, CpuDowngradeAndDontSignal) { - CoordinatedVideoAdapter adapter; - CpuAdapterListener cpu_listener; - adapter.SignalCpuAdaptationUnable.connect( - &cpu_listener, &CpuAdapterListener::OnCpuAdaptationSignalled); - - adapter.set_cpu_adaptation(true); - adapter.set_cpu_smoothing(true); - VideoFormat format(640, 360, VideoFormat::FpsToInterval(30), FOURCC_I420); - adapter.SetInputFormat(format); - adapter.OnOutputFormatRequest(format); - - // System load is high. Downgrade. - UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); - - // System load is high, process is not, Do not downgrade again. - UpdateCpuLoad(&adapter, 1, 1, 0.25f, 0.95f); - - // System load is high, process is not, Do not downgrade again and do not - // signal. - adapter.set_cpu_adaptation(false); - UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); - rtc::Thread::Current()->ProcessMessages(kShortWaitTimeout); - EXPECT_TRUE(!cpu_listener.received_cpu_signal()); - adapter.set_cpu_adaptation(true); -} - -// Test that we require enough time before we downgrade. -TEST_F(VideoAdapterTest, CpuMinTimeRequirement) { - CoordinatedVideoAdapter adapter; - CpuAdapterListener cpu_listener; - adapter.SignalCpuAdaptationUnable.connect( - &cpu_listener, &CpuAdapterListener::OnCpuAdaptationSignalled); - - adapter.set_cpu_adaptation(true); - adapter.set_cpu_smoothing(true); - VideoFormat format(640, 360, VideoFormat::FpsToInterval(30), FOURCC_I420); - adapter.SetInputFormat(format); - adapter.OnOutputFormatRequest(format); - - EXPECT_EQ(3, adapter.cpu_load_min_samples()); - adapter.set_cpu_load_min_samples(5); - - for (size_t i = 0; i < 4; ++i) { - adapter.OnCpuLoadUpdated(1, 1, 1.0f, 1.0f); - EXPECT_EQ(640, adapter.output_format().width); - EXPECT_EQ(360, adapter.output_format().height); - } - // The computed cpu load should now be around 93.5%, with the coefficient of - // 0.4 and a seed value of 0.5. That should be high enough to adapt, but it - // isn't enough samples, so we shouldn't have adapted on any of the previous - // samples. - - // One more sample is enough, though, once enough time has passed. - adapter.OnCpuLoadUpdated(1, 1, 1.0f, 1.0f); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(270, adapter.output_format().height); - - // Now the cpu is lower, but we still need enough samples to upgrade. - for (size_t i = 0; i < 4; ++i) { - adapter.OnCpuLoadUpdated(1, 1, 0.1f, 0.1f); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(270, adapter.output_format().height); - } - - // One more sample is enough, once time has elapsed. - adapter.OnCpuLoadUpdated(1, 1, 1.0f, 1.0f); - EXPECT_EQ(640, adapter.output_format().width); - EXPECT_EQ(360, adapter.output_format().height); -} - -TEST_F(VideoAdapterTest, CpuIgnoresSpikes) { - CoordinatedVideoAdapter adapter; - CpuAdapterListener cpu_listener; - adapter.SignalCpuAdaptationUnable.connect( - &cpu_listener, &CpuAdapterListener::OnCpuAdaptationSignalled); - - adapter.set_cpu_adaptation(true); - adapter.set_cpu_smoothing(true); - VideoFormat format(640, 360, VideoFormat::FpsToInterval(30), FOURCC_I420); - adapter.SetInputFormat(format); - adapter.OnOutputFormatRequest(format); - - // System load is high. Downgrade. - for (size_t i = 0; i < 5; ++i) { - UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); - } - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(270, adapter.output_format().height); - - // Now we're in a state where we could upgrade or downgrade, so get to a - // steady state of about 75% cpu usage. - for (size_t i = 0; i < 5; ++i) { - UpdateCpuLoad(&adapter, 1, 1, 0.75f, 0.75f); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(270, adapter.output_format().height); - } - - // Now, the cpu spikes for two samples, but then goes back to - // normal. This shouldn't cause adaptation. - UpdateCpuLoad(&adapter, 1, 1, 0.90f, 0.90f); - UpdateCpuLoad(&adapter, 1, 1, 0.90f, 0.90f); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(270, adapter.output_format().height); - // Back to the steady state for awhile. - for (size_t i = 0; i < 5; ++i) { - UpdateCpuLoad(&adapter, 1, 1, 0.75, 0.75); - EXPECT_EQ(480, adapter.output_format().width); - EXPECT_EQ(270, adapter.output_format().height); - } - - // Now, system cpu usage is starting to drop down. But it takes a bit before - // it gets all the way there. - for (size_t i = 0; i < 10; ++i) { - UpdateCpuLoad(&adapter, 1, 1, 0.5f, 0.5f); - } - EXPECT_EQ(640, adapter.output_format().width); - EXPECT_EQ(360, adapter.output_format().height); -} - -} // namespace cricket -#endif // HAVE_WEBRTC_VIDEO diff --git a/talk/media/base/videocapturer.cc b/talk/media/base/videocapturer.cc index f20e6fb76..139fd09a5 100644 --- a/talk/media/base/videocapturer.cc +++ b/talk/media/base/videocapturer.cc @@ -35,14 +35,13 @@ #include "webrtc/base/common.h" #include "webrtc/base/logging.h" #include "webrtc/base/systeminfo.h" -#include "talk/media/base/videoframefactory.h" #include "talk/media/base/videoprocessor.h" #if defined(HAVE_WEBRTC_VIDEO) #include "talk/media/webrtc/webrtcvideoframe.h" -#include "talk/media/webrtc/webrtcvideoframefactory.h" #endif // HAVE_WEBRTC_VIDEO + namespace cricket { namespace { @@ -353,6 +352,10 @@ void VideoCapturer::OnFrameCaptured(VideoCapturer*, if (SignalVideoFrame.is_empty()) { return; } +#if defined(HAVE_WEBRTC_VIDEO) +#define VIDEO_FRAME_NAME WebRtcVideoFrame +#endif +#if defined(VIDEO_FRAME_NAME) #if !defined(DISABLE_YUV) if (IsScreencast()) { int scaled_width, scaled_height; @@ -498,15 +501,8 @@ void VideoCapturer::OnFrameCaptured(VideoCapturer*, &desired_width, &desired_height); } - if (!frame_factory_) { - LOG(LS_ERROR) << "No video frame factory."; - return; - } - - rtc::scoped_ptr i420_frame( - frame_factory_->CreateAliasedFrame( - captured_frame, desired_width, desired_height)); - if (!i420_frame) { + VIDEO_FRAME_NAME i420_frame; + if (!i420_frame.Alias(captured_frame, desired_width, desired_height)) { // TODO(fbarchard): LOG more information about captured frame attributes. LOG(LS_ERROR) << "Couldn't convert to I420! " << "From " << ToString(captured_frame) << " To " @@ -514,7 +510,7 @@ void VideoCapturer::OnFrameCaptured(VideoCapturer*, return; } - VideoFrame* adapted_frame = i420_frame.get(); + VideoFrame* adapted_frame = &i420_frame; if (enable_video_adapter_ && !IsScreencast()) { VideoFrame* out_frame = NULL; video_adapter_.AdaptFrame(adapted_frame, &out_frame); @@ -532,12 +528,13 @@ void VideoCapturer::OnFrameCaptured(VideoCapturer*, return; } if (muted_) { - // TODO(pthatcher): Use frame_factory_->CreateBlackFrame() instead. adapted_frame->SetToBlack(); } SignalVideoFrame(this, adapted_frame); UpdateStats(captured_frame); + +#endif // VIDEO_FRAME_NAME } void VideoCapturer::SetCaptureState(CaptureState state) { diff --git a/talk/media/base/videocapturer.h b/talk/media/base/videocapturer.h index c60221a55..d4192be58 100644 --- a/talk/media/base/videocapturer.h +++ b/talk/media/base/videocapturer.h @@ -42,7 +42,6 @@ #include "talk/media/base/mediachannel.h" #include "talk/media/base/videoadapter.h" #include "talk/media/base/videocommon.h" -#include "talk/media/base/videoframefactory.h" #include "talk/media/devices/devicemanager.h" @@ -290,11 +289,6 @@ class VideoCapturer return &video_adapter_; } - // Takes ownership. - void set_frame_factory(VideoFrameFactory* frame_factory) { - frame_factory_.reset(frame_factory); - } - // Gets statistics for tracked variables recorded since the last call to // GetStats. Note that calling GetStats resets any gathered data so it // should be called only periodically to log statistics. @@ -332,7 +326,6 @@ class VideoCapturer } void SetSupportedFormats(const std::vector& formats); - VideoFrameFactory* frame_factory() { return frame_factory_.get(); } private: void Construct(); @@ -368,7 +361,6 @@ class VideoCapturer rtc::Thread* thread_; std::string id_; CaptureState capture_state_; - rtc::scoped_ptr frame_factory_; rtc::scoped_ptr capture_format_; std::vector supported_formats_; rtc::scoped_ptr max_format_; diff --git a/talk/media/base/videocapturer_unittest.cc b/talk/media/base/videocapturer_unittest.cc index 37f6bbde4..b70280f1c 100644 --- a/talk/media/base/videocapturer_unittest.cc +++ b/talk/media/base/videocapturer_unittest.cc @@ -1,29 +1,4 @@ -/* - * libjingle - * Copyright 2008 Google Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +// Copyright 2008 Google Inc. #include #include @@ -38,6 +13,15 @@ #include "talk/media/base/videocapturer.h" #include "talk/media/base/videoprocessor.h" +// If HAS_I420_FRAME is not defined the video capturer will not be able to +// provide OnVideoFrame-callbacks since they require cricket::CapturedFrame to +// be decoded as a cricket::VideoFrame (i.e. an I420 frame). This functionality +// only exist if HAS_I420_FRAME is defined below. I420 frames are also a +// requirement for the VideoProcessors so they will not be called either. +#if defined(HAVE_WEBRTC_VIDEO) +#define HAS_I420_FRAME +#endif + using cricket::FakeVideoCapturer; namespace { @@ -698,12 +682,7 @@ TEST_F(VideoCapturerTest, TestRequest16x10_9) { EXPECT_EQ(360, best.height); } -// If HAVE_WEBRTC_VIDEO is not defined the video capturer will not be able to -// provide OnVideoFrame-callbacks since they require cricket::CapturedFrame to -// be decoded as a cricket::VideoFrame (i.e. an I420 frame). This functionality -// only exist if HAVE_WEBRTC_VIDEO is defined below. I420 frames are also a -// requirement for the VideoProcessors so they will not be called either. -#if defined(HAVE_WEBRTC_VIDEO) +#if defined(HAS_I420_FRAME) TEST_F(VideoCapturerTest, VideoFrame) { EXPECT_EQ(cricket::CS_RUNNING, capturer_.Start(cricket::VideoFormat( 640, @@ -756,7 +735,7 @@ TEST_F(VideoCapturerTest, ProcessorDropFrame) { EXPECT_TRUE(capturer_.CaptureFrame()); EXPECT_EQ(0, video_frames_received()); } -#endif // HAVE_WEBRTC_VIDEO +#endif // HAS_I420_FRAME bool HdFormatInList(const std::vector& formats) { for (std::vector::const_iterator found = diff --git a/talk/media/base/videoengine_unittest.h b/talk/media/base/videoengine_unittest.h index 502cf47ce..25811ba07 100644 --- a/talk/media/base/videoengine_unittest.h +++ b/talk/media/base/videoengine_unittest.h @@ -503,18 +503,14 @@ class VideoMediaChannelTest : public testing::Test, media_error_ = cricket::VideoMediaChannel::ERROR_NONE; channel_->SetRecvCodecs(engine_.codecs()); EXPECT_TRUE(channel_->AddSendStream(DefaultSendStreamParams())); - video_capturer_.reset(CreateFakeVideoCapturer()); + + video_capturer_.reset(new cricket::FakeVideoCapturer); cricket::VideoFormat format(640, 480, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420); EXPECT_EQ(cricket::CS_RUNNING, video_capturer_->Start(format)); EXPECT_TRUE(channel_->SetCapturer(kSsrc, video_capturer_.get())); } - - virtual cricket::FakeVideoCapturer* CreateFakeVideoCapturer() { - return new cricket::FakeVideoCapturer(); - } - // Utility method to setup an additional stream to send and receive video. // Used to test send and recv between two streams. void SetUpSecondStream() { @@ -539,7 +535,7 @@ class VideoMediaChannelTest : public testing::Test, // We dont add recv for the second stream. // Setup the receive and renderer for second stream after send. - video_capturer_2_.reset(CreateFakeVideoCapturer()); + video_capturer_2_.reset(new cricket::FakeVideoCapturer()); cricket::VideoFormat format(640, 480, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420); @@ -971,7 +967,7 @@ class VideoMediaChannelTest : public testing::Test, // Add an additional capturer, and hook up a renderer to receive it. cricket::FakeVideoRenderer renderer1; rtc::scoped_ptr capturer( - CreateFakeVideoCapturer()); + new cricket::FakeVideoCapturer); capturer->SetScreencast(true); const int kTestWidth = 160; const int kTestHeight = 120; @@ -1321,7 +1317,7 @@ class VideoMediaChannelTest : public testing::Test, EXPECT_TRUE(SendFrame()); EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout); rtc::scoped_ptr capturer( - CreateFakeVideoCapturer()); + new cricket::FakeVideoCapturer); capturer->SetScreencast(true); cricket::VideoFormat format(480, 360, cricket::VideoFormat::FpsToInterval(30), @@ -1415,7 +1411,7 @@ class VideoMediaChannelTest : public testing::Test, EXPECT_TRUE(channel_->AddSendStream( cricket::StreamParams::CreateLegacy(1))); rtc::scoped_ptr capturer1( - CreateFakeVideoCapturer()); + new cricket::FakeVideoCapturer); capturer1->SetScreencast(true); EXPECT_EQ(cricket::CS_RUNNING, capturer1->Start(capture_format)); // Set up additional stream 2. @@ -1427,7 +1423,7 @@ class VideoMediaChannelTest : public testing::Test, EXPECT_TRUE(channel_->AddSendStream( cricket::StreamParams::CreateLegacy(2))); rtc::scoped_ptr capturer2( - CreateFakeVideoCapturer()); + new cricket::FakeVideoCapturer); capturer2->SetScreencast(true); EXPECT_EQ(cricket::CS_RUNNING, capturer2->Start(capture_format)); // State for all the streams. @@ -1485,7 +1481,7 @@ class VideoMediaChannelTest : public testing::Test, // Registering an external capturer is currently the same as screen casting // (update the test when this changes). rtc::scoped_ptr capturer( - CreateFakeVideoCapturer()); + new cricket::FakeVideoCapturer); capturer->SetScreencast(true); const std::vector* formats = capturer->GetSupportedFormats(); diff --git a/talk/media/base/videoframefactory.h b/talk/media/base/videoframefactory.h deleted file mode 100755 index 301ec1c43..000000000 --- a/talk/media/base/videoframefactory.h +++ /dev/null @@ -1,52 +0,0 @@ -// libjingle -// Copyright 2014 Google Inc. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// 3. The name of the author may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -#ifndef TALK_MEDIA_BASE_VIDEOFRAMEFACTORY_H_ -#define TALK_MEDIA_BASE_VIDEOFRAMEFACTORY_H_ - -namespace cricket { - -struct CapturedFrame; -class VideoFrame; - -// Creates cricket::VideoFrames, or a subclass of cricket::VideoFrame -// depending on the subclass of VideoFrameFactory. -class VideoFrameFactory { - public: - VideoFrameFactory() {} - virtual ~VideoFrameFactory() {} - - // The returned frame aliases the aliased_frame if the input color - // space allows for aliasing, otherwise a color conversion will - // occur. For safety, |input_frame| must outlive the returned - // frame. Returns NULL if conversion fails. - virtual VideoFrame* CreateAliasedFrame( - const CapturedFrame* input_frame, int width, int height) const = 0; -}; - -} // namespace cricket - -#endif // TALK_MEDIA_BASE_VIDEOFRAMEFACTORY_H_ diff --git a/talk/media/webrtc/webrtcvideocapturer.cc b/talk/media/webrtc/webrtcvideocapturer.cc index 38df9cebc..d341d1205 100644 --- a/talk/media/webrtc/webrtcvideocapturer.cc +++ b/talk/media/webrtc/webrtcvideocapturer.cc @@ -37,7 +37,6 @@ #include "webrtc/base/thread.h" #include "webrtc/base/timeutils.h" #include "talk/media/webrtc/webrtcvideoframe.h" -#include "talk/media/webrtc/webrtcvideoframefactory.h" #include "webrtc/base/win32.h" // Need this to #include the impl files. #include "webrtc/modules/video_capture/include/video_capture_factory.h" @@ -127,14 +126,12 @@ WebRtcVideoCapturer::WebRtcVideoCapturer() : factory_(new WebRtcVcmFactory), module_(NULL), captured_frames_(0) { - set_frame_factory(new WebRtcVideoFrameFactory()); } WebRtcVideoCapturer::WebRtcVideoCapturer(WebRtcVcmFactoryInterface* factory) : factory_(factory), module_(NULL), captured_frames_(0) { - set_frame_factory(new WebRtcVideoFrameFactory()); } WebRtcVideoCapturer::~WebRtcVideoCapturer() { diff --git a/talk/media/webrtc/webrtcvideoframefactory.h b/talk/media/webrtc/webrtcvideoframefactory.h deleted file mode 100755 index 448cdcf50..000000000 --- a/talk/media/webrtc/webrtcvideoframefactory.h +++ /dev/null @@ -1,45 +0,0 @@ -// libjingle -// Copyright 2014 Google Inc. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// 3. The name of the author may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -#ifndef TALK_MEDIA_WEBRTC_WEBRTCVIDEOFRAMEFACTORY_H_ -#define TALK_MEDIA_WEBRTC_WEBRTCVIDEOFRAMEFACTORY_H_ - -#include "talk/media/base/videoframefactory.h" - -namespace cricket { - -struct CapturedFrame; - -// Creates instances of cricket::WebRtcVideoFrame. -class WebRtcVideoFrameFactory : public VideoFrameFactory { - public: - virtual VideoFrame* CreateAliasedFrame( - const CapturedFrame* aliased_frame, int width, int height) const OVERRIDE; -}; - -} // namespace cricket - -#endif // TALK_MEDIA_WEBRTC_WEBRTCVIDEOFRAMEFACTORY_H_