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
--- 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());