18281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org/* 22853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 38281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org * 48281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org * Use of this source code is governed by a BSD-style license 58281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org * that can be found in the LICENSE file in the root of the source 68281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org * tree. An additional intellectual property rights grant can be found 78281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org * in the file PATENTS. All contributing project authors may 88281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org * be found in the AUTHORS file in the root of the source tree. 98281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org */ 108281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org 118d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org#include <stdlib.h> 128d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org 138281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org#include <algorithm> 148281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org#include <vector> 158281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org 16a048d7cb0a5bad5ca49bbcc5273cb4cca28c1710pbos@webrtc.org#include "testing/gtest/include/gtest/gtest.h" 178d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org#include "webrtc/common_types.h" 18ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h" 19ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" 20ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" 21779c3d16b9623f38a72439bc013102aeb0077a62sprang@webrtc.org#include "webrtc/modules/rtp_rtcp/source/byte_io.h" 2296edd561703ad9e257e91b92e3c1436bef446f13pbos@webrtc.org#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h" 238d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org#include "webrtc/modules/rtp_rtcp/test/testAPI/test_api.h" 248281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org 25d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.orgnamespace { 26d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org 27d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.orgconst unsigned char kPayloadType = 100; 28d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org 29d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org}; 30d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org 318d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.orgnamespace webrtc { 328281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org 338281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.orgclass RtpRtcpVideoTest : public ::testing::Test { 348281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org protected: 358d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org RtpRtcpVideoTest() 36ac547a653862744d0aae560713f8418ad2852085Peter Boström : rtp_payload_registry_(RTPPayloadStrategy::CreateStrategy(false)), 378d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org test_ssrc_(3456), 388d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org test_timestamp_(4567), 39a678a3baee2e680bd521f3a6caf97707fffd6093stefan@webrtc.org test_sequence_number_(2345), 40ac547a653862744d0aae560713f8418ad2852085Peter Boström fake_clock(123456) {} 418281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org ~RtpRtcpVideoTest() {} 428281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org 438281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org virtual void SetUp() { 448d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org transport_ = new LoopBackTransport(); 45822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org receiver_ = new TestRtpReceiver(); 46822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org receive_statistics_.reset(ReceiveStatistics::Create(&fake_clock)); 472853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org RtpRtcp::Configuration configuration; 482853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.audio = false; 492853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.clock = &fake_clock; 508d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org configuration.outgoing_transport = transport_; 512853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org 528d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org video_module_ = RtpRtcp::CreateRtpRtcp(configuration); 53822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org rtp_receiver_.reset(RtpReceiver::CreateVideoReceiver( 54ac547a653862744d0aae560713f8418ad2852085Peter Boström &fake_clock, receiver_, NULL, &rtp_payload_registry_)); 552853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org 56da903eaabbb6c6830efcafc3c2ade1d36f511e43pbos video_module_->SetRTCPStatus(RtcpMode::kCompound); 57ef92755780253c6a7940c89598a206e58e05b810stefan@webrtc.org video_module_->SetSSRC(test_ssrc_); 587bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org rtp_receiver_->SetNACKStatus(kNackRtcp); 59d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org video_module_->SetStorePacketsStatus(true, 600); 608d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org EXPECT_EQ(0, video_module_->SetSendingStatus(true)); 618281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org 62822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org transport_->SetSendModule(video_module_, &rtp_payload_registry_, 63822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org rtp_receiver_.get(), receive_statistics_.get()); 648281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org 658281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org VideoCodec video_codec; 668281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org memset(&video_codec, 0, sizeof(video_codec)); 678281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org video_codec.plType = 123; 688281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org memcpy(video_codec.plName, "I420", 5); 698281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org 708d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org EXPECT_EQ(0, video_module_->RegisterSendPayload(video_codec)); 71822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(video_codec.plName, 72822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org video_codec.plType, 73822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 90000, 74822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 0, 75822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org video_codec.maxBitrate)); 768d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org 778d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org payload_data_length_ = sizeof(video_frame_); 788d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org 794591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org for (size_t n = 0; n < payload_data_length_; n++) { 808d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org video_frame_[n] = n%10; 818d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org } 828d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org } 838d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org 844591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t BuildRTPheader(uint8_t* dataBuffer, 854591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org uint32_t timestamp, 864591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org uint32_t sequence_number) { 872f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org dataBuffer[0] = static_cast<uint8_t>(0x80); // version 2 882f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org dataBuffer[1] = static_cast<uint8_t>(kPayloadType); 89779c3d16b9623f38a72439bc013102aeb0077a62sprang@webrtc.org ByteWriter<uint16_t>::WriteBigEndian(dataBuffer + 2, sequence_number); 90779c3d16b9623f38a72439bc013102aeb0077a62sprang@webrtc.org ByteWriter<uint32_t>::WriteBigEndian(dataBuffer + 4, timestamp); 91779c3d16b9623f38a72439bc013102aeb0077a62sprang@webrtc.org ByteWriter<uint32_t>::WriteBigEndian(dataBuffer + 8, 0x1234); // SSRC. 924591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t rtpHeaderLength = 12; 938d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org return rtpHeaderLength; 948d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org } 958281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org 964591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t PaddingPacket(uint8_t* buffer, 974591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org uint32_t timestamp, 984591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org uint32_t sequence_number, 994591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t bytes) { 1008d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org // Max in the RFC 3550 is 255 bytes, we limit it to be modulus 32 for SRTP. 1014591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t max_length = 224; 1028281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org 1034591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t padding_bytes_in_packet = max_length; 1048d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org if (bytes < max_length) { 1058d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org padding_bytes_in_packet = (bytes + 16) & 0xffe0; // Keep our modulus 32. 1068d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org } 1078d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org // Correct seq num, timestamp and payload type. 1084591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t header_length = BuildRTPheader(buffer, timestamp, sequence_number); 1098d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org buffer[0] |= 0x20; // Set padding bit. 1102f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org int32_t* data = 1112f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org reinterpret_cast<int32_t*>(&(buffer[header_length])); 1128d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org 1138d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org // Fill data buffer with random data. 1144591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org for (size_t j = 0; j < (padding_bytes_in_packet >> 2); j++) { 1158d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org data[j] = rand(); // NOLINT 1168281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org } 1178d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org // Set number of padding bytes in the last byte of the packet. 1188d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org buffer[header_length + padding_bytes_in_packet - 1] = 1198d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org padding_bytes_in_packet; 1208d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org return padding_bytes_in_packet + header_length; 1218281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org } 1228281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org 1238281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org virtual void TearDown() { 1248d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org delete video_module_; 1258d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org delete transport_; 1268d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org delete receiver_; 1278281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org } 1288281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org 1298d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org int test_id_; 13000b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org rtc::scoped_ptr<ReceiveStatistics> receive_statistics_; 131822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org RTPPayloadRegistry rtp_payload_registry_; 13200b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org rtc::scoped_ptr<RtpReceiver> rtp_receiver_; 1338d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org RtpRtcp* video_module_; 1348d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org LoopBackTransport* transport_; 135822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org TestRtpReceiver* receiver_; 1362f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint32_t test_ssrc_; 1372f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint32_t test_timestamp_; 1382f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint16_t test_sequence_number_; 1392f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint8_t video_frame_[65000]; 1404591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t payload_data_length_; 141a678a3baee2e680bd521f3a6caf97707fffd6093stefan@webrtc.org SimulatedClock fake_clock; 1428281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org}; 1438281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org 1448281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.orgTEST_F(RtpRtcpVideoTest, BasicVideo) { 1452f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint32_t timestamp = 3000; 1468d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org EXPECT_EQ(0, video_module_->SendOutgoingData(kVideoFrameDelta, 123, 1478d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org timestamp, 1488d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org timestamp / 90, 1498d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org video_frame_, 1508d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org payload_data_length_)); 1518d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org} 1528281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org 1538d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.orgTEST_F(RtpRtcpVideoTest, PaddingOnlyFrames) { 1544591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org const size_t kPadSize = 255; 1558d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org uint8_t padding_packet[kPadSize]; 1568d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org uint32_t seq_num = 0; 1578d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org uint32_t timestamp = 3000; 1588d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org VideoCodec codec; 1598d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org codec.codecType = kVideoCodecVP8; 1608d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org codec.plType = kPayloadType; 1618d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org strncpy(codec.plName, "VP8", 4); 162822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(codec.plName, 163822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.plType, 164822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 90000, 165822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 0, 166822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.maxBitrate)); 1678d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org for (int frame_idx = 0; frame_idx < 10; ++frame_idx) { 1688d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org for (int packet_idx = 0; packet_idx < 5; ++packet_idx) { 1694591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t packet_size = PaddingPacket(padding_packet, timestamp, seq_num, 1704591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org kPadSize); 1718d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org ++seq_num; 172a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org RTPHeader header; 17300b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org rtc::scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create()); 174a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org EXPECT_TRUE(parser->Parse(padding_packet, packet_size, &header)); 175822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org PayloadUnion payload_specific; 176822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org EXPECT_TRUE(rtp_payload_registry_.GetPayloadSpecifics(header.payloadType, 177d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org &payload_specific)); 1787bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org const uint8_t* payload = padding_packet + header.headerLength; 1794591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org const size_t payload_length = packet_size - header.headerLength; 1807bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, payload, 1817bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org payload_length, 182822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org payload_specific, true)); 1834591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org EXPECT_EQ(0u, receiver_->payload_size()); 1847bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org EXPECT_EQ(payload_length, receiver_->rtp_header().header.paddingLength); 1858d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org } 1868d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org timestamp += 3000; 187a678a3baee2e680bd521f3a6caf97707fffd6093stefan@webrtc.org fake_clock.AdvanceTimeMilliseconds(33); 1888d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org } 1898281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org} 1908281e7dd4a8ac4b00aededd8ebf52e93f1d980e8pwestin@webrtc.org 1918d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org} // namespace webrtc 192