Home | History | Annotate | Download | only in source
      1 /*
      2  * Copyright 2012, 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 "PlaybackSession"
     19 #include <utils/Log.h>
     20 
     21 #include "PlaybackSession.h"
     22 
     23 #include "Converter.h"
     24 #include "MediaPuller.h"
     25 #include "RepeaterSource.h"
     26 #include "Sender.h"
     27 #include "TSPacketizer.h"
     28 #include "include/avc_utils.h"
     29 
     30 #include <binder/IServiceManager.h>
     31 #include <gui/ISurfaceComposer.h>
     32 #include <gui/SurfaceComposerClient.h>
     33 #include <media/IHDCP.h>
     34 #include <media/stagefright/foundation/ABitReader.h>
     35 #include <media/stagefright/foundation/ABuffer.h>
     36 #include <media/stagefright/foundation/ADebug.h>
     37 #include <media/stagefright/foundation/AMessage.h>
     38 #include <media/stagefright/foundation/hexdump.h>
     39 #include <media/stagefright/AudioSource.h>
     40 #include <media/stagefright/DataSource.h>
     41 #include <media/stagefright/MediaDefs.h>
     42 #include <media/stagefright/MediaErrors.h>
     43 #include <media/stagefright/MediaExtractor.h>
     44 #include <media/stagefright/MediaSource.h>
     45 #include <media/stagefright/MetaData.h>
     46 #include <media/stagefright/MPEG2TSWriter.h>
     47 #include <media/stagefright/SurfaceMediaSource.h>
     48 #include <media/stagefright/Utils.h>
     49 
     50 #include <OMX_IVCommon.h>
     51 
     52 namespace android {
     53 
     54 struct WifiDisplaySource::PlaybackSession::Track : public AHandler {
     55     enum {
     56         kWhatStopped,
     57     };
     58 
     59     Track(const sp<AMessage> &notify,
     60           const sp<ALooper> &pullLooper,
     61           const sp<ALooper> &codecLooper,
     62           const sp<MediaPuller> &mediaPuller,
     63           const sp<Converter> &converter);
     64 
     65     void setRepeaterSource(const sp<RepeaterSource> &source);
     66 
     67     sp<AMessage> getFormat();
     68     bool isAudio() const;
     69 
     70     const sp<Converter> &converter() const;
     71     ssize_t packetizerTrackIndex() const;
     72 
     73     void setPacketizerTrackIndex(size_t index);
     74 
     75     status_t start();
     76     void stopAsync();
     77 
     78     void queueAccessUnit(const sp<ABuffer> &accessUnit);
     79     sp<ABuffer> dequeueAccessUnit();
     80 
     81     bool hasOutputBuffer(int64_t *timeUs) const;
     82     void queueOutputBuffer(const sp<ABuffer> &accessUnit);
     83     sp<ABuffer> dequeueOutputBuffer();
     84     bool isSuspended() const;
     85 
     86     size_t countQueuedOutputBuffers() const {
     87         return mQueuedOutputBuffers.size();
     88     }
     89 
     90     void requestIDRFrame();
     91 
     92 protected:
     93     virtual void onMessageReceived(const sp<AMessage> &msg);
     94     virtual ~Track();
     95 
     96 private:
     97     enum {
     98         kWhatMediaPullerStopped,
     99     };
    100 
    101     sp<AMessage> mNotify;
    102     sp<ALooper> mPullLooper;
    103     sp<ALooper> mCodecLooper;
    104     sp<MediaPuller> mMediaPuller;
    105     sp<Converter> mConverter;
    106     bool mStarted;
    107     ssize_t mPacketizerTrackIndex;
    108     bool mIsAudio;
    109     List<sp<ABuffer> > mQueuedAccessUnits;
    110     sp<RepeaterSource> mRepeaterSource;
    111     List<sp<ABuffer> > mQueuedOutputBuffers;
    112     int64_t mLastOutputBufferQueuedTimeUs;
    113 
    114     static bool IsAudioFormat(const sp<AMessage> &format);
    115 
    116     DISALLOW_EVIL_CONSTRUCTORS(Track);
    117 };
    118 
    119 WifiDisplaySource::PlaybackSession::Track::Track(
    120         const sp<AMessage> &notify,
    121         const sp<ALooper> &pullLooper,
    122         const sp<ALooper> &codecLooper,
    123         const sp<MediaPuller> &mediaPuller,
    124         const sp<Converter> &converter)
    125     : mNotify(notify),
    126       mPullLooper(pullLooper),
    127       mCodecLooper(codecLooper),
    128       mMediaPuller(mediaPuller),
    129       mConverter(converter),
    130       mStarted(false),
    131       mPacketizerTrackIndex(-1),
    132       mIsAudio(IsAudioFormat(mConverter->getOutputFormat())),
    133       mLastOutputBufferQueuedTimeUs(-1ll) {
    134 }
    135 
    136 WifiDisplaySource::PlaybackSession::Track::~Track() {
    137     CHECK(!mStarted);
    138 }
    139 
    140 // static
    141 bool WifiDisplaySource::PlaybackSession::Track::IsAudioFormat(
    142         const sp<AMessage> &format) {
    143     AString mime;
    144     CHECK(format->findString("mime", &mime));
    145 
    146     return !strncasecmp(mime.c_str(), "audio/", 6);
    147 }
    148 
    149 sp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() {
    150     return mConverter->getOutputFormat();
    151 }
    152 
    153 bool WifiDisplaySource::PlaybackSession::Track::isAudio() const {
    154     return mIsAudio;
    155 }
    156 
    157 const sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() const {
    158     return mConverter;
    159 }
    160 
    161 ssize_t WifiDisplaySource::PlaybackSession::Track::packetizerTrackIndex() const {
    162     return mPacketizerTrackIndex;
    163 }
    164 
    165 void WifiDisplaySource::PlaybackSession::Track::setPacketizerTrackIndex(size_t index) {
    166     CHECK_LT(mPacketizerTrackIndex, 0);
    167     mPacketizerTrackIndex = index;
    168 }
    169 
    170 status_t WifiDisplaySource::PlaybackSession::Track::start() {
    171     ALOGV("Track::start isAudio=%d", mIsAudio);
    172 
    173     CHECK(!mStarted);
    174 
    175     status_t err = OK;
    176 
    177     if (mMediaPuller != NULL) {
    178         err = mMediaPuller->start();
    179     }
    180 
    181     if (err == OK) {
    182         mStarted = true;
    183     }
    184 
    185     return err;
    186 }
    187 
    188 void WifiDisplaySource::PlaybackSession::Track::stopAsync() {
    189     ALOGV("Track::stopAsync isAudio=%d", mIsAudio);
    190 
    191     mConverter->shutdownAsync();
    192 
    193     sp<AMessage> msg = new AMessage(kWhatMediaPullerStopped, id());
    194 
    195     if (mStarted && mMediaPuller != NULL) {
    196         if (mRepeaterSource != NULL) {
    197             // Let's unblock MediaPuller's MediaSource::read().
    198             mRepeaterSource->wakeUp();
    199         }
    200 
    201         mMediaPuller->stopAsync(msg);
    202     } else {
    203         msg->post();
    204     }
    205 }
    206 
    207 void WifiDisplaySource::PlaybackSession::Track::onMessageReceived(
    208         const sp<AMessage> &msg) {
    209     switch (msg->what()) {
    210         case kWhatMediaPullerStopped:
    211         {
    212             mConverter.clear();
    213 
    214             mStarted = false;
    215 
    216             sp<AMessage> notify = mNotify->dup();
    217             notify->setInt32("what", kWhatStopped);
    218             notify->post();
    219 
    220             ALOGI("kWhatStopped %s posted", mIsAudio ? "audio" : "video");
    221             break;
    222         }
    223 
    224         default:
    225             TRESPASS();
    226     }
    227 }
    228 
    229 void WifiDisplaySource::PlaybackSession::Track::queueAccessUnit(
    230         const sp<ABuffer> &accessUnit) {
    231     mQueuedAccessUnits.push_back(accessUnit);
    232 }
    233 
    234 sp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueAccessUnit() {
    235     if (mQueuedAccessUnits.empty()) {
    236         return NULL;
    237     }
    238 
    239     sp<ABuffer> accessUnit = *mQueuedAccessUnits.begin();
    240     CHECK(accessUnit != NULL);
    241 
    242     mQueuedAccessUnits.erase(mQueuedAccessUnits.begin());
    243 
    244     return accessUnit;
    245 }
    246 
    247 void WifiDisplaySource::PlaybackSession::Track::setRepeaterSource(
    248         const sp<RepeaterSource> &source) {
    249     mRepeaterSource = source;
    250 }
    251 
    252 void WifiDisplaySource::PlaybackSession::Track::requestIDRFrame() {
    253     if (mIsAudio) {
    254         return;
    255     }
    256 
    257     if (mRepeaterSource != NULL) {
    258         mRepeaterSource->wakeUp();
    259     }
    260 
    261     mConverter->requestIDRFrame();
    262 }
    263 
    264 bool WifiDisplaySource::PlaybackSession::Track::hasOutputBuffer(
    265         int64_t *timeUs) const {
    266     *timeUs = 0ll;
    267 
    268     if (mQueuedOutputBuffers.empty()) {
    269         return false;
    270     }
    271 
    272     const sp<ABuffer> &outputBuffer = *mQueuedOutputBuffers.begin();
    273 
    274     CHECK(outputBuffer->meta()->findInt64("timeUs", timeUs));
    275 
    276     return true;
    277 }
    278 
    279 void WifiDisplaySource::PlaybackSession::Track::queueOutputBuffer(
    280         const sp<ABuffer> &accessUnit) {
    281     mQueuedOutputBuffers.push_back(accessUnit);
    282 
    283     mLastOutputBufferQueuedTimeUs = ALooper::GetNowUs();
    284 }
    285 
    286 sp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueOutputBuffer() {
    287     CHECK(!mQueuedOutputBuffers.empty());
    288 
    289     sp<ABuffer> outputBuffer = *mQueuedOutputBuffers.begin();
    290     mQueuedOutputBuffers.erase(mQueuedOutputBuffers.begin());
    291 
    292     return outputBuffer;
    293 }
    294 
    295 bool WifiDisplaySource::PlaybackSession::Track::isSuspended() const {
    296     if (!mQueuedOutputBuffers.empty()) {
    297         return false;
    298     }
    299 
    300     if (mLastOutputBufferQueuedTimeUs < 0ll) {
    301         // We've never seen an output buffer queued, but tracks start
    302         // out live, not suspended.
    303         return false;
    304     }
    305 
    306     // If we've not seen new output data for 60ms or more, we consider
    307     // this track suspended for the time being.
    308     return (ALooper::GetNowUs() - mLastOutputBufferQueuedTimeUs) > 60000ll;
    309 }
    310 
    311 ////////////////////////////////////////////////////////////////////////////////
    312 
    313 WifiDisplaySource::PlaybackSession::PlaybackSession(
    314         const sp<ANetworkSession> &netSession,
    315         const sp<AMessage> &notify,
    316         const in_addr &interfaceAddr,
    317         const sp<IHDCP> &hdcp)
    318     : mNetSession(netSession),
    319       mNotify(notify),
    320       mInterfaceAddr(interfaceAddr),
    321       mHDCP(hdcp),
    322       mWeAreDead(false),
    323       mLastLifesignUs(),
    324       mVideoTrackIndex(-1),
    325       mPrevTimeUs(-1ll),
    326       mAllTracksHavePacketizerIndex(false) {
    327 }
    328 
    329 status_t WifiDisplaySource::PlaybackSession::init(
    330         const char *clientIP, int32_t clientRtp, int32_t clientRtcp,
    331         Sender::TransportMode transportMode,
    332         bool usePCMAudio) {
    333     status_t err = setupPacketizer(usePCMAudio);
    334 
    335     if (err != OK) {
    336         return err;
    337     }
    338 
    339     sp<AMessage> notify = new AMessage(kWhatSenderNotify, id());
    340     mSender = new Sender(mNetSession, notify);
    341 
    342     mSenderLooper = new ALooper;
    343     mSenderLooper->setName("sender_looper");
    344 
    345     mSenderLooper->start(
    346             false /* runOnCallingThread */,
    347             false /* canCallJava */,
    348             PRIORITY_AUDIO);
    349 
    350     mSenderLooper->registerHandler(mSender);
    351 
    352     err = mSender->init(clientIP, clientRtp, clientRtcp, transportMode);
    353 
    354     if (err != OK) {
    355         return err;
    356     }
    357 
    358     updateLiveness();
    359 
    360     return OK;
    361 }
    362 
    363 WifiDisplaySource::PlaybackSession::~PlaybackSession() {
    364 }
    365 
    366 int32_t WifiDisplaySource::PlaybackSession::getRTPPort() const {
    367     return mSender->getRTPPort();
    368 }
    369 
    370 int64_t WifiDisplaySource::PlaybackSession::getLastLifesignUs() const {
    371     return mLastLifesignUs;
    372 }
    373 
    374 void WifiDisplaySource::PlaybackSession::updateLiveness() {
    375     mLastLifesignUs = ALooper::GetNowUs();
    376 }
    377 
    378 status_t WifiDisplaySource::PlaybackSession::play() {
    379     updateLiveness();
    380 
    381     return OK;
    382 }
    383 
    384 status_t WifiDisplaySource::PlaybackSession::finishPlay() {
    385     // XXX Give the dongle a second to bind its sockets.
    386     (new AMessage(kWhatFinishPlay, id()))->post(1000000ll);
    387     return OK;
    388 }
    389 
    390 status_t WifiDisplaySource::PlaybackSession::onFinishPlay() {
    391     return mSender->finishInit();
    392 }
    393 
    394 status_t WifiDisplaySource::PlaybackSession::onFinishPlay2() {
    395     mSender->scheduleSendSR();
    396 
    397     for (size_t i = 0; i < mTracks.size(); ++i) {
    398         CHECK_EQ((status_t)OK, mTracks.editValueAt(i)->start());
    399     }
    400 
    401     sp<AMessage> notify = mNotify->dup();
    402     notify->setInt32("what", kWhatSessionEstablished);
    403     notify->post();
    404 
    405     return OK;
    406 }
    407 
    408 status_t WifiDisplaySource::PlaybackSession::pause() {
    409     updateLiveness();
    410 
    411     return OK;
    412 }
    413 
    414 void WifiDisplaySource::PlaybackSession::destroyAsync() {
    415     ALOGI("destroyAsync");
    416 
    417     for (size_t i = 0; i < mTracks.size(); ++i) {
    418         mTracks.valueAt(i)->stopAsync();
    419     }
    420 }
    421 
    422 void WifiDisplaySource::PlaybackSession::onMessageReceived(
    423         const sp<AMessage> &msg) {
    424     switch (msg->what()) {
    425         case kWhatConverterNotify:
    426         {
    427             if (mWeAreDead) {
    428                 ALOGV("dropping msg '%s' because we're dead",
    429                       msg->debugString().c_str());
    430 
    431                 break;
    432             }
    433 
    434             int32_t what;
    435             CHECK(msg->findInt32("what", &what));
    436 
    437             size_t trackIndex;
    438             CHECK(msg->findSize("trackIndex", &trackIndex));
    439 
    440             if (what == Converter::kWhatAccessUnit) {
    441                 const sp<Track> &track = mTracks.valueFor(trackIndex);
    442 
    443                 ssize_t packetizerTrackIndex = track->packetizerTrackIndex();
    444 
    445                 if (packetizerTrackIndex < 0) {
    446                     packetizerTrackIndex =
    447                         mPacketizer->addTrack(track->getFormat());
    448 
    449                     CHECK_GE(packetizerTrackIndex, 0);
    450 
    451                     track->setPacketizerTrackIndex(packetizerTrackIndex);
    452 
    453                     if (allTracksHavePacketizerIndex()) {
    454                         status_t err = packetizeQueuedAccessUnits();
    455 
    456                         if (err != OK) {
    457                             notifySessionDead();
    458                             break;
    459                         }
    460                     }
    461                 }
    462 
    463                 sp<ABuffer> accessUnit;
    464                 CHECK(msg->findBuffer("accessUnit", &accessUnit));
    465 
    466                 if (!allTracksHavePacketizerIndex()) {
    467                     track->queueAccessUnit(accessUnit);
    468                     break;
    469                 }
    470 
    471                 track->queueOutputBuffer(accessUnit);
    472 
    473                 drainAccessUnits();
    474                 break;
    475             } else if (what == Converter::kWhatEOS) {
    476                 CHECK_EQ(what, Converter::kWhatEOS);
    477 
    478                 ALOGI("output EOS on track %d", trackIndex);
    479 
    480                 ssize_t index = mTracks.indexOfKey(trackIndex);
    481                 CHECK_GE(index, 0);
    482 
    483                 const sp<Converter> &converter =
    484                     mTracks.valueAt(index)->converter();
    485                 looper()->unregisterHandler(converter->id());
    486 
    487                 mTracks.removeItemsAt(index);
    488 
    489                 if (mTracks.isEmpty()) {
    490                     ALOGI("Reached EOS");
    491                 }
    492             } else {
    493                 CHECK_EQ(what, Converter::kWhatError);
    494 
    495                 status_t err;
    496                 CHECK(msg->findInt32("err", &err));
    497 
    498                 ALOGE("converter signaled error %d", err);
    499 
    500                 notifySessionDead();
    501             }
    502             break;
    503         }
    504 
    505         case kWhatSenderNotify:
    506         {
    507             int32_t what;
    508             CHECK(msg->findInt32("what", &what));
    509 
    510             if (what == Sender::kWhatInitDone) {
    511                 onFinishPlay2();
    512             } else if (what == Sender::kWhatSessionDead) {
    513                 notifySessionDead();
    514             } else {
    515                 TRESPASS();
    516             }
    517 
    518             break;
    519         }
    520 
    521         case kWhatFinishPlay:
    522         {
    523             onFinishPlay();
    524             break;
    525         }
    526 
    527         case kWhatTrackNotify:
    528         {
    529             int32_t what;
    530             CHECK(msg->findInt32("what", &what));
    531 
    532             size_t trackIndex;
    533             CHECK(msg->findSize("trackIndex", &trackIndex));
    534 
    535             if (what == Track::kWhatStopped) {
    536                 ALOGI("Track %d stopped", trackIndex);
    537 
    538                 sp<Track> track = mTracks.valueFor(trackIndex);
    539                 looper()->unregisterHandler(track->id());
    540                 mTracks.removeItem(trackIndex);
    541                 track.clear();
    542 
    543                 if (!mTracks.isEmpty()) {
    544                     ALOGI("not all tracks are stopped yet");
    545                     break;
    546                 }
    547 
    548                 mSenderLooper->unregisterHandler(mSender->id());
    549                 mSender.clear();
    550                 mSenderLooper.clear();
    551 
    552                 mPacketizer.clear();
    553 
    554                 sp<AMessage> notify = mNotify->dup();
    555                 notify->setInt32("what", kWhatSessionDestroyed);
    556                 notify->post();
    557             }
    558             break;
    559         }
    560 
    561         case kWhatPacketize:
    562         {
    563             size_t trackIndex;
    564             CHECK(msg->findSize("trackIndex", &trackIndex));
    565 
    566             sp<ABuffer> accessUnit;
    567             CHECK(msg->findBuffer("accessUnit", &accessUnit));
    568 
    569 #if 0
    570             if ((ssize_t)trackIndex == mVideoTrackIndex) {
    571                 int64_t nowUs = ALooper::GetNowUs();
    572                 static int64_t prevNowUs = 0ll;
    573 
    574                 ALOGI("sending AU, dNowUs=%lld us", nowUs - prevNowUs);
    575 
    576                 prevNowUs = nowUs;
    577             }
    578 #endif
    579 
    580             break;
    581         }
    582 
    583         default:
    584             TRESPASS();
    585     }
    586 }
    587 
    588 status_t WifiDisplaySource::PlaybackSession::setupPacketizer(bool usePCMAudio) {
    589     mPacketizer = new TSPacketizer;
    590 
    591     status_t err = addVideoSource();
    592 
    593     if (err != OK) {
    594         return err;
    595     }
    596 
    597     return addAudioSource(usePCMAudio);
    598 }
    599 
    600 status_t WifiDisplaySource::PlaybackSession::addSource(
    601         bool isVideo, const sp<MediaSource> &source, bool isRepeaterSource,
    602         bool usePCMAudio, size_t *numInputBuffers) {
    603     CHECK(!usePCMAudio || !isVideo);
    604     CHECK(!isRepeaterSource || isVideo);
    605 
    606     sp<ALooper> pullLooper = new ALooper;
    607     pullLooper->setName("pull_looper");
    608 
    609     pullLooper->start(
    610             false /* runOnCallingThread */,
    611             false /* canCallJava */,
    612             PRIORITY_AUDIO);
    613 
    614     sp<ALooper> codecLooper = new ALooper;
    615     codecLooper->setName("codec_looper");
    616 
    617     codecLooper->start(
    618             false /* runOnCallingThread */,
    619             false /* canCallJava */,
    620             PRIORITY_AUDIO);
    621 
    622     size_t trackIndex;
    623 
    624     sp<AMessage> notify;
    625 
    626     trackIndex = mTracks.size();
    627 
    628     sp<AMessage> format;
    629     status_t err = convertMetaDataToMessage(source->getFormat(), &format);
    630     CHECK_EQ(err, (status_t)OK);
    631 
    632     if (isVideo) {
    633         format->setInt32("store-metadata-in-buffers", true);
    634 
    635         format->setInt32(
    636                 "color-format", OMX_COLOR_FormatAndroidOpaque);
    637     }
    638 
    639     notify = new AMessage(kWhatConverterNotify, id());
    640     notify->setSize("trackIndex", trackIndex);
    641 
    642     sp<Converter> converter =
    643         new Converter(notify, codecLooper, format, usePCMAudio);
    644 
    645     if (converter->initCheck() != OK) {
    646         return converter->initCheck();
    647     }
    648 
    649     looper()->registerHandler(converter);
    650 
    651     notify = new AMessage(Converter::kWhatMediaPullerNotify, converter->id());
    652     notify->setSize("trackIndex", trackIndex);
    653 
    654     sp<MediaPuller> puller = new MediaPuller(source, notify);
    655     pullLooper->registerHandler(puller);
    656 
    657     if (numInputBuffers != NULL) {
    658         *numInputBuffers = converter->getInputBufferCount();
    659     }
    660 
    661     notify = new AMessage(kWhatTrackNotify, id());
    662     notify->setSize("trackIndex", trackIndex);
    663 
    664     sp<Track> track = new Track(
    665             notify, pullLooper, codecLooper, puller, converter);
    666 
    667     if (isRepeaterSource) {
    668         track->setRepeaterSource(static_cast<RepeaterSource *>(source.get()));
    669     }
    670 
    671     looper()->registerHandler(track);
    672 
    673     mTracks.add(trackIndex, track);
    674 
    675     if (isVideo) {
    676         mVideoTrackIndex = trackIndex;
    677     }
    678 
    679     return OK;
    680 }
    681 
    682 status_t WifiDisplaySource::PlaybackSession::addVideoSource() {
    683     sp<SurfaceMediaSource> source = new SurfaceMediaSource(width(), height());
    684 
    685     source->setUseAbsoluteTimestamps();
    686 
    687 #if 1
    688     sp<RepeaterSource> videoSource =
    689         new RepeaterSource(source, 30.0 /* rateHz */);
    690 #endif
    691 
    692 #if 1
    693     size_t numInputBuffers;
    694     status_t err = addSource(
    695             true /* isVideo */, videoSource, true /* isRepeaterSource */,
    696             false /* usePCMAudio */, &numInputBuffers);
    697 #else
    698     size_t numInputBuffers;
    699     status_t err = addSource(
    700             true /* isVideo */, source, false /* isRepeaterSource */,
    701             false /* usePCMAudio */, &numInputBuffers);
    702 #endif
    703 
    704     if (err != OK) {
    705         return err;
    706     }
    707 
    708     err = source->setMaxAcquiredBufferCount(numInputBuffers);
    709     CHECK_EQ(err, (status_t)OK);
    710 
    711     mBufferQueue = source->getBufferQueue();
    712 
    713     return OK;
    714 }
    715 
    716 status_t WifiDisplaySource::PlaybackSession::addAudioSource(bool usePCMAudio) {
    717     sp<AudioSource> audioSource = new AudioSource(
    718             AUDIO_SOURCE_REMOTE_SUBMIX,
    719             48000 /* sampleRate */,
    720             2 /* channelCount */);
    721 
    722     if (audioSource->initCheck() == OK) {
    723         return addSource(
    724                 false /* isVideo */, audioSource, false /* isRepeaterSource */,
    725                 usePCMAudio, NULL /* numInputBuffers */);
    726     }
    727 
    728     ALOGW("Unable to instantiate audio source");
    729 
    730     return OK;
    731 }
    732 
    733 sp<ISurfaceTexture> WifiDisplaySource::PlaybackSession::getSurfaceTexture() {
    734     return mBufferQueue;
    735 }
    736 
    737 int32_t WifiDisplaySource::PlaybackSession::width() const {
    738     return 1280;
    739 }
    740 
    741 int32_t WifiDisplaySource::PlaybackSession::height() const {
    742     return 720;
    743 }
    744 
    745 void WifiDisplaySource::PlaybackSession::requestIDRFrame() {
    746     for (size_t i = 0; i < mTracks.size(); ++i) {
    747         const sp<Track> &track = mTracks.valueAt(i);
    748 
    749         track->requestIDRFrame();
    750     }
    751 }
    752 
    753 bool WifiDisplaySource::PlaybackSession::allTracksHavePacketizerIndex() {
    754     if (mAllTracksHavePacketizerIndex) {
    755         return true;
    756     }
    757 
    758     for (size_t i = 0; i < mTracks.size(); ++i) {
    759         if (mTracks.valueAt(i)->packetizerTrackIndex() < 0) {
    760             return false;
    761         }
    762     }
    763 
    764     mAllTracksHavePacketizerIndex = true;
    765 
    766     return true;
    767 }
    768 
    769 status_t WifiDisplaySource::PlaybackSession::packetizeAccessUnit(
    770         size_t trackIndex, const sp<ABuffer> &accessUnit,
    771         sp<ABuffer> *packets) {
    772     const sp<Track> &track = mTracks.valueFor(trackIndex);
    773 
    774     uint32_t flags = 0;
    775 
    776     bool isHDCPEncrypted = false;
    777     uint64_t inputCTR;
    778     uint8_t HDCP_private_data[16];
    779     if (mHDCP != NULL && !track->isAudio()) {
    780         isHDCPEncrypted = true;
    781 
    782         status_t err = mHDCP->encrypt(
    783                 accessUnit->data(), accessUnit->size(),
    784                 trackIndex  /* streamCTR */,
    785                 &inputCTR,
    786                 accessUnit->data());
    787 
    788         if (err != OK) {
    789             ALOGE("Failed to HDCP-encrypt media data (err %d)",
    790                   err);
    791 
    792             return err;
    793         }
    794 
    795         HDCP_private_data[0] = 0x00;
    796 
    797         HDCP_private_data[1] =
    798             (((trackIndex >> 30) & 3) << 1) | 1;
    799 
    800         HDCP_private_data[2] = (trackIndex >> 22) & 0xff;
    801 
    802         HDCP_private_data[3] =
    803             (((trackIndex >> 15) & 0x7f) << 1) | 1;
    804 
    805         HDCP_private_data[4] = (trackIndex >> 7) & 0xff;
    806 
    807         HDCP_private_data[5] =
    808             ((trackIndex & 0x7f) << 1) | 1;
    809 
    810         HDCP_private_data[6] = 0x00;
    811 
    812         HDCP_private_data[7] =
    813             (((inputCTR >> 60) & 0x0f) << 1) | 1;
    814 
    815         HDCP_private_data[8] = (inputCTR >> 52) & 0xff;
    816 
    817         HDCP_private_data[9] =
    818             (((inputCTR >> 45) & 0x7f) << 1) | 1;
    819 
    820         HDCP_private_data[10] = (inputCTR >> 37) & 0xff;
    821 
    822         HDCP_private_data[11] =
    823             (((inputCTR >> 30) & 0x7f) << 1) | 1;
    824 
    825         HDCP_private_data[12] = (inputCTR >> 22) & 0xff;
    826 
    827         HDCP_private_data[13] =
    828             (((inputCTR >> 15) & 0x7f) << 1) | 1;
    829 
    830         HDCP_private_data[14] = (inputCTR >> 7) & 0xff;
    831 
    832         HDCP_private_data[15] =
    833             ((inputCTR & 0x7f) << 1) | 1;
    834 
    835 #if 0
    836         ALOGI("HDCP_private_data:");
    837         hexdump(HDCP_private_data, sizeof(HDCP_private_data));
    838 
    839         ABitReader br(HDCP_private_data, sizeof(HDCP_private_data));
    840         CHECK_EQ(br.getBits(13), 0);
    841         CHECK_EQ(br.getBits(2), (trackIndex >> 30) & 3);
    842         CHECK_EQ(br.getBits(1), 1u);
    843         CHECK_EQ(br.getBits(15), (trackIndex >> 15) & 0x7fff);
    844         CHECK_EQ(br.getBits(1), 1u);
    845         CHECK_EQ(br.getBits(15), trackIndex & 0x7fff);
    846         CHECK_EQ(br.getBits(1), 1u);
    847         CHECK_EQ(br.getBits(11), 0);
    848         CHECK_EQ(br.getBits(4), (inputCTR >> 60) & 0xf);
    849         CHECK_EQ(br.getBits(1), 1u);
    850         CHECK_EQ(br.getBits(15), (inputCTR >> 45) & 0x7fff);
    851         CHECK_EQ(br.getBits(1), 1u);
    852         CHECK_EQ(br.getBits(15), (inputCTR >> 30) & 0x7fff);
    853         CHECK_EQ(br.getBits(1), 1u);
    854         CHECK_EQ(br.getBits(15), (inputCTR >> 15) & 0x7fff);
    855         CHECK_EQ(br.getBits(1), 1u);
    856         CHECK_EQ(br.getBits(15), inputCTR & 0x7fff);
    857         CHECK_EQ(br.getBits(1), 1u);
    858 #endif
    859 
    860         flags |= TSPacketizer::IS_ENCRYPTED;
    861     }
    862 
    863     int64_t timeUs = ALooper::GetNowUs();
    864     if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll <= timeUs) {
    865         flags |= TSPacketizer::EMIT_PCR;
    866         flags |= TSPacketizer::EMIT_PAT_AND_PMT;
    867 
    868         mPrevTimeUs = timeUs;
    869     }
    870 
    871     mPacketizer->packetize(
    872             track->packetizerTrackIndex(), accessUnit, packets, flags,
    873             !isHDCPEncrypted ? NULL : HDCP_private_data,
    874             !isHDCPEncrypted ? 0 : sizeof(HDCP_private_data),
    875             track->isAudio() ? 2 : 0 /* numStuffingBytes */);
    876 
    877     return OK;
    878 }
    879 
    880 status_t WifiDisplaySource::PlaybackSession::packetizeQueuedAccessUnits() {
    881     for (;;) {
    882         bool gotMoreData = false;
    883         for (size_t i = 0; i < mTracks.size(); ++i) {
    884             size_t trackIndex = mTracks.keyAt(i);
    885             const sp<Track> &track = mTracks.valueAt(i);
    886 
    887             sp<ABuffer> accessUnit = track->dequeueAccessUnit();
    888             if (accessUnit != NULL) {
    889                 track->queueOutputBuffer(accessUnit);
    890                 gotMoreData = true;
    891             }
    892         }
    893 
    894         if (!gotMoreData) {
    895             break;
    896         }
    897     }
    898 
    899     return OK;
    900 }
    901 
    902 void WifiDisplaySource::PlaybackSession::notifySessionDead() {
    903     // Inform WifiDisplaySource of our premature death (wish).
    904     sp<AMessage> notify = mNotify->dup();
    905     notify->setInt32("what", kWhatSessionDead);
    906     notify->post();
    907 
    908     mWeAreDead = true;
    909 }
    910 
    911 void WifiDisplaySource::PlaybackSession::drainAccessUnits() {
    912     ALOGV("audio/video has %d/%d buffers ready.",
    913             mTracks.valueFor(1)->countQueuedOutputBuffers(),
    914             mTracks.valueFor(0)->countQueuedOutputBuffers());
    915 
    916     while (drainAccessUnit()) {
    917     }
    918 }
    919 
    920 bool WifiDisplaySource::PlaybackSession::drainAccessUnit() {
    921     ssize_t minTrackIndex = -1;
    922     int64_t minTimeUs = -1ll;
    923 
    924     for (size_t i = 0; i < mTracks.size(); ++i) {
    925         const sp<Track> &track = mTracks.valueAt(i);
    926 
    927         int64_t timeUs;
    928         if (track->hasOutputBuffer(&timeUs)) {
    929             if (minTrackIndex < 0 || timeUs < minTimeUs) {
    930                 minTrackIndex = mTracks.keyAt(i);
    931                 minTimeUs = timeUs;
    932             }
    933         } else if (!track->isSuspended()) {
    934             // We still consider this track "live", so it should keep
    935             // delivering output data whose time stamps we'll have to
    936             // consider for proper interleaving.
    937             return false;
    938         }
    939     }
    940 
    941     if (minTrackIndex < 0) {
    942         return false;
    943     }
    944 
    945     const sp<Track> &track = mTracks.valueFor(minTrackIndex);
    946     sp<ABuffer> accessUnit = track->dequeueOutputBuffer();
    947 
    948     sp<ABuffer> packets;
    949     status_t err = packetizeAccessUnit(minTrackIndex, accessUnit, &packets);
    950 
    951     if (err != OK) {
    952         notifySessionDead();
    953     }
    954 
    955     if ((ssize_t)minTrackIndex == mVideoTrackIndex) {
    956         packets->meta()->setInt32("isVideo", 1);
    957     }
    958     mSender->queuePackets(minTimeUs, packets);
    959 
    960     return true;
    961 }
    962 
    963 }  // namespace android
    964 
    965