Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(188)

Side by Side Diff: media/formats/mp4/avc_unittest.cc

Issue 626193003: Implement extended syntax for AVC/h264 unit tests (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <string.h> 5 #include <string.h>
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/strings/string_util.h" 8 #include "base/strings/string_util.h"
9 #include "media/base/decrypt_config.h" 9 #include "media/base/decrypt_config.h"
10 #include "media/base/stream_parser_buffer.h" 10 #include "media/base/stream_parser_buffer.h"
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 112
113 static void WriteStartCodeAndNALUType(std::vector<uint8>* buffer, 113 static void WriteStartCodeAndNALUType(std::vector<uint8>* buffer,
114 const std::string& nal_unit_type) { 114 const std::string& nal_unit_type) {
115 buffer->push_back(0x00); 115 buffer->push_back(0x00);
116 buffer->push_back(0x00); 116 buffer->push_back(0x00);
117 buffer->push_back(0x00); 117 buffer->push_back(0x00);
118 buffer->push_back(0x01); 118 buffer->push_back(0x01);
119 buffer->push_back(StringToNALUType(nal_unit_type)); 119 buffer->push_back(StringToNALUType(nal_unit_type));
120 } 120 }
121 121
122 void StringToAnnexB(const std::string& str, std::vector<uint8>* buffer, 122 void StringToAnnexB(const std::string& str, std::vector<uint8>* buffer,
wolenetz 2014/10/07 23:37:40 nit: Document the format of |str| in method commen
servolk 2014/10/07 23:57:19 Done.
123 std::vector<SubsampleEntry>* subsamples) { 123 std::vector<SubsampleEntry>* subsamples) {
124 DCHECK(!str.empty()); 124 DCHECK(!str.empty());
125 125
126 std::vector<std::string> tokens; 126 std::vector<std::string> tokens;
wolenetz 2014/10/07 23:37:40 nit: s/tokens/subsample_specs/
servolk 2014/10/07 23:57:18 Done.
127 EXPECT_GT(Tokenize(str, " ", &tokens), 0u); 127 EXPECT_GT(Tokenize(str, " ", &tokens), 0u);
128 128
129 buffer->clear(); 129 buffer->clear();
130 for (size_t i = 0; i < tokens.size(); ++i) { 130 for (size_t i = 0; i < tokens.size(); ++i) {
131 SubsampleEntry entry; 131 SubsampleEntry entry;
132 size_t start = buffer->size(); 132 size_t start = buffer->size();
133 133
134 WriteStartCodeAndNALUType(buffer, tokens[i]); 134 std::vector<std::string> subsample_nalus;
135 EXPECT_GT(Tokenize(tokens[i], ",", &subsample_nalus), 0u);
136 for (size_t j = 0; j < subsample_nalus.size(); ++j) {
137 WriteStartCodeAndNALUType(buffer, subsample_nalus[j]);
138
139 // Write junk for the payload since the current code doesn't
140 // actually look at it.
141 buffer->push_back(0x32);
142 buffer->push_back(0x12);
143 buffer->push_back(0x67);
144 }
135 145
136 entry.clear_bytes = buffer->size() - start; 146 entry.clear_bytes = buffer->size() - start;
137 147
138 // Write junk for the payload since the current code doesn't
139 // actually look at it.
140 buffer->push_back(0x32);
141 buffer->push_back(0x12);
142 buffer->push_back(0x67);
143
144 if (subsamples) { 148 if (subsamples) {
145 // Simulate the encrypted bits containing something that looks 149 // Simulate the encrypted bits containing something that looks
146 // like a SPS NALU. 150 // like a SPS NALU.
147 WriteStartCodeAndNALUType(buffer, "SPS"); 151 WriteStartCodeAndNALUType(buffer, "SPS");
148 } 152 }
149 153
150 entry.cypher_bytes = buffer->size() - start - entry.clear_bytes; 154 entry.cypher_bytes = buffer->size() - start - entry.clear_bytes;
151 155
152 if (subsamples) { 156 if (subsamples) {
153 subsamples->push_back(entry); 157 subsamples->push_back(entry);
154 } 158 }
155 } 159 }
156 } 160 }
157 161
162 int FindSubsampleIndex(const std::vector<uint8>& buffer,
163 const std::vector<SubsampleEntry>* subsamples,
164 const uint8* ptr) {
165 DCHECK(ptr >= &buffer[0]);
166 DCHECK(ptr <= &buffer[buffer.size()-1]);
167 if (!subsamples || subsamples->empty())
168 return 0;
169
170 const uint8* p = &buffer[0];
171 for (size_t i = 0; i < subsamples->size(); ++i) {
172 p += (*subsamples)[i].clear_bytes + (*subsamples)[i].cypher_bytes;
173 if (p > ptr) {
174 return i;
175 }
176 }
177 DCHECK(false);
wolenetz 2014/10/07 23:37:39 nit: NOTREACHED();
servolk 2014/10/07 23:57:18 Done.
178 return 0;
179 }
180
158 std::string AnnexBToString(const std::vector<uint8>& buffer, 181 std::string AnnexBToString(const std::vector<uint8>& buffer,
159 const std::vector<SubsampleEntry>& subsamples) { 182 const std::vector<SubsampleEntry>& subsamples) {
160 std::stringstream ss; 183 std::stringstream ss;
161 184
162 H264Parser parser; 185 H264Parser parser;
163 parser.SetEncryptedStream(&buffer[0], buffer.size(), subsamples); 186 parser.SetEncryptedStream(&buffer[0], buffer.size(), subsamples);
164 187
165 H264NALU nalu; 188 H264NALU nalu;
166 bool first = true; 189 bool first = true;
190 size_t current_subsample = 0;
wolenetz 2014/10/07 23:37:39 nit: s/ple/ple_index/
servolk 2014/10/07 23:57:19 Done.
167 while (parser.AdvanceToNextNALU(&nalu) == H264Parser::kOk) { 191 while (parser.AdvanceToNextNALU(&nalu) == H264Parser::kOk) {
192 size_t subsample = FindSubsampleIndex(buffer, &subsamples, nalu.data);
wolenetz 2014/10/07 23:37:39 nit: ditto
servolk 2014/10/07 23:57:18 Done.
168 if (!first) 193 if (!first)
169 ss << " "; 194 ss << (subsample == current_subsample ? "," : " ");
170 else 195 else
171 first = false; 196 first = false;
wolenetz 2014/10/07 23:37:39 nit: maybe add a DCHECK_EQ(subsample_index, curren
servolk 2014/10/07 23:57:19 Done.
172 197
173 ss << NALUTypeToString(nalu.nal_unit_type); 198 ss << NALUTypeToString(nalu.nal_unit_type);
199 current_subsample = subsample;
174 } 200 }
175 return ss.str(); 201 return ss.str();
176 } 202 }
177 203
178 class AVCConversionTest : public testing::TestWithParam<int> { 204 class AVCConversionTest : public testing::TestWithParam<int> {
179 protected: 205 protected:
180 void WriteLength(int length_size, int length, std::vector<uint8>* buf) { 206 void WriteLength(int length_size, int length, std::vector<uint8>* buf) {
181 DCHECK_GE(length, 0); 207 DCHECK_GE(length, 0);
182 DCHECK_LE(length, 255); 208 DCHECK_LE(length, 255);
183 209
(...skipping 15 matching lines...) Expand all
199 }; 225 };
200 226
201 TEST_P(AVCConversionTest, ParseCorrectly) { 227 TEST_P(AVCConversionTest, ParseCorrectly) {
202 std::vector<uint8> buf; 228 std::vector<uint8> buf;
203 std::vector<SubsampleEntry> subsamples; 229 std::vector<SubsampleEntry> subsamples;
204 MakeInputForLength(GetParam(), &buf); 230 MakeInputForLength(GetParam(), &buf);
205 EXPECT_TRUE(AVC::ConvertFrameToAnnexB(GetParam(), &buf)); 231 EXPECT_TRUE(AVC::ConvertFrameToAnnexB(GetParam(), &buf));
206 EXPECT_TRUE(AVC::IsValidAnnexB(buf, subsamples)); 232 EXPECT_TRUE(AVC::IsValidAnnexB(buf, subsamples));
207 EXPECT_EQ(buf.size(), sizeof(kExpected)); 233 EXPECT_EQ(buf.size(), sizeof(kExpected));
208 EXPECT_EQ(0, memcmp(kExpected, &buf[0], sizeof(kExpected))); 234 EXPECT_EQ(0, memcmp(kExpected, &buf[0], sizeof(kExpected)));
209 EXPECT_EQ("P SDC", AnnexBToString(buf, subsamples)); 235 EXPECT_EQ("P,SDC", AnnexBToString(buf, subsamples));
210 } 236 }
211 237
212 // Intentionally write NALU sizes that are larger than the buffer. 238 // Intentionally write NALU sizes that are larger than the buffer.
213 TEST_P(AVCConversionTest, NALUSizeTooLarge) { 239 TEST_P(AVCConversionTest, NALUSizeTooLarge) {
214 std::vector<uint8> buf; 240 std::vector<uint8> buf;
215 WriteLength(GetParam(), 10 * sizeof(kNALU1), &buf); 241 WriteLength(GetParam(), 10 * sizeof(kNALU1), &buf);
216 buf.insert(buf.end(), kNALU1, kNALU1 + sizeof(kNALU1)); 242 buf.insert(buf.end(), kNALU1, kNALU1 + sizeof(kNALU1));
217 EXPECT_FALSE(AVC::ConvertFrameToAnnexB(GetParam(), &buf)); 243 EXPECT_FALSE(AVC::ConvertFrameToAnnexB(GetParam(), &buf));
218 } 244 }
219 245
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 "I EOSeq", 323 "I EOSeq",
298 "I EOSeq EOStr", 324 "I EOSeq EOStr",
299 "I EOStr", 325 "I EOStr",
300 "P", 326 "P",
301 "P P P P", 327 "P P P P",
302 "AUD SPS PPS P", 328 "AUD SPS PPS P",
303 "SEI SEI I", 329 "SEI SEI I",
304 "SEI SEI R14 I", 330 "SEI SEI R14 I",
305 "SPS SPSExt SPS PPS I P", 331 "SPS SPSExt SPS PPS I P",
306 "R14 SEI I", 332 "R14 SEI I",
333 "AUD,I",
334 "AUD,SEI I",
335 "AUD,SEI,SPS,PPS,I"
307 }; 336 };
308 337
309 for (size_t i = 0; i < arraysize(test_cases); ++i) { 338 for (size_t i = 0; i < arraysize(test_cases); ++i) {
310 std::vector<uint8> buf; 339 std::vector<uint8> buf;
311 std::vector<SubsampleEntry> subsamples; 340 std::vector<SubsampleEntry> subsamples;
312 StringToAnnexB(test_cases[i], &buf, NULL); 341 StringToAnnexB(test_cases[i], &buf, NULL);
313 EXPECT_TRUE(AVC::IsValidAnnexB(buf, subsamples)) << "'" << test_cases[i] 342 EXPECT_TRUE(AVC::IsValidAnnexB(buf, subsamples)) << "'" << test_cases[i]
314 << "' failed"; 343 << "' failed";
315 } 344 }
316 } 345 }
317 346
318 TEST_F(AVCConversionTest, InvalidAnnexBConstructs) { 347 TEST_F(AVCConversionTest, InvalidAnnexBConstructs) {
319 static const char* test_cases[] = { 348 static const char* test_cases[] = {
320 "AUD", // No VCL present. 349 "AUD", // No VCL present.
350 "AUD,SEI", // No VCL present.
321 "SPS PPS", // No VCL present. 351 "SPS PPS", // No VCL present.
322 "SPS PPS AUD I", // Parameter sets must come after AUD. 352 "SPS PPS AUD I", // Parameter sets must come after AUD.
323 "SPSExt SPS P", // SPS must come before SPSExt. 353 "SPSExt SPS P", // SPS must come before SPSExt.
324 "SPS PPS SPSExt P", // SPSExt must follow an SPS. 354 "SPS PPS SPSExt P", // SPSExt must follow an SPS.
325 "EOSeq", // EOSeq must come after a VCL. 355 "EOSeq", // EOSeq must come after a VCL.
326 "EOStr", // EOStr must come after a VCL. 356 "EOStr", // EOStr must come after a VCL.
327 "I EOStr EOSeq", // EOSeq must come before EOStr. 357 "I EOStr EOSeq", // EOSeq must come before EOStr.
328 "I R14", // Reserved14-18 must come before first VCL. 358 "I R14", // Reserved14-18 must come before first VCL.
329 "I SEI", // SEI must come before first VCL. 359 "I SEI", // SEI must come before first VCL.
330 "P SPS P", // SPS after first VCL would indicate a new access unit. 360 "P SPS P", // SPS after first VCL would indicate a new access unit.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 << "'" << test_cases[i].input << "' insert failed."; 407 << "'" << test_cases[i].input << "' insert failed.";
378 EXPECT_TRUE(AVC::IsValidAnnexB(buf, subsamples)) 408 EXPECT_TRUE(AVC::IsValidAnnexB(buf, subsamples))
379 << "'" << test_cases[i].input << "' created invalid AnnexB."; 409 << "'" << test_cases[i].input << "' created invalid AnnexB.";
380 EXPECT_EQ(test_cases[i].expected, AnnexBToString(buf, subsamples)) 410 EXPECT_EQ(test_cases[i].expected, AnnexBToString(buf, subsamples))
381 << "'" << test_cases[i].input << "' generated unexpected output."; 411 << "'" << test_cases[i].input << "' generated unexpected output.";
382 } 412 }
383 } 413 }
384 414
385 } // namespace mp4 415 } // namespace mp4
386 } // namespace media 416 } // namespace media
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698