blob: 7c9b61121e33b91a01427dbf0b5cd48d06d25d01 [file] [log] [blame]
pbos@webrtc.org29d58392013-05-16 12:08:03 +00001/*
2 * Copyright (c) 2013 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
pbos@webrtc.org12dc1a32013-08-05 16:22:53 +000011#include <stdio.h>
12
pbos@webrtc.org29d58392013-05-16 12:08:03 +000013#include <map>
14
sprang@webrtc.org131bea82015-02-18 12:46:06 +000015#include "webrtc/video/loopback.h"
16
mflodman@webrtc.org7f944f32013-05-27 15:52:38 +000017#include "testing/gtest/include/gtest/gtest.h"
18
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000019#include "webrtc/call.h"
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +000020#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
pbos@webrtc.org26d12102013-05-29 13:41:03 +000021#include "webrtc/system_wrappers/interface/clock.h"
pbos@webrtc.org1932fe12013-07-05 17:02:37 +000022#include "webrtc/system_wrappers/interface/scoped_ptr.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000023#include "webrtc/test/direct_transport.h"
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +000024#include "webrtc/test/encoder_settings.h"
25#include "webrtc/test/fake_encoder.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000026#include "webrtc/test/run_loop.h"
stefan@webrtc.orgb3265ac2014-11-04 14:57:14 +000027#include "webrtc/test/testsupport/trace_to_stderr.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000028#include "webrtc/test/video_capturer.h"
29#include "webrtc/test/video_renderer.h"
pbos@webrtc.orgf5d4cb12013-05-17 13:44:48 +000030#include "webrtc/typedefs.h"
pbos@webrtc.org29d58392013-05-16 12:08:03 +000031
32namespace webrtc {
sprang@webrtc.org131bea82015-02-18 12:46:06 +000033namespace test {
stefan@webrtc.orgb3265ac2014-11-04 14:57:14 +000034
35static const int kAbsSendTimeExtensionId = 7;
36
pbos@webrtc.orgb613b5a2013-12-03 10:13:04 +000037static const uint32_t kSendSsrc = 0x654321;
stefan@webrtc.orgbfe6e082014-07-31 12:30:18 +000038static const uint32_t kSendRtxSsrc = 0x654322;
pbos@webrtc.orgb613b5a2013-12-03 10:13:04 +000039static const uint32_t kReceiverLocalSsrc = 0x123456;
40
andrew@webrtc.org8f27fcc2015-01-09 20:22:46 +000041static const uint8_t kRtxPayloadType = 96;
stefan@webrtc.orgbfe6e082014-07-31 12:30:18 +000042
sprang@webrtc.org131bea82015-02-18 12:46:06 +000043Loopback::Loopback(const Config& config)
44 : config_(config), clock_(Clock::GetRealTimeClock()) {
45}
46
47Loopback::~Loopback() {
48}
49
50void Loopback::Run() {
stefan@webrtc.orgb3265ac2014-11-04 14:57:14 +000051 scoped_ptr<test::TraceToStderr> trace_to_stderr_;
sprang@webrtc.org131bea82015-02-18 12:46:06 +000052 if (config_.logs)
stefan@webrtc.orgb3265ac2014-11-04 14:57:14 +000053 trace_to_stderr_.reset(new test::TraceToStderr);
54
pbos@webrtc.org1932fe12013-07-05 17:02:37 +000055 scoped_ptr<test::VideoRenderer> local_preview(test::VideoRenderer::Create(
sprang@webrtc.org131bea82015-02-18 12:46:06 +000056 "Local Preview", config_.width, config_.height));
pbos@webrtc.org1932fe12013-07-05 17:02:37 +000057 scoped_ptr<test::VideoRenderer> loopback_video(test::VideoRenderer::Create(
sprang@webrtc.org131bea82015-02-18 12:46:06 +000058 "Loopback Video", config_.width, config_.height));
pbos@webrtc.org29d58392013-05-16 12:08:03 +000059
stefan@webrtc.orgbfe6e082014-07-31 12:30:18 +000060 FakeNetworkPipe::Config pipe_config;
sprang@webrtc.org131bea82015-02-18 12:46:06 +000061 pipe_config.loss_percent = config_.loss_percent;
62 pipe_config.link_capacity_kbps = config_.link_capacity_kbps;
63 pipe_config.queue_length_packets = config_.queue_size;
64 pipe_config.queue_delay_ms = config_.avg_propagation_delay_ms;
65 pipe_config.delay_standard_deviation_ms = config_.std_propagation_delay_ms;
stefan@webrtc.orgbfe6e082014-07-31 12:30:18 +000066 test::DirectTransport transport(pipe_config);
pbos@webrtc.org841c8a42013-09-09 15:04:25 +000067 Call::Config call_config(&transport);
sprang@webrtc.org131bea82015-02-18 12:46:06 +000068
pbos@webrtc.org00873182014-11-25 14:03:34 +000069 call_config.stream_bitrates.min_bitrate_bps =
sprang@webrtc.org131bea82015-02-18 12:46:06 +000070 static_cast<int>(config_.min_bitrate_kbps) * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +000071 call_config.stream_bitrates.start_bitrate_bps =
sprang@webrtc.org131bea82015-02-18 12:46:06 +000072 static_cast<int>(config_.start_bitrate_kbps) * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +000073 call_config.stream_bitrates.max_bitrate_bps =
sprang@webrtc.org131bea82015-02-18 12:46:06 +000074 static_cast<int>(config_.max_bitrate_kbps) * 1000;
pbos@webrtc.org841c8a42013-09-09 15:04:25 +000075 scoped_ptr<Call> call(Call::Create(call_config));
pbos@webrtc.org29d58392013-05-16 12:08:03 +000076
77 // Loopback, call sends to itself.
78 transport.SetReceiver(call->Receiver());
79
pbos@webrtc.orgbd249bc2014-07-07 04:45:15 +000080 VideoSendStream::Config send_config;
pbos@webrtc.orgb613b5a2013-12-03 10:13:04 +000081 send_config.rtp.ssrcs.push_back(kSendSsrc);
stefan@webrtc.orgbfe6e082014-07-31 12:30:18 +000082 send_config.rtp.rtx.ssrcs.push_back(kSendRtxSsrc);
andrew@webrtc.org8f27fcc2015-01-09 20:22:46 +000083 send_config.rtp.rtx.payload_type = kRtxPayloadType;
stefan@webrtc.orgbfe6e082014-07-31 12:30:18 +000084 send_config.rtp.nack.rtp_history_ms = 1000;
stefan@webrtc.orgb3265ac2014-11-04 14:57:14 +000085 send_config.rtp.extensions.push_back(
86 RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId));
pbos@webrtc.org29d58392013-05-16 12:08:03 +000087
pbos@webrtc.org1932fe12013-07-05 17:02:37 +000088 send_config.local_renderer = local_preview.get();
stefan@webrtc.orgb9f54532014-07-04 12:42:07 +000089 scoped_ptr<VideoEncoder> encoder;
sprang@webrtc.org131bea82015-02-18 12:46:06 +000090 if (config_.codec == "VP8") {
pbos@webrtc.orgab990ae2014-09-17 09:02:25 +000091 encoder.reset(VideoEncoder::Create(VideoEncoder::kVp8));
sprang@webrtc.org131bea82015-02-18 12:46:06 +000092 } else if (config_.codec == "VP9") {
stefan@webrtc.org7c29e8c2014-11-04 19:41:15 +000093 encoder.reset(VideoEncoder::Create(VideoEncoder::kVp9));
stefan@webrtc.orgb9f54532014-07-04 12:42:07 +000094 } else {
95 // Codec not supported.
96 assert(false && "Codec not supported!");
97 return;
98 }
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +000099 send_config.encoder_settings.encoder = encoder.get();
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000100 send_config.encoder_settings.payload_name = config_.codec;
andrew@webrtc.org8f27fcc2015-01-09 20:22:46 +0000101 send_config.encoder_settings.payload_type = 124;
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000102
103 VideoEncoderConfig encoder_config(CreateEncoderConfig());
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000104
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +0000105 VideoSendStream* send_stream =
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +0000106 call->CreateVideoSendStream(send_config, encoder_config);
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000107
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000108 scoped_ptr<test::VideoCapturer> capturer(CreateCapturer(send_stream));
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000109
pbos@webrtc.orgbd249bc2014-07-07 04:45:15 +0000110 VideoReceiveStream::Config receive_config;
pbos@webrtc.orgb613b5a2013-12-03 10:13:04 +0000111 receive_config.rtp.remote_ssrc = send_config.rtp.ssrcs[0];
112 receive_config.rtp.local_ssrc = kReceiverLocalSsrc;
stefan@webrtc.orgbfe6e082014-07-31 12:30:18 +0000113 receive_config.rtp.nack.rtp_history_ms = 1000;
andrew@webrtc.org8f27fcc2015-01-09 20:22:46 +0000114 receive_config.rtp.rtx[kRtxPayloadType].ssrc = kSendRtxSsrc;
115 receive_config.rtp.rtx[kRtxPayloadType].payload_type = kRtxPayloadType;
stefan@webrtc.orgb3265ac2014-11-04 14:57:14 +0000116 receive_config.rtp.extensions.push_back(
117 RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId));
pbos@webrtc.org1932fe12013-07-05 17:02:37 +0000118 receive_config.renderer = loopback_video.get();
pbos@webrtc.org776e6f22014-10-29 15:28:39 +0000119 VideoReceiveStream::Decoder decoder =
120 test::CreateMatchingDecoder(send_config.encoder_settings);
121 receive_config.decoders.push_back(decoder);
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000122
pbos@webrtc.org74fa4892013-08-23 09:19:30 +0000123 VideoReceiveStream* receive_stream =
pbos@webrtc.org5a636552013-11-20 10:40:25 +0000124 call->CreateVideoReceiveStream(receive_config);
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000125
pbos@webrtc.orga5c8d2c2014-04-24 11:13:21 +0000126 receive_stream->Start();
127 send_stream->Start();
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000128 capturer->Start();
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000129
pbos@webrtc.orgadf23a52013-07-10 14:07:56 +0000130 test::PressEnterToContinue();
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000131
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000132 capturer->Stop();
pbos@webrtc.orga5c8d2c2014-04-24 11:13:21 +0000133 send_stream->Stop();
134 receive_stream->Stop();
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000135
pbos@webrtc.org2c46f8d2013-11-21 13:49:43 +0000136 call->DestroyVideoReceiveStream(receive_stream);
137 call->DestroyVideoSendStream(send_stream);
pbos@webrtc.org96684672013-08-12 12:59:04 +0000138
pbos@webrtc.org776e6f22014-10-29 15:28:39 +0000139 delete decoder.decoder;
140
pbos@webrtc.org96684672013-08-12 12:59:04 +0000141 transport.StopSending();
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000142}
pbos@webrtc.org023b1012014-05-13 11:26:40 +0000143
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000144VideoEncoderConfig Loopback::CreateEncoderConfig() {
145 VideoEncoderConfig encoder_config;
146 encoder_config.streams = test::CreateVideoStreams(1);
147 VideoStream* stream = &encoder_config.streams[0];
148 stream->width = config_.width;
149 stream->height = config_.height;
150 stream->min_bitrate_bps = static_cast<int>(config_.min_bitrate_kbps) * 1000;
151 stream->max_bitrate_bps = static_cast<int>(config_.max_bitrate_kbps) * 1000;
152 stream->target_bitrate_bps =
153 static_cast<int>(config_.max_bitrate_kbps) * 1000;
154 stream->max_framerate = config_.fps;
155 stream->max_qp = 56;
156 return encoder_config;
pbos@webrtc.org023b1012014-05-13 11:26:40 +0000157}
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000158
159test::VideoCapturer* Loopback::CreateCapturer(VideoSendStream* send_stream) {
160 return test::VideoCapturer::Create(send_stream->Input(), config_.width,
161 config_.height, config_.fps, clock_);
162}
163
164} // namespace test
165} // namespace webrtc