blob: 0ebd0c70d93ff797ebb10fd123fc04ad58be4ad6 [file] [log] [blame]
vspasova@webrtc.orgfd800702012-08-16 14:07:02 +00001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef RTC_TOOLS_FRAME_ANALYZER_VIDEO_QUALITY_ANALYSIS_H_
12#define RTC_TOOLS_FRAME_ANALYZER_VIDEO_QUALITY_ANALYSIS_H_
vspasova@webrtc.orgfd800702012-08-16 14:07:02 +000013
14#include <string>
mandermo7cebe782017-02-16 01:36:43 -080015#include <utility>
Yves Gerey665174f2018-06-19 15:03:05 +020016#include <vector>
vspasova@webrtc.orgfd800702012-08-16 14:07:02 +000017
Magnus Jedvert404be7f2018-08-22 19:23:34 +020018#include "api/video/i420_buffer.h"
19#include "rtc_tools/y4m_file_reader.h"
vspasova@webrtc.orgfd800702012-08-16 14:07:02 +000020
21namespace webrtc {
22namespace test {
23
24struct AnalysisResult {
kjellander@webrtc.orgf880f862013-09-10 12:10:01 +000025 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) {}
vspasova@webrtc.orgfd800702012-08-16 14:07:02 +000030 int frame_number;
31 double psnr_value;
32 double ssim_value;
33};
34
35struct ResultsContainer {
Henrik Kjellander67bcb602015-10-07 08:42:52 +020036 ResultsContainer();
37 ~ResultsContainer();
38
vspasova@webrtc.orgfd800702012-08-16 14:07:02 +000039 std::vector<AnalysisResult> frames;
Edward Lemur2e5966b2018-01-30 15:33:02 +010040 int max_repeated_frames;
41 int max_skipped_frames;
42 int total_skipped_frames;
43 int decode_errors_ref;
44 int decode_errors_test;
vspasova@webrtc.orgfd800702012-08-16 14:07:02 +000045};
46
vspasova@webrtc.orgfd800702012-08-16 14:07:02 +000047// A function to run the PSNR and SSIM analysis on the test file. The test file
48// comprises the frames that were captured during the quality measurement test.
49// There may be missing or duplicate frames. Also the frames start at a random
Magnus Jedvert3e169ac2018-08-24 12:44:59 +000050// position in the original video. We should provide a statistics file along
51// with the test video. The stats file contains the connection between the
52// actual frames in the test file and their bar code number. There is one file
53// for the reference video and one for the test video. The stats file should
54// be in the form 'frame_xxxx yyyy', where xxxx is the consecutive
55// number of the frame in the test video, and yyyy is the barcode number.
56// The stats file could be produced by
57// tools/barcode_tools/barcode_decoder.py. This script decodes the barcodes
58// integrated in every video and generates the stats file. If three was some
59// problem with the decoding there would be 'Barcode error' instead of yyyy.
60// The stat files are used to compare the right frames with each other and
61// to calculate statistics.
62void RunAnalysis(const rtc::scoped_refptr<webrtc::test::Video>& reference_video,
63 const rtc::scoped_refptr<webrtc::test::Video>& test_video,
64 const char* stats_file_reference_name,
65 const char* stats_file_test_name,
66 int width,
67 int height,
68 ResultsContainer* results);
vspasova@webrtc.orgfd800702012-08-16 14:07:02 +000069
Magnus Jedvert404be7f2018-08-22 19:23:34 +020070// Compute PSNR for an I420 buffer (all planes). The max return value (in the
71// case where the test and reference frames are exactly the same) will be 48.
72double Psnr(const rtc::scoped_refptr<I420BufferInterface>& ref_buffer,
73 const rtc::scoped_refptr<I420BufferInterface>& test_buffer);
74
75// Compute SSIM for an I420 buffer (all planes). The max return value (in the
76// case where the test and reference frames are exactly the same) will be 1.
77double Ssim(const rtc::scoped_refptr<I420BufferInterface>& ref_buffer,
78 const rtc::scoped_refptr<I420BufferInterface>& test_buffer);
vspasova@webrtc.orgfd800702012-08-16 14:07:02 +000079
kjellander@webrtc.orgf880f862013-09-10 12:10:01 +000080// Prints the result from the analysis in Chromium performance
81// numbers compatible format to stdout. If the results object contains no frames
82// no output will be written.
83void PrintAnalysisResults(const std::string& label, ResultsContainer* results);
vspasova@webrtc.orgfd800702012-08-16 14:07:02 +000084
kjellander@webrtc.orge2df8b72013-11-03 18:34:51 +000085// Similar to the above, but will print to the specified file handle.
Yves Gerey665174f2018-06-19 15:03:05 +020086void PrintAnalysisResults(FILE* output,
87 const std::string& label,
kjellander@webrtc.orge2df8b72013-11-03 18:34:51 +000088 ResultsContainer* results);
89
Magnus Jedvert3e169ac2018-08-24 12:44:59 +000090// The barcode number that means that the barcode could not be decoded.
91const int DECODE_ERROR = -1;
mandermo7cebe782017-02-16 01:36:43 -080092
Magnus Jedvert3e169ac2018-08-24 12:44:59 +000093// Clusters the frames in the file. First in the pair is the frame number and
94// second is the number of frames in that cluster. So if first frame in video
95// has number 100 and it is repeated 3 after each other, then the first entry
96// in the returned vector has first set to 100 and second set to 3.
97// Decode errors between two frames with same barcode, then it interprets
98// the frame with the decode error as having the same id as the two frames
99// around it. Eg. [400, DECODE_ERROR, DECODE_ERROR, 400] is becomes an entry
100// in return vector with first==400 and second==4. In other cases with decode
101// errors like [400, DECODE_ERROR, 401] becomes three entries, each with
102// second==1 and the middle has first==DECODE_ERROR.
103std::vector<std::pair<int, int> > CalculateFrameClusters(
104 FILE* file,
105 int* num_decode_errors);
mandermo7cebe782017-02-16 01:36:43 -0800106
Magnus Jedvert3e169ac2018-08-24 12:44:59 +0000107// Calculates max repeated and skipped frames and prints them to stdout in a
108// format that is compatible with Chromium performance numbers.
109void GetMaxRepeatedAndSkippedFrames(const std::string& stats_file_ref_name,
110 const std::string& stats_file_test_name,
111 ResultsContainer* results);
kjellander@webrtc.orge2df8b72013-11-03 18:34:51 +0000112
Magnus Jedvert3e169ac2018-08-24 12:44:59 +0000113// Gets the next line from an open stats file.
114bool GetNextStatsLine(FILE* stats_file, char* line);
vspasova@webrtc.orgfd800702012-08-16 14:07:02 +0000115
Magnus Jedvert3e169ac2018-08-24 12:44:59 +0000116// Calculates the size of a I420 frame if given the width and height.
117int GetI420FrameSize(int width, int height);
118
119// Extract the sequence of the frame in the video. I.e. if line is
120// frame_0023 0284, we will get 23.
121int ExtractFrameSequenceNumber(std::string line);
122
123// Checks if there is 'Barcode error' for the given line.
124bool IsThereBarcodeError(std::string line);
125
126// Extract the frame number in the reference video. I.e. if line is
127// frame_0023 0284, we will get 284.
128int ExtractDecodedFrameNumber(std::string line);
vspasova@webrtc.orgfd800702012-08-16 14:07:02 +0000129
vspasova@webrtc.orgfd800702012-08-16 14:07:02 +0000130} // namespace test
131} // namespace webrtc
132
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200133#endif // RTC_TOOLS_FRAME_ANALYZER_VIDEO_QUALITY_ANALYSIS_H_