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 #include "AgnosticDecoderModule.h"
8 #include "OpusDecoder.h"
9 #include "TheoraDecoder.h"
10 #include "VPXDecoder.h"
11 #include "VorbisDecoder.h"
12 #include "WAVDecoder.h"
13 #include "mozilla/Logging.h"
14 #include "mozilla/StaticPrefs_media.h"
15 
16 #ifdef MOZ_AV1
17 #  include "AOMDecoder.h"
18 #  include "DAV1DDecoder.h"
19 #endif
20 
21 namespace mozilla {
22 
SupportsMimeType(const nsACString & aMimeType,DecoderDoctorDiagnostics * aDiagnostics) const23 bool AgnosticDecoderModule::SupportsMimeType(
24     const nsACString& aMimeType, DecoderDoctorDiagnostics* aDiagnostics) const {
25   bool supports =
26       VPXDecoder::IsVPX(aMimeType) || TheoraDecoder::IsTheora(aMimeType);
27 #if defined(__MINGW32__)
28   // If this is a MinGW build we need to force AgnosticDecoderModule to
29   // handle the decision to support Vorbis decoding (instead of
30   // RDD/RemoteDecoderModule) because of Bug 1597408 (Vorbis decoding on
31   // RDD causing sandboxing failure on MinGW-clang).  Typically this
32   // would be dealt with using defines in StaticPrefList.yaml, but we
33   // must handle it here because of Bug 1598426 (the __MINGW32__ define
34   // isn't supported in StaticPrefList.yaml).
35   supports |= VorbisDataDecoder::IsVorbis(aMimeType);
36 #else
37   if (!StaticPrefs::media_rdd_vorbis_enabled() ||
38       !StaticPrefs::media_rdd_process_enabled() ||
39       !BrowserTabsRemoteAutostart()) {
40     supports |= VorbisDataDecoder::IsVorbis(aMimeType);
41   }
42 #endif
43   if (!StaticPrefs::media_rdd_wav_enabled() ||
44       !StaticPrefs::media_rdd_process_enabled() ||
45       !BrowserTabsRemoteAutostart()) {
46     supports |= WaveDataDecoder::IsWave(aMimeType);
47   }
48   if (!StaticPrefs::media_rdd_opus_enabled() ||
49       !StaticPrefs::media_rdd_process_enabled() ||
50       !BrowserTabsRemoteAutostart()) {
51     supports |= OpusDataDecoder::IsOpus(aMimeType);
52   }
53 #ifdef MOZ_AV1
54   // We remove support for decoding AV1 here if RDD is enabled so that
55   // decoding on the content process doesn't accidentally happen in case
56   // something goes wrong with launching the RDD process.
57   if (StaticPrefs::media_av1_enabled() &&
58       !StaticPrefs::media_rdd_process_enabled()) {
59     supports |= AOMDecoder::IsAV1(aMimeType);
60   }
61 #endif
62   MOZ_LOG(sPDMLog, LogLevel::Debug,
63           ("Agnostic decoder %s requested type",
64            supports ? "supports" : "rejects"));
65   return supports;
66 }
67 
CreateVideoDecoder(const CreateDecoderParams & aParams)68 already_AddRefed<MediaDataDecoder> AgnosticDecoderModule::CreateVideoDecoder(
69     const CreateDecoderParams& aParams) {
70   RefPtr<MediaDataDecoder> m;
71 
72   if (VPXDecoder::IsVPX(aParams.mConfig.mMimeType)) {
73     m = new VPXDecoder(aParams);
74   }
75 #ifdef MOZ_AV1
76   // see comment above about AV1 and the RDD process
77   else if (AOMDecoder::IsAV1(aParams.mConfig.mMimeType) &&
78            !StaticPrefs::media_rdd_process_enabled() &&
79            StaticPrefs::media_av1_enabled()) {
80     if (StaticPrefs::media_av1_use_dav1d()) {
81       m = new DAV1DDecoder(aParams);
82     } else {
83       m = new AOMDecoder(aParams);
84     }
85   }
86 #endif
87   else if (TheoraDecoder::IsTheora(aParams.mConfig.mMimeType)) {
88     m = new TheoraDecoder(aParams);
89   }
90 
91   return m.forget();
92 }
93 
CreateAudioDecoder(const CreateDecoderParams & aParams)94 already_AddRefed<MediaDataDecoder> AgnosticDecoderModule::CreateAudioDecoder(
95     const CreateDecoderParams& aParams) {
96   RefPtr<MediaDataDecoder> m;
97 
98   const TrackInfo& config = aParams.mConfig;
99   if (VorbisDataDecoder::IsVorbis(config.mMimeType)) {
100     m = new VorbisDataDecoder(aParams);
101   } else if (OpusDataDecoder::IsOpus(config.mMimeType)) {
102     CreateDecoderParams params(aParams);
103     // Check IsDefaultPlaybackDeviceMono here and set the option in
104     // mOptions so OpusDataDecoder doesn't have to do it later (in case
105     // it is running on RDD).
106     if (IsDefaultPlaybackDeviceMono()) {
107       params.mOptions += CreateDecoderParams::Option::DefaultPlaybackDeviceMono;
108     }
109     m = new OpusDataDecoder(params);
110   } else if (WaveDataDecoder::IsWave(config.mMimeType)) {
111     m = new WaveDataDecoder(aParams);
112   }
113 
114   return m.forget();
115 }
116 
117 }  // namespace mozilla
118