Example #1
0
void
MediaDecoder::OnDecoderDoctorEvent(DecoderDoctorEvent aEvent)
{
  MOZ_ASSERT(NS_IsMainThread());
  // OnDecoderDoctorEvent is disconnected at shutdown time.
  MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
  nsIDocument* doc = GetOwner()->GetDocument();
  if (!doc) {
    return;
  }
  DecoderDoctorDiagnostics diags;
  diags.StoreEvent(doc, aEvent, __func__);
}
Example #2
0
/* static */ bool
MediaSource::IsTypeSupported(const GlobalObject& aOwner, const nsAString& aType)
{
  MOZ_ASSERT(NS_IsMainThread());
  DecoderDoctorDiagnostics diagnostics;
  nsresult rv = IsTypeSupported(aType, &diagnostics);
  nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aOwner.GetAsSupports());
  diagnostics.StoreFormatDiagnostics(window ? window->GetExtantDoc() : nullptr,
                                     aType, NS_SUCCEEDED(rv), __func__);
#define this nullptr
  MSE_API("IsTypeSupported(aType=%s)%s ",
          NS_ConvertUTF16toUTF8(aType).get(), rv == NS_OK ? "OK" : "[not supported]");
#undef this // don't ever remove this line !
  return NS_SUCCEEDED(rv);
}
Example #3
0
/* static */ bool
MediaSource::IsTypeSupported(const GlobalObject& aOwner, const nsAString& aType)
{
  MOZ_ASSERT(NS_IsMainThread());
  DecoderDoctorDiagnostics diagnostics;
  nsresult rv = IsTypeSupported(aType, &diagnostics);
  nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aOwner.GetAsSupports());
  diagnostics.StoreFormatDiagnostics(window ? window->GetExtantDoc() : nullptr,
                                     aType, NS_SUCCEEDED(rv), __func__);
  MOZ_LOG(GetMediaSourceAPILog(),
          mozilla::LogLevel::Debug,
          ("MediaSource::%s: IsTypeSupported(aType=%s) %s",
           __func__,
           NS_ConvertUTF16toUTF8(aType).get(),
           rv == NS_OK ? "OK" : "[not supported]"));
  return NS_SUCCEEDED(rv);
}
Example #4
0
already_AddRefed<MediaDataDecoder>
PDMFactory::CreateDecoder(const CreateDecoderParams& aParams)
{
  if (aParams.mUseBlankDecoder) {
    MOZ_ASSERT(mBlankPDM);
    return CreateDecoderWithPDM(mBlankPDM, aParams);
  }

  const TrackInfo& config = aParams.mConfig;
  bool isEncrypted = mEMEPDM && config.mCrypto.mValid;

  if (isEncrypted) {
    return CreateDecoderWithPDM(mEMEPDM, aParams);
  }

  DecoderDoctorDiagnostics* diagnostics = aParams.mDiagnostics;
  if (diagnostics) {
    // If libraries failed to load, the following loop over mCurrentPDMs
    // will not even try to use them. So we record failures now.
    if (mWMFFailedToLoad) {
      diagnostics->SetWMFFailedToLoad();
    }
    if (mFFmpegFailedToLoad) {
      diagnostics->SetFFmpegFailedToLoad();
    }
    if (mGMPPDMFailedToStartup) {
      diagnostics->SetGMPPDMFailedToStartup();
    }
  }

  for (auto& current : mCurrentPDMs) {
    if (!current->SupportsMimeType(config.mMimeType, diagnostics)) {
      continue;
    }
    RefPtr<MediaDataDecoder> m = CreateDecoderWithPDM(current, aParams);
    if (m) {
      return m.forget();
    }
  }
  NS_WARNING("Unable to create a decoder, no platform found.");
  return nullptr;
}
Example #5
0
already_AddRefed<SourceBuffer>
MediaSource::AddSourceBuffer(const nsAString& aType, ErrorResult& aRv)
{
  MOZ_ASSERT(NS_IsMainThread());
  DecoderDoctorDiagnostics diagnostics;
  nsresult rv = IsTypeSupported(aType, &diagnostics);
  diagnostics.StoreFormatDiagnostics(GetOwner()
                                     ? GetOwner()->GetExtantDoc()
                                     : nullptr,
                                     aType, NS_SUCCEEDED(rv), __func__);
  MSE_API("AddSourceBuffer(aType=%s)%s",
          NS_ConvertUTF16toUTF8(aType).get(),
          rv == NS_OK ? "" : " [not supported]");
  if (NS_FAILED(rv)) {
    aRv.Throw(rv);
    return nullptr;
  }
  if (mSourceBuffers->Length() >= MAX_SOURCE_BUFFERS) {
    aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR);
    return nullptr;
  }
  if (mReadyState != MediaSourceReadyState::Open) {
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
    return nullptr;
  }
  Maybe<MediaContainerType> containerType = MakeMediaContainerType(aType);
  if (!containerType) {
    aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
    return nullptr;
  }
  RefPtr<SourceBuffer> sourceBuffer = new SourceBuffer(this, *containerType);
  if (!sourceBuffer) {
    aRv.Throw(NS_ERROR_FAILURE); // XXX need a better error here
    return nullptr;
  }
  mSourceBuffers->Append(sourceBuffer);
  DDLINKCHILD("sourcebuffer[]", sourceBuffer.get());
  MSE_DEBUG("sourceBuffer=%p", sourceBuffer.get());
  return sourceBuffer.forget();
}
Example #6
0
already_AddRefed<MediaDataDecoder>
PDMFactory::CreateDecoderWithPDM(PlatformDecoderModule* aPDM,
                                 const CreateDecoderParams& aParams)
{
  MOZ_ASSERT(aPDM);
  RefPtr<MediaDataDecoder> m;

  SupportChecker supportChecker;
  const TrackInfo& config = aParams.mConfig;
  supportChecker.AddMediaFormatChecker(config);

  auto reason = supportChecker.Check();
  if (reason != SupportChecker::Result::kSupported) {
    DecoderDoctorDiagnostics* diagnostics = aParams.mDiagnostics;
    if (diagnostics) {
      if (reason == SupportChecker::Result::kVideoFormatNotSupported) {
        diagnostics->SetVideoFormatNotSupport();
      } else if (reason == SupportChecker::Result::kAudioFormatNotSupported) {
        diagnostics->SetAudioFormatNotSupport();
      }
    }
    return nullptr;
  }

  if (config.IsAudio()) {
    m = aPDM->CreateAudioDecoder(aParams);
    return m.forget();
  }

  if (!config.IsVideo()) {
    return nullptr;
  }

  MediaDataDecoderCallback* callback = aParams.mCallback;
  RefPtr<DecoderCallbackFuzzingWrapper> callbackWrapper;
  if (MediaPrefs::PDMFuzzingEnabled()) {
    callbackWrapper = new DecoderCallbackFuzzingWrapper(callback);
    callbackWrapper->SetVideoOutputMinimumInterval(
      TimeDuration::FromMilliseconds(MediaPrefs::PDMFuzzingInterval()));
    callbackWrapper->SetDontDelayInputExhausted(!MediaPrefs::PDMFuzzingDelayInputExhausted());
    callback = callbackWrapper.get();
  }

  CreateDecoderParams params = aParams;
  params.mCallback = callback;

  if (MP4Decoder::IsH264(config.mMimeType) && !aParams.mUseBlankDecoder) {
    RefPtr<H264Converter> h = new H264Converter(aPDM, params);
    const nsresult rv = h->GetLastError();
    if (NS_SUCCEEDED(rv) || rv == NS_ERROR_NOT_INITIALIZED) {
      // The H264Converter either successfully created the wrapped decoder,
      // or there wasn't enough AVCC data to do so. Otherwise, there was some
      // problem, for example WMF DLLs were missing.
      m = h.forget();
    }
  } else {
    m = aPDM->CreateVideoDecoder(params);
  }

  if (callbackWrapper && m) {
    m = new DecoderFuzzingWrapper(m.forget(), callbackWrapper.forget());
  }

  return m.forget();
}
Example #7
0
already_AddRefed<MediaDataDecoder>
PDMFactory::CreateDecoderWithPDM(PlatformDecoderModule* aPDM,
                                 const CreateDecoderParams& aParams)
{
  MOZ_ASSERT(aPDM);
  RefPtr<MediaDataDecoder> m;
  MediaResult* result = aParams.mError;

  SupportChecker supportChecker;
  const TrackInfo& config = aParams.mConfig;
  supportChecker.AddMediaFormatChecker(config);

  auto checkResult = supportChecker.Check();
  if (checkResult.mReason != SupportChecker::Reason::kSupported) {
    DecoderDoctorDiagnostics* diagnostics = aParams.mDiagnostics;
    if (checkResult.mReason
        == SupportChecker::Reason::kVideoFormatNotSupported) {
      if (diagnostics) {
        diagnostics->SetVideoNotSupported();
      }
      if (result) {
        *result = checkResult.mMediaResult;
      }
    } else if (checkResult.mReason
               == SupportChecker::Reason::kAudioFormatNotSupported) {
      if (diagnostics) {
        diagnostics->SetAudioNotSupported();
      }
      if (result) {
        *result = checkResult.mMediaResult;
      }
    }
    return nullptr;
  }

  if (config.IsAudio()) {
    m = aPDM->CreateAudioDecoder(aParams);
    return m.forget();
  }

  if (!config.IsVideo()) {
    *result = MediaResult(
      NS_ERROR_DOM_MEDIA_FATAL_ERR,
      RESULT_DETAIL("Decoder configuration error, expected audio or video."));
    return nullptr;
  }

  if (MP4Decoder::IsH264(config.mMimeType) && !aParams.mUseNullDecoder) {
    RefPtr<H264Converter> h = new H264Converter(aPDM, aParams);
    const nsresult rv = h->GetLastError();
    if (NS_SUCCEEDED(rv) || rv == NS_ERROR_NOT_INITIALIZED) {
      // The H264Converter either successfully created the wrapped decoder,
      // or there wasn't enough AVCC data to do so. Otherwise, there was some
      // problem, for example WMF DLLs were missing.
      m = h.forget();
    }
  } else {
    m = aPDM->CreateVideoDecoder(aParams);
  }

  return m.forget();
}