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

Unified Diff: webrtc/tools/frame_analyzer/video_quality_analysis.cc

Issue 2553693002: Comparison of videos with reference frame not starting from zero (Closed)
Patch Set: Updated PrintMaxRepeatedAndSkippedFrames() for two stat files. Created 4 years 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 side-by-side diff with in-line comments
Download patch
Index: webrtc/tools/frame_analyzer/video_quality_analysis.cc
diff --git a/webrtc/tools/frame_analyzer/video_quality_analysis.cc b/webrtc/tools/frame_analyzer/video_quality_analysis.cc
index c1911ca81c7033e3e063d11338f5d5461d674f18..25de981e754c32ccb414333e73d8ae8abae72683 100644
--- a/webrtc/tools/frame_analyzer/video_quality_analysis.cc
+++ b/webrtc/tools/frame_analyzer/video_quality_analysis.cc
@@ -13,7 +13,10 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
+#include <algorithm>
#include <string>
+#include <map>
+#include <utility>
#define STATS_LINE_LENGTH 32
#define Y4M_FILE_HEADER_MAX_SIZE 200
@@ -224,8 +227,12 @@ double CalculateMetrics(VideoAnalysisMetricsType video_metrics_type,
return result;
}
-void RunAnalysis(const char* reference_file_name, const char* test_file_name,
- const char* stats_file_name, int width, int height,
+void RunAnalysis(const char* reference_file_name,
+ const char* test_file_name,
+ const char* stats_file_reference_name,
+ const char* stats_file_test_name,
+ int width,
+ int height,
ResultsContainer* results) {
// Check if the reference_file_name ends with "y4m".
bool y4m_mode = false;
@@ -234,7 +241,8 @@ void RunAnalysis(const char* reference_file_name, const char* test_file_name,
}
int size = GetI420FrameSize(width, height);
- FILE* stats_file = fopen(stats_file_name, "r");
+ FILE* stats_file_ref = fopen(stats_file_reference_name, "r");
+ FILE* stats_file_test = fopen(stats_file_test_name, "r");
// String buffer for the lines in the stats file.
char line[STATS_LINE_LENGTH];
@@ -244,10 +252,29 @@ void RunAnalysis(const char* reference_file_name, const char* test_file_name,
uint8_t* reference_frame = new uint8_t[size];
int previous_frame_number = -1;
+ // Maps barcode id to the frame id for the reference video.
+ // In case two frames have same id, then we only save the first one.
phoglund 2016/12/08 09:55:44 Add: "This can happen if there are freezes in the
mandermo 2016/12/08 18:08:31 It can also happen that the camera captures two fr
phoglund 2016/12/12 12:46:20 I don't understand when you say the frames have th
+ std::map<int, int> ref_barcode_to_frame;
// While there are entries in the stats file.
- while (GetNextStatsLine(stats_file, line)) {
+ while (GetNextStatsLine(stats_file_ref, line)) {
+ int extracted_ref_frame = ExtractFrameSequenceNumber(line);
+ int decoded_frame_number = ExtractDecodedFrameNumber(line);
+
+ // Insert will only add if it is not in map already, so we only keep first.
phoglund 2016/12/08 09:55:44 nit: End this sentence at the ,
mandermo 2016/12/08 18:08:31 Done.
+ ref_barcode_to_frame.insert(
+ std::make_pair(decoded_frame_number, extracted_ref_frame));
+ }
+
+ while (GetNextStatsLine(stats_file_test, line)) {
int extracted_test_frame = ExtractFrameSequenceNumber(line);
int decoded_frame_number = ExtractDecodedFrameNumber(line);
+ auto it = ref_barcode_to_frame.find(decoded_frame_number);
+ if (it == ref_barcode_to_frame.end()) {
+ // Not found in the reference video.
+ // TODO(mandermo) print
phoglund 2016/12/08 09:55:44 Yeah, print an error here and continue. You'll hav
phoglund 2016/12/12 12:46:20 Please address
+ continue;
+ }
+ int extracted_ref_frame = it->second;
// If there was problem decoding the barcode in this frame or the frame has
// been duplicated, continue.
@@ -263,17 +290,17 @@ void RunAnalysis(const char* reference_file_name, const char* test_file_name,
test_frame);
if (y4m_mode) {
ExtractFrameFromY4mFile(reference_file_name, width, height,
- decoded_frame_number, reference_frame);
+ extracted_ref_frame, reference_frame);
} else {
ExtractFrameFromYuvFile(reference_file_name, width, height,
- decoded_frame_number, reference_frame);
+ extracted_ref_frame, reference_frame);
}
// Calculate the PSNR and SSIM.
- double result_psnr = CalculateMetrics(kPSNR, reference_frame, test_frame,
- width, height);
- double result_ssim = CalculateMetrics(kSSIM, reference_frame, test_frame,
- width, height);
+ double result_psnr =
+ CalculateMetrics(kPSNR, reference_frame, test_frame, width, height);
+ double result_ssim =
+ CalculateMetrics(kSSIM, reference_frame, test_frame, width, height);
previous_frame_number = decoded_frame_number;
@@ -287,62 +314,111 @@ void RunAnalysis(const char* reference_file_name, const char* test_file_name,
}
// Cleanup.
- fclose(stats_file);
+ fclose(stats_file_ref);
+ fclose(stats_file_test);
delete[] test_frame;
delete[] reference_frame;
}
void PrintMaxRepeatedAndSkippedFrames(const std::string& label,
- const std::string& stats_file_name) {
- PrintMaxRepeatedAndSkippedFrames(stdout, label, stats_file_name);
+ const std::string& stats_file_ref_name,
+ const std::string& stats_file_test_name) {
+ PrintMaxRepeatedAndSkippedFrames(stdout, label, stats_file_ref_name,
+ stats_file_test_name);
}
-void PrintMaxRepeatedAndSkippedFrames(FILE* output, const std::string& label,
- const std::string& stats_file_name) {
- FILE* stats_file = fopen(stats_file_name.c_str(), "r");
- if (stats_file == NULL) {
- fprintf(stderr, "Couldn't open stats file for reading: %s\n",
- stats_file_name.c_str());
+namespace {
+std::vector<std::pair<int, int> > GetBarcodeNrToFrequency(FILE* file) {
phoglund 2016/12/08 09:55:44 Number
phoglund 2016/12/08 09:55:44 I would love to have unit tests for these guys sin
mandermo 2016/12/08 18:08:31 I agree the code needs to be easier to test. Maybe
phoglund 2016/12/12 12:46:20 Errors are not returned up the chain today, and I
+ std::vector<std::pair<int, int> > frame_cnt;
phoglund 2016/12/08 09:55:44 It feels a lot more natural to make this a map. Fr
phoglund 2016/12/08 09:55:44 frame_frequency?
mandermo 2016/12/08 18:08:30 frame_frequency.insert(std::pair<int, int>(decoded
mandermo 2016/12/08 18:08:31 Maybe it is more of a frame count than a frequency
phoglund 2016/12/12 12:46:20 Right, it's actually a vector of frame "clusters",
mandermo 2016/12/21 16:42:06 I have renamed the function now and added a commen
+ char line[STATS_LINE_LENGTH];
+ while (GetNextStatsLine(file, line)) {
+ int decoded_frame_number = ExtractDecodedFrameNumber(line);
+ if (frame_cnt.empty() || frame_cnt.back().first != decoded_frame_number) {
+ frame_cnt.push_back(std::make_pair(decoded_frame_number, 1));
+ } else {
+ ++frame_cnt.back().second;
+ }
+ }
+ return frame_cnt;
+}
+} // namespace
+
+void PrintMaxRepeatedAndSkippedFrames(FILE* output,
+ const std::string& label,
+ const std::string& stats_file_ref_name,
+ const std::string& stats_file_test_name) {
+ FILE* stats_file_ref = fopen(stats_file_ref_name.c_str(), "r");
+ FILE* stats_file_test = fopen(stats_file_test_name.c_str(), "r");
+ if (stats_file_ref == NULL) {
+ fprintf(stderr, "Couldn't open reference stats file for reading: %s\n",
+ stats_file_ref_name.c_str());
+ return;
+ }
+ if (stats_file_test == NULL) {
+ fprintf(stderr, "Couldn't open test stats file for reading: %s\n",
+ stats_file_test_name.c_str());
+ fclose(stats_file_ref);
return;
}
- char line[STATS_LINE_LENGTH];
- int repeated_frames = 1;
int max_repeated_frames = 1;
int max_skipped_frames = 1;
- int previous_frame_number = -1;
- while (GetNextStatsLine(stats_file, line)) {
- int decoded_frame_number = ExtractDecodedFrameNumber(line);
+ std::vector<std::pair<int, int> > frame_cnt_ref =
phoglund 2016/12/08 09:55:44 frame_frequency_ref
mandermo 2016/12/08 18:08:30 Maybe it is more of a frame count than a frequency
+ GetBarcodeNrToFrequency(stats_file_ref);
- if (decoded_frame_number == -1) {
- continue;
- }
+ std::vector<std::pair<int, int> > frame_cnt_test =
+ GetBarcodeNrToFrequency(stats_file_test);
- // Calculate how many frames a cluster of repeated frames contains.
- if (decoded_frame_number == previous_frame_number) {
- ++repeated_frames;
- if (repeated_frames > max_repeated_frames) {
- max_repeated_frames = repeated_frames;
- }
- } else {
- repeated_frames = 1;
+ fclose(stats_file_ref);
+ fclose(stats_file_test);
+
+ auto it_ref = frame_cnt_ref.begin();
+ auto it_test = frame_cnt_test.begin();
+ auto end_ref = frame_cnt_ref.end();
+ auto end_test = frame_cnt_test.end();
+
+ if (it_test != end_test) {
phoglund 2016/12/08 09:55:44 if (it_test == end_test) the test file is empty, w
mandermo 2016/12/08 18:08:31 Done. Should I print to output or to stderr like t
+ while (it_ref != end_ref && it_ref->first != it_test->first) {
phoglund 2016/12/08 09:55:44 It's hard to read what happens here. Maybe extract
mandermo 2016/12/08 18:08:31 Commented the code better.
mandermo 2016/12/08 18:08:31 Done. Should I print to output or to stderr like t
+ ++it_ref;
+ }
+ if (it_ref == end_ref) {
+ fprintf(stderr,
+ "The barcode in the test videos first frame is not in the "
+ "reference video.");
+ return;
}
+ max_repeated_frames =
phoglund 2016/12/08 09:55:44 Also not sure if this algorithm is correct. To com
mandermo 2016/12/08 18:08:30 Lets make the unittests and see what output we get
phoglund 2016/12/12 12:46:20 Ok, I think counting the frame clusters like your
mandermo 2016/12/21 16:42:06 Done.
+ std::max(max_repeated_frames, it_test->second - it_ref->second + 1);
+ }
- // Calculate how much frames have been skipped.
- if (decoded_frame_number != 0 && previous_frame_number != -1) {
- int skipped_frames = decoded_frame_number - previous_frame_number - 1;
- if (skipped_frames > max_skipped_frames) {
- max_skipped_frames = skipped_frames;
- }
+ for (;;) {
+ ++it_test;
+ if (it_test == end_test) {
+ break;
}
- previous_frame_number = decoded_frame_number;
+ int skipped_frames = 0;
+ ++it_ref;
+ while (it_ref != end_ref && it_ref->first != it_test->first) {
+ skipped_frames += it_ref->second;
+ ++it_ref;
+ }
+ if (it_ref == end_ref) {
+ fprintf(stderr,
+ "The barcode in the test video is not in the reference video.");
+ return;
+ }
+ if (skipped_frames > max_skipped_frames) {
+ max_skipped_frames = skipped_frames;
+ }
+ max_repeated_frames =
+ std::max(max_repeated_frames, it_test->second - it_ref->second + 1);
}
+
fprintf(output, "RESULT Max_repeated: %s= %d\n", label.c_str(),
max_repeated_frames);
fprintf(output, "RESULT Max_skipped: %s= %d\n", label.c_str(),
max_skipped_frames);
- fclose(stats_file);
}
void PrintAnalysisResults(const std::string& label, ResultsContainer* results) {

Powered by Google App Engine
This is Rietveld 408576698