tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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