summaryrefslogtreecommitdiff
path: root/media/cast/video_sender/video_sender.h
blob: 5b436dca7f3ddf63d244bd8f9cb435d47dd4429a (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
146
147
148
149
150
151
152
153
154
155
156
// 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/tick_clock.h"
#include "base/time/time.h"
#include "media/cast/cast_config.h"
#include "media/cast/cast_environment.h"
#include "media/cast/congestion_control/congestion_control.h"
#include "media/cast/logging/logging_defines.h"
#include "media/cast/rtcp/rtcp.h"
#include "media/cast/rtcp/sender_rtcp_event_subscriber.h"
#include "media/filters/gpu_video_accelerator_factories.h"
#include "media/video/video_encode_accelerator.h"

namespace media {
class VideoFrame;

namespace cast {
class LocalRtcpVideoSenderFeedback;
class LocalVideoEncoderCallback;
class VideoEncoder;

namespace transport {
class CastTransportSender;
}

// 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<CastEnvironment> cast_environment,
              const VideoSenderConfig& video_config,
              const scoped_refptr<GpuVideoAcceleratorFactories>& gpu_factories,
              const CastInitializationCallback& cast_initialization_cb,
              transport::CastTransportSender* const transport_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 scoped_refptr<media::VideoFrame>& video_frame,
                           const base::TimeTicks& capture_time);

  // Only called from the main cast thread.
  void IncomingRtcpPacket(scoped_ptr<Packet> packet);

  // Store rtp stats computed at the Cast transport sender.
  void StoreStatistics(const transport::RtcpSenderInfo& sender_info,
                       base::TimeTicks time_sent,
                       uint32 rtp_timestamp);

 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 transport::EncodedVideoFrame* video_frame,
                             const base::TimeTicks& capture_time);
  void ResendFrame(uint32 resend_frame_id);
  void ReceivedAck(uint32 acked_frame_id);
  void UpdateFramesInFlight();

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

  void SendEncodedVideoFrameToTransport(
      scoped_ptr<transport::EncodedVideoFrame> encoded_frame,
      const base::TimeTicks& capture_time);

  void InitializeTimers();

  void ResendPacketsOnTransportThread(
      const transport::MissingFramesAndPacketsMap& missing_packets);

  base::TimeDelta rtp_max_delay_;
  const int max_frame_rate_;

  scoped_refptr<CastEnvironment> cast_environment_;
  transport::CastTransportSender* const transport_sender_;

  // Subscribes to raw events.
  // Processes raw audio events to be sent over to the cast receiver via RTCP.
  SenderRtcpEventSubscriber event_subscriber_;
  RtpSenderStatistics rtp_stats_;
  scoped_ptr<LocalRtcpVideoSenderFeedback> rtcp_feedback_;
  scoped_ptr<VideoEncoder> video_encoder_;
  scoped_ptr<Rtcp> rtcp_;
  uint8 max_unacked_frames_;
  int last_acked_frame_id_;
  int last_sent_frame_id_;
  int duplicate_ack_;
  base::TimeTicks last_send_time_;
  base::TimeTicks last_checked_skip_count_time_;
  int last_skip_count_;
  CongestionControl congestion_control_;

  // This is a "good enough" mapping for finding the RTP timestamp associated
  // with a video frame. The key is the lowest 8 bits of frame id (which is
  // what is sent via RTCP). This map is used for logging purposes. The only
  // time when this mapping will be incorrect is when it receives an ACK for a
  // old enough frame such that 8-bit wrap around has already occurred, which
  // should be pretty rare.
  RtpTimestamp frame_id_to_rtp_timestamp_[256];

  bool initialized_;
  // Indicator for receiver acknowledgments.
  bool active_session_;

  // NOTE: Weak pointers must be invalidated before all other member variables.
  base::WeakPtrFactory<VideoSender> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(VideoSender);
};

}  // namespace cast
}  // namespace media

#endif  // MEDIA_CAST_VIDEO_SENDER_VIDEO_SENDER_H_