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