void MediaFilter::onOutputBufferDrained(const sp<AMessage> &msg) {
    IOMX::buffer_id bufferID;
    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
    BufferInfo *info = findBufferByID(kPortIndexOutput, bufferID);

    if (mState != STARTED) {
        // we're not running, so we'll just keep that buffer...
        info->mStatus = BufferInfo::OWNED_BY_US;
        return;
    }

    if (info->mGeneration != mGeneration) {
        ALOGV("Caught a stale output buffer [ID %d]", bufferID);
        // buffer is stale (taken before a flush/shutdown) - keep it
        CHECK_EQ(info->mStatus, BufferInfo::OWNED_BY_US);
        return;
    }

    CHECK_EQ(info->mStatus, BufferInfo::OWNED_BY_UPSTREAM);
    info->mStatus = BufferInfo::OWNED_BY_US;

    mAvailableOutputBuffers.push_back(info);

    processBuffers();

    ALOGV("Handled kWhatOutputBufferDrained. [ID %u]",
            bufferID);
}
    void run() override
    {
        setThreadToAudioPriority();

        if (recorder != nullptr)    recorder->start();
        if (player != nullptr)      player->start();

        while (! threadShouldExit())
            processBuffers();
    }
void MediaFilter::onInputBufferFilled(const sp<AMessage> &msg) {
    IOMX::buffer_id bufferID;
    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
    BufferInfo *info = findBufferByID(kPortIndexInput, bufferID);

    if (mState != STARTED) {
        // we're not running, so we'll just keep that buffer...
        info->mStatus = BufferInfo::OWNED_BY_US;
        return;
    }

    if (info->mGeneration != mGeneration) {
        ALOGV("Caught a stale input buffer [ID %d]", bufferID);
        // buffer is stale (taken before a flush/shutdown) - repost it
        CHECK_EQ(info->mStatus, BufferInfo::OWNED_BY_US);
        postFillThisBuffer(info);
        return;
    }

    CHECK_EQ(info->mStatus, BufferInfo::OWNED_BY_UPSTREAM);
    info->mStatus = BufferInfo::OWNED_BY_US;

    sp<ABuffer> buffer;
    int32_t err = OK;
    bool eos = false;

    if (!msg->findBuffer("buffer", &buffer)) {
        // these are unfilled buffers returned by client
        CHECK(msg->findInt32("err", &err));

        if (err == OK) {
            // buffers with no errors are returned on MediaCodec.flush
            ALOGV("saw unfilled buffer (MediaCodec.flush)");
            postFillThisBuffer(info);
            return;
        } else {
            ALOGV("saw error %d instead of an input buffer", err);
            eos = true;
        }

        buffer.clear();
    }

    int32_t isCSD;
    if (buffer != NULL && buffer->meta()->findInt32("csd", &isCSD)
            && isCSD != 0) {
        // ignore codec-specific data buffers
        ALOGW("MediaFilter received a codec-specific data buffer");
        postFillThisBuffer(info);
        return;
    }

    int32_t tmp;
    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
        eos = true;
        err = ERROR_END_OF_STREAM;
    }

    mAvailableInputBuffers.push_back(info);
    processBuffers();

    if (eos) {
        mPortEOS[kPortIndexInput] = true;
        mInputEOSResult = err;
    }

    ALOGV("Handled kWhatInputBufferFilled. [ID %u]", bufferID);
}
void MediaFilter::onMessageReceived(const sp<AMessage> &msg) {
    switch (msg->what()) {
        case kWhatAllocateComponent:
        {
            onAllocateComponent(msg);
            break;
        }
        case kWhatConfigureComponent:
        {
            onConfigureComponent(msg);
            break;
        }
        case kWhatStart:
        {
            onStart();
            break;
        }
        case kWhatProcessBuffers:
        {
            processBuffers();
            break;
        }
        case kWhatInputBufferFilled:
        {
            onInputBufferFilled(msg);
            break;
        }
        case kWhatOutputBufferDrained:
        {
            onOutputBufferDrained(msg);
            break;
        }
        case kWhatShutdown:
        {
            onShutdown(msg);
            break;
        }
        case kWhatFlush:
        {
            onFlush();
            break;
        }
        case kWhatResume:
        {
            // nothing to do
            break;
        }
        case kWhatSetParameters:
        {
            onSetParameters(msg);
            break;
        }
        case kWhatCreateInputSurface:
        {
            onCreateInputSurface();
            break;
        }
        case GraphicBufferListener::kWhatFrameAvailable:
        {
            onInputFrameAvailable();
            break;
        }
        case kWhatSignalEndOfInputStream:
        {
            onSignalEndOfInputStream();
            break;
        }
        default:
        {
            ALOGE("Message not handled:\n%s", msg->debugString().c_str());
            break;
        }
    }
}