diff options
Diffstat (limited to 'chromium/media/cast/cast_sender_impl.cc')
-rw-r--r-- | chromium/media/cast/cast_sender_impl.cc | 274 |
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 |