layer_filtering_transport.cc revision f116bd0d7a3cdad20bb638d5a87427bd920c8904
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" 127f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" 137f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h" 147f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica#include "webrtc/modules/rtp_rtcp/source/byte_io.h" 157f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica#include "webrtc/modules/rtp_rtcp/source/rtp_format.h" 167f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" 177f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica#include "webrtc/test/layer_filtering_transport.h" 187f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica 197f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivicanamespace webrtc { 207f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivicanamespace test { 217f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica 227f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivicaLayerFilteringTransport::LayerFilteringTransport( 237f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica const FakeNetworkPipe::Config& config, 24f116bd0d7a3cdad20bb638d5a87427bd920c8904stefan Call* send_call, 257f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica uint8_t vp8_video_payload_type, 267f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica uint8_t vp9_video_payload_type, 277a975f75e7fa7a9335411ef22b6687f78f7b297fsprang uint8_t tl_discard_threshold, 287a975f75e7fa7a9335411ef22b6687f78f7b297fsprang uint8_t sl_discard_threshold) 29f116bd0d7a3cdad20bb638d5a87427bd920c8904stefan : test::DirectTransport(config, send_call), 307f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica vp8_video_payload_type_(vp8_video_payload_type), 317f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica vp9_video_payload_type_(vp9_video_payload_type), 327a975f75e7fa7a9335411ef22b6687f78f7b297fsprang tl_discard_threshold_(tl_discard_threshold), 33f116bd0d7a3cdad20bb638d5a87427bd920c8904stefan sl_discard_threshold_(sl_discard_threshold) {} 34e78e2c714bdbecb910526746d9e3678a245a8f8bivica 35e78e2c714bdbecb910526746d9e3678a245a8f8bivicauint16_t LayerFilteringTransport::NextSequenceNumber(uint32_t ssrc) { 36e78e2c714bdbecb910526746d9e3678a245a8f8bivica auto it = current_seq_nums_.find(ssrc); 37e78e2c714bdbecb910526746d9e3678a245a8f8bivica if (it == current_seq_nums_.end()) 38e78e2c714bdbecb910526746d9e3678a245a8f8bivica return current_seq_nums_[ssrc] = 10000; 39e78e2c714bdbecb910526746d9e3678a245a8f8bivica return ++it->second; 40e78e2c714bdbecb910526746d9e3678a245a8f8bivica} 417f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica 421d8a506405734d0cef9653704b036ca4f1388960stefanbool LayerFilteringTransport::SendRtp(const uint8_t* packet, 431d8a506405734d0cef9653704b036ca4f1388960stefan size_t length, 441d8a506405734d0cef9653704b036ca4f1388960stefan const PacketOptions& options) { 457a975f75e7fa7a9335411ef22b6687f78f7b297fsprang if (tl_discard_threshold_ == 0 && sl_discard_threshold_ == 0) { 467f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica // Nothing to change, forward the packet immediately. 471d8a506405734d0cef9653704b036ca4f1388960stefan return test::DirectTransport::SendRtp(packet, length, options); 487f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica } 497f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica 507f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica bool set_marker_bit = false; 517f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica rtc::scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create()); 527f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica RTPHeader header; 537f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica parser->Parse(packet, length, &header); 547f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica 557f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica if (header.payloadType == vp8_video_payload_type_ || 567f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica header.payloadType == vp9_video_payload_type_) { 577f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica const uint8_t* payload = packet + header.headerLength; 5891d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK_GT(length, header.headerLength); 597f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica const size_t payload_length = length - header.headerLength; 6091d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK_GT(payload_length, header.paddingLength); 617f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica const size_t payload_data_length = payload_length - header.paddingLength; 627f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica 637f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica const bool is_vp8 = header.payloadType == vp8_video_payload_type_; 647f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica rtc::scoped_ptr<RtpDepacketizer> depacketizer( 657f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica RtpDepacketizer::Create(is_vp8 ? kRtpVideoVp8 : kRtpVideoVp9)); 667f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica RtpDepacketizer::ParsedPayload parsed_payload; 677f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica if (depacketizer->Parse(&parsed_payload, payload, payload_data_length)) { 687a975f75e7fa7a9335411ef22b6687f78f7b297fsprang const uint8_t temporalIdx = 697f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica is_vp8 ? parsed_payload.type.Video.codecHeader.VP8.temporalIdx 707a975f75e7fa7a9335411ef22b6687f78f7b297fsprang : parsed_payload.type.Video.codecHeader.VP9.temporal_idx; 717a975f75e7fa7a9335411ef22b6687f78f7b297fsprang const uint8_t spatialIdx = 727f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica is_vp8 ? kNoSpatialIdx 737a975f75e7fa7a9335411ef22b6687f78f7b297fsprang : parsed_payload.type.Video.codecHeader.VP9.spatial_idx; 747a975f75e7fa7a9335411ef22b6687f78f7b297fsprang if (sl_discard_threshold_ > 0 && 757a975f75e7fa7a9335411ef22b6687f78f7b297fsprang spatialIdx == sl_discard_threshold_ - 1 && 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; 797f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica } 807a975f75e7fa7a9335411ef22b6687f78f7b297fsprang if ((tl_discard_threshold_ > 0 && temporalIdx != kNoTemporalIdx && 817a975f75e7fa7a9335411ef22b6687f78f7b297fsprang temporalIdx >= tl_discard_threshold_) || 827a975f75e7fa7a9335411ef22b6687f78f7b297fsprang (sl_discard_threshold_ > 0 && spatialIdx != kNoSpatialIdx && 837a975f75e7fa7a9335411ef22b6687f78f7b297fsprang spatialIdx >= sl_discard_threshold_)) { 847a975f75e7fa7a9335411ef22b6687f78f7b297fsprang return true; // Discard the packet. 857f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica } 867f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica } else { 877f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica RTC_NOTREACHED() << "Parse error"; 887f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica } 897f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica } 907f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica 917f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica uint8_t temp_buffer[IP_PACKET_SIZE]; 927f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica memcpy(temp_buffer, packet, length); 937f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica 947f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica // We are discarding some of the packets (specifically, whole layers), so 957f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica // make sure the marker bit is set properly, and that sequence numbers are 967f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica // continuous. 97e78e2c714bdbecb910526746d9e3678a245a8f8bivica if (set_marker_bit) 987f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica temp_buffer[1] |= kRtpMarkerBitMask; 997f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica 100e78e2c714bdbecb910526746d9e3678a245a8f8bivica uint16_t seq_num = NextSequenceNumber(header.ssrc); 101e78e2c714bdbecb910526746d9e3678a245a8f8bivica ByteWriter<uint16_t>::WriteBigEndian(&temp_buffer[2], seq_num); 1021d8a506405734d0cef9653704b036ca4f1388960stefan return test::DirectTransport::SendRtp(temp_buffer, length, options); 1037f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica} 1047f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica 1057f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica} // namespace test 1067f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica} // namespace webrtc 107