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

Unified Diff: content/renderer/media/audio_renderer_impl.h

Issue 9347029: Decouple 'give me more data' and 'rendered end of stream' audio callbacks. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 8 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 side-by-side diff with in-line comments
Download patch
Index: content/renderer/media/audio_renderer_impl.h
===================================================================
--- content/renderer/media/audio_renderer_impl.h (revision 122285)
+++ content/renderer/media/audio_renderer_impl.h (working copy)
@@ -19,9 +19,14 @@
#include <vector>
+#include "base/callback.h"
+#include "base/cancelable_callback.h"
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/message_loop_proxy.h"
#include "base/synchronization/lock.h"
+#include "base/time.h"
#include "content/renderer/media/audio_device.h"
#include "media/audio/audio_io.h"
#include "media/audio/audio_parameters.h"
@@ -32,6 +37,7 @@
class CONTENT_EXPORT AudioRendererImpl
: public media::AudioRendererBase,
+ NON_EXPORTED_BASE(public base::SupportsWeakPtr<AudioRendererImpl>),
NON_EXPORTED_BASE(public media::AudioRendererSink::RenderCallback) {
public:
// Methods called on Render thread ------------------------------------------
@@ -67,6 +73,17 @@
FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest,
DestroyedMessageLoop_ConsumeAudioSamples);
FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest, UpdateEarliestEndTime);
+
+ enum state { NOT_PLAYING, PLAYING, ENDED_EVENT_SCHEDULED, STOPPED };
+
+ // Thread-safe accessor. Not necessary on all current platforms,
+ // state can be set to STOPPED only on the pipeline thread,
+ // but better to have it safe for the future.
+ bool stopped() {
+ base::AutoLock auto_lock(audio_renderer_impl_lock_);
+ return (state_ == STOPPED);
+ }
+
// Helper methods.
// Convert number of bytes to duration of time using information about the
// number of channels, sample rate and sample bits.
@@ -76,6 +93,12 @@
void DoPlay();
void DoPause();
void DoSeek();
+ void DoSignalEndOfStream();
+ // We cannot set pipeline message loop in the constructor/initializer because
+ // message loop is not created at that moment. So set it after it is created,
+ // in the DoPlay(). Also DCHECK() that all functions we are expecting to be
+ // called from the pipeline message loop are actually called from it.
+ void DoSetOrCheckMessageLoopProxy();
// media::AudioRendererSink::RenderCallback implementation.
virtual size_t Render(const std::vector<float*>& audio_data,
@@ -83,8 +106,20 @@
size_t audio_delay_milliseconds) OVERRIDE;
virtual void OnRenderError() OVERRIDE;
+ // Returns current message loop proxy.
+ // Made virtual so test can override -- tests use
+ // ChildProcess::current()->io_message_loop_proxy() instead of
+ // MessageLoop::current()->message_loop_proxy().
+ virtual base::MessageLoopProxy* current_message_loop_proxy() {
+ return MessageLoop::current()->message_loop_proxy();
+ }
+
+ // Returns delay in ms before call to OnRenderEndOfStream().
+ // Made virtual so test can override.
+ virtual int64 OnRenderEndOfStreamDelay();
+
// Accessors used by tests.
- base::Time earliest_end_time() const {
+ base::Time earliest_end_time() {
return earliest_end_time_;
}
@@ -101,11 +136,14 @@
base::TimeDelta request_delay,
base::Time time_now);
+ // Lock protecting data that can be accessed form pipeline and audio threads.
+ base::Lock audio_renderer_impl_lock_;
+
// Used to calculate audio delay given bytes.
uint32 bytes_per_second_;
- // A flag that indicates this filter is called to stop.
- bool stopped_;
+ // Current state.
+ state state_;
// The sink (destination) for rendered audio.
scoped_refptr<media::AudioRendererSink> sink_;
@@ -127,10 +165,22 @@
// empty till that time. Workaround is not bulletproof, as we don't exactly
// know when that particular data would start playing, but it is much better
// than nothing.
+ // Access should be protected by lock as it can be accessed by pipeline and
+ // audio threads.
base::Time earliest_end_time_;
AudioParameters audio_parameters_;
+ // Use message loop proxy, not message loop itself, to avoid crash
+ // because of message loop that ended while we are still playing.
+ // We don't need complex shutdown operations, just not posting tasks
+ // is enough, so we can use message loop proxy.
+ scoped_refptr<base::MessageLoopProxy> pipeline_message_loop_proxy_;
+
+ // Cancellable closure called on end of stream.
+ // We may schedule the task but later cancel it on seek / pause.
+ base::CancelableClosure signal_end_of_stream_callback_;
+
DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl);
};
« no previous file with comments | « no previous file | content/renderer/media/audio_renderer_impl.cc » ('j') | content/renderer/media/audio_renderer_impl.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698