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

Unified Diff: services/media/audio/platform/generic/standard_output_base.cc

Issue 1471813002: Mix to an intermediate buffer. (Closed) Base URL: https://github.com/domokit/mojo.git@change7
Patch Set: rebase on top of samples_per_frame -> channels patchset Created 5 years 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
Index: services/media/audio/platform/generic/standard_output_base.cc
diff --git a/services/media/audio/platform/generic/standard_output_base.cc b/services/media/audio/platform/generic/standard_output_base.cc
index 34d53d2d5cb932cedb8d9cb347475d9745605d40..2cef0aa0e04e41177a91fa63fd4d456ad2044191 100644
--- a/services/media/audio/platform/generic/standard_output_base.cc
+++ b/services/media/audio/platform/generic/standard_output_base.cc
@@ -78,7 +78,26 @@ void StandardOutputBase::Process() {
break;
}
+ // If we have a mix job, then we must have an output formatter, and an
+ // intermediate buffer allocated, and it must be large enough for the mix
+ // job we were given.
+ DCHECK(mix_buf_);
+ DCHECK(output_formatter_);
+ DCHECK_LE(cur_mix_job_.buf_frames, mix_buf_frames_);
+
+ // Fill the intermediate buffer with silence.
+ size_t bytes_to_zero = sizeof(*mix_buf_)
+ * cur_mix_job_.buf_frames
+ * output_formatter_->channels();
+ ::memset(mix_buf_.get(), 0, bytes_to_zero);
+
+ // Mix each track into the intermediate buffer, then clip/format into the
+ // final buffer.
ForeachTrack(setup_mix_, process_mix_);
+ output_formatter_->ProduceOutput(mix_buf_.get(),
+ cur_mix_job_.buf,
+ cur_mix_job_.buf_frames);
+
mixed = true;
} while (FinishMixJob(cur_mix_job_));
}
@@ -119,7 +138,9 @@ MediaResult StandardOutputBase::InitializeLink(
if (!track) { return MediaResult::INVALID_ARGUMENT; }
// Pick a mixer based on the input and output formats.
- bk->mixer = Mixer::Select(track->Format(), output_format_);
+ bk->mixer = Mixer::Select(track->Format(), output_formatter_
+ ? &output_formatter_->format()
+ : nullptr);
if (bk->mixer == nullptr) { return MediaResult::UNSUPPORTED_CONFIG; }
// Looks like things went well. Stash a reference to our bookkeeping and get
@@ -132,6 +153,16 @@ StandardOutputBase::TrackBookkeeping* StandardOutputBase::AllocBookkeeping() {
return new TrackBookkeeping();
}
+void StandardOutputBase::SetupMixBuffer(uint32_t max_mix_frames) {
+ DCHECK_GT(output_formatter_->channels(), 0u);
+ DCHECK_GT(max_mix_frames, 0u);
+ DCHECK_LE(max_mix_frames, std::numeric_limits<uint32_t>::max() /
+ output_formatter_->channels());
+
+ mix_buf_frames_ = max_mix_frames;
+ mix_buf_.reset(new int32_t[mix_buf_frames_ * output_formatter_->channels()]);
+}
+
void StandardOutputBase::ForeachTrack(const TrackSetupTask& setup,
const TrackProcessTask& process) {
for (auto iter = links_.begin(); iter != links_.end(); ) {
@@ -218,7 +249,6 @@ bool StandardOutputBase::ProcessMix(
DCHECK(packet);
// We had better have a valid job, or why are we here?
- DCHECK(cur_mix_job_.buf);
DCHECK(cur_mix_job_.buf_frames);
DCHECK(cur_mix_job_.frames_produced <= cur_mix_job_.buf_frames);
@@ -241,8 +271,8 @@ bool StandardOutputBase::ProcessMix(
}
uint32_t frames_left = cur_mix_job_.buf_frames - cur_mix_job_.frames_produced;
- void* buf = static_cast<uint8_t*>(cur_mix_job_.buf)
- + (cur_mix_job_.frames_produced * output_bytes_per_frame_);
+ int32_t* buf = mix_buf_.get()
+ + (cur_mix_job_.frames_produced * output_formatter_->channels());
// Figure out where the first and last sampling points of this job are,
// expressed in fractional track frames.

Powered by Google App Engine
This is Rietveld 408576698