Home | History | Annotate | Download | only in rtsp
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "ARTPWriter"
     19 #include <utils/Log.h>
     20 
     21 #include "ARTPWriter.h"
     22 
     23 #include <fcntl.h>
     24 
     25 #include <media/MediaSource.h>
     26 #include <media/stagefright/foundation/ABuffer.h>
     27 #include <media/stagefright/foundation/ADebug.h>
     28 #include <media/stagefright/foundation/AMessage.h>
     29 #include <media/stagefright/foundation/hexdump.h>
     30 #include <media/stagefright/MediaBuffer.h>
     31 #include <media/stagefright/MediaDefs.h>
     32 #include <media/stagefright/MetaData.h>
     33 #include <utils/ByteOrder.h>
     34 
     35 #define PT      97
     36 #define PT_STR  "97"
     37 
     38 namespace android {
     39 
     40 // static const size_t kMaxPacketSize = 65507;  // maximum payload in UDP over IP
     41 static const size_t kMaxPacketSize = 1500;
     42 
     43 static int UniformRand(int limit) {
     44     return ((double)rand() * limit) / RAND_MAX;
     45 }
     46 
     47 ARTPWriter::ARTPWriter(int fd)
     48     : mFlags(0),
     49       mFd(dup(fd)),
     50       mLooper(new ALooper),
     51       mReflector(new AHandlerReflector<ARTPWriter>(this)) {
     52     CHECK_GE(fd, 0);
     53 
     54     mLooper->setName("rtp writer");
     55     mLooper->registerHandler(mReflector);
     56     mLooper->start();
     57 
     58     mSocket = socket(AF_INET, SOCK_DGRAM, 0);
     59     CHECK_GE(mSocket, 0);
     60 
     61     memset(mRTPAddr.sin_zero, 0, sizeof(mRTPAddr.sin_zero));
     62     mRTPAddr.sin_family = AF_INET;
     63 
     64 #if 1
     65     mRTPAddr.sin_addr.s_addr = INADDR_ANY;
     66 #else
     67     mRTPAddr.sin_addr.s_addr = inet_addr("172.19.18.246");
     68 #endif
     69 
     70     mRTPAddr.sin_port = htons(5634);
     71     CHECK_EQ(0, ntohs(mRTPAddr.sin_port) & 1);
     72 
     73     mRTCPAddr = mRTPAddr;
     74     mRTCPAddr.sin_port = htons(ntohs(mRTPAddr.sin_port) | 1);
     75 
     76 #if LOG_TO_FILES
     77     mRTPFd = open(
     78             "/data/misc/rtpout.bin",
     79             O_WRONLY | O_CREAT | O_TRUNC,
     80             0644);
     81     CHECK_GE(mRTPFd, 0);
     82 
     83     mRTCPFd = open(
     84             "/data/misc/rtcpout.bin",
     85             O_WRONLY | O_CREAT | O_TRUNC,
     86             0644);
     87     CHECK_GE(mRTCPFd, 0);
     88 #endif
     89 }
     90 
     91 ARTPWriter::~ARTPWriter() {
     92 #if LOG_TO_FILES
     93     close(mRTCPFd);
     94     mRTCPFd = -1;
     95 
     96     close(mRTPFd);
     97     mRTPFd = -1;
     98 #endif
     99 
    100     close(mSocket);
    101     mSocket = -1;
    102 
    103     close(mFd);
    104     mFd = -1;
    105 }
    106 
    107 status_t ARTPWriter::addSource(const sp<MediaSource> &source) {
    108     mSource = source;
    109     return OK;
    110 }
    111 
    112 bool ARTPWriter::reachedEOS() {
    113     Mutex::Autolock autoLock(mLock);
    114     return (mFlags & kFlagEOS) != 0;
    115 }
    116 
    117 status_t ARTPWriter::start(MetaData * /* params */) {
    118     Mutex::Autolock autoLock(mLock);
    119     if (mFlags & kFlagStarted) {
    120         return INVALID_OPERATION;
    121     }
    122 
    123     mFlags &= ~kFlagEOS;
    124     mSourceID = rand();
    125     mSeqNo = UniformRand(65536);
    126     mRTPTimeBase = rand();
    127     mNumRTPSent = 0;
    128     mNumRTPOctetsSent = 0;
    129     mLastRTPTime = 0;
    130     mLastNTPTime = 0;
    131     mNumSRsSent = 0;
    132 
    133     const char *mime;
    134     CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime));
    135 
    136     mMode = INVALID;
    137     if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
    138         mMode = H264;
    139     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_H263)) {
    140         mMode = H263;
    141     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
    142         mMode = AMR_NB;
    143     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
    144         mMode = AMR_WB;
    145     } else {
    146         TRESPASS();
    147     }
    148 
    149     (new AMessage(kWhatStart, mReflector))->post();
    150 
    151     while (!(mFlags & kFlagStarted)) {
    152         mCondition.wait(mLock);
    153     }
    154 
    155     return OK;
    156 }
    157 
    158 status_t ARTPWriter::stop() {
    159     Mutex::Autolock autoLock(mLock);
    160     if (!(mFlags & kFlagStarted)) {
    161         return OK;
    162     }
    163 
    164     (new AMessage(kWhatStop, mReflector))->post();
    165 
    166     while (mFlags & kFlagStarted) {
    167         mCondition.wait(mLock);
    168     }
    169     return OK;
    170 }
    171 
    172 status_t ARTPWriter::pause() {
    173     return OK;
    174 }
    175 
    176 static void StripStartcode(MediaBufferBase *buffer) {
    177     if (buffer->range_length() < 4) {
    178         return;
    179     }
    180 
    181     const uint8_t *ptr =
    182         (const uint8_t *)buffer->data() + buffer->range_offset();
    183 
    184     if (!memcmp(ptr, "\x00\x00\x00\x01", 4)) {
    185         buffer->set_range(
    186                 buffer->range_offset() + 4, buffer->range_length() - 4);
    187     }
    188 }
    189 
    190 void ARTPWriter::onMessageReceived(const sp<AMessage> &msg) {
    191     switch (msg->what()) {
    192         case kWhatStart:
    193         {
    194             CHECK_EQ(mSource->start(), (status_t)OK);
    195 
    196 #if 0
    197             if (mMode == H264) {
    198                 MediaBufferBase *buffer;
    199                 CHECK_EQ(mSource->read(&buffer), (status_t)OK);
    200 
    201                 StripStartcode(buffer);
    202                 makeH264SPropParamSets(buffer);
    203                 buffer->release();
    204                 buffer = NULL;
    205             }
    206 
    207             dumpSessionDesc();
    208 #endif
    209 
    210             {
    211                 Mutex::Autolock autoLock(mLock);
    212                 mFlags |= kFlagStarted;
    213                 mCondition.signal();
    214             }
    215 
    216             (new AMessage(kWhatRead, mReflector))->post();
    217             (new AMessage(kWhatSendSR, mReflector))->post();
    218             break;
    219         }
    220 
    221         case kWhatStop:
    222         {
    223             CHECK_EQ(mSource->stop(), (status_t)OK);
    224 
    225             sendBye();
    226 
    227             {
    228                 Mutex::Autolock autoLock(mLock);
    229                 mFlags &= ~kFlagStarted;
    230                 mCondition.signal();
    231             }
    232             break;
    233         }
    234 
    235         case kWhatRead:
    236         {
    237             {
    238                 Mutex::Autolock autoLock(mLock);
    239                 if (!(mFlags & kFlagStarted)) {
    240                     break;
    241                 }
    242             }
    243 
    244             onRead(msg);
    245             break;
    246         }
    247 
    248         case kWhatSendSR:
    249         {
    250             {
    251                 Mutex::Autolock autoLock(mLock);
    252                 if (!(mFlags & kFlagStarted)) {
    253                     break;
    254                 }
    255             }
    256 
    257             onSendSR(msg);
    258             break;
    259         }
    260 
    261         default:
    262             TRESPASS();
    263             break;
    264     }
    265 }
    266 
    267 void ARTPWriter::onRead(const sp<AMessage> &msg) {
    268     MediaBufferBase *mediaBuf;
    269     status_t err = mSource->read(&mediaBuf);
    270 
    271     if (err != OK) {
    272         ALOGI("reached EOS.");
    273 
    274         Mutex::Autolock autoLock(mLock);
    275         mFlags |= kFlagEOS;
    276         return;
    277     }
    278 
    279     if (mediaBuf->range_length() > 0) {
    280         ALOGV("read buffer of size %zu", mediaBuf->range_length());
    281 
    282         if (mMode == H264) {
    283             StripStartcode(mediaBuf);
    284             sendAVCData(mediaBuf);
    285         } else if (mMode == H263) {
    286             sendH263Data(mediaBuf);
    287         } else if (mMode == AMR_NB || mMode == AMR_WB) {
    288             sendAMRData(mediaBuf);
    289         }
    290     }
    291 
    292     mediaBuf->release();
    293     mediaBuf = NULL;
    294 
    295     msg->post();
    296 }
    297 
    298 void ARTPWriter::onSendSR(const sp<AMessage> &msg) {
    299     sp<ABuffer> buffer = new ABuffer(65536);
    300     buffer->setRange(0, 0);
    301 
    302     addSR(buffer);
    303     addSDES(buffer);
    304 
    305     send(buffer, true /* isRTCP */);
    306 
    307     ++mNumSRsSent;
    308     msg->post(3000000);
    309 }
    310 
    311 void ARTPWriter::send(const sp<ABuffer> &buffer, bool isRTCP) {
    312     ssize_t n = sendto(
    313             mSocket, buffer->data(), buffer->size(), 0,
    314             (const struct sockaddr *)(isRTCP ? &mRTCPAddr : &mRTPAddr),
    315             sizeof(mRTCPAddr));
    316 
    317     CHECK_EQ(n, (ssize_t)buffer->size());
    318 
    319 #if LOG_TO_FILES
    320     int fd = isRTCP ? mRTCPFd : mRTPFd;
    321 
    322     uint32_t ms = tolel(ALooper::GetNowUs() / 1000ll);
    323     uint32_t length = tolel(buffer->size());
    324     write(fd, &ms, sizeof(ms));
    325     write(fd, &length, sizeof(length));
    326     write(fd, buffer->data(), buffer->size());
    327 #endif
    328 }
    329 
    330 void ARTPWriter::addSR(const sp<ABuffer> &buffer) {
    331     uint8_t *data = buffer->data() + buffer->size();
    332 
    333     data[0] = 0x80 | 0;
    334     data[1] = 200;  // SR
    335     data[2] = 0;
    336     data[3] = 6;
    337     data[4] = mSourceID >> 24;
    338     data[5] = (mSourceID >> 16) & 0xff;
    339     data[6] = (mSourceID >> 8) & 0xff;
    340     data[7] = mSourceID & 0xff;
    341 
    342     data[8] = mLastNTPTime >> (64 - 8);
    343     data[9] = (mLastNTPTime >> (64 - 16)) & 0xff;
    344     data[10] = (mLastNTPTime >> (64 - 24)) & 0xff;
    345     data[11] = (mLastNTPTime >> 32) & 0xff;
    346     data[12] = (mLastNTPTime >> 24) & 0xff;
    347     data[13] = (mLastNTPTime >> 16) & 0xff;
    348     data[14] = (mLastNTPTime >> 8) & 0xff;
    349     data[15] = mLastNTPTime & 0xff;
    350 
    351     data[16] = (mLastRTPTime >> 24) & 0xff;
    352     data[17] = (mLastRTPTime >> 16) & 0xff;
    353     data[18] = (mLastRTPTime >> 8) & 0xff;
    354     data[19] = mLastRTPTime & 0xff;
    355 
    356     data[20] = mNumRTPSent >> 24;
    357     data[21] = (mNumRTPSent >> 16) & 0xff;
    358     data[22] = (mNumRTPSent >> 8) & 0xff;
    359     data[23] = mNumRTPSent & 0xff;
    360 
    361     data[24] = mNumRTPOctetsSent >> 24;
    362     data[25] = (mNumRTPOctetsSent >> 16) & 0xff;
    363     data[26] = (mNumRTPOctetsSent >> 8) & 0xff;
    364     data[27] = mNumRTPOctetsSent & 0xff;
    365 
    366     buffer->setRange(buffer->offset(), buffer->size() + 28);
    367 }
    368 
    369 void ARTPWriter::addSDES(const sp<ABuffer> &buffer) {
    370     uint8_t *data = buffer->data() + buffer->size();
    371     data[0] = 0x80 | 1;
    372     data[1] = 202;  // SDES
    373     data[4] = mSourceID >> 24;
    374     data[5] = (mSourceID >> 16) & 0xff;
    375     data[6] = (mSourceID >> 8) & 0xff;
    376     data[7] = mSourceID & 0xff;
    377 
    378     size_t offset = 8;
    379 
    380     data[offset++] = 1;  // CNAME
    381 
    382     static const char *kCNAME = "someone@somewhere";
    383     data[offset++] = strlen(kCNAME);
    384 
    385     memcpy(&data[offset], kCNAME, strlen(kCNAME));
    386     offset += strlen(kCNAME);
    387 
    388     data[offset++] = 7;  // NOTE
    389 
    390     static const char *kNOTE = "Hell's frozen over.";
    391     data[offset++] = strlen(kNOTE);
    392 
    393     memcpy(&data[offset], kNOTE, strlen(kNOTE));
    394     offset += strlen(kNOTE);
    395 
    396     data[offset++] = 0;
    397 
    398     if ((offset % 4) > 0) {
    399         size_t count = 4 - (offset % 4);
    400         switch (count) {
    401             case 3:
    402                 data[offset++] = 0;
    403             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
    418 uint64_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 
    429 void 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(AStringPrintf("%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(AStringPrintf("/%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 
    526 void ARTPWriter::makeH264SPropParamSets(MediaBufferBase *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         AStringPrintf("%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 
    554 void 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 
    570 void ARTPWriter::sendAVCData(MediaBufferBase *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 
    666 void ARTPWriter::sendH263Data(MediaBufferBase *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 
    728 static 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 
    744 void ARTPWriter::sendAMRData(MediaBufferBase *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