summaryrefslogtreecommitdiffstats
path: root/media/cast/cast_sender_impl.cc
diff options
context:
space:
mode:
authorpwestin@google.com <pwestin@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-12 00:05:01 +0000
committerpwestin@google.com <pwestin@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-12 00:05:01 +0000
commit428c39804a10f55c0ae81392b25806bc0117d053 (patch)
tree8a913d600a181cf7d03d01120c3dab83437985ec /media/cast/cast_sender_impl.cc
parente05f7f3d6db7108e73a92fb004ded36fa3e7624d (diff)
downloadchromium_src-428c39804a10f55c0ae81392b25806bc0117d053.zip
chromium_src-428c39804a10f55c0ae81392b25806bc0117d053.tar.gz
chromium_src-428c39804a10f55c0ae81392b25806bc0117d053.tar.bz2
Added cast sender impl and made required modifications to the pacer.
BUG= Review URL: https://chromiumcodereview.appspot.com/24051002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@222666 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/cast/cast_sender_impl.cc')
-rw-r--r--media/cast/cast_sender_impl.cc176
1 files changed, 176 insertions, 0 deletions
diff --git a/media/cast/cast_sender_impl.cc b/media/cast/cast_sender_impl.cc
new file mode 100644
index 0000000..76f2f99
--- /dev/null
+++ b/media/cast/cast_sender_impl.cc
@@ -0,0 +1,176 @@
+// 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.
+#include "media/cast/cast_sender_impl.h"
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
+
+namespace media {
+namespace cast {
+
+// The LocalFrameInput class posts all incoming frames; audio and video to the
+// main cast thread for processing.
+// This make the cast sender interface thread safe.
+class LocalFrameInput : public FrameInput {
+ public:
+ LocalFrameInput(scoped_refptr<CastThread> cast_thread,
+ base::WeakPtr<AudioSender> audio_sender,
+ base::WeakPtr<VideoSender> video_sender)
+ : cast_thread_(cast_thread),
+ audio_sender_(audio_sender),
+ video_sender_(video_sender) {}
+
+ virtual void InsertRawVideoFrame(const I420VideoFrame* video_frame,
+ const base::TimeTicks& capture_time,
+ const base::Closure callback) OVERRIDE {
+ cast_thread_->PostTask(CastThread::MAIN, FROM_HERE,
+ base::Bind(&VideoSender::InsertRawVideoFrame, video_sender_,
+ video_frame, capture_time, callback));
+ }
+
+ virtual void InsertCodedVideoFrame(const EncodedVideoFrame* video_frame,
+ const base::TimeTicks& capture_time,
+ const base::Closure callback) OVERRIDE {
+ cast_thread_->PostTask(CastThread::MAIN, FROM_HERE,
+ base::Bind(&VideoSender::InsertCodedVideoFrame, video_sender_,
+ video_frame, capture_time, callback));
+ }
+
+ virtual void InsertRawAudioFrame(const PcmAudioFrame* audio_frame,
+ const base::TimeTicks& recorded_time,
+ const base::Closure callback) OVERRIDE {
+ cast_thread_->PostTask(CastThread::MAIN, FROM_HERE,
+ base::Bind(&AudioSender::InsertRawAudioFrame, audio_sender_,
+ audio_frame, recorded_time, callback));
+ }
+
+ virtual void InsertCodedAudioFrame(const EncodedAudioFrame* audio_frame,
+ const base::TimeTicks& recorded_time,
+ const base::Closure callback) OVERRIDE {
+ cast_thread_->PostTask(CastThread::MAIN, FROM_HERE,
+ base::Bind(&AudioSender::InsertCodedAudioFrame, audio_sender_,
+ audio_frame, recorded_time, callback));
+ }
+
+ private:
+ scoped_refptr<CastThread> cast_thread_;
+ base::WeakPtr<AudioSender> audio_sender_;
+ base::WeakPtr<VideoSender> video_sender_;
+};
+
+// LocalCastSenderPacketReceiver handle the incoming packets to the cast sender
+// it's only expected to receive RTCP feedback packets from the remote cast
+// receiver. The class verifies that that it is a RTCP packet and based on the
+// SSRC of the incoming packet route the packet to the correct sender; audio or
+// video.
+//
+// Definition of SSRC as defined in RFC 3550.
+// Synchronization source (SSRC): The source of a stream of RTP
+// packets, identified by a 32-bit numeric SSRC identifier carried in
+// the RTP header so as not to be dependent upon the network address.
+// All packets from a synchronization source form part of the same
+// timing and sequence number space, so a receiver groups packets by
+// synchronization source for playback. Examples of synchronization
+// sources include the sender of a stream of packets derived from a
+// signal source such as a microphone or a camera, or an RTP mixer
+// (see below). A synchronization source may change its data format,
+// e.g., audio encoding, over time. The SSRC identifier is a
+// randomly chosen value meant to be globally unique within a
+// particular RTP session (see Section 8). A participant need not
+// use the same SSRC identifier for all the RTP sessions in a
+// multimedia session; the binding of the SSRC identifiers is
+// provided through RTCP (see Section 6.5.1). If a participant
+// generates multiple streams in one RTP session, for example from
+// separate video cameras, each MUST be identified as a different
+// SSRC.
+
+class LocalCastSenderPacketReceiver : public PacketReceiver {
+ public:
+ LocalCastSenderPacketReceiver(scoped_refptr<CastThread> cast_thread,
+ base::WeakPtr<AudioSender> audio_sender,
+ base::WeakPtr<VideoSender> video_sender,
+ uint32 ssrc_of_audio_sender,
+ uint32 ssrc_of_video_sender)
+ : cast_thread_(cast_thread),
+ audio_sender_(audio_sender),
+ video_sender_(video_sender),
+ ssrc_of_audio_sender_(ssrc_of_audio_sender),
+ ssrc_of_video_sender_(ssrc_of_video_sender) {}
+
+ virtual ~LocalCastSenderPacketReceiver() {}
+
+ virtual void ReceivedPacket(const uint8* packet,
+ int length,
+ const base::Closure callback) OVERRIDE {
+ if (!Rtcp::IsRtcpPacket(packet, length)) {
+ // We should have no incoming RTP packets.
+ // No action; just log and call the callback informing that we are done
+ // with the packet.
+ VLOG(1) << "Unexpectedly received a RTP packet in the cast sender";
+ cast_thread_->PostTask(CastThread::MAIN, FROM_HERE, callback);
+ return;
+ }
+ uint32 ssrc_of_sender = Rtcp::GetSsrcOfSender(packet, length);
+ if (ssrc_of_sender == ssrc_of_audio_sender_) {
+ cast_thread_->PostTask(CastThread::MAIN, FROM_HERE,
+ base::Bind(&AudioSender::IncomingRtcpPacket, audio_sender_,
+ packet, length, callback));
+ } else if (ssrc_of_sender == ssrc_of_video_sender_) {
+ cast_thread_->PostTask(CastThread::MAIN, FROM_HERE,
+ base::Bind(&VideoSender::IncomingRtcpPacket, video_sender_,
+ packet, length, callback));
+ } else {
+ // No action; just log and call the callback informing that we are done
+ // with the packet.
+ VLOG(1) << "Received a RTCP packet with a non matching sender SSRC "
+ << ssrc_of_sender;
+
+ cast_thread_->PostTask(CastThread::MAIN, FROM_HERE, callback);
+ }
+ }
+
+ private:
+ scoped_refptr<CastThread> cast_thread_;
+ base::WeakPtr<AudioSender> audio_sender_;
+ base::WeakPtr<VideoSender> video_sender_;
+ uint32 ssrc_of_audio_sender_;
+ uint32 ssrc_of_video_sender_;
+};
+
+CastSender* CastSender::CreateCastSender(
+ scoped_refptr<CastThread> cast_thread,
+ const AudioSenderConfig& audio_config,
+ const VideoSenderConfig& video_config,
+ VideoEncoderController* const video_encoder_controller,
+ PacketSender* const packet_sender) {
+ return new CastSenderImpl(cast_thread,
+ audio_config,
+ video_config,
+ video_encoder_controller,
+ packet_sender);
+}
+
+CastSenderImpl::CastSenderImpl(
+ scoped_refptr<CastThread> cast_thread,
+ const AudioSenderConfig& audio_config,
+ const VideoSenderConfig& video_config,
+ VideoEncoderController* const video_encoder_controller,
+ PacketSender* const packet_sender)
+ : pacer_(cast_thread, packet_sender),
+ audio_sender_(cast_thread, audio_config, &pacer_),
+ video_sender_(cast_thread, video_config, video_encoder_controller,
+ &pacer_),
+ frame_input_(new LocalFrameInput(cast_thread, audio_sender_.AsWeakPtr(),
+ video_sender_.AsWeakPtr())),
+ packet_receiver_(new LocalCastSenderPacketReceiver(cast_thread,
+ audio_sender_.AsWeakPtr(), video_sender_.AsWeakPtr(),
+ audio_config.incoming_feedback_ssrc,
+ video_config.incoming_feedback_ssrc)) {}
+
+CastSenderImpl::~CastSenderImpl() {}
+
+} // namespace cast
+} // namespace media