Index: webrtc/common_video/libyuv/webrtc_libyuv.cc |
diff --git a/webrtc/common_video/libyuv/webrtc_libyuv.cc b/webrtc/common_video/libyuv/webrtc_libyuv.cc |
index ae8d6b1ef58ddb6cf8d4ceeab07fd1696462566d..aba0f359e995b8c6cc8ad7e588b511ee850174db 100644 |
--- a/webrtc/common_video/libyuv/webrtc_libyuv.cc |
+++ b/webrtc/common_video/libyuv/webrtc_libyuv.cc |
@@ -288,15 +288,41 @@ int ConvertFromI420(const VideoFrame& src_frame, |
ConvertVideoType(dst_video_type)); |
} |
-// Compute PSNR for an I420 frame (all planes) |
+// Compute PSNR for an I420 frame (all planes). Can upscale test frame. |
double I420PSNR(const VideoFrameBuffer& ref_buffer, |
const VideoFrameBuffer& test_buffer) { |
- if ((ref_buffer.width() != test_buffer.width()) || |
- (ref_buffer.height() != test_buffer.height())) |
+ if ((ref_buffer.width() < test_buffer.width()) || |
+ (ref_buffer.height() < test_buffer.height())) { |
return -1; |
- else if (ref_buffer.width() < 0 || ref_buffer.height() < 0) |
+ } else if (ref_buffer.width() < 0 || ref_buffer.height() < 0) { |
return -1; |
- |
+ } else if ((ref_buffer.width() > test_buffer.width()) || |
+ (ref_buffer.height() > test_buffer.height())) { |
+ rtc::scoped_refptr<I420Buffer> upscaled_buffer = |
sprang_webrtc
2017/02/09 17:10:39
Maybe you can move this declaration up to method s
ilnik
2017/02/10 10:11:43
Done.
|
+ I420Buffer::Create(ref_buffer.width(), ref_buffer.height()); |
+ int result = libyuv::I420Scale( |
sprang_webrtc
2017/02/09 17:10:39
Don't need this temporary
ilnik
2017/02/10 10:11:43
Done.
|
+ test_buffer.DataY(), test_buffer.StrideY(), test_buffer.DataU(), |
+ test_buffer.StrideU(), test_buffer.DataV(), test_buffer.StrideV(), |
+ test_buffer.width(), test_buffer.height(), |
+ upscaled_buffer->MutableDataY(), upscaled_buffer->StrideY(), |
+ upscaled_buffer->MutableDataU(), upscaled_buffer->StrideU(), |
+ upscaled_buffer->MutableDataV(), upscaled_buffer->StrideV(), |
+ upscaled_buffer->width(), upscaled_buffer->height(), |
+ libyuv::kFilterBilinear); |
+ if (result != 0) { |
+ return -1; |
+ } |
+ double psnr = libyuv::I420Psnr( |
+ ref_buffer.DataY(), ref_buffer.StrideY(), ref_buffer.DataU(), |
+ ref_buffer.StrideU(), ref_buffer.DataV(), ref_buffer.StrideV(), |
+ upscaled_buffer->DataY(), upscaled_buffer->StrideY(), |
+ upscaled_buffer->DataU(), upscaled_buffer->StrideU(), |
+ upscaled_buffer->DataV(), upscaled_buffer->StrideV(), |
+ upscaled_buffer->width(), upscaled_buffer->height()); |
+ // LibYuv sets the max psnr value to 128, we restrict it here. |
+ // In case of 0 mse in one frame, 128 can skew the results significantly. |
+ return (psnr > kPerfectPSNR) ? kPerfectPSNR : psnr; |
+ } |
double psnr = libyuv::I420Psnr(ref_buffer.DataY(), ref_buffer.StrideY(), |
ref_buffer.DataU(), ref_buffer.StrideU(), |
ref_buffer.DataV(), ref_buffer.StrideV(), |
@@ -317,15 +343,38 @@ double I420PSNR(const VideoFrame* ref_frame, const VideoFrame* test_frame) { |
*test_frame->video_frame_buffer()); |
} |
-// Compute SSIM for an I420 frame (all planes) |
+// Compute SSIM for an I420 frame (all planes). Can upscale test_buffer. |
double I420SSIM(const VideoFrameBuffer& ref_buffer, |
const VideoFrameBuffer& test_buffer) { |
- if ((ref_buffer.width() != test_buffer.width()) || |
- (ref_buffer.height() != test_buffer.height())) |
+ if ((ref_buffer.width() < test_buffer.width()) || |
+ (ref_buffer.height() < test_buffer.height())) { |
return -1; |
- else if (ref_buffer.width() < 0 || ref_buffer.height() < 0) |
+ } else if (ref_buffer.width() < 0 || ref_buffer.height() < 0) { |
return -1; |
- |
+ } else if ((ref_buffer.width() > test_buffer.width()) || |
+ (ref_buffer.height() > test_buffer.height())) { |
+ rtc::scoped_refptr<I420Buffer> upscaled_buffer = |
sprang_webrtc
2017/02/09 17:10:39
dito
ilnik
2017/02/10 10:11:43
Done.
|
+ I420Buffer::Create(ref_buffer.width(), ref_buffer.height()); |
+ int result = libyuv::I420Scale( |
+ test_buffer.DataY(), test_buffer.StrideY(), test_buffer.DataU(), |
+ test_buffer.StrideU(), test_buffer.DataV(), test_buffer.StrideV(), |
+ test_buffer.width(), test_buffer.height(), |
+ upscaled_buffer->MutableDataY(), upscaled_buffer->StrideY(), |
+ upscaled_buffer->MutableDataU(), upscaled_buffer->StrideU(), |
+ upscaled_buffer->MutableDataV(), upscaled_buffer->StrideV(), |
+ upscaled_buffer->width(), upscaled_buffer->height(), |
+ libyuv::kFilterBilinear); |
+ if (result != 0) { |
+ return -1; |
+ } |
+ return libyuv::I420Ssim( |
+ ref_buffer.DataY(), ref_buffer.StrideY(), ref_buffer.DataU(), |
+ ref_buffer.StrideU(), ref_buffer.DataV(), ref_buffer.StrideV(), |
+ upscaled_buffer->DataY(), upscaled_buffer->StrideY(), |
+ upscaled_buffer->DataU(), upscaled_buffer->StrideU(), |
+ upscaled_buffer->DataV(), upscaled_buffer->StrideV(), |
+ upscaled_buffer->width(), upscaled_buffer->height()); |
+ } |
return libyuv::I420Ssim(ref_buffer.DataY(), ref_buffer.StrideY(), |
ref_buffer.DataU(), ref_buffer.StrideU(), |
ref_buffer.DataV(), ref_buffer.StrideV(), |