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 11 #include "webrtc/common_types.h" 12 #include "webrtc/engine_configurations.h" 13 #include "webrtc/modules/video_coding/codecs/i420/main/interface/i420.h" 14 #include "webrtc/system_wrappers/interface/scoped_ptr.h" 15 #include "webrtc/test/channel_transport/include/channel_transport.h" 16 #include "webrtc/video_engine/include/vie_base.h" 17 #include "webrtc/video_engine/include/vie_capture.h" 18 #include "webrtc/video_engine/include/vie_codec.h" 19 #include "webrtc/video_engine/include/vie_external_codec.h" 20 #include "webrtc/video_engine/include/vie_network.h" 21 #include "webrtc/video_engine/include/vie_render.h" 22 #include "webrtc/video_engine/include/vie_rtp_rtcp.h" 23 #include "webrtc/video_engine/test/auto_test/interface/vie_autotest.h" 24 #include "webrtc/video_engine/test/auto_test/interface/vie_autotest_defines.h" 25 #include "webrtc/video_engine/test/libvietest/include/tb_I420_codec.h" 26 #include "webrtc/video_engine/test/libvietest/include/tb_capture_device.h" 27 #include "webrtc/video_engine/test/libvietest/include/tb_interfaces.h" 28 #include "webrtc/video_engine/test/libvietest/include/tb_video_channel.h" 29 #include "webrtc/voice_engine/include/voe_base.h" 30 31 class TestCodecObserver : public webrtc::ViEEncoderObserver, 32 public webrtc::ViEDecoderObserver { 33 public: 34 int incoming_codec_called_; 35 int incoming_rate_called_; 36 int decoder_timing_called_; 37 int outgoing_rate_called_; 38 39 unsigned char last_payload_type_; 40 uint16_t last_width_; 41 uint16_t last_height_; 42 43 unsigned int last_outgoing_framerate_; 44 unsigned int last_outgoing_bitrate_; 45 unsigned int last_incoming_framerate_; 46 unsigned int last_incoming_bitrate_; 47 unsigned int suspend_change_called_; 48 49 webrtc::VideoCodec incoming_codec_; 50 51 TestCodecObserver() 52 : incoming_codec_called_(0), 53 incoming_rate_called_(0), 54 decoder_timing_called_(0), 55 outgoing_rate_called_(0), 56 last_payload_type_(0), 57 last_width_(0), 58 last_height_(0), 59 last_outgoing_framerate_(0), 60 last_outgoing_bitrate_(0), 61 last_incoming_framerate_(0), 62 last_incoming_bitrate_(0), 63 suspend_change_called_(0) { 64 memset(&incoming_codec_, 0, sizeof(incoming_codec_)); 65 } 66 virtual void IncomingCodecChanged(const int video_channel, 67 const webrtc::VideoCodec& video_codec) { 68 incoming_codec_called_++; 69 last_payload_type_ = video_codec.plType; 70 last_width_ = video_codec.width; 71 last_height_ = video_codec.height; 72 73 memcpy(&incoming_codec_, &video_codec, sizeof(video_codec)); 74 } 75 76 virtual void IncomingRate(const int video_channel, 77 const unsigned int framerate, 78 const unsigned int bitrate) { 79 incoming_rate_called_++; 80 last_incoming_framerate_ += framerate; 81 last_incoming_bitrate_ += bitrate; 82 } 83 84 virtual void DecoderTiming(int decode_ms, 85 int max_decode_ms, 86 int current_delay_ms, 87 int target_delay_ms, 88 int jitter_buffer_ms, 89 int min_playout_delay_ms, 90 int render_delay_ms) { 91 ++decoder_timing_called_; 92 // TODO(fischman): anything useful to be done with the data here? 93 } 94 95 virtual void OutgoingRate(const int video_channel, 96 const unsigned int framerate, 97 const unsigned int bitrate) { 98 outgoing_rate_called_++; 99 last_outgoing_framerate_ += framerate; 100 last_outgoing_bitrate_ += bitrate; 101 } 102 103 virtual void SuspendChange(int video_channel, bool is_suspended) OVERRIDE { 104 suspend_change_called_++; 105 } 106 107 virtual void RequestNewKeyFrame(const int video_channel) { 108 } 109 }; 110 111 class RenderFilter : public webrtc::ViEEffectFilter { 112 public: 113 int num_frames_; 114 unsigned int last_render_width_; 115 unsigned int last_render_height_; 116 117 RenderFilter() 118 : num_frames_(0), 119 last_render_width_(0), 120 last_render_height_(0) { 121 } 122 123 virtual ~RenderFilter() { 124 } 125 virtual int Transform(int size, 126 unsigned char* frame_buffer, 127 int64_t ntp_time_ms, 128 unsigned int timestamp, 129 unsigned int width, 130 unsigned int height) { 131 num_frames_++; 132 last_render_width_ = width; 133 last_render_height_ = height; 134 return 0; 135 } 136 }; 137 138 void ViEAutoTest::ViECodecStandardTest() { 139 TbInterfaces interfaces("ViECodecStandardTest"); 140 141 TbCaptureDevice capture_device = TbCaptureDevice(interfaces); 142 int capture_id = capture_device.captureId; 143 144 webrtc::VideoEngine* video_engine = interfaces.video_engine; 145 webrtc::ViEBase* base = interfaces.base; 146 webrtc::ViECapture* capture = interfaces.capture; 147 webrtc::ViERender* render = interfaces.render; 148 webrtc::ViECodec* codec = interfaces.codec; 149 webrtc::ViERTP_RTCP* rtp_rtcp = interfaces.rtp_rtcp; 150 webrtc::ViENetwork* network = interfaces.network; 151 152 int video_channel = -1; 153 EXPECT_EQ(0, base->CreateChannel(video_channel)); 154 EXPECT_EQ(0, capture->ConnectCaptureDevice(capture_id, video_channel)); 155 EXPECT_EQ(0, rtp_rtcp->SetRTCPStatus( 156 video_channel, webrtc::kRtcpCompound_RFC4585)); 157 158 EXPECT_EQ(0, rtp_rtcp->SetKeyFrameRequestMethod( 159 video_channel, webrtc::kViEKeyFrameRequestPliRtcp)); 160 EXPECT_EQ(0, rtp_rtcp->SetTMMBRStatus(video_channel, true)); 161 EXPECT_EQ(0, render->AddRenderer(capture_id, _window1, 0, 0.0, 0.0, 1.0, 162 1.0)); 163 EXPECT_EQ(0, render->AddRenderer(video_channel, _window2, 1, 0.0, 0.0, 1.0, 164 1.0)); 165 EXPECT_EQ(0, render->StartRender(capture_id)); 166 EXPECT_EQ(0, render->StartRender(video_channel)); 167 168 webrtc::VideoCodec video_codec; 169 memset(&video_codec, 0, sizeof(webrtc::VideoCodec)); 170 for (int idx = 0; idx < codec->NumberOfCodecs(); idx++) { 171 EXPECT_EQ(0, codec->GetCodec(idx, video_codec)); 172 if (video_codec.codecType != webrtc::kVideoCodecI420) { 173 video_codec.width = 640; 174 video_codec.height = 480; 175 } 176 if (video_codec.codecType == webrtc::kVideoCodecI420) { 177 video_codec.width = 176; 178 video_codec.height = 144; 179 } 180 EXPECT_EQ(0, codec->SetReceiveCodec(video_channel, video_codec)); 181 } 182 183 for (int idx = 0; idx < codec->NumberOfCodecs(); idx++) { 184 EXPECT_EQ(0, codec->GetCodec(idx, video_codec)); 185 if (video_codec.codecType == webrtc::kVideoCodecVP8) { 186 EXPECT_EQ(0, codec->SetSendCodec(video_channel, video_codec)); 187 break; 188 } 189 } 190 const char* ip_address = "127.0.0.1"; 191 const uint16_t rtp_port = 6000; 192 193 webrtc::scoped_ptr<webrtc::test::VideoChannelTransport> 194 video_channel_transport( 195 new webrtc::test::VideoChannelTransport(network, video_channel)); 196 197 ASSERT_EQ(0, video_channel_transport->SetSendDestination(ip_address, 198 rtp_port)); 199 ASSERT_EQ(0, video_channel_transport->SetLocalReceiver(rtp_port)); 200 201 EXPECT_EQ(0, base->StartReceive(video_channel)); 202 EXPECT_EQ(0, base->StartSend(video_channel)); 203 204 // Make sure all codecs runs 205 { 206 webrtc::ViEImageProcess* image_process = 207 webrtc::ViEImageProcess::GetInterface(video_engine); 208 TestCodecObserver codec_observer; 209 EXPECT_EQ(0, codec->RegisterDecoderObserver(video_channel, codec_observer)); 210 ViETest::Log("Loop through all codecs for %d seconds", 211 kAutoTestSleepTimeMs / 1000); 212 213 for (int i = 0; i < codec->NumberOfCodecs() - 2; i++) { 214 EXPECT_EQ(0, codec->GetCodec(i, video_codec)); 215 if (video_codec.codecType == webrtc::kVideoCodecI420) { 216 // Lower resolution to sockets keep up. 217 video_codec.width = 176; 218 video_codec.height = 144; 219 video_codec.maxFramerate = 15; 220 } 221 EXPECT_EQ(0, codec->SetSendCodec(video_channel, video_codec)); 222 ViETest::Log("\t %d. %s", i, video_codec.plName); 223 224 RenderFilter frame_counter; 225 EXPECT_EQ(0, image_process->RegisterRenderEffectFilter(video_channel, 226 frame_counter)); 227 AutoTestSleep(kAutoTestSleepTimeMs); 228 229 // Verify we've received and decoded correct payload. 230 EXPECT_EQ(video_codec.codecType, 231 codec_observer.incoming_codec_.codecType); 232 233 // This requirement is quite relaxed, but it's hard to say what's an 234 // acceptable number of received frames when we take into account the 235 // wide variety of devices (and that we run under valgrind). 236 EXPECT_GT(frame_counter.num_frames_, 0); 237 238 EXPECT_EQ(0, image_process->DeregisterRenderEffectFilter( 239 video_channel)); 240 } 241 image_process->Release(); 242 EXPECT_EQ(0, codec->DeregisterDecoderObserver(video_channel)); 243 ViETest::Log("Done!"); 244 } 245 246 // Test Callbacks 247 TestCodecObserver codec_observer; 248 EXPECT_EQ(0, codec->RegisterEncoderObserver(video_channel, codec_observer)); 249 EXPECT_EQ(0, codec->RegisterDecoderObserver(video_channel, codec_observer)); 250 251 ViETest::Log("\nTesting codec callbacks..."); 252 253 for (int idx = 0; idx < codec->NumberOfCodecs(); idx++) { 254 EXPECT_EQ(0, codec->GetCodec(idx, video_codec)); 255 if (video_codec.codecType == webrtc::kVideoCodecVP8) { 256 EXPECT_EQ(0, codec->SetSendCodec(video_channel, video_codec)); 257 break; 258 } 259 } 260 AutoTestSleep(kAutoTestSleepTimeMs); 261 262 // Verify the delay estimates are larger than 0. 263 int avg_send_delay = 0; 264 int max_send_delay = 0; 265 EXPECT_TRUE(codec->GetSendSideDelay(video_channel, &avg_send_delay, 266 &max_send_delay)); 267 EXPECT_GT(avg_send_delay, 0); 268 EXPECT_GE(max_send_delay, avg_send_delay); 269 int receive_delay_ms = 0; 270 EXPECT_EQ(0, codec->GetReceiveSideDelay(video_channel, &receive_delay_ms)); 271 EXPECT_GT(receive_delay_ms, 0); 272 273 EXPECT_EQ(0, base->StopSend(video_channel)); 274 EXPECT_EQ(0, codec->DeregisterEncoderObserver(video_channel)); 275 EXPECT_EQ(0, codec->DeregisterDecoderObserver(video_channel)); 276 277 EXPECT_GT(codec_observer.incoming_codec_called_, 0); 278 EXPECT_GT(codec_observer.incoming_rate_called_, 0); 279 EXPECT_GT(codec_observer.decoder_timing_called_, 0); 280 EXPECT_GT(codec_observer.outgoing_rate_called_, 0); 281 282 EXPECT_EQ(0, base->StopReceive(video_channel)); 283 EXPECT_EQ(0, render->StopRender(video_channel)); 284 EXPECT_EQ(0, render->RemoveRenderer(capture_id)); 285 EXPECT_EQ(0, render->RemoveRenderer(video_channel)); 286 EXPECT_EQ(0, capture->DisconnectCaptureDevice(video_channel)); 287 EXPECT_EQ(0, base->DeleteChannel(video_channel)); 288 } 289 290 void ViEAutoTest::ViECodecExtendedTest() { 291 { 292 ViETest::Log(" "); 293 ViETest::Log("========================================"); 294 ViETest::Log(" ViECodec Extended Test\n"); 295 296 ViECodecExternalCodecTest(); 297 298 TbInterfaces interfaces("ViECodecExtendedTest"); 299 webrtc::ViEBase* base = interfaces.base; 300 webrtc::ViECapture* capture = interfaces.capture; 301 webrtc::ViERender* render = interfaces.render; 302 webrtc::ViECodec* codec = interfaces.codec; 303 webrtc::ViERTP_RTCP* rtp_rtcp = interfaces.rtp_rtcp; 304 webrtc::ViENetwork* network = interfaces.network; 305 306 TbCaptureDevice capture_device = TbCaptureDevice(interfaces); 307 int capture_id = capture_device.captureId; 308 309 int video_channel = -1; 310 EXPECT_EQ(0, base->CreateChannel(video_channel)); 311 EXPECT_EQ(0, capture->ConnectCaptureDevice(capture_id, video_channel)); 312 EXPECT_EQ(0, rtp_rtcp->SetRTCPStatus( 313 video_channel, webrtc::kRtcpCompound_RFC4585)); 314 EXPECT_EQ(0, rtp_rtcp->SetKeyFrameRequestMethod( 315 video_channel, webrtc::kViEKeyFrameRequestPliRtcp)); 316 EXPECT_EQ(0, rtp_rtcp->SetTMMBRStatus(video_channel, true)); 317 EXPECT_EQ(0, render->AddRenderer(capture_id, _window1, 0, 0.0, 0.0, 1.0, 318 1.0)); 319 320 EXPECT_EQ(0, render->AddRenderer(video_channel, _window2, 1, 0.0, 0.0, 1.0, 321 1.0)); 322 EXPECT_EQ(0, render->StartRender(capture_id)); 323 EXPECT_EQ(0, render->StartRender(video_channel)); 324 325 webrtc::VideoCodec video_codec; 326 memset(&video_codec, 0, sizeof(webrtc::VideoCodec)); 327 for (int idx = 0; idx < codec->NumberOfCodecs(); idx++) { 328 EXPECT_EQ(0, codec->GetCodec(idx, video_codec)); 329 if (video_codec.codecType != webrtc::kVideoCodecI420) { 330 video_codec.width = 640; 331 video_codec.height = 480; 332 } 333 EXPECT_EQ(0, codec->SetReceiveCodec(video_channel, video_codec)); 334 } 335 336 const char* ip_address = "127.0.0.1"; 337 const uint16_t rtp_port = 6000; 338 339 webrtc::scoped_ptr<webrtc::test::VideoChannelTransport> 340 video_channel_transport( 341 new webrtc::test::VideoChannelTransport(network, video_channel)); 342 343 ASSERT_EQ(0, video_channel_transport->SetSendDestination(ip_address, 344 rtp_port)); 345 ASSERT_EQ(0, video_channel_transport->SetLocalReceiver(rtp_port)); 346 347 EXPECT_EQ(0, base->StartSend(video_channel)); 348 EXPECT_EQ(0, base->StartReceive(video_channel)); 349 350 // Codec specific tests 351 memset(&video_codec, 0, sizeof(webrtc::VideoCodec)); 352 EXPECT_EQ(0, base->StopSend(video_channel)); 353 354 TestCodecObserver codec_observer; 355 EXPECT_EQ(0, codec->RegisterEncoderObserver(video_channel, codec_observer)); 356 EXPECT_EQ(0, codec->RegisterDecoderObserver(video_channel, codec_observer)); 357 EXPECT_EQ(0, base->StopReceive(video_channel)); 358 359 EXPECT_EQ(0, render->StopRender(video_channel)); 360 EXPECT_EQ(0, render->RemoveRenderer(capture_id)); 361 EXPECT_EQ(0, render->RemoveRenderer(video_channel)); 362 EXPECT_EQ(0, capture->DisconnectCaptureDevice(video_channel)); 363 EXPECT_EQ(0, base->DeleteChannel(video_channel)); 364 } 365 366 // Multiple send channels. 367 { 368 // Create two channels, where the second channel is created from the 369 // first channel. Send different resolutions on the channels and verify 370 // the received streams. 371 TbInterfaces video_engine("ViECodecExtendedTest2"); 372 TbCaptureDevice tb_capture(video_engine); 373 webrtc::ViENetwork* network = video_engine.network; 374 375 // Create channel 1. 376 int video_channel_1 = -1; 377 EXPECT_EQ(0, video_engine.base->CreateChannel(video_channel_1)); 378 379 // Create channel 2 based on the first channel. 380 int video_channel_2 = -1; 381 EXPECT_EQ(0, video_engine.base->CreateChannel( 382 video_channel_2, video_channel_1)); 383 EXPECT_NE(video_channel_1, video_channel_2) 384 << "Channel 2 should be unique."; 385 386 const char* ip_address = "127.0.0.1"; 387 uint16_t rtp_port_1 = 12000; 388 uint16_t rtp_port_2 = 13000; 389 390 webrtc::scoped_ptr<webrtc::test::VideoChannelTransport> 391 video_channel_transport_1( 392 new webrtc::test::VideoChannelTransport(network, video_channel_1)); 393 394 ASSERT_EQ(0, video_channel_transport_1->SetSendDestination(ip_address, 395 rtp_port_1)); 396 ASSERT_EQ(0, video_channel_transport_1->SetLocalReceiver(rtp_port_1)); 397 398 webrtc::scoped_ptr<webrtc::test::VideoChannelTransport> 399 video_channel_transport_2( 400 new webrtc::test::VideoChannelTransport(network, video_channel_2)); 401 402 ASSERT_EQ(0, video_channel_transport_2->SetSendDestination(ip_address, 403 rtp_port_2)); 404 ASSERT_EQ(0, video_channel_transport_2->SetLocalReceiver(rtp_port_2)); 405 406 EXPECT_EQ(0, video_engine.rtp_rtcp->SetLocalSSRC(video_channel_1, 1)); 407 EXPECT_EQ(0, video_engine.rtp_rtcp->SetLocalSSRC(video_channel_2, 2)); 408 tb_capture.ConnectTo(video_channel_1); 409 tb_capture.ConnectTo(video_channel_2); 410 EXPECT_EQ(0, video_engine.rtp_rtcp->SetKeyFrameRequestMethod( 411 video_channel_1, webrtc::kViEKeyFrameRequestPliRtcp)); 412 EXPECT_EQ(0, video_engine.rtp_rtcp->SetKeyFrameRequestMethod( 413 video_channel_2, webrtc::kViEKeyFrameRequestPliRtcp)); 414 EXPECT_EQ(0, video_engine.render->AddRenderer(video_channel_1, _window1, 0, 415 0.0, 0.0, 1.0, 1.0)); 416 EXPECT_EQ(0, video_engine.render->StartRender(video_channel_1)); 417 EXPECT_EQ(0, video_engine.render->AddRenderer(video_channel_2, _window2, 0, 418 0.0, 0.0, 1.0, 1.0)); 419 EXPECT_EQ(0, video_engine.render->StartRender(video_channel_2)); 420 421 // Set Send codec. 422 uint16_t codec_width = 320; 423 uint16_t codec_height = 240; 424 bool codec_set = false; 425 webrtc::VideoCodec video_codec; 426 webrtc::VideoCodec send_codec1; 427 webrtc::VideoCodec send_codec2; 428 for (int idx = 0; idx < video_engine.codec->NumberOfCodecs(); idx++) { 429 EXPECT_EQ(0, video_engine.codec->GetCodec(idx, video_codec)); 430 EXPECT_EQ(0, video_engine.codec->SetReceiveCodec(video_channel_1, 431 video_codec)); 432 if (video_codec.codecType == webrtc::kVideoCodecVP8) { 433 memcpy(&send_codec1, &video_codec, sizeof(video_codec)); 434 send_codec1.width = codec_width; 435 send_codec1.height = codec_height; 436 EXPECT_EQ(0, video_engine.codec->SetSendCodec( 437 video_channel_1, send_codec1)); 438 memcpy(&send_codec2, &video_codec, sizeof(video_codec)); 439 send_codec2.width = 2 * codec_width; 440 send_codec2.height = 2 * codec_height; 441 EXPECT_EQ(0, video_engine.codec->SetSendCodec( 442 video_channel_2, send_codec2)); 443 codec_set = true; 444 break; 445 } 446 } 447 EXPECT_TRUE(codec_set); 448 449 // We need to verify using render effect filter since we won't trigger 450 // a decode reset in loopback (due to using the same SSRC). 451 RenderFilter filter1; 452 RenderFilter filter2; 453 EXPECT_EQ(0, video_engine.image_process->RegisterRenderEffectFilter( 454 video_channel_1, filter1)); 455 EXPECT_EQ(0, video_engine.image_process->RegisterRenderEffectFilter( 456 video_channel_2, filter2)); 457 458 EXPECT_EQ(0, video_engine.base->StartReceive(video_channel_1)); 459 EXPECT_EQ(0, video_engine.base->StartSend(video_channel_1)); 460 EXPECT_EQ(0, video_engine.base->StartReceive(video_channel_2)); 461 EXPECT_EQ(0, video_engine.base->StartSend(video_channel_2)); 462 463 AutoTestSleep(kAutoTestSleepTimeMs); 464 465 EXPECT_EQ(0, video_engine.base->StopReceive(video_channel_1)); 466 EXPECT_EQ(0, video_engine.base->StopSend(video_channel_1)); 467 EXPECT_EQ(0, video_engine.base->StopReceive(video_channel_2)); 468 EXPECT_EQ(0, video_engine.base->StopSend(video_channel_2)); 469 470 EXPECT_EQ(0, video_engine.image_process->DeregisterRenderEffectFilter( 471 video_channel_1)); 472 EXPECT_EQ(0, video_engine.image_process->DeregisterRenderEffectFilter( 473 video_channel_2)); 474 EXPECT_EQ(send_codec1.width, filter1.last_render_width_); 475 EXPECT_EQ(send_codec1.height, filter1.last_render_height_); 476 EXPECT_EQ(send_codec2.width, filter2.last_render_width_); 477 EXPECT_EQ(send_codec2.height, filter2.last_render_height_); 478 479 EXPECT_EQ(0, video_engine.base->DeleteChannel(video_channel_1)); 480 EXPECT_EQ(0, video_engine.base->DeleteChannel(video_channel_2)); 481 } 482 } 483 484 void ViEAutoTest::ViECodecAPITest() { 485 webrtc::VideoEngine* video_engine = NULL; 486 video_engine = webrtc::VideoEngine::Create(); 487 EXPECT_TRUE(video_engine != NULL); 488 489 webrtc::ViEBase* base = webrtc::ViEBase::GetInterface(video_engine); 490 EXPECT_EQ(0, base->Init()); 491 492 int video_channel = -1; 493 EXPECT_EQ(0, base->CreateChannel(video_channel)); 494 495 webrtc::ViECodec* codec = webrtc::ViECodec::GetInterface(video_engine); 496 EXPECT_TRUE(codec != NULL); 497 498 webrtc::VideoCodec video_codec; 499 memset(&video_codec, 0, sizeof(webrtc::VideoCodec)); 500 501 const int number_of_codecs = codec->NumberOfCodecs(); 502 503 for (int i = 0; i < number_of_codecs; i++) { 504 EXPECT_EQ(0, codec->GetCodec(i, video_codec)); 505 if (video_codec.codecType == webrtc::kVideoCodecVP8) { 506 video_codec.codecSpecific.VP8.automaticResizeOn = true; 507 video_codec.codecSpecific.VP8.frameDroppingOn = true; 508 video_codec.codecSpecific.VP8.keyFrameInterval = 300; 509 EXPECT_EQ(0, codec->SetSendCodec(video_channel, video_codec)); 510 break; 511 } 512 } 513 const unsigned int kMinBitrate = 123; 514 video_codec.minBitrate = kMinBitrate; 515 video_codec.startBitrate = 50; 516 EXPECT_EQ(0, codec->SetSendCodec(video_channel, video_codec)); 517 EXPECT_EQ(0, codec->GetSendCodec(video_channel, video_codec)); 518 EXPECT_EQ(kMinBitrate, video_codec.startBitrate); 519 520 memset(&video_codec, 0, sizeof(video_codec)); 521 EXPECT_EQ(0, codec->GetSendCodec(video_channel, video_codec)); 522 EXPECT_EQ(webrtc::kVideoCodecVP8, video_codec.codecType); 523 EXPECT_TRUE(video_codec.codecSpecific.VP8.automaticResizeOn); 524 EXPECT_TRUE(video_codec.codecSpecific.VP8.frameDroppingOn); 525 EXPECT_EQ(300, video_codec.codecSpecific.VP8.keyFrameInterval); 526 527 for (int i = 0; i < number_of_codecs; i++) { 528 EXPECT_EQ(0, codec->GetCodec(i, video_codec)); 529 if (video_codec.codecType == webrtc::kVideoCodecI420) { 530 EXPECT_EQ(0, codec->SetSendCodec(video_channel, video_codec)); 531 break; 532 } 533 } 534 535 memset(&video_codec, 0, sizeof(video_codec)); 536 EXPECT_EQ(0, codec->GetSendCodec(video_channel, video_codec)); 537 EXPECT_EQ(webrtc::kVideoCodecI420, video_codec.codecType); 538 539 // Register a generic codec 540 memset(&video_codec, 0, sizeof(video_codec)); 541 video_codec.codecType = webrtc::kVideoCodecGeneric; 542 strcpy(video_codec.plName, "generic-codec"); 543 uint8_t payload_type = 127; 544 video_codec.plType = payload_type; 545 video_codec.minBitrate = 100; 546 video_codec.startBitrate = 500; 547 video_codec.maxBitrate = 10000; 548 video_codec.width = 1920; 549 video_codec.height = 1080; 550 video_codec.maxFramerate = 30; 551 video_codec.qpMax = 50; 552 553 webrtc::ViEExternalCodec* external_codec = 554 webrtc::ViEExternalCodec::GetInterface(video_engine); 555 EXPECT_TRUE(external_codec != NULL); 556 557 // Any encoder will do. 558 webrtc::I420Encoder encoder; 559 EXPECT_EQ(0, external_codec->RegisterExternalSendCodec(video_channel, 560 payload_type, &encoder, 561 false)); 562 EXPECT_EQ(0, codec->SetSendCodec(video_channel, video_codec)); 563 564 memset(&video_codec, 0, sizeof(video_codec)); 565 EXPECT_EQ(0, codec->GetSendCodec(video_channel, video_codec)); 566 EXPECT_EQ(webrtc::kVideoCodecGeneric, video_codec.codecType); 567 568 EXPECT_EQ(0, base->DeleteChannel(video_channel)); 569 570 EXPECT_EQ(0, external_codec->Release()); 571 EXPECT_EQ(0, codec->Release()); 572 EXPECT_EQ(0, base->Release()); 573 EXPECT_TRUE(webrtc::VideoEngine::Delete(video_engine)); 574 } 575 576 void ViEAutoTest::ViECodecExternalCodecTest() { 577 ViETest::Log(" "); 578 ViETest::Log("========================================"); 579 ViETest::Log(" ViEExternalCodec Test\n"); 580 581 /// ************************************************************** 582 // Begin create/initialize WebRTC Video Engine for testing 583 /// ************************************************************** 584 585 /// ************************************************************** 586 // Engine ready. Begin testing class 587 /// ************************************************************** 588 589 #ifdef WEBRTC_VIDEO_ENGINE_EXTERNAL_CODEC_API 590 int number_of_errors = 0; 591 { 592 int error = 0; 593 TbInterfaces ViE("ViEExternalCodec"); 594 TbCaptureDevice capture_device(ViE); 595 TbVideoChannel channel(ViE, webrtc::kVideoCodecI420, 352, 288, 30, 596 (352 * 288 * 3 * 8 * 30) / (2 * 1000)); 597 capture_device.ConnectTo(channel.videoChannel); 598 599 error = ViE.render->AddRenderer(channel.videoChannel, _window1, 0, 0.0, 0.0, 600 1.0, 1.0); 601 number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d", 602 __FUNCTION__, __LINE__); 603 error = ViE.render->StartRender(channel.videoChannel); 604 number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d", 605 __FUNCTION__, __LINE__); 606 607 channel.StartReceive(); 608 channel.StartSend(); 609 610 ViETest::Log("Using internal I420 codec"); 611 AutoTestSleep(kAutoTestSleepTimeMs / 2); 612 613 webrtc::ViEExternalCodec* vie_external_codec = 614 webrtc::ViEExternalCodec::GetInterface(ViE.video_engine); 615 number_of_errors += ViETest::TestError(vie_external_codec != NULL, 616 "ERROR: %s at line %d", 617 __FUNCTION__, __LINE__); 618 webrtc::VideoCodec codec; 619 error = ViE.codec->GetSendCodec(channel.videoChannel, codec); 620 number_of_errors += ViETest::TestError(vie_external_codec != NULL, 621 "ERROR: %s at line %d", 622 __FUNCTION__, __LINE__); 623 624 // Use external encoder instead. 625 { 626 TbI420Encoder ext_encoder; 627 628 // Test to register on wrong channel. 629 error = vie_external_codec->RegisterExternalSendCodec( 630 channel.videoChannel + 5, codec.plType, &ext_encoder, false); 631 number_of_errors += ViETest::TestError(error == -1, 632 "ERROR: %s at line %d", 633 __FUNCTION__, __LINE__); 634 number_of_errors += ViETest::TestError( 635 ViE.LastError() == kViECodecInvalidArgument, 636 "ERROR: %s at line %d", __FUNCTION__, __LINE__); 637 638 error = vie_external_codec->RegisterExternalSendCodec( 639 channel.videoChannel, codec.plType, &ext_encoder, false); 640 number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d", 641 __FUNCTION__, __LINE__); 642 643 // Use new external encoder 644 error = ViE.codec->SetSendCodec(channel.videoChannel, codec); 645 number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d", 646 __FUNCTION__, __LINE__); 647 648 TbI420Decoder ext_decoder; 649 error = vie_external_codec->RegisterExternalReceiveCodec( 650 channel.videoChannel, codec.plType, &ext_decoder); 651 number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d", 652 __FUNCTION__, __LINE__); 653 654 error = ViE.codec->SetReceiveCodec(channel.videoChannel, codec); 655 number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d", 656 __FUNCTION__, __LINE__); 657 658 ViETest::Log("Using external I420 codec"); 659 AutoTestSleep(kAutoTestSleepTimeMs); 660 661 // Test to deregister on wrong channel 662 error = vie_external_codec->DeRegisterExternalSendCodec( 663 channel.videoChannel + 5, codec.plType); 664 number_of_errors += ViETest::TestError(error == -1, 665 "ERROR: %s at line %d", 666 __FUNCTION__, __LINE__); 667 number_of_errors += ViETest::TestError( 668 ViE.LastError() == kViECodecInvalidArgument, "ERROR: %s at line %d", 669 __FUNCTION__, __LINE__); 670 671 // Test to deregister wrong payload type. 672 error = vie_external_codec->DeRegisterExternalSendCodec( 673 channel.videoChannel, codec.plType - 1); 674 number_of_errors += ViETest::TestError(error == -1, 675 "ERROR: %s at line %d", 676 __FUNCTION__, __LINE__); 677 678 // Deregister external send codec 679 error = vie_external_codec->DeRegisterExternalSendCodec( 680 channel.videoChannel, codec.plType); 681 number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d", 682 __FUNCTION__, __LINE__); 683 684 error = vie_external_codec->DeRegisterExternalReceiveCodec( 685 channel.videoChannel, codec.plType); 686 number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d", 687 __FUNCTION__, __LINE__); 688 689 // Verify that the encoder and decoder has been used 690 TbI420Encoder::FunctionCalls encode_calls = 691 ext_encoder.GetFunctionCalls(); 692 number_of_errors += ViETest::TestError(encode_calls.InitEncode == 1, 693 "ERROR: %s at line %d", 694 __FUNCTION__, __LINE__); 695 number_of_errors += ViETest::TestError(encode_calls.Release == 1, 696 "ERROR: %s at line %d", 697 __FUNCTION__, __LINE__); 698 number_of_errors += ViETest::TestError(encode_calls.Encode > 30, 699 "ERROR: %s at line %d", 700 __FUNCTION__, __LINE__); 701 number_of_errors += ViETest::TestError( 702 encode_calls.RegisterEncodeCompleteCallback == 1, 703 "ERROR: %s at line %d", __FUNCTION__, __LINE__); 704 number_of_errors += ViETest::TestError( 705 encode_calls.SetChannelParameters > 1, "ERROR: %s at line %d", 706 __FUNCTION__, __LINE__); 707 number_of_errors += ViETest::TestError(encode_calls.SetRates > 1, 708 "ERROR: %s at line %d", 709 __FUNCTION__, __LINE__); 710 711 TbI420Decoder::FunctionCalls decode_calls = 712 ext_decoder.GetFunctionCalls(); 713 number_of_errors += ViETest::TestError(decode_calls.InitDecode == 1, 714 "ERROR: %s at line %d", 715 __FUNCTION__, __LINE__); 716 number_of_errors += ViETest::TestError(decode_calls.Release == 1, 717 "ERROR: %s at line %d", 718 __FUNCTION__, __LINE__); 719 number_of_errors += ViETest::TestError(decode_calls.Decode > 30, 720 "ERROR: %s at line %d", 721 __FUNCTION__, __LINE__); 722 number_of_errors += ViETest::TestError( 723 decode_calls.RegisterDecodeCompleteCallback == 1, 724 "ERROR: %s at line %d", __FUNCTION__, __LINE__); 725 726 ViETest::Log("Changing payload type Using external I420 codec"); 727 728 codec.plType = codec.plType - 1; 729 error = vie_external_codec->RegisterExternalReceiveCodec( 730 channel.videoChannel, codec.plType, &ext_decoder); 731 number_of_errors += ViETest::TestError(error == 0, 732 "ERROR: %s at line %d", 733 __FUNCTION__, __LINE__); 734 735 error = ViE.codec->SetReceiveCodec(channel.videoChannel, 736 codec); 737 number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d", 738 __FUNCTION__, __LINE__); 739 740 error = vie_external_codec->RegisterExternalSendCodec( 741 channel.videoChannel, codec.plType, &ext_encoder, false); 742 number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d", 743 __FUNCTION__, __LINE__); 744 745 // Use new external encoder 746 error = ViE.codec->SetSendCodec(channel.videoChannel, 747 codec); 748 number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d", 749 __FUNCTION__, __LINE__); 750 751 AutoTestSleep(kAutoTestSleepTimeMs / 2); 752 753 /// ************************************************************** 754 // Testing finished. Tear down Video Engine 755 /// ************************************************************** 756 757 error = vie_external_codec->DeRegisterExternalSendCodec( 758 channel.videoChannel, codec.plType); 759 number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d", 760 __FUNCTION__, __LINE__); 761 error = vie_external_codec->DeRegisterExternalReceiveCodec( 762 channel.videoChannel, codec.plType); 763 number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d", 764 __FUNCTION__, __LINE__); 765 766 // Verify that the encoder and decoder has been used 767 encode_calls = ext_encoder.GetFunctionCalls(); 768 number_of_errors += ViETest::TestError(encode_calls.InitEncode == 2, 769 "ERROR: %s at line %d", 770 __FUNCTION__, __LINE__); 771 number_of_errors += ViETest::TestError(encode_calls.Release == 2, 772 "ERROR: %s at line %d", 773 __FUNCTION__, __LINE__); 774 number_of_errors += ViETest::TestError(encode_calls.Encode > 30, 775 "ERROR: %s at line %d", 776 __FUNCTION__, __LINE__); 777 number_of_errors += ViETest::TestError( 778 encode_calls.RegisterEncodeCompleteCallback == 2, 779 "ERROR: %s at line %d", __FUNCTION__, __LINE__); 780 number_of_errors += ViETest::TestError( 781 encode_calls.SetChannelParameters > 1, "ERROR: %s at line %d", 782 __FUNCTION__, __LINE__); 783 number_of_errors += ViETest::TestError(encode_calls.SetRates > 1, 784 "ERROR: %s at line %d", 785 __FUNCTION__, __LINE__); 786 decode_calls = ext_decoder.GetFunctionCalls(); 787 number_of_errors += ViETest::TestError(decode_calls.InitDecode == 2, 788 "ERROR: %s at line %d", 789 __FUNCTION__, __LINE__); 790 number_of_errors += ViETest::TestError(decode_calls.Release == 2, 791 "ERROR: %s at line %d", 792 __FUNCTION__, __LINE__); 793 number_of_errors += ViETest::TestError(decode_calls.Decode > 30, 794 "ERROR: %s at line %d", 795 __FUNCTION__, __LINE__); 796 number_of_errors += ViETest::TestError( 797 decode_calls.RegisterDecodeCompleteCallback == 2, 798 "ERROR: %s at line %d", __FUNCTION__, __LINE__); 799 800 int remaining_interfaces = vie_external_codec->Release(); 801 number_of_errors += ViETest::TestError(remaining_interfaces == 0, 802 "ERROR: %s at line %d", 803 __FUNCTION__, __LINE__); 804 } // tbI420Encoder and ext_decoder goes out of scope. 805 806 ViETest::Log("Using internal I420 codec"); 807 AutoTestSleep(kAutoTestSleepTimeMs / 2); 808 } 809 if (number_of_errors > 0) { 810 // Test failed 811 ViETest::Log(" "); 812 ViETest::Log(" ERROR ViEExternalCodec Test FAILED!"); 813 ViETest::Log(" Number of errors: %d", number_of_errors); 814 ViETest::Log("========================================"); 815 ViETest::Log(" "); 816 return; 817 } 818 819 ViETest::Log(" "); 820 ViETest::Log(" ViEExternalCodec Test PASSED!"); 821 ViETest::Log("========================================"); 822 ViETest::Log(" "); 823 return; 824 825 #else 826 ViETest::Log(" ViEExternalCodec not enabled\n"); 827 return; 828 #endif 829 } 830