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/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
UniformRand(int limit)43 static int UniformRand(int limit) {
44 return ((double)rand() * limit) / RAND_MAX;
45 }
46
ARTPWriter(int fd)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
~ARTPWriter()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
addSource(const sp<MediaSource> & source)107 status_t ARTPWriter::addSource(const sp<MediaSource> &source) {
108 mSource = source;
109 return OK;
110 }
111
reachedEOS()112 bool ARTPWriter::reachedEOS() {
113 Mutex::Autolock autoLock(mLock);
114 return (mFlags & kFlagEOS) != 0;
115 }
116
start(MetaData *)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
stop()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
pause()172 status_t ARTPWriter::pause() {
173 return OK;
174 }
175
StripStartcode(MediaBufferBase * buffer)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
onMessageReceived(const sp<AMessage> & msg)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
onRead(const sp<AMessage> & msg)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
onSendSR(const sp<AMessage> & msg)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
send(const sp<ABuffer> & buffer,bool isRTCP)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
addSR(const sp<ABuffer> & buffer)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
addSDES(const sp<ABuffer> & buffer)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
GetNowNTP()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
dumpSessionDesc()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
makeH264SPropParamSets(MediaBufferBase * buffer)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
sendBye()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
sendAVCData(MediaBufferBase * mediaBuf)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
sendH263Data(MediaBufferBase * mediaBuf)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
getFrameSize(bool isWide,unsigned FT)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
sendAMRData(MediaBufferBase * mediaBuf)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