Exemplo n.º 1
0
static bool
IsSupportedH264Codec(const nsAString& aCodec)
{
  int16_t profile = 0, level = 0;

  if (!ExtractH264CodecDetails(aCodec, profile, level)) {
    return false;
  }

#ifdef XP_WIN
  // Disable 4k video on windows vista since it performs poorly.
  if (!IsWin7OrLater() &&
      level >= H264_LEVEL_5) {
    return false;
  }
#endif

  // Just assume what we can play on all platforms the codecs/formats that
  // WMF can play, since we don't have documentation about what other
  // platforms can play... According to the WMF documentation:
  // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815%28v=vs.85%29.aspx
  // "The Media Foundation H.264 video decoder is a Media Foundation Transform
  // that supports decoding of Baseline, Main, and High profiles, up to level
  // 5.1.". We also report that we can play Extended profile, as there are
  // bitstreams that are Extended compliant that are also Baseline compliant.
  return level >= H264_LEVEL_1 &&
         level <= H264_LEVEL_5_1 &&
         (profile == H264_PROFILE_BASE ||
          profile == H264_PROFILE_MAIN ||
          profile == H264_PROFILE_EXTENDED ||
          profile == H264_PROFILE_HIGH);
}
Exemplo n.º 2
0
static bool
IsWhitelistedH264Codec(const nsAString& aCodec)
{
  uint8_t profile = 0, constraint = 0, level = 0;

  if (!ExtractH264CodecDetails(aCodec, profile, constraint, level)) {
    return false;
  }

  // Just assume what we can play on all platforms the codecs/formats that
  // WMF can play, since we don't have documentation about what other
  // platforms can play... According to the WMF documentation:
  // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815%28v=vs.85%29.aspx
  // "The Media Foundation H.264 video decoder is a Media Foundation Transform
  // that supports decoding of Baseline, Main, and High profiles, up to level
  // 5.1.". We extend the limit to level 5.2, relying on the decoder to handle
  // any potential errors, the level limit being rather arbitrary.
  // We also report that we can play Extended profile, as there are
  // bitstreams that are Extended compliant that are also Baseline compliant.
  return level >= H264_LEVEL_1 &&
         level <= H264_LEVEL_5_2 &&
         (profile == H264_PROFILE_BASE ||
          profile == H264_PROFILE_MAIN ||
          profile == H264_PROFILE_EXTENDED ||
          profile == H264_PROFILE_HIGH);
}
Exemplo n.º 3
0
bool
IsH264CodecString(const nsAString& aCodec)
{
  int16_t profile = 0;
  int16_t level = 0;
  return ExtractH264CodecDetails(aCodec, profile, level);
}
Exemplo n.º 4
0
bool
IsH264CodecString(const nsAString& aCodec)
{
  uint8_t profile = 0;
  uint8_t constraint = 0;
  uint8_t level = 0;
  return ExtractH264CodecDetails(aCodec, profile, constraint, level);
}
Exemplo n.º 5
0
bool
IsH264ContentType(const nsAString& aContentType)
{
    return CheckContentType(aContentType,
    [](const nsAString& type) {
        return type.EqualsLiteral("video/mp4");
    },
    [](const nsAString& codec) {
        int16_t profile = 0;
        int16_t level = 0;
        return ExtractH264CodecDetails(codec, profile, level);
    }
                           );
}
Exemplo n.º 6
0
/* statis */ nsTArray<UniquePtr<TrackInfo>>
MP4Decoder::GetTracksInfo(const MediaContainerType& aType, MediaResult& aError)
{
  nsTArray<UniquePtr<TrackInfo>> tracks;

  if (!IsTypeValid(aType)) {
    aError = MediaResult(
      NS_ERROR_DOM_MEDIA_FATAL_ERR,
      RESULT_DETAIL("Invalid type:%s", aType.Type().AsString().get()));
    return tracks;
  }

  aError = NS_OK;

  const MediaCodecs& codecs = aType.ExtendedType().Codecs();
  if (codecs.IsEmpty()) {
    return tracks;
  }

  const bool isVideo = aType.Type() == MEDIAMIMETYPE("video/mp4") ||
                       aType.Type() == MEDIAMIMETYPE("video/quicktime") ||
                       aType.Type() == MEDIAMIMETYPE("video/x-m4v");

  for (const auto& codec : codecs.Range()) {
    if (IsAACCodecString(codec)) {
      tracks.AppendElement(
        CreateTrackInfoWithMIMETypeAndContainerTypeExtraParameters(
          NS_LITERAL_CSTRING("audio/mp4a-latm"), aType));
      continue;
    }
    if (codec.EqualsLiteral("mp3")) {
      tracks.AppendElement(
        CreateTrackInfoWithMIMETypeAndContainerTypeExtraParameters(
          NS_LITERAL_CSTRING("audio/mpeg"), aType));
      continue;
    }
    if (codec.EqualsLiteral("opus") || codec.EqualsLiteral("flac")) {
      tracks.AppendElement(
        CreateTrackInfoWithMIMETypeAndContainerTypeExtraParameters(
          NS_LITERAL_CSTRING("audio/") + NS_ConvertUTF16toUTF8(codec), aType));
      continue;
    }
    if (IsVP9CodecString(codec)) {
      auto trackInfo =
        CreateTrackInfoWithMIMETypeAndContainerTypeExtraParameters(
          NS_LITERAL_CSTRING("video/vp9"), aType);
      uint8_t profile = 0;
      uint8_t level = 0;
      uint8_t bitDepth = 0;
      if (ExtractVPXCodecDetails(codec, profile, level, bitDepth)) {
        trackInfo->GetAsVideoInfo()->mBitDepth = bitDepth;
      }
      tracks.AppendElement(std::move(trackInfo));
      continue;
    }
    if (isVideo && IsWhitelistedH264Codec(codec)) {
      auto trackInfo =
        CreateTrackInfoWithMIMETypeAndContainerTypeExtraParameters(
          NS_LITERAL_CSTRING("video/avc"), aType);
      uint8_t profile = 0, constraint = 0, level = 0;
      MOZ_ALWAYS_TRUE(
        ExtractH264CodecDetails(codec, profile, constraint, level));
      uint32_t width = aType.ExtendedType().GetWidth().refOr(1280);
      uint32_t height = aType.ExtendedType().GetHeight().refOr(720);
      trackInfo->GetAsVideoInfo()->mExtraData =
        H264::CreateExtraData(profile, constraint, level, { width, height });
      tracks.AppendElement(std::move(trackInfo));
      continue;
    }
    // Unknown codec
    aError =
      MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
                  RESULT_DETAIL("Unknown codec:%s",
                                NS_ConvertUTF16toUTF8(codec).get()));
  }
  return tracks;
}