• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 #include "media/cast/cast_sender_impl.h"
5 
6 #include "base/bind.h"
7 #include "base/callback.h"
8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h"
10 #include "media/base/video_frame.h"
11 
12 namespace media {
13 namespace cast {
14 
15 // The LocalFrameInput class posts all incoming frames; audio and video to the
16 // main cast thread for processing.
17 // This make the cast sender interface thread safe.
18 class LocalFrameInput : public FrameInput {
19  public:
LocalFrameInput(scoped_refptr<CastEnvironment> cast_environment,base::WeakPtr<AudioSender> audio_sender,base::WeakPtr<VideoSender> video_sender)20   LocalFrameInput(scoped_refptr<CastEnvironment> cast_environment,
21                   base::WeakPtr<AudioSender> audio_sender,
22                   base::WeakPtr<VideoSender> video_sender)
23      : cast_environment_(cast_environment),
24        audio_sender_(audio_sender),
25        video_sender_(video_sender) {}
26 
InsertRawVideoFrame(const scoped_refptr<media::VideoFrame> & video_frame,const base::TimeTicks & capture_time)27   virtual void InsertRawVideoFrame(
28       const scoped_refptr<media::VideoFrame>& video_frame,
29       const base::TimeTicks& capture_time) OVERRIDE {
30     cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
31         base::Bind(&VideoSender::InsertRawVideoFrame, video_sender_,
32             video_frame, capture_time));
33   }
34 
InsertCodedVideoFrame(const EncodedVideoFrame * video_frame,const base::TimeTicks & capture_time,const base::Closure callback)35   virtual void InsertCodedVideoFrame(const EncodedVideoFrame* video_frame,
36                                      const base::TimeTicks& capture_time,
37                                      const base::Closure callback) OVERRIDE {
38     cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
39         base::Bind(&VideoSender::InsertCodedVideoFrame, video_sender_,
40             video_frame, capture_time, callback));
41   }
42 
InsertAudio(const AudioBus * audio_bus,const base::TimeTicks & recorded_time,const base::Closure & done_callback)43   virtual void InsertAudio(const AudioBus* audio_bus,
44                            const base::TimeTicks& recorded_time,
45                            const base::Closure& done_callback) OVERRIDE {
46     cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
47         base::Bind(&AudioSender::InsertAudio, audio_sender_,
48             audio_bus, recorded_time, done_callback));
49   }
50 
InsertCodedAudioFrame(const EncodedAudioFrame * audio_frame,const base::TimeTicks & recorded_time,const base::Closure callback)51   virtual void InsertCodedAudioFrame(const EncodedAudioFrame* audio_frame,
52                                      const base::TimeTicks& recorded_time,
53                                      const base::Closure callback) OVERRIDE {
54     cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
55         base::Bind(&AudioSender::InsertCodedAudioFrame, audio_sender_,
56             audio_frame, recorded_time, callback));
57   }
58 
59  protected:
~LocalFrameInput()60   virtual ~LocalFrameInput() {}
61 
62  private:
63   friend class base::RefCountedThreadSafe<LocalFrameInput>;
64 
65   scoped_refptr<CastEnvironment> cast_environment_;
66   base::WeakPtr<AudioSender> audio_sender_;
67   base::WeakPtr<VideoSender> video_sender_;
68 };
69 
70 // LocalCastSenderPacketReceiver handle the incoming packets to the cast sender
71 // it's only expected to receive RTCP feedback packets from the remote cast
72 // receiver. The class verifies that that it is a RTCP packet and based on the
73 // SSRC of the incoming packet route the packet to the correct sender; audio or
74 // video.
75 //
76 // Definition of SSRC as defined in RFC 3550.
77 // Synchronization source (SSRC): The source of a stream of RTP
78 //    packets, identified by a 32-bit numeric SSRC identifier carried in
79 //    the RTP header so as not to be dependent upon the network address.
80 //    All packets from a synchronization source form part of the same
81 //    timing and sequence number space, so a receiver groups packets by
82 //    synchronization source for playback.  Examples of synchronization
83 //    sources include the sender of a stream of packets derived from a
84 //    signal source such as a microphone or a camera, or an RTP mixer
85 //    (see below).  A synchronization source may change its data format,
86 //    e.g., audio encoding, over time.  The SSRC identifier is a
87 //    randomly chosen value meant to be globally unique within a
88 //    particular RTP session (see Section 8).  A participant need not
89 //    use the same SSRC identifier for all the RTP sessions in a
90 //    multimedia session; the binding of the SSRC identifiers is
91 //    provided through RTCP (see Section 6.5.1).  If a participant
92 //    generates multiple streams in one RTP session, for example from
93 //    separate video cameras, each MUST be identified as a different
94 //    SSRC.
95 
96 class LocalCastSenderPacketReceiver : public PacketReceiver {
97  public:
LocalCastSenderPacketReceiver(scoped_refptr<CastEnvironment> cast_environment,base::WeakPtr<AudioSender> audio_sender,base::WeakPtr<VideoSender> video_sender,uint32 ssrc_of_audio_sender,uint32 ssrc_of_video_sender)98   LocalCastSenderPacketReceiver(scoped_refptr<CastEnvironment> cast_environment,
99                                 base::WeakPtr<AudioSender> audio_sender,
100                                 base::WeakPtr<VideoSender> video_sender,
101                                 uint32 ssrc_of_audio_sender,
102                                 uint32 ssrc_of_video_sender)
103       : cast_environment_(cast_environment),
104         audio_sender_(audio_sender),
105         video_sender_(video_sender),
106         ssrc_of_audio_sender_(ssrc_of_audio_sender),
107         ssrc_of_video_sender_(ssrc_of_video_sender) {}
108 
ReceivedPacket(const uint8 * packet,size_t length,const base::Closure callback)109   virtual void ReceivedPacket(const uint8* packet,
110                               size_t length,
111                               const base::Closure callback) OVERRIDE {
112     if (!Rtcp::IsRtcpPacket(packet, length)) {
113       // We should have no incoming RTP packets.
114       // No action; just log and call the callback informing that we are done
115       // with the packet.
116       VLOG(1) << "Unexpectedly received a RTP packet in the cast sender";
117       cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, callback);
118       return;
119     }
120     uint32 ssrc_of_sender = Rtcp::GetSsrcOfSender(packet, length);
121     if (ssrc_of_sender == ssrc_of_audio_sender_) {
122       cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
123           base::Bind(&AudioSender::IncomingRtcpPacket, audio_sender_,
124               packet, length, callback));
125     } else if (ssrc_of_sender == ssrc_of_video_sender_) {
126       cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
127           base::Bind(&VideoSender::IncomingRtcpPacket, video_sender_,
128               packet, length, callback));
129     } else {
130       // No action; just log and call the callback informing that we are done
131       // with the packet.
132       VLOG(1) << "Received a RTCP packet with a non matching sender SSRC "
133               << ssrc_of_sender;
134 
135       cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, callback);
136     }
137   }
138 
139  protected:
~LocalCastSenderPacketReceiver()140   virtual ~LocalCastSenderPacketReceiver() {}
141 
142  private:
143   friend class base::RefCountedThreadSafe<LocalCastSenderPacketReceiver>;
144 
145   scoped_refptr<CastEnvironment> cast_environment_;
146   base::WeakPtr<AudioSender> audio_sender_;
147   base::WeakPtr<VideoSender> video_sender_;
148   const uint32 ssrc_of_audio_sender_;
149   const uint32 ssrc_of_video_sender_;
150 };
151 
CreateCastSender(scoped_refptr<CastEnvironment> cast_environment,const AudioSenderConfig & audio_config,const VideoSenderConfig & video_config,VideoEncoderController * const video_encoder_controller,PacketSender * const packet_sender)152 CastSender* CastSender::CreateCastSender(
153     scoped_refptr<CastEnvironment> cast_environment,
154     const AudioSenderConfig& audio_config,
155     const VideoSenderConfig& video_config,
156     VideoEncoderController* const video_encoder_controller,
157     PacketSender* const packet_sender) {
158   return new CastSenderImpl(cast_environment,
159                             audio_config,
160                             video_config,
161                             video_encoder_controller,
162                             packet_sender);
163 }
164 
CastSenderImpl(scoped_refptr<CastEnvironment> cast_environment,const AudioSenderConfig & audio_config,const VideoSenderConfig & video_config,VideoEncoderController * const video_encoder_controller,PacketSender * const packet_sender)165 CastSenderImpl::CastSenderImpl(
166     scoped_refptr<CastEnvironment> cast_environment,
167     const AudioSenderConfig& audio_config,
168     const VideoSenderConfig& video_config,
169     VideoEncoderController* const video_encoder_controller,
170     PacketSender* const packet_sender)
171     : pacer_(cast_environment, packet_sender),
172       audio_sender_(cast_environment, audio_config, &pacer_),
173       video_sender_(cast_environment, video_config, video_encoder_controller,
174                     &pacer_),
175       frame_input_(new LocalFrameInput(cast_environment,
176                                        audio_sender_.AsWeakPtr(),
177                                        video_sender_.AsWeakPtr())),
178       packet_receiver_(new LocalCastSenderPacketReceiver(cast_environment,
179           audio_sender_.AsWeakPtr(), video_sender_.AsWeakPtr(),
180           audio_config.incoming_feedback_ssrc,
181           video_config.incoming_feedback_ssrc)) {}
182 
~CastSenderImpl()183 CastSenderImpl::~CastSenderImpl() {}
184 
frame_input()185 scoped_refptr<FrameInput> CastSenderImpl::frame_input() {
186   return frame_input_;
187 }
188 
packet_receiver()189 scoped_refptr<PacketReceiver> CastSenderImpl::packet_receiver() {
190   return packet_receiver_;
191 }
192 
193 }  // namespace cast
194 }  // namespace media
195