/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "OMXDecoder"
#include <utils/Log.h>

#undef NDEBUG
#include <assert.h>
#include <ctype.h>

#include <OMX_Component.h>

#include <media/stagefright/ESDS.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/OMXDecoder.h>

namespace android {

class OMXMediaBuffer : public MediaBuffer {
public:
    OMXMediaBuffer(IOMX::buffer_id buffer_id, const sp<IMemory> &mem)
        : MediaBuffer(mem->pointer(),
                      mem->size()),
          mBufferID(buffer_id),
          mMem(mem) {
    }

    IOMX::buffer_id buffer_id() const { return mBufferID; }

private:
    IOMX::buffer_id mBufferID;
    sp<IMemory> mMem;

    OMXMediaBuffer(const OMXMediaBuffer &);
    OMXMediaBuffer &operator=(const OMXMediaBuffer &);
};

struct CodecInfo {
    const char *mime;
    const char *codec;
};

static const CodecInfo kDecoderInfo[] = {
    { "audio/mpeg", "OMX.TI.MP3.decode" },
    { "audio/mpeg", "OMX.PV.mp3dec" },
    { "audio/3gpp", "OMX.TI.AMR.decode" },
    { "audio/3gpp", "OMX.PV.amrdec" },
    { "audio/mp4a-latm", "OMX.TI.AAC.decode" },
    { "audio/mp4a-latm", "OMX.PV.aacdec" },
    { "video/mp4v-es", "OMX.qcom.video.decoder.mpeg4" },
    { "video/mp4v-es", "OMX.TI.Video.Decoder" },
    { "video/mp4v-es", "OMX.PV.mpeg4dec" },
    { "video/3gpp", "OMX.qcom.video.decoder.h263" },
    { "video/3gpp", "OMX.TI.Video.Decoder" },
    { "video/3gpp", "OMX.PV.h263dec" },
    { "video/avc", "OMX.qcom.video.decoder.avc" },
    { "video/avc", "OMX.TI.Video.Decoder" },
    { "video/avc", "OMX.PV.avcdec" },
};

static const CodecInfo kEncoderInfo[] = {
    { "audio/3gpp", "OMX.PV.amrencnb" },
    { "audio/mp4a-latm", "OMX.PV.aacenc" },
    { "video/mp4v-es", "OMX.qcom.video.encoder.mpeg4" },
    { "video/mp4v-es", "OMX.PV.mpeg4enc" },
    { "video/3gpp", "OMX.qcom.video.encoder.h263" },
    { "video/3gpp", "OMX.PV.h263enc" },
    { "video/avc", "OMX.PV.avcenc" },
};

static const char *GetCodec(const CodecInfo *info, size_t numInfos,
                            const char *mime, int index) {
    assert(index >= 0);
    for(size_t i = 0; i < numInfos; ++i) {
        if (!strcasecmp(mime, info[i].mime)) {
            if (index == 0) {
                return info[i].codec;
            }

            --index;
        }
    }

    return NULL;
}

// static
OMXDecoder *OMXDecoder::Create(
        OMXClient *client, const sp<MetaData> &meta,
        bool createEncoder) {
    const char *mime;
    bool success = meta->findCString(kKeyMIMEType, &mime);
    assert(success);

    sp<IOMX> omx = client->interface();

    const char *codec = NULL;
    IOMX::node_id node = 0;
    for (int index = 0;; ++index) {
        if (createEncoder) {
            codec = GetCodec(
                    kEncoderInfo, sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]),
                    mime, index);
        } else {
            codec = GetCodec(
                    kDecoderInfo, sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]),
                    mime, index);
        }

        if (!codec) {
            return NULL;
        }

        LOGI("Attempting to allocate OMX node '%s'", codec);

        status_t err = omx->allocate_node(codec, &node);
        if (err == OK) {
            break;
        }
    }

    uint32_t quirks = 0;
    if (!strcmp(codec, "OMX.PV.avcdec")) {
        quirks |= kWantsRawNALFrames;
    }
    if (!strcmp(codec, "OMX.TI.AAC.decode")
        || !strcmp(codec, "OMX.TI.MP3.decode")) {
        quirks |= kDoesntReturnBuffersOnDisable;
    }
    if (!strcmp(codec, "OMX.TI.AAC.decode")) {
        quirks |= kDoesntFlushOnExecutingToIdle;
        quirks |= kDoesntProperlyFlushAllPortsAtOnce;
    }
    if (!strncmp(codec, "OMX.qcom.video.encoder.", 23)) {
        quirks |= kRequiresAllocateBufferOnInputPorts;
    }
    if (!strncmp(codec, "OMX.qcom.video.decoder.", 23)) {
        quirks |= kRequiresAllocateBufferOnOutputPorts;
    }
    if (!strncmp(codec, "OMX.qcom.video.", 15)) {
        quirks |= kRequiresLoadedToIdleAfterAllocation;
    }

    OMXDecoder *decoder = new OMXDecoder(client, node, mime, codec, quirks);

    uint32_t type;
    const void *data;
    size_t size;
    if (meta->findData(kKeyESDS, &type, &data, &size)) {
        ESDS esds((const char *)data, size);
        assert(esds.InitCheck() == OK);
        
        const void *codec_specific_data;
        size_t codec_specific_data_size;
        esds.getCodecSpecificInfo(
                &codec_specific_data, &codec_specific_data_size);

        printf("found codec specific data of size %d\n",
               codec_specific_data_size);

        decoder->addCodecSpecificData(
                codec_specific_data, codec_specific_data_size);
    } else if (meta->findData(kKeyAVCC, &type, &data, &size)) {
        printf("found avcc of size %d\n", size);

        const uint8_t *ptr = (const uint8_t *)data + 6;
        size -= 6;
        while (size >= 2) {
            size_t length = ptr[0] << 8 | ptr[1];

            ptr += 2;
            size -= 2;

            // printf("length = %d, size = %d\n", length, size);

            assert(size >= length);

            decoder->addCodecSpecificData(ptr, length);

            ptr += length;
            size -= length;

            if (size <= 1) {
                break;
            }

            ptr++;  // XXX skip trailing 0x01 byte???
            --size;
        }
    }

    return decoder;
}

