forked from maitrungduc1410/webrtc
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
xianglai
committed
Oct 21, 2020
1 parent
dbdfc7d
commit 4965451
Showing
6 changed files
with
389 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
#include "examples/video_capture/vcm_capturer_test.h" | ||
|
||
#include "modules/video_capture/video_capture_factory.h" | ||
#include "rtc_base/logging.h" | ||
|
||
namespace webrtc_demo { | ||
|
||
VcmCapturerTest::VcmCapturerTest() : vcm_(nullptr) {} | ||
|
||
VcmCapturerTest::~VcmCapturerTest() { | ||
Destroy(); | ||
} | ||
|
||
bool VcmCapturerTest::Init(size_t width, | ||
size_t height, | ||
size_t target_fps, | ||
size_t capture_device_index) { | ||
std::unique_ptr<webrtc::VideoCaptureModule::DeviceInfo> device_info( | ||
webrtc::VideoCaptureFactory::CreateDeviceInfo()); | ||
|
||
char device_name[256]; | ||
char unique_name[256]; | ||
|
||
if (device_info->GetDeviceName(static_cast<uint32_t>(capture_device_index), | ||
device_name, sizeof(device_name), unique_name, | ||
sizeof(unique_name)) != 0) { | ||
Destroy(); | ||
return false; | ||
} | ||
|
||
vcm_ = webrtc::VideoCaptureFactory::Create(unique_name); | ||
if (!vcm_) { | ||
return false; | ||
} | ||
vcm_->RegisterCaptureDataCallback(this); | ||
|
||
device_info->GetCapability(vcm_->CurrentDeviceName(), 0, capability_); | ||
capability_.width = static_cast<int32_t>(width); | ||
capability_.height = static_cast<int32_t>(height); | ||
capability_.maxFPS = static_cast<int32_t>(target_fps); | ||
capability_.videoType = webrtc::VideoType::kI420; | ||
|
||
if (vcm_->StartCapture(capability_) != 0) { | ||
Destroy(); | ||
return false; | ||
} | ||
|
||
RTC_CHECK(vcm_->CaptureStarted()); | ||
return true; | ||
} | ||
|
||
VcmCapturerTest* VcmCapturerTest::Create(size_t width, | ||
size_t height, | ||
size_t target_fps, | ||
size_t capture_device_index) { | ||
std::unique_ptr<VcmCapturerTest> vcm_capturer(new VcmCapturerTest()); | ||
if (!vcm_capturer->Init(width, height, target_fps, capture_device_index)) { | ||
RTC_LOG(LS_WARNING) << "Failed to create VcmCapturer(w = " << width | ||
<< ", h = " << height << ", fps = " << target_fps | ||
<< ")"; | ||
return nullptr; | ||
} | ||
return vcm_capturer.release(); | ||
} | ||
|
||
void VcmCapturerTest::Destroy() { | ||
if (!vcm_) | ||
return; | ||
|
||
vcm_->StopCapture(); | ||
vcm_->DeRegisterCaptureDataCallback(); | ||
// Release reference to VCM. | ||
vcm_ = nullptr; | ||
} | ||
|
||
void VcmCapturerTest::OnFrame(const webrtc::VideoFrame& frame) { | ||
static auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>( | ||
std::chrono::system_clock::now().time_since_epoch()).count(); | ||
static size_t cnt = 0; | ||
|
||
RTC_LOG(LS_INFO) << "OnFrame"; | ||
VideoCapturerTest::OnFrame(frame); | ||
|
||
cnt++; | ||
auto timestamp_curr = std::chrono::duration_cast<std::chrono::milliseconds>( | ||
std::chrono::system_clock::now().time_since_epoch()).count(); | ||
if(timestamp_curr - timestamp > 1000) { | ||
RTC_LOG(LS_INFO) << "FPS: " << cnt; | ||
cnt = 0; | ||
timestamp = timestamp_curr; | ||
} | ||
} | ||
|
||
} // namespace webrtc_demo |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#ifndef EXAMPLES_VIDEO_CAPTURE_VCM_CAPTURER_TEST_H_ | ||
#define EXAMPLES_VIDEO_CAPTURE_VCM_CAPTURER_TEST_H_ | ||
|
||
#include <memory> | ||
|
||
#include "modules/video_capture/video_capture.h" | ||
#include "examples/video_capture/video_capturer_test.h" | ||
|
||
namespace webrtc_demo { | ||
|
||
class VcmCapturerTest : public VideoCapturerTest, | ||
public rtc::VideoSinkInterface<webrtc::VideoFrame> { | ||
public: | ||
static VcmCapturerTest* Create(size_t width, | ||
size_t height, | ||
size_t target_fps, | ||
size_t capture_device_index); | ||
|
||
virtual ~VcmCapturerTest(); | ||
|
||
void OnFrame(const webrtc::VideoFrame& frame) override; | ||
|
||
private: | ||
VcmCapturerTest(); | ||
|
||
bool Init(size_t width, | ||
size_t height, | ||
size_t target_fps, | ||
size_t capture_device_index); | ||
|
||
void Destroy(); | ||
|
||
rtc::scoped_refptr<webrtc::VideoCaptureModule> vcm_; | ||
webrtc::VideoCaptureCapability capability_; | ||
}; | ||
|
||
} // namespace webrtc_demo | ||
|
||
#endif // EXAMPLES_VIDEO_CAPTURE_VCM_CAPTURER_TEST_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#include "modules/video_capture/video_capture_factory.h" | ||
#include "rtc_base/logging.h" | ||
#include "examples/video_capture/vcm_capturer_test.h" | ||
#include "test/video_renderer.h" | ||
|
||
#include <iostream> | ||
#include <thread> | ||
|
||
int main() { | ||
const size_t kWidth = 1920; | ||
const size_t kHeight = 1080; | ||
const size_t kFps = 30; | ||
|
||
std::unique_ptr<webrtc_demo::VcmCapturerTest> capturer; | ||
std::unique_ptr<webrtc::VideoCaptureModule::DeviceInfo> info( | ||
webrtc::VideoCaptureFactory::CreateDeviceInfo()); | ||
std::unique_ptr<webrtc::test::VideoRenderer> renderer; | ||
|
||
if (!info) { | ||
RTC_LOG(LERROR) << "CreateDeviceInfo failed"; | ||
return -1; | ||
} | ||
int num_devices = info->NumberOfDevices(); | ||
for (int i = 0; i < num_devices; ++i) { | ||
capturer.reset( | ||
webrtc_demo::VcmCapturerTest::Create(kWidth, kHeight, kFps, i)); | ||
if (capturer) { | ||
break; | ||
} | ||
} | ||
|
||
if (!capturer) { | ||
RTC_LOG(LERROR) << "Cannot found available video device"; | ||
return -1; | ||
} | ||
|
||
renderer.reset(webrtc::test::VideoRenderer::Create("Camera", kWidth, kHeight)); | ||
capturer->AddOrUpdateSink(renderer.get(), rtc::VideoSinkWants()); | ||
|
||
std::this_thread::sleep_for(std::chrono::seconds(30)); | ||
capturer->RemoveSink(renderer.get()); | ||
|
||
RTC_LOG(WARNING) << "Demo exit"; | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
#include "examples/video_capture/video_capturer_test.h" | ||
|
||
#include "api/video/i420_buffer.h" | ||
#include "api/video/video_rotation.h" | ||
#include "rtc_base/logging.h" | ||
|
||
namespace webrtc_demo { | ||
|
||
VideoCapturerTest::~VideoCapturerTest() = default; | ||
|
||
void VideoCapturerTest::OnFrame(const webrtc::VideoFrame& original_frame) { | ||
int cropped_width = 0; | ||
int cropped_height = 0; | ||
int out_width = 0; | ||
int out_height = 0; | ||
|
||
webrtc::VideoFrame frame = MaybePreprocess(original_frame); | ||
|
||
if (!video_adapter_.AdaptFrameResolution( | ||
frame.width(), frame.height(), frame.timestamp_us() * 1000, | ||
&cropped_width, &cropped_height, &out_width, &out_height)) { | ||
// Drop frame in order to respect frame rate constraint. | ||
return; | ||
} | ||
|
||
if (out_height != frame.height() || out_width != frame.width()) { | ||
// Video adapter has requested a down-scale. Allocate a new buffer and | ||
// return scaled version. | ||
// For simplicity, only scale here without cropping. | ||
rtc::scoped_refptr<webrtc::I420Buffer> scaled_buffer = | ||
webrtc::I420Buffer::Create(out_width, out_height); | ||
scaled_buffer->ScaleFrom(*frame.video_frame_buffer()->ToI420()); | ||
webrtc::VideoFrame::Builder new_frame_builder = | ||
webrtc::VideoFrame::Builder() | ||
.set_video_frame_buffer(scaled_buffer) | ||
.set_rotation(webrtc::kVideoRotation_0) | ||
.set_timestamp_us(frame.timestamp_us()) | ||
.set_id(frame.id()); | ||
; | ||
if (frame.has_update_rect()) { | ||
webrtc::VideoFrame::UpdateRect new_rect = | ||
frame.update_rect().ScaleWithFrame(frame.width(), frame.height(), 0, | ||
0, frame.width(), frame.height(), | ||
out_width, out_height); | ||
new_frame_builder.set_update_rect(new_rect); | ||
} | ||
broadcaster_.OnFrame(new_frame_builder.build()); | ||
} else { | ||
// No adaptations needed, just return the frame as is. | ||
broadcaster_.OnFrame(frame); | ||
} | ||
} | ||
|
||
rtc::VideoSinkWants VideoCapturerTest::GetSinkWants() { | ||
return broadcaster_.wants(); | ||
} | ||
|
||
void VideoCapturerTest::AddOrUpdateSink( | ||
rtc::VideoSinkInterface<webrtc::VideoFrame>* sink, | ||
const rtc::VideoSinkWants& wants) { | ||
broadcaster_.AddOrUpdateSink(sink, wants); | ||
UpdateVideoAdapter(); | ||
} | ||
|
||
void VideoCapturerTest::RemoveSink( | ||
rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) { | ||
broadcaster_.RemoveSink(sink); | ||
UpdateVideoAdapter(); | ||
} | ||
|
||
void VideoCapturerTest::UpdateVideoAdapter() { | ||
video_adapter_.OnSinkWants(broadcaster_.wants()); | ||
} | ||
|
||
webrtc::VideoFrame VideoCapturerTest::MaybePreprocess( | ||
const webrtc::VideoFrame& frame) { | ||
std::lock_guard<std::mutex> lock(mutex_); | ||
if (preprocessor_ != nullptr) { | ||
return preprocessor_->Preprocess(frame); | ||
} else { | ||
return frame; | ||
} | ||
} | ||
} // namespace webrtc_demo |
Oops, something went wrong.