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