17f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica/* 27f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 37f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica * 47f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica * Use of this source code is governed by a BSD-style license 57f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica * that can be found in the LICENSE file in the root of the source 67f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica * tree. An additional intellectual property rights grant can be found 77f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica * in the file PATENTS. All contributing project authors may 87f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica * be found in the AUTHORS file in the root of the source tree. 97f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica */ 107f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica 117f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica#include "webrtc/base/checks.h" 12ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" 13ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/rtp_rtcp/source/byte_io.h" 147f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica#include "webrtc/modules/rtp_rtcp/source/rtp_format.h" 157f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" 167f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica#include "webrtc/test/layer_filtering_transport.h" 177f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica 187f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivicanamespace webrtc { 197f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivicanamespace test { 207f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica 217f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivicaLayerFilteringTransport::LayerFilteringTransport( 227f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica const FakeNetworkPipe::Config& config, 23f116bd0d7a3cdad20bb638d5a87427bd920c8904stefan Call* send_call, 247f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica uint8_t vp8_video_payload_type, 257f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica uint8_t vp9_video_payload_type, 26ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang int selected_tl, 27ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang int selected_sl) 28f116bd0d7a3cdad20bb638d5a87427bd920c8904stefan : test::DirectTransport(config, send_call), 297f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica vp8_video_payload_type_(vp8_video_payload_type), 307f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica vp9_video_payload_type_(vp9_video_payload_type), 31ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang selected_tl_(selected_tl), 32ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang selected_sl_(selected_sl), 33ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang discarded_last_packet_(false) {} 34e78e2c714bdbecb910526746d9e3678a245a8f8bivica 35ce4aef16eec96862199e89b6d3ffe059558ac2c0sprangbool LayerFilteringTransport::DiscardedLastPacket() const { 36ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang return discarded_last_packet_; 37e78e2c714bdbecb910526746d9e3678a245a8f8bivica} 387f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica 391d8a506405734d0cef9653704b036ca4f1388960stefanbool LayerFilteringTransport::SendRtp(const uint8_t* packet, 401d8a506405734d0cef9653704b036ca4f1388960stefan size_t length, 411d8a506405734d0cef9653704b036ca4f1388960stefan const PacketOptions& options) { 42ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang if (selected_tl_ == -1 && selected_sl_ == -1) { 437f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica // Nothing to change, forward the packet immediately. 441d8a506405734d0cef9653704b036ca4f1388960stefan return test::DirectTransport::SendRtp(packet, length, options); 457f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica } 467f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica 477f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica bool set_marker_bit = false; 48ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang RtpUtility::RtpHeaderParser parser(packet, length); 497f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica RTPHeader header; 50f6975f46131981f83e0c88d276dee6b6c5753180danilchap parser.Parse(&header); 51ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang 52ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang RTC_DCHECK_LE(length, static_cast<size_t>(IP_PACKET_SIZE)); 53ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang uint8_t temp_buffer[IP_PACKET_SIZE]; 54ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang memcpy(temp_buffer, packet, length); 557f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica 567f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica if (header.payloadType == vp8_video_payload_type_ || 577f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica header.payloadType == vp9_video_payload_type_) { 587f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica const uint8_t* payload = packet + header.headerLength; 5991d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK_GT(length, header.headerLength); 607f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica const size_t payload_length = length - header.headerLength; 6191d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK_GT(payload_length, header.paddingLength); 627f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica const size_t payload_data_length = payload_length - header.paddingLength; 637f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica 647f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica const bool is_vp8 = header.payloadType == vp8_video_payload_type_; 657f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica rtc::scoped_ptr<RtpDepacketizer> depacketizer( 667f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica RtpDepacketizer::Create(is_vp8 ? kRtpVideoVp8 : kRtpVideoVp9)); 677f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica RtpDepacketizer::ParsedPayload parsed_payload; 687f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica if (depacketizer->Parse(&parsed_payload, payload, payload_data_length)) { 69ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang const int temporal_idx = static_cast<int>( 707f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica is_vp8 ? parsed_payload.type.Video.codecHeader.VP8.temporalIdx 71ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang : parsed_payload.type.Video.codecHeader.VP9.temporal_idx); 72ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang const int spatial_idx = static_cast<int>( 737f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica is_vp8 ? kNoSpatialIdx 74ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang : parsed_payload.type.Video.codecHeader.VP9.spatial_idx); 75ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang if (selected_sl_ >= 0 && spatial_idx == selected_sl_ && 767f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica parsed_payload.type.Video.codecHeader.VP9.end_of_frame) { 777f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica // This layer is now the last in the superframe. 787f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica set_marker_bit = true; 79ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang } else if ((selected_tl_ >= 0 && temporal_idx != kNoTemporalIdx && 80ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang temporal_idx > selected_tl_) || 81ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang (selected_sl_ >= 0 && spatial_idx != kNoSpatialIdx && 82ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang spatial_idx > selected_sl_)) { 83ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang // Truncate packet to a padding packet. 84ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang length = header.headerLength + 1; 85ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang temp_buffer[0] |= (1 << 5); // P = 1. 86ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang temp_buffer[1] &= 0x7F; // M = 0. 87ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang discarded_last_packet_ = true; 88ce4aef16eec96862199e89b6d3ffe059558ac2c0sprang temp_buffer[header.headerLength] = 1; // One byte of padding. 897f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica } 907f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica } else { 917f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica RTC_NOTREACHED() << "Parse error"; 927f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica } 937f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica } 947f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica 957f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica // We are discarding some of the packets (specifically, whole layers), so 967f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica // make sure the marker bit is set properly, and that sequence numbers are 977f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica // continuous. 98e78e2c714bdbecb910526746d9e3678a245a8f8bivica if (set_marker_bit) 997f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica temp_buffer[1] |= kRtpMarkerBitMask; 1007f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica 1011d8a506405734d0cef9653704b036ca4f1388960stefan return test::DirectTransport::SendRtp(temp_buffer, length, options); 1027f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica} 1037f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica 1047f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica} // namespace test 1057f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica} // namespace webrtc 106