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/IMemory.h>
     25 #include <binder/IPCThreadState.h>
     26 #include <binder/IServiceManager.h>
     27 #include <binder/MemoryDealer.h>
     28 #include <gui/BufferQueue.h>
     29 #include <gui/Surface.h>
     30 #include <media/ICrypto.h>
     31 #include <media/IOMX.h>
     32 #include <media/IResourceManagerService.h>
     33 #include <media/stagefright/foundation/ABuffer.h>
     34 #include <media/stagefright/foundation/ADebug.h>
     35 #include <media/stagefright/foundation/AMessage.h>
     36 #include <media/stagefright/foundation/AString.h>
     37 #include <media/stagefright/foundation/hexdump.h>
     38 #include <media/stagefright/ACodec.h>
     39 #include <media/stagefright/BufferProducerWrapper.h>
     40 #include <media/stagefright/MediaCodec.h>
     41 #include <media/stagefright/MediaCodecList.h>
     42 #include <media/stagefright/MediaDefs.h>
     43 #include <media/stagefright/MediaErrors.h>
     44 #include <media/stagefright/MediaFilter.h>
     45 #include <media/stagefright/MetaData.h>
     46 #include <media/stagefright/OMXClient.h>
     47 #include <media/stagefright/PersistentSurface.h>
     48 #include <media/stagefright/SurfaceUtils.h>
     49 #include <mediautils/BatteryNotifier.h>
     50 #include <private/android_filesystem_config.h>
     51 #include <utils/Log.h>
     52 #include <utils/Singleton.h>
     53 
     54 namespace android {
     55 
     56 static int64_t getId(sp<IResourceManagerClient> client) {
     57     return (int64_t) client.get();
     58 }
     59 
     60 static bool isResourceError(status_t err) {
     61     return (err == NO_MEMORY);
     62 }
     63 
     64 static const int kMaxRetry = 2;
     65 static const int kMaxReclaimWaitTimeInUs = 500000;  // 0.5s
     66 
     67 struct ResourceManagerClient : public BnResourceManagerClient {
     68     ResourceManagerClient(MediaCodec* codec) : mMediaCodec(codec) {}
     69 
     70     virtual bool reclaimResource() {
     71         sp<MediaCodec> codec = mMediaCodec.promote();
     72         if (codec == NULL) {
     73             // codec is already gone.
     74             return true;
     75         }
     76         status_t err = codec->reclaim();
     77         if (err == WOULD_BLOCK) {
     78             ALOGD("Wait for the client to release codec.");
     79             usleep(kMaxReclaimWaitTimeInUs);
     80             ALOGD("Try to reclaim again.");
     81             err = codec->reclaim(true /* force */);
     82         }
     83         if (err != OK) {
     84             ALOGW("ResourceManagerClient failed to release codec with err %d", err);
     85         }
     86         return (err == OK);
     87     }
     88 
     89     virtual String8 getName() {
     90         String8 ret;
     91         sp<MediaCodec> codec = mMediaCodec.promote();
     92         if (codec == NULL) {
     93             // codec is already gone.
     94             return ret;
     95         }
     96 
     97         AString name;
     98         if (codec->getName(&name) == OK) {
     99             ret.setTo(name.c_str());
    100         }
    101         return ret;
    102     }
    103 
    104 protected:
    105     virtual ~ResourceManagerClient() {}
    106 
    107 private:
    108     wp<MediaCodec> mMediaCodec;
    109 
    110     DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient);
    111 };
    112 
    113 MediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy(pid_t pid)
    114         : mPid(pid) {
    115     if (mPid == MediaCodec::kNoPid) {
    116         mPid = IPCThreadState::self()->getCallingPid();
    117     }
    118 }
    119 
    120 MediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() {
    121     if (mService != NULL) {
    122         IInterface::asBinder(mService)->unlinkToDeath(this);
    123     }
    124 }
    125 
    126 void MediaCodec::ResourceManagerServiceProxy::init() {
    127     sp<IServiceManager> sm = defaultServiceManager();
    128     sp<IBinder> binder = sm->getService(String16("media.resource_manager"));
    129     mService = interface_cast<IResourceManagerService>(binder);
    130     if (mService == NULL) {
    131         ALOGE("Failed to get ResourceManagerService");
    132         return;
    133     }
    134     IInterface::asBinder(mService)->linkToDeath(this);
    135 }
    136 
    137 void MediaCodec::ResourceManagerServiceProxy::binderDied(const wp<IBinder>& /*who*/) {
    138     ALOGW("ResourceManagerService died.");
    139     Mutex::Autolock _l(mLock);
    140     mService.clear();
    141 }
    142 
    143 void MediaCodec::ResourceManagerServiceProxy::addResource(
    144         int64_t clientId,
    145         const sp<IResourceManagerClient> client,
    146         const Vector<MediaResource> &resources) {
    147     Mutex::Autolock _l(mLock);
    148     if (mService == NULL) {
    149         return;
    150     }
    151     mService->addResource(mPid, clientId, client, resources);
    152 }
    153 
    154 void MediaCodec::ResourceManagerServiceProxy::removeResource(int64_t clientId) {
    155     Mutex::Autolock _l(mLock);
    156     if (mService == NULL) {
    157         return;
    158     }
    159     mService->removeResource(mPid, clientId);
    160 }
    161 
    162 bool MediaCodec::ResourceManagerServiceProxy::reclaimResource(
    163         const Vector<MediaResource> &resources) {
    164     Mutex::Autolock _l(mLock);
    165     if (mService == NULL) {
    166         return false;
    167     }
    168     return mService->reclaimResource(mPid, resources);
    169 }
    170 
    171 // static
    172 sp<MediaCodec> MediaCodec::CreateByType(
    173         const sp<ALooper> &looper, const AString &mime, bool encoder, status_t *err, pid_t pid) {
    174     sp<MediaCodec> codec = new MediaCodec(looper, pid);
    175 
    176     const status_t ret = codec->init(mime, true /* nameIsType */, encoder);
    177     if (err != NULL) {
    178         *err = ret;
    179     }
    180     return ret == OK ? codec : NULL; // NULL deallocates codec.
    181 }
    182 
    183 // static
    184 sp<MediaCodec> MediaCodec::CreateByComponentName(
    185         const sp<ALooper> &looper, const AString &name, status_t *err, pid_t pid) {
    186     sp<MediaCodec> codec = new MediaCodec(looper, pid);
    187 
    188     const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */);
    189     if (err != NULL) {
    190         *err = ret;
    191     }
    192     return ret == OK ? codec : NULL; // NULL deallocates codec.
    193 }
    194 
    195 // static
    196 status_t MediaCodec::QueryCapabilities(
    197         const AString &name, const AString &mime, bool isEncoder,
    198         sp<MediaCodecInfo::Capabilities> *caps /* nonnull */) {
    199     // TRICKY: this method is used by MediaCodecList/Info during its
    200     // initialization. As such, we cannot create a MediaCodec instance
    201     // because that requires an initialized MediaCodecList.
    202 
    203     sp<CodecBase> codec = GetCodecBase(name);
    204     if (codec == NULL) {
    205         return NAME_NOT_FOUND;
    206     }
    207 
    208     return codec->queryCapabilities(name, mime, isEncoder, caps);
    209 }
    210 
    211 // static
    212 sp<PersistentSurface> MediaCodec::CreatePersistentInputSurface() {
    213     OMXClient client;
    214     CHECK_EQ(client.connect(), (status_t)OK);
    215     sp<IOMX> omx = client.interface();
    216 
    217     const sp<IMediaCodecList> mediaCodecList = MediaCodecList::getInstance();
    218     if (mediaCodecList == NULL) {
    219         ALOGE("Failed to obtain MediaCodecList!");
    220         return NULL; // if called from Java should raise IOException
    221     }
    222 
    223     AString tmp;
    224     sp<AMessage> globalSettings = mediaCodecList->getGlobalSettings();
    225     if (globalSettings == NULL || !globalSettings->findString(
    226             kMaxEncoderInputBuffers, &tmp)) {
    227         ALOGE("Failed to get encoder input buffer count!");
    228         return NULL;
    229     }
    230 
    231     int32_t bufferCount = strtol(tmp.c_str(), NULL, 10);
    232     if (bufferCount <= 0
    233             || bufferCount > BufferQueue::MAX_MAX_ACQUIRED_BUFFERS) {
    234         ALOGE("Encoder input buffer count is invalid!");
    235         return NULL;
    236     }
    237 
    238     sp<IGraphicBufferProducer> bufferProducer;
    239     sp<IGraphicBufferConsumer> bufferConsumer;
    240 
    241     status_t err = omx->createPersistentInputSurface(
    242             &bufferProducer, &bufferConsumer);
    243 
    244     if (err != OK) {
    245         ALOGE("Failed to create persistent input surface.");
    246         return NULL;
    247     }
    248 
    249     err = bufferConsumer->setMaxAcquiredBufferCount(bufferCount);
    250 
    251     if (err != NO_ERROR) {
    252         ALOGE("Unable to set BQ max acquired buffer count to %u: %d",
    253                 bufferCount, err);
    254         return NULL;
    255     }
    256 
    257     return new PersistentSurface(bufferProducer, bufferConsumer);
    258 }
    259 
    260 MediaCodec::MediaCodec(const sp<ALooper> &looper, pid_t pid)
    261     : mState(UNINITIALIZED),
    262       mReleasedByResourceManager(false),
    263       mLooper(looper),
    264       mCodec(NULL),
    265       mReplyID(0),
    266       mFlags(0),
    267       mStickyError(OK),
    268       mSoftRenderer(NULL),
    269       mResourceManagerClient(new ResourceManagerClient(this)),
    270       mResourceManagerService(new ResourceManagerServiceProxy(pid)),
    271       mBatteryStatNotified(false),
    272       mIsVideo(false),
    273       mVideoWidth(0),
    274       mVideoHeight(0),
    275       mRotationDegrees(0),
    276       mDequeueInputTimeoutGeneration(0),
    277       mDequeueInputReplyID(0),
    278       mDequeueOutputTimeoutGeneration(0),
    279       mDequeueOutputReplyID(0),
    280       mHaveInputSurface(false),
    281       mHavePendingInputBuffers(false) {
    282 }
    283 
    284 MediaCodec::~MediaCodec() {
    285     CHECK_EQ(mState, UNINITIALIZED);
    286     mResourceManagerService->removeResource(getId(mResourceManagerClient));
    287 }
    288 
    289 // static
    290 status_t MediaCodec::PostAndAwaitResponse(
    291         const sp<AMessage> &msg, sp<AMessage> *response) {
    292     status_t err = msg->postAndAwaitResponse(response);
    293 
    294     if (err != OK) {
    295         return err;
    296     }
    297 
    298     if (!(*response)->findInt32("err", &err)) {
    299         err = OK;
    300     }
    301 
    302     return err;
    303 }
    304 
    305 void MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) {
    306     int32_t finalErr = err;
    307     if (mReleasedByResourceManager) {
    308         // override the err code if MediaCodec has been released by ResourceManager.
    309         finalErr = DEAD_OBJECT;
    310     }
    311 
    312     sp<AMessage> response = new AMessage;
    313     response->setInt32("err", finalErr);
    314     response->postReply(replyID);
    315 }
    316 
    317 //static
    318 sp<CodecBase> MediaCodec::GetCodecBase(const AString &name, bool nameIsType) {
    319     // at this time only ACodec specifies a mime type.
    320     if (nameIsType || name.startsWithIgnoreCase("omx.")) {
    321         return new ACodec;
    322     } else if (name.startsWithIgnoreCase("android.filter.")) {
    323         return new MediaFilter;
    324     } else {
    325         return NULL;
    326     }
    327 }
    328 
    329 status_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) {
    330     mResourceManagerService->init();
    331 
    332     // save init parameters for reset
    333     mInitName = name;
    334     mInitNameIsType = nameIsType;
    335     mInitIsEncoder = encoder;
    336 
    337     // Current video decoders do not return from OMX_FillThisBuffer
    338     // quickly, violating the OpenMAX specs, until that is remedied
    339     // we need to invest in an extra looper to free the main event
    340     // queue.
    341 
    342     mCodec = GetCodecBase(name, nameIsType);
    343     if (mCodec == NULL) {
    344         return NAME_NOT_FOUND;
    345     }
    346 
    347     bool secureCodec = false;
    348     if (nameIsType && !strncasecmp(name.c_str(), "video/", 6)) {
    349         mIsVideo = true;
    350     } else {
    351         AString tmp = name;
    352         if (tmp.endsWith(".secure")) {
    353             secureCodec = true;
    354             tmp.erase(tmp.size() - 7, 7);
    355         }
    356         const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
    357         if (mcl == NULL) {
    358             mCodec = NULL;  // remove the codec.
    359             return NO_INIT; // if called from Java should raise IOException
    360         }
    361         ssize_t codecIdx = mcl->findCodecByName(tmp.c_str());
    362         if (codecIdx >= 0) {
    363             const sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx);
    364             Vector<AString> mimes;
    365             info->getSupportedMimes(&mimes);
    366             for (size_t i = 0; i < mimes.size(); i++) {
    367                 if (mimes[i].startsWith("video/")) {
    368                     mIsVideo = true;
    369                     break;
    370                 }
    371             }
    372         }
    373     }
    374 
    375     if (mIsVideo) {
    376         // video codec needs dedicated looper
    377         if (mCodecLooper == NULL) {
    378             mCodecLooper = new ALooper;
    379             mCodecLooper->setName("CodecLooper");
    380             mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
    381         }
    382 
    383         mCodecLooper->registerHandler(mCodec);
    384     } else {
    385         mLooper->registerHandler(mCodec);
    386     }
    387 
    388     mLooper->registerHandler(this);
    389 
    390     mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, this));
    391 
    392     sp<AMessage> msg = new AMessage(kWhatInit, this);
    393     msg->setString("name", name);
    394     msg->setInt32("nameIsType", nameIsType);
    395 
    396     if (nameIsType) {
    397         msg->setInt32("encoder", encoder);
    398     }
    399 
    400     status_t err;
    401     Vector<MediaResource> resources;
    402     MediaResource::Type type =
    403             secureCodec ? MediaResource::kSecureCodec : MediaResource::kNonSecureCodec;
    404     MediaResource::SubType subtype =
    405             mIsVideo ? MediaResource::kVideoCodec : MediaResource::kAudioCodec;
    406     resources.push_back(MediaResource(type, subtype, 1));
    407     for (int i = 0; i <= kMaxRetry; ++i) {
    408         if (i > 0) {
    409             // Don't try to reclaim resource for the first time.
    410             if (!mResourceManagerService->reclaimResource(resources)) {
    411                 break;
    412             }
    413         }
    414 
    415         sp<AMessage> response;
    416         err = PostAndAwaitResponse(msg, &response);
    417         if (!isResourceError(err)) {
    418             break;
    419         }
    420     }
    421     return err;
    422 }
    423 
    424 status_t MediaCodec::setCallback(const sp<AMessage> &callback) {
    425     sp<AMessage> msg = new AMessage(kWhatSetCallback, this);
    426     msg->setMessage("callback", callback);
    427 
    428     sp<AMessage> response;
    429     return PostAndAwaitResponse(msg, &response);
    430 }
    431 
    432 status_t MediaCodec::setOnFrameRenderedNotification(const sp<AMessage> &notify) {
    433     sp<AMessage> msg = new AMessage(kWhatSetNotification, this);
    434     msg->setMessage("on-frame-rendered", notify);
    435     return msg->post();
    436 }
    437 
    438 status_t MediaCodec::configure(
    439         const sp<AMessage> &format,
    440         const sp<Surface> &surface,
    441         const sp<ICrypto> &crypto,
    442         uint32_t flags) {
    443     sp<AMessage> msg = new AMessage(kWhatConfigure, this);
    444 
    445     if (mIsVideo) {
    446         format->findInt32("width", &mVideoWidth);
    447         format->findInt32("height", &mVideoHeight);
    448         if (!format->findInt32("rotation-degrees", &mRotationDegrees)) {
    449             mRotationDegrees = 0;
    450         }
    451 
    452         // Prevent possible integer overflow in downstream code.
    453         if (mInitIsEncoder
    454                 && (uint64_t)mVideoWidth * mVideoHeight > (uint64_t)INT32_MAX / 4) {
    455             ALOGE("buffer size is too big, width=%d, height=%d", mVideoWidth, mVideoHeight);
    456             return BAD_VALUE;
    457         }
    458     }
    459 
    460     msg->setMessage("format", format);
    461     msg->setInt32("flags", flags);
    462     msg->setObject("surface", surface);
    463 
    464     if (crypto != NULL) {
    465         msg->setPointer("crypto", crypto.get());
    466     }
    467 
    468     // save msg for reset
    469     mConfigureMsg = msg;
    470 
    471     status_t err;
    472     Vector<MediaResource> resources;
    473     MediaResource::Type type = (mFlags & kFlagIsSecure) ?
    474             MediaResource::kSecureCodec : MediaResource::kNonSecureCodec;
    475     MediaResource::SubType subtype =
    476             mIsVideo ? MediaResource::kVideoCodec : MediaResource::kAudioCodec;
    477     resources.push_back(MediaResource(type, subtype, 1));
    478     // Don't know the buffer size at this point, but it's fine to use 1 because
    479     // the reclaimResource call doesn't consider the requester's buffer size for now.
    480     resources.push_back(MediaResource(MediaResource::kGraphicMemory, 1));
    481     for (int i = 0; i <= kMaxRetry; ++i) {
    482         if (i > 0) {
    483             // Don't try to reclaim resource for the first time.
    484             if (!mResourceManagerService->reclaimResource(resources)) {
    485                 break;
    486             }
    487         }
    488 
    489         sp<AMessage> response;
    490         err = PostAndAwaitResponse(msg, &response);
    491         if (err != OK && err != INVALID_OPERATION) {
    492             // MediaCodec now set state to UNINITIALIZED upon any fatal error.
    493             // To maintain backward-compatibility, do a reset() to put codec
    494             // back into INITIALIZED state.
    495             // But don't reset if the err is INVALID_OPERATION, which means
    496             // the configure failure is due to wrong state.
    497 
    498             ALOGE("configure failed with err 0x%08x, resetting...", err);
    499             reset();
    500         }
    501         if (!isResourceError(err)) {
    502             break;
    503         }
    504     }
    505     return err;
    506 }
    507 
    508 status_t MediaCodec::setInputSurface(
    509         const sp<PersistentSurface> &surface) {
    510     sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
    511     msg->setObject("input-surface", surface.get());
    512 
    513     sp<AMessage> response;
    514     return PostAndAwaitResponse(msg, &response);
    515 }
    516 
    517 status_t MediaCodec::setSurface(const sp<Surface> &surface) {
    518     sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
    519     msg->setObject("surface", surface);
    520 
    521     sp<AMessage> response;
    522     return PostAndAwaitResponse(msg, &response);
    523 }
    524 
    525 status_t MediaCodec::createInputSurface(
    526         sp<IGraphicBufferProducer>* bufferProducer) {
    527     sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, this);
    528 
    529     sp<AMessage> response;
    530     status_t err = PostAndAwaitResponse(msg, &response);
    531     if (err == NO_ERROR) {
    532         // unwrap the sp<IGraphicBufferProducer>
    533         sp<RefBase> obj;
    534         bool found = response->findObject("input-surface", &obj);
    535         CHECK(found);
    536         sp<BufferProducerWrapper> wrapper(
    537                 static_cast<BufferProducerWrapper*>(obj.get()));
    538         *bufferProducer = wrapper->getBufferProducer();
    539     } else {
    540         ALOGW("createInputSurface failed, err=%d", err);
    541     }
    542     return err;
    543 }
    544 
    545 uint64_t MediaCodec::getGraphicBufferSize() {
    546     if (!mIsVideo) {
    547         return 0;
    548     }
    549 
    550     uint64_t size = 0;
    551     size_t portNum = sizeof(mPortBuffers) / sizeof((mPortBuffers)[0]);
    552     for (size_t i = 0; i < portNum; ++i) {
    553         // TODO: this is just an estimation, we should get the real buffer size from ACodec.
    554         size += mPortBuffers[i].size() * mVideoWidth * mVideoHeight * 3 / 2;
    555     }
    556     return size;
    557 }
    558 
    559 void MediaCodec::addResource(
    560         MediaResource::Type type, MediaResource::SubType subtype, uint64_t value) {
    561     Vector<MediaResource> resources;
    562     resources.push_back(MediaResource(type, subtype, value));
    563     mResourceManagerService->addResource(
    564             getId(mResourceManagerClient), mResourceManagerClient, resources);
    565 }
    566 
    567 status_t MediaCodec::start() {
    568     sp<AMessage> msg = new AMessage(kWhatStart, this);
    569 
    570     status_t err;
    571     Vector<MediaResource> resources;
    572     MediaResource::Type type = (mFlags & kFlagIsSecure) ?
    573             MediaResource::kSecureCodec : MediaResource::kNonSecureCodec;
    574     MediaResource::SubType subtype =
    575             mIsVideo ? MediaResource::kVideoCodec : MediaResource::kAudioCodec;
    576     resources.push_back(MediaResource(type, subtype, 1));
    577     // Don't know the buffer size at this point, but it's fine to use 1 because
    578     // the reclaimResource call doesn't consider the requester's buffer size for now.
    579     resources.push_back(MediaResource(MediaResource::kGraphicMemory, 1));
    580     for (int i = 0; i <= kMaxRetry; ++i) {
    581         if (i > 0) {
    582             // Don't try to reclaim resource for the first time.
    583             if (!mResourceManagerService->reclaimResource(resources)) {
    584                 break;
    585             }
    586             // Recover codec from previous error before retry start.
    587             err = reset();
    588             if (err != OK) {
    589                 ALOGE("retrying start: failed to reset codec");
    590                 break;
    591             }
    592             sp<AMessage> response;
    593             err = PostAndAwaitResponse(mConfigureMsg, &response);
    594             if (err != OK) {
    595                 ALOGE("retrying start: failed to configure codec");
    596                 break;
    597             }
    598         }
    599 
    600         sp<AMessage> response;
    601         err = PostAndAwaitResponse(msg, &response);
    602         if (!isResourceError(err)) {
    603             break;
    604         }
    605     }
    606     return err;
    607 }
    608 
    609 status_t MediaCodec::stop() {
    610     sp<AMessage> msg = new AMessage(kWhatStop, this);
    611 
    612     sp<AMessage> response;
    613     return PostAndAwaitResponse(msg, &response);
    614 }
    615 
    616 bool MediaCodec::hasPendingBuffer(int portIndex) {
    617     const Vector<BufferInfo> &buffers = mPortBuffers[portIndex];
    618     for (size_t i = 0; i < buffers.size(); ++i) {
    619         const BufferInfo &info = buffers.itemAt(i);
    620         if (info.mOwnedByClient) {
    621             return true;
    622         }
    623     }
    624     return false;
    625 }
    626 
    627 bool MediaCodec::hasPendingBuffer() {
    628     return hasPendingBuffer(kPortIndexInput) || hasPendingBuffer(kPortIndexOutput);
    629 }
    630 
    631 status_t MediaCodec::reclaim(bool force) {
    632     ALOGD("MediaCodec::reclaim(%p) %s", this, mInitName.c_str());
    633     sp<AMessage> msg = new AMessage(kWhatRelease, this);
    634     msg->setInt32("reclaimed", 1);
    635     msg->setInt32("force", force ? 1 : 0);
    636 
    637     sp<AMessage> response;
    638     status_t ret = PostAndAwaitResponse(msg, &response);
    639     if (ret == -ENOENT) {
    640         ALOGD("MediaCodec looper is gone, skip reclaim");
    641         ret = OK;
    642     }
    643     return ret;
    644 }
    645 
    646 status_t MediaCodec::release() {
    647     sp<AMessage> msg = new AMessage(kWhatRelease, this);
    648 
    649     sp<AMessage> response;
    650     return PostAndAwaitResponse(msg, &response);
    651 }
    652 
    653 status_t MediaCodec::reset() {
    654     /* When external-facing MediaCodec object is created,
    655        it is already initialized.  Thus, reset is essentially
    656        release() followed by init(), plus clearing the state */
    657 
    658     status_t err = release();
    659 
    660     // unregister handlers
    661     if (mCodec != NULL) {
    662         if (mCodecLooper != NULL) {
    663             mCodecLooper->unregisterHandler(mCodec->id());
    664         } else {
    665             mLooper->unregisterHandler(mCodec->id());
    666         }
    667         mCodec = NULL;
    668     }
    669     mLooper->unregisterHandler(id());
    670 
    671     mFlags = 0;    // clear all flags
    672     mStickyError = OK;
    673 
    674     // reset state not reset by setState(UNINITIALIZED)
    675     mReplyID = 0;
    676     mDequeueInputReplyID = 0;
    677     mDequeueOutputReplyID = 0;
    678     mDequeueInputTimeoutGeneration = 0;
    679     mDequeueOutputTimeoutGeneration = 0;
    680     mHaveInputSurface = false;
    681 
    682     if (err == OK) {
    683         err = init(mInitName, mInitNameIsType, mInitIsEncoder);
    684     }
    685     return err;
    686 }
    687 
    688 status_t MediaCodec::queueInputBuffer(
    689         size_t index,
    690         size_t offset,
    691         size_t size,
    692         int64_t presentationTimeUs,
    693         uint32_t flags,
    694         AString *errorDetailMsg) {
    695     if (errorDetailMsg != NULL) {
    696         errorDetailMsg->clear();
    697     }
    698 
    699     sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
    700     msg->setSize("index", index);
    701     msg->setSize("offset", offset);
    702     msg->setSize("size", size);
    703     msg->setInt64("timeUs", presentationTimeUs);
    704     msg->setInt32("flags", flags);
    705     msg->setPointer("errorDetailMsg", errorDetailMsg);
    706 
    707     sp<AMessage> response;
    708     return PostAndAwaitResponse(msg, &response);
    709 }
    710 
    711 status_t MediaCodec::queueSecureInputBuffer(
    712         size_t index,
    713         size_t offset,
    714         const CryptoPlugin::SubSample *subSamples,
    715         size_t numSubSamples,
    716         const uint8_t key[16],
    717         const uint8_t iv[16],
    718         CryptoPlugin::Mode mode,
    719         const CryptoPlugin::Pattern &pattern,
    720         int64_t presentationTimeUs,
    721         uint32_t flags,
    722         AString *errorDetailMsg) {
    723     if (errorDetailMsg != NULL) {
    724         errorDetailMsg->clear();
    725     }
    726 
    727     sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
    728     msg->setSize("index", index);
    729     msg->setSize("offset", offset);
    730     msg->setPointer("subSamples", (void *)subSamples);
    731     msg->setSize("numSubSamples", numSubSamples);
    732     msg->setPointer("key", (void *)key);
    733     msg->setPointer("iv", (void *)iv);
    734     msg->setInt32("mode", mode);
    735     msg->setInt32("encryptBlocks", pattern.mEncryptBlocks);
    736     msg->setInt32("skipBlocks", pattern.mSkipBlocks);
    737     msg->setInt64("timeUs", presentationTimeUs);
    738     msg->setInt32("flags", flags);
    739     msg->setPointer("errorDetailMsg", errorDetailMsg);
    740 
    741     sp<AMessage> response;
    742     status_t err = PostAndAwaitResponse(msg, &response);
    743 
    744     return err;
    745 }
    746 
    747 status_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
    748     sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, this);
    749     msg->setInt64("timeoutUs", timeoutUs);
    750 
    751     sp<AMessage> response;
    752     status_t err;
    753     if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
    754         return err;
    755     }
    756 
    757     CHECK(response->findSize("index", index));
    758 
    759     return OK;
    760 }
    761 
    762 status_t MediaCodec::dequeueOutputBuffer(
    763         size_t *index,
    764         size_t *offset,
    765         size_t *size,
    766         int64_t *presentationTimeUs,
    767         uint32_t *flags,
    768         int64_t timeoutUs) {
    769     sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, this);
    770     msg->setInt64("timeoutUs", timeoutUs);
    771 
    772     sp<AMessage> response;
    773     status_t err;
    774     if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
    775         return err;
    776     }
    777 
    778     CHECK(response->findSize("index", index));
    779     CHECK(response->findSize("offset", offset));
    780     CHECK(response->findSize("size", size));
    781     CHECK(response->findInt64("timeUs", presentationTimeUs));
    782     CHECK(response->findInt32("flags", (int32_t *)flags));
    783 
    784     return OK;
    785 }
    786 
    787 status_t MediaCodec::renderOutputBufferAndRelease(size_t index) {
    788     sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
    789     msg->setSize("index", index);
    790     msg->setInt32("render", true);
    791 
    792     sp<AMessage> response;
    793     return PostAndAwaitResponse(msg, &response);
    794 }
    795 
    796 status_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestampNs) {
    797     sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
    798     msg->setSize("index", index);
    799     msg->setInt32("render", true);
    800     msg->setInt64("timestampNs", timestampNs);
    801 
    802     sp<AMessage> response;
    803     return PostAndAwaitResponse(msg, &response);
    804 }
    805 
    806 status_t MediaCodec::releaseOutputBuffer(size_t index) {
    807     sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
    808     msg->setSize("index", index);
    809 
    810     sp<AMessage> response;
    811     return PostAndAwaitResponse(msg, &response);
    812 }
    813 
    814 status_t MediaCodec::signalEndOfInputStream() {
    815     sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, this);
    816 
    817     sp<AMessage> response;
    818     return PostAndAwaitResponse(msg, &response);
    819 }
    820 
    821 status_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
    822     sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, this);
    823 
    824     sp<AMessage> response;
    825     status_t err;
    826     if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
    827         return err;
    828     }
    829 
    830     CHECK(response->findMessage("format", format));
    831 
    832     return OK;
    833 }
    834 
    835 status_t MediaCodec::getInputFormat(sp<AMessage> *format) const {
    836     sp<AMessage> msg = new AMessage(kWhatGetInputFormat, this);
    837 
    838     sp<AMessage> response;
    839     status_t err;
    840     if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
    841         return err;
    842     }
    843 
    844     CHECK(response->findMessage("format", format));
    845 
    846     return OK;
    847 }
    848 
    849 status_t MediaCodec::getName(AString *name) const {
    850     sp<AMessage> msg = new AMessage(kWhatGetName, this);
    851 
    852     sp<AMessage> response;
    853     status_t err;
    854     if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
    855         return err;
    856     }
    857 
    858     CHECK(response->findString("name", name));
    859 
    860     return OK;
    861 }
    862 
    863 status_t MediaCodec::getWidevineLegacyBuffers(Vector<sp<ABuffer> > *buffers) const {
    864     sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
    865     msg->setInt32("portIndex", kPortIndexInput);
    866     msg->setPointer("buffers", buffers);
    867     msg->setInt32("widevine", true);
    868 
    869     sp<AMessage> response;
    870     return PostAndAwaitResponse(msg, &response);
    871 }
    872 
    873 status_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
    874     sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
    875     msg->setInt32("portIndex", kPortIndexInput);
    876     msg->setPointer("buffers", buffers);
    877 
    878     sp<AMessage> response;
    879     return PostAndAwaitResponse(msg, &response);
    880 }
    881 
    882 status_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const {
    883     sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
    884     msg->setInt32("portIndex", kPortIndexOutput);
    885     msg->setPointer("buffers", buffers);
    886 
    887     sp<AMessage> response;
    888     return PostAndAwaitResponse(msg, &response);
    889 }
    890 
    891 status_t MediaCodec::getOutputBuffer(size_t index, sp<ABuffer> *buffer) {
    892     sp<AMessage> format;
    893     return getBufferAndFormat(kPortIndexOutput, index, buffer, &format);
    894 }
    895 
    896 status_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) {
    897     sp<ABuffer> buffer;
    898     return getBufferAndFormat(kPortIndexOutput, index, &buffer, format);
    899 }
    900 
    901 status_t MediaCodec::getInputBuffer(size_t index, sp<ABuffer> *buffer) {
    902     sp<AMessage> format;
    903     return getBufferAndFormat(kPortIndexInput, index, buffer, &format);
    904 }
    905 
    906 bool MediaCodec::isExecuting() const {
    907     return mState == STARTED || mState == FLUSHED;
    908 }
    909 
    910 status_t MediaCodec::getBufferAndFormat(
    911         size_t portIndex, size_t index,
    912         sp<ABuffer> *buffer, sp<AMessage> *format) {
    913     // use mutex instead of a context switch
    914     if (mReleasedByResourceManager) {
    915         ALOGE("getBufferAndFormat - resource already released");
    916         return DEAD_OBJECT;
    917     }
    918 
    919     if (buffer == NULL) {
    920         ALOGE("getBufferAndFormat - null ABuffer");
    921         return INVALID_OPERATION;
    922     }
    923 
    924     if (format == NULL) {
    925         ALOGE("getBufferAndFormat - null AMessage");
    926         return INVALID_OPERATION;
    927     }
    928 
    929     buffer->clear();
    930     format->clear();
    931 
    932     if (!isExecuting()) {
    933         ALOGE("getBufferAndFormat - not executing");
    934         return INVALID_OPERATION;
    935     }
    936 
    937     // we do not want mPortBuffers to change during this section
    938     // we also don't want mOwnedByClient to change during this
    939     Mutex::Autolock al(mBufferLock);
    940 
    941     Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
    942     if (index >= buffers->size()) {
    943         ALOGE("getBufferAndFormat - trying to get buffer with "
    944               "bad index (index=%zu buffer_size=%zu)", index, buffers->size());
    945         return INVALID_OPERATION;
    946     }
    947 
    948     const BufferInfo &info = buffers->itemAt(index);
    949     if (!info.mOwnedByClient) {
    950         ALOGE("getBufferAndFormat - invalid operation "
    951               "(the index %zu is not owned by client)", index);
    952         return INVALID_OPERATION;
    953     }
    954 
    955     // by the time buffers array is initialized, crypto is set
    956     *buffer = (portIndex == kPortIndexInput && mCrypto != NULL) ?
    957                   info.mEncryptedData :
    958                   info.mData;
    959 
    960     *format = info.mFormat;
    961 
    962     return OK;
    963 }
    964 
    965 status_t MediaCodec::flush() {
    966     sp<AMessage> msg = new AMessage(kWhatFlush, this);
    967 
    968     sp<AMessage> response;
    969     return PostAndAwaitResponse(msg, &response);
    970 }
    971 
    972 status_t MediaCodec::requestIDRFrame() {
    973     (new AMessage(kWhatRequestIDRFrame, this))->post();
    974 
    975     return OK;
    976 }
    977 
    978 void MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
    979     sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, this);
    980     msg->setMessage("notify", notify);
    981     msg->post();
    982 }
    983 
    984 ////////////////////////////////////////////////////////////////////////////////
    985 
    986 void MediaCodec::cancelPendingDequeueOperations() {
    987     if (mFlags & kFlagDequeueInputPending) {
    988         PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION);
    989 
    990         ++mDequeueInputTimeoutGeneration;
    991         mDequeueInputReplyID = 0;
    992         mFlags &= ~kFlagDequeueInputPending;
    993     }
    994 
    995     if (mFlags & kFlagDequeueOutputPending) {
    996         PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION);
    997 
    998         ++mDequeueOutputTimeoutGeneration;
    999         mDequeueOutputReplyID = 0;
   1000         mFlags &= ~kFlagDequeueOutputPending;
   1001     }
   1002 }
   1003 
   1004 bool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
   1005     if (!isExecuting() || (mFlags & kFlagIsAsync)
   1006             || (newRequest && (mFlags & kFlagDequeueInputPending))) {
   1007         PostReplyWithError(replyID, INVALID_OPERATION);
   1008         return true;
   1009     } else if (mFlags & kFlagStickyError) {
   1010         PostReplyWithError(replyID, getStickyError());
   1011         return true;
   1012     }
   1013 
   1014     ssize_t index = dequeuePortBuffer(kPortIndexInput);
   1015 
   1016     if (index < 0) {
   1017         CHECK_EQ(index, -EAGAIN);
   1018         return false;
   1019     }
   1020 
   1021     sp<AMessage> response = new AMessage;
   1022     response->setSize("index", index);
   1023     response->postReply(replyID);
   1024 
   1025     return true;
   1026 }
   1027 
   1028 bool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
   1029     if (!isExecuting() || (mFlags & kFlagIsAsync)
   1030             || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
   1031         PostReplyWithError(replyID, INVALID_OPERATION);
   1032     } else if (mFlags & kFlagStickyError) {
   1033         PostReplyWithError(replyID, getStickyError());
   1034     } else if (mFlags & kFlagOutputBuffersChanged) {
   1035         PostReplyWithError(replyID, INFO_OUTPUT_BUFFERS_CHANGED);
   1036         mFlags &= ~kFlagOutputBuffersChanged;
   1037     } else if (mFlags & kFlagOutputFormatChanged) {
   1038         PostReplyWithError(replyID, INFO_FORMAT_CHANGED);
   1039         mFlags &= ~kFlagOutputFormatChanged;
   1040     } else {
   1041         sp<AMessage> response = new AMessage;
   1042         ssize_t index = dequeuePortBuffer(kPortIndexOutput);
   1043 
   1044         if (index < 0) {
   1045             CHECK_EQ(index, -EAGAIN);
   1046             return false;
   1047         }
   1048 
   1049         const sp<ABuffer> &buffer =
   1050             mPortBuffers[kPortIndexOutput].itemAt(index).mData;
   1051 
   1052         response->setSize("index", index);
   1053         response->setSize("offset", buffer->offset());
   1054         response->setSize("size", buffer->size());
   1055 
   1056         int64_t timeUs;
   1057         CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
   1058 
   1059         response->setInt64("timeUs", timeUs);
   1060 
   1061         int32_t omxFlags;
   1062         CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
   1063 
   1064         uint32_t flags = 0;
   1065         if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
   1066             flags |= BUFFER_FLAG_SYNCFRAME;
   1067         }
   1068         if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   1069             flags |= BUFFER_FLAG_CODECCONFIG;
   1070         }
   1071         if (omxFlags & OMX_BUFFERFLAG_EOS) {
   1072             flags |= BUFFER_FLAG_EOS;
   1073         }
   1074 
   1075         response->setInt32("flags", flags);
   1076         response->postReply(replyID);
   1077     }
   1078 
   1079     return true;
   1080 }
   1081 
   1082 void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
   1083     switch (msg->what()) {
   1084         case kWhatCodecNotify:
   1085         {
   1086             int32_t what;
   1087             CHECK(msg->findInt32("what", &what));
   1088 
   1089             switch (what) {
   1090                 case CodecBase::kWhatError:
   1091                 {
   1092                     int32_t err, actionCode;
   1093                     CHECK(msg->findInt32("err", &err));
   1094                     CHECK(msg->findInt32("actionCode", &actionCode));
   1095 
   1096                     ALOGE("Codec reported err %#x, actionCode %d, while in state %d",
   1097                             err, actionCode, mState);
   1098                     if (err == DEAD_OBJECT) {
   1099                         mFlags |= kFlagSawMediaServerDie;
   1100                         mFlags &= ~kFlagIsComponentAllocated;
   1101                     }
   1102 
   1103                     bool sendErrorResponse = true;
   1104 
   1105                     switch (mState) {
   1106                         case INITIALIZING:
   1107                         {
   1108                             setState(UNINITIALIZED);
   1109                             break;
   1110                         }
   1111 
   1112                         case CONFIGURING:
   1113                         {
   1114                             setState(actionCode == ACTION_CODE_FATAL ?
   1115                                     UNINITIALIZED : INITIALIZED);
   1116                             break;
   1117                         }
   1118 
   1119                         case STARTING:
   1120                         {
   1121                             setState(actionCode == ACTION_CODE_FATAL ?
   1122                                     UNINITIALIZED : CONFIGURED);
   1123                             break;
   1124                         }
   1125 
   1126                         case STOPPING:
   1127                         case RELEASING:
   1128                         {
   1129                             // Ignore the error, assuming we'll still get
   1130                             // the shutdown complete notification.
   1131 
   1132                             sendErrorResponse = false;
   1133 
   1134                             if (mFlags & kFlagSawMediaServerDie) {
   1135                                 // MediaServer died, there definitely won't
   1136                                 // be a shutdown complete notification after
   1137                                 // all.
   1138 
   1139                                 // note that we're directly going from
   1140                                 // STOPPING->UNINITIALIZED, instead of the
   1141                                 // usual STOPPING->INITIALIZED state.
   1142                                 setState(UNINITIALIZED);
   1143                                 if (mState == RELEASING) {
   1144                                     mComponentName.clear();
   1145                                 }
   1146                                 (new AMessage)->postReply(mReplyID);
   1147                             }
   1148                             break;
   1149                         }
   1150 
   1151                         case FLUSHING:
   1152                         {
   1153                             if (actionCode == ACTION_CODE_FATAL) {
   1154                                 setState(UNINITIALIZED);
   1155                             } else {
   1156                                 setState(
   1157                                         (mFlags & kFlagIsAsync) ? FLUSHED : STARTED);
   1158                             }
   1159                             break;
   1160                         }
   1161 
   1162                         case FLUSHED:
   1163                         case STARTED:
   1164                         {
   1165                             sendErrorResponse = false;
   1166 
   1167                             setStickyError(err);
   1168                             postActivityNotificationIfPossible();
   1169 
   1170                             cancelPendingDequeueOperations();
   1171 
   1172                             if (mFlags & kFlagIsAsync) {
   1173                                 onError(err, actionCode);
   1174                             }
   1175                             switch (actionCode) {
   1176                             case ACTION_CODE_TRANSIENT:
   1177                                 break;
   1178                             case ACTION_CODE_RECOVERABLE:
   1179                                 setState(INITIALIZED);
   1180                                 break;
   1181                             default:
   1182                                 setState(UNINITIALIZED);
   1183                                 break;
   1184                             }
   1185                             break;
   1186                         }
   1187 
   1188                         default:
   1189                         {
   1190                             sendErrorResponse = false;
   1191 
   1192                             setStickyError(err);
   1193                             postActivityNotificationIfPossible();
   1194 
   1195                             // actionCode in an uninitialized state is always fatal.
   1196                             if (mState == UNINITIALIZED) {
   1197                                 actionCode = ACTION_CODE_FATAL;
   1198                             }
   1199                             if (mFlags & kFlagIsAsync) {
   1200                                 onError(err, actionCode);
   1201                             }
   1202                             switch (actionCode) {
   1203                             case ACTION_CODE_TRANSIENT:
   1204                                 break;
   1205                             case ACTION_CODE_RECOVERABLE:
   1206                                 setState(INITIALIZED);
   1207                                 break;
   1208                             default:
   1209                                 setState(UNINITIALIZED);
   1210                                 break;
   1211                             }
   1212                             break;
   1213                         }
   1214                     }
   1215 
   1216                     if (sendErrorResponse) {
   1217                         PostReplyWithError(mReplyID, err);
   1218                     }
   1219                     break;
   1220                 }
   1221 
   1222                 case CodecBase::kWhatComponentAllocated:
   1223                 {
   1224                     CHECK_EQ(mState, INITIALIZING);
   1225                     setState(INITIALIZED);
   1226                     mFlags |= kFlagIsComponentAllocated;
   1227 
   1228                     CHECK(msg->findString("componentName", &mComponentName));
   1229 
   1230                     if (mComponentName.startsWith("OMX.google.")) {
   1231                         mFlags |= kFlagUsesSoftwareRenderer;
   1232                     } else {
   1233                         mFlags &= ~kFlagUsesSoftwareRenderer;
   1234                     }
   1235 
   1236                     MediaResource::Type resourceType;
   1237                     if (mComponentName.endsWith(".secure")) {
   1238                         mFlags |= kFlagIsSecure;
   1239                         resourceType = MediaResource::kSecureCodec;
   1240                     } else {
   1241                         mFlags &= ~kFlagIsSecure;
   1242                         resourceType = MediaResource::kNonSecureCodec;
   1243                     }
   1244 
   1245                     if (mIsVideo) {
   1246                         // audio codec is currently ignored.
   1247                         addResource(resourceType, MediaResource::kVideoCodec, 1);
   1248                     }
   1249 
   1250                     (new AMessage)->postReply(mReplyID);
   1251                     break;
   1252                 }
   1253 
   1254                 case CodecBase::kWhatComponentConfigured:
   1255                 {
   1256                     if (mState == UNINITIALIZED || mState == INITIALIZED) {
   1257                         // In case a kWhatError message came in and replied with error,
   1258                         // we log a warning and ignore.
   1259                         ALOGW("configure interrupted by error, current state %d", mState);
   1260                         break;
   1261                     }
   1262                     CHECK_EQ(mState, CONFIGURING);
   1263 
   1264                     // reset input surface flag
   1265                     mHaveInputSurface = false;
   1266 
   1267                     CHECK(msg->findMessage("input-format", &mInputFormat));
   1268                     CHECK(msg->findMessage("output-format", &mOutputFormat));
   1269                     ALOGV("[%s] configured as input format: %s, output format: %s",
   1270                             mComponentName.c_str(),
   1271                             mInputFormat->debugString(4).c_str(),
   1272                             mOutputFormat->debugString(4).c_str());
   1273                     int32_t usingSwRenderer;
   1274                     if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer)
   1275                             && usingSwRenderer) {
   1276                         mFlags |= kFlagUsesSoftwareRenderer;
   1277                     }
   1278                     setState(CONFIGURED);
   1279                     (new AMessage)->postReply(mReplyID);
   1280                     break;
   1281                 }
   1282 
   1283                 case CodecBase::kWhatInputSurfaceCreated:
   1284                 {
   1285                     // response to initiateCreateInputSurface()
   1286                     status_t err = NO_ERROR;
   1287                     sp<AMessage> response = new AMessage;
   1288                     if (!msg->findInt32("err", &err)) {
   1289                         sp<RefBase> obj;
   1290                         msg->findObject("input-surface", &obj);
   1291                         CHECK(msg->findMessage("input-format", &mInputFormat));
   1292                         CHECK(msg->findMessage("output-format", &mOutputFormat));
   1293                         ALOGV("[%s] input surface created as input format: %s, output format: %s",
   1294                                 mComponentName.c_str(),
   1295                                 mInputFormat->debugString(4).c_str(),
   1296                                 mOutputFormat->debugString(4).c_str());
   1297                         CHECK(obj != NULL);
   1298                         response->setObject("input-surface", obj);
   1299                         mHaveInputSurface = true;
   1300                     } else {
   1301                         response->setInt32("err", err);
   1302                     }
   1303                     response->postReply(mReplyID);
   1304                     break;
   1305                 }
   1306 
   1307                 case CodecBase::kWhatInputSurfaceAccepted:
   1308                 {
   1309                     // response to initiateSetInputSurface()
   1310                     status_t err = NO_ERROR;
   1311                     sp<AMessage> response = new AMessage();
   1312                     if (!msg->findInt32("err", &err)) {
   1313                         mHaveInputSurface = true;
   1314                     } else {
   1315                         response->setInt32("err", err);
   1316                     }
   1317                     response->postReply(mReplyID);
   1318                     break;
   1319                 }
   1320 
   1321                 case CodecBase::kWhatSignaledInputEOS:
   1322                 {
   1323                     // response to signalEndOfInputStream()
   1324                     sp<AMessage> response = new AMessage;
   1325                     status_t err;
   1326                     if (msg->findInt32("err", &err)) {
   1327                         response->setInt32("err", err);
   1328                     }
   1329                     response->postReply(mReplyID);
   1330                     break;
   1331                 }
   1332 
   1333 
   1334                 case CodecBase::kWhatBuffersAllocated:
   1335                 {
   1336                     Mutex::Autolock al(mBufferLock);
   1337                     int32_t portIndex;
   1338                     CHECK(msg->findInt32("portIndex", &portIndex));
   1339 
   1340                     ALOGV("%s buffers allocated",
   1341                           portIndex == kPortIndexInput ? "input" : "output");
   1342 
   1343                     CHECK(portIndex == kPortIndexInput
   1344                             || portIndex == kPortIndexOutput);
   1345 
   1346                     mPortBuffers[portIndex].clear();
   1347 
   1348                     Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
   1349 
   1350                     sp<RefBase> obj;
   1351                     CHECK(msg->findObject("portDesc", &obj));
   1352 
   1353                     sp<CodecBase::PortDescription> portDesc =
   1354                         static_cast<CodecBase::PortDescription *>(obj.get());
   1355 
   1356                     size_t numBuffers = portDesc->countBuffers();
   1357 
   1358                     size_t totalSize = 0;
   1359                     for (size_t i = 0; i < numBuffers; ++i) {
   1360                         if (portIndex == kPortIndexInput && mCrypto != NULL) {
   1361                             totalSize += portDesc->bufferAt(i)->capacity();
   1362                         }
   1363                     }
   1364 
   1365                     if (totalSize) {
   1366                         mDealer = new MemoryDealer(totalSize, "MediaCodec");
   1367                     }
   1368 
   1369                     for (size_t i = 0; i < numBuffers; ++i) {
   1370                         BufferInfo info;
   1371                         info.mBufferID = portDesc->bufferIDAt(i);
   1372                         info.mOwnedByClient = false;
   1373                         info.mData = portDesc->bufferAt(i);
   1374                         info.mNativeHandle = portDesc->handleAt(i);
   1375                         info.mMemRef = portDesc->memRefAt(i);
   1376 
   1377                         if (portIndex == kPortIndexInput && mCrypto != NULL) {
   1378                             sp<IMemory> mem = mDealer->allocate(info.mData->capacity());
   1379                             info.mEncryptedData =
   1380                                 new ABuffer(mem->pointer(), info.mData->capacity());
   1381                             info.mSharedEncryptedBuffer = mem;
   1382                         }
   1383 
   1384                         buffers->push_back(info);
   1385                     }
   1386 
   1387                     if (portIndex == kPortIndexOutput) {
   1388                         if (mState == STARTING) {
   1389                             // We're always allocating output buffers after
   1390                             // allocating input buffers, so this is a good
   1391                             // indication that now all buffers are allocated.
   1392                             if (mIsVideo) {
   1393                                 addResource(
   1394                                         MediaResource::kGraphicMemory,
   1395                                         MediaResource::kUnspecifiedSubType,
   1396                                         getGraphicBufferSize());
   1397                             }
   1398                             setState(STARTED);
   1399                             (new AMessage)->postReply(mReplyID);
   1400                         } else {
   1401                             mFlags |= kFlagOutputBuffersChanged;
   1402                             postActivityNotificationIfPossible();
   1403                         }
   1404                     }
   1405                     break;
   1406                 }
   1407 
   1408                 case CodecBase::kWhatOutputFormatChanged:
   1409                 {
   1410                     CHECK(msg->findMessage("format", &mOutputFormat));
   1411 
   1412                     ALOGV("[%s] output format changed to: %s",
   1413                             mComponentName.c_str(), mOutputFormat->debugString(4).c_str());
   1414 
   1415                     if (mSoftRenderer == NULL &&
   1416                             mSurface != NULL &&
   1417                             (mFlags & kFlagUsesSoftwareRenderer)) {
   1418                         AString mime;
   1419                         CHECK(mOutputFormat->findString("mime", &mime));
   1420 
   1421                         // TODO: propagate color aspects to software renderer to allow better
   1422                         // color conversion to RGB. For now, just mark dataspace for YUV
   1423                         // rendering.
   1424                         int32_t dataSpace;
   1425                         if (mOutputFormat->findInt32("android._dataspace", &dataSpace)) {
   1426                             ALOGD("[%s] setting dataspace on output surface to #%x",
   1427                                     mComponentName.c_str(), dataSpace);
   1428                             int err = native_window_set_buffers_data_space(
   1429                                     mSurface.get(), (android_dataspace)dataSpace);
   1430                             ALOGW_IF(err != 0, "failed to set dataspace on surface (%d)", err);
   1431                         }
   1432 
   1433                         if (mime.startsWithIgnoreCase("video/")) {
   1434                             mSoftRenderer = new SoftwareRenderer(mSurface, mRotationDegrees);
   1435                         }
   1436                     }
   1437 
   1438                     if (mFlags & kFlagIsEncoder) {
   1439                         // Before we announce the format change we should
   1440                         // collect codec specific data and amend the output
   1441                         // format as necessary.
   1442                         mFlags |= kFlagGatherCodecSpecificData;
   1443                     } else if (mFlags & kFlagIsAsync) {
   1444                         onOutputFormatChanged();
   1445                     } else {
   1446                         mFlags |= kFlagOutputFormatChanged;
   1447                         postActivityNotificationIfPossible();
   1448                     }
   1449 
   1450                     // Notify mCrypto of video resolution changes
   1451                     if (mCrypto != NULL) {
   1452                         int32_t left, top, right, bottom, width, height;
   1453                         if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
   1454                             mCrypto->notifyResolution(right - left + 1, bottom - top + 1);
   1455                         } else if (mOutputFormat->findInt32("width", &width)
   1456                                 && mOutputFormat->findInt32("height", &height)) {
   1457                             mCrypto->notifyResolution(width, height);
   1458                         }
   1459                     }
   1460 
   1461                     break;
   1462                 }
   1463 
   1464                 case CodecBase::kWhatOutputFramesRendered:
   1465                 {
   1466                     // ignore these in all states except running, and check that we have a
   1467                     // notification set
   1468                     if (mState == STARTED && mOnFrameRenderedNotification != NULL) {
   1469                         sp<AMessage> notify = mOnFrameRenderedNotification->dup();
   1470                         notify->setMessage("data", msg);
   1471                         notify->post();
   1472                     }
   1473                     break;
   1474                 }
   1475 
   1476                 case CodecBase::kWhatFillThisBuffer:
   1477                 {
   1478                     /* size_t index = */updateBuffers(kPortIndexInput, msg);
   1479 
   1480                     if (mState == FLUSHING
   1481                             || mState == STOPPING
   1482                             || mState == RELEASING) {
   1483                         returnBuffersToCodecOnPort(kPortIndexInput);
   1484                         break;
   1485                     }
   1486 
   1487                     if (!mCSD.empty()) {
   1488                         ssize_t index = dequeuePortBuffer(kPortIndexInput);
   1489                         CHECK_GE(index, 0);
   1490 
   1491                         // If codec specific data had been specified as
   1492                         // part of the format in the call to configure and
   1493                         // if there's more csd left, we submit it here
   1494                         // clients only get access to input buffers once
   1495                         // this data has been exhausted.
   1496 
   1497                         status_t err = queueCSDInputBuffer(index);
   1498 
   1499                         if (err != OK) {
   1500                             ALOGE("queueCSDInputBuffer failed w/ error %d",
   1501                                   err);
   1502 
   1503                             setStickyError(err);
   1504                             postActivityNotificationIfPossible();
   1505 
   1506                             cancelPendingDequeueOperations();
   1507                         }
   1508                         break;
   1509                     }
   1510 
   1511                     if (mFlags & kFlagIsAsync) {
   1512                         if (!mHaveInputSurface) {
   1513                             if (mState == FLUSHED) {
   1514                                 mHavePendingInputBuffers = true;
   1515                             } else {
   1516                                 onInputBufferAvailable();
   1517                             }
   1518                         }
   1519                     } else if (mFlags & kFlagDequeueInputPending) {
   1520                         CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
   1521 
   1522                         ++mDequeueInputTimeoutGeneration;
   1523                         mFlags &= ~kFlagDequeueInputPending;
   1524                         mDequeueInputReplyID = 0;
   1525                     } else {
   1526                         postActivityNotificationIfPossible();
   1527                     }
   1528                     break;
   1529                 }
   1530 
   1531                 case CodecBase::kWhatDrainThisBuffer:
   1532                 {
   1533                     /* size_t index = */updateBuffers(kPortIndexOutput, msg);
   1534 
   1535                     if (mState == FLUSHING
   1536                             || mState == STOPPING
   1537                             || mState == RELEASING) {
   1538                         returnBuffersToCodecOnPort(kPortIndexOutput);
   1539                         break;
   1540                     }
   1541 
   1542                     sp<ABuffer> buffer;
   1543                     CHECK(msg->findBuffer("buffer", &buffer));
   1544 
   1545                     int32_t omxFlags;
   1546                     CHECK(msg->findInt32("flags", &omxFlags));
   1547 
   1548                     buffer->meta()->setInt32("omxFlags", omxFlags);
   1549 
   1550                     if (mFlags & kFlagGatherCodecSpecificData) {
   1551                         // This is the very first output buffer after a
   1552                         // format change was signalled, it'll either contain
   1553                         // the one piece of codec specific data we can expect
   1554                         // or there won't be codec specific data.
   1555                         if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   1556                             status_t err =
   1557                                 amendOutputFormatWithCodecSpecificData(buffer);
   1558 
   1559                             if (err != OK) {
   1560                                 ALOGE("Codec spit out malformed codec "
   1561                                       "specific data!");
   1562                             }
   1563                         }
   1564 
   1565                         mFlags &= ~kFlagGatherCodecSpecificData;
   1566                         if (mFlags & kFlagIsAsync) {
   1567                             onOutputFormatChanged();
   1568                         } else {
   1569                             mFlags |= kFlagOutputFormatChanged;
   1570                         }
   1571                     }
   1572 
   1573                     if (mFlags & kFlagIsAsync) {
   1574                         onOutputBufferAvailable();
   1575                     } else if (mFlags & kFlagDequeueOutputPending) {
   1576                         CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
   1577 
   1578                         ++mDequeueOutputTimeoutGeneration;
   1579                         mFlags &= ~kFlagDequeueOutputPending;
   1580                         mDequeueOutputReplyID = 0;
   1581                     } else {
   1582                         postActivityNotificationIfPossible();
   1583                     }
   1584 
   1585                     break;
   1586                 }
   1587 
   1588                 case CodecBase::kWhatEOS:
   1589                 {
   1590                     // We already notify the client of this by using the
   1591                     // corresponding flag in "onOutputBufferReady".
   1592                     break;
   1593                 }
   1594 
   1595                 case CodecBase::kWhatShutdownCompleted:
   1596                 {
   1597                     if (mState == STOPPING) {
   1598                         setState(INITIALIZED);
   1599                     } else {
   1600                         CHECK_EQ(mState, RELEASING);
   1601                         setState(UNINITIALIZED);
   1602                         mComponentName.clear();
   1603                     }
   1604                     mFlags &= ~kFlagIsComponentAllocated;
   1605 
   1606                     mResourceManagerService->removeResource(getId(mResourceManagerClient));
   1607 
   1608                     (new AMessage)->postReply(mReplyID);
   1609                     break;
   1610                 }
   1611 
   1612                 case CodecBase::kWhatFlushCompleted:
   1613                 {
   1614                     if (mState != FLUSHING) {
   1615                         ALOGW("received FlushCompleted message in state %d",
   1616                                 mState);
   1617                         break;
   1618                     }
   1619 
   1620                     if (mFlags & kFlagIsAsync) {
   1621                         setState(FLUSHED);
   1622                     } else {
   1623                         setState(STARTED);
   1624                         mCodec->signalResume();
   1625                     }
   1626 
   1627                     (new AMessage)->postReply(mReplyID);
   1628                     break;
   1629                 }
   1630 
   1631                 default:
   1632                     TRESPASS();
   1633             }
   1634             break;
   1635         }
   1636 
   1637         case kWhatInit:
   1638         {
   1639             sp<AReplyToken> replyID;
   1640             CHECK(msg->senderAwaitsResponse(&replyID));
   1641 
   1642             if (mState != UNINITIALIZED) {
   1643                 PostReplyWithError(replyID, INVALID_OPERATION);
   1644                 break;
   1645             }
   1646 
   1647             mReplyID = replyID;
   1648             setState(INITIALIZING);
   1649 
   1650             AString name;
   1651             CHECK(msg->findString("name", &name));
   1652 
   1653             int32_t nameIsType;
   1654             int32_t encoder = false;
   1655             CHECK(msg->findInt32("nameIsType", &nameIsType));
   1656             if (nameIsType) {
   1657                 CHECK(msg->findInt32("encoder", &encoder));
   1658             }
   1659 
   1660             sp<AMessage> format = new AMessage;
   1661 
   1662             if (nameIsType) {
   1663                 format->setString("mime", name.c_str());
   1664                 format->setInt32("encoder", encoder);
   1665             } else {
   1666                 format->setString("componentName", name.c_str());
   1667             }
   1668 
   1669             mCodec->initiateAllocateComponent(format);
   1670             break;
   1671         }
   1672 
   1673         case kWhatSetNotification:
   1674         {
   1675             sp<AMessage> notify;
   1676             if (msg->findMessage("on-frame-rendered", &notify)) {
   1677                 mOnFrameRenderedNotification = notify;
   1678             }
   1679             break;
   1680         }
   1681 
   1682         case kWhatSetCallback:
   1683         {
   1684             sp<AReplyToken> replyID;
   1685             CHECK(msg->senderAwaitsResponse(&replyID));
   1686 
   1687             if (mState == UNINITIALIZED
   1688                     || mState == INITIALIZING
   1689                     || isExecuting()) {
   1690                 // callback can't be set after codec is executing,
   1691                 // or before it's initialized (as the callback
   1692                 // will be cleared when it goes to INITIALIZED)
   1693                 PostReplyWithError(replyID, INVALID_OPERATION);
   1694                 break;
   1695             }
   1696 
   1697             sp<AMessage> callback;
   1698             CHECK(msg->findMessage("callback", &callback));
   1699 
   1700             mCallback = callback;
   1701 
   1702             if (mCallback != NULL) {
   1703                 ALOGI("MediaCodec will operate in async mode");
   1704                 mFlags |= kFlagIsAsync;
   1705             } else {
   1706                 mFlags &= ~kFlagIsAsync;
   1707             }
   1708 
   1709             sp<AMessage> response = new AMessage;
   1710             response->postReply(replyID);
   1711             break;
   1712         }
   1713 
   1714         case kWhatConfigure:
   1715         {
   1716             sp<AReplyToken> replyID;
   1717             CHECK(msg->senderAwaitsResponse(&replyID));
   1718 
   1719             if (mState != INITIALIZED) {
   1720                 PostReplyWithError(replyID, INVALID_OPERATION);
   1721                 break;
   1722             }
   1723 
   1724             sp<RefBase> obj;
   1725             CHECK(msg->findObject("surface", &obj));
   1726 
   1727             sp<AMessage> format;
   1728             CHECK(msg->findMessage("format", &format));
   1729 
   1730             int32_t push;
   1731             if (msg->findInt32("push-blank-buffers-on-shutdown", &push) && push != 0) {
   1732                 mFlags |= kFlagPushBlankBuffersOnShutdown;
   1733             }
   1734 
   1735             if (obj != NULL) {
   1736                 format->setObject("native-window", obj);
   1737                 status_t err = handleSetSurface(static_cast<Surface *>(obj.get()));
   1738                 if (err != OK) {
   1739                     PostReplyWithError(replyID, err);
   1740                     break;
   1741                 }
   1742             } else {
   1743                 handleSetSurface(NULL);
   1744             }
   1745 
   1746             mReplyID = replyID;
   1747             setState(CONFIGURING);
   1748 
   1749             void *crypto;
   1750             if (!msg->findPointer("crypto", &crypto)) {
   1751                 crypto = NULL;
   1752             }
   1753 
   1754             mCrypto = static_cast<ICrypto *>(crypto);
   1755 
   1756             uint32_t flags;
   1757             CHECK(msg->findInt32("flags", (int32_t *)&flags));
   1758 
   1759             if (flags & CONFIGURE_FLAG_ENCODE) {
   1760                 format->setInt32("encoder", true);
   1761                 mFlags |= kFlagIsEncoder;
   1762             }
   1763 
   1764             extractCSD(format);
   1765 
   1766             mCodec->initiateConfigureComponent(format);
   1767             break;
   1768         }
   1769 
   1770         case kWhatSetSurface:
   1771         {
   1772             sp<AReplyToken> replyID;
   1773             CHECK(msg->senderAwaitsResponse(&replyID));
   1774 
   1775             status_t err = OK;
   1776             sp<Surface> surface;
   1777 
   1778             switch (mState) {
   1779                 case CONFIGURED:
   1780                 case STARTED:
   1781                 case FLUSHED:
   1782                 {
   1783                     sp<RefBase> obj;
   1784                     (void)msg->findObject("surface", &obj);
   1785                     sp<Surface> surface = static_cast<Surface *>(obj.get());
   1786                     if (mSurface == NULL) {
   1787                         // do not support setting surface if it was not set
   1788                         err = INVALID_OPERATION;
   1789                     } else if (obj == NULL) {
   1790                         // do not support unsetting surface
   1791                         err = BAD_VALUE;
   1792                     } else {
   1793                         err = connectToSurface(surface);
   1794                         if (err == ALREADY_EXISTS) {
   1795                             // reconnecting to same surface
   1796                             err = OK;
   1797                         } else {
   1798                             if (err == OK) {
   1799                                 if (mFlags & kFlagUsesSoftwareRenderer) {
   1800                                     if (mSoftRenderer != NULL
   1801                                             && (mFlags & kFlagPushBlankBuffersOnShutdown)) {
   1802                                         pushBlankBuffersToNativeWindow(mSurface.get());
   1803                                     }
   1804                                     mSoftRenderer = new SoftwareRenderer(surface);
   1805                                     // TODO: check if this was successful
   1806                                 } else {
   1807                                     err = mCodec->setSurface(surface);
   1808                                 }
   1809                             }
   1810                             if (err == OK) {
   1811                                 (void)disconnectFromSurface();
   1812                                 mSurface = surface;
   1813                             }
   1814                         }
   1815                     }
   1816                     break;
   1817                 }
   1818 
   1819                 default:
   1820                     err = INVALID_OPERATION;
   1821                     break;
   1822             }
   1823 
   1824             PostReplyWithError(replyID, err);
   1825             break;
   1826         }
   1827 
   1828         case kWhatCreateInputSurface:
   1829         case kWhatSetInputSurface:
   1830         {
   1831             sp<AReplyToken> replyID;
   1832             CHECK(msg->senderAwaitsResponse(&replyID));
   1833 
   1834             // Must be configured, but can't have been started yet.
   1835             if (mState != CONFIGURED) {
   1836                 PostReplyWithError(replyID, INVALID_OPERATION);
   1837                 break;
   1838             }
   1839 
   1840             mReplyID = replyID;
   1841             if (msg->what() == kWhatCreateInputSurface) {
   1842                 mCodec->initiateCreateInputSurface();
   1843             } else {
   1844                 sp<RefBase> obj;
   1845                 CHECK(msg->findObject("input-surface", &obj));
   1846 
   1847                 mCodec->initiateSetInputSurface(
   1848                         static_cast<PersistentSurface *>(obj.get()));
   1849             }
   1850             break;
   1851         }
   1852         case kWhatStart:
   1853         {
   1854             sp<AReplyToken> replyID;
   1855             CHECK(msg->senderAwaitsResponse(&replyID));
   1856 
   1857             if (mState == FLUSHED) {
   1858                 setState(STARTED);
   1859                 if (mHavePendingInputBuffers) {
   1860                     onInputBufferAvailable();
   1861                     mHavePendingInputBuffers = false;
   1862                 }
   1863                 mCodec->signalResume();
   1864                 PostReplyWithError(replyID, OK);
   1865                 break;
   1866             } else if (mState != CONFIGURED) {
   1867                 PostReplyWithError(replyID, INVALID_OPERATION);
   1868                 break;
   1869             }
   1870 
   1871             mReplyID = replyID;
   1872             setState(STARTING);
   1873 
   1874             mCodec->initiateStart();
   1875             break;
   1876         }
   1877 
   1878         case kWhatStop:
   1879         case kWhatRelease:
   1880         {
   1881             State targetState =
   1882                 (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED;
   1883 
   1884             sp<AReplyToken> replyID;
   1885             CHECK(msg->senderAwaitsResponse(&replyID));
   1886 
   1887             // already stopped/released
   1888             if (mState == UNINITIALIZED && mReleasedByResourceManager) {
   1889                 sp<AMessage> response = new AMessage;
   1890                 response->setInt32("err", OK);
   1891                 response->postReply(replyID);
   1892                 break;
   1893             }
   1894 
   1895             int32_t reclaimed = 0;
   1896             msg->findInt32("reclaimed", &reclaimed);
   1897             if (reclaimed) {
   1898                 mReleasedByResourceManager = true;
   1899 
   1900                 int32_t force = 0;
   1901                 msg->findInt32("force", &force);
   1902                 if (!force && hasPendingBuffer()) {
   1903                     ALOGW("Can't reclaim codec right now due to pending buffers.");
   1904 
   1905                     // return WOULD_BLOCK to ask resource manager to retry later.
   1906                     sp<AMessage> response = new AMessage;
   1907                     response->setInt32("err", WOULD_BLOCK);
   1908                     response->postReply(replyID);
   1909 
   1910                     // notify the async client
   1911                     if (mFlags & kFlagIsAsync) {
   1912                         onError(DEAD_OBJECT, ACTION_CODE_FATAL);
   1913                     }
   1914                     break;
   1915                 }
   1916             }
   1917 
   1918             if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1
   1919                     && mState != INITIALIZED
   1920                     && mState != CONFIGURED && !isExecuting()) {
   1921                 // 1) Permit release to shut down the component if allocated.
   1922                 //
   1923                 // 2) We may be in "UNINITIALIZED" state already and
   1924                 // also shutdown the encoder/decoder without the
   1925                 // client being aware of this if media server died while
   1926                 // we were being stopped. The client would assume that
   1927                 // after stop() returned, it would be safe to call release()
   1928                 // and it should be in this case, no harm to allow a release()
   1929                 // if we're already uninitialized.
   1930                 sp<AMessage> response = new AMessage;
   1931                 // TODO: we shouldn't throw an exception for stop/release. Change this to wait until
   1932                 // the previous stop/release completes and then reply with OK.
   1933                 status_t err = mState == targetState ? OK : INVALID_OPERATION;
   1934                 response->setInt32("err", err);
   1935                 if (err == OK && targetState == UNINITIALIZED) {
   1936                     mComponentName.clear();
   1937                 }
   1938                 response->postReply(replyID);
   1939                 break;
   1940             }
   1941 
   1942             if (mFlags & kFlagSawMediaServerDie) {
   1943                 // It's dead, Jim. Don't expect initiateShutdown to yield
   1944                 // any useful results now...
   1945                 setState(UNINITIALIZED);
   1946                 if (targetState == UNINITIALIZED) {
   1947                     mComponentName.clear();
   1948                 }
   1949                 (new AMessage)->postReply(replyID);
   1950                 break;
   1951             }
   1952 
   1953             mReplyID = replyID;
   1954             setState(msg->what() == kWhatStop ? STOPPING : RELEASING);
   1955 
   1956             mCodec->initiateShutdown(
   1957                     msg->what() == kWhatStop /* keepComponentAllocated */);
   1958 
   1959             returnBuffersToCodec(reclaimed);
   1960 
   1961             if (mSoftRenderer != NULL && (mFlags & kFlagPushBlankBuffersOnShutdown)) {
   1962                 pushBlankBuffersToNativeWindow(mSurface.get());
   1963             }
   1964             break;
   1965         }
   1966 
   1967         case kWhatDequeueInputBuffer:
   1968         {
   1969             sp<AReplyToken> replyID;
   1970             CHECK(msg->senderAwaitsResponse(&replyID));
   1971 
   1972             if (mFlags & kFlagIsAsync) {
   1973                 ALOGE("dequeueOutputBuffer can't be used in async mode");
   1974                 PostReplyWithError(replyID, INVALID_OPERATION);
   1975                 break;
   1976             }
   1977 
   1978             if (mHaveInputSurface) {
   1979                 ALOGE("dequeueInputBuffer can't be used with input surface");
   1980                 PostReplyWithError(replyID, INVALID_OPERATION);
   1981                 break;
   1982             }
   1983 
   1984             if (handleDequeueInputBuffer(replyID, true /* new request */)) {
   1985                 break;
   1986             }
   1987 
   1988             int64_t timeoutUs;
   1989             CHECK(msg->findInt64("timeoutUs", &timeoutUs));
   1990 
   1991             if (timeoutUs == 0ll) {
   1992                 PostReplyWithError(replyID, -EAGAIN);
   1993                 break;
   1994             }
   1995 
   1996             mFlags |= kFlagDequeueInputPending;
   1997             mDequeueInputReplyID = replyID;
   1998 
   1999             if (timeoutUs > 0ll) {
   2000                 sp<AMessage> timeoutMsg =
   2001                     new AMessage(kWhatDequeueInputTimedOut, this);
   2002                 timeoutMsg->setInt32(
   2003                         "generation", ++mDequeueInputTimeoutGeneration);
   2004                 timeoutMsg->post(timeoutUs);
   2005             }
   2006             break;
   2007         }
   2008 
   2009         case kWhatDequeueInputTimedOut:
   2010         {
   2011             int32_t generation;
   2012             CHECK(msg->findInt32("generation", &generation));
   2013 
   2014             if (generation != mDequeueInputTimeoutGeneration) {
   2015                 // Obsolete
   2016                 break;
   2017             }
   2018 
   2019             CHECK(mFlags & kFlagDequeueInputPending);
   2020 
   2021             PostReplyWithError(mDequeueInputReplyID, -EAGAIN);
   2022 
   2023             mFlags &= ~kFlagDequeueInputPending;
   2024             mDequeueInputReplyID = 0;
   2025             break;
   2026         }
   2027 
   2028         case kWhatQueueInputBuffer:
   2029         {
   2030             sp<AReplyToken> replyID;
   2031             CHECK(msg->senderAwaitsResponse(&replyID));
   2032 
   2033             if (!isExecuting()) {
   2034                 PostReplyWithError(replyID, INVALID_OPERATION);
   2035                 break;
   2036             } else if (mFlags & kFlagStickyError) {
   2037                 PostReplyWithError(replyID, getStickyError());
   2038                 break;
   2039             }
   2040 
   2041             status_t err = onQueueInputBuffer(msg);
   2042 
   2043             PostReplyWithError(replyID, err);
   2044             break;
   2045         }
   2046 
   2047         case kWhatDequeueOutputBuffer:
   2048         {
   2049             sp<AReplyToken> replyID;
   2050             CHECK(msg->senderAwaitsResponse(&replyID));
   2051 
   2052             if (mFlags & kFlagIsAsync) {
   2053                 ALOGE("dequeueOutputBuffer can't be used in async mode");
   2054                 PostReplyWithError(replyID, INVALID_OPERATION);
   2055                 break;
   2056             }
   2057 
   2058             if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
   2059                 break;
   2060             }
   2061 
   2062             int64_t timeoutUs;
   2063             CHECK(msg->findInt64("timeoutUs", &timeoutUs));
   2064 
   2065             if (timeoutUs == 0ll) {
   2066                 PostReplyWithError(replyID, -EAGAIN);
   2067                 break;
   2068             }
   2069 
   2070             mFlags |= kFlagDequeueOutputPending;
   2071             mDequeueOutputReplyID = replyID;
   2072 
   2073             if (timeoutUs > 0ll) {
   2074                 sp<AMessage> timeoutMsg =
   2075                     new AMessage(kWhatDequeueOutputTimedOut, this);
   2076                 timeoutMsg->setInt32(
   2077                         "generation", ++mDequeueOutputTimeoutGeneration);
   2078                 timeoutMsg->post(timeoutUs);
   2079             }
   2080             break;
   2081         }
   2082 
   2083         case kWhatDequeueOutputTimedOut:
   2084         {
   2085             int32_t generation;
   2086             CHECK(msg->findInt32("generation", &generation));
   2087 
   2088             if (generation != mDequeueOutputTimeoutGeneration) {
   2089                 // Obsolete
   2090                 break;
   2091             }
   2092 
   2093             CHECK(mFlags & kFlagDequeueOutputPending);
   2094 
   2095             PostReplyWithError(mDequeueOutputReplyID, -EAGAIN);
   2096 
   2097             mFlags &= ~kFlagDequeueOutputPending;
   2098             mDequeueOutputReplyID = 0;
   2099             break;
   2100         }
   2101 
   2102         case kWhatReleaseOutputBuffer:
   2103         {
   2104             sp<AReplyToken> replyID;
   2105             CHECK(msg->senderAwaitsResponse(&replyID));
   2106 
   2107             if (!isExecuting()) {
   2108                 PostReplyWithError(replyID, INVALID_OPERATION);
   2109                 break;
   2110             } else if (mFlags & kFlagStickyError) {
   2111                 PostReplyWithError(replyID, getStickyError());
   2112                 break;
   2113             }
   2114 
   2115             status_t err = onReleaseOutputBuffer(msg);
   2116 
   2117             PostReplyWithError(replyID, err);
   2118             break;
   2119         }
   2120 
   2121         case kWhatSignalEndOfInputStream:
   2122         {
   2123             sp<AReplyToken> replyID;
   2124             CHECK(msg->senderAwaitsResponse(&replyID));
   2125 
   2126             if (!isExecuting()) {
   2127                 PostReplyWithError(replyID, INVALID_OPERATION);
   2128                 break;
   2129             } else if (mFlags & kFlagStickyError) {
   2130                 PostReplyWithError(replyID, getStickyError());
   2131                 break;
   2132             }
   2133 
   2134             mReplyID = replyID;
   2135             mCodec->signalEndOfInputStream();
   2136             break;
   2137         }
   2138 
   2139         case kWhatGetBuffers:
   2140         {
   2141             sp<AReplyToken> replyID;
   2142             CHECK(msg->senderAwaitsResponse(&replyID));
   2143             // Unfortunately widevine legacy source requires knowing all of the
   2144             // codec input buffers, so we have to provide them even in async mode.
   2145             int32_t widevine = 0;
   2146             msg->findInt32("widevine", &widevine);
   2147 
   2148             if (!isExecuting() || ((mFlags & kFlagIsAsync) && !widevine)) {
   2149                 PostReplyWithError(replyID, INVALID_OPERATION);
   2150                 break;
   2151             } else if (mFlags & kFlagStickyError) {
   2152                 PostReplyWithError(replyID, getStickyError());
   2153                 break;
   2154             }
   2155 
   2156             int32_t portIndex;
   2157             CHECK(msg->findInt32("portIndex", &portIndex));
   2158 
   2159             Vector<sp<ABuffer> > *dstBuffers;
   2160             CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
   2161 
   2162             dstBuffers->clear();
   2163             const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
   2164 
   2165             for (size_t i = 0; i < srcBuffers.size(); ++i) {
   2166                 const BufferInfo &info = srcBuffers.itemAt(i);
   2167 
   2168                 dstBuffers->push_back(
   2169                         (portIndex == kPortIndexInput && mCrypto != NULL)
   2170                                 ? info.mEncryptedData : info.mData);
   2171             }
   2172 
   2173             (new AMessage)->postReply(replyID);
   2174             break;
   2175         }
   2176 
   2177         case kWhatFlush:
   2178         {
   2179             sp<AReplyToken> replyID;
   2180             CHECK(msg->senderAwaitsResponse(&replyID));
   2181 
   2182             if (!isExecuting()) {
   2183                 PostReplyWithError(replyID, INVALID_OPERATION);
   2184                 break;
   2185             } else if (mFlags & kFlagStickyError) {
   2186                 PostReplyWithError(replyID, getStickyError());
   2187                 break;
   2188             }
   2189 
   2190             mReplyID = replyID;
   2191             // TODO: skip flushing if already FLUSHED
   2192             setState(FLUSHING);
   2193 
   2194             mCodec->signalFlush();
   2195             returnBuffersToCodec();
   2196             break;
   2197         }
   2198 
   2199         case kWhatGetInputFormat:
   2200         case kWhatGetOutputFormat:
   2201         {
   2202             sp<AMessage> format =
   2203                 (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat);
   2204 
   2205             sp<AReplyToken> replyID;
   2206             CHECK(msg->senderAwaitsResponse(&replyID));
   2207 
   2208             if ((mState != CONFIGURED && mState != STARTING &&
   2209                  mState != STARTED && mState != FLUSHING &&
   2210                  mState != FLUSHED)
   2211                     || format == NULL) {
   2212                 PostReplyWithError(replyID, INVALID_OPERATION);
   2213                 break;
   2214             } else if (mFlags & kFlagStickyError) {
   2215                 PostReplyWithError(replyID, getStickyError());
   2216                 break;
   2217             }
   2218 
   2219             sp<AMessage> response = new AMessage;
   2220             response->setMessage("format", format);
   2221             response->postReply(replyID);
   2222             break;
   2223         }
   2224 
   2225         case kWhatRequestIDRFrame:
   2226         {
   2227             mCodec->signalRequestIDRFrame();
   2228             break;
   2229         }
   2230 
   2231         case kWhatRequestActivityNotification:
   2232         {
   2233             CHECK(mActivityNotify == NULL);
   2234             CHECK(msg->findMessage("notify", &mActivityNotify));
   2235 
   2236             postActivityNotificationIfPossible();
   2237             break;
   2238         }
   2239 
   2240         case kWhatGetName:
   2241         {
   2242             sp<AReplyToken> replyID;
   2243             CHECK(msg->senderAwaitsResponse(&replyID));
   2244 
   2245             if (mComponentName.empty()) {
   2246                 PostReplyWithError(replyID, INVALID_OPERATION);
   2247                 break;
   2248             }
   2249 
   2250             sp<AMessage> response = new AMessage;
   2251             response->setString("name", mComponentName.c_str());
   2252             response->postReply(replyID);
   2253             break;
   2254         }
   2255 
   2256         case kWhatSetParameters:
   2257         {
   2258             sp<AReplyToken> replyID;
   2259             CHECK(msg->senderAwaitsResponse(&replyID));
   2260 
   2261             sp<AMessage> params;
   2262             CHECK(msg->findMessage("params", &params));
   2263 
   2264             status_t err = onSetParameters(params);
   2265 
   2266             PostReplyWithError(replyID, err);
   2267             break;
   2268         }
   2269 
   2270         default:
   2271             TRESPASS();
   2272     }
   2273 }
   2274 
   2275 void MediaCodec::extractCSD(const sp<AMessage> &format) {
   2276     mCSD.clear();
   2277 
   2278     size_t i = 0;
   2279     for (;;) {
   2280         sp<ABuffer> csd;
   2281         if (!format->findBuffer(AStringPrintf("csd-%u", i).c_str(), &csd)) {
   2282             break;
   2283         }
   2284         if (csd->size() == 0) {
   2285             ALOGW("csd-%zu size is 0", i);
   2286         }
   2287 
   2288         mCSD.push_back(csd);
   2289         ++i;
   2290     }
   2291 
   2292     ALOGV("Found %zu pieces of codec specific data.", mCSD.size());
   2293 }
   2294 
   2295 status_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
   2296     CHECK(!mCSD.empty());
   2297 
   2298     const BufferInfo *info =
   2299         &mPortBuffers[kPortIndexInput].itemAt(bufferIndex);
   2300 
   2301     sp<ABuffer> csd = *mCSD.begin();
   2302     mCSD.erase(mCSD.begin());
   2303 
   2304     const sp<ABuffer> &codecInputData =
   2305         (mCrypto != NULL) ? info->mEncryptedData : info->mData;
   2306 
   2307     if (csd->size() > codecInputData->capacity()) {
   2308         return -EINVAL;
   2309     }
   2310 
   2311     memcpy(codecInputData->data(), csd->data(), csd->size());
   2312 
   2313     AString errorDetailMsg;
   2314 
   2315     sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
   2316     msg->setSize("index", bufferIndex);
   2317     msg->setSize("offset", 0);
   2318     msg->setSize("size", csd->size());
   2319     msg->setInt64("timeUs", 0ll);
   2320     msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
   2321     msg->setPointer("errorDetailMsg", &errorDetailMsg);
   2322 
   2323     return onQueueInputBuffer(msg);
   2324 }
   2325 
   2326 void MediaCodec::setState(State newState) {
   2327     if (newState == INITIALIZED || newState == UNINITIALIZED) {
   2328         delete mSoftRenderer;
   2329         mSoftRenderer = NULL;
   2330 
   2331         mCrypto.clear();
   2332         handleSetSurface(NULL);
   2333 
   2334         mInputFormat.clear();
   2335         mOutputFormat.clear();
   2336         mFlags &= ~kFlagOutputFormatChanged;
   2337         mFlags &= ~kFlagOutputBuffersChanged;
   2338         mFlags &= ~kFlagStickyError;
   2339         mFlags &= ~kFlagIsEncoder;
   2340         mFlags &= ~kFlagGatherCodecSpecificData;
   2341         mFlags &= ~kFlagIsAsync;
   2342         mStickyError = OK;
   2343 
   2344         mActivityNotify.clear();
   2345         mCallback.clear();
   2346     }
   2347 
   2348     if (newState == UNINITIALIZED) {
   2349         // return any straggling buffers, e.g. if we got here on an error
   2350         returnBuffersToCodec();
   2351 
   2352         // The component is gone, mediaserver's probably back up already
   2353         // but should definitely be back up should we try to instantiate
   2354         // another component.. and the cycle continues.
   2355         mFlags &= ~kFlagSawMediaServerDie;
   2356     }
   2357 
   2358     mState = newState;
   2359 
   2360     cancelPendingDequeueOperations();
   2361 
   2362     updateBatteryStat();
   2363 }
   2364 
   2365 void MediaCodec::returnBuffersToCodec(bool isReclaim) {
   2366     returnBuffersToCodecOnPort(kPortIndexInput, isReclaim);
   2367     returnBuffersToCodecOnPort(kPortIndexOutput, isReclaim);
   2368 }
   2369 
   2370 void MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex, bool isReclaim) {
   2371     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
   2372     Mutex::Autolock al(mBufferLock);
   2373 
   2374     Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
   2375 
   2376     for (size_t i = 0; i < buffers->size(); ++i) {
   2377         BufferInfo *info = &buffers->editItemAt(i);
   2378 
   2379         if (info->mNotify != NULL) {
   2380             sp<AMessage> msg = info->mNotify;
   2381             info->mNotify = NULL;
   2382             if (isReclaim && info->mOwnedByClient) {
   2383                 ALOGD("port %d buffer %zu still owned by client when codec is reclaimed",
   2384                         portIndex, i);
   2385             } else {
   2386                 info->mMemRef = NULL;
   2387                 info->mOwnedByClient = false;
   2388             }
   2389 
   2390             if (portIndex == kPortIndexInput) {
   2391                 /* no error, just returning buffers */
   2392                 msg->setInt32("err", OK);
   2393             }
   2394             msg->post();
   2395         }
   2396     }
   2397 
   2398     mAvailPortBuffers[portIndex].clear();
   2399 }
   2400 
   2401 size_t MediaCodec::updateBuffers(
   2402         int32_t portIndex, const sp<AMessage> &msg) {
   2403     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
   2404 
   2405     uint32_t bufferID;
   2406     CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
   2407 
   2408     Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
   2409 
   2410     for (size_t i = 0; i < buffers->size(); ++i) {
   2411         BufferInfo *info = &buffers->editItemAt(i);
   2412 
   2413         if (info->mBufferID == bufferID) {
   2414             CHECK(info->mNotify == NULL);
   2415             CHECK(msg->findMessage("reply", &info->mNotify));
   2416 
   2417             info->mFormat =
   2418                 (portIndex == kPortIndexInput) ? mInputFormat : mOutputFormat;
   2419             mAvailPortBuffers[portIndex].push_back(i);
   2420 
   2421             return i;
   2422         }
   2423     }
   2424 
   2425     TRESPASS();
   2426 
   2427     return 0;
   2428 }
   2429 
   2430 status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
   2431     size_t index;
   2432     size_t offset;
   2433     size_t size;
   2434     int64_t timeUs;
   2435     uint32_t flags;
   2436     CHECK(msg->findSize("index", &index));
   2437     CHECK(msg->findSize("offset", &offset));
   2438     CHECK(msg->findInt64("timeUs", &timeUs));
   2439     CHECK(msg->findInt32("flags", (int32_t *)&flags));
   2440 
   2441     const CryptoPlugin::SubSample *subSamples;
   2442     size_t numSubSamples;
   2443     const uint8_t *key;
   2444     const uint8_t *iv;
   2445     CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
   2446 
   2447     // We allow the simpler queueInputBuffer API to be used even in
   2448     // secure mode, by fabricating a single unencrypted subSample.
   2449     CryptoPlugin::SubSample ss;
   2450     CryptoPlugin::Pattern pattern;
   2451 
   2452     if (msg->findSize("size", &size)) {
   2453         if (mCrypto != NULL) {
   2454             ss.mNumBytesOfClearData = size;
   2455             ss.mNumBytesOfEncryptedData = 0;
   2456 
   2457             subSamples = &ss;
   2458             numSubSamples = 1;
   2459             key = NULL;
   2460             iv = NULL;
   2461             pattern.mEncryptBlocks = 0;
   2462             pattern.mSkipBlocks = 0;
   2463         }
   2464     } else {
   2465         if (mCrypto == NULL) {
   2466             return -EINVAL;
   2467         }
   2468 
   2469         CHECK(msg->findPointer("subSamples", (void **)&subSamples));
   2470         CHECK(msg->findSize("numSubSamples", &numSubSamples));
   2471         CHECK(msg->findPointer("key", (void **)&key));
   2472         CHECK(msg->findPointer("iv", (void **)&iv));
   2473         CHECK(msg->findInt32("encryptBlocks", (int32_t *)&pattern.mEncryptBlocks));
   2474         CHECK(msg->findInt32("skipBlocks", (int32_t *)&pattern.mSkipBlocks));
   2475 
   2476         int32_t tmp;
   2477         CHECK(msg->findInt32("mode", &tmp));
   2478 
   2479         mode = (CryptoPlugin::Mode)tmp;
   2480 
   2481         size = 0;
   2482         for (size_t i = 0; i < numSubSamples; ++i) {
   2483             size += subSamples[i].mNumBytesOfClearData;
   2484             size += subSamples[i].mNumBytesOfEncryptedData;
   2485         }
   2486     }
   2487 
   2488     if (index >= mPortBuffers[kPortIndexInput].size()) {
   2489         return -ERANGE;
   2490     }
   2491 
   2492     BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
   2493 
   2494     if (info->mNotify == NULL || !info->mOwnedByClient) {
   2495         return -EACCES;
   2496     }
   2497 
   2498     if (offset + size > info->mData->capacity()) {
   2499         return -EINVAL;
   2500     }
   2501 
   2502     sp<AMessage> reply = info->mNotify;
   2503     info->mData->setRange(offset, size);
   2504     info->mData->meta()->setInt64("timeUs", timeUs);
   2505 
   2506     if (flags & BUFFER_FLAG_EOS) {
   2507         info->mData->meta()->setInt32("eos", true);
   2508     }
   2509 
   2510     if (flags & BUFFER_FLAG_CODECCONFIG) {
   2511         info->mData->meta()->setInt32("csd", true);
   2512     }
   2513 
   2514     if (mCrypto != NULL) {
   2515         if (size > info->mEncryptedData->capacity()) {
   2516             return -ERANGE;
   2517         }
   2518 
   2519         AString *errorDetailMsg;
   2520         CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
   2521 
   2522         void *dst_pointer = info->mData->base();
   2523         ICrypto::DestinationType dst_type = ICrypto::kDestinationTypeOpaqueHandle;
   2524 
   2525         if (info->mNativeHandle != NULL) {
   2526             dst_pointer = (void *)info->mNativeHandle->handle();
   2527             dst_type = ICrypto::kDestinationTypeNativeHandle;
   2528         } else if ((mFlags & kFlagIsSecure) == 0) {
   2529             dst_type = ICrypto::kDestinationTypeVmPointer;
   2530         }
   2531 
   2532         ssize_t result = mCrypto->decrypt(
   2533                 dst_type,
   2534                 key,
   2535                 iv,
   2536                 mode,
   2537                 pattern,
   2538                 info->mSharedEncryptedBuffer,
   2539                 offset,
   2540                 subSamples,
   2541                 numSubSamples,
   2542                 dst_pointer,
   2543                 errorDetailMsg);
   2544 
   2545         if (result < 0) {
   2546             return result;
   2547         }
   2548 
   2549         info->mData->setRange(0, result);
   2550     }
   2551 
   2552     // synchronization boundary for getBufferAndFormat
   2553     {
   2554         Mutex::Autolock al(mBufferLock);
   2555         info->mOwnedByClient = false;
   2556     }
   2557     reply->setBuffer("buffer", info->mData);
   2558     reply->post();
   2559 
   2560     info->mNotify = NULL;
   2561 
   2562     return OK;
   2563 }
   2564 
   2565 //static
   2566 size_t MediaCodec::CreateFramesRenderedMessage(
   2567         std::list<FrameRenderTracker::Info> done, sp<AMessage> &msg) {
   2568     size_t index = 0;
   2569 
   2570     for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin();
   2571             it != done.cend(); ++it) {
   2572         if (it->getRenderTimeNs() < 0) {
   2573             continue; // dropped frame from tracking
   2574         }
   2575         msg->setInt64(AStringPrintf("%zu-media-time-us", index).c_str(), it->getMediaTimeUs());
   2576         msg->setInt64(AStringPrintf("%zu-system-nano", index).c_str(), it->getRenderTimeNs());
   2577         ++index;
   2578     }
   2579     return index;
   2580 }
   2581 
   2582 status_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
   2583     size_t index;
   2584     CHECK(msg->findSize("index", &index));
   2585 
   2586     int32_t render;
   2587     if (!msg->findInt32("render", &render)) {
   2588         render = 0;
   2589     }
   2590 
   2591     if (!isExecuting()) {
   2592         return -EINVAL;
   2593     }
   2594 
   2595     if (index >= mPortBuffers[kPortIndexOutput].size()) {
   2596         return -ERANGE;
   2597     }
   2598 
   2599     BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
   2600 
   2601     if (info->mNotify == NULL || !info->mOwnedByClient) {
   2602         return -EACCES;
   2603     }
   2604 
   2605     // synchronization boundary for getBufferAndFormat
   2606     {
   2607         Mutex::Autolock al(mBufferLock);
   2608         info->mOwnedByClient = false;
   2609     }
   2610 
   2611     if (render && info->mData != NULL && info->mData->size() != 0) {
   2612         info->mNotify->setInt32("render", true);
   2613 
   2614         int64_t mediaTimeUs = -1;
   2615         info->mData->meta()->findInt64("timeUs", &mediaTimeUs);
   2616 
   2617         int64_t renderTimeNs = 0;
   2618         if (!msg->findInt64("timestampNs", &renderTimeNs)) {
   2619             // use media timestamp if client did not request a specific render timestamp
   2620             ALOGV("using buffer PTS of %lld", (long long)mediaTimeUs);
   2621             renderTimeNs = mediaTimeUs * 1000;
   2622         }
   2623         info->mNotify->setInt64("timestampNs", renderTimeNs);
   2624 
   2625         if (mSoftRenderer != NULL) {
   2626             std::list<FrameRenderTracker::Info> doneFrames = mSoftRenderer->render(
   2627                     info->mData->data(), info->mData->size(),
   2628                     mediaTimeUs, renderTimeNs, NULL, info->mFormat);
   2629 
   2630             // if we are running, notify rendered frames
   2631             if (!doneFrames.empty() && mState == STARTED && mOnFrameRenderedNotification != NULL) {
   2632                 sp<AMessage> notify = mOnFrameRenderedNotification->dup();
   2633                 sp<AMessage> data = new AMessage;
   2634                 if (CreateFramesRenderedMessage(doneFrames, data)) {
   2635                     notify->setMessage("data", data);
   2636                     notify->post();
   2637                 }
   2638             }
   2639         }
   2640     }
   2641 
   2642     info->mNotify->post();
   2643     info->mNotify = NULL;
   2644 
   2645     return OK;
   2646 }
   2647 
   2648 ssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
   2649     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
   2650 
   2651     List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
   2652 
   2653     if (availBuffers->empty()) {
   2654         return -EAGAIN;
   2655     }
   2656 
   2657     size_t index = *availBuffers->begin();
   2658     availBuffers->erase(availBuffers->begin());
   2659 
   2660     BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
   2661     CHECK(!info->mOwnedByClient);
   2662     {
   2663         Mutex::Autolock al(mBufferLock);
   2664         info->mOwnedByClient = true;
   2665 
   2666         // set image-data
   2667         if (info->mFormat != NULL) {
   2668             sp<ABuffer> imageData;
   2669             if (info->mFormat->findBuffer("image-data", &imageData)) {
   2670                 info->mData->meta()->setBuffer("image-data", imageData);
   2671             }
   2672             int32_t left, top, right, bottom;
   2673             if (info->mFormat->findRect("crop", &left, &top, &right, &bottom)) {
   2674                 info->mData->meta()->setRect("crop-rect", left, top, right, bottom);
   2675             }
   2676         }
   2677     }
   2678 
   2679     return index;
   2680 }
   2681 
   2682 status_t MediaCodec::connectToSurface(const sp<Surface> &surface) {
   2683     status_t err = OK;
   2684     if (surface != NULL) {
   2685         uint64_t oldId, newId;
   2686         if (mSurface != NULL
   2687                 && surface->getUniqueId(&newId) == NO_ERROR
   2688                 && mSurface->getUniqueId(&oldId) == NO_ERROR
   2689                 && newId == oldId) {
   2690             ALOGI("[%s] connecting to the same surface. Nothing to do.", mComponentName.c_str());
   2691             return ALREADY_EXISTS;
   2692         }
   2693 
   2694         err = native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA);
   2695         if (err == OK) {
   2696             // Require a fresh set of buffers after each connect by using a unique generation
   2697             // number. Rely on the fact that max supported process id by Linux is 2^22.
   2698             // PID is never 0 so we don't have to worry that we use the default generation of 0.
   2699             // TODO: come up with a unique scheme if other producers also set the generation number.
   2700             static uint32_t mSurfaceGeneration = 0;
   2701             uint32_t generation = (getpid() << 10) | (++mSurfaceGeneration & ((1 << 10) - 1));
   2702             surface->setGenerationNumber(generation);
   2703             ALOGI("[%s] setting surface generation to %u", mComponentName.c_str(), generation);
   2704 
   2705             // HACK: clear any free buffers. Remove when connect will automatically do this.
   2706             // This is needed as the consumer may be holding onto stale frames that it can reattach
   2707             // to this surface after disconnect/connect, and those free frames would inherit the new
   2708             // generation number. Disconnecting after setting a unique generation prevents this.
   2709             native_window_api_disconnect(surface.get(), NATIVE_WINDOW_API_MEDIA);
   2710             err = native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA);
   2711         }
   2712 
   2713         if (err != OK) {
   2714             ALOGE("native_window_api_connect returned an error: %s (%d)", strerror(-err), err);
   2715         }
   2716     }
   2717     // do not return ALREADY_EXISTS unless surfaces are the same
   2718     return err == ALREADY_EXISTS ? BAD_VALUE : err;
   2719 }
   2720 
   2721 status_t MediaCodec::disconnectFromSurface() {
   2722     status_t err = OK;
   2723     if (mSurface != NULL) {
   2724         // Resetting generation is not technically needed, but there is no need to keep it either
   2725         mSurface->setGenerationNumber(0);
   2726         err = native_window_api_disconnect(mSurface.get(), NATIVE_WINDOW_API_MEDIA);
   2727         if (err != OK) {
   2728             ALOGW("native_window_api_disconnect returned an error: %s (%d)", strerror(-err), err);
   2729         }
   2730         // assume disconnected even on error
   2731         mSurface.clear();
   2732     }
   2733     return err;
   2734 }
   2735 
   2736 status_t MediaCodec::handleSetSurface(const sp<Surface> &surface) {
   2737     status_t err = OK;
   2738     if (mSurface != NULL) {
   2739         (void)disconnectFromSurface();
   2740     }
   2741     if (surface != NULL) {
   2742         err = connectToSurface(surface);
   2743         if (err == OK) {
   2744             mSurface = surface;
   2745         }
   2746     }
   2747     return err;
   2748 }
   2749 
   2750 void MediaCodec::onInputBufferAvailable() {
   2751     int32_t index;
   2752     while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) {
   2753         sp<AMessage> msg = mCallback->dup();
   2754         msg->setInt32("callbackID", CB_INPUT_AVAILABLE);
   2755         msg->setInt32("index", index);
   2756         msg->post();
   2757     }
   2758 }
   2759 
   2760 void MediaCodec::onOutputBufferAvailable() {
   2761     int32_t index;
   2762     while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) {
   2763         const sp<ABuffer> &buffer =
   2764             mPortBuffers[kPortIndexOutput].itemAt(index).mData;
   2765         sp<AMessage> msg = mCallback->dup();
   2766         msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE);
   2767         msg->setInt32("index", index);
   2768         msg->setSize("offset", buffer->offset());
   2769         msg->setSize("size", buffer->size());
   2770 
   2771         int64_t timeUs;
   2772         CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
   2773 
   2774         msg->setInt64("timeUs", timeUs);
   2775 
   2776         int32_t omxFlags;
   2777         CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
   2778 
   2779         uint32_t flags = 0;
   2780         if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
   2781             flags |= BUFFER_FLAG_SYNCFRAME;
   2782         }
   2783         if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   2784             flags |= BUFFER_FLAG_CODECCONFIG;
   2785         }
   2786         if (omxFlags & OMX_BUFFERFLAG_EOS) {
   2787             flags |= BUFFER_FLAG_EOS;
   2788         }
   2789 
   2790         msg->setInt32("flags", flags);
   2791 
   2792         msg->post();
   2793     }
   2794 }
   2795 
   2796 void MediaCodec::onError(status_t err, int32_t actionCode, const char *detail) {
   2797     if (mCallback != NULL) {
   2798         sp<AMessage> msg = mCallback->dup();
   2799         msg->setInt32("callbackID", CB_ERROR);
   2800         msg->setInt32("err", err);
   2801         msg->setInt32("actionCode", actionCode);
   2802 
   2803         if (detail != NULL) {
   2804             msg->setString("detail", detail);
   2805         }
   2806 
   2807         msg->post();
   2808     }
   2809 }
   2810 
   2811 void MediaCodec::onOutputFormatChanged() {
   2812     if (mCallback != NULL) {
   2813         sp<AMessage> msg = mCallback->dup();
   2814         msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED);
   2815         msg->setMessage("format", mOutputFormat);
   2816         msg->post();
   2817     }
   2818 }
   2819 
   2820 
   2821 void MediaCodec::postActivityNotificationIfPossible() {
   2822     if (mActivityNotify == NULL) {
   2823         return;
   2824     }
   2825 
   2826     bool isErrorOrOutputChanged =
   2827             (mFlags & (kFlagStickyError
   2828                     | kFlagOutputBuffersChanged
   2829                     | kFlagOutputFormatChanged));
   2830 
   2831     if (isErrorOrOutputChanged
   2832             || !mAvailPortBuffers[kPortIndexInput].empty()
   2833             || !mAvailPortBuffers[kPortIndexOutput].empty()) {
   2834         mActivityNotify->setInt32("input-buffers",
   2835                 mAvailPortBuffers[kPortIndexInput].size());
   2836 
   2837         if (isErrorOrOutputChanged) {
   2838             // we want consumer to dequeue as many times as it can
   2839             mActivityNotify->setInt32("output-buffers", INT32_MAX);
   2840         } else {
   2841             mActivityNotify->setInt32("output-buffers",
   2842                     mAvailPortBuffers[kPortIndexOutput].size());
   2843         }
   2844         mActivityNotify->post();
   2845         mActivityNotify.clear();
   2846     }
   2847 }
   2848 
   2849 status_t MediaCodec::setParameters(const sp<AMessage> &params) {
   2850     sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
   2851     msg->setMessage("params", params);
   2852 
   2853     sp<AMessage> response;
   2854     return PostAndAwaitResponse(msg, &response);
   2855 }
   2856 
   2857 status_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
   2858     mCodec->signalSetParameters(params);
   2859 
   2860     return OK;
   2861 }
   2862 
   2863 status_t MediaCodec::amendOutputFormatWithCodecSpecificData(
   2864         const sp<ABuffer> &buffer) {
   2865     AString mime;
   2866     CHECK(mOutputFormat->findString("mime", &mime));
   2867 
   2868     if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
   2869         // Codec specific data should be SPS and PPS in a single buffer,
   2870         // each prefixed by a startcode (0x00 0x00 0x00 0x01).
   2871         // We separate the two and put them into the output format
   2872         // under the keys "csd-0" and "csd-1".
   2873 
   2874         unsigned csdIndex = 0;
   2875 
   2876         const uint8_t *data = buffer->data();
   2877         size_t size = buffer->size();
   2878 
   2879         const uint8_t *nalStart;
   2880         size_t nalSize;
   2881         while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
   2882             sp<ABuffer> csd = new ABuffer(nalSize + 4);
   2883             memcpy(csd->data(), "\x00\x00\x00\x01", 4);
   2884             memcpy(csd->data() + 4, nalStart, nalSize);
   2885 
   2886             mOutputFormat->setBuffer(
   2887                     AStringPrintf("csd-%u", csdIndex).c_str(), csd);
   2888 
   2889             ++csdIndex;
   2890         }
   2891 
   2892         if (csdIndex != 2) {
   2893             return ERROR_MALFORMED;
   2894         }
   2895     } else {
   2896         // For everything else we just stash the codec specific data into
   2897         // the output format as a single piece of csd under "csd-0".
   2898         mOutputFormat->setBuffer("csd-0", buffer);
   2899     }
   2900 
   2901     return OK;
   2902 }
   2903 
   2904 void MediaCodec::updateBatteryStat() {
   2905     if (!mIsVideo) {
   2906         return;
   2907     }
   2908 
   2909     if (mState == CONFIGURED && !mBatteryStatNotified) {
   2910         BatteryNotifier::getInstance().noteStartVideo();
   2911         mBatteryStatNotified = true;
   2912     } else if (mState == UNINITIALIZED && mBatteryStatNotified) {
   2913         BatteryNotifier::getInstance().noteStopVideo();
   2914         mBatteryStatNotified = false;
   2915     }
   2916 }
   2917 
   2918 }  // namespace android
   2919