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

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

Issue 901833004: [Cast] Repurpose CastInitializationStatus for variable frame size support. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Compile fixes. Created 5 years, 10 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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/sender/audio_encoder.h" 5 #include "media/cast/sender/audio_encoder.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <string> 9 #include <string>
10 10
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 Codec codec, 49 Codec codec,
50 int num_channels, 50 int num_channels,
51 int sampling_rate, 51 int sampling_rate,
52 int samples_per_frame, 52 int samples_per_frame,
53 const FrameEncodedCallback& callback) 53 const FrameEncodedCallback& callback)
54 : cast_environment_(cast_environment), 54 : cast_environment_(cast_environment),
55 codec_(codec), 55 codec_(codec),
56 num_channels_(num_channels), 56 num_channels_(num_channels),
57 samples_per_frame_(samples_per_frame), 57 samples_per_frame_(samples_per_frame),
58 callback_(callback), 58 callback_(callback),
59 cast_initialization_status_(STATUS_AUDIO_UNINITIALIZED), 59 operational_status_(STATUS_UNINITIALIZED),
60 frame_duration_(base::TimeDelta::FromMicroseconds( 60 frame_duration_(base::TimeDelta::FromMicroseconds(
61 base::Time::kMicrosecondsPerSecond * samples_per_frame_ / 61 base::Time::kMicrosecondsPerSecond * samples_per_frame_ /
62 sampling_rate)), 62 sampling_rate)),
63 buffer_fill_end_(0), 63 buffer_fill_end_(0),
64 frame_id_(0), 64 frame_id_(0),
65 frame_rtp_timestamp_(0), 65 frame_rtp_timestamp_(0),
66 samples_dropped_from_buffer_(0) { 66 samples_dropped_from_buffer_(0) {
67 // Support for max sampling rate of 48KHz, 2 channels, 100 ms duration. 67 // Support for max sampling rate of 48KHz, 2 channels, 100 ms duration.
68 const int kMaxSamplesTimesChannelsPerFrame = 48 * 2 * 100; 68 const int kMaxSamplesTimesChannelsPerFrame = 48 * 2 * 100;
69 if (num_channels_ <= 0 || samples_per_frame_ <= 0 || 69 if (num_channels_ <= 0 || samples_per_frame_ <= 0 ||
70 frame_duration_ == base::TimeDelta() || 70 frame_duration_ == base::TimeDelta() ||
71 samples_per_frame_ * num_channels_ > kMaxSamplesTimesChannelsPerFrame) { 71 samples_per_frame_ * num_channels_ > kMaxSamplesTimesChannelsPerFrame) {
72 cast_initialization_status_ = STATUS_INVALID_AUDIO_CONFIGURATION; 72 operational_status_ = STATUS_INVALID_CONFIGURATION;
73 } 73 }
74 } 74 }
75 75
76 CastInitializationStatus InitializationResult() const { 76 OperationalStatus InitializationResult() const {
77 return cast_initialization_status_; 77 return operational_status_;
78 } 78 }
79 79
80 int samples_per_frame() const { 80 int samples_per_frame() const {
81 return samples_per_frame_; 81 return samples_per_frame_;
82 } 82 }
83 83
84 base::TimeDelta frame_duration() const { return frame_duration_; } 84 base::TimeDelta frame_duration() const { return frame_duration_; }
85 85
86 void EncodeAudio(scoped_ptr<AudioBus> audio_bus, 86 void EncodeAudio(scoped_ptr<AudioBus> audio_bus,
87 const base::TimeTicks& recorded_time) { 87 const base::TimeTicks& recorded_time) {
88 DCHECK_EQ(cast_initialization_status_, STATUS_AUDIO_INITIALIZED); 88 DCHECK_EQ(operational_status_, STATUS_INITIALIZED);
89 DCHECK(!recorded_time.is_null()); 89 DCHECK(!recorded_time.is_null());
90 90
91 // Determine whether |recorded_time| is consistent with the amount of audio 91 // Determine whether |recorded_time| is consistent with the amount of audio
92 // data having been processed in the past. Resolve the underrun problem by 92 // data having been processed in the past. Resolve the underrun problem by
93 // dropping data from the internal buffer and skipping ahead the next 93 // dropping data from the internal buffer and skipping ahead the next
94 // frame's RTP timestamp by the estimated number of frames missed. On the 94 // frame's RTP timestamp by the estimated number of frames missed. On the
95 // other hand, don't attempt to resolve overruns: A receiver should 95 // other hand, don't attempt to resolve overruns: A receiver should
96 // gracefully deal with an excess of audio data. 96 // gracefully deal with an excess of audio data.
97 base::TimeDelta buffer_fill_duration = 97 base::TimeDelta buffer_fill_duration =
98 buffer_fill_end_ * frame_duration_ / samples_per_frame_; 98 buffer_fill_end_ * frame_duration_ / samples_per_frame_;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 int buffer_fill_offset, 162 int buffer_fill_offset,
163 int num_samples) = 0; 163 int num_samples) = 0;
164 virtual bool EncodeFromFilledBuffer(std::string* out) = 0; 164 virtual bool EncodeFromFilledBuffer(std::string* out) = 0;
165 165
166 const scoped_refptr<CastEnvironment> cast_environment_; 166 const scoped_refptr<CastEnvironment> cast_environment_;
167 const Codec codec_; 167 const Codec codec_;
168 const int num_channels_; 168 const int num_channels_;
169 const int samples_per_frame_; 169 const int samples_per_frame_;
170 const FrameEncodedCallback callback_; 170 const FrameEncodedCallback callback_;
171 171
172 // Subclass' ctor is expected to set this to STATUS_AUDIO_INITIALIZED. 172 // Subclass' ctor is expected to set this to STATUS_INITIALIZED.
173 CastInitializationStatus cast_initialization_status_; 173 OperationalStatus operational_status_;
174 174
175 // The duration of one frame of encoded audio samples. Derived from 175 // The duration of one frame of encoded audio samples. Derived from
176 // |samples_per_frame_| and the sampling rate. 176 // |samples_per_frame_| and the sampling rate.
177 const base::TimeDelta frame_duration_; 177 const base::TimeDelta frame_duration_;
178 178
179 private: 179 private:
180 // In the case where a call to EncodeAudio() cannot completely fill the 180 // In the case where a call to EncodeAudio() cannot completely fill the
181 // buffer, this points to the position at which to populate data in a later 181 // buffer, this points to the position at which to populate data in a later
182 // call. 182 // call.
183 int buffer_fill_end_; 183 int buffer_fill_end_;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 const FrameEncodedCallback& callback) 216 const FrameEncodedCallback& callback)
217 : ImplBase(cast_environment, 217 : ImplBase(cast_environment,
218 CODEC_AUDIO_OPUS, 218 CODEC_AUDIO_OPUS,
219 num_channels, 219 num_channels,
220 sampling_rate, 220 sampling_rate,
221 sampling_rate / kDefaultFramesPerSecond, /* 10 ms frames */ 221 sampling_rate / kDefaultFramesPerSecond, /* 10 ms frames */
222 callback), 222 callback),
223 encoder_memory_(new uint8[opus_encoder_get_size(num_channels)]), 223 encoder_memory_(new uint8[opus_encoder_get_size(num_channels)]),
224 opus_encoder_(reinterpret_cast<OpusEncoder*>(encoder_memory_.get())), 224 opus_encoder_(reinterpret_cast<OpusEncoder*>(encoder_memory_.get())),
225 buffer_(new float[num_channels * samples_per_frame_]) { 225 buffer_(new float[num_channels * samples_per_frame_]) {
226 if (ImplBase::cast_initialization_status_ != STATUS_AUDIO_UNINITIALIZED || 226 if (ImplBase::operational_status_ != STATUS_UNINITIALIZED ||
227 sampling_rate % samples_per_frame_ != 0 || 227 sampling_rate % samples_per_frame_ != 0 ||
228 !IsValidFrameDuration(frame_duration_)) { 228 !IsValidFrameDuration(frame_duration_)) {
229 return; 229 return;
230 } 230 }
231 if (opus_encoder_init(opus_encoder_, 231 if (opus_encoder_init(opus_encoder_,
232 sampling_rate, 232 sampling_rate,
233 num_channels, 233 num_channels,
234 OPUS_APPLICATION_AUDIO) != OPUS_OK) { 234 OPUS_APPLICATION_AUDIO) != OPUS_OK) {
235 ImplBase::cast_initialization_status_ = 235 ImplBase::operational_status_ = STATUS_INVALID_CONFIGURATION;
236 STATUS_INVALID_AUDIO_CONFIGURATION;
237 return; 236 return;
238 } 237 }
239 ImplBase::cast_initialization_status_ = STATUS_AUDIO_INITIALIZED; 238 ImplBase::operational_status_ = STATUS_INITIALIZED;
240 239
241 if (bitrate <= 0) { 240 if (bitrate <= 0) {
242 // Note: As of 2013-10-31, the encoder in "auto bitrate" mode would use a 241 // Note: As of 2013-10-31, the encoder in "auto bitrate" mode would use a
243 // variable bitrate up to 102kbps for 2-channel, 48 kHz audio and a 10 ms 242 // variable bitrate up to 102kbps for 2-channel, 48 kHz audio and a 10 ms
244 // frame size. The opus library authors may, of course, adjust this in 243 // frame size. The opus library authors may, of course, adjust this in
245 // later versions. 244 // later versions.
246 bitrate = OPUS_AUTO; 245 bitrate = OPUS_AUTO;
247 } 246 }
248 CHECK_EQ(opus_encoder_ctl(opus_encoder_, OPUS_SET_BITRATE(bitrate)), 247 CHECK_EQ(opus_encoder_ctl(opus_encoder_, OPUS_SET_BITRATE(bitrate)),
249 OPUS_OK); 248 OPUS_OK);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 kAccessUnitSamples, 335 kAccessUnitSamples,
337 callback), 336 callback),
338 input_buffer_(AudioBus::Create(num_channels, kAccessUnitSamples)), 337 input_buffer_(AudioBus::Create(num_channels, kAccessUnitSamples)),
339 input_bus_(AudioBus::CreateWrapper(num_channels)), 338 input_bus_(AudioBus::CreateWrapper(num_channels)),
340 max_access_unit_size_(0), 339 max_access_unit_size_(0),
341 output_buffer_(nullptr), 340 output_buffer_(nullptr),
342 converter_(nullptr), 341 converter_(nullptr),
343 file_(nullptr), 342 file_(nullptr),
344 num_access_units_(0), 343 num_access_units_(0),
345 can_resume_(true) { 344 can_resume_(true) {
346 if (ImplBase::cast_initialization_status_ != STATUS_AUDIO_UNINITIALIZED) { 345 if (ImplBase::operational_status_ != STATUS_UNINITIALIZED) {
347 return; 346 return;
348 } 347 }
349 if (!Initialize(sampling_rate, bitrate)) { 348 if (!Initialize(sampling_rate, bitrate)) {
350 ImplBase::cast_initialization_status_ = 349 ImplBase::operational_status_ = STATUS_INVALID_CONFIGURATION;
351 STATUS_INVALID_AUDIO_CONFIGURATION;
352 return; 350 return;
353 } 351 }
354 ImplBase::cast_initialization_status_ = STATUS_AUDIO_INITIALIZED; 352 ImplBase::operational_status_ = STATUS_INITIALIZED;
355 } 353 }
356 354
357 private: 355 private:
358 ~AppleAacImpl() override { Teardown(); } 356 ~AppleAacImpl() override { Teardown(); }
359 357
360 // Destroys the existing audio converter and file, if any. 358 // Destroys the existing audio converter and file, if any.
361 void Teardown() { 359 void Teardown() {
362 if (converter_) { 360 if (converter_) {
363 AudioConverterDispose(converter_); 361 AudioConverterDispose(converter_);
364 converter_ = nullptr; 362 converter_ = nullptr;
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 int num_channels, 698 int num_channels,
701 int sampling_rate, 699 int sampling_rate,
702 const FrameEncodedCallback& callback) 700 const FrameEncodedCallback& callback)
703 : ImplBase(cast_environment, 701 : ImplBase(cast_environment,
704 CODEC_AUDIO_PCM16, 702 CODEC_AUDIO_PCM16,
705 num_channels, 703 num_channels,
706 sampling_rate, 704 sampling_rate,
707 sampling_rate / kDefaultFramesPerSecond, /* 10 ms frames */ 705 sampling_rate / kDefaultFramesPerSecond, /* 10 ms frames */
708 callback), 706 callback),
709 buffer_(new int16[num_channels * samples_per_frame_]) { 707 buffer_(new int16[num_channels * samples_per_frame_]) {
710 if (ImplBase::cast_initialization_status_ != STATUS_AUDIO_UNINITIALIZED) 708 if (ImplBase::operational_status_ != STATUS_UNINITIALIZED)
711 return; 709 return;
712 cast_initialization_status_ = STATUS_AUDIO_INITIALIZED; 710 operational_status_ = STATUS_INITIALIZED;
713 } 711 }
714 712
715 private: 713 private:
716 ~Pcm16Impl() override {} 714 ~Pcm16Impl() override {}
717 715
718 void TransferSamplesIntoBuffer(const AudioBus* audio_bus, 716 void TransferSamplesIntoBuffer(const AudioBus* audio_bus,
719 int source_offset, 717 int source_offset,
720 int buffer_fill_offset, 718 int buffer_fill_offset,
721 int num_samples) override { 719 int num_samples) override {
722 audio_bus->ToInterleavedPartial( 720 audio_bus->ToInterleavedPartial(
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
780 frame_encoded_callback); 778 frame_encoded_callback);
781 break; 779 break;
782 default: 780 default:
783 NOTREACHED() << "Unsupported or unspecified codec for audio encoder"; 781 NOTREACHED() << "Unsupported or unspecified codec for audio encoder";
784 break; 782 break;
785 } 783 }
786 } 784 }
787 785
788 AudioEncoder::~AudioEncoder() {} 786 AudioEncoder::~AudioEncoder() {}
789 787
790 CastInitializationStatus AudioEncoder::InitializationResult() const { 788 OperationalStatus AudioEncoder::InitializationResult() const {
791 DCHECK(insert_thread_checker_.CalledOnValidThread()); 789 DCHECK(insert_thread_checker_.CalledOnValidThread());
792 if (impl_.get()) { 790 if (impl_.get()) {
793 return impl_->InitializationResult(); 791 return impl_->InitializationResult();
794 } 792 }
795 return STATUS_UNSUPPORTED_AUDIO_CODEC; 793 return STATUS_UNSUPPORTED_CODEC;
796 } 794 }
797 795
798 int AudioEncoder::GetSamplesPerFrame() const { 796 int AudioEncoder::GetSamplesPerFrame() const {
799 DCHECK(insert_thread_checker_.CalledOnValidThread()); 797 DCHECK(insert_thread_checker_.CalledOnValidThread());
800 if (InitializationResult() != STATUS_AUDIO_INITIALIZED) { 798 if (InitializationResult() != STATUS_INITIALIZED) {
801 NOTREACHED(); 799 NOTREACHED();
802 return std::numeric_limits<int>::max(); 800 return std::numeric_limits<int>::max();
803 } 801 }
804 return impl_->samples_per_frame(); 802 return impl_->samples_per_frame();
805 } 803 }
806 804
807 base::TimeDelta AudioEncoder::GetFrameDuration() const { 805 base::TimeDelta AudioEncoder::GetFrameDuration() const {
808 DCHECK(insert_thread_checker_.CalledOnValidThread()); 806 DCHECK(insert_thread_checker_.CalledOnValidThread());
809 if (InitializationResult() != STATUS_AUDIO_INITIALIZED) { 807 if (InitializationResult() != STATUS_INITIALIZED) {
810 NOTREACHED(); 808 NOTREACHED();
811 return base::TimeDelta(); 809 return base::TimeDelta();
812 } 810 }
813 return impl_->frame_duration(); 811 return impl_->frame_duration();
814 } 812 }
815 813
816 void AudioEncoder::InsertAudio(scoped_ptr<AudioBus> audio_bus, 814 void AudioEncoder::InsertAudio(scoped_ptr<AudioBus> audio_bus,
817 const base::TimeTicks& recorded_time) { 815 const base::TimeTicks& recorded_time) {
818 DCHECK(insert_thread_checker_.CalledOnValidThread()); 816 DCHECK(insert_thread_checker_.CalledOnValidThread());
819 DCHECK(audio_bus.get()); 817 DCHECK(audio_bus.get());
820 if (InitializationResult() != STATUS_AUDIO_INITIALIZED) { 818 if (InitializationResult() != STATUS_INITIALIZED) {
821 NOTREACHED(); 819 NOTREACHED();
822 return; 820 return;
823 } 821 }
824 cast_environment_->PostTask(CastEnvironment::AUDIO, 822 cast_environment_->PostTask(CastEnvironment::AUDIO,
825 FROM_HERE, 823 FROM_HERE,
826 base::Bind(&AudioEncoder::ImplBase::EncodeAudio, 824 base::Bind(&AudioEncoder::ImplBase::EncodeAudio,
827 impl_, 825 impl_,
828 base::Passed(&audio_bus), 826 base::Passed(&audio_bus),
829 recorded_time)); 827 recorded_time));
830 } 828 }
831 829
832 } // namespace cast 830 } // namespace cast
833 } // namespace media 831 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698