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