OLD | NEW |
---|---|
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2004 Google Inc. | 3 * Copyright 2004 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1218 config_.rtp.remote_ssrc = remote_ssrc; | 1218 config_.rtp.remote_ssrc = remote_ssrc; |
1219 config_.rtp.local_ssrc = local_ssrc; | 1219 config_.rtp.local_ssrc = local_ssrc; |
1220 config_.voe_channel_id = ch; | 1220 config_.voe_channel_id = ch; |
1221 config_.sync_group = sync_group; | 1221 config_.sync_group = sync_group; |
1222 RecreateAudioReceiveStream(use_combined_bwe, extensions); | 1222 RecreateAudioReceiveStream(use_combined_bwe, extensions); |
1223 } | 1223 } |
1224 | 1224 |
1225 ~WebRtcAudioReceiveStream() { | 1225 ~WebRtcAudioReceiveStream() { |
1226 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1226 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1227 call_->DestroyAudioReceiveStream(stream_); | 1227 call_->DestroyAudioReceiveStream(stream_); |
1228 RTC_DCHECK(!audio_callback_.get()); | |
1228 } | 1229 } |
1229 | 1230 |
1230 void RecreateAudioReceiveStream( | 1231 void RecreateAudioReceiveStream( |
1231 const std::vector<webrtc::RtpExtension>& extensions) { | 1232 const std::vector<webrtc::RtpExtension>& extensions) { |
1232 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1233 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1233 RecreateAudioReceiveStream(config_.combined_audio_video_bwe, extensions); | 1234 RecreateAudioReceiveStream(config_.combined_audio_video_bwe, extensions); |
1234 } | 1235 } |
1235 void RecreateAudioReceiveStream(bool use_combined_bwe) { | 1236 void RecreateAudioReceiveStream(bool use_combined_bwe) { |
1236 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1237 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1237 RecreateAudioReceiveStream(use_combined_bwe, config_.rtp.extensions); | 1238 RecreateAudioReceiveStream(use_combined_bwe, config_.rtp.extensions); |
1238 } | 1239 } |
1239 | 1240 |
1240 webrtc::AudioReceiveStream::Stats GetStats() const { | 1241 webrtc::AudioReceiveStream::Stats GetStats() const { |
1241 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1242 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1242 RTC_DCHECK(stream_); | 1243 RTC_DCHECK(stream_); |
1243 return stream_->GetStats(); | 1244 return stream_->GetStats(); |
1244 } | 1245 } |
1245 | 1246 |
1246 int channel() const { | 1247 int channel() const { |
1247 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1248 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1248 return config_.voe_channel_id; | 1249 return config_.voe_channel_id; |
1249 } | 1250 } |
1250 | 1251 |
1252 void SetRawAudioSink(webrtc::VoEExternalMedia* external_media, | |
1253 AudioRenderer::Sink* sink) { | |
1254 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | |
1255 if (sink) { | |
1256 RTC_DCHECK(!audio_callback_.get()); | |
1257 audio_callback_.reset(new AudioCallback(sink)); | |
1258 int err = external_media->RegisterExternalMediaProcessing( | |
the sun
2015/12/10 12:36:32
Add an API on AudioReceiveStream instead: SetRawAu
| |
1259 channel(), webrtc::kPlaybackPerChannel, *audio_callback_.get()); | |
1260 if (err != 0) | |
1261 audio_callback_.reset(); | |
1262 } else if (audio_callback_) { | |
1263 external_media->DeRegisterExternalMediaProcessing( | |
1264 channel(), webrtc::kPlaybackPerChannel); | |
1265 audio_callback_.reset(); | |
1266 } | |
1267 } | |
1268 | |
1251 private: | 1269 private: |
1252 void RecreateAudioReceiveStream(bool use_combined_bwe, | 1270 void RecreateAudioReceiveStream(bool use_combined_bwe, |
1253 const std::vector<webrtc::RtpExtension>& extensions) { | 1271 const std::vector<webrtc::RtpExtension>& extensions) { |
1254 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1272 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1255 if (stream_) { | 1273 if (stream_) { |
1256 call_->DestroyAudioReceiveStream(stream_); | 1274 call_->DestroyAudioReceiveStream(stream_); |
1257 stream_ = nullptr; | 1275 stream_ = nullptr; |
1258 } | 1276 } |
1259 config_.rtp.extensions = extensions; | 1277 config_.rtp.extensions = extensions; |
1260 config_.combined_audio_video_bwe = use_combined_bwe; | 1278 config_.combined_audio_video_bwe = use_combined_bwe; |
1261 RTC_DCHECK(!stream_); | 1279 RTC_DCHECK(!stream_); |
1262 stream_ = call_->CreateAudioReceiveStream(config_); | 1280 stream_ = call_->CreateAudioReceiveStream(config_); |
1263 RTC_CHECK(stream_); | 1281 RTC_CHECK(stream_); |
1264 } | 1282 } |
1265 | 1283 |
1284 class AudioCallback : public webrtc::VoEMediaProcess { | |
1285 public: | |
1286 explicit AudioCallback(AudioRenderer::Sink* sink) : sink_(sink) {} | |
1287 ~AudioCallback() { | |
1288 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
1289 sink_->OnClose(); | |
1290 } | |
1291 | |
1292 private: | |
1293 // VoEMediaProcess implementation. | |
1294 void Process(int channel, | |
1295 webrtc::ProcessingTypes type, | |
1296 int16_t audio_10ms[], | |
1297 size_t length, | |
1298 int sampling_freq, | |
1299 bool is_stereo) override { | |
1300 // Called on the audio thread from webrtc. This can be a ProcessThread | |
1301 // belonging to WebRTC or an externally owned thread. | |
1302 sink_->OnData(&audio_10ms[0], 16, sampling_freq, is_stereo ? 2 : 1, | |
1303 length); | |
1304 } | |
1305 | |
1306 rtc::ThreadChecker thread_checker_; | |
1307 AudioRenderer::Sink* const sink_; | |
1308 RTC_DISALLOW_COPY_AND_ASSIGN(AudioCallback); | |
1309 }; | |
1310 | |
1266 rtc::ThreadChecker worker_thread_checker_; | 1311 rtc::ThreadChecker worker_thread_checker_; |
1267 webrtc::Call* call_ = nullptr; | 1312 webrtc::Call* call_ = nullptr; |
1268 webrtc::AudioReceiveStream::Config config_; | 1313 webrtc::AudioReceiveStream::Config config_; |
1269 // The stream is owned by WebRtcAudioReceiveStream and may be reallocated if | 1314 // The stream is owned by WebRtcAudioReceiveStream and may be reallocated if |
1270 // configuration changes. | 1315 // configuration changes. |
1271 webrtc::AudioReceiveStream* stream_ = nullptr; | 1316 webrtc::AudioReceiveStream* stream_ = nullptr; |
1317 rtc::scoped_ptr<AudioCallback> audio_callback_; | |
1272 | 1318 |
1273 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioReceiveStream); | 1319 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioReceiveStream); |
1274 }; | 1320 }; |
1275 | 1321 |
1276 WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel(WebRtcVoiceEngine* engine, | 1322 WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel(WebRtcVoiceEngine* engine, |
1277 const AudioOptions& options, | 1323 const AudioOptions& options, |
1278 webrtc::Call* call) | 1324 webrtc::Call* call) |
1279 : engine_(engine), call_(call) { | 1325 : engine_(engine), call_(call) { |
1280 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel"; | 1326 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel"; |
1281 RTC_DCHECK(call); | 1327 RTC_DCHECK(call); |
(...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2025 // Deregister default channel, if that's the one being destroyed. | 2071 // Deregister default channel, if that's the one being destroyed. |
2026 if (IsDefaultRecvStream(ssrc)) { | 2072 if (IsDefaultRecvStream(ssrc)) { |
2027 default_recv_ssrc_ = -1; | 2073 default_recv_ssrc_ = -1; |
2028 } | 2074 } |
2029 | 2075 |
2030 const int channel = it->second->channel(); | 2076 const int channel = it->second->channel(); |
2031 | 2077 |
2032 // Clean up and delete the receive stream+channel. | 2078 // Clean up and delete the receive stream+channel. |
2033 LOG(LS_INFO) << "Removing audio receive stream " << ssrc | 2079 LOG(LS_INFO) << "Removing audio receive stream " << ssrc |
2034 << " with VoiceEngine channel #" << channel << "."; | 2080 << " with VoiceEngine channel #" << channel << "."; |
2081 it->second->SetRawAudioSink(engine()->voe()->external_media(), nullptr); | |
2035 delete it->second; | 2082 delete it->second; |
2036 recv_streams_.erase(it); | 2083 recv_streams_.erase(it); |
2037 return DeleteVoEChannel(channel); | 2084 return DeleteVoEChannel(channel); |
2038 } | 2085 } |
2039 | 2086 |
2040 bool WebRtcVoiceMediaChannel::SetLocalRenderer(uint32_t ssrc, | 2087 bool WebRtcVoiceMediaChannel::SetLocalRenderer(uint32_t ssrc, |
2041 AudioRenderer* renderer) { | 2088 AudioRenderer* renderer) { |
2042 auto it = send_streams_.find(ssrc); | 2089 auto it = send_streams_.find(ssrc); |
2043 if (it == send_streams_.end()) { | 2090 if (it == send_streams_.end()) { |
2044 if (renderer) { | 2091 if (renderer) { |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2401 rinfo.decoding_plc = stats.decoding_plc; | 2448 rinfo.decoding_plc = stats.decoding_plc; |
2402 rinfo.decoding_cng = stats.decoding_cng; | 2449 rinfo.decoding_cng = stats.decoding_cng; |
2403 rinfo.decoding_plc_cng = stats.decoding_plc_cng; | 2450 rinfo.decoding_plc_cng = stats.decoding_plc_cng; |
2404 rinfo.capture_start_ntp_time_ms = stats.capture_start_ntp_time_ms; | 2451 rinfo.capture_start_ntp_time_ms = stats.capture_start_ntp_time_ms; |
2405 info->receivers.push_back(rinfo); | 2452 info->receivers.push_back(rinfo); |
2406 } | 2453 } |
2407 | 2454 |
2408 return true; | 2455 return true; |
2409 } | 2456 } |
2410 | 2457 |
2458 void WebRtcVoiceMediaChannel::SetRawAudioSink(uint32_t ssrc, | |
2459 AudioRenderer::Sink* sink) { | |
2460 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | |
2461 const auto it = recv_streams_.find(ssrc); | |
2462 if (it == recv_streams_.end()) { | |
2463 LOG(LS_WARNING) << "SetRawAudioSink: no recv stream" << ssrc; | |
2464 return; | |
2465 } | |
2466 it->second->SetRawAudioSink(engine()->voe()->external_media(), sink); | |
2467 } | |
2468 | |
2411 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { | 2469 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { |
2412 unsigned int ulevel = 0; | 2470 unsigned int ulevel = 0; |
2413 int ret = engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); | 2471 int ret = engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); |
2414 return (ret == 0) ? static_cast<int>(ulevel) : -1; | 2472 return (ret == 0) ? static_cast<int>(ulevel) : -1; |
2415 } | 2473 } |
2416 | 2474 |
2417 int WebRtcVoiceMediaChannel::GetReceiveChannelId(uint32_t ssrc) const { | 2475 int WebRtcVoiceMediaChannel::GetReceiveChannelId(uint32_t ssrc) const { |
2418 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2476 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2419 const auto it = recv_streams_.find(ssrc); | 2477 const auto it = recv_streams_.find(ssrc); |
2420 if (it != recv_streams_.end()) { | 2478 if (it != recv_streams_.end()) { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2485 } | 2543 } |
2486 } else { | 2544 } else { |
2487 LOG(LS_INFO) << "Stopping playout for channel #" << channel; | 2545 LOG(LS_INFO) << "Stopping playout for channel #" << channel; |
2488 engine()->voe()->base()->StopPlayout(channel); | 2546 engine()->voe()->base()->StopPlayout(channel); |
2489 } | 2547 } |
2490 return true; | 2548 return true; |
2491 } | 2549 } |
2492 } // namespace cricket | 2550 } // namespace cricket |
2493 | 2551 |
2494 #endif // HAVE_WEBRTC_VOICE | 2552 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |