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

Side by Side Diff: webrtc/tools/frame_analyzer/video_quality_analysis.cc

Issue 2666333003: Better comparison for frame analyzer (Closed)
Patch Set: Created 3 years, 10 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
OLDNEW
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
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.
338 std::vector<std::pair<int, int> > CalculateFrameClusters(FILE* file) { 341 std::vector<std::pair<int, int> > CalculateFrameClusters(FILE* file) {
339 std::vector<std::pair<int, int> > frame_cnt; 342 std::vector<std::pair<int, int> > frame_cnt;
340 char line[STATS_LINE_LENGTH]; 343 char line[STATS_LINE_LENGTH];
341 while (GetNextStatsLine(file, line)) { 344 while (GetNextStatsLine(file, line)) {
342 int decoded_frame_number = ExtractDecodedFrameNumber(line); 345 int decoded_frame_number;
343 if (decoded_frame_number == -1) { 346 if (IsThereBarcodeError(line)) {
344 continue; 347 decoded_frame_number = DECODE_ERROR;
kjellander_webrtc 2017/02/06 12:30:38 Can we increment a counter for this so we can log
mandermo 2017/02/07 14:25:27 I have now added a separate counter for reference
348 } else {
349 decoded_frame_number = ExtractDecodedFrameNumber(line);
345 } 350 }
346 if (frame_cnt.empty() || frame_cnt.back().first != decoded_frame_number) { 351 if (frame_cnt.size() >= 2 && decoded_frame_number != DECODE_ERROR &&
352 frame_cnt.back().first == DECODE_ERROR &&
353 frame_cnt[frame_cnt.size() - 2].first == decoded_frame_number) {
354 // Handle when there is a decoding error inside a cluster of frames.
355 frame_cnt[frame_cnt.size() - 2].second += frame_cnt.back().second;
356 frame_cnt.pop_back();
357 } else if (frame_cnt.empty() ||
358 frame_cnt.back().first != decoded_frame_number) {
347 frame_cnt.push_back(std::make_pair(decoded_frame_number, 1)); 359 frame_cnt.push_back(std::make_pair(decoded_frame_number, 1));
348 } else { 360 } else {
349 ++frame_cnt.back().second; 361 ++frame_cnt.back().second;
350 } 362 }
351 } 363 }
352 return frame_cnt; 364 return frame_cnt;
353 } 365 }
354 } // namespace 366 } // namespace
355 367
356 void PrintMaxRepeatedAndSkippedFrames(FILE* output, 368 void PrintMaxRepeatedAndSkippedFrames(FILE* output,
357 const std::string& label, 369 const std::string& label,
358 const std::string& stats_file_ref_name, 370 const std::string& stats_file_ref_name,
359 const std::string& stats_file_test_name) { 371 const std::string& stats_file_test_name) {
360 FILE* stats_file_ref = fopen(stats_file_ref_name.c_str(), "r"); 372 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"); 373 FILE* stats_file_test = fopen(stats_file_test_name.c_str(), "r");
362 if (stats_file_ref == NULL) { 374 if (stats_file_ref == NULL) {
363 fprintf(stderr, "Couldn't open reference stats file for reading: %s\n", 375 fprintf(stderr, "Couldn't open reference stats file for reading: %s\n",
364 stats_file_ref_name.c_str()); 376 stats_file_ref_name.c_str());
365 return; 377 return;
366 } 378 }
367 if (stats_file_test == NULL) { 379 if (stats_file_test == NULL) {
368 fprintf(stderr, "Couldn't open test stats file for reading: %s\n", 380 fprintf(stderr, "Couldn't open test stats file for reading: %s\n",
369 stats_file_test_name.c_str()); 381 stats_file_test_name.c_str());
370 fclose(stats_file_ref); 382 fclose(stats_file_ref);
371 return; 383 return;
372 } 384 }
373 385
374 int max_repeated_frames = 1; 386 int max_repeated_frames = 1;
375 int max_skipped_frames = 1; 387 int max_skipped_frames = 0;
376 388
377 std::vector<std::pair<int, int> > frame_cnt_ref = 389 std::vector<std::pair<int, int> > frame_cnt_ref =
378 CalculateFrameClusters(stats_file_ref); 390 CalculateFrameClusters(stats_file_ref);
379 391
380 std::vector<std::pair<int, int> > frame_cnt_test = 392 std::vector<std::pair<int, int> > frame_cnt_test =
381 CalculateFrameClusters(stats_file_test); 393 CalculateFrameClusters(stats_file_test);
382 394
383 fclose(stats_file_ref); 395 fclose(stats_file_ref);
384 fclose(stats_file_test); 396 fclose(stats_file_test);
385 397
386 auto it_ref = frame_cnt_ref.begin(); 398 auto it_ref = frame_cnt_ref.begin();
387 auto it_test = frame_cnt_test.begin(); 399 auto it_test = frame_cnt_test.begin();
388 auto end_ref = frame_cnt_ref.end(); 400 auto end_ref = frame_cnt_ref.end();
389 auto end_test = frame_cnt_test.end(); 401 auto end_test = frame_cnt_test.end();
390 402
391 if (it_test == end_test || it_ref == end_ref) { 403 if (it_test == end_test || it_ref == end_ref) {
392 fprintf(stderr, "Either test or ref file is empty, nothing to print\n"); 404 fprintf(stderr, "Either test or ref file is empty, nothing to print\n");
393 return; 405 return;
394 } 406 }
395 407
408 while (it_test != end_test && it_test->first == DECODE_ERROR) {
409 ++it_test;
410 }
411
412 if (it_test == end_test) {
413 fprintf(stderr, "Test video only has barcode decode errors\n");
414 return;
kjellander_webrtc 2017/02/06 12:30:38 It seems we should start returning an exit code fr
mandermo 2017/02/07 14:25:27 Have added test cases covering different scenarios
415 }
416
396 // Find the first frame in the reference video that match the first frame in 417 // Find the first frame in the reference video that match the first frame in
397 // the test video. 418 // the test video.
398 while (it_ref != end_ref && it_ref->first != it_test->first) { 419 while (it_ref != end_ref &&
420 (it_ref->first == DECODE_ERROR || it_ref->first != it_test->first)) {
399 ++it_ref; 421 ++it_ref;
400 } 422 }
401 if (it_ref == end_ref) { 423 if (it_ref == end_ref) {
402 fprintf(stderr, 424 fprintf(stderr,
403 "The barcode in the test video's first frame is not in the " 425 "The barcode in the test video's first frame is not in the "
404 "reference video.\n"); 426 "reference video.\n");
405 return; 427 return;
406 } 428 }
407 429
430 // The test frames that does not have corresponding barcode in the reference
431 // video.
432 std::vector<int> no_match_in_ref;
433
434 int total_skipped = 0;
408 for (;;) { 435 for (;;) {
409 max_repeated_frames = 436 max_repeated_frames =
410 std::max(max_repeated_frames, it_test->second - it_ref->second + 1); 437 std::max(max_repeated_frames, it_test->second - it_ref->second + 1);
438
439 bool passed_error = false;
440
411 ++it_test; 441 ++it_test;
442 while (it_test != end_test && it_test->first == DECODE_ERROR) {
443 ++it_test;
444 passed_error = true;
445 }
412 if (it_test == end_test) { 446 if (it_test == end_test) {
413 break; 447 break;
414 } 448 }
449
415 int skipped_frames = 0; 450 int skipped_frames = 0;
451 auto old_it_ref = it_ref;
416 ++it_ref; 452 ++it_ref;
417 while (it_ref != end_ref && it_ref->first != it_test->first) { 453 for (; it_ref != end_ref; ++it_ref) {
418 skipped_frames += it_ref->second; 454 if (it_ref->first == DECODE_ERROR) {
419 ++it_ref; 455 passed_error = true;
456 continue;
457 }
458 if (it_ref->first >= it_test->first) {
459 break;
460 }
461 ++skipped_frames;
420 } 462 }
463 if (passed_error) {
464 skipped_frames = 0;
465 }
466 if (it_ref != end_ref && it_ref->first == it_test->first) {
467 total_skipped += skipped_frames;
468 if (skipped_frames > max_skipped_frames) {
469 max_skipped_frames = skipped_frames;
470 }
471 continue;
472 }
473 no_match_in_ref.push_back(it_test->first);
421 if (it_ref == end_ref) { 474 if (it_ref == end_ref) {
422 fprintf(stderr, 475 break;
423 "The barcode in the test video is not in the reference video.\n"); 476 } else {
424 return; 477 it_ref = old_it_ref;
425 }
426 if (skipped_frames > max_skipped_frames) {
427 max_skipped_frames = skipped_frames;
428 } 478 }
429 } 479 }
430 480
431 fprintf(output, "RESULT Max_repeated: %s= %d\n", label.c_str(), 481 fprintf(output, "RESULT Max_repeated: %s= %d\n", label.c_str(),
432 max_repeated_frames); 482 max_repeated_frames);
433 fprintf(output, "RESULT Max_skipped: %s= %d\n", label.c_str(), 483 fprintf(output, "RESULT Max_skipped: %s= %d\n", label.c_str(),
434 max_skipped_frames); 484 max_skipped_frames);
485 fprintf(output, "RESULT Total_skipped: %s= %d\n", label.c_str(),
486 total_skipped);
487 fprintf(output, "RESULT No_matched: [");
488 for (std::size_t i = 0; i < no_match_in_ref.size(); ++i) {
489 if (i > 0) {
490 fprintf(output, ", ");
491 }
492 fprintf(output, "%d", no_match_in_ref[i]);
493 }
494 fprintf(output, "]\n");
435 } 495 }
436 496
437 void PrintAnalysisResults(const std::string& label, ResultsContainer* results) { 497 void PrintAnalysisResults(const std::string& label, ResultsContainer* results) {
438 PrintAnalysisResults(stdout, label, results); 498 PrintAnalysisResults(stdout, label, results);
439 } 499 }
440 500
441 void PrintAnalysisResults(FILE* output, const std::string& label, 501 void PrintAnalysisResults(FILE* output, const std::string& label,
442 ResultsContainer* results) { 502 ResultsContainer* results) {
443 std::vector<AnalysisResult>::iterator iter; 503 std::vector<AnalysisResult>::iterator iter;
444 504
(...skipping 12 matching lines...) Expand all
457 for (iter = results->frames.begin(); iter != results->frames.end() - 1; 517 for (iter = results->frames.begin(); iter != results->frames.end() - 1;
458 ++iter) { 518 ++iter) {
459 fprintf(output, "%f,", iter->ssim_value); 519 fprintf(output, "%f,", iter->ssim_value);
460 } 520 }
461 fprintf(output, "%f] score\n", iter->ssim_value); 521 fprintf(output, "%f] score\n", iter->ssim_value);
462 } 522 }
463 } 523 }
464 524
465 } // namespace test 525 } // namespace test
466 } // namespace webrtc 526 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698