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 3 // found in the LICENSE file. 4 5 #include "base/logging.h" 6 #include "media/cast/audio_receiver/audio_decoder.h" 7 8 #include "third_party/webrtc/modules/audio_coding/main/interface/audio_coding_module.h" 9 #include "third_party/webrtc/modules/interface/module_common_types.h" 10 11 namespace media { 12 namespace cast { 13 14 AudioDecoder::AudioDecoder(scoped_refptr<CastEnvironment> cast_environment, 15 const AudioReceiverConfig& audio_config, 16 RtpPayloadFeedback* incoming_payload_feedback) 17 : cast_environment_(cast_environment), 18 audio_decoder_(webrtc::AudioCodingModule::Create(0)), 19 cast_message_builder_(cast_environment->Clock(), 20 incoming_payload_feedback, &frame_id_map_, audio_config.incoming_ssrc, 21 true, 0), 22 have_received_packets_(false), 23 last_played_out_timestamp_(0) { 24 audio_decoder_->InitializeReceiver(); 25 26 webrtc::CodecInst receive_codec; 27 switch (audio_config.codec) { 28 case kPcm16: 29 receive_codec.pltype = audio_config.rtp_payload_type; 30 strncpy(receive_codec.plname, "L16", 4); 31 receive_codec.plfreq = audio_config.frequency; 32 receive_codec.pacsize = -1; 33 receive_codec.channels = audio_config.channels; 34 receive_codec.rate = -1; 35 break; 36 case kOpus: 37 receive_codec.pltype = audio_config.rtp_payload_type; 38 strncpy(receive_codec.plname, "opus", 5); 39 receive_codec.plfreq = audio_config.frequency; 40 receive_codec.pacsize = -1; 41 receive_codec.channels = audio_config.channels; 42 receive_codec.rate = -1; 43 break; 44 case kExternalAudio: 45 NOTREACHED() << "Codec must be specified for audio decoder"; 46 break; 47 } 48 if (audio_decoder_->RegisterReceiveCodec(receive_codec) != 0) { 49 NOTREACHED() << "Failed to register receive codec"; 50 } 51 52 audio_decoder_->SetMaximumPlayoutDelay(audio_config.rtp_max_delay_ms); 53 audio_decoder_->SetPlayoutMode(webrtc::streaming); 54 } 55 56 AudioDecoder::~AudioDecoder() {} 57 58 bool AudioDecoder::GetRawAudioFrame(int number_of_10ms_blocks, 59 int desired_frequency, 60 PcmAudioFrame* audio_frame, 61 uint32* rtp_timestamp) { 62 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::AUDIO_DECODER)); 63 // We don't care about the race case where a packet arrives at the same time 64 // as this function in called. The data will be there the next time this 65 // function is called. 66 lock_.Acquire(); 67 // Get a local copy under lock. 68 bool have_received_packets = have_received_packets_; 69 lock_.Release(); 70 71 if (!have_received_packets) return false; 72 73 audio_frame->samples.clear(); 74 75 for (int i = 0; i < number_of_10ms_blocks; ++i) { 76 webrtc::AudioFrame webrtc_audio_frame; 77 if (0 != audio_decoder_->PlayoutData10Ms(desired_frequency, 78 &webrtc_audio_frame)) { 79 return false; 80 } 81 if (webrtc_audio_frame.speech_type_ == webrtc::AudioFrame::kPLCCNG || 82 webrtc_audio_frame.speech_type_ == webrtc::AudioFrame::kUndefined) { 83 // We are only interested in real decoded audio. 84 return false; 85 } 86 audio_frame->frequency = webrtc_audio_frame.sample_rate_hz_; 87 audio_frame->channels = webrtc_audio_frame.num_channels_; 88 89 if (i == 0) { 90 // Use the timestamp from the first 10ms block. 91 if (0 != audio_decoder_->PlayoutTimestamp(rtp_timestamp)) { 92 return false; 93 } 94 lock_.Acquire(); 95 last_played_out_timestamp_ = *rtp_timestamp; 96 lock_.Release(); 97 } 98 int samples_per_10ms = webrtc_audio_frame.samples_per_channel_; 99 100 audio_frame->samples.insert( 101 audio_frame->samples.end(), 102 &webrtc_audio_frame.data_[0], 103 &webrtc_audio_frame.data_[samples_per_10ms * audio_frame->channels]); 104 } 105 return true; 106 } 107 108 void AudioDecoder::IncomingParsedRtpPacket(const uint8* payload_data, 109 size_t payload_size, 110 const RtpCastHeader& rtp_header) { 111 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 112 DCHECK_LE(payload_size, kIpPacketSize); 113 audio_decoder_->IncomingPacket(payload_data, static_cast<int32>(payload_size), 114 rtp_header.webrtc); 115 lock_.Acquire(); 116 have_received_packets_ = true; 117 uint32 last_played_out_timestamp = last_played_out_timestamp_; 118 lock_.Release(); 119 120 bool complete = false; 121 if (!frame_id_map_.InsertPacket(rtp_header, &complete)) return; 122 if (!complete) return; 123 124 cast_message_builder_.CompleteFrameReceived(rtp_header.frame_id, 125 rtp_header.is_key_frame); 126 127 frame_id_rtp_timestamp_map_[rtp_header.frame_id] = 128 rtp_header.webrtc.header.timestamp; 129 130 if (last_played_out_timestamp == 0) return; // Nothing is played out yet. 131 132 uint32 latest_frame_id_to_remove = 0; 133 bool frame_to_remove = false; 134 135 FrameIdRtpTimestampMap::iterator it = frame_id_rtp_timestamp_map_.begin(); 136 while (it != frame_id_rtp_timestamp_map_.end()) { 137 if (IsNewerRtpTimestamp(it->second, last_played_out_timestamp)) { 138 break; 139 } 140 frame_to_remove = true; 141 latest_frame_id_to_remove = it->first; 142 frame_id_rtp_timestamp_map_.erase(it); 143 it = frame_id_rtp_timestamp_map_.begin(); 144 } 145 if (!frame_to_remove) return; 146 147 frame_id_map_.RemoveOldFrames(latest_frame_id_to_remove); 148 } 149 150 bool AudioDecoder::TimeToSendNextCastMessage(base::TimeTicks* time_to_send) { 151 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 152 return cast_message_builder_.TimeToSendNextCastMessage(time_to_send); 153 } 154 155 void AudioDecoder::SendCastMessage() { 156 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 157 cast_message_builder_.UpdateCastMessage(); 158 } 159 160 } // namespace cast 161 } // namespace media 162