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