blob: a7c532a7d27158b0ef8a773b6c89cd08308e2e92 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * 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:36 +00009 */
10
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef MEDIA_BASE_FAKEVIDEORENDERER_H_
12#define MEDIA_BASE_FAKEVIDEORENDERER_H_
henrike@webrtc.org28e20752013-07-10 00:45:36 +000013
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "api/video/video_frame.h"
Niels Möllerc6ce9c52018-05-11 11:15:30 +020015#include "api/video/video_sink_interface.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "rtc_base/criticalsection.h"
17#include "rtc_base/logging.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000018
19namespace cricket {
20
21// Faked video renderer that has a callback for actions on rendering.
nisseacd935b2016-11-11 03:55:13 -080022class FakeVideoRenderer : public rtc::VideoSinkInterface<webrtc::VideoFrame> {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000023 public:
24 FakeVideoRenderer()
25 : errors_(0),
26 width_(0),
27 height_(0),
perkjd6c39542016-03-17 10:35:23 +010028 rotation_(webrtc::kVideoRotation_0),
nisse306d52b2016-09-06 07:52:40 -070029 timestamp_us_(0),
henrike@webrtc.org28e20752013-07-10 00:45:36 +000030 num_rendered_frames_(0),
perkjd6c39542016-03-17 10:35:23 +010031 black_frame_(false) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +000032
nisseacd935b2016-11-11 03:55:13 -080033 virtual void OnFrame(const webrtc::VideoFrame& frame) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000034 rtc::CritScope cs(&crit_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000035 // TODO(zhurunz) Check with VP8 team to see if we can remove this
nisseefec5902016-06-09 00:31:39 -070036 // 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-29 21:08:16 -070039 // PeerConnectionIntegrationTest.SendAndReceive16To9AspectRatio.
nisseefec5902016-06-09 00:31:39 -070040 black_frame_ = CheckFrameColorYuv(0, 48, 128, 128, 128, 128, &frame);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000041 // Treat unexpected frame size as error.
henrike@webrtc.org28e20752013-07-10 00:45:36 +000042 ++num_rendered_frames_;
nisse71a0c2f2016-04-04 00:57:29 -070043 width_ = frame.width();
44 height_ = frame.height();
nissef3868762016-04-13 03:29:16 -070045 rotation_ = frame.rotation();
nisse306d52b2016-09-06 07:52:40 -070046 timestamp_us_ = frame.timestamp_us();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000047 }
48
49 int errors() const { return errors_; }
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +000050 int width() const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000051 rtc::CritScope cs(&crit_);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +000052 return width_;
53 }
54 int height() const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000055 rtc::CritScope cs(&crit_);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +000056 return height_;
57 }
perkjcaafdba2016-03-20 07:34:29 -070058 webrtc::VideoRotation rotation() const {
Pera5092412016-02-12 13:30:57 +010059 rtc::CritScope cs(&crit_);
60 return rotation_;
61 }
perkjd6c39542016-03-17 10:35:23 +010062
nisse306d52b2016-09-06 07:52:40 -070063 int64_t timestamp_us() const {
perkjd6c39542016-03-17 10:35:23 +010064 rtc::CritScope cs(&crit_);
nisse306d52b2016-09-06 07:52:40 -070065 return timestamp_us_;
perkjd6c39542016-03-17 10:35:23 +010066 }
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +000067 int num_rendered_frames() const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000068 rtc::CritScope cs(&crit_);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +000069 return num_rendered_frames_;
70 }
71 bool black_frame() const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000072 rtc::CritScope cs(&crit_);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +000073 return black_frame_;
74 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000075
henrike@webrtc.org28e20752013-07-10 00:45:36 +000076 private:
Peter Boström0c4e06b2015-10-07 12:23:21 +020077 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 03:55:13 -080083 const webrtc::VideoFrame* frame) {
nisse05654512016-04-29 02:56:00 -070084 if (!frame || !frame->video_frame_buffer()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000085 return false;
86 }
Magnus Jedvert7a721e82017-06-14 11:28:08 +020087 rtc::scoped_refptr<const webrtc::I420BufferInterface> i420_buffer =
88 frame->video_frame_buffer()->ToI420();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000089 // Y
nisse71a0c2f2016-04-04 00:57:29 -070090 int y_width = frame->width();
91 int y_height = frame->height();
Magnus Jedvert7a721e82017-06-14 11:28:08 +020092 const uint8_t* y_plane = i420_buffer->DataY();
Peter Boström0c4e06b2015-10-07 12:23:21 +020093 const uint8_t* y_pos = y_plane;
Magnus Jedvert7a721e82017-06-14 11:28:08 +020094 int32_t y_pitch = i420_buffer->StrideY();
nisse71a0c2f2016-04-04 00:57:29 -070095 for (int i = 0; i < y_height; ++i) {
96 for (int j = 0; j < y_width; ++j) {
Peter Boström0c4e06b2015-10-07 12:23:21 +020097 uint8_t y_value = *(y_pos + j);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000098 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 11:28:08 +0200105 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 12:23:21 +0200109 const uint8_t* u_pos = u_plane;
110 const uint8_t* v_pos = v_plane;
Magnus Jedvert7a721e82017-06-14 11:28:08 +0200111 int32_t u_pitch = i420_buffer->StrideU();
112 int32_t v_pitch = i420_buffer->StrideV();
nisse71a0c2f2016-04-04 00:57:29 -0700113 for (int i = 0; i < chroma_height; ++i) {
114 for (int j = 0; j < chroma_width; ++j) {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200115 uint8_t u_value = *(u_pos + j);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000116 if (u_value < u_min || u_value > u_max) {
117 return false;
118 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200119 uint8_t v_value = *(v_pos + j);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000120 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 13:30:57 +0100133 webrtc::VideoRotation rotation_;
nisse306d52b2016-09-06 07:52:40 -0700134 int64_t timestamp_us_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000135 int num_rendered_frames_;
136 bool black_frame_;
pbos5ad935c2016-01-25 03:52:44 -0800137 rtc::CriticalSection crit_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000138};
139
140} // namespace cricket
141
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200142#endif // MEDIA_BASE_FAKEVIDEORENDERER_H_