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

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: Added newline in debug prints for PrintMaxRepeatedAndSkippedFrames Created 3 years, 11 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 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..dfb7d900657540ca87adc6e38e79b143a721abe6 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.
+ 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.
+ 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
+ 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,124 @@ 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 {
+// Clusters the frames in the file. First in the pair is the frame number and
+// second is the number
+// of frames in that cluster. So if first frame in video has number 100 and it
+// is repeated 3 after
+// each other, then the first entry in the returned vector has first set to 100
+// and second set
+// to 3.
+std::vector<std::pair<int, int> > CalculateFrameClusters(FILE* file) {
+ std::vector<std::pair<int, int> > frame_cnt;
+ char line[STATS_LINE_LENGTH];
+ while (GetNextStatsLine(file, line)) {
+ int decoded_frame_number = ExtractDecodedFrameNumber(line);
+ if (decoded_frame_number == -1) {
+ continue;
+ }
+ 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 =
+ CalculateFrameClusters(stats_file_ref);
- if (decoded_frame_number == -1) {
- continue;
- }
+ std::vector<std::pair<int, int> > frame_cnt_test =
+ CalculateFrameClusters(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);
- // 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;
- }
+ 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 || it_ref == end_ref) {
+ fprintf(stderr, "Either test or ref file is empty, nothing to print\n");
+ return;
+ }
+
+ // Find the first frame in the reference video that match the first frame in
+ // the test video.
+ while (it_ref != end_ref && it_ref->first != it_test->first) {
+ ++it_ref;
+ }
+ if (it_ref == end_ref) {
+ fprintf(stderr,
+ "The barcode in the test video's first frame is not in the "
+ "reference video.\n");
+ return;
+ }
+
+ for (;;) {
+ max_repeated_frames =
+ std::max(max_repeated_frames, it_test->second - it_ref->second + 1);
+ ++it_test;
+ if (it_test == end_test) {
+ break;
+ }
+ 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.\n");
+ return;
+ }
+ if (skipped_frames > max_skipped_frames) {
+ max_skipped_frames = skipped_frames;
}
- previous_frame_number = decoded_frame_number;
}
+
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) {
« no previous file with comments | « webrtc/tools/frame_analyzer/video_quality_analysis.h ('k') | webrtc/tools/frame_analyzer/video_quality_analysis_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698