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

Unified Diff: media/audio/audio_output_mixer.cc

Issue 10154007: Change the way audio mixer gets "pending bytes" (amount of data currently buffered (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 8 years, 8 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 | « media/audio/audio_output_mixer.h ('k') | media/audio/audio_output_proxy_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/audio/audio_output_mixer.cc
===================================================================
--- media/audio/audio_output_mixer.cc (revision 133745)
+++ media/audio/audio_output_mixer.cc (working copy)
@@ -5,6 +5,7 @@
#include "media/audio/audio_output_mixer.h"
#include <algorithm>
+#include <utility>
#include "base/bind.h"
#include "base/compiler_specific.h"
@@ -44,6 +45,7 @@
stream->Close();
return false;
}
+ buffer_data_.clear(); // Just in case.
physical_stream_.reset(stream);
close_timer_.Reset();
return true;
@@ -69,6 +71,7 @@
proxy_data->audio_source_callback = callback;
proxy_data->volume = volume;
proxy_data->pending_bytes = 0;
+ proxy_data->prebuffering = true;
}
// We cannot start physical stream under the lock,
// OnMoreData() would try acquiring it...
@@ -96,8 +99,10 @@
}
}
if (physical_stream_.get()) {
- if (stop_physical_stream)
+ if (stop_physical_stream) {
physical_stream_->Stop();
+ buffer_data_.clear(); // Just in case.
+ }
close_timer_.Reset();
}
}
@@ -155,6 +160,15 @@
// at the end. That would speed things up but complicate stopping
// the stream.
base::AutoLock lock(lock_);
+
+ // Did we see this buffer before?
vrk (LEFT CHROMIUM) 2012/04/26 00:54:57 For linux, I believe we will always have a unique
+ // If so, get lengths of released data, and delete buffer from the buffer map.
+ int bytes_released = 0;
+ BufferMap::iterator it = buffer_data_.find(dest);
+ if (it != buffer_data_.end()) {
+ bytes_released = it->second.length;
+ buffer_data_.erase(it);
+ }
if (proxies_.empty())
return 0;
uint32 actual_total_size = 0;
@@ -169,37 +183,36 @@
uint8* actual_dest = dest;
for (ProxyMap::iterator it = proxies_.begin(); it != proxies_.end(); ++it) {
ProxyData* proxy_data = &it->second;
- // TODO(enal): We don't know |pending _bytes| for individual stream, and we
- // should give that value to individual stream's OnMoreData(). I believe it
- // can be used there to evaluate exact position of data it should return.
- // Current code "sorta works" if everything works perfectly, but would have
- // problems if some of the buffers are only partially filled -- we don't
- // know how how much data was in the buffer OS returned to us, so we cannot
- // correctly calculate new value. If we know number of buffers we can solve
- // the problem by storing not one value but vector of them.
- int pending_bytes = std::min(proxy_data->pending_bytes,
- buffers_state.pending_bytes);
+
+ // Handle prebuffering:
+ // * If we already saw this buffer for this proxy, prebuffering is done,
+ // proxy now is in the steady state.
+ // * Otherwise add buffer to the set for this proxy.
+ if (proxy_data->prebuffering) {
+ std::set<void*>::iterator it = proxy_data->buffers.find(dest);
+ if (it != proxy_data->buffers.end()) {
+ // Release memory used by set, we don't need it anymore.
+ std::set<void*> empty;
+ empty.swap(proxy_data->buffers);
+ proxy_data->prebuffering = false;
+ } else {
+ proxy_data->buffers.insert(dest);
+ }
+ }
+ if (!proxy_data->prebuffering) {
+ proxy_data->pending_bytes -= bytes_released;
+ DCHECK_GE(proxy_data->pending_bytes, 0);
+ }
+
// Note: there is no way we can deduce hardware_delay_bytes for the
// particular proxy stream. Use zero instead.
uint32 actual_size = proxy_data->audio_source_callback->OnMoreData(
actual_dest,
max_size,
- AudioBuffersState(pending_bytes, 0));
-
- // Should update pending_bytes for each proxy.
- // If stream ended, pending_bytes goes down by max_size.
- if (actual_size == 0) {
- pending_bytes -= max_size;
- proxy_data->pending_bytes = std::max(pending_bytes, 0);
+ AudioBuffersState(proxy_data->pending_bytes, 0));
+ if (actual_size == 0)
continue;
- }
- // Otherwise, it goes up by amount of data. It cannot exceed max amount of
- // data we can buffer, but we don't know that value. So we increment
- // pending_bytes unconditionally but adjust it before actual use (which
- // would be on a next OnMoreData() call).
- proxy_data->pending_bytes = pending_bytes + actual_size;
-
// No need to mix muted stream.
double volume = proxy_data->volume;
if (volume == 0.0)
@@ -228,6 +241,17 @@
actual_total_size = std::max(actual_size, actual_total_size);
}
}
+
+ // Now go through all proxies once again and increase pending_bytes
+ // for each proxy. Could not do it earlier because we did not know
+ // actual_total_size.
+ for (ProxyMap::iterator it = proxies_.begin(); it != proxies_.end(); ++it) {
+ it->second.pending_bytes += actual_total_size;
+ }
+
+ buffer_data_.insert(
+ std::pair<void*, BufferData>(dest, BufferData(actual_total_size)));
+ DCHECK_LE(buffer_data_.size(), 5u);
return actual_total_size;
}
« no previous file with comments | « media/audio/audio_output_mixer.h ('k') | media/audio/audio_output_proxy_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698