Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(518)

Side by Side Diff: webrtc/voice_engine/channel.cc

Issue 2861583005: Resolves race between Channel::ProcessAndEncodeAudio() and Channel::StopSend() (Closed)
Patch Set: Added one extra lock Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/voice_engine/channel.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 1199 matching lines...) Expand 10 before | Expand all | Expand 10 after
1210 return 0; 1210 return 0;
1211 } 1211 }
1212 1212
1213 int32_t Channel::StartSend() { 1213 int32_t Channel::StartSend() {
1214 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 1214 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
1215 "Channel::StartSend()"); 1215 "Channel::StartSend()");
1216 if (channel_state_.Get().sending) { 1216 if (channel_state_.Get().sending) {
1217 return 0; 1217 return 0;
1218 } 1218 }
1219 channel_state_.SetSending(true); 1219 channel_state_.SetSending(true);
1220 1220 {
1221 // It is now OK to start posting tasks to the encoder task queue.
1222 rtc::CritScope cs(&encoder_queue_lock_);
1223 encoder_queue_is_active_ = true;
1224 }
1221 // Resume the previous sequence number which was reset by StopSend(). This 1225 // Resume the previous sequence number which was reset by StopSend(). This
1222 // needs to be done before |sending| is set to true on the RTP/RTCP module. 1226 // needs to be done before |sending| is set to true on the RTP/RTCP module.
1223 if (send_sequence_number_) { 1227 if (send_sequence_number_) {
1224 _rtpRtcpModule->SetSequenceNumber(send_sequence_number_); 1228 _rtpRtcpModule->SetSequenceNumber(send_sequence_number_);
1225 } 1229 }
1226 _rtpRtcpModule->SetSendingMediaStatus(true); 1230 _rtpRtcpModule->SetSendingMediaStatus(true);
1227 if (_rtpRtcpModule->SetSendingStatus(true) != 0) { 1231 if (_rtpRtcpModule->SetSendingStatus(true) != 0) {
1228 _engineStatisticsPtr->SetLastError( 1232 _engineStatisticsPtr->SetLastError(
1229 VE_RTP_RTCP_MODULE_ERROR, kTraceError, 1233 VE_RTP_RTCP_MODULE_ERROR, kTraceError,
1230 "StartSend() RTP/RTCP failed to start sending"); 1234 "StartSend() RTP/RTCP failed to start sending");
(...skipping 14 matching lines...) Expand all
1245 } 1249 }
1246 channel_state_.SetSending(false); 1250 channel_state_.SetSending(false);
1247 1251
1248 // Post a task to the encoder thread which sets an event when the task is 1252 // Post a task to the encoder thread which sets an event when the task is
1249 // executed. We know that no more encoding tasks will be added to the task 1253 // executed. We know that no more encoding tasks will be added to the task
1250 // queue for this channel since sending is now deactivated. It means that, 1254 // queue for this channel since sending is now deactivated. It means that,
1251 // if we wait for the event to bet set, we know that no more pending tasks 1255 // if we wait for the event to bet set, we know that no more pending tasks
1252 // exists and it is therfore guaranteed that the task queue will never try 1256 // exists and it is therfore guaranteed that the task queue will never try
1253 // to acccess and invalid channel object. 1257 // to acccess and invalid channel object.
1254 RTC_DCHECK(encoder_queue_); 1258 RTC_DCHECK(encoder_queue_);
1259
1255 rtc::Event flush(false, false); 1260 rtc::Event flush(false, false);
1256 encoder_queue_->PostTask([&flush]() { flush.Set(); }); 1261 {
1262 // Clear |encoder_queue_is_active_| under lock to prevent any other tasks
1263 // than this final "flush task" to be posted on the queue.
1264 rtc::CritScope cs(&encoder_queue_lock_);
1265 encoder_queue_is_active_ = false;
1266 encoder_queue_->PostTask([&flush]() { flush.Set(); });
1267 }
1257 flush.Wait(rtc::Event::kForever); 1268 flush.Wait(rtc::Event::kForever);
1258 1269
1259 // Store the sequence number to be able to pick up the same sequence for 1270 // Store the sequence number to be able to pick up the same sequence for
1260 // the next StartSend(). This is needed for restarting device, otherwise 1271 // the next StartSend(). This is needed for restarting device, otherwise
1261 // it might cause libSRTP to complain about packets being replayed. 1272 // it might cause libSRTP to complain about packets being replayed.
1262 // TODO(xians): Remove this workaround after RtpRtcpModule's refactoring 1273 // TODO(xians): Remove this workaround after RtpRtcpModule's refactoring
1263 // CL is landed. See issue 1274 // CL is landed. See issue
1264 // https://code.google.com/p/webrtc/issues/detail?id=2111 . 1275 // https://code.google.com/p/webrtc/issues/detail?id=2111 .
1265 send_sequence_number_ = _rtpRtcpModule->SequenceNumber(); 1276 send_sequence_number_ = _rtpRtcpModule->SequenceNumber();
1266 1277
(...skipping 1450 matching lines...) Expand 10 before | Expand all | Expand 10 after
2717 else 2728 else
2718 audio_coding_->DisableNack(); 2729 audio_coding_->DisableNack();
2719 } 2730 }
2720 2731
2721 // Called when we are missing one or more packets. 2732 // Called when we are missing one or more packets.
2722 int Channel::ResendPackets(const uint16_t* sequence_numbers, int length) { 2733 int Channel::ResendPackets(const uint16_t* sequence_numbers, int length) {
2723 return _rtpRtcpModule->SendNACK(sequence_numbers, length); 2734 return _rtpRtcpModule->SendNACK(sequence_numbers, length);
2724 } 2735 }
2725 2736
2726 void Channel::ProcessAndEncodeAudio(const AudioFrame& audio_input) { 2737 void Channel::ProcessAndEncodeAudio(const AudioFrame& audio_input) {
2727 RTC_DCHECK(channel_state_.Get().sending); 2738 // Avoid posting any new tasks if sending was already stopped in StopSend().
2739 rtc::CritScope cs(&encoder_queue_lock_);
2740 if (!encoder_queue_is_active_) {
2741 return;
2742 }
2728 std::unique_ptr<AudioFrame> audio_frame(new AudioFrame()); 2743 std::unique_ptr<AudioFrame> audio_frame(new AudioFrame());
2729 // TODO(henrika): try to avoid copying by moving ownership of audio frame 2744 // TODO(henrika): try to avoid copying by moving ownership of audio frame
2730 // either into pool of frames or into the task itself. 2745 // either into pool of frames or into the task itself.
2731 audio_frame->CopyFrom(audio_input); 2746 audio_frame->CopyFrom(audio_input);
2732 audio_frame->id_ = ChannelId(); 2747 audio_frame->id_ = ChannelId();
2733 encoder_queue_->PostTask(std::unique_ptr<rtc::QueuedTask>( 2748 encoder_queue_->PostTask(std::unique_ptr<rtc::QueuedTask>(
2734 new ProcessAndEncodeAudioTask(std::move(audio_frame), this))); 2749 new ProcessAndEncodeAudioTask(std::move(audio_frame), this)));
2735 } 2750 }
2736 2751
2737 void Channel::ProcessAndEncodeAudio(const int16_t* audio_data, 2752 void Channel::ProcessAndEncodeAudio(const int16_t* audio_data,
2738 int sample_rate, 2753 int sample_rate,
2739 size_t number_of_frames, 2754 size_t number_of_frames,
2740 size_t number_of_channels) { 2755 size_t number_of_channels) {
2741 RTC_DCHECK(channel_state_.Get().sending); 2756 // Avoid posting as new task if sending was already stopped in StopSend().
2757 rtc::CritScope cs(&encoder_queue_lock_);
2758 if (!encoder_queue_is_active_) {
2759 return;
2760 }
2742 CodecInst codec; 2761 CodecInst codec;
2743 GetSendCodec(codec); 2762 GetSendCodec(codec);
2744 std::unique_ptr<AudioFrame> audio_frame(new AudioFrame()); 2763 std::unique_ptr<AudioFrame> audio_frame(new AudioFrame());
2745 audio_frame->id_ = ChannelId(); 2764 audio_frame->id_ = ChannelId();
2746 audio_frame->sample_rate_hz_ = std::min(codec.plfreq, sample_rate); 2765 audio_frame->sample_rate_hz_ = std::min(codec.plfreq, sample_rate);
2747 audio_frame->num_channels_ = std::min(number_of_channels, codec.channels); 2766 audio_frame->num_channels_ = std::min(number_of_channels, codec.channels);
2748 RemixAndResample(audio_data, number_of_frames, number_of_channels, 2767 RemixAndResample(audio_data, number_of_frames, number_of_channels,
2749 sample_rate, &input_resampler_, audio_frame.get()); 2768 sample_rate, &input_resampler_, audio_frame.get());
2750 encoder_queue_->PostTask(std::unique_ptr<rtc::QueuedTask>( 2769 encoder_queue_->PostTask(std::unique_ptr<rtc::QueuedTask>(
2751 new ProcessAndEncodeAudioTask(std::move(audio_frame), this))); 2770 new ProcessAndEncodeAudioTask(std::move(audio_frame), this)));
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
3121 int64_t min_rtt = 0; 3140 int64_t min_rtt = 0;
3122 if (_rtpRtcpModule->RTT(remoteSSRC, &rtt, &avg_rtt, &min_rtt, &max_rtt) != 3141 if (_rtpRtcpModule->RTT(remoteSSRC, &rtt, &avg_rtt, &min_rtt, &max_rtt) !=
3123 0) { 3142 0) {
3124 return 0; 3143 return 0;
3125 } 3144 }
3126 return rtt; 3145 return rtt;
3127 } 3146 }
3128 3147
3129 } // namespace voe 3148 } // namespace voe
3130 } // namespace webrtc 3149 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/voice_engine/channel.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698