summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorcrogers@google.com <crogers@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-31 05:16:49 +0000
committercrogers@google.com <crogers@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-31 05:16:49 +0000
commit25c6f51153579b0e8c45c0a94670866d1da09be0 (patch)
tree3543758dbf62c3d0ec1e0bf0059c14c79948dd04 /media
parenta00a2e3f25769148ef514adf02597a97fc6e7552 (diff)
downloadchromium_src-25c6f51153579b0e8c45c0a94670866d1da09be0.zip
chromium_src-25c6f51153579b0e8c45c0a94670866d1da09be0.tar.gz
chromium_src-25c6f51153579b0e8c45c0a94670866d1da09be0.tar.bz2
Support sending MIDI data with throttling
The Web MIDI API allows sending of MIDI data, but we need to take care to not send too much data from the renderer to the browser. We implement a throttling mechanism where the browser process acknowledges the number of sent bytes back to the renderer, and the renderer only sends new data if it hasn't already sent too much unacknowledged data. BUG=163795 TEST=none Review URL: https://chromiumcodereview.appspot.com/19612004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@214570 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/midi/midi_manager.cc25
-rw-r--r--media/midi/midi_manager.h35
-rw-r--r--media/midi/midi_manager_mac.cc8
-rw-r--r--media/midi/midi_manager_mac.h3
4 files changed, 61 insertions, 10 deletions
diff --git a/media/midi/midi_manager.cc b/media/midi/midi_manager.cc
index 3f74477..05fcfa4 100644
--- a/media/midi/midi_manager.cc
+++ b/media/midi/midi_manager.cc
@@ -4,6 +4,10 @@
#include "media/midi/midi_manager.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/threading/thread.h"
+
namespace media {
#if !defined(OS_MACOSX)
@@ -54,9 +58,26 @@ void MIDIManager::ReceiveMIDIData(
double timestamp) {
base::AutoLock auto_lock(clients_lock_);
- // TODO(crogers): Filter out sysex.
for (ClientList::iterator i = clients_.begin(); i != clients_.end(); ++i)
(*i)->ReceiveMIDIData(port_index, data, length, timestamp);
-};
+}
+
+void MIDIManager::DispatchSendMIDIData(MIDIManagerClient* client,
+ int port_index,
+ const uint8* data,
+ size_t length,
+ double timestamp) {
+ // Lazily create the thread when first needed.
+ if (!send_thread_) {
+ send_thread_.reset(new base::Thread("MIDISendThread"));
+ send_thread_->Start();
+ send_message_loop_ = send_thread_->message_loop_proxy();
+ }
+
+ send_message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&MIDIManager::SendMIDIData, base::Unretained(this),
+ client, port_index, data, length, timestamp));
+}
} // namespace media
diff --git a/media/midi/midi_manager.h b/media/midi/midi_manager.h
index e13b2c3..c2b26ab 100644
--- a/media/midi/midi_manager.h
+++ b/media/midi/midi_manager.h
@@ -8,10 +8,16 @@
#include <set>
#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop_proxy.h"
#include "base/synchronization/lock.h"
#include "media/base/media_export.h"
#include "media/midi/midi_port_info.h"
+namespace base {
+class Thread;
+}
+
namespace media {
// A MIDIManagerClient registers with the MIDIManager to receive MIDI data.
@@ -31,6 +37,12 @@ class MEDIA_EXPORT MIDIManagerClient {
const uint8* data,
size_t length,
double timestamp) = 0;
+
+ // AccumulateMIDIBytesSent() is called to acknowledge when bytes have
+ // successfully been sent to the hardware.
+ // This happens as a result of the client having previously called
+ // MIDIManager::DispatchSendMIDIData().
+ virtual void AccumulateMIDIBytesSent(size_t n) = 0;
};
// Manages access to all MIDI hardware.
@@ -50,15 +62,18 @@ class MEDIA_EXPORT MIDIManager {
// A client calls ReleaseSession() to stop receiving MIDI data.
void EndSession(MIDIManagerClient* client);
- // SendMIDIData() sends one or more messages at the given time.
+ // DispatchSendMIDIData() schedules one or more messages to be sent
+ // at the given time on a dedicated thread.
// |port_index| represents the specific output port from output_ports().
// |data| represents a series of bytes encoding one or more MIDI messages.
// |length| is the number of bytes in |data|.
- // |timestamp| is the time to send the data, in seconds.
- virtual void SendMIDIData(int port_index,
+ // |timestamp| is the time to send the data, in seconds. A value of 0
+ // means send "now" or as soon as possible.
+ void DispatchSendMIDIData(MIDIManagerClient* client,
+ int port_index,
const uint8* data,
size_t length,
- double timestamp) = 0;
+ double timestamp);
// input_ports() is a list of MIDI ports for receiving MIDI data.
// Each individual port in this list can be identified by its
@@ -74,6 +89,13 @@ class MEDIA_EXPORT MIDIManager {
// Initializes the MIDI system, returning |true| on success.
virtual bool Initialize() = 0;
+ // Implements the platform-specific details of sending MIDI data.
+ virtual void SendMIDIData(MIDIManagerClient* client,
+ int port_index,
+ const uint8* data,
+ size_t length,
+ double timestamp) = 0;
+
void AddInputPort(const MIDIPortInfo& info);
void AddOutputPort(const MIDIPortInfo& info);
@@ -96,6 +118,11 @@ class MEDIA_EXPORT MIDIManager {
MIDIPortInfoList input_ports_;
MIDIPortInfoList output_ports_;
+ // |send_thread_| is used to send MIDI data by calling the platform-specific
+ // API.
+ scoped_ptr<base::Thread> send_thread_;
+ scoped_refptr<base::MessageLoopProxy> send_message_loop_;
+
DISALLOW_COPY_AND_ASSIGN(MIDIManager);
};
diff --git a/media/midi/midi_manager_mac.cc b/media/midi/midi_manager_mac.cc
index fa4b3fd..d766bdb 100644
--- a/media/midi/midi_manager_mac.cc
+++ b/media/midi/midi_manager_mac.cc
@@ -146,12 +146,12 @@ void MIDIManagerMac::ReadMidi(MIDIEndpointRef source,
}
}
-void MIDIManagerMac::SendMIDIData(int port_index,
+void MIDIManagerMac::SendMIDIData(MIDIManagerClient* client,
+ int port_index,
const uint8* data,
size_t length,
double timestamp) {
- // TODO(crogers): Filter out sysex.
-
+ // System Exclusive has already been filtered.
MIDITimeStamp coremidi_timestamp = SecondsToMIDITimeStamp(timestamp);
midi_packet_ = MIDIPacketListAdd(
@@ -175,6 +175,8 @@ void MIDIManagerMac::SendMIDIData(int port_index,
// Re-initialize for next time.
midi_packet_ = MIDIPacketListInit(packet_list_);
+
+ client->AccumulateMIDIBytesSent(length);
}
MIDIPortInfo MIDIManagerMac::GetPortInfoFromEndpoint(
diff --git a/media/midi/midi_manager_mac.h b/media/midi/midi_manager_mac.h
index f513e11..ed7b524 100644
--- a/media/midi/midi_manager_mac.h
+++ b/media/midi/midi_manager_mac.h
@@ -23,7 +23,8 @@ class MEDIA_EXPORT MIDIManagerMac : public MIDIManager {
// MIDIManager implementation.
virtual bool Initialize() OVERRIDE;
- virtual void SendMIDIData(int port_index,
+ virtual void SendMIDIData(MIDIManagerClient* client,
+ int port_index,
const uint8* data,
size_t length,
double timestamp) OVERRIDE;