|  | <!-- go/cmark --> | 
|  | <!--* freshness: {owner: 'jakobi' reviewed: '2021-04-13'} *--> | 
|  |  | 
|  | # NetEq | 
|  |  | 
|  | NetEq is the audio jitter buffer and packet loss concealer. The jitter buffer is | 
|  | an adaptive jitter buffer, meaning that the buffering delay is continuously | 
|  | optimized based on the network conditions. Its main goal is to ensure a smooth | 
|  | playout of incoming audio packets from the network with a low amount of audio | 
|  | artifacts (alterations to the original content of the packets) while at the same | 
|  | time keep the delay as low as possible. | 
|  |  | 
|  | ## API | 
|  |  | 
|  | At a high level, the NetEq API has two main functions: | 
|  | [`InsertPacket`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/neteq/neteq.h;l=198;drc=4461f059d180fe8c2886d422ebd1cb55b5c83e72) | 
|  | and | 
|  | [`GetAudio`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/neteq/neteq.h;l=219;drc=4461f059d180fe8c2886d422ebd1cb55b5c83e72). | 
|  |  | 
|  | ### InsertPacket | 
|  |  | 
|  | [`InsertPacket`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/neteq/neteq.h;l=198;drc=4461f059d180fe8c2886d422ebd1cb55b5c83e72) | 
|  | delivers an RTP packet from the network to NetEq where the following happens: | 
|  |  | 
|  | 1.  The packet is discarded if it is too late for playout (for example if it was | 
|  | reordered). Otherwize it is put into the packet buffer where it is stored | 
|  | until it is time for playout. If the buffer is full, discard all the | 
|  | existing packets (this should be rare). | 
|  | 2.  The interarrival time between packets is analyzed and statistics is updated | 
|  | which is used to derive a new target playout delay. The interarrival time is | 
|  | measured in the number of GetAudio ‘ticks’ and thus clock drift between the | 
|  | sender and receiver can be accounted for. | 
|  |  | 
|  | ### GetAudio | 
|  |  | 
|  | [`GetAudio`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/neteq/neteq.h;l=219;drc=4461f059d180fe8c2886d422ebd1cb55b5c83e72) | 
|  | pulls 10 ms of audio from NetEq for playout. A much simplified decision logic is | 
|  | as follows: | 
|  |  | 
|  | 1.  If there is 10 ms audio in the sync buffer then return that. | 
|  | 2.  If the next packet is available (based on RTP timestamp) in the packet | 
|  | buffer then decode it and append the result to the sync buffer. | 
|  | 1.  Compare the current delay estimate (filtered buffer level) with the | 
|  | target delay and time stretch (accelerate or decelerate) the contents of | 
|  | the sync buffer if the buffer level is too high or too low. | 
|  | 2.  Return 10 ms of audio from the sync buffer. | 
|  | 3.  If the last decoded packet was a discontinuous transmission (DTX) packet | 
|  | then generate comfort noise. | 
|  | 4.  If there is no available packet for decoding due to the next packet having | 
|  | not arrived or been lost then generate packet loss concealment by | 
|  | extrapolating the remaining audio in the sync buffer or by asking the | 
|  | decoder to produce it. | 
|  |  | 
|  | In summary, the output is the result one of the following operations: | 
|  |  | 
|  | *   Normal: audio decoded from a packet. | 
|  | *   Acceleration: accelerated playout of a decoded packet. | 
|  | *   Preemptive expand: decelerated playout of a decoded packet. | 
|  | *   Expand: packet loss concealment generated by NetEq or the decoder. | 
|  | *   Merge: audio stitched together from packet loss concealment to decoded data | 
|  | in case of a loss. | 
|  | *   Comfort noise (CNG): comfort noise generated by NetEq or the decoder between | 
|  | talk spurts due to discontinuous transmission of packets (DTX). | 
|  |  | 
|  | ## Statistics | 
|  |  | 
|  | There are a number of functions that can be used to query the internal state of | 
|  | NetEq, statistics about the type of audio output and latency metrics such as how | 
|  | long time packets have waited in the buffer. | 
|  |  | 
|  | *   [`NetworkStatistics`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/neteq/neteq.h;l=273;drc=4461f059d180fe8c2886d422ebd1cb55b5c83e72): | 
|  | instantaneous values or stats averaged over the duration since last call to | 
|  | this function. | 
|  | *   [`GetLifetimeStatistics`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/neteq/neteq.h;l=280;drc=4461f059d180fe8c2886d422ebd1cb55b5c83e72): | 
|  | cumulative stats that persist over the lifetime of the class. | 
|  | *   [`GetOperationsAndState`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/neteq/neteq.h;l=284;drc=4461f059d180fe8c2886d422ebd1cb55b5c83e72): | 
|  | information about the internal state of NetEq (is only inteded to be used | 
|  | for testing and debugging). | 
|  |  | 
|  | ## Tests and tools | 
|  |  | 
|  | *   [`neteq_rtpplay`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/modules/audio_coding/neteq/tools/neteq_rtpplay.cc;drc=cee751abff598fc19506f77de08bea7c61b9dcca): | 
|  | Simulate NetEq behavior based on either an RTP dump, a PCAP file or an RTC | 
|  | event log. A replacement audio file can also be used instead of the original | 
|  | payload. Outputs aggregated statistics and optionally an audio file to | 
|  | listen to. | 
|  | *   [`neteq_speed_test`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/modules/audio_coding/neteq/test/neteq_speed_test.cc;drc=2ab97f6f8e27b47c0d9beeb8b6ca5387bda9f55c): | 
|  | Measure performance of NetEq, used on perf bots. | 
|  | *   Unit tests including bit exactness tests where RTP file is used as an input | 
|  | to NetEq, the output is concatenated and a checksum is calculated and | 
|  | compared against a reference. | 
|  |  | 
|  | ## Other responsibilities | 
|  |  | 
|  | *   Dual-tone multi-frequency signaling (DTMF): receive telephone events and | 
|  | produce dual tone waveforms. | 
|  | *   Forward error correction (RED or codec inband FEC): split inserted packets | 
|  | and prioritize the payloads. | 
|  | *   NACK (negative acknowledgement): keep track of lost packets and generate a | 
|  | list of packets to NACK. | 
|  | *   Audio/video sync: NetEq can be instructed to increase the latency in order | 
|  | to keep audio and video in sync. |