OMXDecoder::OMXDecoder(OMXClient *client, IOMX::node_id node,
                       const char *mime, const char *codec,
                       uint32_t quirks)
    : mClient(client),
      mOMX(mClient->interface()),
      mNode(node),
      mComponentName(strdup(codec)),
      mIsMP3(!strcasecmp(mime, "audio/mpeg")),
      mIsAVC(!strcasecmp(mime, "video/avc")),
      mQuirks(quirks),
      mSource(NULL),
      mCodecSpecificDataIterator(mCodecSpecificData.begin()),
      mState(OMX_StateLoaded),
      mPortStatusMask(kPortStatusActive << 2 | kPortStatusActive),
      mShutdownInitiated(false),
      mDealer(new MemoryDealer(5 * 1024 * 1024)),
      mSeeking(false),
      mStarted(false),
      mErrorCondition(OK),
      mReachedEndOfInput(false) {
    mClient->registerObserver(mNode, this);

    mBuffers.push();  // input buffers
    mBuffers.push();  // output buffers
}

OMXDecoder::~OMXDecoder() {
    if (mStarted) {
        stop();
    }

    for (List<CodecSpecificData>::iterator it = mCodecSpecificData.begin();
         it != mCodecSpecificData.end(); ++it) {
        free((*it).data);
    }
    mCodecSpecificData.clear();

    mClient->unregisterObserver(mNode);

    status_t err = mOMX->free_node(mNode);
    assert(err == OK);
    mNode = 0;

    free(mComponentName);
    mComponentName = NULL;
}

void OMXDecoder::setSource(MediaSource *source) {
    Mutex::Autolock autoLock(mLock);

    assert(mSource == NULL);

    mSource = source;
    setup();
}

status_t OMXDecoder::start(MetaData *) {
    assert(!mStarted);

    // mDealer->dump("Decoder Dealer");

    sp<MetaData> params = new MetaData;
    if (mIsAVC && !(mQuirks & kWantsRawNALFrames)) {
        params->setInt32(kKeyNeedsNALFraming, true);
    }

    status_t err = mSource->start(params.get());

    if (err != OK) {
        return err;
    }

    postStart();

    mStarted = true;

    return OK;
}

status_t OMXDecoder::stop() {
    assert(mStarted);

    LOGI("Initiating OMX Node shutdown, busy polling.");
    initiateShutdown();

    // Important: initiateShutdown must be called first, _then_ release
    // buffers we're holding onto.
    while (!mOutputBuffers.empty()) {
        MediaBuffer *buffer = *mOutputBuffers.begin();
        mOutputBuffers.erase(mOutputBuffers.begin());

        LOGV("releasing buffer %p.", buffer->data());

        buffer->release();
        buffer = NULL;
    }

    int attempt = 1;
    while (mState != OMX_StateLoaded && attempt < 20) {
        usleep(100000);

        ++attempt;
    }

    if (mState != OMX_StateLoaded) {
        LOGE("!!! OMX Node '%s' did NOT shutdown cleanly !!!", mComponentName);
    } else {
        LOGI("OMX Node '%s' has shutdown cleanly.", mComponentName);
    }

    mSource->stop();

    mCodecSpecificDataIterator = mCodecSpecificData.begin();
    mShutdownInitiated = false;
    mSeeking = false;
    mStarted = false;
    mErrorCondition = OK;
    mReachedEndOfInput = false;

    return OK;
}

sp<MetaData> OMXDecoder::getFormat() {
    return mOutputFormat;
}

status_t OMXDecoder::read(
        MediaBuffer **out, const ReadOptions *options) {
    assert(mStarted);

    *out = NULL;

    Mutex::Autolock autoLock(mLock);

    if (mErrorCondition != OK && mErrorCondition != ERROR_END_OF_STREAM) {
        // Errors are sticky.
        return mErrorCondition;
    }

    int64_t seekTimeUs;
    if (options && options->getSeekTo(&seekTimeUs)) {
        LOGI("[%s] seeking to %lld us", mComponentName, seekTimeUs);

        mErrorCondition = OK;
        mReachedEndOfInput = false;

        setPortStatus(kPortIndexInput, kPortStatusFlushing);
        setPortStatus(kPortIndexOutput, kPortStatusFlushing);

        mSeeking = true;
        mSeekTimeUs = seekTimeUs;

        while (!mOutputBuffers.empty()) {
            OMXMediaBuffer *buffer =
                static_cast<OMXMediaBuffer *>(*mOutputBuffers.begin());

            // We could have used buffer->release() instead, but we're
            // holding the lock and signalBufferReturned attempts to acquire
            // the lock.
            buffer->claim();
            mBuffers.editItemAt(
                    kPortIndexOutput).push_back(buffer->buffer_id());
            buffer = NULL;

            mOutputBuffers.erase(mOutputBuffers.begin());
        }

        // XXX One of TI's decoders appears to ignore a flush if it doesn't
        // currently hold on to any buffers on the port in question and
        // never sends the completion event... FIXME

        status_t err = mOMX->send_command(mNode, OMX_CommandFlush, OMX_ALL);
        assert(err == OK);

        // Once flushing is completed buffers will again be scheduled to be
        // filled/emptied.
    }

    while (mErrorCondition == OK && mOutputBuffers.empty()) {
        mOutputBufferAvailable.wait(mLock);
    }

    if (!mOutputBuffers.empty()) {
        MediaBuffer *buffer = *mOutputBuffers.begin();
        mOutputBuffers.erase(mOutputBuffers.begin());

        *out = buffer;

        return OK;
    } else {
        assert(mErrorCondition != OK);
        return mErrorCondition;
    }
}

void OMXDecoder::addCodecSpecificData(const void *data, size_t size) {
    CodecSpecificData specific;
    specific.data = malloc(size);
    memcpy(specific.data, data, size);
    specific.size = size;

    mCodecSpecificData.push_back(specific);
    mCodecSpecificDataIterator = mCodecSpecificData.begin();
}

void OMXDecoder::onOMXMessage(const omx_message &msg) {
    Mutex::Autolock autoLock(mLock);

    switch (msg.type) {
        case omx_message::START:
        {
            onStart();
            break;
        }

        case omx_message::EVENT:
        {
            onEvent(msg.u.event_data.event, msg.u.event_data.data1,
                    msg.u.event_data.data2);
            break;
        }

        case omx_message::EMPTY_BUFFER_DONE:
        {
            onEmptyBufferDone(msg.u.buffer_data.buffer);
            break;
        }

        case omx_message::FILL_BUFFER_DONE:
        case omx_message::INITIAL_FILL_BUFFER:
        {
            onFillBufferDone(msg);
            break;
        }

        default:
            LOGE("received unknown omx_message type %d", msg.type);
            break;
    }
}

void OMXDecoder::setAMRFormat() {
    OMX_AUDIO_PARAM_AMRTYPE def;
    def.nSize = sizeof(def);
    def.nVersion.s.nVersionMajor = 1;
    def.nVersion.s.nVersionMinor = 1;
    def.nPortIndex = kPortIndexInput;

    status_t err =
        mOMX->get_parameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));

    assert(err == NO_ERROR);

    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
    def.eAMRBandMode = OMX_AUDIO_AMRBandModeNB0;

    err = mOMX->set_parameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
    assert(err == NO_ERROR);
}

