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