summaryrefslogtreecommitdiff
path: root/media/cast/video_sender/video_sender.h
blob: 9098e975c4f8ee5959db81e1c301c10a67b5e201 (plain)
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
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_CAST_VIDEO_SENDER_VIDEO_SENDER_H_
#define MEDIA_CAST_VIDEO_SENDER_VIDEO_SENDER_H_

#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/non_thread_safe.h"
#include "base/time/default_tick_clock.h"
#include "base/time/tick_clock.h"
#include "base/time/time.h"
#include "media/cast/cast_config.h"
#include "media/cast/cast_thread.h"
#include "media/cast/congestion_control/congestion_control.h"
#include "media/cast/rtcp/rtcp.h"
#include "media/cast/rtp_sender/rtp_sender.h"

namespace media {
namespace cast {

class VideoEncoder;
class LocalRtcpVideoSenderFeedback;
class LocalRtpVideoSenderStatistics;
class LocalVideoEncoderCallback;
class PacedPacketSender;

// 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 base::NonThreadSafe,
                    public base::SupportsWeakPtr<VideoSender> {
 public:
  VideoSender(scoped_refptr<CastThread> cast_thread,
              const VideoSenderConfig& video_config,
              VideoEncoderController* const video_encoder_controller,
              PacedPacketSender* const paced_packet_sender);

  virtual ~VideoSender();

  // The video_frame must be valid until the closure callback is called.
  // The closure callback is called from the video encoder thread as soon as
  // the encoder is done with the frame; it does not mean that the encoded frame
  // has been sent out.
  void InsertRawVideoFrame(
      const I420VideoFrame* video_frame,
      const base::TimeTicks& capture_time,
      const base::Closure callback);

  // The video_frame must be valid until the closure callback is called.
  // The closure callback is called from the main thread as soon as
  // the cast sender is done with the frame; it does not mean that the encoded
  // frame has been sent out.
  void InsertCodedVideoFrame(const EncodedVideoFrame* video_frame,
                             const base::TimeTicks& capture_time,
                             const base::Closure callback);

  // Only called from the main cast thread.
  void IncomingRtcpPacket(const uint8* packet, int length,
                          const base::Closure callback);

  void set_clock(base::TickClock* clock) {
    clock_ = clock;
    congestion_control_.set_clock(clock);
    rtcp_->set_clock(clock);
    rtp_sender_->set_clock(clock);
  }

 protected:
  // Protected for testability.
  void OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback);

 private:
  friend class LocalRtcpVideoSenderFeedback;

  // Schedule when we should send the next RTPC report,
  // via a PostDelayedTask to the main cast thread.
  void ScheduleNextRtcpReport();
  void SendRtcpReport();

  // Schedule when we should check that we have received an acknowledgment, or a
  // loss report from our remote peer. If we have not heard back from our remote
  // peer we speculatively resend our oldest unacknowledged frame (the whole
  // frame). Note for this to happen we need to lose all pending packets (in
  // normal operation 3 full frames), hence this is the last resort to prevent
  // us getting stuck after a long outage.
  void ScheduleNextResendCheck();
  void ResendCheck();

  // Monitor how many frames that are silently dropped by the video sender
  // per time unit.
  void ScheduleNextSkippedFramesCheck();
  void SkippedFramesCheck();

  void SendEncodedVideoFrame(const EncodedVideoFrame* video_frame,
                             const base::TimeTicks& capture_time);
  void OnReceivedIntraFrameRequest();
  void ResendFrame(uint8 resend_frame_id);
  void ReceivedAck(uint8 acked_frame_id);
  void UpdateFramesInFlight();

  void SendEncodedVideoFrameMainThread(
      scoped_ptr<EncodedVideoFrame> video_frame,
      const base::TimeTicks& capture_time);

  const uint32 incoming_feedback_ssrc_;
  const base::TimeDelta rtp_max_delay_;
  const int max_frame_rate_;

  scoped_refptr<CastThread> cast_thread_;
  scoped_ptr<LocalRtcpVideoSenderFeedback> rtcp_feedback_;
  scoped_ptr<LocalRtpVideoSenderStatistics> rtp_video_sender_statistics_;
  scoped_refptr<VideoEncoder> video_encoder_;
  scoped_ptr<Rtcp> rtcp_;
  scoped_ptr<RtpSender> rtp_sender_;
  VideoEncoderController* video_encoder_controller_;
  uint8 max_unacked_frames_;
  int last_acked_frame_id_;
  int last_sent_frame_id_;
  int last_sent_key_frame_id_;
  int duplicate_ack_;
  base::TimeTicks last_send_time_;
  base::TimeTicks last_checked_skip_count_time_;
  int last_skip_count_;
  CongestionControl congestion_control_;

  base::DefaultTickClock default_tick_clock_;
  base::TickClock* clock_;

  base::WeakPtrFactory<VideoSender> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(VideoSender);
};

}  // namespace cast
}  // namespace media

#endif  // MEDIA_CAST_VIDEO_SENDER_VIDEO_SENDER_H_