Delete VideoAdapter::AdaptFrame

This CL deletes VideoAdapter::AdaptFrame and replaces the remaining calls with AdaptFrameResolution instead.

I do not expect this CL to fix the flaky VideoAdapterTests yet. I intend to replace FileVideoCapturer with a deterministic FakeVideoCapturer in a follow-up CL.

BUG=4317
R=pbos@webrtc.org, pthatcher@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/44769004

Cr-Commit-Position: refs/heads/master@{#8848}
This commit is contained in:
Magnus Jedvert 2015-03-24 15:18:39 +01:00
parent 45636ece8a
commit ac27e20477
3 changed files with 25 additions and 130 deletions

View File

@ -147,9 +147,9 @@ float VideoAdapter::FindLowerScale(int width, int height,
// There are several frame sizes used by Adapter. This explains them // There are several frame sizes used by Adapter. This explains them
// input_format - set once by server to frame size expected from the camera. // input_format - set once by server to frame size expected from the camera.
// The input frame size is also updated in every call to AdaptFrame. // The input frame size is also updated in AdaptFrameResolution.
// output_format - size that output would like to be. Includes framerate. // output_format - size that output would like to be. Includes framerate.
// The output frame size is also updated in every call to AdaptFrame. // The output frame size is also updated in AdaptFrameResolution.
// output_num_pixels - size that output should be constrained to. Used to // output_num_pixels - size that output should be constrained to. Used to
// compute output_format from in_frame. // compute output_format from in_frame.
// in_frame - actual camera captured frame size, which is typically the same // in_frame - actual camera captured frame size, which is typically the same
@ -349,75 +349,12 @@ VideoFormat VideoAdapter::AdaptFrameResolution(int in_width, int in_height) {
return output_format_; return output_format_;
} }
// TODO(fbarchard): Add AdaptFrameRate function that only drops frames but
// not resolution.
bool VideoAdapter::AdaptFrame(VideoFrame* in_frame, VideoFrame** out_frame) {
if (!in_frame || !out_frame)
return false;
const VideoFormat adapted_format =
AdaptFrameResolution(static_cast<int>(in_frame->GetWidth()),
static_cast<int>(in_frame->GetHeight()));
rtc::CritScope cs(&critical_section_);
if (adapted_format.IsSize0x0()) {
*out_frame = NULL;
return true;
}
if (in_frame->GetWidth() == static_cast<size_t>(adapted_format.width) &&
in_frame->GetHeight() == static_cast<size_t>(adapted_format.height)) {
// The dimensions are correct and we aren't muting, so use the input frame.
*out_frame = in_frame;
} else {
if (!StretchToOutputFrame(in_frame)) {
LOG(LS_VERBOSE) << "VAdapt Stretch Failed.";
return false;
}
*out_frame = output_frame_.get();
}
return true;
}
void VideoAdapter::set_scale_third(bool enable) { void VideoAdapter::set_scale_third(bool enable) {
LOG(LS_INFO) << "Video Adapter third scaling is now " LOG(LS_INFO) << "Video Adapter third scaling is now "
<< (enable ? "enabled" : "disabled"); << (enable ? "enabled" : "disabled");
scale_third_ = enable; scale_third_ = enable;
} }
// Scale or Blacken the frame. Returns true if successful.
bool VideoAdapter::StretchToOutputFrame(const VideoFrame* in_frame) {
int output_width = output_format_.width;
int output_height = output_format_.height;
// Create and stretch the output frame if it has not been created yet or its
// size is not same as the expected.
bool stretched = false;
if (!output_frame_ ||
output_frame_->GetWidth() != static_cast<size_t>(output_width) ||
output_frame_->GetHeight() != static_cast<size_t>(output_height)) {
output_frame_.reset(
in_frame->Stretch(output_width, output_height, true, true));
if (!output_frame_) {
LOG(LS_WARNING) << "Adapter failed to stretch frame to "
<< output_width << "x" << output_height;
return false;
}
stretched = true;
}
if (!stretched) {
// The output frame does not need to be blacken and has not been stretched
// from the input frame yet, stretch the input frame. This is the most
// common case.
in_frame->StretchToFrame(output_frame_.get(), true, true);
}
return true;
}
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// Implementation of CoordinatedVideoAdapter // Implementation of CoordinatedVideoAdapter
CoordinatedVideoAdapter::CoordinatedVideoAdapter() CoordinatedVideoAdapter::CoordinatedVideoAdapter()

View File

@ -53,7 +53,8 @@ class VideoAdapter {
int GetOutputNumPixels() const; int GetOutputNumPixels() const;
const VideoFormat& input_format(); const VideoFormat& input_format();
// Returns true if the adapter is dropping frames in calls to AdaptFrame. // Returns true if the adapter will always return zero size from
// AdaptFrameResolution.
bool drops_all_frames() const; bool drops_all_frames() const;
const VideoFormat& output_format(); const VideoFormat& output_format();
@ -61,18 +62,6 @@ class VideoAdapter {
// resolution will be 0x0 if the frame should be dropped. // resolution will be 0x0 if the frame should be dropped.
VideoFormat AdaptFrameResolution(int in_width, int in_height); VideoFormat AdaptFrameResolution(int in_width, int in_height);
// Adapt the input frame from the input format to the output format. Return
// true and set the output frame to NULL if the input frame is dropped. Return
// true and set the out frame to output_frame_ if the input frame is adapted
// successfully. Return false otherwise.
// Note that, if no adaptation is required, |out_frame| will refer directly
// in_frame. If a copy is always required, the caller must do an explicit
// copy.
// If a copy has taken place, |output_frame_| is owned by the VideoAdapter
// and will remain usable until the adapter is destroyed or AdaptFrame is
// called again.
bool AdaptFrame(VideoFrame* in_frame, VideoFrame** out_frame);
void set_scale_third(bool enable); void set_scale_third(bool enable);
bool scale_third() const { return scale_third_; } bool scale_third() const { return scale_third_; }
@ -88,7 +77,6 @@ class VideoAdapter {
float FindScale(const float* scale_factors, float FindScale(const float* scale_factors,
const float upbias, int width, int height, const float upbias, int width, int height,
int target_num_pixels); int target_num_pixels);
bool StretchToOutputFrame(const VideoFrame* in_frame);
VideoFormat input_format_; VideoFormat input_format_;
VideoFormat output_format_; VideoFormat output_format_;
@ -101,7 +89,6 @@ class VideoAdapter {
size_t previous_width_; // Previous adapter output width. size_t previous_width_; // Previous adapter output width.
size_t previous_height_; // Previous adapter output height. size_t previous_height_; // Previous adapter output height.
int64 interval_next_frame_; int64 interval_next_frame_;
rtc::scoped_ptr<VideoFrame> output_frame_;
// The critical section to protect the above variables. // The critical section to protect the above variables.
rtc::CriticalSection critical_section_; rtc::CriticalSection critical_section_;

View File

@ -25,8 +25,6 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 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 <limits.h> // For INT_MAX #include <limits.h> // For INT_MAX
#include <string> #include <string>
#include <vector> #include <vector>
@ -35,7 +33,6 @@
#include "talk/media/base/testutils.h" #include "talk/media/base/testutils.h"
#include "talk/media/base/videoadapter.h" #include "talk/media/base/videoadapter.h"
#include "talk/media/devices/filevideocapturer.h" #include "talk/media/devices/filevideocapturer.h"
#include "talk/media/webrtc/webrtcvideoframe.h"
#include "webrtc/base/gunit.h" #include "webrtc/base/gunit.h"
#include "webrtc/base/logging.h" #include "webrtc/base/logging.h"
#include "webrtc/base/sigslot.h" #include "webrtc/base/sigslot.h"
@ -89,8 +86,6 @@ class VideoAdapterTest : public testing::Test {
explicit VideoCapturerListener(VideoAdapter* adapter) explicit VideoCapturerListener(VideoAdapter* adapter)
: video_adapter_(adapter), : video_adapter_(adapter),
adapted_frame_(NULL),
copied_output_frame_(),
captured_frames_(0), captured_frames_(0),
dropped_frames_(0), dropped_frames_(0),
last_adapt_was_no_op_(false) { last_adapt_was_no_op_(false) {
@ -98,22 +93,15 @@ class VideoAdapterTest : public testing::Test {
void OnFrameCaptured(VideoCapturer* capturer, void OnFrameCaptured(VideoCapturer* capturer,
const CapturedFrame* captured_frame) { const CapturedFrame* captured_frame) {
WebRtcVideoFrame temp_i420;
EXPECT_TRUE(temp_i420.Init(captured_frame,
captured_frame->width, abs(captured_frame->height), true));
VideoFrame* out_frame = NULL;
rtc::CritScope lock(&crit_); rtc::CritScope lock(&crit_);
EXPECT_TRUE(video_adapter_->AdaptFrame(&temp_i420, &out_frame)); const int in_width = captured_frame->width;
if (out_frame) { const int in_height = abs(captured_frame->height);
if (out_frame == &temp_i420) { const VideoFormat adapted_format =
last_adapt_was_no_op_ = true; video_adapter_->AdaptFrameResolution(in_width, in_height);
copied_output_frame_.reset(temp_i420.Copy()); if (!adapted_format.IsSize0x0()) {
adapted_frame_ = copied_output_frame_.get(); adapted_format_ = adapted_format;
} else { last_adapt_was_no_op_ = (in_width == adapted_format.width &&
last_adapt_was_no_op_ = false; in_height == adapted_format.height);
adapted_frame_ = out_frame;
copied_output_frame_.reset();
}
} else { } else {
++dropped_frames_; ++dropped_frames_;
} }
@ -126,9 +114,9 @@ class VideoAdapterTest : public testing::Test {
stats.captured_frames = captured_frames_; stats.captured_frames = captured_frames_;
stats.dropped_frames = dropped_frames_; stats.dropped_frames = dropped_frames_;
stats.last_adapt_was_no_op = last_adapt_was_no_op_; stats.last_adapt_was_no_op = last_adapt_was_no_op_;
if (adapted_frame_ != NULL) { if (!adapted_format_.IsSize0x0()) {
stats.adapted_width = static_cast<int>(adapted_frame_->GetWidth()); stats.adapted_width = adapted_format_.width;
stats.adapted_height = static_cast<int>(adapted_frame_->GetHeight()); stats.adapted_height = adapted_format_.height;
} else { } else {
stats.adapted_width = stats.adapted_height = -1; stats.adapted_width = stats.adapted_height = -1;
} }
@ -136,19 +124,10 @@ class VideoAdapterTest : public testing::Test {
return stats; return stats;
} }
VideoFrame* CopyAdaptedFrame() {
rtc::CritScope lock(&crit_);
if (adapted_frame_ == NULL) {
return NULL;
}
return adapted_frame_->Copy();
}
private: private:
rtc::CriticalSection crit_; rtc::CriticalSection crit_;
VideoAdapter* video_adapter_; VideoAdapter* video_adapter_;
const VideoFrame* adapted_frame_; VideoFormat adapted_format_;
rtc::scoped_ptr<VideoFrame> copied_output_frame_;
int captured_frames_; int captured_frames_;
int dropped_frames_; int dropped_frames_;
bool last_adapt_was_no_op_; bool last_adapt_was_no_op_;
@ -812,12 +791,9 @@ TEST(CoordinatedVideoAdapterTest, TestViewRequestPlusCameraSwitch) {
// Now, the camera reopens at VGA. // Now, the camera reopens at VGA.
// Both the frame and the output format should be 640x360. // Both the frame and the output format should be 640x360.
WebRtcVideoFrame in_frame; const VideoFormat out_format = adapter.AdaptFrameResolution(640, 360);
in_frame.InitToBlack(640, 360, 1, 1, 33, 33); EXPECT_EQ(640, out_format.width);
VideoFrame* out_frame; EXPECT_EQ(360, out_format.height);
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 // At this point, the view is no longer adapted, since the input has resized
// small enough to fit the last view request. // small enough to fit the last view request.
EXPECT_EQ(0, adapter.adapt_reason()); EXPECT_EQ(0, adapter.adapt_reason());
@ -853,13 +829,9 @@ TEST(CoordinatedVideoAdapterTest, TestVGAWidth) {
// But if frames come in at 640x360, we shouldn't adapt them down. // But if frames come in at 640x360, we shouldn't adapt them down.
// Fake a 640x360 frame. // Fake a 640x360 frame.
WebRtcVideoFrame in_frame; VideoFormat out_format = adapter.AdaptFrameResolution(640, 360);
in_frame.InitToBlack(640, 360, 1, 1, 33, 33); EXPECT_EQ(640, out_format.width);
VideoFrame* out_frame; EXPECT_EQ(360, out_format.height);
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 // Similarly, no-op adapt requests for other reasons shouldn't change
// adaptation state (before a previous bug, the previous EXPECTs would // adaptation state (before a previous bug, the previous EXPECTs would
@ -867,10 +839,10 @@ TEST(CoordinatedVideoAdapterTest, TestVGAWidth) {
// fix the adaptation state). // fix the adaptation state).
adapter.set_cpu_adaptation(true); adapter.set_cpu_adaptation(true);
UpdateCpuLoad(&adapter, 1, 1, 0.7f, 0.7f); UpdateCpuLoad(&adapter, 1, 1, 0.7f, 0.7f);
adapter.AdaptFrame(&in_frame, &out_frame); out_format = adapter.AdaptFrameResolution(640, 360);
EXPECT_EQ(640u, out_frame->GetWidth()); EXPECT_EQ(640, out_format.width);
EXPECT_EQ(360u, out_frame->GetHeight()); EXPECT_EQ(360, out_format.height);
} }
// When adapting resolution for CPU or GD, the quantity of pixels that the // When adapting resolution for CPU or GD, the quantity of pixels that the
@ -1331,4 +1303,3 @@ TEST_F(VideoAdapterTest, CpuIgnoresSpikes) {
} }
} // namespace cricket } // namespace cricket
#endif // HAVE_WEBRTC_VIDEO