AgnosticDecoderModule.cpp (5324B)
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 9 #include "VPXDecoder.h" 10 #include "VideoUtils.h" 11 #include "mozilla/Logging.h" 12 #include "mozilla/StaticPrefs_media.h" 13 14 #ifdef MOZ_AV1 15 # include "AOMDecoder.h" 16 # include "DAV1DDecoder.h" 17 #endif 18 19 namespace mozilla { 20 21 enum class DecoderType { 22 #ifdef MOZ_AV1 23 AV1, 24 #endif 25 Opus, 26 Vorbis, 27 VPX, 28 Wave, 29 }; 30 31 static bool IsAvailableInDefault(DecoderType type) { 32 switch (type) { 33 #ifdef MOZ_AV1 34 case DecoderType::AV1: 35 return StaticPrefs::media_av1_enabled(); 36 #endif 37 case DecoderType::Opus: 38 case DecoderType::Vorbis: 39 case DecoderType::VPX: 40 case DecoderType::Wave: 41 return true; 42 default: 43 return false; 44 } 45 } 46 47 static bool IsAvailableInRdd(DecoderType type) { 48 switch (type) { 49 #ifdef MOZ_AV1 50 case DecoderType::AV1: 51 return StaticPrefs::media_av1_enabled(); 52 #endif 53 case DecoderType::Opus: 54 return StaticPrefs::media_rdd_opus_enabled(); 55 case DecoderType::Vorbis: 56 #if defined(__MINGW32__) 57 // If this is a MinGW build we need to force AgnosticDecoderModule to 58 // handle the decision to support Vorbis decoding (instead of 59 // RDD/RemoteDecoderModule) because of Bug 1597408 (Vorbis decoding on 60 // RDD causing sandboxing failure on MinGW-clang). Typically this 61 // would be dealt with using defines in StaticPrefList.yaml, but we 62 // must handle it here because of Bug 1598426 (the __MINGW32__ define 63 // isn't supported in StaticPrefList.yaml). 64 return false; 65 #else 66 return StaticPrefs::media_rdd_vorbis_enabled(); 67 #endif 68 case DecoderType::VPX: 69 return StaticPrefs::media_rdd_vpx_enabled(); 70 case DecoderType::Wave: 71 return StaticPrefs::media_rdd_wav_enabled(); 72 default: 73 return false; 74 } 75 } 76 77 static bool IsAvailableInUtility(DecoderType type) { 78 switch (type) { 79 case DecoderType::Opus: 80 case DecoderType::Vorbis: 81 case DecoderType::Wave: 82 return true; 83 // Others are video codecs, don't take care of them 84 default: 85 return false; 86 } 87 } 88 89 // Checks if decoder is available in the current process 90 static bool IsAvailable(DecoderType type) { 91 return XRE_IsRDDProcess() ? IsAvailableInRdd(type) 92 : XRE_IsUtilityProcess() ? IsAvailableInUtility(type) 93 : IsAvailableInDefault(type); 94 } 95 96 media::DecodeSupportSet AgnosticDecoderModule::SupportsMimeType( 97 const nsACString& aMimeType, DecoderDoctorDiagnostics* aDiagnostics) const { 98 UniquePtr<TrackInfo> trackInfo = CreateTrackInfoWithMIMEType(aMimeType); 99 if (!trackInfo) { 100 return media::DecodeSupportSet{}; 101 } 102 return Supports(SupportDecoderParams(*trackInfo), aDiagnostics); 103 } 104 105 media::DecodeSupportSet AgnosticDecoderModule::Supports( 106 const SupportDecoderParams& aParams, 107 DecoderDoctorDiagnostics* aDiagnostics) const { 108 // This should only be supported by MFMediaEngineDecoderModule. 109 if (aParams.mMediaEngineId) { 110 return media::DecodeSupportSet{}; 111 } 112 113 const auto& trackInfo = aParams.mConfig; 114 const nsACString& mimeType = trackInfo.mMimeType; 115 116 bool supports = 117 #ifdef MOZ_AV1 118 // We remove support for decoding AV1 here if RDD is enabled so that 119 // decoding on the content process doesn't accidentally happen in case 120 // something goes wrong with launching the RDD process. 121 (AOMDecoder::IsAV1(mimeType) && IsAvailable(DecoderType::AV1)) || 122 #endif 123 (VPXDecoder::IsVPX(mimeType) && IsAvailable(DecoderType::VPX)); 124 MOZ_LOG(sPDMLog, LogLevel::Debug, 125 ("Agnostic decoder %s requested type '%s'", 126 supports ? "supports" : "rejects", mimeType.BeginReading())); 127 if (supports) { 128 return media::DecodeSupport::SoftwareDecode; 129 } 130 return media::DecodeSupportSet{}; 131 } 132 133 already_AddRefed<MediaDataDecoder> AgnosticDecoderModule::CreateVideoDecoder( 134 const CreateDecoderParams& aParams) { 135 if (Supports(SupportDecoderParams(aParams), nullptr /* diagnostic */) 136 .isEmpty()) { 137 return nullptr; 138 } 139 RefPtr<MediaDataDecoder> m; 140 141 if (VPXDecoder::IsVPX(aParams.mConfig.mMimeType)) { 142 m = new VPXDecoder(aParams); 143 } 144 #ifdef MOZ_AV1 145 // We remove support for decoding AV1 here if RDD is enabled so that 146 // decoding on the content process doesn't accidentally happen in case 147 // something goes wrong with launching the RDD process. 148 if (StaticPrefs::media_av1_enabled() && 149 (!StaticPrefs::media_rdd_process_enabled() || XRE_IsRDDProcess()) && 150 AOMDecoder::IsAV1(aParams.mConfig.mMimeType)) { 151 if (StaticPrefs::media_av1_use_dav1d()) { 152 m = new DAV1DDecoder(aParams); 153 } else { 154 m = new AOMDecoder(aParams); 155 } 156 } 157 #endif 158 159 return m.forget(); 160 } 161 162 already_AddRefed<MediaDataDecoder> AgnosticDecoderModule::CreateAudioDecoder( 163 const CreateDecoderParams& aParams) { 164 return nullptr; 165 } 166 167 /* static */ 168 already_AddRefed<PlatformDecoderModule> AgnosticDecoderModule::Create() { 169 RefPtr<PlatformDecoderModule> pdm = new AgnosticDecoderModule(); 170 return pdm.forget(); 171 } 172 173 } // namespace mozilla