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 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
225 // Iterate through all packets in |packet_list|. | 225 // Iterate through all packets in |packet_list|. |
226 while (it != packet_list->end()) { | 226 while (it != packet_list->end()) { |
227 Packet* packet = (*it); // Just to make the notation more intuitive. | 227 Packet* packet = (*it); // Just to make the notation more intuitive. |
228 // Get codec type for this payload. | 228 // Get codec type for this payload. |
229 const DecoderDatabase::DecoderInfo* info = | 229 const DecoderDatabase::DecoderInfo* info = |
230 decoder_database.GetDecoderInfo(packet->header.payloadType); | 230 decoder_database.GetDecoderInfo(packet->header.payloadType); |
231 if (!info) { | 231 if (!info) { |
232 LOG(LS_WARNING) << "SplitAudio unknown payload type"; | 232 LOG(LS_WARNING) << "SplitAudio unknown payload type"; |
233 return kUnknownPayloadType; | 233 return kUnknownPayloadType; |
234 } | 234 } |
235 // No splitting for a sync-packet. | 235 // No splitting for a sync-packet nor for any format handled internally. |
236 if (packet->sync_packet) { | 236 if (packet->sync_packet || |
237 info->IsComfortNoise() || info->IsDtmf() || info->IsRed()) { | |
237 ++it; | 238 ++it; |
238 continue; | 239 continue; |
239 } | 240 } |
240 PacketList new_packets; | 241 const AudioDecoder* decoder = info->GetDecoder(); |
241 switch (info->codec_type) { | 242 RTC_DCHECK(decoder); |
242 case NetEqDecoder::kDecoderPCMu: | 243 AudioDecoder::PacketSplits splits = |
243 case NetEqDecoder::kDecoderPCMa: { | 244 decoder->SplitPacket(packet->payload, packet->payload_length); |
244 // 8 bytes per ms; 8 timestamps per ms. | 245 if (splits.empty()) { |
245 SplitBySamples(packet, 8, 8, &new_packets); | 246 return kFrameSplitError; |
246 break; | 247 } else if (splits.size() == 1 && |
248 splits[0].byte_offset == 0 && | |
249 splits[0].num_bytes == packet->payload_length && | |
250 splits[0].timestamp_offset == 0) { | |
251 // No splitting necessary; move on to the next packet | |
kwiberg-webrtc
2016/08/26 12:39:25
Hmm. Wouldn't it be better to test just the first
ossu
2016/08/26 13:05:30
Nah, I think it's fine if you can figure out that
| |
252 ++it; | |
253 } else { | |
254 PacketList new_packets; | |
255 for (const auto& split : splits) { | |
256 Packet* new_packet = new Packet; | |
kwiberg-webrtc
2016/08/26 12:39:25
Ew. Consider using unique_ptr in this block, and u
ossu
2016/08/26 13:05:30
Hello. I'm the messenger. Please don't shoot me! :
| |
257 const uint8_t* payload_ptr = packet->payload + split.byte_offset; | |
258 new_packet->payload_length = split.num_bytes; | |
259 new_packet->header = packet->header; | |
260 new_packet->header.timestamp += split.timestamp_offset; | |
261 new_packet->primary = packet->primary; | |
262 new_packet->payload = new uint8_t[split.num_bytes]; | |
263 memcpy(new_packet->payload, payload_ptr, split.num_bytes); | |
264 new_packets.push_back(new_packet); | |
247 } | 265 } |
248 case NetEqDecoder::kDecoderPCMu_2ch: | 266 |
249 case NetEqDecoder::kDecoderPCMa_2ch: { | 267 // Insert new packets into original list, before the element pointed to by |
250 // 2 * 8 bytes per ms; 8 timestamps per ms. | 268 // iterator |it|. |
251 SplitBySamples(packet, 2 * 8, 8, &new_packets); | 269 packet_list->splice(it, new_packets, new_packets.begin(), |
252 break; | 270 new_packets.end()); |
253 } | 271 // Delete old packet payload. |
254 case NetEqDecoder::kDecoderG722: { | 272 delete [] (*it)->payload; |
255 // 8 bytes per ms; 16 timestamps per ms. | 273 delete (*it); |
256 SplitBySamples(packet, 8, 16, &new_packets); | 274 // Remove |it| from the packet list. This operation effectively moves the |
257 break; | 275 // iterator |it| to the next packet in the list. Thus, we do not have to |
258 } | 276 // increment it manually. |
259 case NetEqDecoder::kDecoderPCM16B: { | 277 it = packet_list->erase(it); |
260 // 16 bytes per ms; 8 timestamps per ms. | |
261 SplitBySamples(packet, 16, 8, &new_packets); | |
262 break; | |
263 } | |
264 case NetEqDecoder::kDecoderPCM16Bwb: { | |
265 // 32 bytes per ms; 16 timestamps per ms. | |
266 SplitBySamples(packet, 32, 16, &new_packets); | |
267 break; | |
268 } | |
269 case NetEqDecoder::kDecoderPCM16Bswb32kHz: { | |
270 // 64 bytes per ms; 32 timestamps per ms. | |
271 SplitBySamples(packet, 64, 32, &new_packets); | |
272 break; | |
273 } | |
274 case NetEqDecoder::kDecoderPCM16Bswb48kHz: { | |
275 // 96 bytes per ms; 48 timestamps per ms. | |
276 SplitBySamples(packet, 96, 48, &new_packets); | |
277 break; | |
278 } | |
279 case NetEqDecoder::kDecoderPCM16B_2ch: { | |
280 // 2 * 16 bytes per ms; 8 timestamps per ms. | |
281 SplitBySamples(packet, 2 * 16, 8, &new_packets); | |
282 break; | |
283 } | |
284 case NetEqDecoder::kDecoderPCM16Bwb_2ch: { | |
285 // 2 * 32 bytes per ms; 16 timestamps per ms. | |
286 SplitBySamples(packet, 2 * 32, 16, &new_packets); | |
287 break; | |
288 } | |
289 case NetEqDecoder::kDecoderPCM16Bswb32kHz_2ch: { | |
290 // 2 * 64 bytes per ms; 32 timestamps per ms. | |
291 SplitBySamples(packet, 2 * 64, 32, &new_packets); | |
292 break; | |
293 } | |
294 case NetEqDecoder::kDecoderPCM16Bswb48kHz_2ch: { | |
295 // 2 * 96 bytes per ms; 48 timestamps per ms. | |
296 SplitBySamples(packet, 2 * 96, 48, &new_packets); | |
297 break; | |
298 } | |
299 case NetEqDecoder::kDecoderPCM16B_5ch: { | |
300 // 5 * 16 bytes per ms; 8 timestamps per ms. | |
301 SplitBySamples(packet, 5 * 16, 8, &new_packets); | |
302 break; | |
303 } | |
304 case NetEqDecoder::kDecoderILBC: { | |
305 size_t bytes_per_frame; | |
306 int timestamps_per_frame; | |
307 if (packet->payload_length >= 950) { | |
308 LOG(LS_WARNING) << "SplitAudio too large iLBC payload"; | |
309 return kTooLargePayload; | |
310 } | |
311 if (packet->payload_length % 38 == 0) { | |
312 // 20 ms frames. | |
313 bytes_per_frame = 38; | |
314 timestamps_per_frame = 160; | |
315 } else if (packet->payload_length % 50 == 0) { | |
316 // 30 ms frames. | |
317 bytes_per_frame = 50; | |
318 timestamps_per_frame = 240; | |
319 } else { | |
320 LOG(LS_WARNING) << "SplitAudio invalid iLBC payload"; | |
321 return kFrameSplitError; | |
322 } | |
323 int ret = SplitByFrames(packet, bytes_per_frame, timestamps_per_frame, | |
324 &new_packets); | |
325 if (ret < 0) { | |
326 return ret; | |
327 } else if (ret == kNoSplit) { | |
328 // Do not split at all. Simply advance to the next packet in the list. | |
329 ++it; | |
330 // We do not have any new packets to insert, and should not delete the | |
331 // old one. Skip the code after the switch case, and jump straight to | |
332 // the next packet in the while loop. | |
333 continue; | |
334 } | |
335 break; | |
336 } | |
337 default: { | |
338 // Do not split at all. Simply advance to the next packet in the list. | |
339 ++it; | |
340 // We do not have any new packets to insert, and should not delete the | |
341 // old one. Skip the code after the switch case, and jump straight to | |
342 // the next packet in the while loop. | |
343 continue; | |
344 } | |
345 } | 278 } |
346 // Insert new packets into original list, before the element pointed to by | |
347 // iterator |it|. | |
348 packet_list->splice(it, new_packets, new_packets.begin(), | |
349 new_packets.end()); | |
350 // Delete old packet payload. | |
351 delete [] (*it)->payload; | |
352 delete (*it); | |
353 // Remove |it| from the packet list. This operation effectively moves the | |
354 // iterator |it| to the next packet in the list. Thus, we do not have to | |
355 // increment it manually. | |
356 it = packet_list->erase(it); | |
357 } | 279 } |
358 return kOK; | 280 return kOK; |
359 } | 281 } |
360 | |
361 void PayloadSplitter::SplitBySamples(const Packet* packet, | |
362 size_t bytes_per_ms, | |
363 uint32_t timestamps_per_ms, | |
364 PacketList* new_packets) { | |
365 assert(packet); | |
366 assert(new_packets); | |
367 | |
368 size_t split_size_bytes = packet->payload_length; | |
369 | |
370 // Find a "chunk size" >= 20 ms and < 40 ms. | |
371 size_t min_chunk_size = bytes_per_ms * 20; | |
372 // Reduce the split size by half as long as |split_size_bytes| is at least | |
373 // twice the minimum chunk size (so that the resulting size is at least as | |
374 // large as the minimum chunk size). | |
375 while (split_size_bytes >= 2 * min_chunk_size) { | |
376 split_size_bytes >>= 1; | |
377 } | |
378 uint32_t timestamps_per_chunk = static_cast<uint32_t>( | |
379 split_size_bytes * timestamps_per_ms / bytes_per_ms); | |
380 uint32_t timestamp = packet->header.timestamp; | |
381 | |
382 uint8_t* payload_ptr = packet->payload; | |
383 size_t len = packet->payload_length; | |
384 while (len >= (2 * split_size_bytes)) { | |
385 Packet* new_packet = new Packet; | |
386 new_packet->payload_length = split_size_bytes; | |
387 new_packet->header = packet->header; | |
388 new_packet->header.timestamp = timestamp; | |
389 timestamp += timestamps_per_chunk; | |
390 new_packet->primary = packet->primary; | |
391 new_packet->payload = new uint8_t[split_size_bytes]; | |
392 memcpy(new_packet->payload, payload_ptr, split_size_bytes); | |
393 payload_ptr += split_size_bytes; | |
394 new_packets->push_back(new_packet); | |
395 len -= split_size_bytes; | |
396 } | |
397 | |
398 if (len > 0) { | |
399 Packet* new_packet = new Packet; | |
400 new_packet->payload_length = len; | |
401 new_packet->header = packet->header; | |
402 new_packet->header.timestamp = timestamp; | |
403 new_packet->primary = packet->primary; | |
404 new_packet->payload = new uint8_t[len]; | |
405 memcpy(new_packet->payload, payload_ptr, len); | |
406 new_packets->push_back(new_packet); | |
407 } | |
408 } | |
409 | |
410 int PayloadSplitter::SplitByFrames(const Packet* packet, | |
411 size_t bytes_per_frame, | |
412 uint32_t timestamps_per_frame, | |
413 PacketList* new_packets) { | |
414 if (packet->payload_length % bytes_per_frame != 0) { | |
415 LOG(LS_WARNING) << "SplitByFrames length mismatch"; | |
416 return kFrameSplitError; | |
417 } | |
418 | |
419 if (packet->payload_length == bytes_per_frame) { | |
420 // Special case. Do not split the payload. | |
421 return kNoSplit; | |
422 } | |
423 | |
424 uint32_t timestamp = packet->header.timestamp; | |
425 uint8_t* payload_ptr = packet->payload; | |
426 size_t len = packet->payload_length; | |
427 while (len > 0) { | |
428 assert(len >= bytes_per_frame); | |
429 Packet* new_packet = new Packet; | |
430 new_packet->payload_length = bytes_per_frame; | |
431 new_packet->header = packet->header; | |
432 new_packet->header.timestamp = timestamp; | |
433 timestamp += timestamps_per_frame; | |
434 new_packet->primary = packet->primary; | |
435 new_packet->payload = new uint8_t[bytes_per_frame]; | |
436 memcpy(new_packet->payload, payload_ptr, bytes_per_frame); | |
437 payload_ptr += bytes_per_frame; | |
438 new_packets->push_back(new_packet); | |
439 len -= bytes_per_frame; | |
440 } | |
441 return kOK; | |
442 } | |
443 | 282 |
444 } // namespace webrtc | 283 } // namespace webrtc |
OLD | NEW |