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

Unified Diff: services/media/audio/platform/linux/alsa_output.cc

Issue 1471813002: Mix to an intermediate buffer. (Closed) Base URL: https://github.com/domokit/mojo.git@change7
Patch Set: Final rebase before landing Created 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « services/media/audio/platform/linux/alsa_output.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: services/media/audio/platform/linux/alsa_output.cc
diff --git a/services/media/audio/platform/linux/alsa_output.cc b/services/media/audio/platform/linux/alsa_output.cc
index e10c073e615c4af69ba0401acb7fe7194fcba520..b2740c66a1885113244896f8d2e587a8170a3267 100644
--- a/services/media/audio/platform/linux/alsa_output.cc
+++ b/services/media/audio/platform/linux/alsa_output.cc
@@ -75,20 +75,18 @@ AudioOutputPtr AlsaOutput::New(AudioOutputManager* manager) {
MediaResult AlsaOutput::Configure(LpcmMediaTypeDetailsPtr config) {
if (!config) { return MediaResult::INVALID_ARGUMENT; }
- if (output_format_) { return MediaResult::BAD_STATE; }
+ if (output_formatter_) { return MediaResult::BAD_STATE; }
+
+ output_formatter_ = OutputFormatter::Select(config);
+ if (!output_formatter_) { return MediaResult::UNSUPPORTED_CONFIG; }
- uint32_t bytes_per_sample;
switch (config->sample_format) {
case LpcmSampleFormat::UNSIGNED_8:
alsa_format_ = SND_PCM_FORMAT_U8;
- silence_byte_ = 0x80;
- bytes_per_sample = 1;
break;
case LpcmSampleFormat::SIGNED_16:
alsa_format_ = SND_PCM_FORMAT_S16;
- silence_byte_ = 0x00;
- bytes_per_sample = 2;
break;
case LpcmSampleFormat::SIGNED_24_IN_32:
@@ -115,18 +113,14 @@ MediaResult AlsaOutput::Configure(LpcmMediaTypeDetailsPtr config) {
&frames_per_tick_);
DCHECK(is_precise);
- // Figure out how many bytes there are per frame.
- output_bytes_per_frame_ = bytes_per_sample * config->channels;
-
// Success
- output_format_ = config.Pass();
return MediaResult::OK;
}
MediaResult AlsaOutput::Init() {
static const char* kAlsaDevice = "default";
- if (!output_format_) { return MediaResult::BAD_STATE; }
+ if (!output_formatter_) { return MediaResult::BAD_STATE; }
if (alsa_device_) { return MediaResult::BAD_STATE; }
snd_pcm_sframes_t res;
@@ -142,17 +136,17 @@ MediaResult AlsaOutput::Init() {
res = snd_pcm_set_params(alsa_device_,
alsa_format_,
SND_PCM_ACCESS_RW_INTERLEAVED,
- output_format_->channels,
- output_format_->frames_per_second,
+ output_formatter_->format()->channels,
+ output_formatter_->format()->frames_per_second,
0, // do not allow ALSA resample
local_time::to_usec<unsigned int>(TARGET_LATENCY));
if (res) {
LOG(ERROR) << "Failed to configure ALSA device \"" << kAlsaDevice << "\" "
<< "(res = " << res << ")";
LOG(ERROR) << "Requested channels : "
- << output_format_->channels;
+ << output_formatter_->format()->channels;
LOG(ERROR) << "Requested frames per second: "
- << output_format_->frames_per_second;
+ << output_formatter_->format()->frames_per_second;
LOG(ERROR) << "Requested ALSA format : " << alsa_format_;
Cleanup();
return MediaResult::INTERNAL_ERROR;
@@ -168,8 +162,13 @@ MediaResult AlsaOutput::Init() {
return MediaResult::INTERNAL_ERROR;
}
+ size_t buffer_size;
mix_buf_frames_ = res;
- mix_buf_.reset(new uint8_t[mix_buf_frames_ * output_bytes_per_frame_]);
+ buffer_size = mix_buf_frames_ * output_formatter_->bytes_per_frame();
+ mix_buf_.reset(new uint8_t[buffer_size]);
+
+ // Set up the intermediate buffer at the StandardOutputBase level
+ SetupMixBuffer(mix_buf_frames_);
return MediaResult::OK;
}
@@ -279,11 +278,6 @@ bool AlsaOutput::StartMixJob(MixJob* job, const LocalTime& process_start) {
job->local_to_output = &local_to_output_;
job->local_to_output_gen = local_to_output_gen_;
- // TODO(johngro): optimize this if we can. The first buffer we mix can just
- // put its samples directly into the output buffer, and does not need to
- // accumulate and clip. In theory, we only need to put silence in the
- // places where our outputs are not going to already overwrite.
- FillMixBufWithSilence(job->buf_frames);
return true;
}
@@ -308,16 +302,6 @@ bool AlsaOutput::FinishMixJob(const MixJob& job) {
return true;
}
-void AlsaOutput::FillMixBufWithSilence(uint32_t frames) {
- DCHECK(mix_buf_);
- DCHECK(frames <= mix_buf_frames_);
-
- // TODO(johngro): someday, this may not be this simple. Filling unsigned
- // multibyte sample formats, or floating point formats, will require something
- // more sophisticated than filling with a single byte pattern.
- ::memset(mix_buf_.get(), silence_byte_, frames * output_bytes_per_frame_);
-}
-
void AlsaOutput::HandleAsUnderflow() {
snd_pcm_sframes_t res;
@@ -339,7 +323,7 @@ void AlsaOutput::HandleAsUnderflow() {
// silence. When we have better control of our thread priorities, prime this
// with the minimimum amt we can get away with and still be able to start
// mixing without underflowing.
- FillMixBufWithSilence(mix_buf_frames_);
+ output_formatter_->FillWithSilence(mix_buf_.get(), mix_buf_frames_);
res = snd_pcm_writei(alsa_device_, mix_buf_.get(), mix_buf_frames_);
if (res < 0) {
« no previous file with comments | « services/media/audio/platform/linux/alsa_output.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698