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

Side by Side Diff: media/cast/audio_sender/audio_encoder.cc

Issue 109413004: Cast:Adding cast_transport_config and cleaning up (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nits Created 6 years, 11 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 | Annotate | Revision Log
OLDNEW
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/audio_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"
(...skipping 20 matching lines...) Expand all
31 31
32 // Base class that handles the common problem of feeding one or more AudioBus' 32 // Base class that handles the common problem of feeding one or more AudioBus'
33 // data into a 10 ms buffer and then, once the buffer is full, encoding the 33 // data into a 10 ms buffer and then, once the buffer is full, encoding the
34 // signal and emitting an EncodedAudioFrame via the FrameEncodedCallback. 34 // signal and emitting an EncodedAudioFrame via the FrameEncodedCallback.
35 // 35 //
36 // Subclasses complete the implementation by handling the actual encoding 36 // Subclasses complete the implementation by handling the actual encoding
37 // details. 37 // details.
38 class AudioEncoder::ImplBase { 38 class AudioEncoder::ImplBase {
39 public: 39 public:
40 ImplBase(CastEnvironment* cast_environment, 40 ImplBase(CastEnvironment* cast_environment,
41 AudioCodec codec, int num_channels, int sampling_rate, 41 transport::AudioCodec codec, int num_channels, int sampling_rate,
42 const FrameEncodedCallback& callback) 42 const FrameEncodedCallback& callback)
43 : cast_environment_(cast_environment), 43 : cast_environment_(cast_environment),
44 codec_(codec), num_channels_(num_channels), 44 codec_(codec), num_channels_(num_channels),
45 samples_per_10ms_(sampling_rate / 100), 45 samples_per_10ms_(sampling_rate / 100),
46 callback_(callback), 46 callback_(callback),
47 buffer_fill_end_(0), 47 buffer_fill_end_(0),
48 frame_id_(0) { 48 frame_id_(0) {
49 CHECK_GT(num_channels_, 0); 49 CHECK_GT(num_channels_, 0);
50 CHECK_GT(samples_per_10ms_, 0); 50 CHECK_GT(samples_per_10ms_, 0);
51 CHECK_EQ(sampling_rate % 100, 0); 51 CHECK_EQ(sampling_rate % 100, 0);
52 CHECK_LE(samples_per_10ms_ * num_channels_, 52 CHECK_LE(samples_per_10ms_ * num_channels_,
53 EncodedAudioFrame::kMaxNumberOfSamples); 53 transport::EncodedAudioFrame::kMaxNumberOfSamples);
54 } 54 }
55 55
56 virtual ~ImplBase() {} 56 virtual ~ImplBase() {}
57 57
58 void EncodeAudio(const AudioBus* audio_bus, 58 void EncodeAudio(const AudioBus* audio_bus,
59 const base::TimeTicks& recorded_time, 59 const base::TimeTicks& recorded_time,
60 const base::Closure& done_callback) { 60 const base::Closure& done_callback) {
61 int src_pos = 0; 61 int src_pos = 0;
62 while (src_pos < audio_bus->frames()) { 62 while (src_pos < audio_bus->frames()) {
63 const int num_samples_to_xfer = 63 const int num_samples_to_xfer =
64 std::min(samples_per_10ms_ - buffer_fill_end_, 64 std::min(samples_per_10ms_ - buffer_fill_end_,
65 audio_bus->frames() - src_pos); 65 audio_bus->frames() - src_pos);
66 DCHECK_EQ(audio_bus->channels(), num_channels_); 66 DCHECK_EQ(audio_bus->channels(), num_channels_);
67 TransferSamplesIntoBuffer( 67 TransferSamplesIntoBuffer(
68 audio_bus, src_pos, buffer_fill_end_, num_samples_to_xfer); 68 audio_bus, src_pos, buffer_fill_end_, num_samples_to_xfer);
69 src_pos += num_samples_to_xfer; 69 src_pos += num_samples_to_xfer;
70 buffer_fill_end_ += num_samples_to_xfer; 70 buffer_fill_end_ += num_samples_to_xfer;
71 71
72 if (src_pos == audio_bus->frames()) { 72 if (src_pos == audio_bus->frames()) {
73 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, 73 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
74 done_callback); 74 done_callback);
75 // Note: |audio_bus| is now invalid.. 75 // Note: |audio_bus| is now invalid..
76 } 76 }
77 77
78 if (buffer_fill_end_ == samples_per_10ms_) { 78 if (buffer_fill_end_ == samples_per_10ms_) {
79 scoped_ptr<EncodedAudioFrame> audio_frame(new EncodedAudioFrame()); 79 scoped_ptr<transport::EncodedAudioFrame> audio_frame(
80 new transport::EncodedAudioFrame());
80 audio_frame->codec = codec_; 81 audio_frame->codec = codec_;
81 audio_frame->frame_id = frame_id_++; 82 audio_frame->frame_id = frame_id_++;
82 audio_frame->samples = samples_per_10ms_; 83 audio_frame->samples = samples_per_10ms_;
83 if (EncodeFromFilledBuffer(&audio_frame->data)) { 84 if (EncodeFromFilledBuffer(&audio_frame->data)) {
84 // Compute an offset to determine the recorded time for the first 85 // Compute an offset to determine the recorded time for the first
85 // audio sample in the buffer. 86 // audio sample in the buffer.
86 const base::TimeDelta buffer_time_offset = 87 const base::TimeDelta buffer_time_offset =
87 (buffer_fill_end_ - src_pos) * 88 (buffer_fill_end_ - src_pos) *
88 base::TimeDelta::FromMilliseconds(10) / samples_per_10ms_; 89 base::TimeDelta::FromMilliseconds(10) / samples_per_10ms_;
89 // TODO(miu): Consider batching EncodedAudioFrames so we only post a 90 // TODO(miu): Consider batching EncodedAudioFrames so we only post a
90 // at most one task for each call to this method. 91 // at most one task for each call to this method.
91 cast_environment_->PostTask( 92 cast_environment_->PostTask(
92 CastEnvironment::MAIN, FROM_HERE, 93 CastEnvironment::MAIN, FROM_HERE,
93 base::Bind(callback_, base::Passed(&audio_frame), 94 base::Bind(callback_, base::Passed(&audio_frame),
94 recorded_time - buffer_time_offset)); 95 recorded_time - buffer_time_offset));
95 } 96 }
96 buffer_fill_end_ = 0; 97 buffer_fill_end_ = 0;
97 } 98 }
98 } 99 }
99 } 100 }
100 101
101 protected: 102 protected:
102 virtual void TransferSamplesIntoBuffer(const AudioBus* audio_bus, 103 virtual void TransferSamplesIntoBuffer(const AudioBus* audio_bus,
103 int source_offset, 104 int source_offset,
104 int buffer_fill_offset, 105 int buffer_fill_offset,
105 int num_samples) = 0; 106 int num_samples) = 0;
106 virtual bool EncodeFromFilledBuffer(std::string* out) = 0; 107 virtual bool EncodeFromFilledBuffer(std::string* out) = 0;
107 108
108 CastEnvironment* const cast_environment_; 109 CastEnvironment* const cast_environment_;
109 const AudioCodec codec_; 110 const transport::AudioCodec codec_;
110 const int num_channels_; 111 const int num_channels_;
111 const int samples_per_10ms_; 112 const int samples_per_10ms_;
112 const FrameEncodedCallback callback_; 113 const FrameEncodedCallback callback_;
113 114
114 private: 115 private:
115 // In the case where a call to EncodeAudio() cannot completely fill the 116 // In the case where a call to EncodeAudio() cannot completely fill the
116 // buffer, this points to the position at which to populate data in a later 117 // buffer, this points to the position at which to populate data in a later
117 // call. 118 // call.
118 int buffer_fill_end_; 119 int buffer_fill_end_;
119 120
120 // A counter used to label EncodedAudioFrames. 121 // A counter used to label EncodedAudioFrames.
121 uint32 frame_id_; 122 uint32 frame_id_;
122 123
123 private: 124 private:
124 DISALLOW_COPY_AND_ASSIGN(ImplBase); 125 DISALLOW_COPY_AND_ASSIGN(ImplBase);
125 }; 126 };
126 127
127 class AudioEncoder::OpusImpl : public AudioEncoder::ImplBase { 128 class AudioEncoder::OpusImpl : public AudioEncoder::ImplBase {
128 public: 129 public:
129 OpusImpl(CastEnvironment* cast_environment, 130 OpusImpl(CastEnvironment* cast_environment,
130 int num_channels, int sampling_rate, int bitrate, 131 int num_channels, int sampling_rate, int bitrate,
131 const FrameEncodedCallback& callback) 132 const FrameEncodedCallback& callback)
132 : ImplBase(cast_environment, kOpus, num_channels, sampling_rate, 133 : ImplBase(cast_environment, transport::kOpus, num_channels,
133 callback), 134 sampling_rate, callback),
134 encoder_memory_(new uint8[opus_encoder_get_size(num_channels)]), 135 encoder_memory_(new uint8[opus_encoder_get_size(num_channels)]),
135 opus_encoder_(reinterpret_cast<OpusEncoder*>(encoder_memory_.get())), 136 opus_encoder_(reinterpret_cast<OpusEncoder*>(encoder_memory_.get())),
136 buffer_(new float[num_channels * samples_per_10ms_]) { 137 buffer_(new float[num_channels * samples_per_10ms_]) {
137 CHECK_EQ(opus_encoder_init(opus_encoder_, sampling_rate, num_channels, 138 CHECK_EQ(opus_encoder_init(opus_encoder_, sampling_rate, num_channels,
138 OPUS_APPLICATION_AUDIO), 139 OPUS_APPLICATION_AUDIO),
139 OPUS_OK); 140 OPUS_OK);
140 if (bitrate <= 0) { 141 if (bitrate <= 0) {
141 // Note: As of 2013-10-31, the encoder in "auto bitrate" mode would use a 142 // Note: As of 2013-10-31, the encoder in "auto bitrate" mode would use a
142 // variable bitrate up to 102kbps for 2-channel, 48 kHz audio and a 10 ms 143 // variable bitrate up to 102kbps for 2-channel, 48 kHz audio and a 10 ms
143 // frame size. The opus library authors may, of course, adjust this in 144 // frame size. The opus library authors may, of course, adjust this in
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 static const int kOpusMaxPayloadSize = 4000; 197 static const int kOpusMaxPayloadSize = 4000;
197 198
198 DISALLOW_COPY_AND_ASSIGN(OpusImpl); 199 DISALLOW_COPY_AND_ASSIGN(OpusImpl);
199 }; 200 };
200 201
201 class AudioEncoder::Pcm16Impl : public AudioEncoder::ImplBase { 202 class AudioEncoder::Pcm16Impl : public AudioEncoder::ImplBase {
202 public: 203 public:
203 Pcm16Impl(CastEnvironment* cast_environment, 204 Pcm16Impl(CastEnvironment* cast_environment,
204 int num_channels, int sampling_rate, 205 int num_channels, int sampling_rate,
205 const FrameEncodedCallback& callback) 206 const FrameEncodedCallback& callback)
206 : ImplBase(cast_environment, kPcm16, num_channels, sampling_rate, 207 : ImplBase(cast_environment, transport::kPcm16, num_channels,
207 callback), 208 sampling_rate, callback),
208 buffer_(new int16[num_channels * samples_per_10ms_]) {} 209 buffer_(new int16[num_channels * samples_per_10ms_]) {}
209 210
210 virtual ~Pcm16Impl() {} 211 virtual ~Pcm16Impl() {}
211 212
212 private: 213 private:
213 virtual void TransferSamplesIntoBuffer(const AudioBus* audio_bus, 214 virtual void TransferSamplesIntoBuffer(const AudioBus* audio_bus,
214 int source_offset, 215 int source_offset,
215 int buffer_fill_offset, 216 int buffer_fill_offset,
216 int num_samples) OVERRIDE { 217 int num_samples) OVERRIDE {
217 audio_bus->ToInterleavedPartial( 218 audio_bus->ToInterleavedPartial(
(...skipping 21 matching lines...) Expand all
239 AudioEncoder::AudioEncoder( 240 AudioEncoder::AudioEncoder(
240 const scoped_refptr<CastEnvironment>& cast_environment, 241 const scoped_refptr<CastEnvironment>& cast_environment,
241 const AudioSenderConfig& audio_config, 242 const AudioSenderConfig& audio_config,
242 const FrameEncodedCallback& frame_encoded_callback) 243 const FrameEncodedCallback& frame_encoded_callback)
243 : cast_environment_(cast_environment) { 244 : cast_environment_(cast_environment) {
244 // Note: It doesn't matter which thread constructs AudioEncoder, just so long 245 // Note: It doesn't matter which thread constructs AudioEncoder, just so long
245 // as all calls to InsertAudio() are by the same thread. 246 // as all calls to InsertAudio() are by the same thread.
246 insert_thread_checker_.DetachFromThread(); 247 insert_thread_checker_.DetachFromThread();
247 248
248 switch (audio_config.codec) { 249 switch (audio_config.codec) {
249 case kOpus: 250 case transport::kOpus:
250 impl_.reset(new OpusImpl( 251 impl_.reset(new OpusImpl(
251 cast_environment, audio_config.channels, audio_config.frequency, 252 cast_environment, audio_config.channels, audio_config.frequency,
252 audio_config.bitrate, frame_encoded_callback)); 253 audio_config.bitrate, frame_encoded_callback));
253 break; 254 break;
254 case kPcm16: 255 case transport::kPcm16:
255 impl_.reset(new Pcm16Impl( 256 impl_.reset(new Pcm16Impl(
256 cast_environment, audio_config.channels, audio_config.frequency, 257 cast_environment, audio_config.channels, audio_config.frequency,
257 frame_encoded_callback)); 258 frame_encoded_callback));
258 break; 259 break;
259 default: 260 default:
260 NOTREACHED() << "Unsupported or unspecified codec for audio encoder"; 261 NOTREACHED() << "Unsupported or unspecified codec for audio encoder";
261 break; 262 break;
262 } 263 }
263 } 264 }
264 265
(...skipping 20 matching lines...) Expand all
285 const base::TimeTicks& recorded_time, 286 const base::TimeTicks& recorded_time,
286 const base::Closure& done_callback) { 287 const base::Closure& done_callback) {
287 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::AUDIO_ENCODER)); 288 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::AUDIO_ENCODER));
288 impl_->EncodeAudio(audio_bus, recorded_time, done_callback); 289 impl_->EncodeAudio(audio_bus, recorded_time, done_callback);
289 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, 290 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
290 base::Bind(LogAudioEncodedEvent, cast_environment_, recorded_time)); 291 base::Bind(LogAudioEncodedEvent, cast_environment_, recorded_time));
291 } 292 }
292 293
293 } // namespace cast 294 } // namespace cast
294 } // namespace media 295 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/audio_sender/audio_encoder.h ('k') | media/cast/audio_sender/audio_encoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698