Bug 1377015 - MediaCodecs::ContainsPrefix implementation and tests - r=rillian draft
authorGerald Squelart <gsquelart@mozilla.com>
Thu, 29 Jun 2017 11:17:56 -0700
changeset 602174 3a60c01da1d91adf29f51ce3c32f8df60282c90a
parent 602051 f3483af8ecf997453064201c49c48a682c7f3c29
child 635495 9130226537e02336babc343073770a607c45738a
push id66315
push usergsquelart@mozilla.com
push dateThu, 29 Jun 2017 18:58:03 +0000
reviewersrillian
bugs1377015
milestone56.0a1
Bug 1377015 - MediaCodecs::ContainsPrefix implementation and tests - r=rillian Many video codecs use a suffix to specify level, profile and optional features, like "avc1.42E001" or "vp09.00.41.08". MediaCodecs::ContainsPrefix() can be used to facilitate codec identification from their prefix alone, e.g.: "avc1" or "vp09". MozReview-Commit-ID: D6kcjggXptS
dom/media/MediaMIMETypes.cpp
dom/media/MediaMIMETypes.h
dom/media/gtest/TestMediaMIMETypes.cpp
--- a/dom/media/MediaMIMETypes.cpp
+++ b/dom/media/MediaMIMETypes.cpp
@@ -102,16 +102,29 @@ MediaCodecs::ContainsAll(const MediaCode
   for (const auto& codecToTest : codecsToTest) {
     if (!Contains(codecToTest)) {
       return false;
     }
   }
   return true;
 }
 
+bool
+MediaCodecs::ContainsPrefix(const nsAString& aCodecPrefix) const
+{
+  const size_t prefixLength = aCodecPrefix.Length();
+  for (const auto& myCodec : Range()) {
+    if (myCodec.Length() >= prefixLength &&
+        memcmp(myCodec.Data(), aCodecPrefix.Data(), prefixLength) == 0) {
+      return true;
+    }
+  }
+  return false;
+}
+
 size_t
 MediaCodecs::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
 {
   return mCodecs.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
 }
 
 
 static int32_t
--- a/dom/media/MediaMIMETypes.h
+++ b/dom/media/MediaMIMETypes.h
@@ -98,17 +98,17 @@ private:
   nsCString mMIMEType; // UTF8 MIME "type/subtype".
 };
 
 Maybe<MediaMIMEType> MakeMediaMIMEType(const nsAString& aType);
 Maybe<MediaMIMEType> MakeMediaMIMEType(const nsACString& aType);
 Maybe<MediaMIMEType> MakeMediaMIMEType(const char* aType);
 
 
