Index: webrtc/modules/video_coding/codecs/tools/video_quality_measurement.cc |
diff --git a/webrtc/modules/video_coding/codecs/tools/video_quality_measurement.cc b/webrtc/modules/video_coding/codecs/tools/video_quality_measurement.cc |
deleted file mode 100644 |
index f82ba42803250e6461674f169dcbffa74a7f7ed4..0000000000000000000000000000000000000000 |
--- a/webrtc/modules/video_coding/codecs/tools/video_quality_measurement.cc |
+++ /dev/null |
@@ -1,560 +0,0 @@ |
-/* |
- * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
- * |
- * Use of this source code is governed by a BSD-style license |
- * that can be found in the LICENSE file in the root of the source |
- * tree. An additional intellectual property rights grant can be found |
- * in the file PATENTS. All contributing project authors may |
- * be found in the AUTHORS file in the root of the source tree. |
- */ |
- |
-#include <assert.h> |
-#include <stdio.h> |
-#include <time.h> |
-#include <string.h> |
- |
-#include <stdarg.h> |
-#include <sys/stat.h> // To check for directory existence. |
- |
-#ifndef S_ISDIR // Not defined in stat.h on Windows. |
-#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR) |
-#endif |
- |
-#include "webrtc/common_types.h" |
-#include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h" |
-#include "webrtc/modules/video_coding/codecs/test/stats.h" |
-#include "webrtc/modules/video_coding/codecs/test/videoprocessor.h" |
-#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" |
-#include "webrtc/modules/video_coding/include/video_coding.h" |
-#include "webrtc/rtc_base/flags.h" |
-#include "webrtc/rtc_base/format_macros.h" |
-#include "webrtc/test/testsupport/frame_reader.h" |
-#include "webrtc/test/testsupport/frame_writer.h" |
-#include "webrtc/test/testsupport/metrics/video_metrics.h" |
-#include "webrtc/test/testsupport/packet_reader.h" |
-#include "webrtc/test/video_codec_settings.h" |
- |
-DEFINE_string(test_name, "Quality test", "The name of the test to run. "); |
-DEFINE_string(test_description, |
- "", |
- "A more detailed description about what " |
- "the current test is about."); |
-DEFINE_string(input_filename, |
- "", |
- "Input file. " |
- "The source video file to be encoded and decoded. Must be in " |
- ".yuv format"); |
-DEFINE_int(width, -1, "Width in pixels of the frames in the input file."); |
-DEFINE_int(height, -1, "Height in pixels of the frames in the input file."); |
-DEFINE_int(framerate, |
- 30, |
- "Frame rate of the input file, in FPS " |
- "(frames-per-second). "); |
-DEFINE_string(output_dir, |
- ".", |
- "Output directory. " |
- "The directory where the output file will be put. Must already " |
- "exist."); |
-DEFINE_bool(use_single_core, |
- false, |
- "Force using a single core. If set to " |
- "true, only one core will be used for processing. Using a single " |
- "core is necessary to get a deterministic behavior for the" |
- "encoded frames - using multiple cores will produce different " |
- "encoded frames since multiple cores are competing to consume the " |
- "byte budget for each frame in parallel. If set to false, " |
- "the maximum detected number of cores will be used. "); |
-DEFINE_bool(disable_fixed_random_seed, |
- false, |
- "Set this flag to disable the" |
- "usage of a fixed random seed for the random generator used " |
- "for packet loss. Disabling this will cause consecutive runs " |
- "loose packets at different locations, which is bad for " |
- "reproducibility."); |
-DEFINE_string(output_filename, |
- "", |
- "Output file. " |
- "The name of the output video file resulting of the processing " |
- "of the source file. By default this is the same name as the " |
- "input file with '_out' appended before the extension."); |
-DEFINE_int(bitrate, 500, "Bit rate in kilobits/second."); |
-DEFINE_int(keyframe_interval, |
- 0, |
- "Forces a keyframe every Nth frame. " |
- "0 means the encoder decides when to insert keyframes. Note that " |
- "the encoder may create a keyframe in other locations in addition " |
- "to the interval that is set using this parameter."); |
-DEFINE_int(temporal_layers, |
- 0, |
- "The number of temporal layers to use " |
- "(VP8 specific codec setting). Must be 0-4."); |
-DEFINE_int(packet_size, |
- 1500, |
- "Simulated network packet size in bytes (MTU). " |
- "Used for packet loss simulation."); |
-DEFINE_int(max_payload_size, |
- 1440, |
- "Max payload size in bytes for the " |
- "encoder."); |
-DEFINE_string(packet_loss_mode, |
- "uniform", |
- "Packet loss mode. Two different " |
- "packet loss models are supported: uniform or burst. This " |
- "setting has no effect unless packet_loss_rate is >0. "); |
-DEFINE_float(packet_loss_probability, |
- 0.0f, |
- "Packet loss probability. A value " |
- "between 0.0 and 1.0 that defines the probability of a packet " |
- "being lost. 0.1 means 10% and so on."); |
-DEFINE_int(packet_loss_burst_length, |
- 1, |
- "Packet loss burst length. Defines " |
- "how many packets will be lost in a burst when a packet has been " |
- "decided to be lost. Must be >=1."); |
-DEFINE_bool(csv, |
- false, |
- "CSV output. Enabling this will output all frame " |
- "statistics at the end of execution. Recommended to run combined " |
- "with --noverbose to avoid mixing output."); |
-DEFINE_bool(python, |
- false, |
- "Python output. Enabling this will output all frame " |
- "statistics as a Python script at the end of execution. " |
- "Recommended to run combine with --noverbose to avoid mixing " |
- "output."); |
-DEFINE_bool(verbose, |
- true, |
- "Verbose mode. Prints a lot of debugging info. " |
- "Suitable for tracking progress but not for capturing output. " |
- "Disable with --noverbose flag."); |
-DEFINE_bool(help, false, "Prints this message."); |
- |
-// Custom log method that only prints if the verbose flag is given. |
-// Supports all the standard printf parameters and formatting (just forwarded). |
-int Log(const char* format, ...) { |
- int result = 0; |
- if (FLAG_verbose) { |
- va_list args; |
- va_start(args, format); |
- result = vprintf(format, args); |
- va_end(args); |
- } |
- return result; |
-} |
- |
-// Validates the arguments given as command line flags and fills in the |
-// TestConfig struct with all configurations needed for video processing. |
-// Returns 0 if everything is OK, otherwise an exit code. |
-int HandleCommandLineFlags(webrtc::test::TestConfig* config, |
- const std::string& usage) { |
- // Validate the mandatory flags: |
- if (strlen(FLAG_input_filename) == 0 || |
- FLAG_width == -1 || FLAG_height == -1) { |
- printf("%s\n", usage.c_str()); |
- return 1; |
- } |
- config->name = FLAG_test_name; |
- config->description = FLAG_test_description; |
- |
- // Verify the input file exists and is readable. |
- FILE* test_file; |
- test_file = fopen(FLAG_input_filename, "rb"); |
- if (test_file == NULL) { |
- fprintf(stderr, "Cannot read the specified input file: %s\n", |
- FLAG_input_filename); |
- return 2; |
- } |
- fclose(test_file); |
- config->input_filename = FLAG_input_filename; |
- |
- // Verify the output dir exists. |
- struct stat dir_info; |
- if (!(stat(FLAG_output_dir, &dir_info) == 0 && |
- S_ISDIR(dir_info.st_mode))) { |
- fprintf(stderr, "Cannot find output directory: %s\n", |
- FLAG_output_dir); |
- return 3; |
- } |
- config->output_dir = FLAG_output_dir; |
- |
- // Manufacture an output filename if none was given. |
- if (strlen(FLAG_output_filename) == 0) { |
- // Cut out the filename without extension from the given input file |
- // (which may include a path) |
- size_t startIndex = config->input_filename.find_last_of("/") + 1; |
- if (startIndex == 0) { |
- startIndex = 0; |
- } |
- config->output_filename = |
- config->input_filename.substr( |
- startIndex, config->input_filename.find_last_of(".") - startIndex) + |
- "_out.yuv"; |
- } else { |
- config->output_filename = FLAG_output_filename; |
- } |
- |
- // Verify output file can be written. |
- if (config->output_dir != ".") { |
- config->output_filename = |
- config->output_dir + "/" + config->output_filename; |
- } |
- test_file = fopen(config->output_filename.c_str(), "wb"); |
- if (test_file == NULL) { |
- fprintf(stderr, "Cannot write output file: %s\n", |
- config->output_filename.c_str()); |
- return 4; |
- } |
- fclose(test_file); |
- |
- // Check single core flag. |
- config->use_single_core = FLAG_use_single_core; |
- |
- // Get codec specific configuration. |
- webrtc::test::CodecSettings(webrtc::kVideoCodecVP8, &config->codec_settings); |
- |
- // Check the temporal layers. |
- if (FLAG_temporal_layers < 0 || |
- FLAG_temporal_layers > webrtc::kMaxTemporalStreams) { |
- fprintf(stderr, "Temporal layers number must be 0-4, was: %d\n", |
- FLAG_temporal_layers); |
- return 13; |
- } |
- config->codec_settings.VP8()->numberOfTemporalLayers = FLAG_temporal_layers; |
- |
- // Check the bit rate. |
- if (FLAG_bitrate <= 0) { |
- fprintf(stderr, "Bit rate must be >0 kbps, was: %d\n", FLAG_bitrate); |
- return 5; |
- } |
- config->codec_settings.startBitrate = FLAG_bitrate; |
- |
- // Check the keyframe interval. |
- if (FLAG_keyframe_interval < 0) { |
- fprintf(stderr, "Keyframe interval must be >=0, was: %d\n", |
- FLAG_keyframe_interval); |
- return 6; |
- } |
- config->keyframe_interval = FLAG_keyframe_interval; |
- |
- // Check packet size and max payload size. |
- if (FLAG_packet_size <= 0) { |
- fprintf(stderr, "Packet size must be >0 bytes, was: %d\n", |
- FLAG_packet_size); |
- return 7; |
- } |
- config->networking_config.packet_size_in_bytes = |
- static_cast<size_t>(FLAG_packet_size); |
- |
- if (FLAG_max_payload_size <= 0) { |
- fprintf(stderr, "Max payload size must be >0 bytes, was: %d\n", |
- FLAG_max_payload_size); |
- return 8; |
- } |
- config->networking_config.max_payload_size_in_bytes = |
- static_cast<size_t>(FLAG_max_payload_size); |
- |
- // Check the width and height |
- if (FLAG_width <= 0 || FLAG_height <= 0) { |
- fprintf(stderr, "Width and height must be >0."); |
- return 9; |
- } |
- config->codec_settings.width = FLAG_width; |
- config->codec_settings.height = FLAG_height; |
- config->codec_settings.maxFramerate = FLAG_framerate; |
- |
- // Calculate the size of each frame to read (according to YUV spec). |
- config->frame_length_in_bytes = |
- 3 * config->codec_settings.width * config->codec_settings.height / 2; |
- |
- // Check packet loss settings |
- if (strcmp(FLAG_packet_loss_mode, "uniform") == 0) { |
- config->networking_config.packet_loss_mode = webrtc::test::kUniform; |
- } else if (strcmp(FLAG_packet_loss_mode, "burst") == 0) { |
- config->networking_config.packet_loss_mode = webrtc::test::kBurst; |
- } else { |
- fprintf(stderr, |
- "Unsupported packet loss mode, must be 'uniform' or " |
- "'burst'\n."); |
- return 10; |
- } |
- |
- if (FLAG_packet_loss_probability < 0.0 || |
- FLAG_packet_loss_probability > 1.0) { |
- fprintf(stderr, |
- "Invalid packet loss probability. Must be 0.0 - 1.0, " |
- "was: %f\n", |
- FLAG_packet_loss_probability); |
- return 11; |
- } |
- config->networking_config.packet_loss_probability = |
- FLAG_packet_loss_probability; |
- |
- if (FLAG_packet_loss_burst_length < 1) { |
- fprintf(stderr, |
- "Invalid packet loss burst length, must be >=1, " |
- "was: %d\n", |
- FLAG_packet_loss_burst_length); |
- return 12; |
- } |
- config->networking_config.packet_loss_burst_length = |
- FLAG_packet_loss_burst_length; |
- config->verbose = FLAG_verbose; |
- return 0; |
-} |
- |
-void CalculateSsimVideoMetrics(webrtc::test::TestConfig* config, |
- webrtc::test::QualityMetricsResult* result) { |
- Log("Calculating SSIM...\n"); |
- I420SSIMFromFiles( |
- config->input_filename.c_str(), config->output_filename.c_str(), |
- config->codec_settings.width, config->codec_settings.height, result); |
- Log(" Average: %3.2f\n", result->average); |
- Log(" Min : %3.2f (frame %d)\n", result->min, result->min_frame_number); |
- Log(" Max : %3.2f (frame %d)\n", result->max, result->max_frame_number); |
-} |
- |
-void CalculatePsnrVideoMetrics(webrtc::test::TestConfig* config, |
- webrtc::test::QualityMetricsResult* result) { |
- Log("Calculating PSNR...\n"); |
- I420PSNRFromFiles( |
- config->input_filename.c_str(), config->output_filename.c_str(), |
- config->codec_settings.width, config->codec_settings.height, result); |
- Log(" Average: %3.2f\n", result->average); |
- Log(" Min : %3.2f (frame %d)\n", result->min, result->min_frame_number); |
- Log(" Max : %3.2f (frame %d)\n", result->max, result->max_frame_number); |
-} |
- |
-void PrintConfigurationSummary(const webrtc::test::TestConfig& config) { |
- Log("Quality test with parameters:\n"); |
- Log(" Test name : %s\n", config.name.c_str()); |
- Log(" Description : %s\n", config.description.c_str()); |
- Log(" Input filename : %s\n", config.input_filename.c_str()); |
- Log(" Output directory : %s\n", config.output_dir.c_str()); |
- Log(" Output filename : %s\n", config.output_filename.c_str()); |
- Log(" Frame length : %" PRIuS " bytes\n", config.frame_length_in_bytes); |
- Log(" Packet size : %" PRIuS " bytes\n", |
- config.networking_config.packet_size_in_bytes); |
- Log(" Max payload size : %" PRIuS " bytes\n", |
- config.networking_config.max_payload_size_in_bytes); |
- Log(" Packet loss:\n"); |
- Log(" Mode : %s\n", |
- PacketLossModeToStr(config.networking_config.packet_loss_mode)); |
- Log(" Probability : %2.1f\n", |
- config.networking_config.packet_loss_probability); |
- Log(" Burst length : %d packets\n", |
- config.networking_config.packet_loss_burst_length); |
-} |
- |
-void PrintCsvOutput(const webrtc::test::Stats& stats, |
- const webrtc::test::QualityMetricsResult& ssim_result, |
- const webrtc::test::QualityMetricsResult& psnr_result) { |
- Log( |
- "\nCSV output (recommended to run with --noverbose to skip the " |
- "above output)\n"); |
- printf( |
- "frame_number encoding_successful decoding_successful " |
- "encode_return_code decode_return_code " |
- "encode_time_in_us decode_time_in_us " |
- "bit_rate_in_kbps encoded_frame_length_in_bytes frame_type " |
- "packets_dropped total_packets " |
- "ssim psnr\n"); |
- |
- for (unsigned int i = 0; i < stats.stats_.size(); ++i) { |
- const webrtc::test::FrameStatistic& f = stats.stats_[i]; |
- const webrtc::test::FrameResult& ssim = ssim_result.frames[i]; |
- const webrtc::test::FrameResult& psnr = psnr_result.frames[i]; |
- printf("%4d, %d, %d, %2d, %2d, %6d, %6d, %5d, %7" PRIuS |
- ", %d, %2d, %2" PRIuS ", %5.3f, %5.2f\n", |
- f.frame_number, f.encoding_successful, f.decoding_successful, |
- f.encode_return_code, f.decode_return_code, f.encode_time_in_us, |
- f.decode_time_in_us, f.bit_rate_in_kbps, |
- f.encoded_frame_length_in_bytes, f.frame_type, f.packets_dropped, |
- f.total_packets, ssim.value, psnr.value); |
- } |
-} |
- |
-void PrintPythonOutput(const webrtc::test::TestConfig& config, |
- const webrtc::test::Stats& stats, |
- const webrtc::test::QualityMetricsResult& ssim_result, |
- const webrtc::test::QualityMetricsResult& psnr_result) { |
- Log( |
- "\nPython output (recommended to run with --noverbose to skip the " |
- "above output)\n"); |
- printf( |
- "test_configuration = [" |
- "{'name': 'name', 'value': '%s'},\n" |
- "{'name': 'description', 'value': '%s'},\n" |
- "{'name': 'test_number', 'value': '%d'},\n" |
- "{'name': 'input_filename', 'value': '%s'},\n" |
- "{'name': 'output_filename', 'value': '%s'},\n" |
- "{'name': 'output_dir', 'value': '%s'},\n" |
- "{'name': 'packet_size_in_bytes', 'value': '%" PRIuS |
- "'},\n" |
- "{'name': 'max_payload_size_in_bytes', 'value': '%" PRIuS |
- "'},\n" |
- "{'name': 'packet_loss_mode', 'value': '%s'},\n" |
- "{'name': 'packet_loss_probability', 'value': '%f'},\n" |
- "{'name': 'packet_loss_burst_length', 'value': '%d'},\n" |
- "{'name': 'exclude_frame_types', 'value': '%s'},\n" |
- "{'name': 'frame_length_in_bytes', 'value': '%" PRIuS |
- "'},\n" |
- "{'name': 'use_single_core', 'value': '%s'},\n" |
- "{'name': 'keyframe_interval;', 'value': '%d'},\n" |
- "{'name': 'video_codec_type', 'value': '%s'},\n" |
- "{'name': 'width', 'value': '%d'},\n" |
- "{'name': 'height', 'value': '%d'},\n" |
- "{'name': 'bit_rate_in_kbps', 'value': '%d'},\n" |
- "]\n", |
- config.name.c_str(), config.description.c_str(), config.test_number, |
- config.input_filename.c_str(), config.output_filename.c_str(), |
- config.output_dir.c_str(), config.networking_config.packet_size_in_bytes, |
- config.networking_config.max_payload_size_in_bytes, |
- PacketLossModeToStr(config.networking_config.packet_loss_mode), |
- config.networking_config.packet_loss_probability, |
- config.networking_config.packet_loss_burst_length, |
- ExcludeFrameTypesToStr(config.exclude_frame_types), |
- config.frame_length_in_bytes, config.use_single_core ? "True " : "False", |
- config.keyframe_interval, |
- CodecTypeToPayloadString(config.codec_settings.codecType), |
- config.codec_settings.width, config.codec_settings.height, |
- config.codec_settings.startBitrate); |
- printf( |
- "frame_data_types = {" |
- "'frame_number': ('number', 'Frame number'),\n" |
- "'encoding_successful': ('boolean', 'Encoding successful?'),\n" |
- "'decoding_successful': ('boolean', 'Decoding successful?'),\n" |
- "'encode_time': ('number', 'Encode time (us)'),\n" |
- "'decode_time': ('number', 'Decode time (us)'),\n" |
- "'encode_return_code': ('number', 'Encode return code'),\n" |
- "'decode_return_code': ('number', 'Decode return code'),\n" |
- "'bit_rate': ('number', 'Bit rate (kbps)'),\n" |
- "'encoded_frame_length': " |
- "('number', 'Encoded frame length (bytes)'),\n" |
- "'frame_type': ('string', 'Frame type'),\n" |
- "'packets_dropped': ('number', 'Packets dropped'),\n" |
- "'total_packets': ('number', 'Total packets'),\n" |
- "'ssim': ('number', 'SSIM'),\n" |
- "'psnr': ('number', 'PSNR (dB)'),\n" |
- "}\n"); |
- printf("frame_data = ["); |
- for (unsigned int i = 0; i < stats.stats_.size(); ++i) { |
- const webrtc::test::FrameStatistic& f = stats.stats_[i]; |
- const webrtc::test::FrameResult& ssim = ssim_result.frames[i]; |
- const webrtc::test::FrameResult& psnr = psnr_result.frames[i]; |
- printf( |
- "{'frame_number': %d, " |
- "'encoding_successful': %s, 'decoding_successful': %s, " |
- "'encode_time': %d, 'decode_time': %d, " |
- "'encode_return_code': %d, 'decode_return_code': %d, " |
- "'bit_rate': %d, 'encoded_frame_length': %" PRIuS |
- ", " |
- "'frame_type': %s, 'packets_dropped': %d, " |
- "'total_packets': %" PRIuS ", 'ssim': %f, 'psnr': %f},\n", |
- f.frame_number, f.encoding_successful ? "True " : "False", |
- f.decoding_successful ? "True " : "False", f.encode_time_in_us, |
- f.decode_time_in_us, f.encode_return_code, f.decode_return_code, |
- f.bit_rate_in_kbps, f.encoded_frame_length_in_bytes, |
- f.frame_type == webrtc::kVideoFrameDelta ? "'Delta'" : "'Other'", |
- f.packets_dropped, f.total_packets, ssim.value, psnr.value); |
- } |
- printf("]\n"); |
-} |
- |
-// Runs a quality measurement on the input file supplied to the program. |
-// The input file must be in YUV format. |
-int main(int argc, char* argv[]) { |
- std::string program_name = argv[0]; |
- std::string usage = |
- "Quality test application for video comparisons.\n" |
- "Run " + |
- program_name + |
- " --help for usage.\n" |
- "Example usage:\n" + |
- program_name + |
- " --input_filename=filename.yuv --width=352 --height=288\n"; |
- |
- rtc::FlagList::SetFlagsFromCommandLine(&argc, argv, true); |
- if (FLAG_help) { |
- rtc::FlagList::Print(nullptr, false); |
- return 0; |
- } |
- |
- // Create TestConfig. |
- webrtc::test::TestConfig config; |
- |
- int return_code = HandleCommandLineFlags(&config, usage); |
- // Exit if an invalid argument is supplied. |
- if (return_code != 0) { |
- return return_code; |
- } |
- |
- PrintConfigurationSummary(config); |
- |
- webrtc::VP8Encoder* encoder = webrtc::VP8Encoder::Create(); |
- webrtc::VP8Decoder* decoder = webrtc::VP8Decoder::Create(); |
- webrtc::test::Stats stats; |
- webrtc::test::YuvFrameReaderImpl frame_reader(config.input_filename, |
- config.codec_settings.width, |
- config.codec_settings.height); |
- webrtc::test::YuvFrameWriterImpl frame_writer(config.output_filename, |
- config.codec_settings.width, |
- config.codec_settings.height); |
- frame_reader.Init(); |
- frame_writer.Init(); |
- webrtc::test::PacketReader packet_reader; |
- |
- webrtc::test::PacketManipulatorImpl packet_manipulator( |
- &packet_reader, config.networking_config, config.verbose); |
- // By default the packet manipulator is seeded with a fixed random. |
- // If disabled we must generate a new seed. |
- if (FLAG_disable_fixed_random_seed) { |
- packet_manipulator.InitializeRandomSeed(time(NULL)); |
- } |
- webrtc::test::VideoProcessor* processor = new webrtc::test::VideoProcessor( |
- encoder, decoder, &frame_reader, &frame_writer, &packet_manipulator, |
- config, &stats, nullptr /* encoded_frame_writer */, |
- nullptr /* decoded_frame_writer */); |
- processor->Init(); |
- |
- const int num_frames = frame_reader.NumberOfFrames(); |
- int frame_number = 0; |
- while (frame_number < num_frames) { |
- processor->ProcessFrame(frame_number); |
- if (frame_number % 80 == 0) { |
- Log("\n"); // make the output a bit nicer. |
- } |
- Log("."); |
- frame_number++; |
- } |
- Log("\n"); |
- Log("Processed %d frames\n", frame_number); |
- |
- // Release encoder and decoder to make sure they have finished processing. |
- processor->Release(); |
- |
- // Verify statistics are correct: |
- assert(frame_number == static_cast<int>(stats.stats_.size())); |
- |
- // Close the files before we start using them for SSIM/PSNR calculations. |
- frame_reader.Close(); |
- frame_writer.Close(); |
- |
- stats.PrintSummary(); |
- |
- webrtc::test::QualityMetricsResult ssim_result; |
- CalculateSsimVideoMetrics(&config, &ssim_result); |
- webrtc::test::QualityMetricsResult psnr_result; |
- CalculatePsnrVideoMetrics(&config, &psnr_result); |
- |
- if (FLAG_csv) { |
- PrintCsvOutput(stats, ssim_result, psnr_result); |
- } |
- if (FLAG_python) { |
- PrintPythonOutput(config, stats, ssim_result, psnr_result); |
- } |
- delete processor; |
- delete encoder; |
- delete decoder; |
- Log("Quality test finished!"); |
- return 0; |
-} |