1 /* 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 #include "webrtc/test/frame_generator.h" 11 12 #include <math.h> 13 #include <stdio.h> 14 #include <string.h> 15 16 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" 17 18 namespace webrtc { 19 namespace test { 20 namespace { 21 22 class ChromaGenerator : public FrameGenerator { 23 public: 24 ChromaGenerator(size_t width, size_t height) 25 : angle_(0.0), width_(width), height_(height) { 26 assert(width > 0); 27 assert(height > 0); 28 } 29 30 virtual I420VideoFrame* NextFrame() OVERRIDE { 31 frame_.CreateEmptyFrame(static_cast<int>(width_), 32 static_cast<int>(height_), 33 static_cast<int>(width_), 34 static_cast<int>((width_ + 1) / 2), 35 static_cast<int>((width_ + 1) / 2)); 36 angle_ += 30.0; 37 uint8_t u = fabs(sin(angle_)) * 0xFF; 38 uint8_t v = fabs(cos(angle_)) * 0xFF; 39 40 memset(frame_.buffer(kYPlane), 0x80, frame_.allocated_size(kYPlane)); 41 memset(frame_.buffer(kUPlane), u, frame_.allocated_size(kUPlane)); 42 memset(frame_.buffer(kVPlane), v, frame_.allocated_size(kVPlane)); 43 return &frame_; 44 } 45 46 private: 47 double angle_; 48 size_t width_; 49 size_t height_; 50 I420VideoFrame frame_; 51 }; 52 53 class YuvFileGenerator : public FrameGenerator { 54 public: 55 YuvFileGenerator(FILE* file, size_t width, size_t height) 56 : file_(file), width_(width), height_(height) { 57 assert(file); 58 assert(width > 0); 59 assert(height > 0); 60 frame_size_ = CalcBufferSize( 61 kI420, static_cast<int>(width_), static_cast<int>(height_)); 62 frame_buffer_ = new uint8_t[frame_size_]; 63 } 64 65 virtual ~YuvFileGenerator() { 66 fclose(file_); 67 delete[] frame_buffer_; 68 } 69 70 virtual I420VideoFrame* NextFrame() OVERRIDE { 71 size_t count = fread(frame_buffer_, 1, frame_size_, file_); 72 if (count < frame_size_) { 73 rewind(file_); 74 return NextFrame(); 75 } 76 77 frame_.CreateEmptyFrame(static_cast<int>(width_), 78 static_cast<int>(height_), 79 static_cast<int>(width_), 80 static_cast<int>((width_ + 1) / 2), 81 static_cast<int>((width_ + 1) / 2)); 82 83 ConvertToI420(kI420, 84 frame_buffer_, 85 0, 86 0, 87 static_cast<int>(width_), 88 static_cast<int>(height_), 89 0, 90 kRotateNone, 91 &frame_); 92 return &frame_; 93 } 94 95 private: 96 FILE* file_; 97 size_t width_; 98 size_t height_; 99 size_t frame_size_; 100 uint8_t* frame_buffer_; 101 I420VideoFrame frame_; 102 }; 103 } // namespace 104 105 FrameGenerator* FrameGenerator::Create(size_t width, size_t height) { 106 return new ChromaGenerator(width, height); 107 } 108 109 FrameGenerator* FrameGenerator::CreateFromYuvFile(const char* file, 110 size_t width, 111 size_t height) { 112 FILE* file_handle = fopen(file, "rb"); 113 assert(file_handle); 114 return new YuvFileGenerator(file_handle, width, height); 115 } 116 117 } // namespace test 118 } // namespace webrtc 119