New class VideoReceiver2, a trimmed-down vcm::VideoReceiver

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}
This commit is contained in:
Niels Möller 2019-09-09 12:51:55 +02:00 committed by Commit Bot
parent 4d6b2691bd
commit ee3d995091
6 changed files with 212 additions and 11 deletions

View File

@ -140,6 +140,8 @@ rtc_static_library("video_coding") {
"video_coding_impl.cc",
"video_coding_impl.h",
"video_receiver.cc",
"video_receiver2.cc",
"video_receiver2.h",
]
deps += [

View File

@ -0,0 +1,126 @@
/*
* 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

View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2019 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 MODULES_VIDEO_CODING_VIDEO_RECEIVER2_H_
#define MODULES_VIDEO_CODING_VIDEO_RECEIVER2_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/timing.h"
#include "rtc_base/thread_checker.h"
#include "system_wrappers/include/clock.h"
namespace webrtc {
// This class is a copy of vcm::VideoReceiver, trimmed down to what's used by
// VideoReceive stream, with the aim to incrementally trim it down further and
// ultimately delete it. It's difficult to do this incrementally with the
// original VideoReceiver class, since it is used by the legacy
// VideoCodingModule api.
class VideoReceiver2 {
public:
VideoReceiver2(Clock* clock, VCMTiming* timing);
~VideoReceiver2();
int32_t RegisterReceiveCodec(const VideoCodec* receiveCodec,
int32_t numberOfCores,
bool requireKeyFrame);
void RegisterExternalDecoder(VideoDecoder* externalDecoder,
uint8_t payloadType);
int32_t RegisterReceiveCallback(VCMReceiveCallback* receiveCallback);
int32_t Decode(const webrtc::VCMEncodedFrame* frame);
void TriggerDecoderShutdown();
// Notification methods that are used to check our internal state and validate
// threading assumptions. These are called by VideoReceiveStream.
// See |IsDecoderThreadRunning()| for more details.
void DecoderThreadStarting();
void DecoderThreadStopped();
private:
// Used for DCHECKing thread correctness.
// In build where DCHECKs are enabled, will return false before
// DecoderThreadStarting is called, then true until DecoderThreadStopped
// is called.
// In builds where DCHECKs aren't enabled, it will return true.
bool IsDecoderThreadRunning();
rtc::ThreadChecker construction_thread_checker_;
rtc::ThreadChecker decoder_thread_checker_;
Clock* const clock_;
VCMTiming* timing_;
VCMDecodedFrameCallback decodedFrameCallback_;
// Callbacks are set before the decoder thread starts.
// Once the decoder thread has been started, usage of |_codecDataBase| moves
// over to the decoder thread.
VCMDecoderDataBase codecDataBase_;
#if RTC_DCHECK_IS_ON
bool decoder_thread_is_running_ = false;
#endif
};
} // namespace webrtc
#endif // MODULES_VIDEO_CODING_VIDEO_RECEIVER2_H_

View File

@ -22,7 +22,7 @@
#include "modules/rtp_rtcp/include/flexfec_receiver.h"
#include "modules/rtp_rtcp/source/source_tracker.h"
#include "modules/video_coding/frame_buffer2.h"
#include "modules/video_coding/video_coding_impl.h"
#include "modules/video_coding/video_receiver2.h"
#include "rtc_base/synchronization/sequence_checker.h"
#include "rtc_base/task_queue.h"
#include "system_wrappers/include/clock.h"
@ -173,7 +173,7 @@ class VideoReceiveStream : public webrtc::VideoReceiveStream,
const std::unique_ptr<ReceiveStatistics> rtp_receive_statistics_;
std::unique_ptr<VCMTiming> timing_; // Jitter buffer experiment.
vcm::VideoReceiver video_receiver_;
VideoReceiver2 video_receiver_;
std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>> incoming_video_stream_;
RtpVideoStreamReceiver rtp_video_stream_receiver_;
std::unique_ptr<VideoStreamDecoder> video_stream_decoder_;

View File

@ -10,15 +10,14 @@
#include "video/video_stream_decoder.h"
#include "modules/video_coding/include/video_coding.h"
#include "modules/video_coding/video_coding_impl.h"
#include "modules/video_coding/video_receiver2.h"
#include "rtc_base/checks.h"
#include "video/receive_statistics_proxy.h"
namespace webrtc {
VideoStreamDecoder::VideoStreamDecoder(
vcm::VideoReceiver* video_receiver,
VideoReceiver2* video_receiver,
ReceiveStatisticsProxy* receive_statistics_proxy,
rtc::VideoSinkInterface<VideoFrame>* incoming_video_stream)
: video_receiver_(video_receiver),

View File

@ -26,15 +26,12 @@
namespace webrtc {
class ReceiveStatisticsProxy;
namespace vcm {
class VideoReceiver;
} // namespace vcm
class VideoReceiver2;
class VideoStreamDecoder : public VCMReceiveCallback {
public:
VideoStreamDecoder(
vcm::VideoReceiver* video_receiver,
VideoReceiver2* video_receiver,
ReceiveStatisticsProxy* receive_statistics_proxy,
rtc::VideoSinkInterface<VideoFrame>* incoming_video_stream);
~VideoStreamDecoder() override;
@ -55,7 +52,7 @@ class VideoStreamDecoder : public VCMReceiveCallback {
// Used for all registered callbacks except rendering.
rtc::CriticalSection crit_;
vcm::VideoReceiver* const video_receiver_;
VideoReceiver2* const video_receiver_;
ReceiveStatisticsProxy* const receive_stats_callback_;
rtc::VideoSinkInterface<VideoFrame>* const incoming_video_stream_;