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. |
17 // This make the cast sender interface thread safe. | 17 // This makes the cast sender interface thread safe. |
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 void SetAudioSender(base::WeakPtr<AudioSender> audio_sender) OVERRIDE { |
24 audio_sender_(audio_sender), | 24 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
25 video_sender_(video_sender) {} | 25 audio_sender_ = audio_sender; |
26 } | |
27 | |
28 void SetVideoSender(base::WeakPtr<VideoSender> video_sender) OVERRIDE { | |
29 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | |
30 video_sender_ = video_sender; | |
31 } | |
26 | 32 |
27 virtual void InsertRawVideoFrame( | 33 virtual void InsertRawVideoFrame( |
28 const scoped_refptr<media::VideoFrame>& video_frame, | 34 const scoped_refptr<media::VideoFrame>& video_frame, |
29 const base::TimeTicks& capture_time) OVERRIDE { | 35 const base::TimeTicks& capture_time) OVERRIDE { |
30 cast_environment_->PostTask(CastEnvironment::MAIN, | 36 if (!video_sender_) { |
31 FROM_HERE, | 37 NOTREACHED(); |
Ami GONE FROM CHROMIUM
2014/02/13 18:02:14
Then why not simply
CHECK(video_sender_);
?
Alpha Left Google
2014/02/13 19:53:59
NOTREACHED() should be a DCHECK. So this should be
mikhal1
2014/02/14 18:03:16
Adding the DCHECKs cause the code to crash when ca
| |
32 base::Bind(&VideoSender::InsertRawVideoFrame, | 38 return; |
33 video_sender_, | 39 } |
34 video_frame, | 40 cast_environment_->PostTask( |
35 capture_time)); | 41 CastEnvironment::MAIN, |
42 FROM_HERE, | |
43 base::Bind(&LocalFrameInput::InsertRawVideoOnMainThread, | |
44 base::Unretained(this), | |
Ami GONE FROM CHROMIUM
2014/02/13 18:02:14
what makes Unretained safe?
(in general, any Unre
Alpha Left Google
2014/02/13 19:53:59
FrameInput is RefCountedThreadSafe so there's no n
| |
45 video_frame, | |
46 capture_time)); | |
47 } | |
48 | |
49 void InsertRawVideoOnMainThread( | |
50 const scoped_refptr<media::VideoFrame>& video_frame, | |
51 const base::TimeTicks& capture_time) { | |
52 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | |
53 video_sender_->InsertRawVideoFrame(video_frame, capture_time); | |
Ami GONE FROM CHROMIUM
2014/02/13 18:02:14
What if video_sender_'s been invalidated by this p
Alpha Left Google
2014/02/13 19:53:59
video_sender_ is a WeakPtr. That's why it's derefe
Ami GONE FROM CHROMIUM
2014/02/13 20:43:50
I don't understand this comment.
Bind is magic whe
Alpha Left Google
2014/02/13 20:50:35
The reason doing a Bind in line 44 doesn't work is
Ami GONE FROM CHROMIUM
2014/02/13 20:57:31
I think you misunderstood my suggestion.
I'm sugge
Ami GONE FROM CHROMIUM
2014/02/13 21:02:30
hclam@ points out in person that if SetVideoSender
mikhal1
2014/02/14 18:03:16
Redone. Let me know what you think.
On 2014/02/13
| |
36 } | 54 } |
37 | 55 |
38 virtual void InsertAudio(const AudioBus* audio_bus, | 56 virtual void InsertAudio(const AudioBus* audio_bus, |
Ami GONE FROM CHROMIUM
2014/02/13 18:02:14
same comments apply to audio below as video above.
mikhal1
2014/02/14 18:03:16
Done.
| |
39 const base::TimeTicks& recorded_time, | 57 const base::TimeTicks& recorded_time, |
40 const base::Closure& done_callback) OVERRIDE { | 58 const base::Closure& done_callback) OVERRIDE { |
41 cast_environment_->PostTask(CastEnvironment::MAIN, | 59 if (!audio_sender_) { |
42 FROM_HERE, | 60 NOTREACHED(); |
43 base::Bind(&AudioSender::InsertAudio, | 61 return; |
44 audio_sender_, | 62 } |
45 audio_bus, | 63 cast_environment_->PostTask( |
46 recorded_time, | 64 CastEnvironment::MAIN, |
47 done_callback)); | 65 FROM_HERE, |
66 base::Bind(&LocalFrameInput::InsertAudioOnMainThread, | |
67 base::Unretained(this), | |
68 audio_bus, | |
69 recorded_time, | |
70 done_callback)); | |
71 } | |
72 | |
73 void InsertAudioOnMainThread(const AudioBus* audio_bus, | |
74 const base::TimeTicks& recorded_time, | |
75 const base::Closure& done_callback) { | |
76 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | |
77 audio_sender_->InsertAudio(audio_bus, recorded_time, done_callback); | |
48 } | 78 } |
49 | 79 |
50 protected: | 80 protected: |
51 virtual ~LocalFrameInput() {} | 81 virtual ~LocalFrameInput() {} |
52 | 82 |
53 private: | 83 private: |
54 friend class base::RefCountedThreadSafe<LocalFrameInput>; | 84 friend class base::RefCountedThreadSafe<LocalFrameInput>; |
55 | 85 |
56 scoped_refptr<CastEnvironment> cast_environment_; | 86 scoped_refptr<CastEnvironment> cast_environment_; |
57 base::WeakPtr<AudioSender> audio_sender_; | 87 base::WeakPtr<AudioSender> audio_sender_; |
58 base::WeakPtr<VideoSender> video_sender_; | 88 base::WeakPtr<VideoSender> video_sender_; |
59 | 89 |
60 DISALLOW_COPY_AND_ASSIGN(LocalFrameInput); | 90 DISALLOW_COPY_AND_ASSIGN(LocalFrameInput); |
61 }; | 91 }; |
62 | 92 |
63 CastSender* CastSender::CreateCastSender( | 93 CastSender* CastSender::CreateCastSender( |
64 scoped_refptr<CastEnvironment> cast_environment, | 94 scoped_refptr<CastEnvironment> cast_environment, |
65 const AudioSenderConfig* audio_config, | 95 const CastInitializationCallback& cast_initialization, |
Ami GONE FROM CHROMIUM
2014/02/13 18:02:14
fwiw in media/ code we've followed a convention th
mikhal1
2014/02/14 18:03:16
Done.
| |
66 const VideoSenderConfig* video_config, | |
67 const scoped_refptr<GpuVideoAcceleratorFactories>& gpu_factories, | |
68 const CastInitializationCallback& initialization_status, | |
69 transport::CastTransportSender* const transport_sender) { | 96 transport::CastTransportSender* const transport_sender) { |
70 CHECK(cast_environment); | 97 CHECK(cast_environment); |
71 return new CastSenderImpl(cast_environment, | 98 return new CastSenderImpl( |
72 audio_config, | 99 cast_environment, cast_initialization, transport_sender); |
73 video_config, | |
74 gpu_factories, | |
75 initialization_status, | |
76 transport_sender); | |
77 } | 100 } |
78 | 101 |
79 CastSenderImpl::CastSenderImpl( | 102 CastSenderImpl::CastSenderImpl( |
80 scoped_refptr<CastEnvironment> cast_environment, | 103 scoped_refptr<CastEnvironment> cast_environment, |
81 const AudioSenderConfig* audio_config, | 104 const CastInitializationCallback& cast_initialization, |
82 const VideoSenderConfig* video_config, | |
83 const scoped_refptr<GpuVideoAcceleratorFactories>& gpu_factories, | |
84 const CastInitializationCallback& initialization_status, | |
85 transport::CastTransportSender* const transport_sender) | 105 transport::CastTransportSender* const transport_sender) |
86 : initialization_callback_(initialization_status), | 106 : initialization_callback_(cast_initialization), |
87 packet_receiver_( | 107 packet_receiver_( |
88 base::Bind(&CastSenderImpl::ReceivedPacket, base::Unretained(this))), | 108 base::Bind(&CastSenderImpl::ReceivedPacket, base::Unretained(this))), |
Ami GONE FROM CHROMIUM
2014/02/13 18:02:14
I'm guessing Unretained here to avoid a reference
mikhal1
2014/02/14 18:03:16
Done.
| |
89 cast_environment_(cast_environment), | 109 cast_environment_(cast_environment), |
110 transport_sender_(transport_sender), | |
111 ssrc_of_audio_sender_(0), | |
112 ssrc_of_video_sender_(0), | |
90 weak_factory_(this) { | 113 weak_factory_(this) { |
91 CHECK(cast_environment); | 114 CHECK(cast_environment); |
92 CHECK(audio_config || video_config); | 115 frame_input_ = new LocalFrameInput(cast_environment); |
116 } | |
93 | 117 |
94 base::WeakPtr<AudioSender> audio_sender_ptr; | 118 void CastSenderImpl::InitializeAudio(const AudioSenderConfig& audio_config) { |
95 base::WeakPtr<VideoSender> video_sender_ptr; | 119 CHECK(audio_config.use_external_encoder || |
Alpha Left Google
2014/02/13 19:53:59
DCHECK that this is called on the cast main thread
mikhal1
2014/02/14 18:03:16
Done.
| |
120 cast_environment_->HasAudioEncoderThread()); | |
96 | 121 |
97 if (audio_config) { | 122 audio_sender_.reset( |
98 CHECK(audio_config->use_external_encoder || | 123 new AudioSender(cast_environment_, audio_config, transport_sender_)); |
99 cast_environment->HasAudioEncoderThread()); | |
100 | 124 |
101 audio_sender_.reset( | 125 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 | 126 |
106 CastInitializationStatus status = audio_sender_->InitializationResult(); | 127 if (status == STATUS_AUDIO_INITIALIZED) { |
107 if (status != STATUS_INITIALIZED || !video_config) { | 128 ssrc_of_audio_sender_ = audio_config.incoming_feedback_ssrc; |
108 if (status == STATUS_INITIALIZED && !video_config) { | 129 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 } | 130 } |
122 if (video_config) { | |
123 CHECK(video_config->use_external_encoder || | |
124 cast_environment->HasVideoEncoderThread()); | |
125 | 131 |
126 video_sender_.reset( | 132 cast_environment_->PostTask(CastEnvironment::MAIN, |
127 new VideoSender(cast_environment, | 133 FROM_HERE, |
128 *video_config, | 134 base::Bind(&CastSenderImpl::InitializationResult, |
129 gpu_factories, | 135 weak_factory_.GetWeakPtr(), |
130 base::Bind(&CastSenderImpl::InitializationResult, | 136 status)); |
131 weak_factory_.GetWeakPtr()), | 137 } |
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 | 138 |
139 // Handing over responsibility to call NotifyInitialization to the | 139 void CastSenderImpl::InitializeVideo( |
140 // video sender. | 140 const VideoSenderConfig& video_config, |
141 const scoped_refptr<GpuVideoAcceleratorFactories>& gpu_factories) { | |
142 CHECK(video_config.use_external_encoder || | |
Alpha Left Google
2014/02/13 19:53:59
DCHECK that this is called on the cast main thread
mikhal1
2014/02/14 18:03:16
Done.
| |
143 cast_environment_->HasVideoEncoderThread()); | |
144 | |
145 video_sender_.reset( | |
146 new VideoSender(cast_environment_, | |
147 video_config, | |
148 gpu_factories, | |
149 base::Bind(&CastSenderImpl::InitializationResult, | |
150 weak_factory_.GetWeakPtr()), | |
151 transport_sender_)); | |
152 | |
153 ssrc_of_video_sender_ = video_config.incoming_feedback_ssrc; | |
154 frame_input_->SetVideoSender(video_sender_->AsWeakPtr()); | |
141 } | 155 } |
142 | 156 |
143 CastSenderImpl::~CastSenderImpl() {} | 157 CastSenderImpl::~CastSenderImpl() {} |
144 | 158 |
145 // ReceivedPacket handle the incoming packets to the cast sender | 159 // ReceivedPacket handle the incoming packets to the cast sender |
146 // it's only expected to receive RTCP feedback packets from the remote cast | 160 // 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 | 161 // 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 | 162 // SSRC of the incoming packet route the packet to the correct sender; audio or |
149 // video. | 163 // video. |
150 // | 164 // |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
210 return base::Bind(&CastSenderImpl::ReceivedPacket, base::Unretained(this)); | 224 return base::Bind(&CastSenderImpl::ReceivedPacket, base::Unretained(this)); |
211 } | 225 } |
212 | 226 |
213 void CastSenderImpl::InitializationResult(CastInitializationStatus status) | 227 void CastSenderImpl::InitializationResult(CastInitializationStatus status) |
214 const { | 228 const { |
215 initialization_callback_.Run(status); | 229 initialization_callback_.Run(status); |
216 } | 230 } |
217 | 231 |
218 } // namespace cast | 232 } // namespace cast |
219 } // namespace media | 233 } // namespace media |
OLD | NEW |