DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef DecoderDoctorDiagnostics_h_
#define DecoderDoctorDiagnostics_h_

#include "MediaResult.h"
#include "nsString.h"

class nsIDocument;

namespace mozilla {

struct DecoderDoctorEvent {
  enum Domain {
    eAudioSinkStartup,
  } mDomain;
  nsresult mResult;
};

// DecoderDoctorDiagnostics class, used to gather data from PDMs/DecoderTraits,
// and then notify the user about issues preventing (or worsening) playback.
//
// The expected usage is:
// 1. Instantiate a DecoderDoctorDiagnostics in a function (close to the point
//    where a webpage is trying to know whether some MIME types can be played,
//    or trying to play a media file).
// 2. Pass a pointer to the DecoderDoctorDiagnostics structure to one of the
//    CanPlayStatus/IsTypeSupported/(others?). During that call, some PDMs may
//    add relevant diagnostic information.
// 3. Analyze the collected diagnostics, and optionally dispatch an event to the
//    UX, to notify the user about potential playback issues and how to resolve
//    them.
//
// This class' methods must be called from the main thread.

class DecoderDoctorDiagnostics
{
public:
  // Store the diagnostic information collected so far on a document for a
  // given format. All diagnostics for a document will be analyzed together
  // within a short timeframe.
  // Should only be called once.
  void StoreFormatDiagnostics(nsIDocument* aDocument,
                              const nsAString& aFormat,
                              bool aCanPlay,
                              const char* aCallSite);

  void StoreMediaKeySystemAccess(nsIDocument* aDocument,
                                 const nsAString& aKeySystem,
                                 bool aIsSupported,
                                 const char* aCallSite);

  void StoreEvent(nsIDocument* aDocument,
                  const DecoderDoctorEvent& aEvent,
                  const char* aCallSite);

  void StoreDecodeError(nsIDocument* aDocument,
                        const MediaResult& aError,
                        const nsString& aMediaSrc,
                        const char* aCallSite);

  void StoreDecodeWarning(nsIDocument* aDocument,
                          const MediaResult& aWarning,
                          const nsString& aMediaSrc,
                          const char* aCallSite);

  enum DiagnosticsType
  {
    eUnsaved,
    eFormatSupportCheck,
    eMediaKeySystemAccessRequest,
    eEvent,
    eDecodeError,
    eDecodeWarning
  };
  DiagnosticsType Type() const { return mDiagnosticsType; }

  // Description string, for logging purposes; only call on stored diags.
  nsCString GetDescription() const;

  // Methods to record diagnostic information:

  const nsAString& Format() const { return mFormat; }
  bool CanPlay() const { return mCanPlay; }

  void SetWMFFailedToLoad() { mWMFFailedToLoad = true; }
  bool DidWMFFailToLoad() const { return mWMFFailedToLoad; }

  void SetFFmpegFailedToLoad() { mFFmpegFailedToLoad = true; }
  bool DidFFmpegFailToLoad() const { return mFFmpegFailedToLoad; }

  void SetGMPPDMFailedToStartup() { mGMPPDMFailedToStartup = true; }
  bool DidGMPPDMFailToStartup() const { return mGMPPDMFailedToStartup; }

  void SetVideoNotSupported() { mVideoNotSupported = true; }
  void SetAudioNotSupported() { mAudioNotSupported = true; }

  void SetGMP(const nsACString& aGMP) { mGMP = aGMP; }
  const nsACString& GMP() const { return mGMP; }

  const nsAString& KeySystem() const { return mKeySystem; }
  bool IsKeySystemSupported() const { return mIsKeySystemSupported; }
  enum KeySystemIssue {
    eUnset,
    eWidevineWithNoWMF
  };
  void SetKeySystemIssue(KeySystemIssue aKeySystemIssue)
  {
    mKeySystemIssue = aKeySystemIssue;
  }
  KeySystemIssue GetKeySystemIssue() const
  {
    return mKeySystemIssue;
  }

  DecoderDoctorEvent event() const
  {
    return mEvent;
  }

  const MediaResult& DecodeIssue() const { return mDecodeIssue; }
  const nsString& DecodeIssueMediaSrc() const
  {
    return mDecodeIssueMediaSrc;
  }

private:
  // Currently-known type of diagnostics. Set from one of the 'Store...' methods.
  // This helps ensure diagnostics are only stored once,
  // and makes it easy to know what information they contain.
  DiagnosticsType mDiagnosticsType = eUnsaved;

  nsString mFormat;
  // True if there is at least one decoder that can play that format.
  bool mCanPlay = false;

  bool mWMFFailedToLoad = false;
  bool mFFmpegFailedToLoad = false;
  bool mGMPPDMFailedToStartup = false;
  bool mVideoNotSupported = false;
  bool mAudioNotSupported = false;
  nsCString mGMP;

  nsString mKeySystem;
  bool mIsKeySystemSupported = false;
  KeySystemIssue mKeySystemIssue = eUnset;

  DecoderDoctorEvent mEvent;

  MediaResult mDecodeIssue = NS_OK;
  nsString mDecodeIssueMediaSrc;
};

} // namespace mozilla

#endif