1 /*
2  * libjingle
3  * Copyright 2010 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_WEBRTC_FAKEWEBRTCVIDEOENGINE_H_
29 #define TALK_MEDIA_WEBRTC_FAKEWEBRTCVIDEOENGINE_H_
30 
31 #include <map>
32 #include <set>
33 #include <vector>
34 
35 #include "talk/media/base/codec.h"
36 #include "talk/media/webrtc/fakewebrtccommon.h"
37 #include "talk/media/webrtc/webrtcvideodecoderfactory.h"
38 #include "talk/media/webrtc/webrtcvideoencoderfactory.h"
39 #include "webrtc/base/basictypes.h"
40 #include "webrtc/base/criticalsection.h"
41 #include "webrtc/base/gunit.h"
42 #include "webrtc/base/stringutils.h"
43 #include "webrtc/base/thread_annotations.h"
44 #include "webrtc/modules/video_coding/include/video_error_codes.h"
45 #include "webrtc/video_decoder.h"
46 #include "webrtc/video_encoder.h"
47 
48 namespace cricket {
49 
50 static const int kMinVideoBitrate = 100;
51 static const int kStartVideoBitrate = 300;
52 static const int kMaxVideoBitrate = 1000;
53 
54 // WebRtc channel id and capture id share the same number space.
55 // This is how AddRenderer(renderId, ...) is able to tell if it is adding a
56 // renderer for a channel or it is adding a renderer for a capturer.
57 static const int kViEChannelIdBase = 0;
58 static const int kViEChannelIdMax = 1000;
59 
60 // Fake class for mocking out webrtc::VideoDecoder
61 class FakeWebRtcVideoDecoder : public webrtc::VideoDecoder {
62  public:
FakeWebRtcVideoDecoder()63   FakeWebRtcVideoDecoder()
64       : num_frames_received_(0) {
65   }
66 
InitDecode(const webrtc::VideoCodec *,int32_t)67   virtual int32_t InitDecode(const webrtc::VideoCodec*, int32_t) {
68     return WEBRTC_VIDEO_CODEC_OK;
69   }
70 
Decode(const webrtc::EncodedImage &,bool,const webrtc::RTPFragmentationHeader *,const webrtc::CodecSpecificInfo *,int64_t)71   virtual int32_t Decode(const webrtc::EncodedImage&,
72                          bool,
73                          const webrtc::RTPFragmentationHeader*,
74                          const webrtc::CodecSpecificInfo*,
75                          int64_t) {
76     num_frames_received_++;
77     return WEBRTC_VIDEO_CODEC_OK;
78   }
79 
RegisterDecodeCompleteCallback(webrtc::DecodedImageCallback *)80   virtual int32_t RegisterDecodeCompleteCallback(
81       webrtc::DecodedImageCallback*) {
82     return WEBRTC_VIDEO_CODEC_OK;
83   }
84 
Release()85   virtual int32_t Release() { return WEBRTC_VIDEO_CODEC_OK; }
86 
Reset()87   virtual int32_t Reset() { return WEBRTC_VIDEO_CODEC_OK; }
88 
GetNumFramesReceived()89   int GetNumFramesReceived() const {
90     return num_frames_received_;
91   }
92 
93  private:
94   int num_frames_received_;
95 };
96 
97 // Fake class for mocking out WebRtcVideoDecoderFactory.
98 class FakeWebRtcVideoDecoderFactory : public WebRtcVideoDecoderFactory {
99  public:
FakeWebRtcVideoDecoderFactory()100   FakeWebRtcVideoDecoderFactory()
101       : num_created_decoders_(0) {
102   }
103 
CreateVideoDecoder(webrtc::VideoCodecType type)104   virtual webrtc::VideoDecoder* CreateVideoDecoder(
105       webrtc::VideoCodecType type) {
106     if (supported_codec_types_.count(type) == 0) {
107       return NULL;
108     }
109     FakeWebRtcVideoDecoder* decoder = new FakeWebRtcVideoDecoder();
110     decoders_.push_back(decoder);
111     num_created_decoders_++;
112     return decoder;
113   }
114 
DestroyVideoDecoder(webrtc::VideoDecoder * decoder)115   virtual void DestroyVideoDecoder(webrtc::VideoDecoder* decoder) {
116     decoders_.erase(
117         std::remove(decoders_.begin(), decoders_.end(), decoder),
118         decoders_.end());
119     delete decoder;
120   }
121 
AddSupportedVideoCodecType(webrtc::VideoCodecType type)122   void AddSupportedVideoCodecType(webrtc::VideoCodecType type) {
123     supported_codec_types_.insert(type);
124   }
125 
GetNumCreatedDecoders()126   int GetNumCreatedDecoders() {
127     return num_created_decoders_;
128   }
129 
decoders()130   const std::vector<FakeWebRtcVideoDecoder*>& decoders() {
131     return decoders_;
132   }
133 
134  private:
135   std::set<webrtc::VideoCodecType> supported_codec_types_;
136   std::vector<FakeWebRtcVideoDecoder*> decoders_;
137   int num_created_decoders_;
138 };
139 
140 // Fake class for mocking out webrtc::VideoEnoder
141 class FakeWebRtcVideoEncoder : public webrtc::VideoEncoder {
142  public:
FakeWebRtcVideoEncoder()143   FakeWebRtcVideoEncoder() : num_frames_encoded_(0) {}
144 
InitEncode(const webrtc::VideoCodec * codecSettings,int32_t numberOfCores,size_t maxPayloadSize)145   virtual int32_t InitEncode(const webrtc::VideoCodec* codecSettings,
146                              int32_t numberOfCores,
147                              size_t maxPayloadSize) {
148     rtc::CritScope lock(&crit_);
149     codec_settings_ = *codecSettings;
150     return WEBRTC_VIDEO_CODEC_OK;
151   }
152 
GetCodecSettings()153   webrtc::VideoCodec GetCodecSettings() {
154     rtc::CritScope lock(&crit_);
155     return codec_settings_;
156   }
157 
Encode(const webrtc::VideoFrame & inputImage,const webrtc::CodecSpecificInfo * codecSpecificInfo,const std::vector<webrtc::FrameType> * frame_types)158   virtual int32_t Encode(const webrtc::VideoFrame& inputImage,
159                          const webrtc::CodecSpecificInfo* codecSpecificInfo,
160                          const std::vector<webrtc::FrameType>* frame_types) {
161     rtc::CritScope lock(&crit_);
162     ++num_frames_encoded_;
163     return WEBRTC_VIDEO_CODEC_OK;
164   }
165 
RegisterEncodeCompleteCallback(webrtc::EncodedImageCallback * callback)166   virtual int32_t RegisterEncodeCompleteCallback(
167       webrtc::EncodedImageCallback* callback) {
168     return WEBRTC_VIDEO_CODEC_OK;
169   }
170 
Release()171   virtual int32_t Release() { return WEBRTC_VIDEO_CODEC_OK; }
172 
SetChannelParameters(uint32_t packetLoss,int64_t rtt)173   virtual int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) {
174     return WEBRTC_VIDEO_CODEC_OK;
175   }
176 
SetRates(uint32_t newBitRate,uint32_t frameRate)177   virtual int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) {
178     return WEBRTC_VIDEO_CODEC_OK;
179   }
180 
GetNumEncodedFrames()181   int GetNumEncodedFrames() {
182     rtc::CritScope lock(&crit_);
183     return num_frames_encoded_;
184   }
185 
186  private:
187   rtc::CriticalSection crit_;
188   int num_frames_encoded_ GUARDED_BY(crit_);
189   webrtc::VideoCodec codec_settings_ GUARDED_BY(crit_);
190 };
191 
192 // Fake class for mocking out WebRtcVideoEncoderFactory.
193 class FakeWebRtcVideoEncoderFactory : public WebRtcVideoEncoderFactory {
194  public:
FakeWebRtcVideoEncoderFactory()195   FakeWebRtcVideoEncoderFactory()
196       : num_created_encoders_(0), encoders_have_internal_sources_(false) {}
197 
CreateVideoEncoder(webrtc::VideoCodecType type)198   virtual webrtc::VideoEncoder* CreateVideoEncoder(
199       webrtc::VideoCodecType type) {
200     if (supported_codec_types_.count(type) == 0) {
201       return NULL;
202     }
203     FakeWebRtcVideoEncoder* encoder = new FakeWebRtcVideoEncoder();
204     encoders_.push_back(encoder);
205     num_created_encoders_++;
206     return encoder;
207   }
208 
DestroyVideoEncoder(webrtc::VideoEncoder * encoder)209   virtual void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) {
210     encoders_.erase(
211         std::remove(encoders_.begin(), encoders_.end(), encoder),
212         encoders_.end());
213     delete encoder;
214   }
215 
codecs()216   virtual const std::vector<WebRtcVideoEncoderFactory::VideoCodec>& codecs()
217       const {
218     return codecs_;
219   }
220 
EncoderTypeHasInternalSource(webrtc::VideoCodecType type)221   virtual bool EncoderTypeHasInternalSource(
222       webrtc::VideoCodecType type) const override {
223     return encoders_have_internal_sources_;
224   }
225 
set_encoders_have_internal_sources(bool internal_source)226   void set_encoders_have_internal_sources(bool internal_source) {
227     encoders_have_internal_sources_ = internal_source;
228   }
229 
AddSupportedVideoCodecType(webrtc::VideoCodecType type,const std::string & name)230   void AddSupportedVideoCodecType(webrtc::VideoCodecType type,
231                                   const std::string& name) {
232     supported_codec_types_.insert(type);
233     codecs_.push_back(
234         WebRtcVideoEncoderFactory::VideoCodec(type, name, 1280, 720, 30));
235   }
236 
GetNumCreatedEncoders()237   int GetNumCreatedEncoders() {
238     return num_created_encoders_;
239   }
240 
encoders()241   const std::vector<FakeWebRtcVideoEncoder*>& encoders() {
242     return encoders_;
243   }
244 
245  private:
246   std::set<webrtc::VideoCodecType> supported_codec_types_;
247   std::vector<WebRtcVideoEncoderFactory::VideoCodec> codecs_;
248   std::vector<FakeWebRtcVideoEncoder*> encoders_;
249   int num_created_encoders_;
250   bool encoders_have_internal_sources_;
251 };
252 
253 }  // namespace cricket
254 
255 #endif  // TALK_MEDIA_WEBRTC_FAKEWEBRTCVIDEOENGINE_H_
256