| 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 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 int stride, | 63 int stride, |
| 64 FILE* file) { | 64 FILE* file) { |
| 65 for (int i = 0; i < height; i++, buf += stride) { | 65 for (int i = 0; i < height; i++, buf += stride) { |
| 66 if (fwrite(buf, 1, width, file) != static_cast<unsigned int>(width)) | 66 if (fwrite(buf, 1, width, file) != static_cast<unsigned int>(width)) |
| 67 return -1; | 67 return -1; |
| 68 } | 68 } |
| 69 return 0; | 69 return 0; |
| 70 } | 70 } |
| 71 | 71 |
| 72 // TODO(nisse): Belongs with the test code? | 72 // TODO(nisse): Belongs with the test code? |
| 73 int PrintVideoFrame(const VideoFrameBuffer& frame, FILE* file) { | 73 int PrintVideoFrame(const I420BufferInterface& frame, FILE* file) { |
| 74 int width = frame.width(); | 74 int width = frame.width(); |
| 75 int height = frame.height(); | 75 int height = frame.height(); |
| 76 int chroma_width = (width + 1) / 2; | 76 int chroma_width = frame.ChromaWidth(); |
| 77 int chroma_height = (height + 1) / 2; | 77 int chroma_height = frame.ChromaHeight(); |
| 78 | 78 |
| 79 if (PrintPlane(frame.DataY(), width, height, | 79 if (PrintPlane(frame.DataY(), width, height, |
| 80 frame.StrideY(), file) < 0) { | 80 frame.StrideY(), file) < 0) { |
| 81 return -1; | 81 return -1; |
| 82 } | 82 } |
| 83 if (PrintPlane(frame.DataU(), | 83 if (PrintPlane(frame.DataU(), |
| 84 chroma_width, chroma_height, | 84 chroma_width, chroma_height, |
| 85 frame.StrideU(), file) < 0) { | 85 frame.StrideU(), file) < 0) { |
| 86 return -1; | 86 return -1; |
| 87 } | 87 } |
| 88 if (PrintPlane(frame.DataV(), | 88 if (PrintPlane(frame.DataV(), |
| 89 chroma_width, chroma_height, | 89 chroma_width, chroma_height, |
| 90 frame.StrideV(), file) < 0) { | 90 frame.StrideV(), file) < 0) { |
| 91 return -1; | 91 return -1; |
| 92 } | 92 } |
| 93 return 0; | 93 return 0; |
| 94 } | 94 } |
| 95 | 95 |
| 96 int PrintVideoFrame(const VideoFrame& frame, FILE* file) { | 96 int PrintVideoFrame(const VideoFrame& frame, FILE* file) { |
| 97 return PrintVideoFrame(*frame.video_frame_buffer(), file); | 97 return PrintVideoFrame(*frame.video_frame_buffer()->ToI420(), file); |
| 98 } | 98 } |
| 99 | 99 |
| 100 int ExtractBuffer(const rtc::scoped_refptr<VideoFrameBuffer>& input_frame, | 100 int ExtractBuffer(const rtc::scoped_refptr<I420BufferInterface>& input_frame, |
| 101 size_t size, | 101 size_t size, |
| 102 uint8_t* buffer) { | 102 uint8_t* buffer) { |
| 103 RTC_DCHECK(buffer); | 103 RTC_DCHECK(buffer); |
| 104 if (!input_frame) | 104 if (!input_frame) |
| 105 return -1; | 105 return -1; |
| 106 int width = input_frame->width(); | 106 int width = input_frame->width(); |
| 107 int height = input_frame->height(); | 107 int height = input_frame->height(); |
| 108 size_t length = CalcBufferSize(VideoType::kI420, width, height); | 108 size_t length = CalcBufferSize(VideoType::kI420, width, height); |
| 109 if (size < length) { | 109 if (size < length) { |
| 110 return -1; | 110 return -1; |
| 111 } | 111 } |
| 112 | 112 |
| 113 int chroma_width = (width + 1) / 2; | 113 int chroma_width = input_frame->ChromaWidth(); |
| 114 int chroma_height = (height + 1) / 2; | 114 int chroma_height = input_frame->ChromaHeight(); |
| 115 | 115 |
| 116 libyuv::I420Copy(input_frame->DataY(), | 116 libyuv::I420Copy(input_frame->DataY(), |
| 117 input_frame->StrideY(), | 117 input_frame->StrideY(), |
| 118 input_frame->DataU(), | 118 input_frame->DataU(), |
| 119 input_frame->StrideU(), | 119 input_frame->StrideU(), |
| 120 input_frame->DataV(), | 120 input_frame->DataV(), |
| 121 input_frame->StrideV(), | 121 input_frame->StrideV(), |
| 122 buffer, width, | 122 buffer, width, |
| 123 buffer + width*height, chroma_width, | 123 buffer + width*height, chroma_width, |
| 124 buffer + width*height + chroma_width*chroma_height, | 124 buffer + width*height + chroma_width*chroma_height, |
| 125 chroma_width, | 125 chroma_width, |
| 126 width, height); | 126 width, height); |
| 127 | 127 |
| 128 return static_cast<int>(length); | 128 return static_cast<int>(length); |
| 129 } | 129 } |
| 130 | 130 |
| 131 int ExtractBuffer(const VideoFrame& input_frame, size_t size, uint8_t* buffer) { | 131 int ExtractBuffer(const VideoFrame& input_frame, size_t size, uint8_t* buffer) { |
| 132 return ExtractBuffer(input_frame.video_frame_buffer(), size, buffer); | 132 return ExtractBuffer(input_frame.video_frame_buffer()->ToI420(), size, |
| 133 buffer); |
| 133 } | 134 } |
| 134 | 135 |
| 135 int ConvertNV12ToRGB565(const uint8_t* src_frame, | 136 int ConvertNV12ToRGB565(const uint8_t* src_frame, |
| 136 uint8_t* dst_frame, | 137 uint8_t* dst_frame, |
| 137 int width, int height) { | 138 int width, int height) { |
| 138 int abs_height = (height < 0) ? -height : height; | 139 int abs_height = (height < 0) ? -height : height; |
| 139 const uint8_t* yplane = src_frame; | 140 const uint8_t* yplane = src_frame; |
| 140 const uint8_t* uvInterlaced = src_frame + (width * abs_height); | 141 const uint8_t* uvInterlaced = src_frame + (width * abs_height); |
| 141 | 142 |
| 142 return libyuv::NV12ToRGB565(yplane, width, | 143 return libyuv::NV12ToRGB565(yplane, width, |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 src_width, src_height, | 234 src_width, src_height, |
| 234 dst_width, dst_height, | 235 dst_width, dst_height, |
| 235 ConvertRotationMode(rotation), | 236 ConvertRotationMode(rotation), |
| 236 ConvertVideoType(src_video_type)); | 237 ConvertVideoType(src_video_type)); |
| 237 } | 238 } |
| 238 | 239 |
| 239 int ConvertFromI420(const VideoFrame& src_frame, | 240 int ConvertFromI420(const VideoFrame& src_frame, |
| 240 VideoType dst_video_type, | 241 VideoType dst_video_type, |
| 241 int dst_sample_size, | 242 int dst_sample_size, |
| 242 uint8_t* dst_frame) { | 243 uint8_t* dst_frame) { |
| 244 rtc::scoped_refptr<I420BufferInterface> i420_buffer = |
| 245 src_frame.video_frame_buffer()->ToI420(); |
| 243 return libyuv::ConvertFromI420( | 246 return libyuv::ConvertFromI420( |
| 244 src_frame.video_frame_buffer()->DataY(), | 247 i420_buffer->DataY(), i420_buffer->StrideY(), i420_buffer->DataU(), |
| 245 src_frame.video_frame_buffer()->StrideY(), | 248 i420_buffer->StrideU(), i420_buffer->DataV(), i420_buffer->StrideV(), |
| 246 src_frame.video_frame_buffer()->DataU(), | 249 dst_frame, dst_sample_size, src_frame.width(), src_frame.height(), |
| 247 src_frame.video_frame_buffer()->StrideU(), | |
| 248 src_frame.video_frame_buffer()->DataV(), | |
| 249 src_frame.video_frame_buffer()->StrideV(), | |
| 250 dst_frame, dst_sample_size, | |
| 251 src_frame.width(), src_frame.height(), | |
| 252 ConvertVideoType(dst_video_type)); | 250 ConvertVideoType(dst_video_type)); |
| 253 } | 251 } |
| 254 | 252 |
| 255 // Compute PSNR for an I420 frame (all planes). Can upscale test frame. | 253 // Compute PSNR for an I420 frame (all planes). Can upscale test frame. |
| 256 double I420PSNR(const VideoFrameBuffer& ref_buffer, | 254 double I420PSNR(const I420BufferInterface& ref_buffer, |
| 257 const VideoFrameBuffer& test_buffer) { | 255 const I420BufferInterface& test_buffer) { |
| 258 RTC_DCHECK_GE(ref_buffer.width(), test_buffer.width()); | 256 RTC_DCHECK_GE(ref_buffer.width(), test_buffer.width()); |
| 259 RTC_DCHECK_GE(ref_buffer.height(), test_buffer.height()); | 257 RTC_DCHECK_GE(ref_buffer.height(), test_buffer.height()); |
| 260 if ((ref_buffer.width() != test_buffer.width()) || | 258 if ((ref_buffer.width() != test_buffer.width()) || |
| 261 (ref_buffer.height() != test_buffer.height())) { | 259 (ref_buffer.height() != test_buffer.height())) { |
| 262 rtc::scoped_refptr<I420Buffer> scaled_buffer = | 260 rtc::scoped_refptr<I420Buffer> scaled_buffer = |
| 263 I420Buffer::Create(ref_buffer.width(), ref_buffer.height()); | 261 I420Buffer::Create(ref_buffer.width(), ref_buffer.height()); |
| 264 scaled_buffer->ScaleFrom(test_buffer); | 262 scaled_buffer->ScaleFrom(test_buffer); |
| 265 return I420PSNR(ref_buffer, *scaled_buffer); | 263 return I420PSNR(ref_buffer, *scaled_buffer); |
| 266 } | 264 } |
| 267 double psnr = libyuv::I420Psnr( | 265 double psnr = libyuv::I420Psnr( |
| 268 ref_buffer.DataY(), ref_buffer.StrideY(), ref_buffer.DataU(), | 266 ref_buffer.DataY(), ref_buffer.StrideY(), ref_buffer.DataU(), |
| 269 ref_buffer.StrideU(), ref_buffer.DataV(), ref_buffer.StrideV(), | 267 ref_buffer.StrideU(), ref_buffer.DataV(), ref_buffer.StrideV(), |
| 270 test_buffer.DataY(), test_buffer.StrideY(), test_buffer.DataU(), | 268 test_buffer.DataY(), test_buffer.StrideY(), test_buffer.DataU(), |
| 271 test_buffer.StrideU(), test_buffer.DataV(), test_buffer.StrideV(), | 269 test_buffer.StrideU(), test_buffer.DataV(), test_buffer.StrideV(), |
| 272 test_buffer.width(), test_buffer.height()); | 270 test_buffer.width(), test_buffer.height()); |
| 273 // LibYuv sets the max psnr value to 128, we restrict it here. | 271 // LibYuv sets the max psnr value to 128, we restrict it here. |
| 274 // In case of 0 mse in one frame, 128 can skew the results significantly. | 272 // In case of 0 mse in one frame, 128 can skew the results significantly. |
| 275 return (psnr > kPerfectPSNR) ? kPerfectPSNR : psnr; | 273 return (psnr > kPerfectPSNR) ? kPerfectPSNR : psnr; |
| 276 } | 274 } |
| 277 | 275 |
| 278 // Compute PSNR for an I420 frame (all planes) | 276 // Compute PSNR for an I420 frame (all planes) |
| 279 double I420PSNR(const VideoFrame* ref_frame, const VideoFrame* test_frame) { | 277 double I420PSNR(const VideoFrame* ref_frame, const VideoFrame* test_frame) { |
| 280 if (!ref_frame || !test_frame) | 278 if (!ref_frame || !test_frame) |
| 281 return -1; | 279 return -1; |
| 282 return I420PSNR(*ref_frame->video_frame_buffer(), | 280 return I420PSNR(*ref_frame->video_frame_buffer()->ToI420(), |
| 283 *test_frame->video_frame_buffer()); | 281 *test_frame->video_frame_buffer()->ToI420()); |
| 284 } | 282 } |
| 285 | 283 |
| 286 // Compute SSIM for an I420 frame (all planes). Can upscale test_buffer. | 284 // Compute SSIM for an I420 frame (all planes). Can upscale test_buffer. |
| 287 double I420SSIM(const VideoFrameBuffer& ref_buffer, | 285 double I420SSIM(const I420BufferInterface& ref_buffer, |
| 288 const VideoFrameBuffer& test_buffer) { | 286 const I420BufferInterface& test_buffer) { |
| 289 RTC_DCHECK_GE(ref_buffer.width(), test_buffer.width()); | 287 RTC_DCHECK_GE(ref_buffer.width(), test_buffer.width()); |
| 290 RTC_DCHECK_GE(ref_buffer.height(), test_buffer.height()); | 288 RTC_DCHECK_GE(ref_buffer.height(), test_buffer.height()); |
| 291 if ((ref_buffer.width() != test_buffer.width()) || | 289 if ((ref_buffer.width() != test_buffer.width()) || |
| 292 (ref_buffer.height() != test_buffer.height())) { | 290 (ref_buffer.height() != test_buffer.height())) { |
| 293 rtc::scoped_refptr<I420Buffer> scaled_buffer = | 291 rtc::scoped_refptr<I420Buffer> scaled_buffer = |
| 294 I420Buffer::Create(ref_buffer.width(), ref_buffer.height()); | 292 I420Buffer::Create(ref_buffer.width(), ref_buffer.height()); |
| 295 scaled_buffer->ScaleFrom(test_buffer); | 293 scaled_buffer->ScaleFrom(test_buffer); |
| 296 return I420SSIM(ref_buffer, *scaled_buffer); | 294 return I420SSIM(ref_buffer, *scaled_buffer); |
| 297 } | 295 } |
| 298 return libyuv::I420Ssim( | 296 return libyuv::I420Ssim( |
| 299 ref_buffer.DataY(), ref_buffer.StrideY(), ref_buffer.DataU(), | 297 ref_buffer.DataY(), ref_buffer.StrideY(), ref_buffer.DataU(), |
| 300 ref_buffer.StrideU(), ref_buffer.DataV(), ref_buffer.StrideV(), | 298 ref_buffer.StrideU(), ref_buffer.DataV(), ref_buffer.StrideV(), |
| 301 test_buffer.DataY(), test_buffer.StrideY(), test_buffer.DataU(), | 299 test_buffer.DataY(), test_buffer.StrideY(), test_buffer.DataU(), |
| 302 test_buffer.StrideU(), test_buffer.DataV(), test_buffer.StrideV(), | 300 test_buffer.StrideU(), test_buffer.DataV(), test_buffer.StrideV(), |
| 303 test_buffer.width(), test_buffer.height()); | 301 test_buffer.width(), test_buffer.height()); |
| 304 } | 302 } |
| 305 double I420SSIM(const VideoFrame* ref_frame, const VideoFrame* test_frame) { | 303 double I420SSIM(const VideoFrame* ref_frame, const VideoFrame* test_frame) { |
| 306 if (!ref_frame || !test_frame) | 304 if (!ref_frame || !test_frame) |
| 307 return -1; | 305 return -1; |
| 308 return I420SSIM(*ref_frame->video_frame_buffer(), | 306 return I420SSIM(*ref_frame->video_frame_buffer()->ToI420(), |
| 309 *test_frame->video_frame_buffer()); | 307 *test_frame->video_frame_buffer()->ToI420()); |
| 310 } | 308 } |
| 311 | 309 |
| 312 void NV12Scale(std::vector<uint8_t>* tmp_buffer, | 310 void NV12Scale(std::vector<uint8_t>* tmp_buffer, |
| 313 const uint8_t* src_y, int src_stride_y, | 311 const uint8_t* src_y, int src_stride_y, |
| 314 const uint8_t* src_uv, int src_stride_uv, | 312 const uint8_t* src_uv, int src_stride_uv, |
| 315 int src_width, int src_height, | 313 int src_width, int src_height, |
| 316 uint8_t* dst_y, int dst_stride_y, | 314 uint8_t* dst_y, int dst_stride_y, |
| 317 uint8_t* dst_uv, int dst_stride_uv, | 315 uint8_t* dst_uv, int dst_stride_uv, |
| 318 int dst_width, int dst_height) { | 316 int dst_width, int dst_height) { |
| 319 const int src_chroma_width = (src_width + 1) / 2; | 317 const int src_chroma_width = (src_width + 1) / 2; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 413 src_v, src_uv_width, | 411 src_v, src_uv_width, |
| 414 src_width, src_height, | 412 src_width, src_height, |
| 415 dst_y, dst_stride_y, | 413 dst_y, dst_stride_y, |
| 416 dst_u, dst_stride_u, | 414 dst_u, dst_stride_u, |
| 417 dst_v, dst_stride_v, | 415 dst_v, dst_stride_v, |
| 418 dst_width, dst_height, | 416 dst_width, dst_height, |
| 419 libyuv::kFilterBox); | 417 libyuv::kFilterBox); |
| 420 } | 418 } |
| 421 | 419 |
| 422 } // namespace webrtc | 420 } // namespace webrtc |
| OLD | NEW |