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/AACDecoder.h"
     22 #include "include/AACEncoder.h"
     23 #include "include/AMRNBDecoder.h"
     24 #include "include/AMRNBEncoder.h"
     25 #include "include/AMRWBDecoder.h"
     26 #include "include/AMRWBEncoder.h"
     27 #include "include/AVCDecoder.h"
     28 #include "include/AVCEncoder.h"
     29 #include "include/G711Decoder.h"
     30 #include "include/M4vH263Decoder.h"
     31 #include "include/M4vH263Encoder.h"
     32 #include "include/MP3Decoder.h"
     33 #include "include/VorbisDecoder.h"
     34 #include "include/VPXDecoder.h"
     35 
     36 #include "include/ESDS.h"
     37 
     38 #include <binder/IServiceManager.h>
     39 #include <binder/MemoryDealer.h>
     40 #include <binder/ProcessState.h>
     41 #include <media/IMediaPlayerService.h>
     42 #include <media/stagefright/MediaBuffer.h>
     43 #include <media/stagefright/MediaBufferGroup.h>
     44 #include <media/stagefright/MediaDebug.h>
     45 #include <media/stagefright/MediaDefs.h>
     46 #include <media/stagefright/MediaExtractor.h>
     47 #include <media/stagefright/MetaData.h>
     48 #include <media/stagefright/OMXCodec.h>
     49 #include <media/stagefright/Utils.h>
     50 #include <utils/Vector.h>
     51 
     52 #include <OMX_Audio.h>
     53 #include <OMX_Component.h>
     54 
     55 #include "include/ThreadedSource.h"
     56 
     57 namespace android {
     58 
     59 static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
     60 
     61 struct CodecInfo {
     62     const char *mime;
     63     const char *codec;
     64 };
     65 
     66 #define FACTORY_CREATE(name) \
     67 static sp<MediaSource> Make##name(const sp<MediaSource> &source) { \
     68     return new name(source); \
     69 }
     70 
     71 #define FACTORY_CREATE_ENCODER(name) \
     72 static sp<MediaSource> Make##name(const sp<MediaSource> &source, const sp<MetaData> &meta) { \
     73     return new name(source, meta); \
     74 }
     75 
     76 #define FACTORY_REF(name) { #name, Make##name },
     77 
     78 FACTORY_CREATE(MP3Decoder)
     79 FACTORY_CREATE(AMRNBDecoder)
     80 FACTORY_CREATE(AMRWBDecoder)
     81 FACTORY_CREATE(AACDecoder)
     82 FACTORY_CREATE(AVCDecoder)
     83 FACTORY_CREATE(G711Decoder)
     84 FACTORY_CREATE(M4vH263Decoder)
     85 FACTORY_CREATE(VorbisDecoder)
     86 FACTORY_CREATE(VPXDecoder)
     87 FACTORY_CREATE_ENCODER(AMRNBEncoder)
     88 FACTORY_CREATE_ENCODER(AMRWBEncoder)
     89 FACTORY_CREATE_ENCODER(AACEncoder)
     90 FACTORY_CREATE_ENCODER(AVCEncoder)
     91 FACTORY_CREATE_ENCODER(M4vH263Encoder)
     92 
     93 static sp<MediaSource> InstantiateSoftwareEncoder(
     94         const char *name, const sp<MediaSource> &source,
     95         const sp<MetaData> &meta) {
     96     struct FactoryInfo {
     97         const char *name;
     98         sp<MediaSource> (*CreateFunc)(const sp<MediaSource> &, const sp<MetaData> &);
     99     };
    100 
    101     static const FactoryInfo kFactoryInfo[] = {
    102         FACTORY_REF(AMRNBEncoder)
    103         FACTORY_REF(AMRWBEncoder)
    104         FACTORY_REF(AACEncoder)
    105         FACTORY_REF(AVCEncoder)
    106         FACTORY_REF(M4vH263Encoder)
    107     };
    108     for (size_t i = 0;
    109          i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) {
    110         if (!strcmp(name, kFactoryInfo[i].name)) {
    111             return (*kFactoryInfo[i].CreateFunc)(source, meta);
    112         }
    113     }
    114 
    115     return NULL;
    116 }
    117 
    118 static sp<MediaSource> InstantiateSoftwareCodec(
    119         const char *name, const sp<MediaSource> &source) {
    120     struct FactoryInfo {
    121         const char *name;
    122         sp<MediaSource> (*CreateFunc)(const sp<MediaSource> &);
    123     };
    124 
    125     static const FactoryInfo kFactoryInfo[] = {
    126         FACTORY_REF(MP3Decoder)
    127         FACTORY_REF(AMRNBDecoder)
    128         FACTORY_REF(AMRWBDecoder)
    129         FACTORY_REF(AACDecoder)
    130         FACTORY_REF(AVCDecoder)
    131         FACTORY_REF(G711Decoder)
    132         FACTORY_REF(M4vH263Decoder)
    133         FACTORY_REF(VorbisDecoder)
    134         FACTORY_REF(VPXDecoder)
    135     };
    136     for (size_t i = 0;
    137          i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) {
    138         if (!strcmp(name, kFactoryInfo[i].name)) {
    139             if (!strcmp(name, "VPXDecoder")) {
    140                 return new ThreadedSource(
    141                         (*kFactoryInfo[i].CreateFunc)(source));
    142             }
    143             return (*kFactoryInfo[i].CreateFunc)(source);
    144         }
    145     }
    146 
    147     return NULL;
    148 }
    149 
    150 #undef FACTORY_REF
    151 #undef FACTORY_CREATE
    152 
    153 static const CodecInfo kDecoderInfo[] = {
    154     { MEDIA_MIMETYPE_IMAGE_JPEG, "OMX.TI.JPEG.decode" },
    155 //    { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" },
    156     { MEDIA_MIMETYPE_AUDIO_MPEG, "MP3Decoder" },
    157 //    { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.PV.mp3dec" },
    158 //    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.decode" },
    159     { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBDecoder" },
    160 //    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrdec" },
    161     { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" },
    162     { MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBDecoder" },
    163 //    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.PV.amrdec" },
    164     { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.decode" },
    165     { MEDIA_MIMETYPE_AUDIO_AAC, "AACDecoder" },
    166 //    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacdec" },
    167     { MEDIA_MIMETYPE_AUDIO_G711_ALAW, "G711Decoder" },
    168     { MEDIA_MIMETYPE_AUDIO_G711_MLAW, "G711Decoder" },
    169     { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.7x30.video.decoder.mpeg4" },
    170     { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.decoder.mpeg4" },
    171     { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" },
    172     { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.SEC.MPEG4.Decoder" },
    173     { MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH263Decoder" },
    174 //    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4dec" },
    175     { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.7x30.video.decoder.h263" },
    176     { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" },
    177     { MEDIA_MIMETYPE_VIDEO_H263, "OMX.SEC.H263.Decoder" },
    178     { MEDIA_MIMETYPE_VIDEO_H263, "M4vH263Decoder" },
    179 //    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263dec" },
    180     { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.7x30.video.decoder.avc" },
    181     { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" },
    182     { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" },
    183     { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.SEC.AVC.Decoder" },
    184     { MEDIA_MIMETYPE_VIDEO_AVC, "AVCDecoder" },
    185 //    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcdec" },
    186     { MEDIA_MIMETYPE_AUDIO_VORBIS, "VorbisDecoder" },
    187     { MEDIA_MIMETYPE_VIDEO_VPX, "VPXDecoder" },
    188 };
    189 
    190 static const CodecInfo kEncoderInfo[] = {
    191     { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.encode" },
    192     { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBEncoder" },
    193     { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.encode" },
    194     { MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBEncoder" },
    195     { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.encode" },
    196     { MEDIA_MIMETYPE_AUDIO_AAC, "AACEncoder" },
    197 //    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacenc" },
    198     { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.7x30.video.encoder.mpeg4" },
    199     { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.encoder.mpeg4" },
    200     { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.encoder" },
    201     { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.SEC.MPEG4.Encoder" },
    202     { MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH263Encoder" },
    203 //    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4enc" },
    204     { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.7x30.video.encoder.h263" },
    205     { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.encoder.h263" },
    206     { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.encoder" },
    207     { MEDIA_MIMETYPE_VIDEO_H263, "OMX.SEC.H263.Encoder" },
    208     { MEDIA_MIMETYPE_VIDEO_H263, "M4vH263Encoder" },
    209 //    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263enc" },
    210     { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.7x30.video.encoder.avc" },
    211     { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.encoder.avc" },
    212     { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.encoder" },
    213     { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.SEC.AVC.Encoder" },
    214     { MEDIA_MIMETYPE_VIDEO_AVC, "AVCEncoder" },
    215 //    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcenc" },
    216 };
    217 
    218 #undef OPTIONAL
    219 
    220 #define CODEC_LOGI(x, ...) LOGI("[%s] "x, mComponentName, ##__VA_ARGS__)
    221 #define CODEC_LOGV(x, ...) LOGV("[%s] "x, mComponentName, ##__VA_ARGS__)
    222 #define CODEC_LOGE(x, ...) LOGE("[%s] "x, mComponentName, ##__VA_ARGS__)
    223 
    224 struct OMXCodecObserver : public BnOMXObserver {
    225     OMXCodecObserver() {
    226     }
    227 
    228     void setCodec(const sp<OMXCodec> &target) {
    229         mTarget = target;
    230     }
    231 
    232     // from IOMXObserver
    233     virtual void onMessage(const omx_message &msg) {
    234         sp<OMXCodec> codec = mTarget.promote();
    235 
    236         if (codec.get() != NULL) {
    237             Mutex::Autolock autoLock(codec->mLock);
    238             codec->on_message(msg);
    239             codec.clear();
    240         }
    241     }
    242 
    243 protected:
    244     virtual ~OMXCodecObserver() {}
    245 
    246 private:
    247     wp<OMXCodec> mTarget;
    248 
    249     OMXCodecObserver(const OMXCodecObserver &);
    250     OMXCodecObserver &operator=(const OMXCodecObserver &);
    251 };
    252 
    253 static const char *GetCodec(const CodecInfo *info, size_t numInfos,
    254                             const char *mime, int index) {
    255     CHECK(index >= 0);
    256     for(size_t i = 0; i < numInfos; ++i) {
    257         if (!strcasecmp(mime, info[i].mime)) {
    258             if (index == 0) {
    259                 return info[i].codec;
    260             }
    261 
    262             --index;
    263         }
    264     }
    265 
    266     return NULL;
    267 }
    268 
    269 enum {
    270     kAVCProfileBaseline      = 0x42,
    271     kAVCProfileMain          = 0x4d,
    272     kAVCProfileExtended      = 0x58,
    273     kAVCProfileHigh          = 0x64,
    274     kAVCProfileHigh10        = 0x6e,
    275     kAVCProfileHigh422       = 0x7a,
    276     kAVCProfileHigh444       = 0xf4,
    277     kAVCProfileCAVLC444Intra = 0x2c
    278 };
    279 
    280 static const char *AVCProfileToString(uint8_t profile) {
    281     switch (profile) {
    282         case kAVCProfileBaseline:
    283             return "Baseline";
    284         case kAVCProfileMain:
    285             return "Main";
    286         case kAVCProfileExtended:
    287             return "Extended";
    288         case kAVCProfileHigh:
    289             return "High";
    290         case kAVCProfileHigh10:
    291             return "High 10";
    292         case kAVCProfileHigh422:
    293             return "High 422";
    294         case kAVCProfileHigh444:
    295             return "High 444";
    296         case kAVCProfileCAVLC444Intra:
    297             return "CAVLC 444 Intra";
    298         default:   return "Unknown";
    299     }
    300 }
    301 
    302 template<class T>
    303 static void InitOMXParams(T *params) {
    304     params->nSize = sizeof(T);
    305     params->nVersion.s.nVersionMajor = 1;
    306     params->nVersion.s.nVersionMinor = 0;
    307     params->nVersion.s.nRevision = 0;
    308     params->nVersion.s.nStep = 0;
    309 }
    310 
    311 static bool IsSoftwareCodec(const char *componentName) {
    312     if (!strncmp("OMX.PV.", componentName, 7)) {
    313         return true;
    314     }
    315 
    316     return false;
    317 }
    318 
    319 // A sort order in which non-OMX components are first,
    320 // followed by software codecs, i.e. OMX.PV.*, followed
    321 // by all the others.
    322 static int CompareSoftwareCodecsFirst(
    323         const String8 *elem1, const String8 *elem2) {
    324     bool isNotOMX1 = strncmp(elem1->string(), "OMX.", 4);
    325     bool isNotOMX2 = strncmp(elem2->string(), "OMX.", 4);
    326 
    327     if (isNotOMX1) {
    328         if (isNotOMX2) { return 0; }
    329         return -1;
    330     }
    331     if (isNotOMX2) {
    332         return 1;
    333     }
    334 
    335     bool isSoftwareCodec1 = IsSoftwareCodec(elem1->string());
    336     bool isSoftwareCodec2 = IsSoftwareCodec(elem2->string());
    337 
    338     if (isSoftwareCodec1) {
    339         if (isSoftwareCodec2) { return 0; }
    340         return -1;
    341     }
    342 
    343     if (isSoftwareCodec2) {
    344         return 1;
    345     }
    346 
    347     return 0;
    348 }
    349 
    350 // static
    351 uint32_t OMXCodec::getComponentQuirks(
    352         const char *componentName, bool isEncoder) {
    353     uint32_t quirks = 0;
    354 
    355     if (!strcmp(componentName, "OMX.PV.avcdec")) {
    356         quirks |= kWantsNALFragments;
    357     }
    358     if (!strcmp(componentName, "OMX.TI.MP3.decode")) {
    359         quirks |= kNeedsFlushBeforeDisable;
    360         quirks |= kDecoderLiesAboutNumberOfChannels;
    361     }
    362     if (!strcmp(componentName, "OMX.TI.AAC.decode")) {
    363         quirks |= kNeedsFlushBeforeDisable;
    364         quirks |= kRequiresFlushCompleteEmulation;
    365         quirks |= kSupportsMultipleFramesPerInputBuffer;
    366     }
    367     if (!strncmp(componentName, "OMX.qcom.video.encoder.", 23)) {
    368         quirks |= kRequiresLoadedToIdleAfterAllocation;
    369         quirks |= kRequiresAllocateBufferOnInputPorts;
    370         quirks |= kRequiresAllocateBufferOnOutputPorts;
    371         if (!strncmp(componentName, "OMX.qcom.video.encoder.avc", 26)) {
    372 
    373             // The AVC encoder advertises the size of output buffers
    374             // based on the input video resolution and assumes
    375             // the worst/least compression ratio is 0.5. It is found that
    376             // sometimes, the output buffer size is larger than
    377             // size advertised by the encoder.
    378             quirks |= kRequiresLargerEncoderOutputBuffer;
    379         }
    380     }
    381     if (!strncmp(componentName, "OMX.qcom.7x30.video.encoder.", 28)) {
    382     }
    383     if (!strncmp(componentName, "OMX.qcom.video.decoder.", 23)) {
    384         quirks |= kRequiresAllocateBufferOnOutputPorts;
    385         quirks |= kDefersOutputBufferAllocation;
    386     }
    387     if (!strncmp(componentName, "OMX.qcom.7x30.video.decoder.", 28)) {
    388         quirks |= kRequiresAllocateBufferOnInputPorts;
    389         quirks |= kRequiresAllocateBufferOnOutputPorts;
    390         quirks |= kDefersOutputBufferAllocation;
    391     }
    392 
    393     if (!strncmp(componentName, "OMX.TI.", 7)) {
    394         // Apparently I must not use OMX_UseBuffer on either input or
    395         // output ports on any of the TI components or quote:
    396         // "(I) may have unexpected problem (sic) which can be timing related
    397         //  and hard to reproduce."
    398 
    399         quirks |= kRequiresAllocateBufferOnInputPorts;
    400         quirks |= kRequiresAllocateBufferOnOutputPorts;
    401         if (!strncmp(componentName, "OMX.TI.Video.encoder", 20)) {
    402             quirks |= kAvoidMemcopyInputRecordingFrames;
    403         }
    404     }
    405 
    406     if (!strcmp(componentName, "OMX.TI.Video.Decoder")) {
    407         quirks |= kInputBufferSizesAreBogus;
    408     }
    409 
    410     if (!strncmp(componentName, "OMX.SEC.", 8) && !isEncoder) {
    411         // These output buffers contain no video data, just some
    412         // opaque information that allows the overlay to display their
    413         // contents.
    414         quirks |= kOutputBuffersAreUnreadable;
    415     }
    416 
    417     if (!strncmp(componentName, "OMX.SEC.", 8) && isEncoder) {
    418         // These input buffers contain meta data (for instance,
    419         // information helps locate the actual YUV data, or
    420         // the physical address of the YUV data).
    421         quirks |= kStoreMetaDataInInputVideoBuffers;
    422     }
    423 
    424     return quirks;
    425 }
    426 
    427 // static
    428 void OMXCodec::findMatchingCodecs(
    429         const char *mime,
    430         bool createEncoder, const char *matchComponentName,
    431         uint32_t flags,
    432         Vector<String8> *matchingCodecs) {
    433     matchingCodecs->clear();
    434 
    435     for (int index = 0;; ++index) {
    436         const char *componentName;
    437 
    438         if (createEncoder) {
    439             componentName = GetCodec(
    440                     kEncoderInfo,
    441                     sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]),
    442                     mime, index);
    443         } else {
    444             componentName = GetCodec(
    445                     kDecoderInfo,
    446                     sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]),
    447                     mime, index);
    448         }
    449 
    450         if (!componentName) {
    451             break;
    452         }
    453 
    454         // If a specific codec is requested, skip the non-matching ones.
    455         if (matchComponentName && strcmp(componentName, matchComponentName)) {
    456             continue;
    457         }
    458 
    459         matchingCodecs->push(String8(componentName));
    460     }
    461 
    462     if (flags & kPreferSoftwareCodecs) {
    463         matchingCodecs->sort(CompareSoftwareCodecsFirst);
    464     }
    465 }
    466 
    467 // static
    468 sp<MediaSource> OMXCodec::Create(
    469         const sp<IOMX> &omx,
    470         const sp<MetaData> &meta, bool createEncoder,
    471         const sp<MediaSource> &source,
    472         const char *matchComponentName,
    473         uint32_t flags) {
    474     const char *mime;
    475     bool success = meta->findCString(kKeyMIMEType, &mime);
    476     CHECK(success);
    477 
    478     Vector<String8> matchingCodecs;
    479     findMatchingCodecs(
    480             mime, createEncoder, matchComponentName, flags, &matchingCodecs);
    481 
    482     if (matchingCodecs.isEmpty()) {
    483         return NULL;
    484     }
    485 
    486     sp<OMXCodecObserver> observer = new OMXCodecObserver;
    487     IOMX::node_id node = 0;
    488 
    489     const char *componentName;
    490     for (size_t i = 0; i < matchingCodecs.size(); ++i) {
    491         componentName = matchingCodecs[i].string();
    492 
    493         sp<MediaSource> softwareCodec = createEncoder?
    494             InstantiateSoftwareEncoder(componentName, source, meta):
    495             InstantiateSoftwareCodec(componentName, source);
    496 
    497         if (softwareCodec != NULL) {
    498             LOGV("Successfully allocated software codec '%s'", componentName);
    499 
    500             return softwareCodec;
    501         }
    502 
    503         LOGV("Attempting to allocate OMX node '%s'", componentName);
    504 
    505         uint32_t quirks = getComponentQuirks(componentName, createEncoder);
    506 
    507         if (!createEncoder
    508                 && (quirks & kOutputBuffersAreUnreadable)
    509                 && (flags & kClientNeedsFramebuffer)) {
    510             if (strncmp(componentName, "OMX.SEC.", 8)) {
    511                 // For OMX.SEC.* decoders we can enable a special mode that
    512                 // gives the client access to the framebuffer contents.
    513 
    514                 LOGW("Component '%s' does not give the client access to "
    515                      "the framebuffer contents. Skipping.",
    516                      componentName);
    517 
    518                 continue;
    519             }
    520         }
    521 
    522         status_t err = omx->allocateNode(componentName, observer, &node);
    523         if (err == OK) {
    524             LOGV("Successfully allocated OMX node '%s'", componentName);
    525 
    526             sp<OMXCodec> codec = new OMXCodec(
    527                     omx, node, quirks,
    528                     createEncoder, mime, componentName,
    529                     source);
    530 
    531             observer->setCodec(codec);
    532 
    533             err = codec->configureCodec(meta, flags);
    534 
    535             if (err == OK) {
    536                 return codec;
    537             }
    538 
    539             LOGV("Failed to configure codec '%s'", componentName);
    540         }
    541     }
    542 
    543     return NULL;
    544 }
    545 
    546 status_t OMXCodec::configureCodec(const sp<MetaData> &meta, uint32_t flags) {
    547     if (!(flags & kIgnoreCodecSpecificData)) {
    548         uint32_t type;
    549         const void *data;
    550         size_t size;
    551         if (meta->findData(kKeyESDS, &type, &data, &size)) {
    552             ESDS esds((const char *)data, size);
    553             CHECK_EQ(esds.InitCheck(), OK);
    554 
    555             const void *codec_specific_data;
    556             size_t codec_specific_data_size;
    557             esds.getCodecSpecificInfo(
    558                     &codec_specific_data, &codec_specific_data_size);
    559 
    560             addCodecSpecificData(
    561                     codec_specific_data, codec_specific_data_size);
    562         } else if (meta->findData(kKeyAVCC, &type, &data, &size)) {
    563             // Parse the AVCDecoderConfigurationRecord
    564 
    565             const uint8_t *ptr = (const uint8_t *)data;
    566 
    567             CHECK(size >= 7);
    568             CHECK_EQ(ptr[0], 1);  // configurationVersion == 1
    569             uint8_t profile = ptr[1];
    570             uint8_t level = ptr[3];
    571 
    572             // There is decodable content out there that fails the following
    573             // assertion, let's be lenient for now...
    574             // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
    575 
    576             size_t lengthSize = 1 + (ptr[4] & 3);
    577 
    578             // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
    579             // violates it...
    580             // CHECK((ptr[5] >> 5) == 7);  // reserved
    581 
    582             size_t numSeqParameterSets = ptr[5] & 31;
    583 
    584             ptr += 6;
    585             size -= 6;
    586 
    587             for (size_t i = 0; i < numSeqParameterSets; ++i) {
    588                 CHECK(size >= 2);
    589                 size_t length = U16_AT(ptr);
    590 
    591                 ptr += 2;
    592                 size -= 2;
    593 
    594                 CHECK(size >= length);
    595 
    596                 addCodecSpecificData(ptr, length);
    597 
    598                 ptr += length;
    599                 size -= length;
    600             }
    601 
    602             CHECK(size >= 1);
    603             size_t numPictureParameterSets = *ptr;
    604             ++ptr;
    605             --size;
    606 
    607             for (size_t i = 0; i < numPictureParameterSets; ++i) {
    608                 CHECK(size >= 2);
    609                 size_t length = U16_AT(ptr);
    610 
    611                 ptr += 2;
    612                 size -= 2;
    613 
    614                 CHECK(size >= length);
    615 
    616                 addCodecSpecificData(ptr, length);
    617 
    618                 ptr += length;
    619                 size -= length;
    620             }
    621 
    622             CODEC_LOGV(
    623                     "AVC profile = %d (%s), level = %d",
    624                     (int)profile, AVCProfileToString(profile), level);
    625 
    626             if (!strcmp(mComponentName, "OMX.TI.Video.Decoder")
    627                 && (profile != kAVCProfileBaseline || level > 30)) {
    628                 // This stream exceeds the decoder's capabilities. The decoder
    629                 // does not handle this gracefully and would clobber the heap
    630                 // and wreak havoc instead...
    631 
    632                 LOGE("Profile and/or level exceed the decoder's capabilities.");
    633                 return ERROR_UNSUPPORTED;
    634             }
    635         }
    636     }
    637 
    638     int32_t bitRate = 0;
    639     if (mIsEncoder) {
    640         CHECK(meta->findInt32(kKeyBitRate, &bitRate));
    641     }
    642     if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mMIME)) {
    643         setAMRFormat(false /* isWAMR */, bitRate);
    644     }
    645     if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mMIME)) {
    646         setAMRFormat(true /* isWAMR */, bitRate);
    647     }
    648     if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mMIME)) {
    649         int32_t numChannels, sampleRate;
    650         CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
    651         CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
    652 
    653         setAACFormat(numChannels, sampleRate, bitRate);
    654     }
    655 
    656     if (!strncasecmp(mMIME, "video/", 6)) {
    657 
    658         if (mIsEncoder) {
    659             setVideoInputFormat(mMIME, meta);
    660         } else {
    661             int32_t width, height;
    662             bool success = meta->findInt32(kKeyWidth, &width);
    663             success = success && meta->findInt32(kKeyHeight, &height);
    664             CHECK(success);
    665             status_t err = setVideoOutputFormat(
    666                     mMIME, width, height);
    667 
    668             if (err != OK) {
    669                 return err;
    670             }
    671         }
    672     }
    673 
    674     if (!strcasecmp(mMIME, MEDIA_MIMETYPE_IMAGE_JPEG)
    675         && !strcmp(mComponentName, "OMX.TI.JPEG.decode")) {
    676         OMX_COLOR_FORMATTYPE format =
    677             OMX_COLOR_Format32bitARGB8888;
    678             // OMX_COLOR_FormatYUV420PackedPlanar;
    679             // OMX_COLOR_FormatCbYCrY;
    680             // OMX_COLOR_FormatYUV411Planar;
    681 
    682         int32_t width, height;
    683         bool success = meta->findInt32(kKeyWidth, &width);
    684         success = success && meta->findInt32(kKeyHeight, &height);
    685 
    686         int32_t compressedSize;
    687         success = success && meta->findInt32(
    688                 kKeyMaxInputSize, &compressedSize);
    689 
    690         CHECK(success);
    691         CHECK(compressedSize > 0);
    692 
    693         setImageOutputFormat(format, width, height);
    694         setJPEGInputFormat(width, height, (OMX_U32)compressedSize);
    695     }
    696 
    697     int32_t maxInputSize;
    698     if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
    699         setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize);
    700     }
    701 
    702     if (!strcmp(mComponentName, "OMX.TI.AMR.encode")
    703         || !strcmp(mComponentName, "OMX.TI.WBAMR.encode")
    704         || !strcmp(mComponentName, "OMX.TI.AAC.encode")) {
    705         setMinBufferSize(kPortIndexOutput, 8192);  // XXX
    706     }
    707 
    708     initOutputFormat(meta);
    709 
    710     if ((flags & kClientNeedsFramebuffer)
    711             && !strncmp(mComponentName, "OMX.SEC.", 8)) {
    712         OMX_INDEXTYPE index;
    713 
    714         status_t err =
    715             mOMX->getExtensionIndex(
    716                     mNode,
    717                     "OMX.SEC.index.ThumbnailMode",
    718                     &index);
    719 
    720         if (err != OK) {
    721             return err;
    722         }
    723 
    724         OMX_BOOL enable = OMX_TRUE;
    725         err = mOMX->setConfig(mNode, index, &enable, sizeof(enable));
    726 
    727         if (err != OK) {
    728             CODEC_LOGE("setConfig('OMX.SEC.index.ThumbnailMode') "
    729                        "returned error 0x%08x", err);
    730 
    731             return err;
    732         }
    733 
    734         mQuirks &= ~kOutputBuffersAreUnreadable;
    735     }
    736 
    737     return OK;
    738 }
    739 
    740 void OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) {
    741     OMX_PARAM_PORTDEFINITIONTYPE def;
    742     InitOMXParams(&def);
    743     def.nPortIndex = portIndex;
    744 
    745     status_t err = mOMX->getParameter(
    746             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    747     CHECK_EQ(err, OK);
    748 
    749     if ((portIndex == kPortIndexInput && (mQuirks & kInputBufferSizesAreBogus))
    750         || (def.nBufferSize < size)) {
    751         def.nBufferSize = size;
    752     }
    753 
    754     err = mOMX->setParameter(
    755             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    756     CHECK_EQ(err, OK);
    757 
    758     err = mOMX->getParameter(
    759             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    760     CHECK_EQ(err, OK);
    761 
    762     // Make sure the setting actually stuck.
    763     if (portIndex == kPortIndexInput
    764             && (mQuirks & kInputBufferSizesAreBogus)) {
    765         CHECK_EQ(def.nBufferSize, size);
    766     } else {
    767         CHECK(def.nBufferSize >= size);
    768     }
    769 }
    770 
    771 status_t OMXCodec::setVideoPortFormatType(
    772         OMX_U32 portIndex,
    773         OMX_VIDEO_CODINGTYPE compressionFormat,
    774         OMX_COLOR_FORMATTYPE colorFormat) {
    775     OMX_VIDEO_PARAM_PORTFORMATTYPE format;
    776     InitOMXParams(&format);
    777     format.nPortIndex = portIndex;
    778     format.nIndex = 0;
    779     bool found = false;
    780 
    781     OMX_U32 index = 0;
    782     for (;;) {
    783         format.nIndex = index;
    784         status_t err = mOMX->getParameter(
    785                 mNode, OMX_IndexParamVideoPortFormat,
    786                 &format, sizeof(format));
    787 
    788         if (err != OK) {
    789             return err;
    790         }
    791 
    792         // The following assertion is violated by TI's video decoder.
    793         // CHECK_EQ(format.nIndex, index);
    794 
    795 #if 1
    796         CODEC_LOGV("portIndex: %ld, index: %ld, eCompressionFormat=%d eColorFormat=%d",
    797              portIndex,
    798              index, format.eCompressionFormat, format.eColorFormat);
    799 #endif
    800 
    801         if (!strcmp("OMX.TI.Video.encoder", mComponentName)) {
    802             if (portIndex == kPortIndexInput
    803                     && colorFormat == format.eColorFormat) {
    804                 // eCompressionFormat does not seem right.
    805                 found = true;
    806                 break;
    807             }
    808             if (portIndex == kPortIndexOutput
    809                     && compressionFormat == format.eCompressionFormat) {
    810                 // eColorFormat does not seem right.
    811                 found = true;
    812                 break;
    813             }
    814         }
    815 
    816         if (format.eCompressionFormat == compressionFormat
    817             && format.eColorFormat == colorFormat) {
    818             found = true;
    819             break;
    820         }
    821 
    822         ++index;
    823     }
    824 
    825     if (!found) {
    826         return UNKNOWN_ERROR;
    827     }
    828 
    829     CODEC_LOGV("found a match.");
    830     status_t err = mOMX->setParameter(
    831             mNode, OMX_IndexParamVideoPortFormat,
    832             &format, sizeof(format));
    833 
    834     return err;
    835 }
    836 
    837 static size_t getFrameSize(
    838         OMX_COLOR_FORMATTYPE colorFormat, int32_t width, int32_t height) {
    839     switch (colorFormat) {
    840         case OMX_COLOR_FormatYCbYCr:
    841         case OMX_COLOR_FormatCbYCrY:
    842             return width * height * 2;
    843 
    844         case OMX_COLOR_FormatYUV420Planar:
    845         case OMX_COLOR_FormatYUV420SemiPlanar:
    846             return (width * height * 3) / 2;
    847 
    848         default:
    849             CHECK(!"Should not be here. Unsupported color format.");
    850             break;
    851     }
    852 }
    853 
    854 status_t OMXCodec::findTargetColorFormat(
    855         const sp<MetaData>& meta, OMX_COLOR_FORMATTYPE *colorFormat) {
    856     LOGV("findTargetColorFormat");
    857     CHECK(mIsEncoder);
    858 
    859     *colorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
    860     int32_t targetColorFormat;
    861     if (meta->findInt32(kKeyColorFormat, &targetColorFormat)) {
    862         *colorFormat = (OMX_COLOR_FORMATTYPE) targetColorFormat;
    863     } else {
    864         if (!strcasecmp("OMX.TI.Video.encoder", mComponentName)) {
    865             *colorFormat = OMX_COLOR_FormatYCbYCr;
    866         }
    867     }
    868 
    869     // Check whether the target color format is supported.
    870     return isColorFormatSupported(*colorFormat, kPortIndexInput);
    871 }
    872 
    873 status_t OMXCodec::isColorFormatSupported(
    874         OMX_COLOR_FORMATTYPE colorFormat, int portIndex) {
    875     LOGV("isColorFormatSupported: %d", static_cast<int>(colorFormat));
    876 
    877     // Enumerate all the color formats supported by
    878     // the omx component to see whether the given
    879     // color format is supported.
    880     OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
    881     InitOMXParams(&portFormat);
    882     portFormat.nPortIndex = portIndex;
    883     OMX_U32 index = 0;
    884     portFormat.nIndex = index;
    885     while (true) {
    886         if (OMX_ErrorNone != mOMX->getParameter(
    887                 mNode, OMX_IndexParamVideoPortFormat,
    888                 &portFormat, sizeof(portFormat))) {
    889             break;
    890         }
    891         // Make sure that omx component does not overwrite
    892         // the incremented index (bug 2897413).
    893         CHECK_EQ(index, portFormat.nIndex);
    894         if ((portFormat.eColorFormat == colorFormat)) {
    895             LOGV("Found supported color format: %d", portFormat.eColorFormat);
    896             return OK;  // colorFormat is supported!
    897         }
    898         ++index;
    899         portFormat.nIndex = index;
    900 
    901         // OMX Spec defines less than 50 color formats
    902         // 1000 is more than enough for us to tell whether the omx
    903         // component in question is buggy or not.
    904         if (index >= 1000) {
    905             LOGE("More than %ld color formats are supported???", index);
    906             break;
    907         }
    908     }
    909 
    910     LOGE("color format %d is not supported", colorFormat);
    911     return UNKNOWN_ERROR;
    912 }
    913 
    914 void OMXCodec::setVideoInputFormat(
    915         const char *mime, const sp<MetaData>& meta) {
    916 
    917     int32_t width, height, frameRate, bitRate, stride, sliceHeight;
    918     bool success = meta->findInt32(kKeyWidth, &width);
    919     success = success && meta->findInt32(kKeyHeight, &height);
    920     success = success && meta->findInt32(kKeySampleRate, &frameRate);
    921     success = success && meta->findInt32(kKeyBitRate, &bitRate);
    922     success = success && meta->findInt32(kKeyStride, &stride);
    923     success = success && meta->findInt32(kKeySliceHeight, &sliceHeight);
    924     CHECK(success);
    925     CHECK(stride != 0);
    926 
    927     OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
    928     if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
    929         compressionFormat = OMX_VIDEO_CodingAVC;
    930     } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
    931         compressionFormat = OMX_VIDEO_CodingMPEG4;
    932     } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
    933         compressionFormat = OMX_VIDEO_CodingH263;
    934     } else {
    935         LOGE("Not a supported video mime type: %s", mime);
    936         CHECK(!"Should not be here. Not a supported video mime type.");
    937     }
    938 
    939     OMX_COLOR_FORMATTYPE colorFormat;
    940     CHECK_EQ(OK, findTargetColorFormat(meta, &colorFormat));
    941 
    942     status_t err;
    943     OMX_PARAM_PORTDEFINITIONTYPE def;
    944     OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
    945 
    946     //////////////////////// Input port /////////////////////////
    947     CHECK_EQ(setVideoPortFormatType(
    948             kPortIndexInput, OMX_VIDEO_CodingUnused,
    949             colorFormat), OK);
    950 
    951     InitOMXParams(&def);
    952     def.nPortIndex = kPortIndexInput;
    953 
    954     err = mOMX->getParameter(
    955             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    956     CHECK_EQ(err, OK);
    957 
    958     def.nBufferSize = getFrameSize(colorFormat,
    959             stride > 0? stride: -stride, sliceHeight);
    960 
    961     CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
    962 
    963     video_def->nFrameWidth = width;
    964     video_def->nFrameHeight = height;
    965     video_def->nStride = stride;
    966     video_def->nSliceHeight = sliceHeight;
    967     video_def->xFramerate = (frameRate << 16);  // Q16 format
    968     video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
    969     video_def->eColorFormat = colorFormat;
    970 
    971     err = mOMX->setParameter(
    972             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    973     CHECK_EQ(err, OK);
    974 
    975     //////////////////////// Output port /////////////////////////
    976     CHECK_EQ(setVideoPortFormatType(
    977             kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused),
    978             OK);
    979     InitOMXParams(&def);
    980     def.nPortIndex = kPortIndexOutput;
    981 
    982     err = mOMX->getParameter(
    983             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    984 
    985     CHECK_EQ(err, OK);
    986     CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
    987 
    988     video_def->nFrameWidth = width;
    989     video_def->nFrameHeight = height;
    990     video_def->xFramerate = 0;      // No need for output port
    991     video_def->nBitrate = bitRate;  // Q16 format
    992     video_def->eCompressionFormat = compressionFormat;
    993     video_def->eColorFormat = OMX_COLOR_FormatUnused;
    994     if (mQuirks & kRequiresLargerEncoderOutputBuffer) {
    995         // Increases the output buffer size
    996         def.nBufferSize = ((def.nBufferSize * 3) >> 1);
    997     }
    998 
    999     err = mOMX->setParameter(
   1000             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   1001     CHECK_EQ(err, OK);
   1002 
   1003     /////////////////// Codec-specific ////////////////////////
   1004     switch (compressionFormat) {
   1005         case OMX_VIDEO_CodingMPEG4:
   1006         {
   1007             CHECK_EQ(setupMPEG4EncoderParameters(meta), OK);
   1008             break;
   1009         }
   1010 
   1011         case OMX_VIDEO_CodingH263:
   1012             CHECK_EQ(setupH263EncoderParameters(meta), OK);
   1013             break;
   1014 
   1015         case OMX_VIDEO_CodingAVC:
   1016         {
   1017             CHECK_EQ(setupAVCEncoderParameters(meta), OK);
   1018             break;
   1019         }
   1020 
   1021         default:
   1022             CHECK(!"Support for this compressionFormat to be implemented.");
   1023             break;
   1024     }
   1025 }
   1026 
   1027 static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
   1028     if (iFramesInterval < 0) {
   1029         return 0xFFFFFFFF;
   1030     } else if (iFramesInterval == 0) {
   1031         return 0;
   1032     }
   1033     OMX_U32 ret = frameRate * iFramesInterval;
   1034     CHECK(ret > 1);
   1035     return ret;
   1036 }
   1037 
   1038 status_t OMXCodec::setupErrorCorrectionParameters() {
   1039     OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
   1040     InitOMXParams(&errorCorrectionType);
   1041     errorCorrectionType.nPortIndex = kPortIndexOutput;
   1042 
   1043     status_t err = mOMX->getParameter(
   1044             mNode, OMX_IndexParamVideoErrorCorrection,
   1045             &errorCorrectionType, sizeof(errorCorrectionType));
   1046     if (err != OK) {
   1047         LOGW("Error correction param query is not supported");
   1048         return OK;  // Optional feature. Ignore this failure
   1049     }
   1050 
   1051     errorCorrectionType.bEnableHEC = OMX_FALSE;
   1052     errorCorrectionType.bEnableResync = OMX_TRUE;
   1053     errorCorrectionType.nResynchMarkerSpacing = 256;
   1054     errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
   1055     errorCorrectionType.bEnableRVLC = OMX_FALSE;
   1056 
   1057     err = mOMX->setParameter(
   1058             mNode, OMX_IndexParamVideoErrorCorrection,
   1059             &errorCorrectionType, sizeof(errorCorrectionType));
   1060     if (err != OK) {
   1061         LOGW("Error correction param configuration is not supported");
   1062     }
   1063 
   1064     // Optional feature. Ignore the failure.
   1065     return OK;
   1066 }
   1067 
   1068 status_t OMXCodec::setupBitRate(int32_t bitRate) {
   1069     OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
   1070     InitOMXParams(&bitrateType);
   1071     bitrateType.nPortIndex = kPortIndexOutput;
   1072 
   1073     status_t err = mOMX->getParameter(
   1074             mNode, OMX_IndexParamVideoBitrate,
   1075             &bitrateType, sizeof(bitrateType));
   1076     CHECK_EQ(err, OK);
   1077 
   1078     bitrateType.eControlRate = OMX_Video_ControlRateVariable;
   1079     bitrateType.nTargetBitrate = bitRate;
   1080 
   1081     err = mOMX->setParameter(
   1082             mNode, OMX_IndexParamVideoBitrate,
   1083             &bitrateType, sizeof(bitrateType));
   1084     CHECK_EQ(err, OK);
   1085     return OK;
   1086 }
   1087 
   1088 status_t OMXCodec::getVideoProfileLevel(
   1089         const sp<MetaData>& meta,
   1090         const CodecProfileLevel& defaultProfileLevel,
   1091         CodecProfileLevel &profileLevel) {
   1092     CODEC_LOGV("Default profile: %ld, level %ld",
   1093             defaultProfileLevel.mProfile, defaultProfileLevel.mLevel);
   1094 
   1095     // Are the default profile and level overwriten?
   1096     int32_t profile, level;
   1097     if (!meta->findInt32(kKeyVideoProfile, &profile)) {
   1098         profile = defaultProfileLevel.mProfile;
   1099     }
   1100     if (!meta->findInt32(kKeyVideoLevel, &level)) {
   1101         level = defaultProfileLevel.mLevel;
   1102     }
   1103     CODEC_LOGV("Target profile: %d, level: %d", profile, level);
   1104 
   1105     // Are the target profile and level supported by the encoder?
   1106     OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
   1107     InitOMXParams(&param);
   1108     param.nPortIndex = kPortIndexOutput;
   1109     for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
   1110         status_t err = mOMX->getParameter(
   1111                 mNode, OMX_IndexParamVideoProfileLevelQuerySupported,
   1112                 &param, sizeof(param));
   1113 
   1114         if (err != OK) break;
   1115 
   1116         int32_t supportedProfile = static_cast<int32_t>(param.eProfile);
   1117         int32_t supportedLevel = static_cast<int32_t>(param.eLevel);
   1118         CODEC_LOGV("Supported profile: %d, level %d",
   1119             supportedProfile, supportedLevel);
   1120 
   1121         if (profile == supportedProfile &&
   1122             level <= supportedLevel) {
   1123             // We can further check whether the level is a valid
   1124             // value; but we will leave that to the omx encoder component
   1125             // via OMX_SetParameter call.
   1126             profileLevel.mProfile = profile;
   1127             profileLevel.mLevel = level;
   1128             return OK;
   1129         }
   1130     }
   1131 
   1132     CODEC_LOGE("Target profile (%d) and level (%d) is not supported",
   1133             profile, level);
   1134     return BAD_VALUE;
   1135 }
   1136 
   1137 status_t OMXCodec::setupH263EncoderParameters(const sp<MetaData>& meta) {
   1138     int32_t iFramesInterval, frameRate, bitRate;
   1139     bool success = meta->findInt32(kKeyBitRate, &bitRate);
   1140     success = success && meta->findInt32(kKeySampleRate, &frameRate);
   1141     success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
   1142     CHECK(success);
   1143     OMX_VIDEO_PARAM_H263TYPE h263type;
   1144     InitOMXParams(&h263type);
   1145     h263type.nPortIndex = kPortIndexOutput;
   1146 
   1147     status_t err = mOMX->getParameter(
   1148             mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
   1149     CHECK_EQ(err, OK);
   1150 
   1151     h263type.nAllowedPictureTypes =
   1152         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
   1153 
   1154     h263type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
   1155     if (h263type.nPFrames == 0) {
   1156         h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
   1157     }
   1158     h263type.nBFrames = 0;
   1159 
   1160     // Check profile and level parameters
   1161     CodecProfileLevel defaultProfileLevel, profileLevel;
   1162     defaultProfileLevel.mProfile = h263type.eProfile;
   1163     defaultProfileLevel.mLevel = h263type.eLevel;
   1164     err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel);
   1165     if (err != OK) return err;
   1166     h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profileLevel.mProfile);
   1167     h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(profileLevel.mLevel);
   1168 
   1169     h263type.bPLUSPTYPEAllowed = OMX_FALSE;
   1170     h263type.bForceRoundingTypeToZero = OMX_FALSE;
   1171     h263type.nPictureHeaderRepetition = 0;
   1172     h263type.nGOBHeaderInterval = 0;
   1173 
   1174     err = mOMX->setParameter(
   1175             mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
   1176     CHECK_EQ(err, OK);
   1177 
   1178     CHECK_EQ(setupBitRate(bitRate), OK);
   1179     CHECK_EQ(setupErrorCorrectionParameters(), OK);
   1180 
   1181     return OK;
   1182 }
   1183 
   1184 status_t OMXCodec::setupMPEG4EncoderParameters(const sp<MetaData>& meta) {
   1185     int32_t iFramesInterval, frameRate, bitRate;
   1186     bool success = meta->findInt32(kKeyBitRate, &bitRate);
   1187     success = success && meta->findInt32(kKeySampleRate, &frameRate);
   1188     success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
   1189     CHECK(success);
   1190     OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
   1191     InitOMXParams(&mpeg4type);
   1192     mpeg4type.nPortIndex = kPortIndexOutput;
   1193 
   1194     status_t err = mOMX->getParameter(
   1195             mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
   1196     CHECK_EQ(err, OK);
   1197 
   1198     mpeg4type.nSliceHeaderSpacing = 0;
   1199     mpeg4type.bSVH = OMX_FALSE;
   1200     mpeg4type.bGov = OMX_FALSE;
   1201 
   1202     mpeg4type.nAllowedPictureTypes =
   1203         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
   1204 
   1205     mpeg4type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
   1206     if (mpeg4type.nPFrames == 0) {
   1207         mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
   1208     }
   1209     mpeg4type.nBFrames = 0;
   1210     mpeg4type.nIDCVLCThreshold = 0;
   1211     mpeg4type.bACPred = OMX_TRUE;
   1212     mpeg4type.nMaxPacketSize = 256;
   1213     mpeg4type.nTimeIncRes = 1000;
   1214     mpeg4type.nHeaderExtension = 0;
   1215     mpeg4type.bReversibleVLC = OMX_FALSE;
   1216 
   1217     // Check profile and level parameters
   1218     CodecProfileLevel defaultProfileLevel, profileLevel;
   1219     defaultProfileLevel.mProfile = mpeg4type.eProfile;
   1220     defaultProfileLevel.mLevel = mpeg4type.eLevel;
   1221     err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel);
   1222     if (err != OK) return err;
   1223     mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profileLevel.mProfile);
   1224     mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(profileLevel.mLevel);
   1225 
   1226     err = mOMX->setParameter(
   1227             mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
   1228     CHECK_EQ(err, OK);
   1229 
   1230     CHECK_EQ(setupBitRate(bitRate), OK);
   1231     CHECK_EQ(setupErrorCorrectionParameters(), OK);
   1232 
   1233     return OK;
   1234 }
   1235 
   1236 status_t OMXCodec::setupAVCEncoderParameters(const sp<MetaData>& meta) {
   1237     int32_t iFramesInterval, frameRate, bitRate;
   1238     bool success = meta->findInt32(kKeyBitRate, &bitRate);
   1239     success = success && meta->findInt32(kKeySampleRate, &frameRate);
   1240     success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
   1241     CHECK(success);
   1242 
   1243     OMX_VIDEO_PARAM_AVCTYPE h264type;
   1244     InitOMXParams(&h264type);
   1245     h264type.nPortIndex = kPortIndexOutput;
   1246 
   1247     status_t err = mOMX->getParameter(
   1248             mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
   1249     CHECK_EQ(err, OK);
   1250 
   1251     h264type.nAllowedPictureTypes =
   1252         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
   1253 
   1254     h264type.nSliceHeaderSpacing = 0;
   1255     h264type.nBFrames = 0;   // No B frames support yet
   1256     h264type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
   1257     if (h264type.nPFrames == 0) {
   1258         h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
   1259     }
   1260 
   1261     // Check profile and level parameters
   1262     CodecProfileLevel defaultProfileLevel, profileLevel;
   1263     defaultProfileLevel.mProfile = h264type.eProfile;
   1264     defaultProfileLevel.mLevel = h264type.eLevel;
   1265     err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel);
   1266     if (err != OK) return err;
   1267     h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profileLevel.mProfile);
   1268     h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(profileLevel.mLevel);
   1269 
   1270     if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
   1271         h264type.bUseHadamard = OMX_TRUE;
   1272         h264type.nRefFrames = 1;
   1273         h264type.nRefIdx10ActiveMinus1 = 0;
   1274         h264type.nRefIdx11ActiveMinus1 = 0;
   1275         h264type.bEntropyCodingCABAC = OMX_FALSE;
   1276         h264type.bWeightedPPrediction = OMX_FALSE;
   1277         h264type.bconstIpred = OMX_FALSE;
   1278         h264type.bDirect8x8Inference = OMX_FALSE;
   1279         h264type.bDirectSpatialTemporal = OMX_FALSE;
   1280         h264type.nCabacInitIdc = 0;
   1281     }
   1282 
   1283     if (h264type.nBFrames != 0) {
   1284         h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
   1285     }
   1286 
   1287     h264type.bEnableUEP = OMX_FALSE;
   1288     h264type.bEnableFMO = OMX_FALSE;
   1289     h264type.bEnableASO = OMX_FALSE;
   1290     h264type.bEnableRS = OMX_FALSE;
   1291     h264type.bFrameMBsOnly = OMX_TRUE;
   1292     h264type.bMBAFF = OMX_FALSE;
   1293     h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
   1294 
   1295     err = mOMX->setParameter(
   1296             mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
   1297     CHECK_EQ(err, OK);
   1298 
   1299     CHECK_EQ(setupBitRate(bitRate), OK);
   1300 
   1301     return OK;
   1302 }
   1303 
   1304 status_t OMXCodec::setVideoOutputFormat(
   1305         const char *mime, OMX_U32 width, OMX_U32 height) {
   1306     CODEC_LOGV("setVideoOutputFormat width=%ld, height=%ld", width, height);
   1307 
   1308     OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
   1309     if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
   1310         compressionFormat = OMX_VIDEO_CodingAVC;
   1311     } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
   1312         compressionFormat = OMX_VIDEO_CodingMPEG4;
   1313     } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
   1314         compressionFormat = OMX_VIDEO_CodingH263;
   1315     } else {
   1316         LOGE("Not a supported video mime type: %s", mime);
   1317         CHECK(!"Should not be here. Not a supported video mime type.");
   1318     }
   1319 
   1320     status_t err = setVideoPortFormatType(
   1321             kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
   1322 
   1323     if (err != OK) {
   1324         return err;
   1325     }
   1326 
   1327 #if 1
   1328     {
   1329         OMX_VIDEO_PARAM_PORTFORMATTYPE format;
   1330         InitOMXParams(&format);
   1331         format.nPortIndex = kPortIndexOutput;
   1332         format.nIndex = 0;
   1333 
   1334         status_t err = mOMX->getParameter(
   1335                 mNode, OMX_IndexParamVideoPortFormat,
   1336                 &format, sizeof(format));
   1337         CHECK_EQ(err, OK);
   1338         CHECK_EQ(format.eCompressionFormat, OMX_VIDEO_CodingUnused);
   1339 
   1340         static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
   1341 
   1342         CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
   1343                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
   1344                || format.eColorFormat == OMX_COLOR_FormatCbYCrY
   1345                || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar);
   1346 
   1347         err = mOMX->setParameter(
   1348                 mNode, OMX_IndexParamVideoPortFormat,
   1349                 &format, sizeof(format));
   1350 
   1351         if (err != OK) {
   1352             return err;
   1353         }
   1354     }
   1355 #endif
   1356 
   1357     OMX_PARAM_PORTDEFINITIONTYPE def;
   1358     InitOMXParams(&def);
   1359     def.nPortIndex = kPortIndexInput;
   1360 
   1361     OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
   1362 
   1363     err = mOMX->getParameter(
   1364             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   1365 
   1366     CHECK_EQ(err, OK);
   1367 
   1368 #if 1
   1369     // XXX Need a (much) better heuristic to compute input buffer sizes.
   1370     const size_t X = 64 * 1024;
   1371     if (def.nBufferSize < X) {
   1372         def.nBufferSize = X;
   1373     }
   1374 #endif
   1375 
   1376     CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
   1377 
   1378     video_def->nFrameWidth = width;
   1379     video_def->nFrameHeight = height;
   1380 
   1381     video_def->eCompressionFormat = compressionFormat;
   1382     video_def->eColorFormat = OMX_COLOR_FormatUnused;
   1383 
   1384     err = mOMX->setParameter(
   1385             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   1386 
   1387     if (err != OK) {
   1388         return err;
   1389     }
   1390 
   1391     ////////////////////////////////////////////////////////////////////////////
   1392 
   1393     InitOMXParams(&def);
   1394     def.nPortIndex = kPortIndexOutput;
   1395 
   1396     err = mOMX->getParameter(
   1397             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   1398     CHECK_EQ(err, OK);
   1399     CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
   1400 
   1401 #if 0
   1402     def.nBufferSize =
   1403         (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2;  // YUV420
   1404 #endif
   1405 
   1406     video_def->nFrameWidth = width;
   1407     video_def->nFrameHeight = height;
   1408 
   1409     err = mOMX->setParameter(
   1410             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   1411 
   1412     return err;
   1413 }
   1414 
   1415 OMXCodec::OMXCodec(
   1416         const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks,
   1417         bool isEncoder,
   1418         const char *mime,
   1419         const char *componentName,
   1420         const sp<MediaSource> &source)
   1421     : mOMX(omx),
   1422       mOMXLivesLocally(omx->livesLocally(getpid())),
   1423       mNode(node),
   1424       mQuirks(quirks),
   1425       mIsEncoder(isEncoder),
   1426       mMIME(strdup(mime)),
   1427       mComponentName(strdup(componentName)),
   1428       mSource(source),
   1429       mCodecSpecificDataIndex(0),
   1430       mState(LOADED),
   1431       mInitialBufferSubmit(true),
   1432       mSignalledEOS(false),
   1433       mNoMoreOutputData(false),
   1434       mOutputPortSettingsHaveChanged(false),
   1435       mSeekTimeUs(-1),
   1436       mSeekMode(ReadOptions::SEEK_CLOSEST_SYNC),
   1437       mTargetTimeUs(-1),
   1438       mSkipTimeUs(-1),
   1439       mLeftOverBuffer(NULL),
   1440       mPaused(false) {
   1441     mPortStatus[kPortIndexInput] = ENABLED;
   1442     mPortStatus[kPortIndexOutput] = ENABLED;
   1443 
   1444     setComponentRole();
   1445 }
   1446 
   1447 // static
   1448 void OMXCodec::setComponentRole(
   1449         const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder,
   1450         const char *mime) {
   1451     struct MimeToRole {
   1452         const char *mime;
   1453         const char *decoderRole;
   1454         const char *encoderRole;
   1455     };
   1456 
   1457     static const MimeToRole kMimeToRole[] = {
   1458         { MEDIA_MIMETYPE_AUDIO_MPEG,
   1459             "audio_decoder.mp3", "audio_encoder.mp3" },
   1460         { MEDIA_MIMETYPE_AUDIO_AMR_NB,
   1461             "audio_decoder.amrnb", "audio_encoder.amrnb" },
   1462         { MEDIA_MIMETYPE_AUDIO_AMR_WB,
   1463             "audio_decoder.amrwb", "audio_encoder.amrwb" },
   1464         { MEDIA_MIMETYPE_AUDIO_AAC,
   1465             "audio_decoder.aac", "audio_encoder.aac" },
   1466         { MEDIA_MIMETYPE_VIDEO_AVC,
   1467             "video_decoder.avc", "video_encoder.avc" },
   1468         { MEDIA_MIMETYPE_VIDEO_MPEG4,
   1469             "video_decoder.mpeg4", "video_encoder.mpeg4" },
   1470         { MEDIA_MIMETYPE_VIDEO_H263,
   1471             "video_decoder.h263", "video_encoder.h263" },
   1472     };
   1473 
   1474     static const size_t kNumMimeToRole =
   1475         sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
   1476 
   1477     size_t i;
   1478     for (i = 0; i < kNumMimeToRole; ++i) {
   1479         if (!strcasecmp(mime, kMimeToRole[i].mime)) {
   1480             break;
   1481         }
   1482     }
   1483 
   1484     if (i == kNumMimeToRole) {
   1485         return;
   1486     }
   1487 
   1488     const char *role =
   1489         isEncoder ? kMimeToRole[i].encoderRole
   1490                   : kMimeToRole[i].decoderRole;
   1491 
   1492     if (role != NULL) {
   1493         OMX_PARAM_COMPONENTROLETYPE roleParams;
   1494         InitOMXParams(&roleParams);
   1495 
   1496         strncpy((char *)roleParams.cRole,
   1497                 role, OMX_MAX_STRINGNAME_SIZE - 1);
   1498 
   1499         roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
   1500 
   1501         status_t err = omx->setParameter(
   1502                 node, OMX_IndexParamStandardComponentRole,
   1503                 &roleParams, sizeof(roleParams));
   1504 
   1505         if (err != OK) {
   1506             LOGW("Failed to set standard component role '%s'.", role);
   1507         }
   1508     }
   1509 }
   1510 
   1511 void OMXCodec::setComponentRole() {
   1512     setComponentRole(mOMX, mNode, mIsEncoder, mMIME);
   1513 }
   1514 
   1515 OMXCodec::~OMXCodec() {
   1516     mSource.clear();
   1517 
   1518     CHECK(mState == LOADED || mState == ERROR);
   1519 
   1520     status_t err = mOMX->freeNode(mNode);
   1521     CHECK_EQ(err, OK);
   1522 
   1523     mNode = NULL;
   1524     setState(DEAD);
   1525 
   1526     clearCodecSpecificData();
   1527 
   1528     free(mComponentName);
   1529     mComponentName = NULL;
   1530 
   1531     free(mMIME);
   1532     mMIME = NULL;
   1533 }
   1534 
   1535 status_t OMXCodec::init() {
   1536     // mLock is held.
   1537 
   1538     CHECK_EQ(mState, LOADED);
   1539 
   1540     status_t err;
   1541     if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) {
   1542         err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
   1543         CHECK_EQ(err, OK);
   1544         setState(LOADED_TO_IDLE);
   1545     }
   1546 
   1547     err = allocateBuffers();
   1548     CHECK_EQ(err, OK);
   1549 
   1550     if (mQuirks & kRequiresLoadedToIdleAfterAllocation) {
   1551         err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
   1552         CHECK_EQ(err, OK);
   1553 
   1554         setState(LOADED_TO_IDLE);
   1555     }
   1556 
   1557     while (mState != EXECUTING && mState != ERROR) {
   1558         mAsyncCompletion.wait(mLock);
   1559     }
   1560 
   1561     return mState == ERROR ? UNKNOWN_ERROR : OK;
   1562 }
   1563 
   1564 // static
   1565 bool OMXCodec::isIntermediateState(State state) {
   1566     return state == LOADED_TO_IDLE
   1567         || state == IDLE_TO_EXECUTING
   1568         || state == EXECUTING_TO_IDLE
   1569         || state == IDLE_TO_LOADED
   1570         || state == RECONFIGURING;
   1571 }
   1572 
   1573 status_t OMXCodec::allocateBuffers() {
   1574     status_t err = allocateBuffersOnPort(kPortIndexInput);
   1575 
   1576     if (err != OK) {
   1577         return err;
   1578     }
   1579 
   1580     return allocateBuffersOnPort(kPortIndexOutput);
   1581 }
   1582 
   1583 status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
   1584     OMX_PARAM_PORTDEFINITIONTYPE def;
   1585     InitOMXParams(&def);
   1586     def.nPortIndex = portIndex;
   1587 
   1588     status_t err = mOMX->getParameter(
   1589             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   1590 
   1591     if (err != OK) {
   1592         return err;
   1593     }
   1594 
   1595     CODEC_LOGI("allocating %lu buffers of size %lu on %s port",
   1596             def.nBufferCountActual, def.nBufferSize,
   1597             portIndex == kPortIndexInput ? "input" : "output");
   1598 
   1599     size_t totalSize = def.nBufferCountActual * def.nBufferSize;
   1600     mDealer[portIndex] = new MemoryDealer(totalSize, "OMXCodec");
   1601 
   1602     for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
   1603         sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
   1604         CHECK(mem.get() != NULL);
   1605 
   1606         BufferInfo info;
   1607         info.mData = NULL;
   1608         info.mSize = def.nBufferSize;
   1609 
   1610         IOMX::buffer_id buffer;
   1611         if (portIndex == kPortIndexInput
   1612                 && (mQuirks & kRequiresAllocateBufferOnInputPorts)) {
   1613             if (mOMXLivesLocally) {
   1614                 mem.clear();
   1615 
   1616                 err = mOMX->allocateBuffer(
   1617                         mNode, portIndex, def.nBufferSize, &buffer,
   1618                         &info.mData);
   1619             } else {
   1620                 err = mOMX->allocateBufferWithBackup(
   1621                         mNode, portIndex, mem, &buffer);
   1622             }
   1623         } else if (portIndex == kPortIndexOutput
   1624                 && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) {
   1625             if (mOMXLivesLocally) {
   1626                 mem.clear();
   1627 
   1628                 err = mOMX->allocateBuffer(
   1629                         mNode, portIndex, def.nBufferSize, &buffer,
   1630                         &info.mData);
   1631             } else {
   1632                 err = mOMX->allocateBufferWithBackup(
   1633                         mNode, portIndex, mem, &buffer);
   1634             }
   1635         } else {
   1636             err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
   1637         }
   1638 
   1639         if (err != OK) {
   1640             LOGE("allocate_buffer_with_backup failed");
   1641             return err;
   1642         }
   1643 
   1644         if (mem != NULL) {
   1645             info.mData = mem->pointer();
   1646         }
   1647 
   1648         info.mBuffer = buffer;
   1649         info.mOwnedByComponent = false;
   1650         info.mMem = mem;
   1651         info.mMediaBuffer = NULL;
   1652 
   1653         if (portIndex == kPortIndexOutput) {
   1654             if (!(mOMXLivesLocally
   1655                         && (mQuirks & kRequiresAllocateBufferOnOutputPorts)
   1656                         && (mQuirks & kDefersOutputBufferAllocation))) {
   1657                 // If the node does not fill in the buffer ptr at this time,
   1658                 // we will defer creating the MediaBuffer until receiving
   1659                 // the first FILL_BUFFER_DONE notification instead.
   1660                 info.mMediaBuffer = new MediaBuffer(info.mData, info.mSize);
   1661                 info.mMediaBuffer->setObserver(this);
   1662             }
   1663         }
   1664 
   1665         mPortBuffers[portIndex].push(info);
   1666 
   1667         CODEC_LOGV("allocated buffer %p on %s port", buffer,
   1668              portIndex == kPortIndexInput ? "input" : "output");
   1669     }
   1670 
   1671     // dumpPortStatus(portIndex);
   1672 
   1673     return OK;
   1674 }
   1675 
   1676 void OMXCodec::on_message(const omx_message &msg) {
   1677     switch (msg.type) {
   1678         case omx_message::EVENT:
   1679         {
   1680             onEvent(
   1681                  msg.u.event_data.event, msg.u.event_data.data1,
   1682                  msg.u.event_data.data2);
   1683 
   1684             break;
   1685         }
   1686 
   1687         case omx_message::EMPTY_BUFFER_DONE:
   1688         {
   1689             IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
   1690 
   1691             CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer);
   1692 
   1693             Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
   1694             size_t i = 0;
   1695             while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
   1696                 ++i;
   1697             }
   1698 
   1699             CHECK(i < buffers->size());
   1700             if (!(*buffers)[i].mOwnedByComponent) {
   1701                 LOGW("We already own input buffer %p, yet received "
   1702                      "an EMPTY_BUFFER_DONE.", buffer);
   1703             }
   1704 
   1705             {
   1706                 BufferInfo *info = &buffers->editItemAt(i);
   1707                 info->mOwnedByComponent = false;
   1708                 if (info->mMediaBuffer != NULL) {
   1709                     // It is time to release the media buffers storing meta data
   1710                     info->mMediaBuffer->release();
   1711                     info->mMediaBuffer = NULL;
   1712                 }
   1713             }
   1714 
   1715             if (mPortStatus[kPortIndexInput] == DISABLING) {
   1716                 CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
   1717 
   1718                 status_t err =
   1719                     mOMX->freeBuffer(mNode, kPortIndexInput, buffer);
   1720                 CHECK_EQ(err, OK);
   1721 
   1722                 buffers->removeAt(i);
   1723             } else if (mState != ERROR
   1724                     && mPortStatus[kPortIndexInput] != SHUTTING_DOWN) {
   1725                 CHECK_EQ(mPortStatus[kPortIndexInput], ENABLED);
   1726                 drainInputBuffer(&buffers->editItemAt(i));
   1727             }
   1728             break;
   1729         }
   1730 
   1731         case omx_message::FILL_BUFFER_DONE:
   1732         {
   1733             IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
   1734             OMX_U32 flags = msg.u.extended_buffer_data.flags;
   1735 
   1736             CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx, timestamp: %lld us (%.2f secs))",
   1737                  buffer,
   1738                  msg.u.extended_buffer_data.range_length,
   1739                  flags,
   1740                  msg.u.extended_buffer_data.timestamp,
   1741                  msg.u.extended_buffer_data.timestamp / 1E6);
   1742 
   1743             Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
   1744             size_t i = 0;
   1745             while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
   1746                 ++i;
   1747             }
   1748 
   1749             CHECK(i < buffers->size());
   1750             BufferInfo *info = &buffers->editItemAt(i);
   1751 
   1752             if (!info->mOwnedByComponent) {
   1753                 LOGW("We already own output buffer %p, yet received "
   1754                      "a FILL_BUFFER_DONE.", buffer);
   1755             }
   1756 
   1757             info->mOwnedByComponent = false;
   1758 
   1759             if (mPortStatus[kPortIndexOutput] == DISABLING) {
   1760                 CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
   1761 
   1762                 status_t err =
   1763                     mOMX->freeBuffer(mNode, kPortIndexOutput, buffer);
   1764                 CHECK_EQ(err, OK);
   1765 
   1766                 buffers->removeAt(i);
   1767 #if 0
   1768             } else if (mPortStatus[kPortIndexOutput] == ENABLED
   1769                        && (flags & OMX_BUFFERFLAG_EOS)) {
   1770                 CODEC_LOGV("No more output data.");
   1771                 mNoMoreOutputData = true;
   1772                 mBufferFilled.signal();
   1773 #endif
   1774             } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) {
   1775                 CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED);
   1776 
   1777                 if (info->mMediaBuffer == NULL) {
   1778                     CHECK(mOMXLivesLocally);
   1779                     CHECK(mQuirks & kRequiresAllocateBufferOnOutputPorts);
   1780                     CHECK(mQuirks & kDefersOutputBufferAllocation);
   1781 
   1782                     // The qcom video decoders on Nexus don't actually allocate
   1783                     // output buffer memory on a call to OMX_AllocateBuffer
   1784                     // the "pBuffer" member of the OMX_BUFFERHEADERTYPE
   1785                     // structure is only filled in later.
   1786 
   1787                     info->mMediaBuffer = new MediaBuffer(
   1788                             msg.u.extended_buffer_data.data_ptr,
   1789                             info->mSize);
   1790                     info->mMediaBuffer->setObserver(this);
   1791                 }
   1792 
   1793                 MediaBuffer *buffer = info->mMediaBuffer;
   1794 
   1795                 if (msg.u.extended_buffer_data.range_offset
   1796                         + msg.u.extended_buffer_data.range_length
   1797                             > buffer->size()) {
   1798                     CODEC_LOGE(
   1799                             "Codec lied about its buffer size requirements, "
   1800                             "sending a buffer larger than the originally "
   1801                             "advertised size in FILL_BUFFER_DONE!");
   1802                 }
   1803                 buffer->set_range(
   1804                         msg.u.extended_buffer_data.range_offset,
   1805                         msg.u.extended_buffer_data.range_length);
   1806 
   1807                 buffer->meta_data()->clear();
   1808 
   1809                 buffer->meta_data()->setInt64(
   1810                         kKeyTime, msg.u.extended_buffer_data.timestamp);
   1811 
   1812                 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) {
   1813                     buffer->meta_data()->setInt32(kKeyIsSyncFrame, true);
   1814                 }
   1815                 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) {
   1816                     buffer->meta_data()->setInt32(kKeyIsCodecConfig, true);
   1817                 }
   1818 
   1819                 if (mQuirks & kOutputBuffersAreUnreadable) {
   1820                     buffer->meta_data()->setInt32(kKeyIsUnreadable, true);
   1821                 }
   1822 
   1823                 buffer->meta_data()->setPointer(
   1824                         kKeyPlatformPrivate,
   1825                         msg.u.extended_buffer_data.platform_private);
   1826 
   1827                 buffer->meta_data()->setPointer(
   1828                         kKeyBufferID,
   1829                         msg.u.extended_buffer_data.buffer);
   1830 
   1831                 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) {
   1832                     CODEC_LOGV("No more output data.");
   1833                     mNoMoreOutputData = true;
   1834                 }
   1835 
   1836                 if (mTargetTimeUs >= 0) {
   1837                     CHECK(msg.u.extended_buffer_data.timestamp <= mTargetTimeUs);
   1838 
   1839                     if (msg.u.extended_buffer_data.timestamp < mTargetTimeUs) {
   1840                         CODEC_LOGV(
   1841                                 "skipping output buffer at timestamp %lld us",
   1842                                 msg.u.extended_buffer_data.timestamp);
   1843 
   1844                         fillOutputBuffer(info);
   1845                         break;
   1846                     }
   1847 
   1848                     CODEC_LOGV(
   1849                             "returning output buffer at target timestamp "
   1850                             "%lld us",
   1851                             msg.u.extended_buffer_data.timestamp);
   1852 
   1853                     mTargetTimeUs = -1;
   1854                 }
   1855 
   1856                 mFilledBuffers.push_back(i);
   1857                 mBufferFilled.signal();
   1858             }
   1859 
   1860             break;
   1861         }
   1862 
   1863         default:
   1864         {
   1865             CHECK(!"should not be here.");
   1866             break;
   1867         }
   1868     }
   1869 }
   1870 
   1871 void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
   1872     switch (event) {
   1873         case OMX_EventCmdComplete:
   1874         {
   1875             onCmdComplete((OMX_COMMANDTYPE)data1, data2);
   1876             break;
   1877         }
   1878 
   1879         case OMX_EventError:
   1880         {
   1881             CODEC_LOGE("ERROR(0x%08lx, %ld)", data1, data2);
   1882 
   1883             setState(ERROR);
   1884             break;
   1885         }
   1886 
   1887         case OMX_EventPortSettingsChanged:
   1888         {
   1889             onPortSettingsChanged(data1);
   1890             break;
   1891         }
   1892 
   1893 #if 0
   1894         case OMX_EventBufferFlag:
   1895         {
   1896             CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1);
   1897 
   1898             if (data1 == kPortIndexOutput) {
   1899                 mNoMoreOutputData = true;
   1900             }
   1901             break;
   1902         }
   1903 #endif
   1904 
   1905         default:
   1906         {
   1907             CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2);
   1908             break;
   1909         }
   1910     }
   1911 }
   1912 
   1913 // Has the format changed in any way that the client would have to be aware of?
   1914 static bool formatHasNotablyChanged(
   1915         const sp<MetaData> &from, const sp<MetaData> &to) {
   1916     if (from.get() == NULL && to.get() == NULL) {
   1917         return false;
   1918     }
   1919 
   1920     if ((from.get() == NULL && to.get() != NULL)
   1921         || (from.get() != NULL && to.get() == NULL)) {
   1922         return true;
   1923     }
   1924 
   1925     const char *mime_from, *mime_to;
   1926     CHECK(from->findCString(kKeyMIMEType, &mime_from));
   1927     CHECK(to->findCString(kKeyMIMEType, &mime_to));
   1928 
   1929     if (strcasecmp(mime_from, mime_to)) {
   1930         return true;
   1931     }
   1932 
   1933     if (!strcasecmp(mime_from, MEDIA_MIMETYPE_VIDEO_RAW)) {
   1934         int32_t colorFormat_from, colorFormat_to;
   1935         CHECK(from->findInt32(kKeyColorFormat, &colorFormat_from));
   1936         CHECK(to->findInt32(kKeyColorFormat, &colorFormat_to));
   1937 
   1938         if (colorFormat_from != colorFormat_to) {
   1939             return true;
   1940         }
   1941 
   1942         int32_t width_from, width_to;
   1943         CHECK(from->findInt32(kKeyWidth, &width_from));
   1944         CHECK(to->findInt32(kKeyWidth, &width_to));
   1945 
   1946         if (width_from != width_to) {
   1947             return true;
   1948         }
   1949 
   1950         int32_t height_from, height_to;
   1951         CHECK(from->findInt32(kKeyHeight, &height_from));
   1952         CHECK(to->findInt32(kKeyHeight, &height_to));
   1953 
   1954         if (height_from != height_to) {
   1955             return true;
   1956         }
   1957     } else if (!strcasecmp(mime_from, MEDIA_MIMETYPE_AUDIO_RAW)) {
   1958         int32_t numChannels_from, numChannels_to;
   1959         CHECK(from->findInt32(kKeyChannelCount, &numChannels_from));
   1960         CHECK(to->findInt32(kKeyChannelCount, &numChannels_to));
   1961 
   1962         if (numChannels_from != numChannels_to) {
   1963             return true;
   1964         }
   1965 
   1966         int32_t sampleRate_from, sampleRate_to;
   1967         CHECK(from->findInt32(kKeySampleRate, &sampleRate_from));
   1968         CHECK(to->findInt32(kKeySampleRate, &sampleRate_to));
   1969 
   1970         if (sampleRate_from != sampleRate_to) {
   1971             return true;
   1972         }
   1973     }
   1974 
   1975     return false;
   1976 }
   1977 
   1978 void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) {
   1979     switch (cmd) {
   1980         case OMX_CommandStateSet:
   1981         {
   1982             onStateChange((OMX_STATETYPE)data);
   1983             break;
   1984         }
   1985 
   1986         case OMX_CommandPortDisable:
   1987         {
   1988             OMX_U32 portIndex = data;
   1989             CODEC_LOGV("PORT_DISABLED(%ld)", portIndex);
   1990 
   1991             CHECK(mState == EXECUTING || mState == RECONFIGURING);
   1992             CHECK_EQ(mPortStatus[portIndex], DISABLING);
   1993             CHECK_EQ(mPortBuffers[portIndex].size(), 0);
   1994 
   1995             mPortStatus[portIndex] = DISABLED;
   1996 
   1997             if (mState == RECONFIGURING) {
   1998                 CHECK_EQ(portIndex, kPortIndexOutput);
   1999 
   2000                 sp<MetaData> oldOutputFormat = mOutputFormat;
   2001                 initOutputFormat(mSource->getFormat());
   2002 
   2003                 // Don't notify clients if the output port settings change
   2004                 // wasn't of importance to them, i.e. it may be that just the
   2005                 // number of buffers has changed and nothing else.
   2006                 mOutputPortSettingsHaveChanged =
   2007                     formatHasNotablyChanged(oldOutputFormat, mOutputFormat);
   2008 
   2009                 enablePortAsync(portIndex);
   2010 
   2011                 status_t err = allocateBuffersOnPort(portIndex);
   2012                 CHECK_EQ(err, OK);
   2013             }
   2014             break;
   2015         }
   2016 
   2017         case OMX_CommandPortEnable:
   2018         {
   2019             OMX_U32 portIndex = data;
   2020             CODEC_LOGV("PORT_ENABLED(%ld)", portIndex);
   2021 
   2022             CHECK(mState == EXECUTING || mState == RECONFIGURING);
   2023             CHECK_EQ(mPortStatus[portIndex], ENABLING);
   2024 
   2025             mPortStatus[portIndex] = ENABLED;
   2026 
   2027             if (mState == RECONFIGURING) {
   2028                 CHECK_EQ(portIndex, kPortIndexOutput);
   2029 
   2030                 setState(EXECUTING);
   2031 
   2032                 fillOutputBuffers();
   2033             }
   2034             break;
   2035         }
   2036 
   2037         case OMX_CommandFlush:
   2038         {
   2039             OMX_U32 portIndex = data;
   2040 
   2041             CODEC_LOGV("FLUSH_DONE(%ld)", portIndex);
   2042 
   2043             CHECK_EQ(mPortStatus[portIndex], SHUTTING_DOWN);
   2044             mPortStatus[portIndex] = ENABLED;
   2045 
   2046             CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]),
   2047                      mPortBuffers[portIndex].size());
   2048 
   2049             if (mState == RECONFIGURING) {
   2050                 CHECK_EQ(portIndex, kPortIndexOutput);
   2051 
   2052                 disablePortAsync(portIndex);
   2053             } else if (mState == EXECUTING_TO_IDLE) {
   2054                 if (mPortStatus[kPortIndexInput] == ENABLED
   2055                     && mPortStatus[kPortIndexOutput] == ENABLED) {
   2056                     CODEC_LOGV("Finished flushing both ports, now completing "
   2057                          "transition from EXECUTING to IDLE.");
   2058 
   2059                     mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
   2060                     mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
   2061 
   2062                     status_t err =
   2063                         mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
   2064                     CHECK_EQ(err, OK);
   2065                 }
   2066             } else {
   2067                 // We're flushing both ports in preparation for seeking.
   2068 
   2069                 if (mPortStatus[kPortIndexInput] == ENABLED
   2070                     && mPortStatus[kPortIndexOutput] == ENABLED) {
   2071                     CODEC_LOGV("Finished flushing both ports, now continuing from"
   2072                          " seek-time.");
   2073 
   2074                     // We implicitly resume pulling on our upstream source.
   2075                     mPaused = false;
   2076 
   2077                     drainInputBuffers();
   2078                     fillOutputBuffers();
   2079                 }
   2080             }
   2081 
   2082             break;
   2083         }
   2084 
   2085         default:
   2086         {
   2087             CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data);
   2088             break;
   2089         }
   2090     }
   2091 }
   2092 
   2093 void OMXCodec::onStateChange(OMX_STATETYPE newState) {
   2094     CODEC_LOGV("onStateChange %d", newState);
   2095 
   2096     switch (newState) {
   2097         case OMX_StateIdle:
   2098         {
   2099             CODEC_LOGV("Now Idle.");
   2100             if (mState == LOADED_TO_IDLE) {
   2101                 status_t err = mOMX->sendCommand(
   2102                         mNode, OMX_CommandStateSet, OMX_StateExecuting);
   2103 
   2104                 CHECK_EQ(err, OK);
   2105 
   2106                 setState(IDLE_TO_EXECUTING);
   2107             } else {
   2108                 CHECK_EQ(mState, EXECUTING_TO_IDLE);
   2109 
   2110                 CHECK_EQ(
   2111                     countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
   2112                     mPortBuffers[kPortIndexInput].size());
   2113 
   2114                 CHECK_EQ(
   2115                     countBuffersWeOwn(mPortBuffers[kPortIndexOutput]),
   2116                     mPortBuffers[kPortIndexOutput].size());
   2117 
   2118                 status_t err = mOMX->sendCommand(
   2119                         mNode, OMX_CommandStateSet, OMX_StateLoaded);
   2120 
   2121                 CHECK_EQ(err, OK);
   2122 
   2123                 err = freeBuffersOnPort(kPortIndexInput);
   2124                 CHECK_EQ(err, OK);
   2125 
   2126                 err = freeBuffersOnPort(kPortIndexOutput);
   2127                 CHECK_EQ(err, OK);
   2128 
   2129                 mPortStatus[kPortIndexInput] = ENABLED;
   2130                 mPortStatus[kPortIndexOutput] = ENABLED;
   2131 
   2132                 setState(IDLE_TO_LOADED);
   2133             }
   2134             break;
   2135         }
   2136 
   2137         case OMX_StateExecuting:
   2138         {
   2139             CHECK_EQ(mState, IDLE_TO_EXECUTING);
   2140 
   2141             CODEC_LOGV("Now Executing.");
   2142 
   2143             setState(EXECUTING);
   2144 
   2145             // Buffers will be submitted to the component in the first
   2146             // call to OMXCodec::read as mInitialBufferSubmit is true at
   2147             // this point. This ensures that this on_message call returns,
   2148             // releases the lock and ::init can notice the state change and
   2149             // itself return.
   2150             break;
   2151         }
   2152 
   2153         case OMX_StateLoaded:
   2154         {
   2155             CHECK_EQ(mState, IDLE_TO_LOADED);
   2156 
   2157             CODEC_LOGV("Now Loaded.");
   2158 
   2159             setState(LOADED);
   2160             break;
   2161         }
   2162 
   2163         case OMX_StateInvalid:
   2164         {
   2165             setState(ERROR);
   2166             break;
   2167         }
   2168 
   2169         default:
   2170         {
   2171             CHECK(!"should not be here.");
   2172             break;
   2173         }
   2174     }
   2175 }
   2176 
   2177 // static
   2178 size_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) {
   2179     size_t n = 0;
   2180     for (size_t i = 0; i < buffers.size(); ++i) {
   2181         if (!buffers[i].mOwnedByComponent) {
   2182             ++n;
   2183         }
   2184     }
   2185 
   2186     return n;
   2187 }
   2188 
   2189 status_t OMXCodec::freeBuffersOnPort(
   2190         OMX_U32 portIndex, bool onlyThoseWeOwn) {
   2191     Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
   2192 
   2193     status_t stickyErr = OK;
   2194 
   2195     for (size_t i = buffers->size(); i-- > 0;) {
   2196         BufferInfo *info = &buffers->editItemAt(i);
   2197 
   2198         if (onlyThoseWeOwn && info->mOwnedByComponent) {
   2199             continue;
   2200         }
   2201 
   2202         CHECK_EQ(info->mOwnedByComponent, false);
   2203 
   2204         CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex);
   2205 
   2206         status_t err =
   2207             mOMX->freeBuffer(mNode, portIndex, info->mBuffer);
   2208 
   2209         if (err != OK) {
   2210             stickyErr = err;
   2211         }
   2212 
   2213         if (info->mMediaBuffer != NULL) {
   2214             info->mMediaBuffer->setObserver(NULL);
   2215 
   2216             // Make sure nobody but us owns this buffer at this point.
   2217             CHECK_EQ(info->mMediaBuffer->refcount(), 0);
   2218 
   2219             info->mMediaBuffer->release();
   2220             info->mMediaBuffer = NULL;
   2221         }
   2222 
   2223         buffers->removeAt(i);
   2224     }
   2225 
   2226     CHECK(onlyThoseWeOwn || buffers->isEmpty());
   2227 
   2228     return stickyErr;
   2229 }
   2230 
   2231 void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) {
   2232     CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex);
   2233 
   2234     CHECK_EQ(mState, EXECUTING);
   2235     CHECK_EQ(portIndex, kPortIndexOutput);
   2236     setState(RECONFIGURING);
   2237 
   2238     if (mQuirks & kNeedsFlushBeforeDisable) {
   2239         if (!flushPortAsync(portIndex)) {
   2240             onCmdComplete(OMX_CommandFlush, portIndex);
   2241         }
   2242     } else {
   2243         disablePortAsync(portIndex);
   2244     }
   2245 }
   2246 
   2247 bool OMXCodec::flushPortAsync(OMX_U32 portIndex) {
   2248     CHECK(mState == EXECUTING || mState == RECONFIGURING
   2249             || mState == EXECUTING_TO_IDLE);
   2250 
   2251     CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.",
   2252          portIndex, countBuffersWeOwn(mPortBuffers[portIndex]),
   2253          mPortBuffers[portIndex].size());
   2254 
   2255     CHECK_EQ(mPortStatus[portIndex], ENABLED);
   2256     mPortStatus[portIndex] = SHUTTING_DOWN;
   2257 
   2258     if ((mQuirks & kRequiresFlushCompleteEmulation)
   2259         && countBuffersWeOwn(mPortBuffers[portIndex])
   2260                 == mPortBuffers[portIndex].size()) {
   2261         // No flush is necessary and this component fails to send a
   2262         // flush-complete event in this case.
   2263 
   2264         return false;
   2265     }
   2266 
   2267     status_t err =
   2268         mOMX->sendCommand(mNode, OMX_CommandFlush, portIndex);
   2269     CHECK_EQ(err, OK);
   2270 
   2271     return true;
   2272 }
   2273 
   2274 void OMXCodec::disablePortAsync(OMX_U32 portIndex) {
   2275     CHECK(mState == EXECUTING || mState == RECONFIGURING);
   2276 
   2277     CHECK_EQ(mPortStatus[portIndex], ENABLED);
   2278     mPortStatus[portIndex] = DISABLING;
   2279 
   2280     status_t err =
   2281         mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex);
   2282     CHECK_EQ(err, OK);
   2283 
   2284     freeBuffersOnPort(portIndex, true);
   2285 }
   2286 
   2287 void OMXCodec::enablePortAsync(OMX_U32 portIndex) {
   2288     CHECK(mState == EXECUTING || mState == RECONFIGURING);
   2289 
   2290     CHECK_EQ(mPortStatus[portIndex], DISABLED);
   2291     mPortStatus[portIndex] = ENABLING;
   2292 
   2293     status_t err =
   2294         mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex);
   2295     CHECK_EQ(err, OK);
   2296 }
   2297 
   2298 void OMXCodec::fillOutputBuffers() {
   2299     CHECK_EQ(mState, EXECUTING);
   2300 
   2301     // This is a workaround for some decoders not properly reporting
   2302     // end-of-output-stream. If we own all input buffers and also own
   2303     // all output buffers and we already signalled end-of-input-stream,
   2304     // the end-of-output-stream is implied.
   2305     if (mSignalledEOS
   2306             && countBuffersWeOwn(mPortBuffers[kPortIndexInput])
   2307                 == mPortBuffers[kPortIndexInput].size()
   2308             && countBuffersWeOwn(mPortBuffers[kPortIndexOutput])
   2309                 == mPortBuffers[kPortIndexOutput].size()) {
   2310         mNoMoreOutputData = true;
   2311         mBufferFilled.signal();
   2312 
   2313         return;
   2314     }
   2315 
   2316     Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
   2317     for (size_t i = 0; i < buffers->size(); ++i) {
   2318         fillOutputBuffer(&buffers->editItemAt(i));
   2319     }
   2320 }
   2321 
   2322 void OMXCodec::drainInputBuffers() {
   2323     CHECK(mState == EXECUTING || mState == RECONFIGURING);
   2324 
   2325     Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
   2326     for (size_t i = 0; i < buffers->size(); ++i) {
   2327         drainInputBuffer(&buffers->editItemAt(i));
   2328     }
   2329 }
   2330 
   2331 void OMXCodec::drainInputBuffer(BufferInfo *info) {
   2332     CHECK_EQ(info->mOwnedByComponent, false);
   2333 
   2334     if (mSignalledEOS) {
   2335         return;
   2336     }
   2337 
   2338     if (mCodecSpecificDataIndex < mCodecSpecificData.size()) {
   2339         const CodecSpecificData *specific =
   2340             mCodecSpecificData[mCodecSpecificDataIndex];
   2341 
   2342         size_t size = specific->mSize;
   2343 
   2344         if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME)
   2345                 && !(mQuirks & kWantsNALFragments)) {
   2346             static const uint8_t kNALStartCode[4] =
   2347                     { 0x00, 0x00, 0x00, 0x01 };
   2348 
   2349             CHECK(info->mSize >= specific->mSize + 4);
   2350 
   2351             size += 4;
   2352 
   2353             memcpy(info->mData, kNALStartCode, 4);
   2354             memcpy((uint8_t *)info->mData + 4,
   2355                    specific->mData, specific->mSize);
   2356         } else {
   2357             CHECK(info->mSize >= specific->mSize);
   2358             memcpy(info->mData, specific->mData, specific->mSize);
   2359         }
   2360 
   2361         mNoMoreOutputData = false;
   2362 
   2363         CODEC_LOGV("calling emptyBuffer with codec specific data");
   2364 
   2365         status_t err = mOMX->emptyBuffer(
   2366                 mNode, info->mBuffer, 0, size,
   2367                 OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG,
   2368                 0);
   2369         CHECK_EQ(err, OK);
   2370 
   2371         info->mOwnedByComponent = true;
   2372 
   2373         ++mCodecSpecificDataIndex;
   2374         return;
   2375     }
   2376 
   2377     if (mPaused) {
   2378         return;
   2379     }
   2380 
   2381     status_t err;
   2382 
   2383     bool signalEOS = false;
   2384     int64_t timestampUs = 0;
   2385 
   2386     size_t offset = 0;
   2387     int32_t n = 0;
   2388     for (;;) {
   2389         MediaBuffer *srcBuffer;
   2390         MediaSource::ReadOptions options;
   2391         if (mSkipTimeUs >= 0) {
   2392             options.setSkipFrame(mSkipTimeUs);
   2393         }
   2394         if (mSeekTimeUs >= 0) {
   2395             if (mLeftOverBuffer) {
   2396                 mLeftOverBuffer->release();
   2397                 mLeftOverBuffer = NULL;
   2398             }
   2399             options.setSeekTo(mSeekTimeUs, mSeekMode);
   2400 
   2401             mSeekTimeUs = -1;
   2402             mSeekMode = ReadOptions::SEEK_CLOSEST_SYNC;
   2403             mBufferFilled.signal();
   2404 
   2405             err = mSource->read(&srcBuffer, &options);
   2406 
   2407             if (err == OK) {
   2408                 int64_t targetTimeUs;
   2409                 if (srcBuffer->meta_data()->findInt64(
   2410                             kKeyTargetTime, &targetTimeUs)
   2411                         && targetTimeUs >= 0) {
   2412                     mTargetTimeUs = targetTimeUs;
   2413                 } else {
   2414                     mTargetTimeUs = -1;
   2415                 }
   2416             }
   2417         } else if (mLeftOverBuffer) {
   2418             srcBuffer = mLeftOverBuffer;
   2419             mLeftOverBuffer = NULL;
   2420 
   2421             err = OK;
   2422         } else {
   2423             err = mSource->read(&srcBuffer, &options);
   2424         }
   2425 
   2426         if (err != OK) {
   2427             signalEOS = true;
   2428             mFinalStatus = err;
   2429             mSignalledEOS = true;
   2430             break;
   2431         }
   2432 
   2433         size_t remainingBytes = info->mSize - offset;
   2434 
   2435         if (srcBuffer->range_length() > remainingBytes) {
   2436             if (offset == 0) {
   2437                 CODEC_LOGE(
   2438                      "Codec's input buffers are too small to accomodate "
   2439                      "buffer read from source (info->mSize = %d, srcLength = %d)",
   2440                      info->mSize, srcBuffer->range_length());
   2441 
   2442                 srcBuffer->release();
   2443                 srcBuffer = NULL;
   2444 
   2445                 setState(ERROR);
   2446                 return;
   2447             }
   2448 
   2449             mLeftOverBuffer = srcBuffer;
   2450             break;
   2451         }
   2452 
   2453         // Do not release the media buffer if it stores meta data
   2454         // instead of YUV data. The release is delayed until
   2455         // EMPTY_BUFFER_DONE callback is received.
   2456         bool releaseBuffer = true;
   2457         if (mIsEncoder && (mQuirks & kAvoidMemcopyInputRecordingFrames)) {
   2458             CHECK(mOMXLivesLocally && offset == 0);
   2459             OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *) info->mBuffer;
   2460             header->pBuffer = (OMX_U8 *) srcBuffer->data() + srcBuffer->range_offset();
   2461         } else {
   2462             if (mQuirks & kStoreMetaDataInInputVideoBuffers) {
   2463                 releaseBuffer = false;
   2464                 info->mMediaBuffer = srcBuffer;
   2465             }
   2466             memcpy((uint8_t *)info->mData + offset,
   2467                     (const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(),
   2468                     srcBuffer->range_length());
   2469         }
   2470 
   2471         int64_t lastBufferTimeUs;
   2472         CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs));
   2473         CHECK(lastBufferTimeUs >= 0);
   2474 
   2475         if (offset == 0) {
   2476             timestampUs = lastBufferTimeUs;
   2477         }
   2478 
   2479         offset += srcBuffer->range_length();
   2480 
   2481         if (releaseBuffer) {
   2482             srcBuffer->release();
   2483             srcBuffer = NULL;
   2484         }
   2485 
   2486         ++n;
   2487 
   2488         if (!(mQuirks & kSupportsMultipleFramesPerInputBuffer)) {
   2489             break;
   2490         }
   2491 
   2492         int64_t coalescedDurationUs = lastBufferTimeUs - timestampUs;
   2493 
   2494         if (coalescedDurationUs > 250000ll) {
   2495             // Don't coalesce more than 250ms worth of encoded data at once.
   2496             break;
   2497         }
   2498     }
   2499 
   2500     if (n > 1) {
   2501         LOGV("coalesced %d frames into one input buffer", n);
   2502     }
   2503 
   2504     OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
   2505 
   2506     if (signalEOS) {
   2507         flags |= OMX_BUFFERFLAG_EOS;
   2508     } else {
   2509         mNoMoreOutputData = false;
   2510     }
   2511 
   2512     CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), "
   2513                "timestamp %lld us (%.2f secs)",
   2514                info->mBuffer, offset,
   2515                timestampUs, timestampUs / 1E6);
   2516 
   2517     err = mOMX->emptyBuffer(
   2518             mNode, info->mBuffer, 0, offset,
   2519             flags, timestampUs);
   2520 
   2521     if (err != OK) {
   2522         setState(ERROR);
   2523         return;
   2524     }
   2525 
   2526     info->mOwnedByComponent = true;
   2527 
   2528     // This component does not ever signal the EOS flag on output buffers,
   2529     // Thanks for nothing.
   2530     if (mSignalledEOS && !strcmp(mComponentName, "OMX.TI.Video.encoder")) {
   2531         mNoMoreOutputData = true;
   2532         mBufferFilled.signal();
   2533     }
   2534 }
   2535 
   2536 void OMXCodec::fillOutputBuffer(BufferInfo *info) {
   2537     CHECK_EQ(info->mOwnedByComponent, false);
   2538 
   2539     if (mNoMoreOutputData) {
   2540         CODEC_LOGV("There is no more output data available, not "
   2541              "calling fillOutputBuffer");
   2542         return;
   2543     }
   2544 
   2545     CODEC_LOGV("Calling fill_buffer on buffer %p", info->mBuffer);
   2546     status_t err = mOMX->fillBuffer(mNode, info->mBuffer);
   2547 
   2548     if (err != OK) {
   2549         CODEC_LOGE("fillBuffer failed w/ error 0x%08x", err);
   2550 
   2551         setState(ERROR);
   2552         return;
   2553     }
   2554 
   2555     info->mOwnedByComponent = true;
   2556 }
   2557 
   2558 void OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) {
   2559     Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
   2560     for (size_t i = 0; i < buffers->size(); ++i) {
   2561         if ((*buffers)[i].mBuffer == buffer) {
   2562             drainInputBuffer(&buffers->editItemAt(i));
   2563             return;
   2564         }
   2565     }
   2566 
   2567     CHECK(!"should not be here.");
   2568 }
   2569 
   2570 void OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) {
   2571     Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
   2572     for (size_t i = 0; i < buffers->size(); ++i) {
   2573         if ((*buffers)[i].mBuffer == buffer) {
   2574             fillOutputBuffer(&buffers->editItemAt(i));
   2575             return;
   2576         }
   2577     }
   2578 
   2579     CHECK(!"should not be here.");
   2580 }
   2581 
   2582 void OMXCodec::setState(State newState) {
   2583     mState = newState;
   2584     mAsyncCompletion.signal();
   2585 
   2586     // This may cause some spurious wakeups but is necessary to
   2587     // unblock the reader if we enter ERROR state.
   2588     mBufferFilled.signal();
   2589 }
   2590 
   2591 void OMXCodec::setRawAudioFormat(
   2592         OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
   2593 
   2594     // port definition
   2595     OMX_PARAM_PORTDEFINITIONTYPE def;
   2596     InitOMXParams(&def);
   2597     def.nPortIndex = portIndex;
   2598     status_t err = mOMX->getParameter(
   2599             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   2600     CHECK_EQ(err, OK);
   2601     def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
   2602     CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition,
   2603             &def, sizeof(def)), OK);
   2604 
   2605     // pcm param
   2606     OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
   2607     InitOMXParams(&pcmParams);
   2608     pcmParams.nPortIndex = portIndex;
   2609 
   2610     err = mOMX->getParameter(
   2611             mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
   2612 
   2613     CHECK_EQ(err, OK);
   2614 
   2615     pcmParams.nChannels = numChannels;
   2616     pcmParams.eNumData = OMX_NumericalDataSigned;
   2617     pcmParams.bInterleaved = OMX_TRUE;
   2618     pcmParams.nBitPerSample = 16;
   2619     pcmParams.nSamplingRate = sampleRate;
   2620     pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
   2621 
   2622     if (numChannels == 1) {
   2623         pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF;
   2624     } else {
   2625         CHECK_EQ(numChannels, 2);
   2626 
   2627         pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
   2628         pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
   2629     }
   2630 
   2631     err = mOMX->setParameter(
   2632             mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
   2633 
   2634     CHECK_EQ(err, OK);
   2635 }
   2636 
   2637 static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(bool isAMRWB, int32_t bps) {
   2638     if (isAMRWB) {
   2639         if (bps <= 6600) {
   2640             return OMX_AUDIO_AMRBandModeWB0;
   2641         } else if (bps <= 8850) {
   2642             return OMX_AUDIO_AMRBandModeWB1;
   2643         } else if (bps <= 12650) {
   2644             return OMX_AUDIO_AMRBandModeWB2;
   2645         } else if (bps <= 14250) {
   2646             return OMX_AUDIO_AMRBandModeWB3;
   2647         } else if (bps <= 15850) {
   2648             return OMX_AUDIO_AMRBandModeWB4;
   2649         } else if (bps <= 18250) {
   2650             return OMX_AUDIO_AMRBandModeWB5;
   2651         } else if (bps <= 19850) {
   2652             return OMX_AUDIO_AMRBandModeWB6;
   2653         } else if (bps <= 23050) {
   2654             return OMX_AUDIO_AMRBandModeWB7;
   2655         }
   2656 
   2657         // 23850 bps
   2658         return OMX_AUDIO_AMRBandModeWB8;
   2659     } else {  // AMRNB
   2660         if (bps <= 4750) {
   2661             return OMX_AUDIO_AMRBandModeNB0;
   2662         } else if (bps <= 5150) {
   2663             return OMX_AUDIO_AMRBandModeNB1;
   2664         } else if (bps <= 5900) {
   2665             return OMX_AUDIO_AMRBandModeNB2;
   2666         } else if (bps <= 6700) {
   2667             return OMX_AUDIO_AMRBandModeNB3;
   2668         } else if (bps <= 7400) {
   2669             return OMX_AUDIO_AMRBandModeNB4;
   2670         } else if (bps <= 7950) {
   2671             return OMX_AUDIO_AMRBandModeNB5;
   2672         } else if (bps <= 10200) {
   2673             return OMX_AUDIO_AMRBandModeNB6;
   2674         }
   2675 
   2676         // 12200 bps
   2677         return OMX_AUDIO_AMRBandModeNB7;
   2678     }
   2679 }
   2680 
   2681 void OMXCodec::setAMRFormat(bool isWAMR, int32_t bitRate) {
   2682     OMX_U32 portIndex = mIsEncoder ? kPortIndexOutput : kPortIndexInput;
   2683 
   2684     OMX_AUDIO_PARAM_AMRTYPE def;
   2685     InitOMXParams(&def);
   2686     def.nPortIndex = portIndex;
   2687 
   2688     status_t err =
   2689         mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
   2690 
   2691     CHECK_EQ(err, OK);
   2692 
   2693     def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
   2694 
   2695     def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitRate);
   2696     err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
   2697     CHECK_EQ(err, OK);
   2698 
   2699     ////////////////////////
   2700 
   2701     if (mIsEncoder) {
   2702         sp<MetaData> format = mSource->getFormat();
   2703         int32_t sampleRate;
   2704         int32_t numChannels;
   2705         CHECK(format->findInt32(kKeySampleRate, &sampleRate));
   2706         CHECK(format->findInt32(kKeyChannelCount, &numChannels));
   2707 
   2708         setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
   2709     }
   2710 }
   2711 
   2712 void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate, int32_t bitRate) {
   2713     CHECK(numChannels == 1 || numChannels == 2);
   2714     if (mIsEncoder) {
   2715         //////////////// input port ////////////////////
   2716         setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
   2717 
   2718         //////////////// output port ////////////////////
   2719         // format
   2720         OMX_AUDIO_PARAM_PORTFORMATTYPE format;
   2721         format.nPortIndex = kPortIndexOutput;
   2722         format.nIndex = 0;
   2723         status_t err = OMX_ErrorNone;
   2724         while (OMX_ErrorNone == err) {
   2725             CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioPortFormat,
   2726                     &format, sizeof(format)), OK);
   2727             if (format.eEncoding == OMX_AUDIO_CodingAAC) {
   2728                 break;
   2729             }
   2730             format.nIndex++;
   2731         }
   2732         CHECK_EQ(OK, err);
   2733         CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamAudioPortFormat,
   2734                 &format, sizeof(format)), OK);
   2735 
   2736         // port definition
   2737         OMX_PARAM_PORTDEFINITIONTYPE def;
   2738         InitOMXParams(&def);
   2739         def.nPortIndex = kPortIndexOutput;
   2740         CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamPortDefinition,
   2741                 &def, sizeof(def)), OK);
   2742         def.format.audio.bFlagErrorConcealment = OMX_TRUE;
   2743         def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
   2744         CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition,
   2745                 &def, sizeof(def)), OK);
   2746 
   2747         // profile
   2748         OMX_AUDIO_PARAM_AACPROFILETYPE profile;
   2749         InitOMXParams(&profile);
   2750         profile.nPortIndex = kPortIndexOutput;
   2751         CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioAac,
   2752                 &profile, sizeof(profile)), OK);
   2753         profile.nChannels = numChannels;
   2754         profile.eChannelMode = (numChannels == 1?
   2755                 OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo);
   2756         profile.nSampleRate = sampleRate;
   2757         profile.nBitRate = bitRate;
   2758         profile.nAudioBandWidth = 0;
   2759         profile.nFrameLength = 0;
   2760         profile.nAACtools = OMX_AUDIO_AACToolAll;
   2761         profile.nAACERtools = OMX_AUDIO_AACERNone;
   2762         profile.eAACProfile = OMX_AUDIO_AACObjectLC;
   2763         profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
   2764         CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamAudioAac,
   2765                 &profile, sizeof(profile)), OK);
   2766 
   2767     } else {
   2768         OMX_AUDIO_PARAM_AACPROFILETYPE profile;
   2769         InitOMXParams(&profile);
   2770         profile.nPortIndex = kPortIndexInput;
   2771 
   2772         status_t err = mOMX->getParameter(
   2773                 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
   2774         CHECK_EQ(err, OK);
   2775 
   2776         profile.nChannels = numChannels;
   2777         profile.nSampleRate = sampleRate;
   2778         profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
   2779 
   2780         err = mOMX->setParameter(
   2781                 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
   2782         CHECK_EQ(err, OK);
   2783     }
   2784 }
   2785 
   2786 void OMXCodec::setImageOutputFormat(
   2787         OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) {
   2788     CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height);
   2789 
   2790 #if 0
   2791     OMX_INDEXTYPE index;
   2792     status_t err = mOMX->get_extension_index(
   2793             mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index);
   2794     CHECK_EQ(err, OK);
   2795 
   2796     err = mOMX->set_config(mNode, index, &format, sizeof(format));
   2797     CHECK_EQ(err, OK);
   2798 #endif
   2799 
   2800     OMX_PARAM_PORTDEFINITIONTYPE def;
   2801     InitOMXParams(&def);
   2802     def.nPortIndex = kPortIndexOutput;
   2803 
   2804     status_t err = mOMX->getParameter(
   2805             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   2806     CHECK_EQ(err, OK);
   2807 
   2808     CHECK_EQ(def.eDomain, OMX_PortDomainImage);
   2809 
   2810     OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
   2811 
   2812     CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused);
   2813     imageDef->eColorFormat = format;
   2814     imageDef->nFrameWidth = width;
   2815     imageDef->nFrameHeight = height;
   2816 
   2817     switch (format) {
   2818         case OMX_COLOR_FormatYUV420PackedPlanar:
   2819         case OMX_COLOR_FormatYUV411Planar:
   2820         {
   2821             def.nBufferSize = (width * height * 3) / 2;
   2822             break;
   2823         }
   2824 
   2825         case OMX_COLOR_FormatCbYCrY:
   2826         {
   2827             def.nBufferSize = width * height * 2;
   2828             break;
   2829         }
   2830 
   2831         case OMX_COLOR_Format32bitARGB8888:
   2832         {
   2833             def.nBufferSize = width * height * 4;
   2834             break;
   2835         }
   2836 
   2837         case OMX_COLOR_Format16bitARGB4444:
   2838         case OMX_COLOR_Format16bitARGB1555:
   2839         case OMX_COLOR_Format16bitRGB565:
   2840         case OMX_COLOR_Format16bitBGR565:
   2841         {
   2842             def.nBufferSize = width * height * 2;
   2843             break;
   2844         }
   2845 
   2846         default:
   2847             CHECK(!"Should not be here. Unknown color format.");
   2848             break;
   2849     }
   2850 
   2851     def.nBufferCountActual = def.nBufferCountMin;
   2852 
   2853     err = mOMX->setParameter(
   2854             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   2855     CHECK_EQ(err, OK);
   2856 }
   2857 
   2858 void OMXCodec::setJPEGInputFormat(
   2859         OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) {
   2860     OMX_PARAM_PORTDEFINITIONTYPE def;
   2861     InitOMXParams(&def);
   2862     def.nPortIndex = kPortIndexInput;
   2863 
   2864     status_t err = mOMX->getParameter(
   2865             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   2866     CHECK_EQ(err, OK);
   2867 
   2868     CHECK_EQ(def.eDomain, OMX_PortDomainImage);
   2869     OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
   2870 
   2871     CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingJPEG);
   2872     imageDef->nFrameWidth = width;
   2873     imageDef->nFrameHeight = height;
   2874 
   2875     def.nBufferSize = compressedSize;
   2876     def.nBufferCountActual = def.nBufferCountMin;
   2877 
   2878     err = mOMX->setParameter(
   2879             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   2880     CHECK_EQ(err, OK);
   2881 }
   2882 
   2883 void OMXCodec::addCodecSpecificData(const void *data, size_t size) {
   2884     CodecSpecificData *specific =
   2885         (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1);
   2886 
   2887     specific->mSize = size;
   2888     memcpy(specific->mData, data, size);
   2889 
   2890     mCodecSpecificData.push(specific);
   2891 }
   2892 
   2893 void OMXCodec::clearCodecSpecificData() {
   2894     for (size_t i = 0; i < mCodecSpecificData.size(); ++i) {
   2895         free(mCodecSpecificData.editItemAt(i));
   2896     }
   2897     mCodecSpecificData.clear();
   2898     mCodecSpecificDataIndex = 0;
   2899 }
   2900 
   2901 status_t OMXCodec::start(MetaData *meta) {
   2902     Mutex::Autolock autoLock(mLock);
   2903 
   2904     if (mState != LOADED) {
   2905         return UNKNOWN_ERROR;
   2906     }
   2907 
   2908     sp<MetaData> params = new MetaData;
   2909     if (mQuirks & kWantsNALFragments) {
   2910         params->setInt32(kKeyWantsNALFragments, true);
   2911     }
   2912     if (meta) {
   2913         int64_t startTimeUs = 0;
   2914         int64_t timeUs;
   2915         if (meta->findInt64(kKeyTime, &timeUs)) {
   2916             startTimeUs = timeUs;
   2917         }
   2918         params->setInt64(kKeyTime, startTimeUs);
   2919     }
   2920     status_t err = mSource->start(params.get());
   2921 
   2922     if (err != OK) {
   2923         return err;
   2924     }
   2925 
   2926     mCodecSpecificDataIndex = 0;
   2927     mInitialBufferSubmit = true;
   2928     mSignalledEOS = false;
   2929     mNoMoreOutputData = false;
   2930     mOutputPortSettingsHaveChanged = false;
   2931     mSeekTimeUs = -1;
   2932     mSeekMode = ReadOptions::SEEK_CLOSEST_SYNC;
   2933     mTargetTimeUs = -1;
   2934     mFilledBuffers.clear();
   2935     mPaused = false;
   2936 
   2937     return init();
   2938 }
   2939 
   2940 status_t OMXCodec::stop() {
   2941     CODEC_LOGV("stop mState=%d", mState);
   2942 
   2943     Mutex::Autolock autoLock(mLock);
   2944 
   2945     while (isIntermediateState(mState)) {
   2946         mAsyncCompletion.wait(mLock);
   2947     }
   2948 
   2949     switch (mState) {
   2950         case LOADED:
   2951         case ERROR:
   2952             break;
   2953 
   2954         case EXECUTING:
   2955         {
   2956             setState(EXECUTING_TO_IDLE);
   2957 
   2958             if (mQuirks & kRequiresFlushBeforeShutdown) {
   2959                 CODEC_LOGV("This component requires a flush before transitioning "
   2960                      "from EXECUTING to IDLE...");
   2961 
   2962                 bool emulateInputFlushCompletion =
   2963                     !flushPortAsync(kPortIndexInput);
   2964 
   2965                 bool emulateOutputFlushCompletion =
   2966                     !flushPortAsync(kPortIndexOutput);
   2967 
   2968                 if (emulateInputFlushCompletion) {
   2969                     onCmdComplete(OMX_CommandFlush, kPortIndexInput);
   2970                 }
   2971 
   2972                 if (emulateOutputFlushCompletion) {
   2973                     onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
   2974                 }
   2975             } else {
   2976                 mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
   2977                 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
   2978 
   2979                 status_t err =
   2980                     mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
   2981                 CHECK_EQ(err, OK);
   2982             }
   2983 
   2984             while (mState != LOADED && mState != ERROR) {
   2985                 mAsyncCompletion.wait(mLock);
   2986             }
   2987 
   2988             break;
   2989         }
   2990 
   2991         default:
   2992         {
   2993             CHECK(!"should not be here.");
   2994             break;
   2995         }
   2996     }
   2997 
   2998     if (mLeftOverBuffer) {
   2999         mLeftOverBuffer->release();
   3000         mLeftOverBuffer = NULL;
   3001     }
   3002 
   3003     mSource->stop();
   3004 
   3005     CODEC_LOGV("stopped");
   3006 
   3007     return OK;
   3008 }
   3009 
   3010 sp<MetaData> OMXCodec::getFormat() {
   3011     Mutex::Autolock autoLock(mLock);
   3012 
   3013     return mOutputFormat;
   3014 }
   3015 
   3016 status_t OMXCodec::read(
   3017         MediaBuffer **buffer, const ReadOptions *options) {
   3018     *buffer = NULL;
   3019 
   3020     Mutex::Autolock autoLock(mLock);
   3021 
   3022     if (mState != EXECUTING && mState != RECONFIGURING) {
   3023         return UNKNOWN_ERROR;
   3024     }
   3025 
   3026     bool seeking = false;
   3027     int64_t seekTimeUs;
   3028     ReadOptions::SeekMode seekMode;
   3029     if (options && options->getSeekTo(&seekTimeUs, &seekMode)) {
   3030         seeking = true;
   3031     }
   3032     int64_t skipTimeUs;
   3033     if (options && options->getSkipFrame(&skipTimeUs)) {
   3034         mSkipTimeUs = skipTimeUs;
   3035     } else {
   3036         mSkipTimeUs = -1;
   3037     }
   3038 
   3039     if (mInitialBufferSubmit) {
   3040         mInitialBufferSubmit = false;
   3041 
   3042         if (seeking) {
   3043             CHECK(seekTimeUs >= 0);
   3044             mSeekTimeUs = seekTimeUs;
   3045             mSeekMode = seekMode;
   3046 
   3047             // There's no reason to trigger the code below, there's
   3048             // nothing to flush yet.
   3049             seeking = false;
   3050             mPaused = false;
   3051         }
   3052 
   3053         drainInputBuffers();
   3054 
   3055         if (mState == EXECUTING) {
   3056             // Otherwise mState == RECONFIGURING and this code will trigger
   3057             // after the output port is reenabled.
   3058             fillOutputBuffers();
   3059         }
   3060     }
   3061 
   3062     if (seeking) {
   3063         CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
   3064 
   3065         mSignalledEOS = false;
   3066 
   3067         CHECK(seekTimeUs >= 0);
   3068         mSeekTimeUs = seekTimeUs;
   3069         mSeekMode = seekMode;
   3070 
   3071         mFilledBuffers.clear();
   3072 
   3073         CHECK_EQ(mState, EXECUTING);
   3074 
   3075         bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput);
   3076         bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput);
   3077 
   3078         if (emulateInputFlushCompletion) {
   3079             onCmdComplete(OMX_CommandFlush, kPortIndexInput);
   3080         }
   3081 
   3082         if (emulateOutputFlushCompletion) {
   3083             onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
   3084         }
   3085 
   3086         while (mSeekTimeUs >= 0) {
   3087             mBufferFilled.wait(mLock);
   3088         }
   3089     }
   3090 
   3091     while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) {
   3092         mBufferFilled.wait(mLock);
   3093     }
   3094 
   3095     if (mState == ERROR) {
   3096         return UNKNOWN_ERROR;
   3097     }
   3098 
   3099     if (mFilledBuffers.empty()) {
   3100         return mSignalledEOS ? mFinalStatus : ERROR_END_OF_STREAM;
   3101     }
   3102 
   3103     if (mOutputPortSettingsHaveChanged) {
   3104         mOutputPortSettingsHaveChanged = false;
   3105 
   3106         return INFO_FORMAT_CHANGED;
   3107     }
   3108 
   3109     size_t index = *mFilledBuffers.begin();
   3110     mFilledBuffers.erase(mFilledBuffers.begin());
   3111 
   3112     BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
   3113     info->mMediaBuffer->add_ref();
   3114     *buffer = info->mMediaBuffer;
   3115 
   3116     return OK;
   3117 }
   3118 
   3119 void OMXCodec::signalBufferReturned(MediaBuffer *buffer) {
   3120     Mutex::Autolock autoLock(mLock);
   3121 
   3122     Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
   3123     for (size_t i = 0; i < buffers->size(); ++i) {
   3124         BufferInfo *info = &buffers->editItemAt(i);
   3125 
   3126         if (info->mMediaBuffer == buffer) {
   3127             CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED);
   3128             fillOutputBuffer(info);
   3129             return;
   3130         }
   3131     }
   3132 
   3133     CHECK(!"should not be here.");
   3134 }
   3135 
   3136 static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) {
   3137     static const char *kNames[] = {
   3138         "OMX_IMAGE_CodingUnused",
   3139         "OMX_IMAGE_CodingAutoDetect",
   3140         "OMX_IMAGE_CodingJPEG",
   3141         "OMX_IMAGE_CodingJPEG2K",
   3142         "OMX_IMAGE_CodingEXIF",
   3143         "OMX_IMAGE_CodingTIFF",
   3144         "OMX_IMAGE_CodingGIF",
   3145         "OMX_IMAGE_CodingPNG",
   3146         "OMX_IMAGE_CodingLZW",
   3147         "OMX_IMAGE_CodingBMP",
   3148     };
   3149 
   3150     size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
   3151 
   3152     if (type < 0 || (size_t)type >= numNames) {
   3153         return "UNKNOWN";
   3154     } else {
   3155         return kNames[type];
   3156     }
   3157 }
   3158 
   3159 static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) {
   3160     static const char *kNames[] = {
   3161         "OMX_COLOR_FormatUnused",
   3162         "OMX_COLOR_FormatMonochrome",
   3163         "OMX_COLOR_Format8bitRGB332",
   3164         "OMX_COLOR_Format12bitRGB444",
   3165         "OMX_COLOR_Format16bitARGB4444",
   3166         "OMX_COLOR_Format16bitARGB1555",
   3167         "OMX_COLOR_Format16bitRGB565",
   3168         "OMX_COLOR_Format16bitBGR565",
   3169         "OMX_COLOR_Format18bitRGB666",
   3170         "OMX_COLOR_Format18bitARGB1665",
   3171         "OMX_COLOR_Format19bitARGB1666",
   3172         "OMX_COLOR_Format24bitRGB888",
   3173         "OMX_COLOR_Format24bitBGR888",
   3174         "OMX_COLOR_Format24bitARGB1887",
   3175         "OMX_COLOR_Format25bitARGB1888",
   3176         "OMX_COLOR_Format32bitBGRA8888",
   3177         "OMX_COLOR_Format32bitARGB8888",
   3178         "OMX_COLOR_FormatYUV411Planar",
   3179         "OMX_COLOR_FormatYUV411PackedPlanar",
   3180         "OMX_COLOR_FormatYUV420Planar",
   3181         "OMX_COLOR_FormatYUV420PackedPlanar",
   3182         "OMX_COLOR_FormatYUV420SemiPlanar",
   3183         "OMX_COLOR_FormatYUV422Planar",
   3184         "OMX_COLOR_FormatYUV422PackedPlanar",
   3185         "OMX_COLOR_FormatYUV422SemiPlanar",
   3186         "OMX_COLOR_FormatYCbYCr",
   3187         "OMX_COLOR_FormatYCrYCb",
   3188         "OMX_COLOR_FormatCbYCrY",
   3189         "OMX_COLOR_FormatCrYCbY",
   3190         "OMX_COLOR_FormatYUV444Interleaved",
   3191         "OMX_COLOR_FormatRawBayer8bit",
   3192         "OMX_COLOR_FormatRawBayer10bit",
   3193         "OMX_COLOR_FormatRawBayer8bitcompressed",
   3194         "OMX_COLOR_FormatL2",
   3195         "OMX_COLOR_FormatL4",
   3196         "OMX_COLOR_FormatL8",
   3197         "OMX_COLOR_FormatL16",
   3198         "OMX_COLOR_FormatL24",
   3199         "OMX_COLOR_FormatL32",
   3200         "OMX_COLOR_FormatYUV420PackedSemiPlanar",
   3201         "OMX_COLOR_FormatYUV422PackedSemiPlanar",
   3202         "OMX_COLOR_Format18BitBGR666",
   3203         "OMX_COLOR_Format24BitARGB6666",
   3204         "OMX_COLOR_Format24BitABGR6666",
   3205     };
   3206 
   3207     size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
   3208 
   3209     if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) {
   3210         return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar";
   3211     } else if (type < 0 || (size_t)type >= numNames) {
   3212         return "UNKNOWN";
   3213     } else {
   3214         return kNames[type];
   3215     }
   3216 }
   3217 
   3218 static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) {
   3219     static const char *kNames[] = {
   3220         "OMX_VIDEO_CodingUnused",
   3221         "OMX_VIDEO_CodingAutoDetect",
   3222         "OMX_VIDEO_CodingMPEG2",
   3223         "OMX_VIDEO_CodingH263",
   3224         "OMX_VIDEO_CodingMPEG4",
   3225         "OMX_VIDEO_CodingWMV",
   3226         "OMX_VIDEO_CodingRV",
   3227         "OMX_VIDEO_CodingAVC",
   3228         "OMX_VIDEO_CodingMJPEG",
   3229     };
   3230 
   3231     size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
   3232 
   3233     if (type < 0 || (size_t)type >= numNames) {
   3234         return "UNKNOWN";
   3235     } else {
   3236         return kNames[type];
   3237     }
   3238 }
   3239 
   3240 static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) {
   3241     static const char *kNames[] = {
   3242         "OMX_AUDIO_CodingUnused",
   3243         "OMX_AUDIO_CodingAutoDetect",
   3244         "OMX_AUDIO_CodingPCM",
   3245         "OMX_AUDIO_CodingADPCM",
   3246         "OMX_AUDIO_CodingAMR",
   3247         "OMX_AUDIO_CodingGSMFR",
   3248         "OMX_AUDIO_CodingGSMEFR",
   3249         "OMX_AUDIO_CodingGSMHR",
   3250         "OMX_AUDIO_CodingPDCFR",
   3251         "OMX_AUDIO_CodingPDCEFR",
   3252         "OMX_AUDIO_CodingPDCHR",
   3253         "OMX_AUDIO_CodingTDMAFR",
   3254         "OMX_AUDIO_CodingTDMAEFR",
   3255         "OMX_AUDIO_CodingQCELP8",
   3256         "OMX_AUDIO_CodingQCELP13",
   3257         "OMX_AUDIO_CodingEVRC",
   3258         "OMX_AUDIO_CodingSMV",
   3259         "OMX_AUDIO_CodingG711",
   3260         "OMX_AUDIO_CodingG723",
   3261         "OMX_AUDIO_CodingG726",
   3262         "OMX_AUDIO_CodingG729",
   3263         "OMX_AUDIO_CodingAAC",
   3264         "OMX_AUDIO_CodingMP3",
   3265         "OMX_AUDIO_CodingSBC",
   3266         "OMX_AUDIO_CodingVORBIS",
   3267         "OMX_AUDIO_CodingWMA",
   3268         "OMX_AUDIO_CodingRA",
   3269         "OMX_AUDIO_CodingMIDI",
   3270     };
   3271 
   3272     size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
   3273 
   3274     if (type < 0 || (size_t)type >= numNames) {
   3275         return "UNKNOWN";
   3276     } else {
   3277         return kNames[type];
   3278     }
   3279 }
   3280 
   3281 static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) {
   3282     static const char *kNames[] = {
   3283         "OMX_AUDIO_PCMModeLinear",
   3284         "OMX_AUDIO_PCMModeALaw",
   3285         "OMX_AUDIO_PCMModeMULaw",
   3286     };
   3287 
   3288     size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
   3289 
   3290     if (type < 0 || (size_t)type >= numNames) {
   3291         return "UNKNOWN";
   3292     } else {
   3293         return kNames[type];
   3294     }
   3295 }
   3296 
   3297 static const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) {
   3298     static const char *kNames[] = {
   3299         "OMX_AUDIO_AMRBandModeUnused",
   3300         "OMX_AUDIO_AMRBandModeNB0",
   3301         "OMX_AUDIO_AMRBandModeNB1",
   3302         "OMX_AUDIO_AMRBandModeNB2",
   3303         "OMX_AUDIO_AMRBandModeNB3",
   3304         "OMX_AUDIO_AMRBandModeNB4",
   3305         "OMX_AUDIO_AMRBandModeNB5",
   3306         "OMX_AUDIO_AMRBandModeNB6",
   3307         "OMX_AUDIO_AMRBandModeNB7",
   3308         "OMX_AUDIO_AMRBandModeWB0",
   3309         "OMX_AUDIO_AMRBandModeWB1",
   3310         "OMX_AUDIO_AMRBandModeWB2",
   3311         "OMX_AUDIO_AMRBandModeWB3",
   3312         "OMX_AUDIO_AMRBandModeWB4",
   3313         "OMX_AUDIO_AMRBandModeWB5",
   3314         "OMX_AUDIO_AMRBandModeWB6",
   3315         "OMX_AUDIO_AMRBandModeWB7",
   3316         "OMX_AUDIO_AMRBandModeWB8",
   3317     };
   3318 
   3319     size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
   3320 
   3321     if (type < 0 || (size_t)type >= numNames) {
   3322         return "UNKNOWN";
   3323     } else {
   3324         return kNames[type];
   3325     }
   3326 }
   3327 
   3328 static const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) {
   3329     static const char *kNames[] = {
   3330         "OMX_AUDIO_AMRFrameFormatConformance",
   3331         "OMX_AUDIO_AMRFrameFormatIF1",
   3332         "OMX_AUDIO_AMRFrameFormatIF2",
   3333         "OMX_AUDIO_AMRFrameFormatFSF",
   3334         "OMX_AUDIO_AMRFrameFormatRTPPayload",
   3335         "OMX_AUDIO_AMRFrameFormatITU",
   3336     };
   3337 
   3338     size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
   3339 
   3340     if (type < 0 || (size_t)type >= numNames) {
   3341         return "UNKNOWN";
   3342     } else {
   3343         return kNames[type];
   3344     }
   3345 }
   3346 
   3347 void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
   3348     OMX_PARAM_PORTDEFINITIONTYPE def;
   3349     InitOMXParams(&def);
   3350     def.nPortIndex = portIndex;
   3351 
   3352     status_t err = mOMX->getParameter(
   3353             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   3354     CHECK_EQ(err, OK);
   3355 
   3356     printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output");
   3357 
   3358     CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput)
   3359           || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput));
   3360 
   3361     printf("  nBufferCountActual = %ld\n", def.nBufferCountActual);
   3362     printf("  nBufferCountMin = %ld\n", def.nBufferCountMin);
   3363     printf("  nBufferSize = %ld\n", def.nBufferSize);
   3364 
   3365     switch (def.eDomain) {
   3366         case OMX_PortDomainImage:
   3367         {
   3368             const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
   3369 
   3370             printf("\n");
   3371             printf("  // Image\n");
   3372             printf("  nFrameWidth = %ld\n", imageDef->nFrameWidth);
   3373             printf("  nFrameHeight = %ld\n", imageDef->nFrameHeight);
   3374             printf("  nStride = %ld\n", imageDef->nStride);
   3375 
   3376             printf("  eCompressionFormat = %s\n",
   3377                    imageCompressionFormatString(imageDef->eCompressionFormat));
   3378 
   3379             printf("  eColorFormat = %s\n",
   3380                    colorFormatString(imageDef->eColorFormat));
   3381 
   3382             break;
   3383         }
   3384 
   3385         case OMX_PortDomainVideo:
   3386         {
   3387             OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
   3388 
   3389             printf("\n");
   3390             printf("  // Video\n");
   3391             printf("  nFrameWidth = %ld\n", videoDef->nFrameWidth);
   3392             printf("  nFrameHeight = %ld\n", videoDef->nFrameHeight);
   3393             printf("  nStride = %ld\n", videoDef->nStride);
   3394 
   3395             printf("  eCompressionFormat = %s\n",
   3396                    videoCompressionFormatString(videoDef->eCompressionFormat));
   3397 
   3398             printf("  eColorFormat = %s\n",
   3399                    colorFormatString(videoDef->eColorFormat));
   3400 
   3401             break;
   3402         }
   3403 
   3404         case OMX_PortDomainAudio:
   3405         {
   3406             OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
   3407 
   3408             printf("\n");
   3409             printf("  // Audio\n");
   3410             printf("  eEncoding = %s\n",
   3411                    audioCodingTypeString(audioDef->eEncoding));
   3412 
   3413             if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) {
   3414                 OMX_AUDIO_PARAM_PCMMODETYPE params;
   3415                 InitOMXParams(&params);
   3416                 params.nPortIndex = portIndex;
   3417 
   3418                 err = mOMX->getParameter(
   3419                         mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
   3420                 CHECK_EQ(err, OK);
   3421 
   3422                 printf("  nSamplingRate = %ld\n", params.nSamplingRate);
   3423                 printf("  nChannels = %ld\n", params.nChannels);
   3424                 printf("  bInterleaved = %d\n", params.bInterleaved);
   3425                 printf("  nBitPerSample = %ld\n", params.nBitPerSample);
   3426 
   3427                 printf("  eNumData = %s\n",
   3428                        params.eNumData == OMX_NumericalDataSigned
   3429                         ? "signed" : "unsigned");
   3430 
   3431                 printf("  ePCMMode = %s\n", audioPCMModeString(params.ePCMMode));
   3432             } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) {
   3433                 OMX_AUDIO_PARAM_AMRTYPE amr;
   3434                 InitOMXParams(&amr);
   3435                 amr.nPortIndex = portIndex;
   3436 
   3437                 err = mOMX->getParameter(
   3438                         mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
   3439                 CHECK_EQ(err, OK);
   3440 
   3441                 printf("  nChannels = %ld\n", amr.nChannels);
   3442                 printf("  eAMRBandMode = %s\n",
   3443                         amrBandModeString(amr.eAMRBandMode));
   3444                 printf("  eAMRFrameFormat = %s\n",
   3445                         amrFrameFormatString(amr.eAMRFrameFormat));
   3446             }
   3447 
   3448             break;
   3449         }
   3450 
   3451         default:
   3452         {
   3453             printf("  // Unknown\n");
   3454             break;
   3455         }
   3456     }
   3457 
   3458     printf("}\n");
   3459 }
   3460 
   3461 void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
   3462     mOutputFormat = new MetaData;
   3463     mOutputFormat->setCString(kKeyDecoderComponent, mComponentName);
   3464     if (mIsEncoder) {
   3465         int32_t timeScale;
   3466         if (inputFormat->findInt32(kKeyTimeScale, &timeScale)) {
   3467             mOutputFormat->setInt32(kKeyTimeScale, timeScale);
   3468         }
   3469     }
   3470 
   3471     OMX_PARAM_PORTDEFINITIONTYPE def;
   3472     InitOMXParams(&def);
   3473     def.nPortIndex = kPortIndexOutput;
   3474 
   3475     status_t err = mOMX->getParameter(
   3476             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   3477     CHECK_EQ(err, OK);
   3478 
   3479     switch (def.eDomain) {
   3480         case OMX_PortDomainImage:
   3481         {
   3482             OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
   3483             CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused);
   3484 
   3485             mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
   3486             mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat);
   3487             mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth);
   3488             mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight);
   3489             break;
   3490         }
   3491 
   3492         case OMX_PortDomainAudio:
   3493         {
   3494             OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio;
   3495 
   3496             if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) {
   3497                 OMX_AUDIO_PARAM_PCMMODETYPE params;
   3498                 InitOMXParams(&params);
   3499                 params.nPortIndex = kPortIndexOutput;
   3500 
   3501                 err = mOMX->getParameter(
   3502                         mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
   3503                 CHECK_EQ(err, OK);
   3504 
   3505                 CHECK_EQ(params.eNumData, OMX_NumericalDataSigned);
   3506                 CHECK_EQ(params.nBitPerSample, 16);
   3507                 CHECK_EQ(params.ePCMMode, OMX_AUDIO_PCMModeLinear);
   3508 
   3509                 int32_t numChannels, sampleRate;
   3510                 inputFormat->findInt32(kKeyChannelCount, &numChannels);
   3511                 inputFormat->findInt32(kKeySampleRate, &sampleRate);
   3512 
   3513                 if ((OMX_U32)numChannels != params.nChannels) {
   3514                     LOGW("Codec outputs a different number of channels than "
   3515                          "the input stream contains (contains %d channels, "
   3516                          "codec outputs %ld channels).",
   3517                          numChannels, params.nChannels);
   3518                 }
   3519 
   3520                 mOutputFormat->setCString(
   3521                         kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
   3522 
   3523                 // Use the codec-advertised number of channels, as some
   3524                 // codecs appear to output stereo even if the input data is
   3525                 // mono. If we know the codec lies about this information,
   3526                 // use the actual number of channels instead.
   3527                 mOutputFormat->setInt32(
   3528                         kKeyChannelCount,
   3529                         (mQuirks & kDecoderLiesAboutNumberOfChannels)
   3530                             ? numChannels : params.nChannels);
   3531 
   3532                 // The codec-reported sampleRate is not reliable...
   3533                 mOutputFormat->setInt32(kKeySampleRate, sampleRate);
   3534             } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) {
   3535                 OMX_AUDIO_PARAM_AMRTYPE amr;
   3536                 InitOMXParams(&amr);
   3537                 amr.nPortIndex = kPortIndexOutput;
   3538 
   3539                 err = mOMX->getParameter(
   3540                         mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
   3541                 CHECK_EQ(err, OK);
   3542 
   3543                 CHECK_EQ(amr.nChannels, 1);
   3544                 mOutputFormat->setInt32(kKeyChannelCount, 1);
   3545 
   3546                 if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0
   3547                     && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) {
   3548                     mOutputFormat->setCString(
   3549                             kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB);
   3550                     mOutputFormat->setInt32(kKeySampleRate, 8000);
   3551                 } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0
   3552                             && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) {
   3553                     mOutputFormat->setCString(
   3554                             kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB);
   3555                     mOutputFormat->setInt32(kKeySampleRate, 16000);
   3556                 } else {
   3557                     CHECK(!"Unknown AMR band mode.");
   3558                 }
   3559             } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) {
   3560                 mOutputFormat->setCString(
   3561                         kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
   3562                 int32_t numChannels, sampleRate, bitRate;
   3563                 inputFormat->findInt32(kKeyChannelCount, &numChannels);
   3564                 inputFormat->findInt32(kKeySampleRate, &sampleRate);
   3565                 inputFormat->findInt32(kKeyBitRate, &bitRate);
   3566                 mOutputFormat->setInt32(kKeyChannelCount, numChannels);
   3567                 mOutputFormat->setInt32(kKeySampleRate, sampleRate);
   3568                 mOutputFormat->setInt32(kKeyBitRate, bitRate);
   3569             } else {
   3570                 CHECK(!"Should not be here. Unknown audio encoding.");
   3571             }
   3572             break;
   3573         }
   3574 
   3575         case OMX_PortDomainVideo:
   3576         {
   3577             OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
   3578 
   3579             if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) {
   3580                 mOutputFormat->setCString(
   3581                         kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
   3582             } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
   3583                 mOutputFormat->setCString(
   3584                         kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
   3585             } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) {
   3586                 mOutputFormat->setCString(
   3587                         kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
   3588             } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) {
   3589                 mOutputFormat->setCString(
   3590                         kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
   3591             } else {
   3592                 CHECK(!"Unknown compression format.");
   3593             }
   3594 
   3595             if (!strcmp(mComponentName, "OMX.PV.avcdec")) {
   3596                 // This component appears to be lying to me.
   3597                 mOutputFormat->setInt32(
   3598                         kKeyWidth, (video_def->nFrameWidth + 15) & -16);
   3599                 mOutputFormat->setInt32(
   3600                         kKeyHeight, (video_def->nFrameHeight + 15) & -16);
   3601             } else {
   3602                 mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth);
   3603                 mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight);
   3604             }
   3605 
   3606             mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat);
   3607             break;
   3608         }
   3609 
   3610         default:
   3611         {
   3612             CHECK(!"should not be here, neither audio nor video.");
   3613             break;
   3614         }
   3615     }
   3616 }
   3617 
   3618 status_t OMXCodec::pause() {
   3619     Mutex::Autolock autoLock(mLock);
   3620 
   3621     mPaused = true;
   3622 
   3623     return OK;
   3624 }
   3625 
   3626 ////////////////////////////////////////////////////////////////////////////////
   3627 
   3628 status_t QueryCodecs(
   3629         const sp<IOMX> &omx,
   3630         const char *mime, bool queryDecoders,
   3631         Vector<CodecCapabilities> *results) {
   3632     results->clear();
   3633 
   3634     for (int index = 0;; ++index) {
   3635         const char *componentName;
   3636 
   3637         if (!queryDecoders) {
   3638             componentName = GetCodec(
   3639                     kEncoderInfo, sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]),
   3640                     mime, index);
   3641         } else {
   3642             componentName = GetCodec(
   3643                     kDecoderInfo, sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]),
   3644                     mime, index);
   3645         }
   3646 
   3647         if (!componentName) {
   3648             return OK;
   3649         }
   3650 
   3651         if (strncmp(componentName, "OMX.", 4)) {
   3652             // Not an OpenMax component but a software codec.
   3653 
   3654             results->push();
   3655             CodecCapabilities *caps = &results->editItemAt(results->size() - 1);
   3656             caps->mComponentName = componentName;
   3657 
   3658             continue;
   3659         }
   3660 
   3661         sp<OMXCodecObserver> observer = new OMXCodecObserver;
   3662         IOMX::node_id node;
   3663         status_t err = omx->allocateNode(componentName, observer, &node);
   3664 
   3665         if (err != OK) {
   3666             continue;
   3667         }
   3668 
   3669         OMXCodec::setComponentRole(omx, node, !queryDecoders, mime);
   3670 
   3671         results->push();
   3672         CodecCapabilities *caps = &results->editItemAt(results->size() - 1);
   3673         caps->mComponentName = componentName;
   3674 
   3675         OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
   3676         InitOMXParams(&param);
   3677 
   3678         param.nPortIndex = queryDecoders ? 0 : 1;
   3679 
   3680         for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
   3681             err = omx->getParameter(
   3682                     node, OMX_IndexParamVideoProfileLevelQuerySupported,
   3683                     &param, sizeof(param));
   3684 
   3685             if (err != OK) {
   3686                 break;
   3687             }
   3688 
   3689             CodecProfileLevel profileLevel;
   3690             profileLevel.mProfile = param.eProfile;
   3691             profileLevel.mLevel = param.eLevel;
   3692 
   3693             caps->mProfileLevels.push(profileLevel);
   3694         }
   3695 
   3696         CHECK_EQ(omx->freeNode(node), OK);
   3697     }
   3698 }
   3699 
   3700 }  // namespace android
   3701