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