1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 //#define LOG_NDEBUG 0 18 #define LOG_TAG "ARTPWriter" 19 #include <utils/Log.h> 20 21 #include "ARTPWriter.h" 22 23 #include <fcntl.h> 24 25 #include <media/MediaSource.h> 26 #include <media/stagefright/foundation/ABuffer.h> 27 #include <media/stagefright/foundation/ADebug.h> 28 #include <media/stagefright/foundation/AMessage.h> 29 #include <media/stagefright/foundation/hexdump.h> 30 #include <media/stagefright/MediaBuffer.h> 31 #include <media/stagefright/MediaDefs.h> 32 #include <media/stagefright/MetaData.h> 33 #include <utils/ByteOrder.h> 34 35 #define PT 97 36 #define PT_STR "97" 37 38 namespace android { 39 40 // static const size_t kMaxPacketSize = 65507; // maximum payload in UDP over IP 41 static const size_t kMaxPacketSize = 1500; 42 43 static int UniformRand(int limit) { 44 return ((double)rand() * limit) / RAND_MAX; 45 } 46 47 ARTPWriter::ARTPWriter(int fd) 48 : mFlags(0), 49 mFd(dup(fd)), 50 mLooper(new ALooper), 51 mReflector(new AHandlerReflector<ARTPWriter>(this)) { 52 CHECK_GE(fd, 0); 53 54 mLooper->setName("rtp writer"); 55 mLooper->registerHandler(mReflector); 56 mLooper->start(); 57 58 mSocket = socket(AF_INET, SOCK_DGRAM, 0); 59 CHECK_GE(mSocket, 0); 60 61 memset(mRTPAddr.sin_zero, 0, sizeof(mRTPAddr.sin_zero)); 62 mRTPAddr.sin_family = AF_INET; 63 64 #if 1 65 mRTPAddr.sin_addr.s_addr = INADDR_ANY; 66 #else 67 mRTPAddr.sin_addr.s_addr = inet_addr("172.19.18.246"); 68 #endif 69 70 mRTPAddr.sin_port = htons(5634); 71 CHECK_EQ(0, ntohs(mRTPAddr.sin_port) & 1); 72 73 mRTCPAddr = mRTPAddr; 74 mRTCPAddr.sin_port = htons(ntohs(mRTPAddr.sin_port) | 1); 75 76 #if LOG_TO_FILES 77 mRTPFd = open( 78 "/data/misc/rtpout.bin", 79 O_WRONLY | O_CREAT | O_TRUNC, 80 0644); 81 CHECK_GE(mRTPFd, 0); 82 83 mRTCPFd = open( 84 "/data/misc/rtcpout.bin", 85 O_WRONLY | O_CREAT | O_TRUNC, 86 0644); 87 CHECK_GE(mRTCPFd, 0); 88 #endif 89 } 90 91 ARTPWriter::~ARTPWriter() { 92 #if LOG_TO_FILES 93 close(mRTCPFd); 94 mRTCPFd = -1; 95 96 close(mRTPFd); 97 mRTPFd = -1; 98 #endif 99 100 close(mSocket); 101 mSocket = -1; 102 103 close(mFd); 104 mFd = -1; 105 } 106 107 status_t ARTPWriter::addSource(const sp<MediaSource> &source) { 108 mSource = source; 109 return OK; 110 } 111 112 bool ARTPWriter::reachedEOS() { 113 Mutex::Autolock autoLock(mLock); 114 return (mFlags & kFlagEOS) != 0; 115 } 116 117 status_t ARTPWriter::start(MetaData * /* params */) { 118 Mutex::Autolock autoLock(mLock); 119 if (mFlags & kFlagStarted) { 120 return INVALID_OPERATION; 121 } 122 123 mFlags &= ~kFlagEOS; 124 mSourceID = rand(); 125 mSeqNo = UniformRand(65536); 126 mRTPTimeBase = rand(); 127 mNumRTPSent = 0; 128 mNumRTPOctetsSent = 0; 129 mLastRTPTime = 0; 130 mLastNTPTime = 0; 131 mNumSRsSent = 0; 132 133 const char *mime; 134 CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime)); 135 136 mMode = INVALID; 137 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 138 mMode = H264; 139 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_H263)) { 140 mMode = H263; 141 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) { 142 mMode = AMR_NB; 143 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) { 144 mMode = AMR_WB; 145 } else { 146 TRESPASS(); 147 } 148 149 (new AMessage(kWhatStart, mReflector))->post(); 150 151 while (!(mFlags & kFlagStarted)) { 152 mCondition.wait(mLock); 153 } 154 155 return OK; 156 } 157 158 status_t ARTPWriter::stop() { 159 Mutex::Autolock autoLock(mLock); 160 if (!(mFlags & kFlagStarted)) { 161 return OK; 162 } 163 164 (new AMessage(kWhatStop, mReflector))->post(); 165 166 while (mFlags & kFlagStarted) { 167 mCondition.wait(mLock); 168 } 169 return OK; 170 } 171 172 status_t ARTPWriter::pause() { 173 return OK; 174 } 175 176 static void StripStartcode(MediaBufferBase *buffer) { 177 if (buffer->range_length() < 4) { 178 return; 179 } 180 181 const uint8_t *ptr = 182 (const uint8_t *)buffer->data() + buffer->range_offset(); 183 184 if (!memcmp(ptr, "\x00\x00\x00\x01", 4)) { 185 buffer->set_range( 186 buffer->range_offset() + 4, buffer->range_length() - 4); 187 } 188 } 189 190 void ARTPWriter::onMessageReceived(const sp<AMessage> &msg) { 191 switch (msg->what()) { 192 case kWhatStart: 193 { 194 CHECK_EQ(mSource->start(), (status_t)OK); 195 196 #if 0 197 if (mMode == H264) { 198 MediaBufferBase *buffer; 199 CHECK_EQ(mSource->read(&buffer), (status_t)OK); 200 201 StripStartcode(buffer); 202 makeH264SPropParamSets(buffer); 203 buffer->release(); 204 buffer = NULL; 205 } 206 207 dumpSessionDesc(); 208 #endif 209 210 { 211 Mutex::Autolock autoLock(mLock); 212 mFlags |= kFlagStarted; 213 mCondition.signal(); 214 } 215 216 (new AMessage(kWhatRead, mReflector))->post(); 217 (new AMessage(kWhatSendSR, mReflector))->post(); 218 break; 219 } 220 221 case kWhatStop: 222 { 223 CHECK_EQ(mSource->stop(), (status_t)OK); 224 225 sendBye(); 226 227 { 228 Mutex::Autolock autoLock(mLock); 229 mFlags &= ~kFlagStarted; 230 mCondition.signal(); 231 } 232 break; 233 } 234 235 case kWhatRead: 236 { 237 { 238 Mutex::Autolock autoLock(mLock); 239 if (!(mFlags & kFlagStarted)) { 240 break; 241 } 242 } 243 244 onRead(msg); 245 break; 246 } 247 248 case kWhatSendSR: 249 { 250 { 251 Mutex::Autolock autoLock(mLock); 252 if (!(mFlags & kFlagStarted)) { 253 break; 254 } 255 } 256 257 onSendSR(msg); 258 break; 259 } 260 261 default: 262 TRESPASS(); 263 break; 264 } 265 } 266 267 void ARTPWriter::onRead(const sp<AMessage> &msg) { 268 MediaBufferBase *mediaBuf; 269 status_t err = mSource->read(&mediaBuf); 270 271 if (err != OK) { 272 ALOGI("reached EOS."); 273 274 Mutex::Autolock autoLock(mLock); 275 mFlags |= kFlagEOS; 276 return; 277 } 278 279 if (mediaBuf->range_length() > 0) { 280 ALOGV("read buffer of size %zu", mediaBuf->range_length()); 281 282 if (mMode == H264) { 283 StripStartcode(mediaBuf); 284 sendAVCData(mediaBuf); 285 } else if (mMode == H263) { 286 sendH263Data(mediaBuf); 287 } else if (mMode == AMR_NB || mMode == AMR_WB) { 288 sendAMRData(mediaBuf); 289 } 290 } 291 292 mediaBuf->release(); 293 mediaBuf = NULL; 294 295 msg->post(); 296 } 297 298 void ARTPWriter::onSendSR(const sp<AMessage> &msg) { 299 sp<ABuffer> buffer = new ABuffer(65536); 300 buffer->setRange(0, 0); 301 302 addSR(buffer); 303 addSDES(buffer); 304 305 send(buffer, true /* isRTCP */); 306 307 ++mNumSRsSent; 308 msg->post(3000000); 309 } 310 311 void ARTPWriter::send(const sp<ABuffer> &buffer, bool isRTCP) { 312 ssize_t n = sendto( 313 mSocket, buffer->data(), buffer->size(), 0, 314 (const struct sockaddr *)(isRTCP ? &mRTCPAddr : &mRTPAddr), 315 sizeof(mRTCPAddr)); 316 317 CHECK_EQ(n, (ssize_t)buffer->size()); 318 319 #if LOG_TO_FILES 320 int fd = isRTCP ? mRTCPFd : mRTPFd; 321 322 uint32_t ms = tolel(ALooper::GetNowUs() / 1000ll); 323 uint32_t length = tolel(buffer->size()); 324 write(fd, &ms, sizeof(ms)); 325 write(fd, &length, sizeof(length)); 326 write(fd, buffer->data(), buffer->size()); 327 #endif 328 } 329 330 void ARTPWriter::addSR(const sp<ABuffer> &buffer) { 331 uint8_t *data = buffer->data() + buffer->size(); 332 333 data[0] = 0x80 | 0; 334 data[1] = 200; // SR 335 data[2] = 0; 336 data[3] = 6; 337 data[4] = mSourceID >> 24; 338 data[5] = (mSourceID >> 16) & 0xff; 339 data[6] = (mSourceID >> 8) & 0xff; 340 data[7] = mSourceID & 0xff; 341 342 data[8] = mLastNTPTime >> (64 - 8); 343 data[9] = (mLastNTPTime >> (64 - 16)) & 0xff; 344 data[10] = (mLastNTPTime >> (64 - 24)) & 0xff; 345 data[11] = (mLastNTPTime >> 32) & 0xff; 346 data[12] = (mLastNTPTime >> 24) & 0xff; 347 data[13] = (mLastNTPTime >> 16) & 0xff; 348 data[14] = (mLastNTPTime >> 8) & 0xff; 349 data[15] = mLastNTPTime & 0xff; 350 351 data[16] = (mLastRTPTime >> 24) & 0xff; 352 data[17] = (mLastRTPTime >> 16) & 0xff; 353 data[18] = (mLastRTPTime >> 8) & 0xff; 354 data[19] = mLastRTPTime & 0xff; 355 356 data[20] = mNumRTPSent >> 24; 357 data[21] = (mNumRTPSent >> 16) & 0xff; 358 data[22] = (mNumRTPSent >> 8) & 0xff; 359 data[23] = mNumRTPSent & 0xff; 360 361 data[24] = mNumRTPOctetsSent >> 24; 362 data[25] = (mNumRTPOctetsSent >> 16) & 0xff; 363 data[26] = (mNumRTPOctetsSent >> 8) & 0xff; 364 data[27] = mNumRTPOctetsSent & 0xff; 365 366 buffer->setRange(buffer->offset(), buffer->size() + 28); 367 } 368 369 void ARTPWriter::addSDES(const sp<ABuffer> &buffer) { 370 uint8_t *data = buffer->data() + buffer->size(); 371 data[0] = 0x80 | 1; 372 data[1] = 202; // SDES 373 data[4] = mSourceID >> 24; 374 data[5] = (mSourceID >> 16) & 0xff; 375 data[6] = (mSourceID >> 8) & 0xff; 376 data[7] = mSourceID & 0xff; 377 378 size_t offset = 8; 379 380 data[offset++] = 1; // CNAME 381 382 static const char *kCNAME = "someone@somewhere"; 383 data[offset++] = strlen(kCNAME); 384 385 memcpy(&data[offset], kCNAME, strlen(kCNAME)); 386 offset += strlen(kCNAME); 387 388 data[offset++] = 7; // NOTE 389 390 static const char *kNOTE = "Hell's frozen over."; 391 data[offset++] = strlen(kNOTE); 392 393 memcpy(&data[offset], kNOTE, strlen(kNOTE)); 394 offset += strlen(kNOTE); 395 396 data[offset++] = 0; 397 398 if ((offset % 4) > 0) { 399 size_t count = 4 - (offset % 4); 400 switch (count) { 401 case 3: 402 data[offset++] = 0; 403 [[fallthrough]]; 404 case 2: 405 data[offset++] = 0; 406 [[fallthrough]]; 407 case 1: 408 data[offset++] = 0; 409 } 410 } 411 412 size_t numWords = (offset / 4) - 1; 413 data[2] = numWords >> 8; 414 data[3] = numWords & 0xff; 415 416 buffer->setRange(buffer->offset(), buffer->size() + offset); 417 } 418 419 // static 420 uint64_t ARTPWriter::GetNowNTP() { 421 uint64_t nowUs = ALooper::GetNowUs(); 422 423 nowUs += ((70LL * 365 + 17) * 24) * 60 * 60 * 1000000LL; 424 425 uint64_t hi = nowUs / 1000000LL; 426 uint64_t lo = ((1LL << 32) * (nowUs % 1000000LL)) / 1000000LL; 427 428 return (hi << 32) | lo; 429 } 430 431 void ARTPWriter::dumpSessionDesc() { 432 AString sdp; 433 sdp = "v=0\r\n"; 434 435 sdp.append("o=- "); 436 437 uint64_t ntp = GetNowNTP(); 438 sdp.append(ntp); 439 sdp.append(" "); 440 sdp.append(ntp); 441 sdp.append(" IN IP4 127.0.0.0\r\n"); 442 443 sdp.append( 444 "s=Sample\r\n" 445 "i=Playing around\r\n" 446 "c=IN IP4 "); 447 448 struct in_addr addr; 449 addr.s_addr = ntohl(INADDR_LOOPBACK); 450 451 sdp.append(inet_ntoa(addr)); 452 453 sdp.append( 454 "\r\n" 455 "t=0 0\r\n" 456 "a=range:npt=now-\r\n"); 457 458 sp<MetaData> meta = mSource->getFormat(); 459 460 if (mMode == H264 || mMode == H263) { 461 sdp.append("m=video "); 462 } else { 463 sdp.append("m=audio "); 464 } 465 466 sdp.append(AStringPrintf("%d", ntohs(mRTPAddr.sin_port))); 467 sdp.append( 468 " RTP/AVP " PT_STR "\r\n" 469 "b=AS 320000\r\n" 470 "a=rtpmap:" PT_STR " "); 471 472 if (mMode == H264) { 473 sdp.append("H264/90000"); 474 } else if (mMode == H263) { 475 sdp.append("H263-1998/90000"); 476 } else if (mMode == AMR_NB || mMode == AMR_WB) { 477 int32_t sampleRate, numChannels; 478 CHECK(mSource->getFormat()->findInt32(kKeySampleRate, &sampleRate)); 479 CHECK(mSource->getFormat()->findInt32(kKeyChannelCount, &numChannels)); 480 481 CHECK_EQ(numChannels, 1); 482 CHECK_EQ(sampleRate, (mMode == AMR_NB) ? 8000 : 16000); 483 484 sdp.append(mMode == AMR_NB ? "AMR" : "AMR-WB"); 485 sdp.append(AStringPrintf("/%d/%d", sampleRate, numChannels)); 486 } else { 487 TRESPASS(); 488 } 489 490 sdp.append("\r\n"); 491 492 if (mMode == H264 || mMode == H263) { 493 int32_t width, height; 494 CHECK(meta->findInt32(kKeyWidth, &width)); 495 CHECK(meta->findInt32(kKeyHeight, &height)); 496 497 sdp.append("a=cliprect 0,0,"); 498 sdp.append(height); 499 sdp.append(","); 500 sdp.append(width); 501 sdp.append("\r\n"); 502 503 sdp.append( 504 "a=framesize:" PT_STR " "); 505 sdp.append(width); 506 sdp.append("-"); 507 sdp.append(height); 508 sdp.append("\r\n"); 509 } 510 511 if (mMode == H264) { 512 sdp.append( 513 "a=fmtp:" PT_STR " profile-level-id="); 514 sdp.append(mProfileLevel); 515 sdp.append(";sprop-parameter-sets="); 516 517 sdp.append(mSeqParamSet); 518 sdp.append(","); 519 sdp.append(mPicParamSet); 520 sdp.append(";packetization-mode=1\r\n"); 521 } else if (mMode == AMR_NB || mMode == AMR_WB) { 522 sdp.append("a=fmtp:" PT_STR " octed-align\r\n"); 523 } 524 525 ALOGI("%s", sdp.c_str()); 526 } 527 528 void ARTPWriter::makeH264SPropParamSets(MediaBufferBase *buffer) { 529 static const char kStartCode[] = "\x00\x00\x00\x01"; 530 531 const uint8_t *data = 532 (const uint8_t *)buffer->data() + buffer->range_offset(); 533 size_t size = buffer->range_length(); 534 535 CHECK_GE(size, 0u); 536 537 size_t startCodePos = 0; 538 while (startCodePos + 3 < size 539 && memcmp(kStartCode, &data[startCodePos], 4)) { 540 ++startCodePos; 541 } 542 543 CHECK_LT(startCodePos + 3, size); 544 545 CHECK_EQ((unsigned)data[0], 0x67u); 546 547 mProfileLevel = 548 AStringPrintf("%02X%02X%02X", data[1], data[2], data[3]); 549 550 encodeBase64(data, startCodePos, &mSeqParamSet); 551 552 encodeBase64(&data[startCodePos + 4], size - startCodePos - 4, 553 &mPicParamSet); 554 } 555 556 void ARTPWriter::sendBye() { 557 sp<ABuffer> buffer = new ABuffer(8); 558 uint8_t *data = buffer->data(); 559 *data++ = (2 << 6) | 1; 560 *data++ = 203; 561 *data++ = 0; 562 *data++ = 1; 563 *data++ = mSourceID >> 24; 564 *data++ = (mSourceID >> 16) & 0xff; 565 *data++ = (mSourceID >> 8) & 0xff; 566 *data++ = mSourceID & 0xff; 567 buffer->setRange(0, 8); 568 569 send(buffer, true /* isRTCP */); 570 } 571 572 void ARTPWriter::sendAVCData(MediaBufferBase *mediaBuf) { 573 // 12 bytes RTP header + 2 bytes for the FU-indicator and FU-header. 574 CHECK_GE(kMaxPacketSize, 12u + 2u); 575 576 int64_t timeUs; 577 CHECK(mediaBuf->meta_data().findInt64(kKeyTime, &timeUs)); 578 579 uint32_t rtpTime = mRTPTimeBase + (timeUs * 9 / 100LL); 580 581 const uint8_t *mediaData = 582 (const uint8_t *)mediaBuf->data() + mediaBuf->range_offset(); 583 584 sp<ABuffer> buffer = new ABuffer(kMaxPacketSize); 585 if (mediaBuf->range_length() + 12 <= buffer->capacity()) { 586 // The data fits into a single packet 587 uint8_t *data = buffer->data(); 588 data[0] = 0x80; 589 data[1] = (1 << 7) | PT; // M-bit 590 data[2] = (mSeqNo >> 8) & 0xff; 591 data[3] = mSeqNo & 0xff; 592 data[4] = rtpTime >> 24; 593 data[5] = (rtpTime >> 16) & 0xff; 594 data[6] = (rtpTime >> 8) & 0xff; 595 data[7] = rtpTime & 0xff; 596 data[8] = mSourceID >> 24; 597 data[9] = (mSourceID >> 16) & 0xff; 598 data[10] = (mSourceID >> 8) & 0xff; 599 data[11] = mSourceID & 0xff; 600 601 memcpy(&data[12], 602 mediaData, mediaBuf->range_length()); 603 604 buffer->setRange(0, mediaBuf->range_length() + 12); 605 606 send(buffer, false /* isRTCP */); 607 608 ++mSeqNo; 609 ++mNumRTPSent; 610 mNumRTPOctetsSent += buffer->size() - 12; 611 } else { 612 // FU-A 613 614 unsigned nalType = mediaData[0]; 615 size_t offset = 1; 616 617 bool firstPacket = true; 618 while (offset < mediaBuf->range_length()) { 619 size_t size = mediaBuf->range_length() - offset; 620 bool lastPacket = true; 621 if (size + 12 + 2 > buffer->capacity()) { 622 lastPacket = false; 623 size = buffer->capacity() - 12 - 2; 624 } 625 626 uint8_t *data = buffer->data(); 627 data[0] = 0x80; 628 data[1] = (lastPacket ? (1 << 7) : 0x00) | PT; // M-bit 629 data[2] = (mSeqNo >> 8) & 0xff; 630 data[3] = mSeqNo & 0xff; 631 data[4] = rtpTime >> 24; 632 data[5] = (rtpTime >> 16) & 0xff; 633 data[6] = (rtpTime >> 8) & 0xff; 634 data[7] = rtpTime & 0xff; 635 data[8] = mSourceID >> 24; 636 data[9] = (mSourceID >> 16) & 0xff; 637 data[10] = (mSourceID >> 8) & 0xff; 638 data[11] = mSourceID & 0xff; 639 640 data[12] = 28 | (nalType & 0xe0); 641 642 CHECK(!firstPacket || !lastPacket); 643 644 data[13] = 645 (firstPacket ? 0x80 : 0x00) 646 | (lastPacket ? 0x40 : 0x00) 647 | (nalType & 0x1f); 648 649 memcpy(&data[14], &mediaData[offset], size); 650 651 buffer->setRange(0, 14 + size); 652 653 send(buffer, false /* isRTCP */); 654 655 ++mSeqNo; 656 ++mNumRTPSent; 657 mNumRTPOctetsSent += buffer->size() - 12; 658 659 firstPacket = false; 660 offset += size; 661 } 662 } 663 664 mLastRTPTime = rtpTime; 665 mLastNTPTime = GetNowNTP(); 666 } 667 668 void ARTPWriter::sendH263Data(MediaBufferBase *mediaBuf) { 669 CHECK_GE(kMaxPacketSize, 12u + 2u); 670 671 int64_t timeUs; 672 CHECK(mediaBuf->meta_data().findInt64(kKeyTime, &timeUs)); 673 674 uint32_t rtpTime = mRTPTimeBase + (timeUs * 9 / 100LL); 675 676 const uint8_t *mediaData = 677 (const uint8_t *)mediaBuf->data() + mediaBuf->range_offset(); 678 679 // hexdump(mediaData, mediaBuf->range_length()); 680 681 CHECK_EQ((unsigned)mediaData[0], 0u); 682 CHECK_EQ((unsigned)mediaData[1], 0u); 683 684 size_t offset = 2; 685 size_t size = mediaBuf->range_length(); 686 687 while (offset < size) { 688 sp<ABuffer> buffer = new ABuffer(kMaxPacketSize); 689 // CHECK_LE(mediaBuf->range_length() -2 + 14, buffer->capacity()); 690 691 size_t remaining = size - offset; 692 bool lastPacket = (remaining + 14 <= buffer->capacity()); 693 if (!lastPacket) { 694 remaining = buffer->capacity() - 14; 695 } 696 697 uint8_t *data = buffer->data(); 698 data[0] = 0x80; 699 data[1] = (lastPacket ? 0x80 : 0x00) | PT; // M-bit 700 data[2] = (mSeqNo >> 8) & 0xff; 701 data[3] = mSeqNo & 0xff; 702 data[4] = rtpTime >> 24; 703 data[5] = (rtpTime >> 16) & 0xff; 704 data[6] = (rtpTime >> 8) & 0xff; 705 data[7] = rtpTime & 0xff; 706 data[8] = mSourceID >> 24; 707 data[9] = (mSourceID >> 16) & 0xff; 708 data[10] = (mSourceID >> 8) & 0xff; 709 data[11] = mSourceID & 0xff; 710 711 data[12] = (offset == 2) ? 0x04 : 0x00; // P=?, V=0 712 data[13] = 0x00; // PLEN = PEBIT = 0 713 714 memcpy(&data[14], &mediaData[offset], remaining); 715 offset += remaining; 716 717 buffer->setRange(0, remaining + 14); 718 719 send(buffer, false /* isRTCP */); 720 721 ++mSeqNo; 722 ++mNumRTPSent; 723 mNumRTPOctetsSent += buffer->size() - 12; 724 } 725 726 mLastRTPTime = rtpTime; 727 mLastNTPTime = GetNowNTP(); 728 } 729 730 static size_t getFrameSize(bool isWide, unsigned FT) { 731 static const size_t kFrameSizeNB[8] = { 732 95, 103, 118, 134, 148, 159, 204, 244 733 }; 734 static const size_t kFrameSizeWB[9] = { 735 132, 177, 253, 285, 317, 365, 397, 461, 477 736 }; 737 738 size_t frameSize = isWide ? kFrameSizeWB[FT] : kFrameSizeNB[FT]; 739 740 // Round up bits to bytes and add 1 for the header byte. 741 frameSize = (frameSize + 7) / 8 + 1; 742 743 return frameSize; 744 } 745 746 void ARTPWriter::sendAMRData(MediaBufferBase *mediaBuf) { 747 const uint8_t *mediaData = 748 (const uint8_t *)mediaBuf->data() + mediaBuf->range_offset(); 749 750 size_t mediaLength = mediaBuf->range_length(); 751 752 CHECK_GE(kMaxPacketSize, 12u + 1u + mediaLength); 753 754 const bool isWide = (mMode == AMR_WB); 755 756 int64_t timeUs; 757 CHECK(mediaBuf->meta_data().findInt64(kKeyTime, &timeUs)); 758 uint32_t rtpTime = mRTPTimeBase + (timeUs / (isWide ? 250 : 125)); 759 760 // hexdump(mediaData, mediaLength); 761 762 Vector<uint8_t> tableOfContents; 763 size_t srcOffset = 0; 764 while (srcOffset < mediaLength) { 765 uint8_t toc = mediaData[srcOffset]; 766 767 unsigned FT = (toc >> 3) & 0x0f; 768 CHECK((isWide && FT <= 8) || (!isWide && FT <= 7)); 769 770 tableOfContents.push(toc); 771 srcOffset += getFrameSize(isWide, FT); 772 } 773 CHECK_EQ(srcOffset, mediaLength); 774 775 sp<ABuffer> buffer = new ABuffer(kMaxPacketSize); 776 CHECK_LE(mediaLength + 12 + 1, buffer->capacity()); 777 778 // The data fits into a single packet 779 uint8_t *data = buffer->data(); 780 data[0] = 0x80; 781 data[1] = PT; 782 if (mNumRTPSent == 0) { 783 // Signal start of talk-spurt. 784 data[1] |= 0x80; // M-bit 785 } 786 data[2] = (mSeqNo >> 8) & 0xff; 787 data[3] = mSeqNo & 0xff; 788 data[4] = rtpTime >> 24; 789 data[5] = (rtpTime >> 16) & 0xff; 790 data[6] = (rtpTime >> 8) & 0xff; 791 data[7] = rtpTime & 0xff; 792 data[8] = mSourceID >> 24; 793 data[9] = (mSourceID >> 16) & 0xff; 794 data[10] = (mSourceID >> 8) & 0xff; 795 data[11] = mSourceID & 0xff; 796 797 data[12] = 0xf0; // CMR=15, RR=0 798 799 size_t dstOffset = 13; 800 801 for (size_t i = 0; i < tableOfContents.size(); ++i) { 802 uint8_t toc = tableOfContents[i]; 803 804 if (i + 1 < tableOfContents.size()) { 805 toc |= 0x80; 806 } else { 807 toc &= ~0x80; 808 } 809 810 data[dstOffset++] = toc; 811 } 812 813 srcOffset = 0; 814 for (size_t i = 0; i < tableOfContents.size(); ++i) { 815 uint8_t toc = tableOfContents[i]; 816 unsigned FT = (toc >> 3) & 0x0f; 817 size_t frameSize = getFrameSize(isWide, FT); 818 819 ++srcOffset; // skip toc 820 memcpy(&data[dstOffset], &mediaData[srcOffset], frameSize - 1); 821 srcOffset += frameSize - 1; 822 dstOffset += frameSize - 1; 823 } 824 825 buffer->setRange(0, dstOffset); 826 827 send(buffer, false /* isRTCP */); 828 829 ++mSeqNo; 830 ++mNumRTPSent; 831 mNumRTPOctetsSent += buffer->size() - 12; 832 833 mLastRTPTime = rtpTime; 834 mLastNTPTime = GetNowNTP(); 835 } 836 837 } // namespace android 838 839