void
GonkDecoderManager::ProcessInput(bool aEndOfStream)
{
  MOZ_ASSERT(OnTaskLooper());

  status_t rv = ProcessQueuedSamples();
  if (rv >= 0) {
    if (!aEndOfStream && rv <= MIN_QUEUED_SAMPLES) {
      mDecodeCallback->InputExhausted();
    }

    if (mToDo.get() == nullptr) {
      mToDo = new AMessage(kNotifyDecoderActivity, id());
      if (aEndOfStream) {
        mToDo->setInt32("input-eos", 1);
      }
      mDecoder->requestActivityNotification(mToDo);
    } else if (aEndOfStream) {
      mToDo->setInt32("input-eos", 1);
    }
  } else {
    GMDD_LOG("input processed: error#%d", rv);
    mDecodeCallback->Error(MediaDataDecoderError::FATAL_ERROR);
  }
}
void
GonkDecoderManager::ProcessToDo(bool aEndOfStream)
{
  MOZ_ASSERT(OnTaskLooper());

  MOZ_ASSERT(mToDo.get() != nullptr);
  mToDo.clear();

  if (NumQueuedSamples() > 0 && ProcessQueuedSamples() < 0) {
    mDecodeCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
                                            __func__));
    return;
  }

  while (mWaitOutput.Length() > 0) {
    RefPtr<MediaData> output;
    WaitOutputInfo wait = mWaitOutput.ElementAt(0);
    nsresult rv = Output(wait.mOffset, output);
    if (rv == NS_OK) {
      MOZ_ASSERT(output);
      mDecodeCallback->Output(output);
      UpdateWaitingList(output->mTime);
    } else if (rv == NS_ERROR_ABORT) {
      // EOS
      MOZ_ASSERT(mQueuedSamples.IsEmpty());
      if (output) {
        mDecodeCallback->Output(output);
        UpdateWaitingList(output->mTime);
      }
      MOZ_ASSERT(mWaitOutput.Length() == 1);
      mWaitOutput.RemoveElementAt(0);
      mDecodeCallback->DrainComplete();
      ResetEOS();
      return;
    } else if (rv == NS_ERROR_NOT_AVAILABLE) {
      break;
    } else {
      mDecodeCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
                                              __func__));
      return;
    }
  }

  if (!aEndOfStream && NumQueuedSamples() <= MIN_QUEUED_SAMPLES) {
    mDecodeCallback->InputExhausted();
    // No need to shedule todo task this time because InputExhausted() will
    // cause Input() to be invoked and do it for us.
    return;
  }

  if (NumQueuedSamples() || mWaitOutput.Length() > 0) {
    mToDo = new AMessage(kNotifyDecoderActivity, id());
    if (aEndOfStream) {
      mToDo->setInt32("input-eos", 1);
    }
    mDecoder->requestActivityNotification(mToDo);
  }
}