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 | 4 |
5 #include "media/cast/audio_sender/audio_encoder.h" | 5 #include "media/cast/sender/audio_encoder.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
11 #include "base/location.h" | 11 #include "base/location.h" |
12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
13 #include "base/sys_byteorder.h" | 13 #include "base/sys_byteorder.h" |
14 #include "base/time/time.h" | 14 #include "base/time/time.h" |
15 #include "media/base/audio_bus.h" | 15 #include "media/base/audio_bus.h" |
(...skipping 21 matching lines...) Expand all Loading... |
37 // Base class that handles the common problem of feeding one or more AudioBus' | 37 // Base class that handles the common problem of feeding one or more AudioBus' |
38 // data into a buffer and then, once the buffer is full, encoding the signal and | 38 // data into a buffer and then, once the buffer is full, encoding the signal and |
39 // emitting an EncodedFrame via the FrameEncodedCallback. | 39 // emitting an EncodedFrame via the FrameEncodedCallback. |
40 // | 40 // |
41 // Subclasses complete the implementation by handling the actual encoding | 41 // Subclasses complete the implementation by handling the actual encoding |
42 // details. | 42 // details. |
43 class AudioEncoder::ImplBase | 43 class AudioEncoder::ImplBase |
44 : public base::RefCountedThreadSafe<AudioEncoder::ImplBase> { | 44 : public base::RefCountedThreadSafe<AudioEncoder::ImplBase> { |
45 public: | 45 public: |
46 ImplBase(const scoped_refptr<CastEnvironment>& cast_environment, | 46 ImplBase(const scoped_refptr<CastEnvironment>& cast_environment, |
47 transport::Codec codec, | 47 Codec codec, |
48 int num_channels, | 48 int num_channels, |
49 int sampling_rate, | 49 int sampling_rate, |
50 const FrameEncodedCallback& callback) | 50 const FrameEncodedCallback& callback) |
51 : cast_environment_(cast_environment), | 51 : cast_environment_(cast_environment), |
52 codec_(codec), | 52 codec_(codec), |
53 num_channels_(num_channels), | 53 num_channels_(num_channels), |
54 samples_per_frame_(sampling_rate / kFramesPerSecond), | 54 samples_per_frame_(sampling_rate / kFramesPerSecond), |
55 callback_(callback), | 55 callback_(callback), |
56 cast_initialization_status_(STATUS_AUDIO_UNINITIALIZED), | 56 cast_initialization_status_(STATUS_AUDIO_UNINITIALIZED), |
57 buffer_fill_end_(0), | 57 buffer_fill_end_(0), |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 samples_per_frame_ - buffer_fill_end_, audio_bus->frames() - src_pos); | 110 samples_per_frame_ - buffer_fill_end_, audio_bus->frames() - src_pos); |
111 DCHECK_EQ(audio_bus->channels(), num_channels_); | 111 DCHECK_EQ(audio_bus->channels(), num_channels_); |
112 TransferSamplesIntoBuffer( | 112 TransferSamplesIntoBuffer( |
113 audio_bus.get(), src_pos, buffer_fill_end_, num_samples_to_xfer); | 113 audio_bus.get(), src_pos, buffer_fill_end_, num_samples_to_xfer); |
114 src_pos += num_samples_to_xfer; | 114 src_pos += num_samples_to_xfer; |
115 buffer_fill_end_ += num_samples_to_xfer; | 115 buffer_fill_end_ += num_samples_to_xfer; |
116 | 116 |
117 if (buffer_fill_end_ < samples_per_frame_) | 117 if (buffer_fill_end_ < samples_per_frame_) |
118 break; | 118 break; |
119 | 119 |
120 scoped_ptr<transport::EncodedFrame> audio_frame( | 120 scoped_ptr<EncodedFrame> audio_frame( |
121 new transport::EncodedFrame()); | 121 new EncodedFrame()); |
122 audio_frame->dependency = transport::EncodedFrame::KEY; | 122 audio_frame->dependency = EncodedFrame::KEY; |
123 audio_frame->frame_id = frame_id_; | 123 audio_frame->frame_id = frame_id_; |
124 audio_frame->referenced_frame_id = frame_id_; | 124 audio_frame->referenced_frame_id = frame_id_; |
125 audio_frame->rtp_timestamp = frame_rtp_timestamp_; | 125 audio_frame->rtp_timestamp = frame_rtp_timestamp_; |
126 audio_frame->reference_time = frame_capture_time_; | 126 audio_frame->reference_time = frame_capture_time_; |
127 | 127 |
128 if (EncodeFromFilledBuffer(&audio_frame->data)) { | 128 if (EncodeFromFilledBuffer(&audio_frame->data)) { |
129 cast_environment_->PostTask( | 129 cast_environment_->PostTask( |
130 CastEnvironment::MAIN, | 130 CastEnvironment::MAIN, |
131 FROM_HERE, | 131 FROM_HERE, |
132 base::Bind(callback_, base::Passed(&audio_frame))); | 132 base::Bind(callback_, base::Passed(&audio_frame))); |
(...skipping 11 matching lines...) Expand all Loading... |
144 friend class base::RefCountedThreadSafe<ImplBase>; | 144 friend class base::RefCountedThreadSafe<ImplBase>; |
145 virtual ~ImplBase() {} | 145 virtual ~ImplBase() {} |
146 | 146 |
147 virtual void TransferSamplesIntoBuffer(const AudioBus* audio_bus, | 147 virtual void TransferSamplesIntoBuffer(const AudioBus* audio_bus, |
148 int source_offset, | 148 int source_offset, |
149 int buffer_fill_offset, | 149 int buffer_fill_offset, |
150 int num_samples) = 0; | 150 int num_samples) = 0; |
151 virtual bool EncodeFromFilledBuffer(std::string* out) = 0; | 151 virtual bool EncodeFromFilledBuffer(std::string* out) = 0; |
152 | 152 |
153 const scoped_refptr<CastEnvironment> cast_environment_; | 153 const scoped_refptr<CastEnvironment> cast_environment_; |
154 const transport::Codec codec_; | 154 const Codec codec_; |
155 const int num_channels_; | 155 const int num_channels_; |
156 const int samples_per_frame_; | 156 const int samples_per_frame_; |
157 const FrameEncodedCallback callback_; | 157 const FrameEncodedCallback callback_; |
158 | 158 |
159 // Subclass' ctor is expected to set this to STATUS_AUDIO_INITIALIZED. | 159 // Subclass' ctor is expected to set this to STATUS_AUDIO_INITIALIZED. |
160 CastInitializationStatus cast_initialization_status_; | 160 CastInitializationStatus cast_initialization_status_; |
161 | 161 |
162 private: | 162 private: |
163 // In the case where a call to EncodeAudio() cannot completely fill the | 163 // In the case where a call to EncodeAudio() cannot completely fill the |
164 // buffer, this points to the position at which to populate data in a later | 164 // buffer, this points to the position at which to populate data in a later |
(...skipping 21 matching lines...) Expand all Loading... |
186 }; | 186 }; |
187 | 187 |
188 class AudioEncoder::OpusImpl : public AudioEncoder::ImplBase { | 188 class AudioEncoder::OpusImpl : public AudioEncoder::ImplBase { |
189 public: | 189 public: |
190 OpusImpl(const scoped_refptr<CastEnvironment>& cast_environment, | 190 OpusImpl(const scoped_refptr<CastEnvironment>& cast_environment, |
191 int num_channels, | 191 int num_channels, |
192 int sampling_rate, | 192 int sampling_rate, |
193 int bitrate, | 193 int bitrate, |
194 const FrameEncodedCallback& callback) | 194 const FrameEncodedCallback& callback) |
195 : ImplBase(cast_environment, | 195 : ImplBase(cast_environment, |
196 transport::CODEC_AUDIO_OPUS, | 196 CODEC_AUDIO_OPUS, |
197 num_channels, | 197 num_channels, |
198 sampling_rate, | 198 sampling_rate, |
199 callback), | 199 callback), |
200 encoder_memory_(new uint8[opus_encoder_get_size(num_channels)]), | 200 encoder_memory_(new uint8[opus_encoder_get_size(num_channels)]), |
201 opus_encoder_(reinterpret_cast<OpusEncoder*>(encoder_memory_.get())), | 201 opus_encoder_(reinterpret_cast<OpusEncoder*>(encoder_memory_.get())), |
202 buffer_(new float[num_channels * samples_per_frame_]) { | 202 buffer_(new float[num_channels * samples_per_frame_]) { |
203 if (ImplBase::cast_initialization_status_ != STATUS_AUDIO_UNINITIALIZED) | 203 if (ImplBase::cast_initialization_status_ != STATUS_AUDIO_UNINITIALIZED) |
204 return; | 204 return; |
205 if (opus_encoder_init(opus_encoder_, | 205 if (opus_encoder_init(opus_encoder_, |
206 sampling_rate, | 206 sampling_rate, |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 DISALLOW_COPY_AND_ASSIGN(OpusImpl); | 276 DISALLOW_COPY_AND_ASSIGN(OpusImpl); |
277 }; | 277 }; |
278 | 278 |
279 class AudioEncoder::Pcm16Impl : public AudioEncoder::ImplBase { | 279 class AudioEncoder::Pcm16Impl : public AudioEncoder::ImplBase { |
280 public: | 280 public: |
281 Pcm16Impl(const scoped_refptr<CastEnvironment>& cast_environment, | 281 Pcm16Impl(const scoped_refptr<CastEnvironment>& cast_environment, |
282 int num_channels, | 282 int num_channels, |
283 int sampling_rate, | 283 int sampling_rate, |
284 const FrameEncodedCallback& callback) | 284 const FrameEncodedCallback& callback) |
285 : ImplBase(cast_environment, | 285 : ImplBase(cast_environment, |
286 transport::CODEC_AUDIO_PCM16, | 286 CODEC_AUDIO_PCM16, |
287 num_channels, | 287 num_channels, |
288 sampling_rate, | 288 sampling_rate, |
289 callback), | 289 callback), |
290 buffer_(new int16[num_channels * samples_per_frame_]) { | 290 buffer_(new int16[num_channels * samples_per_frame_]) { |
291 if (ImplBase::cast_initialization_status_ != STATUS_AUDIO_UNINITIALIZED) | 291 if (ImplBase::cast_initialization_status_ != STATUS_AUDIO_UNINITIALIZED) |
292 return; | 292 return; |
293 cast_initialization_status_ = STATUS_AUDIO_INITIALIZED; | 293 cast_initialization_status_ = STATUS_AUDIO_INITIALIZED; |
294 } | 294 } |
295 | 295 |
296 private: | 296 private: |
(...skipping 25 matching lines...) Expand all Loading... |
322 const scoped_ptr<int16[]> buffer_; | 322 const scoped_ptr<int16[]> buffer_; |
323 | 323 |
324 DISALLOW_COPY_AND_ASSIGN(Pcm16Impl); | 324 DISALLOW_COPY_AND_ASSIGN(Pcm16Impl); |
325 }; | 325 }; |
326 | 326 |
327 AudioEncoder::AudioEncoder( | 327 AudioEncoder::AudioEncoder( |
328 const scoped_refptr<CastEnvironment>& cast_environment, | 328 const scoped_refptr<CastEnvironment>& cast_environment, |
329 int num_channels, | 329 int num_channels, |
330 int sampling_rate, | 330 int sampling_rate, |
331 int bitrate, | 331 int bitrate, |
332 transport::Codec codec, | 332 Codec codec, |
333 const FrameEncodedCallback& frame_encoded_callback) | 333 const FrameEncodedCallback& frame_encoded_callback) |
334 : cast_environment_(cast_environment) { | 334 : cast_environment_(cast_environment) { |
335 // Note: It doesn't matter which thread constructs AudioEncoder, just so long | 335 // Note: It doesn't matter which thread constructs AudioEncoder, just so long |
336 // as all calls to InsertAudio() are by the same thread. | 336 // as all calls to InsertAudio() are by the same thread. |
337 insert_thread_checker_.DetachFromThread(); | 337 insert_thread_checker_.DetachFromThread(); |
338 switch (codec) { | 338 switch (codec) { |
339 case transport::CODEC_AUDIO_OPUS: | 339 case CODEC_AUDIO_OPUS: |
340 impl_ = new OpusImpl(cast_environment, | 340 impl_ = new OpusImpl(cast_environment, |
341 num_channels, | 341 num_channels, |
342 sampling_rate, | 342 sampling_rate, |
343 bitrate, | 343 bitrate, |
344 frame_encoded_callback); | 344 frame_encoded_callback); |
345 break; | 345 break; |
346 case transport::CODEC_AUDIO_PCM16: | 346 case CODEC_AUDIO_PCM16: |
347 impl_ = new Pcm16Impl(cast_environment, | 347 impl_ = new Pcm16Impl(cast_environment, |
348 num_channels, | 348 num_channels, |
349 sampling_rate, | 349 sampling_rate, |
350 frame_encoded_callback); | 350 frame_encoded_callback); |
351 break; | 351 break; |
352 default: | 352 default: |
353 NOTREACHED() << "Unsupported or unspecified codec for audio encoder"; | 353 NOTREACHED() << "Unsupported or unspecified codec for audio encoder"; |
354 break; | 354 break; |
355 } | 355 } |
356 } | 356 } |
(...skipping 19 matching lines...) Expand all Loading... |
376 cast_environment_->PostTask(CastEnvironment::AUDIO, | 376 cast_environment_->PostTask(CastEnvironment::AUDIO, |
377 FROM_HERE, | 377 FROM_HERE, |
378 base::Bind(&AudioEncoder::ImplBase::EncodeAudio, | 378 base::Bind(&AudioEncoder::ImplBase::EncodeAudio, |
379 impl_, | 379 impl_, |
380 base::Passed(&audio_bus), | 380 base::Passed(&audio_bus), |
381 recorded_time)); | 381 recorded_time)); |
382 } | 382 } |
383 | 383 |
384 } // namespace cast | 384 } // namespace cast |
385 } // namespace media | 385 } // namespace media |
OLD | NEW |