Home | History | Annotate | Download | only in libstagefright
      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 "MediaCodec"
     19 #include <inttypes.h>
     20 
     21 #include "include/avc_utils.h"
     22 #include "include/SoftwareRenderer.h"
     23 
     24 #include <binder/IBatteryStats.h>
     25 #include <binder/IServiceManager.h>
     26 #include <gui/Surface.h>
     27 #include <media/ICrypto.h>
     28 #include <media/stagefright/foundation/ABuffer.h>
     29 #include <media/stagefright/foundation/ADebug.h>
     30 #include <media/stagefright/foundation/AMessage.h>
     31 #include <media/stagefright/foundation/AString.h>
     32 #include <media/stagefright/foundation/hexdump.h>
     33 #include <media/stagefright/ACodec.h>
     34 #include <media/stagefright/BufferProducerWrapper.h>
     35 #include <media/stagefright/MediaCodec.h>
     36 #include <media/stagefright/MediaCodecList.h>
     37 #include <media/stagefright/MediaDefs.h>
     38 #include <media/stagefright/MediaErrors.h>
     39 #include <media/stagefright/MetaData.h>
     40 #include <media/stagefright/NativeWindowWrapper.h>
     41 #include <private/android_filesystem_config.h>
     42 #include <utils/Log.h>
     43 #include <utils/Singleton.h>
     44 
     45 namespace android {
     46 
     47 struct MediaCodec::BatteryNotifier : public Singleton<BatteryNotifier> {
     48     BatteryNotifier();
     49 
     50     void noteStartVideo();
     51     void noteStopVideo();
     52     void noteStartAudio();
     53     void noteStopAudio();
     54 
     55 private:
     56     int32_t mVideoRefCount;
     57     int32_t mAudioRefCount;
     58     sp<IBatteryStats> mBatteryStatService;
     59 };
     60 
     61 ANDROID_SINGLETON_STATIC_INSTANCE(MediaCodec::BatteryNotifier)
     62 
     63 MediaCodec::BatteryNotifier::BatteryNotifier() :
     64     mVideoRefCount(0),
     65     mAudioRefCount(0) {
     66     // get battery service
     67     const sp<IServiceManager> sm(defaultServiceManager());
     68     if (sm != NULL) {
     69         const String16 name("batterystats");
     70         mBatteryStatService = interface_cast<IBatteryStats>(sm->getService(name));
     71         if (mBatteryStatService == NULL) {
     72             ALOGE("batterystats service unavailable!");
     73         }
     74     }
     75 }
     76 
     77 void MediaCodec::BatteryNotifier::noteStartVideo() {
     78     if (mVideoRefCount == 0 && mBatteryStatService != NULL) {
     79         mBatteryStatService->noteStartVideo(AID_MEDIA);
     80     }
     81     mVideoRefCount++;
     82 }
     83 
     84 void MediaCodec::BatteryNotifier::noteStopVideo() {
     85     if (mVideoRefCount == 0) {
     86         ALOGW("BatteryNotifier::noteStop(): video refcount is broken!");
     87         return;
     88     }
     89 
     90     mVideoRefCount--;
     91     if (mVideoRefCount == 0 && mBatteryStatService != NULL) {
     92         mBatteryStatService->noteStopVideo(AID_MEDIA);
     93     }
     94 }
     95 
     96 void MediaCodec::BatteryNotifier::noteStartAudio() {
     97     if (mAudioRefCount == 0 && mBatteryStatService != NULL) {
     98         mBatteryStatService->noteStartAudio(AID_MEDIA);
     99     }
    100     mAudioRefCount++;
    101 }
    102 
    103 void MediaCodec::BatteryNotifier::noteStopAudio() {
    104     if (mAudioRefCount == 0) {
    105         ALOGW("BatteryNotifier::noteStop(): audio refcount is broken!");
    106         return;
    107     }
    108 
    109     mAudioRefCount--;
    110     if (mAudioRefCount == 0 && mBatteryStatService != NULL) {
    111         mBatteryStatService->noteStopAudio(AID_MEDIA);
    112     }
    113 }
    114 // static
    115 sp<MediaCodec> MediaCodec::CreateByType(
    116         const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err) {
    117     sp<MediaCodec> codec = new MediaCodec(looper);
    118 
    119     const status_t ret = codec->init(mime, true /* nameIsType */, encoder);
    120     if (err != NULL) {
    121         *err = ret;
    122     }
    123     return ret == OK ? codec : NULL; // NULL deallocates codec.
    124 }
    125 
    126 // static
    127 sp<MediaCodec> MediaCodec::CreateByComponentName(
    128         const sp<ALooper> &looper, const char *name, status_t *err) {
    129     sp<MediaCodec> codec = new MediaCodec(looper);
    130 
    131     const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */);
    132     if (err != NULL) {
    133         *err = ret;
    134     }
    135     return ret == OK ? codec : NULL; // NULL deallocates codec.
    136 }
    137 
    138 MediaCodec::MediaCodec(const sp<ALooper> &looper)
    139     : mState(UNINITIALIZED),
    140       mLooper(looper),
    141       mCodec(NULL),
    142       mReplyID(0),
    143       mFlags(0),
    144       mStickyError(OK),
    145       mSoftRenderer(NULL),
    146       mBatteryStatNotified(false),
    147       mIsVideo(false),
    148       mDequeueInputTimeoutGeneration(0),
    149       mDequeueInputReplyID(0),
    150       mDequeueOutputTimeoutGeneration(0),
    151       mDequeueOutputReplyID(0),
    152       mHaveInputSurface(false) {
    153 }
    154 
    155 MediaCodec::~MediaCodec() {
    156     CHECK_EQ(mState, UNINITIALIZED);
    157 }
    158 
    159 // static
    160 status_t MediaCodec::PostAndAwaitResponse(
    161         const sp<AMessage> &msg, sp<AMessage> *response) {
    162     status_t err = msg->postAndAwaitResponse(response);
    163 
    164     if (err != OK) {
    165         return err;
    166     }
    167 
    168     if (!(*response)->findInt32("err", &err)) {
    169         err = OK;
    170     }
    171 
    172     return err;
    173 }
    174 
    175 // static
    176 void MediaCodec::PostReplyWithError(int32_t replyID, int32_t err) {
    177     sp<AMessage> response = new AMessage;
    178     response->setInt32("err", err);
    179     response->postReply(replyID);
    180 }
    181 
    182 status_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) {
    183     // save init parameters for reset
    184     mInitName = name;
    185     mInitNameIsType = nameIsType;
    186     mInitIsEncoder = encoder;
    187 
    188     // Current video decoders do not return from OMX_FillThisBuffer
    189     // quickly, violating the OpenMAX specs, until that is remedied
    190     // we need to invest in an extra looper to free the main event
    191     // queue.
    192     mCodec = new ACodec;
    193     bool needDedicatedLooper = false;
    194     if (nameIsType && !strncasecmp(name.c_str(), "video/", 6)) {
    195         needDedicatedLooper = true;
    196     } else {
    197         AString tmp = name;
    198         if (tmp.endsWith(".secure")) {
    199             tmp.erase(tmp.size() - 7, 7);
    200         }
    201         const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
    202         ssize_t codecIdx = mcl->findCodecByName(tmp.c_str());
    203         if (codecIdx >= 0) {
    204             const sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx);
    205             Vector<AString> mimes;
    206             info->getSupportedMimes(&mimes);
    207             for (size_t i = 0; i < mimes.size(); i++) {
    208                 if (mimes[i].startsWith("video/")) {
    209                     needDedicatedLooper = true;
    210                     break;
    211                 }
    212             }
    213         }
    214     }
    215 
    216     if (needDedicatedLooper) {
    217         if (mCodecLooper == NULL) {
    218             mCodecLooper = new ALooper;
    219             mCodecLooper->setName("CodecLooper");
    220             mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
    221         }
    222 
    223         mCodecLooper->registerHandler(mCodec);
    224     } else {
    225         mLooper->registerHandler(mCodec);
    226     }
    227 
    228     mLooper->registerHandler(this);
    229 
    230     mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, id()));
    231 
    232     sp<AMessage> msg = new AMessage(kWhatInit, id());
    233     msg->setString("name", name);
    234     msg->setInt32("nameIsType", nameIsType);
    235 
    236     if (nameIsType) {
    237         msg->setInt32("encoder", encoder);
    238     }
    239 
    240     sp<AMessage> response;
    241     return PostAndAwaitResponse(msg, &response);
    242 }
    243 
    244 status_t MediaCodec::setCallback(const sp<AMessage> &callback) {
    245     sp<AMessage> msg = new AMessage(kWhatSetCallback, id());
    246     msg->setMessage("callback", callback);
    247 
    248     sp<AMessage> response;
    249     return PostAndAwaitResponse(msg, &response);
    250 }
    251 
    252 status_t MediaCodec::configure(
    253         const sp<AMessage> &format,
    254         const sp<Surface> &nativeWindow,
    255         const sp<ICrypto> &crypto,
    256         uint32_t flags) {
    257     sp<AMessage> msg = new AMessage(kWhatConfigure, id());
    258 
    259     msg->setMessage("format", format);
    260     msg->setInt32("flags", flags);
    261 
    262     if (nativeWindow != NULL) {
    263         msg->setObject(
    264                 "native-window",
    265                 new NativeWindowWrapper(nativeWindow));
    266     }
    267 
    268     if (crypto != NULL) {
    269         msg->setPointer("crypto", crypto.get());
    270     }
    271 
    272     sp<AMessage> response;
    273     status_t err = PostAndAwaitResponse(msg, &response);
    274 
    275     if (err != OK && err != INVALID_OPERATION) {
    276         // MediaCodec now set state to UNINITIALIZED upon any fatal error.
    277         // To maintain backward-compatibility, do a reset() to put codec
    278         // back into INITIALIZED state.
    279         // But don't reset if the err is INVALID_OPERATION, which means
    280         // the configure failure is due to wrong state.
    281 
    282         ALOGE("configure failed with err 0x%08x, resetting...", err);
    283         reset();
    284     }
    285 
    286     return err;
    287 }
    288 
    289 status_t MediaCodec::createInputSurface(
    290         sp<IGraphicBufferProducer>* bufferProducer) {
    291     sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, id());
    292 
    293     sp<AMessage> response;
    294     status_t err = PostAndAwaitResponse(msg, &response);
    295     if (err == NO_ERROR) {
    296         // unwrap the sp<IGraphicBufferProducer>
    297         sp<RefBase> obj;
    298         bool found = response->findObject("input-surface", &obj);
    299         CHECK(found);
    300         sp<BufferProducerWrapper> wrapper(
    301                 static_cast<BufferProducerWrapper*>(obj.get()));
    302         *bufferProducer = wrapper->getBufferProducer();
    303     } else {
    304         ALOGW("createInputSurface failed, err=%d", err);
    305     }
    306     return err;
    307 }
    308 
    309 status_t MediaCodec::start() {
    310     sp<AMessage> msg = new AMessage(kWhatStart, id());
    311 
    312     sp<AMessage> response;
    313     return PostAndAwaitResponse(msg, &response);
    314 }
    315 
    316 status_t MediaCodec::stop() {
    317     sp<AMessage> msg = new AMessage(kWhatStop, id());
    318 
    319     sp<AMessage> response;
    320     return PostAndAwaitResponse(msg, &response);
    321 }
    322 
    323 status_t MediaCodec::release() {
    324     sp<AMessage> msg = new AMessage(kWhatRelease, id());
    325 
    326     sp<AMessage> response;
    327     return PostAndAwaitResponse(msg, &response);
    328 }
    329 
    330 status_t MediaCodec::reset() {
    331     /* When external-facing MediaCodec object is created,
    332        it is already initialized.  Thus, reset is essentially
    333        release() followed by init(), plus clearing the state */
    334 
    335     status_t err = release();
    336 
    337     // unregister handlers
    338     if (mCodec != NULL) {
    339         if (mCodecLooper != NULL) {
    340             mCodecLooper->unregisterHandler(mCodec->id());
    341         } else {
    342             mLooper->unregisterHandler(mCodec->id());
    343         }
    344         mCodec = NULL;
    345     }
    346     mLooper->unregisterHandler(id());
    347 
    348     mFlags = 0;    // clear all flags
    349     mStickyError = OK;
    350 
    351     // reset state not reset by setState(UNINITIALIZED)
    352     mReplyID = 0;
    353     mDequeueInputReplyID = 0;
    354     mDequeueOutputReplyID = 0;
    355     mDequeueInputTimeoutGeneration = 0;
    356     mDequeueOutputTimeoutGeneration = 0;
    357     mHaveInputSurface = false;
    358 
    359     if (err == OK) {
    360         err = init(mInitName, mInitNameIsType, mInitIsEncoder);
    361     }
    362     return err;
    363 }
    364 
    365 status_t MediaCodec::queueInputBuffer(
    366         size_t index,
    367         size_t offset,
    368         size_t size,
    369         int64_t presentationTimeUs,
    370         uint32_t flags,
    371         AString *errorDetailMsg) {
    372     if (errorDetailMsg != NULL) {
    373         errorDetailMsg->clear();
    374     }
    375 
    376     sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
    377     msg->setSize("index", index);
    378     msg->setSize("offset", offset);
    379     msg->setSize("size", size);
    380     msg->setInt64("timeUs", presentationTimeUs);
    381     msg->setInt32("flags", flags);
    382     msg->setPointer("errorDetailMsg", errorDetailMsg);
    383 
    384     sp<AMessage> response;
    385     return PostAndAwaitResponse(msg, &response);
    386 }
    387 
    388 status_t MediaCodec::queueSecureInputBuffer(
    389         size_t index,
    390         size_t offset,
    391         const CryptoPlugin::SubSample *subSamples,
    392         size_t numSubSamples,
    393         const uint8_t key[16],
    394         const uint8_t iv[16],
    395         CryptoPlugin::Mode mode,
    396         int64_t presentationTimeUs,
    397         uint32_t flags,
    398         AString *errorDetailMsg) {
    399     if (errorDetailMsg != NULL) {
    400         errorDetailMsg->clear();
    401     }
    402 
    403     sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
    404     msg->setSize("index", index);
    405     msg->setSize("offset", offset);
    406     msg->setPointer("subSamples", (void *)subSamples);
    407     msg->setSize("numSubSamples", numSubSamples);
    408     msg->setPointer("key", (void *)key);
    409     msg->setPointer("iv", (void *)iv);
    410     msg->setInt32("mode", mode);
    411     msg->setInt64("timeUs", presentationTimeUs);
    412     msg->setInt32("flags", flags);
    413     msg->setPointer("errorDetailMsg", errorDetailMsg);
    414 
    415     sp<AMessage> response;
    416     status_t err = PostAndAwaitResponse(msg, &response);
    417 
    418     return err;
    419 }
    420 
    421 status_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
    422     sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, id());
    423     msg->setInt64("timeoutUs", timeoutUs);
    424 
    425     sp<AMessage> response;
    426     status_t err;
    427     if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
    428         return err;
    429     }
    430 
    431     CHECK(response->findSize("index", index));
    432 
    433     return OK;
    434 }
    435 
    436 status_t MediaCodec::dequeueOutputBuffer(
    437         size_t *index,
    438         size_t *offset,
    439         size_t *size,
    440         int64_t *presentationTimeUs,
    441         uint32_t *flags,
    442         int64_t timeoutUs) {
    443     sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, id());
    444     msg->setInt64("timeoutUs", timeoutUs);
    445 
    446     sp<AMessage> response;
    447     status_t err;
    448     if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
    449         return err;
    450     }
    451 
    452     CHECK(response->findSize("index", index));
    453     CHECK(response->findSize("offset", offset));
    454     CHECK(response->findSize("size", size));
    455     CHECK(response->findInt64("timeUs", presentationTimeUs));
    456     CHECK(response->findInt32("flags", (int32_t *)flags));
    457 
    458     return OK;
    459 }
    460 
    461 status_t MediaCodec::renderOutputBufferAndRelease(size_t index) {
    462     sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
    463     msg->setSize("index", index);
    464     msg->setInt32("render", true);
    465 
    466     sp<AMessage> response;
    467     return PostAndAwaitResponse(msg, &response);
    468 }
    469 
    470 status_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestampNs) {
    471     sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
    472     msg->setSize("index", index);
    473     msg->setInt32("render", true);
    474     msg->setInt64("timestampNs", timestampNs);
    475 
    476     sp<AMessage> response;
    477     return PostAndAwaitResponse(msg, &response);
    478 }
    479 
    480 status_t MediaCodec::releaseOutputBuffer(size_t index) {
    481     sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
    482     msg->setSize("index", index);
    483 
    484     sp<AMessage> response;
    485     return PostAndAwaitResponse(msg, &response);
    486 }
    487 
    488 status_t MediaCodec::signalEndOfInputStream() {
    489     sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, id());
    490 
    491     sp<AMessage> response;
    492     return PostAndAwaitResponse(msg, &response);
    493 }
    494 
    495 status_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
    496     sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, id());
    497 
    498     sp<AMessage> response;
    499     status_t err;
    500     if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
    501         return err;
    502     }
    503 
    504     CHECK(response->findMessage("format", format));
    505 
    506     return OK;
    507 }
    508 
    509 status_t MediaCodec::getInputFormat(sp<AMessage> *format) const {
    510     sp<AMessage> msg = new AMessage(kWhatGetInputFormat, id());
    511 
    512     sp<AMessage> response;
    513     status_t err;
    514     if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
    515         return err;
    516     }
    517 
    518     CHECK(response->findMessage("format", format));
    519 
    520     return OK;
    521 }
    522 
    523 status_t MediaCodec::getName(AString *name) const {
    524     sp<AMessage> msg = new AMessage(kWhatGetName, id());
    525 
    526     sp<AMessage> response;
    527     status_t err;
    528     if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
    529         return err;
    530     }
    531 
    532     CHECK(response->findString("name", name));
    533 
    534     return OK;
    535 }
    536 
    537 status_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
    538     sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
    539     msg->setInt32("portIndex", kPortIndexInput);
    540     msg->setPointer("buffers", buffers);
    541 
    542     sp<AMessage> response;
    543     return PostAndAwaitResponse(msg, &response);
    544 }
    545 
    546 status_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const {
    547     sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
    548     msg->setInt32("portIndex", kPortIndexOutput);
    549     msg->setPointer("buffers", buffers);
    550 
    551     sp<AMessage> response;
    552     return PostAndAwaitResponse(msg, &response);
    553 }
    554 
    555 status_t MediaCodec::getOutputBuffer(size_t index, sp<ABuffer> *buffer) {
    556     sp<AMessage> format;
    557     return getBufferAndFormat(kPortIndexOutput, index, buffer, &format);
    558 }
    559 
    560 status_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) {
    561     sp<ABuffer> buffer;
    562     return getBufferAndFormat(kPortIndexOutput, index, &buffer, format);
    563 }
    564 
    565 status_t MediaCodec::getInputBuffer(size_t index, sp<ABuffer> *buffer) {
    566     sp<AMessage> format;
    567     return getBufferAndFormat(kPortIndexInput, index, buffer, &format);
    568 }
    569 
    570 bool MediaCodec::isExecuting() const {
    571     return mState == STARTED || mState == FLUSHED;
    572 }
    573 
    574 status_t MediaCodec::getBufferAndFormat(
    575         size_t portIndex, size_t index,
    576         sp<ABuffer> *buffer, sp<AMessage> *format) {
    577     // use mutex instead of a context switch
    578 
    579     buffer->clear();
    580     format->clear();
    581     if (!isExecuting()) {
    582         return INVALID_OPERATION;
    583     }
    584 
    585     // we do not want mPortBuffers to change during this section
    586     // we also don't want mOwnedByClient to change during this
    587     Mutex::Autolock al(mBufferLock);
    588     Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
    589     if (index < buffers->size()) {
    590         const BufferInfo &info = buffers->itemAt(index);
    591         if (info.mOwnedByClient) {
    592             // by the time buffers array is initialized, crypto is set
    593             if (portIndex == kPortIndexInput && mCrypto != NULL) {
    594                 *buffer = info.mEncryptedData;
    595             } else {
    596                 *buffer = info.mData;
    597             }
    598             *format = info.mFormat;
    599         }
    600     }
    601     return OK;
    602 }
    603 
    604 status_t MediaCodec::flush() {
    605     sp<AMessage> msg = new AMessage(kWhatFlush, id());
    606 
    607     sp<AMessage> response;
    608     return PostAndAwaitResponse(msg, &response);
    609 }
    610 
    611 status_t MediaCodec::requestIDRFrame() {
    612     (new AMessage(kWhatRequestIDRFrame, id()))->post();
    613 
    614     return OK;
    615 }
    616 
    617 void MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
    618     sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, id());
    619     msg->setMessage("notify", notify);
    620     msg->post();
    621 }
    622 
    623 ////////////////////////////////////////////////////////////////////////////////
    624 
    625 void MediaCodec::cancelPendingDequeueOperations() {
    626     if (mFlags & kFlagDequeueInputPending) {
    627         PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION);
    628 
    629         ++mDequeueInputTimeoutGeneration;
    630         mDequeueInputReplyID = 0;
    631         mFlags &= ~kFlagDequeueInputPending;
    632     }
    633 
    634     if (mFlags & kFlagDequeueOutputPending) {
    635         PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION);
    636 
    637         ++mDequeueOutputTimeoutGeneration;
    638         mDequeueOutputReplyID = 0;
    639         mFlags &= ~kFlagDequeueOutputPending;
    640     }
    641 }
    642 
    643 bool MediaCodec::handleDequeueInputBuffer(uint32_t replyID, bool newRequest) {
    644     if (!isExecuting() || (mFlags & kFlagIsAsync)
    645             || (newRequest && (mFlags & kFlagDequeueInputPending))) {
    646         PostReplyWithError(replyID, INVALID_OPERATION);
    647         return true;
    648     } else if (mFlags & kFlagStickyError) {
    649         PostReplyWithError(replyID, getStickyError());
    650         return true;
    651     }
    652 
    653     ssize_t index = dequeuePortBuffer(kPortIndexInput);
    654 
    655     if (index < 0) {
    656         CHECK_EQ(index, -EAGAIN);
    657         return false;
    658     }
    659 
    660     sp<AMessage> response = new AMessage;
    661     response->setSize("index", index);
    662     response->postReply(replyID);
    663 
    664     return true;
    665 }
    666 
    667 bool MediaCodec::handleDequeueOutputBuffer(uint32_t replyID, bool newRequest) {
    668     sp<AMessage> response = new AMessage;
    669 
    670     if (!isExecuting() || (mFlags & kFlagIsAsync)
    671             || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
    672         response->setInt32("err", INVALID_OPERATION);
    673     } else if (mFlags & kFlagStickyError) {
    674         response->setInt32("err", getStickyError());
    675     } else if (mFlags & kFlagOutputBuffersChanged) {
    676         response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED);
    677         mFlags &= ~kFlagOutputBuffersChanged;
    678     } else if (mFlags & kFlagOutputFormatChanged) {
    679         response->setInt32("err", INFO_FORMAT_CHANGED);
    680         mFlags &= ~kFlagOutputFormatChanged;
    681     } else {
    682         ssize_t index = dequeuePortBuffer(kPortIndexOutput);
    683 
    684         if (index < 0) {
    685             CHECK_EQ(index, -EAGAIN);
    686             return false;
    687         }
    688 
    689         const sp<ABuffer> &buffer =
    690             mPortBuffers[kPortIndexOutput].itemAt(index).mData;
    691 
    692         response->setSize("index", index);
    693         response->setSize("offset", buffer->offset());
    694         response->setSize("size", buffer->size());
    695 
    696         int64_t timeUs;
    697         CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
    698 
    699         response->setInt64("timeUs", timeUs);
    700 
    701         int32_t omxFlags;
    702         CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
    703 
    704         uint32_t flags = 0;
    705         if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
    706             flags |= BUFFER_FLAG_SYNCFRAME;
    707         }
    708         if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
    709             flags |= BUFFER_FLAG_CODECCONFIG;
    710         }
    711         if (omxFlags & OMX_BUFFERFLAG_EOS) {
    712             flags |= BUFFER_FLAG_EOS;
    713         }
    714 
    715         response->setInt32("flags", flags);
    716     }
    717 
    718     response->postReply(replyID);
    719 
    720     return true;
    721 }
    722 
    723 void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
    724     switch (msg->what()) {
    725         case kWhatCodecNotify:
    726         {
    727             int32_t what;
    728             CHECK(msg->findInt32("what", &what));
    729 
    730             switch (what) {
    731                 case CodecBase::kWhatError:
    732                 {
    733                     int32_t err, actionCode;
    734                     CHECK(msg->findInt32("err", &err));
    735                     CHECK(msg->findInt32("actionCode", &actionCode));
    736 
    737                     ALOGE("Codec reported err %#x, actionCode %d, while in state %d",
    738                             err, actionCode, mState);
    739                     if (err == DEAD_OBJECT) {
    740                         mFlags |= kFlagSawMediaServerDie;
    741                         mFlags &= ~kFlagIsComponentAllocated;
    742                     }
    743 
    744                     bool sendErrorResponse = true;
    745 
    746                     switch (mState) {
    747                         case INITIALIZING:
    748                         {
    749                             setState(UNINITIALIZED);
    750                             break;
    751                         }
    752 
    753                         case CONFIGURING:
    754                         {
    755                             setState(actionCode == ACTION_CODE_FATAL ?
    756                                     UNINITIALIZED : INITIALIZED);
    757                             break;
    758                         }
    759 
    760                         case STARTING:
    761                         {
    762                             setState(actionCode == ACTION_CODE_FATAL ?
    763                                     UNINITIALIZED : CONFIGURED);
    764                             break;
    765                         }
    766 
    767                         case STOPPING:
    768                         case RELEASING:
    769                         {
    770                             // Ignore the error, assuming we'll still get
    771                             // the shutdown complete notification.
    772 
    773                             sendErrorResponse = false;
    774 
    775                             if (mFlags & kFlagSawMediaServerDie) {
    776                                 // MediaServer died, there definitely won't
    777                                 // be a shutdown complete notification after
    778                                 // all.
    779 
    780                                 // note that we're directly going from
    781                                 // STOPPING->UNINITIALIZED, instead of the
    782                                 // usual STOPPING->INITIALIZED state.
    783                                 setState(UNINITIALIZED);
    784                                 if (mState == RELEASING) {
    785                                     mComponentName.clear();
    786                                 }
    787                                 (new AMessage)->postReply(mReplyID);
    788                             }
    789                             break;
    790                         }
    791 
    792                         case FLUSHING:
    793                         {
    794                             if (actionCode == ACTION_CODE_FATAL) {
    795                                 setState(UNINITIALIZED);
    796                             } else {
    797                                 setState(
    798                                         (mFlags & kFlagIsAsync) ? FLUSHED : STARTED);
    799                             }
    800                             break;
    801                         }
    802 
    803                         case FLUSHED:
    804                         case STARTED:
    805                         {
    806                             sendErrorResponse = false;
    807 
    808                             setStickyError(err);
    809                             postActivityNotificationIfPossible();
    810 
    811                             cancelPendingDequeueOperations();
    812 
    813                             if (mFlags & kFlagIsAsync) {
    814                                 onError(err, actionCode);
    815                             }
    816                             switch (actionCode) {
    817                             case ACTION_CODE_TRANSIENT:
    818                                 break;
    819                             case ACTION_CODE_RECOVERABLE:
    820                                 setState(INITIALIZED);
    821                                 break;
    822                             default:
    823                                 setState(UNINITIALIZED);
    824                                 break;
    825                             }
    826                             break;
    827                         }
    828 
    829                         default:
    830                         {
    831                             sendErrorResponse = false;
    832 
    833                             setStickyError(err);
    834                             postActivityNotificationIfPossible();
    835 
    836                             // actionCode in an uninitialized state is always fatal.
    837                             if (mState == UNINITIALIZED) {
    838                                 actionCode = ACTION_CODE_FATAL;
    839                             }
    840                             if (mFlags & kFlagIsAsync) {
    841                                 onError(err, actionCode);
    842                             }
    843                             switch (actionCode) {
    844                             case ACTION_CODE_TRANSIENT:
    845                                 break;
    846                             case ACTION_CODE_RECOVERABLE:
    847                                 setState(INITIALIZED);
    848                                 break;
    849                             default:
    850                                 setState(UNINITIALIZED);
    851                                 break;
    852                             }
    853                             break;
    854                         }
    855                     }
    856 
    857                     if (sendErrorResponse) {
    858                         PostReplyWithError(mReplyID, err);
    859                     }
    860                     break;
    861                 }
    862 
    863                 case CodecBase::kWhatComponentAllocated:
    864                 {
    865                     CHECK_EQ(mState, INITIALIZING);
    866                     setState(INITIALIZED);
    867                     mFlags |= kFlagIsComponentAllocated;
    868 
    869                     CHECK(msg->findString("componentName", &mComponentName));
    870 
    871                     if (mComponentName.startsWith("OMX.google.")) {
    872                         mFlags |= kFlagUsesSoftwareRenderer;
    873                     } else {
    874                         mFlags &= ~kFlagUsesSoftwareRenderer;
    875                     }
    876 
    877                     if (mComponentName.endsWith(".secure")) {
    878                         mFlags |= kFlagIsSecure;
    879                     } else {
    880                         mFlags &= ~kFlagIsSecure;
    881                     }
    882 
    883                     (new AMessage)->postReply(mReplyID);
    884                     break;
    885                 }
    886 
    887                 case CodecBase::kWhatComponentConfigured:
    888                 {
    889                     CHECK_EQ(mState, CONFIGURING);
    890 
    891                     // reset input surface flag
    892                     mHaveInputSurface = false;
    893 
    894                     CHECK(msg->findMessage("input-format", &mInputFormat));
    895                     CHECK(msg->findMessage("output-format", &mOutputFormat));
    896 
    897                     int32_t usingSwRenderer;
    898                     if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer)
    899                             && usingSwRenderer) {
    900                         mFlags |= kFlagUsesSoftwareRenderer;
    901                     }
    902                     setState(CONFIGURED);
    903                     (new AMessage)->postReply(mReplyID);
    904                     break;
    905                 }
    906 
    907                 case CodecBase::kWhatInputSurfaceCreated:
    908                 {
    909                     // response to initiateCreateInputSurface()
    910                     status_t err = NO_ERROR;
    911                     sp<AMessage> response = new AMessage();
    912                     if (!msg->findInt32("err", &err)) {
    913                         sp<RefBase> obj;
    914                         msg->findObject("input-surface", &obj);
    915                         CHECK(obj != NULL);
    916                         response->setObject("input-surface", obj);
    917                         mHaveInputSurface = true;
    918                     } else {
    919                         response->setInt32("err", err);
    920                     }
    921                     response->postReply(mReplyID);
    922                     break;
    923                 }
    924 
    925                 case CodecBase::kWhatSignaledInputEOS:
    926                 {
    927                     // response to signalEndOfInputStream()
    928                     sp<AMessage> response = new AMessage();
    929                     status_t err;
    930                     if (msg->findInt32("err", &err)) {
    931                         response->setInt32("err", err);
    932                     }
    933                     response->postReply(mReplyID);
    934                     break;
    935                 }
    936 
    937 
    938                 case CodecBase::kWhatBuffersAllocated:
    939                 {
    940                     Mutex::Autolock al(mBufferLock);
    941                     int32_t portIndex;
    942                     CHECK(msg->findInt32("portIndex", &portIndex));
    943 
    944                     ALOGV("%s buffers allocated",
    945                           portIndex == kPortIndexInput ? "input" : "output");
    946 
    947                     CHECK(portIndex == kPortIndexInput
    948                             || portIndex == kPortIndexOutput);
    949 
    950                     mPortBuffers[portIndex].clear();
    951 
    952                     Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
    953 
    954                     sp<RefBase> obj;
    955                     CHECK(msg->findObject("portDesc", &obj));
    956 
    957                     sp<CodecBase::PortDescription> portDesc =
    958                         static_cast<CodecBase::PortDescription *>(obj.get());
    959 
    960                     size_t numBuffers = portDesc->countBuffers();
    961 
    962                     for (size_t i = 0; i < numBuffers; ++i) {
    963                         BufferInfo info;
    964                         info.mBufferID = portDesc->bufferIDAt(i);
    965                         info.mOwnedByClient = false;
    966                         info.mData = portDesc->bufferAt(i);
    967 
    968                         if (portIndex == kPortIndexInput && mCrypto != NULL) {
    969                             info.mEncryptedData =
    970                                 new ABuffer(info.mData->capacity());
    971                         }
    972 
    973                         buffers->push_back(info);
    974                     }
    975 
    976                     if (portIndex == kPortIndexOutput) {
    977                         if (mState == STARTING) {
    978                             // We're always allocating output buffers after
    979                             // allocating input buffers, so this is a good
    980                             // indication that now all buffers are allocated.
    981                             setState(STARTED);
    982                             (new AMessage)->postReply(mReplyID);
    983                         } else {
    984                             mFlags |= kFlagOutputBuffersChanged;
    985                             postActivityNotificationIfPossible();
    986                         }
    987                     }
    988                     break;
    989                 }
    990 
    991                 case CodecBase::kWhatOutputFormatChanged:
    992                 {
    993                     ALOGV("codec output format changed");
    994 
    995                     if (mSoftRenderer == NULL &&
    996                             mNativeWindow != NULL &&
    997                             (mFlags & kFlagUsesSoftwareRenderer)) {
    998                         AString mime;
    999                         CHECK(msg->findString("mime", &mime));
   1000 
   1001                         if (mime.startsWithIgnoreCase("video/")) {
   1002                             mSoftRenderer = new SoftwareRenderer(mNativeWindow);
   1003                         }
   1004                     }
   1005 
   1006                     mOutputFormat = msg;
   1007 
   1008                     if (mFlags & kFlagIsEncoder) {
   1009                         // Before we announce the format change we should
   1010                         // collect codec specific data and amend the output
   1011                         // format as necessary.
   1012                         mFlags |= kFlagGatherCodecSpecificData;
   1013                     } else if (mFlags & kFlagIsAsync) {
   1014                         onOutputFormatChanged();
   1015                     } else {
   1016                         mFlags |= kFlagOutputFormatChanged;
   1017                         postActivityNotificationIfPossible();
   1018                     }
   1019 
   1020                     // Notify mCrypto of video resolution changes
   1021                     if (mCrypto != NULL) {
   1022                         int32_t left, top, right, bottom, width, height;
   1023                         if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
   1024                             mCrypto->notifyResolution(right - left + 1, bottom - top + 1);
   1025                         } else if (mOutputFormat->findInt32("width", &width)
   1026                                 && mOutputFormat->findInt32("height", &height)) {
   1027                             mCrypto->notifyResolution(width, height);
   1028                         }
   1029                     }
   1030 
   1031                     break;
   1032                 }
   1033 
   1034                 case CodecBase::kWhatFillThisBuffer:
   1035                 {
   1036                     /* size_t index = */updateBuffers(kPortIndexInput, msg);
   1037 
   1038                     if (mState == FLUSHING
   1039                             || mState == STOPPING
   1040                             || mState == RELEASING) {
   1041                         returnBuffersToCodecOnPort(kPortIndexInput);
   1042                         break;
   1043                     }
   1044 
   1045                     if (!mCSD.empty()) {
   1046                         ssize_t index = dequeuePortBuffer(kPortIndexInput);
   1047                         CHECK_GE(index, 0);
   1048 
   1049                         // If codec specific data had been specified as
   1050                         // part of the format in the call to configure and
   1051                         // if there's more csd left, we submit it here
   1052                         // clients only get access to input buffers once
   1053                         // this data has been exhausted.
   1054 
   1055                         status_t err = queueCSDInputBuffer(index);
   1056 
   1057                         if (err != OK) {
   1058                             ALOGE("queueCSDInputBuffer failed w/ error %d",
   1059                                   err);
   1060 
   1061                             setStickyError(err);
   1062                             postActivityNotificationIfPossible();
   1063 
   1064                             cancelPendingDequeueOperations();
   1065                         }
   1066                         break;
   1067                     }
   1068 
   1069                     if (mFlags & kFlagIsAsync) {
   1070                         if (!mHaveInputSurface) {
   1071                             onInputBufferAvailable();
   1072                         }
   1073                     } else if (mFlags & kFlagDequeueInputPending) {
   1074                         CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
   1075 
   1076                         ++mDequeueInputTimeoutGeneration;
   1077                         mFlags &= ~kFlagDequeueInputPending;
   1078                         mDequeueInputReplyID = 0;
   1079                     } else {
   1080                         postActivityNotificationIfPossible();
   1081                     }
   1082                     break;
   1083                 }
   1084 
   1085                 case CodecBase::kWhatDrainThisBuffer:
   1086                 {
   1087                     /* size_t index = */updateBuffers(kPortIndexOutput, msg);
   1088 
   1089                     if (mState == FLUSHING
   1090                             || mState == STOPPING
   1091                             || mState == RELEASING) {
   1092                         returnBuffersToCodecOnPort(kPortIndexOutput);
   1093                         break;
   1094                     }
   1095 
   1096                     sp<ABuffer> buffer;
   1097                     CHECK(msg->findBuffer("buffer", &buffer));
   1098 
   1099                     int32_t omxFlags;
   1100                     CHECK(msg->findInt32("flags", &omxFlags));
   1101 
   1102                     buffer->meta()->setInt32("omxFlags", omxFlags);
   1103 
   1104                     if (mFlags & kFlagGatherCodecSpecificData) {
   1105                         // This is the very first output buffer after a
   1106                         // format change was signalled, it'll either contain
   1107                         // the one piece of codec specific data we can expect
   1108                         // or there won't be codec specific data.
   1109                         if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   1110                             status_t err =
   1111                                 amendOutputFormatWithCodecSpecificData(buffer);
   1112 
   1113                             if (err != OK) {
   1114                                 ALOGE("Codec spit out malformed codec "
   1115                                       "specific data!");
   1116                             }
   1117                         }
   1118 
   1119                         mFlags &= ~kFlagGatherCodecSpecificData;
   1120                         if (mFlags & kFlagIsAsync) {
   1121                             onOutputFormatChanged();
   1122                         } else {
   1123                             mFlags |= kFlagOutputFormatChanged;
   1124                         }
   1125                     }
   1126 
   1127                     if (mFlags & kFlagIsAsync) {
   1128                         onOutputBufferAvailable();
   1129                     } else if (mFlags & kFlagDequeueOutputPending) {
   1130                         CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
   1131 
   1132                         ++mDequeueOutputTimeoutGeneration;
   1133                         mFlags &= ~kFlagDequeueOutputPending;
   1134                         mDequeueOutputReplyID = 0;
   1135                     } else {
   1136                         postActivityNotificationIfPossible();
   1137                     }
   1138 
   1139                     break;
   1140                 }
   1141 
   1142                 case CodecBase::kWhatEOS:
   1143                 {
   1144                     // We already notify the client of this by using the
   1145                     // corresponding flag in "onOutputBufferReady".
   1146                     break;
   1147                 }
   1148 
   1149                 case CodecBase::kWhatShutdownCompleted:
   1150                 {
   1151                     if (mState == STOPPING) {
   1152                         setState(INITIALIZED);
   1153                     } else {
   1154                         CHECK_EQ(mState, RELEASING);
   1155                         setState(UNINITIALIZED);
   1156                         mComponentName.clear();
   1157                     }
   1158                     mFlags &= ~kFlagIsComponentAllocated;
   1159 
   1160                     (new AMessage)->postReply(mReplyID);
   1161                     break;
   1162                 }
   1163 
   1164                 case CodecBase::kWhatFlushCompleted:
   1165                 {
   1166                     if (mState != FLUSHING) {
   1167                         ALOGW("received FlushCompleted message in state %d",
   1168                                 mState);
   1169                         break;
   1170                     }
   1171 
   1172                     if (mFlags & kFlagIsAsync) {
   1173                         setState(FLUSHED);
   1174                     } else {
   1175                         setState(STARTED);
   1176                         mCodec->signalResume();
   1177                     }
   1178 
   1179                     (new AMessage)->postReply(mReplyID);
   1180                     break;
   1181                 }
   1182 
   1183                 default:
   1184                     TRESPASS();
   1185             }
   1186             break;
   1187         }
   1188 
   1189         case kWhatInit:
   1190         {
   1191             uint32_t replyID;
   1192             CHECK(msg->senderAwaitsResponse(&replyID));
   1193 
   1194             if (mState != UNINITIALIZED) {
   1195                 PostReplyWithError(replyID, INVALID_OPERATION);
   1196                 break;
   1197             }
   1198 
   1199             mReplyID = replyID;
   1200             setState(INITIALIZING);
   1201 
   1202             AString name;
   1203             CHECK(msg->findString("name", &name));
   1204 
   1205             int32_t nameIsType;
   1206             int32_t encoder = false;
   1207             CHECK(msg->findInt32("nameIsType", &nameIsType));
   1208             if (nameIsType) {
   1209                 CHECK(msg->findInt32("encoder", &encoder));
   1210             }
   1211 
   1212             sp<AMessage> format = new AMessage;
   1213 
   1214             if (nameIsType) {
   1215                 format->setString("mime", name.c_str());
   1216                 format->setInt32("encoder", encoder);
   1217             } else {
   1218                 format->setString("componentName", name.c_str());
   1219             }
   1220 
   1221             mCodec->initiateAllocateComponent(format);
   1222             break;
   1223         }
   1224 
   1225         case kWhatSetCallback:
   1226         {
   1227             uint32_t replyID;
   1228             CHECK(msg->senderAwaitsResponse(&replyID));
   1229 
   1230             if (mState == UNINITIALIZED
   1231                     || mState == INITIALIZING
   1232                     || isExecuting()) {
   1233                 // callback can't be set after codec is executing,
   1234                 // or before it's initialized (as the callback
   1235                 // will be cleared when it goes to INITIALIZED)
   1236                 PostReplyWithError(replyID, INVALID_OPERATION);
   1237                 break;
   1238             }
   1239 
   1240             sp<AMessage> callback;
   1241             CHECK(msg->findMessage("callback", &callback));
   1242 
   1243             mCallback = callback;
   1244 
   1245             if (mCallback != NULL) {
   1246                 ALOGI("MediaCodec will operate in async mode");
   1247                 mFlags |= kFlagIsAsync;
   1248             } else {
   1249                 mFlags &= ~kFlagIsAsync;
   1250             }
   1251 
   1252             sp<AMessage> response = new AMessage;
   1253             response->postReply(replyID);
   1254             break;
   1255         }
   1256 
   1257         case kWhatConfigure:
   1258         {
   1259             uint32_t replyID;
   1260             CHECK(msg->senderAwaitsResponse(&replyID));
   1261 
   1262             if (mState != INITIALIZED) {
   1263                 PostReplyWithError(replyID, INVALID_OPERATION);
   1264                 break;
   1265             }
   1266 
   1267             sp<RefBase> obj;
   1268             if (!msg->findObject("native-window", &obj)) {
   1269                 obj.clear();
   1270             }
   1271 
   1272             sp<AMessage> format;
   1273             CHECK(msg->findMessage("format", &format));
   1274 
   1275             if (obj != NULL) {
   1276                 format->setObject("native-window", obj);
   1277 
   1278                 status_t err = setNativeWindow(
   1279                     static_cast<NativeWindowWrapper *>(obj.get())
   1280                         ->getSurfaceTextureClient());
   1281 
   1282                 if (err != OK) {
   1283                     PostReplyWithError(replyID, err);
   1284                     break;
   1285                 }
   1286             } else {
   1287                 setNativeWindow(NULL);
   1288             }
   1289 
   1290             mReplyID = replyID;
   1291             setState(CONFIGURING);
   1292 
   1293             void *crypto;
   1294             if (!msg->findPointer("crypto", &crypto)) {
   1295                 crypto = NULL;
   1296             }
   1297 
   1298             mCrypto = static_cast<ICrypto *>(crypto);
   1299 
   1300             uint32_t flags;
   1301             CHECK(msg->findInt32("flags", (int32_t *)&flags));
   1302 
   1303             if (flags & CONFIGURE_FLAG_ENCODE) {
   1304                 format->setInt32("encoder", true);
   1305                 mFlags |= kFlagIsEncoder;
   1306             }
   1307 
   1308             extractCSD(format);
   1309 
   1310             mCodec->initiateConfigureComponent(format);
   1311             break;
   1312         }
   1313 
   1314         case kWhatCreateInputSurface:
   1315         {
   1316             uint32_t replyID;
   1317             CHECK(msg->senderAwaitsResponse(&replyID));
   1318 
   1319             // Must be configured, but can't have been started yet.
   1320             if (mState != CONFIGURED) {
   1321                 PostReplyWithError(replyID, INVALID_OPERATION);
   1322                 break;
   1323             }
   1324 
   1325             mReplyID = replyID;
   1326             mCodec->initiateCreateInputSurface();
   1327             break;
   1328         }
   1329 
   1330         case kWhatStart:
   1331         {
   1332             uint32_t replyID;
   1333             CHECK(msg->senderAwaitsResponse(&replyID));
   1334 
   1335             if (mState == FLUSHED) {
   1336                 setState(STARTED);
   1337                 mCodec->signalResume();
   1338                 PostReplyWithError(replyID, OK);
   1339                 break;
   1340             } else if (mState != CONFIGURED) {
   1341                 PostReplyWithError(replyID, INVALID_OPERATION);
   1342                 break;
   1343             }
   1344 
   1345             mReplyID = replyID;
   1346             setState(STARTING);
   1347 
   1348             mCodec->initiateStart();
   1349             break;
   1350         }
   1351 
   1352         case kWhatStop:
   1353         case kWhatRelease:
   1354         {
   1355             State targetState =
   1356                 (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED;
   1357 
   1358             uint32_t replyID;
   1359             CHECK(msg->senderAwaitsResponse(&replyID));
   1360 
   1361             if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1
   1362                     && mState != INITIALIZED
   1363                     && mState != CONFIGURED && !isExecuting()) {
   1364                 // 1) Permit release to shut down the component if allocated.
   1365                 //
   1366                 // 2) We may be in "UNINITIALIZED" state already and
   1367                 // also shutdown the encoder/decoder without the
   1368                 // client being aware of this if media server died while
   1369                 // we were being stopped. The client would assume that
   1370                 // after stop() returned, it would be safe to call release()
   1371                 // and it should be in this case, no harm to allow a release()
   1372                 // if we're already uninitialized.
   1373                 sp<AMessage> response = new AMessage;
   1374                 status_t err = mState == targetState ? OK : INVALID_OPERATION;
   1375                 response->setInt32("err", err);
   1376                 if (err == OK && targetState == UNINITIALIZED) {
   1377                     mComponentName.clear();
   1378                 }
   1379                 response->postReply(replyID);
   1380                 break;
   1381             }
   1382 
   1383             if (mFlags & kFlagSawMediaServerDie) {
   1384                 // It's dead, Jim. Don't expect initiateShutdown to yield
   1385                 // any useful results now...
   1386                 setState(UNINITIALIZED);
   1387                 if (targetState == UNINITIALIZED) {
   1388                     mComponentName.clear();
   1389                 }
   1390                 (new AMessage)->postReply(replyID);
   1391                 break;
   1392             }
   1393 
   1394             mReplyID = replyID;
   1395             setState(msg->what() == kWhatStop ? STOPPING : RELEASING);
   1396 
   1397             mCodec->initiateShutdown(
   1398                     msg->what() == kWhatStop /* keepComponentAllocated */);
   1399 
   1400             returnBuffersToCodec();
   1401             break;
   1402         }
   1403 
   1404         case kWhatDequeueInputBuffer:
   1405         {
   1406             uint32_t replyID;
   1407             CHECK(msg->senderAwaitsResponse(&replyID));
   1408 
   1409             if (mFlags & kFlagIsAsync) {
   1410                 ALOGE("dequeueOutputBuffer can't be used in async mode");
   1411                 PostReplyWithError(replyID, INVALID_OPERATION);
   1412                 break;
   1413             }
   1414 
   1415             if (mHaveInputSurface) {
   1416                 ALOGE("dequeueInputBuffer can't be used with input surface");
   1417                 PostReplyWithError(replyID, INVALID_OPERATION);
   1418                 break;
   1419             }
   1420 
   1421             if (handleDequeueInputBuffer(replyID, true /* new request */)) {
   1422                 break;
   1423             }
   1424 
   1425             int64_t timeoutUs;
   1426             CHECK(msg->findInt64("timeoutUs", &timeoutUs));
   1427 
   1428             if (timeoutUs == 0ll) {
   1429                 PostReplyWithError(replyID, -EAGAIN);
   1430                 break;
   1431             }
   1432 
   1433             mFlags |= kFlagDequeueInputPending;
   1434             mDequeueInputReplyID = replyID;
   1435 
   1436             if (timeoutUs > 0ll) {
   1437                 sp<AMessage> timeoutMsg =
   1438                     new AMessage(kWhatDequeueInputTimedOut, id());
   1439                 timeoutMsg->setInt32(
   1440                         "generation", ++mDequeueInputTimeoutGeneration);
   1441                 timeoutMsg->post(timeoutUs);
   1442             }
   1443             break;
   1444         }
   1445 
   1446         case kWhatDequeueInputTimedOut:
   1447         {
   1448             int32_t generation;
   1449             CHECK(msg->findInt32("generation", &generation));
   1450 
   1451             if (generation != mDequeueInputTimeoutGeneration) {
   1452                 // Obsolete
   1453                 break;
   1454             }
   1455 
   1456             CHECK(mFlags & kFlagDequeueInputPending);
   1457 
   1458             PostReplyWithError(mDequeueInputReplyID, -EAGAIN);
   1459 
   1460             mFlags &= ~kFlagDequeueInputPending;
   1461             mDequeueInputReplyID = 0;
   1462             break;
   1463         }
   1464 
   1465         case kWhatQueueInputBuffer:
   1466         {
   1467             uint32_t replyID;
   1468             CHECK(msg->senderAwaitsResponse(&replyID));
   1469 
   1470             if (!isExecuting()) {
   1471                 PostReplyWithError(replyID, INVALID_OPERATION);
   1472                 break;
   1473             } else if (mFlags & kFlagStickyError) {
   1474                 PostReplyWithError(replyID, getStickyError());
   1475                 break;
   1476             }
   1477 
   1478             status_t err = onQueueInputBuffer(msg);
   1479 
   1480             PostReplyWithError(replyID, err);
   1481             break;
   1482         }
   1483 
   1484         case kWhatDequeueOutputBuffer:
   1485         {
   1486             uint32_t replyID;
   1487             CHECK(msg->senderAwaitsResponse(&replyID));
   1488 
   1489             if (mFlags & kFlagIsAsync) {
   1490                 ALOGE("dequeueOutputBuffer can't be used in async mode");
   1491                 PostReplyWithError(replyID, INVALID_OPERATION);
   1492                 break;
   1493             }
   1494 
   1495             if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
   1496                 break;
   1497             }
   1498 
   1499             int64_t timeoutUs;
   1500             CHECK(msg->findInt64("timeoutUs", &timeoutUs));
   1501 
   1502             if (timeoutUs == 0ll) {
   1503                 PostReplyWithError(replyID, -EAGAIN);
   1504                 break;
   1505             }
   1506 
   1507             mFlags |= kFlagDequeueOutputPending;
   1508             mDequeueOutputReplyID = replyID;
   1509 
   1510             if (timeoutUs > 0ll) {
   1511                 sp<AMessage> timeoutMsg =
   1512                     new AMessage(kWhatDequeueOutputTimedOut, id());
   1513                 timeoutMsg->setInt32(
   1514                         "generation", ++mDequeueOutputTimeoutGeneration);
   1515                 timeoutMsg->post(timeoutUs);
   1516             }
   1517             break;
   1518         }
   1519 
   1520         case kWhatDequeueOutputTimedOut:
   1521         {
   1522             int32_t generation;
   1523             CHECK(msg->findInt32("generation", &generation));
   1524 
   1525             if (generation != mDequeueOutputTimeoutGeneration) {
   1526                 // Obsolete
   1527                 break;
   1528             }
   1529 
   1530             CHECK(mFlags & kFlagDequeueOutputPending);
   1531 
   1532             PostReplyWithError(mDequeueOutputReplyID, -EAGAIN);
   1533 
   1534             mFlags &= ~kFlagDequeueOutputPending;
   1535             mDequeueOutputReplyID = 0;
   1536             break;
   1537         }
   1538 
   1539         case kWhatReleaseOutputBuffer:
   1540         {
   1541             uint32_t replyID;
   1542             CHECK(msg->senderAwaitsResponse(&replyID));
   1543 
   1544             if (!isExecuting()) {
   1545                 PostReplyWithError(replyID, INVALID_OPERATION);
   1546                 break;
   1547             } else if (mFlags & kFlagStickyError) {
   1548                 PostReplyWithError(replyID, getStickyError());
   1549                 break;
   1550             }
   1551 
   1552             status_t err = onReleaseOutputBuffer(msg);
   1553 
   1554             PostReplyWithError(replyID, err);
   1555             break;
   1556         }
   1557 
   1558         case kWhatSignalEndOfInputStream:
   1559         {
   1560             uint32_t replyID;
   1561             CHECK(msg->senderAwaitsResponse(&replyID));
   1562 
   1563             if (!isExecuting()) {
   1564                 PostReplyWithError(replyID, INVALID_OPERATION);
   1565                 break;
   1566             } else if (mFlags & kFlagStickyError) {
   1567                 PostReplyWithError(replyID, getStickyError());
   1568                 break;
   1569             }
   1570 
   1571             mReplyID = replyID;
   1572             mCodec->signalEndOfInputStream();
   1573             break;
   1574         }
   1575 
   1576         case kWhatGetBuffers:
   1577         {
   1578             uint32_t replyID;
   1579             CHECK(msg->senderAwaitsResponse(&replyID));
   1580 
   1581             if (!isExecuting() || (mFlags & kFlagIsAsync)) {
   1582                 PostReplyWithError(replyID, INVALID_OPERATION);
   1583                 break;
   1584             } else if (mFlags & kFlagStickyError) {
   1585                 PostReplyWithError(replyID, getStickyError());
   1586                 break;
   1587             }
   1588 
   1589             int32_t portIndex;
   1590             CHECK(msg->findInt32("portIndex", &portIndex));
   1591 
   1592             Vector<sp<ABuffer> > *dstBuffers;
   1593             CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
   1594 
   1595             dstBuffers->clear();
   1596             const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
   1597 
   1598             for (size_t i = 0; i < srcBuffers.size(); ++i) {
   1599                 const BufferInfo &info = srcBuffers.itemAt(i);
   1600 
   1601                 dstBuffers->push_back(
   1602                         (portIndex == kPortIndexInput && mCrypto != NULL)
   1603                                 ? info.mEncryptedData : info.mData);
   1604             }
   1605 
   1606             (new AMessage)->postReply(replyID);
   1607             break;
   1608         }
   1609 
   1610         case kWhatFlush:
   1611         {
   1612             uint32_t replyID;
   1613             CHECK(msg->senderAwaitsResponse(&replyID));
   1614 
   1615             if (!isExecuting()) {
   1616                 PostReplyWithError(replyID, INVALID_OPERATION);
   1617                 break;
   1618             } else if (mFlags & kFlagStickyError) {
   1619                 PostReplyWithError(replyID, getStickyError());
   1620                 break;
   1621             }
   1622 
   1623             mReplyID = replyID;
   1624             // TODO: skip flushing if already FLUSHED
   1625             setState(FLUSHING);
   1626 
   1627             mCodec->signalFlush();
   1628             returnBuffersToCodec();
   1629             break;
   1630         }
   1631 
   1632         case kWhatGetInputFormat:
   1633         case kWhatGetOutputFormat:
   1634         {
   1635             sp<AMessage> format =
   1636                 (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat);
   1637 
   1638             uint32_t replyID;
   1639             CHECK(msg->senderAwaitsResponse(&replyID));
   1640 
   1641             if ((mState != CONFIGURED && mState != STARTING &&
   1642                  mState != STARTED && mState != FLUSHING &&
   1643                  mState != FLUSHED)
   1644                     || format == NULL) {
   1645                 PostReplyWithError(replyID, INVALID_OPERATION);
   1646                 break;
   1647             } else if (mFlags & kFlagStickyError) {
   1648                 PostReplyWithError(replyID, getStickyError());
   1649                 break;
   1650             }
   1651 
   1652             sp<AMessage> response = new AMessage;
   1653             response->setMessage("format", format);
   1654             response->postReply(replyID);
   1655             break;
   1656         }
   1657 
   1658         case kWhatRequestIDRFrame:
   1659         {
   1660             mCodec->signalRequestIDRFrame();
   1661             break;
   1662         }
   1663 
   1664         case kWhatRequestActivityNotification:
   1665         {
   1666             CHECK(mActivityNotify == NULL);
   1667             CHECK(msg->findMessage("notify", &mActivityNotify));
   1668 
   1669             postActivityNotificationIfPossible();
   1670             break;
   1671         }
   1672 
   1673         case kWhatGetName:
   1674         {
   1675             uint32_t replyID;
   1676             CHECK(msg->senderAwaitsResponse(&replyID));
   1677 
   1678             if (mComponentName.empty()) {
   1679                 PostReplyWithError(replyID, INVALID_OPERATION);
   1680                 break;
   1681             }
   1682 
   1683             sp<AMessage> response = new AMessage;
   1684             response->setString("name", mComponentName.c_str());
   1685             response->postReply(replyID);
   1686             break;
   1687         }
   1688 
   1689         case kWhatSetParameters:
   1690         {
   1691             uint32_t replyID;
   1692             CHECK(msg->senderAwaitsResponse(&replyID));
   1693 
   1694             sp<AMessage> params;
   1695             CHECK(msg->findMessage("params", &params));
   1696 
   1697             status_t err = onSetParameters(params);
   1698 
   1699             PostReplyWithError(replyID, err);
   1700             break;
   1701         }
   1702 
   1703         default:
   1704             TRESPASS();
   1705     }
   1706 }
   1707 
   1708 void MediaCodec::extractCSD(const sp<AMessage> &format) {
   1709     mCSD.clear();
   1710 
   1711     size_t i = 0;
   1712     for (;;) {
   1713         sp<ABuffer> csd;
   1714         if (!format->findBuffer(StringPrintf("csd-%u", i).c_str(), &csd)) {
   1715             break;
   1716         }
   1717 
   1718         mCSD.push_back(csd);
   1719         ++i;
   1720     }
   1721 
   1722     ALOGV("Found %zu pieces of codec specific data.", mCSD.size());
   1723 }
   1724 
   1725 status_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
   1726     CHECK(!mCSD.empty());
   1727 
   1728     const BufferInfo *info =
   1729         &mPortBuffers[kPortIndexInput].itemAt(bufferIndex);
   1730 
   1731     sp<ABuffer> csd = *mCSD.begin();
   1732     mCSD.erase(mCSD.begin());
   1733 
   1734     const sp<ABuffer> &codecInputData =
   1735         (mCrypto != NULL) ? info->mEncryptedData : info->mData;
   1736 
   1737     if (csd->size() > codecInputData->capacity()) {
   1738         return -EINVAL;
   1739     }
   1740 
   1741     memcpy(codecInputData->data(), csd->data(), csd->size());
   1742 
   1743     AString errorDetailMsg;
   1744 
   1745     sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
   1746     msg->setSize("index", bufferIndex);
   1747     msg->setSize("offset", 0);
   1748     msg->setSize("size", csd->size());
   1749     msg->setInt64("timeUs", 0ll);
   1750     msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
   1751     msg->setPointer("errorDetailMsg", &errorDetailMsg);
   1752 
   1753     return onQueueInputBuffer(msg);
   1754 }
   1755 
   1756 void MediaCodec::setState(State newState) {
   1757     if (newState == INITIALIZED || newState == UNINITIALIZED) {
   1758         delete mSoftRenderer;
   1759         mSoftRenderer = NULL;
   1760 
   1761         mCrypto.clear();
   1762         setNativeWindow(NULL);
   1763 
   1764         mInputFormat.clear();
   1765         mOutputFormat.clear();
   1766         mFlags &= ~kFlagOutputFormatChanged;
   1767         mFlags &= ~kFlagOutputBuffersChanged;
   1768         mFlags &= ~kFlagStickyError;
   1769         mFlags &= ~kFlagIsEncoder;
   1770         mFlags &= ~kFlagGatherCodecSpecificData;
   1771         mFlags &= ~kFlagIsAsync;
   1772         mStickyError = OK;
   1773 
   1774         mActivityNotify.clear();
   1775         mCallback.clear();
   1776     }
   1777 
   1778     if (newState == UNINITIALIZED) {
   1779         // return any straggling buffers, e.g. if we got here on an error
   1780         returnBuffersToCodec();
   1781 
   1782         // The component is gone, mediaserver's probably back up already
   1783         // but should definitely be back up should we try to instantiate
   1784         // another component.. and the cycle continues.
   1785         mFlags &= ~kFlagSawMediaServerDie;
   1786     }
   1787 
   1788     mState = newState;
   1789 
   1790     cancelPendingDequeueOperations();
   1791 
   1792     updateBatteryStat();
   1793 }
   1794 
   1795 void MediaCodec::returnBuffersToCodec() {
   1796     returnBuffersToCodecOnPort(kPortIndexInput);
   1797     returnBuffersToCodecOnPort(kPortIndexOutput);
   1798 }
   1799 
   1800 void MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) {
   1801     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
   1802     Mutex::Autolock al(mBufferLock);
   1803 
   1804     Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
   1805 
   1806     for (size_t i = 0; i < buffers->size(); ++i) {
   1807         BufferInfo *info = &buffers->editItemAt(i);
   1808 
   1809         if (info->mNotify != NULL) {
   1810             sp<AMessage> msg = info->mNotify;
   1811             info->mNotify = NULL;
   1812             info->mOwnedByClient = false;
   1813 
   1814             if (portIndex == kPortIndexInput) {
   1815                 /* no error, just returning buffers */
   1816                 msg->setInt32("err", OK);
   1817             }
   1818             msg->post();
   1819         }
   1820     }
   1821 
   1822     mAvailPortBuffers[portIndex].clear();
   1823 }
   1824 
   1825 size_t MediaCodec::updateBuffers(
   1826         int32_t portIndex, const sp<AMessage> &msg) {
   1827     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
   1828 
   1829     uint32_t bufferID;
   1830     CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
   1831 
   1832     Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
   1833 
   1834     for (size_t i = 0; i < buffers->size(); ++i) {
   1835         BufferInfo *info = &buffers->editItemAt(i);
   1836 
   1837         if (info->mBufferID == bufferID) {
   1838             CHECK(info->mNotify == NULL);
   1839             CHECK(msg->findMessage("reply", &info->mNotify));
   1840 
   1841             info->mFormat =
   1842                 (portIndex == kPortIndexInput) ? mInputFormat : mOutputFormat;
   1843             mAvailPortBuffers[portIndex].push_back(i);
   1844 
   1845             return i;
   1846         }
   1847     }
   1848 
   1849     TRESPASS();
   1850 
   1851     return 0;
   1852 }
   1853 
   1854 status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
   1855     size_t index;
   1856     size_t offset;
   1857     size_t size;
   1858     int64_t timeUs;
   1859     uint32_t flags;
   1860     CHECK(msg->findSize("index", &index));
   1861     CHECK(msg->findSize("offset", &offset));
   1862     CHECK(msg->findInt64("timeUs", &timeUs));
   1863     CHECK(msg->findInt32("flags", (int32_t *)&flags));
   1864 
   1865     const CryptoPlugin::SubSample *subSamples;
   1866     size_t numSubSamples;
   1867     const uint8_t *key;
   1868     const uint8_t *iv;
   1869     CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
   1870 
   1871     // We allow the simpler queueInputBuffer API to be used even in
   1872     // secure mode, by fabricating a single unencrypted subSample.
   1873     CryptoPlugin::SubSample ss;
   1874 
   1875     if (msg->findSize("size", &size)) {
   1876         if (mCrypto != NULL) {
   1877             ss.mNumBytesOfClearData = size;
   1878             ss.mNumBytesOfEncryptedData = 0;
   1879 
   1880             subSamples = &ss;
   1881             numSubSamples = 1;
   1882             key = NULL;
   1883             iv = NULL;
   1884         }
   1885     } else {
   1886         if (mCrypto == NULL) {
   1887             return -EINVAL;
   1888         }
   1889 
   1890         CHECK(msg->findPointer("subSamples", (void **)&subSamples));
   1891         CHECK(msg->findSize("numSubSamples", &numSubSamples));
   1892         CHECK(msg->findPointer("key", (void **)&key));
   1893         CHECK(msg->findPointer("iv", (void **)&iv));
   1894 
   1895         int32_t tmp;
   1896         CHECK(msg->findInt32("mode", &tmp));
   1897 
   1898         mode = (CryptoPlugin::Mode)tmp;
   1899 
   1900         size = 0;
   1901         for (size_t i = 0; i < numSubSamples; ++i) {
   1902             size += subSamples[i].mNumBytesOfClearData;
   1903             size += subSamples[i].mNumBytesOfEncryptedData;
   1904         }
   1905     }
   1906 
   1907     if (index >= mPortBuffers[kPortIndexInput].size()) {
   1908         return -ERANGE;
   1909     }
   1910 
   1911     BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
   1912 
   1913     if (info->mNotify == NULL || !info->mOwnedByClient) {
   1914         return -EACCES;
   1915     }
   1916 
   1917     if (offset + size > info->mData->capacity()) {
   1918         return -EINVAL;
   1919     }
   1920 
   1921     sp<AMessage> reply = info->mNotify;
   1922     info->mData->setRange(offset, size);
   1923     info->mData->meta()->setInt64("timeUs", timeUs);
   1924 
   1925     if (flags & BUFFER_FLAG_EOS) {
   1926         info->mData->meta()->setInt32("eos", true);
   1927     }
   1928 
   1929     if (flags & BUFFER_FLAG_CODECCONFIG) {
   1930         info->mData->meta()->setInt32("csd", true);
   1931     }
   1932 
   1933     if (mCrypto != NULL) {
   1934         if (size > info->mEncryptedData->capacity()) {
   1935             return -ERANGE;
   1936         }
   1937 
   1938         AString *errorDetailMsg;
   1939         CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
   1940 
   1941         ssize_t result = mCrypto->decrypt(
   1942                 (mFlags & kFlagIsSecure) != 0,
   1943                 key,
   1944                 iv,
   1945                 mode,
   1946                 info->mEncryptedData->base() + offset,
   1947                 subSamples,
   1948                 numSubSamples,
   1949                 info->mData->base(),
   1950                 errorDetailMsg);
   1951 
   1952         if (result < 0) {
   1953             return result;
   1954         }
   1955 
   1956         info->mData->setRange(0, result);
   1957     }
   1958 
   1959     // synchronization boundary for getBufferAndFormat
   1960     {
   1961         Mutex::Autolock al(mBufferLock);
   1962         info->mOwnedByClient = false;
   1963     }
   1964     reply->setBuffer("buffer", info->mData);
   1965     reply->post();
   1966 
   1967     info->mNotify = NULL;
   1968 
   1969     return OK;
   1970 }
   1971 
   1972 status_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
   1973     size_t index;
   1974     CHECK(msg->findSize("index", &index));
   1975 
   1976     int32_t render;
   1977     if (!msg->findInt32("render", &render)) {
   1978         render = 0;
   1979     }
   1980 
   1981     if (!isExecuting()) {
   1982         return -EINVAL;
   1983     }
   1984 
   1985     if (index >= mPortBuffers[kPortIndexOutput].size()) {
   1986         return -ERANGE;
   1987     }
   1988 
   1989     BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
   1990 
   1991     if (info->mNotify == NULL || !info->mOwnedByClient) {
   1992         return -EACCES;
   1993     }
   1994 
   1995     // synchronization boundary for getBufferAndFormat
   1996     {
   1997         Mutex::Autolock al(mBufferLock);
   1998         info->mOwnedByClient = false;
   1999     }
   2000 
   2001     if (render && info->mData != NULL && info->mData->size() != 0) {
   2002         info->mNotify->setInt32("render", true);
   2003 
   2004         int64_t timestampNs = 0;
   2005         if (msg->findInt64("timestampNs", &timestampNs)) {
   2006             info->mNotify->setInt64("timestampNs", timestampNs);
   2007         } else {
   2008             // TODO: it seems like we should use the timestamp
   2009             // in the (media)buffer as it potentially came from
   2010             // an input surface, but we did not propagate it prior to
   2011             // API 20.  Perhaps check for target SDK version.
   2012 #if 0
   2013             if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
   2014                 ALOGV("using buffer PTS of %" PRId64, timestampNs);
   2015                 timestampNs *= 1000;
   2016             }
   2017 #endif
   2018         }
   2019 
   2020         if (mSoftRenderer != NULL) {
   2021             mSoftRenderer->render(
   2022                     info->mData->data(), info->mData->size(),
   2023                     timestampNs, NULL, info->mFormat);
   2024         }
   2025     }
   2026 
   2027     info->mNotify->post();
   2028     info->mNotify = NULL;
   2029 
   2030     return OK;
   2031 }
   2032 
   2033 ssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
   2034     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
   2035 
   2036     List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
   2037 
   2038     if (availBuffers->empty()) {
   2039         return -EAGAIN;
   2040     }
   2041 
   2042     size_t index = *availBuffers->begin();
   2043     availBuffers->erase(availBuffers->begin());
   2044 
   2045     BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
   2046     CHECK(!info->mOwnedByClient);
   2047     {
   2048         Mutex::Autolock al(mBufferLock);
   2049         info->mOwnedByClient = true;
   2050 
   2051         // set image-data
   2052         if (info->mFormat != NULL) {
   2053             sp<ABuffer> imageData;
   2054             if (info->mFormat->findBuffer("image-data", &imageData)) {
   2055                 info->mData->meta()->setBuffer("image-data", imageData);
   2056             }
   2057             int32_t left, top, right, bottom;
   2058             if (info->mFormat->findRect("crop", &left, &top, &right, &bottom)) {
   2059                 info->mData->meta()->setRect("crop-rect", left, top, right, bottom);
   2060             }
   2061         }
   2062     }
   2063 
   2064     return index;
   2065 }
   2066 
   2067 status_t MediaCodec::setNativeWindow(
   2068         const sp<Surface> &surfaceTextureClient) {
   2069     status_t err;
   2070 
   2071     if (mNativeWindow != NULL) {
   2072         err = native_window_api_disconnect(
   2073                 mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA);
   2074 
   2075         if (err != OK) {
   2076             ALOGW("native_window_api_disconnect returned an error: %s (%d)",
   2077                     strerror(-err), err);
   2078         }
   2079 
   2080         mNativeWindow.clear();
   2081     }
   2082 
   2083     if (surfaceTextureClient != NULL) {
   2084         err = native_window_api_connect(
   2085                 surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA);
   2086 
   2087         if (err != OK) {
   2088             ALOGE("native_window_api_connect returned an error: %s (%d)",
   2089                     strerror(-err), err);
   2090 
   2091             return err;
   2092         }
   2093 
   2094         mNativeWindow = surfaceTextureClient;
   2095     }
   2096 
   2097     return OK;
   2098 }
   2099 
   2100 void MediaCodec::onInputBufferAvailable() {
   2101     int32_t index;
   2102     while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) {
   2103         sp<AMessage> msg = mCallback->dup();
   2104         msg->setInt32("callbackID", CB_INPUT_AVAILABLE);
   2105         msg->setInt32("index", index);
   2106         msg->post();
   2107     }
   2108 }
   2109 
   2110 void MediaCodec::onOutputBufferAvailable() {
   2111     int32_t index;
   2112     while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) {
   2113         const sp<ABuffer> &buffer =
   2114             mPortBuffers[kPortIndexOutput].itemAt(index).mData;
   2115         sp<AMessage> msg = mCallback->dup();
   2116         msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE);
   2117         msg->setInt32("index", index);
   2118         msg->setSize("offset", buffer->offset());
   2119         msg->setSize("size", buffer->size());
   2120 
   2121         int64_t timeUs;
   2122         CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
   2123 
   2124         msg->setInt64("timeUs", timeUs);
   2125 
   2126         int32_t omxFlags;
   2127         CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
   2128 
   2129         uint32_t flags = 0;
   2130         if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
   2131             flags |= BUFFER_FLAG_SYNCFRAME;
   2132         }
   2133         if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   2134             flags |= BUFFER_FLAG_CODECCONFIG;
   2135         }
   2136         if (omxFlags & OMX_BUFFERFLAG_EOS) {
   2137             flags |= BUFFER_FLAG_EOS;
   2138         }
   2139 
   2140         msg->setInt32("flags", flags);
   2141 
   2142         msg->post();
   2143     }
   2144 }
   2145 
   2146 void MediaCodec::onError(status_t err, int32_t actionCode, const char *detail) {
   2147     if (mCallback != NULL) {
   2148         sp<AMessage> msg = mCallback->dup();
   2149         msg->setInt32("callbackID", CB_ERROR);
   2150         msg->setInt32("err", err);
   2151         msg->setInt32("actionCode", actionCode);
   2152 
   2153         if (detail != NULL) {
   2154             msg->setString("detail", detail);
   2155         }
   2156 
   2157         msg->post();
   2158     }
   2159 }
   2160 
   2161 void MediaCodec::onOutputFormatChanged() {
   2162     if (mCallback != NULL) {
   2163         sp<AMessage> msg = mCallback->dup();
   2164         msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED);
   2165         msg->setMessage("format", mOutputFormat);
   2166         msg->post();
   2167     }
   2168 }
   2169 
   2170 
   2171 void MediaCodec::postActivityNotificationIfPossible() {
   2172     if (mActivityNotify == NULL) {
   2173         return;
   2174     }
   2175 
   2176     bool isErrorOrOutputChanged =
   2177             (mFlags & (kFlagStickyError
   2178                     | kFlagOutputBuffersChanged
   2179                     | kFlagOutputFormatChanged));
   2180 
   2181     if (isErrorOrOutputChanged
   2182             || !mAvailPortBuffers[kPortIndexInput].empty()
   2183             || !mAvailPortBuffers[kPortIndexOutput].empty()) {
   2184         mActivityNotify->setInt32("input-buffers",
   2185                 mAvailPortBuffers[kPortIndexInput].size());
   2186 
   2187         if (isErrorOrOutputChanged) {
   2188             // we want consumer to dequeue as many times as it can
   2189             mActivityNotify->setInt32("output-buffers", INT32_MAX);
   2190         } else {
   2191             mActivityNotify->setInt32("output-buffers",
   2192                     mAvailPortBuffers[kPortIndexOutput].size());
   2193         }
   2194         mActivityNotify->post();
   2195         mActivityNotify.clear();
   2196     }
   2197 }
   2198 
   2199 status_t MediaCodec::setParameters(const sp<AMessage> &params) {
   2200     sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
   2201     msg->setMessage("params", params);
   2202 
   2203     sp<AMessage> response;
   2204     return PostAndAwaitResponse(msg, &response);
   2205 }
   2206 
   2207 status_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
   2208     mCodec->signalSetParameters(params);
   2209 
   2210     return OK;
   2211 }
   2212 
   2213 status_t MediaCodec::amendOutputFormatWithCodecSpecificData(
   2214         const sp<ABuffer> &buffer) {
   2215     AString mime;
   2216     CHECK(mOutputFormat->findString("mime", &mime));
   2217 
   2218     if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
   2219         // Codec specific data should be SPS and PPS in a single buffer,
   2220         // each prefixed by a startcode (0x00 0x00 0x00 0x01).
   2221         // We separate the two and put them into the output format
   2222         // under the keys "csd-0" and "csd-1".
   2223 
   2224         unsigned csdIndex = 0;
   2225 
   2226         const uint8_t *data = buffer->data();
   2227         size_t size = buffer->size();
   2228 
   2229         const uint8_t *nalStart;
   2230         size_t nalSize;
   2231         while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
   2232             sp<ABuffer> csd = new ABuffer(nalSize + 4);
   2233             memcpy(csd->data(), "\x00\x00\x00\x01", 4);
   2234             memcpy(csd->data() + 4, nalStart, nalSize);
   2235 
   2236             mOutputFormat->setBuffer(
   2237                     StringPrintf("csd-%u", csdIndex).c_str(), csd);
   2238 
   2239             ++csdIndex;
   2240         }
   2241 
   2242         if (csdIndex != 2) {
   2243             return ERROR_MALFORMED;
   2244         }
   2245     } else {
   2246         // For everything else we just stash the codec specific data into
   2247         // the output format as a single piece of csd under "csd-0".
   2248         mOutputFormat->setBuffer("csd-0", buffer);
   2249     }
   2250 
   2251     return OK;
   2252 }
   2253 
   2254 void MediaCodec::updateBatteryStat() {
   2255     if (mState == CONFIGURED && !mBatteryStatNotified) {
   2256         AString mime;
   2257         CHECK(mOutputFormat != NULL &&
   2258                 mOutputFormat->findString("mime", &mime));
   2259 
   2260         mIsVideo = mime.startsWithIgnoreCase("video/");
   2261 
   2262         BatteryNotifier& notifier(BatteryNotifier::getInstance());
   2263 
   2264         if (mIsVideo) {
   2265             notifier.noteStartVideo();
   2266         } else {
   2267             notifier.noteStartAudio();
   2268         }
   2269 
   2270         mBatteryStatNotified = true;
   2271     } else if (mState == UNINITIALIZED && mBatteryStatNotified) {
   2272         BatteryNotifier& notifier(BatteryNotifier::getInstance());
   2273 
   2274         if (mIsVideo) {
   2275             notifier.noteStopVideo();
   2276         } else {
   2277             notifier.noteStopAudio();
   2278         }
   2279 
   2280         mBatteryStatNotified = false;
   2281     }
   2282 }
   2283 
   2284 }  // namespace android
   2285