• 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/audio_coding/neteq/payload_splitter.h"
12 
13 #include <assert.h>
14 
15 #include "webrtc/base/logging.h"
16 #include "webrtc/modules/audio_coding/neteq/decoder_database.h"
17 
18 namespace webrtc {
19 
20 // The method loops through a list of packets {A, B, C, ...}. Each packet is
21 // split into its corresponding RED payloads, {A1, A2, ...}, which is
22 // temporarily held in the list |new_packets|.
23 // When the first packet in |packet_list| has been processed, the orignal packet
24 // is replaced by the new ones in |new_packets|, so that |packet_list| becomes:
25 // {A1, A2, ..., B, C, ...}. The method then continues with B, and C, until all
26 // the original packets have been replaced by their split payloads.
SplitRed(PacketList * packet_list)27 int PayloadSplitter::SplitRed(PacketList* packet_list) {
28   int ret = kOK;
29   PacketList::iterator it = packet_list->begin();
30   while (it != packet_list->end()) {
31     PacketList new_packets;  // An empty list to store the split packets in.
32     Packet* red_packet = (*it);
33     assert(red_packet->payload);
34     uint8_t* payload_ptr = red_packet->payload;
35 
36     // Read RED headers (according to RFC 2198):
37     //
38     //    0                   1                   2                   3
39     //    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
40     //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41     //   |F|   block PT  |  timestamp offset         |   block length    |
42     //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43     // Last RED header:
44     //    0 1 2 3 4 5 6 7
45     //   +-+-+-+-+-+-+-+-+
46     //   |0|   Block PT  |
47     //   +-+-+-+-+-+-+-+-+
48 
49     bool last_block = false;
50     size_t sum_length = 0;
51     while (!last_block) {
52       Packet* new_packet = new Packet;
53       new_packet->header = red_packet->header;
54       // Check the F bit. If F == 0, this was the last block.
55       last_block = ((*payload_ptr & 0x80) == 0);
56       // Bits 1 through 7 are payload type.
57       new_packet->header.payloadType = payload_ptr[0] & 0x7F;
58       if (last_block) {
59         // No more header data to read.
60         ++sum_length;  // Account for RED header size of 1 byte.
61         new_packet->payload_length = red_packet->payload_length - sum_length;
62         new_packet->primary = true;  // Last block is always primary.
63         payload_ptr += 1;  // Advance to first payload byte.
64       } else {
65         // Bits 8 through 21 are timestamp offset.
66         int timestamp_offset = (payload_ptr[1] << 6) +
67             ((payload_ptr[2] & 0xFC) >> 2);
68         new_packet->header.timestamp = red_packet->header.timestamp -
69             timestamp_offset;
70         // Bits 22 through 31 are payload length.
71         new_packet->payload_length = ((payload_ptr[2] & 0x03) << 8) +
72             payload_ptr[3];
73         new_packet->primary = false;
74         payload_ptr += 4;  // Advance to next RED header.
75       }
76       sum_length += new_packet->payload_length;
77       sum_length += 4;  // Account for RED header size of 4 bytes.
78       // Store in new list of packets.
79       new_packets.push_back(new_packet);
80     }
81 
82     // Populate the new packets with payload data.
83     // |payload_ptr| now points at the first payload byte.
84     PacketList::iterator new_it;
85     for (new_it = new_packets.begin(); new_it != new_packets.end(); ++new_it) {
86       size_t payload_length = (*new_it)->payload_length;
87       if (payload_ptr + payload_length >
88           red_packet->payload + red_packet->payload_length) {
89         // The block lengths in the RED headers do not match the overall packet
90         // length. Something is corrupt. Discard this and the remaining
91         // payloads from this packet.
92         LOG(LS_WARNING) << "SplitRed length mismatch";
93         while (new_it != new_packets.end()) {
94           // Payload should not have been allocated yet.
95           assert(!(*new_it)->payload);
96           delete (*new_it);
97           new_it = new_packets.erase(new_it);
98         }
99         ret = kRedLengthMismatch;
100         break;
101       }
102       (*new_it)->payload = new uint8_t[payload_length];
103       memcpy((*new_it)->payload, payload_ptr, payload_length);
104       payload_ptr += payload_length;
105     }
106     // Reverse the order of the new packets, so that the primary payload is
107     // always first.
108     new_packets.reverse();
109     // Insert new packets into original list, before the element pointed to by
110     // iterator |it|.
111     packet_list->splice(it, new_packets, new_packets.begin(),
112                         new_packets.end());
113     // Delete old packet payload.
114     delete [] (*it)->payload;
115     delete (*it);
116     // Remove |it| from the packet list. This operation effectively moves the
117     // iterator |it| to the next packet in the list. Thus, we do not have to
118     // increment it manually.
119     it = packet_list->erase(it);
120   }
121   return ret;
122 }
123 
SplitFec(PacketList * packet_list,DecoderDatabase * decoder_database)124 int PayloadSplitter::SplitFec(PacketList* packet_list,
125                               DecoderDatabase* decoder_database) {
126   PacketList::iterator it = packet_list->begin();
127   // Iterate through all packets in |packet_list|.
128   while (it != packet_list->end()) {
129     Packet* packet = (*it);  // Just to make the notation more intuitive.
130     // Get codec type for this payload.
131     uint8_t payload_type = packet->header.payloadType;
132     const DecoderDatabase::DecoderInfo* info =
133         decoder_database->GetDecoderInfo(payload_type);
134     if (!info) {
135       LOG(LS_WARNING) << "SplitFec unknown payload type";
136       return kUnknownPayloadType;
137     }
138     // No splitting for a sync-packet.
139     if (packet->sync_packet) {
140       ++it;
141       continue;
142     }
143 
144     // Not an FEC packet.
145     AudioDecoder* decoder = decoder_database->GetDecoder(payload_type);
146     // decoder should not return NULL.
147     assert(decoder != NULL);
148     if (!decoder ||
149         !decoder->PacketHasFec(packet->payload, packet->payload_length)) {
150       ++it;
151       continue;
152     }
153 
154     switch (info->codec_type) {
155       case NetEqDecoder::kDecoderOpus:
156       case NetEqDecoder::kDecoderOpus_2ch: {
157         // The main payload of this packet should be decoded as a primary
158         // payload, even if it comes as a secondary payload in a RED packet.
159         packet->primary = true;
160 
161         Packet* new_packet = new Packet;
162         new_packet->header = packet->header;
163         int duration = decoder->
164             PacketDurationRedundant(packet->payload, packet->payload_length);
165         new_packet->header.timestamp -= duration;
166         new_packet->payload = new uint8_t[packet->payload_length];
167         memcpy(new_packet->payload, packet->payload, packet->payload_length);
168         new_packet->payload_length = packet->payload_length;
169         new_packet->primary = false;
170         new_packet->waiting_time = packet->waiting_time;
171         new_packet->sync_packet = packet->sync_packet;
172 
173         packet_list->insert(it, new_packet);
174         break;
175       }
176       default: {
177         LOG(LS_WARNING) << "SplitFec wrong payload type";
178         return kFecSplitError;
179       }
180     }
181 
182     ++it;
183   }
184   return kOK;
185 }
186 
CheckRedPayloads(PacketList * packet_list,const DecoderDatabase & decoder_database)187 int PayloadSplitter::CheckRedPayloads(PacketList* packet_list,
188                                       const DecoderDatabase& decoder_database) {
189   PacketList::iterator it = packet_list->begin();
190   int main_payload_type = -1;
191   int num_deleted_packets = 0;
192   while (it != packet_list->end()) {
193     uint8_t this_payload_type = (*it)->header.payloadType;
194     if (!decoder_database.IsDtmf(this_payload_type) &&
195         !decoder_database.IsComfortNoise(this_payload_type)) {
196       if (main_payload_type == -1) {
197         // This is the first packet in the list which is non-DTMF non-CNG.
198         main_payload_type = this_payload_type;
199       } else {
200         if (this_payload_type != main_payload_type) {
201           // We do not allow redundant payloads of a different type.
202           // Discard this payload.
203           delete [] (*it)->payload;
204           delete (*it);
205           // Remove |it| from the packet list. This operation effectively
206           // moves the iterator |it| to the next packet in the list. Thus, we
207           // do not have to increment it manually.
208           it = packet_list->erase(it);
209           ++num_deleted_packets;
210           continue;
211         }
212       }
213     }
214     ++it;
215   }
216   return num_deleted_packets;
217 }
218 
SplitAudio(PacketList * packet_list,const DecoderDatabase & decoder_database)219 int PayloadSplitter::SplitAudio(PacketList* packet_list,
220                                 const DecoderDatabase& decoder_database) {
221   PacketList::iterator it = packet_list->begin();
222   // Iterate through all packets in |packet_list|.
223   while (it != packet_list->end()) {
224     Packet* packet = (*it);  // Just to make the notation more intuitive.
225     // Get codec type for this payload.
226     const DecoderDatabase::DecoderInfo* info =
227         decoder_database.GetDecoderInfo(packet->header.payloadType);
228     if (!info) {
229       LOG(LS_WARNING) << "SplitAudio unknown payload type";
230       return kUnknownPayloadType;
231     }
232     // No splitting for a sync-packet.
233     if (packet->sync_packet) {
234       ++it;
235       continue;
236     }
237     PacketList new_packets;
238     switch (info->codec_type) {
239       case NetEqDecoder::kDecoderPCMu:
240       case NetEqDecoder::kDecoderPCMa: {
241         // 8 bytes per ms; 8 timestamps per ms.
242         SplitBySamples(packet, 8, 8, &new_packets);
243         break;
244       }
245       case NetEqDecoder::kDecoderPCMu_2ch:
246       case NetEqDecoder::kDecoderPCMa_2ch: {
247         // 2 * 8 bytes per ms; 8 timestamps per ms.
248         SplitBySamples(packet, 2 * 8, 8, &new_packets);
249         break;
250       }
251       case NetEqDecoder::kDecoderG722: {
252         // 8 bytes per ms; 16 timestamps per ms.
253         SplitBySamples(packet, 8, 16, &new_packets);
254         break;
255       }
256       case NetEqDecoder::kDecoderPCM16B: {
257         // 16 bytes per ms; 8 timestamps per ms.
258         SplitBySamples(packet, 16, 8, &new_packets);
259         break;
260       }
261       case NetEqDecoder::kDecoderPCM16Bwb: {
262         // 32 bytes per ms; 16 timestamps per ms.
263         SplitBySamples(packet, 32, 16, &new_packets);
264         break;
265       }
266       case NetEqDecoder::kDecoderPCM16Bswb32kHz: {
267         // 64 bytes per ms; 32 timestamps per ms.
268         SplitBySamples(packet, 64, 32, &new_packets);
269         break;
270       }
271       case NetEqDecoder::kDecoderPCM16Bswb48kHz: {
272         // 96 bytes per ms; 48 timestamps per ms.
273         SplitBySamples(packet, 96, 48, &new_packets);
274         break;
275       }
276       case NetEqDecoder::kDecoderPCM16B_2ch: {
277         // 2 * 16 bytes per ms; 8 timestamps per ms.
278         SplitBySamples(packet, 2 * 16, 8, &new_packets);
279         break;
280       }
281       case NetEqDecoder::kDecoderPCM16Bwb_2ch: {
282         // 2 * 32 bytes per ms; 16 timestamps per ms.
283         SplitBySamples(packet, 2 * 32, 16, &new_packets);
284         break;
285       }
286       case NetEqDecoder::kDecoderPCM16Bswb32kHz_2ch: {
287         // 2 * 64 bytes per ms; 32 timestamps per ms.
288         SplitBySamples(packet, 2 * 64, 32, &new_packets);
289         break;
290       }
291       case NetEqDecoder::kDecoderPCM16Bswb48kHz_2ch: {
292         // 2 * 96 bytes per ms; 48 timestamps per ms.
293         SplitBySamples(packet, 2 * 96, 48, &new_packets);
294         break;
295       }
296       case NetEqDecoder::kDecoderPCM16B_5ch: {
297         // 5 * 16 bytes per ms; 8 timestamps per ms.
298         SplitBySamples(packet, 5 * 16, 8, &new_packets);
299         break;
300       }
301       case NetEqDecoder::kDecoderILBC: {
302         size_t bytes_per_frame;
303         int timestamps_per_frame;
304         if (packet->payload_length >= 950) {
305           LOG(LS_WARNING) << "SplitAudio too large iLBC payload";
306           return kTooLargePayload;
307         }
308         if (packet->payload_length % 38 == 0) {
309           // 20 ms frames.
310           bytes_per_frame = 38;
311           timestamps_per_frame = 160;
312         } else if (packet->payload_length % 50 == 0) {
313           // 30 ms frames.
314           bytes_per_frame = 50;
315           timestamps_per_frame = 240;
316         } else {
317           LOG(LS_WARNING) << "SplitAudio invalid iLBC payload";
318           return kFrameSplitError;
319         }
320         int ret = SplitByFrames(packet, bytes_per_frame, timestamps_per_frame,
321                                 &new_packets);
322         if (ret < 0) {
323           return ret;
324         } else if (ret == kNoSplit) {
325           // Do not split at all. Simply advance to the next packet in the list.
326           ++it;
327           // We do not have any new packets to insert, and should not delete the
328           // old one. Skip the code after the switch case, and jump straight to
329           // the next packet in the while loop.
330           continue;
331         }
332         break;
333       }
334       default: {
335         // Do not split at all. Simply advance to the next packet in the list.
336         ++it;
337         // We do not have any new packets to insert, and should not delete the
338         // old one. Skip the code after the switch case, and jump straight to
339         // the next packet in the while loop.
340         continue;
341       }
342     }
343     // Insert new packets into original list, before the element pointed to by
344     // iterator |it|.
345     packet_list->splice(it, new_packets, new_packets.begin(),
346                         new_packets.end());
347     // Delete old packet payload.
348     delete [] (*it)->payload;
349     delete (*it);
350     // Remove |it| from the packet list. This operation effectively moves the
351     // iterator |it| to the next packet in the list. Thus, we do not have to
352     // increment it manually.
353     it = packet_list->erase(it);
354   }
355   return kOK;
356 }
357 
SplitBySamples(const Packet * packet,size_t bytes_per_ms,uint32_t timestamps_per_ms,PacketList * new_packets)358 void PayloadSplitter::SplitBySamples(const Packet* packet,
359                                      size_t bytes_per_ms,
360                                      uint32_t timestamps_per_ms,
361                                      PacketList* new_packets) {
362   assert(packet);
363   assert(new_packets);
364 
365   size_t split_size_bytes = packet->payload_length;
366 
367   // Find a "chunk size" >= 20 ms and < 40 ms.
368   size_t min_chunk_size = bytes_per_ms * 20;
369   // Reduce the split size by half as long as |split_size_bytes| is at least
370   // twice the minimum chunk size (so that the resulting size is at least as
371   // large as the minimum chunk size).
372   while (split_size_bytes >= 2 * min_chunk_size) {
373     split_size_bytes >>= 1;
374   }
375   uint32_t timestamps_per_chunk = static_cast<uint32_t>(
376       split_size_bytes * timestamps_per_ms / bytes_per_ms);
377   uint32_t timestamp = packet->header.timestamp;
378 
379   uint8_t* payload_ptr = packet->payload;
380   size_t len = packet->payload_length;
381   while (len >= (2 * split_size_bytes)) {
382     Packet* new_packet = new Packet;
383     new_packet->payload_length = split_size_bytes;
384     new_packet->header = packet->header;
385     new_packet->header.timestamp = timestamp;
386     timestamp += timestamps_per_chunk;
387     new_packet->primary = packet->primary;
388     new_packet->payload = new uint8_t[split_size_bytes];
389     memcpy(new_packet->payload, payload_ptr, split_size_bytes);
390     payload_ptr += split_size_bytes;
391     new_packets->push_back(new_packet);
392     len -= split_size_bytes;
393   }
394 
395   if (len > 0) {
396     Packet* new_packet = new Packet;
397     new_packet->payload_length = len;
398     new_packet->header = packet->header;
399     new_packet->header.timestamp = timestamp;
400     new_packet->primary = packet->primary;
401     new_packet->payload = new uint8_t[len];
402     memcpy(new_packet->payload, payload_ptr, len);
403     new_packets->push_back(new_packet);
404   }
405 }
406 
SplitByFrames(const Packet * packet,size_t bytes_per_frame,uint32_t timestamps_per_frame,PacketList * new_packets)407 int PayloadSplitter::SplitByFrames(const Packet* packet,
408                                    size_t bytes_per_frame,
409                                    uint32_t timestamps_per_frame,
410                                    PacketList* new_packets) {
411   if (packet->payload_length % bytes_per_frame != 0) {
412     LOG(LS_WARNING) << "SplitByFrames length mismatch";
413     return kFrameSplitError;
414   }
415 
416   if (packet->payload_length == bytes_per_frame) {
417     // Special case. Do not split the payload.
418     return kNoSplit;
419   }
420 
421   uint32_t timestamp = packet->header.timestamp;
422   uint8_t* payload_ptr = packet->payload;
423   size_t len = packet->payload_length;
424   while (len > 0) {
425     assert(len >= bytes_per_frame);
426     Packet* new_packet = new Packet;
427     new_packet->payload_length = bytes_per_frame;
428     new_packet->header = packet->header;
429     new_packet->header.timestamp = timestamp;
430     timestamp += timestamps_per_frame;
431     new_packet->primary = packet->primary;
432     new_packet->payload = new uint8_t[bytes_per_frame];
433     memcpy(new_packet->payload, payload_ptr, bytes_per_frame);
434     payload_ptr += bytes_per_frame;
435     new_packets->push_back(new_packet);
436     len -= bytes_per_frame;
437   }
438   return kOK;
439 }
440 
441 }  // namespace webrtc
442