/* * 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 * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "NETEQTEST_DummyRTPpacket.h" #include #include #include #ifdef WIN32 #include #else #include // for htons, htonl, etc #endif int NETEQTEST_DummyRTPpacket::readFromFile(FILE *fp) { if (!fp) { return -1; } uint16_t length, plen; uint32_t offset; int packetLen = 0; bool readNextPacket = true; while (readNextPacket) { readNextPacket = false; if (fread(&length, 2, 1, fp) == 0) { reset(); return -2; } length = ntohs(length); if (fread(&plen, 2, 1, fp) == 0) { reset(); return -1; } packetLen = ntohs(plen); if (fread(&offset, 4, 1, fp) == 0) { reset(); return -1; } // Store in local variable until we have passed the reset below. uint32_t receiveTime = ntohl(offset); // Use length here because a plen of 0 specifies rtcp. length = (uint16_t) (length - _kRDHeaderLen); // check buffer size if (_datagram && _memSize < length + 1) { reset(); } if (!_datagram) { // Add one extra byte, to be able to fake a dummy payload of 1 byte. _datagram = new uint8_t[length + 1]; _memSize = length + 1; } memset(_datagram, 0, length + 1); if (length == 0) { _datagramLen = 0; _rtpParsed = false; return packetLen; } // Read basic header if (fread((unsigned short *) _datagram, 1, _kBasicHeaderLen, fp) != (size_t)_kBasicHeaderLen) { reset(); return -1; } _receiveTime = receiveTime; _datagramLen = _kBasicHeaderLen; // Parse the basic header webrtc::WebRtcRTPHeader tempRTPinfo; int P, X, CC; parseBasicHeader(&tempRTPinfo, &P, &X, &CC); // Check if we have to extend the header if (X != 0 || CC != 0) { int newLen = _kBasicHeaderLen + CC * 4 + X * 4; assert(_memSize >= newLen); // Read extension from file size_t readLen = newLen - _kBasicHeaderLen; if (fread(&_datagram[_kBasicHeaderLen], 1, readLen, fp) != readLen) { reset(); return -1; } _datagramLen = newLen; if (X != 0) { int totHdrLen = calcHeaderLength(X, CC); assert(_memSize >= totHdrLen); // Read extension from file size_t readLen = totHdrLen - newLen; if (fread(&_datagram[newLen], 1, readLen, fp) != readLen) { reset(); return -1; } _datagramLen = totHdrLen; } } _datagramLen = length; if (!_blockList.empty() && _blockList.count(payloadType()) > 0) { readNextPacket = true; } } _rtpParsed = false; assert(_memSize > _datagramLen); _payloadLen = 1; // Set the length to 1 byte. return packetLen; } int NETEQTEST_DummyRTPpacket::writeToFile(FILE *fp) { if (!fp) { return -1; } uint16_t length, plen; uint32_t offset; // length including RTPplay header length = htons(_datagramLen + _kRDHeaderLen); if (fwrite(&length, 2, 1, fp) != 1) { return -1; } // payload length plen = htons(_datagramLen); if (fwrite(&plen, 2, 1, fp) != 1) { return -1; } // offset (=receive time) offset = htonl(_receiveTime); if (fwrite(&offset, 4, 1, fp) != 1) { return -1; } // Figure out the length of the RTP header. int headerLen; if (_datagramLen == 0) { // No payload at all; we are done writing to file. headerLen = 0; } else { parseHeader(); headerLen = _payloadPtr - _datagram; assert(headerLen >= 0); } // write RTP header if (fwrite((unsigned short *) _datagram, 1, headerLen, fp) != static_cast(headerLen)) { return -1; } return (headerLen + _kRDHeaderLen); // total number of bytes written } void NETEQTEST_DummyRTPpacket::parseHeader() { NETEQTEST_RTPpacket::parseHeader(); // Change _payloadLen to 1 byte. The memory should always be big enough. assert(_memSize > _datagramLen); _payloadLen = 1; }