1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "webrtc/modules/rtp_rtcp/source/fec_test_helper.h" 12 13 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" 14 15 namespace webrtc { 16 17 FrameGenerator::FrameGenerator() 18 : num_packets_(0), seq_num_(0), timestamp_(0) {} 19 20 void FrameGenerator::NewFrame(int num_packets) { 21 num_packets_ = num_packets; 22 timestamp_ += 3000; 23 } 24 25 uint16_t FrameGenerator::NextSeqNum() { return ++seq_num_; } 26 27 RtpPacket* FrameGenerator::NextPacket(int offset, size_t length) { 28 RtpPacket* rtp_packet = new RtpPacket; 29 for (size_t i = 0; i < length; ++i) 30 rtp_packet->data[i + kRtpHeaderSize] = offset + i; 31 rtp_packet->length = length + kRtpHeaderSize; 32 memset(&rtp_packet->header, 0, sizeof(WebRtcRTPHeader)); 33 rtp_packet->header.frameType = kVideoFrameDelta; 34 rtp_packet->header.header.headerLength = kRtpHeaderSize; 35 rtp_packet->header.header.markerBit = (num_packets_ == 1); 36 rtp_packet->header.header.sequenceNumber = seq_num_; 37 rtp_packet->header.header.timestamp = timestamp_; 38 rtp_packet->header.header.payloadType = kVp8PayloadType; 39 BuildRtpHeader(rtp_packet->data, &rtp_packet->header.header); 40 ++seq_num_; 41 --num_packets_; 42 return rtp_packet; 43 } 44 45 // Creates a new RtpPacket with the RED header added to the packet. 46 RtpPacket* FrameGenerator::BuildMediaRedPacket(const RtpPacket* packet) { 47 const int kHeaderLength = packet->header.header.headerLength; 48 RtpPacket* red_packet = new RtpPacket; 49 red_packet->header = packet->header; 50 red_packet->length = packet->length + 1; // 1 byte RED header. 51 memset(red_packet->data, 0, red_packet->length); 52 // Copy RTP header. 53 memcpy(red_packet->data, packet->data, kHeaderLength); 54 SetRedHeader(red_packet, red_packet->data[1] & 0x7f, kHeaderLength); 55 memcpy(red_packet->data + kHeaderLength + 1, packet->data + kHeaderLength, 56 packet->length - kHeaderLength); 57 return red_packet; 58 } 59 60 // Creates a new RtpPacket with FEC payload and red header. Does this by 61 // creating a new fake media RtpPacket, clears the marker bit and adds a RED 62 // header. Finally replaces the payload with the content of |packet->data|. 63 RtpPacket* FrameGenerator::BuildFecRedPacket(const Packet* packet) { 64 // Create a fake media packet to get a correct header. 1 byte RED header. 65 ++num_packets_; 66 RtpPacket* red_packet = NextPacket(0, packet->length + 1); 67 red_packet->data[1] &= ~0x80; // Clear marker bit. 68 const int kHeaderLength = red_packet->header.header.headerLength; 69 SetRedHeader(red_packet, kFecPayloadType, kHeaderLength); 70 memcpy(red_packet->data + kHeaderLength + 1, packet->data, packet->length); 71 red_packet->length = kHeaderLength + 1 + packet->length; 72 return red_packet; 73 } 74 75 void FrameGenerator::SetRedHeader(Packet* red_packet, uint8_t payload_type, 76 int header_length) const { 77 // Replace pltype. 78 red_packet->data[1] &= 0x80; // Reset. 79 red_packet->data[1] += kRedPayloadType; // Replace. 80 81 // Add RED header, f-bit always 0. 82 red_packet->data[header_length] = payload_type; 83 } 84 85 void FrameGenerator::BuildRtpHeader(uint8_t* data, const RTPHeader* header) { 86 data[0] = 0x80; // Version 2. 87 data[1] = header->payloadType; 88 data[1] |= (header->markerBit ? kRtpMarkerBitMask : 0); 89 RtpUtility::AssignUWord16ToBuffer(data + 2, header->sequenceNumber); 90 RtpUtility::AssignUWord32ToBuffer(data + 4, header->timestamp); 91 RtpUtility::AssignUWord32ToBuffer(data + 8, header->ssrc); 92 } 93 94 } // namespace webrtc 95