| 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 |