| 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/audio_sender/audio_encoder.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "media/cast/cast_defines.h" | 10 #include "media/cast/cast_defines.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 frequency_(frequency), | 28 frequency_(frequency), |
| 29 cast_thread_(cast_thread), | 29 cast_thread_(cast_thread), |
| 30 last_timestamp_(0) {} | 30 last_timestamp_(0) {} |
| 31 | 31 |
| 32 virtual int32 SendData( | 32 virtual int32 SendData( |
| 33 webrtc::FrameType /*frame_type*/, | 33 webrtc::FrameType /*frame_type*/, |
| 34 uint8 /*payload_type*/, | 34 uint8 /*payload_type*/, |
| 35 uint32 timestamp, | 35 uint32 timestamp, |
| 36 const uint8* payload_data, | 36 const uint8* payload_data, |
| 37 uint16 payload_size, | 37 uint16 payload_size, |
| 38 const webrtc::RTPFragmentationHeader* /*fragmentation*/) OVERRIDE { | 38 const webrtc::RTPFragmentationHeader* /*fragmentation*/) { |
| 39 scoped_ptr<EncodedAudioFrame> audio_frame(new EncodedAudioFrame()); | 39 scoped_ptr<EncodedAudioFrame> audio_frame(new EncodedAudioFrame()); |
| 40 audio_frame->codec = codec_; | 40 audio_frame->codec = codec_; |
| 41 audio_frame->samples = timestamp - last_timestamp_; | 41 audio_frame->samples = timestamp - last_timestamp_; |
| 42 DCHECK(audio_frame->samples <= kMaxNumberOfSamples); | 42 DCHECK(audio_frame->samples <= kMaxNumberOfSamples); |
| 43 last_timestamp_ = timestamp; | 43 last_timestamp_ = timestamp; |
| 44 audio_frame->data.insert(audio_frame->data.begin(), | 44 audio_frame->data.insert(audio_frame->data.begin(), |
| 45 payload_data, | 45 payload_data, |
| 46 payload_data + payload_size); | 46 payload_data + payload_size); |
| 47 | 47 |
| 48 cast_thread_->PostTask(CastThread::MAIN, FROM_HERE, | 48 cast_thread_->PostTask(CastThread::MAIN, FROM_HERE, |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 default: | 103 default: |
| 104 DCHECK(false) << "Codec must be specified for audio encoder"; | 104 DCHECK(false) << "Codec must be specified for audio encoder"; |
| 105 return; | 105 return; |
| 106 } | 106 } |
| 107 if (audio_encoder_->RegisterSendCodec(send_codec) != 0) { | 107 if (audio_encoder_->RegisterSendCodec(send_codec) != 0) { |
| 108 DCHECK(false) << "Invalid webrtc return value; failed to register codec"; | 108 DCHECK(false) << "Invalid webrtc return value; failed to register codec"; |
| 109 } | 109 } |
| 110 } | 110 } |
| 111 | 111 |
| 112 AudioEncoder::~AudioEncoder() { | 112 AudioEncoder::~AudioEncoder() { |
| 113 webrtc::AudioCodingModule::Destroy(audio_encoder_); |
| 113 } | 114 } |
| 114 | 115 |
| 115 // Called from main cast thread. | 116 // Called from main cast thread. |
| 116 void AudioEncoder::InsertRawAudioFrame( | 117 void AudioEncoder::InsertRawAudioFrame( |
| 117 const PcmAudioFrame* audio_frame, | 118 const PcmAudioFrame* audio_frame, |
| 118 const base::TimeTicks& recorded_time, | 119 const base::TimeTicks& recorded_time, |
| 119 const FrameEncodedCallback& frame_encoded_callback, | 120 const FrameEncodedCallback& frame_encoded_callback, |
| 120 const base::Closure release_callback) { | 121 const base::Closure release_callback) { |
| 121 cast_thread_->PostTask(CastThread::AUDIO_ENCODER, FROM_HERE, | 122 cast_thread_->PostTask(CastThread::AUDIO_ENCODER, FROM_HERE, |
| 122 base::Bind(&AudioEncoder::EncodeAudioFrameThread, this, audio_frame, | 123 base::Bind(&AudioEncoder::EncodeAudioFrameThread, this, audio_frame, |
| 123 recorded_time, frame_encoded_callback, release_callback)); | 124 recorded_time, frame_encoded_callback, release_callback)); |
| 124 } | 125 } |
| 125 | 126 |
| 126 // Called from cast audio encoder thread. | 127 // Called from cast audio encoder thread. |
| 127 void AudioEncoder::EncodeAudioFrameThread( | 128 void AudioEncoder::EncodeAudioFrameThread( |
| 128 const PcmAudioFrame* audio_frame, | 129 const PcmAudioFrame* audio_frame, |
| 129 const base::TimeTicks& recorded_time, | 130 const base::TimeTicks& recorded_time, |
| 130 const FrameEncodedCallback& frame_encoded_callback, | 131 const FrameEncodedCallback& frame_encoded_callback, |
| 131 const base::Closure release_callback) { | 132 const base::Closure release_callback) { |
| 132 DCHECK(cast_thread_->CurrentlyOn(CastThread::AUDIO_ENCODER)); | 133 DCHECK(cast_thread_->CurrentlyOn(CastThread::AUDIO_ENCODER)); |
| 133 int samples_per_10ms = audio_frame->frequency / 100; | 134 int samples_per_10ms = audio_frame->frequency / 100; |
| 134 size_t number_of_10ms_blocks = audio_frame->samples.size() / | 135 int number_of_10ms_blocks = audio_frame->samples.size() / |
| 135 (samples_per_10ms * audio_frame->channels); | 136 (samples_per_10ms * audio_frame->channels); |
| 136 DCHECK(webrtc::AudioFrame::kMaxDataSizeSamples > samples_per_10ms) | 137 DCHECK(webrtc::AudioFrame::kMaxDataSizeSamples > samples_per_10ms) |
| 137 << "webrtc sanity check failed"; | 138 << "webrtc sanity check failed"; |
| 138 | 139 |
| 139 for (size_t i = 0; i < number_of_10ms_blocks; ++i) { | 140 for (int i = 0; i < number_of_10ms_blocks; ++i) { |
| 140 webrtc::AudioFrame webrtc_audio_frame; | 141 webrtc::AudioFrame webrtc_audio_frame; |
| 141 webrtc_audio_frame.timestamp_ = timestamp_; | 142 webrtc_audio_frame.timestamp_ = timestamp_; |
| 142 | 143 |
| 143 // Due to the webrtc::AudioFrame declaration we need to copy our data into | 144 // Due to the webrtc::AudioFrame declaration we need to copy our data into |
| 144 // the webrtc structure. | 145 // the webrtc structure. |
| 145 memcpy(&webrtc_audio_frame.data_[0], | 146 memcpy(&webrtc_audio_frame.data_[0], |
| 146 &audio_frame->samples[i * samples_per_10ms * audio_frame->channels], | 147 &audio_frame->samples[i * samples_per_10ms * audio_frame->channels], |
| 147 samples_per_10ms * audio_frame->channels * sizeof(int16)); | 148 samples_per_10ms * audio_frame->channels * sizeof(int16)); |
| 148 webrtc_audio_frame.samples_per_channel_ = samples_per_10ms; | 149 webrtc_audio_frame.samples_per_channel_ = samples_per_10ms; |
| 149 webrtc_audio_frame.sample_rate_hz_ = audio_frame->frequency; | 150 webrtc_audio_frame.sample_rate_hz_ = audio_frame->frequency; |
| 150 webrtc_audio_frame.num_channels_ = audio_frame->channels; | 151 webrtc_audio_frame.num_channels_ = audio_frame->channels; |
| 151 | 152 |
| 152 // webrtc::AudioCodingModule is thread safe. | 153 // webrtc::AudioCodingModule is thread safe. |
| 153 if (audio_encoder_->Add10MsData(webrtc_audio_frame) != 0) { | 154 if (audio_encoder_->Add10MsData(webrtc_audio_frame) != 0) { |
| 154 DCHECK(false) << "Invalid webrtc return value"; | 155 DCHECK(false) << "Invalid webrtc return value"; |
| 155 } | 156 } |
| 156 timestamp_ += samples_per_10ms; | 157 timestamp_ += samples_per_10ms; |
| 157 } | 158 } |
| 158 // We are done with the audio frame release it. | 159 // We are done with the audio frame release it. |
| 159 cast_thread_->PostTask(CastThread::MAIN, FROM_HERE, release_callback); | 160 cast_thread_->PostTask(CastThread::MAIN, FROM_HERE, release_callback); |
| 160 | 161 |
| 161 // Note: | 162 // Note: |
| 162 // Not all insert of 10 ms will generate a callback with encoded data. | 163 // Not all insert of 10 ms will generate a callback with encoded data. |
| 163 webrtc_encoder_callback_->SetEncodedCallbackInfo(recorded_time, | 164 webrtc_encoder_callback_->SetEncodedCallbackInfo(recorded_time, |
| 164 &frame_encoded_callback); | 165 &frame_encoded_callback); |
| 165 for (size_t i = 0; i < number_of_10ms_blocks; ++i) { | 166 for (int i = 0; i < number_of_10ms_blocks; ++i) { |
| 166 audio_encoder_->Process(); | 167 audio_encoder_->Process(); |
| 167 } | 168 } |
| 168 } | 169 } |
| 169 | 170 |
| 170 } // namespace media | 171 } // namespace media |
| 171 } // namespace cast | 172 } // namespace cast |
| OLD | NEW |