1 /* 2 * libjingle 3 * Copyright 2011 Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef TALK_MEDIA_BASE_FAKEVIDEORENDERER_H_ 29 #define TALK_MEDIA_BASE_FAKEVIDEORENDERER_H_ 30 31 #include "talk/base/sigslot.h" 32 #include "talk/media/base/videoframe.h" 33 #include "talk/media/base/videorenderer.h" 34 35 namespace cricket { 36 37 // Faked video renderer that has a callback for actions on rendering. 38 class FakeVideoRenderer : public VideoRenderer { 39 public: 40 FakeVideoRenderer() 41 : errors_(0), 42 width_(0), 43 height_(0), 44 num_set_sizes_(0), 45 num_rendered_frames_(0), 46 black_frame_(false) { 47 } 48 49 virtual bool SetSize(int width, int height, int reserved) { 50 width_ = width; 51 height_ = height; 52 ++num_set_sizes_; 53 SignalSetSize(width, height, reserved); 54 return true; 55 } 56 57 virtual bool RenderFrame(const VideoFrame* frame) { 58 // TODO(zhurunz) Check with VP8 team to see if we can remove this 59 // tolerance on Y values. 60 black_frame_ = CheckFrameColorYuv(6, 48, 128, 128, 128, 128, frame); 61 // Treat unexpected frame size as error. 62 if (!frame || 63 frame->GetWidth() != static_cast<size_t>(width_) || 64 frame->GetHeight() != static_cast<size_t>(height_)) { 65 ++errors_; 66 return false; 67 } 68 ++num_rendered_frames_; 69 SignalRenderFrame(frame); 70 return true; 71 } 72 73 int errors() const { return errors_; } 74 int width() const { return width_; } 75 int height() const { return height_; } 76 int num_set_sizes() const { return num_set_sizes_; } 77 int num_rendered_frames() const { return num_rendered_frames_; } 78 bool black_frame() const { return black_frame_; } 79 80 sigslot::signal3<int, int, int> SignalSetSize; 81 sigslot::signal1<const VideoFrame*> SignalRenderFrame; 82 83 private: 84 static bool CheckFrameColorYuv(uint8 y_min, uint8 y_max, 85 uint8 u_min, uint8 u_max, 86 uint8 v_min, uint8 v_max, 87 const cricket::VideoFrame* frame) { 88 if (!frame) { 89 return false; 90 } 91 // Y 92 size_t y_width = frame->GetWidth(); 93 size_t y_height = frame->GetHeight(); 94 const uint8* y_plane = frame->GetYPlane(); 95 const uint8* y_pos = y_plane; 96 int32 y_pitch = frame->GetYPitch(); 97 for (size_t i = 0; i < y_height; ++i) { 98 for (size_t j = 0; j < y_width; ++j) { 99 uint8 y_value = *(y_pos + j); 100 if (y_value < y_min || y_value > y_max) { 101 return false; 102 } 103 } 104 y_pos += y_pitch; 105 } 106 // U and V 107 size_t chroma_width = frame->GetChromaWidth(); 108 size_t chroma_height = frame->GetChromaHeight(); 109 const uint8* u_plane = frame->GetUPlane(); 110 const uint8* v_plane = frame->GetVPlane(); 111 const uint8* u_pos = u_plane; 112 const uint8* v_pos = v_plane; 113 int32 u_pitch = frame->GetUPitch(); 114 int32 v_pitch = frame->GetVPitch(); 115 for (size_t i = 0; i < chroma_height; ++i) { 116 for (size_t j = 0; j < chroma_width; ++j) { 117 uint8 u_value = *(u_pos + j); 118 if (u_value < u_min || u_value > u_max) { 119 return false; 120 } 121 uint8 v_value = *(v_pos + j); 122 if (v_value < v_min || v_value > v_max) { 123 return false; 124 } 125 } 126 u_pos += u_pitch; 127 v_pos += v_pitch; 128 } 129 return true; 130 } 131 132 int errors_; 133 int width_; 134 int height_; 135 int num_set_sizes_; 136 int num_rendered_frames_; 137 bool black_frame_; 138 }; 139 140 } // namespace cricket 141 142 #endif // TALK_MEDIA_BASE_FAKEVIDEORENDERER_H_ 143