1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
media / cast / sender / video_sender.h [blame]
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_CAST_SENDER_VIDEO_SENDER_H_
#define MEDIA_CAST_SENDER_VIDEO_SENDER_H_
#include <memory>
#include "base/functional/callback.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/tick_clock.h"
#include "base/time/time.h"
#include "media/capture/video/video_capture_feedback.h"
#include "media/cast/cast_callbacks.h"
#include "media/cast/cast_config.h"
#include "media/cast/common/rtp_time.h"
#include "media/cast/sender/frame_sender.h"
namespace openscreen::cast {
class Sender;
}
namespace media {
class VideoEncoderMetricsProvider;
class VideoFrame;
} // namespace media
namespace media::cast {
class VideoEncoder;
using PlayoutDelayChangeCB = base::RepeatingCallback<void(base::TimeDelta)>;
// Not thread safe. Only called from the main cast thread.
// This class owns all objects related to sending video, objects that create RTP
// packets, congestion control, video encoder, parsing and sending of
// RTCP packets.
// Additionally it posts a bunch of delayed tasks to the main thread for various
// timeouts.
class VideoSender : public FrameSender::Client {
public:
// New way of instantiating using an openscreen::cast::Sender. Since the
// |Sender| instance is destroyed when renegotiation is complete, |this|
// is also invalid and should be immediately torn down.
VideoSender(scoped_refptr<CastEnvironment> cast_environment,
const FrameSenderConfig& video_config,
StatusChangeCallback status_change_cb,
const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
std::unique_ptr<openscreen::cast::Sender> sender,
std::unique_ptr<media::VideoEncoderMetricsProvider>
encoder_metrics_provider,
PlayoutDelayChangeCB playout_delay_change_cb,
media::VideoCaptureFeedbackCB feedback_cb,
FrameSender::GetSuggestedVideoBitrateCB get_bitrate_cb);
VideoSender(const VideoSender&) = delete;
VideoSender& operator=(const VideoSender&) = delete;
~VideoSender() override;
// Note: It is not guaranteed that |video_frame| will actually be encoded and
// sent, if VideoSender detects too many frames in flight. Therefore, clients
// should be careful about the rate at which this method is called.
virtual void InsertRawVideoFrame(scoped_refptr<media::VideoFrame> video_frame,
base::TimeTicks reference_time);
void SetTargetPlayoutDelay(base::TimeDelta new_target_playout_delay);
base::TimeDelta GetTargetPlayoutDelay() const;
base::WeakPtr<VideoSender> AsWeakPtr();
protected:
// For mocking in unit tests.
VideoSender();
// FrameSender::Client overrides.
int GetNumberOfFramesInEncoder() const final;
base::TimeDelta GetEncoderBacklogDuration() const final;
private:
// Called by the |video_encoder_| with the next EncodedFrame to send.
void OnEncodedVideoFrame(std::unique_ptr<SenderEncodedFrame> encoded_frame);
// The backing frame sender implementation.
std::unique_ptr<FrameSender> frame_sender_;
// Encodes media::VideoFrame images into EncodedFrames. Per configuration,
// this will point to either the internal software-based encoder or a proxy to
// a hardware-based encoder.
std::unique_ptr<VideoEncoder> video_encoder_;
scoped_refptr<CastEnvironment> cast_environment_;
// The number of frames queued for encoding, but not yet sent.
int frames_in_encoder_ = 0;
// The duration of video queued for encoding, but not yet sent.
base::TimeDelta duration_in_encoder_;
// The timestamp of the frame that was last enqueued in |video_encoder_|.
RtpTimeTicks last_enqueued_frame_rtp_timestamp_;
base::TimeTicks last_enqueued_frame_reference_time_;
// Remember what we set the bitrate to before, no need to set it again if
// we get the same value.
int last_bitrate_ = 0;
// The total amount of time between a frame's capture/recording on the sender
// and its playback on the receiver (i.e., shown to a user).
base::TimeDelta min_playout_delay_;
base::TimeDelta max_playout_delay_;
PlayoutDelayChangeCB playout_delay_change_cb_;
media::VideoCaptureFeedbackCB feedback_cb_;
// Indicates we are operating in a mode where the target playout latency is
// low for best user experience. When operating in low latency mode, we
// prefer dropping frames over increasing target playout time.
bool low_latency_mode_ = false;
// The video encoder's performance metrics as of the last call to
// OnEncodedVideoFrame(). See header file comments for SenderEncodedFrame for
// an explanation of these values.
double last_reported_encoder_utilization_ = -1.0;
double last_reported_lossiness_ = -1.0;
// Used to calculate the percentage of lost frames. We currently report this
// metric as the number of frames dropped in the entire session.
int number_of_frames_inserted_ = 0;
int number_of_frames_dropped_ = 0;
// Used to throttle metrics reporting of the bitrate.
int frames_since_bitrate_reported_ = 0;
// This tracks the time when the request was sent to encoder to encode a key
// frame on receiving a Pli message. It is used to limit the sender not
// to duplicately respond to multiple Pli messages in a short period.
base::TimeTicks last_time_attempted_to_resolve_pli_;
// NOTE: Weak pointers must be invalidated before all other member variables.
base::WeakPtrFactory<VideoSender> weak_factory_{this};
};
} // namespace media::cast
#endif // MEDIA_CAST_SENDER_VIDEO_SENDER_H_