The vcm::VideoReceiver class is used by both VideoReceiveStream and the legacy api VideoCodingModule. They have different requirements, since the latter uses the old jitterbuffer and runs the code on a ProcessThread. By making a copy and trimming it down to what's actually used by VideoReceiveStream, we can drop the dependency on the old jitterbuffer, without breaking the legacy api. This should also make it easier to do follow-up refactorings to trim down the class further, and ultimately remove it. Bug: webrtc:7408 Change-Id: Iec8a167fe5d0425114b0b67a5b4c2fd5fc4fa150 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/151910 Commit-Queue: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Cr-Commit-Position: refs/heads/master@{#29108}
127 lines
4.0 KiB
C++
127 lines
4.0 KiB
C++
/*
|
|
* 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 <stddef.h>
|
|
|
|
#include <cstdint>
|
|
#include <vector>
|
|
|
|
#include "modules/video_coding/video_receiver2.h"
|
|
|
|
#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.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)
|
|
: clock_(clock),
|
|
timing_(timing),
|
|
decodedFrameCallback_(timing_, clock_),
|
|
codecDataBase_() {
|
|
decoder_thread_checker_.Detach();
|
|
}
|
|
|
|
VideoReceiver2::~VideoReceiver2() {
|
|
RTC_DCHECK_RUN_ON(&construction_thread_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_thread_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.
|
|
void VideoReceiver2::RegisterExternalDecoder(VideoDecoder* externalDecoder,
|
|
uint8_t payloadType) {
|
|
RTC_DCHECK_RUN_ON(&construction_thread_checker_);
|
|
RTC_DCHECK(!IsDecoderThreadRunning());
|
|
if (externalDecoder == nullptr) {
|
|
RTC_CHECK(codecDataBase_.DeregisterExternalDecoder(payloadType));
|
|
return;
|
|
}
|
|
codecDataBase_.RegisterExternalDecoder(externalDecoder, payloadType);
|
|
}
|
|
|
|
void VideoReceiver2::TriggerDecoderShutdown() {
|
|
RTC_DCHECK_RUN_ON(&construction_thread_checker_);
|
|
RTC_DCHECK(IsDecoderThreadRunning());
|
|
}
|
|
|
|
void VideoReceiver2::DecoderThreadStarting() {
|
|
RTC_DCHECK_RUN_ON(&construction_thread_checker_);
|
|
RTC_DCHECK(!IsDecoderThreadRunning());
|
|
#if RTC_DCHECK_IS_ON
|
|
decoder_thread_is_running_ = true;
|
|
#endif
|
|
}
|
|
|
|
void VideoReceiver2::DecoderThreadStopped() {
|
|
RTC_DCHECK_RUN_ON(&construction_thread_checker_);
|
|
RTC_DCHECK(IsDecoderThreadRunning());
|
|
#if RTC_DCHECK_IS_ON
|
|
decoder_thread_is_running_ = false;
|
|
decoder_thread_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_thread_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_->TimeInMilliseconds());
|
|
}
|
|
|
|
// Register possible receive codecs, can be called multiple times
|
|
int32_t VideoReceiver2::RegisterReceiveCodec(const VideoCodec* receiveCodec,
|
|
int32_t numberOfCores,
|
|
bool requireKeyFrame) {
|
|
RTC_DCHECK_RUN_ON(&construction_thread_checker_);
|
|
RTC_DCHECK(!IsDecoderThreadRunning());
|
|
if (receiveCodec == nullptr) {
|
|
return VCM_PARAMETER_ERROR;
|
|
}
|
|
if (!codecDataBase_.RegisterReceiveCodec(receiveCodec, numberOfCores,
|
|
requireKeyFrame)) {
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
bool VideoReceiver2::IsDecoderThreadRunning() {
|
|
#if RTC_DCHECK_IS_ON
|
|
return decoder_thread_is_running_;
|
|
#else
|
|
return true;
|
|
#endif
|
|
}
|
|
|
|
} // namespace webrtc
|