14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file. 44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <math.h> 6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <cstdio> 74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "media/cast/test/video_utility.h" 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "third_party/libyuv/include/libyuv/compare.h" 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/gfx/size.h" 114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace media { 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace cast { 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)double I420PSNR(const scoped_refptr<media::VideoFrame>& frame1, 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const scoped_refptr<media::VideoFrame>& frame2) { 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (frame1->coded_size().width() != frame2->coded_size().width() || 18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) frame1->coded_size().height() != frame2->coded_size().height()) return -1; 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return libyuv::I420Psnr( 21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) frame1->data(VideoFrame::kYPlane), frame1->stride(VideoFrame::kYPlane), 22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) frame1->data(VideoFrame::kUPlane), frame1->stride(VideoFrame::kUPlane), 23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) frame1->data(VideoFrame::kVPlane), frame1->stride(VideoFrame::kVPlane), 24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) frame2->data(VideoFrame::kYPlane), frame2->stride(VideoFrame::kYPlane), 25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) frame2->data(VideoFrame::kUPlane), frame2->stride(VideoFrame::kUPlane), 26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) frame2->data(VideoFrame::kVPlane), frame2->stride(VideoFrame::kVPlane), 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) frame1->coded_size().width(), frame1->coded_size().height()); 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void PopulateVideoFrame(VideoFrame* frame, int start_value) { 31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int width = frame->coded_size().width(); 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int height = frame->coded_size().height(); 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int half_width = (width + 1) / 2; 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int half_height = (height + 1) / 2; 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) uint8* y_plane = frame->data(VideoFrame::kYPlane); 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) uint8* u_plane = frame->data(VideoFrame::kUPlane); 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) uint8* v_plane = frame->data(VideoFrame::kVPlane); 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Set Y. 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (int i = 0; i < width * height; ++i) { 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) y_plane[i] = static_cast<uint8>(start_value + i); 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Set U. 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (int i = 0; i < half_width * half_height; ++i) { 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) u_plane[i] = static_cast<uint8>(start_value + i); 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Set V. 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (int i = 0; i < half_width * half_height; ++i) { 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) v_plane[i] = static_cast<uint8>(start_value + i); 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool PopulateVideoFrameFromFile(VideoFrame* frame, FILE* video_file) { 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int width = frame->coded_size().width(); 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int height = frame->coded_size().height(); 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int half_width = (width + 1) / 2; 59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int half_height = (height + 1) / 2; 60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) size_t frame_size = width * height + 2 * half_width * half_height; 61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) uint8* y_plane = frame->data(VideoFrame::kYPlane); 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) uint8* u_plane = frame->data(VideoFrame::kUPlane); 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) uint8* v_plane = frame->data(VideoFrame::kVPlane); 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) uint8* raw_data = new uint8[frame_size]; 66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) size_t count = fread(raw_data, 1, frame_size, video_file); 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (count != frame_size) return false; 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) memcpy(y_plane, raw_data, width * height); 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) memcpy(u_plane, raw_data + width * height, half_width * half_height); 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) memcpy(v_plane, raw_data + width * height + 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) half_width * half_height, half_width * half_height); 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delete [] raw_data; 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace cast 784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace media 79