Refactor frame generation code so it can be used by multiple modules.
R=pbos@webrtc.org, stefan@webrtc.org, pbos, stefan
BUG=
Review URL: https://webrtc-codereview.appspot.com/2240004
git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@4791 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/video_engine/test/common/file_capturer.cc b/video_engine/test/common/file_capturer.cc
deleted file mode 100644
index fa04caa..0000000
--- a/video_engine/test/common/file_capturer.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "webrtc/video_engine/test/common/file_capturer.h"
-
-#include <stdio.h>
-
-#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
-
-namespace webrtc {
-namespace test {
-
-YuvFileFrameGenerator* YuvFileFrameGenerator::Create(const char* file,
- size_t width,
- size_t height,
- Clock* clock) {
- FILE* file_handle = fopen(file, "r");
- if (file_handle == NULL) {
- return NULL;
- }
- return new YuvFileFrameGenerator(file_handle, width, height, clock);
-}
-
-YuvFileFrameGenerator::YuvFileFrameGenerator(FILE* file,
- size_t width,
- size_t height,
- Clock* clock)
- : FrameGenerator(width, height, clock), file_(file) {
- frame_size_ = CalcBufferSize(
- kI420, static_cast<int>(width_), static_cast<int>(height_));
- frame_buffer_ = new uint8_t[frame_size_];
-}
-
-YuvFileFrameGenerator::~YuvFileFrameGenerator() {
- fclose(file_);
- delete[] frame_buffer_;
-}
-
-void YuvFileFrameGenerator::GenerateNextFrame() {
- size_t count = fread(frame_buffer_, 1, frame_size_, file_);
- if (count < frame_size_) {
- rewind(file_);
- return;
- }
-
- ConvertToI420(kI420,
- frame_buffer_,
- 0,
- 0,
- static_cast<int>(width_),
- static_cast<int>(height_),
- 0,
- kRotateNone,
- &frame_);
-}
-} // namespace test
-} // namespace webrtc
diff --git a/video_engine/test/common/file_capturer.h b/video_engine/test/common/file_capturer.h
deleted file mode 100644
index 2ec9f86..0000000
--- a/video_engine/test/common/file_capturer.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-#ifndef WEBRTC_VIDEO_ENGINE_TEST_COMMON_FILE_CAPTURER_H_
-#define WEBRTC_VIDEO_ENGINE_TEST_COMMON_FILE_CAPTURER_H_
-
-#include <stdio.h>
-
-#include "webrtc/typedefs.h"
-#include "webrtc/video_engine/test/common/frame_generator.h"
-#include "webrtc/video_engine/test/common/video_capturer.h"
-
-namespace webrtc {
-
-class Clock;
-
-class VideoSendStreamInput;
-
-namespace test {
-
-class YuvFileFrameGenerator : public FrameGenerator {
- public:
- static YuvFileFrameGenerator* Create(const char* file_name,
- size_t width,
- size_t height,
- Clock* clock);
- virtual ~YuvFileFrameGenerator();
-
- private:
- YuvFileFrameGenerator(FILE* file, size_t width, size_t height, Clock* clock);
- virtual void GenerateNextFrame() OVERRIDE;
-
- FILE* file_;
- size_t frame_size_;
- uint8_t* frame_buffer_;
-};
-} // namespace test
-} // namespace webrtc
-
-#endif // WEBRTC_VIDEO_ENGINE_TEST_COMMON_VIDEO_CAPTURER_H_
diff --git a/video_engine/test/common/frame_generator.cc b/video_engine/test/common/frame_generator.cc
deleted file mode 100644
index 9f4fae1..0000000
--- a/video_engine/test/common/frame_generator.cc
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "webrtc/video_engine/test/common/frame_generator.h"
-
-#include <math.h>
-#include <string.h>
-
-#include "webrtc/system_wrappers/interface/clock.h"
-#include "webrtc/video_engine/new_include/video_send_stream.h"
-
-namespace webrtc {
-namespace test {
-
-FrameGenerator* FrameGenerator::Create(size_t width,
- size_t height,
- Clock* clock) {
- return new ChromaFrameGenerator(width, height, clock);
-}
-
-void FrameGenerator::InsertFrame(VideoSendStreamInput* input) {
- int64_t time_before = clock_->CurrentNtpInMilliseconds();
- frame_.set_render_time_ms(time_before);
-
- GenerateNextFrame();
-
- int64_t time_after = clock_->CurrentNtpInMilliseconds();
- input->PutFrame(frame_, static_cast<uint32_t>(time_after - time_before));
-}
-
-FrameGenerator::FrameGenerator(size_t width, size_t height, Clock* clock)
- : width_(width), height_(height), clock_(clock) {
- // Generate frame by constructor arguments
- assert(width > 0);
- assert(height > 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));
-}
-
-BlackFrameGenerator::BlackFrameGenerator(size_t width,
- size_t height,
- Clock* clock)
- : FrameGenerator(width, height, clock) {
- memset(frame_.buffer(kYPlane), 0x00, frame_.allocated_size(kYPlane));
- memset(frame_.buffer(kUPlane), 0x80, frame_.allocated_size(kUPlane));
- memset(frame_.buffer(kVPlane), 0x80, frame_.allocated_size(kVPlane));
-}
-
-void BlackFrameGenerator::GenerateNextFrame() {}
-
-WhiteFrameGenerator::WhiteFrameGenerator(size_t width,
- size_t height,
- Clock* clock)
- : FrameGenerator(width, height, clock) {
- memset(frame_.buffer(kYPlane), 0xFF, frame_.allocated_size(kYPlane));
- memset(frame_.buffer(kUPlane), 0x80, frame_.allocated_size(kUPlane));
- memset(frame_.buffer(kVPlane), 0x80, frame_.allocated_size(kVPlane));
-}
-
-void WhiteFrameGenerator::GenerateNextFrame() {}
-
-ChromaFrameGenerator::ChromaFrameGenerator(size_t width,
- size_t height,
- Clock* clock)
- : FrameGenerator(width, height, clock) {
- memset(frame_.buffer(kYPlane), 0x80, frame_.allocated_size(kYPlane));
-}
-
-void ChromaFrameGenerator::GenerateNextFrame() {
- double angle = static_cast<double>(frame_.render_time_ms()) / 1000.0;
- uint8_t u = fabs(sin(angle)) * 0xFF;
- uint8_t v = fabs(cos(angle)) * 0xFF;
-
- memset(frame_.buffer(kUPlane), u, frame_.allocated_size(kUPlane));
- memset(frame_.buffer(kVPlane), v, frame_.allocated_size(kVPlane));
-}
-} // test
-} // webrtc
diff --git a/video_engine/test/common/frame_generator.h b/video_engine/test/common/frame_generator.h
deleted file mode 100644
index c378458..0000000
--- a/video_engine/test/common/frame_generator.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-#ifndef WEBRTC_VIDEO_ENGINE_TEST_COMMON_FRAME_GENERATOR_H_
-#define WEBRTC_VIDEO_ENGINE_TEST_COMMON_FRAME_GENERATOR_H_
-
-#include "webrtc/common_video/interface/i420_video_frame.h"
-#include "webrtc/typedefs.h"
-
-namespace webrtc {
-
-class Clock;
-
-class VideoSendStreamInput;
-
-namespace test {
-
-// A set of classes that generate sequences of I420VideoFrames for testing
-// without using the webcam.
-class FrameGenerator {
- public:
- static FrameGenerator* Create(size_t width, size_t height, Clock* clock);
- virtual ~FrameGenerator() {}
-
- void InsertFrame(VideoSendStreamInput* input);
-
- protected:
- FrameGenerator(size_t width, size_t height, Clock* clock);
- virtual void GenerateNextFrame() = 0;
-
- size_t width_, height_;
- I420VideoFrame frame_;
- Clock* clock_;
-};
-
-class BlackFrameGenerator : public FrameGenerator {
- public:
- BlackFrameGenerator(size_t width, size_t height, Clock* clock);
-
- private:
- virtual void GenerateNextFrame() OVERRIDE;
-};
-
-class WhiteFrameGenerator : public FrameGenerator {
- public:
- WhiteFrameGenerator(size_t width, size_t height, Clock* clock);
-
- private:
- virtual void GenerateNextFrame() OVERRIDE;
-};
-
-class ChromaFrameGenerator : public FrameGenerator {
- public:
- ChromaFrameGenerator(size_t width, size_t height, Clock* clock);
-
- private:
- virtual void GenerateNextFrame() OVERRIDE;
-};
-} // test
-} // webrtc
-
-#endif // WEBRTC_VIDEO_ENGINE_TEST_COMMON_FRAME_GENERATOR_H_
diff --git a/video_engine/test/common/frame_generator_capturer.cc b/video_engine/test/common/frame_generator_capturer.cc
index 0c2a15c..96a7af8 100644
--- a/video_engine/test/common/frame_generator_capturer.cc
+++ b/video_engine/test/common/frame_generator_capturer.cc
@@ -10,22 +10,58 @@
#include "webrtc/video_engine/test/common/frame_generator_capturer.h"
+#include <math.h>
+#include <string.h>
+
+#include "webrtc/common_video/test/frame_generator.h"
+#include "webrtc/system_wrappers/interface/clock.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/event_wrapper.h"
#include "webrtc/system_wrappers/interface/sleep.h"
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
-#include "webrtc/video_engine/test/common/frame_generator.h"
+#include "webrtc/video_engine/new_include/video_send_stream.h"
namespace webrtc {
namespace test {
+namespace {
+class ChromaGenerator : public FrameGenerator {
+ public:
+ ChromaGenerator(size_t width, size_t height, Clock* clock) : clock_(clock) {
+ assert(width > 0);
+ assert(height > 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));
+ memset(frame_.buffer(kYPlane), 0x80, frame_.allocated_size(kYPlane));
+ }
+
+ virtual I420VideoFrame& NextFrame() OVERRIDE {
+ double angle =
+ static_cast<double>(clock_->CurrentNtpInMilliseconds()) / 1000.0;
+ uint8_t u = fabs(sin(angle)) * 0xFF;
+ uint8_t v = fabs(cos(angle)) * 0xFF;
+
+ memset(frame_.buffer(kUPlane), u, frame_.allocated_size(kUPlane));
+ memset(frame_.buffer(kVPlane), v, frame_.allocated_size(kVPlane));
+ return frame_;
+ }
+
+ private:
+ Clock* clock_;
+ I420VideoFrame frame_;
+};
+} // namespace
FrameGeneratorCapturer* FrameGeneratorCapturer::Create(
VideoSendStreamInput* input,
- FrameGenerator* frame_generator,
- int target_fps) {
- FrameGeneratorCapturer* capturer =
- new FrameGeneratorCapturer(input, frame_generator, target_fps);
-
+ size_t width,
+ size_t height,
+ int target_fps,
+ Clock* clock) {
+ FrameGeneratorCapturer* capturer = new FrameGeneratorCapturer(
+ clock, input, new ChromaGenerator(width, height, clock), target_fps);
if (!capturer->Init()) {
delete capturer;
return NULL;
@@ -34,11 +70,32 @@
return capturer;
}
-FrameGeneratorCapturer::FrameGeneratorCapturer(
+FrameGeneratorCapturer* FrameGeneratorCapturer::CreateFromYuvFile(
VideoSendStreamInput* input,
- FrameGenerator* frame_generator,
- int target_fps)
+ const char* 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),
+ target_fps);
+ if (!capturer->Init()) {
+ delete capturer;
+ return NULL;
+ }
+
+ return capturer;
+}
+
+FrameGeneratorCapturer::FrameGeneratorCapturer(Clock* clock,
+ VideoSendStreamInput* input,
+ FrameGenerator* frame_generator,
+ int target_fps)
: VideoCapturer(input),
+ clock_(clock),
sending_(false),
tick_(EventWrapper::Create()),
lock_(CriticalSectionWrapper::CreateCriticalSection()),
@@ -82,8 +139,13 @@
void FrameGeneratorCapturer::InsertFrame() {
{
CriticalSectionScoped cs(lock_.get());
- if (sending_)
- frame_generator_->InsertFrame(input_);
+ if (sending_) {
+ int64_t time_before = clock_->CurrentNtpInMilliseconds();
+ I420VideoFrame& frame = frame_generator_->NextFrame();
+ frame.set_render_time_ms(time_before);
+ int64_t time_after = clock_->CurrentNtpInMilliseconds();
+ input_->PutFrame(frame, static_cast<uint32_t>(time_after - time_before));
+ }
}
tick_->Wait(WEBRTC_EVENT_INFINITE);
}
diff --git a/video_engine/test/common/frame_generator_capturer.h b/video_engine/test/common/frame_generator_capturer.h
index df84e16..ad7fdeb 100644
--- a/video_engine/test/common/frame_generator_capturer.h
+++ b/video_engine/test/common/frame_generator_capturer.h
@@ -26,24 +26,33 @@
class FrameGeneratorCapturer : public VideoCapturer {
public:
- // The FrameGeneratorCapturer takes ownership of the FrameGenerator, which
- // will be freed when the FrameGeneratorCapturer is deleted.
static FrameGeneratorCapturer* Create(VideoSendStreamInput* input,
- FrameGenerator* frame_generator,
- int target_fps);
+ size_t width,
+ size_t height,
+ int target_fps,
+ Clock* clock);
+
+ static FrameGeneratorCapturer* CreateFromYuvFile(VideoSendStreamInput* input,
+ const char* file_name,
+ size_t width,
+ size_t height,
+ int target_fps,
+ Clock* clock);
virtual ~FrameGeneratorCapturer();
virtual void Start() OVERRIDE;
virtual void Stop() OVERRIDE;
private:
- FrameGeneratorCapturer(VideoSendStreamInput* input,
+ FrameGeneratorCapturer(Clock* clock,
+ VideoSendStreamInput* input,
FrameGenerator* frame_generator,
int target_fps);
bool Init();
void InsertFrame();
static bool Run(void* obj);
+ Clock* clock_;
bool sending_;
scoped_ptr<EventWrapper> tick_;
diff --git a/video_engine/test/common/video_capturer.cc b/video_engine/test/common/video_capturer.cc
index 624bb9d..9a1bd0c 100644
--- a/video_engine/test/common/video_capturer.cc
+++ b/video_engine/test/common/video_capturer.cc
@@ -11,8 +11,6 @@
#include "webrtc/video_engine/test/common/video_capturer.h"
#include "webrtc/test/testsupport/fileutils.h"
-#include "webrtc/video_engine/test/common/file_capturer.h"
-#include "webrtc/video_engine/test/common/frame_generator.h"
#include "webrtc/video_engine/test/common/frame_generator_capturer.h"
#include "webrtc/video_engine/test/common/vcm_capturer.h"
@@ -44,8 +42,7 @@
// TODO(pbos): Log a warning that this failed.
FrameGeneratorCapturer* frame_generator_capturer =
- FrameGeneratorCapturer::Create(
- input, FrameGenerator::Create(width, height, clock), fps);
+ FrameGeneratorCapturer::Create(input, width, height, fps, clock);
if (frame_generator_capturer != NULL) {
return frame_generator_capturer;
}
diff --git a/video_engine/test/engine_tests.cc b/video_engine/test/engine_tests.cc
index bd3c6fe..f404e02 100644
--- a/video_engine/test/engine_tests.cc
+++ b/video_engine/test/engine_tests.cc
@@ -22,7 +22,6 @@
#include "webrtc/video_engine/test/common/direct_transport.h"
#include "webrtc/video_engine/test/common/fake_decoder.h"
#include "webrtc/video_engine/test/common/fake_encoder.h"
-#include "webrtc/video_engine/test/common/frame_generator.h"
#include "webrtc/video_engine/test/common/frame_generator_capturer.h"
#include "webrtc/video_engine/test/common/generate_ssrcs.h"
#include "webrtc/video_engine/test/common/rtp_rtcp_observer.h"
@@ -84,12 +83,12 @@
}
void CreateFrameGenerator() {
- frame_generator_capturer_.reset(test::FrameGeneratorCapturer::Create(
- send_stream_->Input(),
- test::FrameGenerator::Create(send_config_.codec.width,
- send_config_.codec.height,
- Clock::GetRealTimeClock()),
- 30));
+ frame_generator_capturer_.reset(
+ test::FrameGeneratorCapturer::Create(send_stream_->Input(),
+ send_config_.codec.width,
+ send_config_.codec.height,
+ 30,
+ Clock::GetRealTimeClock()));
}
void StartSending() {
diff --git a/video_engine/test/full_stack.cc b/video_engine/test/full_stack.cc
index 365423f..5f1240f 100644
--- a/video_engine/test/full_stack.cc
+++ b/video_engine/test/full_stack.cc
@@ -25,7 +25,6 @@
#include "webrtc/typedefs.h"
#include "webrtc/video_engine/new_include/call.h"
#include "webrtc/video_engine/test/common/direct_transport.h"
-#include "webrtc/video_engine/test/common/file_capturer.h"
#include "webrtc/video_engine/test/common/frame_generator_capturer.h"
#include "webrtc/video_engine/test/common/generate_ssrcs.h"
#include "webrtc/video_engine/test/common/statistics.h"
@@ -304,17 +303,14 @@
VideoSendStream* send_stream = call->CreateSendStream(send_config);
analyzer.input_ = send_stream->Input();
- Clock* test_clock = Clock::GetRealTimeClock();
-
scoped_ptr<test::FrameGeneratorCapturer> file_capturer(
- test::FrameGeneratorCapturer::Create(
+ test::FrameGeneratorCapturer::CreateFromYuvFile(
&analyzer,
- test::YuvFileFrameGenerator::Create(
- test::ResourcePath(params.clip.name, "yuv").c_str(),
- params.clip.width,
- params.clip.height,
- test_clock),
- params.clip.fps));
+ test::ResourcePath(params.clip.name, "yuv").c_str(),
+ params.clip.width,
+ params.clip.height,
+ params.clip.fps,
+ Clock::GetRealTimeClock()));
VideoReceiveStream::Config receive_config = call->GetDefaultReceiveConfig();
receive_config.rtp.ssrc = send_config.rtp.ssrcs[0];
diff --git a/video_engine/test/rampup_tests.cc b/video_engine/test/rampup_tests.cc
index 8e3e027..f263efa 100644
--- a/video_engine/test/rampup_tests.cc
+++ b/video_engine/test/rampup_tests.cc
@@ -25,7 +25,6 @@
#include "webrtc/video_engine/test/common/direct_transport.h"
#include "webrtc/video_engine/test/common/fake_decoder.h"
#include "webrtc/video_engine/test/common/fake_encoder.h"
-#include "webrtc/video_engine/test/common/frame_generator.h"
#include "webrtc/video_engine/test/common/frame_generator_capturer.h"
#include "webrtc/video_engine/test/common/generate_ssrcs.h"
@@ -168,12 +167,11 @@
call->CreateReceiveStream(receive_config);
scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
- test::FrameGeneratorCapturer::Create(
- send_stream->Input(),
- test::FrameGenerator::Create(send_config.codec.width,
- send_config.codec.height,
- Clock::GetRealTimeClock()),
- 30));
+ test::FrameGeneratorCapturer::Create(send_stream->Input(),
+ send_config.codec.width,
+ send_config.codec.height,
+ 30,
+ Clock::GetRealTimeClock()));
receive_stream->StartReceive();
send_stream->StartSend();
diff --git a/video_engine/test/send_stream_tests.cc b/video_engine/test/send_stream_tests.cc
index 879a3e4..10ad66d 100644
--- a/video_engine/test/send_stream_tests.cc
+++ b/video_engine/test/send_stream_tests.cc
@@ -16,7 +16,6 @@
#include "webrtc/system_wrappers/interface/sleep.h"
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
#include "webrtc/video_engine/test/common/fake_encoder.h"
-#include "webrtc/video_engine/test/common/frame_generator.h"
#include "webrtc/video_engine/test/common/frame_generator_capturer.h"
#include "webrtc/video_engine/test/common/null_transport.h"
#include "webrtc/video_engine/new_include/call.h"
@@ -54,9 +53,7 @@
VideoSendStream* send_stream = call->CreateSendStream(config);
scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
test::FrameGeneratorCapturer::Create(
- send_stream->Input(),
- test::FrameGenerator::Create(320, 240, Clock::GetRealTimeClock()),
- 30));
+ send_stream->Input(), 320, 240, 30, Clock::GetRealTimeClock()));
send_stream->StartSend();
frame_generator_capturer->Start();
diff --git a/video_engine/test/tests.gypi b/video_engine/test/tests.gypi
index 11e26ed..3164ff5 100644
--- a/video_engine/test/tests.gypi
+++ b/video_engine/test/tests.gypi
@@ -18,12 +18,8 @@
'common/fake_decoder.h',
'common/fake_encoder.cc',
'common/fake_encoder.h',
- 'common/file_capturer.cc',
- 'common/file_capturer.h',
'common/flags.cc',
'common/flags.h',
- 'common/frame_generator.cc',
- 'common/frame_generator.h',
'common/frame_generator_capturer.cc',
'common/frame_generator_capturer.h',
'common/generate_ssrcs.cc',
@@ -119,6 +115,7 @@
'<(webrtc_root)/modules/modules.gyp:video_capture_module',
'<(webrtc_root)/test/test.gyp:test_support',
'video_engine_core',
+ '<(webrtc_root)/common_video/common_video.gyp:frame_generator',
],
},
{