| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include "webrtc/test/testsupport/metrics/video_metrics.h" | 11 #include "webrtc/test/testsupport/metrics/video_metrics.h" |
| 12 | 12 |
| 13 #include <assert.h> | 13 #include <assert.h> |
| 14 #include <stdio.h> | 14 #include <stdio.h> |
| 15 | 15 |
| 16 #include <algorithm> // min_element, max_element | 16 #include <algorithm> // min_element, max_element |
| 17 #include <memory> | 17 #include <memory> |
| 18 | 18 |
| 19 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" | 19 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" |
| 20 #include "webrtc/test/frame_utils.h" |
| 20 #include "webrtc/video_frame.h" | 21 #include "webrtc/video_frame.h" |
| 21 #include "libyuv/convert.h" | 22 #include "libyuv/convert.h" |
| 22 | 23 |
| 23 namespace webrtc { | 24 namespace webrtc { |
| 24 namespace test { | 25 namespace test { |
| 25 | 26 |
| 26 // Copy here so our callers won't need to include libyuv for this constant. | 27 // Copy here so our callers won't need to include libyuv for this constant. |
| 27 double kMetricsPerfectPSNR = kPerfectPSNR; | 28 double kMetricsPerfectPSNR = kPerfectPSNR; |
| 28 | 29 |
| 29 // Used for calculating min and max values. | 30 // Used for calculating min and max values. |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 FILE* test_fp = fopen(test_filename, "rb"); | 104 FILE* test_fp = fopen(test_filename, "rb"); |
| 104 if (test_fp == NULL) { | 105 if (test_fp == NULL) { |
| 105 // Cannot open test file. | 106 // Cannot open test file. |
| 106 fprintf(stderr, "Cannot open file %s\n", test_filename); | 107 fprintf(stderr, "Cannot open file %s\n", test_filename); |
| 107 fclose(ref_fp); | 108 fclose(ref_fp); |
| 108 return -2; | 109 return -2; |
| 109 } | 110 } |
| 110 int frame_number = 0; | 111 int frame_number = 0; |
| 111 | 112 |
| 112 // Read reference and test frames. | 113 // Read reference and test frames. |
| 113 const size_t frame_length = 3 * width * height >> 1; | 114 for (;;) { |
| 114 rtc::scoped_refptr<I420Buffer> ref_i420_buffer; | 115 rtc::scoped_refptr<I420Buffer> ref_i420_buffer( |
| 115 rtc::scoped_refptr<I420Buffer> test_i420_buffer; | 116 test::ReadI420Buffer(width, height, ref_fp)); |
| 116 std::unique_ptr<uint8_t[]> ref_buffer(new uint8_t[frame_length]); | 117 if (!ref_i420_buffer) |
| 117 std::unique_ptr<uint8_t[]> test_buffer(new uint8_t[frame_length]); | 118 break; |
| 118 | 119 |
| 119 // Set decoded image parameters. | 120 rtc::scoped_refptr<I420Buffer> test_i420_buffer( |
| 120 int half_width = (width + 1) / 2; | 121 test::ReadI420Buffer(width, height, test_fp)); |
| 121 ref_i420_buffer = | |
| 122 I420Buffer::Create(width, height, width, half_width, half_width); | |
| 123 test_i420_buffer = | |
| 124 I420Buffer::Create(width, height, width, half_width, half_width); | |
| 125 | 122 |
| 126 // TODO(nisse): Have a frame reader in one place. And read directly | 123 if (!test_i420_buffer) |
| 127 // into the planes of an I420Buffer, the extra copying below is silly. | 124 break; |
| 128 size_t ref_bytes = fread(ref_buffer.get(), 1, frame_length, ref_fp); | |
| 129 size_t test_bytes = fread(test_buffer.get(), 1, frame_length, test_fp); | |
| 130 while (ref_bytes == frame_length && test_bytes == frame_length) { | |
| 131 // Converting from buffer to plane representation. | |
| 132 size_t size_y = width * height; | |
| 133 size_t size_uv = half_width * ((height + 1) / 2); | |
| 134 libyuv::I420Copy( | |
| 135 ref_buffer.get(), width, | |
| 136 ref_buffer.get() + size_y, half_width, | |
| 137 ref_buffer.get() + size_y + size_uv, half_width, | |
| 138 ref_i420_buffer->MutableDataY(), ref_i420_buffer->StrideY(), | |
| 139 ref_i420_buffer->MutableDataU(), ref_i420_buffer->StrideU(), | |
| 140 ref_i420_buffer->MutableDataV(), ref_i420_buffer->StrideV(), | |
| 141 width, height); | |
| 142 | |
| 143 libyuv::I420Copy( | |
| 144 test_buffer.get(), width, | |
| 145 test_buffer.get() + size_y, half_width, | |
| 146 test_buffer.get() + size_y + size_uv, half_width, | |
| 147 test_i420_buffer->MutableDataY(), test_i420_buffer->StrideY(), | |
| 148 test_i420_buffer->MutableDataU(), test_i420_buffer->StrideU(), | |
| 149 test_i420_buffer->MutableDataV(), test_i420_buffer->StrideV(), | |
| 150 width, height); | |
| 151 | 125 |
| 152 switch (video_metrics_type) { | 126 switch (video_metrics_type) { |
| 153 case kPSNR: | 127 case kPSNR: |
| 154 CalculateFrame(kPSNR, *ref_i420_buffer, *test_i420_buffer, frame_number, | 128 CalculateFrame(kPSNR, *ref_i420_buffer, *test_i420_buffer, frame_number, |
| 155 psnr_result); | 129 psnr_result); |
| 156 break; | 130 break; |
| 157 case kSSIM: | 131 case kSSIM: |
| 158 CalculateFrame(kSSIM, *ref_i420_buffer, *test_i420_buffer, frame_number, | 132 CalculateFrame(kSSIM, *ref_i420_buffer, *test_i420_buffer, frame_number, |
| 159 ssim_result); | 133 ssim_result); |
| 160 break; | 134 break; |
| 161 case kBoth: | 135 case kBoth: |
| 162 CalculateFrame(kPSNR, *ref_i420_buffer, *test_i420_buffer, frame_number, | 136 CalculateFrame(kPSNR, *ref_i420_buffer, *test_i420_buffer, frame_number, |
| 163 psnr_result); | 137 psnr_result); |
| 164 CalculateFrame(kSSIM, *ref_i420_buffer, *test_i420_buffer, frame_number, | 138 CalculateFrame(kSSIM, *ref_i420_buffer, *test_i420_buffer, frame_number, |
| 165 ssim_result); | 139 ssim_result); |
| 166 break; | 140 break; |
| 167 } | 141 } |
| 168 frame_number++; | 142 frame_number++; |
| 169 ref_bytes = fread(ref_buffer.get(), 1, frame_length, ref_fp); | |
| 170 test_bytes = fread(test_buffer.get(), 1, frame_length, test_fp); | |
| 171 } | 143 } |
| 172 int return_code = 0; | 144 int return_code = 0; |
| 173 if (frame_number == 0) { | 145 if (frame_number == 0) { |
| 174 fprintf(stderr, "Tried to measure video metrics from empty files " | 146 fprintf(stderr, "Tried to measure video metrics from empty files " |
| 175 "(reference file: %s test file: %s)\n", ref_filename, | 147 "(reference file: %s test file: %s)\n", ref_filename, |
| 176 test_filename); | 148 test_filename); |
| 177 return_code = -3; | 149 return_code = -3; |
| 178 } else { | 150 } else { |
| 179 CalculateStats(psnr_result); | 151 CalculateStats(psnr_result); |
| 180 CalculateStats(ssim_result); | 152 CalculateStats(ssim_result); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 211 int width, | 183 int width, |
| 212 int height, | 184 int height, |
| 213 QualityMetricsResult* result) { | 185 QualityMetricsResult* result) { |
| 214 assert(result != NULL); | 186 assert(result != NULL); |
| 215 return CalculateMetrics(kSSIM, ref_filename, test_filename, width, height, | 187 return CalculateMetrics(kSSIM, ref_filename, test_filename, width, height, |
| 216 NULL, result); | 188 NULL, result); |
| 217 } | 189 } |
| 218 | 190 |
| 219 } // namespace test | 191 } // namespace test |
| 220 } // namespace webrtc | 192 } // namespace webrtc |
| OLD | NEW |