OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 ++num_deleted_packets; | 205 ++num_deleted_packets; |
206 continue; | 206 continue; |
207 } | 207 } |
208 } | 208 } |
209 } | 209 } |
210 ++it; | 210 ++it; |
211 } | 211 } |
212 return num_deleted_packets; | 212 return num_deleted_packets; |
213 } | 213 } |
214 | 214 |
215 int PayloadSplitter::SplitAudio(PacketList* packet_list, | |
216 const DecoderDatabase& decoder_database) { | |
217 PacketList::iterator it = packet_list->begin(); | |
218 // Iterate through all packets in |packet_list|. | |
219 while (it != packet_list->end()) { | |
220 Packet* packet = (*it); // Just to make the notation more intuitive. | |
221 // Get codec type for this payload. | |
222 const DecoderDatabase::DecoderInfo* info = | |
223 decoder_database.GetDecoderInfo(packet->header.payloadType); | |
224 if (!info) { | |
225 LOG(LS_WARNING) << "SplitAudio unknown payload type"; | |
226 return kUnknownPayloadType; | |
227 } | |
228 PacketList new_packets; | |
229 switch (info->codec_type) { | |
230 case NetEqDecoder::kDecoderPCMu: | |
231 case NetEqDecoder::kDecoderPCMa: { | |
232 // 8 bytes per ms; 8 timestamps per ms. | |
233 SplitBySamples(packet, 8, 8, &new_packets); | |
234 break; | |
235 } | |
236 case NetEqDecoder::kDecoderPCMu_2ch: | |
237 case NetEqDecoder::kDecoderPCMa_2ch: { | |
238 // 2 * 8 bytes per ms; 8 timestamps per ms. | |
239 SplitBySamples(packet, 2 * 8, 8, &new_packets); | |
240 break; | |
241 } | |
242 case NetEqDecoder::kDecoderG722: { | |
243 // 8 bytes per ms; 16 timestamps per ms. | |
244 SplitBySamples(packet, 8, 16, &new_packets); | |
245 break; | |
246 } | |
247 case NetEqDecoder::kDecoderPCM16B: { | |
248 // 16 bytes per ms; 8 timestamps per ms. | |
249 SplitBySamples(packet, 16, 8, &new_packets); | |
250 break; | |
251 } | |
252 case NetEqDecoder::kDecoderPCM16Bwb: { | |
253 // 32 bytes per ms; 16 timestamps per ms. | |
254 SplitBySamples(packet, 32, 16, &new_packets); | |
255 break; | |
256 } | |
257 case NetEqDecoder::kDecoderPCM16Bswb32kHz: { | |
258 // 64 bytes per ms; 32 timestamps per ms. | |
259 SplitBySamples(packet, 64, 32, &new_packets); | |
260 break; | |
261 } | |
262 case NetEqDecoder::kDecoderPCM16Bswb48kHz: { | |
263 // 96 bytes per ms; 48 timestamps per ms. | |
264 SplitBySamples(packet, 96, 48, &new_packets); | |
265 break; | |
266 } | |
267 case NetEqDecoder::kDecoderPCM16B_2ch: { | |
268 // 2 * 16 bytes per ms; 8 timestamps per ms. | |
269 SplitBySamples(packet, 2 * 16, 8, &new_packets); | |
270 break; | |
271 } | |
272 case NetEqDecoder::kDecoderPCM16Bwb_2ch: { | |
273 // 2 * 32 bytes per ms; 16 timestamps per ms. | |
274 SplitBySamples(packet, 2 * 32, 16, &new_packets); | |
275 break; | |
276 } | |
277 case NetEqDecoder::kDecoderPCM16Bswb32kHz_2ch: { | |
278 // 2 * 64 bytes per ms; 32 timestamps per ms. | |
279 SplitBySamples(packet, 2 * 64, 32, &new_packets); | |
280 break; | |
281 } | |
282 case NetEqDecoder::kDecoderPCM16Bswb48kHz_2ch: { | |
283 // 2 * 96 bytes per ms; 48 timestamps per ms. | |
284 SplitBySamples(packet, 2 * 96, 48, &new_packets); | |
285 break; | |
286 } | |
287 case NetEqDecoder::kDecoderPCM16B_5ch: { | |
288 // 5 * 16 bytes per ms; 8 timestamps per ms. | |
289 SplitBySamples(packet, 5 * 16, 8, &new_packets); | |
290 break; | |
291 } | |
292 case NetEqDecoder::kDecoderILBC: { | |
293 size_t bytes_per_frame; | |
294 int timestamps_per_frame; | |
295 if (packet->payload.size() >= 950) { | |
296 LOG(LS_WARNING) << "SplitAudio too large iLBC payload"; | |
297 return kTooLargePayload; | |
298 } | |
299 if (packet->payload.size() % 38 == 0) { | |
300 // 20 ms frames. | |
301 bytes_per_frame = 38; | |
302 timestamps_per_frame = 160; | |
303 } else if (packet->payload.size() % 50 == 0) { | |
304 // 30 ms frames. | |
305 bytes_per_frame = 50; | |
306 timestamps_per_frame = 240; | |
307 } else { | |
308 LOG(LS_WARNING) << "SplitAudio invalid iLBC payload"; | |
309 return kFrameSplitError; | |
310 } | |
311 int ret = SplitByFrames(packet, bytes_per_frame, timestamps_per_frame, | |
312 &new_packets); | |
313 if (ret < 0) { | |
314 return ret; | |
315 } else if (ret == kNoSplit) { | |
316 // Do not split at all. Simply advance to the next packet in the list. | |
317 ++it; | |
318 // We do not have any new packets to insert, and should not delete the | |
319 // old one. Skip the code after the switch case, and jump straight to | |
320 // the next packet in the while loop. | |
321 continue; | |
322 } | |
323 break; | |
324 } | |
325 default: { | |
326 // Do not split at all. Simply advance to the next packet in the list. | |
327 ++it; | |
328 // We do not have any new packets to insert, and should not delete the | |
329 // old one. Skip the code after the switch case, and jump straight to | |
330 // the next packet in the while loop. | |
331 continue; | |
332 } | |
333 } | |
334 // Insert new packets into original list, before the element pointed to by | |
335 // iterator |it|. | |
336 packet_list->splice(it, new_packets, new_packets.begin(), | |
337 new_packets.end()); | |
338 // Delete old packet payload. | |
339 delete (*it); | |
340 // Remove |it| from the packet list. This operation effectively moves the | |
341 // iterator |it| to the next packet in the list. Thus, we do not have to | |
342 // increment it manually. | |
343 it = packet_list->erase(it); | |
344 } | |
345 return kOK; | |
346 } | |
347 | |
348 void PayloadSplitter::SplitBySamples(const Packet* packet, | |
349 size_t bytes_per_ms, | |
350 uint32_t timestamps_per_ms, | |
351 PacketList* new_packets) { | |
352 assert(packet); | |
353 assert(new_packets); | |
354 | |
355 size_t split_size_bytes = packet->payload.size(); | |
356 | |
357 // Find a "chunk size" >= 20 ms and < 40 ms. | |
358 size_t min_chunk_size = bytes_per_ms * 20; | |
359 // Reduce the split size by half as long as |split_size_bytes| is at least | |
360 // twice the minimum chunk size (so that the resulting size is at least as | |
361 // large as the minimum chunk size). | |
362 while (split_size_bytes >= 2 * min_chunk_size) { | |
363 split_size_bytes >>= 1; | |
364 } | |
365 uint32_t timestamps_per_chunk = static_cast<uint32_t>( | |
366 split_size_bytes * timestamps_per_ms / bytes_per_ms); | |
367 uint32_t timestamp = packet->header.timestamp; | |
368 | |
369 const uint8_t* payload_ptr = packet->payload.data(); | |
370 size_t len = packet->payload.size(); | |
371 while (len >= (2 * split_size_bytes)) { | |
372 Packet* new_packet = new Packet; | |
373 new_packet->header = packet->header; | |
374 new_packet->header.timestamp = timestamp; | |
375 timestamp += timestamps_per_chunk; | |
376 new_packet->primary = packet->primary; | |
377 new_packet->payload.SetData(payload_ptr, split_size_bytes); | |
378 payload_ptr += split_size_bytes; | |
379 new_packets->push_back(new_packet); | |
380 len -= split_size_bytes; | |
381 } | |
382 | |
383 if (len > 0) { | |
384 Packet* new_packet = new Packet; | |
385 new_packet->header = packet->header; | |
386 new_packet->header.timestamp = timestamp; | |
387 new_packet->primary = packet->primary; | |
388 new_packet->payload.SetData(payload_ptr, len); | |
389 new_packets->push_back(new_packet); | |
390 } | |
391 } | |
392 | |
393 int PayloadSplitter::SplitByFrames(const Packet* packet, | |
394 size_t bytes_per_frame, | |
395 uint32_t timestamps_per_frame, | |
396 PacketList* new_packets) { | |
397 if (packet->payload.size() % bytes_per_frame != 0) { | |
398 LOG(LS_WARNING) << "SplitByFrames length mismatch"; | |
399 return kFrameSplitError; | |
400 } | |
401 | |
402 if (packet->payload.size() == bytes_per_frame) { | |
403 // Special case. Do not split the payload. | |
404 return kNoSplit; | |
405 } | |
406 | |
407 uint32_t timestamp = packet->header.timestamp; | |
408 const uint8_t* payload_ptr = packet->payload.data(); | |
409 size_t len = packet->payload.size(); | |
410 while (len > 0) { | |
411 assert(len >= bytes_per_frame); | |
412 Packet* new_packet = new Packet; | |
413 new_packet->header = packet->header; | |
414 new_packet->header.timestamp = timestamp; | |
415 timestamp += timestamps_per_frame; | |
416 new_packet->primary = packet->primary; | |
417 new_packet->payload.SetData(payload_ptr, bytes_per_frame); | |
418 payload_ptr += bytes_per_frame; | |
419 new_packets->push_back(new_packet); | |
420 len -= bytes_per_frame; | |
421 } | |
422 return kOK; | |
423 } | |
424 | |
425 } // namespace webrtc | 215 } // namespace webrtc |
OLD | NEW |