| 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 |