This class adds a convenience method that allows *sending* a task to the queue (as opposed to posting). Sending is essentially Post+Wait, a pattern that we don't want to encourage use of in production code, but is convenient to have from a testing perspective and there are already several places in the source code where we use it. Change-Id: I6efd1b2257e6c641294bb6e4eb53b0021d9553ca Bug: webrtc:8848 Reviewed-on: https://webrtc-review.googlesource.com/50441 Reviewed-by: Magnus Jedvert <magjed@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#22022}
159 lines
4.8 KiB
C++
159 lines
4.8 KiB
C++
/*
|
|
* Copyright (c) 2018 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 "media/base/fakevideocapturer.h"
|
|
|
|
#include "rtc_base/arraysize.h"
|
|
|
|
namespace cricket {
|
|
|
|
FakeVideoCapturer::FakeVideoCapturer(bool is_screencast)
|
|
: running_(false),
|
|
is_screencast_(is_screencast),
|
|
rotation_(webrtc::kVideoRotation_0) {
|
|
// Default supported formats. Use ResetSupportedFormats to over write.
|
|
using cricket::VideoFormat;
|
|
static const VideoFormat formats[] = {
|
|
{1280, 720, VideoFormat::FpsToInterval(30), cricket::FOURCC_I420},
|
|
{640, 480, VideoFormat::FpsToInterval(30), cricket::FOURCC_I420},
|
|
{320, 240, VideoFormat::FpsToInterval(30), cricket::FOURCC_I420},
|
|
{160, 120, VideoFormat::FpsToInterval(30), cricket::FOURCC_I420},
|
|
{1280, 720, VideoFormat::FpsToInterval(60), cricket::FOURCC_I420},
|
|
};
|
|
ResetSupportedFormats({&formats[0], &formats[arraysize(formats)]});
|
|
}
|
|
|
|
FakeVideoCapturer::FakeVideoCapturer() : FakeVideoCapturer(false) {}
|
|
|
|
FakeVideoCapturer::~FakeVideoCapturer() {
|
|
SignalDestroyed(this);
|
|
}
|
|
|
|
void FakeVideoCapturer::ResetSupportedFormats(
|
|
const std::vector<cricket::VideoFormat>& formats) {
|
|
SetSupportedFormats(formats);
|
|
}
|
|
|
|
bool FakeVideoCapturer::CaptureFrame() {
|
|
if (!GetCaptureFormat()) {
|
|
return false;
|
|
}
|
|
RTC_CHECK_EQ(GetCaptureFormat()->fourcc, FOURCC_I420);
|
|
return CaptureFrame(frame_source_->GetFrame());
|
|
}
|
|
|
|
bool FakeVideoCapturer::CaptureCustomFrame(int width, int height) {
|
|
// Default to 30fps.
|
|
// TODO(nisse): Would anything break if we always stick to
|
|
// the configure frame interval?
|
|
return CaptureFrame(
|
|
frame_source_->GetFrame(width, height, rtc::kNumMicrosecsPerSec / 30));
|
|
}
|
|
|
|
bool FakeVideoCapturer::CaptureFrame(const webrtc::VideoFrame& frame) {
|
|
if (!running_) {
|
|
return false;
|
|
}
|
|
|
|
int adapted_width;
|
|
int adapted_height;
|
|
int crop_width;
|
|
int crop_height;
|
|
int crop_x;
|
|
int crop_y;
|
|
|
|
// TODO(nisse): It's a bit silly to have this logic in a fake
|
|
// class. Child classes of VideoCapturer are expected to call
|
|
// AdaptFrame, and the test case
|
|
// VideoCapturerTest.SinkWantsMaxPixelAndMaxPixelCountStepUp
|
|
// depends on this.
|
|
if (AdaptFrame(frame.width(), frame.height(), frame.timestamp_us(),
|
|
frame.timestamp_us(), &adapted_width, &adapted_height,
|
|
&crop_width, &crop_height, &crop_x, &crop_y, nullptr)) {
|
|
rtc::scoped_refptr<webrtc::I420Buffer> buffer(
|
|
webrtc::I420Buffer::Create(adapted_width, adapted_height));
|
|
buffer->InitializeData();
|
|
|
|
OnFrame(webrtc::VideoFrame(buffer, frame.rotation(), frame.timestamp_us()),
|
|
frame.width(), frame.height());
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
cricket::CaptureState FakeVideoCapturer::Start(
|
|
const cricket::VideoFormat& format) {
|
|
SetCaptureFormat(&format);
|
|
running_ = true;
|
|
SetCaptureState(cricket::CS_RUNNING);
|
|
frame_source_ = rtc::MakeUnique<FakeFrameSource>(
|
|
format.width, format.height,
|
|
format.interval / rtc::kNumNanosecsPerMicrosec);
|
|
frame_source_->SetRotation(rotation_);
|
|
return cricket::CS_RUNNING;
|
|
}
|
|
|
|
void FakeVideoCapturer::Stop() {
|
|
running_ = false;
|
|
SetCaptureFormat(NULL);
|
|
SetCaptureState(cricket::CS_STOPPED);
|
|
}
|
|
|
|
bool FakeVideoCapturer::IsRunning() {
|
|
return running_;
|
|
}
|
|
|
|
bool FakeVideoCapturer::IsScreencast() const {
|
|
return is_screencast_;
|
|
}
|
|
|
|
bool FakeVideoCapturer::GetPreferredFourccs(std::vector<uint32_t>* fourccs) {
|
|
fourccs->push_back(cricket::FOURCC_I420);
|
|
fourccs->push_back(cricket::FOURCC_MJPG);
|
|
return true;
|
|
}
|
|
|
|
void FakeVideoCapturer::SetRotation(webrtc::VideoRotation rotation) {
|
|
rotation_ = rotation;
|
|
if (frame_source_)
|
|
frame_source_->SetRotation(rotation_);
|
|
}
|
|
|
|
webrtc::VideoRotation FakeVideoCapturer::GetRotation() {
|
|
return rotation_;
|
|
}
|
|
|
|
FakeVideoCapturerWithTaskQueue::FakeVideoCapturerWithTaskQueue(
|
|
bool is_screencast)
|
|
: FakeVideoCapturer(is_screencast) {}
|
|
|
|
FakeVideoCapturerWithTaskQueue::FakeVideoCapturerWithTaskQueue() {}
|
|
|
|
bool FakeVideoCapturerWithTaskQueue::CaptureFrame() {
|
|
if (task_queue_.IsCurrent())
|
|
return FakeVideoCapturer::CaptureFrame();
|
|
bool ret = false;
|
|
task_queue_.SendTask(
|
|
[this, &ret]() { ret = FakeVideoCapturer::CaptureFrame(); });
|
|
return ret;
|
|
}
|
|
|
|
bool FakeVideoCapturerWithTaskQueue::CaptureCustomFrame(int width, int height) {
|
|
if (task_queue_.IsCurrent())
|
|
return FakeVideoCapturer::CaptureCustomFrame(width, height);
|
|
bool ret = false;
|
|
task_queue_.SendTask([this, &ret, width, height]() {
|
|
ret = FakeVideoCapturer::CaptureCustomFrame(width, height);
|
|
});
|
|
return ret;
|
|
}
|
|
|
|
} // namespace cricket
|