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