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 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 namespace { |
331 // The barcode number that means that the barcode could not be decoded. | |
332 const int DECODE_ERROR = -1; | |
333 | |
331 // Clusters the frames in the file. First in the pair is the frame number and | 334 // Clusters the frames in the file. First in the pair is the frame number and |
332 // second is the number | 335 // second is the number |
333 // of frames in that cluster. So if first frame in video has number 100 and it | 336 // of frames in that cluster. So if first frame in video has number 100 and it |
334 // is repeated 3 after | 337 // is repeated 3 after |
335 // each other, then the first entry in the returned vector has first set to 100 | 338 // each other, then the first entry in the returned vector has first set to 100 |
336 // and second set | 339 // and second set |
337 // to 3. | 340 // to 3. |
kjellander_webrtc
2017/02/08 12:39:34
Can you explain in the comment what happens if the
mandermo
2017/02/13 17:04:11
Added comment. Should I move CalculateFrameCluster
kjellander_webrtc
2017/02/14 20:55:58
Please do, I think that'll be very useful in the f
mandermo
2017/02/15 11:52:15
Done. Found I missed +1 when there are decode erro
| |
338 std::vector<std::pair<int, int> > CalculateFrameClusters(FILE* file) { | 341 std::vector<std::pair<int, int> > CalculateFrameClusters( |
342 FILE* file, | |
343 int* num_decode_errors) { | |
344 if (num_decode_errors) { | |
345 *num_decode_errors = 0; | |
346 } | |
339 std::vector<std::pair<int, int> > frame_cnt; | 347 std::vector<std::pair<int, int> > frame_cnt; |
340 char line[STATS_LINE_LENGTH]; | 348 char line[STATS_LINE_LENGTH]; |
341 while (GetNextStatsLine(file, line)) { | 349 while (GetNextStatsLine(file, line)) { |
342 int decoded_frame_number = ExtractDecodedFrameNumber(line); | 350 int decoded_frame_number; |
343 if (decoded_frame_number == -1) { | 351 if (IsThereBarcodeError(line)) { |
344 continue; | 352 decoded_frame_number = DECODE_ERROR; |
353 if (num_decode_errors) { | |
354 ++*num_decode_errors; | |
355 } | |
356 } else { | |
357 decoded_frame_number = ExtractDecodedFrameNumber(line); | |
345 } | 358 } |
346 if (frame_cnt.empty() || frame_cnt.back().first != decoded_frame_number) { | 359 if (frame_cnt.size() >= 2 && decoded_frame_number != DECODE_ERROR && |
360 frame_cnt.back().first == DECODE_ERROR && | |
361 frame_cnt[frame_cnt.size() - 2].first == decoded_frame_number) { | |
362 // Handle when there is a decoding error inside a cluster of frames. | |
363 frame_cnt[frame_cnt.size() - 2].second += frame_cnt.back().second; | |
364 frame_cnt.pop_back(); | |
365 } else if (frame_cnt.empty() || | |
366 frame_cnt.back().first != decoded_frame_number) { | |
347 frame_cnt.push_back(std::make_pair(decoded_frame_number, 1)); | 367 frame_cnt.push_back(std::make_pair(decoded_frame_number, 1)); |
348 } else { | 368 } else { |
349 ++frame_cnt.back().second; | 369 ++frame_cnt.back().second; |
350 } | 370 } |
351 } | 371 } |
352 return frame_cnt; | 372 return frame_cnt; |
353 } | 373 } |
354 } // namespace | 374 } // namespace |
355 | 375 |
356 void PrintMaxRepeatedAndSkippedFrames(FILE* output, | 376 void PrintMaxRepeatedAndSkippedFrames(FILE* output, |
357 const std::string& label, | 377 const std::string& label, |
358 const std::string& stats_file_ref_name, | 378 const std::string& stats_file_ref_name, |
359 const std::string& stats_file_test_name) { | 379 const std::string& stats_file_test_name) { |
360 FILE* stats_file_ref = fopen(stats_file_ref_name.c_str(), "r"); | 380 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"); | 381 FILE* stats_file_test = fopen(stats_file_test_name.c_str(), "r"); |
362 if (stats_file_ref == NULL) { | 382 if (stats_file_ref == NULL) { |
363 fprintf(stderr, "Couldn't open reference stats file for reading: %s\n", | 383 fprintf(stderr, "Couldn't open reference stats file for reading: %s\n", |
364 stats_file_ref_name.c_str()); | 384 stats_file_ref_name.c_str()); |
365 return; | 385 return; |
366 } | 386 } |
367 if (stats_file_test == NULL) { | 387 if (stats_file_test == NULL) { |
368 fprintf(stderr, "Couldn't open test stats file for reading: %s\n", | 388 fprintf(stderr, "Couldn't open test stats file for reading: %s\n", |
369 stats_file_test_name.c_str()); | 389 stats_file_test_name.c_str()); |
370 fclose(stats_file_ref); | 390 fclose(stats_file_ref); |
371 return; | 391 return; |
372 } | 392 } |
373 | 393 |
374 int max_repeated_frames = 1; | 394 int max_repeated_frames = 1; |
kjellander_webrtc
2017/02/08 12:39:33
Does max_repeated_frames = 1 as a starting value m
mandermo
2017/02/13 17:04:11
You have a point. Fixing it will change the old be
| |
375 int max_skipped_frames = 1; | 395 int max_skipped_frames = 0; |
396 | |
397 int decode_errors_ref = 0; | |
398 int decode_errors_test = 0; | |
376 | 399 |
377 std::vector<std::pair<int, int> > frame_cnt_ref = | 400 std::vector<std::pair<int, int> > frame_cnt_ref = |
378 CalculateFrameClusters(stats_file_ref); | 401 CalculateFrameClusters(stats_file_ref, &decode_errors_ref); |
379 | 402 |
380 std::vector<std::pair<int, int> > frame_cnt_test = | 403 std::vector<std::pair<int, int> > frame_cnt_test = |
381 CalculateFrameClusters(stats_file_test); | 404 CalculateFrameClusters(stats_file_test, &decode_errors_test); |
382 | 405 |
383 fclose(stats_file_ref); | 406 fclose(stats_file_ref); |
384 fclose(stats_file_test); | 407 fclose(stats_file_test); |
385 | 408 |
386 auto it_ref = frame_cnt_ref.begin(); | 409 auto it_ref = frame_cnt_ref.begin(); |
387 auto it_test = frame_cnt_test.begin(); | 410 auto it_test = frame_cnt_test.begin(); |
388 auto end_ref = frame_cnt_ref.end(); | 411 auto end_ref = frame_cnt_ref.end(); |
389 auto end_test = frame_cnt_test.end(); | 412 auto end_test = frame_cnt_test.end(); |
390 | 413 |
391 if (it_test == end_test || it_ref == end_ref) { | 414 if (it_test == end_test || it_ref == end_ref) { |
392 fprintf(stderr, "Either test or ref file is empty, nothing to print\n"); | 415 fprintf(stderr, "Either test or ref file is empty, nothing to print\n"); |
393 return; | 416 return; |
394 } | 417 } |
395 | 418 |
419 while (it_test != end_test && it_test->first == DECODE_ERROR) { | |
420 ++it_test; | |
421 } | |
422 | |
423 if (it_test == end_test) { | |
424 fprintf(stderr, "Test video only has barcode decode errors\n"); | |
425 return; | |
426 } | |
427 | |
396 // Find the first frame in the reference video that match the first frame in | 428 // Find the first frame in the reference video that match the first frame in |
397 // the test video. | 429 // the test video. |
398 while (it_ref != end_ref && it_ref->first != it_test->first) { | 430 while (it_ref != end_ref && |
431 (it_ref->first == DECODE_ERROR || it_ref->first != it_test->first)) { | |
399 ++it_ref; | 432 ++it_ref; |
400 } | 433 } |
401 if (it_ref == end_ref) { | 434 if (it_ref == end_ref) { |
402 fprintf(stderr, | 435 fprintf(stderr, |
403 "The barcode in the test video's first frame is not in the " | 436 "The barcode in the test video's first frame is not in the " |
404 "reference video.\n"); | 437 "reference video.\n"); |
405 return; | 438 return; |
406 } | 439 } |
407 | 440 |
441 // The test frames that does not have corresponding barcode in the reference | |
kjellander_webrtc
2017/02/08 12:39:33
Do we have proof that this ever happens? If not I
mandermo
2017/02/13 17:04:11
Have removed that code and print an error instead
| |
442 // video. | |
443 std::vector<int> no_match_in_ref; | |
444 | |
445 int total_skipped = 0; | |
408 for (;;) { | 446 for (;;) { |
409 max_repeated_frames = | 447 max_repeated_frames = |
410 std::max(max_repeated_frames, it_test->second - it_ref->second + 1); | 448 std::max(max_repeated_frames, it_test->second - it_ref->second + 1); |
449 | |
450 bool passed_error = false; | |
451 | |
411 ++it_test; | 452 ++it_test; |
453 while (it_test != end_test && it_test->first == DECODE_ERROR) { | |
454 ++it_test; | |
455 passed_error = true; | |
456 } | |
412 if (it_test == end_test) { | 457 if (it_test == end_test) { |
413 break; | 458 break; |
414 } | 459 } |
460 | |
415 int skipped_frames = 0; | 461 int skipped_frames = 0; |
416 ++it_ref; | 462 ++it_ref; |
417 while (it_ref != end_ref && it_ref->first != it_test->first) { | 463 for (; it_ref != end_ref; ++it_ref) { |
418 skipped_frames += it_ref->second; | 464 if (it_ref->first != DECODE_ERROR && it_ref->first >= it_test->first) { |
419 ++it_ref; | 465 break; |
466 } | |
467 ++skipped_frames; | |
420 } | 468 } |
469 if (passed_error) { | |
470 // If we pass an error in the test video, then we are conservative | |
471 // and will not calculate skipped frames for that part. | |
472 skipped_frames = 0; | |
473 } | |
474 if (it_ref != end_ref && it_ref->first == it_test->first) { | |
475 total_skipped += skipped_frames; | |
476 if (skipped_frames > max_skipped_frames) { | |
477 max_skipped_frames = skipped_frames; | |
478 } | |
479 continue; | |
480 } | |
481 no_match_in_ref.push_back(it_test->first); | |
421 if (it_ref == end_ref) { | 482 if (it_ref == end_ref) { |
422 fprintf(stderr, | 483 break; |
423 "The barcode in the test video is not in the reference video.\n"); | 484 } else { |
424 return; | 485 --it_ref; |
425 } | |
426 if (skipped_frames > max_skipped_frames) { | |
427 max_skipped_frames = skipped_frames; | |
428 } | 486 } |
429 } | 487 } |
430 | 488 |
431 fprintf(output, "RESULT Max_repeated: %s= %d\n", label.c_str(), | 489 fprintf(output, "RESULT Max_repeated: %s= %d\n", label.c_str(), |
432 max_repeated_frames); | 490 max_repeated_frames); |
433 fprintf(output, "RESULT Max_skipped: %s= %d\n", label.c_str(), | 491 fprintf(output, "RESULT Max_skipped: %s= %d\n", label.c_str(), |
434 max_skipped_frames); | 492 max_skipped_frames); |
493 fprintf(output, "RESULT Total_skipped: %s= %d\n", label.c_str(), | |
494 total_skipped); | |
kjellander_webrtc
2017/02/08 12:39:33
Seeing this, I'd like to have total_repeated_frame
kjellander_webrtc
2017/02/08 12:39:33
Name this variable total_skipped_frames to be cons
mandermo
2017/02/13 17:04:11
I don't think such a value provide any meaningful
mandermo
2017/02/13 17:04:11
Done.
kjellander_webrtc
2017/02/14 20:55:58
Why not? If we have periodic freezes, let's say ev
mandermo
2017/02/15 11:52:15
Lets fix it in a follow up CL where we initialize
| |
495 fprintf(output, "RESULT Decode_errors_reference: %s= %d\n", label.c_str(), | |
496 decode_errors_ref); | |
497 fprintf(output, "RESULT Decode_errors_test: %s= %d\n", label.c_str(), | |
498 decode_errors_test); | |
499 fprintf(output, "RESULT No_matched: ["); | |
kjellander_webrtc
2017/02/08 12:39:34
This is not suitable as a perf number. The perf da
mandermo
2017/02/13 17:04:11
Done.
| |
500 for (std::size_t i = 0; i < no_match_in_ref.size(); ++i) { | |
501 if (i > 0) { | |
502 fprintf(output, ", "); | |
503 } | |
504 fprintf(output, "%d", no_match_in_ref[i]); | |
505 } | |
506 fprintf(output, "]\n"); | |
435 } | 507 } |
436 | 508 |
437 void PrintAnalysisResults(const std::string& label, ResultsContainer* results) { | 509 void PrintAnalysisResults(const std::string& label, ResultsContainer* results) { |
438 PrintAnalysisResults(stdout, label, results); | 510 PrintAnalysisResults(stdout, label, results); |
439 } | 511 } |
440 | 512 |
441 void PrintAnalysisResults(FILE* output, const std::string& label, | 513 void PrintAnalysisResults(FILE* output, const std::string& label, |
442 ResultsContainer* results) { | 514 ResultsContainer* results) { |
443 std::vector<AnalysisResult>::iterator iter; | 515 std::vector<AnalysisResult>::iterator iter; |
444 | 516 |
(...skipping 12 matching lines...) Expand all Loading... | |
457 for (iter = results->frames.begin(); iter != results->frames.end() - 1; | 529 for (iter = results->frames.begin(); iter != results->frames.end() - 1; |
458 ++iter) { | 530 ++iter) { |
459 fprintf(output, "%f,", iter->ssim_value); | 531 fprintf(output, "%f,", iter->ssim_value); |
460 } | 532 } |
461 fprintf(output, "%f] score\n", iter->ssim_value); | 533 fprintf(output, "%f] score\n", iter->ssim_value); |
462 } | 534 } |
463 } | 535 } |
464 | 536 |
465 } // namespace test | 537 } // namespace test |
466 } // namespace webrtc | 538 } // namespace webrtc |
OLD | NEW |