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