1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #if !defined(PDMFactory_h_)
8 #  define PDMFactory_h_
9 
10 #  include <utility>
11 #  include "DecoderDoctorDiagnostics.h"
12 #  include "PlatformDecoderModule.h"
13 #  include "mozilla/AlreadyAddRefed.h"
14 #  include "mozilla/EnumSet.h"
15 #  include "mozilla/MozPromise.h"
16 #  include "mozilla/RefPtr.h"
17 #  include "nsISupports.h"
18 #  include "nsStringFwd.h"
19 #  include "nsTArray.h"
20 
21 namespace mozilla {
22 
23 class CDMProxy;
24 class MediaDataDecoder;
25 class MediaResult;
26 class StaticMutex;
27 template <typename T>
28 struct MaxEnumValue;
29 struct CreateDecoderParams;
30 struct CreateDecoderParamsForAsync;
31 struct SupportDecoderParams;
32 enum class RemoteDecodeIn;
33 
34 using PDMCreateDecoderPromise = PlatformDecoderModule::CreateDecoderPromise;
35 
36 class PDMFactory final {
37  public:
38   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PDMFactory)
39 
40   PDMFactory();
41 
42   // Factory method that creates the appropriate PlatformDecoderModule for
43   // the platform we're running on.
44   RefPtr<PDMCreateDecoderPromise> CreateDecoder(
45       const CreateDecoderParams& aParams);
46 
47   bool SupportsMimeType(const nsACString& aMimeType) const;
48   bool Supports(const SupportDecoderParams& aParams,
49                 DecoderDoctorDiagnostics* aDiagnostics) const;
50 
51   // Creates a PlatformDecoderModule that uses a CDMProxy to decrypt or
52   // decrypt-and-decode EME encrypted content. If the CDM only decrypts and
53   // does not decode, we create a PDM and use that to create MediaDataDecoders
54   // that we use on on aTaskQueue to decode the decrypted stream.
55   // This is called on the decode task queue.
56   void SetCDMProxy(CDMProxy* aProxy);
57 
58   static constexpr int kYUV400 = 0;
59   static constexpr int kYUV420 = 1;
60   static constexpr int kYUV422 = 2;
61   static constexpr int kYUV444 = 3;
62 
63   /*
64    * All the codecs we support
65    */
66   enum class MediaCodecs {
67     H264,
68     VP9,
69     VP8,
70     AV1,
71     Theora,
72     AAC,
73     MP3,
74     Opus,
75     Vorbis,
76     Flac,
77     Wave,
78 
79     SENTINEL,
80   };
81 
82   using MediaCodecsSupported = EnumSet<MediaCodecs>;
83 
84   static MediaCodecsSupported Supported(bool aForceRefresh = false);
85   static bool SupportsMimeType(const nsACString& aMimeType,
86                                const MediaCodecsSupported& aSupported);
87 
88   static bool AllDecodersAreRemote();
89 
90  private:
91   virtual ~PDMFactory();
92 
93   void CreatePDMs();
94   void CreateNullPDM();
95   void CreateGpuPDMs();
96   void CreateRddPDMs();
97   void CreateContentPDMs();
98   void CreateDefaultPDMs();
99 
100   template <typename DECODER_MODULE, typename... ARGS>
CreateAndStartupPDM(ARGS &&...aArgs)101   bool CreateAndStartupPDM(ARGS&&... aArgs) {
102     return StartupPDM(DECODER_MODULE::Create(std::forward<ARGS>(aArgs)...));
103   }
104 
105   // Startup the provided PDM and add it to our list if successful.
106   bool StartupPDM(already_AddRefed<PlatformDecoderModule> aPDM,
107                   bool aInsertAtBeginning = false);
108   // Returns the first PDM in our list supporting the mimetype.
109   already_AddRefed<PlatformDecoderModule> GetDecoderModule(
110       const SupportDecoderParams& aParams,
111       DecoderDoctorDiagnostics* aDiagnostics) const;
112 
113   RefPtr<PDMCreateDecoderPromise> CreateDecoderWithPDM(
114       PlatformDecoderModule* aPDM, const CreateDecoderParams& aParams);
115   RefPtr<PDMCreateDecoderPromise> CheckAndMaybeCreateDecoder(
116       CreateDecoderParamsForAsync&& aParams, uint32_t aIndex,
117       Maybe<MediaResult> aEarlierError = Nothing());
118 
119   nsTArray<RefPtr<PlatformDecoderModule>> mCurrentPDMs;
120   RefPtr<PlatformDecoderModule> mEMEPDM;
121   RefPtr<PlatformDecoderModule> mNullPDM;
122 
123   DecoderDoctorDiagnostics::FlagsSet mFailureFlags;
124 
125   friend class RemoteVideoDecoderParent;
126   static void EnsureInit();
127 };
128 
129 // Used for IPDL serialization.
130 // The 'value' have to be the biggest enum from MediaCodecs.
131 template <>
132 struct MaxEnumValue<PDMFactory::MediaCodecs> {
133   static constexpr unsigned int value =
134       static_cast<unsigned int>(PDMFactory::MediaCodecs::SENTINEL);
135 };
136 
137 }  // namespace mozilla
138 
139 #endif /* PDMFactory_h_ */
140