WebMDecoder.cpp (3658B)
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 "WebMDecoder.h" 8 9 #include <utility> 10 11 #include "VPXDecoder.h" 12 #include "mozilla/Preferences.h" 13 #include "mozilla/StaticPrefs_media.h" 14 #ifdef MOZ_AV1 15 # include "AOMDecoder.h" 16 #endif 17 #include "MediaContainerType.h" 18 #include "PDMFactory.h" 19 #include "PlatformDecoderModule.h" 20 #include "VideoUtils.h" 21 22 namespace mozilla { 23 24 /* static */ 25 nsTArray<UniquePtr<TrackInfo>> WebMDecoder::GetTracksInfo( 26 const MediaContainerType& aType, MediaResult& aError) { 27 nsTArray<UniquePtr<TrackInfo>> tracks; 28 const bool isVideo = aType.Type() == MEDIAMIMETYPE("video/webm"); 29 30 if (aType.Type() != MEDIAMIMETYPE("audio/webm") && !isVideo) { 31 aError = MediaResult( 32 NS_ERROR_DOM_MEDIA_FATAL_ERR, 33 RESULT_DETAIL("Invalid type:%s", aType.Type().AsString().get())); 34 return tracks; 35 } 36 37 aError = NS_OK; 38 39 const MediaCodecs& codecs = aType.ExtendedType().Codecs(); 40 if (codecs.IsEmpty()) { 41 return tracks; 42 } 43 44 for (const auto& codec : codecs.Range()) { 45 if (codec.EqualsLiteral("opus") || codec.EqualsLiteral("vorbis")) { 46 tracks.AppendElement( 47 CreateTrackInfoWithMIMETypeAndContainerTypeExtraParameters( 48 "audio/"_ns + NS_ConvertUTF16toUTF8(codec), aType)); 49 continue; 50 } 51 if (isVideo) { 52 UniquePtr<TrackInfo> trackInfo; 53 if (IsVP9CodecString(codec)) { 54 trackInfo = CreateTrackInfoWithMIMETypeAndContainerTypeExtraParameters( 55 "video/vp9"_ns, aType); 56 } else if (IsVP8CodecString(codec)) { 57 trackInfo = CreateTrackInfoWithMIMETypeAndContainerTypeExtraParameters( 58 "video/vp8"_ns, aType); 59 } 60 if (trackInfo) { 61 VPXDecoder::SetVideoInfo(trackInfo->GetAsVideoInfo(), codec); 62 tracks.AppendElement(std::move(trackInfo)); 63 continue; 64 } 65 } 66 #ifdef MOZ_AV1 67 if (StaticPrefs::media_av1_enabled() && IsAV1CodecString(codec)) { 68 auto trackInfo = 69 CreateTrackInfoWithMIMETypeAndContainerTypeExtraParameters( 70 "video/av1"_ns, aType); 71 AOMDecoder::SetVideoInfo(trackInfo->GetAsVideoInfo(), codec); 72 tracks.AppendElement(std::move(trackInfo)); 73 continue; 74 } 75 #endif 76 // Unknown codec 77 aError = MediaResult( 78 NS_ERROR_DOM_MEDIA_FATAL_ERR, 79 RESULT_DETAIL("Unknown codec:%s", NS_ConvertUTF16toUTF8(codec).get())); 80 } 81 return tracks; 82 } 83 84 /* static */ 85 bool WebMDecoder::IsSupportedType(const MediaContainerType& aContainerType) { 86 if (!StaticPrefs::media_webm_enabled()) { 87 return false; 88 } 89 90 MediaResult rv = NS_OK; 91 auto tracks = GetTracksInfo(aContainerType, rv); 92 93 if (NS_FAILED(rv)) { 94 return false; 95 } 96 97 if (tracks.IsEmpty()) { 98 // WebM guarantees that the only codecs it contained are vp8, vp9, opus or 99 // vorbis. 100 return true; 101 } 102 103 // Verify that we have a PDM that supports the whitelisted types, include 104 // color depth 105 RefPtr<PDMFactory> platform = new PDMFactory(); 106 for (const auto& track : tracks) { 107 if (!track || 108 platform 109 ->Supports(SupportDecoderParams(*track), nullptr /* diagnostic */) 110 .isEmpty()) { 111 return false; 112 } 113 } 114 115 return true; 116 } 117 118 /* static */ 119 nsTArray<UniquePtr<TrackInfo>> WebMDecoder::GetTracksInfo( 120 const MediaContainerType& aType) { 121 MediaResult rv = NS_OK; 122 return GetTracksInfo(aType, rv); 123 } 124 125 } // namespace mozilla