• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/byte_io.h"
14 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
15 
16 namespace webrtc {
17 
FrameGenerator()18 FrameGenerator::FrameGenerator()
19     : num_packets_(0), seq_num_(0), timestamp_(0) {}
20 
NewFrame(int num_packets)21 void FrameGenerator::NewFrame(int num_packets) {
22   num_packets_ = num_packets;
23   timestamp_ += 3000;
24 }
25 
NextSeqNum()26 uint16_t FrameGenerator::NextSeqNum() { return ++seq_num_; }
27 
NextPacket(int offset,size_t length)28 RtpPacket* FrameGenerator::NextPacket(int offset, size_t length) {
29   RtpPacket* rtp_packet = new RtpPacket;
30   for (size_t i = 0; i < length; ++i)
31     rtp_packet->data[i + kRtpHeaderSize] = offset + i;
32   rtp_packet->length = length + kRtpHeaderSize;
33   memset(&rtp_packet->header, 0, sizeof(WebRtcRTPHeader));
34   rtp_packet->header.frameType = kVideoFrameDelta;
35   rtp_packet->header.header.headerLength = kRtpHeaderSize;
36   rtp_packet->header.header.markerBit = (num_packets_ == 1);
37   rtp_packet->header.header.sequenceNumber = seq_num_;
38   rtp_packet->header.header.timestamp = timestamp_;
39   rtp_packet->header.header.payloadType = kVp8PayloadType;
40   BuildRtpHeader(rtp_packet->data, &rtp_packet->header.header);
41   ++seq_num_;
42   --num_packets_;
43   return rtp_packet;
44 }
45 
46 // Creates a new RtpPacket with the RED header added to the packet.
BuildMediaRedPacket(const RtpPacket * packet)47 RtpPacket* FrameGenerator::BuildMediaRedPacket(const RtpPacket* packet) {
48   const size_t kHeaderLength = packet->header.header.headerLength;
49   RtpPacket* red_packet = new RtpPacket;
50   red_packet->header = packet->header;
51   red_packet->length = packet->length + 1;  // 1 byte RED header.
52   memset(red_packet->data, 0, red_packet->length);
53   // Copy RTP header.
54   memcpy(red_packet->data, packet->data, kHeaderLength);
55   SetRedHeader(red_packet, red_packet->data[1] & 0x7f, kHeaderLength);
56   memcpy(red_packet->data + kHeaderLength + 1, packet->data + kHeaderLength,
57          packet->length - kHeaderLength);
58   return red_packet;
59 }
60 
61 // Creates a new RtpPacket with FEC payload and red header. Does this by
62 // creating a new fake media RtpPacket, clears the marker bit and adds a RED
63 // header. Finally replaces the payload with the content of |packet->data|.
BuildFecRedPacket(const Packet * packet)64 RtpPacket* FrameGenerator::BuildFecRedPacket(const Packet* packet) {
65   // Create a fake media packet to get a correct header. 1 byte RED header.
66   ++num_packets_;
67   RtpPacket* red_packet = NextPacket(0, packet->length + 1);
68   red_packet->data[1] &= ~0x80;  // Clear marker bit.
69   const size_t kHeaderLength = red_packet->header.header.headerLength;
70   SetRedHeader(red_packet, kFecPayloadType, kHeaderLength);
71   memcpy(red_packet->data + kHeaderLength + 1, packet->data, packet->length);
72   red_packet->length = kHeaderLength + 1 + packet->length;
73   return red_packet;
74 }
75 
SetRedHeader(Packet * red_packet,uint8_t payload_type,size_t header_length) const76 void FrameGenerator::SetRedHeader(Packet* red_packet, uint8_t payload_type,
77                                   size_t header_length) const {
78   // Replace pltype.
79   red_packet->data[1] &= 0x80;             // Reset.
80   red_packet->data[1] += kRedPayloadType;  // Replace.
81 
82   // Add RED header, f-bit always 0.
83   red_packet->data[header_length] = payload_type;
84 }
85 
BuildRtpHeader(uint8_t * data,const RTPHeader * header)86 void FrameGenerator::BuildRtpHeader(uint8_t* data, const RTPHeader* header) {
87   data[0] = 0x80;  // Version 2.
88   data[1] = header->payloadType;
89   data[1] |= (header->markerBit ? kRtpMarkerBitMask : 0);
90   ByteWriter<uint16_t>::WriteBigEndian(data + 2, header->sequenceNumber);
91   ByteWriter<uint32_t>::WriteBigEndian(data + 4, header->timestamp);
92   ByteWriter<uint32_t>::WriteBigEndian(data + 8, header->ssrc);
93 }
94 
95 }  // namespace webrtc
96