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; } } }