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