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
TestCodecObserver()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 }
IncomingCodecChanged(const int video_channel,const webrtc::VideoCodec & video_codec)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
IncomingRate(const int video_channel,const unsigned int framerate,const unsigned int bitrate)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
DecoderTiming(int decode_ms,int max_decode_ms,int current_delay_ms,int target_delay_ms,int jitter_buffer_ms,int min_playout_delay_ms,int render_delay_ms)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
OutgoingRate(const int video_channel,const unsigned int framerate,const unsigned int bitrate)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
SuspendChange(int video_channel,bool is_suspended)103 virtual void SuspendChange(int video_channel, bool is_suspended) OVERRIDE {
104 suspend_change_called_++;
105 }
106
RequestNewKeyFrame(const int video_channel)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
RenderFilter()117 RenderFilter()
118 : num_frames_(0),
119 last_render_width_(0),
120 last_render_height_(0) {
121 }
122
~RenderFilter()123 virtual ~RenderFilter() {
124 }
Transform(int size,unsigned char * frame_buffer,int64_t ntp_time_ms,unsigned int timestamp,unsigned int width,unsigned int height)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
ViECodecStandardTest()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
ViECodecExtendedTest()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
ViECodecAPITest()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
ViECodecExternalCodecTest()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