Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 #include "media/cast/cast_sender_impl.h" | 4 #include "media/cast/cast_sender_impl.h" |
| 5 | 5 |
| 6 #include "base/bind.h" | 6 #include "base/bind.h" |
| 7 #include "base/callback.h" | 7 #include "base/callback.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "media/base/video_frame.h" | 10 #include "media/base/video_frame.h" |
| 11 | 11 |
| 12 namespace media { | 12 namespace media { |
| 13 namespace cast { | 13 namespace cast { |
| 14 | 14 |
| 15 // The LocalFrameInput class posts all incoming frames; audio and video to the | 15 // The LocalFrameInput class posts all incoming frames, both audio and video, to |
| 16 // main cast thread for processing. | 16 // the main cast thread for processing., therefore frames can be inserted from |
| 17 // This make the cast sender interface thread safe. | 17 // any thread. |
| 18 class LocalFrameInput : public FrameInput { | 18 class LocalFrameInput : public FrameInput { |
| 19 public: | 19 public: |
| 20 LocalFrameInput(scoped_refptr<CastEnvironment> cast_environment, | 20 LocalFrameInput(scoped_refptr<CastEnvironment> cast_environment) |
| 21 base::WeakPtr<AudioSender> audio_sender, | 21 : cast_environment_(cast_environment) {} |
| 22 base::WeakPtr<VideoSender> video_sender) | 22 |
| 23 : cast_environment_(cast_environment), | 23 virtual void SetAudioSender(base::WeakPtr<AudioSender> audio_sender) |
| 24 audio_sender_(audio_sender), | 24 OVERRIDE { |
| 25 video_sender_(video_sender) {} | 25 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 26 audio_sender_ = audio_sender; | |
| 27 } | |
| 28 | |
| 29 virtual void SetVideoSender(base::WeakPtr<VideoSender> video_sender) | |
| 30 OVERRIDE { | |
| 31 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | |
| 32 video_sender_ = video_sender; | |
| 33 } | |
| 26 | 34 |
| 27 virtual void InsertRawVideoFrame( | 35 virtual void InsertRawVideoFrame( |
| 28 const scoped_refptr<media::VideoFrame>& video_frame, | 36 const scoped_refptr<media::VideoFrame>& video_frame, |
| 29 const base::TimeTicks& capture_time) OVERRIDE { | 37 const base::TimeTicks& capture_time) OVERRIDE { |
| 30 cast_environment_->PostTask(CastEnvironment::MAIN, | 38 cast_environment_->PostTask(CastEnvironment::MAIN, |
| 31 FROM_HERE, | 39 FROM_HERE, |
| 32 base::Bind(&VideoSender::InsertRawVideoFrame, | 40 base::Bind(&VideoSender::InsertRawVideoFrame, |
| 33 video_sender_, | 41 video_sender_, |
|
Ami GONE FROM CHROMIUM
2014/02/14 18:23:54
Since InsertRVF() can be called on any thread, wha
mikhal1
2014/02/18 19:20:43
Check out the new version!
On 2014/02/14 18:23:54,
| |
| 34 video_frame, | 42 video_frame, |
| 35 capture_time)); | 43 capture_time)); |
| 36 } | 44 } |
| 37 | 45 |
| 38 virtual void InsertAudio(const AudioBus* audio_bus, | 46 virtual void InsertAudio(const AudioBus* audio_bus, |
| 39 const base::TimeTicks& recorded_time, | 47 const base::TimeTicks& recorded_time, |
| 40 const base::Closure& done_callback) OVERRIDE { | 48 const base::Closure& done_callback) OVERRIDE { |
| 41 cast_environment_->PostTask(CastEnvironment::MAIN, | 49 cast_environment_->PostTask(CastEnvironment::MAIN, |
| 42 FROM_HERE, | 50 FROM_HERE, |
| 43 base::Bind(&AudioSender::InsertAudio, | 51 base::Bind(&AudioSender::InsertAudio, |
| 44 audio_sender_, | 52 audio_sender_, |
|
Ami GONE FROM CHROMIUM
2014/02/14 18:23:54
ditto
mikhal1
2014/02/18 19:20:43
Done.
| |
| 45 audio_bus, | 53 audio_bus, |
| 46 recorded_time, | 54 recorded_time, |
| 47 done_callback)); | 55 done_callback)); |
| 48 } | 56 } |
| 49 | 57 |
| 50 protected: | 58 protected: |
| 51 virtual ~LocalFrameInput() {} | 59 virtual ~LocalFrameInput() {} |
| 52 | 60 |
| 53 private: | 61 private: |
| 54 friend class base::RefCountedThreadSafe<LocalFrameInput>; | 62 friend class base::RefCountedThreadSafe<LocalFrameInput>; |
| 55 | 63 |
| 56 scoped_refptr<CastEnvironment> cast_environment_; | 64 scoped_refptr<CastEnvironment> cast_environment_; |
| 57 base::WeakPtr<AudioSender> audio_sender_; | 65 base::WeakPtr<AudioSender> audio_sender_; |
| 58 base::WeakPtr<VideoSender> video_sender_; | 66 base::WeakPtr<VideoSender> video_sender_; |
| 59 | 67 |
| 60 DISALLOW_COPY_AND_ASSIGN(LocalFrameInput); | 68 DISALLOW_COPY_AND_ASSIGN(LocalFrameInput); |
| 61 }; | 69 }; |
| 62 | 70 |
| 63 CastSender* CastSender::CreateCastSender( | 71 CastSender* CastSender::Create( |
| 64 scoped_refptr<CastEnvironment> cast_environment, | 72 scoped_refptr<CastEnvironment> cast_environment, |
| 65 const AudioSenderConfig* audio_config, | 73 const CastInitializationCallback& cast_initialization_cb, |
| 66 const VideoSenderConfig* video_config, | |
| 67 const scoped_refptr<GpuVideoAcceleratorFactories>& gpu_factories, | |
| 68 const CastInitializationCallback& initialization_status, | |
| 69 transport::CastTransportSender* const transport_sender) { | 74 transport::CastTransportSender* const transport_sender) { |
| 70 CHECK(cast_environment); | 75 CHECK(cast_environment); |
| 71 return new CastSenderImpl(cast_environment, | 76 return new CastSenderImpl( |
| 72 audio_config, | 77 cast_environment, cast_initialization_cb, transport_sender); |
| 73 video_config, | |
| 74 gpu_factories, | |
| 75 initialization_status, | |
| 76 transport_sender); | |
| 77 } | 78 } |
| 78 | 79 |
| 79 CastSenderImpl::CastSenderImpl( | 80 CastSenderImpl::CastSenderImpl( |
| 80 scoped_refptr<CastEnvironment> cast_environment, | 81 scoped_refptr<CastEnvironment> cast_environment, |
| 81 const AudioSenderConfig* audio_config, | 82 const CastInitializationCallback& cast_initialization_cb, |
| 82 const VideoSenderConfig* video_config, | |
| 83 const scoped_refptr<GpuVideoAcceleratorFactories>& gpu_factories, | |
| 84 const CastInitializationCallback& initialization_status, | |
| 85 transport::CastTransportSender* const transport_sender) | 83 transport::CastTransportSender* const transport_sender) |
| 86 : initialization_callback_(initialization_status), | 84 : initialization_callback_(cast_initialization_cb), |
| 85 // ReceivedPacket is valid as long as CastSenderImpl is valid, and | |
| 86 // therefore we can call base::Unretained. | |
|
Ami GONE FROM CHROMIUM
2014/02/14 18:23:54
Class is valid as long as OtherClass is valid
does
mikhal1
2014/02/18 19:20:43
I think you may be on to something here :o
Removed
| |
| 87 packet_receiver_( | 87 packet_receiver_( |
| 88 base::Bind(&CastSenderImpl::ReceivedPacket, base::Unretained(this))), | 88 base::Bind(&CastSenderImpl::ReceivedPacket, base::Unretained(this))), |
| 89 cast_environment_(cast_environment), | 89 cast_environment_(cast_environment), |
| 90 transport_sender_(transport_sender), | |
| 91 ssrc_of_audio_sender_(0), | |
| 92 ssrc_of_video_sender_(0), | |
| 90 weak_factory_(this) { | 93 weak_factory_(this) { |
| 91 CHECK(cast_environment); | 94 CHECK(cast_environment); |
| 92 CHECK(audio_config || video_config); | 95 frame_input_ = new LocalFrameInput(cast_environment); |
| 96 } | |
| 93 | 97 |
| 94 base::WeakPtr<AudioSender> audio_sender_ptr; | 98 void CastSenderImpl::InitializeAudio(const AudioSenderConfig& audio_config) { |
| 95 base::WeakPtr<VideoSender> video_sender_ptr; | 99 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 100 CHECK(audio_config.use_external_encoder || | |
| 101 cast_environment_->HasAudioEncoderThread()); | |
| 96 | 102 |
| 97 if (audio_config) { | 103 audio_sender_.reset( |
| 98 CHECK(audio_config->use_external_encoder || | 104 new AudioSender(cast_environment_, audio_config, transport_sender_)); |
| 99 cast_environment->HasAudioEncoderThread()); | |
| 100 | 105 |
| 101 audio_sender_.reset( | 106 CastInitializationStatus status = audio_sender_->InitializationResult(); |
| 102 new AudioSender(cast_environment, *audio_config, transport_sender)); | |
| 103 ssrc_of_audio_sender_ = audio_config->incoming_feedback_ssrc; | |
| 104 audio_sender_ptr = audio_sender_->AsWeakPtr(); | |
| 105 | 107 |
| 106 CastInitializationStatus status = audio_sender_->InitializationResult(); | 108 if (status == STATUS_AUDIO_INITIALIZED) { |
| 107 if (status != STATUS_INITIALIZED || !video_config) { | 109 ssrc_of_audio_sender_ = audio_config.incoming_feedback_ssrc; |
| 108 if (status == STATUS_INITIALIZED && !video_config) { | 110 frame_input_->SetAudioSender(audio_sender_->AsWeakPtr()); |
| 109 // Audio only. | |
| 110 frame_input_ = new LocalFrameInput( | |
| 111 cast_environment, audio_sender_ptr, video_sender_ptr); | |
| 112 } | |
| 113 cast_environment->PostTask( | |
| 114 CastEnvironment::MAIN, | |
| 115 FROM_HERE, | |
| 116 base::Bind(&CastSenderImpl::InitializationResult, | |
| 117 weak_factory_.GetWeakPtr(), | |
| 118 status)); | |
| 119 return; | |
| 120 } | |
| 121 } | 111 } |
| 122 if (video_config) { | |
| 123 CHECK(video_config->use_external_encoder || | |
| 124 cast_environment->HasVideoEncoderThread()); | |
| 125 | 112 |
| 126 video_sender_.reset( | 113 cast_environment_->PostTask(CastEnvironment::MAIN, |
| 127 new VideoSender(cast_environment, | 114 FROM_HERE, |
| 128 *video_config, | 115 base::Bind(&CastSenderImpl::InitializationResult, |
| 129 gpu_factories, | 116 weak_factory_.GetWeakPtr(), |
| 130 base::Bind(&CastSenderImpl::InitializationResult, | 117 status)); |
| 131 weak_factory_.GetWeakPtr()), | 118 } |
| 132 transport_sender)); | |
| 133 video_sender_ptr = video_sender_->AsWeakPtr(); | |
| 134 ssrc_of_video_sender_ = video_config->incoming_feedback_ssrc; | |
| 135 } | |
| 136 frame_input_ = | |
| 137 new LocalFrameInput(cast_environment, audio_sender_ptr, video_sender_ptr); | |
| 138 | 119 |
| 139 // Handing over responsibility to call NotifyInitialization to the | 120 void CastSenderImpl::InitializeVideo( |
| 140 // video sender. | 121 const VideoSenderConfig& video_config, |
| 122 const scoped_refptr<GpuVideoAcceleratorFactories>& gpu_factories) { | |
| 123 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | |
| 124 CHECK(video_config.use_external_encoder || | |
| 125 cast_environment_->HasVideoEncoderThread()); | |
| 126 | |
| 127 video_sender_.reset( | |
| 128 new VideoSender(cast_environment_, | |
| 129 video_config, | |
| 130 gpu_factories, | |
| 131 base::Bind(&CastSenderImpl::InitializationResult, | |
| 132 weak_factory_.GetWeakPtr()), | |
| 133 transport_sender_)); | |
| 134 | |
| 135 ssrc_of_video_sender_ = video_config.incoming_feedback_ssrc; | |
| 136 frame_input_->SetVideoSender(video_sender_->AsWeakPtr()); | |
| 141 } | 137 } |
| 142 | 138 |
| 143 CastSenderImpl::~CastSenderImpl() {} | 139 CastSenderImpl::~CastSenderImpl() {} |
| 144 | 140 |
| 145 // ReceivedPacket handle the incoming packets to the cast sender | 141 // ReceivedPacket handle the incoming packets to the cast sender |
| 146 // it's only expected to receive RTCP feedback packets from the remote cast | 142 // it's only expected to receive RTCP feedback packets from the remote cast |
| 147 // receiver. The class verifies that that it is a RTCP packet and based on the | 143 // receiver. The class verifies that that it is a RTCP packet and based on the |
| 148 // SSRC of the incoming packet route the packet to the correct sender; audio or | 144 // SSRC of the incoming packet route the packet to the correct sender; audio or |
| 149 // video. | 145 // video. |
| 150 // | 146 // |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 200 } else { | 196 } else { |
| 201 VLOG(1) << "Received a RTCP packet with a non matching sender SSRC " | 197 VLOG(1) << "Received a RTCP packet with a non matching sender SSRC " |
| 202 << ssrc_of_sender; | 198 << ssrc_of_sender; |
| 203 } | 199 } |
| 204 } | 200 } |
| 205 | 201 |
| 206 scoped_refptr<FrameInput> CastSenderImpl::frame_input() { return frame_input_; } | 202 scoped_refptr<FrameInput> CastSenderImpl::frame_input() { return frame_input_; } |
| 207 | 203 |
| 208 transport::PacketReceiverCallback CastSenderImpl::packet_receiver() { | 204 transport::PacketReceiverCallback CastSenderImpl::packet_receiver() { |
| 209 return packet_receiver_; | 205 return packet_receiver_; |
| 210 return base::Bind(&CastSenderImpl::ReceivedPacket, base::Unretained(this)); | 206 return base::Bind(&CastSenderImpl::ReceivedPacket, base::Unretained(this)); |
|
Ami GONE FROM CHROMIUM
2014/02/14 18:23:54
lolwat?
mikhal1
2014/02/18 19:20:43
hmmm...somewhat speechless. Bad merge?
On 2014/02/
| |
| 211 } | 207 } |
| 212 | 208 |
| 213 void CastSenderImpl::InitializationResult(CastInitializationStatus status) | 209 void CastSenderImpl::InitializationResult(CastInitializationStatus status) |
| 214 const { | 210 const { |
| 215 initialization_callback_.Run(status); | 211 initialization_callback_.Run(status); |
| 216 } | 212 } |
| 217 | 213 |
| 218 } // namespace cast | 214 } // namespace cast |
| 219 } // namespace media | 215 } // namespace media |
| OLD | NEW |