blob: 80eba2e3051cd2d1fdf0aa51f62f5048da05ea01 [file] [log] [blame]
/*
* Copyright (c) 2018 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 "modules/include/module_common_types.h"
#include <string.h>
#include <cstdint>
#include <utility>
#include "rtc_base/numerics/safe_conversions.h"
namespace webrtc {
RTPFragmentationHeader::RTPFragmentationHeader()
: fragmentationVectorSize(0),
fragmentationOffset(nullptr),
fragmentationLength(nullptr),
fragmentationTimeDiff(nullptr),
fragmentationPlType(nullptr) {}
RTPFragmentationHeader::RTPFragmentationHeader(RTPFragmentationHeader&& other)
: RTPFragmentationHeader() {
swap(*this, other);
}
RTPFragmentationHeader& RTPFragmentationHeader::operator=(
RTPFragmentationHeader&& other) {
swap(*this, other);
return *this;
}
RTPFragmentationHeader::~RTPFragmentationHeader() {
delete[] fragmentationOffset;
delete[] fragmentationLength;
delete[] fragmentationTimeDiff;
delete[] fragmentationPlType;
}
void swap(RTPFragmentationHeader& a, RTPFragmentationHeader& b) {
using std::swap;
swap(a.fragmentationVectorSize, b.fragmentationVectorSize);
swap(a.fragmentationOffset, b.fragmentationOffset);
swap(a.fragmentationLength, b.fragmentationLength);
swap(a.fragmentationTimeDiff, b.fragmentationTimeDiff);
swap(a.fragmentationPlType, b.fragmentationPlType);
}
void RTPFragmentationHeader::CopyFrom(const RTPFragmentationHeader& src) {
if (this == &src) {
return;
}
if (src.fragmentationVectorSize != fragmentationVectorSize) {
// new size of vectors
// delete old
delete[] fragmentationOffset;
fragmentationOffset = nullptr;
delete[] fragmentationLength;
fragmentationLength = nullptr;
delete[] fragmentationTimeDiff;
fragmentationTimeDiff = nullptr;
delete[] fragmentationPlType;
fragmentationPlType = nullptr;
if (src.fragmentationVectorSize > 0) {
// allocate new
if (src.fragmentationOffset) {
fragmentationOffset = new size_t[src.fragmentationVectorSize];
}
if (src.fragmentationLength) {
fragmentationLength = new size_t[src.fragmentationVectorSize];
}
if (src.fragmentationTimeDiff) {
fragmentationTimeDiff = new uint16_t[src.fragmentationVectorSize];
}
if (src.fragmentationPlType) {
fragmentationPlType = new uint8_t[src.fragmentationVectorSize];
}
}
// set new size
fragmentationVectorSize = src.fragmentationVectorSize;
}
if (src.fragmentationVectorSize > 0) {
// copy values
if (src.fragmentationOffset) {
memcpy(fragmentationOffset, src.fragmentationOffset,
src.fragmentationVectorSize * sizeof(size_t));
}
if (src.fragmentationLength) {
memcpy(fragmentationLength, src.fragmentationLength,
src.fragmentationVectorSize * sizeof(size_t));
}
if (src.fragmentationTimeDiff) {
memcpy(fragmentationTimeDiff, src.fragmentationTimeDiff,
src.fragmentationVectorSize * sizeof(uint16_t));
}
if (src.fragmentationPlType) {
memcpy(fragmentationPlType, src.fragmentationPlType,
src.fragmentationVectorSize * sizeof(uint8_t));
}
}
}
void RTPFragmentationHeader::Resize(size_t size) {
const uint16_t size16 = rtc::dchecked_cast<uint16_t>(size);
if (fragmentationVectorSize < size16) {
uint16_t oldVectorSize = fragmentationVectorSize;
{
// offset
size_t* oldOffsets = fragmentationOffset;
fragmentationOffset = new size_t[size16];
memset(fragmentationOffset + oldVectorSize, 0,
sizeof(size_t) * (size16 - oldVectorSize));
// copy old values
memcpy(fragmentationOffset, oldOffsets, sizeof(size_t) * oldVectorSize);
delete[] oldOffsets;
}
// length
{
size_t* oldLengths = fragmentationLength;
fragmentationLength = new size_t[size16];
memset(fragmentationLength + oldVectorSize, 0,
sizeof(size_t) * (size16 - oldVectorSize));
memcpy(fragmentationLength, oldLengths, sizeof(size_t) * oldVectorSize);
delete[] oldLengths;
}
// time diff
{
uint16_t* oldTimeDiffs = fragmentationTimeDiff;
fragmentationTimeDiff = new uint16_t[size16];
memset(fragmentationTimeDiff + oldVectorSize, 0,
sizeof(uint16_t) * (size16 - oldVectorSize));
memcpy(fragmentationTimeDiff, oldTimeDiffs,
sizeof(uint16_t) * oldVectorSize);
delete[] oldTimeDiffs;
}
// payload type
{
uint8_t* oldTimePlTypes = fragmentationPlType;
fragmentationPlType = new uint8_t[size16];
memset(fragmentationPlType + oldVectorSize, 0,
sizeof(uint8_t) * (size16 - oldVectorSize));
memcpy(fragmentationPlType, oldTimePlTypes,
sizeof(uint8_t) * oldVectorSize);
delete[] oldTimePlTypes;
}
fragmentationVectorSize = size16;
}
}
} // namespace webrtc