OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (c) 2012 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 | |
11 #ifndef WEBRTC_TOOLS_FRAME_ANALYZER_VIDEO_QUALITY_ANALYSIS_H_ | |
12 #define WEBRTC_TOOLS_FRAME_ANALYZER_VIDEO_QUALITY_ANALYSIS_H_ | |
13 | |
14 #include <string> | |
15 #include <vector> | |
16 #include <utility> | |
17 | |
18 #include "libyuv/compare.h" // NOLINT | |
19 #include "libyuv/convert.h" // NOLINT | |
20 | |
21 namespace webrtc { | |
22 namespace test { | |
23 | |
24 struct AnalysisResult { | |
25 AnalysisResult() {} | |
26 AnalysisResult(int frame_number, double psnr_value, double ssim_value) | |
27 : frame_number(frame_number), | |
28 psnr_value(psnr_value), | |
29 ssim_value(ssim_value) {} | |
30 int frame_number; | |
31 double psnr_value; | |
32 double ssim_value; | |
33 }; | |
34 | |
35 struct ResultsContainer { | |
36 ResultsContainer(); | |
37 ~ResultsContainer(); | |
38 | |
39 std::vector<AnalysisResult> frames; | |
40 }; | |
41 | |
42 enum VideoAnalysisMetricsType {kPSNR, kSSIM}; | |
43 | |
44 // A function to run the PSNR and SSIM analysis on the test file. The test file | |
45 // comprises the frames that were captured during the quality measurement test. | |
46 // There may be missing or duplicate frames. Also the frames start at a random | |
47 // position in the original video. We should provide a statistics file along | |
48 // with the test video. The stats file contains the connection between the | |
49 // actual frames in the test file and their bar code number. There is one file | |
50 // for the reference video and one for the test video. The stats file should | |
51 // be in the form 'frame_xxxx yyyy', where xxxx is the consecutive | |
52 // number of the frame in the test video, and yyyy is the barcode number. | |
53 // The stats file could be produced by | |
54 // tools/barcode_tools/barcode_decoder.py. This script decodes the barcodes | |
55 // integrated in every video and generates the stats file. If three was some | |
56 // problem with the decoding there would be 'Barcode error' instead of yyyy. | |
57 // The stat files are used to compare the right frames with each other and | |
58 // to calculate statistics. | |
59 void RunAnalysis(const char* reference_file_name, | |
60 const char* test_file_name, | |
61 const char* stats_file_reference_name, | |
62 const char* stats_file_test_name, | |
63 int width, | |
64 int height, | |
65 ResultsContainer* results); | |
66 | |
67 // Compute PSNR or SSIM for an I420 frame (all planes). When we are calculating | |
68 // PSNR values, the max return value (in the case where the test and reference | |
69 // frames are exactly the same) will be 48. In the case of SSIM the max return | |
70 // value will be 1. | |
71 double CalculateMetrics(VideoAnalysisMetricsType video_metrics_type, | |
72 const uint8_t* ref_frame, | |
73 const uint8_t* test_frame, | |
74 int width, | |
75 int height); | |
76 | |
77 // Prints the result from the analysis in Chromium performance | |
78 // numbers compatible format to stdout. If the results object contains no frames | |
79 // no output will be written. | |
80 void PrintAnalysisResults(const std::string& label, ResultsContainer* results); | |
81 | |
82 // Similar to the above, but will print to the specified file handle. | |
83 void PrintAnalysisResults(FILE* output, const std::string& label, | |
84 ResultsContainer* results); | |
85 | |
86 // The barcode number that means that the barcode could not be decoded. | |
87 const int DECODE_ERROR = -1; | |
88 | |
89 // Clusters the frames in the file. First in the pair is the frame number and | |
90 // second is the number of frames in that cluster. So if first frame in video | |
91 // has number 100 and it is repeated 3 after each other, then the first entry | |
92 // in the returned vector has first set to 100 and second set to 3. | |
93 // Decode errors between two frames with same barcode, then it interprets | |
94 // the frame with the decode error as having the same id as the two frames | |
95 // around it. Eg. [400, DECODE_ERROR, DECODE_ERROR, 400] is becomes an entry | |
96 // in return vector with first==400 and second==4. In other cases with decode | |
97 // errors like [400, DECODE_ERROR, 401] becomes three entries, each with | |
98 // second==1 and the middle has first==DECODE_ERROR. | |
99 std::vector<std::pair<int, int> > CalculateFrameClusters( | |
100 FILE* file, | |
101 int* num_decode_errors); | |
102 | |
103 // Calculates max repeated and skipped frames and prints them to stdout in a | |
104 // format that is compatible with Chromium performance numbers. | |
105 void PrintMaxRepeatedAndSkippedFrames(const std::string& label, | |
106 const std::string& stats_file_ref_name, | |
107 const std::string& stats_file_test_name); | |
108 | |
109 // Similar to the above, but will print to the specified file handle. | |
110 void PrintMaxRepeatedAndSkippedFrames(FILE* output, | |
111 const std::string& label, | |
112 const std::string& stats_file_ref_name, | |
113 const std::string& stats_file_test_name); | |
114 | |
115 // Gets the next line from an open stats file. | |
116 bool GetNextStatsLine(FILE* stats_file, char* line); | |
117 | |
118 // Calculates the size of a I420 frame if given the width and height. | |
119 int GetI420FrameSize(int width, int height); | |
120 | |
121 // Extract the sequence of the frame in the video. I.e. if line is | |
122 // frame_0023 0284, we will get 23. | |
123 int ExtractFrameSequenceNumber(std::string line); | |
124 | |
125 // Checks if there is 'Barcode error' for the given line. | |
126 bool IsThereBarcodeError(std::string line); | |
127 | |
128 // Extract the frame number in the reference video. I.e. if line is | |
129 // frame_0023 0284, we will get 284. | |
130 int ExtractDecodedFrameNumber(std::string line); | |
131 | |
132 // Extracts an I420 frame at position frame_number from the raw YUV file. | |
133 bool ExtractFrameFromYuvFile(const char* i420_file_name, | |
134 int width, | |
135 int height, | |
136 int frame_number, | |
137 uint8_t* result_frame); | |
138 | |
139 // Extracts an I420 frame at position frame_number from the Y4M file. The first | |
140 // frame has corresponded |frame_number| 0. | |
141 bool ExtractFrameFromY4mFile(const char* i420_file_name, | |
142 int width, | |
143 int height, | |
144 int frame_number, | |
145 uint8_t* result_frame); | |
146 | |
147 } // namespace test | |
148 } // namespace webrtc | |
149 | |
150 #endif // WEBRTC_TOOLS_FRAME_ANALYZER_VIDEO_QUALITY_ANALYSIS_H_ | |
OLD | NEW |