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