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#ifndef WEBRTC_MODULES_AUDIO_CODING_NETEQ_PACKET_H_
12#define WEBRTC_MODULES_AUDIO_CODING_NETEQ_PACKET_H_
13
14#include <list>
15
16#include "webrtc/modules/interface/module_common_types.h"
17#include "webrtc/typedefs.h"
18
19namespace webrtc {
20
21// Struct for holding RTP packets.
22struct Packet {
23  RTPHeader header;
24  uint8_t* payload;  // Datagram excluding RTP header and header extension.
25  int payload_length;
26  bool primary;  // Primary, i.e., not redundant payload.
27  int waiting_time;
28  bool sync_packet;
29
30  // Constructor.
31  Packet()
32      : payload(NULL),
33        payload_length(0),
34        primary(true),
35        waiting_time(0),
36        sync_packet(false) {
37  }
38
39  // Comparison operators. Establish a packet ordering based on (1) timestamp,
40  // (2) sequence number, (3) regular packet vs sync-packet and (4) redundancy.
41  // Timestamp and sequence numbers are compared taking wrap-around into
42  // account. If both timestamp and sequence numbers are identical and one of
43  // the packets is sync-packet, the regular packet is considered earlier. For
44  // two regular packets with the same sequence number and timestamp a primary
45  // payload is considered "smaller" than a secondary.
46  bool operator==(const Packet& rhs) const {
47    return (this->header.timestamp == rhs.header.timestamp &&
48        this->header.sequenceNumber == rhs.header.sequenceNumber &&
49        this->primary == rhs.primary &&
50        this->sync_packet == rhs.sync_packet);
51  }
52  bool operator!=(const Packet& rhs) const { return !operator==(rhs); }
53  bool operator<(const Packet& rhs) const {
54    if (this->header.timestamp == rhs.header.timestamp) {
55      if (this->header.sequenceNumber == rhs.header.sequenceNumber) {
56        // Timestamp and sequence numbers are identical. A sync packet should
57        // be recognized "larger" (i.e. "later") compared to a "network packet"
58        // (regular packet from network not sync-packet). If none of the packets
59        // are sync-packets, then deem the left hand side to be "smaller"
60        // (i.e., "earlier") if it is  primary, and right hand side is not.
61        //
62        // The condition on sync packets to be larger than "network packets,"
63        // given same RTP sequence number and timestamp, guarantees that a
64        // "network packet" to be inserted in an earlier position into
65        // |packet_buffer_| compared to a sync packet of same timestamp and
66        // sequence number.
67        if (rhs.sync_packet)
68          return true;
69        if (this->sync_packet)
70          return false;
71        return (this->primary && !rhs.primary);
72      }
73      return (static_cast<uint16_t>(rhs.header.sequenceNumber
74          - this->header.sequenceNumber) < 0xFFFF / 2);
75    }
76    return (static_cast<uint32_t>(rhs.header.timestamp
77        - this->header.timestamp) < 0xFFFFFFFF / 2);
78  }
79  bool operator>(const Packet& rhs) const { return rhs.operator<(*this); }
80  bool operator<=(const Packet& rhs) const { return !operator>(rhs); }
81  bool operator>=(const Packet& rhs) const { return !operator<(rhs); }
82};
83
84// A list of packets.
85typedef std::list<Packet*> PacketList;
86
87}  // namespace webrtc
88#endif  // WEBRTC_MODULES_AUDIO_CODING_NETEQ_PACKET_H_
89