Home | History | Annotate | Download | only in libstagefright
      1 /*
      2  * Copyright (C) 2009 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 "OMXCodec"
     19 #include <utils/Log.h>
     20 
     21 #include "include/AACEncoder.h"
     22 
     23 #include "include/ESDS.h"
     24 
     25 #include <binder/IServiceManager.h>
     26 #include <binder/MemoryDealer.h>
     27 #include <binder/ProcessState.h>
     28 #include <HardwareAPI.h>
     29 #include <media/stagefright/foundation/ADebug.h>
     30 #include <media/IMediaPlayerService.h>
     31 #include <media/stagefright/MediaBuffer.h>
     32 #include <media/stagefright/MediaBufferGroup.h>
     33 #include <media/stagefright/MediaDefs.h>
     34 #include <media/stagefright/MediaCodecList.h>
     35 #include <media/stagefright/MediaExtractor.h>
     36 #include <media/stagefright/MetaData.h>
     37 #include <media/stagefright/OMXCodec.h>
     38 #include <media/stagefright/Utils.h>
     39 #include <media/stagefright/SkipCutBuffer.h>
     40 #include <utils/Vector.h>
     41 
     42 #include <OMX_Audio.h>
     43 #include <OMX_Component.h>
     44 
     45 #include "include/avc_utils.h"
     46 
     47 namespace android {
     48 
     49 // Treat time out as an error if we have not received any output
     50 // buffers after 3 seconds.
     51 const static int64_t kBufferFilledEventTimeOutNs = 3000000000LL;
     52 
     53 // OMX Spec defines less than 50 color formats. If the query for
     54 // color format is executed for more than kMaxColorFormatSupported,
     55 // the query will fail to avoid looping forever.
     56 // 1000 is more than enough for us to tell whether the omx
     57 // component in question is buggy or not.
     58 const static uint32_t kMaxColorFormatSupported = 1000;
     59 
     60 #define FACTORY_CREATE_ENCODER(name) \
     61 static sp<MediaSource> Make##name(const sp<MediaSource> &source, const sp<MetaData> &meta) { \
     62     return new name(source, meta); \
     63 }
     64 
     65 #define FACTORY_REF(name) { #name, Make##name },
     66 
     67 FACTORY_CREATE_ENCODER(AACEncoder)
     68 
     69 static sp<MediaSource> InstantiateSoftwareEncoder(
     70         const char *name, const sp<MediaSource> &source,
     71         const sp<MetaData> &meta) {
     72     struct FactoryInfo {
     73         const char *name;
     74         sp<MediaSource> (*CreateFunc)(const sp<MediaSource> &, const sp<MetaData> &);
     75     };
     76 
     77     static const FactoryInfo kFactoryInfo[] = {
     78         FACTORY_REF(AACEncoder)
     79     };
     80     for (size_t i = 0;
     81          i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) {
     82         if (!strcmp(name, kFactoryInfo[i].name)) {
     83             return (*kFactoryInfo[i].CreateFunc)(source, meta);
     84         }
     85     }
     86 
     87     return NULL;
     88 }
     89 
     90 #undef FACTORY_CREATE_ENCODER
     91 #undef FACTORY_REF
     92 
     93 #define CODEC_LOGI(x, ...) ALOGI("[%s] "x, mComponentName, ##__VA_ARGS__)
     94 #define CODEC_LOGV(x, ...) ALOGV("[%s] "x, mComponentName, ##__VA_ARGS__)
     95 #define CODEC_LOGE(x, ...) ALOGE("[%s] "x, mComponentName, ##__VA_ARGS__)
     96 
     97 struct OMXCodecObserver : public BnOMXObserver {
     98     OMXCodecObserver() {
     99     }
    100 
    101     void setCodec(const sp<OMXCodec> &target) {
    102         mTarget = target;
    103     }
    104 
    105     // from IOMXObserver
    106     virtual void onMessage(const omx_message &msg) {
    107         sp<OMXCodec> codec = mTarget.promote();
    108 
    109         if (codec.get() != NULL) {
    110             Mutex::Autolock autoLock(codec->mLock);
    111             codec->on_message(msg);
    112             codec.clear();
    113         }
    114     }
    115 
    116 protected:
    117     virtual ~OMXCodecObserver() {}
    118 
    119 private:
    120     wp<OMXCodec> mTarget;
    121 
    122     OMXCodecObserver(const OMXCodecObserver &);
    123     OMXCodecObserver &operator=(const OMXCodecObserver &);
    124 };
    125 
    126 template<class T>
    127 static void InitOMXParams(T *params) {
    128     params->nSize = sizeof(T);
    129     params->nVersion.s.nVersionMajor = 1;
    130     params->nVersion.s.nVersionMinor = 0;
    131     params->nVersion.s.nRevision = 0;
    132     params->nVersion.s.nStep = 0;
    133 }
    134 
    135 static bool IsSoftwareCodec(const char *componentName) {
    136     if (!strncmp("OMX.google.", componentName, 11)) {
    137         return true;
    138     }
    139 
    140     if (!strncmp("OMX.", componentName, 4)) {
    141         return false;
    142     }
    143 
    144     return true;
    145 }
    146 
    147 // A sort order in which OMX software codecs are first, followed
    148 // by other (non-OMX) software codecs, followed by everything else.
    149 static int CompareSoftwareCodecsFirst(
    150         const OMXCodec::CodecNameAndQuirks *elem1,
    151         const OMXCodec::CodecNameAndQuirks *elem2) {
    152     bool isOMX1 = !strncmp(elem1->mName.string(), "OMX.", 4);
    153     bool isOMX2 = !strncmp(elem2->mName.string(), "OMX.", 4);
    154 
    155     bool isSoftwareCodec1 = IsSoftwareCodec(elem1->mName.string());
    156     bool isSoftwareCodec2 = IsSoftwareCodec(elem2->mName.string());
    157 
    158     if (isSoftwareCodec1) {
    159         if (!isSoftwareCodec2) { return -1; }
    160 
    161         if (isOMX1) {
    162             if (isOMX2) { return 0; }
    163 
    164             return -1;
    165         } else {
    166             if (isOMX2) { return 0; }
    167 
    168             return 1;
    169         }
    170 
    171         return -1;
    172     }
    173 
    174     if (isSoftwareCodec2) {
    175         return 1;
    176     }
    177 
    178     return 0;
    179 }
    180 
    181 // static
    182 void OMXCodec::findMatchingCodecs(
    183         const char *mime,
    184         bool createEncoder, const char *matchComponentName,
    185         uint32_t flags,
    186         Vector<CodecNameAndQuirks> *matchingCodecs) {
    187     matchingCodecs->clear();
    188 
    189     const MediaCodecList *list = MediaCodecList::getInstance();
    190     if (list == NULL) {
    191         return;
    192     }
    193 
    194     size_t index = 0;
    195     for (;;) {
    196         ssize_t matchIndex =
    197             list->findCodecByType(mime, createEncoder, index);
    198 
    199         if (matchIndex < 0) {
    200             break;
    201         }
    202 
    203         index = matchIndex + 1;
    204 
    205         const char *componentName = list->getCodecName(matchIndex);
    206 
    207         // If a specific codec is requested, skip the non-matching ones.
    208         if (matchComponentName && strcmp(componentName, matchComponentName)) {
    209             continue;
    210         }
    211 
    212         // When requesting software-only codecs, only push software codecs
    213         // When requesting hardware-only codecs, only push hardware codecs
    214         // When there is request neither for software-only nor for
    215         // hardware-only codecs, push all codecs
    216         if (((flags & kSoftwareCodecsOnly) &&   IsSoftwareCodec(componentName)) ||
    217             ((flags & kHardwareCodecsOnly) &&  !IsSoftwareCodec(componentName)) ||
    218             (!(flags & (kSoftwareCodecsOnly | kHardwareCodecsOnly)))) {
    219 
    220             ssize_t index = matchingCodecs->add();
    221             CodecNameAndQuirks *entry = &matchingCodecs->editItemAt(index);
    222             entry->mName = String8(componentName);
    223             entry->mQuirks = getComponentQuirks(list, matchIndex);
    224 
    225             ALOGV("matching '%s' quirks 0x%08x",
    226                   entry->mName.string(), entry->mQuirks);
    227         }
    228     }
    229 
    230     if (flags & kPreferSoftwareCodecs) {
    231         matchingCodecs->sort(CompareSoftwareCodecsFirst);
    232     }
    233 }
    234 
    235 // static
    236 uint32_t OMXCodec::getComponentQuirks(
    237         const MediaCodecList *list, size_t index) {
    238     uint32_t quirks = 0;
    239     if (list->codecHasQuirk(
    240                 index, "requires-allocate-on-input-ports")) {
    241         quirks |= kRequiresAllocateBufferOnInputPorts;
    242     }
    243     if (list->codecHasQuirk(
    244                 index, "requires-allocate-on-output-ports")) {
    245         quirks |= kRequiresAllocateBufferOnOutputPorts;
    246     }
    247     if (list->codecHasQuirk(
    248                 index, "output-buffers-are-unreadable")) {
    249         quirks |= kOutputBuffersAreUnreadable;
    250     }
    251 
    252     return quirks;
    253 }
    254 
    255 // static
    256 bool OMXCodec::findCodecQuirks(const char *componentName, uint32_t *quirks) {
    257     const MediaCodecList *list = MediaCodecList::getInstance();
    258 
    259     if (list == NULL) {
    260         return false;
    261     }
    262 
    263     ssize_t index = list->findCodecByName(componentName);
    264 
    265     if (index < 0) {
    266         return false;
    267     }
    268 
    269     *quirks = getComponentQuirks(list, index);
    270 
    271     return true;
    272 }
    273 
    274 // static
    275 sp<MediaSource> OMXCodec::Create(
    276         const sp<IOMX> &omx,
    277         const sp<MetaData> &meta, bool createEncoder,
    278         const sp<MediaSource> &source,
    279         const char *matchComponentName,
    280         uint32_t flags,
    281         const sp<ANativeWindow> &nativeWindow) {
    282     int32_t requiresSecureBuffers;
    283     if (source->getFormat()->findInt32(
    284                 kKeyRequiresSecureBuffers,
    285                 &requiresSecureBuffers)
    286             && requiresSecureBuffers) {
    287         flags |= kIgnoreCodecSpecificData;
    288         flags |= kUseSecureInputBuffers;
    289     }
    290 
    291     const char *mime;
    292     bool success = meta->findCString(kKeyMIMEType, &mime);
    293     CHECK(success);
    294 
    295     Vector<CodecNameAndQuirks> matchingCodecs;
    296     findMatchingCodecs(
    297             mime, createEncoder, matchComponentName, flags, &matchingCodecs);
    298 
    299     if (matchingCodecs.isEmpty()) {
    300         ALOGV("No matching codecs! (mime: %s, createEncoder: %s, "
    301                 "matchComponentName: %s, flags: 0x%x)",
    302                 mime, createEncoder ? "true" : "false", matchComponentName, flags);
    303         return NULL;
    304     }
    305 
    306     sp<OMXCodecObserver> observer = new OMXCodecObserver;
    307     IOMX::node_id node = 0;
    308 
    309     for (size_t i = 0; i < matchingCodecs.size(); ++i) {
    310         const char *componentNameBase = matchingCodecs[i].mName.string();
    311         uint32_t quirks = matchingCodecs[i].mQuirks;
    312         const char *componentName = componentNameBase;
    313 
    314         AString tmp;
    315         if (flags & kUseSecureInputBuffers) {
    316             tmp = componentNameBase;
    317             tmp.append(".secure");
    318 
    319             componentName = tmp.c_str();
    320         }
    321 
    322         if (createEncoder) {
    323             sp<MediaSource> softwareCodec =
    324                 InstantiateSoftwareEncoder(componentName, source, meta);
    325 
    326             if (softwareCodec != NULL) {
    327                 ALOGV("Successfully allocated software codec '%s'", componentName);
    328 
    329                 return softwareCodec;
    330             }
    331         }
    332 
    333         ALOGV("Attempting to allocate OMX node '%s'", componentName);
    334 
    335         if (!createEncoder
    336                 && (quirks & kOutputBuffersAreUnreadable)
    337                 && (flags & kClientNeedsFramebuffer)) {
    338             if (strncmp(componentName, "OMX.SEC.", 8)) {
    339                 // For OMX.SEC.* decoders we can enable a special mode that
    340                 // gives the client access to the framebuffer contents.
    341 
    342                 ALOGW("Component '%s' does not give the client access to "
    343                      "the framebuffer contents. Skipping.",
    344                      componentName);
    345 
    346                 continue;
    347             }
    348         }
    349 
    350         status_t err = omx->allocateNode(componentName, observer, &node);
    351         if (err == OK) {
    352             ALOGV("Successfully allocated OMX node '%s'", componentName);
    353 
    354             sp<OMXCodec> codec = new OMXCodec(
    355                     omx, node, quirks, flags,
    356                     createEncoder, mime, componentName,
    357                     source, nativeWindow);
    358 
    359             observer->setCodec(codec);
    360 
    361             err = codec->configureCodec(meta);
    362 
    363             if (err == OK) {
    364                 if (!strcmp("OMX.Nvidia.mpeg2v.decode", componentName)) {
    365                     codec->mFlags |= kOnlySubmitOneInputBufferAtOneTime;
    366                 }
    367 
    368                 return codec;
    369             }
    370 
    371             ALOGV("Failed to configure codec '%s'", componentName);
    372         }
    373     }
    374 
    375     return NULL;
    376 }
    377 
    378 status_t OMXCodec::parseAVCCodecSpecificData(
    379         const void *data, size_t size,
    380         unsigned *profile, unsigned *level) {
    381     const uint8_t *ptr = (const uint8_t *)data;
    382 
    383     // verify minimum size and configurationVersion == 1.
    384     if (size < 7 || ptr[0] != 1) {
    385         return ERROR_MALFORMED;
    386     }
    387 
    388     *profile = ptr[1];
    389     *level = ptr[3];
    390 
    391     // There is decodable content out there that fails the following
    392     // assertion, let's be lenient for now...
    393     // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
    394 
    395     size_t lengthSize = 1 + (ptr[4] & 3);
    396 
    397     // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
    398     // violates it...
    399     // CHECK((ptr[5] >> 5) == 7);  // reserved
    400 
    401     size_t numSeqParameterSets = ptr[5] & 31;
    402 
    403     ptr += 6;
    404     size -= 6;
    405 
    406     for (size_t i = 0; i < numSeqParameterSets; ++i) {
    407         if (size < 2) {
    408             return ERROR_MALFORMED;
    409         }
    410 
    411         size_t length = U16_AT(ptr);
    412 
    413         ptr += 2;
    414         size -= 2;
    415 
    416         if (size < length) {
    417             return ERROR_MALFORMED;
    418         }
    419 
    420         addCodecSpecificData(ptr, length);
    421 
    422         ptr += length;
    423         size -= length;
    424     }
    425 
    426     if (size < 1) {
    427         return ERROR_MALFORMED;
    428     }
    429 
    430     size_t numPictureParameterSets = *ptr;
    431     ++ptr;
    432     --size;
    433 
    434     for (size_t i = 0; i < numPictureParameterSets; ++i) {
    435         if (size < 2) {
    436             return ERROR_MALFORMED;
    437         }
    438 
    439         size_t length = U16_AT(ptr);
    440 
    441         ptr += 2;
    442         size -= 2;
    443 
    444         if (size < length) {
    445             return ERROR_MALFORMED;
    446         }
    447 
    448         addCodecSpecificData(ptr, length);
    449 
    450         ptr += length;
    451         size -= length;
    452     }
    453 
    454     return OK;
    455 }
    456 
    457 status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
    458     ALOGV("configureCodec protected=%d",
    459          (mFlags & kEnableGrallocUsageProtected) ? 1 : 0);
    460 
    461     if (!(mFlags & kIgnoreCodecSpecificData)) {
    462         uint32_t type;
    463         const void *data;
    464         size_t size;
    465         if (meta->findData(kKeyESDS, &type, &data, &size)) {
    466             ESDS esds((const char *)data, size);
    467             CHECK_EQ(esds.InitCheck(), (status_t)OK);
    468 
    469             const void *codec_specific_data;
    470             size_t codec_specific_data_size;
    471             esds.getCodecSpecificInfo(
    472                     &codec_specific_data, &codec_specific_data_size);
    473 
    474             addCodecSpecificData(
    475                     codec_specific_data, codec_specific_data_size);
    476         } else if (meta->findData(kKeyAVCC, &type, &data, &size)) {
    477             // Parse the AVCDecoderConfigurationRecord
    478 
    479             unsigned profile, level;
    480             status_t err;
    481             if ((err = parseAVCCodecSpecificData(
    482                             data, size, &profile, &level)) != OK) {
    483                 ALOGE("Malformed AVC codec specific data.");
    484                 return err;
    485             }
    486 
    487             CODEC_LOGI(
    488                     "AVC profile = %u (%s), level = %u",
    489                     profile, AVCProfileToString(profile), level);
    490         } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
    491             addCodecSpecificData(data, size);
    492 
    493             CHECK(meta->findData(kKeyVorbisBooks, &type, &data, &size));
    494             addCodecSpecificData(data, size);
    495         }
    496     }
    497 
    498     int32_t bitRate = 0;
    499     if (mIsEncoder) {
    500         CHECK(meta->findInt32(kKeyBitRate, &bitRate));
    501     }
    502     if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mMIME)) {
    503         setAMRFormat(false /* isWAMR */, bitRate);
    504     } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mMIME)) {
    505         setAMRFormat(true /* isWAMR */, bitRate);
    506     } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mMIME)) {
    507         int32_t numChannels, sampleRate, aacProfile;
    508         CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
    509         CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
    510 
    511         if (!meta->findInt32(kKeyAACProfile, &aacProfile)) {
    512             aacProfile = OMX_AUDIO_AACObjectNull;
    513         }
    514 
    515         int32_t isADTS;
    516         if (!meta->findInt32(kKeyIsADTS, &isADTS)) {
    517             isADTS = false;
    518         }
    519 
    520         status_t err = setAACFormat(numChannels, sampleRate, bitRate, aacProfile, isADTS);
    521         if (err != OK) {
    522             CODEC_LOGE("setAACFormat() failed (err = %d)", err);
    523             return err;
    524         }
    525     } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_MPEG, mMIME)) {
    526         int32_t numChannels, sampleRate;
    527         if (meta->findInt32(kKeyChannelCount, &numChannels)
    528                 && meta->findInt32(kKeySampleRate, &sampleRate)) {
    529             // Since we did not always check for these, leave them optional
    530             // and have the decoder figure it all out.
    531             setRawAudioFormat(
    532                     mIsEncoder ? kPortIndexInput : kPortIndexOutput,
    533                     sampleRate,
    534                     numChannels);
    535         }
    536     } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_ALAW, mMIME)
    537             || !strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_MLAW, mMIME)) {
    538         // These are PCM-like formats with a fixed sample rate but
    539         // a variable number of channels.
    540 
    541         int32_t numChannels;
    542         CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
    543 
    544         setG711Format(numChannels);
    545     } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, mMIME)) {
    546         CHECK(!mIsEncoder);
    547 
    548         int32_t numChannels, sampleRate;
    549         CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
    550         CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
    551 
    552         setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
    553     }
    554 
    555     if (!strncasecmp(mMIME, "video/", 6)) {
    556 
    557         if (mIsEncoder) {
    558             setVideoInputFormat(mMIME, meta);
    559         } else {
    560             status_t err = setVideoOutputFormat(
    561                     mMIME, meta);
    562 
    563             if (err != OK) {
    564                 return err;
    565             }
    566         }
    567     }
    568 
    569     int32_t maxInputSize;
    570     if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
    571         setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize);
    572     }
    573 
    574     initOutputFormat(meta);
    575 
    576     if ((mFlags & kClientNeedsFramebuffer)
    577             && !strncmp(mComponentName, "OMX.SEC.", 8)) {
    578         // This appears to no longer be needed???
    579 
    580         OMX_INDEXTYPE index;
    581 
    582         status_t err =
    583             mOMX->getExtensionIndex(
    584                     mNode,
    585                     "OMX.SEC.index.ThumbnailMode",
    586                     &index);
    587 
    588         if (err != OK) {
    589             return err;
    590         }
    591 
    592         OMX_BOOL enable = OMX_TRUE;
    593         err = mOMX->setConfig(mNode, index, &enable, sizeof(enable));
    594 
    595         if (err != OK) {
    596             CODEC_LOGE("setConfig('OMX.SEC.index.ThumbnailMode') "
    597                        "returned error 0x%08x", err);
    598 
    599             return err;
    600         }
    601 
    602         mQuirks &= ~kOutputBuffersAreUnreadable;
    603     }
    604 
    605     if (mNativeWindow != NULL
    606         && !mIsEncoder
    607         && !strncasecmp(mMIME, "video/", 6)
    608         && !strncmp(mComponentName, "OMX.", 4)) {
    609         status_t err = initNativeWindow();
    610         if (err != OK) {
    611             return err;
    612         }
    613     }
    614 
    615     return OK;
    616 }
    617 
    618 void OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) {
    619     OMX_PARAM_PORTDEFINITIONTYPE def;
    620     InitOMXParams(&def);
    621     def.nPortIndex = portIndex;
    622 
    623     status_t err = mOMX->getParameter(
    624             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    625     CHECK_EQ(err, (status_t)OK);
    626 
    627     if ((portIndex == kPortIndexInput && (mQuirks & kInputBufferSizesAreBogus))
    628         || (def.nBufferSize < size)) {
    629         def.nBufferSize = size;
    630     }
    631 
    632     err = mOMX->setParameter(
    633             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    634     CHECK_EQ(err, (status_t)OK);
    635 
    636     err = mOMX->getParameter(
    637             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    638     CHECK_EQ(err, (status_t)OK);
    639 
    640     // Make sure the setting actually stuck.
    641     if (portIndex == kPortIndexInput
    642             && (mQuirks & kInputBufferSizesAreBogus)) {
    643         CHECK_EQ(def.nBufferSize, size);
    644     } else {
    645         CHECK(def.nBufferSize >= size);
    646     }
    647 }
    648 
    649 status_t OMXCodec::setVideoPortFormatType(
    650         OMX_U32 portIndex,
    651         OMX_VIDEO_CODINGTYPE compressionFormat,
    652         OMX_COLOR_FORMATTYPE colorFormat) {
    653     OMX_VIDEO_PARAM_PORTFORMATTYPE format;
    654     InitOMXParams(&format);
    655     format.nPortIndex = portIndex;
    656     format.nIndex = 0;
    657     bool found = false;
    658 
    659     OMX_U32 index = 0;
    660     for (;;) {
    661         format.nIndex = index;
    662         status_t err = mOMX->getParameter(
    663                 mNode, OMX_IndexParamVideoPortFormat,
    664                 &format, sizeof(format));
    665 
    666         if (err != OK) {
    667             return err;
    668         }
    669 
    670         // The following assertion is violated by TI's video decoder.
    671         // CHECK_EQ(format.nIndex, index);
    672 
    673 #if 1
    674         CODEC_LOGV("portIndex: %ld, index: %ld, eCompressionFormat=%d eColorFormat=%d",
    675              portIndex,
    676              index, format.eCompressionFormat, format.eColorFormat);
    677 #endif
    678 
    679         if (format.eCompressionFormat == compressionFormat
    680                 && format.eColorFormat == colorFormat) {
    681             found = true;
    682             break;
    683         }
    684 
    685         ++index;
    686         if (index >= kMaxColorFormatSupported) {
    687             CODEC_LOGE("color format %d or compression format %d is not supported",
    688                 colorFormat, compressionFormat);
    689             return UNKNOWN_ERROR;
    690         }
    691     }
    692 
    693     if (!found) {
    694         return UNKNOWN_ERROR;
    695     }
    696 
    697     CODEC_LOGV("found a match.");
    698     status_t err = mOMX->setParameter(
    699             mNode, OMX_IndexParamVideoPortFormat,
    700             &format, sizeof(format));
    701 
    702     return err;
    703 }
    704 
    705 static size_t getFrameSize(
    706         OMX_COLOR_FORMATTYPE colorFormat, int32_t width, int32_t height) {
    707     switch (colorFormat) {
    708         case OMX_COLOR_FormatYCbYCr:
    709         case OMX_COLOR_FormatCbYCrY:
    710             return width * height * 2;
    711 
    712         case OMX_COLOR_FormatYUV420Planar:
    713         case OMX_COLOR_FormatYUV420SemiPlanar:
    714         case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
    715         /*
    716         * FIXME: For the Opaque color format, the frame size does not
    717         * need to be (w*h*3)/2. It just needs to
    718         * be larger than certain minimum buffer size. However,
    719         * currently, this opaque foramt has been tested only on
    720         * YUV420 formats. If that is changed, then we need to revisit
    721         * this part in the future
    722         */
    723         case OMX_COLOR_FormatAndroidOpaque:
    724             return (width * height * 3) / 2;
    725 
    726         default:
    727             CHECK(!"Should not be here. Unsupported color format.");
    728             break;
    729     }
    730 }
    731 
    732 status_t OMXCodec::findTargetColorFormat(
    733         const sp<MetaData>& meta, OMX_COLOR_FORMATTYPE *colorFormat) {
    734     ALOGV("findTargetColorFormat");
    735     CHECK(mIsEncoder);
    736 
    737     *colorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
    738     int32_t targetColorFormat;
    739     if (meta->findInt32(kKeyColorFormat, &targetColorFormat)) {
    740         *colorFormat = (OMX_COLOR_FORMATTYPE) targetColorFormat;
    741     }
    742 
    743     // Check whether the target color format is supported.
    744     return isColorFormatSupported(*colorFormat, kPortIndexInput);
    745 }
    746 
    747 status_t OMXCodec::isColorFormatSupported(
    748         OMX_COLOR_FORMATTYPE colorFormat, int portIndex) {
    749     ALOGV("isColorFormatSupported: %d", static_cast<int>(colorFormat));
    750 
    751     // Enumerate all the color formats supported by
    752     // the omx component to see whether the given
    753     // color format is supported.
    754     OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
    755     InitOMXParams(&portFormat);
    756     portFormat.nPortIndex = portIndex;
    757     OMX_U32 index = 0;
    758     portFormat.nIndex = index;
    759     while (true) {
    760         if (OMX_ErrorNone != mOMX->getParameter(
    761                 mNode, OMX_IndexParamVideoPortFormat,
    762                 &portFormat, sizeof(portFormat))) {
    763             break;
    764         }
    765         // Make sure that omx component does not overwrite
    766         // the incremented index (bug 2897413).
    767         CHECK_EQ(index, portFormat.nIndex);
    768         if (portFormat.eColorFormat == colorFormat) {
    769             CODEC_LOGV("Found supported color format: %d", portFormat.eColorFormat);
    770             return OK;  // colorFormat is supported!
    771         }
    772         ++index;
    773         portFormat.nIndex = index;
    774 
    775         if (index >= kMaxColorFormatSupported) {
    776             CODEC_LOGE("More than %ld color formats are supported???", index);
    777             break;
    778         }
    779     }
    780 
    781     CODEC_LOGE("color format %d is not supported", colorFormat);
    782     return UNKNOWN_ERROR;
    783 }
    784 
    785 void OMXCodec::setVideoInputFormat(
    786         const char *mime, const sp<MetaData>& meta) {
    787 
    788     int32_t width, height, frameRate, bitRate, stride, sliceHeight;
    789     bool success = meta->findInt32(kKeyWidth, &width);
    790     success = success && meta->findInt32(kKeyHeight, &height);
    791     success = success && meta->findInt32(kKeyFrameRate, &frameRate);
    792     success = success && meta->findInt32(kKeyBitRate, &bitRate);
    793     success = success && meta->findInt32(kKeyStride, &stride);
    794     success = success && meta->findInt32(kKeySliceHeight, &sliceHeight);
    795     CHECK(success);
    796     CHECK(stride != 0);
    797 
    798     OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
    799     if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
    800         compressionFormat = OMX_VIDEO_CodingAVC;
    801     } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
    802         compressionFormat = OMX_VIDEO_CodingMPEG4;
    803     } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
    804         compressionFormat = OMX_VIDEO_CodingH263;
    805     } else {
    806         ALOGE("Not a supported video mime type: %s", mime);
    807         CHECK(!"Should not be here. Not a supported video mime type.");
    808     }
    809 
    810     OMX_COLOR_FORMATTYPE colorFormat;
    811     CHECK_EQ((status_t)OK, findTargetColorFormat(meta, &colorFormat));
    812 
    813     status_t err;
    814     OMX_PARAM_PORTDEFINITIONTYPE def;
    815     OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
    816 
    817     //////////////////////// Input port /////////////////////////
    818     CHECK_EQ(setVideoPortFormatType(
    819             kPortIndexInput, OMX_VIDEO_CodingUnused,
    820             colorFormat), (status_t)OK);
    821 
    822     InitOMXParams(&def);
    823     def.nPortIndex = kPortIndexInput;
    824 
    825     err = mOMX->getParameter(
    826             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    827     CHECK_EQ(err, (status_t)OK);
    828 
    829     def.nBufferSize = getFrameSize(colorFormat,
    830             stride > 0? stride: -stride, sliceHeight);
    831 
    832     CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
    833 
    834     video_def->nFrameWidth = width;
    835     video_def->nFrameHeight = height;
    836     video_def->nStride = stride;
    837     video_def->nSliceHeight = sliceHeight;
    838     video_def->xFramerate = (frameRate << 16);  // Q16 format
    839     video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
    840     video_def->eColorFormat = colorFormat;
    841 
    842     err = mOMX->setParameter(
    843             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    844     CHECK_EQ(err, (status_t)OK);
    845 
    846     //////////////////////// Output port /////////////////////////
    847     CHECK_EQ(setVideoPortFormatType(
    848             kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused),
    849             (status_t)OK);
    850     InitOMXParams(&def);
    851     def.nPortIndex = kPortIndexOutput;
    852 
    853     err = mOMX->getParameter(
    854             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    855 
    856     CHECK_EQ(err, (status_t)OK);
    857     CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
    858 
    859     video_def->nFrameWidth = width;
    860     video_def->nFrameHeight = height;
    861     video_def->xFramerate = 0;      // No need for output port
    862     video_def->nBitrate = bitRate;  // Q16 format
    863     video_def->eCompressionFormat = compressionFormat;
    864     video_def->eColorFormat = OMX_COLOR_FormatUnused;
    865     if (mQuirks & kRequiresLargerEncoderOutputBuffer) {
    866         // Increases the output buffer size
    867         def.nBufferSize = ((def.nBufferSize * 3) >> 1);
    868     }
    869 
    870     err = mOMX->setParameter(
    871             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    872     CHECK_EQ(err, (status_t)OK);
    873 
    874     /////////////////// Codec-specific ////////////////////////
    875     switch (compressionFormat) {
    876         case OMX_VIDEO_CodingMPEG4:
    877         {
    878             CHECK_EQ(setupMPEG4EncoderParameters(meta), (status_t)OK);
    879             break;
    880         }
    881 
    882         case OMX_VIDEO_CodingH263:
    883             CHECK_EQ(setupH263EncoderParameters(meta), (status_t)OK);
    884             break;
    885 
    886         case OMX_VIDEO_CodingAVC:
    887         {
    888             CHECK_EQ(setupAVCEncoderParameters(meta), (status_t)OK);
    889             break;
    890         }
    891 
    892         default:
    893             CHECK(!"Support for this compressionFormat to be implemented.");
    894             break;
    895     }
    896 }
    897 
    898 static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
    899     if (iFramesInterval < 0) {
    900         return 0xFFFFFFFF;
    901     } else if (iFramesInterval == 0) {
    902         return 0;
    903     }
    904     OMX_U32 ret = frameRate * iFramesInterval - 1;
    905     CHECK(ret > 1);
    906     return ret;
    907 }
    908 
    909 status_t OMXCodec::setupErrorCorrectionParameters() {
    910     OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
    911     InitOMXParams(&errorCorrectionType);
    912     errorCorrectionType.nPortIndex = kPortIndexOutput;
    913 
    914     status_t err = mOMX->getParameter(
    915             mNode, OMX_IndexParamVideoErrorCorrection,
    916             &errorCorrectionType, sizeof(errorCorrectionType));
    917     if (err != OK) {
    918         ALOGW("Error correction param query is not supported");
    919         return OK;  // Optional feature. Ignore this failure
    920     }
    921 
    922     errorCorrectionType.bEnableHEC = OMX_FALSE;
    923     errorCorrectionType.bEnableResync = OMX_TRUE;
    924     errorCorrectionType.nResynchMarkerSpacing = 256;
    925     errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
    926     errorCorrectionType.bEnableRVLC = OMX_FALSE;
    927 
    928     err = mOMX->setParameter(
    929             mNode, OMX_IndexParamVideoErrorCorrection,
    930             &errorCorrectionType, sizeof(errorCorrectionType));
    931     if (err != OK) {
    932         ALOGW("Error correction param configuration is not supported");
    933     }
    934 
    935     // Optional feature. Ignore the failure.
    936     return OK;
    937 }
    938 
    939 status_t OMXCodec::setupBitRate(int32_t bitRate) {
    940     OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
    941     InitOMXParams(&bitrateType);
    942     bitrateType.nPortIndex = kPortIndexOutput;
    943 
    944     status_t err = mOMX->getParameter(
    945             mNode, OMX_IndexParamVideoBitrate,
    946             &bitrateType, sizeof(bitrateType));
    947     CHECK_EQ(err, (status_t)OK);
    948 
    949     bitrateType.eControlRate = OMX_Video_ControlRateVariable;
    950     bitrateType.nTargetBitrate = bitRate;
    951 
    952     err = mOMX->setParameter(
    953             mNode, OMX_IndexParamVideoBitrate,
    954             &bitrateType, sizeof(bitrateType));
    955     CHECK_EQ(err, (status_t)OK);
    956     return OK;
    957 }
    958 
    959 status_t OMXCodec::getVideoProfileLevel(
    960         const sp<MetaData>& meta,
    961         const CodecProfileLevel& defaultProfileLevel,
    962         CodecProfileLevel &profileLevel) {
    963     CODEC_LOGV("Default profile: %ld, level %ld",
    964             defaultProfileLevel.mProfile, defaultProfileLevel.mLevel);
    965 
    966     // Are the default profile and level overwriten?
    967     int32_t profile, level;
    968     if (!meta->findInt32(kKeyVideoProfile, &profile)) {
    969         profile = defaultProfileLevel.mProfile;
    970     }
    971     if (!meta->findInt32(kKeyVideoLevel, &level)) {
    972         level = defaultProfileLevel.mLevel;
    973     }
    974     CODEC_LOGV("Target profile: %d, level: %d", profile, level);
    975 
    976     // Are the target profile and level supported by the encoder?
    977     OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
    978     InitOMXParams(&param);
    979     param.nPortIndex = kPortIndexOutput;
    980     for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
    981         status_t err = mOMX->getParameter(
    982                 mNode, OMX_IndexParamVideoProfileLevelQuerySupported,
    983                 &param, sizeof(param));
    984 
    985         if (err != OK) break;
    986 
    987         int32_t supportedProfile = static_cast<int32_t>(param.eProfile);
    988         int32_t supportedLevel = static_cast<int32_t>(param.eLevel);
    989         CODEC_LOGV("Supported profile: %d, level %d",
    990             supportedProfile, supportedLevel);
    991 
    992         if (profile == supportedProfile &&
    993             level <= supportedLevel) {
    994             // We can further check whether the level is a valid
    995             // value; but we will leave that to the omx encoder component
    996             // via OMX_SetParameter call.
    997             profileLevel.mProfile = profile;
    998             profileLevel.mLevel = level;
    999             return OK;
   1000         }
   1001     }
   1002 
   1003     CODEC_LOGE("Target profile (%d) and level (%d) is not supported",
   1004             profile, level);
   1005     return BAD_VALUE;
   1006 }
   1007 
   1008 status_t OMXCodec::setupH263EncoderParameters(const sp<MetaData>& meta) {
   1009     int32_t iFramesInterval, frameRate, bitRate;
   1010     bool success = meta->findInt32(kKeyBitRate, &bitRate);
   1011     success = success && meta->findInt32(kKeyFrameRate, &frameRate);
   1012     success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
   1013     CHECK(success);
   1014     OMX_VIDEO_PARAM_H263TYPE h263type;
   1015     InitOMXParams(&h263type);
   1016     h263type.nPortIndex = kPortIndexOutput;
   1017 
   1018     status_t err = mOMX->getParameter(
   1019             mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
   1020     CHECK_EQ(err, (status_t)OK);
   1021 
   1022     h263type.nAllowedPictureTypes =
   1023         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
   1024 
   1025     h263type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
   1026     if (h263type.nPFrames == 0) {
   1027         h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
   1028     }
   1029     h263type.nBFrames = 0;
   1030 
   1031     // Check profile and level parameters
   1032     CodecProfileLevel defaultProfileLevel, profileLevel;
   1033     defaultProfileLevel.mProfile = h263type.eProfile;
   1034     defaultProfileLevel.mLevel = h263type.eLevel;
   1035     err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel);
   1036     if (err != OK) return err;
   1037     h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profileLevel.mProfile);
   1038     h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(profileLevel.mLevel);
   1039 
   1040     h263type.bPLUSPTYPEAllowed = OMX_FALSE;
   1041     h263type.bForceRoundingTypeToZero = OMX_FALSE;
   1042     h263type.nPictureHeaderRepetition = 0;
   1043     h263type.nGOBHeaderInterval = 0;
   1044 
   1045     err = mOMX->setParameter(
   1046             mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
   1047     CHECK_EQ(err, (status_t)OK);
   1048 
   1049     CHECK_EQ(setupBitRate(bitRate), (status_t)OK);
   1050     CHECK_EQ(setupErrorCorrectionParameters(), (status_t)OK);
   1051 
   1052     return OK;
   1053 }
   1054 
   1055 status_t OMXCodec::setupMPEG4EncoderParameters(const sp<MetaData>& meta) {
   1056     int32_t iFramesInterval, frameRate, bitRate;
   1057     bool success = meta->findInt32(kKeyBitRate, &bitRate);
   1058     success = success && meta->findInt32(kKeyFrameRate, &frameRate);
   1059     success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
   1060     CHECK(success);
   1061     OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
   1062     InitOMXParams(&mpeg4type);
   1063     mpeg4type.nPortIndex = kPortIndexOutput;
   1064 
   1065     status_t err = mOMX->getParameter(
   1066             mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
   1067     CHECK_EQ(err, (status_t)OK);
   1068 
   1069     mpeg4type.nSliceHeaderSpacing = 0;
   1070     mpeg4type.bSVH = OMX_FALSE;
   1071     mpeg4type.bGov = OMX_FALSE;
   1072 
   1073     mpeg4type.nAllowedPictureTypes =
   1074         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
   1075 
   1076     mpeg4type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
   1077     if (mpeg4type.nPFrames == 0) {
   1078         mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
   1079     }
   1080     mpeg4type.nBFrames = 0;
   1081     mpeg4type.nIDCVLCThreshold = 0;
   1082     mpeg4type.bACPred = OMX_TRUE;
   1083     mpeg4type.nMaxPacketSize = 256;
   1084     mpeg4type.nTimeIncRes = 1000;
   1085     mpeg4type.nHeaderExtension = 0;
   1086     mpeg4type.bReversibleVLC = OMX_FALSE;
   1087 
   1088     // Check profile and level parameters
   1089     CodecProfileLevel defaultProfileLevel, profileLevel;
   1090     defaultProfileLevel.mProfile = mpeg4type.eProfile;
   1091     defaultProfileLevel.mLevel = mpeg4type.eLevel;
   1092     err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel);
   1093     if (err != OK) return err;
   1094     mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profileLevel.mProfile);
   1095     mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(profileLevel.mLevel);
   1096 
   1097     err = mOMX->setParameter(
   1098             mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
   1099     CHECK_EQ(err, (status_t)OK);
   1100 
   1101     CHECK_EQ(setupBitRate(bitRate), (status_t)OK);
   1102     CHECK_EQ(setupErrorCorrectionParameters(), (status_t)OK);
   1103 
   1104     return OK;
   1105 }
   1106 
   1107 status_t OMXCodec::setupAVCEncoderParameters(const sp<MetaData>& meta) {
   1108     int32_t iFramesInterval, frameRate, bitRate;
   1109     bool success = meta->findInt32(kKeyBitRate, &bitRate);
   1110     success = success && meta->findInt32(kKeyFrameRate, &frameRate);
   1111     success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
   1112     CHECK(success);
   1113 
   1114     OMX_VIDEO_PARAM_AVCTYPE h264type;
   1115     InitOMXParams(&h264type);
   1116     h264type.nPortIndex = kPortIndexOutput;
   1117 
   1118     status_t err = mOMX->getParameter(
   1119             mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
   1120     CHECK_EQ(err, (status_t)OK);
   1121 
   1122     h264type.nAllowedPictureTypes =
   1123         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
   1124 
   1125     // Check profile and level parameters
   1126     CodecProfileLevel defaultProfileLevel, profileLevel;
   1127     defaultProfileLevel.mProfile = h264type.eProfile;
   1128     defaultProfileLevel.mLevel = h264type.eLevel;
   1129     err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel);
   1130     if (err != OK) return err;
   1131     h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profileLevel.mProfile);
   1132     h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(profileLevel.mLevel);
   1133 
   1134     // XXX
   1135     if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
   1136         ALOGW("Use baseline profile instead of %d for AVC recording",
   1137             h264type.eProfile);
   1138         h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
   1139     }
   1140 
   1141     if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
   1142         h264type.nSliceHeaderSpacing = 0;
   1143         h264type.bUseHadamard = OMX_TRUE;
   1144         h264type.nRefFrames = 1;
   1145         h264type.nBFrames = 0;
   1146         h264type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
   1147         if (h264type.nPFrames == 0) {
   1148             h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
   1149         }
   1150         h264type.nRefIdx10ActiveMinus1 = 0;
   1151         h264type.nRefIdx11ActiveMinus1 = 0;
   1152         h264type.bEntropyCodingCABAC = OMX_FALSE;
   1153         h264type.bWeightedPPrediction = OMX_FALSE;
   1154         h264type.bconstIpred = OMX_FALSE;
   1155         h264type.bDirect8x8Inference = OMX_FALSE;
   1156         h264type.bDirectSpatialTemporal = OMX_FALSE;
   1157         h264type.nCabacInitIdc = 0;
   1158     }
   1159 
   1160     if (h264type.nBFrames != 0) {
   1161         h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
   1162     }
   1163 
   1164     h264type.bEnableUEP = OMX_FALSE;
   1165     h264type.bEnableFMO = OMX_FALSE;
   1166     h264type.bEnableASO = OMX_FALSE;
   1167     h264type.bEnableRS = OMX_FALSE;
   1168     h264type.bFrameMBsOnly = OMX_TRUE;
   1169     h264type.bMBAFF = OMX_FALSE;
   1170     h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
   1171 
   1172     err = mOMX->setParameter(
   1173             mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
   1174     CHECK_EQ(err, (status_t)OK);
   1175 
   1176     CHECK_EQ(setupBitRate(bitRate), (status_t)OK);
   1177 
   1178     return OK;
   1179 }
   1180 
   1181 status_t OMXCodec::setVideoOutputFormat(
   1182         const char *mime, const sp<MetaData>& meta) {
   1183 
   1184     int32_t width, height;
   1185     bool success = meta->findInt32(kKeyWidth, &width);
   1186     success = success && meta->findInt32(kKeyHeight, &height);
   1187     CHECK(success);
   1188 
   1189     CODEC_LOGV("setVideoOutputFormat width=%ld, height=%ld", width, height);
   1190 
   1191     OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
   1192     if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
   1193         compressionFormat = OMX_VIDEO_CodingAVC;
   1194     } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
   1195         compressionFormat = OMX_VIDEO_CodingMPEG4;
   1196     } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
   1197         compressionFormat = OMX_VIDEO_CodingH263;
   1198     } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VPX, mime)) {
   1199         compressionFormat = OMX_VIDEO_CodingVPX;
   1200     } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG2, mime)) {
   1201         compressionFormat = OMX_VIDEO_CodingMPEG2;
   1202     } else {
   1203         ALOGE("Not a supported video mime type: %s", mime);
   1204         CHECK(!"Should not be here. Not a supported video mime type.");
   1205     }
   1206 
   1207     status_t err = setVideoPortFormatType(
   1208             kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
   1209 
   1210     if (err != OK) {
   1211         return err;
   1212     }
   1213 
   1214 #if 1
   1215     {
   1216         OMX_VIDEO_PARAM_PORTFORMATTYPE format;
   1217         InitOMXParams(&format);
   1218         format.nPortIndex = kPortIndexOutput;
   1219         format.nIndex = 0;
   1220 
   1221         status_t err = mOMX->getParameter(
   1222                 mNode, OMX_IndexParamVideoPortFormat,
   1223                 &format, sizeof(format));
   1224         CHECK_EQ(err, (status_t)OK);
   1225         CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
   1226 
   1227         int32_t colorFormat;
   1228         if (meta->findInt32(kKeyColorFormat, &colorFormat)
   1229                 && colorFormat != OMX_COLOR_FormatUnused
   1230                 && colorFormat != format.eColorFormat) {
   1231 
   1232             while (OMX_ErrorNoMore != err) {
   1233                 format.nIndex++;
   1234                 err = mOMX->getParameter(
   1235                         mNode, OMX_IndexParamVideoPortFormat,
   1236                             &format, sizeof(format));
   1237                 if (format.eColorFormat == colorFormat) {
   1238                     break;
   1239                 }
   1240             }
   1241             if (format.eColorFormat != colorFormat) {
   1242                 CODEC_LOGE("Color format %d is not supported", colorFormat);
   1243                 return ERROR_UNSUPPORTED;
   1244             }
   1245         }
   1246 
   1247         err = mOMX->setParameter(
   1248                 mNode, OMX_IndexParamVideoPortFormat,
   1249                 &format, sizeof(format));
   1250 
   1251         if (err != OK) {
   1252             return err;
   1253         }
   1254     }
   1255 #endif
   1256 
   1257     OMX_PARAM_PORTDEFINITIONTYPE def;
   1258     InitOMXParams(&def);
   1259     def.nPortIndex = kPortIndexInput;
   1260 
   1261     OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
   1262 
   1263     err = mOMX->getParameter(
   1264             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   1265 
   1266     CHECK_EQ(err, (status_t)OK);
   1267 
   1268 #if 1
   1269     // XXX Need a (much) better heuristic to compute input buffer sizes.
   1270     const size_t X = 64 * 1024;
   1271     if (def.nBufferSize < X) {
   1272         def.nBufferSize = X;
   1273     }
   1274 #endif
   1275 
   1276     CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
   1277 
   1278     video_def->nFrameWidth = width;
   1279     video_def->nFrameHeight = height;
   1280 
   1281     video_def->eCompressionFormat = compressionFormat;
   1282     video_def->eColorFormat = OMX_COLOR_FormatUnused;
   1283 
   1284     err = mOMX->setParameter(
   1285             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   1286 
   1287     if (err != OK) {
   1288         return err;
   1289     }
   1290 
   1291     ////////////////////////////////////////////////////////////////////////////
   1292 
   1293     InitOMXParams(&def);
   1294     def.nPortIndex = kPortIndexOutput;
   1295 
   1296     err = mOMX->getParameter(
   1297             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   1298     CHECK_EQ(err, (status_t)OK);
   1299     CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
   1300 
   1301 #if 0
   1302     def.nBufferSize =
   1303         (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2;  // YUV420
   1304 #endif
   1305 
   1306     video_def->nFrameWidth = width;
   1307     video_def->nFrameHeight = height;
   1308 
   1309     err = mOMX->setParameter(
   1310             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   1311 
   1312     return err;
   1313 }
   1314 
   1315 OMXCodec::OMXCodec(
   1316         const sp<IOMX> &omx, IOMX::node_id node,
   1317         uint32_t quirks, uint32_t flags,
   1318         bool isEncoder,
   1319         const char *mime,
   1320         const char *componentName,
   1321         const sp<MediaSource> &source,
   1322         const sp<ANativeWindow> &nativeWindow)
   1323     : mOMX(omx),
   1324       mOMXLivesLocally(omx->livesLocally(node, getpid())),
   1325       mNode(node),
   1326       mQuirks(quirks),
   1327       mFlags(flags),
   1328       mIsEncoder(isEncoder),
   1329       mIsVideo(!strncasecmp("video/", mime, 6)),
   1330       mMIME(strdup(mime)),
   1331       mComponentName(strdup(componentName)),
   1332       mSource(source),
   1333       mCodecSpecificDataIndex(0),
   1334       mState(LOADED),
   1335       mInitialBufferSubmit(true),
   1336       mSignalledEOS(false),
   1337       mNoMoreOutputData(false),
   1338       mOutputPortSettingsHaveChanged(false),
   1339       mSeekTimeUs(-1),
   1340       mSeekMode(ReadOptions::SEEK_CLOSEST_SYNC),
   1341       mTargetTimeUs(-1),
   1342       mOutputPortSettingsChangedPending(false),
   1343       mSkipCutBuffer(NULL),
   1344       mLeftOverBuffer(NULL),
   1345       mPaused(false),
   1346       mNativeWindow(
   1347               (!strncmp(componentName, "OMX.google.", 11)
   1348               || !strcmp(componentName, "OMX.Nvidia.mpeg2v.decode"))
   1349                         ? NULL : nativeWindow) {
   1350     mPortStatus[kPortIndexInput] = ENABLED;
   1351     mPortStatus[kPortIndexOutput] = ENABLED;
   1352 
   1353     setComponentRole();
   1354 }
   1355 
   1356 // static
   1357 void OMXCodec::setComponentRole(
   1358         const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder,
   1359         const char *mime) {
   1360     struct MimeToRole {
   1361         const char *mime;
   1362         const char *decoderRole;
   1363         const char *encoderRole;
   1364     };
   1365 
   1366     static const MimeToRole kMimeToRole[] = {
   1367         { MEDIA_MIMETYPE_AUDIO_MPEG,
   1368             "audio_decoder.mp3", "audio_encoder.mp3" },
   1369         { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
   1370             "audio_decoder.mp1", "audio_encoder.mp1" },
   1371         { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
   1372             "audio_decoder.mp2", "audio_encoder.mp2" },
   1373         { MEDIA_MIMETYPE_AUDIO_AMR_NB,
   1374             "audio_decoder.amrnb", "audio_encoder.amrnb" },
   1375         { MEDIA_MIMETYPE_AUDIO_AMR_WB,
   1376             "audio_decoder.amrwb", "audio_encoder.amrwb" },
   1377         { MEDIA_MIMETYPE_AUDIO_AAC,
   1378             "audio_decoder.aac", "audio_encoder.aac" },
   1379         { MEDIA_MIMETYPE_AUDIO_VORBIS,
   1380             "audio_decoder.vorbis", "audio_encoder.vorbis" },
   1381         { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
   1382             "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
   1383         { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
   1384             "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
   1385         { MEDIA_MIMETYPE_VIDEO_AVC,
   1386             "video_decoder.avc", "video_encoder.avc" },
   1387         { MEDIA_MIMETYPE_VIDEO_MPEG4,
   1388             "video_decoder.mpeg4", "video_encoder.mpeg4" },
   1389         { MEDIA_MIMETYPE_VIDEO_H263,
   1390             "video_decoder.h263", "video_encoder.h263" },
   1391         { MEDIA_MIMETYPE_VIDEO_VPX,
   1392             "video_decoder.vpx", "video_encoder.vpx" },
   1393         { MEDIA_MIMETYPE_AUDIO_RAW,
   1394             "audio_decoder.raw", "audio_encoder.raw" },
   1395         { MEDIA_MIMETYPE_AUDIO_FLAC,
   1396             "audio_decoder.flac", "audio_encoder.flac" },
   1397         { MEDIA_MIMETYPE_AUDIO_MSGSM,
   1398             "audio_decoder.gsm", "audio_encoder.gsm" },
   1399     };
   1400 
   1401     static const size_t kNumMimeToRole =
   1402         sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
   1403 
   1404     size_t i;
   1405     for (i = 0; i < kNumMimeToRole; ++i) {
   1406         if (!strcasecmp(mime, kMimeToRole[i].mime)) {
   1407             break;
   1408         }
   1409     }
   1410 
   1411     if (i == kNumMimeToRole) {
   1412         return;
   1413     }
   1414 
   1415     const char *role =
   1416         isEncoder ? kMimeToRole[i].encoderRole
   1417                   : kMimeToRole[i].decoderRole;
   1418 
   1419     if (role != NULL) {
   1420         OMX_PARAM_COMPONENTROLETYPE roleParams;
   1421         InitOMXParams(&roleParams);
   1422 
   1423         strncpy((char *)roleParams.cRole,
   1424                 role, OMX_MAX_STRINGNAME_SIZE - 1);
   1425 
   1426         roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
   1427 
   1428         status_t err = omx->setParameter(
   1429                 node, OMX_IndexParamStandardComponentRole,
   1430                 &roleParams, sizeof(roleParams));
   1431 
   1432         if (err != OK) {
   1433             ALOGW("Failed to set standard component role '%s'.", role);
   1434         }
   1435     }
   1436 }
   1437 
   1438 void OMXCodec::setComponentRole() {
   1439     setComponentRole(mOMX, mNode, mIsEncoder, mMIME);
   1440 }
   1441 
   1442 OMXCodec::~OMXCodec() {
   1443     mSource.clear();
   1444 
   1445     CHECK(mState == LOADED || mState == ERROR || mState == LOADED_TO_IDLE);
   1446 
   1447     status_t err = mOMX->freeNode(mNode);
   1448     CHECK_EQ(err, (status_t)OK);
   1449 
   1450     mNode = NULL;
   1451     setState(DEAD);
   1452 
   1453     clearCodecSpecificData();
   1454 
   1455     free(mComponentName);
   1456     mComponentName = NULL;
   1457 
   1458     free(mMIME);
   1459     mMIME = NULL;
   1460 }
   1461 
   1462 status_t OMXCodec::init() {
   1463     // mLock is held.
   1464 
   1465     CHECK_EQ((int)mState, (int)LOADED);
   1466 
   1467     status_t err;
   1468     if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) {
   1469         err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
   1470         CHECK_EQ(err, (status_t)OK);
   1471         setState(LOADED_TO_IDLE);
   1472     }
   1473 
   1474     err = allocateBuffers();
   1475     if (err != (status_t)OK) {
   1476         return err;
   1477     }
   1478 
   1479     if (mQuirks & kRequiresLoadedToIdleAfterAllocation) {
   1480         err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
   1481         CHECK_EQ(err, (status_t)OK);
   1482 
   1483         setState(LOADED_TO_IDLE);
   1484     }
   1485 
   1486     while (mState != EXECUTING && mState != ERROR) {
   1487         mAsyncCompletion.wait(mLock);
   1488     }
   1489 
   1490     return mState == ERROR ? UNKNOWN_ERROR : OK;
   1491 }
   1492 
   1493 // static
   1494 bool OMXCodec::isIntermediateState(State state) {
   1495     return state == LOADED_TO_IDLE
   1496         || state == IDLE_TO_EXECUTING
   1497         || state == EXECUTING_TO_IDLE
   1498         || state == IDLE_TO_LOADED
   1499         || state == RECONFIGURING;
   1500 }
   1501 
   1502 status_t OMXCodec::allocateBuffers() {
   1503     status_t err = allocateBuffersOnPort(kPortIndexInput);
   1504 
   1505     if (err != OK) {
   1506         return err;
   1507     }
   1508 
   1509     return allocateBuffersOnPort(kPortIndexOutput);
   1510 }
   1511 
   1512 status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
   1513     if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
   1514         return allocateOutputBuffersFromNativeWindow();
   1515     }
   1516 
   1517     if ((mFlags & kEnableGrallocUsageProtected) && portIndex == kPortIndexOutput) {
   1518         ALOGE("protected output buffers must be stent to an ANativeWindow");
   1519         return PERMISSION_DENIED;
   1520     }
   1521 
   1522     status_t err = OK;
   1523     if ((mFlags & kStoreMetaDataInVideoBuffers)
   1524             && portIndex == kPortIndexInput) {
   1525         err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
   1526         if (err != OK) {
   1527             ALOGE("Storing meta data in video buffers is not supported");
   1528             return err;
   1529         }
   1530     }
   1531 
   1532     OMX_PARAM_PORTDEFINITIONTYPE def;
   1533     InitOMXParams(&def);
   1534     def.nPortIndex = portIndex;
   1535 
   1536     err = mOMX->getParameter(
   1537             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   1538 
   1539     if (err != OK) {
   1540         return err;
   1541     }
   1542 
   1543     CODEC_LOGV("allocating %lu buffers of size %lu on %s port",
   1544             def.nBufferCountActual, def.nBufferSize,
   1545             portIndex == kPortIndexInput ? "input" : "output");
   1546 
   1547     size_t totalSize = def.nBufferCountActual * def.nBufferSize;
   1548     mDealer[portIndex] = new MemoryDealer(totalSize, "OMXCodec");
   1549 
   1550     for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
   1551         sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
   1552         CHECK(mem.get() != NULL);
   1553 
   1554         BufferInfo info;
   1555         info.mData = NULL;
   1556         info.mSize = def.nBufferSize;
   1557 
   1558         IOMX::buffer_id buffer;
   1559         if (portIndex == kPortIndexInput
   1560                 && ((mQuirks & kRequiresAllocateBufferOnInputPorts)
   1561                     || (mFlags & kUseSecureInputBuffers))) {
   1562             if (mOMXLivesLocally) {
   1563                 mem.clear();
   1564 
   1565                 err = mOMX->allocateBuffer(
   1566                         mNode, portIndex, def.nBufferSize, &buffer,
   1567                         &info.mData);
   1568             } else {
   1569                 err = mOMX->allocateBufferWithBackup(
   1570                         mNode, portIndex, mem, &buffer);
   1571             }
   1572         } else if (portIndex == kPortIndexOutput
   1573                 && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) {
   1574             if (mOMXLivesLocally) {
   1575                 mem.clear();
   1576 
   1577                 err = mOMX->allocateBuffer(
   1578                         mNode, portIndex, def.nBufferSize, &buffer,
   1579                         &info.mData);
   1580             } else {
   1581                 err = mOMX->allocateBufferWithBackup(
   1582                         mNode, portIndex, mem, &buffer);
   1583             }
   1584         } else {
   1585             err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
   1586         }
   1587 
   1588         if (err != OK) {
   1589             ALOGE("allocate_buffer_with_backup failed");
   1590             return err;
   1591         }
   1592 
   1593         if (mem != NULL) {
   1594             info.mData = mem->pointer();
   1595         }
   1596 
   1597         info.mBuffer = buffer;
   1598         info.mStatus = OWNED_BY_US;
   1599         info.mMem = mem;
   1600         info.mMediaBuffer = NULL;
   1601 
   1602         if (portIndex == kPortIndexOutput) {
   1603             if (!(mOMXLivesLocally
   1604                         && (mQuirks & kRequiresAllocateBufferOnOutputPorts)
   1605                         && (mQuirks & kDefersOutputBufferAllocation))) {
   1606                 // If the node does not fill in the buffer ptr at this time,
   1607                 // we will defer creating the MediaBuffer until receiving
   1608                 // the first FILL_BUFFER_DONE notification instead.
   1609                 info.mMediaBuffer = new MediaBuffer(info.mData, info.mSize);
   1610                 info.mMediaBuffer->setObserver(this);
   1611             }
   1612         }
   1613 
   1614         mPortBuffers[portIndex].push(info);
   1615 
   1616         CODEC_LOGV("allocated buffer %p on %s port", buffer,
   1617              portIndex == kPortIndexInput ? "input" : "output");
   1618     }
   1619 
   1620     if (portIndex == kPortIndexOutput) {
   1621 
   1622         sp<MetaData> meta = mSource->getFormat();
   1623         int32_t delay = 0;
   1624         if (!meta->findInt32(kKeyEncoderDelay, &delay)) {
   1625             delay = 0;
   1626         }
   1627         int32_t padding = 0;
   1628         if (!meta->findInt32(kKeyEncoderPadding, &padding)) {
   1629             padding = 0;
   1630         }
   1631         int32_t numchannels = 0;
   1632         if (delay + padding) {
   1633             if (mOutputFormat->findInt32(kKeyChannelCount, &numchannels)) {
   1634                 size_t frameSize = numchannels * sizeof(int16_t);
   1635                 if (mSkipCutBuffer != NULL) {
   1636                     size_t prevbuffersize = mSkipCutBuffer->size();
   1637                     if (prevbuffersize != 0) {
   1638                         ALOGW("Replacing SkipCutBuffer holding %d bytes", prevbuffersize);
   1639                     }
   1640                 }
   1641                 mSkipCutBuffer = new SkipCutBuffer(delay * frameSize, padding * frameSize);
   1642             }
   1643         }
   1644     }
   1645 
   1646     // dumpPortStatus(portIndex);
   1647 
   1648     if (portIndex == kPortIndexInput && (mFlags & kUseSecureInputBuffers)) {
   1649         Vector<MediaBuffer *> buffers;
   1650         for (size_t i = 0; i < def.nBufferCountActual; ++i) {
   1651             const BufferInfo &info = mPortBuffers[kPortIndexInput].itemAt(i);
   1652 
   1653             MediaBuffer *mbuf = new MediaBuffer(info.mData, info.mSize);
   1654             buffers.push(mbuf);
   1655         }
   1656 
   1657         status_t err = mSource->setBuffers(buffers);
   1658 
   1659         if (err != OK) {
   1660             for (size_t i = 0; i < def.nBufferCountActual; ++i) {
   1661                 buffers.editItemAt(i)->release();
   1662             }
   1663             buffers.clear();
   1664 
   1665             CODEC_LOGE(
   1666                     "Codec requested to use secure input buffers but "
   1667                     "upstream source didn't support that.");
   1668 
   1669             return err;
   1670         }
   1671     }
   1672 
   1673     return OK;
   1674 }
   1675 
   1676 status_t OMXCodec::applyRotation() {
   1677     sp<MetaData> meta = mSource->getFormat();
   1678 
   1679     int32_t rotationDegrees;
   1680     if (!meta->findInt32(kKeyRotation, &rotationDegrees)) {
   1681         rotationDegrees = 0;
   1682     }
   1683 
   1684     uint32_t transform;
   1685     switch (rotationDegrees) {
   1686         case 0: transform = 0; break;
   1687         case 90: transform = HAL_TRANSFORM_ROT_90; break;
   1688         case 180: transform = HAL_TRANSFORM_ROT_180; break;
   1689         case 270: transform = HAL_TRANSFORM_ROT_270; break;
   1690         default: transform = 0; break;
   1691     }
   1692 
   1693     status_t err = OK;
   1694 
   1695     if (transform) {
   1696         err = native_window_set_buffers_transform(
   1697                 mNativeWindow.get(), transform);
   1698         ALOGE("native_window_set_buffers_transform failed: %s (%d)",
   1699                 strerror(-err), -err);
   1700     }
   1701 
   1702     return err;
   1703 }
   1704 
   1705 status_t OMXCodec::allocateOutputBuffersFromNativeWindow() {
   1706     // Get the number of buffers needed.
   1707     OMX_PARAM_PORTDEFINITIONTYPE def;
   1708     InitOMXParams(&def);
   1709     def.nPortIndex = kPortIndexOutput;
   1710 
   1711     status_t err = mOMX->getParameter(
   1712             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   1713     if (err != OK) {
   1714         CODEC_LOGE("getParameter failed: %d", err);
   1715         return err;
   1716     }
   1717 
   1718     err = native_window_set_buffers_geometry(
   1719             mNativeWindow.get(),
   1720             def.format.video.nFrameWidth,
   1721             def.format.video.nFrameHeight,
   1722             def.format.video.eColorFormat);
   1723 
   1724     if (err != 0) {
   1725         ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
   1726                 strerror(-err), -err);
   1727         return err;
   1728     }
   1729 
   1730     err = applyRotation();
   1731     if (err != OK) {
   1732         return err;
   1733     }
   1734 
   1735     // Set up the native window.
   1736     OMX_U32 usage = 0;
   1737     err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
   1738     if (err != 0) {
   1739         ALOGW("querying usage flags from OMX IL component failed: %d", err);
   1740         // XXX: Currently this error is logged, but not fatal.
   1741         usage = 0;
   1742     }
   1743     if (mFlags & kEnableGrallocUsageProtected) {
   1744         usage |= GRALLOC_USAGE_PROTECTED;
   1745     }
   1746 
   1747     // Make sure to check whether either Stagefright or the video decoder
   1748     // requested protected buffers.
   1749     if (usage & GRALLOC_USAGE_PROTECTED) {
   1750         // Verify that the ANativeWindow sends images directly to
   1751         // SurfaceFlinger.
   1752         int queuesToNativeWindow = 0;
   1753         err = mNativeWindow->query(
   1754                 mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
   1755                 &queuesToNativeWindow);
   1756         if (err != 0) {
   1757             ALOGE("error authenticating native window: %d", err);
   1758             return err;
   1759         }
   1760         if (queuesToNativeWindow != 1) {
   1761             ALOGE("native window could not be authenticated");
   1762             return PERMISSION_DENIED;
   1763         }
   1764     }
   1765 
   1766     ALOGV("native_window_set_usage usage=0x%lx", usage);
   1767     err = native_window_set_usage(
   1768             mNativeWindow.get(), usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
   1769     if (err != 0) {
   1770         ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
   1771         return err;
   1772     }
   1773 
   1774     int minUndequeuedBufs = 0;
   1775     err = mNativeWindow->query(mNativeWindow.get(),
   1776             NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
   1777     if (err != 0) {
   1778         ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
   1779                 strerror(-err), -err);
   1780         return err;
   1781     }
   1782 
   1783     // XXX: Is this the right logic to use?  It's not clear to me what the OMX
   1784     // buffer counts refer to - how do they account for the renderer holding on
   1785     // to buffers?
   1786     if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) {
   1787         OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs;
   1788         def.nBufferCountActual = newBufferCount;
   1789         err = mOMX->setParameter(
   1790                 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   1791         if (err != OK) {
   1792             CODEC_LOGE("setting nBufferCountActual to %lu failed: %d",
   1793                     newBufferCount, err);
   1794             return err;
   1795         }
   1796     }
   1797 
   1798     err = native_window_set_buffer_count(
   1799             mNativeWindow.get(), def.nBufferCountActual);
   1800     if (err != 0) {
   1801         ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
   1802                 -err);
   1803         return err;
   1804     }
   1805 
   1806     CODEC_LOGV("allocating %lu buffers from a native window of size %lu on "
   1807             "output port", def.nBufferCountActual, def.nBufferSize);
   1808 
   1809     // Dequeue buffers and send them to OMX
   1810     for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
   1811         ANativeWindowBuffer* buf;
   1812         err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
   1813         if (err != 0) {
   1814             ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
   1815             break;
   1816         }
   1817 
   1818         sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
   1819         BufferInfo info;
   1820         info.mData = NULL;
   1821         info.mSize = def.nBufferSize;
   1822         info.mStatus = OWNED_BY_US;
   1823         info.mMem = NULL;
   1824         info.mMediaBuffer = new MediaBuffer(graphicBuffer);
   1825         info.mMediaBuffer->setObserver(this);
   1826         mPortBuffers[kPortIndexOutput].push(info);
   1827 
   1828         IOMX::buffer_id bufferId;
   1829         err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
   1830                 &bufferId);
   1831         if (err != 0) {
   1832             CODEC_LOGE("registering GraphicBuffer with OMX IL component "
   1833                     "failed: %d", err);
   1834             break;
   1835         }
   1836 
   1837         mPortBuffers[kPortIndexOutput].editItemAt(i).mBuffer = bufferId;
   1838 
   1839         CODEC_LOGV("registered graphic buffer with ID %p (pointer = %p)",
   1840                 bufferId, graphicBuffer.get());
   1841     }
   1842 
   1843     OMX_U32 cancelStart;
   1844     OMX_U32 cancelEnd;
   1845     if (err != 0) {
   1846         // If an error occurred while dequeuing we need to cancel any buffers
   1847         // that were dequeued.
   1848         cancelStart = 0;
   1849         cancelEnd = mPortBuffers[kPortIndexOutput].size();
   1850     } else {
   1851         // Return the last two buffers to the native window.
   1852         cancelStart = def.nBufferCountActual - minUndequeuedBufs;
   1853         cancelEnd = def.nBufferCountActual;
   1854     }
   1855 
   1856     for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
   1857         BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(i);
   1858         cancelBufferToNativeWindow(info);
   1859     }
   1860 
   1861     return err;
   1862 }
   1863 
   1864 status_t OMXCodec::cancelBufferToNativeWindow(BufferInfo *info) {
   1865     CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
   1866     CODEC_LOGV("Calling cancelBuffer on buffer %p", info->mBuffer);
   1867     int err = mNativeWindow->cancelBuffer(
   1868         mNativeWindow.get(), info->mMediaBuffer->graphicBuffer().get(), -1);
   1869     if (err != 0) {
   1870       CODEC_LOGE("cancelBuffer failed w/ error 0x%08x", err);
   1871 
   1872       setState(ERROR);
   1873       return err;
   1874     }
   1875     info->mStatus = OWNED_BY_NATIVE_WINDOW;
   1876     return OK;
   1877 }
   1878 
   1879 OMXCodec::BufferInfo* OMXCodec::dequeueBufferFromNativeWindow() {
   1880     // Dequeue the next buffer from the native window.
   1881     ANativeWindowBuffer* buf;
   1882     int fenceFd = -1;
   1883     int err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
   1884     if (err != 0) {
   1885       CODEC_LOGE("dequeueBuffer failed w/ error 0x%08x", err);
   1886 
   1887       setState(ERROR);
   1888       return 0;
   1889     }
   1890 
   1891     // Determine which buffer we just dequeued.
   1892     Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
   1893     BufferInfo *bufInfo = 0;
   1894     for (size_t i = 0; i < buffers->size(); i++) {
   1895       sp<GraphicBuffer> graphicBuffer = buffers->itemAt(i).
   1896           mMediaBuffer->graphicBuffer();
   1897       if (graphicBuffer->handle == buf->handle) {
   1898         bufInfo = &buffers->editItemAt(i);
   1899         break;
   1900       }
   1901     }
   1902 
   1903     if (bufInfo == 0) {
   1904         CODEC_LOGE("dequeued unrecognized buffer: %p", buf);
   1905 
   1906         setState(ERROR);
   1907         return 0;
   1908     }
   1909 
   1910     // The native window no longer owns the buffer.
   1911     CHECK_EQ((int)bufInfo->mStatus, (int)OWNED_BY_NATIVE_WINDOW);
   1912     bufInfo->mStatus = OWNED_BY_US;
   1913 
   1914     return bufInfo;
   1915 }
   1916 
   1917 status_t OMXCodec::pushBlankBuffersToNativeWindow() {
   1918     status_t err = NO_ERROR;
   1919     ANativeWindowBuffer* anb = NULL;
   1920     int numBufs = 0;
   1921     int minUndequeuedBufs = 0;
   1922 
   1923     // We need to reconnect to the ANativeWindow as a CPU client to ensure that
   1924     // no frames get dropped by SurfaceFlinger assuming that these are video
   1925     // frames.
   1926     err = native_window_api_disconnect(mNativeWindow.get(),
   1927             NATIVE_WINDOW_API_MEDIA);
   1928     if (err != NO_ERROR) {
   1929         ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
   1930                 strerror(-err), -err);
   1931         return err;
   1932     }
   1933 
   1934     err = native_window_api_connect(mNativeWindow.get(),
   1935             NATIVE_WINDOW_API_CPU);
   1936     if (err != NO_ERROR) {
   1937         ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
   1938                 strerror(-err), -err);
   1939         return err;
   1940     }
   1941 
   1942     err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
   1943             HAL_PIXEL_FORMAT_RGBX_8888);
   1944     if (err != NO_ERROR) {
   1945         ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
   1946                 strerror(-err), -err);
   1947         goto error;
   1948     }
   1949 
   1950     err = native_window_set_usage(mNativeWindow.get(),
   1951             GRALLOC_USAGE_SW_WRITE_OFTEN);
   1952     if (err != NO_ERROR) {
   1953         ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
   1954                 strerror(-err), -err);
   1955         goto error;
   1956     }
   1957 
   1958     err = native_window_set_scaling_mode(mNativeWindow.get(),
   1959             NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
   1960     if (err != OK) {
   1961         ALOGE("error pushing blank frames: set_scaling_mode failed: %s (%d)",
   1962                 strerror(-err), -err);
   1963         goto error;
   1964     }
   1965 
   1966     err = mNativeWindow->query(mNativeWindow.get(),
   1967             NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
   1968     if (err != NO_ERROR) {
   1969         ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
   1970                 "failed: %s (%d)", strerror(-err), -err);
   1971         goto error;
   1972     }
   1973 
   1974     numBufs = minUndequeuedBufs + 1;
   1975     err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
   1976     if (err != NO_ERROR) {
   1977         ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
   1978                 strerror(-err), -err);
   1979         goto error;
   1980     }
   1981 
   1982     // We  push numBufs + 1 buffers to ensure that we've drawn into the same
   1983     // buffer twice.  This should guarantee that the buffer has been displayed
   1984     // on the screen and then been replaced, so an previous video frames are
   1985     // guaranteed NOT to be currently displayed.
   1986     for (int i = 0; i < numBufs + 1; i++) {
   1987         int fenceFd = -1;
   1988         err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
   1989         if (err != NO_ERROR) {
   1990             ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
   1991                     strerror(-err), -err);
   1992             goto error;
   1993         }
   1994 
   1995         sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
   1996 
   1997         // Fill the buffer with the a 1x1 checkerboard pattern ;)
   1998         uint32_t* img = NULL;
   1999         err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
   2000         if (err != NO_ERROR) {
   2001             ALOGE("error pushing blank frames: lock failed: %s (%d)",
   2002                     strerror(-err), -err);
   2003             goto error;
   2004         }
   2005 
   2006         *img = 0;
   2007 
   2008         err = buf->unlock();
   2009         if (err != NO_ERROR) {
   2010             ALOGE("error pushing blank frames: unlock failed: %s (%d)",
   2011                     strerror(-err), -err);
   2012             goto error;
   2013         }
   2014 
   2015         err = mNativeWindow->queueBuffer(mNativeWindow.get(),
   2016                 buf->getNativeBuffer(), -1);
   2017         if (err != NO_ERROR) {
   2018             ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
   2019                     strerror(-err), -err);
   2020             goto error;
   2021         }
   2022 
   2023         anb = NULL;
   2024     }
   2025 
   2026 error:
   2027 
   2028     if (err != NO_ERROR) {
   2029         // Clean up after an error.
   2030         if (anb != NULL) {
   2031             mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
   2032         }
   2033 
   2034         native_window_api_disconnect(mNativeWindow.get(),
   2035                 NATIVE_WINDOW_API_CPU);
   2036         native_window_api_connect(mNativeWindow.get(),
   2037                 NATIVE_WINDOW_API_MEDIA);
   2038 
   2039         return err;
   2040     } else {
   2041         // Clean up after success.
   2042         err = native_window_api_disconnect(mNativeWindow.get(),
   2043                 NATIVE_WINDOW_API_CPU);
   2044         if (err != NO_ERROR) {
   2045             ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
   2046                     strerror(-err), -err);
   2047             return err;
   2048         }
   2049 
   2050         err = native_window_api_connect(mNativeWindow.get(),
   2051                 NATIVE_WINDOW_API_MEDIA);
   2052         if (err != NO_ERROR) {
   2053             ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
   2054                     strerror(-err), -err);
   2055             return err;
   2056         }
   2057 
   2058         return NO_ERROR;
   2059     }
   2060 }
   2061 
   2062 int64_t OMXCodec::getDecodingTimeUs() {
   2063     CHECK(mIsEncoder && mIsVideo);
   2064 
   2065     if (mDecodingTimeList.empty()) {
   2066         CHECK(mSignalledEOS || mNoMoreOutputData);
   2067         // No corresponding input frame available.
   2068         // This could happen when EOS is reached.
   2069         return 0;
   2070     }
   2071 
   2072     List<int64_t>::iterator it = mDecodingTimeList.begin();
   2073     int64_t timeUs = *it;
   2074     mDecodingTimeList.erase(it);
   2075     return timeUs;
   2076 }
   2077 
   2078 void OMXCodec::on_message(const omx_message &msg) {
   2079     if (mState == ERROR) {
   2080         /*
   2081          * only drop EVENT messages, EBD and FBD are still
   2082          * processed for bookkeeping purposes
   2083          */
   2084         if (msg.type == omx_message::EVENT) {
   2085             ALOGW("Dropping OMX EVENT message - we're in ERROR state.");
   2086             return;
   2087         }
   2088     }
   2089 
   2090     switch (msg.type) {
   2091         case omx_message::EVENT:
   2092         {
   2093             onEvent(
   2094                  msg.u.event_data.event, msg.u.event_data.data1,
   2095                  msg.u.event_data.data2);
   2096 
   2097             break;
   2098         }
   2099 
   2100         case omx_message::EMPTY_BUFFER_DONE:
   2101         {
   2102             IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
   2103 
   2104             CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer);
   2105 
   2106             Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
   2107             size_t i = 0;
   2108             while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
   2109                 ++i;
   2110             }
   2111 
   2112             CHECK(i < buffers->size());
   2113             if ((*buffers)[i].mStatus != OWNED_BY_COMPONENT) {
   2114                 ALOGW("We already own input buffer %p, yet received "
   2115                      "an EMPTY_BUFFER_DONE.", buffer);
   2116             }
   2117 
   2118             BufferInfo* info = &buffers->editItemAt(i);
   2119             info->mStatus = OWNED_BY_US;
   2120 
   2121             // Buffer could not be released until empty buffer done is called.
   2122             if (info->mMediaBuffer != NULL) {
   2123                 info->mMediaBuffer->release();
   2124                 info->mMediaBuffer = NULL;
   2125             }
   2126 
   2127             if (mPortStatus[kPortIndexInput] == DISABLING) {
   2128                 CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
   2129 
   2130                 status_t err = freeBuffer(kPortIndexInput, i);
   2131                 CHECK_EQ(err, (status_t)OK);
   2132             } else if (mState != ERROR
   2133                     && mPortStatus[kPortIndexInput] != SHUTTING_DOWN) {
   2134                 CHECK_EQ((int)mPortStatus[kPortIndexInput], (int)ENABLED);
   2135 
   2136                 if (mFlags & kUseSecureInputBuffers) {
   2137                     drainAnyInputBuffer();
   2138                 } else {
   2139                     drainInputBuffer(&buffers->editItemAt(i));
   2140                 }
   2141             }
   2142             break;
   2143         }
   2144 
   2145         case omx_message::FILL_BUFFER_DONE:
   2146         {
   2147             IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
   2148             OMX_U32 flags = msg.u.extended_buffer_data.flags;
   2149 
   2150             CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx, timestamp: %lld us (%.2f secs))",
   2151                  buffer,
   2152                  msg.u.extended_buffer_data.range_length,
   2153                  flags,
   2154                  msg.u.extended_buffer_data.timestamp,
   2155                  msg.u.extended_buffer_data.timestamp / 1E6);
   2156 
   2157             Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
   2158             size_t i = 0;
   2159             while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
   2160                 ++i;
   2161             }
   2162 
   2163             CHECK(i < buffers->size());
   2164             BufferInfo *info = &buffers->editItemAt(i);
   2165 
   2166             if (info->mStatus != OWNED_BY_COMPONENT) {
   2167                 ALOGW("We already own output buffer %p, yet received "
   2168                      "a FILL_BUFFER_DONE.", buffer);
   2169             }
   2170 
   2171             info->mStatus = OWNED_BY_US;
   2172 
   2173             if (mPortStatus[kPortIndexOutput] == DISABLING) {
   2174                 CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
   2175 
   2176                 status_t err = freeBuffer(kPortIndexOutput, i);
   2177                 CHECK_EQ(err, (status_t)OK);
   2178 
   2179 #if 0
   2180             } else if (mPortStatus[kPortIndexOutput] == ENABLED
   2181                        && (flags & OMX_BUFFERFLAG_EOS)) {
   2182                 CODEC_LOGV("No more output data.");
   2183                 mNoMoreOutputData = true;
   2184                 mBufferFilled.signal();
   2185 #endif
   2186             } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) {
   2187                 CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED);
   2188 
   2189                 if (info->mMediaBuffer == NULL) {
   2190                     CHECK(mOMXLivesLocally);
   2191                     CHECK(mQuirks & kRequiresAllocateBufferOnOutputPorts);
   2192                     CHECK(mQuirks & kDefersOutputBufferAllocation);
   2193 
   2194                     // The qcom video decoders on Nexus don't actually allocate
   2195                     // output buffer memory on a call to OMX_AllocateBuffer
   2196                     // the "pBuffer" member of the OMX_BUFFERHEADERTYPE
   2197                     // structure is only filled in later.
   2198 
   2199                     info->mMediaBuffer = new MediaBuffer(
   2200                             msg.u.extended_buffer_data.data_ptr,
   2201                             info->mSize);
   2202                     info->mMediaBuffer->setObserver(this);
   2203                 }
   2204 
   2205                 MediaBuffer *buffer = info->mMediaBuffer;
   2206                 bool isGraphicBuffer = buffer->graphicBuffer() != NULL;
   2207 
   2208                 if (!isGraphicBuffer
   2209                     && msg.u.extended_buffer_data.range_offset
   2210                         + msg.u.extended_buffer_data.range_length
   2211                             > buffer->size()) {
   2212                     CODEC_LOGE(
   2213                             "Codec lied about its buffer size requirements, "
   2214                             "sending a buffer larger than the originally "
   2215                             "advertised size in FILL_BUFFER_DONE!");
   2216                 }
   2217                 buffer->set_range(
   2218                         msg.u.extended_buffer_data.range_offset,
   2219                         msg.u.extended_buffer_data.range_length);
   2220 
   2221                 buffer->meta_data()->clear();
   2222 
   2223                 buffer->meta_data()->setInt64(
   2224                         kKeyTime, msg.u.extended_buffer_data.timestamp);
   2225 
   2226                 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) {
   2227                     buffer->meta_data()->setInt32(kKeyIsSyncFrame, true);
   2228                 }
   2229                 bool isCodecSpecific = false;
   2230                 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) {
   2231                     buffer->meta_data()->setInt32(kKeyIsCodecConfig, true);
   2232                     isCodecSpecific = true;
   2233                 }
   2234 
   2235                 if (isGraphicBuffer || mQuirks & kOutputBuffersAreUnreadable) {
   2236                     buffer->meta_data()->setInt32(kKeyIsUnreadable, true);
   2237                 }
   2238 
   2239                 buffer->meta_data()->setPointer(
   2240                         kKeyPlatformPrivate,
   2241                         msg.u.extended_buffer_data.platform_private);
   2242 
   2243                 buffer->meta_data()->setPointer(
   2244                         kKeyBufferID,
   2245                         msg.u.extended_buffer_data.buffer);
   2246 
   2247                 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) {
   2248                     CODEC_LOGV("No more output data.");
   2249                     mNoMoreOutputData = true;
   2250                 }
   2251 
   2252                 if (mIsEncoder && mIsVideo) {
   2253                     int64_t decodingTimeUs = isCodecSpecific? 0: getDecodingTimeUs();
   2254                     buffer->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs);
   2255                 }
   2256 
   2257                 if (mTargetTimeUs >= 0) {
   2258                     CHECK(msg.u.extended_buffer_data.timestamp <= mTargetTimeUs);
   2259 
   2260                     if (msg.u.extended_buffer_data.timestamp < mTargetTimeUs) {
   2261                         CODEC_LOGV(
   2262                                 "skipping output buffer at timestamp %lld us",
   2263                                 msg.u.extended_buffer_data.timestamp);
   2264 
   2265                         fillOutputBuffer(info);
   2266                         break;
   2267                     }
   2268 
   2269                     CODEC_LOGV(
   2270                             "returning output buffer at target timestamp "
   2271                             "%lld us",
   2272                             msg.u.extended_buffer_data.timestamp);
   2273 
   2274                     mTargetTimeUs = -1;
   2275                 }
   2276 
   2277                 mFilledBuffers.push_back(i);
   2278                 mBufferFilled.signal();
   2279                 if (mIsEncoder) {
   2280                     sched_yield();
   2281                 }
   2282             }
   2283 
   2284             break;
   2285         }
   2286 
   2287         default:
   2288         {
   2289             CHECK(!"should not be here.");
   2290             break;
   2291         }
   2292     }
   2293 }
   2294 
   2295 // Has the format changed in any way that the client would have to be aware of?
   2296 static bool formatHasNotablyChanged(
   2297         const sp<MetaData> &from, const sp<MetaData> &to) {
   2298     if (from.get() == NULL && to.get() == NULL) {
   2299         return false;
   2300     }
   2301 
   2302     if ((from.get() == NULL && to.get() != NULL)
   2303         || (from.get() != NULL && to.get() == NULL)) {
   2304         return true;
   2305     }
   2306 
   2307     const char *mime_from, *mime_to;
   2308     CHECK(from->findCString(kKeyMIMEType, &mime_from));
   2309     CHECK(to->findCString(kKeyMIMEType, &mime_to));
   2310 
   2311     if (strcasecmp(mime_from, mime_to)) {
   2312         return true;
   2313     }
   2314 
   2315     if (!strcasecmp(mime_from, MEDIA_MIMETYPE_VIDEO_RAW)) {
   2316         int32_t colorFormat_from, colorFormat_to;
   2317         CHECK(from->findInt32(kKeyColorFormat, &colorFormat_from));
   2318         CHECK(to->findInt32(kKeyColorFormat, &colorFormat_to));
   2319 
   2320         if (colorFormat_from != colorFormat_to) {
   2321             return true;
   2322         }
   2323 
   2324         int32_t width_from, width_to;
   2325         CHECK(from->findInt32(kKeyWidth, &width_from));
   2326         CHECK(to->findInt32(kKeyWidth, &width_to));
   2327 
   2328         if (width_from != width_to) {
   2329             return true;
   2330         }
   2331 
   2332         int32_t height_from, height_to;
   2333         CHECK(from->findInt32(kKeyHeight, &height_from));
   2334         CHECK(to->findInt32(kKeyHeight, &height_to));
   2335 
   2336         if (height_from != height_to) {
   2337             return true;
   2338         }
   2339 
   2340         int32_t left_from, top_from, right_from, bottom_from;
   2341         CHECK(from->findRect(
   2342                     kKeyCropRect,
   2343                     &left_from, &top_from, &right_from, &bottom_from));
   2344 
   2345         int32_t left_to, top_to, right_to, bottom_to;
   2346         CHECK(to->findRect(
   2347                     kKeyCropRect,
   2348                     &left_to, &top_to, &right_to, &bottom_to));
   2349 
   2350         if (left_to != left_from || top_to != top_from
   2351                 || right_to != right_from || bottom_to != bottom_from) {
   2352             return true;
   2353         }
   2354     } else if (!strcasecmp(mime_from, MEDIA_MIMETYPE_AUDIO_RAW)) {
   2355         int32_t numChannels_from, numChannels_to;
   2356         CHECK(from->findInt32(kKeyChannelCount, &numChannels_from));
   2357         CHECK(to->findInt32(kKeyChannelCount, &numChannels_to));
   2358 
   2359         if (numChannels_from != numChannels_to) {
   2360             return true;
   2361         }
   2362 
   2363         int32_t sampleRate_from, sampleRate_to;
   2364         CHECK(from->findInt32(kKeySampleRate, &sampleRate_from));
   2365         CHECK(to->findInt32(kKeySampleRate, &sampleRate_to));
   2366 
   2367         if (sampleRate_from != sampleRate_to) {
   2368             return true;
   2369         }
   2370     }
   2371 
   2372     return false;
   2373 }
   2374 
   2375 void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
   2376     switch (event) {
   2377         case OMX_EventCmdComplete:
   2378         {
   2379             onCmdComplete((OMX_COMMANDTYPE)data1, data2);
   2380             break;
   2381         }
   2382 
   2383         case OMX_EventError:
   2384         {
   2385             CODEC_LOGE("ERROR(0x%08lx, %ld)", data1, data2);
   2386 
   2387             setState(ERROR);
   2388             break;
   2389         }
   2390 
   2391         case OMX_EventPortSettingsChanged:
   2392         {
   2393             CODEC_LOGV("OMX_EventPortSettingsChanged(port=%ld, data2=0x%08lx)",
   2394                        data1, data2);
   2395 
   2396             if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
   2397                 // There is no need to check whether mFilledBuffers is empty or not
   2398                 // when the OMX_EventPortSettingsChanged is not meant for reallocating
   2399                 // the output buffers.
   2400                 if (data1 == kPortIndexOutput) {
   2401                     CHECK(mFilledBuffers.empty());
   2402                 }
   2403                 onPortSettingsChanged(data1);
   2404             } else if (data1 == kPortIndexOutput &&
   2405                         (data2 == OMX_IndexConfigCommonOutputCrop ||
   2406                          data2 == OMX_IndexConfigCommonScale)) {
   2407 
   2408                 sp<MetaData> oldOutputFormat = mOutputFormat;
   2409                 initOutputFormat(mSource->getFormat());
   2410 
   2411                 if (data2 == OMX_IndexConfigCommonOutputCrop &&
   2412                     formatHasNotablyChanged(oldOutputFormat, mOutputFormat)) {
   2413                     mOutputPortSettingsHaveChanged = true;
   2414 
   2415                 } else if (data2 == OMX_IndexConfigCommonScale) {
   2416                     OMX_CONFIG_SCALEFACTORTYPE scale;
   2417                     InitOMXParams(&scale);
   2418                     scale.nPortIndex = kPortIndexOutput;
   2419 
   2420                     // Change display dimension only when necessary.
   2421                     if (OK == mOMX->getConfig(
   2422                                         mNode,
   2423                                         OMX_IndexConfigCommonScale,
   2424                                         &scale, sizeof(scale))) {
   2425                         int32_t left, top, right, bottom;
   2426                         CHECK(mOutputFormat->findRect(kKeyCropRect,
   2427                                                       &left, &top,
   2428                                                       &right, &bottom));
   2429 
   2430                         // The scale is in 16.16 format.
   2431                         // scale 1.0 = 0x010000. When there is no
   2432                         // need to change the display, skip it.
   2433                         ALOGV("Get OMX_IndexConfigScale: 0x%lx/0x%lx",
   2434                                 scale.xWidth, scale.xHeight);
   2435 
   2436                         if (scale.xWidth != 0x010000) {
   2437                             mOutputFormat->setInt32(kKeyDisplayWidth,
   2438                                     ((right - left +  1) * scale.xWidth)  >> 16);
   2439                             mOutputPortSettingsHaveChanged = true;
   2440                         }
   2441 
   2442                         if (scale.xHeight != 0x010000) {
   2443                             mOutputFormat->setInt32(kKeyDisplayHeight,
   2444                                     ((bottom  - top + 1) * scale.xHeight) >> 16);
   2445                             mOutputPortSettingsHaveChanged = true;
   2446                         }
   2447                     }
   2448                 }
   2449             }
   2450             break;
   2451         }
   2452 
   2453 #if 0
   2454         case OMX_EventBufferFlag:
   2455         {
   2456             CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1);
   2457 
   2458             if (data1 == kPortIndexOutput) {
   2459                 mNoMoreOutputData = true;
   2460             }
   2461             break;
   2462         }
   2463 #endif
   2464 
   2465         default:
   2466         {
   2467             CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2);
   2468             break;
   2469         }
   2470     }
   2471 }
   2472 
   2473 void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) {
   2474     switch (cmd) {
   2475         case OMX_CommandStateSet:
   2476         {
   2477             onStateChange((OMX_STATETYPE)data);
   2478             break;
   2479         }
   2480 
   2481         case OMX_CommandPortDisable:
   2482         {
   2483             OMX_U32 portIndex = data;
   2484             CODEC_LOGV("PORT_DISABLED(%ld)", portIndex);
   2485 
   2486             CHECK(mState == EXECUTING || mState == RECONFIGURING);
   2487             CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLING);
   2488             CHECK_EQ(mPortBuffers[portIndex].size(), 0u);
   2489 
   2490             mPortStatus[portIndex] = DISABLED;
   2491 
   2492             if (mState == RECONFIGURING) {
   2493                 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
   2494 
   2495                 sp<MetaData> oldOutputFormat = mOutputFormat;
   2496                 initOutputFormat(mSource->getFormat());
   2497 
   2498                 // Don't notify clients if the output port settings change
   2499                 // wasn't of importance to them, i.e. it may be that just the
   2500                 // number of buffers has changed and nothing else.
   2501                 bool formatChanged = formatHasNotablyChanged(oldOutputFormat, mOutputFormat);
   2502                 if (!mOutputPortSettingsHaveChanged) {
   2503                     mOutputPortSettingsHaveChanged = formatChanged;
   2504                 }
   2505 
   2506                 status_t err = enablePortAsync(portIndex);
   2507                 if (err != OK) {
   2508                     CODEC_LOGE("enablePortAsync(%ld) failed (err = %d)", portIndex, err);
   2509                     setState(ERROR);
   2510                 } else {
   2511                     err = allocateBuffersOnPort(portIndex);
   2512                     if (err != OK) {
   2513                         CODEC_LOGE("allocateBuffersOnPort (%s) failed "
   2514                                    "(err = %d)",
   2515                                    portIndex == kPortIndexInput
   2516                                         ? "input" : "output",
   2517                                    err);
   2518 
   2519                         setState(ERROR);
   2520                     }
   2521                 }
   2522             }
   2523             break;
   2524         }
   2525 
   2526         case OMX_CommandPortEnable:
   2527         {
   2528             OMX_U32 portIndex = data;
   2529             CODEC_LOGV("PORT_ENABLED(%ld)", portIndex);
   2530 
   2531             CHECK(mState == EXECUTING || mState == RECONFIGURING);
   2532             CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLING);
   2533 
   2534             mPortStatus[portIndex] = ENABLED;
   2535 
   2536             if (mState == RECONFIGURING) {
   2537                 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
   2538 
   2539                 setState(EXECUTING);
   2540 
   2541                 fillOutputBuffers();
   2542             }
   2543             break;
   2544         }
   2545 
   2546         case OMX_CommandFlush:
   2547         {
   2548             OMX_U32 portIndex = data;
   2549 
   2550             CODEC_LOGV("FLUSH_DONE(%ld)", portIndex);
   2551 
   2552             CHECK_EQ((int)mPortStatus[portIndex], (int)SHUTTING_DOWN);
   2553             mPortStatus[portIndex] = ENABLED;
   2554 
   2555             CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]),
   2556                      mPortBuffers[portIndex].size());
   2557 
   2558             if (mSkipCutBuffer != NULL && mPortStatus[kPortIndexOutput] == ENABLED) {
   2559                 mSkipCutBuffer->clear();
   2560             }
   2561 
   2562             if (mState == RECONFIGURING) {
   2563                 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
   2564 
   2565                 disablePortAsync(portIndex);
   2566             } else if (mState == EXECUTING_TO_IDLE) {
   2567                 if (mPortStatus[kPortIndexInput] == ENABLED
   2568                     && mPortStatus[kPortIndexOutput] == ENABLED) {
   2569                     CODEC_LOGV("Finished flushing both ports, now completing "
   2570                          "transition from EXECUTING to IDLE.");
   2571 
   2572                     mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
   2573                     mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
   2574 
   2575                     status_t err =
   2576                         mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
   2577                     CHECK_EQ(err, (status_t)OK);
   2578                 }
   2579             } else {
   2580                 // We're flushing both ports in preparation for seeking.
   2581 
   2582                 if (mPortStatus[kPortIndexInput] == ENABLED
   2583                     && mPortStatus[kPortIndexOutput] == ENABLED) {
   2584                     CODEC_LOGV("Finished flushing both ports, now continuing from"
   2585                          " seek-time.");
   2586 
   2587                     // We implicitly resume pulling on our upstream source.
   2588                     mPaused = false;
   2589 
   2590                     drainInputBuffers();
   2591                     fillOutputBuffers();
   2592                 }
   2593 
   2594                 if (mOutputPortSettingsChangedPending) {
   2595                     CODEC_LOGV(
   2596                             "Honoring deferred output port settings change.");
   2597 
   2598                     mOutputPortSettingsChangedPending = false;
   2599                     onPortSettingsChanged(kPortIndexOutput);
   2600                 }
   2601             }
   2602 
   2603             break;
   2604         }
   2605 
   2606         default:
   2607         {
   2608             CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data);
   2609             break;
   2610         }
   2611     }
   2612 }
   2613 
   2614 void OMXCodec::onStateChange(OMX_STATETYPE newState) {
   2615     CODEC_LOGV("onStateChange %d", newState);
   2616 
   2617     switch (newState) {
   2618         case OMX_StateIdle:
   2619         {
   2620             CODEC_LOGV("Now Idle.");
   2621             if (mState == LOADED_TO_IDLE) {
   2622                 status_t err = mOMX->sendCommand(
   2623                         mNode, OMX_CommandStateSet, OMX_StateExecuting);
   2624 
   2625                 CHECK_EQ(err, (status_t)OK);
   2626 
   2627                 setState(IDLE_TO_EXECUTING);
   2628             } else {
   2629                 CHECK_EQ((int)mState, (int)EXECUTING_TO_IDLE);
   2630 
   2631                 if (countBuffersWeOwn(mPortBuffers[kPortIndexInput]) !=
   2632                     mPortBuffers[kPortIndexInput].size()) {
   2633                     ALOGE("Codec did not return all input buffers "
   2634                           "(received %d / %d)",
   2635                             countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
   2636                             mPortBuffers[kPortIndexInput].size());
   2637                     TRESPASS();
   2638                 }
   2639 
   2640                 if (countBuffersWeOwn(mPortBuffers[kPortIndexOutput]) !=
   2641                     mPortBuffers[kPortIndexOutput].size()) {
   2642                     ALOGE("Codec did not return all output buffers "
   2643                           "(received %d / %d)",
   2644                             countBuffersWeOwn(mPortBuffers[kPortIndexOutput]),
   2645                             mPortBuffers[kPortIndexOutput].size());
   2646                     TRESPASS();
   2647                 }
   2648 
   2649                 status_t err = mOMX->sendCommand(
   2650                         mNode, OMX_CommandStateSet, OMX_StateLoaded);
   2651 
   2652                 CHECK_EQ(err, (status_t)OK);
   2653 
   2654                 err = freeBuffersOnPort(kPortIndexInput);
   2655                 CHECK_EQ(err, (status_t)OK);
   2656 
   2657                 err = freeBuffersOnPort(kPortIndexOutput);
   2658                 CHECK_EQ(err, (status_t)OK);
   2659 
   2660                 mPortStatus[kPortIndexInput] = ENABLED;
   2661                 mPortStatus[kPortIndexOutput] = ENABLED;
   2662 
   2663                 if ((mFlags & kEnableGrallocUsageProtected) &&
   2664                         mNativeWindow != NULL) {
   2665                     // We push enough 1x1 blank buffers to ensure that one of
   2666                     // them has made it to the display.  This allows the OMX
   2667                     // component teardown to zero out any protected buffers
   2668                     // without the risk of scanning out one of those buffers.
   2669                     pushBlankBuffersToNativeWindow();
   2670                 }
   2671 
   2672                 setState(IDLE_TO_LOADED);
   2673             }
   2674             break;
   2675         }
   2676 
   2677         case OMX_StateExecuting:
   2678         {
   2679             CHECK_EQ((int)mState, (int)IDLE_TO_EXECUTING);
   2680 
   2681             CODEC_LOGV("Now Executing.");
   2682 
   2683             mOutputPortSettingsChangedPending = false;
   2684 
   2685             setState(EXECUTING);
   2686 
   2687             // Buffers will be submitted to the component in the first
   2688             // call to OMXCodec::read as mInitialBufferSubmit is true at
   2689             // this point. This ensures that this on_message call returns,
   2690             // releases the lock and ::init can notice the state change and
   2691             // itself return.
   2692             break;
   2693         }
   2694 
   2695         case OMX_StateLoaded:
   2696         {
   2697             CHECK_EQ((int)mState, (int)IDLE_TO_LOADED);
   2698 
   2699             CODEC_LOGV("Now Loaded.");
   2700 
   2701             setState(LOADED);
   2702             break;
   2703         }
   2704 
   2705         case OMX_StateInvalid:
   2706         {
   2707             setState(ERROR);
   2708             break;
   2709         }
   2710 
   2711         default:
   2712         {
   2713             CHECK(!"should not be here.");
   2714             break;
   2715         }
   2716     }
   2717 }
   2718 
   2719 // static
   2720 size_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) {
   2721     size_t n = 0;
   2722     for (size_t i = 0; i < buffers.size(); ++i) {
   2723         if (buffers[i].mStatus != OWNED_BY_COMPONENT) {
   2724             ++n;
   2725         }
   2726     }
   2727 
   2728     return n;
   2729 }
   2730 
   2731 status_t OMXCodec::freeBuffersOnPort(
   2732         OMX_U32 portIndex, bool onlyThoseWeOwn) {
   2733     Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
   2734 
   2735     status_t stickyErr = OK;
   2736 
   2737     for (size_t i = buffers->size(); i-- > 0;) {
   2738         BufferInfo *info = &buffers->editItemAt(i);
   2739 
   2740         if (onlyThoseWeOwn && info->mStatus == OWNED_BY_COMPONENT) {
   2741             continue;
   2742         }
   2743 
   2744         CHECK(info->mStatus == OWNED_BY_US
   2745                 || info->mStatus == OWNED_BY_NATIVE_WINDOW);
   2746 
   2747         CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex);
   2748 
   2749         status_t err = freeBuffer(portIndex, i);
   2750 
   2751         if (err != OK) {
   2752             stickyErr = err;
   2753         }
   2754 
   2755     }
   2756 
   2757     CHECK(onlyThoseWeOwn || buffers->isEmpty());
   2758 
   2759     return stickyErr;
   2760 }
   2761 
   2762 status_t OMXCodec::freeBuffer(OMX_U32 portIndex, size_t bufIndex) {
   2763     Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
   2764 
   2765     BufferInfo *info = &buffers->editItemAt(bufIndex);
   2766 
   2767     status_t err = mOMX->freeBuffer(mNode, portIndex, info->mBuffer);
   2768 
   2769     if (err == OK && info->mMediaBuffer != NULL) {
   2770         CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
   2771         info->mMediaBuffer->setObserver(NULL);
   2772 
   2773         // Make sure nobody but us owns this buffer at this point.
   2774         CHECK_EQ(info->mMediaBuffer->refcount(), 0);
   2775 
   2776         // Cancel the buffer if it belongs to an ANativeWindow.
   2777         sp<GraphicBuffer> graphicBuffer = info->mMediaBuffer->graphicBuffer();
   2778         if (info->mStatus == OWNED_BY_US && graphicBuffer != 0) {
   2779             err = cancelBufferToNativeWindow(info);
   2780         }
   2781 
   2782         info->mMediaBuffer->release();
   2783         info->mMediaBuffer = NULL;
   2784     }
   2785 
   2786     if (err == OK) {
   2787         buffers->removeAt(bufIndex);
   2788     }
   2789 
   2790     return err;
   2791 }
   2792 
   2793 void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) {
   2794     CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex);
   2795 
   2796     CHECK_EQ((int)mState, (int)EXECUTING);
   2797     CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
   2798     CHECK(!mOutputPortSettingsChangedPending);
   2799 
   2800     if (mPortStatus[kPortIndexOutput] != ENABLED) {
   2801         CODEC_LOGV("Deferring output port settings change.");
   2802         mOutputPortSettingsChangedPending = true;
   2803         return;
   2804     }
   2805 
   2806     setState(RECONFIGURING);
   2807 
   2808     if (mQuirks & kNeedsFlushBeforeDisable) {
   2809         if (!flushPortAsync(portIndex)) {
   2810             onCmdComplete(OMX_CommandFlush, portIndex);
   2811         }
   2812     } else {
   2813         disablePortAsync(portIndex);
   2814     }
   2815 }
   2816 
   2817 bool OMXCodec::flushPortAsync(OMX_U32 portIndex) {
   2818     CHECK(mState == EXECUTING || mState == RECONFIGURING
   2819             || mState == EXECUTING_TO_IDLE);
   2820 
   2821     CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.",
   2822          portIndex, countBuffersWeOwn(mPortBuffers[portIndex]),
   2823          mPortBuffers[portIndex].size());
   2824 
   2825     CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLED);
   2826     mPortStatus[portIndex] = SHUTTING_DOWN;
   2827 
   2828     if ((mQuirks & kRequiresFlushCompleteEmulation)
   2829         && countBuffersWeOwn(mPortBuffers[portIndex])
   2830                 == mPortBuffers[portIndex].size()) {
   2831         // No flush is necessary and this component fails to send a
   2832         // flush-complete event in this case.
   2833 
   2834         return false;
   2835     }
   2836 
   2837     status_t err =
   2838         mOMX->sendCommand(mNode, OMX_CommandFlush, portIndex);
   2839     CHECK_EQ(err, (status_t)OK);
   2840 
   2841     return true;
   2842 }
   2843 
   2844 void OMXCodec::disablePortAsync(OMX_U32 portIndex) {
   2845     CHECK(mState == EXECUTING || mState == RECONFIGURING);
   2846 
   2847     CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLED);
   2848     mPortStatus[portIndex] = DISABLING;
   2849 
   2850     CODEC_LOGV("sending OMX_CommandPortDisable(%ld)", portIndex);
   2851     status_t err =
   2852         mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex);
   2853     CHECK_EQ(err, (status_t)OK);
   2854 
   2855     freeBuffersOnPort(portIndex, true);
   2856 }
   2857 
   2858 status_t OMXCodec::enablePortAsync(OMX_U32 portIndex) {
   2859     CHECK(mState == EXECUTING || mState == RECONFIGURING);
   2860 
   2861     CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLED);
   2862     mPortStatus[portIndex] = ENABLING;
   2863 
   2864     CODEC_LOGV("sending OMX_CommandPortEnable(%ld)", portIndex);
   2865     return mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex);
   2866 }
   2867 
   2868 void OMXCodec::fillOutputBuffers() {
   2869     CHECK_EQ((int)mState, (int)EXECUTING);
   2870 
   2871     // This is a workaround for some decoders not properly reporting
   2872     // end-of-output-stream. If we own all input buffers and also own
   2873     // all output buffers and we already signalled end-of-input-stream,
   2874     // the end-of-output-stream is implied.
   2875     if (mSignalledEOS
   2876             && countBuffersWeOwn(mPortBuffers[kPortIndexInput])
   2877                 == mPortBuffers[kPortIndexInput].size()
   2878             && countBuffersWeOwn(mPortBuffers[kPortIndexOutput])
   2879                 == mPortBuffers[kPortIndexOutput].size()) {
   2880         mNoMoreOutputData = true;
   2881         mBufferFilled.signal();
   2882 
   2883         return;
   2884     }
   2885 
   2886     Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
   2887     for (size_t i = 0; i < buffers->size(); ++i) {
   2888         BufferInfo *info = &buffers->editItemAt(i);
   2889         if (info->mStatus == OWNED_BY_US) {
   2890             fillOutputBuffer(&buffers->editItemAt(i));
   2891         }
   2892     }
   2893 }
   2894 
   2895 void OMXCodec::drainInputBuffers() {
   2896     CHECK(mState == EXECUTING || mState == RECONFIGURING);
   2897 
   2898     if (mFlags & kUseSecureInputBuffers) {
   2899         Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
   2900         for (size_t i = 0; i < buffers->size(); ++i) {
   2901             if (!drainAnyInputBuffer()
   2902                     || (mFlags & kOnlySubmitOneInputBufferAtOneTime)) {
   2903                 break;
   2904             }
   2905         }
   2906     } else {
   2907         Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
   2908         for (size_t i = 0; i < buffers->size(); ++i) {
   2909             BufferInfo *info = &buffers->editItemAt(i);
   2910 
   2911             if (info->mStatus != OWNED_BY_US) {
   2912                 continue;
   2913             }
   2914 
   2915             if (!drainInputBuffer(info)) {
   2916                 break;
   2917             }
   2918 
   2919             if (mFlags & kOnlySubmitOneInputBufferAtOneTime) {
   2920                 break;
   2921             }
   2922         }
   2923     }
   2924 }
   2925 
   2926 bool OMXCodec::drainAnyInputBuffer() {
   2927     return drainInputBuffer((BufferInfo *)NULL);
   2928 }
   2929 
   2930 OMXCodec::BufferInfo *OMXCodec::findInputBufferByDataPointer(void *ptr) {
   2931     Vector<BufferInfo> *infos = &mPortBuffers[kPortIndexInput];
   2932     for (size_t i = 0; i < infos->size(); ++i) {
   2933         BufferInfo *info = &infos->editItemAt(i);
   2934 
   2935         if (info->mData == ptr) {
   2936             CODEC_LOGV(
   2937                     "input buffer data ptr = %p, buffer_id = %p",
   2938                     ptr,
   2939                     info->mBuffer);
   2940 
   2941             return info;
   2942         }
   2943     }
   2944 
   2945     TRESPASS();
   2946 }
   2947 
   2948 OMXCodec::BufferInfo *OMXCodec::findEmptyInputBuffer() {
   2949     Vector<BufferInfo> *infos = &mPortBuffers[kPortIndexInput];
   2950     for (size_t i = 0; i < infos->size(); ++i) {
   2951         BufferInfo *info = &infos->editItemAt(i);
   2952 
   2953         if (info->mStatus == OWNED_BY_US) {
   2954             return info;
   2955         }
   2956     }
   2957 
   2958     TRESPASS();
   2959 }
   2960 
   2961 bool OMXCodec::drainInputBuffer(BufferInfo *info) {
   2962     if (info != NULL) {
   2963         CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
   2964     }
   2965 
   2966     if (mSignalledEOS) {
   2967         return false;
   2968     }
   2969 
   2970     if (mCodecSpecificDataIndex < mCodecSpecificData.size()) {
   2971         CHECK(!(mFlags & kUseSecureInputBuffers));
   2972 
   2973         const CodecSpecificData *specific =
   2974             mCodecSpecificData[mCodecSpecificDataIndex];
   2975 
   2976         size_t size = specific->mSize;
   2977 
   2978         if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME)
   2979                 && !(mQuirks & kWantsNALFragments)) {
   2980             static const uint8_t kNALStartCode[4] =
   2981                     { 0x00, 0x00, 0x00, 0x01 };
   2982 
   2983             CHECK(info->mSize >= specific->mSize + 4);
   2984 
   2985             size += 4;
   2986 
   2987             memcpy(info->mData, kNALStartCode, 4);
   2988             memcpy((uint8_t *)info->mData + 4,
   2989                    specific->mData, specific->mSize);
   2990         } else {
   2991             CHECK(info->mSize >= specific->mSize);
   2992             memcpy(info->mData, specific->mData, specific->mSize);
   2993         }
   2994 
   2995         mNoMoreOutputData = false;
   2996 
   2997         CODEC_LOGV("calling emptyBuffer with codec specific data");
   2998 
   2999         status_t err = mOMX->emptyBuffer(
   3000                 mNode, info->mBuffer, 0, size,
   3001                 OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG,
   3002                 0);
   3003         CHECK_EQ(err, (status_t)OK);
   3004 
   3005         info->mStatus = OWNED_BY_COMPONENT;
   3006 
   3007         ++mCodecSpecificDataIndex;
   3008         return true;
   3009     }
   3010 
   3011     if (mPaused) {
   3012         return false;
   3013     }
   3014 
   3015     status_t err;
   3016 
   3017     bool signalEOS = false;
   3018     int64_t timestampUs = 0;
   3019 
   3020     size_t offset = 0;
   3021     int32_t n = 0;
   3022 
   3023 
   3024     for (;;) {
   3025         MediaBuffer *srcBuffer;
   3026         if (mSeekTimeUs >= 0) {
   3027             if (mLeftOverBuffer) {
   3028                 mLeftOverBuffer->release();
   3029                 mLeftOverBuffer = NULL;
   3030             }
   3031 
   3032             MediaSource::ReadOptions options;
   3033             options.setSeekTo(mSeekTimeUs, mSeekMode);
   3034 
   3035             mSeekTimeUs = -1;
   3036             mSeekMode = ReadOptions::SEEK_CLOSEST_SYNC;
   3037             mBufferFilled.signal();
   3038 
   3039             err = mSource->read(&srcBuffer, &options);
   3040 
   3041             if (err == OK) {
   3042                 int64_t targetTimeUs;
   3043                 if (srcBuffer->meta_data()->findInt64(
   3044                             kKeyTargetTime, &targetTimeUs)
   3045                         && targetTimeUs >= 0) {
   3046                     CODEC_LOGV("targetTimeUs = %lld us", targetTimeUs);
   3047                     mTargetTimeUs = targetTimeUs;
   3048                 } else {
   3049                     mTargetTimeUs = -1;
   3050                 }
   3051             }
   3052         } else if (mLeftOverBuffer) {
   3053             srcBuffer = mLeftOverBuffer;
   3054             mLeftOverBuffer = NULL;
   3055 
   3056             err = OK;
   3057         } else {
   3058             err = mSource->read(&srcBuffer);
   3059         }
   3060 
   3061         if (err != OK) {
   3062             signalEOS = true;
   3063             mFinalStatus = err;
   3064             mSignalledEOS = true;
   3065             mBufferFilled.signal();
   3066             break;
   3067         }
   3068 
   3069         if (mFlags & kUseSecureInputBuffers) {
   3070             info = findInputBufferByDataPointer(srcBuffer->data());
   3071             CHECK(info != NULL);
   3072         }
   3073 
   3074         size_t remainingBytes = info->mSize - offset;
   3075 
   3076         if (srcBuffer->range_length() > remainingBytes) {
   3077             if (offset == 0) {
   3078                 CODEC_LOGE(
   3079                      "Codec's input buffers are too small to accomodate "
   3080                      "buffer read from source (info->mSize = %d, srcLength = %d)",
   3081                      info->mSize, srcBuffer->range_length());
   3082 
   3083                 srcBuffer->release();
   3084                 srcBuffer = NULL;
   3085 
   3086                 setState(ERROR);
   3087                 return false;
   3088             }
   3089 
   3090             mLeftOverBuffer = srcBuffer;
   3091             break;
   3092         }
   3093 
   3094         bool releaseBuffer = true;
   3095         if (mFlags & kStoreMetaDataInVideoBuffers) {
   3096                 releaseBuffer = false;
   3097                 info->mMediaBuffer = srcBuffer;
   3098         }
   3099 
   3100         if (mFlags & kUseSecureInputBuffers) {
   3101                 // Data in "info" is already provided at this time.
   3102 
   3103                 releaseBuffer = false;
   3104 
   3105                 CHECK(info->mMediaBuffer == NULL);
   3106                 info->mMediaBuffer = srcBuffer;
   3107         } else {
   3108             CHECK(srcBuffer->data() != NULL) ;
   3109             memcpy((uint8_t *)info->mData + offset,
   3110                     (const uint8_t *)srcBuffer->data()
   3111                         + srcBuffer->range_offset(),
   3112                     srcBuffer->range_length());
   3113         }
   3114 
   3115         int64_t lastBufferTimeUs;
   3116         CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs));
   3117         CHECK(lastBufferTimeUs >= 0);
   3118         if (mIsEncoder && mIsVideo) {
   3119             mDecodingTimeList.push_back(lastBufferTimeUs);
   3120         }
   3121 
   3122         if (offset == 0) {
   3123             timestampUs = lastBufferTimeUs;
   3124         }
   3125 
   3126         offset += srcBuffer->range_length();
   3127 
   3128         if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_VORBIS, mMIME)) {
   3129             CHECK(!(mQuirks & kSupportsMultipleFramesPerInputBuffer));
   3130             CHECK_GE(info->mSize, offset + sizeof(int32_t));
   3131 
   3132             int32_t numPageSamples;
   3133             if (!srcBuffer->meta_data()->findInt32(
   3134                         kKeyValidSamples, &numPageSamples)) {
   3135                 numPageSamples = -1;
   3136             }
   3137 
   3138             memcpy((uint8_t *)info->mData + offset,
   3139                    &numPageSamples,
   3140                    sizeof(numPageSamples));
   3141 
   3142             offset += sizeof(numPageSamples);
   3143         }
   3144 
   3145         if (releaseBuffer) {
   3146             srcBuffer->release();
   3147             srcBuffer = NULL;
   3148         }
   3149 
   3150         ++n;
   3151 
   3152         if (!(mQuirks & kSupportsMultipleFramesPerInputBuffer)) {
   3153             break;
   3154         }
   3155 
   3156         int64_t coalescedDurationUs = lastBufferTimeUs - timestampUs;
   3157 
   3158         if (coalescedDurationUs > 250000ll) {
   3159             // Don't coalesce more than 250ms worth of encoded data at once.
   3160             break;
   3161         }
   3162     }
   3163 
   3164     if (n > 1) {
   3165         ALOGV("coalesced %d frames into one input buffer", n);
   3166     }
   3167 
   3168     OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
   3169 
   3170     if (signalEOS) {
   3171         flags |= OMX_BUFFERFLAG_EOS;
   3172     } else {
   3173         mNoMoreOutputData = false;
   3174     }
   3175 
   3176     if (info == NULL) {
   3177         CHECK(mFlags & kUseSecureInputBuffers);
   3178         CHECK(signalEOS);
   3179 
   3180         // This is fishy, there's still a MediaBuffer corresponding to this
   3181         // info available to the source at this point even though we're going
   3182         // to use it to signal EOS to the codec.
   3183         info = findEmptyInputBuffer();
   3184     }
   3185 
   3186     CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), "
   3187                "timestamp %lld us (%.2f secs)",
   3188                info->mBuffer, offset,
   3189                timestampUs, timestampUs / 1E6);
   3190 
   3191     err = mOMX->emptyBuffer(
   3192             mNode, info->mBuffer, 0, offset,
   3193             flags, timestampUs);
   3194 
   3195     if (err != OK) {
   3196         setState(ERROR);
   3197         return false;
   3198     }
   3199 
   3200     info->mStatus = OWNED_BY_COMPONENT;
   3201 
   3202     return true;
   3203 }
   3204 
   3205 void OMXCodec::fillOutputBuffer(BufferInfo *info) {
   3206     CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
   3207 
   3208     if (mNoMoreOutputData) {
   3209         CODEC_LOGV("There is no more output data available, not "
   3210              "calling fillOutputBuffer");
   3211         return;
   3212     }
   3213 
   3214     CODEC_LOGV("Calling fillBuffer on buffer %p", info->mBuffer);
   3215     status_t err = mOMX->fillBuffer(mNode, info->mBuffer);
   3216 
   3217     if (err != OK) {
   3218         CODEC_LOGE("fillBuffer failed w/ error 0x%08x", err);
   3219 
   3220         setState(ERROR);
   3221         return;
   3222     }
   3223 
   3224     info->mStatus = OWNED_BY_COMPONENT;
   3225 }
   3226 
   3227 bool OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) {
   3228     Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
   3229     for (size_t i = 0; i < buffers->size(); ++i) {
   3230         if ((*buffers)[i].mBuffer == buffer) {
   3231             return drainInputBuffer(&buffers->editItemAt(i));
   3232         }
   3233     }
   3234 
   3235     CHECK(!"should not be here.");
   3236 
   3237     return false;
   3238 }
   3239 
   3240 void OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) {
   3241     Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
   3242     for (size_t i = 0; i < buffers->size(); ++i) {
   3243         if ((*buffers)[i].mBuffer == buffer) {
   3244             fillOutputBuffer(&buffers->editItemAt(i));
   3245             return;
   3246         }
   3247     }
   3248 
   3249     CHECK(!"should not be here.");
   3250 }
   3251 
   3252 void OMXCodec::setState(State newState) {
   3253     mState = newState;
   3254     mAsyncCompletion.signal();
   3255 
   3256     // This may cause some spurious wakeups but is necessary to
   3257     // unblock the reader if we enter ERROR state.
   3258     mBufferFilled.signal();
   3259 }
   3260 
   3261 status_t OMXCodec::waitForBufferFilled_l() {
   3262 
   3263     if (mIsEncoder) {
   3264         // For timelapse video recording, the timelapse video recording may
   3265         // not send an input frame for a _long_ time. Do not use timeout
   3266         // for video encoding.
   3267         return mBufferFilled.wait(mLock);
   3268     }
   3269     status_t err = mBufferFilled.waitRelative(mLock, kBufferFilledEventTimeOutNs);
   3270     if (err != OK) {
   3271         CODEC_LOGE("Timed out waiting for output buffers: %d/%d",
   3272             countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
   3273             countBuffersWeOwn(mPortBuffers[kPortIndexOutput]));
   3274     }
   3275     return err;
   3276 }
   3277 
   3278 void OMXCodec::setRawAudioFormat(
   3279         OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
   3280 
   3281     // port definition
   3282     OMX_PARAM_PORTDEFINITIONTYPE def;
   3283     InitOMXParams(&def);
   3284     def.nPortIndex = portIndex;
   3285     status_t err = mOMX->getParameter(
   3286             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   3287     CHECK_EQ(err, (status_t)OK);
   3288     def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
   3289     CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition,
   3290             &def, sizeof(def)), (status_t)OK);
   3291 
   3292     // pcm param
   3293     OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
   3294     InitOMXParams(&pcmParams);
   3295     pcmParams.nPortIndex = portIndex;
   3296 
   3297     err = mOMX->getParameter(
   3298             mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
   3299 
   3300     CHECK_EQ(err, (status_t)OK);
   3301 
   3302     pcmParams.nChannels = numChannels;
   3303     pcmParams.eNumData = OMX_NumericalDataSigned;
   3304     pcmParams.bInterleaved = OMX_TRUE;
   3305     pcmParams.nBitPerSample = 16;
   3306     pcmParams.nSamplingRate = sampleRate;
   3307     pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
   3308 
   3309     CHECK_EQ(getOMXChannelMapping(
   3310                 numChannels, pcmParams.eChannelMapping), (status_t)OK);
   3311 
   3312     err = mOMX->setParameter(
   3313             mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
   3314 
   3315     CHECK_EQ(err, (status_t)OK);
   3316 }
   3317 
   3318 static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(bool isAMRWB, int32_t bps) {
   3319     if (isAMRWB) {
   3320         if (bps <= 6600) {
   3321             return OMX_AUDIO_AMRBandModeWB0;
   3322         } else if (bps <= 8850) {
   3323             return OMX_AUDIO_AMRBandModeWB1;
   3324         } else if (bps <= 12650) {
   3325             return OMX_AUDIO_AMRBandModeWB2;
   3326         } else if (bps <= 14250) {
   3327             return OMX_AUDIO_AMRBandModeWB3;
   3328         } else if (bps <= 15850) {
   3329             return OMX_AUDIO_AMRBandModeWB4;
   3330         } else if (bps <= 18250) {
   3331             return OMX_AUDIO_AMRBandModeWB5;
   3332         } else if (bps <= 19850) {
   3333             return OMX_AUDIO_AMRBandModeWB6;
   3334         } else if (bps <= 23050) {
   3335             return OMX_AUDIO_AMRBandModeWB7;
   3336         }
   3337 
   3338         // 23850 bps
   3339         return OMX_AUDIO_AMRBandModeWB8;
   3340     } else {  // AMRNB
   3341         if (bps <= 4750) {
   3342             return OMX_AUDIO_AMRBandModeNB0;
   3343         } else if (bps <= 5150) {
   3344             return OMX_AUDIO_AMRBandModeNB1;
   3345         } else if (bps <= 5900) {
   3346             return OMX_AUDIO_AMRBandModeNB2;
   3347         } else if (bps <= 6700) {
   3348             return OMX_AUDIO_AMRBandModeNB3;
   3349         } else if (bps <= 7400) {
   3350             return OMX_AUDIO_AMRBandModeNB4;
   3351         } else if (bps <= 7950) {
   3352             return OMX_AUDIO_AMRBandModeNB5;
   3353         } else if (bps <= 10200) {
   3354             return OMX_AUDIO_AMRBandModeNB6;
   3355         }
   3356 
   3357         // 12200 bps
   3358         return OMX_AUDIO_AMRBandModeNB7;
   3359     }
   3360 }
   3361 
   3362 void OMXCodec::setAMRFormat(bool isWAMR, int32_t bitRate) {
   3363     OMX_U32 portIndex = mIsEncoder ? kPortIndexOutput : kPortIndexInput;
   3364 
   3365     OMX_AUDIO_PARAM_AMRTYPE def;
   3366     InitOMXParams(&def);
   3367     def.nPortIndex = portIndex;
   3368 
   3369     status_t err =
   3370         mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
   3371 
   3372     CHECK_EQ(err, (status_t)OK);
   3373 
   3374     def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
   3375 
   3376     def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitRate);
   3377     err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
   3378     CHECK_EQ(err, (status_t)OK);
   3379 
   3380     ////////////////////////
   3381 
   3382     if (mIsEncoder) {
   3383         sp<MetaData> format = mSource->getFormat();
   3384         int32_t sampleRate;
   3385         int32_t numChannels;
   3386         CHECK(format->findInt32(kKeySampleRate, &sampleRate));
   3387         CHECK(format->findInt32(kKeyChannelCount, &numChannels));
   3388 
   3389         setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
   3390     }
   3391 }
   3392 
   3393 status_t OMXCodec::setAACFormat(
   3394         int32_t numChannels, int32_t sampleRate, int32_t bitRate, int32_t aacProfile, bool isADTS) {
   3395     if (numChannels > 2) {
   3396         ALOGW("Number of channels: (%d) \n", numChannels);
   3397     }
   3398 
   3399     if (mIsEncoder) {
   3400         if (isADTS) {
   3401             return -EINVAL;
   3402         }
   3403 
   3404         //////////////// input port ////////////////////
   3405         setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
   3406 
   3407         //////////////// output port ////////////////////
   3408         // format
   3409         OMX_AUDIO_PARAM_PORTFORMATTYPE format;
   3410         InitOMXParams(&format);
   3411         format.nPortIndex = kPortIndexOutput;
   3412         format.nIndex = 0;
   3413         status_t err = OMX_ErrorNone;
   3414         while (OMX_ErrorNone == err) {
   3415             CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioPortFormat,
   3416                     &format, sizeof(format)), (status_t)OK);
   3417             if (format.eEncoding == OMX_AUDIO_CodingAAC) {
   3418                 break;
   3419             }
   3420             format.nIndex++;
   3421         }
   3422         CHECK_EQ((status_t)OK, err);
   3423         CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamAudioPortFormat,
   3424                 &format, sizeof(format)), (status_t)OK);
   3425 
   3426         // port definition
   3427         OMX_PARAM_PORTDEFINITIONTYPE def;
   3428         InitOMXParams(&def);
   3429         def.nPortIndex = kPortIndexOutput;
   3430         CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamPortDefinition,
   3431                 &def, sizeof(def)), (status_t)OK);
   3432         def.format.audio.bFlagErrorConcealment = OMX_TRUE;
   3433         def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
   3434         CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition,
   3435                 &def, sizeof(def)), (status_t)OK);
   3436 
   3437         // profile
   3438         OMX_AUDIO_PARAM_AACPROFILETYPE profile;
   3439         InitOMXParams(&profile);
   3440         profile.nPortIndex = kPortIndexOutput;
   3441         CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioAac,
   3442                 &profile, sizeof(profile)), (status_t)OK);
   3443         profile.nChannels = numChannels;
   3444         profile.eChannelMode = (numChannels == 1?
   3445                 OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo);
   3446         profile.nSampleRate = sampleRate;
   3447         profile.nBitRate = bitRate;
   3448         profile.nAudioBandWidth = 0;
   3449         profile.nFrameLength = 0;
   3450         profile.nAACtools = OMX_AUDIO_AACToolAll;
   3451         profile.nAACERtools = OMX_AUDIO_AACERNone;
   3452         profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
   3453         profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
   3454         err = mOMX->setParameter(mNode, OMX_IndexParamAudioAac,
   3455                 &profile, sizeof(profile));
   3456 
   3457         if (err != OK) {
   3458             CODEC_LOGE("setParameter('OMX_IndexParamAudioAac') failed "
   3459                        "(err = %d)",
   3460                        err);
   3461             return err;
   3462         }
   3463     } else {
   3464         OMX_AUDIO_PARAM_AACPROFILETYPE profile;
   3465         InitOMXParams(&profile);
   3466         profile.nPortIndex = kPortIndexInput;
   3467 
   3468         status_t err = mOMX->getParameter(
   3469                 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
   3470         CHECK_EQ(err, (status_t)OK);
   3471 
   3472         profile.nChannels = numChannels;
   3473         profile.nSampleRate = sampleRate;
   3474 
   3475         profile.eAACStreamFormat =
   3476             isADTS
   3477                 ? OMX_AUDIO_AACStreamFormatMP4ADTS
   3478                 : OMX_AUDIO_AACStreamFormatMP4FF;
   3479 
   3480         err = mOMX->setParameter(
   3481                 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
   3482 
   3483         if (err != OK) {
   3484             CODEC_LOGE("setParameter('OMX_IndexParamAudioAac') failed "
   3485                        "(err = %d)",
   3486                        err);
   3487             return err;
   3488         }
   3489     }
   3490 
   3491     return OK;
   3492 }
   3493 
   3494 void OMXCodec::setG711Format(int32_t numChannels) {
   3495     CHECK(!mIsEncoder);
   3496     setRawAudioFormat(kPortIndexInput, 8000, numChannels);
   3497 }
   3498 
   3499 void OMXCodec::setImageOutputFormat(
   3500         OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) {
   3501     CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height);
   3502 
   3503 #if 0
   3504     OMX_INDEXTYPE index;
   3505     status_t err = mOMX->get_extension_index(
   3506             mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index);
   3507     CHECK_EQ(err, (status_t)OK);
   3508 
   3509     err = mOMX->set_config(mNode, index, &format, sizeof(format));
   3510     CHECK_EQ(err, (status_t)OK);
   3511 #endif
   3512 
   3513     OMX_PARAM_PORTDEFINITIONTYPE def;
   3514     InitOMXParams(&def);
   3515     def.nPortIndex = kPortIndexOutput;
   3516 
   3517     status_t err = mOMX->getParameter(
   3518             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   3519     CHECK_EQ(err, (status_t)OK);
   3520 
   3521     CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage);
   3522 
   3523     OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
   3524 
   3525     CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingUnused);
   3526     imageDef->eColorFormat = format;
   3527     imageDef->nFrameWidth = width;
   3528     imageDef->nFrameHeight = height;
   3529 
   3530     switch (format) {
   3531         case OMX_COLOR_FormatYUV420PackedPlanar:
   3532         case OMX_COLOR_FormatYUV411Planar:
   3533         {
   3534             def.nBufferSize = (width * height * 3) / 2;
   3535             break;
   3536         }
   3537 
   3538         case OMX_COLOR_FormatCbYCrY:
   3539         {
   3540             def.nBufferSize = width * height * 2;
   3541             break;
   3542         }
   3543 
   3544         case OMX_COLOR_Format32bitARGB8888:
   3545         {
   3546             def.nBufferSize = width * height * 4;
   3547             break;
   3548         }
   3549 
   3550         case OMX_COLOR_Format16bitARGB4444:
   3551         case OMX_COLOR_Format16bitARGB1555:
   3552         case OMX_COLOR_Format16bitRGB565:
   3553         case OMX_COLOR_Format16bitBGR565:
   3554         {
   3555             def.nBufferSize = width * height * 2;
   3556             break;
   3557         }
   3558 
   3559         default:
   3560             CHECK(!"Should not be here. Unknown color format.");
   3561             break;
   3562     }
   3563 
   3564     def.nBufferCountActual = def.nBufferCountMin;
   3565 
   3566     err = mOMX->setParameter(
   3567             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   3568     CHECK_EQ(err, (status_t)OK);
   3569 }
   3570 
   3571 void OMXCodec::setJPEGInputFormat(
   3572         OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) {
   3573     OMX_PARAM_PORTDEFINITIONTYPE def;
   3574     InitOMXParams(&def);
   3575     def.nPortIndex = kPortIndexInput;
   3576 
   3577     status_t err = mOMX->getParameter(
   3578             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   3579     CHECK_EQ(err, (status_t)OK);
   3580 
   3581     CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage);
   3582     OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
   3583 
   3584     CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingJPEG);
   3585     imageDef->nFrameWidth = width;
   3586     imageDef->nFrameHeight = height;
   3587 
   3588     def.nBufferSize = compressedSize;
   3589     def.nBufferCountActual = def.nBufferCountMin;
   3590 
   3591     err = mOMX->setParameter(
   3592             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   3593     CHECK_EQ(err, (status_t)OK);
   3594 }
   3595 
   3596 void OMXCodec::addCodecSpecificData(const void *data, size_t size) {
   3597     CodecSpecificData *specific =
   3598         (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1);
   3599 
   3600     specific->mSize = size;
   3601     memcpy(specific->mData, data, size);
   3602 
   3603     mCodecSpecificData.push(specific);
   3604 }
   3605 
   3606 void OMXCodec::clearCodecSpecificData() {
   3607     for (size_t i = 0; i < mCodecSpecificData.size(); ++i) {
   3608         free(mCodecSpecificData.editItemAt(i));
   3609     }
   3610     mCodecSpecificData.clear();
   3611     mCodecSpecificDataIndex = 0;
   3612 }
   3613 
   3614 status_t OMXCodec::start(MetaData *meta) {
   3615     Mutex::Autolock autoLock(mLock);
   3616 
   3617     if (mState != LOADED) {
   3618         CODEC_LOGE("called start in the unexpected state: %d", mState);
   3619         return UNKNOWN_ERROR;
   3620     }
   3621 
   3622     sp<MetaData> params = new MetaData;
   3623     if (mQuirks & kWantsNALFragments) {
   3624         params->setInt32(kKeyWantsNALFragments, true);
   3625     }
   3626     if (meta) {
   3627         int64_t startTimeUs = 0;
   3628         int64_t timeUs;
   3629         if (meta->findInt64(kKeyTime, &timeUs)) {
   3630             startTimeUs = timeUs;
   3631         }
   3632         params->setInt64(kKeyTime, startTimeUs);
   3633     }
   3634 
   3635     mCodecSpecificDataIndex = 0;
   3636     mInitialBufferSubmit = true;
   3637     mSignalledEOS = false;
   3638     mNoMoreOutputData = false;
   3639     mOutputPortSettingsHaveChanged = false;
   3640     mSeekTimeUs = -1;
   3641     mSeekMode = ReadOptions::SEEK_CLOSEST_SYNC;
   3642     mTargetTimeUs = -1;
   3643     mFilledBuffers.clear();
   3644     mPaused = false;
   3645 
   3646     status_t err;
   3647     if (mIsEncoder) {
   3648         // Calling init() before starting its source so that we can configure,
   3649         // if supported, the source to use exactly the same number of input
   3650         // buffers as requested by the encoder.
   3651         if ((err = init()) != OK) {
   3652             CODEC_LOGE("init failed: %d", err);
   3653             return err;
   3654         }
   3655 
   3656         params->setInt32(kKeyNumBuffers, mPortBuffers[kPortIndexInput].size());
   3657         err = mSource->start(params.get());
   3658         if (err != OK) {
   3659             CODEC_LOGE("source failed to start: %d", err);
   3660             stopOmxComponent_l();
   3661         }
   3662         return err;
   3663     }
   3664 
   3665     // Decoder case
   3666     if ((err = mSource->start(params.get())) != OK) {
   3667         CODEC_LOGE("source failed to start: %d", err);
   3668         return err;
   3669     }
   3670     return init();
   3671 }
   3672 
   3673 status_t OMXCodec::stop() {
   3674     CODEC_LOGV("stop mState=%d", mState);
   3675     Mutex::Autolock autoLock(mLock);
   3676     status_t err = stopOmxComponent_l();
   3677     mSource->stop();
   3678 
   3679     CODEC_LOGV("stopped in state %d", mState);
   3680     return err;
   3681 }
   3682 
   3683 status_t OMXCodec::stopOmxComponent_l() {
   3684     CODEC_LOGV("stopOmxComponent_l mState=%d", mState);
   3685 
   3686     while (isIntermediateState(mState)) {
   3687         mAsyncCompletion.wait(mLock);
   3688     }
   3689 
   3690     bool isError = false;
   3691     switch (mState) {
   3692         case LOADED:
   3693             break;
   3694 
   3695         case ERROR:
   3696         {
   3697             if (mPortStatus[kPortIndexOutput] == ENABLING) {
   3698                 // Codec is in a wedged state (technical term)
   3699                 // We've seen an output port settings change from the codec,
   3700                 // We've disabled the output port, then freed the output
   3701                 // buffers, initiated re-enabling the output port but
   3702                 // failed to reallocate the output buffers.
   3703                 // There doesn't seem to be a way to orderly transition
   3704                 // from executing->idle and idle->loaded now that the
   3705                 // output port hasn't been reenabled yet...
   3706                 // Simply free as many resources as we can and pretend
   3707                 // that we're in LOADED state so that the destructor
   3708                 // will free the component instance without asserting.
   3709                 freeBuffersOnPort(kPortIndexInput, true /* onlyThoseWeOwn */);
   3710                 freeBuffersOnPort(kPortIndexOutput, true /* onlyThoseWeOwn */);
   3711                 setState(LOADED);
   3712                 break;
   3713             } else {
   3714                 OMX_STATETYPE state = OMX_StateInvalid;
   3715                 status_t err = mOMX->getState(mNode, &state);
   3716                 CHECK_EQ(err, (status_t)OK);
   3717 
   3718                 if (state != OMX_StateExecuting) {
   3719                     break;
   3720                 }
   3721                 // else fall through to the idling code
   3722             }
   3723 
   3724             isError = true;
   3725         }
   3726 
   3727         case EXECUTING:
   3728         {
   3729             setState(EXECUTING_TO_IDLE);
   3730 
   3731             if (mQuirks & kRequiresFlushBeforeShutdown) {
   3732                 CODEC_LOGV("This component requires a flush before transitioning "
   3733                      "from EXECUTING to IDLE...");
   3734 
   3735                 bool emulateInputFlushCompletion =
   3736                     !flushPortAsync(kPortIndexInput);
   3737 
   3738                 bool emulateOutputFlushCompletion =
   3739                     !flushPortAsync(kPortIndexOutput);
   3740 
   3741                 if (emulateInputFlushCompletion) {
   3742                     onCmdComplete(OMX_CommandFlush, kPortIndexInput);
   3743                 }
   3744 
   3745                 if (emulateOutputFlushCompletion) {
   3746                     onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
   3747                 }
   3748             } else {
   3749                 mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
   3750                 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
   3751 
   3752                 status_t err =
   3753                     mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
   3754                 CHECK_EQ(err, (status_t)OK);
   3755             }
   3756 
   3757             while (mState != LOADED && mState != ERROR) {
   3758                 mAsyncCompletion.wait(mLock);
   3759             }
   3760 
   3761             if (isError) {
   3762                 // We were in the ERROR state coming in, so restore that now
   3763                 // that we've idled the OMX component.
   3764                 setState(ERROR);
   3765             }
   3766 
   3767             break;
   3768         }
   3769 
   3770         default:
   3771         {
   3772             CHECK(!"should not be here.");
   3773             break;
   3774         }
   3775     }
   3776 
   3777     if (mLeftOverBuffer) {
   3778         mLeftOverBuffer->release();
   3779         mLeftOverBuffer = NULL;
   3780     }
   3781 
   3782     return OK;
   3783 }
   3784 
   3785 sp<MetaData> OMXCodec::getFormat() {
   3786     Mutex::Autolock autoLock(mLock);
   3787 
   3788     return mOutputFormat;
   3789 }
   3790 
   3791 status_t OMXCodec::read(
   3792         MediaBuffer **buffer, const ReadOptions *options) {
   3793     status_t err = OK;
   3794     *buffer = NULL;
   3795 
   3796     Mutex::Autolock autoLock(mLock);
   3797 
   3798     if (mState != EXECUTING && mState != RECONFIGURING) {
   3799         return UNKNOWN_ERROR;
   3800     }
   3801 
   3802     bool seeking = false;
   3803     int64_t seekTimeUs;
   3804     ReadOptions::SeekMode seekMode;
   3805     if (options && options->getSeekTo(&seekTimeUs, &seekMode)) {
   3806         seeking = true;
   3807     }
   3808 
   3809     if (mInitialBufferSubmit) {
   3810         mInitialBufferSubmit = false;
   3811 
   3812         if (seeking) {
   3813             CHECK(seekTimeUs >= 0);
   3814             mSeekTimeUs = seekTimeUs;
   3815             mSeekMode = seekMode;
   3816 
   3817             // There's no reason to trigger the code below, there's
   3818             // nothing to flush yet.
   3819             seeking = false;
   3820             mPaused = false;
   3821         }
   3822 
   3823         drainInputBuffers();
   3824 
   3825         if (mState == EXECUTING) {
   3826             // Otherwise mState == RECONFIGURING and this code will trigger
   3827             // after the output port is reenabled.
   3828             fillOutputBuffers();
   3829         }
   3830     }
   3831 
   3832     if (seeking) {
   3833         while (mState == RECONFIGURING) {
   3834             if ((err = waitForBufferFilled_l()) != OK) {
   3835                 return err;
   3836             }
   3837         }
   3838 
   3839         if (mState != EXECUTING) {
   3840             return UNKNOWN_ERROR;
   3841         }
   3842 
   3843         CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
   3844 
   3845         mSignalledEOS = false;
   3846 
   3847         CHECK(seekTimeUs >= 0);
   3848         mSeekTimeUs = seekTimeUs;
   3849         mSeekMode = seekMode;
   3850 
   3851         mFilledBuffers.clear();
   3852 
   3853         CHECK_EQ((int)mState, (int)EXECUTING);
   3854 
   3855         bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput);
   3856         bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput);
   3857 
   3858         if (emulateInputFlushCompletion) {
   3859             onCmdComplete(OMX_CommandFlush, kPortIndexInput);
   3860         }
   3861 
   3862         if (emulateOutputFlushCompletion) {
   3863             onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
   3864         }
   3865 
   3866         while (mSeekTimeUs >= 0) {
   3867             if ((err = waitForBufferFilled_l()) != OK) {
   3868                 return err;
   3869             }
   3870         }
   3871     }
   3872 
   3873     while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) {
   3874         if ((err = waitForBufferFilled_l()) != OK) {
   3875             return err;
   3876         }
   3877     }
   3878 
   3879     if (mState == ERROR) {
   3880         return UNKNOWN_ERROR;
   3881     }
   3882 
   3883     if (mFilledBuffers.empty()) {
   3884         return mSignalledEOS ? mFinalStatus : ERROR_END_OF_STREAM;
   3885     }
   3886 
   3887     if (mOutputPortSettingsHaveChanged) {
   3888         mOutputPortSettingsHaveChanged = false;
   3889 
   3890         return INFO_FORMAT_CHANGED;
   3891     }
   3892 
   3893     size_t index = *mFilledBuffers.begin();
   3894     mFilledBuffers.erase(mFilledBuffers.begin());
   3895 
   3896     BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
   3897     CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
   3898     info->mStatus = OWNED_BY_CLIENT;
   3899 
   3900     info->mMediaBuffer->add_ref();
   3901     if (mSkipCutBuffer != NULL) {
   3902         mSkipCutBuffer->submit(info->mMediaBuffer);
   3903     }
   3904     *buffer = info->mMediaBuffer;
   3905 
   3906     return OK;
   3907 }
   3908 
   3909 void OMXCodec::signalBufferReturned(MediaBuffer *buffer) {
   3910     Mutex::Autolock autoLock(mLock);
   3911 
   3912     Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
   3913     for (size_t i = 0; i < buffers->size(); ++i) {
   3914         BufferInfo *info = &buffers->editItemAt(i);
   3915 
   3916         if (info->mMediaBuffer == buffer) {
   3917             CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED);
   3918             CHECK_EQ((int)info->mStatus, (int)OWNED_BY_CLIENT);
   3919 
   3920             info->mStatus = OWNED_BY_US;
   3921 
   3922             if (buffer->graphicBuffer() == 0) {
   3923                 fillOutputBuffer(info);
   3924             } else {
   3925                 sp<MetaData> metaData = info->mMediaBuffer->meta_data();
   3926                 int32_t rendered = 0;
   3927                 if (!metaData->findInt32(kKeyRendered, &rendered)) {
   3928                     rendered = 0;
   3929                 }
   3930                 if (!rendered) {
   3931                     status_t err = cancelBufferToNativeWindow(info);
   3932                     if (err < 0) {
   3933                         return;
   3934                     }
   3935                 }
   3936 
   3937                 info->mStatus = OWNED_BY_NATIVE_WINDOW;
   3938 
   3939                 // Dequeue the next buffer from the native window.
   3940                 BufferInfo *nextBufInfo = dequeueBufferFromNativeWindow();
   3941                 if (nextBufInfo == 0) {
   3942                     return;
   3943                 }
   3944 
   3945                 // Give the buffer to the OMX node to fill.
   3946                 fillOutputBuffer(nextBufInfo);
   3947             }
   3948             return;
   3949         }
   3950     }
   3951 
   3952     CHECK(!"should not be here.");
   3953 }
   3954 
   3955 static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) {
   3956     static const char *kNames[] = {
   3957         "OMX_IMAGE_CodingUnused",
   3958         "OMX_IMAGE_CodingAutoDetect",
   3959         "OMX_IMAGE_CodingJPEG",
   3960         "OMX_IMAGE_CodingJPEG2K",
   3961         "OMX_IMAGE_CodingEXIF",
   3962         "OMX_IMAGE_CodingTIFF",
   3963         "OMX_IMAGE_CodingGIF",
   3964         "OMX_IMAGE_CodingPNG",
   3965         "OMX_IMAGE_CodingLZW",
   3966         "OMX_IMAGE_CodingBMP",
   3967     };
   3968 
   3969     size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
   3970 
   3971     if (type < 0 || (size_t)type >= numNames) {
   3972         return "UNKNOWN";
   3973     } else {
   3974         return kNames[type];
   3975     }
   3976 }
   3977 
   3978 static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) {
   3979     static const char *kNames[] = {
   3980         "OMX_COLOR_FormatUnused",
   3981         "OMX_COLOR_FormatMonochrome",
   3982         "OMX_COLOR_Format8bitRGB332",
   3983         "OMX_COLOR_Format12bitRGB444",
   3984         "OMX_COLOR_Format16bitARGB4444",
   3985         "OMX_COLOR_Format16bitARGB1555",
   3986         "OMX_COLOR_Format16bitRGB565",
   3987         "OMX_COLOR_Format16bitBGR565",
   3988         "OMX_COLOR_Format18bitRGB666",
   3989         "OMX_COLOR_Format18bitARGB1665",
   3990         "OMX_COLOR_Format19bitARGB1666",
   3991         "OMX_COLOR_Format24bitRGB888",
   3992         "OMX_COLOR_Format24bitBGR888",
   3993         "OMX_COLOR_Format24bitARGB1887",
   3994         "OMX_COLOR_Format25bitARGB1888",
   3995         "OMX_COLOR_Format32bitBGRA8888",
   3996         "OMX_COLOR_Format32bitARGB8888",
   3997         "OMX_COLOR_FormatYUV411Planar",
   3998         "OMX_COLOR_FormatYUV411PackedPlanar",
   3999         "OMX_COLOR_FormatYUV420Planar",
   4000         "OMX_COLOR_FormatYUV420PackedPlanar",
   4001         "OMX_COLOR_FormatYUV420SemiPlanar",
   4002         "OMX_COLOR_FormatYUV422Planar",
   4003         "OMX_COLOR_FormatYUV422PackedPlanar",
   4004         "OMX_COLOR_FormatYUV422SemiPlanar",
   4005         "OMX_COLOR_FormatYCbYCr",
   4006         "OMX_COLOR_FormatYCrYCb",
   4007         "OMX_COLOR_FormatCbYCrY",
   4008         "OMX_COLOR_FormatCrYCbY",
   4009         "OMX_COLOR_FormatYUV444Interleaved",
   4010         "OMX_COLOR_FormatRawBayer8bit",
   4011         "OMX_COLOR_FormatRawBayer10bit",
   4012         "OMX_COLOR_FormatRawBayer8bitcompressed",
   4013         "OMX_COLOR_FormatL2",
   4014         "OMX_COLOR_FormatL4",
   4015         "OMX_COLOR_FormatL8",
   4016         "OMX_COLOR_FormatL16",
   4017         "OMX_COLOR_FormatL24",
   4018         "OMX_COLOR_FormatL32",
   4019         "OMX_COLOR_FormatYUV420PackedSemiPlanar",
   4020         "OMX_COLOR_FormatYUV422PackedSemiPlanar",
   4021         "OMX_COLOR_Format18BitBGR666",
   4022         "OMX_COLOR_Format24BitARGB6666",
   4023         "OMX_COLOR_Format24BitABGR6666",
   4024     };
   4025 
   4026     size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
   4027 
   4028     if (type == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
   4029         return "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar";
   4030     } else if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) {
   4031         return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar";
   4032     } else if (type < 0 || (size_t)type >= numNames) {
   4033         return "UNKNOWN";
   4034     } else {
   4035         return kNames[type];
   4036     }
   4037 }
   4038 
   4039 static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) {
   4040     static const char *kNames[] = {
   4041         "OMX_VIDEO_CodingUnused",
   4042         "OMX_VIDEO_CodingAutoDetect",
   4043         "OMX_VIDEO_CodingMPEG2",
   4044         "OMX_VIDEO_CodingH263",
   4045         "OMX_VIDEO_CodingMPEG4",
   4046         "OMX_VIDEO_CodingWMV",
   4047         "OMX_VIDEO_CodingRV",
   4048         "OMX_VIDEO_CodingAVC",
   4049         "OMX_VIDEO_CodingMJPEG",
   4050     };
   4051 
   4052     size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
   4053 
   4054     if (type < 0 || (size_t)type >= numNames) {
   4055         return "UNKNOWN";
   4056     } else {
   4057         return kNames[type];
   4058     }
   4059 }
   4060 
   4061 static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) {
   4062     static const char *kNames[] = {
   4063         "OMX_AUDIO_CodingUnused",
   4064         "OMX_AUDIO_CodingAutoDetect",
   4065         "OMX_AUDIO_CodingPCM",
   4066         "OMX_AUDIO_CodingADPCM",
   4067         "OMX_AUDIO_CodingAMR",
   4068         "OMX_AUDIO_CodingGSMFR",
   4069         "OMX_AUDIO_CodingGSMEFR",
   4070         "OMX_AUDIO_CodingGSMHR",
   4071         "OMX_AUDIO_CodingPDCFR",
   4072         "OMX_AUDIO_CodingPDCEFR",
   4073         "OMX_AUDIO_CodingPDCHR",
   4074         "OMX_AUDIO_CodingTDMAFR",
   4075         "OMX_AUDIO_CodingTDMAEFR",
   4076         "OMX_AUDIO_CodingQCELP8",
   4077         "OMX_AUDIO_CodingQCELP13",
   4078         "OMX_AUDIO_CodingEVRC",
   4079         "OMX_AUDIO_CodingSMV",
   4080         "OMX_AUDIO_CodingG711",
   4081         "OMX_AUDIO_CodingG723",
   4082         "OMX_AUDIO_CodingG726",
   4083         "OMX_AUDIO_CodingG729",
   4084         "OMX_AUDIO_CodingAAC",
   4085         "OMX_AUDIO_CodingMP3",
   4086         "OMX_AUDIO_CodingSBC",
   4087         "OMX_AUDIO_CodingVORBIS",
   4088         "OMX_AUDIO_CodingWMA",
   4089         "OMX_AUDIO_CodingRA",
   4090         "OMX_AUDIO_CodingMIDI",
   4091     };
   4092 
   4093     size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
   4094 
   4095     if (type < 0 || (size_t)type >= numNames) {
   4096         return "UNKNOWN";
   4097     } else {
   4098         return kNames[type];
   4099     }
   4100 }
   4101 
   4102 static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) {
   4103     static const char *kNames[] = {
   4104         "OMX_AUDIO_PCMModeLinear",
   4105         "OMX_AUDIO_PCMModeALaw",
   4106         "OMX_AUDIO_PCMModeMULaw",
   4107     };
   4108 
   4109     size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
   4110 
   4111     if (type < 0 || (size_t)type >= numNames) {
   4112         return "UNKNOWN";
   4113     } else {
   4114         return kNames[type];
   4115     }
   4116 }
   4117 
   4118 static const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) {
   4119     static const char *kNames[] = {
   4120         "OMX_AUDIO_AMRBandModeUnused",
   4121         "OMX_AUDIO_AMRBandModeNB0",
   4122         "OMX_AUDIO_AMRBandModeNB1",
   4123         "OMX_AUDIO_AMRBandModeNB2",
   4124         "OMX_AUDIO_AMRBandModeNB3",
   4125         "OMX_AUDIO_AMRBandModeNB4",
   4126         "OMX_AUDIO_AMRBandModeNB5",
   4127         "OMX_AUDIO_AMRBandModeNB6",
   4128         "OMX_AUDIO_AMRBandModeNB7",
   4129         "OMX_AUDIO_AMRBandModeWB0",
   4130         "OMX_AUDIO_AMRBandModeWB1",
   4131         "OMX_AUDIO_AMRBandModeWB2",
   4132         "OMX_AUDIO_AMRBandModeWB3",
   4133         "OMX_AUDIO_AMRBandModeWB4",
   4134         "OMX_AUDIO_AMRBandModeWB5",
   4135         "OMX_AUDIO_AMRBandModeWB6",
   4136         "OMX_AUDIO_AMRBandModeWB7",
   4137         "OMX_AUDIO_AMRBandModeWB8",
   4138     };
   4139 
   4140     size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
   4141 
   4142     if (type < 0 || (size_t)type >= numNames) {
   4143         return "UNKNOWN";
   4144     } else {
   4145         return kNames[type];
   4146     }
   4147 }
   4148 
   4149 static const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) {
   4150     static const char *kNames[] = {
   4151         "OMX_AUDIO_AMRFrameFormatConformance",
   4152         "OMX_AUDIO_AMRFrameFormatIF1",
   4153         "OMX_AUDIO_AMRFrameFormatIF2",
   4154         "OMX_AUDIO_AMRFrameFormatFSF",
   4155         "OMX_AUDIO_AMRFrameFormatRTPPayload",
   4156         "OMX_AUDIO_AMRFrameFormatITU",
   4157     };
   4158 
   4159     size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
   4160 
   4161     if (type < 0 || (size_t)type >= numNames) {
   4162         return "UNKNOWN";
   4163     } else {
   4164         return kNames[type];
   4165     }
   4166 }
   4167 
   4168 void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
   4169     OMX_PARAM_PORTDEFINITIONTYPE def;
   4170     InitOMXParams(&def);
   4171     def.nPortIndex = portIndex;
   4172 
   4173     status_t err = mOMX->getParameter(
   4174             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   4175     CHECK_EQ(err, (status_t)OK);
   4176 
   4177     printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output");
   4178 
   4179     CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput)
   4180           || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput));
   4181 
   4182     printf("  nBufferCountActual = %ld\n", def.nBufferCountActual);
   4183     printf("  nBufferCountMin = %ld\n", def.nBufferCountMin);
   4184     printf("  nBufferSize = %ld\n", def.nBufferSize);
   4185 
   4186     switch (def.eDomain) {
   4187         case OMX_PortDomainImage:
   4188         {
   4189             const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
   4190 
   4191             printf("\n");
   4192             printf("  // Image\n");
   4193             printf("  nFrameWidth = %ld\n", imageDef->nFrameWidth);
   4194             printf("  nFrameHeight = %ld\n", imageDef->nFrameHeight);
   4195             printf("  nStride = %ld\n", imageDef->nStride);
   4196 
   4197             printf("  eCompressionFormat = %s\n",
   4198                    imageCompressionFormatString(imageDef->eCompressionFormat));
   4199 
   4200             printf("  eColorFormat = %s\n",
   4201                    colorFormatString(imageDef->eColorFormat));
   4202 
   4203             break;
   4204         }
   4205 
   4206         case OMX_PortDomainVideo:
   4207         {
   4208             OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
   4209 
   4210             printf("\n");
   4211             printf("  // Video\n");
   4212             printf("  nFrameWidth = %ld\n", videoDef->nFrameWidth);
   4213             printf("  nFrameHeight = %ld\n", videoDef->nFrameHeight);
   4214             printf("  nStride = %ld\n", videoDef->nStride);
   4215 
   4216             printf("  eCompressionFormat = %s\n",
   4217                    videoCompressionFormatString(videoDef->eCompressionFormat));
   4218 
   4219             printf("  eColorFormat = %s\n",
   4220                    colorFormatString(videoDef->eColorFormat));
   4221 
   4222             break;
   4223         }
   4224 
   4225         case OMX_PortDomainAudio:
   4226         {
   4227             OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
   4228 
   4229             printf("\n");
   4230             printf("  // Audio\n");
   4231             printf("  eEncoding = %s\n",
   4232                    audioCodingTypeString(audioDef->eEncoding));
   4233 
   4234             if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) {
   4235                 OMX_AUDIO_PARAM_PCMMODETYPE params;
   4236                 InitOMXParams(&params);
   4237                 params.nPortIndex = portIndex;
   4238 
   4239                 err = mOMX->getParameter(
   4240                         mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
   4241                 CHECK_EQ(err, (status_t)OK);
   4242 
   4243                 printf("  nSamplingRate = %ld\n", params.nSamplingRate);
   4244                 printf("  nChannels = %ld\n", params.nChannels);
   4245                 printf("  bInterleaved = %d\n", params.bInterleaved);
   4246                 printf("  nBitPerSample = %ld\n", params.nBitPerSample);
   4247 
   4248                 printf("  eNumData = %s\n",
   4249                        params.eNumData == OMX_NumericalDataSigned
   4250                         ? "signed" : "unsigned");
   4251 
   4252                 printf("  ePCMMode = %s\n", audioPCMModeString(params.ePCMMode));
   4253             } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) {
   4254                 OMX_AUDIO_PARAM_AMRTYPE amr;
   4255                 InitOMXParams(&amr);
   4256                 amr.nPortIndex = portIndex;
   4257 
   4258                 err = mOMX->getParameter(
   4259                         mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
   4260                 CHECK_EQ(err, (status_t)OK);
   4261 
   4262                 printf("  nChannels = %ld\n", amr.nChannels);
   4263                 printf("  eAMRBandMode = %s\n",
   4264                         amrBandModeString(amr.eAMRBandMode));
   4265                 printf("  eAMRFrameFormat = %s\n",
   4266                         amrFrameFormatString(amr.eAMRFrameFormat));
   4267             }
   4268 
   4269             break;
   4270         }
   4271 
   4272         default:
   4273         {
   4274             printf("  // Unknown\n");
   4275             break;
   4276         }
   4277     }
   4278 
   4279     printf("}\n");
   4280 }
   4281 
   4282 status_t OMXCodec::initNativeWindow() {
   4283     // Enable use of a GraphicBuffer as the output for this node.  This must
   4284     // happen before getting the IndexParamPortDefinition parameter because it
   4285     // will affect the pixel format that the node reports.
   4286     status_t err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
   4287     if (err != 0) {
   4288         return err;
   4289     }
   4290 
   4291     return OK;
   4292 }
   4293 
   4294 void OMXCodec::initNativeWindowCrop() {
   4295     int32_t left, top, right, bottom;
   4296 
   4297     CHECK(mOutputFormat->findRect(
   4298                         kKeyCropRect,
   4299                         &left, &top, &right, &bottom));
   4300 
   4301     android_native_rect_t crop;
   4302     crop.left = left;
   4303     crop.top = top;
   4304     crop.right = right + 1;
   4305     crop.bottom = bottom + 1;
   4306 
   4307     // We'll ignore any errors here, if the surface is
   4308     // already invalid, we'll know soon enough.
   4309     native_window_set_crop(mNativeWindow.get(), &crop);
   4310 }
   4311 
   4312 void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
   4313     mOutputFormat = new MetaData;
   4314     mOutputFormat->setCString(kKeyDecoderComponent, mComponentName);
   4315     if (mIsEncoder) {
   4316         int32_t timeScale;
   4317         if (inputFormat->findInt32(kKeyTimeScale, &timeScale)) {
   4318             mOutputFormat->setInt32(kKeyTimeScale, timeScale);
   4319         }
   4320     }
   4321 
   4322     OMX_PARAM_PORTDEFINITIONTYPE def;
   4323     InitOMXParams(&def);
   4324     def.nPortIndex = kPortIndexOutput;
   4325 
   4326     status_t err = mOMX->getParameter(
   4327             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   4328     CHECK_EQ(err, (status_t)OK);
   4329 
   4330     switch (def.eDomain) {
   4331         case OMX_PortDomainImage:
   4332         {
   4333             OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
   4334             CHECK_EQ((int)imageDef->eCompressionFormat,
   4335                      (int)OMX_IMAGE_CodingUnused);
   4336 
   4337             mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
   4338             mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat);
   4339             mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth);
   4340             mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight);
   4341             break;
   4342         }
   4343 
   4344         case OMX_PortDomainAudio:
   4345         {
   4346             OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio;
   4347 
   4348             if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) {
   4349                 OMX_AUDIO_PARAM_PCMMODETYPE params;
   4350                 InitOMXParams(&params);
   4351                 params.nPortIndex = kPortIndexOutput;
   4352 
   4353                 err = mOMX->getParameter(
   4354                         mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
   4355                 CHECK_EQ(err, (status_t)OK);
   4356 
   4357                 CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned);
   4358                 CHECK_EQ(params.nBitPerSample, 16u);
   4359                 CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear);
   4360 
   4361                 int32_t numChannels, sampleRate;
   4362                 inputFormat->findInt32(kKeyChannelCount, &numChannels);
   4363                 inputFormat->findInt32(kKeySampleRate, &sampleRate);
   4364 
   4365                 if ((OMX_U32)numChannels != params.nChannels) {
   4366                     ALOGV("Codec outputs a different number of channels than "
   4367                          "the input stream contains (contains %d channels, "
   4368                          "codec outputs %ld channels).",
   4369                          numChannels, params.nChannels);
   4370                 }
   4371 
   4372                 if (sampleRate != (int32_t)params.nSamplingRate) {
   4373                     ALOGV("Codec outputs at different sampling rate than "
   4374                          "what the input stream contains (contains data at "
   4375                          "%d Hz, codec outputs %lu Hz)",
   4376                          sampleRate, params.nSamplingRate);
   4377                 }
   4378 
   4379                 mOutputFormat->setCString(
   4380                         kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
   4381 
   4382                 // Use the codec-advertised number of channels, as some
   4383                 // codecs appear to output stereo even if the input data is
   4384                 // mono. If we know the codec lies about this information,
   4385                 // use the actual number of channels instead.
   4386                 mOutputFormat->setInt32(
   4387                         kKeyChannelCount,
   4388                         (mQuirks & kDecoderLiesAboutNumberOfChannels)
   4389                             ? numChannels : params.nChannels);
   4390 
   4391                 mOutputFormat->setInt32(kKeySampleRate, params.nSamplingRate);
   4392             } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) {
   4393                 OMX_AUDIO_PARAM_AMRTYPE amr;
   4394                 InitOMXParams(&amr);
   4395                 amr.nPortIndex = kPortIndexOutput;
   4396 
   4397                 err = mOMX->getParameter(
   4398                         mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
   4399                 CHECK_EQ(err, (status_t)OK);
   4400 
   4401                 CHECK_EQ(amr.nChannels, 1u);
   4402                 mOutputFormat->setInt32(kKeyChannelCount, 1);
   4403 
   4404                 if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0
   4405                     && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) {
   4406                     mOutputFormat->setCString(
   4407                             kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB);
   4408                     mOutputFormat->setInt32(kKeySampleRate, 8000);
   4409                 } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0
   4410                             && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) {
   4411                     mOutputFormat->setCString(
   4412                             kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB);
   4413                     mOutputFormat->setInt32(kKeySampleRate, 16000);
   4414                 } else {
   4415                     CHECK(!"Unknown AMR band mode.");
   4416                 }
   4417             } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) {
   4418                 mOutputFormat->setCString(
   4419                         kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
   4420                 int32_t numChannels, sampleRate, bitRate;
   4421                 inputFormat->findInt32(kKeyChannelCount, &numChannels);
   4422                 inputFormat->findInt32(kKeySampleRate, &sampleRate);
   4423                 inputFormat->findInt32(kKeyBitRate, &bitRate);
   4424                 mOutputFormat->setInt32(kKeyChannelCount, numChannels);
   4425                 mOutputFormat->setInt32(kKeySampleRate, sampleRate);
   4426                 mOutputFormat->setInt32(kKeyBitRate, bitRate);
   4427             } else {
   4428                 CHECK(!"Should not be here. Unknown audio encoding.");
   4429             }
   4430             break;
   4431         }
   4432 
   4433         case OMX_PortDomainVideo:
   4434         {
   4435             OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
   4436 
   4437             if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) {
   4438                 mOutputFormat->setCString(
   4439                         kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
   4440             } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
   4441                 mOutputFormat->setCString(
   4442                         kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
   4443             } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) {
   4444                 mOutputFormat->setCString(
   4445                         kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
   4446             } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) {
   4447                 mOutputFormat->setCString(
   4448                         kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
   4449             } else {
   4450                 CHECK(!"Unknown compression format.");
   4451             }
   4452 
   4453             mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth);
   4454             mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight);
   4455             mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat);
   4456 
   4457             if (!mIsEncoder) {
   4458                 OMX_CONFIG_RECTTYPE rect;
   4459                 InitOMXParams(&rect);
   4460                 rect.nPortIndex = kPortIndexOutput;
   4461                 status_t err =
   4462                         mOMX->getConfig(
   4463                             mNode, OMX_IndexConfigCommonOutputCrop,
   4464                             &rect, sizeof(rect));
   4465 
   4466                 CODEC_LOGI(
   4467                         "video dimensions are %ld x %ld",
   4468                         video_def->nFrameWidth, video_def->nFrameHeight);
   4469 
   4470                 if (err == OK) {
   4471                     CHECK_GE(rect.nLeft, 0);
   4472                     CHECK_GE(rect.nTop, 0);
   4473                     CHECK_GE(rect.nWidth, 0u);
   4474                     CHECK_GE(rect.nHeight, 0u);
   4475                     CHECK_LE(rect.nLeft + rect.nWidth - 1, video_def->nFrameWidth);
   4476                     CHECK_LE(rect.nTop + rect.nHeight - 1, video_def->nFrameHeight);
   4477 
   4478                     mOutputFormat->setRect(
   4479                             kKeyCropRect,
   4480                             rect.nLeft,
   4481                             rect.nTop,
   4482                             rect.nLeft + rect.nWidth - 1,
   4483                             rect.nTop + rect.nHeight - 1);
   4484 
   4485                     CODEC_LOGI(
   4486                             "Crop rect is %ld x %ld @ (%ld, %ld)",
   4487                             rect.nWidth, rect.nHeight, rect.nLeft, rect.nTop);
   4488                 } else {
   4489                     mOutputFormat->setRect(
   4490                             kKeyCropRect,
   4491                             0, 0,
   4492                             video_def->nFrameWidth - 1,
   4493                             video_def->nFrameHeight - 1);
   4494                 }
   4495 
   4496                 if (mNativeWindow != NULL) {
   4497                      initNativeWindowCrop();
   4498                 }
   4499             }
   4500             break;
   4501         }
   4502 
   4503         default:
   4504         {
   4505             CHECK(!"should not be here, neither audio nor video.");
   4506             break;
   4507         }
   4508     }
   4509 
   4510     // If the input format contains rotation information, flag the output
   4511     // format accordingly.
   4512 
   4513     int32_t rotationDegrees;
   4514     if (mSource->getFormat()->findInt32(kKeyRotation, &rotationDegrees)) {
   4515         mOutputFormat->setInt32(kKeyRotation, rotationDegrees);
   4516     }
   4517 }
   4518 
   4519 status_t OMXCodec::pause() {
   4520     Mutex::Autolock autoLock(mLock);
   4521 
   4522     mPaused = true;
   4523 
   4524     return OK;
   4525 }
   4526 
   4527 ////////////////////////////////////////////////////////////////////////////////
   4528 
   4529 status_t QueryCodecs(
   4530         const sp<IOMX> &omx,
   4531         const char *mime, bool queryDecoders, bool hwCodecOnly,
   4532         Vector<CodecCapabilities> *results) {
   4533     Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
   4534     results->clear();
   4535 
   4536     OMXCodec::findMatchingCodecs(mime,
   4537             !queryDecoders /*createEncoder*/,
   4538             NULL /*matchComponentName*/,
   4539             hwCodecOnly ? OMXCodec::kHardwareCodecsOnly : 0 /*flags*/,
   4540             &matchingCodecs);
   4541 
   4542     for (size_t c = 0; c < matchingCodecs.size(); c++) {
   4543         const char *componentName = matchingCodecs.itemAt(c).mName.string();
   4544 
   4545         results->push();
   4546         CodecCapabilities *caps = &results->editItemAt(results->size() - 1);
   4547 
   4548         status_t err =
   4549             QueryCodec(omx, componentName, mime, !queryDecoders, caps);
   4550 
   4551         if (err != OK) {
   4552             results->removeAt(results->size() - 1);
   4553         }
   4554     }
   4555 
   4556     return OK;
   4557 }
   4558 
   4559 status_t QueryCodec(
   4560         const sp<IOMX> &omx,
   4561         const char *componentName, const char *mime,
   4562         bool isEncoder,
   4563         CodecCapabilities *caps) {
   4564     if (strncmp(componentName, "OMX.", 4)) {
   4565         // Not an OpenMax component but a software codec.
   4566 
   4567         caps->mComponentName = componentName;
   4568         return OK;
   4569     }
   4570 
   4571     sp<OMXCodecObserver> observer = new OMXCodecObserver;
   4572     IOMX::node_id node;
   4573     status_t err = omx->allocateNode(componentName, observer, &node);
   4574 
   4575     if (err != OK) {
   4576         return err;
   4577     }
   4578 
   4579     OMXCodec::setComponentRole(omx, node, isEncoder, mime);
   4580 
   4581     caps->mComponentName = componentName;
   4582 
   4583     OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
   4584     InitOMXParams(&param);
   4585 
   4586     param.nPortIndex = !isEncoder ? 0 : 1;
   4587 
   4588     for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
   4589         err = omx->getParameter(
   4590                 node, OMX_IndexParamVideoProfileLevelQuerySupported,
   4591                 &param, sizeof(param));
   4592 
   4593         if (err != OK) {
   4594             break;
   4595         }
   4596 
   4597         CodecProfileLevel profileLevel;
   4598         profileLevel.mProfile = param.eProfile;
   4599         profileLevel.mLevel = param.eLevel;
   4600 
   4601         caps->mProfileLevels.push(profileLevel);
   4602     }
   4603 
   4604     // Color format query
   4605     OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
   4606     InitOMXParams(&portFormat);
   4607     portFormat.nPortIndex = !isEncoder ? 1 : 0;
   4608     for (portFormat.nIndex = 0;; ++portFormat.nIndex)  {
   4609         err = omx->getParameter(
   4610                 node, OMX_IndexParamVideoPortFormat,
   4611                 &portFormat, sizeof(portFormat));
   4612         if (err != OK) {
   4613             break;
   4614         }
   4615         caps->mColorFormats.push(portFormat.eColorFormat);
   4616     }
   4617 
   4618     CHECK_EQ(omx->freeNode(node), (status_t)OK);
   4619 
   4620     return OK;
   4621 }
   4622 
   4623 status_t QueryCodecs(
   4624         const sp<IOMX> &omx,
   4625         const char *mimeType, bool queryDecoders,
   4626         Vector<CodecCapabilities> *results) {
   4627     return QueryCodecs(omx, mimeType, queryDecoders, false /*hwCodecOnly*/, results);
   4628 }
   4629 
   4630 // These are supposed be equivalent to the logic in
   4631 // "audio_channel_out_mask_from_count".
   4632 status_t getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) {
   4633     switch (numChannels) {
   4634         case 1:
   4635             map[0] = OMX_AUDIO_ChannelCF;
   4636             break;
   4637         case 2:
   4638             map[0] = OMX_AUDIO_ChannelLF;
   4639             map[1] = OMX_AUDIO_ChannelRF;
   4640             break;
   4641         case 3:
   4642             map[0] = OMX_AUDIO_ChannelLF;
   4643             map[1] = OMX_AUDIO_ChannelRF;
   4644             map[2] = OMX_AUDIO_ChannelCF;
   4645             break;
   4646         case 4:
   4647             map[0] = OMX_AUDIO_ChannelLF;
   4648             map[1] = OMX_AUDIO_ChannelRF;
   4649             map[2] = OMX_AUDIO_ChannelLR;
   4650             map[3] = OMX_AUDIO_ChannelRR;
   4651             break;
   4652         case 5:
   4653             map[0] = OMX_AUDIO_ChannelLF;
   4654             map[1] = OMX_AUDIO_ChannelRF;
   4655             map[2] = OMX_AUDIO_ChannelCF;
   4656             map[3] = OMX_AUDIO_ChannelLR;
   4657             map[4] = OMX_AUDIO_ChannelRR;
   4658             break;
   4659         case 6:
   4660             map[0] = OMX_AUDIO_ChannelLF;
   4661             map[1] = OMX_AUDIO_ChannelRF;
   4662             map[2] = OMX_AUDIO_ChannelCF;
   4663             map[3] = OMX_AUDIO_ChannelLFE;
   4664             map[4] = OMX_AUDIO_ChannelLR;
   4665             map[5] = OMX_AUDIO_ChannelRR;
   4666             break;
   4667         case 7:
   4668             map[0] = OMX_AUDIO_ChannelLF;
   4669             map[1] = OMX_AUDIO_ChannelRF;
   4670             map[2] = OMX_AUDIO_ChannelCF;
   4671             map[3] = OMX_AUDIO_ChannelLFE;
   4672             map[4] = OMX_AUDIO_ChannelLR;
   4673             map[5] = OMX_AUDIO_ChannelRR;
   4674             map[6] = OMX_AUDIO_ChannelCS;
   4675             break;
   4676         case 8:
   4677             map[0] = OMX_AUDIO_ChannelLF;
   4678             map[1] = OMX_AUDIO_ChannelRF;
   4679             map[2] = OMX_AUDIO_ChannelCF;
   4680             map[3] = OMX_AUDIO_ChannelLFE;
   4681             map[4] = OMX_AUDIO_ChannelLR;
   4682             map[5] = OMX_AUDIO_ChannelRR;
   4683             map[6] = OMX_AUDIO_ChannelLS;
   4684             map[7] = OMX_AUDIO_ChannelRS;
   4685             break;
   4686         default:
   4687             return -EINVAL;
   4688     }
   4689 
   4690     return OK;
   4691 }
   4692 
   4693 }  // namespace android
   4694