Offline screenshare quality test, plus loopback.
BUG=4171
R=mflodman@webrtc.org, pbos@webrtc.org, stefan@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/34109004
Cr-Commit-Position: refs/heads/master@{#8408}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8408 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/test/frame_generator.cc b/webrtc/test/frame_generator.cc
index 4dd76ae..b7eada9 100644
--- a/webrtc/test/frame_generator.cc
+++ b/webrtc/test/frame_generator.cc
@@ -13,6 +13,7 @@
#include <stdio.h>
#include <string.h>
+#include "webrtc/base/checks.h"
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
namespace webrtc {
@@ -52,66 +53,98 @@
class YuvFileGenerator : public FrameGenerator {
public:
- YuvFileGenerator(FILE* file, size_t width, size_t height)
- : file_(file), width_(width), height_(height) {
- assert(file);
+ YuvFileGenerator(std::vector<FILE*> files,
+ size_t width,
+ size_t height,
+ int frame_repeat_count)
+ : file_index_(0),
+ files_(files),
+ width_(width),
+ height_(height),
+ frame_size_(CalcBufferSize(kI420,
+ static_cast<int>(width_),
+ static_cast<int>(height_))),
+ frame_buffer_(new uint8_t[frame_size_]),
+ frame_display_count_(frame_repeat_count),
+ current_display_count_(0) {
assert(width > 0);
assert(height > 0);
- frame_size_ = CalcBufferSize(
- kI420, static_cast<int>(width_), static_cast<int>(height_));
- frame_buffer_ = new uint8_t[frame_size_];
+ ReadNextFrame();
}
virtual ~YuvFileGenerator() {
- fclose(file_);
- delete[] frame_buffer_;
+ for (FILE* file : files_)
+ fclose(file);
}
virtual I420VideoFrame* NextFrame() OVERRIDE {
- size_t count = fread(frame_buffer_, 1, frame_size_, file_);
- if (count < frame_size_) {
- rewind(file_);
- return NextFrame();
+ if (frame_display_count_ > 0) {
+ if (current_display_count_ < frame_display_count_) {
+ ++current_display_count_;
+ } else {
+ ReadNextFrame();
+ current_display_count_ = 0;
+ }
}
- frame_.CreateEmptyFrame(static_cast<int>(width_),
- static_cast<int>(height_),
- static_cast<int>(width_),
- static_cast<int>((width_ + 1) / 2),
- static_cast<int>((width_ + 1) / 2));
+ current_frame_.CopyFrame(last_read_frame_);
+ return ¤t_frame_;
+ }
- ConvertToI420(kI420,
- frame_buffer_,
- 0,
- 0,
- static_cast<int>(width_),
- static_cast<int>(height_),
- 0,
- kRotateNone,
- &frame_);
- return &frame_;
+ void ReadNextFrame() {
+ size_t bytes_read =
+ fread(frame_buffer_.get(), 1, frame_size_, files_[file_index_]);
+ if (bytes_read < frame_size_) {
+ // No more frames to read in this file, rewind and move to next file.
+ rewind(files_[file_index_]);
+ file_index_ = (file_index_ + 1) % files_.size();
+ bytes_read = fread(frame_buffer_.get(), 1, frame_size_,
+ files_[file_index_]);
+ assert(bytes_read >= frame_size_);
+ }
+
+ last_read_frame_.CreateEmptyFrame(
+ static_cast<int>(width_), static_cast<int>(height_),
+ static_cast<int>(width_), static_cast<int>((width_ + 1) / 2),
+ static_cast<int>((width_ + 1) / 2));
+
+ ConvertToI420(kI420, frame_buffer_.get(), 0, 0, static_cast<int>(width_),
+ static_cast<int>(height_), 0, kRotateNone, &last_read_frame_);
}
private:
- FILE* file_;
- size_t width_;
- size_t height_;
- size_t frame_size_;
- uint8_t* frame_buffer_;
- I420VideoFrame frame_;
+ size_t file_index_;
+ const std::vector<FILE*> files_;
+ const size_t width_;
+ const size_t height_;
+ const size_t frame_size_;
+ const scoped_ptr<uint8_t[]> frame_buffer_;
+ const int frame_display_count_;
+ int current_display_count_;
+ I420VideoFrame current_frame_;
+ I420VideoFrame last_read_frame_;
};
} // namespace
-FrameGenerator* FrameGenerator::Create(size_t width, size_t height) {
+FrameGenerator* FrameGenerator::CreateChromaGenerator(size_t width,
+ size_t height) {
return new ChromaGenerator(width, height);
}
-FrameGenerator* FrameGenerator::CreateFromYuvFile(const char* file,
- size_t width,
- size_t height) {
- FILE* file_handle = fopen(file, "rb");
- assert(file_handle);
- return new YuvFileGenerator(file_handle, width, height);
+FrameGenerator* FrameGenerator::CreateFromYuvFile(
+ std::vector<std::string> filenames,
+ size_t width,
+ size_t height,
+ int frame_repeat_count) {
+ assert(!filenames.empty());
+ std::vector<FILE*> files;
+ for (const std::string& filename : filenames) {
+ FILE* file = fopen(filename.c_str(), "rb");
+ DCHECK(file != nullptr);
+ files.push_back(file);
+ }
+
+ return new YuvFileGenerator(files, width, height, frame_repeat_count);
}
} // namespace test
diff --git a/webrtc/test/frame_generator.h b/webrtc/test/frame_generator.h
index fe10612..4598de8 100644
--- a/webrtc/test/frame_generator.h
+++ b/webrtc/test/frame_generator.h
@@ -10,6 +10,9 @@
#ifndef WEBRTC_COMMON_VIDEO_TEST_FRAME_GENERATOR_H_
#define WEBRTC_COMMON_VIDEO_TEST_FRAME_GENERATOR_H_
+#include <string>
+#include <vector>
+
#include "webrtc/common_video/interface/i420_video_frame.h"
#include "webrtc/typedefs.h"
@@ -24,10 +27,17 @@
// Returns video frame that remains valid until next call.
virtual I420VideoFrame* NextFrame() = 0;
- static FrameGenerator* Create(size_t width, size_t height);
- static FrameGenerator* CreateFromYuvFile(const char* file,
+ // Creates a test frame generator that creates fully saturated frames with
+ // varying U, V values over time.
+ static FrameGenerator* CreateChromaGenerator(size_t width, size_t height);
+
+ // Creates a frame generator that repeatedly plays a set of yuv files.
+ // The frame_repeat_count determines how many times each frame is shown,
+ // with 0 = show the first frame indefinitely, 1 = show each frame once, etc.
+ static FrameGenerator* CreateFromYuvFile(std::vector<std::string> files,
size_t width,
- size_t height);
+ size_t height,
+ int frame_repeat_count);
};
} // namespace test
} // namespace webrtc
diff --git a/webrtc/test/frame_generator_capturer.cc b/webrtc/test/frame_generator_capturer.cc
index d1c17c7..721c29a 100644
--- a/webrtc/test/frame_generator_capturer.cc
+++ b/webrtc/test/frame_generator_capturer.cc
@@ -28,7 +28,8 @@
int target_fps,
Clock* clock) {
FrameGeneratorCapturer* capturer = new FrameGeneratorCapturer(
- clock, input, FrameGenerator::Create(width, height), target_fps);
+ clock, input, FrameGenerator::CreateChromaGenerator(width, height),
+ target_fps);
if (!capturer->Init()) {
delete capturer;
return NULL;
@@ -39,15 +40,15 @@
FrameGeneratorCapturer* FrameGeneratorCapturer::CreateFromYuvFile(
VideoSendStreamInput* input,
- const char* file_name,
+ const std::string& file_name,
size_t width,
size_t height,
int target_fps,
Clock* clock) {
FrameGeneratorCapturer* capturer = new FrameGeneratorCapturer(
- clock,
- input,
- FrameGenerator::CreateFromYuvFile(file_name, width, height),
+ clock, input,
+ FrameGenerator::CreateFromYuvFile(std::vector<std::string>(1, file_name),
+ width, height, 1),
target_fps);
if (!capturer->Init()) {
delete capturer;
diff --git a/webrtc/test/frame_generator_capturer.h b/webrtc/test/frame_generator_capturer.h
index ee3f0e0..de2874e 100644
--- a/webrtc/test/frame_generator_capturer.h
+++ b/webrtc/test/frame_generator_capturer.h
@@ -10,6 +10,8 @@
#ifndef WEBRTC_VIDEO_ENGINE_TEST_COMMON_FRAME_GENERATOR_CAPTURER_H_
#define WEBRTC_VIDEO_ENGINE_TEST_COMMON_FRAME_GENERATOR_CAPTURER_H_
+#include <string>
+
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
#include "webrtc/test/video_capturer.h"
#include "webrtc/typedefs.h"
@@ -33,7 +35,7 @@
Clock* clock);
static FrameGeneratorCapturer* CreateFromYuvFile(VideoSendStreamInput* input,
- const char* file_name,
+ const std::string& file_name,
size_t width,
size_t height,
int target_fps,
@@ -45,12 +47,13 @@
int64_t first_frame_capture_time() const { return first_frame_capture_time_; }
- private:
FrameGeneratorCapturer(Clock* clock,
VideoSendStreamInput* input,
FrameGenerator* frame_generator,
int target_fps);
bool Init();
+
+ private:
void InsertFrame();
static bool Run(void* obj);