void OMXDecoder::setAACFormat() {
    OMX_AUDIO_PARAM_AACPROFILETYPE def;
    def.nSize = sizeof(def);
    def.nVersion.s.nVersionMajor = 1;
    def.nVersion.s.nVersionMinor = 1;
    def.nPortIndex = kPortIndexInput;

    status_t err =
        mOMX->get_parameter(mNode, OMX_IndexParamAudioAac, &def, sizeof(def));
    assert(err == NO_ERROR);

    def.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;

    err = mOMX->set_parameter(mNode, OMX_IndexParamAudioAac, &def, sizeof(def));
    assert(err == NO_ERROR);
}

status_t OMXDecoder::setVideoPortFormatType(
        OMX_U32 portIndex,
        OMX_VIDEO_CODINGTYPE compressionFormat,
        OMX_COLOR_FORMATTYPE colorFormat) {
    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
    format.nSize = sizeof(format);
    format.nVersion.s.nVersionMajor = 1;
    format.nVersion.s.nVersionMinor = 1;
    format.nPortIndex = portIndex;
    format.nIndex = 0;
    bool found = false;

    OMX_U32 index = 0;
    for (;;) {
        format.nIndex = index;
        status_t err = mOMX->get_parameter(
                mNode, OMX_IndexParamVideoPortFormat,
                &format, sizeof(format));

        if (err != OK) {
            return err;
        }

        // The following assertion is violated by TI's video decoder.
        // assert(format.nIndex == index);

        if (format.eCompressionFormat == compressionFormat
            && format.eColorFormat == colorFormat) {
            found = true;
            break;
        }

        ++index;
    }

    if (!found) {
        return UNKNOWN_ERROR;
    }

    status_t err = mOMX->set_parameter(
            mNode, OMX_IndexParamVideoPortFormat,
            &format, sizeof(format));

    return err;
}

#if 1
void OMXDecoder::setVideoOutputFormat(
        const char *mime, OMX_U32 width, OMX_U32 height) {
    LOGI("setVideoOutputFormat width=%ld, height=%ld", width, height);

#if 1
    // Enabling this code appears to be the right thing(tm), but,...
    // the TI decoder then loses the ability to output YUV420 and only outputs
    // YCbYCr (16bit)
    if (!strcasecmp("video/avc", mime)) {
        OMX_PARAM_COMPONENTROLETYPE role;
        role.nSize = sizeof(role);
        role.nVersion.s.nVersionMajor = 1;
        role.nVersion.s.nVersionMinor = 1;
        strncpy((char *)role.cRole, "video_decoder.avc",
                OMX_MAX_STRINGNAME_SIZE - 1);
        role.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';

        status_t err = mOMX->set_parameter(
                mNode, OMX_IndexParamStandardComponentRole,
                &role, sizeof(role));
        assert(err == OK);
    }
#endif

    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
    if (!strcasecmp("video/avc", mime)) {
        compressionFormat = OMX_VIDEO_CodingAVC;
    } else if (!strcasecmp("video/mp4v-es", mime)) {
        compressionFormat = OMX_VIDEO_CodingMPEG4;
    } else if (!strcasecmp("video/3gpp", mime)) {
        compressionFormat = OMX_VIDEO_CodingH263;
    } else {
        assert(!"Should not be here. Not a supported video mime type.");
    }

    setVideoPortFormatType(
            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);

#if 1
    {
        OMX_VIDEO_PARAM_PORTFORMATTYPE format;
        format.nSize = sizeof(format);
        format.nVersion.s.nVersionMajor = 1;
        format.nVersion.s.nVersionMinor = 1;
        format.nPortIndex = kPortIndexOutput;
        format.nIndex = 0;

        status_t err = mOMX->get_parameter(
                mNode, OMX_IndexParamVideoPortFormat,
                &format, sizeof(format));
        assert(err == OK);

        assert(format.eCompressionFormat == OMX_VIDEO_CodingUnused);

        static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;

        assert(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
               || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
               || format.eColorFormat == OMX_COLOR_FormatCbYCrY
               || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar);

        err = mOMX->set_parameter(
                mNode, OMX_IndexParamVideoPortFormat,
                &format, sizeof(format));
        assert(err == OK);
    }
#endif

    OMX_PARAM_PORTDEFINITIONTYPE def;
    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;

    bool is_encoder = strstr(mComponentName, ".encoder.") != NULL;  // XXX

    def.nSize = sizeof(def);
    def.nVersion.s.nVersionMajor = 1;
    def.nVersion.s.nVersionMinor = 1;
    def.nPortIndex = is_encoder ? kPortIndexOutput : kPortIndexInput;

    status_t err = mOMX->get_parameter(
            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));

    assert(err == NO_ERROR);

#if 1
    // XXX Need a (much) better heuristic to compute input buffer sizes.
    const size_t X = 64 * 1024;
    if (def.nBufferSize < X) {
        def.nBufferSize = X;
    }
