1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
/*
* Copyright (c) 2004 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 MEDIA_BASE_FAKEVIDEOCAPTURER_H_
#define MEDIA_BASE_FAKEVIDEOCAPTURER_H_
#include <string.h>
#include <memory>
#include <vector>
#include "api/video/i420_buffer.h"
#include "api/video/video_frame.h"
#include "media/base/videocapturer.h"
#include "media/base/videocommon.h"
#include "rtc_base/timeutils.h"
namespace cricket {
// Fake video capturer that allows the test to manually pump in frames.
class FakeVideoCapturer : public cricket::VideoCapturer {
public:
explicit FakeVideoCapturer(bool is_screencast)
: running_(false),
initial_timestamp_(rtc::TimeNanos()),
next_timestamp_(rtc::kNumNanosecsPerMillisec),
is_screencast_(is_screencast),
rotation_(webrtc::kVideoRotation_0) {
// Default supported formats. Use ResetSupportedFormats to over write.
std::vector<cricket::VideoFormat> formats;
formats.push_back(cricket::VideoFormat(1280, 720,
cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
formats.push_back(cricket::VideoFormat(640, 480,
cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
formats.push_back(cricket::VideoFormat(320, 240,
cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
formats.push_back(cricket::VideoFormat(160, 120,
cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
formats.push_back(cricket::VideoFormat(1280, 720,
cricket::VideoFormat::FpsToInterval(60), cricket::FOURCC_I420));
ResetSupportedFormats(formats);
}
FakeVideoCapturer() : FakeVideoCapturer(false) {}
~FakeVideoCapturer() {
SignalDestroyed(this);
}
void ResetSupportedFormats(const std::vector<cricket::VideoFormat>& formats) {
SetSupportedFormats(formats);
}
bool CaptureFrame() {
if (!GetCaptureFormat()) {
return false;
}
return CaptureCustomFrame(GetCaptureFormat()->width,
GetCaptureFormat()->height,
GetCaptureFormat()->interval,
GetCaptureFormat()->fourcc);
}
bool CaptureCustomFrame(int width, int height, uint32_t fourcc) {
// Default to 30fps.
return CaptureCustomFrame(width, height, rtc::kNumNanosecsPerSec / 30,
fourcc);
}
bool CaptureCustomFrame(int width,
int height,
int64_t timestamp_interval,
uint32_t fourcc) {
if (!running_) {
return false;
}
RTC_CHECK(fourcc == FOURCC_I420);
RTC_CHECK(width > 0);
RTC_CHECK(height > 0);
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(width, height,
next_timestamp_ / rtc::kNumNanosecsPerMicrosec,
next_timestamp_ / rtc::kNumNanosecsPerMicrosec,
&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, rotation_,
next_timestamp_ / rtc::kNumNanosecsPerMicrosec),
width, height);
}
next_timestamp_ += timestamp_interval;
return true;
}
sigslot::signal1<FakeVideoCapturer*> SignalDestroyed;
cricket::CaptureState Start(const cricket::VideoFormat& format) override {
SetCaptureFormat(&format);
running_ = true;
SetCaptureState(cricket::CS_RUNNING);
return cricket::CS_RUNNING;
}
void Stop() override {
running_ = false;
SetCaptureFormat(NULL);
SetCaptureState(cricket::CS_STOPPED);
}
bool IsRunning() override { return running_; }
bool IsScreencast() const override { return is_screencast_; }
bool GetPreferredFourccs(std::vector<uint32_t>* fourccs) override {
fourccs->push_back(cricket::FOURCC_I420);
fourccs->push_back(cricket::FOURCC_MJPG);
return true;
}
void SetRotation(webrtc::VideoRotation rotation) {
rotation_ = rotation;
}
webrtc::VideoRotation GetRotation() { return rotation_; }
private:
bool running_;
int64_t initial_timestamp_;
int64_t next_timestamp_;
const bool is_screencast_;
webrtc::VideoRotation rotation_;
};
} // namespace cricket
#endif // MEDIA_BASE_FAKEVIDEOCAPTURER_H_
|