PageRenderTime 46ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/webrtc/video_engine/test/auto_test/source/vie_autotest_simulcast.cc

https://bitbucket.org/bohlooli/webrtc
C++ | 655 lines | 538 code | 78 blank | 39 comment | 159 complexity | 0f3ac89ffea882b0265b5241fe1440d7 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, BSD-3-Clause
  1. /*
  2. * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #include <iostream> // NOLINT
  11. #include "common_types.h" // NOLINT
  12. #include "video_engine/include/vie_base.h"
  13. #include "video_engine/include/vie_capture.h"
  14. #include "video_engine/include/vie_codec.h"
  15. #include "video_engine/include/vie_network.h"
  16. #include "video_engine/include/vie_render.h"
  17. #include "video_engine/include/vie_rtp_rtcp.h"
  18. #include "video_engine/test/auto_test/interface/vie_autotest.h"
  19. #include "video_engine/test/auto_test/interface/vie_autotest_defines.h"
  20. #include "video_engine/test/libvietest/include/tb_external_transport.h"
  21. #include "voice_engine/include/voe_base.h"
  22. enum RelayMode {
  23. kRelayOneStream = 1,
  24. kRelayAllStreams = 2
  25. };
  26. #define VCM_RED_PAYLOAD_TYPE 96
  27. #define VCM_ULPFEC_PAYLOAD_TYPE 97
  28. const int kNumStreams = 3;
  29. void InitialSingleStreamSettings(webrtc::VideoCodec* video_codec) {
  30. video_codec->numberOfSimulcastStreams = 0;
  31. video_codec->width = 1200;
  32. video_codec->height = 800;
  33. }
  34. void SetSimulcastSettings(webrtc::VideoCodec* video_codec) {
  35. video_codec->width = 1280;
  36. video_codec->height = 720;
  37. // Simulcast settings.
  38. video_codec->numberOfSimulcastStreams = kNumStreams;
  39. video_codec->simulcastStream[0].width = 320;
  40. video_codec->simulcastStream[0].height = 180;
  41. video_codec->simulcastStream[0].numberOfTemporalLayers = 0;
  42. video_codec->simulcastStream[0].maxBitrate = 100;
  43. video_codec->simulcastStream[0].qpMax = video_codec->qpMax;
  44. video_codec->simulcastStream[1].width = 640;
  45. video_codec->simulcastStream[1].height = 360;
  46. video_codec->simulcastStream[1].numberOfTemporalLayers = 0;
  47. video_codec->simulcastStream[1].maxBitrate = 500;
  48. video_codec->simulcastStream[1].qpMax = video_codec->qpMax;
  49. video_codec->simulcastStream[2].width = 1280;
  50. video_codec->simulcastStream[2].height = 720;
  51. video_codec->simulcastStream[2].numberOfTemporalLayers = 0;
  52. video_codec->simulcastStream[2].maxBitrate = 1200;
  53. video_codec->simulcastStream[2].qpMax = video_codec->qpMax;
  54. }
  55. void RuntimeSingleStreamSettings(webrtc::VideoCodec* video_codec) {
  56. SetSimulcastSettings(video_codec);
  57. video_codec->width = 1200;
  58. video_codec->height = 800;
  59. video_codec->numberOfSimulcastStreams = kNumStreams;
  60. video_codec->simulcastStream[0].maxBitrate = 0;
  61. video_codec->simulcastStream[1].maxBitrate = 0;
  62. video_codec->simulcastStream[2].maxBitrate = 0;
  63. }
  64. int VideoEngineSimulcastTest(void* window1, void* window2) {
  65. // *******************************************************
  66. // Begin create/initialize Video Engine for testing
  67. // *******************************************************
  68. int error = 0;
  69. int receive_channels[kNumStreams];
  70. // Create a VideoEngine instance.
  71. webrtc::VideoEngine* video_engine = NULL;
  72. video_engine = webrtc::VideoEngine::Create();
  73. if (video_engine == NULL) {
  74. printf("ERROR in VideoEngine::Create\n");
  75. return -1;
  76. }
  77. error = video_engine->SetTraceFilter(webrtc::kTraceAll);
  78. if (error == -1) {
  79. printf("ERROR in VideoEngine::SetTraceLevel\n");
  80. return -1;
  81. }
  82. std::string trace_file =
  83. ViETest::GetResultOutputPath() + "ViESimulcast_trace.txt";
  84. error = video_engine->SetTraceFile(trace_file.c_str());
  85. if (error == -1) {
  86. printf("ERROR in VideoEngine::SetTraceFile\n");
  87. return -1;
  88. }
  89. // Init VideoEngine and create a channel.
  90. webrtc::ViEBase* vie_base = webrtc::ViEBase::GetInterface(video_engine);
  91. if (vie_base == NULL) {
  92. printf("ERROR in ViEBase::GetInterface\n");
  93. return -1;
  94. }
  95. error = vie_base->Init();
  96. if (error == -1) {
  97. printf("ERROR in ViEBase::Init\n");
  98. return -1;
  99. }
  100. RelayMode relay_mode = kRelayOneStream;
  101. printf("Select relay mode:\n");
  102. printf("\t1. Relay one stream\n");
  103. printf("\t2. Relay all streams\n");
  104. if (scanf("%d", reinterpret_cast<int*>(&relay_mode)) != 1) {
  105. printf("Error in scanf()\n");
  106. return -1;
  107. }
  108. getchar();
  109. webrtc::ViERTP_RTCP* vie_rtp_rtcp =
  110. webrtc::ViERTP_RTCP::GetInterface(video_engine);
  111. if (vie_rtp_rtcp == NULL) {
  112. printf("ERROR in ViERTP_RTCP::GetInterface\n");
  113. return -1;
  114. }
  115. printf("Bandwidth estimation modes:\n");
  116. printf("1. Multi-stream bandwidth estimation\n");
  117. printf("2. Single-stream bandwidth estimation\n");
  118. printf("Choose bandwidth estimation mode (default is 1): ");
  119. std::string str;
  120. std::getline(std::cin, str);
  121. int bwe_mode_choice = atoi(str.c_str());
  122. webrtc::BandwidthEstimationMode bwe_mode;
  123. switch (bwe_mode_choice) {
  124. case 1:
  125. bwe_mode = webrtc::kViEMultiStreamEstimation;
  126. break;
  127. case 2:
  128. bwe_mode = webrtc::kViESingleStreamEstimation;
  129. break;
  130. default:
  131. bwe_mode = webrtc::kViEMultiStreamEstimation;
  132. break;
  133. }
  134. error = vie_rtp_rtcp->SetBandwidthEstimationMode(bwe_mode);
  135. if (error == -1) {
  136. printf("ERROR in ViERTP_RTCP::SetBandwidthEstimationMode\n");
  137. return -1;
  138. }
  139. int video_channel = -1;
  140. error = vie_base->CreateChannel(video_channel);
  141. if (error == -1) {
  142. printf("ERROR in ViEBase::CreateChannel\n");
  143. return -1;
  144. }
  145. for (int i = 0; i < kNumStreams; ++i) {
  146. receive_channels[i] = -1;
  147. error = vie_base->CreateReceiveChannel(receive_channels[i], video_channel);
  148. if (error == -1) {
  149. printf("ERROR in ViEBase::CreateChannel\n");
  150. return -1;
  151. }
  152. }
  153. // List available capture devices, allocate and connect.
  154. webrtc::ViECapture* vie_capture =
  155. webrtc::ViECapture::GetInterface(video_engine);
  156. if (vie_base == NULL) {
  157. printf("ERROR in ViECapture::GetInterface\n");
  158. return -1;
  159. }
  160. const unsigned int KMaxDeviceNameLength = 128;
  161. const unsigned int KMaxUniqueIdLength = 256;
  162. char device_name[KMaxDeviceNameLength];
  163. memset(device_name, 0, KMaxDeviceNameLength);
  164. char unique_id[KMaxUniqueIdLength];
  165. memset(unique_id, 0, KMaxUniqueIdLength);
  166. printf("Available capture devices:\n");
  167. int capture_idx = 0;
  168. for (capture_idx = 0; capture_idx < vie_capture->NumberOfCaptureDevices();
  169. capture_idx++) {
  170. memset(device_name, 0, KMaxDeviceNameLength);
  171. memset(unique_id, 0, KMaxUniqueIdLength);
  172. error = vie_capture->GetCaptureDevice(capture_idx, device_name,
  173. KMaxDeviceNameLength, unique_id,
  174. KMaxUniqueIdLength);
  175. if (error == -1) {
  176. printf("ERROR in ViECapture::GetCaptureDevice\n");
  177. return -1;
  178. }
  179. printf("\t %d. %s\n", capture_idx + 1, device_name);
  180. }
  181. printf("\nChoose capture device: ");
  182. #ifdef WEBRTC_ANDROID
  183. capture_idx = 0;
  184. printf("0\n");
  185. #else
  186. if (scanf("%d", &capture_idx) != 1) {
  187. printf("Error in scanf()\n");
  188. return -1;
  189. }
  190. getchar();
  191. // Compensate for idx start at 1.
  192. capture_idx = capture_idx - 1;
  193. #endif
  194. error = vie_capture->GetCaptureDevice(capture_idx, device_name,
  195. KMaxDeviceNameLength, unique_id,
  196. KMaxUniqueIdLength);
  197. if (error == -1) {
  198. printf("ERROR in ViECapture::GetCaptureDevice\n");
  199. return -1;
  200. }
  201. int capture_id = 0;
  202. error = vie_capture->AllocateCaptureDevice(unique_id, KMaxUniqueIdLength,
  203. capture_id);
  204. if (error == -1) {
  205. printf("ERROR in ViECapture::AllocateCaptureDevice\n");
  206. return -1;
  207. }
  208. error = vie_capture->ConnectCaptureDevice(capture_id, video_channel);
  209. if (error == -1) {
  210. printf("ERROR in ViECapture::ConnectCaptureDevice\n");
  211. return -1;
  212. }
  213. error = vie_capture->StartCapture(capture_id);
  214. if (error == -1) {
  215. printf("ERROR in ViECapture::StartCapture\n");
  216. return -1;
  217. }
  218. // RTP/RTCP settings.
  219. error = vie_rtp_rtcp->SetRTCPStatus(video_channel,
  220. webrtc::kRtcpCompound_RFC4585);
  221. if (error == -1) {
  222. printf("ERROR in ViERTP_RTCP::SetRTCPStatus\n");
  223. return -1;
  224. }
  225. vie_rtp_rtcp->SetRembStatus(video_channel, true, false);
  226. if (error == -1) {
  227. printf("ERROR in ViERTP_RTCP::SetRTCPStatus\n");
  228. return -1;
  229. }
  230. error = vie_rtp_rtcp->SetKeyFrameRequestMethod(
  231. video_channel, webrtc::kViEKeyFrameRequestPliRtcp);
  232. if (error == -1) {
  233. printf("ERROR in ViERTP_RTCP::SetKeyFrameRequestMethod\n");
  234. return -1;
  235. }
  236. for (int i = 0; i < kNumStreams; ++i) {
  237. error = vie_rtp_rtcp->SetRTCPStatus(receive_channels[i],
  238. webrtc::kRtcpCompound_RFC4585);
  239. if (error == -1) {
  240. printf("ERROR in ViERTP_RTCP::SetRTCPStatus\n");
  241. return -1;
  242. }
  243. vie_rtp_rtcp->SetRembStatus(receive_channels[i], false, true);
  244. if (error == -1) {
  245. printf("ERROR in ViERTP_RTCP::SetRTCPStatus\n");
  246. return -1;
  247. }
  248. error = vie_rtp_rtcp->SetKeyFrameRequestMethod(
  249. receive_channels[i], webrtc::kViEKeyFrameRequestPliRtcp);
  250. if (error == -1) {
  251. printf("ERROR in ViERTP_RTCP::SetKeyFrameRequestMethod\n");
  252. return -1;
  253. }
  254. }
  255. // Set up rendering.
  256. webrtc::ViERender* vie_render = webrtc::ViERender::GetInterface(video_engine);
  257. if (vie_render == NULL) {
  258. printf("ERROR in ViERender::GetInterface\n");
  259. return -1;
  260. }
  261. error = vie_render->AddRenderer(capture_id, window1, 0, 0.0, 0.0, 1.0, 1.0);
  262. if (error == -1) {
  263. printf("ERROR in ViERender::AddRenderer\n");
  264. return -1;
  265. }
  266. error = vie_render->StartRender(capture_id);
  267. if (error == -1) {
  268. printf("ERROR in ViERender::StartRender\n");
  269. return -1;
  270. }
  271. // Only rendering the thumbnail.
  272. int channel_to_render = video_channel;
  273. if (relay_mode == kRelayAllStreams) {
  274. channel_to_render = receive_channels[0];
  275. }
  276. error = vie_render->AddRenderer(channel_to_render, window2, 1, 0.0, 0.0, 1.0,
  277. 1.0);
  278. if (error == -1) {
  279. printf("ERROR in ViERender::AddRenderer\n");
  280. return -1;
  281. }
  282. error = vie_render->StartRender(channel_to_render);
  283. if (error == -1) {
  284. printf("ERROR in ViERender::StartRender\n");
  285. return -1;
  286. }
  287. // Setup codecs.
  288. webrtc::ViECodec* vie_codec = webrtc::ViECodec::GetInterface(video_engine);
  289. if (vie_codec == NULL) {
  290. printf("ERROR in ViECodec::GetInterface\n");
  291. return -1;
  292. }
  293. // Check available codecs and prepare receive codecs.
  294. printf("\nAvailable codecs:\n");
  295. webrtc::VideoCodec video_codec;
  296. memset(&video_codec, 0, sizeof(webrtc::VideoCodec));
  297. int codec_idx = 0;
  298. for (codec_idx = 0; codec_idx < vie_codec->NumberOfCodecs(); codec_idx++) {
  299. error = vie_codec->GetCodec(codec_idx, video_codec);
  300. if (error == -1) {
  301. printf("ERROR in ViECodec::GetCodec\n");
  302. return -1;
  303. }
  304. // Try to keep the test frame size small when I420.
  305. if (video_codec.codecType != webrtc::kVideoCodecVP8) {
  306. continue;
  307. }
  308. for (int i = 0; i < kNumStreams; ++i) {
  309. error = vie_codec->SetReceiveCodec(receive_channels[i], video_codec);
  310. if (error == -1) {
  311. printf("ERROR in ViECodec::SetReceiveCodec\n");
  312. return -1;
  313. }
  314. }
  315. if (video_codec.codecType != webrtc::kVideoCodecRED &&
  316. video_codec.codecType != webrtc::kVideoCodecULPFEC) {
  317. printf("\t %d. %s\n", codec_idx + 1, video_codec.plName);
  318. }
  319. break;
  320. }
  321. error = vie_codec->GetCodec(codec_idx, video_codec);
  322. if (error == -1) {
  323. printf("ERROR in ViECodec::GetCodec\n");
  324. return -1;
  325. }
  326. bool simulcast_mode = true;
  327. int num_streams = 1;
  328. // Set spatial resolution option.
  329. if (simulcast_mode) {
  330. SetSimulcastSettings(&video_codec);
  331. num_streams = video_codec.numberOfSimulcastStreams;
  332. } else {
  333. InitialSingleStreamSettings(&video_codec);
  334. num_streams = 1;
  335. }
  336. // Set start bit rate.
  337. std::cout << std::endl;
  338. std::cout << "Choose start rate (in kbps). Press enter for default: ";
  339. std::getline(std::cin, str);
  340. int start_rate = atoi(str.c_str());
  341. if (start_rate != 0) {
  342. video_codec.startBitrate = start_rate;
  343. }
  344. error = vie_codec->SetSendCodec(video_channel, video_codec);
  345. if (error == -1) {
  346. printf("ERROR in ViECodec::SetSendCodec\n");
  347. return -1;
  348. }
  349. // Address settings.
  350. webrtc::ViENetwork* vie_network =
  351. webrtc::ViENetwork::GetInterface(video_engine);
  352. if (vie_network == NULL) {
  353. printf("ERROR in ViENetwork::GetInterface\n");
  354. return -1;
  355. }
  356. TbExternalTransport::SsrcChannelMap ssrc_channel_map;
  357. for (int idx = 0; idx < num_streams; idx++) {
  358. error = vie_rtp_rtcp->SetLocalSSRC(video_channel, idx + 1, // SSRC
  359. webrtc::kViEStreamTypeNormal, idx);
  360. ssrc_channel_map[idx + 1] = receive_channels[idx];
  361. if (error == -1) {
  362. printf("ERROR in ViERTP_RTCP::SetLocalSSRC(idx:%d)\n",
  363. idx);
  364. return -1;
  365. }
  366. }
  367. TbExternalTransport::SsrcChannelMap* channel_map = &ssrc_channel_map;
  368. if (relay_mode == kRelayOneStream) {
  369. channel_map = NULL;
  370. }
  371. // Setting External transport.
  372. TbExternalTransport ext_transport(*vie_network, video_channel, channel_map);
  373. error = vie_network->RegisterSendTransport(video_channel, ext_transport);
  374. if (error == -1) {
  375. printf("ERROR in ViECodec::RegisterSendTransport \n");
  376. return -1;
  377. }
  378. for (int i = 0; i < kNumStreams; ++i) {
  379. error = vie_network->RegisterSendTransport(receive_channels[i],
  380. ext_transport);
  381. if (error == -1) {
  382. printf("ERROR in ViECodec::RegisterSendTransport \n");
  383. return -1;
  384. }
  385. }
  386. // Set network one-way delay value.
  387. // 10 ms one-way delay.
  388. NetworkParameters network;
  389. network.loss_model = kUniformLoss;
  390. network.mean_one_way_delay = 10;
  391. ext_transport.SetNetworkParameters(network);
  392. if (relay_mode == kRelayOneStream) {
  393. ext_transport.SetSSRCFilter(num_streams);
  394. }
  395. error = vie_base->StartSend(video_channel);
  396. if (error == -1) {
  397. printf("ERROR in ViENetwork::StartSend\n");
  398. return -1;
  399. }
  400. error = vie_base->StartReceive(video_channel);
  401. if (error == -1) {
  402. printf("ERROR in ViENetwork::StartReceive\n");
  403. return -1;
  404. }
  405. for (int i = 0; i < kNumStreams; ++i) {
  406. error = vie_base->StartReceive(receive_channels[i]);
  407. if (error == -1) {
  408. printf("ERROR in ViENetwork::StartReceive\n");
  409. return -1;
  410. }
  411. }
  412. // Create a receive channel to verify that it doesn't mess up toggling
  413. // between single stream and simulcast.
  414. int video_channel2 = -1;
  415. error = vie_base->CreateReceiveChannel(video_channel2, video_channel);
  416. if (error == -1) {
  417. printf("ERROR in ViEBase::CreateReceiveChannel\n");
  418. return -1;
  419. }
  420. // *******************************************************
  421. // Engine started
  422. // *******************************************************
  423. printf("\nSimulcast call started\n\n");
  424. do {
  425. printf("Enter new SSRC filter 1,2 or 3\n");
  426. printf("... or 0 to switch between simulcast and a single stream\n");
  427. printf("Press enter to stop...");
  428. str.clear();
  429. std::getline(std::cin, str);
  430. if (!str.empty()) {
  431. int ssrc = atoi(str.c_str());
  432. if (ssrc == 0) {
  433. // Toggle between simulcast and a single stream with different
  434. // resolution.
  435. if (simulcast_mode) {
  436. RuntimeSingleStreamSettings(&video_codec);
  437. num_streams = 1;
  438. printf("Disabling simulcast\n");
  439. } else {
  440. SetSimulcastSettings(&video_codec);
  441. num_streams = video_codec.numberOfSimulcastStreams;
  442. printf("Enabling simulcast\n");
  443. }
  444. simulcast_mode = !simulcast_mode;
  445. if (vie_codec->SetSendCodec(video_channel, video_codec) != 0) {
  446. printf("ERROR switching between simulcast and single stream\n");
  447. return -1;
  448. }
  449. for (int idx = 0; idx < num_streams; idx++) {
  450. error = vie_rtp_rtcp->SetLocalSSRC(video_channel, idx + 1, // SSRC
  451. webrtc::kViEStreamTypeNormal, idx);
  452. if (error == -1) {
  453. printf("ERROR in ViERTP_RTCP::SetLocalSSRC(idx:%d)\n", idx);
  454. return -1;
  455. }
  456. }
  457. if (relay_mode == kRelayOneStream) {
  458. ext_transport.SetSSRCFilter(num_streams);
  459. }
  460. } else if (ssrc > 0 && ssrc < 4) {
  461. if (relay_mode == kRelayOneStream) {
  462. ext_transport.SetSSRCFilter(ssrc);
  463. }
  464. } else {
  465. printf("Invalid SSRC\n");
  466. }
  467. } else {
  468. break;
  469. }
  470. } while (true);
  471. // *******************************************************
  472. // Testing finished. Tear down Video Engine
  473. // *******************************************************
  474. error = vie_base->DeleteChannel(video_channel2);
  475. if (error == -1) {
  476. printf("ERROR in ViEBase::DeleteChannel\n");
  477. return -1;
  478. }
  479. for (int i = 0; i < kNumStreams; ++i) {
  480. error = vie_base->StopReceive(receive_channels[i]);
  481. if (error == -1) {
  482. printf("ERROR in ViEBase::StopReceive\n");
  483. return -1;
  484. }
  485. }
  486. error = vie_base->StopReceive(video_channel);
  487. if (error == -1) {
  488. printf("ERROR in ViEBase::StopReceive\n");
  489. return -1;
  490. }
  491. error = vie_base->StopSend(video_channel);
  492. if (error == -1) {
  493. printf("ERROR in ViEBase::StopSend\n");
  494. return -1;
  495. }
  496. error = vie_render->StopRender(capture_id);
  497. if (error == -1) {
  498. printf("ERROR in ViERender::StopRender\n");
  499. return -1;
  500. }
  501. error = vie_render->RemoveRenderer(capture_id);
  502. if (error == -1) {
  503. printf("ERROR in ViERender::RemoveRenderer\n");
  504. return -1;
  505. }
  506. error = vie_render->StopRender(channel_to_render);
  507. if (error == -1) {
  508. printf("ERROR in ViERender::StopRender\n");
  509. return -1;
  510. }
  511. error = vie_render->RemoveRenderer(channel_to_render);
  512. if (error == -1) {
  513. printf("ERROR in ViERender::RemoveRenderer\n");
  514. return -1;
  515. }
  516. error = vie_capture->StopCapture(capture_id);
  517. if (error == -1) {
  518. printf("ERROR in ViECapture::StopCapture\n");
  519. return -1;
  520. }
  521. error = vie_capture->DisconnectCaptureDevice(video_channel);
  522. if (error == -1) {
  523. printf("ERROR in ViECapture::DisconnectCaptureDevice\n");
  524. return -1;
  525. }
  526. error = vie_capture->ReleaseCaptureDevice(capture_id);
  527. if (error == -1) {
  528. printf("ERROR in ViECapture::ReleaseCaptureDevice\n");
  529. return -1;
  530. }
  531. for (int i = 0; i < kNumStreams; ++i) {
  532. error = vie_base->DeleteChannel(receive_channels[i]);
  533. if (error == -1) {
  534. printf("ERROR in ViEBase::DeleteChannel\n");
  535. return -1;
  536. }
  537. }
  538. error = vie_base->DeleteChannel(video_channel);
  539. if (error == -1) {
  540. printf("ERROR in ViEBase::DeleteChannel\n");
  541. return -1;
  542. }
  543. int remaining_interfaces = 0;
  544. remaining_interfaces = vie_codec->Release();
  545. remaining_interfaces += vie_capture->Release();
  546. remaining_interfaces += vie_rtp_rtcp->Release();
  547. remaining_interfaces += vie_render->Release();
  548. remaining_interfaces += vie_network->Release();
  549. remaining_interfaces += vie_base->Release();
  550. if (remaining_interfaces > 0) {
  551. printf("ERROR: Could not release all interfaces\n");
  552. return -1;
  553. }
  554. bool deleted = webrtc::VideoEngine::Delete(video_engine);
  555. if (deleted == false) {
  556. printf("ERROR in VideoEngine::Delete\n");
  557. return -1;
  558. }
  559. return 0;
  560. }
  561. int ViEAutoTest::ViESimulcastCall() {
  562. ViETest::Log(" ");
  563. ViETest::Log("========================================");
  564. ViETest::Log(" ViE Autotest Simulcast Call\n");
  565. if (VideoEngineSimulcastTest(_window1, _window2) == 0) {
  566. ViETest::Log(" ");
  567. ViETest::Log(" ViE Autotest Simulcast Call Done");
  568. ViETest::Log("========================================");
  569. ViETest::Log(" ");
  570. return 0;
  571. }
  572. ViETest::Log(" ");
  573. ViETest::Log(" ViE Autotest Simulcast Call Failed");
  574. ViETest::Log("========================================");
  575. ViETest::Log(" ");
  576. return 1;
  577. }