#endif

    assert(def.eDomain == OMX_PortDomainVideo);
    
    video_def->nFrameWidth = width;
    video_def->nFrameHeight = height;

    video_def->eColorFormat = OMX_COLOR_FormatUnused;

    err = mOMX->set_parameter(
            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    assert(err == NO_ERROR);

    ////////////////////////////////////////////////////////////////////////////

    def.nSize = sizeof(def);
    def.nVersion.s.nVersionMajor = 1;
    def.nVersion.s.nVersionMinor = 1;
    def.nPortIndex = is_encoder ? kPortIndexInput : kPortIndexOutput;

    err = mOMX->get_parameter(
            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    assert(err == NO_ERROR);

    assert(def.eDomain == OMX_PortDomainVideo);
    
#if 0
    def.nBufferSize =
        (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2;  // YUV420
#endif

    video_def->nFrameWidth = width;
    video_def->nFrameHeight = height;

    err = mOMX->set_parameter(
            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    assert(err == NO_ERROR);
}

#else
static void hexdump(const void *_data, size_t size) {
    char line[256];
    char tmp[16];

    const uint8_t *data = (const uint8_t *)_data;
    size_t offset = 0;
    while (offset < size) {
        sprintf(line, "0x%04x  ", offset);

        size_t n = size - offset;
        if (n > 16) {
            n = 16;
        }

        for (size_t i = 0; i < 16; ++i) {
            if (i == 8) {
                strcat(line, " ");
            }

            if (offset + i < size) {
                sprintf(tmp, "%02x ", data[offset + i]);
                strcat(line, tmp);
            } else {
                strcat(line, "   ");
            }
        }

        strcat(line, " ");

        for (size_t i = 0; i < n; ++i) {
            if (isprint(data[offset + i])) {
                sprintf(tmp, "%c", data[offset + i]);
                strcat(line, tmp);
            } else {
                strcat(line, ".");
            }
        }

        LOGI(line);

        offset += 16;
    }
}

static void DumpPortDefinitionType(const void *_param) {
    OMX_PARAM_PORTDEFINITIONTYPE *param = (OMX_PARAM_PORTDEFINITIONTYPE *)_param;

    LOGI("nPortIndex=%ld eDir=%s nBufferCountActual=%ld nBufferCountMin=%ld nBufferSize=%ld", param->nPortIndex, param->eDir == OMX_DirInput ? "input" : "output",
        param->nBufferCountActual, param->nBufferCountMin, param->nBufferSize);

    if (param->eDomain == OMX_PortDomainVideo) {
        OMX_VIDEO_PORTDEFINITIONTYPE *video = &param->format.video;
        LOGI("nFrameWidth=%ld nFrameHeight=%ld nStride=%ld nSliceHeight=%ld nBitrate=%ld xFramerate=%ld eCompressionFormat=%d eColorFormat=%d",
            video->nFrameWidth, video->nFrameHeight, video->nStride, video->nSliceHeight, video->nBitrate, video->xFramerate, video->eCompressionFormat, video->eColorFormat);
    } else {
        hexdump(param, param->nSize);
    }
}

void OMXDecoder::setVideoOutputFormat(
        const char *mime, OMX_U32 width, OMX_U32 height) {
    LOGI("setVideoOutputFormat width=%ld, height=%ld", width, height);

#if 0
    // Enabling this code appears to be the right thing(tm), but,...
    // the decoder then loses the ability to output YUV420 and only outputs
    // YCbYCr (16bit)
    {
        OMX_PARAM_COMPONENTROLETYPE role;
        role.nSize = sizeof(role);
        role.nVersion.s.nVersionMajor = 1;
        role.nVersion.s.nVersionMinor = 1;
        strncpy((char *)role.cRole, "video_decoder.avc",
                OMX_MAX_STRINGNAME_SIZE - 1);
        role.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';

        status_t err = mOMX->set_parameter(
                mNode, OMX_IndexParamStandardComponentRole,
                &role, sizeof(role));
        assert(err == OK);
    }
#endif

    setVideoPortFormatType(
            kPortIndexInput, OMX_VIDEO_CodingAVC, OMX_COLOR_FormatUnused);

#if 1
    {
        OMX_VIDEO_PARAM_PORTFORMATTYPE format;
        format.nSize = sizeof(format);
        format.nVersion.s.nVersionMajor = 1;
        format.nVersion.s.nVersionMinor = 1;
        format.nPortIndex = kPortIndexOutput;
        format.nIndex = 0;

        status_t err = mOMX->get_parameter(
                mNode, OMX_IndexParamVideoPortFormat,
                &format, sizeof(format));
        assert(err == OK);

        LOGI("XXX MyOMX_GetParameter OMX_IndexParamVideoPortFormat");
        hexdump(&format, format.nSize);

        assert(format.eCompressionFormat == OMX_VIDEO_CodingUnused);
        assert(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
               || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
               || format.eColorFormat == OMX_COLOR_FormatCbYCrY);

        err = mOMX->set_parameter(
                mNode, OMX_IndexParamVideoPortFormat,
                &format, sizeof(format));
        assert(err == OK);
    }
#endif

    OMX_PORT_PARAM_TYPE ptype;
    ptype.nSize = sizeof(ptype);
    ptype.nVersion.s.nVersionMajor = 1;
    ptype.nVersion.s.nVersionMinor = 1;

    status_t err = mOMX->get_parameter(
            mNode, OMX_IndexParamVideoInit, &ptype, sizeof(ptype));
    assert(err == OK);

    LOGI("XXX MyOMX_GetParameter OMX_IndexParamVideoInit");
    hexdump(&ptype, ptype.nSize);

    OMX_PARAM_PORTDEFINITIONTYPE def;
    def.nSize = sizeof(def);
    def.nVersion.s.nVersionMajor = 1;
    def.nVersion.s.nVersionMinor = 1;
    def.nPortIndex = kPortIndexInput;

    err = mOMX->get_parameter(
            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    assert(err == OK);

    LOGI("XXX MyOMX_GetParameter OMX_IndexParamPortDefinition");
    DumpPortDefinitionType(&def);

    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
    video_def->nFrameWidth = width;
    video_def->nFrameHeight = height;

    err = mOMX->set_parameter(
            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    assert(err == OK);

    ////////////////////////////////////////////////////////////////////////////

    def.nPortIndex = kPortIndexOutput;

    err = mOMX->get_parameter(
            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    assert(err == OK);

    LOGI("XXX MyOMX_GetParameter OMX_IndexParamPortDefinition");
    DumpPortDefinitionType(&def);

    video_def->nFrameWidth = width;
    video_def->nFrameHeight = height;

    err = mOMX->set_parameter(
            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    assert(err == OK);
}

#endif

void OMXDecoder::setup() {
    const sp<MetaData> &meta = mSource->getFormat();

    const char *mime;
    bool success = meta->findCString(kKeyMIMEType, &mime);
    assert(success);

    if (!strcasecmp(mime, "audio/3gpp")) {
        setAMRFormat();
    } else if (!strcasecmp(mime, "audio/mp4a-latm")) {
        setAACFormat();
    } else if (!strncasecmp(mime, "video/", 6)) {
        int32_t width, height;
        bool success = meta->findInt32(kKeyWidth, &width);
        success = success && meta->findInt32(kKeyHeight, &height);
        assert(success);

        setVideoOutputFormat(mime, width, height);
    }

    // dumpPortDefinition(0);
    // dumpPortDefinition(1);

    mOutputFormat = new MetaData;
    mOutputFormat->setCString(kKeyDecoderComponent, mComponentName);

    OMX_PARAM_PORTDEFINITIONTYPE def;
    def.nSize = sizeof(def);
    def.nVersion.s.nVersionMajor = 1;
    def.nVersion.s.nVersionMinor = 1;
    def.nPortIndex = kPortIndexOutput;

    status_t err = mOMX->get_parameter(
            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    assert(err == NO_ERROR);

    switch (def.eDomain) {
        case OMX_PortDomainAudio:
        {
            OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio;

            assert(audio_def->eEncoding == OMX_AUDIO_CodingPCM);

            OMX_AUDIO_PARAM_PCMMODETYPE params;
            params.nSize = sizeof(params);
            params.nVersion.s.nVersionMajor = 1;
            params.nVersion.s.nVersionMinor = 1;
            params.nPortIndex = kPortIndexOutput;

            err = mOMX->get_parameter(
                    mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
            assert(err == OK);

            assert(params.eNumData == OMX_NumericalDataSigned);
            assert(params.nBitPerSample == 16);
            assert(params.ePCMMode == OMX_AUDIO_PCMModeLinear);

            int32_t numChannels, sampleRate;
            meta->findInt32(kKeyChannelCount, &numChannels);
            meta->findInt32(kKeySampleRate, &sampleRate);

            mOutputFormat->setCString(kKeyMIMEType, "audio/raw");
            mOutputFormat->setInt32(kKeyChannelCount, numChannels);
            mOutputFormat->setInt32(kKeySampleRate, sampleRate);
            break;
        }

        case OMX_PortDomainVideo:
        {
            OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;

            if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) {
                mOutputFormat->setCString(kKeyMIMEType, "video/raw");
            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
                mOutputFormat->setCString(kKeyMIMEType, "video/mp4v-es");
            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) {
                mOutputFormat->setCString(kKeyMIMEType, "video/3gpp");
            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) {
                mOutputFormat->setCString(kKeyMIMEType, "video/avc");
            } else {
                assert(!"Unknown compression format.");
            }

            if (!strcmp(mComponentName, "OMX.PV.avcdec")) {
                // This component appears to be lying to me.
                mOutputFormat->setInt32(
                        kKeyWidth, (video_def->nFrameWidth + 15) & -16);
                mOutputFormat->setInt32(
                        kKeyHeight, (video_def->nFrameHeight + 15) & -16);
            } else {
                mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth);
                mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight);
            }

            mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat);
            break;
        }

        default:
        {
            assert(!"should not be here, neither audio nor video.");
            break;
        }
    }
}

void OMXDecoder::onStart() {
    if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) {
        status_t err =
            mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateIdle);
        assert(err == NO_ERROR);
    }

    allocateBuffers(kPortIndexInput);
    allocateBuffers(kPortIndexOutput);

    if (mQuirks & kRequiresLoadedToIdleAfterAllocation) {
        // XXX this should happen before AllocateBuffers, but qcom's
        // h264 vdec disagrees.
        status_t err =
            mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateIdle);
        assert(err == NO_ERROR);
    }
}

void OMXDecoder::allocateBuffers(OMX_U32 port_index) {
    assert(mBuffers[port_index].empty());

    OMX_U32 num_buffers;
    OMX_U32 buffer_size;

    OMX_PARAM_PORTDEFINITIONTYPE def;
    def.nSize = sizeof(def);
    def.nVersion.s.nVersionMajor = 1;
    def.nVersion.s.nVersionMinor = 1;
    def.nVersion.s.nRevision = 0;
    def.nVersion.s.nStep = 0;
    def.nPortIndex = port_index;

    status_t err = mOMX->get_parameter(
            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    assert(err == NO_ERROR);

    num_buffers = def.nBufferCountActual;
    buffer_size = def.nBufferSize;

    LOGV("[%s] port %ld: allocating %ld buffers of size %ld each\n",
           mComponentName, port_index, num_buffers, buffer_size);

    for (OMX_U32 i = 0; i < num_buffers; ++i) {
        sp<IMemory> mem = mDealer->allocate(buffer_size);
        if (mem.get() == NULL) {
            LOGE("[%s] allocating IMemory of size %ld FAILED.",
                 mComponentName, buffer_size);
        }
        assert(mem.get() != NULL);

        IOMX::buffer_id buffer;
        status_t err;

        if (port_index == kPortIndexInput
                && (mQuirks & kRequiresAllocateBufferOnInputPorts)) {
            // qcom's H.263 encoder appears to want to allocate its own input
            // buffers.
            err = mOMX->allocate_buffer_with_backup(mNode, port_index, mem, &buffer);
            if (err != OK) {
                LOGE("[%s] allocate_buffer_with_backup failed with error %d",
                     mComponentName, err);
            }
        } else if (port_index == kPortIndexOutput
                && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) {
#if 1
            err = mOMX->allocate_buffer_with_backup(mNode, port_index, mem, &buffer);
#else
            // XXX This is fine as long as we are either running the player
            // inside the media server process or we are using the
            // QComHardwareRenderer to output the frames.
            err = mOMX->allocate_buffer(mNode, port_index, buffer_size, &buffer);
#endif
            if (err != OK) {
                LOGE("[%s] allocate_buffer_with_backup failed with error %d",
                     mComponentName, err);
            }
        } else {
            err = mOMX->use_buffer(mNode, port_index, mem, &buffer);
            if (err != OK) {
                LOGE("[%s] use_buffer failed with error %d",
                     mComponentName, err);
            }
        }
        assert(err == OK);

        LOGV("allocated %s buffer %p.",
             port_index == kPortIndexInput ? "INPUT" : "OUTPUT",
             buffer);

        mBuffers.editItemAt(port_index).push_back(buffer);
        mBufferMap.add(buffer, mem);

        if (port_index == kPortIndexOutput) {
            OMXMediaBuffer *media_buffer = new OMXMediaBuffer(buffer, mem);
            media_buffer->setObserver(this);

            mMediaBufferMap.add(buffer, media_buffer);
        }
    }

    LOGV("allocate %s buffers done.",
         port_index == kPortIndexInput ? "INPUT" : "OUTPUT");
}

void OMXDecoder::onEvent(
        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
    LOGV("[%s] onEvent event=%d, data1=%ld, data2=%ld",
         mComponentName, event, data1, data2);

    switch (event) {
        case OMX_EventCmdComplete: {
            onEventCmdComplete(
                    static_cast<OMX_COMMANDTYPE>(data1), data2);

            break;
        }

        case OMX_EventPortSettingsChanged: {
            onEventPortSettingsChanged(data1);
            break;
        }

        case OMX_EventBufferFlag: {
            // initiateShutdown();
            break;
        }

        default:
            break;
    }
}

void OMXDecoder::onEventCmdComplete(OMX_COMMANDTYPE type, OMX_U32 data) {
    switch (type) {
        case OMX_CommandStateSet: {
            OMX_STATETYPE state = static_cast<OMX_STATETYPE>(data);
            onStateChanged(state);
            break;
        }

        case OMX_CommandPortDisable: {
            OMX_U32 port_index = data;
            assert(getPortStatus(port_index) == kPortStatusDisabled);

            status_t err =
                mOMX->send_command(mNode, OMX_CommandPortEnable, port_index);

            allocateBuffers(port_index);

            break;
        }

        case OMX_CommandPortEnable: {
            OMX_U32 port_index = data;
            assert(getPortStatus(port_index) ==kPortStatusDisabled);
            setPortStatus(port_index, kPortStatusActive);

            assert(port_index == kPortIndexOutput);

            BufferList *obuffers = &mBuffers.editItemAt(kPortIndexOutput);
            while (!obuffers->empty()) {
                IOMX::buffer_id buffer = *obuffers->begin();
                obuffers->erase(obuffers->begin());

                status_t err = mClient->fillBuffer(mNode, buffer);
                assert(err == NO_ERROR);
            }

            break;
        }

        case OMX_CommandFlush: {
            OMX_U32 port_index = data;
            LOGV("Port %ld flush complete.", port_index);

            PortStatus status = getPortStatus(port_index);

            assert(status == kPortStatusFlushing
                    || status == kPortStatusFlushingToDisabled
                    || status == kPortStatusFlushingToShutdown);

            switch (status) {
                case kPortStatusFlushing:
                {
                    // This happens when we're flushing before a seek.
                    setPortStatus(port_index, kPortStatusActive);
                    BufferList *buffers = &mBuffers.editItemAt(port_index);
                    while (!buffers->empty()) {
                        IOMX::buffer_id buffer = *buffers->begin();
                        buffers->erase(buffers->begin());

                        if (port_index == kPortIndexInput) {
                            postEmptyBufferDone(buffer);
                        } else {
                            postInitialFillBuffer(buffer);
                        }
                    }
                    break;
                }

                case kPortStatusFlushingToDisabled:
                {
                    // Port settings have changed and the (buggy) OMX component
                    // does not properly return buffers on disabling, we need to
                    // do a flush first and _then_ disable the port in question.

                    setPortStatus(port_index, kPortStatusDisabled);
                    status_t err = mOMX->send_command(
                            mNode, OMX_CommandPortDisable, port_index);
                    assert(err == OK);

                    freePortBuffers(port_index);
                    break;
                }

                default:
                {
                    assert(status == kPortStatusFlushingToShutdown);

                    setPortStatus(port_index, kPortStatusShutdown);
                    if (getPortStatus(kPortIndexInput) == kPortStatusShutdown
                        && getPortStatus(kPortIndexOutput) == kPortStatusShutdown) {
                        status_t err = mOMX->send_command(
                                mNode, OMX_CommandStateSet, OMX_StateIdle);
                        assert(err == OK);
                    }
                    break;
                }
            }
            break;
        }

        default:
            break;
    }
}

void OMXDecoder::onEventPortSettingsChanged(OMX_U32 port_index) {
    assert(getPortStatus(port_index) == kPortStatusActive);

    status_t err;

    if (mQuirks & kDoesntReturnBuffersOnDisable) {
        // Decoder does not properly return our buffers when disabled...
        // Need to flush port instead and _then_ disable.

        setPortStatus(port_index, kPortStatusFlushingToDisabled);

        err = mOMX->send_command(mNode, OMX_CommandFlush, port_index);
    } else {
        setPortStatus(port_index, kPortStatusDisabled);

        err = mOMX->send_command(mNode, OMX_CommandPortDisable, port_index);
    }

    assert(err == NO_ERROR);
}

void OMXDecoder::onStateChanged(OMX_STATETYPE to) {
    if (mState == OMX_StateLoaded) {
        assert(to == OMX_StateIdle);

        mState = to;

        status_t err =
            mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateExecuting);
        assert(err == NO_ERROR);
    } else if (mState == OMX_StateIdle) {
        if (to == OMX_StateExecuting) {
            mState = to;

            BufferList *ibuffers = &mBuffers.editItemAt(kPortIndexInput);
            while (!ibuffers->empty()) {
                IOMX::buffer_id buffer = *ibuffers->begin();
                ibuffers->erase(ibuffers->begin());

                postEmptyBufferDone(buffer);
            }

            BufferList *obuffers = &mBuffers.editItemAt(kPortIndexOutput);
            while (!obuffers->empty()) {
                IOMX::buffer_id buffer = *obuffers->begin();
                obuffers->erase(obuffers->begin());

                postInitialFillBuffer(buffer);
            }
        } else {
            assert(to == OMX_StateLoaded);

            mState = to;

            setPortStatus(kPortIndexInput, kPortStatusActive);
            setPortStatus(kPortIndexOutput, kPortStatusActive);
        }
    } else if (mState == OMX_StateExecuting) {
        assert(to == OMX_StateIdle);

        mState = to;

        LOGV("Executing->Idle complete, initiating Idle->Loaded");
        status_t err =
            mClient->send_command(mNode, OMX_CommandStateSet, OMX_StateLoaded);
        assert(err == NO_ERROR);

        freePortBuffers(kPortIndexInput);
        freePortBuffers(kPortIndexOutput);
    }
}

void OMXDecoder::initiateShutdown() {
    Mutex::Autolock autoLock(mLock);

    if (mShutdownInitiated) {
        return;
    }
    
    if (mState == OMX_StateLoaded) {
        return;
    }

    assert(mState == OMX_StateExecuting);

    mShutdownInitiated = true;

    status_t err;
    if (mQuirks & kDoesntFlushOnExecutingToIdle) {
        if (mQuirks & kDoesntProperlyFlushAllPortsAtOnce) {
            err = mOMX->send_command(mNode, OMX_CommandFlush, kPortIndexInput);
            assert(err == OK);

            err = mOMX->send_command(mNode, OMX_CommandFlush, kPortIndexOutput);
        } else {
            err = mOMX->send_command(mNode, OMX_CommandFlush, OMX_ALL);
        }

        setPortStatus(kPortIndexInput, kPortStatusFlushingToShutdown);
        setPortStatus(kPortIndexOutput, kPortStatusFlushingToShutdown);
    } else {
        err = mClient->send_command(
                mNode, OMX_CommandStateSet, OMX_StateIdle);

        setPortStatus(kPortIndexInput, kPortStatusShutdown);
        setPortStatus(kPortIndexOutput, kPortStatusShutdown);
    }
    assert(err == OK);
}

void OMXDecoder::setPortStatus(OMX_U32 port_index, PortStatus status) {
    int shift = 3 * port_index;

    mPortStatusMask &= ~(7 << shift);
    mPortStatusMask |= status << shift;
}

OMXDecoder::PortStatus OMXDecoder::getPortStatus(
        OMX_U32 port_index) const {
    int shift = 3 * port_index;

    return static_cast<PortStatus>((mPortStatusMask >> shift) & 7);
}

void OMXDecoder::onEmptyBufferDone(IOMX::buffer_id buffer) {
    LOGV("[%s] onEmptyBufferDone (%p)", mComponentName, buffer);

    status_t err;
    switch (getPortStatus(kPortIndexInput)) {
        case kPortStatusDisabled:
            freeInputBuffer(buffer);
            err = NO_ERROR;
            break;

        case kPortStatusShutdown:
            LOGV("We're shutting down, enqueue INPUT buffer %p.", buffer);
            mBuffers.editItemAt(kPortIndexInput).push_back(buffer);
            err = NO_ERROR;
            break;

        case kPortStatusFlushing:
        case kPortStatusFlushingToDisabled:
        case kPortStatusFlushingToShutdown:
            LOGV("We're currently flushing, enqueue INPUT buffer %p.", buffer);
            mBuffers.editItemAt(kPortIndexInput).push_back(buffer);
            err = NO_ERROR;
            break;

        default:
            onRealEmptyBufferDone(buffer);
            err = NO_ERROR;
            break;
    }
    assert(err == NO_ERROR);
}

void OMXDecoder::onFillBufferDone(const omx_message &msg) {
    IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;

    LOGV("[%s] on%sFillBufferDone (%p, size:%ld)", mComponentName,
         msg.type == omx_message::INITIAL_FILL_BUFFER ? "Initial" : "",
         buffer, msg.u.extended_buffer_data.range_length);

    status_t err;
    switch (getPortStatus(kPortIndexOutput)) {
        case kPortStatusDisabled:
            freeOutputBuffer(buffer);
            err = NO_ERROR;
            break;
        case kPortStatusShutdown:
            LOGV("We're shutting down, enqueue OUTPUT buffer %p.", buffer);
            mBuffers.editItemAt(kPortIndexOutput).push_back(buffer);
            err = NO_ERROR;
            break;

        case kPortStatusFlushing:
        case kPortStatusFlushingToDisabled:
        case kPortStatusFlushingToShutdown:
            LOGV("We're currently flushing, enqueue OUTPUT buffer %p.", buffer);
            mBuffers.editItemAt(kPortIndexOutput).push_back(buffer);
            err = NO_ERROR;
            break;

        default:
        {
            if (msg.type == omx_message::INITIAL_FILL_BUFFER) {
                err = mClient->fillBuffer(mNode, buffer);
            } else {
                LOGV("[%s] Filled OUTPUT buffer %p, flags=0x%08lx.",
                     mComponentName, buffer, msg.u.extended_buffer_data.flags);

                onRealFillBufferDone(msg);
                err = NO_ERROR;
            }
            break;
        }
    }
    assert(err == NO_ERROR);
}

void OMXDecoder::onRealEmptyBufferDone(IOMX::buffer_id buffer) {
    if (mReachedEndOfInput) {
        // We already sent the EOS notification.

        mBuffers.editItemAt(kPortIndexInput).push_back(buffer);
        return;
    }

    const sp<IMemory> mem = mBufferMap.valueFor(buffer);
    assert(mem.get() != NULL);

    static const uint8_t kNALStartCode[4] = { 0x00, 0x00, 0x00, 0x01 };

    if (mCodecSpecificDataIterator != mCodecSpecificData.end()) {
        List<CodecSpecificData>::iterator it = mCodecSpecificDataIterator;

        size_t range_length = 0;

        if (mIsAVC && !(mQuirks & kWantsRawNALFrames)) {
            assert((*mCodecSpecificDataIterator).size + 4 <= mem->size());

            memcpy(mem->pointer(), kNALStartCode, 4);

            memcpy((uint8_t *)mem->pointer() + 4, (*it).data, (*it).size);
            range_length = (*it).size + 4;
        } else {
            assert((*mCodecSpecificDataIterator).size <= mem->size());

            memcpy((uint8_t *)mem->pointer(), (*it).data, (*it).size);
            range_length = (*it).size;
        }

        ++mCodecSpecificDataIterator;

        status_t err = mClient->emptyBuffer(
                mNode, buffer, 0, range_length, 
                OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG,
                0);

        assert(err == NO_ERROR);

        return;
    }

    LOGV("[%s] waiting for input data", mComponentName);

    MediaBuffer *input_buffer;
    for (;;) {
        status_t err;

        if (mSeeking) {
            MediaSource::ReadOptions options;
            options.setSeekTo(mSeekTimeUs);

            mSeeking = false;

            err = mSource->read(&input_buffer, &options);
        } else {
            err = mSource->read(&input_buffer);
        }
        assert((err == OK && input_buffer != NULL)
               || (err != OK && input_buffer == NULL));

        if (err == ERROR_END_OF_STREAM) {
            LOGE("[%s] Reached end of stream.", mComponentName);
            mReachedEndOfInput = true;
        } else {
            LOGV("[%s] got input data", mComponentName);
        }

        if (err != OK) {
            status_t err2 = mClient->emptyBuffer(
                    mNode, buffer, 0, 0, OMX_BUFFERFLAG_EOS, 0);

            assert(err2 == NO_ERROR);
            return;
        }

        if (mSeeking) {
            input_buffer->release();
            input_buffer = NULL;

            continue;
        }

        break;
    }

    const uint8_t *src_data =
        (const uint8_t *)input_buffer->data() + input_buffer->range_offset();

    size_t src_length = input_buffer->range_length();
    if (src_length == 195840) {
        // When feeding the output of the AVC decoder into the H263 encoder,
        // buffer sizes mismatch if width % 16 != 0 || height % 16 != 0.
        src_length = 194400;  // XXX HACK
    } else if (src_length == 115200) {
        src_length = 114240;  // XXX HACK
    }

    if (src_length > mem->size()) {
        LOGE("src_length=%d > mem->size() = %d\n",
             src_length, mem->size());
    }

    assert(src_length <= mem->size());
    memcpy(mem->pointer(), src_data, src_length);

    OMX_U32 flags = 0;
    if (!mIsMP3) {
        // Only mp3 audio data may be streamed, all other data is assumed
        // to be fed into the decoder at frame boundaries.
        flags |= OMX_BUFFERFLAG_ENDOFFRAME;
    }

    int32_t units, scale;
    bool success =
        input_buffer->meta_data()->findInt32(kKeyTimeUnits, &units);

    success = success &&
        input_buffer->meta_data()->findInt32(kKeyTimeScale, &scale);

    OMX_TICKS timestamp = 0;

    if (success) {
        timestamp = ((OMX_S64)units * 1000000) / scale;
    }

    input_buffer->release();
    input_buffer = NULL;

    LOGV("[%s] Calling EmptyBuffer on buffer %p size:%d flags:0x%08lx",
         mComponentName, buffer, src_length, flags);

    status_t err2 = mClient->emptyBuffer(
            mNode, buffer, 0, src_length, flags, timestamp);
    assert(err2 == OK);
}

void OMXDecoder::onRealFillBufferDone(const omx_message &msg) {
    OMXMediaBuffer *media_buffer =
        mMediaBufferMap.valueFor(msg.u.extended_buffer_data.buffer);

    media_buffer->set_range(
            msg.u.extended_buffer_data.range_offset,
            msg.u.extended_buffer_data.range_length);

    media_buffer->add_ref();

    media_buffer->meta_data()->clear();

    media_buffer->meta_data()->setInt32(
            kKeyTimeUnits,
            (msg.u.extended_buffer_data.timestamp + 500) / 1000);
    media_buffer->meta_data()->setInt32(kKeyTimeScale, 1000);

    if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) {
        media_buffer->meta_data()->setInt32(kKeyIsSyncFrame, true);
    }

    media_buffer->meta_data()->setPointer(
            kKeyPlatformPrivate,
            msg.u.extended_buffer_data.platform_private);

    if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) {
        mErrorCondition = ERROR_END_OF_STREAM;
    }

    mOutputBuffers.push_back(media_buffer);
    mOutputBufferAvailable.signal();
}

