/* * Copyright (c) 2010 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #ifndef MEDIA_ENGINE_FAKEWEBRTCVIDEOENGINE_H_ #define MEDIA_ENGINE_FAKEWEBRTCVIDEOENGINE_H_ #include #include #include #include #include "api/video_codecs/video_decoder.h" #include "api/video_codecs/video_encoder.h" #include "media/base/codec.h" #include "media/engine/webrtcvideodecoderfactory.h" #include "media/engine/webrtcvideoencoderfactory.h" #include "modules/video_coding/include/video_error_codes.h" #include "rtc_base/basictypes.h" #include "rtc_base/criticalsection.h" #include "rtc_base/gunit.h" #include "rtc_base/stringutils.h" #include "rtc_base/thread_annotations.h" namespace cricket { static const int kEventTimeoutMs = 10000; // Fake class for mocking out webrtc::VideoDecoder class FakeWebRtcVideoDecoder : public webrtc::VideoDecoder { public: FakeWebRtcVideoDecoder() : num_frames_received_(0) {} virtual int32_t InitDecode(const webrtc::VideoCodec*, int32_t) { return WEBRTC_VIDEO_CODEC_OK; } virtual int32_t Decode(const webrtc::EncodedImage&, bool, const webrtc::RTPFragmentationHeader*, const webrtc::CodecSpecificInfo*, int64_t) { num_frames_received_++; return WEBRTC_VIDEO_CODEC_OK; } virtual int32_t RegisterDecodeCompleteCallback( webrtc::DecodedImageCallback*) { return WEBRTC_VIDEO_CODEC_OK; } virtual int32_t Release() { return WEBRTC_VIDEO_CODEC_OK; } int GetNumFramesReceived() const { return num_frames_received_; } private: int num_frames_received_; }; // Fake class for mocking out WebRtcVideoDecoderFactory. class FakeWebRtcVideoDecoderFactory : public WebRtcVideoDecoderFactory { public: FakeWebRtcVideoDecoderFactory() : num_created_decoders_(0) { } virtual webrtc::VideoDecoder* CreateVideoDecoder( webrtc::VideoCodecType type) { if (supported_codec_types_.count(type) == 0) { return NULL; } FakeWebRtcVideoDecoder* decoder = new FakeWebRtcVideoDecoder(); decoders_.push_back(decoder); num_created_decoders_++; return decoder; } virtual webrtc::VideoDecoder* CreateVideoDecoderWithParams( webrtc::VideoCodecType type, VideoDecoderParams params) { params_.push_back(params); return CreateVideoDecoder(type); } virtual void DestroyVideoDecoder(webrtc::VideoDecoder* decoder) { decoders_.erase( std::remove(decoders_.begin(), decoders_.end(), decoder), decoders_.end()); delete decoder; } void AddSupportedVideoCodecType(webrtc::VideoCodecType type) { supported_codec_types_.insert(type); } int GetNumCreatedDecoders() { return num_created_decoders_; } const std::vector& decoders() { return decoders_; } const std::vector& params() { return params_; } private: std::set supported_codec_types_; std::vector decoders_; int num_created_decoders_; std::vector params_; }; // Fake class for mocking out webrtc::VideoEnoder class FakeWebRtcVideoEncoder : public webrtc::VideoEncoder { public: FakeWebRtcVideoEncoder() : init_encode_event_(false, false), num_frames_encoded_(0) {} int32_t InitEncode(const webrtc::VideoCodec* codecSettings, int32_t numberOfCores, size_t maxPayloadSize) override { rtc::CritScope lock(&crit_); codec_settings_ = *codecSettings; init_encode_event_.Set(); return WEBRTC_VIDEO_CODEC_OK; } bool WaitForInitEncode() { return init_encode_event_.Wait(kEventTimeoutMs); } webrtc::VideoCodec GetCodecSettings() { rtc::CritScope lock(&crit_); return codec_settings_; } int32_t Encode(const webrtc::VideoFrame& inputImage, const webrtc::CodecSpecificInfo* codecSpecificInfo, const std::vector* frame_types) override { rtc::CritScope lock(&crit_); ++num_frames_encoded_; init_encode_event_.Set(); return WEBRTC_VIDEO_CODEC_OK; } int32_t RegisterEncodeCompleteCallback( webrtc::EncodedImageCallback* callback) override { return WEBRTC_VIDEO_CODEC_OK; } int32_t Release() override { return WEBRTC_VIDEO_CODEC_OK; } int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) override { return WEBRTC_VIDEO_CODEC_OK; } int32_t SetRateAllocation(const webrtc::BitrateAllocation& allocation, uint32_t framerate) override { return WEBRTC_VIDEO_CODEC_OK; } int GetNumEncodedFrames() { rtc::CritScope lock(&crit_); return num_frames_encoded_; } private: rtc::CriticalSection crit_; rtc::Event init_encode_event_; int num_frames_encoded_ RTC_GUARDED_BY(crit_); webrtc::VideoCodec codec_settings_ RTC_GUARDED_BY(crit_); }; // Fake class for mocking out WebRtcVideoEncoderFactory. class FakeWebRtcVideoEncoderFactory : public WebRtcVideoEncoderFactory { public: FakeWebRtcVideoEncoderFactory() : created_video_encoder_event_(false, false), num_created_encoders_(0), encoders_have_internal_sources_(false) {} webrtc::VideoEncoder* CreateVideoEncoder( const cricket::VideoCodec& codec) override { rtc::CritScope lock(&crit_); if (!FindMatchingCodec(codecs_, codec)) return nullptr; FakeWebRtcVideoEncoder* encoder = new FakeWebRtcVideoEncoder(); encoders_.push_back(encoder); num_created_encoders_++; created_video_encoder_event_.Set(); return encoder; } bool WaitForCreatedVideoEncoders(int num_encoders) { int64_t start_offset_ms = rtc::TimeMillis(); int64_t wait_time = kEventTimeoutMs; do { if (GetNumCreatedEncoders() >= num_encoders) return true; wait_time = kEventTimeoutMs - (rtc::TimeMillis() - start_offset_ms); } while (wait_time > 0 && created_video_encoder_event_.Wait(wait_time)); return false; } void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) override { rtc::CritScope lock(&crit_); encoders_.erase( std::remove(encoders_.begin(), encoders_.end(), encoder), encoders_.end()); delete encoder; } const std::vector& supported_codecs() const override { return codecs_; } bool EncoderTypeHasInternalSource( webrtc::VideoCodecType type) const override { return encoders_have_internal_sources_; } void set_encoders_have_internal_sources(bool internal_source) { encoders_have_internal_sources_ = internal_source; } void AddSupportedVideoCodec(const cricket::VideoCodec& codec) { codecs_.push_back(codec); } void AddSupportedVideoCodecType(const std::string& name) { codecs_.push_back(cricket::VideoCodec(name)); } int GetNumCreatedEncoders() { rtc::CritScope lock(&crit_); return num_created_encoders_; } const std::vector encoders() { rtc::CritScope lock(&crit_); return encoders_; } private: rtc::CriticalSection crit_; rtc::Event created_video_encoder_event_; std::vector codecs_; std::vector encoders_ RTC_GUARDED_BY(crit_); int num_created_encoders_ RTC_GUARDED_BY(crit_); bool encoders_have_internal_sources_; }; } // namespace cricket #endif // MEDIA_ENGINE_FAKEWEBRTCVIDEOENGINE_H_