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 <utils/Log.h>
     20 
     21 #include <media/stagefright/MediaCodec.h>
     22 
     23 #include "include/SoftwareRenderer.h"
     24 
     25 #include <gui/Surface.h>
     26 #include <media/ICrypto.h>
     27 #include <media/stagefright/foundation/ABuffer.h>
     28 #include <media/stagefright/foundation/ADebug.h>
     29 #include <media/stagefright/foundation/AMessage.h>
     30 #include <media/stagefright/foundation/AString.h>
     31 #include <media/stagefright/foundation/hexdump.h>
     32 #include <media/stagefright/ACodec.h>
     33 #include <media/stagefright/BufferProducerWrapper.h>
     34 #include <media/stagefright/MediaCodecList.h>
     35 #include <media/stagefright/MediaDefs.h>
     36 #include <media/stagefright/MediaErrors.h>
     37 #include <media/stagefright/MetaData.h>
     38 #include <media/stagefright/NativeWindowWrapper.h>
     39 
     40 #include "include/avc_utils.h"
     41 
     42 namespace android {
     43 
     44 // static
     45 sp<MediaCodec> MediaCodec::CreateByType(
     46         const sp<ALooper> &looper, const char *mime, bool encoder) {
     47     sp<MediaCodec> codec = new MediaCodec(looper);
     48     if (codec->init(mime, true /* nameIsType */, encoder) != OK) {
     49         return NULL;
     50     }
     51 
     52     return codec;
     53 }
     54 
     55 // static
     56 sp<MediaCodec> MediaCodec::CreateByComponentName(
     57         const sp<ALooper> &looper, const char *name) {
     58     sp<MediaCodec> codec = new MediaCodec(looper);
     59     if (codec->init(name, false /* nameIsType */, false /* encoder */) != OK) {
     60         return NULL;
     61     }
     62 
     63     return codec;
     64 }
     65 
     66 MediaCodec::MediaCodec(const sp<ALooper> &looper)
     67     : mState(UNINITIALIZED),
     68       mLooper(looper),
     69       mCodec(new ACodec),
     70       mReplyID(0),
     71       mFlags(0),
     72       mSoftRenderer(NULL),
     73       mDequeueInputTimeoutGeneration(0),
     74       mDequeueInputReplyID(0),
     75       mDequeueOutputTimeoutGeneration(0),
     76       mDequeueOutputReplyID(0),
     77       mHaveInputSurface(false) {
     78 }
     79 
     80 MediaCodec::~MediaCodec() {
     81     CHECK_EQ(mState, UNINITIALIZED);
     82 }
     83 
     84 // static
     85 status_t MediaCodec::PostAndAwaitResponse(
     86         const sp<AMessage> &msg, sp<AMessage> *response) {
     87     status_t err = msg->postAndAwaitResponse(response);
     88 
     89     if (err != OK) {
     90         return err;
     91     }
     92 
     93     if (!(*response)->findInt32("err", &err)) {
     94         err = OK;
     95     }
     96 
     97     return err;
     98 }
     99 
    100 status_t MediaCodec::init(const char *name, bool nameIsType, bool encoder) {
    101     // Current video decoders do not return from OMX_FillThisBuffer
    102     // quickly, violating the OpenMAX specs, until that is remedied
    103     // we need to invest in an extra looper to free the main event
    104     // queue.
    105     bool needDedicatedLooper = false;
    106     if (nameIsType && !strncasecmp(name, "video/", 6)) {
    107         needDedicatedLooper = true;
    108     } else {
    109         AString tmp = name;
    110         if (tmp.endsWith(".secure")) {
    111             tmp.erase(tmp.size() - 7, 7);
    112         }
    113         const MediaCodecList *mcl = MediaCodecList::getInstance();
    114         ssize_t codecIdx = mcl->findCodecByName(tmp.c_str());
    115         if (codecIdx >= 0) {
    116             Vector<AString> types;
    117             if (mcl->getSupportedTypes(codecIdx, &types) == OK) {
    118                 for (int i = 0; i < types.size(); i++) {
    119                     if (types[i].startsWith("video/")) {
    120                         needDedicatedLooper = true;
    121                         break;
    122                     }
    123                 }
    124             }
    125         }
    126     }
    127 
    128     if (needDedicatedLooper) {
    129         if (mCodecLooper == NULL) {
    130             mCodecLooper = new ALooper;
    131             mCodecLooper->setName("CodecLooper");
    132             mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
    133         }
    134 
    135         mCodecLooper->registerHandler(mCodec);
    136     } else {
    137         mLooper->registerHandler(mCodec);
    138     }
    139 
    140     mLooper->registerHandler(this);
    141 
    142     mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, id()));
    143 
    144     sp<AMessage> msg = new AMessage(kWhatInit, id());
    145     msg->setString("name", name);
    146     msg->setInt32("nameIsType", nameIsType);
    147 
    148     if (nameIsType) {
    149         msg->setInt32("encoder", encoder);
    150     }
    151 
    152     sp<AMessage> response;
    153     return PostAndAwaitResponse(msg, &response);
    154 }
    155 
    156 status_t MediaCodec::configure(
    157         const sp<AMessage> &format,
    158         const sp<Surface> &nativeWindow,
    159         const sp<ICrypto> &crypto,
    160         uint32_t flags) {
    161     sp<AMessage> msg = new AMessage(kWhatConfigure, id());
    162 
    163     msg->setMessage("format", format);
    164     msg->setInt32("flags", flags);
    165 
    166     if (nativeWindow != NULL) {
    167         msg->setObject(
    168                 "native-window",
    169                 new NativeWindowWrapper(nativeWindow));
    170     }
    171 
    172     if (crypto != NULL) {
    173         msg->setPointer("crypto", crypto.get());
    174     }
    175 
    176     sp<AMessage> response;
    177     return PostAndAwaitResponse(msg, &response);
    178 }
    179 
    180 status_t MediaCodec::createInputSurface(
    181         sp<IGraphicBufferProducer>* bufferProducer) {
    182     sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, id());
    183 
    184     sp<AMessage> response;
    185     status_t err = PostAndAwaitResponse(msg, &response);
    186     if (err == NO_ERROR) {
    187         // unwrap the sp<IGraphicBufferProducer>
    188         sp<RefBase> obj;
    189         bool found = response->findObject("input-surface", &obj);
    190         CHECK(found);
    191         sp<BufferProducerWrapper> wrapper(
    192                 static_cast<BufferProducerWrapper*>(obj.get()));
    193         *bufferProducer = wrapper->getBufferProducer();
    194     } else {
    195         ALOGW("createInputSurface failed, err=%d", err);
    196     }
    197     return err;
    198 }
    199 
    200 status_t MediaCodec::start() {
    201     sp<AMessage> msg = new AMessage(kWhatStart, id());
    202 
    203     sp<AMessage> response;
    204     return PostAndAwaitResponse(msg, &response);
    205 }
    206 
    207 status_t MediaCodec::stop() {
    208     sp<AMessage> msg = new AMessage(kWhatStop, id());
    209 
    210     sp<AMessage> response;
    211     return PostAndAwaitResponse(msg, &response);
    212 }
    213 
    214 status_t MediaCodec::release() {
    215     sp<AMessage> msg = new AMessage(kWhatRelease, id());
    216 
    217     sp<AMessage> response;
    218     return PostAndAwaitResponse(msg, &response);
    219 }
    220 
    221 status_t MediaCodec::queueInputBuffer(
    222         size_t index,
    223         size_t offset,
    224         size_t size,
    225         int64_t presentationTimeUs,
    226         uint32_t flags,
    227         AString *errorDetailMsg) {
    228     if (errorDetailMsg != NULL) {
    229         errorDetailMsg->clear();
    230     }
    231 
    232     sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
    233     msg->setSize("index", index);
    234     msg->setSize("offset", offset);
    235     msg->setSize("size", size);
    236     msg->setInt64("timeUs", presentationTimeUs);
    237     msg->setInt32("flags", flags);
    238     msg->setPointer("errorDetailMsg", errorDetailMsg);
    239 
    240     sp<AMessage> response;
    241     return PostAndAwaitResponse(msg, &response);
    242 }
    243 
    244 status_t MediaCodec::queueSecureInputBuffer(
    245         size_t index,
    246         size_t offset,
    247         const CryptoPlugin::SubSample *subSamples,
    248         size_t numSubSamples,
    249         const uint8_t key[16],
    250         const uint8_t iv[16],
    251         CryptoPlugin::Mode mode,
    252         int64_t presentationTimeUs,
    253         uint32_t flags,
    254         AString *errorDetailMsg) {
    255     if (errorDetailMsg != NULL) {
    256         errorDetailMsg->clear();
    257     }
    258 
    259     sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
    260     msg->setSize("index", index);
    261     msg->setSize("offset", offset);
    262     msg->setPointer("subSamples", (void *)subSamples);
    263     msg->setSize("numSubSamples", numSubSamples);
    264     msg->setPointer("key", (void *)key);
    265     msg->setPointer("iv", (void *)iv);
    266     msg->setInt32("mode", mode);
    267     msg->setInt64("timeUs", presentationTimeUs);
    268     msg->setInt32("flags", flags);
    269     msg->setPointer("errorDetailMsg", errorDetailMsg);
    270 
    271     sp<AMessage> response;
    272     status_t err = PostAndAwaitResponse(msg, &response);
    273 
    274     return err;
    275 }
    276 
    277 status_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
    278     sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, id());
    279     msg->setInt64("timeoutUs", timeoutUs);
    280 
    281     sp<AMessage> response;
    282     status_t err;
    283     if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
    284         return err;
    285     }
    286 
    287     CHECK(response->findSize("index", index));
    288 
    289     return OK;
    290 }
    291 
    292 status_t MediaCodec::dequeueOutputBuffer(
    293         size_t *index,
    294         size_t *offset,
    295         size_t *size,
    296         int64_t *presentationTimeUs,
    297         uint32_t *flags,
    298         int64_t timeoutUs) {
    299     sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, id());
    300     msg->setInt64("timeoutUs", timeoutUs);
    301 
    302     sp<AMessage> response;
    303     status_t err;
    304     if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
    305         return err;
    306     }
    307 
    308     CHECK(response->findSize("index", index));
    309     CHECK(response->findSize("offset", offset));
    310     CHECK(response->findSize("size", size));
    311     CHECK(response->findInt64("timeUs", presentationTimeUs));
    312     CHECK(response->findInt32("flags", (int32_t *)flags));
    313 
    314     return OK;
    315 }
    316 
    317 status_t MediaCodec::renderOutputBufferAndRelease(size_t index) {
    318     sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
    319     msg->setSize("index", index);
    320     msg->setInt32("render", true);
    321 
    322     sp<AMessage> response;
    323     return PostAndAwaitResponse(msg, &response);
    324 }
    325 
    326 status_t MediaCodec::releaseOutputBuffer(size_t index) {
    327     sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
    328     msg->setSize("index", index);
    329 
    330     sp<AMessage> response;
    331     return PostAndAwaitResponse(msg, &response);
    332 }
    333 
    334 status_t MediaCodec::signalEndOfInputStream() {
    335     sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, id());
    336 
    337     sp<AMessage> response;
    338     return PostAndAwaitResponse(msg, &response);
    339 }
    340 
    341 status_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
    342     sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, id());
    343 
    344     sp<AMessage> response;
    345     status_t err;
    346     if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
    347         return err;
    348     }
    349 
    350     CHECK(response->findMessage("format", format));
    351 
    352     return OK;
    353 }
    354 
    355 status_t MediaCodec::getName(AString *name) const {
    356     sp<AMessage> msg = new AMessage(kWhatGetName, id());
    357 
    358     sp<AMessage> response;
    359     status_t err;
    360     if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
    361         return err;
    362     }
    363 
    364     CHECK(response->findString("name", name));
    365 
    366     return OK;
    367 }
    368 
    369 status_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
    370     sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
    371     msg->setInt32("portIndex", kPortIndexInput);
    372     msg->setPointer("buffers", buffers);
    373 
    374     sp<AMessage> response;
    375     return PostAndAwaitResponse(msg, &response);
    376 }
    377 
    378 status_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const {
    379     sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
    380     msg->setInt32("portIndex", kPortIndexOutput);
    381     msg->setPointer("buffers", buffers);
    382 
    383     sp<AMessage> response;
    384     return PostAndAwaitResponse(msg, &response);
    385 }
    386 
    387 status_t MediaCodec::flush() {
    388     sp<AMessage> msg = new AMessage(kWhatFlush, id());
    389 
    390     sp<AMessage> response;
    391     return PostAndAwaitResponse(msg, &response);
    392 }
    393 
    394 status_t MediaCodec::requestIDRFrame() {
    395     (new AMessage(kWhatRequestIDRFrame, id()))->post();
    396 
    397     return OK;
    398 }
    399 
    400 void MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
    401     sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, id());
    402     msg->setMessage("notify", notify);
    403     msg->post();
    404 }
    405 
    406 ////////////////////////////////////////////////////////////////////////////////
    407 
    408 void MediaCodec::cancelPendingDequeueOperations() {
    409     if (mFlags & kFlagDequeueInputPending) {
    410         sp<AMessage> response = new AMessage;
    411         response->setInt32("err", INVALID_OPERATION);
    412         response->postReply(mDequeueInputReplyID);
    413 
    414         ++mDequeueInputTimeoutGeneration;
    415         mDequeueInputReplyID = 0;
    416         mFlags &= ~kFlagDequeueInputPending;
    417     }
    418 
    419     if (mFlags & kFlagDequeueOutputPending) {
    420         sp<AMessage> response = new AMessage;
    421         response->setInt32("err", INVALID_OPERATION);
    422         response->postReply(mDequeueOutputReplyID);
    423 
    424         ++mDequeueOutputTimeoutGeneration;
    425         mDequeueOutputReplyID = 0;
    426         mFlags &= ~kFlagDequeueOutputPending;
    427     }
    428 }
    429 
    430 bool MediaCodec::handleDequeueInputBuffer(uint32_t replyID, bool newRequest) {
    431     if (mState != STARTED
    432             || (mFlags & kFlagStickyError)
    433             || (newRequest && (mFlags & kFlagDequeueInputPending))) {
    434         sp<AMessage> response = new AMessage;
    435         response->setInt32("err", INVALID_OPERATION);
    436 
    437         response->postReply(replyID);
    438 
    439         return true;
    440     }
    441 
    442     ssize_t index = dequeuePortBuffer(kPortIndexInput);
    443 
    444     if (index < 0) {
    445         CHECK_EQ(index, -EAGAIN);
    446         return false;
    447     }
    448 
    449     sp<AMessage> response = new AMessage;
    450     response->setSize("index", index);
    451     response->postReply(replyID);
    452 
    453     return true;
    454 }
    455 
    456 bool MediaCodec::handleDequeueOutputBuffer(uint32_t replyID, bool newRequest) {
    457     sp<AMessage> response = new AMessage;
    458 
    459     if (mState != STARTED
    460             || (mFlags & kFlagStickyError)
    461             || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
    462         response->setInt32("err", INVALID_OPERATION);
    463     } else if (mFlags & kFlagOutputBuffersChanged) {
    464         response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED);
    465         mFlags &= ~kFlagOutputBuffersChanged;
    466     } else if (mFlags & kFlagOutputFormatChanged) {
    467         response->setInt32("err", INFO_FORMAT_CHANGED);
    468         mFlags &= ~kFlagOutputFormatChanged;
    469     } else {
    470         ssize_t index = dequeuePortBuffer(kPortIndexOutput);
    471 
    472         if (index < 0) {
    473             CHECK_EQ(index, -EAGAIN);
    474             return false;
    475         }
    476 
    477         const sp<ABuffer> &buffer =
    478             mPortBuffers[kPortIndexOutput].itemAt(index).mData;
    479 
    480         response->setSize("index", index);
    481         response->setSize("offset", buffer->offset());
    482         response->setSize("size", buffer->size());
    483 
    484         int64_t timeUs;
    485         CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
    486 
    487         response->setInt64("timeUs", timeUs);
    488 
    489         int32_t omxFlags;
    490         CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
    491 
    492         uint32_t flags = 0;
    493         if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
    494             flags |= BUFFER_FLAG_SYNCFRAME;
    495         }
    496         if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
    497             flags |= BUFFER_FLAG_CODECCONFIG;
    498         }
    499         if (omxFlags & OMX_BUFFERFLAG_EOS) {
    500             flags |= BUFFER_FLAG_EOS;
    501         }
    502 
    503         response->setInt32("flags", flags);
    504     }
    505 
    506     response->postReply(replyID);
    507 
    508     return true;
    509 }
    510 
    511 void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
    512     switch (msg->what()) {
    513         case kWhatCodecNotify:
    514         {
    515             int32_t what;
    516             CHECK(msg->findInt32("what", &what));
    517 
    518             switch (what) {
    519                 case ACodec::kWhatError:
    520                 {
    521                     int32_t omxError, internalError;
    522                     CHECK(msg->findInt32("omx-error", &omxError));
    523                     CHECK(msg->findInt32("err", &internalError));
    524 
    525                     ALOGE("Codec reported an error. "
    526                           "(omx error 0x%08x, internalError %d)",
    527                           omxError, internalError);
    528 
    529                     if (omxError == OMX_ErrorResourcesLost
    530                             && internalError == DEAD_OBJECT) {
    531                         mFlags |= kFlagSawMediaServerDie;
    532                     }
    533 
    534                     bool sendErrorReponse = true;
    535 
    536                     switch (mState) {
    537                         case INITIALIZING:
    538                         {
    539                             setState(UNINITIALIZED);
    540                             break;
    541                         }
    542 
    543                         case CONFIGURING:
    544                         {
    545                             setState(INITIALIZED);
    546                             break;
    547                         }
    548 
    549                         case STARTING:
    550                         {
    551                             setState(CONFIGURED);
    552                             break;
    553                         }
    554 
    555                         case STOPPING:
    556                         case RELEASING:
    557                         {
    558                             // Ignore the error, assuming we'll still get
    559                             // the shutdown complete notification.
    560 
    561                             sendErrorReponse = false;
    562 
    563                             if (mFlags & kFlagSawMediaServerDie) {
    564                                 // MediaServer died, there definitely won't
    565                                 // be a shutdown complete notification after
    566                                 // all.
    567 
    568                                 // note that we're directly going from
    569                                 // STOPPING->UNINITIALIZED, instead of the
    570                                 // usual STOPPING->INITIALIZED state.
    571                                 setState(UNINITIALIZED);
    572 
    573                                 (new AMessage)->postReply(mReplyID);
    574                             }
    575                             break;
    576                         }
    577 
    578                         case FLUSHING:
    579                         {
    580                             setState(STARTED);
    581                             break;
    582                         }
    583 
    584                         case STARTED:
    585                         {
    586                             sendErrorReponse = false;
    587 
    588                             mFlags |= kFlagStickyError;
    589                             postActivityNotificationIfPossible();
    590 
    591                             cancelPendingDequeueOperations();
    592                             break;
    593                         }
    594 
    595                         default:
    596                         {
    597                             sendErrorReponse = false;
    598 
    599                             mFlags |= kFlagStickyError;
    600                             postActivityNotificationIfPossible();
    601                             break;
    602                         }
    603                     }
    604 
    605                     if (sendErrorReponse) {
    606                         sp<AMessage> response = new AMessage;
    607                         response->setInt32("err", UNKNOWN_ERROR);
    608 
    609                         response->postReply(mReplyID);
    610                     }
    611                     break;
    612                 }
    613 
    614                 case ACodec::kWhatComponentAllocated:
    615                 {
    616                     CHECK_EQ(mState, INITIALIZING);
    617                     setState(INITIALIZED);
    618 
    619                     CHECK(msg->findString("componentName", &mComponentName));
    620 
    621                     if (mComponentName.startsWith("OMX.google.")) {
    622                         mFlags |= kFlagIsSoftwareCodec;
    623                     } else {
    624                         mFlags &= ~kFlagIsSoftwareCodec;
    625                     }
    626 
    627                     if (mComponentName.endsWith(".secure")) {
    628                         mFlags |= kFlagIsSecure;
    629                     } else {
    630                         mFlags &= ~kFlagIsSecure;
    631                     }
    632 
    633                     (new AMessage)->postReply(mReplyID);
    634                     break;
    635                 }
    636 
    637                 case ACodec::kWhatComponentConfigured:
    638                 {
    639                     CHECK_EQ(mState, CONFIGURING);
    640                     setState(CONFIGURED);
    641 
    642                     // reset input surface flag
    643                     mHaveInputSurface = false;
    644 
    645                     (new AMessage)->postReply(mReplyID);
    646                     break;
    647                 }
    648 
    649                 case ACodec::kWhatInputSurfaceCreated:
    650                 {
    651                     // response to ACodec::kWhatCreateInputSurface
    652                     status_t err = NO_ERROR;
    653                     sp<AMessage> response = new AMessage();
    654                     if (!msg->findInt32("err", &err)) {
    655                         sp<RefBase> obj;
    656                         msg->findObject("input-surface", &obj);
    657                         CHECK(obj != NULL);
    658                         response->setObject("input-surface", obj);
    659                         mHaveInputSurface = true;
    660                     } else {
    661                         response->setInt32("err", err);
    662                     }
    663                     response->postReply(mReplyID);
    664                     break;
    665                 }
    666 
    667                 case ACodec::kWhatSignaledInputEOS:
    668                 {
    669                     // response to ACodec::kWhatSignalEndOfInputStream
    670                     sp<AMessage> response = new AMessage();
    671                     status_t err;
    672                     if (msg->findInt32("err", &err)) {
    673                         response->setInt32("err", err);
    674                     }
    675                     response->postReply(mReplyID);
    676                     break;
    677                 }
    678 
    679 
    680                 case ACodec::kWhatBuffersAllocated:
    681                 {
    682                     int32_t portIndex;
    683                     CHECK(msg->findInt32("portIndex", &portIndex));
    684 
    685                     ALOGV("%s buffers allocated",
    686                           portIndex == kPortIndexInput ? "input" : "output");
    687 
    688                     CHECK(portIndex == kPortIndexInput
    689                             || portIndex == kPortIndexOutput);
    690 
    691                     mPortBuffers[portIndex].clear();
    692 
    693                     Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
    694 
    695                     sp<RefBase> obj;
    696                     CHECK(msg->findObject("portDesc", &obj));
    697 
    698                     sp<ACodec::PortDescription> portDesc =
    699                         static_cast<ACodec::PortDescription *>(obj.get());
    700 
    701                     size_t numBuffers = portDesc->countBuffers();
    702 
    703                     for (size_t i = 0; i < numBuffers; ++i) {
    704                         BufferInfo info;
    705                         info.mBufferID = portDesc->bufferIDAt(i);
    706                         info.mOwnedByClient = false;
    707                         info.mData = portDesc->bufferAt(i);
    708 
    709                         if (portIndex == kPortIndexInput && mCrypto != NULL) {
    710                             info.mEncryptedData =
    711                                 new ABuffer(info.mData->capacity());
    712                         }
    713 
    714                         buffers->push_back(info);
    715                     }
    716 
    717                     if (portIndex == kPortIndexOutput) {
    718                         if (mState == STARTING) {
    719                             // We're always allocating output buffers after
    720                             // allocating input buffers, so this is a good
    721                             // indication that now all buffers are allocated.
    722                             setState(STARTED);
    723                             (new AMessage)->postReply(mReplyID);
    724                         } else {
    725                             mFlags |= kFlagOutputBuffersChanged;
    726                             postActivityNotificationIfPossible();
    727                         }
    728                     }
    729                     break;
    730                 }
    731 
    732                 case ACodec::kWhatOutputFormatChanged:
    733                 {
    734                     ALOGV("codec output format changed");
    735 
    736                     if ((mFlags & kFlagIsSoftwareCodec)
    737                             && mNativeWindow != NULL) {
    738                         AString mime;
    739                         CHECK(msg->findString("mime", &mime));
    740 
    741                         if (!strncasecmp("video/", mime.c_str(), 6)) {
    742                             delete mSoftRenderer;
    743                             mSoftRenderer = NULL;
    744 
    745                             int32_t width, height;
    746                             CHECK(msg->findInt32("width", &width));
    747                             CHECK(msg->findInt32("height", &height));
    748 
    749                             int32_t colorFormat;
    750                             CHECK(msg->findInt32(
    751                                         "color-format", &colorFormat));
    752 
    753                             sp<MetaData> meta = new MetaData;
    754                             meta->setInt32(kKeyWidth, width);
    755                             meta->setInt32(kKeyHeight, height);
    756                             meta->setInt32(kKeyColorFormat, colorFormat);
    757 
    758                             mSoftRenderer =
    759                                 new SoftwareRenderer(mNativeWindow, meta);
    760                         }
    761                     }
    762 
    763                     mOutputFormat = msg;
    764 
    765                     if (mFlags & kFlagIsEncoder) {
    766                         // Before we announce the format change we should
    767                         // collect codec specific data and amend the output
    768                         // format as necessary.
    769                         mFlags |= kFlagGatherCodecSpecificData;
    770                     } else {
    771                         mFlags |= kFlagOutputFormatChanged;
    772                         postActivityNotificationIfPossible();
    773                     }
    774                     break;
    775                 }
    776 
    777                 case ACodec::kWhatFillThisBuffer:
    778                 {
    779                     /* size_t index = */updateBuffers(kPortIndexInput, msg);
    780 
    781                     if (mState == FLUSHING
    782                             || mState == STOPPING
    783                             || mState == RELEASING) {
    784                         returnBuffersToCodecOnPort(kPortIndexInput);
    785                         break;
    786                     }
    787 
    788                     if (!mCSD.empty()) {
    789                         ssize_t index = dequeuePortBuffer(kPortIndexInput);
    790                         CHECK_GE(index, 0);
    791 
    792                         // If codec specific data had been specified as
    793                         // part of the format in the call to configure and
    794                         // if there's more csd left, we submit it here
    795                         // clients only get access to input buffers once
    796                         // this data has been exhausted.
    797 
    798                         status_t err = queueCSDInputBuffer(index);
    799 
    800                         if (err != OK) {
    801                             ALOGE("queueCSDInputBuffer failed w/ error %d",
    802                                   err);
    803 
    804                             mFlags |= kFlagStickyError;
    805                             postActivityNotificationIfPossible();
    806 
    807                             cancelPendingDequeueOperations();
    808                         }
    809                         break;
    810                     }
    811 
    812                     if (mFlags & kFlagDequeueInputPending) {
    813                         CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
    814 
    815                         ++mDequeueInputTimeoutGeneration;
    816                         mFlags &= ~kFlagDequeueInputPending;
    817                         mDequeueInputReplyID = 0;
    818                     } else {
    819                         postActivityNotificationIfPossible();
    820                     }
    821                     break;
    822                 }
    823 
    824                 case ACodec::kWhatDrainThisBuffer:
    825                 {
    826                     /* size_t index = */updateBuffers(kPortIndexOutput, msg);
    827 
    828                     if (mState == FLUSHING
    829                             || mState == STOPPING
    830                             || mState == RELEASING) {
    831                         returnBuffersToCodecOnPort(kPortIndexOutput);
    832                         break;
    833                     }
    834 
    835                     sp<ABuffer> buffer;
    836                     CHECK(msg->findBuffer("buffer", &buffer));
    837 
    838                     int32_t omxFlags;
    839                     CHECK(msg->findInt32("flags", &omxFlags));
    840 
    841                     buffer->meta()->setInt32("omxFlags", omxFlags);
    842 
    843                     if (mFlags & kFlagGatherCodecSpecificData) {
    844                         // This is the very first output buffer after a
    845                         // format change was signalled, it'll either contain
    846                         // the one piece of codec specific data we can expect
    847                         // or there won't be codec specific data.
    848                         if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
    849                             status_t err =
    850                                 amendOutputFormatWithCodecSpecificData(buffer);
    851 
    852                             if (err != OK) {
    853                                 ALOGE("Codec spit out malformed codec "
    854                                       "specific data!");
    855                             }
    856                         }
    857 
    858                         mFlags &= ~kFlagGatherCodecSpecificData;
    859                         mFlags |= kFlagOutputFormatChanged;
    860                     }
    861 
    862                     if (mFlags & kFlagDequeueOutputPending) {
    863                         CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
    864 
    865                         ++mDequeueOutputTimeoutGeneration;
    866                         mFlags &= ~kFlagDequeueOutputPending;
    867                         mDequeueOutputReplyID = 0;
    868                     } else {
    869                         postActivityNotificationIfPossible();
    870                     }
    871 
    872                     break;
    873                 }
    874 
    875                 case ACodec::kWhatEOS:
    876                 {
    877                     // We already notify the client of this by using the
    878                     // corresponding flag in "onOutputBufferReady".
    879                     break;
    880                 }
    881 
    882                 case ACodec::kWhatShutdownCompleted:
    883                 {
    884                     if (mState == STOPPING) {
    885                         setState(INITIALIZED);
    886                     } else {
    887                         CHECK_EQ(mState, RELEASING);
    888                         setState(UNINITIALIZED);
    889                     }
    890 
    891                     (new AMessage)->postReply(mReplyID);
    892                     break;
    893                 }
    894 
    895                 case ACodec::kWhatFlushCompleted:
    896                 {
    897                     CHECK_EQ(mState, FLUSHING);
    898                     setState(STARTED);
    899 
    900                     mCodec->signalResume();
    901 
    902                     (new AMessage)->postReply(mReplyID);
    903                     break;
    904                 }
    905 
    906                 default:
    907                     TRESPASS();
    908             }
    909             break;
    910         }
    911 
    912         case kWhatInit:
    913         {
    914             uint32_t replyID;
    915             CHECK(msg->senderAwaitsResponse(&replyID));
    916 
    917             if (mState != UNINITIALIZED) {
    918                 sp<AMessage> response = new AMessage;
    919                 response->setInt32("err", INVALID_OPERATION);
    920 
    921                 response->postReply(replyID);
    922                 break;
    923             }
    924 
    925             mReplyID = replyID;
    926             setState(INITIALIZING);
    927 
    928             AString name;
    929             CHECK(msg->findString("name", &name));
    930 
    931             int32_t nameIsType;
    932             int32_t encoder = false;
    933             CHECK(msg->findInt32("nameIsType", &nameIsType));
    934             if (nameIsType) {
    935                 CHECK(msg->findInt32("encoder", &encoder));
    936             }
    937 
    938             sp<AMessage> format = new AMessage;
    939 
    940             if (nameIsType) {
    941                 format->setString("mime", name.c_str());
    942                 format->setInt32("encoder", encoder);
    943             } else {
    944                 format->setString("componentName", name.c_str());
    945             }
    946 
    947             mCodec->initiateAllocateComponent(format);
    948             break;
    949         }
    950 
    951         case kWhatConfigure:
    952         {
    953             uint32_t replyID;
    954             CHECK(msg->senderAwaitsResponse(&replyID));
    955 
    956             if (mState != INITIALIZED) {
    957                 sp<AMessage> response = new AMessage;
    958                 response->setInt32("err", INVALID_OPERATION);
    959 
    960                 response->postReply(replyID);
    961                 break;
    962             }
    963 
    964             sp<RefBase> obj;
    965             if (!msg->findObject("native-window", &obj)) {
    966                 obj.clear();
    967             }
    968 
    969             sp<AMessage> format;
    970             CHECK(msg->findMessage("format", &format));
    971 
    972             if (obj != NULL) {
    973                 format->setObject("native-window", obj);
    974 
    975                 status_t err = setNativeWindow(
    976                     static_cast<NativeWindowWrapper *>(obj.get())
    977                         ->getSurfaceTextureClient());
    978 
    979                 if (err != OK) {
    980                     sp<AMessage> response = new AMessage;
    981                     response->setInt32("err", err);
    982 
    983                     response->postReply(replyID);
    984                     break;
    985                 }
    986             } else {
    987                 setNativeWindow(NULL);
    988             }
    989 
    990             mReplyID = replyID;
    991             setState(CONFIGURING);
    992 
    993             void *crypto;
    994             if (!msg->findPointer("crypto", &crypto)) {
    995                 crypto = NULL;
    996             }
    997 
    998             mCrypto = static_cast<ICrypto *>(crypto);
    999 
   1000             uint32_t flags;
   1001             CHECK(msg->findInt32("flags", (int32_t *)&flags));
   1002 
   1003             if (flags & CONFIGURE_FLAG_ENCODE) {
   1004                 format->setInt32("encoder", true);
   1005                 mFlags |= kFlagIsEncoder;
   1006             }
   1007 
   1008             extractCSD(format);
   1009 
   1010             mCodec->initiateConfigureComponent(format);
   1011             break;
   1012         }
   1013 
   1014         case kWhatCreateInputSurface:
   1015         {
   1016             uint32_t replyID;
   1017             CHECK(msg->senderAwaitsResponse(&replyID));
   1018 
   1019             // Must be configured, but can't have been started yet.
   1020             if (mState != CONFIGURED) {
   1021                 sp<AMessage> response = new AMessage;
   1022                 response->setInt32("err", INVALID_OPERATION);
   1023 
   1024                 response->postReply(replyID);
   1025                 break;
   1026             }
   1027 
   1028             mReplyID = replyID;
   1029             mCodec->initiateCreateInputSurface();
   1030             break;
   1031         }
   1032 
   1033         case kWhatStart:
   1034         {
   1035             uint32_t replyID;
   1036             CHECK(msg->senderAwaitsResponse(&replyID));
   1037 
   1038             if (mState != CONFIGURED) {
   1039                 sp<AMessage> response = new AMessage;
   1040                 response->setInt32("err", INVALID_OPERATION);
   1041 
   1042                 response->postReply(replyID);
   1043                 break;
   1044             }
   1045 
   1046             mReplyID = replyID;
   1047             setState(STARTING);
   1048 
   1049             mCodec->initiateStart();
   1050             break;
   1051         }
   1052 
   1053         case kWhatStop:
   1054         case kWhatRelease:
   1055         {
   1056             State targetState =
   1057                 (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED;
   1058 
   1059             uint32_t replyID;
   1060             CHECK(msg->senderAwaitsResponse(&replyID));
   1061 
   1062             if (mState != INITIALIZED
   1063                     && mState != CONFIGURED && mState != STARTED) {
   1064                 // We may be in "UNINITIALIZED" state already without the
   1065                 // client being aware of this if media server died while
   1066                 // we were being stopped. The client would assume that
   1067                 // after stop() returned, it would be safe to call release()
   1068                 // and it should be in this case, no harm to allow a release()
   1069                 // if we're already uninitialized.
   1070                 // Similarly stopping a stopped MediaCodec should be benign.
   1071                 sp<AMessage> response = new AMessage;
   1072                 response->setInt32(
   1073                         "err",
   1074                         mState == targetState ? OK : INVALID_OPERATION);
   1075 
   1076                 response->postReply(replyID);
   1077                 break;
   1078             }
   1079 
   1080             if (mFlags & kFlagSawMediaServerDie) {
   1081                 // It's dead, Jim. Don't expect initiateShutdown to yield
   1082                 // any useful results now...
   1083                 setState(UNINITIALIZED);
   1084                 (new AMessage)->postReply(replyID);
   1085                 break;
   1086             }
   1087 
   1088             mReplyID = replyID;
   1089             setState(msg->what() == kWhatStop ? STOPPING : RELEASING);
   1090 
   1091             mCodec->initiateShutdown(
   1092                     msg->what() == kWhatStop /* keepComponentAllocated */);
   1093 
   1094             returnBuffersToCodec();
   1095             break;
   1096         }
   1097 
   1098         case kWhatDequeueInputBuffer:
   1099         {
   1100             uint32_t replyID;
   1101             CHECK(msg->senderAwaitsResponse(&replyID));
   1102 
   1103             if (mHaveInputSurface) {
   1104                 ALOGE("dequeueInputBuffer can't be used with input surface");
   1105                 sp<AMessage> response = new AMessage;
   1106                 response->setInt32("err", INVALID_OPERATION);
   1107                 response->postReply(replyID);
   1108                 break;
   1109             }
   1110 
   1111             if (handleDequeueInputBuffer(replyID, true /* new request */)) {
   1112                 break;
   1113             }
   1114 
   1115             int64_t timeoutUs;
   1116             CHECK(msg->findInt64("timeoutUs", &timeoutUs));
   1117 
   1118             if (timeoutUs == 0ll) {
   1119                 sp<AMessage> response = new AMessage;
   1120                 response->setInt32("err", -EAGAIN);
   1121                 response->postReply(replyID);
   1122                 break;
   1123             }
   1124 
   1125             mFlags |= kFlagDequeueInputPending;
   1126             mDequeueInputReplyID = replyID;
   1127 
   1128             if (timeoutUs > 0ll) {
   1129                 sp<AMessage> timeoutMsg =
   1130                     new AMessage(kWhatDequeueInputTimedOut, id());
   1131                 timeoutMsg->setInt32(
   1132                         "generation", ++mDequeueInputTimeoutGeneration);
   1133                 timeoutMsg->post(timeoutUs);
   1134             }
   1135             break;
   1136         }
   1137 
   1138         case kWhatDequeueInputTimedOut:
   1139         {
   1140             int32_t generation;
   1141             CHECK(msg->findInt32("generation", &generation));
   1142 
   1143             if (generation != mDequeueInputTimeoutGeneration) {
   1144                 // Obsolete
   1145                 break;
   1146             }
   1147 
   1148             CHECK(mFlags & kFlagDequeueInputPending);
   1149 
   1150             sp<AMessage> response = new AMessage;
   1151             response->setInt32("err", -EAGAIN);
   1152             response->postReply(mDequeueInputReplyID);
   1153 
   1154             mFlags &= ~kFlagDequeueInputPending;
   1155             mDequeueInputReplyID = 0;
   1156             break;
   1157         }
   1158 
   1159         case kWhatQueueInputBuffer:
   1160         {
   1161             uint32_t replyID;
   1162             CHECK(msg->senderAwaitsResponse(&replyID));
   1163 
   1164             if (mState != STARTED || (mFlags & kFlagStickyError)) {
   1165                 sp<AMessage> response = new AMessage;
   1166                 response->setInt32("err", INVALID_OPERATION);
   1167 
   1168                 response->postReply(replyID);
   1169                 break;
   1170             }
   1171 
   1172             status_t err = onQueueInputBuffer(msg);
   1173 
   1174             sp<AMessage> response = new AMessage;
   1175             response->setInt32("err", err);
   1176             response->postReply(replyID);
   1177             break;
   1178         }
   1179 
   1180         case kWhatDequeueOutputBuffer:
   1181         {
   1182             uint32_t replyID;
   1183             CHECK(msg->senderAwaitsResponse(&replyID));
   1184 
   1185             if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
   1186                 break;
   1187             }
   1188 
   1189             int64_t timeoutUs;
   1190             CHECK(msg->findInt64("timeoutUs", &timeoutUs));
   1191 
   1192             if (timeoutUs == 0ll) {
   1193                 sp<AMessage> response = new AMessage;
   1194                 response->setInt32("err", -EAGAIN);
   1195                 response->postReply(replyID);
   1196                 break;
   1197             }
   1198 
   1199             mFlags |= kFlagDequeueOutputPending;
   1200             mDequeueOutputReplyID = replyID;
   1201 
   1202             if (timeoutUs > 0ll) {
   1203                 sp<AMessage> timeoutMsg =
   1204                     new AMessage(kWhatDequeueOutputTimedOut, id());
   1205                 timeoutMsg->setInt32(
   1206                         "generation", ++mDequeueOutputTimeoutGeneration);
   1207                 timeoutMsg->post(timeoutUs);
   1208             }
   1209             break;
   1210         }
   1211 
   1212         case kWhatDequeueOutputTimedOut:
   1213         {
   1214             int32_t generation;
   1215             CHECK(msg->findInt32("generation", &generation));
   1216 
   1217             if (generation != mDequeueOutputTimeoutGeneration) {
   1218                 // Obsolete
   1219                 break;
   1220             }
   1221 
   1222             CHECK(mFlags & kFlagDequeueOutputPending);
   1223 
   1224             sp<AMessage> response = new AMessage;
   1225             response->setInt32("err", -EAGAIN);
   1226             response->postReply(mDequeueOutputReplyID);
   1227 
   1228             mFlags &= ~kFlagDequeueOutputPending;
   1229             mDequeueOutputReplyID = 0;
   1230             break;
   1231         }
   1232 
   1233         case kWhatReleaseOutputBuffer:
   1234         {
   1235             uint32_t replyID;
   1236             CHECK(msg->senderAwaitsResponse(&replyID));
   1237 
   1238             if (mState != STARTED || (mFlags & kFlagStickyError)) {
   1239                 sp<AMessage> response = new AMessage;
   1240                 response->setInt32("err", INVALID_OPERATION);
   1241 
   1242                 response->postReply(replyID);
   1243                 break;
   1244             }
   1245 
   1246             status_t err = onReleaseOutputBuffer(msg);
   1247 
   1248             sp<AMessage> response = new AMessage;
   1249             response->setInt32("err", err);
   1250             response->postReply(replyID);
   1251             break;
   1252         }
   1253 
   1254         case kWhatSignalEndOfInputStream:
   1255         {
   1256             uint32_t replyID;
   1257             CHECK(msg->senderAwaitsResponse(&replyID));
   1258 
   1259             if (mState != STARTED || (mFlags & kFlagStickyError)) {
   1260                 sp<AMessage> response = new AMessage;
   1261                 response->setInt32("err", INVALID_OPERATION);
   1262 
   1263                 response->postReply(replyID);
   1264                 break;
   1265             }
   1266 
   1267             mReplyID = replyID;
   1268             mCodec->signalEndOfInputStream();
   1269             break;
   1270         }
   1271 
   1272         case kWhatGetBuffers:
   1273         {
   1274             uint32_t replyID;
   1275             CHECK(msg->senderAwaitsResponse(&replyID));
   1276 
   1277             if (mState != STARTED || (mFlags & kFlagStickyError)) {
   1278                 sp<AMessage> response = new AMessage;
   1279                 response->setInt32("err", INVALID_OPERATION);
   1280 
   1281                 response->postReply(replyID);
   1282                 break;
   1283             }
   1284 
   1285             int32_t portIndex;
   1286             CHECK(msg->findInt32("portIndex", &portIndex));
   1287 
   1288             Vector<sp<ABuffer> > *dstBuffers;
   1289             CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
   1290 
   1291             dstBuffers->clear();
   1292             const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
   1293 
   1294             for (size_t i = 0; i < srcBuffers.size(); ++i) {
   1295                 const BufferInfo &info = srcBuffers.itemAt(i);
   1296 
   1297                 dstBuffers->push_back(
   1298                         (portIndex == kPortIndexInput && mCrypto != NULL)
   1299                                 ? info.mEncryptedData : info.mData);
   1300             }
   1301 
   1302             (new AMessage)->postReply(replyID);
   1303             break;
   1304         }
   1305 
   1306         case kWhatFlush:
   1307         {
   1308             uint32_t replyID;
   1309             CHECK(msg->senderAwaitsResponse(&replyID));
   1310 
   1311             if (mState != STARTED || (mFlags & kFlagStickyError)) {
   1312                 sp<AMessage> response = new AMessage;
   1313                 response->setInt32("err", INVALID_OPERATION);
   1314 
   1315                 response->postReply(replyID);
   1316                 break;
   1317             }
   1318 
   1319             mReplyID = replyID;
   1320             setState(FLUSHING);
   1321 
   1322             mCodec->signalFlush();
   1323             returnBuffersToCodec();
   1324             break;
   1325         }
   1326 
   1327         case kWhatGetOutputFormat:
   1328         {
   1329             uint32_t replyID;
   1330             CHECK(msg->senderAwaitsResponse(&replyID));
   1331 
   1332             if ((mState != STARTED && mState != FLUSHING)
   1333                     || (mFlags & kFlagStickyError)
   1334                     || mOutputFormat == NULL) {
   1335                 sp<AMessage> response = new AMessage;
   1336                 response->setInt32("err", INVALID_OPERATION);
   1337 
   1338                 response->postReply(replyID);
   1339                 break;
   1340             }
   1341 
   1342             sp<AMessage> response = new AMessage;
   1343             response->setMessage("format", mOutputFormat);
   1344             response->postReply(replyID);
   1345             break;
   1346         }
   1347 
   1348         case kWhatRequestIDRFrame:
   1349         {
   1350             mCodec->signalRequestIDRFrame();
   1351             break;
   1352         }
   1353 
   1354         case kWhatRequestActivityNotification:
   1355         {
   1356             CHECK(mActivityNotify == NULL);
   1357             CHECK(msg->findMessage("notify", &mActivityNotify));
   1358 
   1359             postActivityNotificationIfPossible();
   1360             break;
   1361         }
   1362 
   1363         case kWhatGetName:
   1364         {
   1365             uint32_t replyID;
   1366             CHECK(msg->senderAwaitsResponse(&replyID));
   1367 
   1368             if (mComponentName.empty()) {
   1369                 sp<AMessage> response = new AMessage;
   1370                 response->setInt32("err", INVALID_OPERATION);
   1371 
   1372                 response->postReply(replyID);
   1373                 break;
   1374             }
   1375 
   1376             sp<AMessage> response = new AMessage;
   1377             response->setString("name", mComponentName.c_str());
   1378             response->postReply(replyID);
   1379             break;
   1380         }
   1381 
   1382         case kWhatSetParameters:
   1383         {
   1384             uint32_t replyID;
   1385             CHECK(msg->senderAwaitsResponse(&replyID));
   1386 
   1387             sp<AMessage> params;
   1388             CHECK(msg->findMessage("params", &params));
   1389 
   1390             status_t err = onSetParameters(params);
   1391 
   1392             sp<AMessage> response = new AMessage;
   1393             response->setInt32("err", err);
   1394 
   1395             response->postReply(replyID);
   1396             break;
   1397         }
   1398 
   1399         default:
   1400             TRESPASS();
   1401     }
   1402 }
   1403 
   1404 void MediaCodec::extractCSD(const sp<AMessage> &format) {
   1405     mCSD.clear();
   1406 
   1407     size_t i = 0;
   1408     for (;;) {
   1409         sp<ABuffer> csd;
   1410         if (!format->findBuffer(StringPrintf("csd-%u", i).c_str(), &csd)) {
   1411             break;
   1412         }
   1413 
   1414         mCSD.push_back(csd);
   1415         ++i;
   1416     }
   1417 
   1418     ALOGV("Found %u pieces of codec specific data.", mCSD.size());
   1419 }
   1420 
   1421 status_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
   1422     CHECK(!mCSD.empty());
   1423 
   1424     BufferInfo *info =
   1425         &mPortBuffers[kPortIndexInput].editItemAt(bufferIndex);
   1426 
   1427     sp<ABuffer> csd = *mCSD.begin();
   1428     mCSD.erase(mCSD.begin());
   1429 
   1430     const sp<ABuffer> &codecInputData =
   1431         (mCrypto != NULL) ? info->mEncryptedData : info->mData;
   1432 
   1433     if (csd->size() > codecInputData->capacity()) {
   1434         return -EINVAL;
   1435     }
   1436 
   1437     memcpy(codecInputData->data(), csd->data(), csd->size());
   1438 
   1439     AString errorDetailMsg;
   1440 
   1441     sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
   1442     msg->setSize("index", bufferIndex);
   1443     msg->setSize("offset", 0);
   1444     msg->setSize("size", csd->size());
   1445     msg->setInt64("timeUs", 0ll);
   1446     msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
   1447     msg->setPointer("errorDetailMsg", &errorDetailMsg);
   1448 
   1449     return onQueueInputBuffer(msg);
   1450 }
   1451 
   1452 void MediaCodec::setState(State newState) {
   1453     if (newState == INITIALIZED || newState == UNINITIALIZED) {
   1454         delete mSoftRenderer;
   1455         mSoftRenderer = NULL;
   1456 
   1457         mCrypto.clear();
   1458         setNativeWindow(NULL);
   1459 
   1460         mOutputFormat.clear();
   1461         mFlags &= ~kFlagOutputFormatChanged;
   1462         mFlags &= ~kFlagOutputBuffersChanged;
   1463         mFlags &= ~kFlagStickyError;
   1464         mFlags &= ~kFlagIsEncoder;
   1465         mFlags &= ~kFlagGatherCodecSpecificData;
   1466 
   1467         mActivityNotify.clear();
   1468     }
   1469 
   1470     if (newState == UNINITIALIZED) {
   1471         mComponentName.clear();
   1472 
   1473         // The component is gone, mediaserver's probably back up already
   1474         // but should definitely be back up should we try to instantiate
   1475         // another component.. and the cycle continues.
   1476         mFlags &= ~kFlagSawMediaServerDie;
   1477     }
   1478 
   1479     mState = newState;
   1480 
   1481     cancelPendingDequeueOperations();
   1482 }
   1483 
   1484 void MediaCodec::returnBuffersToCodec() {
   1485     returnBuffersToCodecOnPort(kPortIndexInput);
   1486     returnBuffersToCodecOnPort(kPortIndexOutput);
   1487 }
   1488 
   1489 void MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) {
   1490     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
   1491 
   1492     Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
   1493 
   1494     for (size_t i = 0; i < buffers->size(); ++i) {
   1495         BufferInfo *info = &buffers->editItemAt(i);
   1496 
   1497         if (info->mNotify != NULL) {
   1498             sp<AMessage> msg = info->mNotify;
   1499             info->mNotify = NULL;
   1500             info->mOwnedByClient = false;
   1501 
   1502             if (portIndex == kPortIndexInput) {
   1503                 /* no error, just returning buffers */
   1504                 msg->setInt32("err", OK);
   1505             }
   1506             msg->post();
   1507         }
   1508     }
   1509 
   1510     mAvailPortBuffers[portIndex].clear();
   1511 }
   1512 
   1513 size_t MediaCodec::updateBuffers(
   1514         int32_t portIndex, const sp<AMessage> &msg) {
   1515     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
   1516 
   1517     void *bufferID;
   1518     CHECK(msg->findPointer("buffer-id", &bufferID));
   1519 
   1520     Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
   1521 
   1522     for (size_t i = 0; i < buffers->size(); ++i) {
   1523         BufferInfo *info = &buffers->editItemAt(i);
   1524 
   1525         if (info->mBufferID == bufferID) {
   1526             CHECK(info->mNotify == NULL);
   1527             CHECK(msg->findMessage("reply", &info->mNotify));
   1528 
   1529             mAvailPortBuffers[portIndex].push_back(i);
   1530 
   1531             return i;
   1532         }
   1533     }
   1534 
   1535     TRESPASS();
   1536 
   1537     return 0;
   1538 }
   1539 
   1540 status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
   1541     size_t index;
   1542     size_t offset;
   1543     size_t size;
   1544     int64_t timeUs;
   1545     uint32_t flags;
   1546     CHECK(msg->findSize("index", &index));
   1547     CHECK(msg->findSize("offset", &offset));
   1548     CHECK(msg->findInt64("timeUs", &timeUs));
   1549     CHECK(msg->findInt32("flags", (int32_t *)&flags));
   1550 
   1551     const CryptoPlugin::SubSample *subSamples;
   1552     size_t numSubSamples;
   1553     const uint8_t *key;
   1554     const uint8_t *iv;
   1555     CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
   1556 
   1557     // We allow the simpler queueInputBuffer API to be used even in
   1558     // secure mode, by fabricating a single unencrypted subSample.
   1559     CryptoPlugin::SubSample ss;
   1560 
   1561     if (msg->findSize("size", &size)) {
   1562         if (mCrypto != NULL) {
   1563             ss.mNumBytesOfClearData = size;
   1564             ss.mNumBytesOfEncryptedData = 0;
   1565 
   1566             subSamples = &ss;
   1567             numSubSamples = 1;
   1568             key = NULL;
   1569             iv = NULL;
   1570         }
   1571     } else {
   1572         if (mCrypto == NULL) {
   1573             return -EINVAL;
   1574         }
   1575 
   1576         CHECK(msg->findPointer("subSamples", (void **)&subSamples));
   1577         CHECK(msg->findSize("numSubSamples", &numSubSamples));
   1578         CHECK(msg->findPointer("key", (void **)&key));
   1579         CHECK(msg->findPointer("iv", (void **)&iv));
   1580 
   1581         int32_t tmp;
   1582         CHECK(msg->findInt32("mode", &tmp));
   1583 
   1584         mode = (CryptoPlugin::Mode)tmp;
   1585 
   1586         size = 0;
   1587         for (size_t i = 0; i < numSubSamples; ++i) {
   1588             size += subSamples[i].mNumBytesOfClearData;
   1589             size += subSamples[i].mNumBytesOfEncryptedData;
   1590         }
   1591     }
   1592 
   1593     if (index >= mPortBuffers[kPortIndexInput].size()) {
   1594         return -ERANGE;
   1595     }
   1596 
   1597     BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
   1598 
   1599     if (info->mNotify == NULL || !info->mOwnedByClient) {
   1600         return -EACCES;
   1601     }
   1602 
   1603     if (offset + size > info->mData->capacity()) {
   1604         return -EINVAL;
   1605     }
   1606 
   1607     sp<AMessage> reply = info->mNotify;
   1608     info->mData->setRange(offset, size);
   1609     info->mData->meta()->setInt64("timeUs", timeUs);
   1610 
   1611     if (flags & BUFFER_FLAG_EOS) {
   1612         info->mData->meta()->setInt32("eos", true);
   1613     }
   1614 
   1615     if (flags & BUFFER_FLAG_CODECCONFIG) {
   1616         info->mData->meta()->setInt32("csd", true);
   1617     }
   1618 
   1619     if (mCrypto != NULL) {
   1620         if (size > info->mEncryptedData->capacity()) {
   1621             return -ERANGE;
   1622         }
   1623 
   1624         AString *errorDetailMsg;
   1625         CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
   1626 
   1627         ssize_t result = mCrypto->decrypt(
   1628                 (mFlags & kFlagIsSecure) != 0,
   1629                 key,
   1630                 iv,
   1631                 mode,
   1632                 info->mEncryptedData->base() + offset,
   1633                 subSamples,
   1634                 numSubSamples,
   1635                 info->mData->base(),
   1636                 errorDetailMsg);
   1637 
   1638         if (result < 0) {
   1639             return result;
   1640         }
   1641 
   1642         info->mData->setRange(0, result);
   1643     }
   1644 
   1645     reply->setBuffer("buffer", info->mData);
   1646     reply->post();
   1647 
   1648     info->mNotify = NULL;
   1649     info->mOwnedByClient = false;
   1650 
   1651     return OK;
   1652 }
   1653 
   1654 status_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
   1655     size_t index;
   1656     CHECK(msg->findSize("index", &index));
   1657 
   1658     int32_t render;
   1659     if (!msg->findInt32("render", &render)) {
   1660         render = 0;
   1661     }
   1662 
   1663     if (mState != STARTED) {
   1664         return -EINVAL;
   1665     }
   1666 
   1667     if (index >= mPortBuffers[kPortIndexOutput].size()) {
   1668         return -ERANGE;
   1669     }
   1670 
   1671     BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
   1672 
   1673     if (info->mNotify == NULL || !info->mOwnedByClient) {
   1674         return -EACCES;
   1675     }
   1676 
   1677     if (render && (info->mData == NULL || info->mData->size() != 0)) {
   1678         info->mNotify->setInt32("render", true);
   1679 
   1680         if (mSoftRenderer != NULL) {
   1681             mSoftRenderer->render(
   1682                     info->mData->data(), info->mData->size(), NULL);
   1683         }
   1684     }
   1685 
   1686     info->mNotify->post();
   1687     info->mNotify = NULL;
   1688     info->mOwnedByClient = false;
   1689 
   1690     return OK;
   1691 }
   1692 
   1693 ssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
   1694     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
   1695 
   1696     List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
   1697 
   1698     if (availBuffers->empty()) {
   1699         return -EAGAIN;
   1700     }
   1701 
   1702     size_t index = *availBuffers->begin();
   1703     availBuffers->erase(availBuffers->begin());
   1704 
   1705     BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
   1706     CHECK(!info->mOwnedByClient);
   1707     info->mOwnedByClient = true;
   1708 
   1709     return index;
   1710 }
   1711 
   1712 status_t MediaCodec::setNativeWindow(
   1713         const sp<Surface> &surfaceTextureClient) {
   1714     status_t err;
   1715 
   1716     if (mNativeWindow != NULL) {
   1717         err = native_window_api_disconnect(
   1718                 mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA);
   1719 
   1720         if (err != OK) {
   1721             ALOGW("native_window_api_disconnect returned an error: %s (%d)",
   1722                     strerror(-err), err);
   1723         }
   1724 
   1725         mNativeWindow.clear();
   1726     }
   1727 
   1728     if (surfaceTextureClient != NULL) {
   1729         err = native_window_api_connect(
   1730                 surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA);
   1731 
   1732         if (err != OK) {
   1733             ALOGE("native_window_api_connect returned an error: %s (%d)",
   1734                     strerror(-err), err);
   1735 
   1736             return err;
   1737         }
   1738 
   1739         mNativeWindow = surfaceTextureClient;
   1740     }
   1741 
   1742     return OK;
   1743 }
   1744 
   1745 void MediaCodec::postActivityNotificationIfPossible() {
   1746     if (mActivityNotify == NULL) {
   1747         return;
   1748     }
   1749 
   1750     if ((mFlags & (kFlagStickyError
   1751                     | kFlagOutputBuffersChanged
   1752                     | kFlagOutputFormatChanged))
   1753             || !mAvailPortBuffers[kPortIndexInput].empty()
   1754             || !mAvailPortBuffers[kPortIndexOutput].empty()) {
   1755         mActivityNotify->post();
   1756         mActivityNotify.clear();
   1757     }
   1758 }
   1759 
   1760 status_t MediaCodec::setParameters(const sp<AMessage> &params) {
   1761     sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
   1762     msg->setMessage("params", params);
   1763 
   1764     sp<AMessage> response;
   1765     return PostAndAwaitResponse(msg, &response);
   1766 }
   1767 
   1768 status_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
   1769     mCodec->signalSetParameters(params);
   1770 
   1771     return OK;
   1772 }
   1773 
   1774 status_t MediaCodec::amendOutputFormatWithCodecSpecificData(
   1775         const sp<ABuffer> &buffer) {
   1776     AString mime;
   1777     CHECK(mOutputFormat->findString("mime", &mime));
   1778 
   1779     if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
   1780         // Codec specific data should be SPS and PPS in a single buffer,
   1781         // each prefixed by a startcode (0x00 0x00 0x00 0x01).
   1782         // We separate the two and put them into the output format
   1783         // under the keys "csd-0" and "csd-1".
   1784 
   1785         unsigned csdIndex = 0;
   1786 
   1787         const uint8_t *data = buffer->data();
   1788         size_t size = buffer->size();
   1789 
   1790         const uint8_t *nalStart;
   1791         size_t nalSize;
   1792         while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
   1793             sp<ABuffer> csd = new ABuffer(nalSize + 4);
   1794             memcpy(csd->data(), "\x00\x00\x00\x01", 4);
   1795             memcpy(csd->data() + 4, nalStart, nalSize);
   1796 
   1797             mOutputFormat->setBuffer(
   1798                     StringPrintf("csd-%u", csdIndex).c_str(), csd);
   1799 
   1800             ++csdIndex;
   1801         }
   1802 
   1803         if (csdIndex != 2) {
   1804             return ERROR_MALFORMED;
   1805         }
   1806     } else {
   1807         // For everything else we just stash the codec specific data into
   1808         // the output format as a single piece of csd under "csd-0".
   1809         mOutputFormat->setBuffer("csd-0", buffer);
   1810     }
   1811 
   1812     return OK;
   1813 }
   1814 
   1815 }  // namespace android
   1816