void OMXDecoder::signalBufferReturned(MediaBuffer *_buffer) {
    Mutex::Autolock autoLock(mLock);

    OMXMediaBuffer *media_buffer = static_cast<OMXMediaBuffer *>(_buffer);

    IOMX::buffer_id buffer = media_buffer->buffer_id();

    PortStatus outputStatus = getPortStatus(kPortIndexOutput);
    if (outputStatus == kPortStatusShutdown
            || outputStatus == kPortStatusFlushing
            || outputStatus == kPortStatusFlushingToDisabled
            || outputStatus == kPortStatusFlushingToShutdown) {
        mBuffers.editItemAt(kPortIndexOutput).push_back(buffer);
    } else {
        LOGV("[%s] Calling FillBuffer on buffer %p.", mComponentName, buffer);

        status_t err = mClient->fillBuffer(mNode, buffer);
        assert(err == NO_ERROR);
    }
}

void OMXDecoder::freeInputBuffer(IOMX::buffer_id buffer) {
    LOGV("freeInputBuffer %p", buffer);

    status_t err = mOMX->free_buffer(mNode, kPortIndexInput, buffer);
    assert(err == NO_ERROR);
    mBufferMap.removeItem(buffer);

    LOGV("freeInputBuffer %p done", buffer);
}

