예제 #1
0
GMPErr
ChromiumCDMAdapter::GMPInit(const GMPPlatformAPI* aPlatformAPI)
{
  GMP_LOG("ChromiumCDMAdapter::GMPInit");
  sPlatform = aPlatformAPI;
  if (!mLib) {
    return GMPGenericErr;
  }

#ifdef MOZILLA_OFFICIAL
  // Note: we must call the VerifyCdmHost_0 function if it's present before
  // we call the initialize function.
  auto verify = reinterpret_cast<decltype(::VerifyCdmHost_0)*>(
    PR_FindFunctionSymbol(mLib, STRINGIFY(VerifyCdmHost_0)));
  if (verify) {
    nsTArray<cdm::HostFile> files;
    for (HostFileData& hostFile : mHostFiles) {
      files.AppendElement(TakeToCDMHostFile(hostFile));
    }
    bool result = verify(files.Elements(), files.Length());
    GMP_LOG("%s VerifyCdmHost_0 returned %d", __func__, result);
  }
#endif

  auto init = reinterpret_cast<decltype(::INITIALIZE_CDM_MODULE)*>(
    PR_FindFunctionSymbol(mLib, STRINGIFY(INITIALIZE_CDM_MODULE)));
  if (!init) {
    return GMPGenericErr;
  }

  GMP_LOG(STRINGIFY(INITIALIZE_CDM_MODULE) "()");
  init();

  return GMPNoErr;
}
예제 #2
0
void
ChromiumCDMAdapter::GMPShutdown()
{
  GMP_LOG("ChromiumCDMAdapter::GMPShutdown()");

  decltype(::DeinitializeCdmModule)* deinit;
  deinit = (decltype(deinit))(PR_FindFunctionSymbol(mLib, "DeinitializeCdmModule"));
  if (deinit) {
    GMP_LOG("DeinitializeCdmModule()");
    deinit();
  }
}
예제 #3
0
GMPErr
ChromiumCDMAdapter::GMPGetAPI(const char* aAPIName,
                              void* aHostAPI,
                              void** aPluginAPI,
                              uint32_t aDecryptorId)
{
  GMP_LOG("ChromiumCDMAdapter::GMPGetAPI(%s, 0x%p, 0x%p, %u) this=0x%p",
          aAPIName,
          aHostAPI,
          aPluginAPI,
          aDecryptorId,
          this);
  bool isCDM9 = !strcmp(aAPIName, CHROMIUM_CDM_API);
  bool isCDM8 = !strcmp(aAPIName, CHROMIUM_CDM_API_BACKWARD_COMPAT);
  if (isCDM8 || isCDM9) {
    auto create = reinterpret_cast<decltype(::CreateCdmInstance)*>(
      PR_FindFunctionSymbol(mLib, "CreateCdmInstance"));
    if (!create) {
      GMP_LOG("ChromiumCDMAdapter::GMPGetAPI(%s, 0x%p, 0x%p, %u) this=0x%p "
              "FAILED to find CreateCdmInstance",
              aAPIName,
              aHostAPI,
              aPluginAPI,
              aDecryptorId,
              this);
      return GMPGenericErr;
    }

    int version = isCDM8 ? cdm::ContentDecryptionModule_8::kVersion :
                           cdm::ContentDecryptionModule_9::kVersion;
    void* cdm =
      create(version,
             kEMEKeySystemWidevine.get(),
             kEMEKeySystemWidevine.Length(),
             &ChromiumCdmHost,
             aHostAPI);
    if (!cdm) {
      GMP_LOG("ChromiumCDMAdapter::GMPGetAPI(%s, 0x%p, 0x%p, %u) this=0x%p "
              "FAILED to create cdm version %d",
              aAPIName,
              aHostAPI,
              aPluginAPI,
              aDecryptorId,
              this,
              version);
      return GMPGenericErr;
    }
    GMP_LOG("cdm: 0x%p, version: %d", cdm, version);
    *aPluginAPI = cdm;
  }
  return *aPluginAPI ? GMPNoErr : GMPNotImplementedErr;
}
예제 #4
0
PGMPVideoDecoderParent* GMPContentParent::AllocPGMPVideoDecoderParent(
    const uint32_t& aDecryptorId) {
  GMP_LOG("GMPContentParent::AllocPGMPVideoDecoderParent(this=%p)", this);
  GMPVideoDecoderParent* vdp = new GMPVideoDecoderParent(this);
  NS_ADDREF(vdp);
  return vdp;
}
예제 #5
0
void GMPContentParent::ActorDestroy(ActorDestroyReason aWhy) {
  GMP_LOG("GMPContentParent::ActorDestroy(this=%p, aWhy=%d)", this,
          static_cast<int>(aWhy));
  MOZ_ASSERT(mVideoDecoders.IsEmpty() && mVideoEncoders.IsEmpty() &&
             mChromiumCDMs.IsEmpty());
  NS_DispatchToCurrentThread(new ReleaseGMPContentParent(this));
}
예제 #6
0
void GMPContentParent::AddCloseBlocker() {
  MOZ_ASSERT(GMPEventTarget()->IsOnCurrentThread());
  ++mCloseBlockerCount;
  GMP_LOG(
      "GMPContentParent::AddCloseBlocker(this=%p) mCloseBlockerCount=%" PRIu32,
      this, mCloseBlockerCount);
}
예제 #7
0
bool GMPContentParent::DeallocPChromiumCDMParent(PChromiumCDMParent* aActor) {
  GMP_LOG("GMPContentParent::DeallocPChromiumCDMParent(this=%p, aActor=%p)",
          this, aActor);
  ChromiumCDMParent* parent = static_cast<ChromiumCDMParent*>(aActor);
  NS_RELEASE(parent);
  return true;
}
예제 #8
0
bool GMPContentParent::DeallocPGMPVideoEncoderParent(
    PGMPVideoEncoderParent* aActor) {
  GMP_LOG("GMPContentParent::DeallocPGMPVideoEncoderParent(this=%p, aActor=%p)",
          this, aActor);
  GMPVideoEncoderParent* vep = static_cast<GMPVideoEncoderParent*>(aActor);
  NS_RELEASE(vep);
  return true;
}
예제 #9
0
void GMPContentParent::ChromiumCDMDestroyed(ChromiumCDMParent* aCDM) {
  GMP_LOG("GMPContentParent::ChromiumCDMDestroyed(this=%p, aCDM=%p)", this,
          aCDM);
  MOZ_ASSERT(GMPEventTarget()->IsOnCurrentThread());

  MOZ_ALWAYS_TRUE(mChromiumCDMs.RemoveElement(aCDM));
  CloseIfUnused();
}
예제 #10
0
void GMPContentParent::RemoveCloseBlocker() {
  MOZ_ASSERT(GMPEventTarget()->IsOnCurrentThread());
  --mCloseBlockerCount;
  GMP_LOG(
      "GMPContentParent::RemoveCloseBlocker(this=%p) "
      "mCloseBlockerCount=%" PRIu32,
      this, mCloseBlockerCount);
  CloseIfUnused();
}
예제 #11
0
void GMPContentParent::VideoEncoderDestroyed(GMPVideoEncoderParent* aEncoder) {
  GMP_LOG("GMPContentParent::VideoEncoderDestroyed(this=%p, aEncoder=%p)", this,
          aEncoder);
  MOZ_ASSERT(GMPEventTarget()->IsOnCurrentThread());

  // If the constructor fails, we'll get called before it's added
  Unused << NS_WARN_IF(!mVideoEncoders.RemoveElement(aEncoder));
  CloseIfUnused();
}
예제 #12
0
GMPContentParent::~GMPContentParent() {
  GMP_LOG(
      "GMPContentParent::~GMPContentParent(this=%p) mVideoDecoders.IsEmpty=%s, "
      "mVideoEncoders.IsEmpty=%s, mChromiumCDMs.IsEmpty=%s, "
      "mCloseBlockerCount=%" PRIu32,
      this, GetBoolString(mVideoDecoders.IsEmpty()),
      GetBoolString(mVideoEncoders.IsEmpty()),
      GetBoolString(mChromiumCDMs.IsEmpty()), mCloseBlockerCount);
}
예제 #13
0
GMPContentParent::GMPContentParent(GMPParent* aParent)
    : mParent(aParent), mPluginId(0) {
  GMP_LOG("GMPContentParent::GMPContentParent(this=%p), aParent=%p", this,
          aParent);
  if (mParent) {
    SetDisplayName(mParent->GetDisplayName());
    SetPluginId(mParent->GetPluginId());
  }
}
예제 #14
0
void*
ChromiumCdmHost(int aHostInterfaceVersion, void* aUserData)
{
  GMP_LOG("ChromiumCdmHostFunc(%d, %p)", aHostInterfaceVersion, aUserData);
  if (aHostInterfaceVersion != cdm::Host_8::kVersion &&
      aHostInterfaceVersion != cdm::Host_9::kVersion) {
    return nullptr;
  }
  return aUserData;
}
예제 #15
0
already_AddRefed<ChromiumCDMParent> GMPContentParent::GetChromiumCDM() {
  GMP_LOG("GMPContentParent::GetChromiumCDM(this=%p)", this);
  PChromiumCDMParent* actor = SendPChromiumCDMConstructor();
  if (!actor) {
    return nullptr;
  }
  RefPtr<ChromiumCDMParent> parent = static_cast<ChromiumCDMParent*>(actor);

  // TODO: Remove parent from mChromiumCDMs in ChromiumCDMParent::Destroy().
  mChromiumCDMs.AppendElement(parent);

  return parent.forget();
}
예제 #16
0
nsresult GMPContentParent::GetGMPVideoEncoder(GMPVideoEncoderParent** aGMPVE) {
  GMP_LOG("GMPContentParent::GetGMPVideoEncoder(this=%p)", this);
  // returned with one anonymous AddRef that locks it until Destroy
  PGMPVideoEncoderParent* pvep = SendPGMPVideoEncoderConstructor();
  if (!pvep) {
    return NS_ERROR_FAILURE;
  }
  GMPVideoEncoderParent* vep = static_cast<GMPVideoEncoderParent*>(pvep);
  // This addref corresponds to the Proxy pointer the consumer is returned.
  // It's dropped by calling Close() on the interface.
  NS_ADDREF(vep);
  *aGMPVE = vep;
  mVideoEncoders.AppendElement(vep);

  return NS_OK;
}
예제 #17
0
DWORD WINAPI
QueryDosDeviceWHook(LPCWSTR lpDeviceName, LPWSTR lpTargetPath, DWORD ucchMax)
{
  if (!sDeviceNames) {
    return 0;
  }
  std::wstring name = std::wstring(lpDeviceName);
  auto iter = sDeviceNames->find(name);
  if (iter == sDeviceNames->end()) {
    return 0;
  }
  const std::wstring& device = iter->second;
  if (device.size() + 1 > ucchMax) {
    return 0;
  }
  PodCopy(lpTargetPath, device.c_str(), device.size());
  lpTargetPath[device.size()] = 0;
  GMP_LOG("QueryDosDeviceWHook %S -> %S", lpDeviceName, lpTargetPath);
  return name.size();
}
예제 #18
0
nsCOMPtr<nsISerialEventTarget> GMPContentParent::GMPEventTarget() {
  if (!mGMPEventTarget) {
    GMP_LOG("GMPContentParent::GMPEventTarget(this=%p)", this);
    nsCOMPtr<mozIGeckoMediaPluginService> mps =
        do_GetService("@mozilla.org/gecko-media-plugin-service;1");
    MOZ_ASSERT(mps);
    if (!mps) {
      return nullptr;
    }
    // Not really safe if we just grab to the mGMPEventTarget, as we don't know
    // what thread we're running on and other threads may be trying to
    // access this without locks!  However, debug only, and primary failure
    // mode outside of compiler-helped TSAN is a leak.  But better would be
    // to use swap() under a lock.
    nsCOMPtr<nsIThread> gmpThread;
    mps->GetThread(getter_AddRefs(gmpThread));
    MOZ_ASSERT(gmpThread);

    mGMPEventTarget = gmpThread->SerialEventTarget();
  }

  return mGMPEventTarget;
}
예제 #19
0
void GMPContentParent::CloseIfUnused() {
  GMP_LOG(
      "GMPContentParent::CloseIfUnused(this=%p) mVideoDecoders.IsEmpty=%s, "
      "mVideoEncoders.IsEmpty=%s, mChromiumCDMs.IsEmpty=%s, "
      "mCloseBlockerCount=%" PRIu32,
      this, GetBoolString(mVideoDecoders.IsEmpty()),
      GetBoolString(mVideoEncoders.IsEmpty()),
      GetBoolString(mChromiumCDMs.IsEmpty()), mCloseBlockerCount);
  if (mVideoDecoders.IsEmpty() && mVideoEncoders.IsEmpty() &&
      mChromiumCDMs.IsEmpty() && mCloseBlockerCount == 0) {
    RefPtr<GMPContentParent> toClose;
    if (mParent) {
      toClose = mParent->ForgetGMPContentParent();
    } else {
      toClose = this;
      RefPtr<GeckoMediaPluginServiceChild> gmp(
          GeckoMediaPluginServiceChild::GetSingleton());
      gmp->RemoveGMPContentParent(toClose);
    }
    NS_DispatchToCurrentThread(NewRunnableMethod(
        "gmp::GMPContentParent::Close", toClose, &GMPContentParent::Close));
  }
}
예제 #20
0
PChromiumCDMParent* GMPContentParent::AllocPChromiumCDMParent() {
  GMP_LOG("GMPContentParent::AllocPChromiumCDMParent(this=%p)", this);
  ChromiumCDMParent* parent = new ChromiumCDMParent(this, GetPluginId());
  NS_ADDREF(parent);
  return parent;
}
예제 #21
0
PGMPVideoEncoderParent* GMPContentParent::AllocPGMPVideoEncoderParent() {
  GMP_LOG("GMPContentParent::AllocPGMPVideoEncoderParent(this=%p)", this);
  GMPVideoEncoderParent* vep = new GMPVideoEncoderParent(this);
  NS_ADDREF(vep);
  return vep;
}