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/stagefright/foundation/ABuffer.h> 26#include <media/stagefright/foundation/ADebug.h> 27#include <media/stagefright/foundation/AMessage.h> 28#include <media/stagefright/foundation/hexdump.h> 29#include <media/stagefright/MediaBuffer.h> 30#include <media/stagefright/MediaDefs.h> 31#include <media/stagefright/MediaSource.h> 32#include <media/stagefright/MetaData.h> 33#include <utils/ByteOrder.h> 34 35#define PT 97 36#define PT_STR "97" 37 38namespace android { 39 40// static const size_t kMaxPacketSize = 65507; // maximum payload in UDP over IP 41static const size_t kMaxPacketSize = 1500; 42 43static int UniformRand(int limit) { 44 return ((double)rand() * limit) / RAND_MAX; 45} 46 47ARTPWriter::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 91ARTPWriter::~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 107status_t ARTPWriter::addSource(const sp<MediaSource> &source) { 108 mSource = source; 109 return OK; 110} 111 112bool ARTPWriter::reachedEOS() { 113 Mutex::Autolock autoLock(mLock); 114 return (mFlags & kFlagEOS) != 0; 115} 116 117status_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->id()))->post(); 150 151 while (!(mFlags & kFlagStarted)) { 152 mCondition.wait(mLock); 153 } 154 155 return OK; 156} 157 158status_t ARTPWriter::stop() { 159 Mutex::Autolock autoLock(mLock); 160 if (!(mFlags & kFlagStarted)) { 161 return OK; 162 } 163 164 (new AMessage(kWhatStop, mReflector->id()))->post(); 165 166 while (mFlags & kFlagStarted) { 167 mCondition.wait(mLock); 168 } 169 return OK; 170} 171 172status_t ARTPWriter::pause() { 173 return OK; 174} 175 176static void StripStartcode(MediaBuffer *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 190void 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 MediaBuffer *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->id()))->post(); 217 (new AMessage(kWhatSendSR, mReflector->id()))->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 267void ARTPWriter::onRead(const sp<AMessage> &msg) { 268 MediaBuffer *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 %d", 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 298void 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 311void 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 330void 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 369void 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 case 2: 404 data[offset++] = 0; 405 case 1: 406 data[offset++] = 0; 407 } 408 } 409 410 size_t numWords = (offset / 4) - 1; 411 data[2] = numWords >> 8; 412 data[3] = numWords & 0xff; 413 414 buffer->setRange(buffer->offset(), buffer->size() + offset); 415} 416 417// static 418uint64_t ARTPWriter::GetNowNTP() { 419 uint64_t nowUs = ALooper::GetNowUs(); 420 421 nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll; 422 423 uint64_t hi = nowUs / 1000000ll; 424 uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll; 425 426 return (hi << 32) | lo; 427} 428 429void ARTPWriter::dumpSessionDesc() { 430 AString sdp; 431 sdp = "v=0\r\n"; 432 433 sdp.append("o=- "); 434 435 uint64_t ntp = GetNowNTP(); 436 sdp.append(ntp); 437 sdp.append(" "); 438 sdp.append(ntp); 439 sdp.append(" IN IP4 127.0.0.0\r\n"); 440 441 sdp.append( 442 "s=Sample\r\n" 443 "i=Playing around\r\n" 444 "c=IN IP4 "); 445 446 struct in_addr addr; 447 addr.s_addr = ntohl(INADDR_LOOPBACK); 448 449 sdp.append(inet_ntoa(addr)); 450 451 sdp.append( 452 "\r\n" 453 "t=0 0\r\n" 454 "a=range:npt=now-\r\n"); 455 456 sp<MetaData> meta = mSource->getFormat(); 457 458 if (mMode == H264 || mMode == H263) { 459 sdp.append("m=video "); 460 } else { 461 sdp.append("m=audio "); 462 } 463 464 sdp.append(StringPrintf("%d", ntohs(mRTPAddr.sin_port))); 465 sdp.append( 466 " RTP/AVP " PT_STR "\r\n" 467 "b=AS 320000\r\n" 468 "a=rtpmap:" PT_STR " "); 469 470 if (mMode == H264) { 471 sdp.append("H264/90000"); 472 } else if (mMode == H263) { 473 sdp.append("H263-1998/90000"); 474 } else if (mMode == AMR_NB || mMode == AMR_WB) { 475 int32_t sampleRate, numChannels; 476 CHECK(mSource->getFormat()->findInt32(kKeySampleRate, &sampleRate)); 477 CHECK(mSource->getFormat()->findInt32(kKeyChannelCount, &numChannels)); 478 479 CHECK_EQ(numChannels, 1); 480 CHECK_EQ(sampleRate, (mMode == AMR_NB) ? 8000 : 16000); 481 482 sdp.append(mMode == AMR_NB ? "AMR" : "AMR-WB"); 483 sdp.append(StringPrintf("/%d/%d", sampleRate, numChannels)); 484 } else { 485 TRESPASS(); 486 } 487 488 sdp.append("\r\n"); 489 490 if (mMode == H264 || mMode == H263) { 491 int32_t width, height; 492 CHECK(meta->findInt32(kKeyWidth, &width)); 493 CHECK(meta->findInt32(kKeyHeight, &height)); 494 495 sdp.append("a=cliprect 0,0,"); 496 sdp.append(height); 497 sdp.append(","); 498 sdp.append(width); 499 sdp.append("\r\n"); 500 501 sdp.append( 502 "a=framesize:" PT_STR " "); 503 sdp.append(width); 504 sdp.append("-"); 505 sdp.append(height); 506 sdp.append("\r\n"); 507 } 508 509 if (mMode == H264) { 510 sdp.append( 511 "a=fmtp:" PT_STR " profile-level-id="); 512 sdp.append(mProfileLevel); 513 sdp.append(";sprop-parameter-sets="); 514 515 sdp.append(mSeqParamSet); 516 sdp.append(","); 517 sdp.append(mPicParamSet); 518 sdp.append(";packetization-mode=1\r\n"); 519 } else if (mMode == AMR_NB || mMode == AMR_WB) { 520 sdp.append("a=fmtp:" PT_STR " octed-align\r\n"); 521 } 522 523 ALOGI("%s", sdp.c_str()); 524} 525 526void ARTPWriter::makeH264SPropParamSets(MediaBuffer *buffer) { 527 static const char kStartCode[] = "\x00\x00\x00\x01"; 528 529 const uint8_t *data = 530 (const uint8_t *)buffer->data() + buffer->range_offset(); 531 size_t size = buffer->range_length(); 532 533 CHECK_GE(size, 0u); 534 535 size_t startCodePos = 0; 536 while (startCodePos + 3 < size 537 && memcmp(kStartCode, &data[startCodePos], 4)) { 538 ++startCodePos; 539 } 540 541 CHECK_LT(startCodePos + 3, size); 542 543 CHECK_EQ((unsigned)data[0], 0x67u); 544 545 mProfileLevel = 546 StringPrintf("%02X%02X%02X", data[1], data[2], data[3]); 547 548 encodeBase64(data, startCodePos, &mSeqParamSet); 549 550 encodeBase64(&data[startCodePos + 4], size - startCodePos - 4, 551 &mPicParamSet); 552} 553 554void ARTPWriter::sendBye() { 555 sp<ABuffer> buffer = new ABuffer(8); 556 uint8_t *data = buffer->data(); 557 *data++ = (2 << 6) | 1; 558 *data++ = 203; 559 *data++ = 0; 560 *data++ = 1; 561 *data++ = mSourceID >> 24; 562 *data++ = (mSourceID >> 16) & 0xff; 563 *data++ = (mSourceID >> 8) & 0xff; 564 *data++ = mSourceID & 0xff; 565 buffer->setRange(0, 8); 566 567 send(buffer, true /* isRTCP */); 568} 569 570void ARTPWriter::sendAVCData(MediaBuffer *mediaBuf) { 571 // 12 bytes RTP header + 2 bytes for the FU-indicator and FU-header. 572 CHECK_GE(kMaxPacketSize, 12u + 2u); 573 574 int64_t timeUs; 575 CHECK(mediaBuf->meta_data()->findInt64(kKeyTime, &timeUs)); 576 577 uint32_t rtpTime = mRTPTimeBase + (timeUs * 9 / 100ll); 578 579 const uint8_t *mediaData = 580 (const uint8_t *)mediaBuf->data() + mediaBuf->range_offset(); 581 582 sp<ABuffer> buffer = new ABuffer(kMaxPacketSize); 583 if (mediaBuf->range_length() + 12 <= buffer->capacity()) { 584 // The data fits into a single packet 585 uint8_t *data = buffer->data(); 586 data[0] = 0x80; 587 data[1] = (1 << 7) | PT; // M-bit 588 data[2] = (mSeqNo >> 8) & 0xff; 589 data[3] = mSeqNo & 0xff; 590 data[4] = rtpTime >> 24; 591 data[5] = (rtpTime >> 16) & 0xff; 592 data[6] = (rtpTime >> 8) & 0xff; 593 data[7] = rtpTime & 0xff; 594 data[8] = mSourceID >> 24; 595 data[9] = (mSourceID >> 16) & 0xff; 596 data[10] = (mSourceID >> 8) & 0xff; 597 data[11] = mSourceID & 0xff; 598 599 memcpy(&data[12], 600 mediaData, mediaBuf->range_length()); 601 602 buffer->setRange(0, mediaBuf->range_length() + 12); 603 604 send(buffer, false /* isRTCP */); 605 606 ++mSeqNo; 607 ++mNumRTPSent; 608 mNumRTPOctetsSent += buffer->size() - 12; 609 } else { 610 // FU-A 611 612 unsigned nalType = mediaData[0]; 613 size_t offset = 1; 614 615 bool firstPacket = true; 616 while (offset < mediaBuf->range_length()) { 617 size_t size = mediaBuf->range_length() - offset; 618 bool lastPacket = true; 619 if (size + 12 + 2 > buffer->capacity()) { 620 lastPacket = false; 621 size = buffer->capacity() - 12 - 2; 622 } 623 624 uint8_t *data = buffer->data(); 625 data[0] = 0x80; 626 data[1] = (lastPacket ? (1 << 7) : 0x00) | PT; // M-bit 627 data[2] = (mSeqNo >> 8) & 0xff; 628 data[3] = mSeqNo & 0xff; 629 data[4] = rtpTime >> 24; 630 data[5] = (rtpTime >> 16) & 0xff; 631 data[6] = (rtpTime >> 8) & 0xff; 632 data[7] = rtpTime & 0xff; 633 data[8] = mSourceID >> 24; 634 data[9] = (mSourceID >> 16) & 0xff; 635 data[10] = (mSourceID >> 8) & 0xff; 636 data[11] = mSourceID & 0xff; 637 638 data[12] = 28 | (nalType & 0xe0); 639 640 CHECK(!firstPacket || !lastPacket); 641 642 data[13] = 643 (firstPacket ? 0x80 : 0x00) 644 | (lastPacket ? 0x40 : 0x00) 645 | (nalType & 0x1f); 646 647 memcpy(&data[14], &mediaData[offset], size); 648 649 buffer->setRange(0, 14 + size); 650 651 send(buffer, false /* isRTCP */); 652 653 ++mSeqNo; 654 ++mNumRTPSent; 655 mNumRTPOctetsSent += buffer->size() - 12; 656 657 firstPacket = false; 658 offset += size; 659 } 660 } 661 662 mLastRTPTime = rtpTime; 663 mLastNTPTime = GetNowNTP(); 664} 665 666void ARTPWriter::sendH263Data(MediaBuffer *mediaBuf) { 667 CHECK_GE(kMaxPacketSize, 12u + 2u); 668 669 int64_t timeUs; 670 CHECK(mediaBuf->meta_data()->findInt64(kKeyTime, &timeUs)); 671 672 uint32_t rtpTime = mRTPTimeBase + (timeUs * 9 / 100ll); 673 674 const uint8_t *mediaData = 675 (const uint8_t *)mediaBuf->data() + mediaBuf->range_offset(); 676 677 // hexdump(mediaData, mediaBuf->range_length()); 678 679 CHECK_EQ((unsigned)mediaData[0], 0u); 680 CHECK_EQ((unsigned)mediaData[1], 0u); 681 682 size_t offset = 2; 683 size_t size = mediaBuf->range_length(); 684 685 while (offset < size) { 686 sp<ABuffer> buffer = new ABuffer(kMaxPacketSize); 687 // CHECK_LE(mediaBuf->range_length() -2 + 14, buffer->capacity()); 688 689 size_t remaining = size - offset; 690 bool lastPacket = (remaining + 14 <= buffer->capacity()); 691 if (!lastPacket) { 692 remaining = buffer->capacity() - 14; 693 } 694 695 uint8_t *data = buffer->data(); 696 data[0] = 0x80; 697 data[1] = (lastPacket ? 0x80 : 0x00) | PT; // M-bit 698 data[2] = (mSeqNo >> 8) & 0xff; 699 data[3] = mSeqNo & 0xff; 700 data[4] = rtpTime >> 24; 701 data[5] = (rtpTime >> 16) & 0xff; 702 data[6] = (rtpTime >> 8) & 0xff; 703 data[7] = rtpTime & 0xff; 704 data[8] = mSourceID >> 24; 705 data[9] = (mSourceID >> 16) & 0xff; 706 data[10] = (mSourceID >> 8) & 0xff; 707 data[11] = mSourceID & 0xff; 708 709 data[12] = (offset == 2) ? 0x04 : 0x00; // P=?, V=0 710 data[13] = 0x00; // PLEN = PEBIT = 0 711 712 memcpy(&data[14], &mediaData[offset], remaining); 713 offset += remaining; 714 715 buffer->setRange(0, remaining + 14); 716 717 send(buffer, false /* isRTCP */); 718 719 ++mSeqNo; 720 ++mNumRTPSent; 721 mNumRTPOctetsSent += buffer->size() - 12; 722 } 723 724 mLastRTPTime = rtpTime; 725 mLastNTPTime = GetNowNTP(); 726} 727 728static size_t getFrameSize(bool isWide, unsigned FT) { 729 static const size_t kFrameSizeNB[8] = { 730 95, 103, 118, 134, 148, 159, 204, 244 731 }; 732 static const size_t kFrameSizeWB[9] = { 733 132, 177, 253, 285, 317, 365, 397, 461, 477 734 }; 735 736 size_t frameSize = isWide ? kFrameSizeWB[FT] : kFrameSizeNB[FT]; 737 738 // Round up bits to bytes and add 1 for the header byte. 739 frameSize = (frameSize + 7) / 8 + 1; 740 741 return frameSize; 742} 743 744void ARTPWriter::sendAMRData(MediaBuffer *mediaBuf) { 745 const uint8_t *mediaData = 746 (const uint8_t *)mediaBuf->data() + mediaBuf->range_offset(); 747 748 size_t mediaLength = mediaBuf->range_length(); 749 750 CHECK_GE(kMaxPacketSize, 12u + 1u + mediaLength); 751 752 const bool isWide = (mMode == AMR_WB); 753 754 int64_t timeUs; 755 CHECK(mediaBuf->meta_data()->findInt64(kKeyTime, &timeUs)); 756 uint32_t rtpTime = mRTPTimeBase + (timeUs / (isWide ? 250 : 125)); 757 758 // hexdump(mediaData, mediaLength); 759 760 Vector<uint8_t> tableOfContents; 761 size_t srcOffset = 0; 762 while (srcOffset < mediaLength) { 763 uint8_t toc = mediaData[srcOffset]; 764 765 unsigned FT = (toc >> 3) & 0x0f; 766 CHECK((isWide && FT <= 8) || (!isWide && FT <= 7)); 767 768 tableOfContents.push(toc); 769 srcOffset += getFrameSize(isWide, FT); 770 } 771 CHECK_EQ(srcOffset, mediaLength); 772 773 sp<ABuffer> buffer = new ABuffer(kMaxPacketSize); 774 CHECK_LE(mediaLength + 12 + 1, buffer->capacity()); 775 776 // The data fits into a single packet 777 uint8_t *data = buffer->data(); 778 data[0] = 0x80; 779 data[1] = PT; 780 if (mNumRTPSent == 0) { 781 // Signal start of talk-spurt. 782 data[1] |= 0x80; // M-bit 783 } 784 data[2] = (mSeqNo >> 8) & 0xff; 785 data[3] = mSeqNo & 0xff; 786 data[4] = rtpTime >> 24; 787 data[5] = (rtpTime >> 16) & 0xff; 788 data[6] = (rtpTime >> 8) & 0xff; 789 data[7] = rtpTime & 0xff; 790 data[8] = mSourceID >> 24; 791 data[9] = (mSourceID >> 16) & 0xff; 792 data[10] = (mSourceID >> 8) & 0xff; 793 data[11] = mSourceID & 0xff; 794 795 data[12] = 0xf0; // CMR=15, RR=0 796 797 size_t dstOffset = 13; 798 799 for (size_t i = 0; i < tableOfContents.size(); ++i) { 800 uint8_t toc = tableOfContents[i]; 801 802 if (i + 1 < tableOfContents.size()) { 803 toc |= 0x80; 804 } else { 805 toc &= ~0x80; 806 } 807 808 data[dstOffset++] = toc; 809 } 810 811 srcOffset = 0; 812 for (size_t i = 0; i < tableOfContents.size(); ++i) { 813 uint8_t toc = tableOfContents[i]; 814 unsigned FT = (toc >> 3) & 0x0f; 815 size_t frameSize = getFrameSize(isWide, FT); 816 817 ++srcOffset; // skip toc 818 memcpy(&data[dstOffset], &mediaData[srcOffset], frameSize - 1); 819 srcOffset += frameSize - 1; 820 dstOffset += frameSize - 1; 821 } 822 823 buffer->setRange(0, dstOffset); 824 825 send(buffer, false /* isRTCP */); 826 827 ++mSeqNo; 828 ++mNumRTPSent; 829 mNumRTPOctetsSent += buffer->size() - 12; 830 831 mLastRTPTime = rtpTime; 832 mLastNTPTime = GetNowNTP(); 833} 834 835} // namespace android 836 837