-// A list of codecs attached to a MediaExtendedMIMEType.
+// A list of case-sensitive codecs attached to a MediaExtendedMIMEType.
 class MediaCodecs
 {
 public:
   MediaCodecs() { }
   // Construction from a comma-separated list of codecs. Unchecked.
   explicit MediaCodecs(const nsAString& aCodecs) : mCodecs(aCodecs) { }
   // Construction from a literal comma-separated list of codecs. Unchecked.
   template <size_t N>
@@ -127,19 +127,24 @@ public:
   // This will iterate through all codecs, even empty ones (except if the
   // original list was an empty string). Iterators dereference to
   // 'const nsDependentString', valid for as long as this MediaCodecs object.
   RangeType Range() const
   {
     return RangeType(mCodecs);
   };
 
+  // Does this list of codecs contain the given aCodec?
   bool Contains(const nsAString& aCodec) const;
+  // Does this list of codecs contain *all* the codecs in the given list?
   bool ContainsAll(const MediaCodecs& aCodecs) const;
 
+  // Does this list of codecs contain a codec starting with the given prefix?
+  bool ContainsPrefix(const nsAString& aCodecPrefix) const;
+
   template <size_t N>
   bool operator==(const char (&aType)[N]) const
   {
     return mCodecs.EqualsASCII(aType, N - 1);
   }
 
   size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
--- a/dom/media/gtest/TestMediaMIMETypes.cpp
+++ b/dom/media/gtest/TestMediaMIMETypes.cpp
@@ -89,53 +89,70 @@ TEST(MediaMIMETypes, MediaMIMEType)
 
 TEST(MediaMIMETypes, MediaCodecs)
 {
   MediaCodecs empty("");
   EXPECT_TRUE(empty.IsEmpty());
   EXPECT_TRUE(empty.AsString().EqualsLiteral(""));
   EXPECT_FALSE(empty.Contains(NS_LITERAL_STRING("")));
   EXPECT_FALSE(empty.Contains(NS_LITERAL_STRING("c1")));
+  EXPECT_FALSE(empty.ContainsPrefix(NS_LITERAL_STRING("")));
+  EXPECT_FALSE(empty.ContainsPrefix(NS_LITERAL_STRING("c1")));
   int iterations = 0;
   for (const auto& codec : empty.Range()) {
     ++iterations;
     Unused << codec;
   }
   EXPECT_EQ(0, iterations);
 
   MediaCodecs space(" ");
   EXPECT_FALSE(space.IsEmpty());
   EXPECT_TRUE(space.AsString().EqualsLiteral(" "));
   EXPECT_TRUE(space.Contains(NS_LITERAL_STRING("")));
   EXPECT_FALSE(space.Contains(NS_LITERAL_STRING("c1")));
+  EXPECT_TRUE(space.ContainsPrefix(NS_LITERAL_STRING("")));
+  EXPECT_FALSE(space.ContainsPrefix(NS_LITERAL_STRING("c")));
+  EXPECT_FALSE(space.ContainsPrefix(NS_LITERAL_STRING("c1")));
   iterations = 0;
   for (const auto& codec : space.Range()) {
     ++iterations;
     EXPECT_TRUE(codec.IsEmpty());
   }
   EXPECT_EQ(1, iterations);
 
   MediaCodecs one(" c1 ");
   EXPECT_FALSE(one.IsEmpty());
   EXPECT_TRUE(one.AsString().EqualsLiteral(" c1 "));
   EXPECT_FALSE(one.Contains(NS_LITERAL_STRING("")));
   EXPECT_TRUE(one.Contains(NS_LITERAL_STRING("c1")));
+  EXPECT_TRUE(one.ContainsPrefix(NS_LITERAL_STRING("")));
+  EXPECT_TRUE(one.ContainsPrefix(NS_LITERAL_STRING("c")));
+  EXPECT_TRUE(one.ContainsPrefix(NS_LITERAL_STRING("c1")));
+  EXPECT_FALSE(one.ContainsPrefix(NS_LITERAL_STRING("c1x")));
+  EXPECT_FALSE(one.ContainsPrefix(NS_LITERAL_STRING("c1 ")));
   iterations = 0;
   for (const auto& codec : one.Range()) {
     ++iterations;
     EXPECT_TRUE(codec.EqualsLiteral("c1"));
   }
   EXPECT_EQ(1, iterations);
 
   MediaCodecs two(" c1 , c2 ");
   EXPECT_FALSE(two.IsEmpty());
   EXPECT_TRUE(two.AsString().EqualsLiteral(" c1 , c2 "));
   EXPECT_FALSE(two.Contains(NS_LITERAL_STRING("")));
   EXPECT_TRUE(two.Contains(NS_LITERAL_STRING("c1")));
   EXPECT_TRUE(two.Contains(NS_LITERAL_STRING("c2")));
+  EXPECT_TRUE(two.ContainsPrefix(NS_LITERAL_STRING("")));
+  EXPECT_TRUE(two.ContainsPrefix(NS_LITERAL_STRING("c")));
+  EXPECT_FALSE(two.ContainsPrefix(NS_LITERAL_STRING("1")));
+  EXPECT_TRUE(two.ContainsPrefix(NS_LITERAL_STRING("c1")));
+  EXPECT_TRUE(two.ContainsPrefix(NS_LITERAL_STRING("c2")));
+  EXPECT_FALSE(two.ContainsPrefix(NS_LITERAL_STRING("c1x")));
+  EXPECT_FALSE(two.ContainsPrefix(NS_LITERAL_STRING("c2x")));
   iterations = 0;
   for (const auto& codec : two.Range()) {
     ++iterations;
     char buffer[] = "c0";
     buffer[1] += iterations;
     EXPECT_TRUE(codec.EqualsASCII(buffer));
   }
   EXPECT_EQ(2, iterations);
@@ -224,16 +241,21 @@ TEST(MediaMIMETypes, MediaExtendedMIMETy
     MakeMediaExtendedMIMEType(
       "video/mp4; codecs=\"a,b\"; width=1024; Height=768; FrameRate=60; BITRATE=100000");
   EXPECT_TRUE(type->HaveCodecs());
   EXPECT_FALSE(type->Codecs().IsEmpty());
   EXPECT_TRUE(type->Codecs().AsString().EqualsASCII("a,b"));
   EXPECT_TRUE(type->Codecs() == "a,b");
   EXPECT_TRUE(type->Codecs().Contains(NS_LITERAL_STRING("a")));
   EXPECT_TRUE(type->Codecs().Contains(NS_LITERAL_STRING("b")));
+  EXPECT_TRUE(type->Codecs().ContainsPrefix(NS_LITERAL_STRING("a")));
+  EXPECT_TRUE(type->Codecs().ContainsPrefix(NS_LITERAL_STRING("b")));
+  EXPECT_FALSE(type->Codecs().ContainsPrefix(NS_LITERAL_STRING("ab")));
+  EXPECT_FALSE(type->Codecs().ContainsPrefix(NS_LITERAL_STRING("ba")));
+  EXPECT_FALSE(type->Codecs().ContainsPrefix(NS_LITERAL_STRING("a,b")));
   EXPECT_TRUE(!!type->GetWidth());
   EXPECT_EQ(1024, *type->GetWidth());
   EXPECT_TRUE(!!type->GetHeight());
   EXPECT_EQ(768, *type->GetHeight());
   EXPECT_TRUE(!!type->GetFramerate());
   EXPECT_EQ(60, *type->GetFramerate());
   EXPECT_TRUE(!!type->GetBitrate());
   EXPECT_EQ(100000, *type->GetBitrate());