void OMXDecoder::freeOutputBuffer(IOMX::buffer_id buffer) {
    LOGV("freeOutputBuffer %p", buffer);

    status_t err = mOMX->free_buffer(mNode, kPortIndexOutput, buffer);
    assert(err == NO_ERROR);
    mBufferMap.removeItem(buffer);

    ssize_t index = mMediaBufferMap.indexOfKey(buffer);
    assert(index >= 0);
    MediaBuffer *mbuffer = mMediaBufferMap.editValueAt(index);
    mMediaBufferMap.removeItemsAt(index);
    mbuffer->setObserver(NULL);
    mbuffer->release();
    mbuffer = NULL;

    LOGV("freeOutputBuffer %p done", buffer);
}

void OMXDecoder::dumpPortDefinition(OMX_U32 port_index) {
    OMX_PARAM_PORTDEFINITIONTYPE def;
    def.nSize = sizeof(def);
    def.nVersion.s.nVersionMajor = 1;
    def.nVersion.s.nVersionMinor = 1;
    def.nPortIndex = port_index;

    status_t err = mOMX->get_parameter(
            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    assert(err == NO_ERROR);

    LOGI("DumpPortDefinition on port %ld", port_index);
    LOGI("nBufferCountActual = %ld, nBufferCountMin = %ld, nBufferSize = %ld",
         def.nBufferCountActual, def.nBufferCountMin, def.nBufferSize);
    switch (def.eDomain) {
        case OMX_PortDomainAudio:
        {
            LOGI("eDomain = AUDIO");

            if (port_index == kPortIndexOutput) {
                OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio;
                assert(audio_def->eEncoding == OMX_AUDIO_CodingPCM);

                OMX_AUDIO_PARAM_PCMMODETYPE params;
                params.nSize = sizeof(params);
                params.nVersion.s.nVersionMajor = 1;
                params.nVersion.s.nVersionMinor = 1;
                params.nPortIndex = port_index;

                err = mOMX->get_parameter(
                        mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
                assert(err == OK);

                assert(params.nChannels == 1 || params.bInterleaved);
                assert(params.eNumData == OMX_NumericalDataSigned);
                assert(params.nBitPerSample == 16);
                assert(params.ePCMMode == OMX_AUDIO_PCMModeLinear);

                LOGI("nChannels = %ld, nSamplingRate = %ld",
                     params.nChannels, params.nSamplingRate);
            }

            break;
        }

        case OMX_PortDomainVideo:
        {
            LOGI("eDomain = VIDEO");

            OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
            LOGI("nFrameWidth = %ld, nFrameHeight = %ld, nStride = %ld, "
                 "nSliceHeight = %ld",
                 video_def->nFrameWidth, video_def->nFrameHeight,
                 video_def->nStride, video_def->nSliceHeight);
            LOGI("nBitrate = %ld, xFrameRate = %.2f",
                 video_def->nBitrate, video_def->xFramerate / 65536.0f);
            LOGI("eCompressionFormat = %d, eColorFormat = %d",
                 video_def->eCompressionFormat, video_def->eColorFormat);

            break;
        }

        default:
            LOGI("eDomain = UNKNOWN");
            break;
    }
}

void OMXDecoder::postStart() {
    omx_message msg;
    msg.type = omx_message::START;
    postMessage(msg);
}

void OMXDecoder::postEmptyBufferDone(IOMX::buffer_id buffer) {
    omx_message msg;
    msg.type = omx_message::EMPTY_BUFFER_DONE;
    msg.u.buffer_data.node = mNode;
    msg.u.buffer_data.buffer = buffer;
    postMessage(msg);
}

void OMXDecoder::postInitialFillBuffer(IOMX::buffer_id buffer) {
    omx_message msg;
    msg.type = omx_message::INITIAL_FILL_BUFFER;
    msg.u.buffer_data.node = mNode;
    msg.u.buffer_data.buffer = buffer;
    postMessage(msg);
}

void OMXDecoder::freePortBuffers(OMX_U32 port_index) {
    BufferList *buffers = &mBuffers.editItemAt(port_index);
    while (!buffers->empty()) {
        IOMX::buffer_id buffer = *buffers->begin();
        buffers->erase(buffers->begin());

        if (port_index == kPortIndexInput) {
            freeInputBuffer(buffer);
        } else {
            freeOutputBuffer(buffer);
        }
    }
}

}  // namespace android
