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 17 #include "third_party/libyuv/include/libyuv/compare.h" 18 #include "third_party/libyuv/include/libyuv/convert.h" 19 20 namespace webrtc { 21 namespace test { 22 23 struct AnalysisResult { 24 AnalysisResult() {} 25 AnalysisResult(int frame_number, double psnr_value, double ssim_value) 26 : frame_number(frame_number), 27 psnr_value(psnr_value), 28 ssim_value(ssim_value) {} 29 int frame_number; 30 double psnr_value; 31 double ssim_value; 32 }; 33 34 struct ResultsContainer { 35 std::vector<AnalysisResult> frames; 36 }; 37 38 enum VideoAnalysisMetricsType {kPSNR, kSSIM}; 39 40 // A function to run the PSNR and SSIM analysis on the test file. The test file 41 // comprises the frames that were captured during the quality measurement test. 42 // There may be missing or duplicate frames. Also the frames start at a random 43 // position in the original video. We should provide a statistics file along 44 // with the test video. The stats file contains the connection between the 45 // actual frames in the test file and their position in the reference video, so 46 // that the analysis could run with the right frames from both videos. The stats 47 // file should be in the form 'frame_xxxx yyyy', where xxxx is the consecutive 48 // number of the frame in the test video, and yyyy is the equivalent frame in 49 // the reference video. The stats file could be produced by 50 // tools/barcode_tools/barcode_decoder.py. This script decodes the barcodes 51 // integrated in every video and generates the stats file. If three was some 52 // problem with the decoding there would be 'Barcode error' instead of yyyy. 53 void RunAnalysis(const char* reference_file_name, const char* test_file_name, 54 const char* stats_file_name, int width, int height, 55 ResultsContainer* results); 56 57 // Compute PSNR or SSIM for an I420 frame (all planes). When we are calculating 58 // PSNR values, the max return value (in the case where the test and reference 59 // frames are exactly the same) will be 48. In the case of SSIM the max return 60 // value will be 1. 61 double CalculateMetrics(VideoAnalysisMetricsType video_metrics_type, 62 const uint8* ref_frame, const uint8* test_frame, 63 int width, int height); 64 65 // Prints the result from the analysis in Chromium performance 66 // numbers compatible format to stdout. If the results object contains no frames 67 // no output will be written. 68 void PrintAnalysisResults(const std::string& label, ResultsContainer* results); 69 70 // Similar to the above, but will print to the specified file handle. 71 void PrintAnalysisResults(FILE* output, const std::string& label, 72 ResultsContainer* results); 73 74 // Calculates max repeated and skipped frames and prints them to stdout in a 75 // format that is compatible with Chromium performance numbers. 76 void PrintMaxRepeatedAndSkippedFrames(const std::string& label, 77 const std::string& stats_file_name); 78 79 // Similar to the above, but will print to the specified file handle. 80 void PrintMaxRepeatedAndSkippedFrames(FILE* output, const std::string& label, 81 const std::string& stats_file_name); 82 83 // Gets the next line from an open stats file. 84 bool GetNextStatsLine(FILE* stats_file, char* line); 85 86 // Calculates the size of a I420 frame if given the width and height. 87 int GetI420FrameSize(int width, int height); 88 89 // Extract the sequence of the frame in the video. I.e. if line is 90 // frame_0023 0284, we will get 23. 91 int ExtractFrameSequenceNumber(std::string line); 92 93 // Checks if there is 'Barcode error' for the given line. 94 bool IsThereBarcodeError(std::string line); 95 96 // Extract the frame number in the reference video. I.e. if line is 97 // frame_0023 0284, we will get 284. 98 int ExtractDecodedFrameNumber(std::string line); 99 100 // Extracts an I420 frame at position frame_number from the raw YUV file. 101 bool ExtractFrameFromYuvFile(const char* i420_file_name, int width, int height, 102 int frame_number, uint8* result_frame); 103 104 // Extracts an I420 frame at position frame_number from the Y4M file. The first 105 // frame has corresponded |frame_number| 0. 106 bool ExtractFrameFromY4mFile(const char* i420_file_name, int width, int height, 107 int frame_number, uint8* result_frame); 108 109 110 } // namespace test 111 } // namespace webrtc 112 113 #endif // WEBRTC_TOOLS_FRAME_ANALYZER_VIDEO_QUALITY_ANALYSIS_H_ 114