Removed SSRC knowledge from ViEEncoder.
SSRC knowledge is contained withing VideoSendStream. That also means that debug recording is moved to VideoSendStream. I think that make sence since that allows debug recording with external encoder implementations one day. BUG=webrtc:5687 Review-Url: https://codereview.webrtc.org/1936503002 Cr-Commit-Position: refs/heads/master@{#12632}
This commit is contained in:
parent
ef00ec1d4e
commit
600246e63f
@ -230,7 +230,7 @@ class VideoCodingModule : public Module {
|
||||
//
|
||||
// Return value : VCM_OK, on success.
|
||||
// < 0, on error.
|
||||
virtual int32_t IntraFrameRequest(int stream_index) = 0;
|
||||
virtual int32_t IntraFrameRequest(size_t stream_index) = 0;
|
||||
|
||||
// Frame Dropper enable. Can be used to disable the frame dropping when the
|
||||
// encoder
|
||||
|
||||
@ -152,7 +152,7 @@ class VideoCodingModuleImpl : public VideoCodingModule {
|
||||
return sender_.AddVideoFrame(videoFrame, contentMetrics, codecSpecificInfo);
|
||||
}
|
||||
|
||||
int32_t IntraFrameRequest(int stream_index) override {
|
||||
int32_t IntraFrameRequest(size_t stream_index) override {
|
||||
return sender_.IntraFrameRequest(stream_index);
|
||||
}
|
||||
|
||||
|
||||
@ -88,7 +88,7 @@ class VideoSender : public Module {
|
||||
const VideoContentMetrics* _contentMetrics,
|
||||
const CodecSpecificInfo* codecSpecificInfo);
|
||||
|
||||
int32_t IntraFrameRequest(int stream_index);
|
||||
int32_t IntraFrameRequest(size_t stream_index);
|
||||
int32_t EnableFrameDropper(bool enable);
|
||||
|
||||
void SuspendBelowMinBitrate();
|
||||
|
||||
@ -335,11 +335,10 @@ int32_t VideoSender::AddVideoFrame(const VideoFrame& videoFrame,
|
||||
return VCM_OK;
|
||||
}
|
||||
|
||||
int32_t VideoSender::IntraFrameRequest(int stream_index) {
|
||||
int32_t VideoSender::IntraFrameRequest(size_t stream_index) {
|
||||
{
|
||||
rtc::CritScope lock(¶ms_crit_);
|
||||
if (stream_index < 0 ||
|
||||
static_cast<size_t>(stream_index) >= next_frame_types_.size()) {
|
||||
if (stream_index >= next_frame_types_.size()) {
|
||||
return -1;
|
||||
}
|
||||
next_frame_types_[stream_index] = kVideoFrameKey;
|
||||
@ -353,7 +352,7 @@ int32_t VideoSender::IntraFrameRequest(int stream_index) {
|
||||
// encoder_crit_.
|
||||
rtc::CritScope lock(&encoder_crit_);
|
||||
rtc::CritScope params_lock(¶ms_crit_);
|
||||
if (static_cast<size_t>(stream_index) >= next_frame_types_.size())
|
||||
if (stream_index >= next_frame_types_.size())
|
||||
return -1;
|
||||
if (_encoder != nullptr && _encoder->InternalSource()) {
|
||||
// Try to request the frame if we have an external encoder with
|
||||
|
||||
@ -290,10 +290,6 @@ TEST_F(TestVideoSenderWithMockEncoder, TestIntraRequests) {
|
||||
EXPECT_EQ(-1, sender_->IntraFrameRequest(3));
|
||||
ExpectIntraRequest(-1);
|
||||
AddFrame();
|
||||
|
||||
EXPECT_EQ(-1, sender_->IntraFrameRequest(-1));
|
||||
ExpectIntraRequest(-1);
|
||||
AddFrame();
|
||||
}
|
||||
|
||||
TEST_F(TestVideoSenderWithMockEncoder, TestIntraRequestsInternalCapture) {
|
||||
@ -313,7 +309,6 @@ TEST_F(TestVideoSenderWithMockEncoder, TestIntraRequestsInternalCapture) {
|
||||
EXPECT_EQ(0, sender_->IntraFrameRequest(2));
|
||||
// No requests expected since these indices are out of bounds.
|
||||
EXPECT_EQ(-1, sender_->IntraFrameRequest(3));
|
||||
EXPECT_EQ(-1, sender_->IntraFrameRequest(-1));
|
||||
}
|
||||
|
||||
TEST_F(TestVideoSenderWithMockEncoder, TestEncoderParametersForInternalSource) {
|
||||
|
||||
@ -13,16 +13,18 @@
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/video/vie_encoder.h"
|
||||
|
||||
static const int kMinKeyFrameRequestIntervalMs = 300;
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
EncoderStateFeedback::EncoderStateFeedback() : vie_encoder_(nullptr) {}
|
||||
|
||||
void EncoderStateFeedback::Init(const std::vector<uint32_t>& ssrcs,
|
||||
ViEEncoder* encoder) {
|
||||
EncoderStateFeedback::EncoderStateFeedback(Clock* clock,
|
||||
const std::vector<uint32_t>& ssrcs,
|
||||
ViEEncoder* encoder)
|
||||
: clock_(clock),
|
||||
ssrcs_(ssrcs),
|
||||
vie_encoder_(encoder),
|
||||
time_last_intra_request_ms_(ssrcs.size(), -1) {
|
||||
RTC_DCHECK(!ssrcs.empty());
|
||||
rtc::CritScope lock(&crit_);
|
||||
ssrcs_ = ssrcs;
|
||||
vie_encoder_ = encoder;
|
||||
}
|
||||
|
||||
bool EncoderStateFeedback::HasSsrc(uint32_t ssrc) {
|
||||
@ -33,41 +35,59 @@ bool EncoderStateFeedback::HasSsrc(uint32_t ssrc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t EncoderStateFeedback::GetStreamIndex(uint32_t ssrc) {
|
||||
for (size_t i = 0; i < ssrcs_.size(); ++i) {
|
||||
if (ssrcs_[i] == ssrc)
|
||||
return i;
|
||||
}
|
||||
RTC_NOTREACHED() << "Unknown ssrc " << ssrc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EncoderStateFeedback::OnReceivedIntraFrameRequest(uint32_t ssrc) {
|
||||
rtc::CritScope lock(&crit_);
|
||||
if (!HasSsrc(ssrc))
|
||||
return;
|
||||
RTC_DCHECK(vie_encoder_);
|
||||
|
||||
vie_encoder_->OnReceivedIntraFrameRequest(ssrc);
|
||||
size_t index = GetStreamIndex(ssrc);
|
||||
{
|
||||
int64_t now_ms = clock_->TimeInMilliseconds();
|
||||
rtc::CritScope lock(&crit_);
|
||||
if (time_last_intra_request_ms_[index] + kMinKeyFrameRequestIntervalMs >
|
||||
now_ms) {
|
||||
return;
|
||||
}
|
||||
time_last_intra_request_ms_[index] = now_ms;
|
||||
}
|
||||
|
||||
vie_encoder_->OnReceivedIntraFrameRequest(index);
|
||||
}
|
||||
|
||||
void EncoderStateFeedback::OnReceivedSLI(uint32_t ssrc, uint8_t picture_id) {
|
||||
rtc::CritScope lock(&crit_);
|
||||
if (!HasSsrc(ssrc))
|
||||
return;
|
||||
RTC_DCHECK(vie_encoder_);
|
||||
|
||||
vie_encoder_->OnReceivedSLI(ssrc, picture_id);
|
||||
vie_encoder_->OnReceivedSLI(picture_id);
|
||||
}
|
||||
|
||||
void EncoderStateFeedback::OnReceivedRPSI(uint32_t ssrc, uint64_t picture_id) {
|
||||
rtc::CritScope lock(&crit_);
|
||||
if (!HasSsrc(ssrc))
|
||||
return;
|
||||
RTC_DCHECK(vie_encoder_);
|
||||
|
||||
vie_encoder_->OnReceivedRPSI(ssrc, picture_id);
|
||||
vie_encoder_->OnReceivedRPSI(picture_id);
|
||||
}
|
||||
|
||||
// Sending SSRCs for this encoder should never change since they are configured
|
||||
// once and not reconfigured.
|
||||
// once and not reconfigured, however, OnLocalSsrcChanged is called when the
|
||||
// RtpModules are created with a different SSRC than what will be used in the
|
||||
// end.
|
||||
// TODO(perkj): Can we make sure the RTP module is created with the right SSRC
|
||||
// from the beginning so this method is not triggered during creation ?
|
||||
void EncoderStateFeedback::OnLocalSsrcChanged(uint32_t old_ssrc,
|
||||
uint32_t new_ssrc) {
|
||||
if (!RTC_DCHECK_IS_ON)
|
||||
return;
|
||||
rtc::CritScope lock(&crit_);
|
||||
if (ssrcs_.empty()) // Encoder not yet attached (or detached for teardown).
|
||||
|
||||
if (old_ssrc == 0) // old_ssrc == 0 during creation.
|
||||
return;
|
||||
// SSRC shouldn't change to something we haven't already registered with the
|
||||
// encoder.
|
||||
|
||||
@ -7,10 +7,6 @@
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
// TODO(mflodman) ViEEncoder has a time check to not send key frames too often,
|
||||
// move the logic to this class.
|
||||
|
||||
#ifndef WEBRTC_VIDEO_ENCODER_STATE_FEEDBACK_H_
|
||||
#define WEBRTC_VIDEO_ENCODER_STATE_FEEDBACK_H_
|
||||
|
||||
@ -18,6 +14,7 @@
|
||||
|
||||
#include "webrtc/base/criticalsection.h"
|
||||
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
#include "webrtc/system_wrappers/include/clock.h"
|
||||
#include "webrtc/typedefs.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -26,22 +23,24 @@ class ViEEncoder;
|
||||
|
||||
class EncoderStateFeedback : public RtcpIntraFrameObserver {
|
||||
public:
|
||||
EncoderStateFeedback();
|
||||
|
||||
// Adds an encoder to receive feedback for a set of SSRCs.
|
||||
void Init(const std::vector<uint32_t>& ssrc, ViEEncoder* encoder);
|
||||
|
||||
EncoderStateFeedback(Clock* clock,
|
||||
const std::vector<uint32_t>& ssrcs,
|
||||
ViEEncoder* encoder);
|
||||
void OnReceivedIntraFrameRequest(uint32_t ssrc) override;
|
||||
void OnReceivedSLI(uint32_t ssrc, uint8_t picture_id) override;
|
||||
void OnReceivedRPSI(uint32_t ssrc, uint64_t picture_id) override;
|
||||
void OnLocalSsrcChanged(uint32_t old_ssrc, uint32_t new_ssrc) override;
|
||||
|
||||
private:
|
||||
bool HasSsrc(uint32_t ssrc) EXCLUSIVE_LOCKS_REQUIRED(crit_);
|
||||
rtc::CriticalSection crit_;
|
||||
bool HasSsrc(uint32_t ssrc);
|
||||
size_t GetStreamIndex(uint32_t ssrc);
|
||||
|
||||
std::vector<uint32_t> ssrcs_ GUARDED_BY(crit_);
|
||||
ViEEncoder* vie_encoder_ GUARDED_BY(crit_);
|
||||
Clock* const clock_;
|
||||
const std::vector<uint32_t> ssrcs_;
|
||||
ViEEncoder* const vie_encoder_;
|
||||
|
||||
rtc::CriticalSection crit_;
|
||||
std::vector<int64_t> time_last_intra_request_ms_ GUARDED_BY(crit_);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -12,10 +12,6 @@
|
||||
|
||||
#include "testing/gmock/include/gmock/gmock.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
|
||||
#include "webrtc/modules/pacing/paced_sender.h"
|
||||
#include "webrtc/modules/pacing/packet_router.h"
|
||||
#include "webrtc/modules/utility/include/mock/mock_process_thread.h"
|
||||
#include "webrtc/video/vie_encoder.h"
|
||||
|
||||
@ -27,42 +23,59 @@ class MockVieEncoder : public ViEEncoder {
|
||||
public:
|
||||
explicit MockVieEncoder(ProcessThread* process_thread)
|
||||
: ViEEncoder(1,
|
||||
std::vector<uint32_t>(),
|
||||
process_thread,
|
||||
nullptr,
|
||||
nullptr) {}
|
||||
~MockVieEncoder() {}
|
||||
|
||||
MOCK_METHOD1(OnReceivedIntraFrameRequest,
|
||||
void(uint32_t));
|
||||
MOCK_METHOD2(OnReceivedSLI,
|
||||
void(uint32_t ssrc, uint8_t picture_id));
|
||||
MOCK_METHOD2(OnReceivedRPSI,
|
||||
void(uint32_t ssrc, uint64_t picture_id));
|
||||
MOCK_METHOD1(OnReceivedIntraFrameRequest, void(size_t));
|
||||
MOCK_METHOD1(OnReceivedSLI, void(uint8_t picture_id));
|
||||
MOCK_METHOD1(OnReceivedRPSI, void(uint64_t picture_id));
|
||||
};
|
||||
|
||||
TEST(VieKeyRequestTest, CreateAndTriggerRequests) {
|
||||
static const uint32_t kSsrc = 1234;
|
||||
NiceMock<MockProcessThread> process_thread;
|
||||
PacketRouter router;
|
||||
MockVieEncoder encoder(&process_thread);
|
||||
class VieKeyRequestTest : public ::testing::Test {
|
||||
public:
|
||||
VieKeyRequestTest()
|
||||
: encoder_(&process_thread_),
|
||||
simulated_clock_(123456789),
|
||||
encoder_state_feedback_(
|
||||
&simulated_clock_,
|
||||
std::vector<uint32_t>(1, VieKeyRequestTest::kSsrc),
|
||||
&encoder_) {}
|
||||
|
||||
EncoderStateFeedback encoder_state_feedback;
|
||||
encoder_state_feedback.Init(std::vector<uint32_t>(1, kSsrc), &encoder);
|
||||
protected:
|
||||
const uint32_t kSsrc = 1234;
|
||||
NiceMock<MockProcessThread> process_thread_;
|
||||
MockVieEncoder encoder_;
|
||||
SimulatedClock simulated_clock_;
|
||||
EncoderStateFeedback encoder_state_feedback_;
|
||||
};
|
||||
|
||||
EXPECT_CALL(encoder, OnReceivedIntraFrameRequest(kSsrc))
|
||||
.Times(1);
|
||||
encoder_state_feedback.OnReceivedIntraFrameRequest(kSsrc);
|
||||
TEST_F(VieKeyRequestTest, CreateAndTriggerRequests) {
|
||||
EXPECT_CALL(encoder_, OnReceivedIntraFrameRequest(0)).Times(1);
|
||||
encoder_state_feedback_.OnReceivedIntraFrameRequest(kSsrc);
|
||||
|
||||
const uint8_t sli_picture_id = 3;
|
||||
EXPECT_CALL(encoder, OnReceivedSLI(kSsrc, sli_picture_id))
|
||||
.Times(1);
|
||||
encoder_state_feedback.OnReceivedSLI(kSsrc, sli_picture_id);
|
||||
EXPECT_CALL(encoder_, OnReceivedSLI(sli_picture_id)).Times(1);
|
||||
encoder_state_feedback_.OnReceivedSLI(kSsrc, sli_picture_id);
|
||||
|
||||
const uint64_t rpsi_picture_id = 9;
|
||||
EXPECT_CALL(encoder, OnReceivedRPSI(kSsrc, rpsi_picture_id))
|
||||
.Times(1);
|
||||
encoder_state_feedback.OnReceivedRPSI(kSsrc, rpsi_picture_id);
|
||||
EXPECT_CALL(encoder_, OnReceivedRPSI(rpsi_picture_id)).Times(1);
|
||||
encoder_state_feedback_.OnReceivedRPSI(kSsrc, rpsi_picture_id);
|
||||
}
|
||||
|
||||
TEST_F(VieKeyRequestTest, TooManyOnReceivedIntraFrameRequest) {
|
||||
EXPECT_CALL(encoder_, OnReceivedIntraFrameRequest(0)).Times(1);
|
||||
encoder_state_feedback_.OnReceivedIntraFrameRequest(kSsrc);
|
||||
encoder_state_feedback_.OnReceivedIntraFrameRequest(kSsrc);
|
||||
simulated_clock_.AdvanceTimeMilliseconds(10);
|
||||
encoder_state_feedback_.OnReceivedIntraFrameRequest(kSsrc);
|
||||
|
||||
EXPECT_CALL(encoder_, OnReceivedIntraFrameRequest(0)).Times(1);
|
||||
simulated_clock_.AdvanceTimeMilliseconds(300);
|
||||
encoder_state_feedback_.OnReceivedIntraFrameRequest(kSsrc);
|
||||
encoder_state_feedback_.OnReceivedIntraFrameRequest(kSsrc);
|
||||
encoder_state_feedback_.OnReceivedIntraFrameRequest(kSsrc);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include "webrtc/modules/pacing/packet_router.h"
|
||||
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
|
||||
#include "webrtc/modules/utility/include/process_thread.h"
|
||||
#include "webrtc/modules/video_coding/utility/ivf_file_writer.h"
|
||||
#include "webrtc/video/call_stats.h"
|
||||
#include "webrtc/video/video_capture_input.h"
|
||||
#include "webrtc/video/vie_remb.h"
|
||||
@ -376,10 +377,12 @@ VideoSendStream::VideoSendStream(
|
||||
config.post_encode_callback,
|
||||
&stats_proxy_),
|
||||
vie_encoder_(num_cpu_cores,
|
||||
config_.rtp.ssrcs,
|
||||
module_process_thread_,
|
||||
&stats_proxy_,
|
||||
&overuse_detector_),
|
||||
encoder_feedback_(Clock::GetRealTimeClock(),
|
||||
config.rtp.ssrcs,
|
||||
&vie_encoder_),
|
||||
video_sender_(vie_encoder_.video_sender()),
|
||||
bandwidth_observer_(congestion_controller_->GetBitrateController()
|
||||
->CreateRtcpBandwidthObserver()),
|
||||
@ -407,7 +410,6 @@ VideoSendStream::VideoSendStream(
|
||||
RTC_DCHECK(congestion_controller_);
|
||||
RTC_DCHECK(remb_);
|
||||
|
||||
encoder_feedback_.Init(config_.rtp.ssrcs, &vie_encoder_);
|
||||
|
||||
// RTP/RTCP initialization.
|
||||
for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
|
||||
@ -567,6 +569,13 @@ void VideoSendStream::EncoderProcess() {
|
||||
vie_encoder_.SetEncoder(encoder_settings->video_codec,
|
||||
encoder_settings->min_transmit_bitrate_bps,
|
||||
payload_router_.MaxPayloadLength(), this);
|
||||
|
||||
// Clear stats for disabled layers.
|
||||
for (size_t i = encoder_settings->streams.size();
|
||||
i < config_.rtp.ssrcs.size(); ++i) {
|
||||
stats_proxy_.OnInactiveSsrc(config_.rtp.ssrcs[i]);
|
||||
}
|
||||
|
||||
if (config_.suspend_below_min_bitrate) {
|
||||
video_sender_->SuspendBelowMinBitrate();
|
||||
bitrate_allocator_->EnforceMinBitrate(false);
|
||||
@ -627,8 +636,33 @@ int32_t VideoSendStream::Encoded(const EncodedImage& encoded_image,
|
||||
// |encoded_frame_proxy_| forwards frames to |config_.post_encode_callback|;
|
||||
encoded_frame_proxy_.Encoded(encoded_image, codec_specific_info,
|
||||
fragmentation);
|
||||
return payload_router_.Encoded(encoded_image, codec_specific_info,
|
||||
fragmentation);
|
||||
int32_t return_value = payload_router_.Encoded(
|
||||
encoded_image, codec_specific_info, fragmentation);
|
||||
|
||||
if (kEnableFrameRecording) {
|
||||
int layer = codec_specific_info->codecType == kVideoCodecVP8
|
||||
? codec_specific_info->codecSpecific.VP8.simulcastIdx
|
||||
: 0;
|
||||
IvfFileWriter* file_writer;
|
||||
{
|
||||
if (file_writers_[layer] == nullptr) {
|
||||
std::ostringstream oss;
|
||||
oss << "send_bitstream_ssrc";
|
||||
for (uint32_t ssrc : config_.rtp.ssrcs)
|
||||
oss << "_" << ssrc;
|
||||
oss << "_layer" << layer << ".ivf";
|
||||
file_writers_[layer] =
|
||||
IvfFileWriter::Open(oss.str(), codec_specific_info->codecType);
|
||||
}
|
||||
file_writer = file_writers_[layer].get();
|
||||
}
|
||||
if (file_writer) {
|
||||
bool ok = file_writer->WriteFrame(encoded_image);
|
||||
RTC_DCHECK(ok);
|
||||
}
|
||||
}
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
void VideoSendStream::ConfigureProtection() {
|
||||
|
||||
@ -34,6 +34,7 @@ namespace webrtc {
|
||||
class BitrateAllocator;
|
||||
class CallStats;
|
||||
class CongestionController;
|
||||
class IvfFileWriter;
|
||||
class ProcessThread;
|
||||
class RtpRtcp;
|
||||
class ViEEncoder;
|
||||
@ -126,6 +127,10 @@ class VideoSendStream : public webrtc::VideoSendStream,
|
||||
BitrateAllocator* const bitrate_allocator_;
|
||||
VieRemb* const remb_;
|
||||
|
||||
static const bool kEnableFrameRecording = false;
|
||||
static const int kMaxLayers = 3;
|
||||
std::unique_ptr<IvfFileWriter> file_writers_[kMaxLayers];
|
||||
|
||||
rtc::PlatformThread encoder_thread_;
|
||||
rtc::Event encoder_wakeup_event_;
|
||||
volatile int stop_encoder_thread_;
|
||||
@ -134,8 +139,8 @@ class VideoSendStream : public webrtc::VideoSendStream,
|
||||
GUARDED_BY(encoder_settings_crit_);
|
||||
|
||||
OveruseFrameDetector overuse_detector_;
|
||||
EncoderStateFeedback encoder_feedback_;
|
||||
ViEEncoder vie_encoder_;
|
||||
EncoderStateFeedback encoder_feedback_;
|
||||
vcm::VideoSender* const video_sender_;
|
||||
|
||||
const std::unique_ptr<RtcpBandwidthObserver> bandwidth_observer_;
|
||||
|
||||
@ -17,26 +17,18 @@
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/base/logging.h"
|
||||
#include "webrtc/base/trace_event.h"
|
||||
#include "webrtc/common_video/include/frame_callback.h"
|
||||
#include "webrtc/common_video/include/video_image.h"
|
||||
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
|
||||
#include "webrtc/modules/pacing/paced_sender.h"
|
||||
#include "webrtc/modules/utility/include/process_thread.h"
|
||||
#include "webrtc/modules/video_coding/include/video_codec_interface.h"
|
||||
#include "webrtc/modules/video_coding/include/video_coding.h"
|
||||
#include "webrtc/modules/video_coding/include/video_coding_defines.h"
|
||||
#include "webrtc/system_wrappers/include/clock.h"
|
||||
#include "webrtc/system_wrappers/include/metrics.h"
|
||||
#include "webrtc/system_wrappers/include/tick_util.h"
|
||||
#include "webrtc/video/overuse_frame_detector.h"
|
||||
#include "webrtc/video/payload_router.h"
|
||||
#include "webrtc/video/send_statistics_proxy.h"
|
||||
#include "webrtc/video_frame.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
static const float kStopPaddingThresholdMs = 2000;
|
||||
static const int kMinKeyFrameRequestIntervalMs = 300;
|
||||
|
||||
class QMVideoSettingsCallback : public VCMQMSettingsCallback {
|
||||
public:
|
||||
@ -54,12 +46,10 @@ class QMVideoSettingsCallback : public VCMQMSettingsCallback {
|
||||
};
|
||||
|
||||
ViEEncoder::ViEEncoder(uint32_t number_of_cores,
|
||||
const std::vector<uint32_t>& ssrcs,
|
||||
ProcessThread* module_process_thread,
|
||||
SendStatisticsProxy* stats_proxy,
|
||||
OveruseFrameDetector* overuse_detector)
|
||||
: number_of_cores_(number_of_cores),
|
||||
ssrcs_(ssrcs),
|
||||
vp_(VideoProcessing::Create()),
|
||||
qm_callback_(new QMVideoSettingsCallback(vp_.get())),
|
||||
video_sender_(Clock::GetRealTimeClock(),
|
||||
@ -76,7 +66,6 @@ ViEEncoder::ViEEncoder(uint32_t number_of_cores,
|
||||
network_is_transmitting_(true),
|
||||
encoder_paused_(true),
|
||||
encoder_paused_and_dropped_frame_(false),
|
||||
time_last_intra_request_ms_(ssrcs.size(), -1),
|
||||
module_process_thread_(module_process_thread),
|
||||
has_received_sli_(false),
|
||||
picture_id_sli_(0),
|
||||
@ -156,11 +145,6 @@ void ViEEncoder::SetEncoder(const webrtc::VideoCodec& video_codec,
|
||||
}
|
||||
|
||||
if (stats_proxy_) {
|
||||
// Clear stats for disabled layers.
|
||||
for (size_t i = video_codec.numberOfSimulcastStreams; i < ssrcs_.size();
|
||||
++i) {
|
||||
stats_proxy_->OnInactiveSsrc(ssrcs_[i]);
|
||||
}
|
||||
VideoEncoderConfig::ContentType content_type =
|
||||
VideoEncoderConfig::ContentType::kRealtimeVideo;
|
||||
switch (video_codec.mode) {
|
||||
@ -353,30 +337,6 @@ int32_t ViEEncoder::Encoded(const EncodedImage& encoded_image,
|
||||
}
|
||||
|
||||
overuse_detector_->FrameSent(encoded_image._timeStamp);
|
||||
if (kEnableFrameRecording) {
|
||||
int layer = codec_specific_info->codecType == kVideoCodecVP8
|
||||
? codec_specific_info->codecSpecific.VP8.simulcastIdx
|
||||
: 0;
|
||||
IvfFileWriter* file_writer;
|
||||
{
|
||||
rtc::CritScope lock(&data_cs_);
|
||||
if (file_writers_[layer] == nullptr) {
|
||||
std::ostringstream oss;
|
||||
oss << "send_bitstream_ssrc";
|
||||
for (uint32_t ssrc : ssrcs_)
|
||||
oss << "_" << ssrc;
|
||||
oss << "_layer" << layer << ".ivf";
|
||||
file_writers_[layer] =
|
||||
IvfFileWriter::Open(oss.str(), codec_specific_info->codecType);
|
||||
}
|
||||
file_writer = file_writers_[layer].get();
|
||||
}
|
||||
if (file_writer) {
|
||||
bool ok = file_writer->WriteFrame(encoded_image);
|
||||
RTC_DCHECK(ok);
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
@ -387,40 +347,22 @@ void ViEEncoder::SendStatistics(uint32_t bit_rate,
|
||||
stats_proxy_->OnEncoderStatsUpdate(frame_rate, bit_rate, encoder_name);
|
||||
}
|
||||
|
||||
void ViEEncoder::OnReceivedSLI(uint32_t /*ssrc*/,
|
||||
uint8_t picture_id) {
|
||||
void ViEEncoder::OnReceivedSLI(uint8_t picture_id) {
|
||||
rtc::CritScope lock(&data_cs_);
|
||||
picture_id_sli_ = picture_id;
|
||||
has_received_sli_ = true;
|
||||
}
|
||||
|
||||
void ViEEncoder::OnReceivedRPSI(uint32_t /*ssrc*/,
|
||||
uint64_t picture_id) {
|
||||
void ViEEncoder::OnReceivedRPSI(uint64_t picture_id) {
|
||||
rtc::CritScope lock(&data_cs_);
|
||||
picture_id_rpsi_ = picture_id;
|
||||
has_received_rpsi_ = true;
|
||||
}
|
||||
|
||||
void ViEEncoder::OnReceivedIntraFrameRequest(uint32_t ssrc) {
|
||||
void ViEEncoder::OnReceivedIntraFrameRequest(size_t stream_index) {
|
||||
// Key frame request from remote side, signal to VCM.
|
||||
TRACE_EVENT0("webrtc", "OnKeyFrameRequest");
|
||||
|
||||
for (size_t i = 0; i < ssrcs_.size(); ++i) {
|
||||
if (ssrcs_[i] != ssrc)
|
||||
continue;
|
||||
int64_t now_ms = TickTime::MillisecondTimestamp();
|
||||
{
|
||||
rtc::CritScope lock(&data_cs_);
|
||||
if (time_last_intra_request_ms_[i] + kMinKeyFrameRequestIntervalMs >
|
||||
now_ms) {
|
||||
return;
|
||||
}
|
||||
time_last_intra_request_ms_[i] = now_ms;
|
||||
}
|
||||
video_sender_.IntraFrameRequest(static_cast<int>(i));
|
||||
return;
|
||||
}
|
||||
RTC_NOTREACHED() << "Should not receive keyframe requests on unknown SSRCs.";
|
||||
video_sender_.IntraFrameRequest(stream_index);
|
||||
}
|
||||
|
||||
void ViEEncoder::OnBitrateUpdated(uint32_t bitrate_bps,
|
||||
@ -443,8 +385,8 @@ void ViEEncoder::OnBitrateUpdated(uint32_t bitrate_bps,
|
||||
if (!video_suspension_changed)
|
||||
return;
|
||||
// Video suspend-state changed, inform codec observer.
|
||||
LOG(LS_INFO) << "Video suspend state changed " << video_is_suspended
|
||||
<< " for ssrc " << ssrcs_[0];
|
||||
LOG(LS_INFO) << "Video suspend state changed " << video_is_suspended;
|
||||
|
||||
if (stats_proxy_)
|
||||
stats_proxy_->OnSuspendChange(video_is_suspended);
|
||||
}
|
||||
|
||||
@ -23,7 +23,6 @@
|
||||
#include "webrtc/media/base/videosinkinterface.h"
|
||||
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
#include "webrtc/modules/video_coding/include/video_coding_defines.h"
|
||||
#include "webrtc/modules/video_coding/utility/ivf_file_writer.h"
|
||||
#include "webrtc/modules/video_coding/video_coding_impl.h"
|
||||
#include "webrtc/modules/video_processing/include/video_processing.h"
|
||||
#include "webrtc/typedefs.h"
|
||||
@ -58,7 +57,6 @@ class ViEEncoder : public VideoEncoderRateObserver,
|
||||
friend class ViEBitrateObserver;
|
||||
|
||||
ViEEncoder(uint32_t number_of_cores,
|
||||
const std::vector<uint32_t>& ssrcs,
|
||||
ProcessThread* module_process_thread,
|
||||
SendStatisticsProxy* stats_proxy,
|
||||
OveruseFrameDetector* overuse_detector);
|
||||
@ -108,9 +106,9 @@ class ViEEncoder : public VideoEncoderRateObserver,
|
||||
const std::string& encoder_name) override;
|
||||
|
||||
// virtual to test EncoderStateFeedback with mocks.
|
||||
virtual void OnReceivedIntraFrameRequest(uint32_t ssrc);
|
||||
virtual void OnReceivedSLI(uint32_t ssrc, uint8_t picture_id);
|
||||
virtual void OnReceivedRPSI(uint32_t ssrc, uint64_t picture_id);
|
||||
virtual void OnReceivedIntraFrameRequest(size_t stream_index);
|
||||
virtual void OnReceivedSLI(uint8_t picture_id);
|
||||
virtual void OnReceivedRPSI(uint64_t picture_id);
|
||||
|
||||
int GetPaddingNeededBps() const;
|
||||
|
||||
@ -119,15 +117,11 @@ class ViEEncoder : public VideoEncoderRateObserver,
|
||||
int64_t round_trip_time_ms);
|
||||
|
||||
private:
|
||||
static const bool kEnableFrameRecording = false;
|
||||
static const int kMaxLayers = 3;
|
||||
|
||||
bool EncoderPaused() const EXCLUSIVE_LOCKS_REQUIRED(data_cs_);
|
||||
void TraceFrameDropStart() EXCLUSIVE_LOCKS_REQUIRED(data_cs_);
|
||||
void TraceFrameDropEnd() EXCLUSIVE_LOCKS_REQUIRED(data_cs_);
|
||||
|
||||
const uint32_t number_of_cores_;
|
||||
const std::vector<uint32_t> ssrcs_;
|
||||
|
||||
const std::unique_ptr<VideoProcessing> vp_;
|
||||
const std::unique_ptr<QMVideoSettingsCallback> qm_callback_;
|
||||
@ -148,7 +142,6 @@ class ViEEncoder : public VideoEncoderRateObserver,
|
||||
bool network_is_transmitting_ GUARDED_BY(data_cs_);
|
||||
bool encoder_paused_ GUARDED_BY(data_cs_);
|
||||
bool encoder_paused_and_dropped_frame_ GUARDED_BY(data_cs_);
|
||||
std::vector<int64_t> time_last_intra_request_ms_ GUARDED_BY(data_cs_);
|
||||
|
||||
rtc::CriticalSection sink_cs_;
|
||||
EncodedImageCallback* sink_ GUARDED_BY(sink_cs_);
|
||||
@ -161,8 +154,6 @@ class ViEEncoder : public VideoEncoderRateObserver,
|
||||
uint64_t picture_id_rpsi_ GUARDED_BY(data_cs_);
|
||||
|
||||
bool video_suspended_ GUARDED_BY(data_cs_);
|
||||
|
||||
std::unique_ptr<IvfFileWriter> file_writers_[kMaxLayers] GUARDED_BY(data_cs_);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user