1e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org/* 2e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org * 4e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org * Use of this source code is governed by a BSD-style license 5e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org * that can be found in the LICENSE file in the root of the source 6e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org * tree. An additional intellectual property rights grant can be found 7e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org * in the file PATENTS. All contributing project authors may 8e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org */ 10e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org 11e5abc854f3dc47de16067c2a41476c39b7626722henrik.lundin@webrtc.org#include "webrtc/modules/audio_coding/neteq/tools/packet.h" 12655819eb8dfd638d060c3cdd1ba37fe0a47d0cafhenrik.lundin@webrtc.org 13655819eb8dfd638d060c3cdd1ba37fe0a47d0cafhenrik.lundin@webrtc.org#include <string.h> 14655819eb8dfd638d060c3cdd1ba37fe0a47d0cafhenrik.lundin@webrtc.org 15655819eb8dfd638d060c3cdd1ba37fe0a47d0cafhenrik.lundin@webrtc.org#include "webrtc/modules/interface/module_common_types.h" 16e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" 17e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org 18e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.orgnamespace webrtc { 19e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.orgnamespace test { 20e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org 21e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.orgPacket::Packet(uint8_t* packet_memory, 22e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org size_t allocated_bytes, 23e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org double time_ms, 24e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org const RtpHeaderParser& parser) 25e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org : payload_memory_(packet_memory), 26e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org payload_(NULL), 27e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org packet_length_bytes_(allocated_bytes), 28e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org payload_length_bytes_(0), 29e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org virtual_packet_length_bytes_(allocated_bytes), 30e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org virtual_payload_length_bytes_(0), 31e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org time_ms_(time_ms) { 32e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org valid_header_ = ParseHeader(parser); 33e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org} 34e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org 35e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.orgPacket::Packet(uint8_t* packet_memory, 36e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org size_t allocated_bytes, 37e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org size_t virtual_packet_length_bytes, 38e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org double time_ms, 39e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org const RtpHeaderParser& parser) 40e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org : payload_memory_(packet_memory), 41e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org payload_(NULL), 42e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org packet_length_bytes_(allocated_bytes), 43e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org payload_length_bytes_(0), 44e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org virtual_packet_length_bytes_(virtual_packet_length_bytes), 45e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org virtual_payload_length_bytes_(0), 46e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org time_ms_(time_ms) { 47e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org valid_header_ = ParseHeader(parser); 48e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org} 49e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org 50e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.orgPacket::Packet(uint8_t* packet_memory, size_t allocated_bytes, double time_ms) 51e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org : payload_memory_(packet_memory), 52e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org payload_(NULL), 53e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org packet_length_bytes_(allocated_bytes), 54e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org payload_length_bytes_(0), 55e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org virtual_packet_length_bytes_(allocated_bytes), 56e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org virtual_payload_length_bytes_(0), 57e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org time_ms_(time_ms) { 58e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create()); 59e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org valid_header_ = ParseHeader(*parser); 60e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org} 61e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org 62e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.orgPacket::Packet(uint8_t* packet_memory, 63e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org size_t allocated_bytes, 64e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org size_t virtual_packet_length_bytes, 65e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org double time_ms) 66e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org : payload_memory_(packet_memory), 67e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org payload_(NULL), 68e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org packet_length_bytes_(allocated_bytes), 69e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org payload_length_bytes_(0), 70e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org virtual_packet_length_bytes_(virtual_packet_length_bytes), 71e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org virtual_payload_length_bytes_(0), 72e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org time_ms_(time_ms) { 73e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create()); 74e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org valid_header_ = ParseHeader(*parser); 75e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org} 76e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org 77e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.orgbool Packet::ExtractRedHeaders(std::list<RTPHeader*>* headers) const { 78e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org // 79e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org // 0 1 2 3 80e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 81e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 82e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org // |1| block PT | timestamp offset | block length | 83e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 84e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org // |1| ... | 85e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 86e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org // |0| block PT | 87e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org // +-+-+-+-+-+-+-+-+ 88e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org // 89e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org 90e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org assert(payload_); 91e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org const uint8_t* payload_ptr = payload_; 92e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org const uint8_t* payload_end_ptr = payload_ptr + payload_length_bytes_; 93e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org 94e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org // Find all RED headers with the extension bit set to 1. That is, all headers 95e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org // but the last one. 96e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org while ((payload_ptr < payload_end_ptr) && (*payload_ptr & 0x80)) { 97e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org RTPHeader* header = new RTPHeader; 98e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org CopyToHeader(header); 99e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org header->payloadType = payload_ptr[0] & 0x7F; 100e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org uint32_t offset = (payload_ptr[1] << 6) + ((payload_ptr[2] & 0xFC) >> 2); 101e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org header->timestamp -= offset; 102e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org headers->push_front(header); 103e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org payload_ptr += 4; 104e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org } 105e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org // Last header. 106e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org assert(payload_ptr < payload_end_ptr); 107e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org if (payload_ptr >= payload_end_ptr) { 108e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org return false; // Payload too short. 109e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org } 110e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org RTPHeader* header = new RTPHeader; 111e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org CopyToHeader(header); 112e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org header->payloadType = payload_ptr[0] & 0x7F; 113e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org headers->push_front(header); 114e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org return true; 115e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org} 116e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org 117e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.orgvoid Packet::DeleteRedHeaders(std::list<RTPHeader*>* headers) { 118e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org while (!headers->empty()) { 119e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org delete headers->front(); 120e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org headers->pop_front(); 121e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org } 122e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org} 123e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org 124655819eb8dfd638d060c3cdd1ba37fe0a47d0cafhenrik.lundin@webrtc.orgvoid Packet::ConvertHeader(WebRtcRTPHeader* copy_to) const { 125655819eb8dfd638d060c3cdd1ba37fe0a47d0cafhenrik.lundin@webrtc.org memcpy(©_to->header, &header_, sizeof(header_)); 126655819eb8dfd638d060c3cdd1ba37fe0a47d0cafhenrik.lundin@webrtc.org copy_to->frameType = kAudioFrameSpeech; 127655819eb8dfd638d060c3cdd1ba37fe0a47d0cafhenrik.lundin@webrtc.org copy_to->type.Audio.numEnergy = 0; 128655819eb8dfd638d060c3cdd1ba37fe0a47d0cafhenrik.lundin@webrtc.org copy_to->type.Audio.channel = 1; 129655819eb8dfd638d060c3cdd1ba37fe0a47d0cafhenrik.lundin@webrtc.org copy_to->type.Audio.isCNG = false; 130655819eb8dfd638d060c3cdd1ba37fe0a47d0cafhenrik.lundin@webrtc.org} 131655819eb8dfd638d060c3cdd1ba37fe0a47d0cafhenrik.lundin@webrtc.org 132e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.orgbool Packet::ParseHeader(const RtpHeaderParser& parser) { 133e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org bool valid_header = parser.Parse( 134e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org payload_memory_.get(), static_cast<int>(packet_length_bytes_), &header_); 135e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org assert(valid_header); 136e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org if (!valid_header) { 137e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org return false; 138e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org } 139e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org assert(header_.headerLength <= packet_length_bytes_); 140e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org payload_ = &payload_memory_[header_.headerLength]; 141e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org assert(packet_length_bytes_ >= header_.headerLength); 142e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org payload_length_bytes_ = packet_length_bytes_ - header_.headerLength; 143e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org assert(virtual_packet_length_bytes_ >= header_.headerLength); 144e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org virtual_payload_length_bytes_ = 145e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org virtual_packet_length_bytes_ - header_.headerLength; 146e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org return true; 147e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org} 148e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org 149e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.orgvoid Packet::CopyToHeader(RTPHeader* destination) const { 150e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org destination->markerBit = header_.markerBit; 151e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org destination->payloadType = header_.payloadType; 152e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org destination->sequenceNumber = header_.sequenceNumber; 153e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org destination->timestamp = header_.timestamp; 154e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org destination->ssrc = header_.ssrc; 155e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org destination->numCSRCs = header_.numCSRCs; 156e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org destination->paddingLength = header_.paddingLength; 157e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org destination->headerLength = header_.headerLength; 158e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org destination->payload_type_frequency = header_.payload_type_frequency; 159e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org memcpy(&destination->arrOfCSRCs, 160e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org &header_.arrOfCSRCs, 161e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org sizeof(header_.arrOfCSRCs)); 162e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org memcpy( 163e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org &destination->extension, &header_.extension, sizeof(header_.extension)); 164e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org} 165e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org 166e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org} // namespace test 167e7d9de31cd13fb915c858c54a84ab39f788c3c69henrik.lundin@webrtc.org} // namespace webrtc 168