1 // Copyright 2014 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 "media/cast/receiver/audio_decoder.h" 6 7 #include "base/bind.h" 8 #include "base/bind_helpers.h" 9 #include "base/location.h" 10 #include "base/logging.h" 11 #include "base/memory/ref_counted.h" 12 #include "base/sys_byteorder.h" 13 #include "media/cast/cast_defines.h" 14 #include "third_party/opus/src/include/opus.h" 15 16 namespace media { 17 namespace cast { 18 19 // Base class that handles the common problem of detecting dropped frames, and 20 // then invoking the Decode() method implemented by the subclasses to convert 21 // the encoded payload data into usable audio data. 22 class AudioDecoder::ImplBase 23 : public base::RefCountedThreadSafe<AudioDecoder::ImplBase> { 24 public: 25 ImplBase(const scoped_refptr<CastEnvironment>& cast_environment, 26 Codec codec, 27 int num_channels, 28 int sampling_rate) 29 : cast_environment_(cast_environment), 30 codec_(codec), 31 num_channels_(num_channels), 32 cast_initialization_status_(STATUS_AUDIO_UNINITIALIZED), 33 seen_first_frame_(false) { 34 if (num_channels_ <= 0 || sampling_rate <= 0 || sampling_rate % 100 != 0) 35 cast_initialization_status_ = STATUS_INVALID_AUDIO_CONFIGURATION; 36 } 37 38 CastInitializationStatus InitializationResult() const { 39 return cast_initialization_status_; 40 } 41 42 void DecodeFrame(scoped_ptr<EncodedFrame> encoded_frame, 43 const DecodeFrameCallback& callback) { 44 DCHECK_EQ(cast_initialization_status_, STATUS_AUDIO_INITIALIZED); 45 46 COMPILE_ASSERT(sizeof(encoded_frame->frame_id) == sizeof(last_frame_id_), 47 size_of_frame_id_types_do_not_match); 48 bool is_continuous = true; 49 if (seen_first_frame_) { 50 const uint32 frames_ahead = encoded_frame->frame_id - last_frame_id_; 51 if (frames_ahead > 1) { 52 RecoverBecauseFramesWereDropped(); 53 is_continuous = false; 54 } 55 } else { 56 seen_first_frame_ = true; 57 } 58 last_frame_id_ = encoded_frame->frame_id; 59 60 scoped_ptr<AudioBus> decoded_audio = Decode( 61 encoded_frame->mutable_bytes(), 62 static_cast<int>(encoded_frame->data.size())); 63 cast_environment_->PostTask(CastEnvironment::MAIN, 64 FROM_HERE, 65 base::Bind(callback, 66 base::Passed(&decoded_audio), 67 is_continuous)); 68 } 69 70 protected: 71 friend class base::RefCountedThreadSafe<ImplBase>; 72 virtual ~ImplBase() {} 73 74 virtual void RecoverBecauseFramesWereDropped() {} 75 76 // Note: Implementation of Decode() is allowed to mutate |data|. 77 virtual scoped_ptr<AudioBus> Decode(uint8* data, int len) = 0; 78 79 const scoped_refptr<CastEnvironment> cast_environment_; 80 const Codec codec_; 81 const int num_channels_; 82 83 // Subclass' ctor is expected to set this to STATUS_AUDIO_INITIALIZED. 84 CastInitializationStatus cast_initialization_status_; 85 86 private: 87 bool seen_first_frame_; 88 uint32 last_frame_id_; 89 90 DISALLOW_COPY_AND_ASSIGN(ImplBase); 91 }; 92 93 class AudioDecoder::OpusImpl : public AudioDecoder::ImplBase { 94 public: 95 OpusImpl(const scoped_refptr<CastEnvironment>& cast_environment, 96 int num_channels, 97 int sampling_rate) 98 : ImplBase(cast_environment, 99 CODEC_AUDIO_OPUS, 100 num_channels, 101 sampling_rate), 102 decoder_memory_(new uint8[opus_decoder_get_size(num_channels)]), 103 opus_decoder_(reinterpret_cast<OpusDecoder*>(decoder_memory_.get())), 104 max_samples_per_frame_( 105 kOpusMaxFrameDurationMillis * sampling_rate / 1000), 106 buffer_(new float[max_samples_per_frame_ * num_channels]) { 107 if (ImplBase::cast_initialization_status_ != STATUS_AUDIO_UNINITIALIZED) 108 return; 109 if (opus_decoder_init(opus_decoder_, sampling_rate, num_channels) != 110 OPUS_OK) { 111 ImplBase::cast_initialization_status_ = 112 STATUS_INVALID_AUDIO_CONFIGURATION; 113 return; 114 } 115 ImplBase::cast_initialization_status_ = STATUS_AUDIO_INITIALIZED; 116 } 117 118 private: 119 virtual ~OpusImpl() {} 120 121 virtual void RecoverBecauseFramesWereDropped() OVERRIDE { 122 // Passing NULL for the input data notifies the decoder of frame loss. 123 const opus_int32 result = 124 opus_decode_float( 125 opus_decoder_, NULL, 0, buffer_.get(), max_samples_per_frame_, 0); 126 DCHECK_GE(result, 0); 127 } 128 129 virtual scoped_ptr<AudioBus> Decode(uint8* data, int len) OVERRIDE { 130 scoped_ptr<AudioBus> audio_bus; 131 const opus_int32 num_samples_decoded = opus_decode_float( 132 opus_decoder_, data, len, buffer_.get(), max_samples_per_frame_, 0); 133 if (num_samples_decoded <= 0) 134 return audio_bus.Pass(); // Decode error. 135 136 // Copy interleaved samples from |buffer_| into a new AudioBus (where 137 // samples are stored in planar format, for each channel). 138 audio_bus = AudioBus::Create(num_channels_, num_samples_decoded).Pass(); 139 // TODO(miu): This should be moved into AudioBus::FromInterleaved(). 140 for (int ch = 0; ch < num_channels_; ++ch) { 141 const float* src = buffer_.get() + ch; 142 const float* const src_end = src + num_samples_decoded * num_channels_; 143 float* dest = audio_bus->channel(ch); 144 for (; src < src_end; src += num_channels_, ++dest) 145 *dest = *src; 146 } 147 return audio_bus.Pass(); 148 } 149 150 const scoped_ptr<uint8[]> decoder_memory_; 151 OpusDecoder* const opus_decoder_; 152 const int max_samples_per_frame_; 153 const scoped_ptr<float[]> buffer_; 154 155 // According to documentation in third_party/opus/src/include/opus.h, we must 156 // provide enough space in |buffer_| to contain 120ms of samples. At 48 kHz, 157 // then, that means 5760 samples times the number of channels. 158 static const int kOpusMaxFrameDurationMillis = 120; 159 160 DISALLOW_COPY_AND_ASSIGN(OpusImpl); 161 }; 162 163 class AudioDecoder::Pcm16Impl : public AudioDecoder::ImplBase { 164 public: 165 Pcm16Impl(const scoped_refptr<CastEnvironment>& cast_environment, 166 int num_channels, 167 int sampling_rate) 168 : ImplBase(cast_environment, 169 CODEC_AUDIO_PCM16, 170 num_channels, 171 sampling_rate) { 172 if (ImplBase::cast_initialization_status_ != STATUS_AUDIO_UNINITIALIZED) 173 return; 174 ImplBase::cast_initialization_status_ = STATUS_AUDIO_INITIALIZED; 175 } 176 177 private: 178 virtual ~Pcm16Impl() {} 179 180 virtual scoped_ptr<AudioBus> Decode(uint8* data, int len) OVERRIDE { 181 scoped_ptr<AudioBus> audio_bus; 182 const int num_samples = len / sizeof(int16) / num_channels_; 183 if (num_samples <= 0) 184 return audio_bus.Pass(); 185 186 int16* const pcm_data = reinterpret_cast<int16*>(data); 187 #if defined(ARCH_CPU_LITTLE_ENDIAN) 188 // Convert endianness. 189 const int num_elements = num_samples * num_channels_; 190 for (int i = 0; i < num_elements; ++i) 191 pcm_data[i] = static_cast<int16>(base::NetToHost16(pcm_data[i])); 192 #endif 193 audio_bus = AudioBus::Create(num_channels_, num_samples).Pass(); 194 audio_bus->FromInterleaved(pcm_data, num_samples, sizeof(int16)); 195 return audio_bus.Pass(); 196 } 197 198 DISALLOW_COPY_AND_ASSIGN(Pcm16Impl); 199 }; 200 201 AudioDecoder::AudioDecoder( 202 const scoped_refptr<CastEnvironment>& cast_environment, 203 int channels, 204 int sampling_rate, 205 Codec codec) 206 : cast_environment_(cast_environment) { 207 switch (codec) { 208 case CODEC_AUDIO_OPUS: 209 impl_ = new OpusImpl(cast_environment, channels, sampling_rate); 210 break; 211 case CODEC_AUDIO_PCM16: 212 impl_ = new Pcm16Impl(cast_environment, channels, sampling_rate); 213 break; 214 default: 215 NOTREACHED() << "Unknown or unspecified codec."; 216 break; 217 } 218 } 219 220 AudioDecoder::~AudioDecoder() {} 221 222 CastInitializationStatus AudioDecoder::InitializationResult() const { 223 if (impl_.get()) 224 return impl_->InitializationResult(); 225 return STATUS_UNSUPPORTED_AUDIO_CODEC; 226 } 227 228 void AudioDecoder::DecodeFrame( 229 scoped_ptr<EncodedFrame> encoded_frame, 230 const DecodeFrameCallback& callback) { 231 DCHECK(encoded_frame.get()); 232 DCHECK(!callback.is_null()); 233 if (!impl_.get() || 234 impl_->InitializationResult() != STATUS_AUDIO_INITIALIZED) { 235 callback.Run(make_scoped_ptr<AudioBus>(NULL), false); 236 return; 237 } 238 cast_environment_->PostTask(CastEnvironment::AUDIO, 239 FROM_HERE, 240 base::Bind(&AudioDecoder::ImplBase::DecodeFrame, 241 impl_, 242 base::Passed(&encoded_frame), 243 callback)); 244 } 245 246 } // namespace cast 247 } // namespace media 248