Refactor to use std::list in the video rtp play tools.
BUG= TEST= Review URL: https://webrtc-codereview.appspot.com/349013 git-svn-id: http://webrtc.googlecode.com/svn/trunk@1504 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
152c34cf11
commit
8fe03af674
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
@ -23,8 +23,6 @@
|
||||
|
||||
namespace webrtc
|
||||
{
|
||||
class ListWrapper;
|
||||
|
||||
// Number of time periods used for (max) window filter for packet loss
|
||||
// TODO (marpan): set reasonable window size for filtered packet loss,
|
||||
// adjustment should be based on logged/real data of loss stats/correlation.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
@ -11,7 +11,6 @@
|
||||
#ifndef WEBRTC_MODULES_VIDEO_CODING_MEDIA_OPTIMIZATION_H_
|
||||
#define WEBRTC_MODULES_VIDEO_CODING_MEDIA_OPTIMIZATION_H_
|
||||
|
||||
#include "list_wrapper.h"
|
||||
#include "module_common_types.h"
|
||||
#include "video_coding.h"
|
||||
#include "trace.h"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
@ -83,14 +83,14 @@ int DecodeFromStorageTest(CmdArgs& args)
|
||||
vcm->RegisterFrameStorageCallback(&storageCallback);
|
||||
vcmPlayback->RegisterReceiveCallback(&receiveCallback);
|
||||
RTPPlayer rtpStream(rtpFilename.c_str(), &dataCallback, &clock);
|
||||
ListWrapper payloadTypes;
|
||||
payloadTypes.PushFront(new PayloadCodecTuple(VCM_VP8_PAYLOAD_TYPE, "VP8", kVideoCodecVP8));
|
||||
PayloadTypeList payloadTypes;
|
||||
payloadTypes.push_front(new PayloadCodecTuple(VCM_VP8_PAYLOAD_TYPE, "VP8",
|
||||
kVideoCodecVP8));
|
||||
|
||||
// Register receive codecs in VCM
|
||||
ListItem* item = payloadTypes.First();
|
||||
while (item != NULL)
|
||||
{
|
||||
PayloadCodecTuple* payloadType = static_cast<PayloadCodecTuple*>(item->GetItem());
|
||||
for (PayloadTypeList::iterator it = payloadTypes.begin();
|
||||
it != payloadTypes.end(); ++it) {
|
||||
PayloadCodecTuple* payloadType = *it;
|
||||
if (payloadType != NULL)
|
||||
{
|
||||
VideoCodec codec;
|
||||
@ -108,9 +108,8 @@ int DecodeFromStorageTest(CmdArgs& args)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
item = payloadTypes.Next(item);
|
||||
}
|
||||
if (rtpStream.Initialize(payloadTypes) < 0)
|
||||
if (rtpStream.Initialize(&payloadTypes) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@ -163,17 +162,10 @@ int DecodeFromStorageTest(CmdArgs& args)
|
||||
rtpStream.Print();
|
||||
|
||||
// Tear down
|
||||
item = payloadTypes.First();
|
||||
while (item != NULL)
|
||||
while (!payloadTypes.empty())
|
||||
{
|
||||
PayloadCodecTuple* payloadType = static_cast<PayloadCodecTuple*>(item->GetItem());
|
||||
if (payloadType != NULL)
|
||||
{
|
||||
delete payloadType;
|
||||
}
|
||||
ListItem* itemToRemove = item;
|
||||
item = payloadTypes.Next(item);
|
||||
payloadTypes.Erase(itemToRemove);
|
||||
delete payloadTypes.front();
|
||||
payloadTypes.pop_front();
|
||||
}
|
||||
VideoCodingModule::Destroy(vcm);
|
||||
vcm = NULL;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
@ -56,7 +56,7 @@ TransportCallback::SendPacket(int channel, const void *data, int len)
|
||||
// Insert outgoing packet into list
|
||||
if (transmitPacket)
|
||||
{
|
||||
rtpPacket* newPacket = new rtpPacket();
|
||||
RtpPacket* newPacket = new RtpPacket();
|
||||
memcpy(newPacket->data, data, len);
|
||||
newPacket->length = len;
|
||||
// Simulate receive time = network delay + packet jitter
|
||||
@ -66,7 +66,7 @@ TransportCallback::SendPacket(int channel, const void *data, int len)
|
||||
simulatedDelay = (WebRtc_Word32)NormalDist(_networkDelayMs,
|
||||
sqrt(_jitterVar));
|
||||
newPacket->receiveTime = now + simulatedDelay;
|
||||
_rtpPackets.PushBack(newPacket);
|
||||
_rtpPackets.push_back(newPacket);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -75,14 +75,14 @@ int
|
||||
TransportCallback::TransportPackets()
|
||||
{
|
||||
// Are we ready to send packets to the receiver?
|
||||
rtpPacket* packet = NULL;
|
||||
RtpPacket* packet = NULL;
|
||||
TickTimeBase clock;
|
||||
int64_t now = clock.MillisecondTimestamp();
|
||||
|
||||
while (!_rtpPackets.Empty())
|
||||
while (!_rtpPackets.empty())
|
||||
{
|
||||
// Take first packet in list
|
||||
packet = static_cast<rtpPacket*>((_rtpPackets.First())->GetItem());
|
||||
packet = _rtpPackets.front();
|
||||
WebRtc_Word64 timeToReceive = packet->receiveTime - now;
|
||||
if (timeToReceive > 0)
|
||||
{
|
||||
@ -90,7 +90,7 @@ TransportCallback::TransportPackets()
|
||||
break;
|
||||
}
|
||||
|
||||
_rtpPackets.PopFront();
|
||||
_rtpPackets.pop_front();
|
||||
// Send to receive side
|
||||
if (_rtp->IncomingPacket((const WebRtc_UWord8*)packet->data,
|
||||
packet->length) < 0)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
@ -25,113 +25,114 @@
|
||||
|
||||
using namespace webrtc;
|
||||
|
||||
RawRtpPacket::RawRtpPacket(WebRtc_UWord8* data, WebRtc_UWord16 len)
|
||||
:
|
||||
rtpData(), rtpLen(len), resendTimeMs(-1)
|
||||
{
|
||||
rtpData = new WebRtc_UWord8[rtpLen];
|
||||
memcpy(rtpData, data, rtpLen);
|
||||
RawRtpPacket::RawRtpPacket(uint8_t* rtp_data, uint16_t rtp_length)
|
||||
: data(rtp_data),
|
||||
length(rtp_length),
|
||||
resend_time_ms(-1) {
|
||||
data = new uint8_t[length];
|
||||
memcpy(data, rtp_data, length);
|
||||
}
|
||||
|
||||
RawRtpPacket::~RawRtpPacket()
|
||||
{
|
||||
delete [] rtpData;
|
||||
RawRtpPacket::~RawRtpPacket() {
|
||||
delete [] data;
|
||||
}
|
||||
|
||||
LostPackets::LostPackets()
|
||||
:
|
||||
_critSect(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
_lossCount(0),
|
||||
_debugFile(NULL)
|
||||
{
|
||||
_debugFile = fopen("PacketLossDebug.txt", "w");
|
||||
: crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
loss_count_(0),
|
||||
debug_file_(NULL),
|
||||
packets_() {
|
||||
debug_file_ = fopen("PacketLossDebug.txt", "w");
|
||||
}
|
||||
|
||||
LostPackets::~LostPackets()
|
||||
{
|
||||
if (_debugFile)
|
||||
{
|
||||
fclose(_debugFile);
|
||||
}
|
||||
ListItem* item = First();
|
||||
while (item != NULL)
|
||||
{
|
||||
RawRtpPacket* packet = static_cast<RawRtpPacket*>(item->GetItem());
|
||||
if (packet != NULL)
|
||||
{
|
||||
delete packet;
|
||||
LostPackets::~LostPackets() {
|
||||
if (debug_file_) {
|
||||
fclose(debug_file_);
|
||||
}
|
||||
while (!packets_.empty()) {
|
||||
delete packets_.front();
|
||||
packets_.pop_front();
|
||||
}
|
||||
delete crit_sect_;
|
||||
}
|
||||
|
||||
void LostPackets::AddPacket(RawRtpPacket* packet) {
|
||||
CriticalSectionScoped cs(crit_sect_);
|
||||
packets_.push_back(packet);
|
||||
uint16_t seq_num = (packet->data[2] << 8) + packet->data[3];
|
||||
if (debug_file_ != NULL) {
|
||||
fprintf(debug_file_, "%u Lost packet: %u\n", loss_count_, seq_num);
|
||||
}
|
||||
++loss_count_;
|
||||
}
|
||||
|
||||
void LostPackets::SetResendTime(uint16_t resend_seq_num,
|
||||
int64_t resend_time_ms,
|
||||
int64_t now_ms) {
|
||||
CriticalSectionScoped cs(crit_sect_);
|
||||
for (RtpPacketIterator it = packets_.begin(); it != packets_.end(); ++it) {
|
||||
const uint16_t seq_num = ((*it)->data[2] << 8) +
|
||||
(*it)->data[3];
|
||||
if (resend_seq_num == seq_num) {
|
||||
if ((*it)->resend_time_ms + 10 < now_ms) {
|
||||
if (debug_file_ != NULL) {
|
||||
fprintf(debug_file_, "Resend %u at %u\n", seq_num,
|
||||
MaskWord64ToUWord32(resend_time_ms));
|
||||
}
|
||||
Erase(item);
|
||||
item = First();
|
||||
(*it)->resend_time_ms = resend_time_ms;
|
||||
}
|
||||
return;
|
||||
}
|
||||
delete _critSect;
|
||||
}
|
||||
assert(false);
|
||||
}
|
||||
|
||||
WebRtc_UWord32 LostPackets::AddPacket(WebRtc_UWord8* rtpData, WebRtc_UWord16 rtpLen)
|
||||
{
|
||||
CriticalSectionScoped cs(_critSect);
|
||||
RawRtpPacket* packet = new RawRtpPacket(rtpData, rtpLen);
|
||||
ListItem* newItem = new ListItem(packet);
|
||||
Insert(Last(), newItem);
|
||||
const WebRtc_UWord16 seqNo = (rtpData[2] << 8) + rtpData[3];
|
||||
if (_debugFile != NULL)
|
||||
{
|
||||
fprintf(_debugFile, "%u Lost packet: %u\n", _lossCount, seqNo);
|
||||
RawRtpPacket* LostPackets::NextPacketToResend(int64_t timeNow) {
|
||||
CriticalSectionScoped cs(crit_sect_);
|
||||
for (RtpPacketIterator it = packets_.begin(); it != packets_.end(); ++it) {
|
||||
if (timeNow >= (*it)->resend_time_ms && (*it)->resend_time_ms != -1) {
|
||||
RawRtpPacket* packet = *it;
|
||||
it = packets_.erase(it);
|
||||
return packet;
|
||||
}
|
||||
_lossCount++;
|
||||
return 0;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WebRtc_UWord32 LostPackets::SetResendTime(WebRtc_UWord16 sequenceNumber,
|
||||
WebRtc_Word64 resendTime,
|
||||
WebRtc_Word64 nowMs)
|
||||
{
|
||||
CriticalSectionScoped cs(_critSect);
|
||||
ListItem* item = First();
|
||||
while (item != NULL)
|
||||
{
|
||||
RawRtpPacket* packet = static_cast<RawRtpPacket*>(item->GetItem());
|
||||
const WebRtc_UWord16 seqNo = (packet->rtpData[2] << 8) + packet->rtpData[3];
|
||||
if (sequenceNumber == seqNo && packet->resendTimeMs + 10 < nowMs)
|
||||
{
|
||||
if (_debugFile != NULL)
|
||||
{
|
||||
fprintf(_debugFile, "Resend %u at %u\n", seqNo, MaskWord64ToUWord32(resendTime));
|
||||
}
|
||||
packet->resendTimeMs = resendTime;
|
||||
return 0;
|
||||
}
|
||||
item = Next(item);
|
||||
int LostPackets::NumberOfPacketsToResend() const {
|
||||
CriticalSectionScoped cs(crit_sect_);
|
||||
int count = 0;
|
||||
for (ConstRtpPacketIterator it = packets_.begin(); it != packets_.end();
|
||||
++it) {
|
||||
if ((*it)->resend_time_ms >= 0) {
|
||||
count++;
|
||||
}
|
||||
fprintf(_debugFile, "Packet not lost %u\n", sequenceNumber);
|
||||
return -1;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
WebRtc_UWord32 LostPackets::NumberOfPacketsToResend() const
|
||||
{
|
||||
CriticalSectionScoped cs(_critSect);
|
||||
WebRtc_UWord32 count = 0;
|
||||
ListItem* item = First();
|
||||
while (item != NULL)
|
||||
{
|
||||
RawRtpPacket* packet = static_cast<RawRtpPacket*>(item->GetItem());
|
||||
if (packet->resendTimeMs >= 0)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
item = Next(item);
|
||||
}
|
||||
return count;
|
||||
void LostPackets::SetPacketResent(uint16_t seq_num, int64_t now_ms) {
|
||||
CriticalSectionScoped cs(crit_sect_);
|
||||
if (debug_file_ != NULL) {
|
||||
fprintf(debug_file_, "Resent %u at %u\n", seq_num,
|
||||
MaskWord64ToUWord32(now_ms));
|
||||
}
|
||||
}
|
||||
|
||||
void LostPackets::ResentPacket(WebRtc_UWord16 seqNo, WebRtc_Word64 nowMs)
|
||||
{
|
||||
CriticalSectionScoped cs(_critSect);
|
||||
if (_debugFile != NULL)
|
||||
{
|
||||
fprintf(_debugFile, "Resent %u at %u\n", seqNo,
|
||||
MaskWord64ToUWord32(nowMs));
|
||||
}
|
||||
void LostPackets::Print() const {
|
||||
CriticalSectionScoped cs(crit_sect_);
|
||||
printf("Lost packets: %u\n", loss_count_);
|
||||
printf("Packets waiting to be resent: %u\n",
|
||||
NumberOfPacketsToResend());
|
||||
printf("Packets still lost: %u\n",
|
||||
static_cast<unsigned int>(packets_.size()));
|
||||
printf("Sequence numbers:\n");
|
||||
for (ConstRtpPacketIterator it = packets_.begin(); it != packets_.end();
|
||||
++it) {
|
||||
uint16_t seq_num = ((*it)->data[2] << 8) + (*it)->data[3];
|
||||
printf("%u, ", seq_num);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
RTPPlayer::RTPPlayer(const char* filename,
|
||||
@ -176,7 +177,7 @@ RTPPlayer::~RTPPlayer()
|
||||
}
|
||||
}
|
||||
|
||||
WebRtc_Word32 RTPPlayer::Initialize(const ListWrapper& payloadList)
|
||||
WebRtc_Word32 RTPPlayer::Initialize(const PayloadTypeList* payloadList)
|
||||
{
|
||||
std::srand(321);
|
||||
for (int i=0; i < RAND_VEC_LENGTH; i++)
|
||||
@ -205,10 +206,9 @@ WebRtc_Word32 RTPPlayer::Initialize(const ListWrapper& payloadList)
|
||||
return -1;
|
||||
}
|
||||
// Register payload types
|
||||
ListItem* item = payloadList.First();
|
||||
while (item != NULL)
|
||||
{
|
||||
PayloadCodecTuple* payloadType = static_cast<PayloadCodecTuple*>(item->GetItem());
|
||||
for (PayloadTypeList::const_iterator it = payloadList->begin();
|
||||
it != payloadList->end(); ++it) {
|
||||
PayloadCodecTuple* payloadType = *it;
|
||||
if (payloadType != NULL)
|
||||
{
|
||||
VideoCodec videoCodec;
|
||||
@ -219,7 +219,6 @@ WebRtc_Word32 RTPPlayer::Initialize(const ListWrapper& payloadList)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
item = payloadList.Next(item);
|
||||
}
|
||||
if (ReadHeader() < 0)
|
||||
{
|
||||
@ -286,43 +285,21 @@ WebRtc_UWord32 RTPPlayer::TimeUntilNextPacket() const
|
||||
|
||||
WebRtc_Word32 RTPPlayer::NextPacket(const WebRtc_Word64 timeNow)
|
||||
{
|
||||
// Send any packets ready to be resent
|
||||
_lostPackets.Lock();
|
||||
ListItem* item = _lostPackets.First();
|
||||
_lostPackets.Unlock();
|
||||
while (item != NULL)
|
||||
{
|
||||
_lostPackets.Lock();
|
||||
RawRtpPacket* packet = static_cast<RawRtpPacket*>(item->GetItem());
|
||||
_lostPackets.Unlock();
|
||||
if (timeNow >= packet->resendTimeMs && packet->resendTimeMs != -1)
|
||||
{
|
||||
const WebRtc_UWord16 seqNo = (packet->rtpData[2] << 8) + packet->rtpData[3];
|
||||
printf("Resend: %u\n", seqNo);
|
||||
WebRtc_Word32 ret = SendPacket(packet->rtpData, packet->rtpLen);
|
||||
ListItem* itemToRemove = item;
|
||||
_lostPackets.Lock();
|
||||
item = _lostPackets.Next(item);
|
||||
_lostPackets.Erase(itemToRemove);
|
||||
delete packet;
|
||||
_lostPackets.Unlock();
|
||||
_resendPacketCount++;
|
||||
if (ret > 0)
|
||||
{
|
||||
_lostPackets.ResentPacket(seqNo,
|
||||
_clock->MillisecondTimestamp());
|
||||
}
|
||||
else if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_lostPackets.Lock();
|
||||
item = _lostPackets.Next(item);
|
||||
_lostPackets.Unlock();
|
||||
}
|
||||
// Send any packets ready to be resent,
|
||||
RawRtpPacket* resend_packet = _lostPackets.NextPacketToResend(timeNow);
|
||||
while (resend_packet != NULL) {
|
||||
const uint16_t seqNo = (resend_packet->data[2] << 8) +
|
||||
resend_packet->data[3];
|
||||
printf("Resend: %u\n", seqNo);
|
||||
int ret = SendPacket(resend_packet->data, resend_packet->length);
|
||||
delete resend_packet;
|
||||
_resendPacketCount++;
|
||||
if (ret > 0) {
|
||||
_lostPackets.SetPacketResent(seqNo, _clock->MillisecondTimestamp());
|
||||
} else if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
resend_packet = _lostPackets.NextPacketToResend(timeNow);
|
||||
}
|
||||
|
||||
// Send any packets from rtp file
|
||||
@ -344,7 +321,7 @@ WebRtc_Word32 RTPPlayer::NextPacket(const WebRtc_Word64 timeNow)
|
||||
{
|
||||
RawRtpPacket* rtpPacket = _reorderBuffer;
|
||||
_reorderBuffer = NULL;
|
||||
SendPacket(rtpPacket->rtpData, rtpPacket->rtpLen);
|
||||
SendPacket(rtpPacket->data, rtpPacket->length);
|
||||
delete rtpPacket;
|
||||
}
|
||||
_firstPacket = false;
|
||||
@ -379,11 +356,11 @@ WebRtc_Word32 RTPPlayer::SendPacket(WebRtc_UWord8* rtpData, WebRtc_UWord16 rtpLe
|
||||
{
|
||||
const WebRtc_UWord16 seqNo = (rtpData[2] << 8) + rtpData[3];
|
||||
printf("Throw: %u\n", seqNo);
|
||||
_lostPackets.AddPacket(rtpData, rtpLen);
|
||||
_lostPackets.AddPacket(new RawRtpPacket(rtpData, rtpLen));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (rtpLen > 0)
|
||||
{
|
||||
WebRtc_Word32 ret = _rtpModule.IncomingPacket(rtpData, rtpLen);
|
||||
if (ret < 0)
|
||||
@ -461,17 +438,6 @@ WebRtc_Word32 RTPPlayer::ResendPackets(const WebRtc_UWord16* sequenceNumbers, We
|
||||
|
||||
void RTPPlayer::Print() const
|
||||
{
|
||||
printf("Lost packets: %u, resent packets: %u\n", _lostPackets.TotalNumberOfLosses(), _resendPacketCount);
|
||||
printf("Packets still lost: %u\n", _lostPackets.GetSize());
|
||||
printf("Packets waiting to be resent: %u\n", _lostPackets.NumberOfPacketsToResend());
|
||||
printf("Sequence numbers:\n");
|
||||
ListItem* item = _lostPackets.First();
|
||||
while (item != NULL)
|
||||
{
|
||||
RawRtpPacket* packet = static_cast<RawRtpPacket*>(item->GetItem());
|
||||
const WebRtc_UWord16 seqNo = (packet->rtpData[2] << 8) + packet->rtpData[3];
|
||||
printf("%u, ", seqNo);
|
||||
item = _lostPackets.Next(item);
|
||||
}
|
||||
printf("\n");
|
||||
printf("Resent packets: %u\n", _resendPacketCount);
|
||||
_lostPackets.Print();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
@ -13,48 +13,55 @@
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "rtp_rtcp.h"
|
||||
#include "list_wrapper.h"
|
||||
#include "critical_section_wrapper.h"
|
||||
#include "video_coding_defines.h"
|
||||
#include "modules/video_coding/main/source/tick_time_base.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#define HDR_SIZE 8 // rtpplay packet header size in bytes
|
||||
#define FIRSTLINELEN 40
|
||||
#define RAND_VEC_LENGTH 4096
|
||||
|
||||
class PayloadCodecTuple;
|
||||
|
||||
struct RawRtpPacket
|
||||
{
|
||||
public:
|
||||
RawRtpPacket(WebRtc_UWord8* data, WebRtc_UWord16 len);
|
||||
RawRtpPacket(WebRtc_UWord8* rtp_data, WebRtc_UWord16 rtp_length);
|
||||
~RawRtpPacket();
|
||||
|
||||
WebRtc_UWord8* rtpData;
|
||||
WebRtc_UWord16 rtpLen;
|
||||
WebRtc_Word64 resendTimeMs;
|
||||
uint8_t* data;
|
||||
uint16_t length;
|
||||
int64_t resend_time_ms;
|
||||
};
|
||||
|
||||
class LostPackets : public webrtc::ListWrapper
|
||||
{
|
||||
public:
|
||||
LostPackets();
|
||||
~LostPackets();
|
||||
typedef std::list<PayloadCodecTuple*> PayloadTypeList;
|
||||
typedef std::list<RawRtpPacket*> RtpPacketList;
|
||||
typedef RtpPacketList::iterator RtpPacketIterator;
|
||||
typedef RtpPacketList::const_iterator ConstRtpPacketIterator;
|
||||
|
||||
WebRtc_UWord32 AddPacket(WebRtc_UWord8* rtpData, WebRtc_UWord16 rtpLen);
|
||||
WebRtc_UWord32 SetResendTime(WebRtc_UWord16 sequenceNumber,
|
||||
WebRtc_Word64 resendTime,
|
||||
WebRtc_Word64 nowMs);
|
||||
WebRtc_UWord32 TotalNumberOfLosses() const { return _lossCount; };
|
||||
WebRtc_UWord32 NumberOfPacketsToResend() const;
|
||||
void ResentPacket(WebRtc_UWord16 seqNo, WebRtc_Word64 nowMs);
|
||||
void Lock() {_critSect->Enter();};
|
||||
void Unlock() {_critSect->Leave();};
|
||||
private:
|
||||
webrtc::CriticalSectionWrapper* _critSect;
|
||||
WebRtc_UWord32 _lossCount;
|
||||
FILE* _debugFile;
|
||||
class LostPackets {
|
||||
public:
|
||||
LostPackets();
|
||||
~LostPackets();
|
||||
|
||||
void AddPacket(RawRtpPacket* packet);
|
||||
void SetResendTime(uint16_t sequenceNumber,
|
||||
int64_t resendTime,
|
||||
int64_t nowMs);
|
||||
RawRtpPacket* NextPacketToResend(int64_t timeNow);
|
||||
int NumberOfPacketsToResend() const;
|
||||
void SetPacketResent(uint16_t seqNo, int64_t nowMs);
|
||||
void Print() const;
|
||||
|
||||
private:
|
||||
webrtc::CriticalSectionWrapper* crit_sect_;
|
||||
int loss_count_;
|
||||
FILE* debug_file_;
|
||||
RtpPacketList packets_;
|
||||
};
|
||||
|
||||
struct PayloadCodecTuple
|
||||
@ -74,7 +81,7 @@ public:
|
||||
webrtc::TickTimeBase* clock);
|
||||
virtual ~RTPPlayer();
|
||||
|
||||
WebRtc_Word32 Initialize(const webrtc::ListWrapper& payloadList);
|
||||
WebRtc_Word32 Initialize(const PayloadTypeList* payloadList);
|
||||
WebRtc_Word32 NextPacket(const WebRtc_Word64 timeNow);
|
||||
WebRtc_UWord32 TimeUntilNextPacket() const;
|
||||
WebRtc_Word32 SimulatePacketLoss(float lossRate, bool enableNack = false, WebRtc_UWord32 rttMs = 0);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
@ -225,11 +225,11 @@ RTPSendCompleteCallback::~RTPSendCompleteCallback()
|
||||
RtpDump::DestroyRtpDump(_rtpDump);
|
||||
}
|
||||
// Delete remaining packets
|
||||
while (!_rtpPackets.Empty())
|
||||
while (!_rtpPackets.empty())
|
||||
{
|
||||
// Take first packet in list
|
||||
delete static_cast<rtpPacket*>((_rtpPackets.First())->GetItem());
|
||||
_rtpPackets.PopFront();
|
||||
// Take first packet in list
|
||||
delete _rtpPackets.front();
|
||||
_rtpPackets.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
@ -254,7 +254,7 @@ RTPSendCompleteCallback::SendPacket(int channel, const void *data, int len)
|
||||
// Insert outgoing packet into list
|
||||
if (transmitPacket)
|
||||
{
|
||||
rtpPacket* newPacket = new rtpPacket();
|
||||
RtpPacket* newPacket = new RtpPacket();
|
||||
memcpy(newPacket->data, data, len);
|
||||
newPacket->length = len;
|
||||
// Simulate receive time = network delay + packet jitter
|
||||
@ -264,16 +264,16 @@ RTPSendCompleteCallback::SendPacket(int channel, const void *data, int len)
|
||||
simulatedDelay = (WebRtc_Word32)NormalDist(_networkDelayMs,
|
||||
sqrt(_jitterVar));
|
||||
newPacket->receiveTime = now + simulatedDelay;
|
||||
_rtpPackets.PushBack(newPacket);
|
||||
_rtpPackets.push_back(newPacket);
|
||||
}
|
||||
|
||||
// Are we ready to send packets to the receiver?
|
||||
rtpPacket* packet = NULL;
|
||||
RtpPacket* packet = NULL;
|
||||
|
||||
while (!_rtpPackets.Empty())
|
||||
while (!_rtpPackets.empty())
|
||||
{
|
||||
// Take first packet in list
|
||||
packet = static_cast<rtpPacket*>((_rtpPackets.First())->GetItem());
|
||||
packet = _rtpPackets.front();
|
||||
WebRtc_Word64 timeToReceive = packet->receiveTime - now;
|
||||
if (timeToReceive > 0)
|
||||
{
|
||||
@ -281,7 +281,7 @@ RTPSendCompleteCallback::SendPacket(int channel, const void *data, int len)
|
||||
break;
|
||||
}
|
||||
|
||||
_rtpPackets.PopFront();
|
||||
_rtpPackets.pop_front();
|
||||
// Send to receive side
|
||||
if (_rtp->IncomingPacket((const WebRtc_UWord8*)packet->data,
|
||||
packet->length) < 0)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
@ -16,11 +16,11 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <string.h>
|
||||
#include <list>
|
||||
|
||||
#include "list_wrapper.h"
|
||||
#include "module_common_types.h"
|
||||
#include "rtp_rtcp.h"
|
||||
#include "test_util.h"
|
||||
@ -29,7 +29,7 @@
|
||||
|
||||
namespace webrtc
|
||||
{
|
||||
class RtpDump;
|
||||
class RtpDump;
|
||||
|
||||
// Send Side - Packetization callback - send an encoded frame to the VCMReceiver
|
||||
class VCMEncodeCompleteCallback: public VCMPacketizationCallback
|
||||
@ -147,7 +147,6 @@ private:
|
||||
WebRtc_UWord32 _decodedBytes;
|
||||
}; // end of VCMDecodeCompleCallback class
|
||||
|
||||
|
||||
// Transport callback
|
||||
// Called by the RTP Sender - simulates sending packets through a network to the
|
||||
// RTP receiver. User can set network conditions as: RTT, packet loss,
|
||||
@ -192,7 +191,7 @@ protected:
|
||||
double _jitterVar;
|
||||
bool _prevLossState;
|
||||
WebRtc_UWord32 _totalSentLength;
|
||||
ListWrapper _rtpPackets;
|
||||
std::list<RtpPacket*> _rtpPackets;
|
||||
RtpDump* _rtpDump;
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
@ -61,12 +61,11 @@ class CmdArgs
|
||||
int MTRxTxTest(CmdArgs& args);
|
||||
double NormalDist(double mean, double stdDev);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WebRtc_Word8 data[1650]; // max packet size
|
||||
WebRtc_Word32 length;
|
||||
WebRtc_Word64 receiveTime;
|
||||
} rtpPacket;
|
||||
struct RtpPacket {
|
||||
WebRtc_Word8 data[1650]; // max packet size
|
||||
WebRtc_Word32 length;
|
||||
WebRtc_Word64 receiveTime;
|
||||
};
|
||||
|
||||
|
||||
// Codec type conversion
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
@ -80,7 +80,7 @@ int RtpPlay(CmdArgs& args)
|
||||
|
||||
bool protectionEnabled = false;
|
||||
VCMVideoProtection protectionMethod = kProtectionNack;
|
||||
WebRtc_UWord32 rttMS = 10;
|
||||
WebRtc_UWord32 rttMS = 0;
|
||||
float lossRate = 0.0f;
|
||||
bool reordering = false;
|
||||
WebRtc_UWord32 renderDelayMs = 0;
|
||||
@ -96,8 +96,9 @@ int RtpPlay(CmdArgs& args)
|
||||
RTPPlayer rtpStream(args.inputFile.c_str(), &dataCallback, &clock);
|
||||
|
||||
|
||||
ListWrapper payloadTypes;
|
||||
payloadTypes.PushFront(new PayloadCodecTuple(VCM_VP8_PAYLOAD_TYPE, "VP8", kVideoCodecVP8));
|
||||
PayloadTypeList payloadTypes;
|
||||
payloadTypes.push_front(new PayloadCodecTuple(VCM_VP8_PAYLOAD_TYPE, "VP8",
|
||||
kVideoCodecVP8));
|
||||
|
||||
Trace::CreateTrace();
|
||||
Trace::SetTraceFile((test::OutputPath() + "receiverTestTrace.txt").c_str());
|
||||
@ -115,10 +116,9 @@ int RtpPlay(CmdArgs& args)
|
||||
vcm->RegisterPacketRequestCallback(&rtpStream);
|
||||
|
||||
// Register receive codecs in VCM
|
||||
ListItem* item = payloadTypes.First();
|
||||
while (item != NULL)
|
||||
{
|
||||
PayloadCodecTuple* payloadType = static_cast<PayloadCodecTuple*>(item->GetItem());
|
||||
for (PayloadTypeList::iterator it = payloadTypes.begin();
|
||||
it != payloadTypes.end(); ++it) {
|
||||
PayloadCodecTuple* payloadType = *it;
|
||||
if (payloadType != NULL)
|
||||
{
|
||||
VideoCodec codec;
|
||||
@ -132,15 +132,15 @@ int RtpPlay(CmdArgs& args)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
item = payloadTypes.Next(item);
|
||||
}
|
||||
|
||||
if (rtpStream.Initialize(payloadTypes) < 0)
|
||||
if (rtpStream.Initialize(&payloadTypes) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
bool nackEnabled = protectionEnabled && (protectionMethod == kProtectionNack ||
|
||||
protectionMethod == kProtectionDualDecoder);
|
||||
bool nackEnabled = protectionEnabled &&
|
||||
(protectionMethod == kProtectionNack ||
|
||||
protectionMethod == kProtectionDualDecoder);
|
||||
rtpStream.SimulatePacketLoss(lossRate, nackEnabled, rttMS);
|
||||
rtpStream.SetReordering(reordering);
|
||||
vcm->SetChannelParameters(0, 0, rttMS);
|
||||
@ -166,7 +166,8 @@ int RtpPlay(CmdArgs& args)
|
||||
{
|
||||
vcm->Process();
|
||||
}
|
||||
if (MAX_RUNTIME_MS > -1 && clock.MillisecondTimestamp() >= MAX_RUNTIME_MS)
|
||||
if (MAX_RUNTIME_MS > -1 && clock.MillisecondTimestamp() >=
|
||||
MAX_RUNTIME_MS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -189,17 +190,10 @@ int RtpPlay(CmdArgs& args)
|
||||
rtpStream.Print();
|
||||
|
||||
// Tear down
|
||||
item = payloadTypes.First();
|
||||
while (item != NULL)
|
||||
while (!payloadTypes.empty())
|
||||
{
|
||||
PayloadCodecTuple* payloadType = static_cast<PayloadCodecTuple*>(item->GetItem());
|
||||
if (payloadType != NULL)
|
||||
{
|
||||
delete payloadType;
|
||||
}
|
||||
ListItem* itemToRemove = item;
|
||||
item = payloadTypes.Next(item);
|
||||
payloadTypes.Erase(itemToRemove);
|
||||
delete payloadTypes.front();
|
||||
payloadTypes.pop_front();
|
||||
}
|
||||
delete vcm;
|
||||
vcm = NULL;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
@ -137,10 +137,9 @@ int RtpPlayMT(CmdArgs& args, int releaseTestNo, webrtc::VideoCodecType releaseTe
|
||||
printf("Watch %s to verify that the output is reasonable\n", outFilename.c_str());
|
||||
}
|
||||
RTPPlayer rtpStream(rtpFilename.c_str(), &dataCallback, &clock);
|
||||
ListWrapper payloadTypes;
|
||||
payloadTypes.PushFront(new PayloadCodecTuple(VCM_VP8_PAYLOAD_TYPE,
|
||||
"VP8", kVideoCodecVP8));
|
||||
|
||||
PayloadTypeList payloadTypes;
|
||||
payloadTypes.push_front(new PayloadCodecTuple(VCM_VP8_PAYLOAD_TYPE, "VP8",
|
||||
kVideoCodecVP8));
|
||||
Trace::CreateTrace();
|
||||
Trace::SetTraceFile("receiverTestTrace.txt");
|
||||
Trace::SetLevelFilter(webrtc::kTraceAll);
|
||||
@ -151,7 +150,7 @@ int RtpPlayMT(CmdArgs& args, int releaseTestNo, webrtc::VideoCodecType releaseTe
|
||||
|
||||
SharedState mtState(*vcm, rtpStream);
|
||||
|
||||
if (rtpStream.Initialize(payloadTypes) < 0)
|
||||
if (rtpStream.Initialize(&payloadTypes) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@ -172,10 +171,9 @@ int RtpPlayMT(CmdArgs& args, int releaseTestNo, webrtc::VideoCodecType releaseTe
|
||||
&mtState, kNormalPriority, "DecodeThread");
|
||||
|
||||
// Register receive codecs in VCM
|
||||
ListItem* item = payloadTypes.First();
|
||||
while (item != NULL)
|
||||
{
|
||||
PayloadCodecTuple* payloadType = static_cast<PayloadCodecTuple*>(item->GetItem());
|
||||
for (PayloadTypeList::iterator it = payloadTypes.begin();
|
||||
it != payloadTypes.end(); ++it) {
|
||||
PayloadCodecTuple* payloadType = *it;
|
||||
if (payloadType != NULL)
|
||||
{
|
||||
VideoCodec codec;
|
||||
@ -186,7 +184,6 @@ int RtpPlayMT(CmdArgs& args, int releaseTestNo, webrtc::VideoCodecType releaseTe
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
item = payloadTypes.Next(item);
|
||||
}
|
||||
|
||||
if (processingThread != NULL)
|
||||
@ -235,17 +232,10 @@ int RtpPlayMT(CmdArgs& args, int releaseTestNo, webrtc::VideoCodecType releaseTe
|
||||
waitEvent.Wait(MAX_RUNTIME_MS);
|
||||
|
||||
// Tear down
|
||||
item = payloadTypes.First();
|
||||
while (item != NULL)
|
||||
while (!payloadTypes.empty())
|
||||
{
|
||||
PayloadCodecTuple* payloadType = static_cast<PayloadCodecTuple*>(item->GetItem());
|
||||
if (payloadType != NULL)
|
||||
{
|
||||
delete payloadType;
|
||||
}
|
||||
ListItem* itemToRemove = item;
|
||||
item = payloadTypes.Next(item);
|
||||
payloadTypes.Erase(itemToRemove);
|
||||
delete payloadTypes.front();
|
||||
payloadTypes.pop_front();
|
||||
}
|
||||
while (!processingThread->Stop())
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user