Adding SSIM and PSNR videoFrame based functions
Review URL: https://webrtc-codereview.appspot.com/867005 git-svn-id: http://webrtc.googlecode.com/svn/trunk@2871 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
f9a0713866
commit
3f9a721da5
@ -139,10 +139,18 @@ int MirrorI420UpDown(const VideoFrame* src_frame,
|
||||
VideoFrame* dst_frame);
|
||||
|
||||
// Compute PSNR for an I420 frame (all planes).
|
||||
double I420PSNR(const VideoFrame* ref_frame,
|
||||
const VideoFrame* test_frame);
|
||||
// Compute SSIM for an I420 frame (all planes).
|
||||
double I420SSIM(const VideoFrame* ref_frame,
|
||||
const VideoFrame* test_frame);
|
||||
|
||||
// TODO(mikhal): Remove these functions and keep only the above functionality.
|
||||
// Compute PSNR for an I420 buffer (all planes).
|
||||
double I420PSNR(const uint8_t* ref_frame,
|
||||
const uint8_t* test_frame,
|
||||
int width, int height);
|
||||
// Compute SSIM for an I420 frame (all planes).
|
||||
// Compute SSIM for an I420 buffer (all planes).
|
||||
double I420SSIM(const uint8_t* ref_frame,
|
||||
const uint8_t* test_frame,
|
||||
int width, int height);
|
||||
|
@ -158,8 +158,7 @@ TEST_F(TestLibYuv, ConvertTest) {
|
||||
output_file) != static_cast<unsigned int>(frame_length_)) {
|
||||
return;
|
||||
}
|
||||
psnr = I420PSNR(orig_frame.Buffer(), res_i420_frame.Buffer(),
|
||||
width_, height_);
|
||||
psnr = I420PSNR(&orig_frame, &res_i420_frame);
|
||||
// Optimization Speed- quality trade-off => 45 dB only (platform dependant).
|
||||
EXPECT_GT(ceil(psnr), 44);
|
||||
j++;
|
||||
@ -171,8 +170,7 @@ TEST_F(TestLibYuv, ConvertTest) {
|
||||
kUYVY, 0, out_uyvy_buffer));
|
||||
EXPECT_EQ(0, ConvertToI420(kUYVY, out_uyvy_buffer, 0, 0, width_, height_,
|
||||
0, kRotateNone, &res_i420_frame));
|
||||
psnr = I420PSNR(orig_frame.Buffer(), res_i420_frame.Buffer(),
|
||||
width_, height_);
|
||||
psnr = I420PSNR(&orig_frame, &res_i420_frame);
|
||||
EXPECT_EQ(48.0, psnr);
|
||||
if (fwrite(res_i420_frame.Buffer(), 1, frame_length_,
|
||||
output_file) != static_cast<unsigned int>(frame_length_)) {
|
||||
@ -211,8 +209,7 @@ TEST_F(TestLibYuv, ConvertTest) {
|
||||
return;
|
||||
}
|
||||
|
||||
psnr = I420PSNR(orig_frame.Buffer(), res_i420_frame.Buffer(),
|
||||
width_, height_);
|
||||
psnr = I420PSNR(&orig_frame, &res_i420_frame);
|
||||
EXPECT_EQ(48.0, psnr);
|
||||
j++;
|
||||
delete [] outYV120Buffer;
|
||||
@ -229,8 +226,7 @@ TEST_F(TestLibYuv, ConvertTest) {
|
||||
output_file) != static_cast<unsigned int>(frame_length_)) {
|
||||
return;
|
||||
}
|
||||
psnr = I420PSNR(orig_frame.Buffer(), res_i420_frame.Buffer(),
|
||||
width_, height_);
|
||||
psnr = I420PSNR(&orig_frame, &res_i420_frame);
|
||||
EXPECT_EQ(48.0, psnr);
|
||||
|
||||
// printf("\nConvert #%d I420 <-> RGB565\n", j);
|
||||
@ -245,8 +241,7 @@ TEST_F(TestLibYuv, ConvertTest) {
|
||||
output_file) != static_cast<unsigned int>(frame_length_)) {
|
||||
return;
|
||||
}
|
||||
psnr = I420PSNR(orig_frame.Buffer(), res_i420_frame.Buffer(),
|
||||
width_, height_);
|
||||
psnr = I420PSNR(&orig_frame, &res_i420_frame);
|
||||
// TODO(leozwang) Investigate the right psnr should be set for I420ToRGB565,
|
||||
// Another example is I420ToRGB24, the psnr is 44
|
||||
EXPECT_GT(ceil(psnr), 40);
|
||||
@ -263,8 +258,7 @@ TEST_F(TestLibYuv, ConvertTest) {
|
||||
output_file) != static_cast<unsigned int>(frame_length_)) {
|
||||
return;
|
||||
}
|
||||
psnr = I420PSNR(orig_frame.Buffer(), res_i420_frame.Buffer(),
|
||||
width_, height_);
|
||||
psnr = I420PSNR(&orig_frame, &res_i420_frame);
|
||||
// TODO(leozwang) Investigate the right psnr should be set for I420ToARGB8888,
|
||||
EXPECT_GT(ceil(psnr), 42);
|
||||
|
||||
|
@ -284,6 +284,69 @@ int MirrorI420UpDown(const VideoFrame* src_frame,
|
||||
width, -height);
|
||||
}
|
||||
|
||||
// Compute PSNR for an I420 frame (all planes)
|
||||
double I420PSNR(const VideoFrame* ref_frame,
|
||||
const VideoFrame* test_frame) {
|
||||
if (!ref_frame || !test_frame)
|
||||
return -1;
|
||||
else if ((ref_frame->Width() != test_frame->Width()) ||
|
||||
(ref_frame->Height() != test_frame->Height()))
|
||||
return -1;
|
||||
else if (ref_frame->Width() == 0u || ref_frame->Height() == 0u)
|
||||
return -1;
|
||||
int height = ref_frame->Height() ;
|
||||
int width = ref_frame->Width();
|
||||
int half_width = (width + 1) >> 1;
|
||||
int half_height = (height + 1) >> 1;
|
||||
const uint8_t* src_y_a = ref_frame->Buffer();
|
||||
const uint8_t* src_u_a = src_y_a + width * height;
|
||||
const uint8_t* src_v_a = src_u_a + half_width * half_height;
|
||||
const uint8_t* src_y_b = test_frame->Buffer();
|
||||
const uint8_t* src_u_b = src_y_b + width * height;
|
||||
const uint8_t* src_v_b = src_u_b + half_width * half_height;
|
||||
// In the following: stride is determined by width.
|
||||
double psnr = libyuv::I420Psnr(src_y_a, width,
|
||||
src_u_a, half_width,
|
||||
src_v_a, half_width,
|
||||
src_y_b, width,
|
||||
src_u_b, half_width,
|
||||
src_v_b, half_width,
|
||||
width, height);
|
||||
// LibYuv sets the max psnr value to 128, we restrict it to 48.
|
||||
// In case of 0 mse in one frame, 128 can skew the results significantly.
|
||||
return (psnr > 48.0) ? 48.0 : psnr;
|
||||
}
|
||||
// Compute SSIM for an I420 frame (all planes)
|
||||
double I420SSIM(const VideoFrame* ref_frame,
|
||||
const VideoFrame* test_frame) {
|
||||
if (!ref_frame || !test_frame)
|
||||
return -1;
|
||||
else if ((ref_frame->Width() != test_frame->Width()) ||
|
||||
(ref_frame->Height() != test_frame->Height()))
|
||||
return -1;
|
||||
else if (ref_frame->Width() == 0u || ref_frame->Height() == 0u)
|
||||
return -1;
|
||||
int height = ref_frame->Height() ;
|
||||
int width = ref_frame->Width();
|
||||
int half_width = (width + 1) >> 1;
|
||||
int half_height = (height + 1) >> 1;
|
||||
const uint8_t* src_y_a = ref_frame->Buffer();
|
||||
const uint8_t* src_u_a = src_y_a + width * height;
|
||||
const uint8_t* src_v_a = src_u_a + half_width * half_height;
|
||||
const uint8_t* src_y_b = test_frame->Buffer();
|
||||
const uint8_t* src_u_b = src_y_b + width * height;
|
||||
const uint8_t* src_v_b = src_u_b + half_width * half_height;
|
||||
int stride_y = width;
|
||||
int stride_uv = half_width;
|
||||
return libyuv::I420Ssim(src_y_a, stride_y,
|
||||
src_u_a, stride_uv,
|
||||
src_v_a, stride_uv,
|
||||
src_y_b, stride_y,
|
||||
src_u_b, stride_uv,
|
||||
src_v_b, stride_uv,
|
||||
width, height);
|
||||
}
|
||||
|
||||
// Compute PSNR for an I420 frame (all planes)
|
||||
double I420PSNR(const uint8_t* ref_frame,
|
||||
const uint8_t* test_frame,
|
||||
|
Loading…
x
Reference in New Issue
Block a user