webrtc_m130/modules/rtp_rtcp/source/rtp_sender_video.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

261 lines
10 KiB
C
Raw Normal View History

/*
* Copyright (c) 2012 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_RTP_RTCP_SOURCE_RTP_SENDER_VIDEO_H_
#define MODULES_RTP_RTCP_SOURCE_RTP_SENDER_VIDEO_H_
#include <map>
#include <memory>
#include <vector>
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "api/frame_transformer_interface.h"
#include "api/scoped_refptr.h"
#include "api/sequence_checker.h"
#include "api/task_queue/task_queue_base.h"
#include "api/transport/rtp/dependency_descriptor.h"
#include "api/video/video_codec_type.h"
#include "api/video/video_frame_type.h"
#include "api/video/video_layers_allocation.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/absolute_capture_time_sender.h"
#include "modules/rtp_rtcp/source/active_decode_targets_helper.h"
#include "modules/rtp_rtcp/source/rtp_rtcp_config.h"
#include "modules/rtp_rtcp/source/rtp_sender.h"
#include "modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.h"
#include "modules/rtp_rtcp/source/rtp_video_header.h"
Reland "Reland "Refactors UlpFec and FlexFec to use a common interface."" This is a reland of 49734dc0faa69616a58a1a95c7fc61a4610793cf Patchset 2 contains a fix for the fuzzer set up. Since we now parse an RtpPacket out of the fuzzer data, the header needs to be correct, otherwise we fail before even reaching the FEC code that we actually want to test. Bug: webrtc:11340, chromium:1052323, chromium:1055974 TBR=stefan@webrtc.org Original change's description: > Reland "Refactors UlpFec and FlexFec to use a common interface." > > This is a reland of 11af1d7444fd7438766b7bc52cbd64752d72e32e > > Original change's description: > > Refactors UlpFec and FlexFec to use a common interface. > > > > The new VideoFecGenerator is now injected into RtpSenderVideo, > > and generalizes the usage. > > This also prepares for being able to genera FEC in the RTP egress > > module. > > > > Bug: webrtc:11340 > > Change-Id: I8aa873129b2fb4131eb3399ee88f6ea2747155a3 > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168347 > > Reviewed-by: Stefan Holmer <stefan@webrtc.org> > > Reviewed-by: Sebastian Jansson <srte@webrtc.org> > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#30515} > > Bug: webrtc:11340, chromium:1052323 > Change-Id: Id646047365f1c46cca9e6f3e8eefa5151207b4a0 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168608 > Commit-Queue: Erik Språng <sprang@webrtc.org> > Reviewed-by: Stefan Holmer <stefan@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#30593} Bug: webrtc:11340, chromium:1052323 Change-Id: Ib8925f44e2edfcfeadc95c845c3bfc23822604ed Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/169222 Commit-Queue: Erik Språng <sprang@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30724}
2020-03-05 10:14:04 +01:00
#include "modules/rtp_rtcp/source/video_fec_generator.h"
#include "rtc_base/one_time_event.h"
#include "rtc_base/race_checker.h"
#include "rtc_base/rate_statistics.h"
#include "rtc_base/synchronization/mutex.h"
#include "rtc_base/thread_annotations.h"
namespace webrtc {
class FrameEncryptorInterface;
class RtpPacketizer;
class RtpPacketToSend;
// kConditionallyRetransmitHigherLayers allows retransmission of video frames
// in higher layers if either the last frame in that layer was too far back in
// time, or if we estimate that a new frame will be available in a lower layer
// in a shorter time than it would take to request and receive a retransmission.
enum RetransmissionMode : uint8_t {
kRetransmitOff = 0x0,
kRetransmitBaseLayer = 0x2,
kRetransmitHigherLayers = 0x4,
kRetransmitAllLayers = 0x6,
kConditionallyRetransmitHigherLayers = 0x8
};
class RTPSenderVideo {
public:
static constexpr int64_t kTLRateWindowSizeMs = 2500;
struct Config {
Config() = default;
Config(const Config&) = delete;
Config(Config&&) = default;
// All members of this struct, with the exception of |field_trials|, are
// expected to outlive the RTPSenderVideo object they are passed to.
Clock* clock = nullptr;
RTPSender* rtp_sender = nullptr;
// Some FEC data is duplicated here in preparation of moving FEC to
// the egress stage.
absl::optional<VideoFecGenerator::FecType> fec_type;
size_t fec_overhead_bytes = 0; // Per packet max FEC overhead.
FrameEncryptorInterface* frame_encryptor = nullptr;
bool require_frame_encryption = false;
bool enable_retransmit_all_layers = false;
absl::optional<int> red_payload_type;
const WebRtcKeyValueConfig* field_trials = nullptr;
rtc::scoped_refptr<FrameTransformerInterface> frame_transformer;
TaskQueueBase* send_transport_queue = nullptr;
};
explicit RTPSenderVideo(const Config& config);
virtual ~RTPSenderVideo();
// expected_retransmission_time_ms.has_value() -> retransmission allowed.
// `capture_time_ms` and `clock::CurrentTime` should be using the same epoch.
// Calls to this method is assumed to be externally serialized.
// |estimated_capture_clock_offset_ms| is an estimated clock offset between
// this sender and the original capturer, for this video packet. See
// http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time for more
// details. If the sender and the capture has the same clock, it is supposed
// to be zero valued, which is given as the default.
bool SendVideo(int payload_type,
absl::optional<VideoCodecType> codec_type,
uint32_t rtp_timestamp,
int64_t capture_time_ms,
rtc::ArrayView<const uint8_t> payload,
RTPVideoHeader video_header,
absl::optional<int64_t> expected_retransmission_time_ms,
absl::optional<int64_t> estimated_capture_clock_offset_ms = 0);
bool SendEncodedImage(
int payload_type,
absl::optional<VideoCodecType> codec_type,
uint32_t rtp_timestamp,
const EncodedImage& encoded_image,
RTPVideoHeader video_header,
absl::optional<int64_t> expected_retransmission_time_ms);
// Configures video structures produced by encoder to send using the
// dependency descriptor rtp header extension. Next call to SendVideo should
// have video_header.frame_type == kVideoFrameKey.
// All calls to SendVideo after this call must use video_header compatible
// with the video_structure.
void SetVideoStructure(const FrameDependencyStructure* video_structure);
// Should only be used by a RTPSenderVideoFrameTransformerDelegate and exists
// to ensure correct syncronization.
void SetVideoStructureAfterTransformation(
const FrameDependencyStructure* video_structure);
// Sets current active VideoLayersAllocation. The allocation will be sent
// using the rtp video layers allocation extension. The allocation will be
// sent in full on every key frame. The allocation will be sent once on a
// none discardable delta frame per call to this method and will not contain
// resolution and frame rate.
void SetVideoLayersAllocation(VideoLayersAllocation allocation);
// Should only be used by a RTPSenderVideoFrameTransformerDelegate and exists
// to ensure correct syncronization.
void SetVideoLayersAllocationAfterTransformation(
VideoLayersAllocation allocation);
// Returns the current packetization overhead rate, in bps. Note that this is
// the payload overhead, eg the VP8 payload headers, not the RTP headers
// or extension/
// TODO(sprang): Consider moving this to RtpSenderEgress so it's in the same
// place as the other rate stats.
uint32_t PacketizationOverheadBps() const;
protected:
static uint8_t GetTemporalId(const RTPVideoHeader& header);
bool AllowRetransmission(uint8_t temporal_id,
int32_t retransmission_settings,
int64_t expected_retransmission_time_ms);
private:
struct TemporalLayerStats {
TemporalLayerStats()
: frame_rate_fp1000s(kTLRateWindowSizeMs, 1000 * 1000),
last_frame_time_ms(0) {}
// Frame rate, in frames per 1000 seconds. This essentially turns the fps
// value into a fixed point value with three decimals. Improves precision at
// low frame rates.
RateStatistics frame_rate_fp1000s;
int64_t last_frame_time_ms;
};
enum class SendVideoLayersAllocation {
kSendWithResolution,
kSendWithoutResolution,
kDontSend
};
void SetVideoStructureInternal(
const FrameDependencyStructure* video_structure);
void SetVideoLayersAllocationInternal(VideoLayersAllocation allocation);
void AddRtpHeaderExtensions(
const RTPVideoHeader& video_header,
const absl::optional<AbsoluteCaptureTime>& absolute_capture_time,
bool first_packet,
bool last_packet,
RtpPacketToSend* packet) const
RTC_EXCLUSIVE_LOCKS_REQUIRED(send_checker_);
size_t FecPacketOverhead() const RTC_EXCLUSIVE_LOCKS_REQUIRED(send_checker_);
void LogAndSendToNetwork(
std::vector<std::unique_ptr<RtpPacketToSend>> packets,
size_t unpacketized_payload_size);
bool red_enabled() const { return red_payload_type_.has_value(); }
bool UpdateConditionalRetransmit(uint8_t temporal_id,
int64_t expected_retransmission_time_ms)
RTC_EXCLUSIVE_LOCKS_REQUIRED(stats_mutex_);
Reland "Remove PlayoutDelayOracle and make RtpSenderVideo guarantee delivery" This is a reland of 4f68f5398d7fa3d47c449e99893c9bea07bf7ca2 Original change's description: > Remove PlayoutDelayOracle and make RtpSenderVideo guarantee delivery > > The PlayoutDelayOracle was responsible for making sure the PlayoutDelay > header extension was successfully propagated to the receiving side. Once > it was determined that the receiver had received a frame with the new > delay tag, it's no longer necessary to propagate. > > The issue with this implementation is that it is based on max > extended sequence number reported via RTCP, which makes it often slow > to react, could theoretically fail to produce desired outcome (max > received > X does not guarantee X was fully received and decoded), and > added a lot of code complexity. > > The guarantee of delivery can in fact be accomplished more reliably and > with less code by making sure to tag each frame until an undiscardable > frame is sent. > > This allows containing the logic fully within RTPSenderVideo. > > Bug: webrtc:11340 > Change-Id: I2d1d2b6b67f4f07b8b33336f8fcfcde724243eef > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168221 > Reviewed-by: Stefan Holmer <stefan@webrtc.org> > Reviewed-by: Sebastian Jansson <srte@webrtc.org> > Commit-Queue: Erik Språng <sprang@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#30473} TBR=stefan@webrtc.org Bug: webrtc:11340 Change-Id: I2fdd0004121b13b96497b21e052359e31d0c477a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168305 Commit-Queue: Erik Språng <sprang@webrtc.org> Reviewed-by: Sebastian Jansson <srte@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30479}
2020-02-06 17:10:08 +01:00
void MaybeUpdateCurrentPlayoutDelay(const RTPVideoHeader& header)
RTC_EXCLUSIVE_LOCKS_REQUIRED(send_checker_);
RTPSender* const rtp_sender_;
Clock* const clock_;
const int32_t retransmission_settings_;
// These members should only be accessed from within SendVideo() to avoid
// potential race conditions.
rtc::RaceChecker send_checker_;
VideoRotation last_rotation_ RTC_GUARDED_BY(send_checker_);
absl::optional<ColorSpace> last_color_space_ RTC_GUARDED_BY(send_checker_);
bool transmit_color_space_next_frame_ RTC_GUARDED_BY(send_checker_);
std::unique_ptr<FrameDependencyStructure> video_structure_
RTC_GUARDED_BY(send_checker_);
absl::optional<VideoLayersAllocation> allocation_
RTC_GUARDED_BY(send_checker_);
// Flag indicating if we should send |allocation_|.
SendVideoLayersAllocation send_allocation_ RTC_GUARDED_BY(send_checker_);
Reland "Remove PlayoutDelayOracle and make RtpSenderVideo guarantee delivery" This is a reland of 4f68f5398d7fa3d47c449e99893c9bea07bf7ca2 Original change's description: > Remove PlayoutDelayOracle and make RtpSenderVideo guarantee delivery > > The PlayoutDelayOracle was responsible for making sure the PlayoutDelay > header extension was successfully propagated to the receiving side. Once > it was determined that the receiver had received a frame with the new > delay tag, it's no longer necessary to propagate. > > The issue with this implementation is that it is based on max > extended sequence number reported via RTCP, which makes it often slow > to react, could theoretically fail to produce desired outcome (max > received > X does not guarantee X was fully received and decoded), and > added a lot of code complexity. > > The guarantee of delivery can in fact be accomplished more reliably and > with less code by making sure to tag each frame until an undiscardable > frame is sent. > > This allows containing the logic fully within RTPSenderVideo. > > Bug: webrtc:11340 > Change-Id: I2d1d2b6b67f4f07b8b33336f8fcfcde724243eef > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168221 > Reviewed-by: Stefan Holmer <stefan@webrtc.org> > Reviewed-by: Sebastian Jansson <srte@webrtc.org> > Commit-Queue: Erik Språng <sprang@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#30473} TBR=stefan@webrtc.org Bug: webrtc:11340 Change-Id: I2fdd0004121b13b96497b21e052359e31d0c477a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168305 Commit-Queue: Erik Språng <sprang@webrtc.org> Reviewed-by: Sebastian Jansson <srte@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30479}
2020-02-06 17:10:08 +01:00
// Current target playout delay.
VideoPlayoutDelay current_playout_delay_ RTC_GUARDED_BY(send_checker_);
// Flag indicating if we need to send |current_playout_delay_| in order
Reland "Remove PlayoutDelayOracle and make RtpSenderVideo guarantee delivery" This is a reland of 4f68f5398d7fa3d47c449e99893c9bea07bf7ca2 Original change's description: > Remove PlayoutDelayOracle and make RtpSenderVideo guarantee delivery > > The PlayoutDelayOracle was responsible for making sure the PlayoutDelay > header extension was successfully propagated to the receiving side. Once > it was determined that the receiver had received a frame with the new > delay tag, it's no longer necessary to propagate. > > The issue with this implementation is that it is based on max > extended sequence number reported via RTCP, which makes it often slow > to react, could theoretically fail to produce desired outcome (max > received > X does not guarantee X was fully received and decoded), and > added a lot of code complexity. > > The guarantee of delivery can in fact be accomplished more reliably and > with less code by making sure to tag each frame until an undiscardable > frame is sent. > > This allows containing the logic fully within RTPSenderVideo. > > Bug: webrtc:11340 > Change-Id: I2d1d2b6b67f4f07b8b33336f8fcfcde724243eef > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168221 > Reviewed-by: Stefan Holmer <stefan@webrtc.org> > Reviewed-by: Sebastian Jansson <srte@webrtc.org> > Commit-Queue: Erik Språng <sprang@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#30473} TBR=stefan@webrtc.org Bug: webrtc:11340 Change-Id: I2fdd0004121b13b96497b21e052359e31d0c477a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168305 Commit-Queue: Erik Språng <sprang@webrtc.org> Reviewed-by: Sebastian Jansson <srte@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30479}
2020-02-06 17:10:08 +01:00
// to guarantee it gets delivered.
bool playout_delay_pending_;
// Set by the field trial WebRTC-ForceSendPlayoutDelay to override the playout
// delay of outgoing video frames.
const absl::optional<VideoPlayoutDelay> forced_playout_delay_;
// Should never be held when calling out of this class.
Mutex mutex_;
const absl::optional<int> red_payload_type_;
absl::optional<VideoFecGenerator::FecType> fec_type_;
const size_t fec_overhead_bytes_; // Per packet max FEC overhead.
mutable Mutex stats_mutex_;
RateStatistics packetization_overhead_bitrate_ RTC_GUARDED_BY(stats_mutex_);
std::map<int, TemporalLayerStats> frame_stats_by_temporal_layer_
RTC_GUARDED_BY(stats_mutex_);
OneTimeEvent first_frame_sent_;
// E2EE Custom Video Frame Encryptor (optional)
FrameEncryptorInterface* const frame_encryptor_ = nullptr;
// If set to true will require all outgoing frames to pass through an
// initialized frame_encryptor_ before being sent out of the network.
// Otherwise these payloads will be dropped.
const bool require_frame_encryption_;
// Set to true if the generic descriptor should be authenticated.
const bool generic_descriptor_auth_experiment_;
AbsoluteCaptureTimeSender absolute_capture_time_sender_;
// Tracks updates to the active decode targets and decides when active decode
// targets bitmask should be attached to the dependency descriptor.
ActiveDecodeTargetsHelper active_decode_targets_tracker_;
const rtc::scoped_refptr<RTPSenderVideoFrameTransformerDelegate>
frame_transformer_delegate_;
const bool include_capture_clock_offset_;
};
} // namespace webrtc
#endif // MODULES_RTP_RTCP_SOURCE_RTP_SENDER_VIDEO_H_