Home | History | Annotate | Download | only in wifi-display
      1 /*
      2  * Copyright 2013, 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 "MediaSender"
     19 #include <utils/Log.h>
     20 
     21 #include "MediaSender.h"
     22 
     23 #include "ANetworkSession.h"
     24 #include "rtp/RTPSender.h"
     25 #include "source/TSPacketizer.h"
     26 
     27 #include "include/avc_utils.h"
     28 
     29 #include <media/IHDCP.h>
     30 #include <media/stagefright/foundation/ABuffer.h>
     31 #include <media/stagefright/foundation/ADebug.h>
     32 #include <media/stagefright/foundation/AMessage.h>
     33 
     34 namespace android {
     35 
     36 MediaSender::MediaSender(
     37         const sp<ANetworkSession> &netSession,
     38         const sp<AMessage> &notify)
     39     : mNetSession(netSession),
     40       mNotify(notify),
     41       mMode(MODE_UNDEFINED),
     42       mGeneration(0),
     43       mPrevTimeUs(-1ll),
     44       mInitDoneCount(0),
     45       mLogFile(NULL) {
     46     // mLogFile = fopen("/data/misc/log.ts", "wb");
     47 }
     48 
     49 MediaSender::~MediaSender() {
     50     if (mLogFile != NULL) {
     51         fclose(mLogFile);
     52         mLogFile = NULL;
     53     }
     54 }
     55 
     56 status_t MediaSender::setHDCP(const sp<IHDCP> &hdcp) {
     57     if (mMode != MODE_UNDEFINED) {
     58         return INVALID_OPERATION;
     59     }
     60 
     61     mHDCP = hdcp;
     62 
     63     return OK;
     64 }
     65 
     66 ssize_t MediaSender::addTrack(const sp<AMessage> &format, uint32_t flags) {
     67     if (mMode != MODE_UNDEFINED) {
     68         return INVALID_OPERATION;
     69     }
     70 
     71     TrackInfo info;
     72     info.mFormat = format;
     73     info.mFlags = flags;
     74     info.mPacketizerTrackIndex = -1;
     75 
     76     AString mime;
     77     CHECK(format->findString("mime", &mime));
     78     info.mIsAudio = !strncasecmp("audio/", mime.c_str(), 6);
     79 
     80     size_t index = mTrackInfos.size();
     81     mTrackInfos.push_back(info);
     82 
     83     return index;
     84 }
     85 
     86 status_t MediaSender::initAsync(
     87         ssize_t trackIndex,
     88         const char *remoteHost,
     89         int32_t remoteRTPPort,
     90         RTPSender::TransportMode rtpMode,
     91         int32_t remoteRTCPPort,
     92         RTPSender::TransportMode rtcpMode,
     93         int32_t *localRTPPort) {
     94     if (trackIndex < 0) {
     95         if (mMode != MODE_UNDEFINED) {
     96             return INVALID_OPERATION;
     97         }
     98 
     99         uint32_t flags = 0;
    100         if (mHDCP != NULL) {
    101             // XXX Determine proper HDCP version.
    102             flags |= TSPacketizer::EMIT_HDCP20_DESCRIPTOR;
    103         }
    104         mTSPacketizer = new TSPacketizer(flags);
    105 
    106         status_t err = OK;
    107         for (size_t i = 0; i < mTrackInfos.size(); ++i) {
    108             TrackInfo *info = &mTrackInfos.editItemAt(i);
    109 
    110             ssize_t packetizerTrackIndex =
    111                 mTSPacketizer->addTrack(info->mFormat);
    112 
    113             if (packetizerTrackIndex < 0) {
    114                 err = packetizerTrackIndex;
    115                 break;
    116             }
    117 
    118             info->mPacketizerTrackIndex = packetizerTrackIndex;
    119         }
    120 
    121         if (err == OK) {
    122             sp<AMessage> notify = new AMessage(kWhatSenderNotify, id());
    123             notify->setInt32("generation", mGeneration);
    124             mTSSender = new RTPSender(mNetSession, notify);
    125             looper()->registerHandler(mTSSender);
    126 
    127             err = mTSSender->initAsync(
    128                     remoteHost,
    129                     remoteRTPPort,
    130                     rtpMode,
    131                     remoteRTCPPort,
    132                     rtcpMode,
    133                     localRTPPort);
    134 
    135             if (err != OK) {
    136                 looper()->unregisterHandler(mTSSender->id());
    137                 mTSSender.clear();
    138             }
    139         }
    140 
    141         if (err != OK) {
    142             for (size_t i = 0; i < mTrackInfos.size(); ++i) {
    143                 TrackInfo *info = &mTrackInfos.editItemAt(i);
    144                 info->mPacketizerTrackIndex = -1;
    145             }
    146 
    147             mTSPacketizer.clear();
    148             return err;
    149         }
    150 
    151         mMode = MODE_TRANSPORT_STREAM;
    152         mInitDoneCount = 1;
    153 
    154         return OK;
    155     }
    156 
    157     if (mMode == MODE_TRANSPORT_STREAM) {
    158         return INVALID_OPERATION;
    159     }
    160 
    161     if ((size_t)trackIndex >= mTrackInfos.size()) {
    162         return -ERANGE;
    163     }
    164 
    165     TrackInfo *info = &mTrackInfos.editItemAt(trackIndex);
    166 
    167     if (info->mSender != NULL) {
    168         return INVALID_OPERATION;
    169     }
    170 
    171     sp<AMessage> notify = new AMessage(kWhatSenderNotify, id());
    172     notify->setInt32("generation", mGeneration);
    173     notify->setSize("trackIndex", trackIndex);
    174 
    175     info->mSender = new RTPSender(mNetSession, notify);
    176     looper()->registerHandler(info->mSender);
    177 
    178     status_t err = info->mSender->initAsync(
    179             remoteHost,
    180             remoteRTPPort,
    181             rtpMode,
    182             remoteRTCPPort,
    183             rtcpMode,
    184             localRTPPort);
    185 
    186     if (err != OK) {
    187         looper()->unregisterHandler(info->mSender->id());
    188         info->mSender.clear();
    189 
    190         return err;
    191     }
    192 
    193     if (mMode == MODE_UNDEFINED) {
    194         mInitDoneCount = mTrackInfos.size();
    195     }
    196 
    197     mMode = MODE_ELEMENTARY_STREAMS;
    198 
    199     return OK;
    200 }
    201 
    202 status_t MediaSender::queueAccessUnit(
    203         size_t trackIndex, const sp<ABuffer> &accessUnit) {
    204     if (mMode == MODE_UNDEFINED) {
    205         return INVALID_OPERATION;
    206     }
    207 
    208     if (trackIndex >= mTrackInfos.size()) {
    209         return -ERANGE;
    210     }
    211 
    212     if (mMode == MODE_TRANSPORT_STREAM) {
    213         TrackInfo *info = &mTrackInfos.editItemAt(trackIndex);
    214         info->mAccessUnits.push_back(accessUnit);
    215 
    216         mTSPacketizer->extractCSDIfNecessary(info->mPacketizerTrackIndex);
    217 
    218         for (;;) {
    219             ssize_t minTrackIndex = -1;
    220             int64_t minTimeUs = -1ll;
    221 
    222             for (size_t i = 0; i < mTrackInfos.size(); ++i) {
    223                 const TrackInfo &info = mTrackInfos.itemAt(i);
    224 
    225                 if (info.mAccessUnits.empty()) {
    226                     minTrackIndex = -1;
    227                     minTimeUs = -1ll;
    228                     break;
    229                 }
    230 
    231                 int64_t timeUs;
    232                 const sp<ABuffer> &accessUnit = *info.mAccessUnits.begin();
    233                 CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
    234 
    235                 if (minTrackIndex < 0 || timeUs < minTimeUs) {
    236                     minTrackIndex = i;
    237                     minTimeUs = timeUs;
    238                 }
    239             }
    240 
    241             if (minTrackIndex < 0) {
    242                 return OK;
    243             }
    244 
    245             TrackInfo *info = &mTrackInfos.editItemAt(minTrackIndex);
    246             sp<ABuffer> accessUnit = *info->mAccessUnits.begin();
    247             info->mAccessUnits.erase(info->mAccessUnits.begin());
    248 
    249             sp<ABuffer> tsPackets;
    250             status_t err = packetizeAccessUnit(
    251                     minTrackIndex, accessUnit, &tsPackets);
    252 
    253             if (err == OK) {
    254                 if (mLogFile != NULL) {
    255                     fwrite(tsPackets->data(), 1, tsPackets->size(), mLogFile);
    256                 }
    257 
    258                 int64_t timeUs;
    259                 CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
    260                 tsPackets->meta()->setInt64("timeUs", timeUs);
    261 
    262                 err = mTSSender->queueBuffer(
    263                         tsPackets,
    264                         33 /* packetType */,
    265                         RTPSender::PACKETIZATION_TRANSPORT_STREAM);
    266             }
    267 
    268             if (err != OK) {
    269                 return err;
    270             }
    271         }
    272     }
    273 
    274     TrackInfo *info = &mTrackInfos.editItemAt(trackIndex);
    275 
    276     return info->mSender->queueBuffer(
    277             accessUnit,
    278             info->mIsAudio ? 96 : 97 /* packetType */,
    279             info->mIsAudio
    280                 ? RTPSender::PACKETIZATION_AAC : RTPSender::PACKETIZATION_H264);
    281 }
    282 
    283 void MediaSender::onMessageReceived(const sp<AMessage> &msg) {
    284     switch (msg->what()) {
    285         case kWhatSenderNotify:
    286         {
    287             int32_t generation;
    288             CHECK(msg->findInt32("generation", &generation));
    289             if (generation != mGeneration) {
    290                 break;
    291             }
    292 
    293             onSenderNotify(msg);
    294             break;
    295         }
    296 
    297         default:
    298             TRESPASS();
    299     }
    300 }
    301 
    302 void MediaSender::onSenderNotify(const sp<AMessage> &msg) {
    303     int32_t what;
    304     CHECK(msg->findInt32("what", &what));
    305 
    306     switch (what) {
    307         case RTPSender::kWhatInitDone:
    308         {
    309             --mInitDoneCount;
    310 
    311             int32_t err;
    312             CHECK(msg->findInt32("err", &err));
    313 
    314             if (err != OK) {
    315                 notifyInitDone(err);
    316                 ++mGeneration;
    317                 break;
    318             }
    319 
    320             if (mInitDoneCount == 0) {
    321                 notifyInitDone(OK);
    322             }
    323             break;
    324         }
    325 
    326         case RTPSender::kWhatError:
    327         {
    328             int32_t err;
    329             CHECK(msg->findInt32("err", &err));
    330 
    331             notifyError(err);
    332             break;
    333         }
    334 
    335         case kWhatNetworkStall:
    336         {
    337             size_t numBytesQueued;
    338             CHECK(msg->findSize("numBytesQueued", &numBytesQueued));
    339 
    340             notifyNetworkStall(numBytesQueued);
    341             break;
    342         }
    343 
    344         default:
    345             TRESPASS();
    346     }
    347 }
    348 
    349 void MediaSender::notifyInitDone(status_t err) {
    350     sp<AMessage> notify = mNotify->dup();
    351     notify->setInt32("what", kWhatInitDone);
    352     notify->setInt32("err", err);
    353     notify->post();
    354 }
    355 
    356 void MediaSender::notifyError(status_t err) {
    357     sp<AMessage> notify = mNotify->dup();
    358     notify->setInt32("what", kWhatError);
    359     notify->setInt32("err", err);
    360     notify->post();
    361 }
    362 
    363 void MediaSender::notifyNetworkStall(size_t numBytesQueued) {
    364     sp<AMessage> notify = mNotify->dup();
    365     notify->setInt32("what", kWhatNetworkStall);
    366     notify->setSize("numBytesQueued", numBytesQueued);
    367     notify->post();
    368 }
    369 
    370 status_t MediaSender::packetizeAccessUnit(
    371         size_t trackIndex,
    372         sp<ABuffer> accessUnit,
    373         sp<ABuffer> *tsPackets) {
    374     const TrackInfo &info = mTrackInfos.itemAt(trackIndex);
    375 
    376     uint32_t flags = 0;
    377 
    378     bool isHDCPEncrypted = false;
    379     uint64_t inputCTR;
    380     uint8_t HDCP_private_data[16];
    381 
    382     bool manuallyPrependSPSPPS =
    383         !info.mIsAudio
    384         && (info.mFlags & FLAG_MANUALLY_PREPEND_SPS_PPS)
    385         && IsIDR(accessUnit);
    386 
    387     if (mHDCP != NULL && !info.mIsAudio) {
    388         isHDCPEncrypted = true;
    389 
    390         if (manuallyPrependSPSPPS) {
    391             accessUnit = mTSPacketizer->prependCSD(
    392                     info.mPacketizerTrackIndex, accessUnit);
    393         }
    394 
    395         status_t err = mHDCP->encrypt(
    396                 accessUnit->data(), accessUnit->size(),
    397                 trackIndex  /* streamCTR */,
    398                 &inputCTR,
    399                 accessUnit->data());
    400 
    401         if (err != OK) {
    402             ALOGE("Failed to HDCP-encrypt media data (err %d)",
    403                   err);
    404 
    405             return err;
    406         }
    407 
    408         HDCP_private_data[0] = 0x00;
    409 
    410         HDCP_private_data[1] =
    411             (((trackIndex >> 30) & 3) << 1) | 1;
    412 
    413         HDCP_private_data[2] = (trackIndex >> 22) & 0xff;
    414 
    415         HDCP_private_data[3] =
    416             (((trackIndex >> 15) & 0x7f) << 1) | 1;
    417 
    418         HDCP_private_data[4] = (trackIndex >> 7) & 0xff;
    419 
    420         HDCP_private_data[5] =
    421             ((trackIndex & 0x7f) << 1) | 1;
    422 
    423         HDCP_private_data[6] = 0x00;
    424 
    425         HDCP_private_data[7] =
    426             (((inputCTR >> 60) & 0x0f) << 1) | 1;
    427 
    428         HDCP_private_data[8] = (inputCTR >> 52) & 0xff;
    429 
    430         HDCP_private_data[9] =
    431             (((inputCTR >> 45) & 0x7f) << 1) | 1;
    432 
    433         HDCP_private_data[10] = (inputCTR >> 37) & 0xff;
    434 
    435         HDCP_private_data[11] =
    436             (((inputCTR >> 30) & 0x7f) << 1) | 1;
    437 
    438         HDCP_private_data[12] = (inputCTR >> 22) & 0xff;
    439 
    440         HDCP_private_data[13] =
    441             (((inputCTR >> 15) & 0x7f) << 1) | 1;
    442 
    443         HDCP_private_data[14] = (inputCTR >> 7) & 0xff;
    444 
    445         HDCP_private_data[15] =
    446             ((inputCTR & 0x7f) << 1) | 1;
    447 
    448         flags |= TSPacketizer::IS_ENCRYPTED;
    449     } else if (manuallyPrependSPSPPS) {
    450         flags |= TSPacketizer::PREPEND_SPS_PPS_TO_IDR_FRAMES;
    451     }
    452 
    453     int64_t timeUs = ALooper::GetNowUs();
    454     if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll <= timeUs) {
    455         flags |= TSPacketizer::EMIT_PCR;
    456         flags |= TSPacketizer::EMIT_PAT_AND_PMT;
    457 
    458         mPrevTimeUs = timeUs;
    459     }
    460 
    461     mTSPacketizer->packetize(
    462             info.mPacketizerTrackIndex,
    463             accessUnit,
    464             tsPackets,
    465             flags,
    466             !isHDCPEncrypted ? NULL : HDCP_private_data,
    467             !isHDCPEncrypted ? 0 : sizeof(HDCP_private_data),
    468             info.mIsAudio ? 2 : 0 /* numStuffingBytes */);
    469 
    470     return OK;
    471 }
    472 
    473 }  // namespace android
    474 
    475