Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / media / formats / mp4 / avc_unittest.cc
index 96a8a97..b0aa976 100644 (file)
@@ -119,27 +119,42 @@ static void WriteStartCodeAndNALUType(std::vector<uint8>* buffer,
   buffer->push_back(StringToNALUType(nal_unit_type));
 }
 
+// Input string should be one or more NALU types separated with spaces or
+// commas. NALU grouped together and separated by commas are placed into the
+// same subsample, NALU groups separated by spaces are placed into separate
+// subsamples.
+// For example: input string "SPS PPS I" produces Annex B buffer containing
+// SPS, PPS and I NALUs, each in a separate subsample. While input string
+// "SPS,PPS I" produces Annex B buffer where the first subsample contains SPS
+// and PPS NALUs and the second subsample contains the I-slice NALU.
+// The output buffer will contain a valid-looking Annex B (it's valid-looking in
+// the sense that it has start codes and correct NALU types, but the actual NALU
+// payload is junk).
 void StringToAnnexB(const std::string& str, std::vector<uint8>* buffer,
                     std::vector<SubsampleEntry>* subsamples) {
   DCHECK(!str.empty());
 
-  std::vector<std::string> tokens;
-  EXPECT_GT(Tokenize(str, " ", &tokens), 0u);
+  std::vector<std::string> subsample_specs;
+  EXPECT_GT(Tokenize(str, " ", &subsample_specs), 0u);
 
   buffer->clear();
-  for (size_t i = 0; i < tokens.size(); ++i) {
+  for (size_t i = 0; i < subsample_specs.size(); ++i) {
     SubsampleEntry entry;
     size_t start = buffer->size();
 
-    WriteStartCodeAndNALUType(buffer, tokens[i]);
+    std::vector<std::string> subsample_nalus;
+    EXPECT_GT(Tokenize(subsample_specs[i], ",", &subsample_nalus), 0u);
+    for (size_t j = 0; j < subsample_nalus.size(); ++j) {
+      WriteStartCodeAndNALUType(buffer, subsample_nalus[j]);
 
-    entry.clear_bytes = buffer->size() - start;
+      // Write junk for the payload since the current code doesn't
+      // actually look at it.
+      buffer->push_back(0x32);
+      buffer->push_back(0x12);
+      buffer->push_back(0x67);
+    }
 
-    // Write junk for the payload since the current code doesn't
-    // actually look at it.
-    buffer->push_back(0x32);
-    buffer->push_back(0x12);
-    buffer->push_back(0x67);
+    entry.clear_bytes = buffer->size() - start;
 
     if (subsamples) {
       // Simulate the encrypted bits containing something that looks
@@ -164,13 +179,19 @@ std::string AnnexBToString(const std::vector<uint8>& buffer,
 
   H264NALU nalu;
   bool first = true;
+  size_t current_subsample_index = 0;
   while (parser.AdvanceToNextNALU(&nalu) == H264Parser::kOk) {
-    if (!first)
-      ss << " ";
-    else
+    size_t subsample_index = AVC::FindSubsampleIndex(buffer, &subsamples,
+                                                     nalu.data);
+    if (!first) {
+      ss << (subsample_index == current_subsample_index ? "," : " ");
+    } else {
+      DCHECK_EQ(subsample_index, current_subsample_index);
       first = false;
+    }
 
     ss << NALUTypeToString(nalu.nal_unit_type);
+    current_subsample_index = subsample_index;
   }
   return ss.str();
 }
@@ -206,7 +227,7 @@ TEST_P(AVCConversionTest, ParseCorrectly) {
   EXPECT_TRUE(AVC::IsValidAnnexB(buf, subsamples));
   EXPECT_EQ(buf.size(), sizeof(kExpected));
   EXPECT_EQ(0, memcmp(kExpected, &buf[0], sizeof(kExpected)));
-  EXPECT_EQ("P SDC", AnnexBToString(buf, subsamples));
+  EXPECT_EQ("P,SDC", AnnexBToString(buf, subsamples));
 }
 
 // Intentionally write NALU sizes that are larger than the buffer.
@@ -270,10 +291,10 @@ TEST_F(AVCConversionTest, ConvertConfigToAnnexB) {
 
   std::vector<uint8> buf;
   std::vector<SubsampleEntry> subsamples;
-  EXPECT_TRUE(AVC::ConvertConfigToAnnexB(avc_config, &buf, &subsamples));
+  EXPECT_TRUE(AVC::ConvertConfigToAnnexB(avc_config, &buf));
   EXPECT_EQ(0, memcmp(kExpectedParamSets, &buf[0],
                       sizeof(kExpectedParamSets)));
-  EXPECT_EQ("SPS SPS PPS", AnnexBToString(buf, subsamples));
+  EXPECT_EQ("SPS,SPS,PPS", AnnexBToString(buf, subsamples));
 }
 
 // Verify that we can round trip string -> Annex B -> string.
@@ -304,6 +325,9 @@ TEST_F(AVCConversionTest, ValidAnnexBConstructs) {
     "SEI SEI R14 I",
     "SPS SPSExt SPS PPS I P",
     "R14 SEI I",
+    "AUD,I",
+    "AUD,SEI I",
+    "AUD,SEI,SPS,PPS,I"
   };
 
   for (size_t i = 0; i < arraysize(test_cases); ++i) {
@@ -318,6 +342,7 @@ TEST_F(AVCConversionTest, ValidAnnexBConstructs) {
 TEST_F(AVCConversionTest, InvalidAnnexBConstructs) {
   static const char* test_cases[] = {
     "AUD",  // No VCL present.
+    "AUD,SEI", // No VCL present.
     "SPS PPS",  // No VCL present.
     "SPS PPS AUD I",  // Parameter sets must come after AUD.
     "SPSExt SPS P",  // SPS must come before SPSExt.
@@ -346,14 +371,18 @@ typedef struct {
 
 TEST_F(AVCConversionTest, InsertParamSetsAnnexB) {
   static const InsertTestCases test_cases[] = {
-    { "I", "SPS SPS PPS I" },
-    { "AUD I", "AUD SPS SPS PPS I" },
+    { "I", "SPS,SPS,PPS,I" },
+    { "AUD I", "AUD SPS,SPS,PPS,I" },
 
     // Cases where param sets in |avc_config| are placed before
     // the existing ones.
-    { "SPS PPS I", "SPS SPS PPS SPS PPS I" },
-    { "AUD SPS PPS I", "AUD SPS SPS PPS SPS PPS I" },  // Note: params placed
+    { "SPS,PPS,I", "SPS,SPS,PPS,SPS,PPS,I" },
+    { "AUD,SPS,PPS,I", "AUD,SPS,SPS,PPS,SPS,PPS,I" },  // Note: params placed
                                                        // after AUD.
+
+    // One or more NALUs might follow AUD in the first subsample, we need to
+    // handle this correctly. Params should be inserted right after AUD.
+    { "AUD,SEI I", "AUD,SPS,SPS,PPS,SEI I" },
   };
 
   AVCDecoderConfigurationRecord avc_config;