diff options
Diffstat (limited to 'third_party/libwebrtc/modules/video_coding/video_receiver2.cc')
-rw-r--r-- | third_party/libwebrtc/modules/video_coding/video_receiver2.cc | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/third_party/libwebrtc/modules/video_coding/video_receiver2.cc b/third_party/libwebrtc/modules/video_coding/video_receiver2.cc new file mode 100644 index 0000000000..2e100209e8 --- /dev/null +++ b/third_party/libwebrtc/modules/video_coding/video_receiver2.cc @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2013 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. + */ + +#include "modules/video_coding/video_receiver2.h" + +#include <stddef.h> + +#include <cstdint> +#include <vector> + +#include "api/video_codecs/video_codec.h" +#include "api/video_codecs/video_decoder.h" +#include "modules/video_coding/decoder_database.h" +#include "modules/video_coding/encoded_frame.h" +#include "modules/video_coding/generic_decoder.h" +#include "modules/video_coding/include/video_coding_defines.h" +#include "modules/video_coding/timing/timing.h" +#include "rtc_base/checks.h" +#include "rtc_base/trace_event.h" +#include "system_wrappers/include/clock.h" + +namespace webrtc { + +VideoReceiver2::VideoReceiver2(Clock* clock, + VCMTiming* timing, + const FieldTrialsView& field_trials) + : clock_(clock), + timing_(timing), + decodedFrameCallback_(timing_, clock_, field_trials), + codecDataBase_() { + decoder_sequence_checker_.Detach(); +} + +VideoReceiver2::~VideoReceiver2() { + RTC_DCHECK_RUN_ON(&construction_sequence_checker_); +} + +// Register a receive callback. Will be called whenever there is a new frame +// ready for rendering. +int32_t VideoReceiver2::RegisterReceiveCallback( + VCMReceiveCallback* receiveCallback) { + RTC_DCHECK_RUN_ON(&construction_sequence_checker_); + RTC_DCHECK(!IsDecoderThreadRunning()); + // This value is set before the decoder thread starts and unset after + // the decoder thread has been stopped. + decodedFrameCallback_.SetUserReceiveCallback(receiveCallback); + return VCM_OK; +} + +// Register an externally defined decoder object. This may be called on either +// the construction sequence or the decoder sequence to allow for lazy creation +// of video decoders. If called on the decoder sequence `externalDecoder` cannot +// be a nullptr. It's the responsibility of the caller to make sure that the +// access from the two sequences are mutually exclusive. +void VideoReceiver2::RegisterExternalDecoder(VideoDecoder* externalDecoder, + uint8_t payloadType) { + if (IsDecoderThreadRunning()) { + RTC_DCHECK_RUN_ON(&decoder_sequence_checker_); + // Don't allow deregistering decoders on the decoder thread. + RTC_DCHECK(externalDecoder != nullptr); + } else { + RTC_DCHECK_RUN_ON(&construction_sequence_checker_); + } + + if (externalDecoder == nullptr) { + codecDataBase_.DeregisterExternalDecoder(payloadType); + return; + } + codecDataBase_.RegisterExternalDecoder(payloadType, externalDecoder); +} + +bool VideoReceiver2::IsExternalDecoderRegistered(uint8_t payloadType) const { + RTC_DCHECK_RUN_ON(&decoder_sequence_checker_); + return codecDataBase_.IsExternalDecoderRegistered(payloadType); +} + +void VideoReceiver2::DecoderThreadStarting() { + RTC_DCHECK_RUN_ON(&construction_sequence_checker_); + RTC_DCHECK(!IsDecoderThreadRunning()); +#if RTC_DCHECK_IS_ON + decoder_thread_is_running_ = true; +#endif +} + +void VideoReceiver2::DecoderThreadStopped() { + RTC_DCHECK_RUN_ON(&construction_sequence_checker_); + RTC_DCHECK(IsDecoderThreadRunning()); +#if RTC_DCHECK_IS_ON + decoder_thread_is_running_ = false; + decoder_sequence_checker_.Detach(); +#endif +} + +// Must be called from inside the receive side critical section. +int32_t VideoReceiver2::Decode(const VCMEncodedFrame* frame) { + RTC_DCHECK_RUN_ON(&decoder_sequence_checker_); + TRACE_EVENT0("webrtc", "VideoReceiver2::Decode"); + // Change decoder if payload type has changed + VCMGenericDecoder* decoder = + codecDataBase_.GetDecoder(*frame, &decodedFrameCallback_); + if (decoder == nullptr) { + return VCM_NO_CODEC_REGISTERED; + } + return decoder->Decode(*frame, clock_->CurrentTime()); +} + +// Register possible receive codecs, can be called multiple times +void VideoReceiver2::RegisterReceiveCodec( + uint8_t payload_type, + const VideoDecoder::Settings& settings) { + RTC_DCHECK_RUN_ON(&construction_sequence_checker_); + RTC_DCHECK(!IsDecoderThreadRunning()); + codecDataBase_.RegisterReceiveCodec(payload_type, settings); +} + +bool VideoReceiver2::IsDecoderThreadRunning() { +#if RTC_DCHECK_IS_ON + return decoder_thread_is_running_; +#else + return true; +#endif +} + +} // namespace webrtc |