Refactored vie_autotest_simulcast.cc. This CL on changes the style and renames variables.
BUG= Review URL: https://webrtc-codereview.appspot.com/787008 git-svn-id: http://webrtc.googlecode.com/svn/trunk@2768 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@@ -8,19 +8,19 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream> // NOLINT
|
||||||
|
|
||||||
#include "common_types.h"
|
#include "common_types.h" // NOLINT
|
||||||
#include "tb_external_transport.h"
|
#include "video_engine/include/vie_base.h"
|
||||||
#include "voe_base.h"
|
#include "video_engine/include/vie_capture.h"
|
||||||
#include "vie_autotest_defines.h"
|
#include "video_engine/include/vie_codec.h"
|
||||||
#include "vie_autotest.h"
|
#include "video_engine/include/vie_network.h"
|
||||||
#include "vie_base.h"
|
#include "video_engine/include/vie_render.h"
|
||||||
#include "vie_capture.h"
|
#include "video_engine/include/vie_rtp_rtcp.h"
|
||||||
#include "vie_codec.h"
|
#include "video_engine/test/auto_test/interface/vie_autotest.h"
|
||||||
#include "vie_network.h"
|
#include "video_engine/test/auto_test/interface/vie_autotest_defines.h"
|
||||||
#include "vie_render.h"
|
#include "video_engine/test/libvietest/include/tb_external_transport.h"
|
||||||
#include "vie_rtp_rtcp.h"
|
#include "voice_engine/include/voe_base.h"
|
||||||
|
|
||||||
enum RelayMode {
|
enum RelayMode {
|
||||||
kRelayOneStream = 1,
|
kRelayOneStream = 1,
|
||||||
@@ -41,7 +41,8 @@ void InitialSingleStreamSettings(webrtc::VideoCodec* video_codec) {
|
|||||||
void SetSimulcastSettings(webrtc::VideoCodec* video_codec) {
|
void SetSimulcastSettings(webrtc::VideoCodec* video_codec) {
|
||||||
video_codec->width = 1280;
|
video_codec->width = 1280;
|
||||||
video_codec->height = 720;
|
video_codec->height = 720;
|
||||||
// simulcast settings
|
|
||||||
|
// Simulcast settings.
|
||||||
video_codec->numberOfSimulcastStreams = kNumStreams;
|
video_codec->numberOfSimulcastStreams = kNumStreams;
|
||||||
video_codec->simulcastStream[0].width = 320;
|
video_codec->simulcastStream[0].width = 320;
|
||||||
video_codec->simulcastStream[0].height = 180;
|
video_codec->simulcastStream[0].height = 180;
|
||||||
@@ -72,56 +73,45 @@ void RuntimeSingleStreamSettings(webrtc::VideoCodec* video_codec) {
|
|||||||
video_codec->simulcastStream[2].maxBitrate = 0;
|
video_codec->simulcastStream[2].maxBitrate = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VideoEngineSimulcastTest(void* window1, void* window2)
|
int VideoEngineSimulcastTest(void* window1, void* window2) {
|
||||||
{
|
// *******************************************************
|
||||||
//********************************************************
|
|
||||||
// Begin create/initialize Video Engine for testing
|
// Begin create/initialize Video Engine for testing
|
||||||
//********************************************************
|
// *******************************************************
|
||||||
|
|
||||||
int error = 0;
|
int error = 0;
|
||||||
int receive_channels[kNumStreams];
|
int receive_channels[kNumStreams];
|
||||||
|
|
||||||
//
|
// Create a VideoEngine instance.
|
||||||
// Create a VideoEngine instance
|
webrtc::VideoEngine* video_engine = NULL;
|
||||||
//
|
video_engine = webrtc::VideoEngine::Create();
|
||||||
webrtc::VideoEngine* ptrViE = NULL;
|
if (video_engine == NULL) {
|
||||||
ptrViE = webrtc::VideoEngine::Create();
|
|
||||||
if (ptrViE == NULL)
|
|
||||||
{
|
|
||||||
printf("ERROR in VideoEngine::Create\n");
|
printf("ERROR in VideoEngine::Create\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ptrViE->SetTraceFilter(webrtc::kTraceAll);
|
error = video_engine->SetTraceFilter(webrtc::kTraceAll);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in VideoEngine::SetTraceLevel\n");
|
printf("ERROR in VideoEngine::SetTraceLevel\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string trace_file =
|
std::string trace_file =
|
||||||
ViETest::GetResultOutputPath() + "ViESimulcast_trace.txt";
|
ViETest::GetResultOutputPath() + "ViESimulcast_trace.txt";
|
||||||
error = ptrViE->SetTraceFile(trace_file.c_str());
|
error = video_engine->SetTraceFile(trace_file.c_str());
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in VideoEngine::SetTraceFile\n");
|
printf("ERROR in VideoEngine::SetTraceFile\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// Init VideoEngine and create a channel.
|
||||||
// Init VideoEngine and create a channel
|
webrtc::ViEBase* vie_base = webrtc::ViEBase::GetInterface(video_engine);
|
||||||
//
|
if (vie_base == NULL) {
|
||||||
webrtc::ViEBase* ptrViEBase = webrtc::ViEBase::GetInterface(ptrViE);
|
|
||||||
if (ptrViEBase == NULL)
|
|
||||||
{
|
|
||||||
printf("ERROR in ViEBase::GetInterface\n");
|
printf("ERROR in ViEBase::GetInterface\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ptrViEBase->Init();
|
error = vie_base->Init();
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViEBase::Init\n");
|
printf("ERROR in ViEBase::Init\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -130,377 +120,321 @@ int VideoEngineSimulcastTest(void* window1, void* window2)
|
|||||||
printf("Select relay mode:\n");
|
printf("Select relay mode:\n");
|
||||||
printf("\t1. Relay one stream\n");
|
printf("\t1. Relay one stream\n");
|
||||||
printf("\t2. Relay all streams\n");
|
printf("\t2. Relay all streams\n");
|
||||||
if (scanf("%d", reinterpret_cast<int*>(&relay_mode)) != 1)
|
if (scanf("%d", reinterpret_cast<int*>(&relay_mode)) != 1) {
|
||||||
{
|
|
||||||
printf("Error in scanf()\n");
|
printf("Error in scanf()\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
getchar();
|
getchar();
|
||||||
|
|
||||||
int videoChannel = -1;
|
int video_channel = -1;
|
||||||
error = ptrViEBase->CreateChannel(videoChannel);
|
error = vie_base->CreateChannel(video_channel);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViEBase::CreateChannel\n");
|
printf("ERROR in ViEBase::CreateChannel\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < kNumStreams; ++i) {
|
for (int i = 0; i < kNumStreams; ++i) {
|
||||||
receive_channels[i] = -1;
|
receive_channels[i] = -1;
|
||||||
error = ptrViEBase->CreateReceiveChannel(receive_channels[i],
|
error = vie_base->CreateReceiveChannel(receive_channels[i], video_channel);
|
||||||
videoChannel);
|
if (error == -1) {
|
||||||
if (error == -1)
|
|
||||||
{
|
|
||||||
printf("ERROR in ViEBase::CreateChannel\n");
|
printf("ERROR in ViEBase::CreateChannel\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// List available capture devices, allocate and connect.
|
// List available capture devices, allocate and connect.
|
||||||
//
|
webrtc::ViECapture* vie_capture =
|
||||||
webrtc::ViECapture* ptrViECapture =
|
webrtc::ViECapture::GetInterface(video_engine);
|
||||||
webrtc::ViECapture::GetInterface(ptrViE);
|
if (vie_base == NULL) {
|
||||||
if (ptrViEBase == NULL)
|
|
||||||
{
|
|
||||||
printf("ERROR in ViECapture::GetInterface\n");
|
printf("ERROR in ViECapture::GetInterface\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned int KMaxDeviceNameLength = 128;
|
const unsigned int KMaxDeviceNameLength = 128;
|
||||||
const unsigned int KMaxUniqueIdLength = 256;
|
const unsigned int KMaxUniqueIdLength = 256;
|
||||||
char deviceName[KMaxDeviceNameLength];
|
char device_name[KMaxDeviceNameLength];
|
||||||
memset(deviceName, 0, KMaxDeviceNameLength);
|
memset(device_name, 0, KMaxDeviceNameLength);
|
||||||
char uniqueId[KMaxUniqueIdLength];
|
char unique_id[KMaxUniqueIdLength];
|
||||||
memset(uniqueId, 0, KMaxUniqueIdLength);
|
memset(unique_id, 0, KMaxUniqueIdLength);
|
||||||
|
|
||||||
printf("Available capture devices:\n");
|
printf("Available capture devices:\n");
|
||||||
int captureIdx = 0;
|
int capture_idx = 0;
|
||||||
for (captureIdx = 0;
|
for (capture_idx = 0; capture_idx < vie_capture->NumberOfCaptureDevices();
|
||||||
captureIdx < ptrViECapture->NumberOfCaptureDevices();
|
capture_idx++) {
|
||||||
captureIdx++)
|
memset(device_name, 0, KMaxDeviceNameLength);
|
||||||
{
|
memset(unique_id, 0, KMaxUniqueIdLength);
|
||||||
memset(deviceName, 0, KMaxDeviceNameLength);
|
|
||||||
memset(uniqueId, 0, KMaxUniqueIdLength);
|
|
||||||
|
|
||||||
error = ptrViECapture->GetCaptureDevice(captureIdx, deviceName,
|
error = vie_capture->GetCaptureDevice(capture_idx, device_name,
|
||||||
KMaxDeviceNameLength, uniqueId,
|
KMaxDeviceNameLength, unique_id,
|
||||||
KMaxUniqueIdLength);
|
KMaxUniqueIdLength);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViECapture::GetCaptureDevice\n");
|
printf("ERROR in ViECapture::GetCaptureDevice\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
printf("\t %d. %s\n", captureIdx + 1, deviceName);
|
printf("\t %d. %s\n", capture_idx + 1, device_name);
|
||||||
}
|
}
|
||||||
printf("\nChoose capture device: ");
|
printf("\nChoose capture device: ");
|
||||||
#ifdef WEBRTC_ANDROID
|
#ifdef WEBRTC_ANDROID
|
||||||
captureIdx = 0;
|
capture_idx = 0;
|
||||||
printf("0\n");
|
printf("0\n");
|
||||||
#else
|
#else
|
||||||
if (scanf("%d", &captureIdx) != 1)
|
if (scanf("%d", &capture_idx) != 1) {
|
||||||
{
|
|
||||||
printf("Error in scanf()\n");
|
printf("Error in scanf()\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
getchar();
|
getchar();
|
||||||
captureIdx = captureIdx - 1; // Compensate for idx start at 1.
|
// Compensate for idx start at 1.
|
||||||
|
capture_idx = capture_idx - 1;
|
||||||
#endif
|
#endif
|
||||||
error = ptrViECapture->GetCaptureDevice(captureIdx, deviceName,
|
error = vie_capture->GetCaptureDevice(capture_idx, device_name,
|
||||||
KMaxDeviceNameLength, uniqueId,
|
KMaxDeviceNameLength, unique_id,
|
||||||
KMaxUniqueIdLength);
|
KMaxUniqueIdLength);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViECapture::GetCaptureDevice\n");
|
printf("ERROR in ViECapture::GetCaptureDevice\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int captureId = 0;
|
int capture_id = 0;
|
||||||
error = ptrViECapture->AllocateCaptureDevice(uniqueId, KMaxUniqueIdLength,
|
error = vie_capture->AllocateCaptureDevice(unique_id, KMaxUniqueIdLength,
|
||||||
captureId);
|
capture_id);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViECapture::AllocateCaptureDevice\n");
|
printf("ERROR in ViECapture::AllocateCaptureDevice\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ptrViECapture->ConnectCaptureDevice(captureId, videoChannel);
|
error = vie_capture->ConnectCaptureDevice(capture_id, video_channel);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViECapture::ConnectCaptureDevice\n");
|
printf("ERROR in ViECapture::ConnectCaptureDevice\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ptrViECapture->StartCapture(captureId);
|
error = vie_capture->StartCapture(capture_id);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViECapture::StartCapture\n");
|
printf("ERROR in ViECapture::StartCapture\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// RTP/RTCP settings.
|
||||||
// RTP/RTCP settings
|
webrtc::ViERTP_RTCP* vie_rtp_rtcp =
|
||||||
//
|
webrtc::ViERTP_RTCP::GetInterface(video_engine);
|
||||||
webrtc::ViERTP_RTCP* ptrViERtpRtcp =
|
if (vie_rtp_rtcp == NULL) {
|
||||||
webrtc::ViERTP_RTCP::GetInterface(ptrViE);
|
|
||||||
if (ptrViERtpRtcp == NULL)
|
|
||||||
{
|
|
||||||
printf("ERROR in ViERTP_RTCP::GetInterface\n");
|
printf("ERROR in ViERTP_RTCP::GetInterface\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ptrViERtpRtcp->SetRTCPStatus(videoChannel,
|
error = vie_rtp_rtcp->SetRTCPStatus(video_channel,
|
||||||
webrtc::kRtcpCompound_RFC4585);
|
webrtc::kRtcpCompound_RFC4585);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViERTP_RTCP::SetRTCPStatus\n");
|
printf("ERROR in ViERTP_RTCP::SetRTCPStatus\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptrViERtpRtcp->SetRembStatus(videoChannel, true, false);
|
vie_rtp_rtcp->SetRembStatus(video_channel, true, false);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViERTP_RTCP::SetRTCPStatus\n");
|
printf("ERROR in ViERTP_RTCP::SetRTCPStatus\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ptrViERtpRtcp->SetKeyFrameRequestMethod(
|
error = vie_rtp_rtcp->SetKeyFrameRequestMethod(
|
||||||
videoChannel, webrtc::kViEKeyFrameRequestPliRtcp);
|
video_channel, webrtc::kViEKeyFrameRequestPliRtcp);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViERTP_RTCP::SetKeyFrameRequestMethod\n");
|
printf("ERROR in ViERTP_RTCP::SetKeyFrameRequestMethod\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < kNumStreams; ++i) {
|
for (int i = 0; i < kNumStreams; ++i) {
|
||||||
error = ptrViERtpRtcp->SetRTCPStatus(receive_channels[i],
|
error = vie_rtp_rtcp->SetRTCPStatus(receive_channels[i],
|
||||||
webrtc::kRtcpCompound_RFC4585);
|
webrtc::kRtcpCompound_RFC4585);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViERTP_RTCP::SetRTCPStatus\n");
|
printf("ERROR in ViERTP_RTCP::SetRTCPStatus\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptrViERtpRtcp->SetRembStatus(receive_channels[i], false, true);
|
vie_rtp_rtcp->SetRembStatus(receive_channels[i], false, true);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViERTP_RTCP::SetRTCPStatus\n");
|
printf("ERROR in ViERTP_RTCP::SetRTCPStatus\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ptrViERtpRtcp->SetKeyFrameRequestMethod(
|
error = vie_rtp_rtcp->SetKeyFrameRequestMethod(
|
||||||
receive_channels[i], webrtc::kViEKeyFrameRequestPliRtcp);
|
receive_channels[i], webrtc::kViEKeyFrameRequestPliRtcp);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViERTP_RTCP::SetKeyFrameRequestMethod\n");
|
printf("ERROR in ViERTP_RTCP::SetKeyFrameRequestMethod\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// Set up rendering.
|
||||||
// Set up rendering
|
webrtc::ViERender* vie_render = webrtc::ViERender::GetInterface(video_engine);
|
||||||
//
|
if (vie_render == NULL) {
|
||||||
webrtc::ViERender* ptrViERender = webrtc::ViERender::GetInterface(ptrViE);
|
|
||||||
if (ptrViERender == NULL)
|
|
||||||
{
|
|
||||||
printf("ERROR in ViERender::GetInterface\n");
|
printf("ERROR in ViERender::GetInterface\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
error
|
error = vie_render->AddRenderer(capture_id, window1, 0, 0.0, 0.0, 1.0, 1.0);
|
||||||
= ptrViERender->AddRenderer(captureId, window1, 0, 0.0, 0.0, 1.0, 1.0);
|
if (error == -1) {
|
||||||
if (error == -1)
|
|
||||||
{
|
|
||||||
printf("ERROR in ViERender::AddRenderer\n");
|
printf("ERROR in ViERender::AddRenderer\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ptrViERender->StartRender(captureId);
|
error = vie_render->StartRender(capture_id);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViERender::StartRender\n");
|
printf("ERROR in ViERender::StartRender\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only rendering the thumbnail.
|
// Only rendering the thumbnail.
|
||||||
int channel_to_render = videoChannel;
|
int channel_to_render = video_channel;
|
||||||
if (relay_mode == kRelayAllStreams) {
|
if (relay_mode == kRelayAllStreams) {
|
||||||
channel_to_render = receive_channels[0];
|
channel_to_render = receive_channels[0];
|
||||||
}
|
}
|
||||||
error = ptrViERender->AddRenderer(channel_to_render, window2, 1, 0.0,
|
error = vie_render->AddRenderer(channel_to_render, window2, 1, 0.0, 0.0, 1.0,
|
||||||
0.0, 1.0, 1.0);
|
1.0);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViERender::AddRenderer\n");
|
printf("ERROR in ViERender::AddRenderer\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ptrViERender->StartRender(channel_to_render);
|
error = vie_render->StartRender(channel_to_render);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViERender::StartRender\n");
|
printf("ERROR in ViERender::StartRender\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// Setup codecs.
|
||||||
// Setup codecs
|
webrtc::ViECodec* vie_codec = webrtc::ViECodec::GetInterface(video_engine);
|
||||||
//
|
if (vie_codec == NULL) {
|
||||||
webrtc::ViECodec* ptrViECodec = webrtc::ViECodec::GetInterface(ptrViE);
|
|
||||||
if (ptrViECodec == NULL)
|
|
||||||
{
|
|
||||||
printf("ERROR in ViECodec::GetInterface\n");
|
printf("ERROR in ViECodec::GetInterface\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check available codecs and prepare receive codecs
|
// Check available codecs and prepare receive codecs.
|
||||||
printf("\nAvailable codecs:\n");
|
printf("\nAvailable codecs:\n");
|
||||||
webrtc::VideoCodec videoCodec;
|
webrtc::VideoCodec video_codec;
|
||||||
memset(&videoCodec, 0, sizeof(webrtc::VideoCodec));
|
memset(&video_codec, 0, sizeof(webrtc::VideoCodec));
|
||||||
int codecIdx = 0;
|
int codec_idx = 0;
|
||||||
for (codecIdx = 0; codecIdx < ptrViECodec->NumberOfCodecs(); codecIdx++)
|
for (codec_idx = 0; codec_idx < vie_codec->NumberOfCodecs(); codec_idx++) {
|
||||||
{
|
error = vie_codec->GetCodec(codec_idx, video_codec);
|
||||||
error = ptrViECodec->GetCodec(codecIdx, videoCodec);
|
if (error == -1) {
|
||||||
if (error == -1)
|
|
||||||
{
|
|
||||||
printf("ERROR in ViECodec::GetCodec\n");
|
printf("ERROR in ViECodec::GetCodec\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// try to keep the test frame size small when I420
|
// Try to keep the test frame size small when I420.
|
||||||
if (videoCodec.codecType != webrtc::kVideoCodecVP8)
|
if (video_codec.codecType != webrtc::kVideoCodecVP8) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < kNumStreams; ++i) {
|
for (int i = 0; i < kNumStreams; ++i) {
|
||||||
error = ptrViECodec->SetReceiveCodec(receive_channels[i], videoCodec);
|
error = vie_codec->SetReceiveCodec(receive_channels[i], video_codec);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViECodec::SetReceiveCodec\n");
|
printf("ERROR in ViECodec::SetReceiveCodec\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (videoCodec.codecType != webrtc::kVideoCodecRED
|
if (video_codec.codecType != webrtc::kVideoCodecRED &&
|
||||||
&& videoCodec.codecType != webrtc::kVideoCodecULPFEC)
|
video_codec.codecType != webrtc::kVideoCodecULPFEC) {
|
||||||
{
|
printf("\t %d. %s\n", codec_idx + 1, video_codec.plName);
|
||||||
printf("\t %d. %s\n", codecIdx + 1, videoCodec.plName);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
error = ptrViECodec->GetCodec(codecIdx, videoCodec);
|
error = vie_codec->GetCodec(codec_idx, video_codec);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViECodec::GetCodec\n");
|
printf("ERROR in ViECodec::GetCodec\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool simulcast_mode = true;
|
bool simulcast_mode = true;
|
||||||
int num_streams = 1;
|
int num_streams = 1;
|
||||||
// Set spatial resolution option
|
// Set spatial resolution option.
|
||||||
if (simulcast_mode) {
|
if (simulcast_mode) {
|
||||||
SetSimulcastSettings(&videoCodec);
|
SetSimulcastSettings(&video_codec);
|
||||||
num_streams = videoCodec.numberOfSimulcastStreams;
|
num_streams = video_codec.numberOfSimulcastStreams;
|
||||||
} else {
|
} else {
|
||||||
InitialSingleStreamSettings(&videoCodec);
|
InitialSingleStreamSettings(&video_codec);
|
||||||
num_streams = 1;
|
num_streams = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set start bit rate
|
// Set start bit rate.
|
||||||
std::string str;
|
std::string str;
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::cout << "Choose start rate (in kbps). Press enter for default: ";
|
std::cout << "Choose start rate (in kbps). Press enter for default: ";
|
||||||
std::getline(std::cin, str);
|
std::getline(std::cin, str);
|
||||||
int startRate = atoi(str.c_str());
|
int start_rate = atoi(str.c_str());
|
||||||
if(startRate != 0)
|
if (start_rate != 0) {
|
||||||
{
|
video_codec.startBitrate = start_rate;
|
||||||
videoCodec.startBitrate=startRate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ptrViECodec->SetSendCodec(videoChannel, videoCodec);
|
error = vie_codec->SetSendCodec(video_channel, video_codec);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViECodec::SetSendCodec\n");
|
printf("ERROR in ViECodec::SetSendCodec\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// Address settings
|
// Address settings.
|
||||||
//
|
webrtc::ViENetwork* vie_network =
|
||||||
webrtc::ViENetwork* ptrViENetwork =
|
webrtc::ViENetwork::GetInterface(video_engine);
|
||||||
webrtc::ViENetwork::GetInterface(ptrViE);
|
if (vie_network == NULL) {
|
||||||
if (ptrViENetwork == NULL)
|
|
||||||
{
|
|
||||||
printf("ERROR in ViENetwork::GetInterface\n");
|
printf("ERROR in ViENetwork::GetInterface\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
TbExternalTransport::SsrcChannelMap ssrc_channel_map;
|
TbExternalTransport::SsrcChannelMap ssrc_channel_map;
|
||||||
for (int idx = 0; idx < num_streams; idx++)
|
for (int idx = 0; idx < num_streams; idx++) {
|
||||||
{
|
error = vie_rtp_rtcp->SetLocalSSRC(video_channel, idx + 1, // SSRC
|
||||||
error = ptrViERtpRtcp->SetLocalSSRC(
|
webrtc::kViEStreamTypeNormal, idx);
|
||||||
videoChannel,
|
|
||||||
idx+1, // SSRC
|
|
||||||
webrtc::kViEStreamTypeNormal,
|
|
||||||
idx);
|
|
||||||
ssrc_channel_map[idx + 1] = receive_channels[idx];
|
ssrc_channel_map[idx + 1] = receive_channels[idx];
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViERTP_RTCP::SetLocalSSRC(idx:%d)\n",
|
printf("ERROR in ViERTP_RTCP::SetLocalSSRC(idx:%d)\n",
|
||||||
idx);
|
idx);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TbExternalTransport::SsrcChannelMap* channel_map_ptr = &ssrc_channel_map;
|
TbExternalTransport::SsrcChannelMap* channel_map = &ssrc_channel_map;
|
||||||
if (relay_mode == kRelayOneStream) {
|
if (relay_mode == kRelayOneStream) {
|
||||||
channel_map_ptr = NULL;
|
channel_map = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setting External transport
|
// Setting External transport.
|
||||||
TbExternalTransport extTransport(*(ptrViENetwork), videoChannel,
|
TbExternalTransport ext_transport(*vie_network, video_channel, channel_map);
|
||||||
channel_map_ptr);
|
|
||||||
|
|
||||||
error = ptrViENetwork->RegisterSendTransport(videoChannel,
|
error = vie_network->RegisterSendTransport(video_channel, ext_transport);
|
||||||
extTransport);
|
if (error == -1) {
|
||||||
if (error == -1)
|
|
||||||
{
|
|
||||||
printf("ERROR in ViECodec::RegisterSendTransport \n");
|
printf("ERROR in ViECodec::RegisterSendTransport \n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < kNumStreams; ++i) {
|
for (int i = 0; i < kNumStreams; ++i) {
|
||||||
error = ptrViENetwork->RegisterSendTransport(receive_channels[i],
|
error = vie_network->RegisterSendTransport(receive_channels[i],
|
||||||
extTransport);
|
ext_transport);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViECodec::RegisterSendTransport \n");
|
printf("ERROR in ViECodec::RegisterSendTransport \n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extTransport.SetPacketLoss(0);
|
ext_transport.SetPacketLoss(0);
|
||||||
|
|
||||||
// Set network delay value
|
// Set network delay value.
|
||||||
extTransport.SetNetworkDelay(10);
|
ext_transport.SetNetworkDelay(10);
|
||||||
|
|
||||||
if (relay_mode == kRelayOneStream) {
|
if (relay_mode == kRelayOneStream) {
|
||||||
extTransport.SetSSRCFilter(num_streams);
|
ext_transport.SetSSRCFilter(num_streams);
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ptrViEBase->StartSend(videoChannel);
|
error = vie_base->StartSend(video_channel);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViENetwork::StartSend\n");
|
printf("ERROR in ViENetwork::StartSend\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
error = ptrViEBase->StartReceive(videoChannel);
|
error = vie_base->StartReceive(video_channel);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViENetwork::StartReceive\n");
|
printf("ERROR in ViENetwork::StartReceive\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < kNumStreams; ++i) {
|
for (int i = 0; i < kNumStreams; ++i) {
|
||||||
error = ptrViEBase->StartReceive(receive_channels[i]);
|
error = vie_base->StartReceive(receive_channels[i]);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViENetwork::StartReceive\n");
|
printf("ERROR in ViENetwork::StartReceive\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -508,211 +442,177 @@ int VideoEngineSimulcastTest(void* window1, void* window2)
|
|||||||
|
|
||||||
// Create a receive channel to verify that it doesn't mess up toggling
|
// Create a receive channel to verify that it doesn't mess up toggling
|
||||||
// between single stream and simulcast.
|
// between single stream and simulcast.
|
||||||
int videoChannel2 = -1;
|
int video_channel2 = -1;
|
||||||
error = ptrViEBase->CreateReceiveChannel(videoChannel2, videoChannel);
|
error = vie_base->CreateReceiveChannel(video_channel2, video_channel);
|
||||||
if (error == -1) {
|
if (error == -1) {
|
||||||
printf("ERROR in ViEBase::CreateReceiveChannel\n");
|
printf("ERROR in ViEBase::CreateReceiveChannel\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//********************************************************
|
// *******************************************************
|
||||||
// Engine started
|
// Engine started
|
||||||
//********************************************************
|
// *******************************************************
|
||||||
|
|
||||||
printf("\nSimulcast call started\n\n");
|
printf("\nSimulcast call started\n\n");
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
printf("Enter new SSRC filter 1,2 or 3\n");
|
printf("Enter new SSRC filter 1,2 or 3\n");
|
||||||
printf("... or 0 to switch between simulcast and a single stream\n");
|
printf("... or 0 to switch between simulcast and a single stream\n");
|
||||||
printf("Press enter to stop...");
|
printf("Press enter to stop...");
|
||||||
str.clear();
|
str.clear();
|
||||||
std::getline(std::cin, str);
|
std::getline(std::cin, str);
|
||||||
if (!str.empty())
|
if (!str.empty()) {
|
||||||
{
|
|
||||||
int ssrc = atoi(str.c_str());
|
int ssrc = atoi(str.c_str());
|
||||||
if (ssrc == 0) {
|
if (ssrc == 0) {
|
||||||
// Toggle between simulcast and a single stream with different
|
// Toggle between simulcast and a single stream with different
|
||||||
// resolution.
|
// resolution.
|
||||||
if (simulcast_mode) {
|
if (simulcast_mode) {
|
||||||
RuntimeSingleStreamSettings(&videoCodec);
|
RuntimeSingleStreamSettings(&video_codec);
|
||||||
num_streams = 1;
|
num_streams = 1;
|
||||||
printf("Disabling simulcast\n");
|
printf("Disabling simulcast\n");
|
||||||
} else {
|
} else {
|
||||||
SetSimulcastSettings(&videoCodec);
|
SetSimulcastSettings(&video_codec);
|
||||||
num_streams = videoCodec.numberOfSimulcastStreams;
|
num_streams = video_codec.numberOfSimulcastStreams;
|
||||||
printf("Enabling simulcast\n");
|
printf("Enabling simulcast\n");
|
||||||
}
|
}
|
||||||
simulcast_mode = !simulcast_mode;
|
simulcast_mode = !simulcast_mode;
|
||||||
if (ptrViECodec->SetSendCodec(videoChannel, videoCodec) != 0) {
|
if (vie_codec->SetSendCodec(video_channel, video_codec) != 0) {
|
||||||
printf("ERROR switching between simulcast and single stream\n");
|
printf("ERROR switching between simulcast and single stream\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
for (int idx = 0; idx < num_streams; idx++)
|
for (int idx = 0; idx < num_streams; idx++) {
|
||||||
{
|
error = vie_rtp_rtcp->SetLocalSSRC(video_channel, idx + 1, // SSRC
|
||||||
error = ptrViERtpRtcp->SetLocalSSRC(
|
webrtc::kViEStreamTypeNormal, idx);
|
||||||
videoChannel,
|
if (error == -1) {
|
||||||
idx+1, // SSRC
|
printf("ERROR in ViERTP_RTCP::SetLocalSSRC(idx:%d)\n", idx);
|
||||||
webrtc::kViEStreamTypeNormal,
|
|
||||||
idx);
|
|
||||||
if (error == -1)
|
|
||||||
{
|
|
||||||
printf("ERROR in ViERTP_RTCP::SetLocalSSRC(idx:%d)\n",
|
|
||||||
idx);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (relay_mode == kRelayOneStream) {
|
if (relay_mode == kRelayOneStream) {
|
||||||
extTransport.SetSSRCFilter(num_streams);
|
ext_transport.SetSSRCFilter(num_streams);
|
||||||
}
|
}
|
||||||
} else if (ssrc > 0 && ssrc < 4)
|
} else if (ssrc > 0 && ssrc < 4) {
|
||||||
{
|
|
||||||
if (relay_mode == kRelayOneStream) {
|
if (relay_mode == kRelayOneStream) {
|
||||||
extTransport.SetSSRCFilter(ssrc);
|
ext_transport.SetSSRCFilter(ssrc);
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
{
|
|
||||||
printf("Invalid SSRC\n");
|
printf("Invalid SSRC\n");
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (true);
|
} while (true);
|
||||||
|
|
||||||
//********************************************************
|
// *******************************************************
|
||||||
// Testing finished. Tear down Video Engine
|
// Testing finished. Tear down Video Engine
|
||||||
//********************************************************
|
// *******************************************************
|
||||||
|
error = vie_base->DeleteChannel(video_channel2);
|
||||||
error = ptrViEBase->DeleteChannel(videoChannel2);
|
if (error == -1) {
|
||||||
if (error == -1)
|
|
||||||
{
|
|
||||||
printf("ERROR in ViEBase::DeleteChannel\n");
|
printf("ERROR in ViEBase::DeleteChannel\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < kNumStreams; ++i) {
|
for (int i = 0; i < kNumStreams; ++i) {
|
||||||
error = ptrViEBase->StopReceive(receive_channels[i]);
|
error = vie_base->StopReceive(receive_channels[i]);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViEBase::StopReceive\n");
|
printf("ERROR in ViEBase::StopReceive\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ptrViEBase->StopReceive(videoChannel);
|
error = vie_base->StopReceive(video_channel);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViEBase::StopReceive\n");
|
printf("ERROR in ViEBase::StopReceive\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ptrViEBase->StopSend(videoChannel);
|
error = vie_base->StopSend(video_channel);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViEBase::StopSend\n");
|
printf("ERROR in ViEBase::StopSend\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ptrViERender->StopRender(captureId);
|
error = vie_render->StopRender(capture_id);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViERender::StopRender\n");
|
printf("ERROR in ViERender::StopRender\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ptrViERender->RemoveRenderer(captureId);
|
error = vie_render->RemoveRenderer(capture_id);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViERender::RemoveRenderer\n");
|
printf("ERROR in ViERender::RemoveRenderer\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ptrViERender->StopRender(channel_to_render);
|
error = vie_render->StopRender(channel_to_render);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViERender::StopRender\n");
|
printf("ERROR in ViERender::StopRender\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ptrViERender->RemoveRenderer(channel_to_render);
|
error = vie_render->RemoveRenderer(channel_to_render);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViERender::RemoveRenderer\n");
|
printf("ERROR in ViERender::RemoveRenderer\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ptrViECapture->StopCapture(captureId);
|
error = vie_capture->StopCapture(capture_id);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViECapture::StopCapture\n");
|
printf("ERROR in ViECapture::StopCapture\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ptrViECapture->DisconnectCaptureDevice(videoChannel);
|
error = vie_capture->DisconnectCaptureDevice(video_channel);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViECapture::DisconnectCaptureDevice\n");
|
printf("ERROR in ViECapture::DisconnectCaptureDevice\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ptrViECapture->ReleaseCaptureDevice(captureId);
|
error = vie_capture->ReleaseCaptureDevice(capture_id);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViECapture::ReleaseCaptureDevice\n");
|
printf("ERROR in ViECapture::ReleaseCaptureDevice\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < kNumStreams; ++i) {
|
for (int i = 0; i < kNumStreams; ++i) {
|
||||||
error = ptrViEBase->DeleteChannel(receive_channels[i]);
|
error = vie_base->DeleteChannel(receive_channels[i]);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViEBase::DeleteChannel\n");
|
printf("ERROR in ViEBase::DeleteChannel\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ptrViEBase->DeleteChannel(videoChannel);
|
error = vie_base->DeleteChannel(video_channel);
|
||||||
if (error == -1)
|
if (error == -1) {
|
||||||
{
|
|
||||||
printf("ERROR in ViEBase::DeleteChannel\n");
|
printf("ERROR in ViEBase::DeleteChannel\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int remainingInterfaces = 0;
|
int remaining_interfaces = 0;
|
||||||
remainingInterfaces = ptrViECodec->Release();
|
remaining_interfaces = vie_codec->Release();
|
||||||
remainingInterfaces += ptrViECapture->Release();
|
remaining_interfaces += vie_capture->Release();
|
||||||
remainingInterfaces += ptrViERtpRtcp->Release();
|
remaining_interfaces += vie_rtp_rtcp->Release();
|
||||||
remainingInterfaces += ptrViERender->Release();
|
remaining_interfaces += vie_render->Release();
|
||||||
remainingInterfaces += ptrViENetwork->Release();
|
remaining_interfaces += vie_network->Release();
|
||||||
remainingInterfaces += ptrViEBase->Release();
|
remaining_interfaces += vie_base->Release();
|
||||||
if (remainingInterfaces > 0)
|
if (remaining_interfaces > 0) {
|
||||||
{
|
|
||||||
printf("ERROR: Could not release all interfaces\n");
|
printf("ERROR: Could not release all interfaces\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool deleted = webrtc::VideoEngine::Delete(ptrViE);
|
bool deleted = webrtc::VideoEngine::Delete(video_engine);
|
||||||
if (deleted == false)
|
if (deleted == false) {
|
||||||
{
|
|
||||||
printf("ERROR in VideoEngine::Delete\n");
|
printf("ERROR in VideoEngine::Delete\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
//
|
|
||||||
// END: VideoEngine 3.0 Sample Code
|
|
||||||
//
|
|
||||||
// ===================================================================
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ViEAutoTest::ViESimulcastCall()
|
int ViEAutoTest::ViESimulcastCall() {
|
||||||
{
|
|
||||||
ViETest::Log(" ");
|
ViETest::Log(" ");
|
||||||
ViETest::Log("========================================");
|
ViETest::Log("========================================");
|
||||||
ViETest::Log(" ViE Autotest Simulcast Call\n");
|
ViETest::Log(" ViE Autotest Simulcast Call\n");
|
||||||
|
|
||||||
if (VideoEngineSimulcastTest(_window1, _window2) == 0)
|
if (VideoEngineSimulcastTest(_window1, _window2) == 0) {
|
||||||
{
|
|
||||||
ViETest::Log(" ");
|
ViETest::Log(" ");
|
||||||
ViETest::Log(" ViE Autotest Simulcast Call Done");
|
ViETest::Log(" ViE Autotest Simulcast Call Done");
|
||||||
ViETest::Log("========================================");
|
ViETest::Log("========================================");
|
||||||
|
Reference in New Issue
Block a user