OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 delete[] reference_frame; | 320 delete[] reference_frame; |
321 } | 321 } |
322 | 322 |
323 void PrintMaxRepeatedAndSkippedFrames(const std::string& label, | 323 void PrintMaxRepeatedAndSkippedFrames(const std::string& label, |
324 const std::string& stats_file_ref_name, | 324 const std::string& stats_file_ref_name, |
325 const std::string& stats_file_test_name) { | 325 const std::string& stats_file_test_name) { |
326 PrintMaxRepeatedAndSkippedFrames(stdout, label, stats_file_ref_name, | 326 PrintMaxRepeatedAndSkippedFrames(stdout, label, stats_file_ref_name, |
327 stats_file_test_name); | 327 stats_file_test_name); |
328 } | 328 } |
329 | 329 |
330 namespace { | 330 std::vector<std::pair<int, int> > CalculateFrameClusters( |
331 // Clusters the frames in the file. First in the pair is the frame number and | 331 FILE* file, |
332 // second is the number | 332 int* num_decode_errors) { |
333 // of frames in that cluster. So if first frame in video has number 100 and it | 333 if (num_decode_errors) { |
334 // is repeated 3 after | 334 *num_decode_errors = 0; |
335 // each other, then the first entry in the returned vector has first set to 100 | 335 } |
336 // and second set | |
337 // to 3. | |
338 std::vector<std::pair<int, int> > CalculateFrameClusters(FILE* file) { | |
339 std::vector<std::pair<int, int> > frame_cnt; | 336 std::vector<std::pair<int, int> > frame_cnt; |
340 char line[STATS_LINE_LENGTH]; | 337 char line[STATS_LINE_LENGTH]; |
341 while (GetNextStatsLine(file, line)) { | 338 while (GetNextStatsLine(file, line)) { |
342 int decoded_frame_number = ExtractDecodedFrameNumber(line); | 339 int decoded_frame_number; |
343 if (decoded_frame_number == -1) { | 340 if (IsThereBarcodeError(line)) { |
344 continue; | 341 decoded_frame_number = DECODE_ERROR; |
| 342 if (num_decode_errors) { |
| 343 ++*num_decode_errors; |
| 344 } |
| 345 } else { |
| 346 decoded_frame_number = ExtractDecodedFrameNumber(line); |
345 } | 347 } |
346 if (frame_cnt.empty() || frame_cnt.back().first != decoded_frame_number) { | 348 if (frame_cnt.size() >= 2 && decoded_frame_number != DECODE_ERROR && |
| 349 frame_cnt.back().first == DECODE_ERROR && |
| 350 frame_cnt[frame_cnt.size() - 2].first == decoded_frame_number) { |
| 351 // Handle when there is a decoding error inside a cluster of frames. |
| 352 frame_cnt[frame_cnt.size() - 2].second += frame_cnt.back().second + 1; |
| 353 frame_cnt.pop_back(); |
| 354 } else if (frame_cnt.empty() || |
| 355 frame_cnt.back().first != decoded_frame_number) { |
347 frame_cnt.push_back(std::make_pair(decoded_frame_number, 1)); | 356 frame_cnt.push_back(std::make_pair(decoded_frame_number, 1)); |
348 } else { | 357 } else { |
349 ++frame_cnt.back().second; | 358 ++frame_cnt.back().second; |
350 } | 359 } |
351 } | 360 } |
352 return frame_cnt; | 361 return frame_cnt; |
353 } | 362 } |
354 } // namespace | |
355 | 363 |
356 void PrintMaxRepeatedAndSkippedFrames(FILE* output, | 364 void PrintMaxRepeatedAndSkippedFrames(FILE* output, |
357 const std::string& label, | 365 const std::string& label, |
358 const std::string& stats_file_ref_name, | 366 const std::string& stats_file_ref_name, |
359 const std::string& stats_file_test_name) { | 367 const std::string& stats_file_test_name) { |
360 FILE* stats_file_ref = fopen(stats_file_ref_name.c_str(), "r"); | 368 FILE* stats_file_ref = fopen(stats_file_ref_name.c_str(), "r"); |
361 FILE* stats_file_test = fopen(stats_file_test_name.c_str(), "r"); | 369 FILE* stats_file_test = fopen(stats_file_test_name.c_str(), "r"); |
362 if (stats_file_ref == NULL) { | 370 if (stats_file_ref == NULL) { |
363 fprintf(stderr, "Couldn't open reference stats file for reading: %s\n", | 371 fprintf(stderr, "Couldn't open reference stats file for reading: %s\n", |
364 stats_file_ref_name.c_str()); | 372 stats_file_ref_name.c_str()); |
365 return; | 373 return; |
366 } | 374 } |
367 if (stats_file_test == NULL) { | 375 if (stats_file_test == NULL) { |
368 fprintf(stderr, "Couldn't open test stats file for reading: %s\n", | 376 fprintf(stderr, "Couldn't open test stats file for reading: %s\n", |
369 stats_file_test_name.c_str()); | 377 stats_file_test_name.c_str()); |
370 fclose(stats_file_ref); | 378 fclose(stats_file_ref); |
371 return; | 379 return; |
372 } | 380 } |
373 | 381 |
374 int max_repeated_frames = 1; | 382 int max_repeated_frames = 1; |
375 int max_skipped_frames = 1; | 383 int max_skipped_frames = 0; |
| 384 |
| 385 int decode_errors_ref = 0; |
| 386 int decode_errors_test = 0; |
376 | 387 |
377 std::vector<std::pair<int, int> > frame_cnt_ref = | 388 std::vector<std::pair<int, int> > frame_cnt_ref = |
378 CalculateFrameClusters(stats_file_ref); | 389 CalculateFrameClusters(stats_file_ref, &decode_errors_ref); |
379 | 390 |
380 std::vector<std::pair<int, int> > frame_cnt_test = | 391 std::vector<std::pair<int, int> > frame_cnt_test = |
381 CalculateFrameClusters(stats_file_test); | 392 CalculateFrameClusters(stats_file_test, &decode_errors_test); |
382 | 393 |
383 fclose(stats_file_ref); | 394 fclose(stats_file_ref); |
384 fclose(stats_file_test); | 395 fclose(stats_file_test); |
385 | 396 |
386 auto it_ref = frame_cnt_ref.begin(); | 397 auto it_ref = frame_cnt_ref.begin(); |
387 auto it_test = frame_cnt_test.begin(); | 398 auto it_test = frame_cnt_test.begin(); |
388 auto end_ref = frame_cnt_ref.end(); | 399 auto end_ref = frame_cnt_ref.end(); |
389 auto end_test = frame_cnt_test.end(); | 400 auto end_test = frame_cnt_test.end(); |
390 | 401 |
391 if (it_test == end_test || it_ref == end_ref) { | 402 if (it_test == end_test || it_ref == end_ref) { |
392 fprintf(stderr, "Either test or ref file is empty, nothing to print\n"); | 403 fprintf(stderr, "Either test or ref file is empty, nothing to print\n"); |
393 return; | 404 return; |
394 } | 405 } |
395 | 406 |
| 407 while (it_test != end_test && it_test->first == DECODE_ERROR) { |
| 408 ++it_test; |
| 409 } |
| 410 |
| 411 if (it_test == end_test) { |
| 412 fprintf(stderr, "Test video only has barcode decode errors\n"); |
| 413 return; |
| 414 } |
| 415 |
396 // Find the first frame in the reference video that match the first frame in | 416 // Find the first frame in the reference video that match the first frame in |
397 // the test video. | 417 // the test video. |
398 while (it_ref != end_ref && it_ref->first != it_test->first) { | 418 while (it_ref != end_ref && |
| 419 (it_ref->first == DECODE_ERROR || it_ref->first != it_test->first)) { |
399 ++it_ref; | 420 ++it_ref; |
400 } | 421 } |
401 if (it_ref == end_ref) { | 422 if (it_ref == end_ref) { |
402 fprintf(stderr, | 423 fprintf(stderr, |
403 "The barcode in the test video's first frame is not in the " | 424 "The barcode in the test video's first frame is not in the " |
404 "reference video.\n"); | 425 "reference video.\n"); |
405 return; | 426 return; |
406 } | 427 } |
407 | 428 |
| 429 int total_skipped_frames = 0; |
408 for (;;) { | 430 for (;;) { |
409 max_repeated_frames = | 431 max_repeated_frames = |
410 std::max(max_repeated_frames, it_test->second - it_ref->second + 1); | 432 std::max(max_repeated_frames, it_test->second - it_ref->second + 1); |
| 433 |
| 434 bool passed_error = false; |
| 435 |
411 ++it_test; | 436 ++it_test; |
| 437 while (it_test != end_test && it_test->first == DECODE_ERROR) { |
| 438 ++it_test; |
| 439 passed_error = true; |
| 440 } |
412 if (it_test == end_test) { | 441 if (it_test == end_test) { |
413 break; | 442 break; |
414 } | 443 } |
| 444 |
415 int skipped_frames = 0; | 445 int skipped_frames = 0; |
416 ++it_ref; | 446 ++it_ref; |
417 while (it_ref != end_ref && it_ref->first != it_test->first) { | 447 for (; it_ref != end_ref; ++it_ref) { |
418 skipped_frames += it_ref->second; | 448 if (it_ref->first != DECODE_ERROR && it_ref->first >= it_test->first) { |
419 ++it_ref; | 449 break; |
| 450 } |
| 451 ++skipped_frames; |
420 } | 452 } |
421 if (it_ref == end_ref) { | 453 if (passed_error) { |
422 fprintf(stderr, | 454 // If we pass an error in the test video, then we are conservative |
423 "The barcode in the test video is not in the reference video.\n"); | 455 // and will not calculate skipped frames for that part. |
424 return; | 456 skipped_frames = 0; |
425 } | 457 } |
426 if (skipped_frames > max_skipped_frames) { | 458 if (it_ref != end_ref && it_ref->first == it_test->first) { |
427 max_skipped_frames = skipped_frames; | 459 total_skipped_frames += skipped_frames; |
| 460 if (skipped_frames > max_skipped_frames) { |
| 461 max_skipped_frames = skipped_frames; |
| 462 } |
| 463 continue; |
428 } | 464 } |
| 465 fprintf(stderr, |
| 466 "Found barcode %d in test video, which is not in reference video", |
| 467 it_test->first); |
| 468 return; |
429 } | 469 } |
430 | 470 |
431 fprintf(output, "RESULT Max_repeated: %s= %d\n", label.c_str(), | 471 fprintf(output, "RESULT Max_repeated: %s= %d\n", label.c_str(), |
432 max_repeated_frames); | 472 max_repeated_frames); |
433 fprintf(output, "RESULT Max_skipped: %s= %d\n", label.c_str(), | 473 fprintf(output, "RESULT Max_skipped: %s= %d\n", label.c_str(), |
434 max_skipped_frames); | 474 max_skipped_frames); |
| 475 fprintf(output, "RESULT Total_skipped: %s= %d\n", label.c_str(), |
| 476 total_skipped_frames); |
| 477 fprintf(output, "RESULT Decode_errors_reference: %s= %d\n", label.c_str(), |
| 478 decode_errors_ref); |
| 479 fprintf(output, "RESULT Decode_errors_test: %s= %d\n", label.c_str(), |
| 480 decode_errors_test); |
435 } | 481 } |
436 | 482 |
437 void PrintAnalysisResults(const std::string& label, ResultsContainer* results) { | 483 void PrintAnalysisResults(const std::string& label, ResultsContainer* results) { |
438 PrintAnalysisResults(stdout, label, results); | 484 PrintAnalysisResults(stdout, label, results); |
439 } | 485 } |
440 | 486 |
441 void PrintAnalysisResults(FILE* output, const std::string& label, | 487 void PrintAnalysisResults(FILE* output, const std::string& label, |
442 ResultsContainer* results) { | 488 ResultsContainer* results) { |
443 std::vector<AnalysisResult>::iterator iter; | 489 std::vector<AnalysisResult>::iterator iter; |
444 | 490 |
(...skipping 12 matching lines...) Expand all Loading... |
457 for (iter = results->frames.begin(); iter != results->frames.end() - 1; | 503 for (iter = results->frames.begin(); iter != results->frames.end() - 1; |
458 ++iter) { | 504 ++iter) { |
459 fprintf(output, "%f,", iter->ssim_value); | 505 fprintf(output, "%f,", iter->ssim_value); |
460 } | 506 } |
461 fprintf(output, "%f] score\n", iter->ssim_value); | 507 fprintf(output, "%f] score\n", iter->ssim_value); |
462 } | 508 } |
463 } | 509 } |
464 | 510 |
465 } // namespace test | 511 } // namespace test |
466 } // namespace webrtc | 512 } // namespace webrtc |
OLD | NEW |