1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 117fff32c808707eb6810d1057747069d7afce9939stefan@webrtc.org#include "webrtc/modules/video_coding/main/test/rtp_player.h" 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 133f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <stdio.h> 143f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org 154d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org#include <map> 16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 176696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" 187fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" 197fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h" 207fff32c808707eb6810d1057747069d7afce9939stefan@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h" 217fff32c808707eb6810d1057747069d7afce9939stefan@webrtc.org#include "webrtc/modules/video_coding/main/source/internal_defines.h" 227fff32c808707eb6810d1057747069d7afce9939stefan@webrtc.org#include "webrtc/modules/video_coding/main/test/test_util.h" 231bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org#include "webrtc/system_wrappers/interface/clock.h" 244d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 254d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org#include "webrtc/system_wrappers/interface/scoped_ptr.h" 26ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org#include "webrtc/test/rtp_file_reader.h" 27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 284d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org#if 1 294d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org# define DEBUG_LOG1(text, arg) 304d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org#else 314d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org# define DEBUG_LOG1(text, arg) (printf(text "\n", arg)) 324d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org#endif 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 344d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgnamespace webrtc { 354d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgnamespace rtpplayer { 364d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 374d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgenum { 384d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org kMaxPacketBufferSize = 4096, 394d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org kDefaultTransmissionTimeOffsetExtensionId = 2 404d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org}; 414d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 424d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgclass RawRtpPacket { 434d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org public: 444d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org RawRtpPacket(const uint8_t* data, uint32_t length, uint32_t ssrc, 454d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org uint16_t seq_num) 464d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org : data_(new uint8_t[length]), 474d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org length_(length), 484d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org resend_time_ms_(-1), 494d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org ssrc_(ssrc), 504d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org seq_num_(seq_num) { 514d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org assert(data); 524d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org memcpy(data_.get(), data, length_); 534d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 554d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org const uint8_t* data() const { return data_.get(); } 564d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org uint32_t length() const { return length_; } 574d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org int64_t resend_time_ms() const { return resend_time_ms_; } 584d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org void set_resend_time_ms(int64_t timeMs) { resend_time_ms_ = timeMs; } 594d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org uint32_t ssrc() const { return ssrc_; } 604d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org uint16_t seq_num() const { return seq_num_; } 614d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 624d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org private: 63ba47616ee5a8d8a4d94e160b64b79a56845e291bandrew@webrtc.org scoped_ptr<uint8_t[]> data_; 644d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org uint32_t length_; 654d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org int64_t resend_time_ms_; 664d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org uint32_t ssrc_; 674d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org uint16_t seq_num_; 684d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 694d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org DISALLOW_IMPLICIT_CONSTRUCTORS(RawRtpPacket); 704d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org}; 714d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 724d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgclass LostPackets { 734d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org public: 744d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org LostPackets(Clock* clock, uint32_t rtt_ms) 754d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org : crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), 764d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org debug_file_(fopen("PacketLossDebug.txt", "w")), 774d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org loss_count_(0), 784d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org packets_(), 794d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org clock_(clock), 804d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org rtt_ms_(rtt_ms) { 814d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org assert(clock); 824d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 844d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org ~LostPackets() { 854d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org if (debug_file_) { 86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fclose(debug_file_); 874d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org debug_file_ = NULL; 884d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 894d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org while (!packets_.empty()) { 904d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org delete packets_.back(); 914d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org packets_.pop_back(); 924d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 954d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org void AddPacket(RawRtpPacket* packet) { 964d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org assert(packet); 974d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org printf("Throw: %08x:%u\n", packet->ssrc(), packet->seq_num()); 984d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org CriticalSectionScoped cs(crit_sect_.get()); 994d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org if (debug_file_) { 1004d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org fprintf(debug_file_, "%u Lost packet: %u\n", loss_count_, 1014d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org packet->seq_num()); 1024d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 1034d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org packets_.push_back(packet); 1044d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org loss_count_++; 105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1074d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org void SetResendTime(uint32_t ssrc, int16_t resendSeqNum) { 1084d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org int64_t resend_time_ms = clock_->TimeInMilliseconds() + rtt_ms_; 1094d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org int64_t now_ms = clock_->TimeInMilliseconds(); 1104d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org CriticalSectionScoped cs(crit_sect_.get()); 1114d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org for (RtpPacketIterator it = packets_.begin(); it != packets_.end(); ++it) { 1124d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org RawRtpPacket* packet = *it; 1134d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org if (ssrc == packet->ssrc() && resendSeqNum == packet->seq_num() && 1144d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org packet->resend_time_ms() + 10 < now_ms) { 1154d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org if (debug_file_) { 1164d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org fprintf(debug_file_, "Resend %u at %u\n", packet->seq_num(), 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org MaskWord64ToUWord32(resend_time_ms)); 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1194d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org packet->set_resend_time_ms(resend_time_ms); 1204d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org return; 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1234d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org // We may get here since the captured stream may itself be missing packets. 124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1264d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org RawRtpPacket* NextPacketToResend(int64_t time_now) { 1274d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org CriticalSectionScoped cs(crit_sect_.get()); 1284d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org for (RtpPacketIterator it = packets_.begin(); it != packets_.end(); ++it) { 129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RawRtpPacket* packet = *it; 1304d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org if (time_now >= packet->resend_time_ms() && 1314d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org packet->resend_time_ms() != -1) { 1324d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org packets_.erase(it); 1334d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org return packet; 1344d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1364d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org return NULL; 137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1394d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org int NumberOfPacketsToResend() const { 1404d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org CriticalSectionScoped cs(crit_sect_.get()); 1414d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org int count = 0; 1424d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org for (ConstRtpPacketIterator it = packets_.begin(); it != packets_.end(); 1434d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org ++it) { 1444d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org if ((*it)->resend_time_ms() >= 0) { 145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org count++; 1464d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1484d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org return count; 149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1514d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org void LogPacketResent(RawRtpPacket* packet) { 1524d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org int64_t now_ms = clock_->TimeInMilliseconds(); 1534d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org CriticalSectionScoped cs(crit_sect_.get()); 1544d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org if (debug_file_) { 1554d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org fprintf(debug_file_, "Resent %u at %u\n", packet->seq_num(), 1564d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org MaskWord64ToUWord32(now_ms)); 1574d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1604d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org void Print() const { 1614d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org CriticalSectionScoped cs(crit_sect_.get()); 1624d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org printf("Lost packets: %u\n", loss_count_); 1634d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org printf("Packets waiting to be resent: %d\n", NumberOfPacketsToResend()); 1644d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org printf("Packets still lost: %zd\n", packets_.size()); 1654d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org printf("Sequence numbers:\n"); 1664d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org for (ConstRtpPacketIterator it = packets_.begin(); it != packets_.end(); 1674d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org ++it) { 1684d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org printf("%u, ", (*it)->seq_num()); 1694d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 1704d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org printf("\n"); 171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1734d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org private: 1744d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org typedef std::vector<RawRtpPacket*> RtpPacketList; 1754d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org typedef RtpPacketList::iterator RtpPacketIterator; 1764d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org typedef RtpPacketList::const_iterator ConstRtpPacketIterator; 1774d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 1784d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org scoped_ptr<CriticalSectionWrapper> crit_sect_; 1794d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org FILE* debug_file_; 1804d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org int loss_count_; 1814d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org RtpPacketList packets_; 1824d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org Clock* clock_; 1834d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org uint32_t rtt_ms_; 1844d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 1854d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org DISALLOW_IMPLICIT_CONSTRUCTORS(LostPackets); 1864d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org}; 1874d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 1884d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgclass SsrcHandlers { 1894d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org public: 1904d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org SsrcHandlers(PayloadSinkFactoryInterface* payload_sink_factory, 1914d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org const PayloadTypes& payload_types) 1924d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org : payload_sink_factory_(payload_sink_factory), 1934d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org payload_types_(payload_types), 1944d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org handlers_() { 1954d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org assert(payload_sink_factory); 1964d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1984d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org ~SsrcHandlers() { 1994d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org while (!handlers_.empty()) { 2004d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org delete handlers_.begin()->second; 2014d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org handlers_.erase(handlers_.begin()); 202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2034d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 2044d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 205e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org int RegisterSsrc(uint32_t ssrc, LostPackets* lost_packets, Clock* clock) { 2064d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org if (handlers_.count(ssrc) > 0) { 2074d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org return 0; 2084d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 2094d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org DEBUG_LOG1("Registering handler for ssrc=%08x", ssrc); 2104d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 2114d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org scoped_ptr<Handler> handler( 2124d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org new Handler(ssrc, payload_types_, lost_packets)); 2134d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org handler->payload_sink_.reset(payload_sink_factory_->Create(handler.get())); 2144d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org if (handler->payload_sink_.get() == NULL) { 2154d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org return -1; 216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RtpRtcp::Configuration configuration; 219e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org configuration.clock = clock; 220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org configuration.id = 1; 221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org configuration.audio = false; 2227fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org handler->rtp_module_.reset(RtpReceiver::CreateVideoReceiver( 2237fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org configuration.id, configuration.clock, handler->payload_sink_.get(), 2247fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org NULL, handler->rtp_payload_registry_.get())); 2254d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org if (handler->rtp_module_.get() == NULL) { 2264d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org return -1; 227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 229db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org handler->rtp_module_->SetNACKStatus(kNackOff); 2306696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org handler->rtp_header_parser_->RegisterRtpHeaderExtension( 2314d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org kRtpExtensionTransmissionTimeOffset, 2324d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org kDefaultTransmissionTimeOffsetExtensionId); 2334d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 2344d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org for (PayloadTypesIterator it = payload_types_.begin(); 2354d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org it != payload_types_.end(); ++it) { 2364d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org VideoCodec codec; 2374d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org memset(&codec, 0, sizeof(codec)); 2384d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org strncpy(codec.plName, it->name().c_str(), sizeof(codec.plName)-1); 2394d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org codec.plType = it->payload_type(); 2404d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org codec.codecType = it->codec_type(); 2417fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org if (handler->rtp_module_->RegisterReceivePayload(codec.plName, 2427fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org codec.plType, 2437fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org 90000, 2447fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org 0, 2457fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org codec.maxBitrate) < 0) { 246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 2474d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2494d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 2504d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org handlers_[ssrc] = handler.release(); 251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 2524d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2544d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org void IncomingPacket(const uint8_t* data, uint32_t length) { 2554d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org for (HandlerMapIt it = handlers_.begin(); it != handlers_.end(); ++it) { 2567fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org if (!it->second->rtp_header_parser_->IsRtcp(data, length)) { 2576696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org RTPHeader header; 2586696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org it->second->rtp_header_parser_->Parse(data, length, &header); 2597fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org PayloadUnion payload_specific; 2607fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org it->second->rtp_payload_registry_->GetPayloadSpecifics( 2617fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org header.payloadType, &payload_specific); 262db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org it->second->rtp_module_->IncomingRtpPacket(header, data, length, 263db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org payload_specific, true); 2646696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org } 265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2664d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 2674d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 2684d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org private: 2694d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org class Handler : public RtpStreamInterface { 2704d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org public: 2714d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org Handler(uint32_t ssrc, const PayloadTypes& payload_types, 2724d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org LostPackets* lost_packets) 2736696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org : rtp_header_parser_(RtpHeaderParser::Create()), 2747fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org rtp_payload_registry_(new RTPPayloadRegistry( 27599681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org RTPPayloadStrategy::CreateStrategy(false))), 2766696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org rtp_module_(), 2774d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org payload_sink_(), 2784d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org ssrc_(ssrc), 2794d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org payload_types_(payload_types), 2804d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org lost_packets_(lost_packets) { 2814d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org assert(lost_packets); 282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2834d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org virtual ~Handler() {} 284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2854d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org virtual void ResendPackets(const uint16_t* sequence_numbers, 2864d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org uint16_t length) { 2874d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org assert(sequence_numbers); 2884d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org for (uint16_t i = 0; i < length; i++) { 2894d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org lost_packets_->SetResendTime(ssrc_, sequence_numbers[i]); 2904d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 2914d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2934d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org virtual uint32_t ssrc() const { return ssrc_; } 2944d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org virtual const PayloadTypes& payload_types() const { 2954d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org return payload_types_; 296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2986696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org scoped_ptr<RtpHeaderParser> rtp_header_parser_; 2997fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org scoped_ptr<RTPPayloadRegistry> rtp_payload_registry_; 3007fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org scoped_ptr<RtpReceiver> rtp_module_; 3014d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org scoped_ptr<PayloadSinkInterface> payload_sink_; 3024d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 3034d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org private: 3044d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org uint32_t ssrc_; 3054d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org const PayloadTypes& payload_types_; 3064d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org LostPackets* lost_packets_; 3074d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 3084d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org DISALLOW_COPY_AND_ASSIGN(Handler); 3094d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org }; 3104d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 3114d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org typedef std::map<uint32_t, Handler*> HandlerMap; 3124d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org typedef std::map<uint32_t, Handler*>::iterator HandlerMapIt; 3134d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 3144d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org PayloadSinkFactoryInterface* payload_sink_factory_; 3154d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org PayloadTypes payload_types_; 3164d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org HandlerMap handlers_; 3174d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 3184d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org DISALLOW_IMPLICIT_CONSTRUCTORS(SsrcHandlers); 3194d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org}; 3204d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 3214d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgclass RtpPlayerImpl : public RtpPlayerInterface { 3224d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org public: 3234d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org RtpPlayerImpl(PayloadSinkFactoryInterface* payload_sink_factory, 3244d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org const PayloadTypes& payload_types, Clock* clock, 325ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org scoped_ptr<test::RtpFileReader>* packet_source, 3264d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org float loss_rate, uint32_t rtt_ms, bool reordering) 3274d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org : ssrc_handlers_(payload_sink_factory, payload_types), 3284d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org clock_(clock), 3294d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org next_rtp_time_(0), 3304d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org first_packet_(true), 3314d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org first_packet_rtp_time_(0), 3324d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org first_packet_time_ms_(0), 3334d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org loss_rate_(loss_rate), 3344d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org lost_packets_(clock, rtt_ms), 3354d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org resend_packet_count_(0), 3364d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org no_loss_startup_(100), 3374d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org end_of_file_(false), 3384d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org reordering_(false), 339ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org reorder_buffer_() { 3404d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org assert(clock); 3414d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org assert(packet_source); 3424d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org assert(packet_source->get()); 3434d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org packet_source_.swap(*packet_source); 3444d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org srand(321); 3454d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 3464d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 3474d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org virtual ~RtpPlayerImpl() {} 3484d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 3494d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org virtual int NextPacket(int64_t time_now) { 3504d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org // Send any packets ready to be resent. 35122c283b04855b8775d323e8788a0438ce2d7c2b5henrike@webrtc.org for (RawRtpPacket* packet = lost_packets_.NextPacketToResend(time_now); 35222c283b04855b8775d323e8788a0438ce2d7c2b5henrike@webrtc.org packet != NULL; 35322c283b04855b8775d323e8788a0438ce2d7c2b5henrike@webrtc.org packet = lost_packets_.NextPacketToResend(time_now)) { 3544d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org int ret = SendPacket(packet->data(), packet->length()); 355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (ret > 0) { 3564d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org printf("Resend: %08x:%u\n", packet->ssrc(), packet->seq_num()); 3574d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org lost_packets_.LogPacketResent(packet); 3584d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org resend_packet_count_++; 3594d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 3604d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org delete packet; 3614d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org if (ret < 0) { 362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return ret; 363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 3664d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org // Send any packets from packet source. 3674d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org if (!end_of_file_ && (TimeUntilNextPacket() == 0 || first_packet_)) { 3684d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org if (first_packet_) { 369ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org if (!packet_source_->NextPacket(&next_packet_)) 3704d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org return 0; 371ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org first_packet_rtp_time_ = next_packet_.time_ms; 3724d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org first_packet_time_ms_ = clock_->TimeInMilliseconds(); 3734d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org first_packet_ = false; 3744d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 3754d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 3764d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org if (reordering_ && reorder_buffer_.get() == NULL) { 377ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org reorder_buffer_.reset( 378ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org new RawRtpPacket(next_packet_.data, 379ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org static_cast<uint32_t>(next_packet_.length), 380ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org 0, 381ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org 0)); 3824d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org return 0; 3834d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 384ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org int ret = SendPacket(next_packet_.data, 385ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org static_cast<uint32_t>(next_packet_.length)); 3864d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org if (reorder_buffer_.get()) { 3874d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org SendPacket(reorder_buffer_->data(), reorder_buffer_->length()); 3884d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org reorder_buffer_.reset(NULL); 3894d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 3904d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org if (ret < 0) { 3914d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org return ret; 3924d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 3934d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 394ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org if (!packet_source_->NextPacket(&next_packet_)) { 3954d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org end_of_file_ = true; 3964d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org return 0; 3974d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 398ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org else if (next_packet_.length == 0) { 3994d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org return 0; 4004d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 4024d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 4034d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org if (end_of_file_ && lost_packets_.NumberOfPacketsToResend() == 0) { 4044d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org return 1; 405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 4074d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 4094d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org virtual uint32_t TimeUntilNextPacket() const { 4104d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org int64_t time_left = (next_rtp_time_ - first_packet_rtp_time_) - 4114d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org (clock_->TimeInMilliseconds() - first_packet_time_ms_); 4124d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org if (time_left < 0) { 4134d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org return 0; 414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 4154d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org return static_cast<uint32_t>(time_left); 4164d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 4184d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org virtual void Print() const { 4194d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org printf("Resent packets: %u\n", resend_packet_count_); 4204d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org lost_packets_.Print(); 4214d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 4234d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org private: 4244d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org int SendPacket(const uint8_t* data, uint32_t length) { 4254d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org assert(data); 4264d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org assert(length > 0); 427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 4286696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org scoped_ptr<RtpHeaderParser> rtp_header_parser(RtpHeaderParser::Create()); 4296696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org if (!rtp_header_parser->IsRtcp(data, length)) { 4306696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org RTPHeader header; 4316696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org if (!rtp_header_parser->Parse(data, length, &header)) { 4324d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org return -1; 4334d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 4346696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org uint32_t ssrc = header.ssrc; 435e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org if (ssrc_handlers_.RegisterSsrc(ssrc, &lost_packets_, clock_) < 0) { 4364d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org DEBUG_LOG1("Unable to register ssrc: %d", ssrc); 4374d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org return -1; 4384d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 4404d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org if (no_loss_startup_ > 0) { 4414d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org no_loss_startup_--; 4424d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } else if ((rand() + 1.0)/(RAND_MAX + 1.0) < loss_rate_) { 4436696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org uint16_t seq_num = header.sequenceNumber; 4444d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org lost_packets_.AddPacket(new RawRtpPacket(data, length, ssrc, seq_num)); 4454d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org DEBUG_LOG1("Dropped packet: %d!", header.header.sequenceNumber); 4464d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org return 0; 4474d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 4504d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org ssrc_handlers_.IncomingPacket(data, length); 4514d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org return 1; 4524d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 4544d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org SsrcHandlers ssrc_handlers_; 4554d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org Clock* clock_; 456ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org scoped_ptr<test::RtpFileReader> packet_source_; 457ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org test::RtpFileReader::Packet next_packet_; 4584d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org uint32_t next_rtp_time_; 4594d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org bool first_packet_; 4604d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org int64_t first_packet_rtp_time_; 4614d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org int64_t first_packet_time_ms_; 4624d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org float loss_rate_; 4634d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org LostPackets lost_packets_; 4644d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org uint32_t resend_packet_count_; 4654d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org uint32_t no_loss_startup_; 4664d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org bool end_of_file_; 4674d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org bool reordering_; 4684d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org scoped_ptr<RawRtpPacket> reorder_buffer_; 4694d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 4704d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org DISALLOW_IMPLICIT_CONSTRUCTORS(RtpPlayerImpl); 4714d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org}; 4724d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org 4734d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgRtpPlayerInterface* Create(const std::string& input_filename, 4744d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org PayloadSinkFactoryInterface* payload_sink_factory, Clock* clock, 4754d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org const PayloadTypes& payload_types, float loss_rate, uint32_t rtt_ms, 4764d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org bool reordering) { 477ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org scoped_ptr<test::RtpFileReader> packet_source(test::RtpFileReader::Create( 478ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org test::RtpFileReader::kRtpDump, input_filename)); 4794d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org if (packet_source.get() == NULL) { 480ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org packet_source.reset(test::RtpFileReader::Create(test::RtpFileReader::kPcap, 481ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org input_filename)); 4824d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org if (packet_source.get() == NULL) { 4834d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org return NULL; 484b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 4854d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org } 486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 4874d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org scoped_ptr<RtpPlayerImpl> impl(new RtpPlayerImpl(payload_sink_factory, 4884d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org payload_types, clock, &packet_source, loss_rate, rtt_ms, reordering)); 4894d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org return impl.release(); 490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 4914d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org} // namespace rtpplayer 4924d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org} // namespace webrtc 493