blob: a6753d2743092e1c0a3e18de73612ba6968be788 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:361/*
kjellander1afca732016-02-08 04:46:452 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:363 *
kjellander1afca732016-02-08 04:46:454 * 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.
henrike@webrtc.org28e20752013-07-10 00:45:369 */
10
kjellandera96e2d72016-02-05 07:52:2811#ifndef WEBRTC_MEDIA_BASE_FAKEVIDEORENDERER_H_
12#define WEBRTC_MEDIA_BASE_FAKEVIDEORENDERER_H_
henrike@webrtc.org28e20752013-07-10 00:45:3613
nisseaf916892017-01-10 15:44:2614#include "webrtc/api/video/video_frame.h"
nisse1509fa12016-03-23 11:05:5715#include "webrtc/media/base/videosinkinterface.h"
Edward Lemurc20978e2017-07-06 17:44:3416#include "webrtc/rtc_base/criticalsection.h"
17#include "webrtc/rtc_base/logging.h"
henrike@webrtc.org28e20752013-07-10 00:45:3618
19namespace cricket {
20
21// Faked video renderer that has a callback for actions on rendering.
nisseacd935b2016-11-11 11:55:1322class FakeVideoRenderer : public rtc::VideoSinkInterface<webrtc::VideoFrame> {
henrike@webrtc.org28e20752013-07-10 00:45:3623 public:
24 FakeVideoRenderer()
25 : errors_(0),
26 width_(0),
27 height_(0),
perkjd6c39542016-03-17 09:35:2328 rotation_(webrtc::kVideoRotation_0),
nisse306d52b2016-09-06 14:52:4029 timestamp_us_(0),
henrike@webrtc.org28e20752013-07-10 00:45:3630 num_rendered_frames_(0),
perkjd6c39542016-03-17 09:35:2331 black_frame_(false) {}
henrike@webrtc.org28e20752013-07-10 00:45:3632
nisseacd935b2016-11-11 11:55:1333 virtual void OnFrame(const webrtc::VideoFrame& frame) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:5234 rtc::CritScope cs(&crit_);
henrike@webrtc.org28e20752013-07-10 00:45:3635 // TODO(zhurunz) Check with VP8 team to see if we can remove this
nisseefec5902016-06-09 07:31:3936 // tolerance on Y values. Some unit tests produce Y values close
37 // to 16 rather than close to zero, for supposedly black frames.
38 // Largest value observed is 34, e.g., running
deadbeef1dcb1642017-03-30 04:08:1639 // PeerConnectionIntegrationTest.SendAndReceive16To9AspectRatio.
nisseefec5902016-06-09 07:31:3940 black_frame_ = CheckFrameColorYuv(0, 48, 128, 128, 128, 128, &frame);
henrike@webrtc.org28e20752013-07-10 00:45:3641 // Treat unexpected frame size as error.
henrike@webrtc.org28e20752013-07-10 00:45:3642 ++num_rendered_frames_;
nisse71a0c2f2016-04-04 07:57:2943 width_ = frame.width();
44 height_ = frame.height();
nissef3868762016-04-13 10:29:1645 rotation_ = frame.rotation();
nisse306d52b2016-09-06 14:52:4046 timestamp_us_ = frame.timestamp_us();
henrike@webrtc.org28e20752013-07-10 00:45:3647 }
48
49 int errors() const { return errors_; }
henrika@webrtc.orgaebb1ad2014-01-14 10:00:5850 int width() const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:5251 rtc::CritScope cs(&crit_);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:5852 return width_;
53 }
54 int height() const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:5255 rtc::CritScope cs(&crit_);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:5856 return height_;
57 }
perkjcaafdba2016-03-20 14:34:2958 webrtc::VideoRotation rotation() const {
Pera5092412016-02-12 12:30:5759 rtc::CritScope cs(&crit_);
60 return rotation_;
61 }
perkjd6c39542016-03-17 09:35:2362
nisse306d52b2016-09-06 14:52:4063 int64_t timestamp_us() const {
perkjd6c39542016-03-17 09:35:2364 rtc::CritScope cs(&crit_);
nisse306d52b2016-09-06 14:52:4065 return timestamp_us_;
perkjd6c39542016-03-17 09:35:2366 }
henrika@webrtc.orgaebb1ad2014-01-14 10:00:5867 int num_rendered_frames() const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:5268 rtc::CritScope cs(&crit_);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:5869 return num_rendered_frames_;
70 }
71 bool black_frame() const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:5272 rtc::CritScope cs(&crit_);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:5873 return black_frame_;
74 }
henrike@webrtc.org28e20752013-07-10 00:45:3675
henrike@webrtc.org28e20752013-07-10 00:45:3676 private:
Peter Boström0c4e06b2015-10-07 10:23:2177 static bool CheckFrameColorYuv(uint8_t y_min,
78 uint8_t y_max,
79 uint8_t u_min,
80 uint8_t u_max,
81 uint8_t v_min,
82 uint8_t v_max,
nisseacd935b2016-11-11 11:55:1383 const webrtc::VideoFrame* frame) {
nisse05654512016-04-29 09:56:0084 if (!frame || !frame->video_frame_buffer()) {
henrike@webrtc.org28e20752013-07-10 00:45:3685 return false;
86 }
Magnus Jedvert7a721e82017-06-14 09:28:0887 rtc::scoped_refptr<const webrtc::I420BufferInterface> i420_buffer =
88 frame->video_frame_buffer()->ToI420();
henrike@webrtc.org28e20752013-07-10 00:45:3689 // Y
nisse71a0c2f2016-04-04 07:57:2990 int y_width = frame->width();
91 int y_height = frame->height();
Magnus Jedvert7a721e82017-06-14 09:28:0892 const uint8_t* y_plane = i420_buffer->DataY();
Peter Boström0c4e06b2015-10-07 10:23:2193 const uint8_t* y_pos = y_plane;
Magnus Jedvert7a721e82017-06-14 09:28:0894 int32_t y_pitch = i420_buffer->StrideY();
nisse71a0c2f2016-04-04 07:57:2995 for (int i = 0; i < y_height; ++i) {
96 for (int j = 0; j < y_width; ++j) {
Peter Boström0c4e06b2015-10-07 10:23:2197 uint8_t y_value = *(y_pos + j);
henrike@webrtc.org28e20752013-07-10 00:45:3698 if (y_value < y_min || y_value > y_max) {
99 return false;
100 }
101 }
102 y_pos += y_pitch;
103 }
104 // U and V
Magnus Jedvert7a721e82017-06-14 09:28:08105 int chroma_width = i420_buffer->ChromaWidth();
106 int chroma_height = i420_buffer->ChromaHeight();
107 const uint8_t* u_plane = i420_buffer->DataU();
108 const uint8_t* v_plane = i420_buffer->DataV();
Peter Boström0c4e06b2015-10-07 10:23:21109 const uint8_t* u_pos = u_plane;
110 const uint8_t* v_pos = v_plane;
Magnus Jedvert7a721e82017-06-14 09:28:08111 int32_t u_pitch = i420_buffer->StrideU();
112 int32_t v_pitch = i420_buffer->StrideV();
nisse71a0c2f2016-04-04 07:57:29113 for (int i = 0; i < chroma_height; ++i) {
114 for (int j = 0; j < chroma_width; ++j) {
Peter Boström0c4e06b2015-10-07 10:23:21115 uint8_t u_value = *(u_pos + j);
henrike@webrtc.org28e20752013-07-10 00:45:36116 if (u_value < u_min || u_value > u_max) {
117 return false;
118 }
Peter Boström0c4e06b2015-10-07 10:23:21119 uint8_t v_value = *(v_pos + j);
henrike@webrtc.org28e20752013-07-10 00:45:36120 if (v_value < v_min || v_value > v_max) {
121 return false;
122 }
123 }
124 u_pos += u_pitch;
125 v_pos += v_pitch;
126 }
127 return true;
128 }
129
130 int errors_;
131 int width_;
132 int height_;
Pera5092412016-02-12 12:30:57133 webrtc::VideoRotation rotation_;
nisse306d52b2016-09-06 14:52:40134 int64_t timestamp_us_;
henrike@webrtc.org28e20752013-07-10 00:45:36135 int num_rendered_frames_;
136 bool black_frame_;
pbos5ad935c2016-01-25 11:52:44137 rtc::CriticalSection crit_;
henrike@webrtc.org28e20752013-07-10 00:45:36138};
139
140} // namespace cricket
141
kjellandera96e2d72016-02-05 07:52:28142#endif // WEBRTC_MEDIA_BASE_FAKEVIDEORENDERER_H_