RefPtr<OmxPromiseLayer::OmxCommandPromise>
OmxPromiseLayer::SendCommand(OMX_COMMANDTYPE aCmd, OMX_U32 aParam1, OMX_PTR aCmdData)
{
  if (aCmd == OMX_CommandFlush) {
    // It doesn't support another flush commands before previous one is completed.
    MOZ_RELEASE_ASSERT(!mFlushCommands.Length());

    // Some coomponents don't send event with OMX_ALL, they send flush complete
    // event with input port and another event for output port.
    // In prupose of better compatibility, we interpret the OMX_ALL to OMX_DirInput
    // and OMX_DirOutput flush separately.
    OMX_DIRTYPE types[] = {OMX_DIRTYPE::OMX_DirInput, OMX_DIRTYPE::OMX_DirOutput};
    for(const auto type : types) {
      if ((aParam1 == type) || (aParam1 == OMX_ALL)) {
        mFlushCommands.AppendElement(FlushCommand({type, aCmdData}));
      }

      if (type == OMX_DirInput) {
        // Clear all buffered raw data.
        mRawDatas.Clear();
      }
    }

    // Don't overlay more than one flush command, some components can't overlay flush commands.
    // So here we send another flush after receiving the previous flush completed event.
    if (mFlushCommands.Length()) {
      OMX_ERRORTYPE err =
        mPlatformLayer->SendCommand(OMX_CommandFlush,
                                    mFlushCommands.ElementAt(0).type,
                                    mFlushCommands.ElementAt(0).cmd);
      if (err != OMX_ErrorNone) {
        OmxCommandFailureHolder failure(OMX_ErrorNotReady, OMX_CommandFlush);
        return OmxCommandPromise::CreateAndReject(failure, __func__);
      }
    } else {
      LOG("OMX_CommandFlush parameter error");
      OmxCommandFailureHolder failure(OMX_ErrorNotReady, OMX_CommandFlush);
      return OmxCommandPromise::CreateAndReject(failure, __func__);
    }
  } else {
    OMX_ERRORTYPE err = mPlatformLayer->SendCommand(aCmd, aParam1, aCmdData);
    if (err != OMX_ErrorNone) {
      OmxCommandFailureHolder failure(OMX_ErrorNotReady, aCmd);
      return OmxCommandPromise::CreateAndReject(failure, __func__);
    }
  }

  RefPtr<OmxCommandPromise> p;
  if (aCmd == OMX_CommandStateSet) {
    p = mCommandStatePromise.Ensure(__func__);
  } else if (aCmd == OMX_CommandFlush) {
    p = mFlushPromise.Ensure(__func__);
  } else if (aCmd == OMX_CommandPortEnable) {
    p = mPortEnablePromise.Ensure(__func__);
  } else if (aCmd == OMX_CommandPortDisable) {
    p = mPortDisablePromise.Ensure(__func__);
  } else {
    LOG("error unsupport command");
    MOZ_ASSERT(0);
  }

  return p;
}
NetworkCommandBuffer::Command::~Command()
{
	FlushCommand();
}