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

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

Issue 2515253004: Added tool for reference less video analysis (Closed)
Patch Set: Incorporated Review comments 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 unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <iostream>
14 #include <vector>
15 #include <numeric>
16
17 #include "webrtc/tools/frame_analyzer/reference_less_video_analysis_lib.h"
18 #include "webrtc/tools/frame_analyzer/video_quality_analysis.h"
19 #include "webrtc/tools/simple_command_line_parser.h"
20
21 #define STATS_LINE_LENGTH 28
22 #define PSNR_FREEZE_THRESHOLD 47
23 #define SSIM_FREEZE_THRESHOLD .999
24
25 void get_height_width_fps(int *height, int *width, int *fps,
26 const char* video_file) {
27 // File header looks like :
28 // YUV4MPEG2 W1280 H720 F25:1 Ip A0:0 C420mpeg2 XYSCSS=420MPEG2.
29 char frame_header[STATS_LINE_LENGTH];
30 FILE* input_file = fopen(video_file, "rb");
31
32 fread(frame_header, 1, STATS_LINE_LENGTH, input_file);
33
34 std::string file_header_stats[5];
35 int no_of_stats = 0;
36 char *save_ptr;
37 char *token = strtok_r(frame_header, " ", &save_ptr);
38
39 while (token != NULL) {
40 file_header_stats[no_of_stats++] = token;
41 token = strtok_r(NULL, " ", &save_ptr);
42 }
43
44 *width = std::stoi(file_header_stats[1].erase(0, 1));
45 *height = std::stoi(file_header_stats[2].erase(0, 1));
46 *fps = std::stoi(file_header_stats[3].erase(0, 1));
47
48 printf("Height: %d Width: %d fps:%d \n", *height, *width, *fps);
49 fclose(input_file);
50 }
51
52 bool frozen_frame(std::vector<double> psnr_per_frame,
53 std::vector<double> ssim_per_frame, int frame) {
54 if (psnr_per_frame[frame] >= PSNR_FREEZE_THRESHOLD ||
55 ssim_per_frame[frame] >= SSIM_FREEZE_THRESHOLD)
56 return true;
57 return false;
58 }
59
60 std::vector<int> find_frame_clusters(std::vector<double> psnr_per_frame,
61 std::vector<double> ssim_per_frame) {
62 std::vector<int> identical_frame_clusters;
63 int num_frozen = 0;
64 int total_no_of_frames = psnr_per_frame.size();
65
66 for (int each_frame = 0; each_frame < total_no_of_frames; each_frame++) {
67 if (frozen_frame(psnr_per_frame, ssim_per_frame, each_frame)) {
68 num_frozen++;
69 } else if (num_frozen > 0) {
70 // Not frozen anymore.
71 identical_frame_clusters.push_back(num_frozen);
72 num_frozen = 0;
73 }
74 }
75 return identical_frame_clusters;
76 }
77
78 void print_freezing_metrics(std::vector<double> psnr_per_frame,
79 std::vector<double> ssim_per_frame) {
80 /*
81 * Prints the different metrics mainly:
82 * 1) Identical frame number, PSNR and SSIM values.
83 * 2) Length of continuous frozen frames.
84 * 3) Max length of continuous freezed frames.
85 * 4) No of unique frames found.
86 * 5) Total different identical frames found.
87 *
88 * Sample output:
89 * Printing metrics for file: /usr/local/google/home/charujain/restore/
90 webrtc-checkout/src/webrtc/tools/test_3.y4m
91 =============================
92 Total number of frames received: 74
93 Total identical frames: 5
94 Number of unique frames: 69
95 Printing Identical Frames:
96 Frame Number: 29 PSNR: 48.000000 SSIM: 0.999618
97 Frame Number: 39 PSNR: 48.000000 SSIM: 0.999898
98 Frame Number: 60 PSNR: 48.000000 SSIM: 0.999564
99 Frame Number: 64 PSNR: 48.000000 SSIM: 0.999651
100 Frame Number: 69 PSNR: 48.000000 SSIM: 0.999684
101 Print identical frame which appears in clusters :
102 1 1 1 1 1
103 *
104 */
105 int total_no_of_frames = psnr_per_frame.size();
106 std::vector<int> identical_frame_clusters = find_frame_clusters(
107 psnr_per_frame, ssim_per_frame);
108 int total_identical_frames = std::accumulate(
109 identical_frame_clusters.begin(), identical_frame_clusters.end(), 0);
110 int unique_frames = total_no_of_frames - total_identical_frames;
111
112 printf("Total number of frames received: %d\n", total_no_of_frames);
113 printf("Total identical frames: %d\n", total_identical_frames);
114 printf("Number of unique frames: %d\n", unique_frames);
115
116 printf("Printing Identical Frames: \n");
117 for (int frame = 0; frame < total_no_of_frames; frame++) {
118 if (frozen_frame(psnr_per_frame, ssim_per_frame, frame)) {
119 printf(" Frame Number: %d PSNR: %f SSIM: %f \n", frame,
120 psnr_per_frame[frame], ssim_per_frame[frame]);
121 }
122 }
123
124 printf("Print identical frame which appears in clusters : \n");
125 for (int cluster = 0;
126 cluster < static_cast<int>(identical_frame_clusters.size()); cluster++)
127 printf("%d ", identical_frame_clusters[cluster]);
128 printf("\n");
129 }
130
131 void compute_metrics(char video_file_name[],
132 std::vector<double>* psnr_per_frame,
133 std::vector<double>* ssim_per_frame) {
134 int height = 0, width = 0, fps = 0;
135 get_height_width_fps(&height, &width, &fps, video_file_name);
136
137 int no_of_frames = 0;
138 int size = webrtc::test::GetI420FrameSize(width, height);
139
140 // Allocate buffers for test and reference frames.
141 uint8_t* current_frame = new uint8_t[size];
142 uint8_t* next_frame = new uint8_t[size];
143
144 while (true) {
145 if (!(webrtc::test::ExtractFrameFromY4mFile (video_file_name,
146 width, height,
147 no_of_frames,
148 current_frame))) {
149 break;
150 }
151
152 if (!(webrtc::test::ExtractFrameFromY4mFile (video_file_name,
153 width, height,
154 no_of_frames + 1,
155 next_frame))) {
156 break;
157 }
158
159 double result_psnr = webrtc::test::CalculateMetrics(webrtc::test::kPSNR,
160 current_frame,
161 next_frame,
162 width, height);
163 double result_ssim = webrtc::test::CalculateMetrics(webrtc::test::kSSIM,
164 current_frame,
165 next_frame,
166 width, height);
167
168 psnr_per_frame->push_back(result_psnr);
169 ssim_per_frame->push_back(result_ssim);
170 no_of_frames++;
171 }
172 // Cleanup.
173 delete[] current_frame;
174 delete[] next_frame;
175 }
176
177 void run_analysis(const char* video_file) {
178 FILE* video_file_ptr = fopen(video_file, "r");
179 if (ferror(video_file_ptr)) {
180 printf("Error opening file\n");
181 return;
182 }
183
184 char video_file_name[200];
185 while (fgets(video_file_name, 200, video_file_ptr)) {
186 strtok(video_file_name, "\n");
187
188 // Check for video file extension.
189 if (std::string(video_file_name).substr(strlen(video_file_name)-3, 3)
190 != "y4m") {
191 printf("Only y4m video file format are supported. Found: %s\n",
192 video_file_name);
193 return;
194 }
195 std::vector<double> psnr_per_frame;
196 std::vector<double> ssim_per_frame;
197 compute_metrics(video_file_name, &psnr_per_frame, &ssim_per_frame);
198
199 printf("=============================\n");
200 printf("Printing metrics for file: %s\n", video_file_name);
201 printf("=============================\n");
202 print_freezing_metrics(psnr_per_frame, ssim_per_frame);
203 }
204 fclose(video_file_ptr);
205 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698