summaryrefslogtreecommitdiffstats
path: root/chromium/media/cast/cast_sender_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/media/cast/cast_sender_impl.cc')
-rw-r--r--chromium/media/cast/cast_sender_impl.cc274
1 files changed, 150 insertions, 124 deletions
diff --git a/chromium/media/cast/cast_sender_impl.cc b/chromium/media/cast/cast_sender_impl.cc
index 69ebd53c6bd..361e4d8dc12 100644
--- a/chromium/media/cast/cast_sender_impl.cc
+++ b/chromium/media/cast/cast_sender_impl.cc
@@ -12,62 +12,136 @@
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 {
+// The LocalVideoFrameInput class posts all incoming video frames to the main
+// cast thread for processing.
+class LocalVideoFrameInput : public VideoFrameInput {
public:
- LocalFrameInput(scoped_refptr<CastEnvironment> cast_environment,
- base::WeakPtr<AudioSender> audio_sender,
- base::WeakPtr<VideoSender> video_sender)
- : cast_environment_(cast_environment),
- audio_sender_(audio_sender),
- video_sender_(video_sender) {}
+ LocalVideoFrameInput(scoped_refptr<CastEnvironment> cast_environment,
+ base::WeakPtr<VideoSender> video_sender)
+ : cast_environment_(cast_environment), video_sender_(video_sender) {}
virtual void InsertRawVideoFrame(
const scoped_refptr<media::VideoFrame>& video_frame,
const base::TimeTicks& capture_time) OVERRIDE {
- cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
- base::Bind(&VideoSender::InsertRawVideoFrame, video_sender_,
- video_frame, capture_time));
+ cast_environment_->PostTask(CastEnvironment::MAIN,
+ FROM_HERE,
+ base::Bind(&VideoSender::InsertRawVideoFrame,
+ video_sender_,
+ video_frame,
+ capture_time));
}
- virtual void InsertCodedVideoFrame(const EncodedVideoFrame* video_frame,
- const base::TimeTicks& capture_time,
- const base::Closure callback) OVERRIDE {
- cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
- base::Bind(&VideoSender::InsertCodedVideoFrame, video_sender_,
- video_frame, capture_time, callback));
- }
+ protected:
+ virtual ~LocalVideoFrameInput() {}
- virtual void InsertAudio(const AudioBus* audio_bus,
- const base::TimeTicks& recorded_time,
- const base::Closure& done_callback) OVERRIDE {
- cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
- base::Bind(&AudioSender::InsertAudio, audio_sender_,
- audio_bus, recorded_time, done_callback));
- }
+ private:
+ friend class base::RefCountedThreadSafe<LocalVideoFrameInput>;
+
+ scoped_refptr<CastEnvironment> cast_environment_;
+ base::WeakPtr<VideoSender> video_sender_;
- virtual void InsertCodedAudioFrame(const EncodedAudioFrame* audio_frame,
- const base::TimeTicks& recorded_time,
- const base::Closure callback) OVERRIDE {
- cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
- base::Bind(&AudioSender::InsertCodedAudioFrame, audio_sender_,
- audio_frame, recorded_time, callback));
+ DISALLOW_COPY_AND_ASSIGN(LocalVideoFrameInput);
+};
+
+// The LocalAudioFrameInput class posts all incoming audio frames to the main
+// cast thread for processing. Therefore frames can be inserted from any thread.
+class LocalAudioFrameInput : public AudioFrameInput {
+ public:
+ LocalAudioFrameInput(scoped_refptr<CastEnvironment> cast_environment,
+ base::WeakPtr<AudioSender> audio_sender)
+ : cast_environment_(cast_environment), audio_sender_(audio_sender) {}
+
+ virtual void InsertAudio(scoped_ptr<AudioBus> audio_bus,
+ const base::TimeTicks& recorded_time) OVERRIDE {
+ cast_environment_->PostTask(CastEnvironment::MAIN,
+ FROM_HERE,
+ base::Bind(&AudioSender::InsertAudio,
+ audio_sender_,
+ base::Passed(&audio_bus),
+ recorded_time));
}
protected:
- virtual ~LocalFrameInput() {}
+ virtual ~LocalAudioFrameInput() {}
private:
- friend class base::RefCountedThreadSafe<LocalFrameInput>;
+ friend class base::RefCountedThreadSafe<LocalAudioFrameInput>;
scoped_refptr<CastEnvironment> cast_environment_;
base::WeakPtr<AudioSender> audio_sender_;
- base::WeakPtr<VideoSender> video_sender_;
+
+ DISALLOW_COPY_AND_ASSIGN(LocalAudioFrameInput);
};
-// LocalCastSenderPacketReceiver handle the incoming packets to the cast sender
+scoped_ptr<CastSender> CastSender::Create(
+ scoped_refptr<CastEnvironment> cast_environment,
+ transport::CastTransportSender* const transport_sender) {
+ CHECK(cast_environment);
+ return scoped_ptr<CastSender>(
+ new CastSenderImpl(cast_environment, transport_sender));
+}
+
+CastSenderImpl::CastSenderImpl(
+ scoped_refptr<CastEnvironment> cast_environment,
+ transport::CastTransportSender* const transport_sender)
+ : cast_environment_(cast_environment),
+ transport_sender_(transport_sender),
+ weak_factory_(this) {
+ CHECK(cast_environment);
+}
+
+void CastSenderImpl::InitializeAudio(
+ const AudioSenderConfig& audio_config,
+ const CastInitializationCallback& cast_initialization_cb) {
+ DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
+ CHECK(audio_config.use_external_encoder ||
+ cast_environment_->HasAudioThread());
+
+ VLOG(1) << "CastSenderImpl@" << this << "::InitializeAudio()";
+
+ audio_sender_.reset(
+ new AudioSender(cast_environment_, audio_config, transport_sender_));
+
+ const CastInitializationStatus status = audio_sender_->InitializationResult();
+ if (status == STATUS_AUDIO_INITIALIZED) {
+ ssrc_of_audio_sender_ = audio_config.incoming_feedback_ssrc;
+ audio_frame_input_ =
+ new LocalAudioFrameInput(cast_environment_, audio_sender_->AsWeakPtr());
+ }
+ cast_initialization_cb.Run(status);
+}
+
+void CastSenderImpl::InitializeVideo(
+ const VideoSenderConfig& video_config,
+ const CastInitializationCallback& cast_initialization_cb,
+ const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
+ const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb) {
+ DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
+ CHECK(video_config.use_external_encoder ||
+ cast_environment_->HasVideoThread());
+
+ VLOG(1) << "CastSenderImpl@" << this << "::InitializeVideo()";
+
+ video_sender_.reset(new VideoSender(cast_environment_,
+ video_config,
+ create_vea_cb,
+ create_video_encode_mem_cb,
+ transport_sender_));
+
+ const CastInitializationStatus status = video_sender_->InitializationResult();
+ if (status == STATUS_VIDEO_INITIALIZED) {
+ ssrc_of_video_sender_ = video_config.incoming_feedback_ssrc;
+ video_frame_input_ =
+ new LocalVideoFrameInput(cast_environment_, video_sender_->AsWeakPtr());
+ }
+ cast_initialization_cb.Run(status);
+}
+
+CastSenderImpl::~CastSenderImpl() {
+ VLOG(1) << "CastSenderImpl@" << this << "::~CastSenderImpl()";
+}
+
+// ReceivedPacket 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
@@ -92,102 +166,54 @@ class LocalFrameInput : public FrameInput {
// 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<CastEnvironment> cast_environment,
- base::WeakPtr<AudioSender> audio_sender,
- base::WeakPtr<VideoSender> video_sender,
- uint32 ssrc_of_audio_sender,
- uint32 ssrc_of_video_sender)
- : cast_environment_(cast_environment),
- 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 void ReceivedPacket(const uint8* packet,
- size_t 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_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, callback);
+void CastSenderImpl::ReceivedPacket(scoped_ptr<Packet> packet) {
+ DCHECK(cast_environment_);
+ size_t length = packet->size();
+ const uint8_t* data = &packet->front();
+ if (!Rtcp::IsRtcpPacket(data, length)) {
+ VLOG(1) << "CastSenderImpl@" << this << "::ReceivedPacket() -- "
+ << "Received an invalid (non-RTCP?) packet in the cast sender.";
+ return;
+ }
+ uint32 ssrc_of_sender = Rtcp::GetSsrcOfSender(data, length);
+ if (ssrc_of_sender == ssrc_of_audio_sender_) {
+ if (!audio_sender_) {
+ NOTREACHED();
return;
}
- uint32 ssrc_of_sender = Rtcp::GetSsrcOfSender(packet, length);
- if (ssrc_of_sender == ssrc_of_audio_sender_) {
- cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
- base::Bind(&AudioSender::IncomingRtcpPacket, audio_sender_,
- packet, length, callback));
- } else if (ssrc_of_sender == ssrc_of_video_sender_) {
- cast_environment_->PostTask(CastEnvironment::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_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, callback);
+ cast_environment_->PostTask(CastEnvironment::MAIN,
+ FROM_HERE,
+ base::Bind(&AudioSender::IncomingRtcpPacket,
+ audio_sender_->AsWeakPtr(),
+ base::Passed(&packet)));
+ } else if (ssrc_of_sender == ssrc_of_video_sender_) {
+ if (!video_sender_) {
+ NOTREACHED();
+ return;
}
+ cast_environment_->PostTask(CastEnvironment::MAIN,
+ FROM_HERE,
+ base::Bind(&VideoSender::IncomingRtcpPacket,
+ video_sender_->AsWeakPtr(),
+ base::Passed(&packet)));
+ } else {
+ VLOG(1) << "CastSenderImpl@" << this << "::ReceivedPacket() -- "
+ << "Received a RTCP packet with a non matching sender SSRC "
+ << ssrc_of_sender;
}
+}
- protected:
- virtual ~LocalCastSenderPacketReceiver() {}
-
- private:
- friend class base::RefCountedThreadSafe<LocalCastSenderPacketReceiver>;
-
- scoped_refptr<CastEnvironment> cast_environment_;
- base::WeakPtr<AudioSender> audio_sender_;
- base::WeakPtr<VideoSender> video_sender_;
- const uint32 ssrc_of_audio_sender_;
- const uint32 ssrc_of_video_sender_;
-};
-
-CastSender* CastSender::CreateCastSender(
- scoped_refptr<CastEnvironment> cast_environment,
- const AudioSenderConfig& audio_config,
- const VideoSenderConfig& video_config,
- VideoEncoderController* const video_encoder_controller,
- PacketSender* const packet_sender) {
- return new CastSenderImpl(cast_environment,
- audio_config,
- video_config,
- video_encoder_controller,
- packet_sender);
+scoped_refptr<AudioFrameInput> CastSenderImpl::audio_frame_input() {
+ return audio_frame_input_;
}
-CastSenderImpl::CastSenderImpl(
- scoped_refptr<CastEnvironment> cast_environment,
- const AudioSenderConfig& audio_config,
- const VideoSenderConfig& video_config,
- VideoEncoderController* const video_encoder_controller,
- PacketSender* const packet_sender)
- : pacer_(cast_environment, packet_sender),
- audio_sender_(cast_environment, audio_config, &pacer_),
- video_sender_(cast_environment, video_config, video_encoder_controller,
- &pacer_),
- frame_input_(new LocalFrameInput(cast_environment,
- audio_sender_.AsWeakPtr(),
- video_sender_.AsWeakPtr())),
- packet_receiver_(new LocalCastSenderPacketReceiver(cast_environment,
- audio_sender_.AsWeakPtr(), video_sender_.AsWeakPtr(),
- audio_config.incoming_feedback_ssrc,
- video_config.incoming_feedback_ssrc)) {}
-
-CastSenderImpl::~CastSenderImpl() {}
-
-scoped_refptr<FrameInput> CastSenderImpl::frame_input() {
- return frame_input_;
+scoped_refptr<VideoFrameInput> CastSenderImpl::video_frame_input() {
+ return video_frame_input_;
}
-scoped_refptr<PacketReceiver> CastSenderImpl::packet_receiver() {
- return packet_receiver_;
+transport::PacketReceiverCallback CastSenderImpl::packet_receiver() {
+ return base::Bind(&CastSenderImpl::ReceivedPacket,
+ weak_factory_.GetWeakPtr());
}
} // namespace cast