/// acquires instance for RME interface / singleton class
/// has reference count support
RME* RME::getInstance() {
  if (RMEimpl::mpMutexAsync == NULL) {
    omxilosalservices::OmxILOsalMutex::MutexCreate(RMEimpl::mpMutexAsync);
    if (RMEimpl::mpMutexAsync == NULL) {
      RLOG_ERROR("OmxILOsalMutex::MutexCreate failed for RMEimpl\n");
      return NULL;
    }
  }
  RMEimpl::mpMutexAsync->MutexLock();

  if (RMEimpl::mInstance == NULL) {
#if defined(SW_VARIANT_ANDROID)
    GET_PROPERTY(TRACE_ENABLED_PROPERTY_NAME, value, "0");
    Debug::mTraceEnabled = atoi(value);
#endif
    RLOG_DEBUG("new RMEimpl instance\n");
    RMEimpl::mInstance = new RMEimpl();  // mRefCount set to 1
    if (RMEimpl::mInstance) {
      // init: will create NMF domains
      int status = RMEimpl::mInstance->Init();
      if (status < 0) {
        // refusing to keep going..
        // possible causes: platform domains table badly formed or
        // NMF CM domains failure
        RLOG_ERROR("RMEimpl init\n");
        delete RMEimpl::mInstance;
        RMEimpl::mInstance = NULL;
      }
    } else {
      RLOG_ERROR("RMEimpl instance\n");
    }
  } else {
    RMEimpl::mInstance->mRefCount++;
    RLOG_DEBUG("RME-refcount++ %d\n", RMEimpl::mInstance->mRefCount);
  }

  RMEimpl::mpMutexAsync->MutexUnlock();
  return RMEimpl::mInstance;
}
void CipherFileIO::initHeader() {
  // check if the file has a header, and read it if it does..  Otherwise,
  // create one.
  off_t rawSize = base->getSize();
  if (rawSize >= HEADER_SIZE) {
    rDebug("reading existing header, rawSize = %" PRIi64, rawSize);
    // has a header.. read it
    unsigned char buf[8] = {0};

    IORequest req;
    req.offset = 0;
    req.data = buf;
    req.dataLen = 8;
    base->read(req);

    cipher->streamDecode(buf, sizeof(buf), externalIV, key);

    fileIV = 0;
    for (int i = 0; i < 8; ++i) fileIV = (fileIV << 8) | (uint64_t)buf[i];

    rAssert(fileIV != 0);  // 0 is never used..
  } else {
    rDebug("creating new file IV header");

    unsigned char buf[8] = {0};
    do {
      if (!cipher->randomize(buf, 8, false))
        throw RLOG_ERROR("Unable to generate a random file IV");

      fileIV = 0;
      for (int i = 0; i < 8; ++i) fileIV = (fileIV << 8) | (uint64_t)buf[i];

      if (fileIV == 0)
        rWarning("Unexpected result: randomize returned 8 null bytes!");
    } while (fileIV == 0);  // don't accept 0 as an option..

    if (base->isWritable()) {
      cipher->streamEncode(buf, sizeof(buf), externalIV, key);

      IORequest req;
      req.offset = 0;
      req.data = buf;
      req.dataLen = 8;

      base->write(req);
    } else
      rDebug("base not writable, IV not written..");
  }
  rDebug("initHeader finished, fileIV = %" PRIu64, fileIV);
}