Chromium Code Reviews| Index: media/base/container_names_unittest.cc |
| diff --git a/media/base/container_names_unittest.cc b/media/base/container_names_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..78fa3334ebe1b06963f489ba9f2ebbb4fb20d565 |
| --- /dev/null |
| +++ b/media/base/container_names_unittest.cc |
| @@ -0,0 +1,222 @@ |
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "base/stringprintf.h" |
| +#include "media/base/container_names.h" |
| +#include "media/base/test_data_util.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +namespace media { |
| + |
| +// Template to extract array size. |
| +template <typename T, size_t N> inline size_t size(T(&)[N]) { return N; } |
|
xhwang
2013/04/29 21:00:25
Can you use arraysize directly?
https://code.goo
jrummell
2013/04/30 21:36:50
Done.
|
| + |
| +#define BOM "\xef\xbb\xbf" |
|
xhwang
2013/04/29 21:00:25
what is BOM? Use a more readable name? Or add a co
jrummell
2013/04/30 21:36:50
Done.
|
| + |
| +// Test that the names are in the correct sorted order. |
| +TEST(ContainerNamesTest, CheckSortOrder) { |
| + for (size_t i = 1; i < size(ContainerNames::container_name_mapping); ++i) { |
| + ASSERT_LT(strcmp(ContainerNames::container_name_mapping[i - 1].name, |
|
xhwang
2013/04/29 21:00:25
Use base::strcasecmp ?
https://code.google.com/p/
jrummell
2013/04/30 21:36:50
Done. Also in container_names.cc.
|
| + ContainerNames::container_name_mapping[i].name), |
| + 0) |
| + << ContainerNames::container_name_mapping[i - 1].name << " and " |
| + << ContainerNames::container_name_mapping[i].name |
| + << " are in the wrong order."; |
| + } |
| +} |
| + |
| +// Test that string lookup works for all names in the list. |
| +TEST(ContainerNamesTest, NameLookup) { |
| + ContainerNames cont; |
| + |
| + // Search for all strings. |
| + for (size_t i = 0; i < size(ContainerNames::container_name_mapping); ++i) { |
| + const char* name = ContainerNames::container_name_mapping[i].name; |
| + ASSERT_EQ(ContainerNames::container_name_mapping[i].id, |
| + cont.LookupContainer(name)) << "Unable to lookup " << name; |
| + } |
| + |
| + // Check that some name not in the list fails. |
| + ASSERT_EQ(CONTAINER_UNKNOWN, cont.LookupContainer("foo")); |
| +} |
| + |
| +// Test that small buffers are handled correctly. |
| +TEST(ContainerNamesTest, CheckSmallBufferSize) { |
| + ContainerNames container; |
| + |
| + // Empty buffer. |
| + uint8_t buffer[0]; |
| + EXPECT_EQ(CONTAINER_UNKNOWN, container.LookupContainer(buffer, 0)); |
| + |
| + // Try a simple string |
| + const char buffer1[] = "******** START SCRIPT ********"; |
| + EXPECT_EQ(CONTAINER_SUBVIEWER1, |
| + container.LookupContainer((uint8_t*)buffer1, strlen(buffer1))); |
| + |
| + // Try adding BOM. |
| + const char buffer2[] = "\xef\xbb\xbf" |
| + "Interplay MVE File\x1A\x00\x1A"; |
| + EXPECT_EQ(CONTAINER_IPMOVIE, |
| + container.LookupContainer((uint8_t*)buffer2, 24)); |
| + // Repeat but leave out a character (so it won't match) |
| + EXPECT_EQ(CONTAINER_UNKNOWN, |
| + container.LookupContainer((uint8_t*)buffer2, 23)); |
| + |
| + // Try a simple SRT file. |
| + const char buffer3[] = |
| + "1\n" |
| + "00:03:23,550 --> 00:03:24,375\n" |
| + "You always had a hard time finding your place in this world.\n" |
| + "\n" |
| + "2\n" |
| + "00:03:24,476 --> 00:03:25,175\n" |
| + "What are you talking about?\n"; |
| + EXPECT_EQ(CONTAINER_SRT, |
| + container.LookupContainer((uint8_t*)buffer3, strlen(buffer3))); |
| + |
| + // Try a simple tag. Note that the tag checking requires |
| + // at least 128 characters. |
| + const char buffer4[256] = ".snd"; |
| + EXPECT_EQ(CONTAINER_AU, |
| + container.LookupContainer((uint8_t*)buffer4, sizeof(buffer4))); |
| + |
| + // HLS has it's own loop, so try it |
| + const char buffer5[256] = "#EXTM3U" |
| + "some other random stuff" |
| + "#EXT-X-MEDIA-SEQUENCE:"; |
| + EXPECT_EQ(CONTAINER_HLS, |
| + container.LookupContainer((uint8_t*)buffer5, sizeof(buffer5))); |
| + |
| + // PJS has several loops, so try it |
| + const char buffer6[256] = "1234567890,123456,0\n" |
| + "some filler\n" |
| + "\"quoted string\"\n"; |
| + EXPECT_EQ(CONTAINER_PJS, |
| + container.LookupContainer((uint8_t*)buffer6, sizeof(buffer6))); |
| + |
| + // try a large buffer all 0 |
| + char buffer7[4096]; |
| + memset(buffer7, 0, sizeof(buffer7)); |
| + EXPECT_EQ(CONTAINER_UNKNOWN, |
| + container.LookupContainer((uint8_t*)buffer7, sizeof(buffer7))); |
| + |
| + // reuse buffer, but all \n this time |
| + memset(buffer7, '\n', sizeof(buffer7)); |
| + EXPECT_EQ(CONTAINER_UNKNOWN, |
| + container.LookupContainer((uint8_t*)buffer7, sizeof(buffer7))); |
| +} |
| + |
| +typedef struct Mapping { |
| + enum FFmpegContainerName id; |
| + int length; |
| + const char* name; |
| +} Mapping; |
| + |
| +// The following are the fixed strings compared in ContainerNames. |
| +// Since the first 4 characters are used as a TAG, this checks that the |
| +// TAG is defined correctly. |
| +const Mapping fixed_strings[] = { |
| + { CONTAINER_AMR, 0, "#!AMR" }, |
| + { CONTAINER_APC, 0, "CRYO_APC" }, |
| + { CONTAINER_AQTITLE, 0, "-->> 23" }, |
| + { CONTAINER_ASF, 16, "\x30\x26\xb2\x75\x8e\x66\xcf\x11\xa6\xd9\x00" |
| + "\xaa\x00\x62\xce\x6c" }, |
| + { CONTAINER_ASS, 0, "[Script Info]" }, |
| + { CONTAINER_ASS, 0, BOM "[Script Info]" }, |
| + { CONTAINER_CONCAT, 0, "ffconcat version 1.0" }, |
| + { CONTAINER_DNXHD, 43, "\x00\x00\x02\x80\x01 789*123456789*123456789" |
| + "*123456789*\x04\xd3" }, |
| + { CONTAINER_FFMETADATA, 0, ";FFMETADATA" }, |
| + { CONTAINER_IDF, 12, "\x04\x31\x2e\x34\x00\x00\x00\x00\x4f\x00\x15" |
| + "\x00" }, |
| + { CONTAINER_ILBC, 0, "#!iLBC" }, |
| + { CONTAINER_ISS, 0, "IMA_ADPCM_Sound" }, |
| + { CONTAINER_IV8, 0, "\x01\x01\x03\xb8\x80\x60" }, |
| + { CONTAINER_JV, 0, "JVxx Compression by John M Phillips Copyright " |
| + "(C) 1995 The Bitmap Brothers Ltd." }, |
| + { CONTAINER_LIBNUT, 0, "nut/multimedia container" }, |
| + { CONTAINER_LXF, 8, "LEITCH\x00\x00" }, |
| + { CONTAINER_NUV, 0, "NuppelVideo" }, |
| + { CONTAINER_NUV, 0, "MythTVVideo" }, |
| + { CONTAINER_PAF, 0, "Packed Animation File V1.0\n(c) 1992-96 " |
| + "Amazing Studio\x0a\x1a" }, |
| + { CONTAINER_REALTEXT, 0, "<window" }, |
| + { CONTAINER_REALTEXT, 0, BOM "<window" }, |
| + { CONTAINER_RPL, 0, "ARMovie\x0A" }, |
| + { CONTAINER_SAMI, 0, "<SAMI>" }, |
| + { CONTAINER_SAMI, 0, BOM "<SAMI>" }, |
| + { CONTAINER_SMJPEG, 8, "\x00\x0aSMJPEG" }, |
| + { CONTAINER_VOBSUB, 0, "# VobSub index file," }, |
| + { CONTAINER_VOC, 0, "Creative Voice File\x1A" }, |
| + { CONTAINER_W64, 42, "riff\x2e\x91\xcf\x11\xa5\xd6\x28\xdb\x04\xc1" |
| + "\x00\x00 89*1234wave\xf3\xac\xd3\x11\x8c\xd1" |
| + "\x00\xc0\x4f\x8e\xdb\x8a" }, |
| + { CONTAINER_WEBVTT, 0, "WEBVTT" }, |
| + { CONTAINER_WEBVTT, 0, BOM "WEBVTT" }, |
| + { CONTAINER_WTV, 16, "\xb7\xd8\x00\x20\x37\x49\xda\x11\xa6\x4e\x00" |
| + "\x07\xe9\x5e\xad\x8d" }, |
| + { CONTAINER_YUV4MPEGPIPE, 0, "YUV4MPEG2" }, |
| + { CONTAINER_UNKNOWN, 0, "" } |
| +}; |
| + |
| +// Test that containers that start with fixed strings are handled correctly. |
| +// This is to verify that the TAG matches the first 4 characters of the string. |
| +TEST(ContainerNamesTest, CheckFixedStrings) { |
| + ContainerNames container; |
| + int index = 0; |
| + while (fixed_strings[index].id != CONTAINER_UNKNOWN) { |
| + char buffer[256]; |
| + int length = fixed_strings[index].length; |
| + if (length == 0) |
| + length = strlen(fixed_strings[index].name); |
| + memcpy(buffer, fixed_strings[index].name, length); |
| + // Put some random characters after the string. |
| + buffer[length] = 'a'; |
| + buffer[length + 1] = 'b'; |
| + EXPECT_EQ(fixed_strings[index].id, |
| + container.LookupContainer((uint8_t*)buffer, sizeof(buffer))); |
| + ++index; |
| + } |
| +} |
| + |
| +// Determine the container type of a specified file. |
| +FFmpegContainerName TestFile(const base::FilePath& filename) { |
| + // Open the file. |
| + FILE* f = fopen(filename.value().c_str(), "r"); |
| + EXPECT_NE(f, (FILE*)NULL); |
| + |
| + // Read the first few bytes. |
| + uint8_t buffer[8192]; |
| + size_t read = fread(buffer, sizeof(uint8_t), sizeof(buffer), f); |
| + |
| + // Now determine the type. |
| + ContainerNames container; |
| + return container.LookupContainer(buffer, read); |
| +} |
| + |
| +// Test several files to ensure that the container is detected properly. |
| +TEST(ContainerNamesTest, FileCheck) { |
| + EXPECT_EQ(CONTAINER_OGG, TestFile(GetTestDataFilePath("bear.ogv"))); |
| + EXPECT_EQ(CONTAINER_OGG, TestFile(GetTestDataFilePath("9ch.ogg"))); |
| + EXPECT_EQ(CONTAINER_WAV, TestFile(GetTestDataFilePath("4ch.wav"))); |
| + EXPECT_EQ(CONTAINER_WAV, TestFile(GetTestDataFilePath("sfx_f32le.wav"))); |
| + EXPECT_EQ(CONTAINER_WAV, TestFile(GetTestDataFilePath("sfx_s16le.wav"))); |
| + EXPECT_EQ(CONTAINER_MOV, TestFile(GetTestDataFilePath("bear-1280x720.mp4"))); |
| + EXPECT_EQ(CONTAINER_MOV, TestFile(GetTestDataFilePath("sfx.m4a"))); |
| + EXPECT_EQ(CONTAINER_WEBM, TestFile(GetTestDataFilePath("bear-320x240.webm"))); |
| + EXPECT_EQ(CONTAINER_MP3, TestFile(GetTestDataFilePath("id3_test.mp3"))); |
| + EXPECT_EQ(CONTAINER_MP3, TestFile(GetTestDataFilePath("sfx.mp3"))); |
| + |
| + // now try a few non containers |
| + EXPECT_EQ(CONTAINER_UNKNOWN, TestFile(GetTestDataFilePath("ten_byte_file"))); |
| + EXPECT_EQ(CONTAINER_UNKNOWN, TestFile(GetTestDataFilePath("README"))); |
| + EXPECT_EQ(CONTAINER_UNKNOWN, |
| + TestFile(GetTestDataFilePath("bali_640x360_P422.yuv"))); |
| + EXPECT_EQ(CONTAINER_UNKNOWN, |
| + TestFile(GetTestDataFilePath("bali_640x360_RGB24.rgb"))); |
| + EXPECT_EQ(CONTAINER_UNKNOWN, |
| + TestFile(GetTestDataFilePath("webm_vp8_track_entry"))); |
| +} |
| + |
| +} // namespace media |