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 "include/avc_utils.h"
     27 #include "WifiDisplaySource.h"
     28 
     29 #include <binder/IServiceManager.h>
     30 #include <cutils/properties.h>
     31 #include <media/IHDCP.h>
     32 #include <media/IMediaHTTPService.h>
     33 #include <media/stagefright/foundation/ABitReader.h>
     34 #include <media/stagefright/foundation/ABuffer.h>
     35 #include <media/stagefright/foundation/ADebug.h>
     36 #include <media/stagefright/foundation/AMessage.h>
     37 #include <media/stagefright/foundation/hexdump.h>
     38 #include <media/stagefright/AudioSource.h>
     39 #include <media/stagefright/MediaDefs.h>
     40 #include <media/stagefright/MediaErrors.h>
     41 #include <media/stagefright/MediaSource.h>
     42 #include <media/stagefright/MetaData.h>
     43 #include <media/stagefright/NuMediaExtractor.h>
     44 #include <media/stagefright/SurfaceMediaSource.h>
     45 #include <media/stagefright/Utils.h>
     46 
     47 #include <OMX_IVCommon.h>
     48 
     49 namespace android {
     50 
     51 struct WifiDisplaySource::PlaybackSession::Track : public AHandler {
     52     enum {
     53         kWhatStopped,
     54     };
     55 
     56     Track(const sp<AMessage> &notify,
     57           const sp<ALooper> &pullLooper,
     58           const sp<ALooper> &codecLooper,
     59           const sp<MediaPuller> &mediaPuller,
     60           const sp<Converter> &converter);
     61 
     62     Track(const sp<AMessage> &notify, const sp<AMessage> &format);
     63 
     64     void setRepeaterSource(const sp<RepeaterSource> &source);
     65 
     66     sp<AMessage> getFormat();
     67     bool isAudio() const;
     68 
     69     const sp<Converter> &converter() const;
     70     const sp<RepeaterSource> &repeaterSource() const;
     71 
     72     ssize_t mediaSenderTrackIndex() const;
     73     void setMediaSenderTrackIndex(size_t index);
     74 
     75     status_t start();
     76     void stopAsync();
     77 
     78     void pause();
     79     void resume();
     80 
     81     void queueAccessUnit(const sp<ABuffer> &accessUnit);
     82     sp<ABuffer> dequeueAccessUnit();
     83 
     84     bool hasOutputBuffer(int64_t *timeUs) const;
     85     void queueOutputBuffer(const sp<ABuffer> &accessUnit);
     86     sp<ABuffer> dequeueOutputBuffer();
     87 
     88 #if SUSPEND_VIDEO_IF_IDLE
     89     bool isSuspended() const;
     90 #endif
     91 
     92     size_t countQueuedOutputBuffers() const {
     93         return mQueuedOutputBuffers.size();
     94     }
     95 
     96     void requestIDRFrame();
     97 
     98 protected:
     99     virtual void onMessageReceived(const sp<AMessage> &msg);
    100     virtual ~Track();
    101 
    102 private:
    103     enum {
    104         kWhatMediaPullerStopped,
    105     };
    106 
    107     sp<AMessage> mNotify;
    108     sp<ALooper> mPullLooper;
    109     sp<ALooper> mCodecLooper;
    110     sp<MediaPuller> mMediaPuller;
    111     sp<Converter> mConverter;
    112     sp<AMessage> mFormat;
    113     bool mStarted;
    114     ssize_t mMediaSenderTrackIndex;
    115     bool mIsAudio;
    116     List<sp<ABuffer> > mQueuedAccessUnits;
    117     sp<RepeaterSource> mRepeaterSource;
    118     List<sp<ABuffer> > mQueuedOutputBuffers;
    119     int64_t mLastOutputBufferQueuedTimeUs;
    120 
    121     static bool IsAudioFormat(const sp<AMessage> &format);
    122 
    123     DISALLOW_EVIL_CONSTRUCTORS(Track);
    124 };
    125 
    126 WifiDisplaySource::PlaybackSession::Track::Track(
    127         const sp<AMessage> &notify,
    128         const sp<ALooper> &pullLooper,
    129         const sp<ALooper> &codecLooper,
    130         const sp<MediaPuller> &mediaPuller,
    131         const sp<Converter> &converter)
    132     : mNotify(notify),
    133       mPullLooper(pullLooper),
    134       mCodecLooper(codecLooper),
    135       mMediaPuller(mediaPuller),
    136       mConverter(converter),
    137       mStarted(false),
    138       mIsAudio(IsAudioFormat(mConverter->getOutputFormat())),
    139       mLastOutputBufferQueuedTimeUs(-1ll) {
    140 }
    141 
    142 WifiDisplaySource::PlaybackSession::Track::Track(
    143         const sp<AMessage> &notify, const sp<AMessage> &format)
    144     : mNotify(notify),
    145       mFormat(format),
    146       mStarted(false),
    147       mIsAudio(IsAudioFormat(format)),
    148       mLastOutputBufferQueuedTimeUs(-1ll) {
    149 }
    150 
    151 WifiDisplaySource::PlaybackSession::Track::~Track() {
    152     CHECK(!mStarted);
    153 }
    154 
    155 // static
    156 bool WifiDisplaySource::PlaybackSession::Track::IsAudioFormat(
    157         const sp<AMessage> &format) {
    158     AString mime;
    159     CHECK(format->findString("mime", &mime));
    160 
    161     return !strncasecmp(mime.c_str(), "audio/", 6);
    162 }
    163 
    164 sp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() {
    165     return mFormat != NULL ? mFormat : mConverter->getOutputFormat();
    166 }
    167 
    168 bool WifiDisplaySource::PlaybackSession::Track::isAudio() const {
    169     return mIsAudio;
    170 }
    171 
    172 const sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() const {
    173     return mConverter;
    174 }
    175 
    176 const sp<RepeaterSource> &
    177 WifiDisplaySource::PlaybackSession::Track::repeaterSource() const {
    178     return mRepeaterSource;
    179 }
    180 
    181 ssize_t WifiDisplaySource::PlaybackSession::Track::mediaSenderTrackIndex() const {
    182     CHECK_GE(mMediaSenderTrackIndex, 0);
    183     return mMediaSenderTrackIndex;
    184 }
    185 
    186 void WifiDisplaySource::PlaybackSession::Track::setMediaSenderTrackIndex(
    187         size_t index) {
    188     mMediaSenderTrackIndex = index;
    189 }
    190 
    191 status_t WifiDisplaySource::PlaybackSession::Track::start() {
    192     ALOGV("Track::start isAudio=%d", mIsAudio);
    193 
    194     CHECK(!mStarted);
    195 
    196     status_t err = OK;
    197 
    198     if (mMediaPuller != NULL) {
    199         err = mMediaPuller->start();
    200     }
    201 
    202     if (err == OK) {
    203         mStarted = true;
    204     }
    205 
    206     return err;
    207 }
    208 
    209 void WifiDisplaySource::PlaybackSession::Track::stopAsync() {
    210     ALOGV("Track::stopAsync isAudio=%d", mIsAudio);
    211 
    212     if (mConverter != NULL) {
    213         mConverter->shutdownAsync();
    214     }
    215 
    216     sp<AMessage> msg = new AMessage(kWhatMediaPullerStopped, this);
    217 
    218     if (mStarted && mMediaPuller != NULL) {
    219         if (mRepeaterSource != NULL) {
    220             // Let's unblock MediaPuller's MediaSource::read().
    221             mRepeaterSource->wakeUp();
    222         }
    223 
    224         mMediaPuller->stopAsync(msg);
    225     } else {
    226         mStarted = false;
    227         msg->post();
    228     }
    229 }
    230 
    231 void WifiDisplaySource::PlaybackSession::Track::pause() {
    232     mMediaPuller->pause();
    233 }
    234 
    235 void WifiDisplaySource::PlaybackSession::Track::resume() {
    236     mMediaPuller->resume();
    237 }
    238 
    239 void WifiDisplaySource::PlaybackSession::Track::onMessageReceived(
    240         const sp<AMessage> &msg) {
    241     switch (msg->what()) {
    242         case kWhatMediaPullerStopped:
    243         {
    244             mConverter.clear();
    245 
    246             mStarted = false;
    247 
    248             sp<AMessage> notify = mNotify->dup();
    249             notify->setInt32("what", kWhatStopped);
    250             notify->post();
    251 
    252             ALOGI("kWhatStopped %s posted", mIsAudio ? "audio" : "video");
    253             break;
    254         }
    255 
    256         default:
    257             TRESPASS();
    258     }
    259 }
    260 
    261 void WifiDisplaySource::PlaybackSession::Track::queueAccessUnit(
    262         const sp<ABuffer> &accessUnit) {
    263     mQueuedAccessUnits.push_back(accessUnit);
    264 }
    265 
    266 sp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueAccessUnit() {
    267     if (mQueuedAccessUnits.empty()) {
    268         return NULL;
    269     }
    270 
    271     sp<ABuffer> accessUnit = *mQueuedAccessUnits.begin();
    272     CHECK(accessUnit != NULL);
    273 
    274     mQueuedAccessUnits.erase(mQueuedAccessUnits.begin());
    275 
    276     return accessUnit;
    277 }
    278 
    279 void WifiDisplaySource::PlaybackSession::Track::setRepeaterSource(
    280         const sp<RepeaterSource> &source) {
    281     mRepeaterSource = source;
    282 }
    283 
    284 void WifiDisplaySource::PlaybackSession::Track::requestIDRFrame() {
    285     if (mIsAudio) {
    286         return;
    287     }
    288 
    289     if (mRepeaterSource != NULL) {
    290         mRepeaterSource->wakeUp();
    291     }
    292 
    293     mConverter->requestIDRFrame();
    294 }
    295 
    296 bool WifiDisplaySource::PlaybackSession::Track::hasOutputBuffer(
    297         int64_t *timeUs) const {
    298     *timeUs = 0ll;
    299 
    300     if (mQueuedOutputBuffers.empty()) {
    301         return false;
    302     }
    303 
    304     const sp<ABuffer> &outputBuffer = *mQueuedOutputBuffers.begin();
    305 
    306     CHECK(outputBuffer->meta()->findInt64("timeUs", timeUs));
    307 
    308     return true;
    309 }
    310 
    311 void WifiDisplaySource::PlaybackSession::Track::queueOutputBuffer(
    312         const sp<ABuffer> &accessUnit) {
    313     mQueuedOutputBuffers.push_back(accessUnit);
    314     mLastOutputBufferQueuedTimeUs = ALooper::GetNowUs();
    315 }
    316 
    317 sp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueOutputBuffer() {
    318     CHECK(!mQueuedOutputBuffers.empty());
    319 
    320     sp<ABuffer> outputBuffer = *mQueuedOutputBuffers.begin();
    321     mQueuedOutputBuffers.erase(mQueuedOutputBuffers.begin());
    322 
    323     return outputBuffer;
    324 }
    325 
    326 #if SUSPEND_VIDEO_IF_IDLE
    327 bool WifiDisplaySource::PlaybackSession::Track::isSuspended() const {
    328     if (!mQueuedOutputBuffers.empty()) {
    329         return false;
    330     }
    331 
    332     if (mLastOutputBufferQueuedTimeUs < 0ll) {
    333         // We've never seen an output buffer queued, but tracks start
    334         // out live, not suspended.
    335         return false;
    336     }
    337 
    338     // If we've not seen new output data for 60ms or more, we consider
    339     // this track suspended for the time being.
    340     return (ALooper::GetNowUs() - mLastOutputBufferQueuedTimeUs) > 60000ll;
    341 }
    342 #endif
    343 
    344 ////////////////////////////////////////////////////////////////////////////////
    345 
    346 WifiDisplaySource::PlaybackSession::PlaybackSession(
    347         const String16 &opPackageName,
    348         const sp<ANetworkSession> &netSession,
    349         const sp<AMessage> &notify,
    350         const in_addr &interfaceAddr,
    351         const sp<IHDCP> &hdcp,
    352         const char *path)
    353     : mOpPackageName(opPackageName),
    354       mNetSession(netSession),
    355       mNotify(notify),
    356       mInterfaceAddr(interfaceAddr),
    357       mHDCP(hdcp),
    358       mLocalRTPPort(-1),
    359       mWeAreDead(false),
    360       mPaused(false),
    361       mLastLifesignUs(),
    362       mVideoTrackIndex(-1),
    363       mPrevTimeUs(-1ll),
    364       mPullExtractorPending(false),
    365       mPullExtractorGeneration(0),
    366       mFirstSampleTimeRealUs(-1ll),
    367       mFirstSampleTimeUs(-1ll) {
    368     if (path != NULL) {
    369         mMediaPath.setTo(path);
    370     }
    371 }
    372 
    373 status_t WifiDisplaySource::PlaybackSession::init(
    374         const char *clientIP,
    375         int32_t clientRtp,
    376         RTPSender::TransportMode rtpMode,
    377         int32_t clientRtcp,
    378         RTPSender::TransportMode rtcpMode,
    379         bool enableAudio,
    380         bool usePCMAudio,
    381         bool enableVideo,
    382         VideoFormats::ResolutionType videoResolutionType,
    383         size_t videoResolutionIndex,
    384         VideoFormats::ProfileType videoProfileType,
    385         VideoFormats::LevelType videoLevelType) {
    386     sp<AMessage> notify = new AMessage(kWhatMediaSenderNotify, this);
    387     mMediaSender = new MediaSender(mNetSession, notify);
    388     looper()->registerHandler(mMediaSender);
    389 
    390     mMediaSender->setHDCP(mHDCP);
    391 
    392     status_t err = setupPacketizer(
    393             enableAudio,
    394             usePCMAudio,
    395             enableVideo,
    396             videoResolutionType,
    397             videoResolutionIndex,
    398             videoProfileType,
    399             videoLevelType);
    400 
    401     if (err == OK) {
    402         err = mMediaSender->initAsync(
    403                 -1 /* trackIndex */,
    404                 clientIP,
    405                 clientRtp,
    406                 rtpMode,
    407                 clientRtcp,
    408                 rtcpMode,
    409                 &mLocalRTPPort);
    410     }
    411 
    412     if (err != OK) {
    413         mLocalRTPPort = -1;
    414 
    415         looper()->unregisterHandler(mMediaSender->id());
    416         mMediaSender.clear();
    417 
    418         return err;
    419     }
    420 
    421     updateLiveness();
    422 
    423     return OK;
    424 }
    425 
    426 WifiDisplaySource::PlaybackSession::~PlaybackSession() {
    427 }
    428 
    429 int32_t WifiDisplaySource::PlaybackSession::getRTPPort() const {
    430     return mLocalRTPPort;
    431 }
    432 
    433 int64_t WifiDisplaySource::PlaybackSession::getLastLifesignUs() const {
    434     return mLastLifesignUs;
    435 }
    436 
    437 void WifiDisplaySource::PlaybackSession::updateLiveness() {
    438     mLastLifesignUs = ALooper::GetNowUs();
    439 }
    440 
    441 status_t WifiDisplaySource::PlaybackSession::play() {
    442     updateLiveness();
    443 
    444     (new AMessage(kWhatResume, this))->post();
    445 
    446     return OK;
    447 }
    448 
    449 status_t WifiDisplaySource::PlaybackSession::onMediaSenderInitialized() {
    450     for (size_t i = 0; i < mTracks.size(); ++i) {
    451         CHECK_EQ((status_t)OK, mTracks.editValueAt(i)->start());
    452     }
    453 
    454     sp<AMessage> notify = mNotify->dup();
    455     notify->setInt32("what", kWhatSessionEstablished);
    456     notify->post();
    457 
    458     return OK;
    459 }
    460 
    461 status_t WifiDisplaySource::PlaybackSession::pause() {
    462     updateLiveness();
    463 
    464     (new AMessage(kWhatPause, this))->post();
    465 
    466     return OK;
    467 }
    468 
    469 void WifiDisplaySource::PlaybackSession::destroyAsync() {
    470     ALOGI("destroyAsync");
    471 
    472     for (size_t i = 0; i < mTracks.size(); ++i) {
    473         mTracks.valueAt(i)->stopAsync();
    474     }
    475 }
    476 
    477 void WifiDisplaySource::PlaybackSession::onMessageReceived(
    478         const sp<AMessage> &msg) {
    479     switch (msg->what()) {
    480         case kWhatConverterNotify:
    481         {
    482             if (mWeAreDead) {
    483                 ALOGV("dropping msg '%s' because we're dead",
    484                       msg->debugString().c_str());
    485 
    486                 break;
    487             }
    488 
    489             int32_t what;
    490             CHECK(msg->findInt32("what", &what));
    491 
    492             size_t trackIndex;
    493             CHECK(msg->findSize("trackIndex", &trackIndex));
    494 
    495             if (what == Converter::kWhatAccessUnit) {
    496                 sp<ABuffer> accessUnit;
    497                 CHECK(msg->findBuffer("accessUnit", &accessUnit));
    498 
    499                 const sp<Track> &track = mTracks.valueFor(trackIndex);
    500 
    501                 status_t err = mMediaSender->queueAccessUnit(
    502                         track->mediaSenderTrackIndex(),
    503                         accessUnit);
    504 
    505                 if (err != OK) {
    506                     notifySessionDead();
    507                 }
    508                 break;
    509             } else if (what == Converter::kWhatEOS) {
    510                 CHECK_EQ(what, Converter::kWhatEOS);
    511 
    512                 ALOGI("output EOS on track %zu", trackIndex);
    513 
    514                 ssize_t index = mTracks.indexOfKey(trackIndex);
    515                 CHECK_GE(index, 0);
    516 
    517                 const sp<Converter> &converter =
    518                     mTracks.valueAt(index)->converter();
    519                 looper()->unregisterHandler(converter->id());
    520 
    521                 mTracks.removeItemsAt(index);
    522 
    523                 if (mTracks.isEmpty()) {
    524                     ALOGI("Reached EOS");
    525                 }
    526             } else if (what != Converter::kWhatShutdownCompleted) {
    527                 CHECK_EQ(what, Converter::kWhatError);
    528 
    529                 status_t err;
    530                 CHECK(msg->findInt32("err", &err));
    531 
    532                 ALOGE("converter signaled error %d", err);
    533 
    534                 notifySessionDead();
    535             }
    536             break;
    537         }
    538 
    539         case kWhatMediaSenderNotify:
    540         {
    541             int32_t what;
    542             CHECK(msg->findInt32("what", &what));
    543 
    544             if (what == MediaSender::kWhatInitDone) {
    545                 status_t err;
    546                 CHECK(msg->findInt32("err", &err));
    547 
    548                 if (err == OK) {
    549                     onMediaSenderInitialized();
    550                 } else {
    551                     notifySessionDead();
    552                 }
    553             } else if (what == MediaSender::kWhatError) {
    554                 notifySessionDead();
    555             } else if (what == MediaSender::kWhatNetworkStall) {
    556                 size_t numBytesQueued;
    557                 CHECK(msg->findSize("numBytesQueued", &numBytesQueued));
    558 
    559                 if (mVideoTrackIndex >= 0) {
    560                     const sp<Track> &videoTrack =
    561                         mTracks.valueFor(mVideoTrackIndex);
    562 
    563                     sp<Converter> converter = videoTrack->converter();
    564                     if (converter != NULL) {
    565                         converter->dropAFrame();
    566                     }
    567                 }
    568             } else if (what == MediaSender::kWhatInformSender) {
    569                 onSinkFeedback(msg);
    570             } else {
    571                 TRESPASS();
    572             }
    573             break;
    574         }
    575 
    576         case kWhatTrackNotify:
    577         {
    578             int32_t what;
    579             CHECK(msg->findInt32("what", &what));
    580 
    581             size_t trackIndex;
    582             CHECK(msg->findSize("trackIndex", &trackIndex));
    583 
    584             if (what == Track::kWhatStopped) {
    585                 ALOGI("Track %zu stopped", trackIndex);
    586 
    587                 sp<Track> track = mTracks.valueFor(trackIndex);
    588                 looper()->unregisterHandler(track->id());
    589                 mTracks.removeItem(trackIndex);
    590                 track.clear();
    591 
    592                 if (!mTracks.isEmpty()) {
    593                     ALOGI("not all tracks are stopped yet");
    594                     break;
    595                 }
    596 
    597                 looper()->unregisterHandler(mMediaSender->id());
    598                 mMediaSender.clear();
    599 
    600                 sp<AMessage> notify = mNotify->dup();
    601                 notify->setInt32("what", kWhatSessionDestroyed);
    602                 notify->post();
    603             }
    604             break;
    605         }
    606 
    607         case kWhatPause:
    608         {
    609             if (mExtractor != NULL) {
    610                 ++mPullExtractorGeneration;
    611                 mFirstSampleTimeRealUs = -1ll;
    612                 mFirstSampleTimeUs = -1ll;
    613             }
    614 
    615             if (mPaused) {
    616                 break;
    617             }
    618 
    619             for (size_t i = 0; i < mTracks.size(); ++i) {
    620                 mTracks.editValueAt(i)->pause();
    621             }
    622 
    623             mPaused = true;
    624             break;
    625         }
    626 
    627         case kWhatResume:
    628         {
    629             if (mExtractor != NULL) {
    630                 schedulePullExtractor();
    631             }
    632 
    633             if (!mPaused) {
    634                 break;
    635             }
    636 
    637             for (size_t i = 0; i < mTracks.size(); ++i) {
    638                 mTracks.editValueAt(i)->resume();
    639             }
    640 
    641             mPaused = false;
    642             break;
    643         }
    644 
    645         case kWhatPullExtractorSample:
    646         {
    647             int32_t generation;
    648             CHECK(msg->findInt32("generation", &generation));
    649 
    650             if (generation != mPullExtractorGeneration) {
    651                 break;
    652             }
    653 
    654             mPullExtractorPending = false;
    655 
    656             onPullExtractor();
    657             break;
    658         }
    659 
    660         default:
    661             TRESPASS();
    662     }
    663 }
    664 
    665 void WifiDisplaySource::PlaybackSession::onSinkFeedback(const sp<AMessage> &msg) {
    666     int64_t avgLatencyUs;
    667     CHECK(msg->findInt64("avgLatencyUs", &avgLatencyUs));
    668 
    669     int64_t maxLatencyUs;
    670     CHECK(msg->findInt64("maxLatencyUs", &maxLatencyUs));
    671 
    672     ALOGI("sink reports avg. latency of %lld ms (max %lld ms)",
    673           avgLatencyUs / 1000ll,
    674           maxLatencyUs / 1000ll);
    675 
    676     if (mVideoTrackIndex >= 0) {
    677         const sp<Track> &videoTrack = mTracks.valueFor(mVideoTrackIndex);
    678         sp<Converter> converter = videoTrack->converter();
    679 
    680         if (converter != NULL) {
    681             int32_t videoBitrate =
    682                 Converter::GetInt32Property("media.wfd.video-bitrate", -1);
    683 
    684             char val[PROPERTY_VALUE_MAX];
    685             if (videoBitrate < 0
    686                     && property_get("media.wfd.video-bitrate", val, NULL)
    687                     && !strcasecmp("adaptive", val)) {
    688                 videoBitrate = converter->getVideoBitrate();
    689 
    690                 if (avgLatencyUs > 300000ll) {
    691                     videoBitrate *= 0.6;
    692                 } else if (avgLatencyUs < 100000ll) {
    693                     videoBitrate *= 1.1;
    694                 }
    695             }
    696 
    697             if (videoBitrate > 0) {
    698                 if (videoBitrate < 500000) {
    699                     videoBitrate = 500000;
    700                 } else if (videoBitrate > 10000000) {
    701                     videoBitrate = 10000000;
    702                 }
    703 
    704                 if (videoBitrate != converter->getVideoBitrate()) {
    705                     ALOGI("setting video bitrate to %d bps", videoBitrate);
    706 
    707                     converter->setVideoBitrate(videoBitrate);
    708                 }
    709             }
    710         }
    711 
    712         sp<RepeaterSource> repeaterSource = videoTrack->repeaterSource();
    713         if (repeaterSource != NULL) {
    714             double rateHz =
    715                 Converter::GetInt32Property(
    716                         "media.wfd.video-framerate", -1);
    717 
    718             char val[PROPERTY_VALUE_MAX];
    719             if (rateHz < 0.0
    720                     && property_get("media.wfd.video-framerate", val, NULL)
    721                     && !strcasecmp("adaptive", val)) {
    722                  rateHz = repeaterSource->getFrameRate();
    723 
    724                 if (avgLatencyUs > 300000ll) {
    725                     rateHz *= 0.9;
    726                 } else if (avgLatencyUs < 200000ll) {
    727                     rateHz *= 1.1;
    728                 }
    729             }
    730 
    731             if (rateHz > 0) {
    732                 if (rateHz < 5.0) {
    733                     rateHz = 5.0;
    734                 } else if (rateHz > 30.0) {
    735                     rateHz = 30.0;
    736                 }
    737 
    738                 if (rateHz != repeaterSource->getFrameRate()) {
    739                     ALOGI("setting frame rate to %.2f Hz", rateHz);
    740 
    741                     repeaterSource->setFrameRate(rateHz);
    742                 }
    743             }
    744         }
    745     }
    746 }
    747 
    748 status_t WifiDisplaySource::PlaybackSession::setupMediaPacketizer(
    749         bool enableAudio, bool enableVideo) {
    750     mExtractor = new NuMediaExtractor;
    751 
    752     status_t err = mExtractor->setDataSource(
    753             NULL /* httpService */, mMediaPath.c_str());
    754 
    755     if (err != OK) {
    756         return err;
    757     }
    758 
    759     size_t n = mExtractor->countTracks();
    760     bool haveAudio = false;
    761     bool haveVideo = false;
    762     for (size_t i = 0; i < n; ++i) {
    763         sp<AMessage> format;
    764         err = mExtractor->getTrackFormat(i, &format);
    765 
    766         if (err != OK) {
    767             continue;
    768         }
    769 
    770         AString mime;
    771         CHECK(format->findString("mime", &mime));
    772 
    773         bool isAudio = !strncasecmp(mime.c_str(), "audio/", 6);
    774         bool isVideo = !strncasecmp(mime.c_str(), "video/", 6);
    775 
    776         if (isAudio && enableAudio && !haveAudio) {
    777             haveAudio = true;
    778         } else if (isVideo && enableVideo && !haveVideo) {
    779             haveVideo = true;
    780         } else {
    781             continue;
    782         }
    783 
    784         err = mExtractor->selectTrack(i);
    785 
    786         size_t trackIndex = mTracks.size();
    787 
    788         sp<AMessage> notify = new AMessage(kWhatTrackNotify, this);
    789         notify->setSize("trackIndex", trackIndex);
    790 
    791         sp<Track> track = new Track(notify, format);
    792         looper()->registerHandler(track);
    793 
    794         mTracks.add(trackIndex, track);
    795 
    796         mExtractorTrackToInternalTrack.add(i, trackIndex);
    797 
    798         if (isVideo) {
    799             mVideoTrackIndex = trackIndex;
    800         }
    801 
    802         uint32_t flags = MediaSender::FLAG_MANUALLY_PREPEND_SPS_PPS;
    803 
    804         ssize_t mediaSenderTrackIndex =
    805             mMediaSender->addTrack(format, flags);
    806         CHECK_GE(mediaSenderTrackIndex, 0);
    807 
    808         track->setMediaSenderTrackIndex(mediaSenderTrackIndex);
    809 
    810         if ((haveAudio || !enableAudio) && (haveVideo || !enableVideo)) {
    811             break;
    812         }
    813     }
    814 
    815     return OK;
    816 }
    817 
    818 void WifiDisplaySource::PlaybackSession::schedulePullExtractor() {
    819     if (mPullExtractorPending) {
    820         return;
    821     }
    822 
    823     int64_t delayUs = 1000000; // default delay is 1 sec
    824     int64_t sampleTimeUs;
    825     status_t err = mExtractor->getSampleTime(&sampleTimeUs);
    826 
    827     if (err == OK) {
    828         int64_t nowUs = ALooper::GetNowUs();
    829 
    830         if (mFirstSampleTimeRealUs < 0ll) {
    831             mFirstSampleTimeRealUs = nowUs;
    832             mFirstSampleTimeUs = sampleTimeUs;
    833         }
    834 
    835         int64_t whenUs = sampleTimeUs - mFirstSampleTimeUs + mFirstSampleTimeRealUs;
    836         delayUs = whenUs - nowUs;
    837     } else {
    838         ALOGW("could not get sample time (%d)", err);
    839     }
    840 
    841     sp<AMessage> msg = new AMessage(kWhatPullExtractorSample, this);
    842     msg->setInt32("generation", mPullExtractorGeneration);
    843     msg->post(delayUs);
    844 
    845     mPullExtractorPending = true;
    846 }
    847 
    848 void WifiDisplaySource::PlaybackSession::onPullExtractor() {
    849     sp<ABuffer> accessUnit = new ABuffer(1024 * 1024);
    850     status_t err = mExtractor->readSampleData(accessUnit);
    851     if (err != OK) {
    852         // EOS.
    853         return;
    854     }
    855 
    856     int64_t timeUs;
    857     CHECK_EQ((status_t)OK, mExtractor->getSampleTime(&timeUs));
    858 
    859     accessUnit->meta()->setInt64(
    860             "timeUs", mFirstSampleTimeRealUs + timeUs - mFirstSampleTimeUs);
    861 
    862     size_t trackIndex;
    863     CHECK_EQ((status_t)OK, mExtractor->getSampleTrackIndex(&trackIndex));
    864 
    865     sp<AMessage> msg = new AMessage(kWhatConverterNotify, this);
    866 
    867     msg->setSize(
    868             "trackIndex", mExtractorTrackToInternalTrack.valueFor(trackIndex));
    869 
    870     msg->setInt32("what", Converter::kWhatAccessUnit);
    871     msg->setBuffer("accessUnit", accessUnit);
    872     msg->post();
    873 
    874     mExtractor->advance();
    875 
    876     schedulePullExtractor();
    877 }
    878 
    879 status_t WifiDisplaySource::PlaybackSession::setupPacketizer(
    880         bool enableAudio,
    881         bool usePCMAudio,
    882         bool enableVideo,
    883         VideoFormats::ResolutionType videoResolutionType,
    884         size_t videoResolutionIndex,
    885         VideoFormats::ProfileType videoProfileType,
    886         VideoFormats::LevelType videoLevelType) {
    887     CHECK(enableAudio || enableVideo);
    888 
    889     if (!mMediaPath.empty()) {
    890         return setupMediaPacketizer(enableAudio, enableVideo);
    891     }
    892 
    893     if (enableVideo) {
    894         status_t err = addVideoSource(
    895                 videoResolutionType, videoResolutionIndex, videoProfileType,
    896                 videoLevelType);
    897 
    898         if (err != OK) {
    899             return err;
    900         }
    901     }
    902 
    903     if (!enableAudio) {
    904         return OK;
    905     }
    906 
    907     return addAudioSource(usePCMAudio);
    908 }
    909 
    910 status_t WifiDisplaySource::PlaybackSession::addSource(
    911         bool isVideo, const sp<MediaSource> &source, bool isRepeaterSource,
    912         bool usePCMAudio, unsigned profileIdc, unsigned levelIdc,
    913         unsigned constraintSet, size_t *numInputBuffers) {
    914     CHECK(!usePCMAudio || !isVideo);
    915     CHECK(!isRepeaterSource || isVideo);
    916     CHECK(!profileIdc || isVideo);
    917     CHECK(!levelIdc || isVideo);
    918     CHECK(!constraintSet || isVideo);
    919 
    920     sp<ALooper> pullLooper = new ALooper;
    921     pullLooper->setName("pull_looper");
    922 
    923     pullLooper->start(
    924             false /* runOnCallingThread */,
    925             false /* canCallJava */,
    926             PRIORITY_AUDIO);
    927 
    928     sp<ALooper> codecLooper = new ALooper;
    929     codecLooper->setName("codec_looper");
    930 
    931     codecLooper->start(
    932             false /* runOnCallingThread */,
    933             false /* canCallJava */,
    934             PRIORITY_AUDIO);
    935 
    936     size_t trackIndex;
    937 
    938     sp<AMessage> notify;
    939 
    940     trackIndex = mTracks.size();
    941 
    942     sp<AMessage> format;
    943     status_t err = convertMetaDataToMessage(source->getFormat(), &format);
    944     CHECK_EQ(err, (status_t)OK);
    945 
    946     if (isVideo) {
    947         format->setString("mime", MEDIA_MIMETYPE_VIDEO_AVC);
    948         format->setInt32(
    949                 "android._input-metadata-buffer-type", kMetadataBufferTypeANWBuffer);
    950         format->setInt32("android._store-metadata-in-buffers-output", (mHDCP != NULL)
    951                 && (mHDCP->getCaps() & HDCPModule::HDCP_CAPS_ENCRYPT_NATIVE));
    952         format->setInt32(
    953                 "color-format", OMX_COLOR_FormatAndroidOpaque);
    954         format->setInt32("profile-idc", profileIdc);
    955         format->setInt32("level-idc", levelIdc);
    956         format->setInt32("constraint-set", constraintSet);
    957     } else {
    958         if (usePCMAudio) {
    959             format->setInt32("pcm-encoding", kAudioEncodingPcm16bit);
    960             format->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
    961         } else {
    962             format->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
    963         }
    964     }
    965 
    966     notify = new AMessage(kWhatConverterNotify, this);
    967     notify->setSize("trackIndex", trackIndex);
    968 
    969     sp<Converter> converter = new Converter(notify, codecLooper, format);
    970 
    971     looper()->registerHandler(converter);
    972 
    973     err = converter->init();
    974     if (err != OK) {
    975         ALOGE("%s converter returned err %d", isVideo ? "video" : "audio", err);
    976 
    977         looper()->unregisterHandler(converter->id());
    978         return err;
    979     }
    980 
    981     notify = new AMessage(Converter::kWhatMediaPullerNotify, converter);
    982     notify->setSize("trackIndex", trackIndex);
    983 
    984     sp<MediaPuller> puller = new MediaPuller(source, notify);
    985     pullLooper->registerHandler(puller);
    986 
    987     if (numInputBuffers != NULL) {
    988         *numInputBuffers = converter->getInputBufferCount();
    989     }
    990 
    991     notify = new AMessage(kWhatTrackNotify, this);
    992     notify->setSize("trackIndex", trackIndex);
    993 
    994     sp<Track> track = new Track(
    995             notify, pullLooper, codecLooper, puller, converter);
    996 
    997     if (isRepeaterSource) {
    998         track->setRepeaterSource(static_cast<RepeaterSource *>(source.get()));
    999     }
   1000 
   1001     looper()->registerHandler(track);
   1002 
   1003     mTracks.add(trackIndex, track);
   1004 
   1005     if (isVideo) {
   1006         mVideoTrackIndex = trackIndex;
   1007     }
   1008 
   1009     uint32_t flags = 0;
   1010     if (converter->needToManuallyPrependSPSPPS()) {
   1011         flags |= MediaSender::FLAG_MANUALLY_PREPEND_SPS_PPS;
   1012     }
   1013 
   1014     ssize_t mediaSenderTrackIndex =
   1015         mMediaSender->addTrack(converter->getOutputFormat(), flags);
   1016     CHECK_GE(mediaSenderTrackIndex, 0);
   1017 
   1018     track->setMediaSenderTrackIndex(mediaSenderTrackIndex);
   1019 
   1020     return OK;
   1021 }
   1022 
   1023 status_t WifiDisplaySource::PlaybackSession::addVideoSource(
   1024         VideoFormats::ResolutionType videoResolutionType,
   1025         size_t videoResolutionIndex,
   1026         VideoFormats::ProfileType videoProfileType,
   1027         VideoFormats::LevelType videoLevelType) {
   1028     size_t width, height, framesPerSecond;
   1029     bool interlaced;
   1030     CHECK(VideoFormats::GetConfiguration(
   1031                 videoResolutionType,
   1032                 videoResolutionIndex,
   1033                 &width,
   1034                 &height,
   1035                 &framesPerSecond,
   1036                 &interlaced));
   1037 
   1038     unsigned profileIdc, levelIdc, constraintSet;
   1039     CHECK(VideoFormats::GetProfileLevel(
   1040                 videoProfileType,
   1041                 videoLevelType,
   1042                 &profileIdc,
   1043                 &levelIdc,
   1044                 &constraintSet));
   1045 
   1046     sp<SurfaceMediaSource> source = new SurfaceMediaSource(width, height);
   1047 
   1048     source->setUseAbsoluteTimestamps();
   1049 
   1050     sp<RepeaterSource> videoSource =
   1051         new RepeaterSource(source, framesPerSecond);
   1052 
   1053     size_t numInputBuffers;
   1054     status_t err = addSource(
   1055             true /* isVideo */, videoSource, true /* isRepeaterSource */,
   1056             false /* usePCMAudio */, profileIdc, levelIdc, constraintSet,
   1057             &numInputBuffers);
   1058 
   1059     if (err != OK) {
   1060         return err;
   1061     }
   1062 
   1063     err = source->setMaxAcquiredBufferCount(numInputBuffers);
   1064     CHECK_EQ(err, (status_t)OK);
   1065 
   1066     mProducer = source->getProducer();
   1067 
   1068     return OK;
   1069 }
   1070 
   1071 status_t WifiDisplaySource::PlaybackSession::addAudioSource(bool usePCMAudio) {
   1072     sp<AudioSource> audioSource = new AudioSource(
   1073             AUDIO_SOURCE_REMOTE_SUBMIX,
   1074             mOpPackageName,
   1075             48000 /* sampleRate */,
   1076             2 /* channelCount */);
   1077 
   1078     if (audioSource->initCheck() == OK) {
   1079         return addSource(
   1080                 false /* isVideo */, audioSource, false /* isRepeaterSource */,
   1081                 usePCMAudio, 0 /* profileIdc */, 0 /* levelIdc */,
   1082                 0 /* constraintSet */, NULL /* numInputBuffers */);
   1083     }
   1084 
   1085     ALOGW("Unable to instantiate audio source");
   1086 
   1087     return OK;
   1088 }
   1089 
   1090 sp<IGraphicBufferProducer> WifiDisplaySource::PlaybackSession::getSurfaceTexture() {
   1091     return mProducer;
   1092 }
   1093 
   1094 void WifiDisplaySource::PlaybackSession::requestIDRFrame() {
   1095     for (size_t i = 0; i < mTracks.size(); ++i) {
   1096         const sp<Track> &track = mTracks.valueAt(i);
   1097 
   1098         track->requestIDRFrame();
   1099     }
   1100 }
   1101 
   1102 void WifiDisplaySource::PlaybackSession::notifySessionDead() {
   1103     // Inform WifiDisplaySource of our premature death (wish).
   1104     sp<AMessage> notify = mNotify->dup();
   1105     notify->setInt32("what", kWhatSessionDead);
   1106     notify->post();
   1107 
   1108     mWeAreDead = true;
   1109 }
   1110 
   1111 }  // namespace android
   1112 
   1113