diff --git a/webrtc/modules/video_coding/main/source/codec_database.cc b/webrtc/modules/video_coding/main/source/codec_database.cc index 349791d83b..f870e86a52 100644 --- a/webrtc/modules/video_coding/main/source/codec_database.cc +++ b/webrtc/modules/video_coding/main/source/codec_database.cc @@ -101,7 +101,8 @@ VCMExtDecoderMapItem::VCMExtDecoderMapItem( } VCMCodecDataBase::VCMCodecDataBase( - VideoEncoderRateObserver* encoder_rate_observer) + VideoEncoderRateObserver* encoder_rate_observer, + VCMEncodedFrameCallback* encoded_frame_callback) : number_of_cores_(0), max_payload_size_(kDefaultPayloadSize), periodic_key_frames_(false), @@ -112,10 +113,10 @@ VCMCodecDataBase::VCMCodecDataBase( external_encoder_(NULL), internal_source_(false), encoder_rate_observer_(encoder_rate_observer), + encoded_frame_callback_(encoded_frame_callback), ptr_decoder_(NULL), dec_map_(), - dec_external_map_() { -} + dec_external_map_() {} VCMCodecDataBase::~VCMCodecDataBase() { ResetSender(); @@ -235,11 +236,9 @@ void VCMCodecDataBase::ResetSender() { } // Assuming only one registered encoder - since only one used, no need for more. -bool VCMCodecDataBase::SetSendCodec( - const VideoCodec* send_codec, - int number_of_cores, - size_t max_payload_size, - VCMEncodedFrameCallback* encoded_frame_callback) { +bool VCMCodecDataBase::SetSendCodec(const VideoCodec* send_codec, + int number_of_cores, + size_t max_payload_size) { RTC_DCHECK(send_codec); if (max_payload_size == 0) { max_payload_size = kDefaultPayloadSize; @@ -284,11 +283,7 @@ bool VCMCodecDataBase::SetSendCodec( memcpy(&send_codec_, &new_send_codec, sizeof(send_codec_)); if (!reset_required) { - encoded_frame_callback->SetPayloadType(send_codec_.plType); - if (ptr_encoder_->RegisterEncodeCallback(encoded_frame_callback) < 0) { - LOG(LS_ERROR) << "Failed to register encoded-frame callback."; - return false; - } + encoded_frame_callback_->SetPayloadType(send_codec_.plType); return true; } @@ -296,18 +291,16 @@ bool VCMCodecDataBase::SetSendCodec( DeleteEncoder(); RTC_DCHECK_EQ(encoder_payload_type_, send_codec_.plType) << "Encoder not registered for payload type " << send_codec_.plType; - ptr_encoder_.reset(new VCMGenericEncoder( - external_encoder_, encoder_rate_observer_, internal_source_)); - encoded_frame_callback->SetPayloadType(send_codec_.plType); + ptr_encoder_.reset( + new VCMGenericEncoder(external_encoder_, encoder_rate_observer_, + encoded_frame_callback_, internal_source_)); + encoded_frame_callback_->SetPayloadType(send_codec_.plType); + encoded_frame_callback_->SetInternalSource(internal_source_); if (ptr_encoder_->InitEncode(&send_codec_, number_of_cores_, max_payload_size_) < 0) { LOG(LS_ERROR) << "Failed to initialize video encoder."; DeleteEncoder(); return false; - } else if (ptr_encoder_->RegisterEncodeCallback(encoded_frame_callback) < 0) { - LOG(LS_ERROR) << "Failed to register encoded-frame callback."; - DeleteEncoder(); - return false; } // Intentionally don't check return value since the encoder registration diff --git a/webrtc/modules/video_coding/main/source/codec_database.h b/webrtc/modules/video_coding/main/source/codec_database.h index c8de46f7d3..93aa9c3ba8 100644 --- a/webrtc/modules/video_coding/main/source/codec_database.h +++ b/webrtc/modules/video_coding/main/source/codec_database.h @@ -46,7 +46,8 @@ struct VCMExtDecoderMapItem { class VCMCodecDataBase { public: - explicit VCMCodecDataBase(VideoEncoderRateObserver* encoder_rate_observer); + VCMCodecDataBase(VideoEncoderRateObserver* encoder_rate_observer, + VCMEncodedFrameCallback* encoded_frame_callback); ~VCMCodecDataBase(); // Sender Side @@ -66,8 +67,7 @@ class VCMCodecDataBase { // Returns true if the codec was successfully registered, false otherwise. bool SetSendCodec(const VideoCodec* send_codec, int number_of_cores, - size_t max_payload_size, - VCMEncodedFrameCallback* encoded_frame_callback); + size_t max_payload_size); // Gets the current send codec. Relevant for internal codecs only. // Returns true if there is a send codec, false otherwise. @@ -172,6 +172,7 @@ class VCMCodecDataBase { VideoEncoder* external_encoder_; bool internal_source_; VideoEncoderRateObserver* const encoder_rate_observer_; + VCMEncodedFrameCallback* const encoded_frame_callback_; rtc::scoped_ptr ptr_encoder_; VCMGenericDecoder* ptr_decoder_; DecoderMap dec_map_; diff --git a/webrtc/modules/video_coding/main/source/generic_encoder.cc b/webrtc/modules/video_coding/main/source/generic_encoder.cc index e3ae0dd44b..de196040f0 100644 --- a/webrtc/modules/video_coding/main/source/generic_encoder.cc +++ b/webrtc/modules/video_coding/main/source/generic_encoder.cc @@ -88,50 +88,43 @@ void CopyCodecSpecific(const CodecSpecificInfo* info, RTPVideoHeader* rtp) { //#define DEBUG_ENCODER_BIT_STREAM -VCMGenericEncoder::VCMGenericEncoder(VideoEncoder* encoder, - VideoEncoderRateObserver* rate_observer, - bool internalSource) +VCMGenericEncoder::VCMGenericEncoder( + VideoEncoder* encoder, + VideoEncoderRateObserver* rate_observer, + VCMEncodedFrameCallback* encoded_frame_callback, + bool internalSource) : encoder_(encoder), rate_observer_(rate_observer), - vcm_encoded_frame_callback_(nullptr), - encoder_params_({0, 0, 0, 0}), + vcm_encoded_frame_callback_(encoded_frame_callback), internal_source_(internalSource), + encoder_params_({0, 0, 0, 0}), rotation_(kVideoRotation_0), is_screenshare_(false) {} -VCMGenericEncoder::~VCMGenericEncoder() -{ +VCMGenericEncoder::~VCMGenericEncoder() {} + +int32_t VCMGenericEncoder::Release() { + return encoder_->Release(); } -int32_t VCMGenericEncoder::Release() -{ - { - rtc::CritScope lock(¶ms_lock_); - encoder_params_ = {0, 0, 0, 0}; - vcm_encoded_frame_callback_ = nullptr; - } +int32_t VCMGenericEncoder::InitEncode(const VideoCodec* settings, + int32_t numberOfCores, + size_t maxPayloadSize) { + { + rtc::CritScope lock(¶ms_lock_); + encoder_params_.target_bitrate = settings->startBitrate * 1000; + encoder_params_.input_frame_rate = settings->maxFramerate; + } - return encoder_->Release(); -} - -int32_t -VCMGenericEncoder::InitEncode(const VideoCodec* settings, - int32_t numberOfCores, - size_t maxPayloadSize) -{ - { - rtc::CritScope lock(¶ms_lock_); - encoder_params_.target_bitrate = settings->startBitrate * 1000; - encoder_params_.input_frame_rate = settings->maxFramerate; - } - - is_screenshare_ = settings->mode == VideoCodecMode::kScreensharing; - if (encoder_->InitEncode(settings, numberOfCores, maxPayloadSize) != 0) { - LOG(LS_ERROR) << "Failed to initialize the encoder associated with " - "payload name: " << settings->plName; - return -1; - } - return 0; + is_screenshare_ = settings->mode == VideoCodecMode::kScreensharing; + if (encoder_->InitEncode(settings, numberOfCores, maxPayloadSize) != 0) { + LOG(LS_ERROR) << "Failed to initialize the encoder associated with " + "payload name: " + << settings->plName; + return -1; + } + encoder_->RegisterEncodeCompleteCallback(vcm_encoded_frame_callback_); + return 0; } int32_t VCMGenericEncoder::Encode(const VideoFrame& inputFrame, @@ -142,12 +135,12 @@ int32_t VCMGenericEncoder::Encode(const VideoFrame& inputFrame, rotation_ = inputFrame.rotation(); - if (vcm_encoded_frame_callback_) { - // Keep track of the current frame rotation and apply to the output of the - // encoder. There might not be exact as the encoder could have one frame - // delay but it should be close enough. - vcm_encoded_frame_callback_->SetRotation(rotation_); - } + // Keep track of the current frame rotation and apply to the output of the + // encoder. There might not be exact as the encoder could have one frame delay + // but it should be close enough. + // TODO(pbos): Map from timestamp, this is racy (even if rotation_ is locked + // properly, which it isn't). More than one frame may be in the pipeline. + vcm_encoded_frame_callback_->SetRotation(rotation_); int32_t result = encoder_->Encode(inputFrame, codecSpecificInfo, &frameTypes); if (is_screenshare_ && @@ -201,14 +194,6 @@ int32_t VCMGenericEncoder::RequestFrame( return encoder_->Encode(image, NULL, &frame_types); } -int32_t -VCMGenericEncoder::RegisterEncodeCallback(VCMEncodedFrameCallback* VCMencodedFrameCallback) -{ - VCMencodedFrameCallback->SetInternalSource(internal_source_); - vcm_encoded_frame_callback_ = VCMencodedFrameCallback; - return encoder_->RegisterEncodeCompleteCallback(VCMencodedFrameCallback); -} - bool VCMGenericEncoder::InternalSource() const { diff --git a/webrtc/modules/video_coding/main/source/generic_encoder.h b/webrtc/modules/video_coding/main/source/generic_encoder.h index 5482e507d7..3a7132860f 100644 --- a/webrtc/modules/video_coding/main/source/generic_encoder.h +++ b/webrtc/modules/video_coding/main/source/generic_encoder.h @@ -87,6 +87,7 @@ class VCMGenericEncoder public: VCMGenericEncoder(VideoEncoder* encoder, VideoEncoderRateObserver* rate_observer, + VCMEncodedFrameCallback* encoded_frame_callback, bool internalSource); ~VCMGenericEncoder(); /** @@ -111,13 +112,6 @@ public: const std::vector& frameTypes); void SetEncoderParameters(const EncoderParameters& params); - /** - * Register a transport callback which will be called to deliver the encoded - * buffers - */ - int32_t RegisterEncodeCallback( - VCMEncodedFrameCallback* VCMencodedFrameCallback); - EncoderParameters GetEncoderParameters() const; int32_t SetPeriodicKeyFrames(bool enable); @@ -135,10 +129,10 @@ public: private: VideoEncoder* const encoder_; VideoEncoderRateObserver* const rate_observer_; - VCMEncodedFrameCallback* vcm_encoded_frame_callback_; - EncoderParameters encoder_params_ GUARDED_BY(params_lock_); + VCMEncodedFrameCallback* const vcm_encoded_frame_callback_; const bool internal_source_; mutable rtc::CriticalSection params_lock_; + EncoderParameters encoder_params_ GUARDED_BY(params_lock_); VideoRotation rotation_; bool is_screenshare_; }; // end of VCMGenericEncoder class diff --git a/webrtc/modules/video_coding/main/source/video_receiver.cc b/webrtc/modules/video_coding/main/source/video_receiver.cc index cf0a490da9..77c069cf2d 100644 --- a/webrtc/modules/video_coding/main/source/video_receiver.cc +++ b/webrtc/modules/video_coding/main/source/video_receiver.cc @@ -45,7 +45,7 @@ VideoReceiver::VideoReceiver(Clock* clock, EventFactory* event_factory) _scheduleKeyRequest(false), max_nack_list_size_(0), pre_decode_image_callback_(NULL), - _codecDataBase(NULL), + _codecDataBase(nullptr, nullptr), _receiveStatsTimer(1000, clock_), _retransmissionTimer(10, clock_), _keyRequestTimer(500, clock_) { diff --git a/webrtc/modules/video_coding/main/source/video_sender.cc b/webrtc/modules/video_coding/main/source/video_sender.cc index 38089f7113..98230b1e9e 100644 --- a/webrtc/modules/video_coding/main/source/video_sender.cc +++ b/webrtc/modules/video_coding/main/source/video_sender.cc @@ -35,7 +35,7 @@ VideoSender::VideoSender(Clock* clock, _nextFrameTypes(1, kVideoFrameDelta), _mediaOpt(clock_), _sendStatsCallback(nullptr), - _codecDataBase(encoder_rate_observer), + _codecDataBase(encoder_rate_observer, &_encodedFrameCallback), frame_dropper_enabled_(true), _sendStatsTimer(1000, clock_), current_codec_(), @@ -89,8 +89,8 @@ int32_t VideoSender::RegisterSendCodec(const VideoCodec* sendCodec, return VCM_PARAMETER_ERROR; } - bool ret = _codecDataBase.SetSendCodec( - sendCodec, numberOfCores, maxPayloadSize, &_encodedFrameCallback); + bool ret = + _codecDataBase.SetSendCodec(sendCodec, numberOfCores, maxPayloadSize); // Update encoder regardless of result to make sure that we're not holding on // to a deleted instance.