Mojom updates for Motown.
New mojom files for Motown (mojo/services/media), updates to existing
mojom files, and updates to various c++ files as required. The code to
implement these new interfaces will be submitted in a subsequent CL.

R=johngro@google.com

Review URL: https://codereview.chromium.org/1509323002 .
diff --git a/mojo/dart/packages/mojo_services/lib/mojo/media/audio_server.mojom.dart b/mojo/dart/packages/mojo_services/lib/mojo/media/audio_server.mojom.dart
new file mode 100644
index 0000000..662ccab
--- /dev/null
+++ b/mojo/dart/packages/mojo_services/lib/mojo/media/audio_server.mojom.dart
@@ -0,0 +1,248 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library audio_server_mojom;
+
+import 'dart:async';
+
+import 'package:mojo/bindings.dart' as bindings;
+import 'package:mojo/core.dart' as core;
+import 'package:mojo_services/mojo/media/audio_track.mojom.dart' as audio_track_mojom;
+
+
+
+class _AudioServerCreateTrackParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  Object track = null;
+
+  _AudioServerCreateTrackParams() : super(kVersions.last.size);
+
+  static _AudioServerCreateTrackParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _AudioServerCreateTrackParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _AudioServerCreateTrackParams result = new _AudioServerCreateTrackParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.track = decoder0.decodeInterfaceRequest(8, false, audio_track_mojom.AudioTrackStub.newFromEndpoint);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeInterfaceRequest(track, 8, false);
+  }
+
+  String toString() {
+    return "_AudioServerCreateTrackParams("
+           "track: $track" ")";
+  }
+
+  Map toJson() {
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
+  }
+}
+
+const int _AudioServer_createTrackName = 0;
+
+abstract class AudioServer {
+  static const String serviceName = "mojo::media::AudioServer";
+  void createTrack(Object track);
+}
+
+
+class _AudioServerProxyImpl extends bindings.Proxy {
+  _AudioServerProxyImpl.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
+
+  _AudioServerProxyImpl.fromHandle(core.MojoHandle handle) :
+      super.fromHandle(handle);
+
+  _AudioServerProxyImpl.unbound() : super.unbound();
+
+  static _AudioServerProxyImpl newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For _AudioServerProxyImpl"));
+    return new _AudioServerProxyImpl.fromEndpoint(endpoint);
+  }
+
+  void handleResponse(bindings.ServiceMessage message) {
+    switch (message.header.type) {
+      default:
+        proxyError("Unexpected message type: ${message.header.type}");
+        close(immediate: true);
+        break;
+    }
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "_AudioServerProxyImpl($superString)";
+  }
+}
+
+
+class _AudioServerProxyCalls implements AudioServer {
+  _AudioServerProxyImpl _proxyImpl;
+
+  _AudioServerProxyCalls(this._proxyImpl);
+    void createTrack(Object track) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _AudioServerCreateTrackParams();
+      params.track = track;
+      _proxyImpl.sendMessage(params, _AudioServer_createTrackName);
+    }
+}
+
+
+class AudioServerProxy implements bindings.ProxyBase {
+  final bindings.Proxy impl;
+  AudioServer ptr;
+
+  AudioServerProxy(_AudioServerProxyImpl proxyImpl) :
+      impl = proxyImpl,
+      ptr = new _AudioServerProxyCalls(proxyImpl);
+
+  AudioServerProxy.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) :
+      impl = new _AudioServerProxyImpl.fromEndpoint(endpoint) {
+    ptr = new _AudioServerProxyCalls(impl);
+  }
+
+  AudioServerProxy.fromHandle(core.MojoHandle handle) :
+      impl = new _AudioServerProxyImpl.fromHandle(handle) {
+    ptr = new _AudioServerProxyCalls(impl);
+  }
+
+  AudioServerProxy.unbound() :
+      impl = new _AudioServerProxyImpl.unbound() {
+    ptr = new _AudioServerProxyCalls(impl);
+  }
+
+  factory AudioServerProxy.connectToService(
+      bindings.ServiceConnector s, String url, [String serviceName]) {
+    AudioServerProxy p = new AudioServerProxy.unbound();
+    s.connectToService(url, p, serviceName);
+    return p;
+  }
+
+  static AudioServerProxy newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For AudioServerProxy"));
+    return new AudioServerProxy.fromEndpoint(endpoint);
+  }
+
+  String get serviceName => AudioServer.serviceName;
+
+  Future close({bool immediate: false}) => impl.close(immediate: immediate);
+
+  Future responseOrError(Future f) => impl.responseOrError(f);
+
+  Future get errorFuture => impl.errorFuture;
+
+  int get version => impl.version;
+
+  Future<int> queryVersion() => impl.queryVersion();
+
+  void requireVersion(int requiredVersion) {
+    impl.requireVersion(requiredVersion);
+  }
+
+  String toString() {
+    return "AudioServerProxy($impl)";
+  }
+}
+
+
+class AudioServerStub extends bindings.Stub {
+  AudioServer _impl = null;
+
+  AudioServerStub.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint, [this._impl])
+      : super.fromEndpoint(endpoint);
+
+  AudioServerStub.fromHandle(core.MojoHandle handle, [this._impl])
+      : super.fromHandle(handle);
+
+  AudioServerStub.unbound() : super.unbound();
+
+  static AudioServerStub newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For AudioServerStub"));
+    return new AudioServerStub.fromEndpoint(endpoint);
+  }
+
+
+
+  dynamic handleMessage(bindings.ServiceMessage message) {
+    if (bindings.ControlMessageHandler.isControlMessage(message)) {
+      return bindings.ControlMessageHandler.handleMessage(this,
+                                                          0,
+                                                          message);
+    }
+    assert(_impl != null);
+    switch (message.header.type) {
+      case _AudioServer_createTrackName:
+        var params = _AudioServerCreateTrackParams.deserialize(
+            message.payload);
+        _impl.createTrack(params.track);
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+    return null;
+  }
+
+  AudioServer get impl => _impl;
+  set impl(AudioServer d) {
+    assert(_impl == null);
+    _impl = d;
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "AudioServerStub($superString)";
+  }
+
+  int get version => 0;
+}
+
+
diff --git a/mojo/dart/packages/mojo_services/lib/mojo/media/audio_track.mojom.dart b/mojo/dart/packages/mojo_services/lib/mojo/media/audio_track.mojom.dart
new file mode 100644
index 0000000..d777e29
--- /dev/null
+++ b/mojo/dart/packages/mojo_services/lib/mojo/media/audio_track.mojom.dart
@@ -0,0 +1,931 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library audio_track_mojom;
+
+import 'dart:async';
+
+import 'package:mojo/bindings.dart' as bindings;
+import 'package:mojo/core.dart' as core;
+import 'package:mojo_services/mojo/media/media_common.mojom.dart' as media_common_mojom;
+import 'package:mojo_services/mojo/media/media_pipe.mojom.dart' as media_pipe_mojom;
+import 'package:mojo_services/mojo/media/media_types.mojom.dart' as media_types_mojom;
+import 'package:mojo_services/mojo/media/rate_control.mojom.dart' as rate_control_mojom;
+
+
+
+class AudioTrackDescriptor extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  List<media_types_mojom.MediaTypeSet> supportedMediaTypes = null;
+
+  AudioTrackDescriptor() : super(kVersions.last.size);
+
+  static AudioTrackDescriptor deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static AudioTrackDescriptor decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    AudioTrackDescriptor result = new AudioTrackDescriptor();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(8, false);
+      {
+        var si1 = decoder1.decodeDataHeaderForPointerArray(bindings.kUnspecifiedArrayLength);
+        result.supportedMediaTypes = new List<media_types_mojom.MediaTypeSet>(si1.numElements);
+        for (int i1 = 0; i1 < si1.numElements; ++i1) {
+          
+          var decoder2 = decoder1.decodePointer(bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i1, false);
+          result.supportedMediaTypes[i1] = media_types_mojom.MediaTypeSet.decode(decoder2);
+        }
+      }
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    if (supportedMediaTypes == null) {
+      encoder0.encodeNullPointer(8, false);
+    } else {
+      var encoder1 = encoder0.encodePointerArray(supportedMediaTypes.length, 8, bindings.kUnspecifiedArrayLength);
+      for (int i0 = 0; i0 < supportedMediaTypes.length; ++i0) {
+        
+        encoder1.encodeStruct(supportedMediaTypes[i0], bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i0, false);
+      }
+    }
+  }
+
+  String toString() {
+    return "AudioTrackDescriptor("
+           "supportedMediaTypes: $supportedMediaTypes" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["supportedMediaTypes"] = supportedMediaTypes;
+    return map;
+  }
+}
+
+
+class AudioTrackConfiguration extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(32, 0)
+  ];
+  media_types_mojom.MediaType mediaType = null;
+  int maxFrames = 0;
+  int audioFrameRatio = 1;
+  int mediaTimeRatio = 1;
+
+  AudioTrackConfiguration() : super(kVersions.last.size);
+
+  static AudioTrackConfiguration deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static AudioTrackConfiguration decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    AudioTrackConfiguration result = new AudioTrackConfiguration();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(8, false);
+      result.mediaType = media_types_mojom.MediaType.decode(decoder1);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.maxFrames = decoder0.decodeUint64(16);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.audioFrameRatio = decoder0.decodeUint32(24);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.mediaTimeRatio = decoder0.decodeUint32(28);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeStruct(mediaType, 8, false);
+    
+    encoder0.encodeUint64(maxFrames, 16);
+    
+    encoder0.encodeUint32(audioFrameRatio, 24);
+    
+    encoder0.encodeUint32(mediaTimeRatio, 28);
+  }
+
+  String toString() {
+    return "AudioTrackConfiguration("
+           "mediaType: $mediaType" ", "
+           "maxFrames: $maxFrames" ", "
+           "audioFrameRatio: $audioFrameRatio" ", "
+           "mediaTimeRatio: $mediaTimeRatio" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["mediaType"] = mediaType;
+    map["maxFrames"] = maxFrames;
+    map["audioFrameRatio"] = audioFrameRatio;
+    map["mediaTimeRatio"] = mediaTimeRatio;
+    return map;
+  }
+}
+
+
+class _AudioTrackDescribeParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  _AudioTrackDescribeParams() : super(kVersions.last.size);
+
+  static _AudioTrackDescribeParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _AudioTrackDescribeParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _AudioTrackDescribeParams result = new _AudioTrackDescribeParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "_AudioTrackDescribeParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+class AudioTrackDescribeResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  AudioTrackDescriptor descriptor = null;
+
+  AudioTrackDescribeResponseParams() : super(kVersions.last.size);
+
+  static AudioTrackDescribeResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static AudioTrackDescribeResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    AudioTrackDescribeResponseParams result = new AudioTrackDescribeResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(8, false);
+      result.descriptor = AudioTrackDescriptor.decode(decoder1);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeStruct(descriptor, 8, false);
+  }
+
+  String toString() {
+    return "AudioTrackDescribeResponseParams("
+           "descriptor: $descriptor" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["descriptor"] = descriptor;
+    return map;
+  }
+}
+
+
+class _AudioTrackConfigureParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  AudioTrackConfiguration configuration = null;
+  Object pipe = null;
+
+  _AudioTrackConfigureParams() : super(kVersions.last.size);
+
+  static _AudioTrackConfigureParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _AudioTrackConfigureParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _AudioTrackConfigureParams result = new _AudioTrackConfigureParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(8, false);
+      result.configuration = AudioTrackConfiguration.decode(decoder1);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.pipe = decoder0.decodeInterfaceRequest(16, false, media_pipe_mojom.MediaPipeStub.newFromEndpoint);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeStruct(configuration, 8, false);
+    
+    encoder0.encodeInterfaceRequest(pipe, 16, false);
+  }
+
+  String toString() {
+    return "_AudioTrackConfigureParams("
+           "configuration: $configuration" ", "
+           "pipe: $pipe" ")";
+  }
+
+  Map toJson() {
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
+  }
+}
+
+
+class AudioTrackConfigureResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  media_common_mojom.MediaResult result = null;
+
+  AudioTrackConfigureResponseParams() : super(kVersions.last.size);
+
+  static AudioTrackConfigureResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static AudioTrackConfigureResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    AudioTrackConfigureResponseParams result = new AudioTrackConfigureResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.result = media_common_mojom.MediaResult.decode(decoder0, 8);
+        if (result.result == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable media_common_mojom.MediaResult.');
+        }
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeEnum(result, 8);
+  }
+
+  String toString() {
+    return "AudioTrackConfigureResponseParams("
+           "result: $result" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["result"] = result;
+    return map;
+  }
+}
+
+
+class _AudioTrackGetRateControlParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  Object rateControl = null;
+
+  _AudioTrackGetRateControlParams() : super(kVersions.last.size);
+
+  static _AudioTrackGetRateControlParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _AudioTrackGetRateControlParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _AudioTrackGetRateControlParams result = new _AudioTrackGetRateControlParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.rateControl = decoder0.decodeInterfaceRequest(8, false, rate_control_mojom.RateControlStub.newFromEndpoint);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeInterfaceRequest(rateControl, 8, false);
+  }
+
+  String toString() {
+    return "_AudioTrackGetRateControlParams("
+           "rateControl: $rateControl" ")";
+  }
+
+  Map toJson() {
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
+  }
+}
+
+
+class AudioTrackGetRateControlResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  media_common_mojom.MediaResult result = null;
+
+  AudioTrackGetRateControlResponseParams() : super(kVersions.last.size);
+
+  static AudioTrackGetRateControlResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static AudioTrackGetRateControlResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    AudioTrackGetRateControlResponseParams result = new AudioTrackGetRateControlResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.result = media_common_mojom.MediaResult.decode(decoder0, 8);
+        if (result.result == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable media_common_mojom.MediaResult.');
+        }
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeEnum(result, 8);
+  }
+
+  String toString() {
+    return "AudioTrackGetRateControlResponseParams("
+           "result: $result" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["result"] = result;
+    return map;
+  }
+}
+
+const int _AudioTrack_describeName = 0;
+const int _AudioTrack_configureName = 1;
+const int _AudioTrack_getRateControlName = 2;
+
+abstract class AudioTrack {
+  static const String serviceName = null;
+  dynamic describe([Function responseFactory = null]);
+  dynamic configure(AudioTrackConfiguration configuration,Object pipe,[Function responseFactory = null]);
+  dynamic getRateControl(Object rateControl,[Function responseFactory = null]);
+}
+
+
+class _AudioTrackProxyImpl extends bindings.Proxy {
+  _AudioTrackProxyImpl.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
+
+  _AudioTrackProxyImpl.fromHandle(core.MojoHandle handle) :
+      super.fromHandle(handle);
+
+  _AudioTrackProxyImpl.unbound() : super.unbound();
+
+  static _AudioTrackProxyImpl newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For _AudioTrackProxyImpl"));
+    return new _AudioTrackProxyImpl.fromEndpoint(endpoint);
+  }
+
+  void handleResponse(bindings.ServiceMessage message) {
+    switch (message.header.type) {
+      case _AudioTrack_describeName:
+        var r = AudioTrackDescribeResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      case _AudioTrack_configureName:
+        var r = AudioTrackConfigureResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      case _AudioTrack_getRateControlName:
+        var r = AudioTrackGetRateControlResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      default:
+        proxyError("Unexpected message type: ${message.header.type}");
+        close(immediate: true);
+        break;
+    }
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "_AudioTrackProxyImpl($superString)";
+  }
+}
+
+
+class _AudioTrackProxyCalls implements AudioTrack {
+  _AudioTrackProxyImpl _proxyImpl;
+
+  _AudioTrackProxyCalls(this._proxyImpl);
+    dynamic describe([Function responseFactory = null]) {
+      var params = new _AudioTrackDescribeParams();
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _AudioTrack_describeName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    dynamic configure(AudioTrackConfiguration configuration,Object pipe,[Function responseFactory = null]) {
+      var params = new _AudioTrackConfigureParams();
+      params.configuration = configuration;
+      params.pipe = pipe;
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _AudioTrack_configureName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    dynamic getRateControl(Object rateControl,[Function responseFactory = null]) {
+      var params = new _AudioTrackGetRateControlParams();
+      params.rateControl = rateControl;
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _AudioTrack_getRateControlName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+}
+
+
+class AudioTrackProxy implements bindings.ProxyBase {
+  final bindings.Proxy impl;
+  AudioTrack ptr;
+
+  AudioTrackProxy(_AudioTrackProxyImpl proxyImpl) :
+      impl = proxyImpl,
+      ptr = new _AudioTrackProxyCalls(proxyImpl);
+
+  AudioTrackProxy.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) :
+      impl = new _AudioTrackProxyImpl.fromEndpoint(endpoint) {
+    ptr = new _AudioTrackProxyCalls(impl);
+  }
+
+  AudioTrackProxy.fromHandle(core.MojoHandle handle) :
+      impl = new _AudioTrackProxyImpl.fromHandle(handle) {
+    ptr = new _AudioTrackProxyCalls(impl);
+  }
+
+  AudioTrackProxy.unbound() :
+      impl = new _AudioTrackProxyImpl.unbound() {
+    ptr = new _AudioTrackProxyCalls(impl);
+  }
+
+  factory AudioTrackProxy.connectToService(
+      bindings.ServiceConnector s, String url, [String serviceName]) {
+    AudioTrackProxy p = new AudioTrackProxy.unbound();
+    s.connectToService(url, p, serviceName);
+    return p;
+  }
+
+  static AudioTrackProxy newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For AudioTrackProxy"));
+    return new AudioTrackProxy.fromEndpoint(endpoint);
+  }
+
+  String get serviceName => AudioTrack.serviceName;
+
+  Future close({bool immediate: false}) => impl.close(immediate: immediate);
+
+  Future responseOrError(Future f) => impl.responseOrError(f);
+
+  Future get errorFuture => impl.errorFuture;
+
+  int get version => impl.version;
+
+  Future<int> queryVersion() => impl.queryVersion();
+
+  void requireVersion(int requiredVersion) {
+    impl.requireVersion(requiredVersion);
+  }
+
+  String toString() {
+    return "AudioTrackProxy($impl)";
+  }
+}
+
+
+class AudioTrackStub extends bindings.Stub {
+  AudioTrack _impl = null;
+
+  AudioTrackStub.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint, [this._impl])
+      : super.fromEndpoint(endpoint);
+
+  AudioTrackStub.fromHandle(core.MojoHandle handle, [this._impl])
+      : super.fromHandle(handle);
+
+  AudioTrackStub.unbound() : super.unbound();
+
+  static AudioTrackStub newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For AudioTrackStub"));
+    return new AudioTrackStub.fromEndpoint(endpoint);
+  }
+
+
+  AudioTrackDescribeResponseParams _AudioTrackDescribeResponseParamsFactory(AudioTrackDescriptor descriptor) {
+    var mojo_factory_result = new AudioTrackDescribeResponseParams();
+    mojo_factory_result.descriptor = descriptor;
+    return mojo_factory_result;
+  }
+  AudioTrackConfigureResponseParams _AudioTrackConfigureResponseParamsFactory(media_common_mojom.MediaResult result) {
+    var mojo_factory_result = new AudioTrackConfigureResponseParams();
+    mojo_factory_result.result = result;
+    return mojo_factory_result;
+  }
+  AudioTrackGetRateControlResponseParams _AudioTrackGetRateControlResponseParamsFactory(media_common_mojom.MediaResult result) {
+    var mojo_factory_result = new AudioTrackGetRateControlResponseParams();
+    mojo_factory_result.result = result;
+    return mojo_factory_result;
+  }
+
+  dynamic handleMessage(bindings.ServiceMessage message) {
+    if (bindings.ControlMessageHandler.isControlMessage(message)) {
+      return bindings.ControlMessageHandler.handleMessage(this,
+                                                          0,
+                                                          message);
+    }
+    assert(_impl != null);
+    switch (message.header.type) {
+      case _AudioTrack_describeName:
+        var params = _AudioTrackDescribeParams.deserialize(
+            message.payload);
+        var response = _impl.describe(_AudioTrackDescribeResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _AudioTrack_describeName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _AudioTrack_describeName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case _AudioTrack_configureName:
+        var params = _AudioTrackConfigureParams.deserialize(
+            message.payload);
+        var response = _impl.configure(params.configuration,params.pipe,_AudioTrackConfigureResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _AudioTrack_configureName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _AudioTrack_configureName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case _AudioTrack_getRateControlName:
+        var params = _AudioTrackGetRateControlParams.deserialize(
+            message.payload);
+        var response = _impl.getRateControl(params.rateControl,_AudioTrackGetRateControlResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _AudioTrack_getRateControlName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _AudioTrack_getRateControlName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+    return null;
+  }
+
+  AudioTrack get impl => _impl;
+  set impl(AudioTrack d) {
+    assert(_impl == null);
+    _impl = d;
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "AudioTrackStub($superString)";
+  }
+
+  int get version => 0;
+}
+
+
diff --git a/mojo/dart/packages/mojo_services/lib/mojo/media/media_clock.mojom.dart b/mojo/dart/packages/mojo_services/lib/mojo/media/media_clock.mojom.dart
new file mode 100644
index 0000000..ebc4634
--- /dev/null
+++ b/mojo/dart/packages/mojo_services/lib/mojo/media/media_clock.mojom.dart
@@ -0,0 +1,243 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library media_clock_mojom;
+
+import 'dart:async';
+
+import 'package:mojo/bindings.dart' as bindings;
+import 'package:mojo/core.dart' as core;
+
+class ClockDisposition extends bindings.MojoEnum {
+  static const ClockDisposition passive = const ClockDisposition._(0);
+  static const ClockDisposition slave = const ClockDisposition._(1);
+  static const ClockDisposition preferSlave = const ClockDisposition._(2);
+  static const ClockDisposition indifferent = const ClockDisposition._(3);
+  static const ClockDisposition preferMaster = const ClockDisposition._(4);
+  static const ClockDisposition master = const ClockDisposition._(5);
+
+  const ClockDisposition._(int v) : super(v);
+
+  static const Map<String, ClockDisposition> valuesMap = const {
+    "passive": passive,
+    "slave": slave,
+    "preferSlave": preferSlave,
+    "indifferent": indifferent,
+    "preferMaster": preferMaster,
+    "master": master,
+  };
+  static const List<ClockDisposition> values = const [
+    passive,
+    slave,
+    preferSlave,
+    indifferent,
+    preferMaster,
+    master,
+  ];
+
+  static ClockDisposition valueOf(String name) => valuesMap[name];
+
+  factory ClockDisposition(int v) {
+    switch (v) {
+      case 0:
+        return passive;
+      case 1:
+        return slave;
+      case 2:
+        return preferSlave;
+      case 3:
+        return indifferent;
+      case 4:
+        return preferMaster;
+      case 5:
+        return master;
+      default:
+        return null;
+    }
+  }
+
+  static ClockDisposition decode(bindings.Decoder decoder0, int offset) {
+    int v = decoder0.decodeUint32(offset);
+    ClockDisposition result = new ClockDisposition(v);
+    if (result == null) {
+      throw new bindings.MojoCodecError(
+          'Bad value $v for enum ClockDisposition.');
+    }
+    return result;
+  }
+
+  String toString() {
+    switch(this) {
+      case passive:
+        return 'ClockDisposition.passive';
+      case slave:
+        return 'ClockDisposition.slave';
+      case preferSlave:
+        return 'ClockDisposition.preferSlave';
+      case indifferent:
+        return 'ClockDisposition.indifferent';
+      case preferMaster:
+        return 'ClockDisposition.preferMaster';
+      case master:
+        return 'ClockDisposition.master';
+    }
+  }
+
+  int toJson() => mojoEnumValue;
+}
+
+
+
+abstract class Clock {
+  static const String serviceName = null;
+}
+
+
+class _ClockProxyImpl extends bindings.Proxy {
+  _ClockProxyImpl.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
+
+  _ClockProxyImpl.fromHandle(core.MojoHandle handle) :
+      super.fromHandle(handle);
+
+  _ClockProxyImpl.unbound() : super.unbound();
+
+  static _ClockProxyImpl newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For _ClockProxyImpl"));
+    return new _ClockProxyImpl.fromEndpoint(endpoint);
+  }
+
+  void handleResponse(bindings.ServiceMessage message) {
+    switch (message.header.type) {
+      default:
+        proxyError("Unexpected message type: ${message.header.type}");
+        close(immediate: true);
+        break;
+    }
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "_ClockProxyImpl($superString)";
+  }
+}
+
+
+class _ClockProxyCalls implements Clock {
+  _ClockProxyImpl _proxyImpl;
+
+  _ClockProxyCalls(this._proxyImpl);
+}
+
+
+class ClockProxy implements bindings.ProxyBase {
+  final bindings.Proxy impl;
+  Clock ptr;
+
+  ClockProxy(_ClockProxyImpl proxyImpl) :
+      impl = proxyImpl,
+      ptr = new _ClockProxyCalls(proxyImpl);
+
+  ClockProxy.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) :
+      impl = new _ClockProxyImpl.fromEndpoint(endpoint) {
+    ptr = new _ClockProxyCalls(impl);
+  }
+
+  ClockProxy.fromHandle(core.MojoHandle handle) :
+      impl = new _ClockProxyImpl.fromHandle(handle) {
+    ptr = new _ClockProxyCalls(impl);
+  }
+
+  ClockProxy.unbound() :
+      impl = new _ClockProxyImpl.unbound() {
+    ptr = new _ClockProxyCalls(impl);
+  }
+
+  factory ClockProxy.connectToService(
+      bindings.ServiceConnector s, String url, [String serviceName]) {
+    ClockProxy p = new ClockProxy.unbound();
+    s.connectToService(url, p, serviceName);
+    return p;
+  }
+
+  static ClockProxy newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For ClockProxy"));
+    return new ClockProxy.fromEndpoint(endpoint);
+  }
+
+  String get serviceName => Clock.serviceName;
+
+  Future close({bool immediate: false}) => impl.close(immediate: immediate);
+
+  Future responseOrError(Future f) => impl.responseOrError(f);
+
+  Future get errorFuture => impl.errorFuture;
+
+  int get version => impl.version;
+
+  Future<int> queryVersion() => impl.queryVersion();
+
+  void requireVersion(int requiredVersion) {
+    impl.requireVersion(requiredVersion);
+  }
+
+  String toString() {
+    return "ClockProxy($impl)";
+  }
+}
+
+
+class ClockStub extends bindings.Stub {
+  Clock _impl = null;
+
+  ClockStub.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint, [this._impl])
+      : super.fromEndpoint(endpoint);
+
+  ClockStub.fromHandle(core.MojoHandle handle, [this._impl])
+      : super.fromHandle(handle);
+
+  ClockStub.unbound() : super.unbound();
+
+  static ClockStub newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For ClockStub"));
+    return new ClockStub.fromEndpoint(endpoint);
+  }
+
+
+
+  dynamic handleMessage(bindings.ServiceMessage message) {
+    if (bindings.ControlMessageHandler.isControlMessage(message)) {
+      return bindings.ControlMessageHandler.handleMessage(this,
+                                                          0,
+                                                          message);
+    }
+    assert(_impl != null);
+    switch (message.header.type) {
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+    return null;
+  }
+
+  Clock get impl => _impl;
+  set impl(Clock d) {
+    assert(_impl == null);
+    _impl = d;
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "ClockStub($superString)";
+  }
+
+  int get version => 0;
+}
+
+
diff --git a/mojo/dart/packages/mojo_services/lib/mojo/media/media_common.mojom.dart b/mojo/dart/packages/mojo_services/lib/mojo/media/media_common.mojom.dart
new file mode 100644
index 0000000..2ecb6d1
--- /dev/null
+++ b/mojo/dart/packages/mojo_services/lib/mojo/media/media_common.mojom.dart
@@ -0,0 +1,161 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library media_common_mojom;
+
+import 'dart:async';
+
+import 'package:mojo/bindings.dart' as bindings;
+import 'package:mojo/core.dart' as core;
+
+class MediaResult extends bindings.MojoEnum {
+  static const MediaResult ok = const MediaResult._(0);
+  static const MediaResult unknownError = const MediaResult._(-1);
+  static const MediaResult internalError = const MediaResult._(-2);
+  static const MediaResult notImplemented = const MediaResult._(-3);
+  static const MediaResult unsupportedOperation = const MediaResult._(-4);
+  static const MediaResult unsupportedConfig = const MediaResult._(-5);
+  static const MediaResult invalidArgument = const MediaResult._(-6);
+  static const MediaResult insufficientResources = const MediaResult._(-7);
+  static const MediaResult badState = const MediaResult._(-8);
+  static const MediaResult bufOverflow = const MediaResult._(-9);
+  static const MediaResult flushed = const MediaResult._(-10);
+  static const MediaResult busy = const MediaResult._(-11);
+  static const MediaResult protocolError = const MediaResult._(-12);
+  static const MediaResult alreadyExists = const MediaResult._(-13);
+  static const MediaResult notFound = const MediaResult._(-14);
+  static const MediaResult shuttingDown = const MediaResult._(-15);
+
+  const MediaResult._(int v) : super(v);
+
+  static const Map<String, MediaResult> valuesMap = const {
+    "ok": ok,
+    "unknownError": unknownError,
+    "internalError": internalError,
+    "notImplemented": notImplemented,
+    "unsupportedOperation": unsupportedOperation,
+    "unsupportedConfig": unsupportedConfig,
+    "invalidArgument": invalidArgument,
+    "insufficientResources": insufficientResources,
+    "badState": badState,
+    "bufOverflow": bufOverflow,
+    "flushed": flushed,
+    "busy": busy,
+    "protocolError": protocolError,
+    "alreadyExists": alreadyExists,
+    "notFound": notFound,
+    "shuttingDown": shuttingDown,
+  };
+  static const List<MediaResult> values = const [
+    ok,
+    unknownError,
+    internalError,
+    notImplemented,
+    unsupportedOperation,
+    unsupportedConfig,
+    invalidArgument,
+    insufficientResources,
+    badState,
+    bufOverflow,
+    flushed,
+    busy,
+    protocolError,
+    alreadyExists,
+    notFound,
+    shuttingDown,
+  ];
+
+  static MediaResult valueOf(String name) => valuesMap[name];
+
+  factory MediaResult(int v) {
+    switch (v) {
+      case 0:
+        return ok;
+      case -1:
+        return unknownError;
+      case -2:
+        return internalError;
+      case -3:
+        return notImplemented;
+      case -4:
+        return unsupportedOperation;
+      case -5:
+        return unsupportedConfig;
+      case -6:
+        return invalidArgument;
+      case -7:
+        return insufficientResources;
+      case -8:
+        return badState;
+      case -9:
+        return bufOverflow;
+      case -10:
+        return flushed;
+      case -11:
+        return busy;
+      case -12:
+        return protocolError;
+      case -13:
+        return alreadyExists;
+      case -14:
+        return notFound;
+      case -15:
+        return shuttingDown;
+      default:
+        return null;
+    }
+  }
+
+  static MediaResult decode(bindings.Decoder decoder0, int offset) {
+    int v = decoder0.decodeUint32(offset);
+    MediaResult result = new MediaResult(v);
+    if (result == null) {
+      throw new bindings.MojoCodecError(
+          'Bad value $v for enum MediaResult.');
+    }
+    return result;
+  }
+
+  String toString() {
+    switch(this) {
+      case ok:
+        return 'MediaResult.ok';
+      case unknownError:
+        return 'MediaResult.unknownError';
+      case internalError:
+        return 'MediaResult.internalError';
+      case notImplemented:
+        return 'MediaResult.notImplemented';
+      case unsupportedOperation:
+        return 'MediaResult.unsupportedOperation';
+      case unsupportedConfig:
+        return 'MediaResult.unsupportedConfig';
+      case invalidArgument:
+        return 'MediaResult.invalidArgument';
+      case insufficientResources:
+        return 'MediaResult.insufficientResources';
+      case badState:
+        return 'MediaResult.badState';
+      case bufOverflow:
+        return 'MediaResult.bufOverflow';
+      case flushed:
+        return 'MediaResult.flushed';
+      case busy:
+        return 'MediaResult.busy';
+      case protocolError:
+        return 'MediaResult.protocolError';
+      case alreadyExists:
+        return 'MediaResult.alreadyExists';
+      case notFound:
+        return 'MediaResult.notFound';
+      case shuttingDown:
+        return 'MediaResult.shuttingDown';
+    }
+  }
+
+  int toJson() => mojoEnumValue;
+}
+
+
+
diff --git a/mojo/dart/packages/mojo_services/lib/mojo/media/media_factory.mojom.dart b/mojo/dart/packages/mojo_services/lib/mojo/media/media_factory.mojom.dart
new file mode 100644
index 0000000..7e26112
--- /dev/null
+++ b/mojo/dart/packages/mojo_services/lib/mojo/media/media_factory.mojom.dart
@@ -0,0 +1,480 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library media_factory_mojom;
+
+import 'dart:async';
+
+import 'package:mojo/bindings.dart' as bindings;
+import 'package:mojo/core.dart' as core;
+import 'package:mojo_services/mojo/media/media_types.mojom.dart' as media_types_mojom;
+import 'package:mojo_services/mojo/media/media_player.mojom.dart' as media_player_mojom;
+import 'package:mojo_services/mojo/media/media_sink.mojom.dart' as media_sink_mojom;
+import 'package:mojo_services/mojo/media/media_source.mojom.dart' as media_source_mojom;
+
+
+
+class _MediaFactoryCreatePlayerParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  String originUrl = null;
+  Object player = null;
+
+  _MediaFactoryCreatePlayerParams() : super(kVersions.last.size);
+
+  static _MediaFactoryCreatePlayerParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaFactoryCreatePlayerParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaFactoryCreatePlayerParams result = new _MediaFactoryCreatePlayerParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.originUrl = decoder0.decodeString(8, false);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.player = decoder0.decodeInterfaceRequest(16, false, media_player_mojom.MediaPlayerStub.newFromEndpoint);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeString(originUrl, 8, false);
+    
+    encoder0.encodeInterfaceRequest(player, 16, false);
+  }
+
+  String toString() {
+    return "_MediaFactoryCreatePlayerParams("
+           "originUrl: $originUrl" ", "
+           "player: $player" ")";
+  }
+
+  Map toJson() {
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
+  }
+}
+
+
+class _MediaFactoryCreateSourceParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(32, 0)
+  ];
+  String originUrl = null;
+  List<media_types_mojom.MediaTypeSet> allowedMediaTypes = null;
+  Object source = null;
+
+  _MediaFactoryCreateSourceParams() : super(kVersions.last.size);
+
+  static _MediaFactoryCreateSourceParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaFactoryCreateSourceParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaFactoryCreateSourceParams result = new _MediaFactoryCreateSourceParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.originUrl = decoder0.decodeString(8, false);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(16, true);
+      if (decoder1 == null) {
+        result.allowedMediaTypes = null;
+      } else {
+        var si1 = decoder1.decodeDataHeaderForPointerArray(bindings.kUnspecifiedArrayLength);
+        result.allowedMediaTypes = new List<media_types_mojom.MediaTypeSet>(si1.numElements);
+        for (int i1 = 0; i1 < si1.numElements; ++i1) {
+          
+          var decoder2 = decoder1.decodePointer(bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i1, false);
+          result.allowedMediaTypes[i1] = media_types_mojom.MediaTypeSet.decode(decoder2);
+        }
+      }
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.source = decoder0.decodeInterfaceRequest(24, false, media_source_mojom.MediaSourceStub.newFromEndpoint);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeString(originUrl, 8, false);
+    
+    if (allowedMediaTypes == null) {
+      encoder0.encodeNullPointer(16, true);
+    } else {
+      var encoder1 = encoder0.encodePointerArray(allowedMediaTypes.length, 16, bindings.kUnspecifiedArrayLength);
+      for (int i0 = 0; i0 < allowedMediaTypes.length; ++i0) {
+        
+        encoder1.encodeStruct(allowedMediaTypes[i0], bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i0, false);
+      }
+    }
+    
+    encoder0.encodeInterfaceRequest(source, 24, false);
+  }
+
+  String toString() {
+    return "_MediaFactoryCreateSourceParams("
+           "originUrl: $originUrl" ", "
+           "allowedMediaTypes: $allowedMediaTypes" ", "
+           "source: $source" ")";
+  }
+
+  Map toJson() {
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
+  }
+}
+
+
+class _MediaFactoryCreateSinkParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(32, 0)
+  ];
+  String destinationUrl = null;
+  media_types_mojom.MediaType mediaType = null;
+  Object sink = null;
+
+  _MediaFactoryCreateSinkParams() : super(kVersions.last.size);
+
+  static _MediaFactoryCreateSinkParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaFactoryCreateSinkParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaFactoryCreateSinkParams result = new _MediaFactoryCreateSinkParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.destinationUrl = decoder0.decodeString(8, false);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(16, false);
+      result.mediaType = media_types_mojom.MediaType.decode(decoder1);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.sink = decoder0.decodeInterfaceRequest(24, false, media_sink_mojom.MediaSinkStub.newFromEndpoint);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeString(destinationUrl, 8, false);
+    
+    encoder0.encodeStruct(mediaType, 16, false);
+    
+    encoder0.encodeInterfaceRequest(sink, 24, false);
+  }
+
+  String toString() {
+    return "_MediaFactoryCreateSinkParams("
+           "destinationUrl: $destinationUrl" ", "
+           "mediaType: $mediaType" ", "
+           "sink: $sink" ")";
+  }
+
+  Map toJson() {
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
+  }
+}
+
+const int _MediaFactory_createPlayerName = 0;
+const int _MediaFactory_createSourceName = 1;
+const int _MediaFactory_createSinkName = 2;
+
+abstract class MediaFactory {
+  static const String serviceName = "mojo::media::MediaFactory";
+  void createPlayer(String originUrl, Object player);
+  void createSource(String originUrl, List<media_types_mojom.MediaTypeSet> allowedMediaTypes, Object source);
+  void createSink(String destinationUrl, media_types_mojom.MediaType mediaType, Object sink);
+}
+
+
+class _MediaFactoryProxyImpl extends bindings.Proxy {
+  _MediaFactoryProxyImpl.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
+
+  _MediaFactoryProxyImpl.fromHandle(core.MojoHandle handle) :
+      super.fromHandle(handle);
+
+  _MediaFactoryProxyImpl.unbound() : super.unbound();
+
+  static _MediaFactoryProxyImpl newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For _MediaFactoryProxyImpl"));
+    return new _MediaFactoryProxyImpl.fromEndpoint(endpoint);
+  }
+
+  void handleResponse(bindings.ServiceMessage message) {
+    switch (message.header.type) {
+      default:
+        proxyError("Unexpected message type: ${message.header.type}");
+        close(immediate: true);
+        break;
+    }
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "_MediaFactoryProxyImpl($superString)";
+  }
+}
+
+
+class _MediaFactoryProxyCalls implements MediaFactory {
+  _MediaFactoryProxyImpl _proxyImpl;
+
+  _MediaFactoryProxyCalls(this._proxyImpl);
+    void createPlayer(String originUrl, Object player) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _MediaFactoryCreatePlayerParams();
+      params.originUrl = originUrl;
+      params.player = player;
+      _proxyImpl.sendMessage(params, _MediaFactory_createPlayerName);
+    }
+    void createSource(String originUrl, List<media_types_mojom.MediaTypeSet> allowedMediaTypes, Object source) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _MediaFactoryCreateSourceParams();
+      params.originUrl = originUrl;
+      params.allowedMediaTypes = allowedMediaTypes;
+      params.source = source;
+      _proxyImpl.sendMessage(params, _MediaFactory_createSourceName);
+    }
+    void createSink(String destinationUrl, media_types_mojom.MediaType mediaType, Object sink) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _MediaFactoryCreateSinkParams();
+      params.destinationUrl = destinationUrl;
+      params.mediaType = mediaType;
+      params.sink = sink;
+      _proxyImpl.sendMessage(params, _MediaFactory_createSinkName);
+    }
+}
+
+
+class MediaFactoryProxy implements bindings.ProxyBase {
+  final bindings.Proxy impl;
+  MediaFactory ptr;
+
+  MediaFactoryProxy(_MediaFactoryProxyImpl proxyImpl) :
+      impl = proxyImpl,
+      ptr = new _MediaFactoryProxyCalls(proxyImpl);
+
+  MediaFactoryProxy.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) :
+      impl = new _MediaFactoryProxyImpl.fromEndpoint(endpoint) {
+    ptr = new _MediaFactoryProxyCalls(impl);
+  }
+
+  MediaFactoryProxy.fromHandle(core.MojoHandle handle) :
+      impl = new _MediaFactoryProxyImpl.fromHandle(handle) {
+    ptr = new _MediaFactoryProxyCalls(impl);
+  }
+
+  MediaFactoryProxy.unbound() :
+      impl = new _MediaFactoryProxyImpl.unbound() {
+    ptr = new _MediaFactoryProxyCalls(impl);
+  }
+
+  factory MediaFactoryProxy.connectToService(
+      bindings.ServiceConnector s, String url, [String serviceName]) {
+    MediaFactoryProxy p = new MediaFactoryProxy.unbound();
+    s.connectToService(url, p, serviceName);
+    return p;
+  }
+
+  static MediaFactoryProxy newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For MediaFactoryProxy"));
+    return new MediaFactoryProxy.fromEndpoint(endpoint);
+  }
+
+  String get serviceName => MediaFactory.serviceName;
+
+  Future close({bool immediate: false}) => impl.close(immediate: immediate);
+
+  Future responseOrError(Future f) => impl.responseOrError(f);
+
+  Future get errorFuture => impl.errorFuture;
+
+  int get version => impl.version;
+
+  Future<int> queryVersion() => impl.queryVersion();
+
+  void requireVersion(int requiredVersion) {
+    impl.requireVersion(requiredVersion);
+  }
+
+  String toString() {
+    return "MediaFactoryProxy($impl)";
+  }
+}
+
+
+class MediaFactoryStub extends bindings.Stub {
+  MediaFactory _impl = null;
+
+  MediaFactoryStub.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint, [this._impl])
+      : super.fromEndpoint(endpoint);
+
+  MediaFactoryStub.fromHandle(core.MojoHandle handle, [this._impl])
+      : super.fromHandle(handle);
+
+  MediaFactoryStub.unbound() : super.unbound();
+
+  static MediaFactoryStub newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For MediaFactoryStub"));
+    return new MediaFactoryStub.fromEndpoint(endpoint);
+  }
+
+
+
+  dynamic handleMessage(bindings.ServiceMessage message) {
+    if (bindings.ControlMessageHandler.isControlMessage(message)) {
+      return bindings.ControlMessageHandler.handleMessage(this,
+                                                          0,
+                                                          message);
+    }
+    assert(_impl != null);
+    switch (message.header.type) {
+      case _MediaFactory_createPlayerName:
+        var params = _MediaFactoryCreatePlayerParams.deserialize(
+            message.payload);
+        _impl.createPlayer(params.originUrl, params.player);
+        break;
+      case _MediaFactory_createSourceName:
+        var params = _MediaFactoryCreateSourceParams.deserialize(
+            message.payload);
+        _impl.createSource(params.originUrl, params.allowedMediaTypes, params.source);
+        break;
+      case _MediaFactory_createSinkName:
+        var params = _MediaFactoryCreateSinkParams.deserialize(
+            message.payload);
+        _impl.createSink(params.destinationUrl, params.mediaType, params.sink);
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+    return null;
+  }
+
+  MediaFactory get impl => _impl;
+  set impl(MediaFactory d) {
+    assert(_impl == null);
+    _impl = d;
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "MediaFactoryStub($superString)";
+  }
+
+  int get version => 0;
+}
+
+
diff --git a/mojo/dart/packages/mojo_services/lib/mojo/media/media_metadata.mojom.dart b/mojo/dart/packages/mojo_services/lib/mojo/media/media_metadata.mojom.dart
new file mode 100644
index 0000000..2f033b2
--- /dev/null
+++ b/mojo/dart/packages/mojo_services/lib/mojo/media/media_metadata.mojom.dart
@@ -0,0 +1,134 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library media_metadata_mojom;
+
+import 'dart:async';
+
+import 'package:mojo/bindings.dart' as bindings;
+import 'package:mojo/core.dart' as core;
+
+
+
+class MediaMetadata extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(64, 0)
+  ];
+  int duration = 0;
+  String title = null;
+  String artist = null;
+  String album = null;
+  String publisher = null;
+  String genre = null;
+  String composer = null;
+
+  MediaMetadata() : super(kVersions.last.size);
+
+  static MediaMetadata deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaMetadata decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaMetadata result = new MediaMetadata();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.duration = decoder0.decodeUint64(8);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.title = decoder0.decodeString(16, true);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.artist = decoder0.decodeString(24, true);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.album = decoder0.decodeString(32, true);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.publisher = decoder0.decodeString(40, true);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.genre = decoder0.decodeString(48, true);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.composer = decoder0.decodeString(56, true);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeUint64(duration, 8);
+    
+    encoder0.encodeString(title, 16, true);
+    
+    encoder0.encodeString(artist, 24, true);
+    
+    encoder0.encodeString(album, 32, true);
+    
+    encoder0.encodeString(publisher, 40, true);
+    
+    encoder0.encodeString(genre, 48, true);
+    
+    encoder0.encodeString(composer, 56, true);
+  }
+
+  String toString() {
+    return "MediaMetadata("
+           "duration: $duration" ", "
+           "title: $title" ", "
+           "artist: $artist" ", "
+           "album: $album" ", "
+           "publisher: $publisher" ", "
+           "genre: $genre" ", "
+           "composer: $composer" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["duration"] = duration;
+    map["title"] = title;
+    map["artist"] = artist;
+    map["album"] = album;
+    map["publisher"] = publisher;
+    map["genre"] = genre;
+    map["composer"] = composer;
+    return map;
+  }
+}
+
+
diff --git a/mojo/dart/packages/mojo_services/lib/mojo/media/media_pipe.mojom.dart b/mojo/dart/packages/mojo_services/lib/mojo/media/media_pipe.mojom.dart
new file mode 100644
index 0000000..3670a9d
--- /dev/null
+++ b/mojo/dart/packages/mojo_services/lib/mojo/media/media_pipe.mojom.dart
@@ -0,0 +1,1006 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library media_pipe_mojom;
+
+import 'dart:async';
+
+import 'package:mojo/bindings.dart' as bindings;
+import 'package:mojo/core.dart' as core;
+import 'package:mojo_services/mojo/media/media_common.mojom.dart' as media_common_mojom;
+
+
+
+class MediaPacketRegion extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  int offset = 0;
+  int length = 0;
+
+  MediaPacketRegion() : super(kVersions.last.size);
+
+  static MediaPacketRegion deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaPacketRegion decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaPacketRegion result = new MediaPacketRegion();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.offset = decoder0.decodeUint64(8);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.length = decoder0.decodeUint64(16);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeUint64(offset, 8);
+    
+    encoder0.encodeUint64(length, 16);
+  }
+
+  String toString() {
+    return "MediaPacketRegion("
+           "offset: $offset" ", "
+           "length: $length" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["offset"] = offset;
+    map["length"] = length;
+    return map;
+  }
+}
+
+
+class MediaPacket extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(48, 0)
+  ];
+  static const int kNoTimestamp = 0x7fffffffffffffff;
+  int pts = 0x7fffffffffffffff;
+  int duration = 0;
+  bool endOfStream = false;
+  MediaPacketRegion payload = null;
+  List<MediaPacketRegion> extraPayload = null;
+
+  MediaPacket() : super(kVersions.last.size);
+
+  static MediaPacket deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaPacket decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaPacket result = new MediaPacket();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.pts = decoder0.decodeInt64(8);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.duration = decoder0.decodeUint64(16);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.endOfStream = decoder0.decodeBool(24, 0);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(32, false);
+      result.payload = MediaPacketRegion.decode(decoder1);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(40, true);
+      if (decoder1 == null) {
+        result.extraPayload = null;
+      } else {
+        var si1 = decoder1.decodeDataHeaderForPointerArray(bindings.kUnspecifiedArrayLength);
+        result.extraPayload = new List<MediaPacketRegion>(si1.numElements);
+        for (int i1 = 0; i1 < si1.numElements; ++i1) {
+          
+          var decoder2 = decoder1.decodePointer(bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i1, false);
+          result.extraPayload[i1] = MediaPacketRegion.decode(decoder2);
+        }
+      }
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeInt64(pts, 8);
+    
+    encoder0.encodeUint64(duration, 16);
+    
+    encoder0.encodeBool(endOfStream, 24, 0);
+    
+    encoder0.encodeStruct(payload, 32, false);
+    
+    if (extraPayload == null) {
+      encoder0.encodeNullPointer(40, true);
+    } else {
+      var encoder1 = encoder0.encodePointerArray(extraPayload.length, 40, bindings.kUnspecifiedArrayLength);
+      for (int i0 = 0; i0 < extraPayload.length; ++i0) {
+        
+        encoder1.encodeStruct(extraPayload[i0], bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i0, false);
+      }
+    }
+  }
+
+  String toString() {
+    return "MediaPacket("
+           "pts: $pts" ", "
+           "duration: $duration" ", "
+           "endOfStream: $endOfStream" ", "
+           "payload: $payload" ", "
+           "extraPayload: $extraPayload" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["pts"] = pts;
+    map["duration"] = duration;
+    map["endOfStream"] = endOfStream;
+    map["payload"] = payload;
+    map["extraPayload"] = extraPayload;
+    return map;
+  }
+}
+
+
+class MediaPipeState extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  static const int kMaxPayloadLen = 0x3FFFFFFFFFFFFFFF;
+  core.MojoSharedBuffer payloadBuffer = null;
+  int payloadBufferLen = 0;
+
+  MediaPipeState() : super(kVersions.last.size);
+
+  static MediaPipeState deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaPipeState decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaPipeState result = new MediaPipeState();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.payloadBuffer = decoder0.decodeSharedBufferHandle(8, false);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.payloadBufferLen = decoder0.decodeUint64(16);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeSharedBufferHandle(payloadBuffer, 8, false);
+    
+    encoder0.encodeUint64(payloadBufferLen, 16);
+  }
+
+  String toString() {
+    return "MediaPipeState("
+           "payloadBuffer: $payloadBuffer" ", "
+           "payloadBufferLen: $payloadBufferLen" ")";
+  }
+
+  Map toJson() {
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
+  }
+}
+
+
+class _MediaPipeGetStateParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  _MediaPipeGetStateParams() : super(kVersions.last.size);
+
+  static _MediaPipeGetStateParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaPipeGetStateParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaPipeGetStateParams result = new _MediaPipeGetStateParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "_MediaPipeGetStateParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+class MediaPipeGetStateResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  MediaPipeState state = null;
+
+  MediaPipeGetStateResponseParams() : super(kVersions.last.size);
+
+  static MediaPipeGetStateResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaPipeGetStateResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaPipeGetStateResponseParams result = new MediaPipeGetStateResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(8, false);
+      result.state = MediaPipeState.decode(decoder1);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeStruct(state, 8, false);
+  }
+
+  String toString() {
+    return "MediaPipeGetStateResponseParams("
+           "state: $state" ")";
+  }
+
+  Map toJson() {
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
+  }
+}
+
+
+class _MediaPipeSendPacketParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  MediaPacket packet = null;
+
+  _MediaPipeSendPacketParams() : super(kVersions.last.size);
+
+  static _MediaPipeSendPacketParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaPipeSendPacketParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaPipeSendPacketParams result = new _MediaPipeSendPacketParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(8, false);
+      result.packet = MediaPacket.decode(decoder1);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeStruct(packet, 8, false);
+  }
+
+  String toString() {
+    return "_MediaPipeSendPacketParams("
+           "packet: $packet" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["packet"] = packet;
+    return map;
+  }
+}
+
+
+class MediaPipeSendPacketResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  media_common_mojom.MediaResult result = null;
+
+  MediaPipeSendPacketResponseParams() : super(kVersions.last.size);
+
+  static MediaPipeSendPacketResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaPipeSendPacketResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaPipeSendPacketResponseParams result = new MediaPipeSendPacketResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.result = media_common_mojom.MediaResult.decode(decoder0, 8);
+        if (result.result == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable media_common_mojom.MediaResult.');
+        }
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeEnum(result, 8);
+  }
+
+  String toString() {
+    return "MediaPipeSendPacketResponseParams("
+           "result: $result" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["result"] = result;
+    return map;
+  }
+}
+
+
+class _MediaPipeFlushParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  _MediaPipeFlushParams() : super(kVersions.last.size);
+
+  static _MediaPipeFlushParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaPipeFlushParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaPipeFlushParams result = new _MediaPipeFlushParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "_MediaPipeFlushParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+class MediaPipeFlushResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  media_common_mojom.MediaResult result = null;
+
+  MediaPipeFlushResponseParams() : super(kVersions.last.size);
+
+  static MediaPipeFlushResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaPipeFlushResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaPipeFlushResponseParams result = new MediaPipeFlushResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.result = media_common_mojom.MediaResult.decode(decoder0, 8);
+        if (result.result == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable media_common_mojom.MediaResult.');
+        }
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeEnum(result, 8);
+  }
+
+  String toString() {
+    return "MediaPipeFlushResponseParams("
+           "result: $result" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["result"] = result;
+    return map;
+  }
+}
+
+const int _MediaPipe_getStateName = 0;
+const int _MediaPipe_sendPacketName = 1;
+const int _MediaPipe_flushName = 2;
+
+abstract class MediaPipe {
+  static const String serviceName = null;
+  dynamic getState([Function responseFactory = null]);
+  dynamic sendPacket(MediaPacket packet,[Function responseFactory = null]);
+  dynamic flush([Function responseFactory = null]);
+}
+
+
+class _MediaPipeProxyImpl extends bindings.Proxy {
+  _MediaPipeProxyImpl.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
+
+  _MediaPipeProxyImpl.fromHandle(core.MojoHandle handle) :
+      super.fromHandle(handle);
+
+  _MediaPipeProxyImpl.unbound() : super.unbound();
+
+  static _MediaPipeProxyImpl newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For _MediaPipeProxyImpl"));
+    return new _MediaPipeProxyImpl.fromEndpoint(endpoint);
+  }
+
+  void handleResponse(bindings.ServiceMessage message) {
+    switch (message.header.type) {
+      case _MediaPipe_getStateName:
+        var r = MediaPipeGetStateResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      case _MediaPipe_sendPacketName:
+        var r = MediaPipeSendPacketResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      case _MediaPipe_flushName:
+        var r = MediaPipeFlushResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      default:
+        proxyError("Unexpected message type: ${message.header.type}");
+        close(immediate: true);
+        break;
+    }
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "_MediaPipeProxyImpl($superString)";
+  }
+}
+
+
+class _MediaPipeProxyCalls implements MediaPipe {
+  _MediaPipeProxyImpl _proxyImpl;
+
+  _MediaPipeProxyCalls(this._proxyImpl);
+    dynamic getState([Function responseFactory = null]) {
+      var params = new _MediaPipeGetStateParams();
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _MediaPipe_getStateName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    dynamic sendPacket(MediaPacket packet,[Function responseFactory = null]) {
+      var params = new _MediaPipeSendPacketParams();
+      params.packet = packet;
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _MediaPipe_sendPacketName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    dynamic flush([Function responseFactory = null]) {
+      var params = new _MediaPipeFlushParams();
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _MediaPipe_flushName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+}
+
+
+class MediaPipeProxy implements bindings.ProxyBase {
+  final bindings.Proxy impl;
+  MediaPipe ptr;
+
+  MediaPipeProxy(_MediaPipeProxyImpl proxyImpl) :
+      impl = proxyImpl,
+      ptr = new _MediaPipeProxyCalls(proxyImpl);
+
+  MediaPipeProxy.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) :
+      impl = new _MediaPipeProxyImpl.fromEndpoint(endpoint) {
+    ptr = new _MediaPipeProxyCalls(impl);
+  }
+
+  MediaPipeProxy.fromHandle(core.MojoHandle handle) :
+      impl = new _MediaPipeProxyImpl.fromHandle(handle) {
+    ptr = new _MediaPipeProxyCalls(impl);
+  }
+
+  MediaPipeProxy.unbound() :
+      impl = new _MediaPipeProxyImpl.unbound() {
+    ptr = new _MediaPipeProxyCalls(impl);
+  }
+
+  factory MediaPipeProxy.connectToService(
+      bindings.ServiceConnector s, String url, [String serviceName]) {
+    MediaPipeProxy p = new MediaPipeProxy.unbound();
+    s.connectToService(url, p, serviceName);
+    return p;
+  }
+
+  static MediaPipeProxy newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For MediaPipeProxy"));
+    return new MediaPipeProxy.fromEndpoint(endpoint);
+  }
+
+  String get serviceName => MediaPipe.serviceName;
+
+  Future close({bool immediate: false}) => impl.close(immediate: immediate);
+
+  Future responseOrError(Future f) => impl.responseOrError(f);
+
+  Future get errorFuture => impl.errorFuture;
+
+  int get version => impl.version;
+
+  Future<int> queryVersion() => impl.queryVersion();
+
+  void requireVersion(int requiredVersion) {
+    impl.requireVersion(requiredVersion);
+  }
+
+  String toString() {
+    return "MediaPipeProxy($impl)";
+  }
+}
+
+
+class MediaPipeStub extends bindings.Stub {
+  MediaPipe _impl = null;
+
+  MediaPipeStub.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint, [this._impl])
+      : super.fromEndpoint(endpoint);
+
+  MediaPipeStub.fromHandle(core.MojoHandle handle, [this._impl])
+      : super.fromHandle(handle);
+
+  MediaPipeStub.unbound() : super.unbound();
+
+  static MediaPipeStub newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For MediaPipeStub"));
+    return new MediaPipeStub.fromEndpoint(endpoint);
+  }
+
+
+  MediaPipeGetStateResponseParams _MediaPipeGetStateResponseParamsFactory(MediaPipeState state) {
+    var mojo_factory_result = new MediaPipeGetStateResponseParams();
+    mojo_factory_result.state = state;
+    return mojo_factory_result;
+  }
+  MediaPipeSendPacketResponseParams _MediaPipeSendPacketResponseParamsFactory(media_common_mojom.MediaResult result) {
+    var mojo_factory_result = new MediaPipeSendPacketResponseParams();
+    mojo_factory_result.result = result;
+    return mojo_factory_result;
+  }
+  MediaPipeFlushResponseParams _MediaPipeFlushResponseParamsFactory(media_common_mojom.MediaResult result) {
+    var mojo_factory_result = new MediaPipeFlushResponseParams();
+    mojo_factory_result.result = result;
+    return mojo_factory_result;
+  }
+
+  dynamic handleMessage(bindings.ServiceMessage message) {
+    if (bindings.ControlMessageHandler.isControlMessage(message)) {
+      return bindings.ControlMessageHandler.handleMessage(this,
+                                                          0,
+                                                          message);
+    }
+    assert(_impl != null);
+    switch (message.header.type) {
+      case _MediaPipe_getStateName:
+        var params = _MediaPipeGetStateParams.deserialize(
+            message.payload);
+        var response = _impl.getState(_MediaPipeGetStateResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _MediaPipe_getStateName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _MediaPipe_getStateName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case _MediaPipe_sendPacketName:
+        var params = _MediaPipeSendPacketParams.deserialize(
+            message.payload);
+        var response = _impl.sendPacket(params.packet,_MediaPipeSendPacketResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _MediaPipe_sendPacketName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _MediaPipe_sendPacketName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case _MediaPipe_flushName:
+        var params = _MediaPipeFlushParams.deserialize(
+            message.payload);
+        var response = _impl.flush(_MediaPipeFlushResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _MediaPipe_flushName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _MediaPipe_flushName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+    return null;
+  }
+
+  MediaPipe get impl => _impl;
+  set impl(MediaPipe d) {
+    assert(_impl == null);
+    _impl = d;
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "MediaPipeStub($superString)";
+  }
+
+  int get version => 0;
+}
+
+
diff --git a/mojo/dart/packages/mojo_services/lib/mojo/media/media_player.mojom.dart b/mojo/dart/packages/mojo_services/lib/mojo/media/media_player.mojom.dart
new file mode 100644
index 0000000..bc5a72d
--- /dev/null
+++ b/mojo/dart/packages/mojo_services/lib/mojo/media/media_player.mojom.dart
@@ -0,0 +1,608 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library media_player_mojom;
+
+import 'dart:async';
+
+import 'package:mojo/bindings.dart' as bindings;
+import 'package:mojo/core.dart' as core;
+import 'package:mojo_services/mojo/media/media_metadata.mojom.dart' as media_metadata_mojom;
+import 'package:mojo_services/mojo/media/media_state.mojom.dart' as media_state_mojom;
+import 'package:mojo_services/mojo/media/rate_control.mojom.dart' as rate_control_mojom;
+
+
+
+class MediaPlayerStatus extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(32, 0)
+  ];
+  media_state_mojom.MediaState state = null;
+  rate_control_mojom.TimelineTransform timelineTransform = null;
+  media_metadata_mojom.MediaMetadata metadata = null;
+
+  MediaPlayerStatus() : super(kVersions.last.size);
+
+  static MediaPlayerStatus deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaPlayerStatus decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaPlayerStatus result = new MediaPlayerStatus();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.state = media_state_mojom.MediaState.decode(decoder0, 8);
+        if (result.state == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable media_state_mojom.MediaState.');
+        }
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(16, true);
+      result.timelineTransform = rate_control_mojom.TimelineTransform.decode(decoder1);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(24, true);
+      result.metadata = media_metadata_mojom.MediaMetadata.decode(decoder1);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeEnum(state, 8);
+    
+    encoder0.encodeStruct(timelineTransform, 16, true);
+    
+    encoder0.encodeStruct(metadata, 24, true);
+  }
+
+  String toString() {
+    return "MediaPlayerStatus("
+           "state: $state" ", "
+           "timelineTransform: $timelineTransform" ", "
+           "metadata: $metadata" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["state"] = state;
+    map["timelineTransform"] = timelineTransform;
+    map["metadata"] = metadata;
+    return map;
+  }
+}
+
+
+class _MediaPlayerPlayParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  _MediaPlayerPlayParams() : super(kVersions.last.size);
+
+  static _MediaPlayerPlayParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaPlayerPlayParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaPlayerPlayParams result = new _MediaPlayerPlayParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "_MediaPlayerPlayParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+class _MediaPlayerPauseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  _MediaPlayerPauseParams() : super(kVersions.last.size);
+
+  static _MediaPlayerPauseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaPlayerPauseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaPlayerPauseParams result = new _MediaPlayerPauseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "_MediaPlayerPauseParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+class _MediaPlayerGetStatusParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  int versionLastSeen = 0;
+
+  _MediaPlayerGetStatusParams() : super(kVersions.last.size);
+
+  static _MediaPlayerGetStatusParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaPlayerGetStatusParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaPlayerGetStatusParams result = new _MediaPlayerGetStatusParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.versionLastSeen = decoder0.decodeUint64(8);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeUint64(versionLastSeen, 8);
+  }
+
+  String toString() {
+    return "_MediaPlayerGetStatusParams("
+           "versionLastSeen: $versionLastSeen" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["versionLastSeen"] = versionLastSeen;
+    return map;
+  }
+}
+
+
+class MediaPlayerGetStatusResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  int version = 0;
+  MediaPlayerStatus status = null;
+
+  MediaPlayerGetStatusResponseParams() : super(kVersions.last.size);
+
+  static MediaPlayerGetStatusResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaPlayerGetStatusResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaPlayerGetStatusResponseParams result = new MediaPlayerGetStatusResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.version = decoder0.decodeUint64(8);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(16, false);
+      result.status = MediaPlayerStatus.decode(decoder1);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeUint64(version, 8);
+    
+    encoder0.encodeStruct(status, 16, false);
+  }
+
+  String toString() {
+    return "MediaPlayerGetStatusResponseParams("
+           "version: $version" ", "
+           "status: $status" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["version"] = version;
+    map["status"] = status;
+    return map;
+  }
+}
+
+const int _MediaPlayer_playName = 0;
+const int _MediaPlayer_pauseName = 1;
+const int _MediaPlayer_getStatusName = 2;
+
+abstract class MediaPlayer {
+  static const String serviceName = null;
+  void play();
+  void pause();
+  dynamic getStatus(int versionLastSeen,[Function responseFactory = null]);
+}
+
+
+class _MediaPlayerProxyImpl extends bindings.Proxy {
+  _MediaPlayerProxyImpl.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
+
+  _MediaPlayerProxyImpl.fromHandle(core.MojoHandle handle) :
+      super.fromHandle(handle);
+
+  _MediaPlayerProxyImpl.unbound() : super.unbound();
+
+  static _MediaPlayerProxyImpl newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For _MediaPlayerProxyImpl"));
+    return new _MediaPlayerProxyImpl.fromEndpoint(endpoint);
+  }
+
+  void handleResponse(bindings.ServiceMessage message) {
+    switch (message.header.type) {
+      case _MediaPlayer_getStatusName:
+        var r = MediaPlayerGetStatusResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      default:
+        proxyError("Unexpected message type: ${message.header.type}");
+        close(immediate: true);
+        break;
+    }
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "_MediaPlayerProxyImpl($superString)";
+  }
+}
+
+
+class _MediaPlayerProxyCalls implements MediaPlayer {
+  _MediaPlayerProxyImpl _proxyImpl;
+
+  _MediaPlayerProxyCalls(this._proxyImpl);
+    void play() {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _MediaPlayerPlayParams();
+      _proxyImpl.sendMessage(params, _MediaPlayer_playName);
+    }
+    void pause() {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _MediaPlayerPauseParams();
+      _proxyImpl.sendMessage(params, _MediaPlayer_pauseName);
+    }
+    dynamic getStatus(int versionLastSeen,[Function responseFactory = null]) {
+      var params = new _MediaPlayerGetStatusParams();
+      params.versionLastSeen = versionLastSeen;
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _MediaPlayer_getStatusName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+}
+
+
+class MediaPlayerProxy implements bindings.ProxyBase {
+  final bindings.Proxy impl;
+  MediaPlayer ptr;
+
+  MediaPlayerProxy(_MediaPlayerProxyImpl proxyImpl) :
+      impl = proxyImpl,
+      ptr = new _MediaPlayerProxyCalls(proxyImpl);
+
+  MediaPlayerProxy.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) :
+      impl = new _MediaPlayerProxyImpl.fromEndpoint(endpoint) {
+    ptr = new _MediaPlayerProxyCalls(impl);
+  }
+
+  MediaPlayerProxy.fromHandle(core.MojoHandle handle) :
+      impl = new _MediaPlayerProxyImpl.fromHandle(handle) {
+    ptr = new _MediaPlayerProxyCalls(impl);
+  }
+
+  MediaPlayerProxy.unbound() :
+      impl = new _MediaPlayerProxyImpl.unbound() {
+    ptr = new _MediaPlayerProxyCalls(impl);
+  }
+
+  factory MediaPlayerProxy.connectToService(
+      bindings.ServiceConnector s, String url, [String serviceName]) {
+    MediaPlayerProxy p = new MediaPlayerProxy.unbound();
+    s.connectToService(url, p, serviceName);
+    return p;
+  }
+
+  static MediaPlayerProxy newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For MediaPlayerProxy"));
+    return new MediaPlayerProxy.fromEndpoint(endpoint);
+  }
+
+  String get serviceName => MediaPlayer.serviceName;
+
+  Future close({bool immediate: false}) => impl.close(immediate: immediate);
+
+  Future responseOrError(Future f) => impl.responseOrError(f);
+
+  Future get errorFuture => impl.errorFuture;
+
+  int get version => impl.version;
+
+  Future<int> queryVersion() => impl.queryVersion();
+
+  void requireVersion(int requiredVersion) {
+    impl.requireVersion(requiredVersion);
+  }
+
+  String toString() {
+    return "MediaPlayerProxy($impl)";
+  }
+}
+
+
+class MediaPlayerStub extends bindings.Stub {
+  MediaPlayer _impl = null;
+
+  MediaPlayerStub.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint, [this._impl])
+      : super.fromEndpoint(endpoint);
+
+  MediaPlayerStub.fromHandle(core.MojoHandle handle, [this._impl])
+      : super.fromHandle(handle);
+
+  MediaPlayerStub.unbound() : super.unbound();
+
+  static MediaPlayerStub newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For MediaPlayerStub"));
+    return new MediaPlayerStub.fromEndpoint(endpoint);
+  }
+
+
+  MediaPlayerGetStatusResponseParams _MediaPlayerGetStatusResponseParamsFactory(int version, MediaPlayerStatus status) {
+    var mojo_factory_result = new MediaPlayerGetStatusResponseParams();
+    mojo_factory_result.version = version;
+    mojo_factory_result.status = status;
+    return mojo_factory_result;
+  }
+
+  dynamic handleMessage(bindings.ServiceMessage message) {
+    if (bindings.ControlMessageHandler.isControlMessage(message)) {
+      return bindings.ControlMessageHandler.handleMessage(this,
+                                                          0,
+                                                          message);
+    }
+    assert(_impl != null);
+    switch (message.header.type) {
+      case _MediaPlayer_playName:
+        var params = _MediaPlayerPlayParams.deserialize(
+            message.payload);
+        _impl.play();
+        break;
+      case _MediaPlayer_pauseName:
+        var params = _MediaPlayerPauseParams.deserialize(
+            message.payload);
+        _impl.pause();
+        break;
+      case _MediaPlayer_getStatusName:
+        var params = _MediaPlayerGetStatusParams.deserialize(
+            message.payload);
+        var response = _impl.getStatus(params.versionLastSeen,_MediaPlayerGetStatusResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _MediaPlayer_getStatusName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _MediaPlayer_getStatusName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+    return null;
+  }
+
+  MediaPlayer get impl => _impl;
+  set impl(MediaPlayer d) {
+    assert(_impl == null);
+    _impl = d;
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "MediaPlayerStub($superString)";
+  }
+
+  int get version => 0;
+}
+
+
diff --git a/mojo/dart/packages/mojo_services/lib/mojo/media/media_sink.mojom.dart b/mojo/dart/packages/mojo_services/lib/mojo/media/media_sink.mojom.dart
new file mode 100644
index 0000000..3ee521e
--- /dev/null
+++ b/mojo/dart/packages/mojo_services/lib/mojo/media/media_sink.mojom.dart
@@ -0,0 +1,1033 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library media_sink_mojom;
+
+import 'dart:async';
+
+import 'package:mojo/bindings.dart' as bindings;
+import 'package:mojo/core.dart' as core;
+import 'package:mojo_services/mojo/media/media_clock.mojom.dart' as media_clock_mojom;
+import 'package:mojo_services/mojo/media/media_common.mojom.dart' as media_common_mojom;
+import 'package:mojo_services/mojo/media/media_state.mojom.dart' as media_state_mojom;
+import 'package:mojo_services/mojo/media/media_transport.mojom.dart' as media_transport_mojom;
+import 'package:mojo_services/mojo/media/media_types.mojom.dart' as media_types_mojom;
+import 'package:mojo_services/mojo/media/rate_control.mojom.dart' as rate_control_mojom;
+
+
+
+class MediaSinkStatus extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  media_state_mojom.MediaState state = null;
+  rate_control_mojom.TimelineTransform timelineTransform = null;
+
+  MediaSinkStatus() : super(kVersions.last.size);
+
+  static MediaSinkStatus deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaSinkStatus decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaSinkStatus result = new MediaSinkStatus();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.state = media_state_mojom.MediaState.decode(decoder0, 8);
+        if (result.state == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable media_state_mojom.MediaState.');
+        }
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(16, true);
+      result.timelineTransform = rate_control_mojom.TimelineTransform.decode(decoder1);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeEnum(state, 8);
+    
+    encoder0.encodeStruct(timelineTransform, 16, true);
+  }
+
+  String toString() {
+    return "MediaSinkStatus("
+           "state: $state" ", "
+           "timelineTransform: $timelineTransform" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["state"] = state;
+    map["timelineTransform"] = timelineTransform;
+    return map;
+  }
+}
+
+
+class _MediaSinkGetClockDispositionParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  _MediaSinkGetClockDispositionParams() : super(kVersions.last.size);
+
+  static _MediaSinkGetClockDispositionParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaSinkGetClockDispositionParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaSinkGetClockDispositionParams result = new _MediaSinkGetClockDispositionParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "_MediaSinkGetClockDispositionParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+class MediaSinkGetClockDispositionResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  media_clock_mojom.ClockDisposition clockDisposition = null;
+
+  MediaSinkGetClockDispositionResponseParams() : super(kVersions.last.size);
+
+  static MediaSinkGetClockDispositionResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaSinkGetClockDispositionResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaSinkGetClockDispositionResponseParams result = new MediaSinkGetClockDispositionResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.clockDisposition = media_clock_mojom.ClockDisposition.decode(decoder0, 8);
+        if (result.clockDisposition == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable media_clock_mojom.ClockDisposition.');
+        }
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeEnum(clockDisposition, 8);
+  }
+
+  String toString() {
+    return "MediaSinkGetClockDispositionResponseParams("
+           "clockDisposition: $clockDisposition" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["clockDisposition"] = clockDisposition;
+    return map;
+  }
+}
+
+
+class _MediaSinkGetMasterClockParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  Object masterClock = null;
+
+  _MediaSinkGetMasterClockParams() : super(kVersions.last.size);
+
+  static _MediaSinkGetMasterClockParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaSinkGetMasterClockParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaSinkGetMasterClockParams result = new _MediaSinkGetMasterClockParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.masterClock = decoder0.decodeInterfaceRequest(8, false, media_clock_mojom.ClockStub.newFromEndpoint);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeInterfaceRequest(masterClock, 8, false);
+  }
+
+  String toString() {
+    return "_MediaSinkGetMasterClockParams("
+           "masterClock: $masterClock" ")";
+  }
+
+  Map toJson() {
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
+  }
+}
+
+
+class _MediaSinkSetMasterClockParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  Object masterClock = null;
+
+  _MediaSinkSetMasterClockParams() : super(kVersions.last.size);
+
+  static _MediaSinkSetMasterClockParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaSinkSetMasterClockParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaSinkSetMasterClockParams result = new _MediaSinkSetMasterClockParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.masterClock = decoder0.decodeServiceInterface(8, true, media_clock_mojom.ClockProxy.newFromEndpoint);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeInterface(masterClock, 8, true);
+  }
+
+  String toString() {
+    return "_MediaSinkSetMasterClockParams("
+           "masterClock: $masterClock" ")";
+  }
+
+  Map toJson() {
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
+  }
+}
+
+
+class _MediaSinkGetConsumerParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  Object consumer = null;
+
+  _MediaSinkGetConsumerParams() : super(kVersions.last.size);
+
+  static _MediaSinkGetConsumerParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaSinkGetConsumerParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaSinkGetConsumerParams result = new _MediaSinkGetConsumerParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.consumer = decoder0.decodeInterfaceRequest(8, false, media_transport_mojom.MediaConsumerStub.newFromEndpoint);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeInterfaceRequest(consumer, 8, false);
+  }
+
+  String toString() {
+    return "_MediaSinkGetConsumerParams("
+           "consumer: $consumer" ")";
+  }
+
+  Map toJson() {
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
+  }
+}
+
+
+class _MediaSinkGetStatusParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  int versionLastSeen = 0;
+
+  _MediaSinkGetStatusParams() : super(kVersions.last.size);
+
+  static _MediaSinkGetStatusParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaSinkGetStatusParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaSinkGetStatusParams result = new _MediaSinkGetStatusParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.versionLastSeen = decoder0.decodeUint64(8);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeUint64(versionLastSeen, 8);
+  }
+
+  String toString() {
+    return "_MediaSinkGetStatusParams("
+           "versionLastSeen: $versionLastSeen" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["versionLastSeen"] = versionLastSeen;
+    return map;
+  }
+}
+
+
+class MediaSinkGetStatusResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  int version = 0;
+  MediaSinkStatus status = null;
+
+  MediaSinkGetStatusResponseParams() : super(kVersions.last.size);
+
+  static MediaSinkGetStatusResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaSinkGetStatusResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaSinkGetStatusResponseParams result = new MediaSinkGetStatusResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.version = decoder0.decodeUint64(8);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(16, false);
+      result.status = MediaSinkStatus.decode(decoder1);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeUint64(version, 8);
+    
+    encoder0.encodeStruct(status, 16, false);
+  }
+
+  String toString() {
+    return "MediaSinkGetStatusResponseParams("
+           "version: $version" ", "
+           "status: $status" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["version"] = version;
+    map["status"] = status;
+    return map;
+  }
+}
+
+
+class _MediaSinkPlayParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  _MediaSinkPlayParams() : super(kVersions.last.size);
+
+  static _MediaSinkPlayParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaSinkPlayParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaSinkPlayParams result = new _MediaSinkPlayParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "_MediaSinkPlayParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+class _MediaSinkPauseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  _MediaSinkPauseParams() : super(kVersions.last.size);
+
+  static _MediaSinkPauseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaSinkPauseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaSinkPauseParams result = new _MediaSinkPauseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "_MediaSinkPauseParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+const int _MediaSink_getClockDispositionName = 0;
+const int _MediaSink_getMasterClockName = 1;
+const int _MediaSink_setMasterClockName = 2;
+const int _MediaSink_getConsumerName = 3;
+const int _MediaSink_getStatusName = 4;
+const int _MediaSink_playName = 5;
+const int _MediaSink_pauseName = 6;
+
+abstract class MediaSink {
+  static const String serviceName = null;
+  dynamic getClockDisposition([Function responseFactory = null]);
+  void getMasterClock(Object masterClock);
+  void setMasterClock(Object masterClock);
+  void getConsumer(Object consumer);
+  dynamic getStatus(int versionLastSeen,[Function responseFactory = null]);
+  void play();
+  void pause();
+}
+
+
+class _MediaSinkProxyImpl extends bindings.Proxy {
+  _MediaSinkProxyImpl.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
+
+  _MediaSinkProxyImpl.fromHandle(core.MojoHandle handle) :
+      super.fromHandle(handle);
+
+  _MediaSinkProxyImpl.unbound() : super.unbound();
+
+  static _MediaSinkProxyImpl newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For _MediaSinkProxyImpl"));
+    return new _MediaSinkProxyImpl.fromEndpoint(endpoint);
+  }
+
+  void handleResponse(bindings.ServiceMessage message) {
+    switch (message.header.type) {
+      case _MediaSink_getClockDispositionName:
+        var r = MediaSinkGetClockDispositionResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      case _MediaSink_getStatusName:
+        var r = MediaSinkGetStatusResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      default:
+        proxyError("Unexpected message type: ${message.header.type}");
+        close(immediate: true);
+        break;
+    }
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "_MediaSinkProxyImpl($superString)";
+  }
+}
+
+
+class _MediaSinkProxyCalls implements MediaSink {
+  _MediaSinkProxyImpl _proxyImpl;
+
+  _MediaSinkProxyCalls(this._proxyImpl);
+    dynamic getClockDisposition([Function responseFactory = null]) {
+      var params = new _MediaSinkGetClockDispositionParams();
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _MediaSink_getClockDispositionName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    void getMasterClock(Object masterClock) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _MediaSinkGetMasterClockParams();
+      params.masterClock = masterClock;
+      _proxyImpl.sendMessage(params, _MediaSink_getMasterClockName);
+    }
+    void setMasterClock(Object masterClock) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _MediaSinkSetMasterClockParams();
+      params.masterClock = masterClock;
+      _proxyImpl.sendMessage(params, _MediaSink_setMasterClockName);
+    }
+    void getConsumer(Object consumer) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _MediaSinkGetConsumerParams();
+      params.consumer = consumer;
+      _proxyImpl.sendMessage(params, _MediaSink_getConsumerName);
+    }
+    dynamic getStatus(int versionLastSeen,[Function responseFactory = null]) {
+      var params = new _MediaSinkGetStatusParams();
+      params.versionLastSeen = versionLastSeen;
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _MediaSink_getStatusName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    void play() {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _MediaSinkPlayParams();
+      _proxyImpl.sendMessage(params, _MediaSink_playName);
+    }
+    void pause() {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _MediaSinkPauseParams();
+      _proxyImpl.sendMessage(params, _MediaSink_pauseName);
+    }
+}
+
+
+class MediaSinkProxy implements bindings.ProxyBase {
+  final bindings.Proxy impl;
+  MediaSink ptr;
+
+  MediaSinkProxy(_MediaSinkProxyImpl proxyImpl) :
+      impl = proxyImpl,
+      ptr = new _MediaSinkProxyCalls(proxyImpl);
+
+  MediaSinkProxy.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) :
+      impl = new _MediaSinkProxyImpl.fromEndpoint(endpoint) {
+    ptr = new _MediaSinkProxyCalls(impl);
+  }
+
+  MediaSinkProxy.fromHandle(core.MojoHandle handle) :
+      impl = new _MediaSinkProxyImpl.fromHandle(handle) {
+    ptr = new _MediaSinkProxyCalls(impl);
+  }
+
+  MediaSinkProxy.unbound() :
+      impl = new _MediaSinkProxyImpl.unbound() {
+    ptr = new _MediaSinkProxyCalls(impl);
+  }
+
+  factory MediaSinkProxy.connectToService(
+      bindings.ServiceConnector s, String url, [String serviceName]) {
+    MediaSinkProxy p = new MediaSinkProxy.unbound();
+    s.connectToService(url, p, serviceName);
+    return p;
+  }
+
+  static MediaSinkProxy newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For MediaSinkProxy"));
+    return new MediaSinkProxy.fromEndpoint(endpoint);
+  }
+
+  String get serviceName => MediaSink.serviceName;
+
+  Future close({bool immediate: false}) => impl.close(immediate: immediate);
+
+  Future responseOrError(Future f) => impl.responseOrError(f);
+
+  Future get errorFuture => impl.errorFuture;
+
+  int get version => impl.version;
+
+  Future<int> queryVersion() => impl.queryVersion();
+
+  void requireVersion(int requiredVersion) {
+    impl.requireVersion(requiredVersion);
+  }
+
+  String toString() {
+    return "MediaSinkProxy($impl)";
+  }
+}
+
+
+class MediaSinkStub extends bindings.Stub {
+  MediaSink _impl = null;
+
+  MediaSinkStub.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint, [this._impl])
+      : super.fromEndpoint(endpoint);
+
+  MediaSinkStub.fromHandle(core.MojoHandle handle, [this._impl])
+      : super.fromHandle(handle);
+
+  MediaSinkStub.unbound() : super.unbound();
+
+  static MediaSinkStub newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For MediaSinkStub"));
+    return new MediaSinkStub.fromEndpoint(endpoint);
+  }
+
+
+  MediaSinkGetClockDispositionResponseParams _MediaSinkGetClockDispositionResponseParamsFactory(media_clock_mojom.ClockDisposition clockDisposition) {
+    var mojo_factory_result = new MediaSinkGetClockDispositionResponseParams();
+    mojo_factory_result.clockDisposition = clockDisposition;
+    return mojo_factory_result;
+  }
+  MediaSinkGetStatusResponseParams _MediaSinkGetStatusResponseParamsFactory(int version, MediaSinkStatus status) {
+    var mojo_factory_result = new MediaSinkGetStatusResponseParams();
+    mojo_factory_result.version = version;
+    mojo_factory_result.status = status;
+    return mojo_factory_result;
+  }
+
+  dynamic handleMessage(bindings.ServiceMessage message) {
+    if (bindings.ControlMessageHandler.isControlMessage(message)) {
+      return bindings.ControlMessageHandler.handleMessage(this,
+                                                          0,
+                                                          message);
+    }
+    assert(_impl != null);
+    switch (message.header.type) {
+      case _MediaSink_getClockDispositionName:
+        var params = _MediaSinkGetClockDispositionParams.deserialize(
+            message.payload);
+        var response = _impl.getClockDisposition(_MediaSinkGetClockDispositionResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _MediaSink_getClockDispositionName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _MediaSink_getClockDispositionName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case _MediaSink_getMasterClockName:
+        var params = _MediaSinkGetMasterClockParams.deserialize(
+            message.payload);
+        _impl.getMasterClock(params.masterClock);
+        break;
+      case _MediaSink_setMasterClockName:
+        var params = _MediaSinkSetMasterClockParams.deserialize(
+            message.payload);
+        _impl.setMasterClock(params.masterClock);
+        break;
+      case _MediaSink_getConsumerName:
+        var params = _MediaSinkGetConsumerParams.deserialize(
+            message.payload);
+        _impl.getConsumer(params.consumer);
+        break;
+      case _MediaSink_getStatusName:
+        var params = _MediaSinkGetStatusParams.deserialize(
+            message.payload);
+        var response = _impl.getStatus(params.versionLastSeen,_MediaSinkGetStatusResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _MediaSink_getStatusName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _MediaSink_getStatusName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case _MediaSink_playName:
+        var params = _MediaSinkPlayParams.deserialize(
+            message.payload);
+        _impl.play();
+        break;
+      case _MediaSink_pauseName:
+        var params = _MediaSinkPauseParams.deserialize(
+            message.payload);
+        _impl.pause();
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+    return null;
+  }
+
+  MediaSink get impl => _impl;
+  set impl(MediaSink d) {
+    assert(_impl == null);
+    _impl = d;
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "MediaSinkStub($superString)";
+  }
+
+  int get version => 0;
+}
+
+
diff --git a/mojo/dart/packages/mojo_services/lib/mojo/media/media_source.mojom.dart b/mojo/dart/packages/mojo_services/lib/mojo/media/media_source.mojom.dart
new file mode 100644
index 0000000..8496b98
--- /dev/null
+++ b/mojo/dart/packages/mojo_services/lib/mojo/media/media_source.mojom.dart
@@ -0,0 +1,1445 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library media_source_mojom;
+
+import 'dart:async';
+
+import 'package:mojo/bindings.dart' as bindings;
+import 'package:mojo/core.dart' as core;
+import 'package:mojo_services/mojo/media/media_clock.mojom.dart' as media_clock_mojom;
+import 'package:mojo_services/mojo/media/media_common.mojom.dart' as media_common_mojom;
+import 'package:mojo_services/mojo/media/media_metadata.mojom.dart' as media_metadata_mojom;
+import 'package:mojo_services/mojo/media/media_state.mojom.dart' as media_state_mojom;
+import 'package:mojo_services/mojo/media/media_transport.mojom.dart' as media_transport_mojom;
+import 'package:mojo_services/mojo/media/media_types.mojom.dart' as media_types_mojom;
+
+
+
+class MediaSourceStreamDescriptor extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(32, 0)
+  ];
+  int index = 0;
+  media_types_mojom.MediaType mediaType = null;
+  media_types_mojom.MediaType originalMediaType = null;
+
+  MediaSourceStreamDescriptor() : super(kVersions.last.size);
+
+  static MediaSourceStreamDescriptor deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaSourceStreamDescriptor decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaSourceStreamDescriptor result = new MediaSourceStreamDescriptor();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.index = decoder0.decodeUint32(8);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(16, false);
+      result.mediaType = media_types_mojom.MediaType.decode(decoder1);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(24, false);
+      result.originalMediaType = media_types_mojom.MediaType.decode(decoder1);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeUint32(index, 8);
+    
+    encoder0.encodeStruct(mediaType, 16, false);
+    
+    encoder0.encodeStruct(originalMediaType, 24, false);
+  }
+
+  String toString() {
+    return "MediaSourceStreamDescriptor("
+           "index: $index" ", "
+           "mediaType: $mediaType" ", "
+           "originalMediaType: $originalMediaType" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["index"] = index;
+    map["mediaType"] = mediaType;
+    map["originalMediaType"] = originalMediaType;
+    return map;
+  }
+}
+
+
+class MediaSourceStatus extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  media_state_mojom.MediaState state = null;
+  media_metadata_mojom.MediaMetadata metadata = null;
+
+  MediaSourceStatus() : super(kVersions.last.size);
+
+  static MediaSourceStatus deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaSourceStatus decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaSourceStatus result = new MediaSourceStatus();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.state = media_state_mojom.MediaState.decode(decoder0, 8);
+        if (result.state == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable media_state_mojom.MediaState.');
+        }
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(16, true);
+      result.metadata = media_metadata_mojom.MediaMetadata.decode(decoder1);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeEnum(state, 8);
+    
+    encoder0.encodeStruct(metadata, 16, true);
+  }
+
+  String toString() {
+    return "MediaSourceStatus("
+           "state: $state" ", "
+           "metadata: $metadata" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["state"] = state;
+    map["metadata"] = metadata;
+    return map;
+  }
+}
+
+
+class _MediaSourceGetStreamsParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  _MediaSourceGetStreamsParams() : super(kVersions.last.size);
+
+  static _MediaSourceGetStreamsParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaSourceGetStreamsParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaSourceGetStreamsParams result = new _MediaSourceGetStreamsParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "_MediaSourceGetStreamsParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+class MediaSourceGetStreamsResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  List<MediaSourceStreamDescriptor> streams = null;
+
+  MediaSourceGetStreamsResponseParams() : super(kVersions.last.size);
+
+  static MediaSourceGetStreamsResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaSourceGetStreamsResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaSourceGetStreamsResponseParams result = new MediaSourceGetStreamsResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(8, false);
+      {
+        var si1 = decoder1.decodeDataHeaderForPointerArray(bindings.kUnspecifiedArrayLength);
+        result.streams = new List<MediaSourceStreamDescriptor>(si1.numElements);
+        for (int i1 = 0; i1 < si1.numElements; ++i1) {
+          
+          var decoder2 = decoder1.decodePointer(bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i1, false);
+          result.streams[i1] = MediaSourceStreamDescriptor.decode(decoder2);
+        }
+      }
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    if (streams == null) {
+      encoder0.encodeNullPointer(8, false);
+    } else {
+      var encoder1 = encoder0.encodePointerArray(streams.length, 8, bindings.kUnspecifiedArrayLength);
+      for (int i0 = 0; i0 < streams.length; ++i0) {
+        
+        encoder1.encodeStruct(streams[i0], bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i0, false);
+      }
+    }
+  }
+
+  String toString() {
+    return "MediaSourceGetStreamsResponseParams("
+           "streams: $streams" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["streams"] = streams;
+    return map;
+  }
+}
+
+
+class _MediaSourceGetClockDispositionParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  _MediaSourceGetClockDispositionParams() : super(kVersions.last.size);
+
+  static _MediaSourceGetClockDispositionParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaSourceGetClockDispositionParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaSourceGetClockDispositionParams result = new _MediaSourceGetClockDispositionParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "_MediaSourceGetClockDispositionParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+class MediaSourceGetClockDispositionResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  media_clock_mojom.ClockDisposition clockDisposition = null;
+
+  MediaSourceGetClockDispositionResponseParams() : super(kVersions.last.size);
+
+  static MediaSourceGetClockDispositionResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaSourceGetClockDispositionResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaSourceGetClockDispositionResponseParams result = new MediaSourceGetClockDispositionResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.clockDisposition = media_clock_mojom.ClockDisposition.decode(decoder0, 8);
+        if (result.clockDisposition == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable media_clock_mojom.ClockDisposition.');
+        }
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeEnum(clockDisposition, 8);
+  }
+
+  String toString() {
+    return "MediaSourceGetClockDispositionResponseParams("
+           "clockDisposition: $clockDisposition" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["clockDisposition"] = clockDisposition;
+    return map;
+  }
+}
+
+
+class _MediaSourceGetMasterClockParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  Object masterClock = null;
+
+  _MediaSourceGetMasterClockParams() : super(kVersions.last.size);
+
+  static _MediaSourceGetMasterClockParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaSourceGetMasterClockParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaSourceGetMasterClockParams result = new _MediaSourceGetMasterClockParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.masterClock = decoder0.decodeInterfaceRequest(8, false, media_clock_mojom.ClockStub.newFromEndpoint);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeInterfaceRequest(masterClock, 8, false);
+  }
+
+  String toString() {
+    return "_MediaSourceGetMasterClockParams("
+           "masterClock: $masterClock" ")";
+  }
+
+  Map toJson() {
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
+  }
+}
+
+
+class _MediaSourceSetMasterClockParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  Object masterClock = null;
+
+  _MediaSourceSetMasterClockParams() : super(kVersions.last.size);
+
+  static _MediaSourceSetMasterClockParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaSourceSetMasterClockParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaSourceSetMasterClockParams result = new _MediaSourceSetMasterClockParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.masterClock = decoder0.decodeServiceInterface(8, true, media_clock_mojom.ClockProxy.newFromEndpoint);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeInterface(masterClock, 8, true);
+  }
+
+  String toString() {
+    return "_MediaSourceSetMasterClockParams("
+           "masterClock: $masterClock" ")";
+  }
+
+  Map toJson() {
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
+  }
+}
+
+
+class _MediaSourceGetProducerParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  int streamIndex = 0;
+  Object producer = null;
+
+  _MediaSourceGetProducerParams() : super(kVersions.last.size);
+
+  static _MediaSourceGetProducerParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaSourceGetProducerParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaSourceGetProducerParams result = new _MediaSourceGetProducerParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.streamIndex = decoder0.decodeUint32(8);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.producer = decoder0.decodeInterfaceRequest(12, false, media_transport_mojom.MediaProducerStub.newFromEndpoint);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeUint32(streamIndex, 8);
+    
+    encoder0.encodeInterfaceRequest(producer, 12, false);
+  }
+
+  String toString() {
+    return "_MediaSourceGetProducerParams("
+           "streamIndex: $streamIndex" ", "
+           "producer: $producer" ")";
+  }
+
+  Map toJson() {
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
+  }
+}
+
+
+class _MediaSourceGetPullModeProducerParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  int streamIndex = 0;
+  Object producer = null;
+
+  _MediaSourceGetPullModeProducerParams() : super(kVersions.last.size);
+
+  static _MediaSourceGetPullModeProducerParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaSourceGetPullModeProducerParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaSourceGetPullModeProducerParams result = new _MediaSourceGetPullModeProducerParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.streamIndex = decoder0.decodeUint32(8);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.producer = decoder0.decodeInterfaceRequest(12, false, media_transport_mojom.MediaPullModeProducerStub.newFromEndpoint);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeUint32(streamIndex, 8);
+    
+    encoder0.encodeInterfaceRequest(producer, 12, false);
+  }
+
+  String toString() {
+    return "_MediaSourceGetPullModeProducerParams("
+           "streamIndex: $streamIndex" ", "
+           "producer: $producer" ")";
+  }
+
+  Map toJson() {
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
+  }
+}
+
+
+class _MediaSourceGetStatusParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  int versionLastSeen = 0;
+
+  _MediaSourceGetStatusParams() : super(kVersions.last.size);
+
+  static _MediaSourceGetStatusParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaSourceGetStatusParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaSourceGetStatusParams result = new _MediaSourceGetStatusParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.versionLastSeen = decoder0.decodeUint64(8);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeUint64(versionLastSeen, 8);
+  }
+
+  String toString() {
+    return "_MediaSourceGetStatusParams("
+           "versionLastSeen: $versionLastSeen" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["versionLastSeen"] = versionLastSeen;
+    return map;
+  }
+}
+
+
+class MediaSourceGetStatusResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  int version = 0;
+  MediaSourceStatus status = null;
+
+  MediaSourceGetStatusResponseParams() : super(kVersions.last.size);
+
+  static MediaSourceGetStatusResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaSourceGetStatusResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaSourceGetStatusResponseParams result = new MediaSourceGetStatusResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.version = decoder0.decodeUint64(8);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(16, false);
+      result.status = MediaSourceStatus.decode(decoder1);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeUint64(version, 8);
+    
+    encoder0.encodeStruct(status, 16, false);
+  }
+
+  String toString() {
+    return "MediaSourceGetStatusResponseParams("
+           "version: $version" ", "
+           "status: $status" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["version"] = version;
+    map["status"] = status;
+    return map;
+  }
+}
+
+
+class _MediaSourcePrepareParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  _MediaSourcePrepareParams() : super(kVersions.last.size);
+
+  static _MediaSourcePrepareParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaSourcePrepareParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaSourcePrepareParams result = new _MediaSourcePrepareParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "_MediaSourcePrepareParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+class MediaSourcePrepareResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  MediaSourcePrepareResponseParams() : super(kVersions.last.size);
+
+  static MediaSourcePrepareResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaSourcePrepareResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaSourcePrepareResponseParams result = new MediaSourcePrepareResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "MediaSourcePrepareResponseParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+const int _MediaSource_getStreamsName = 0;
+const int _MediaSource_getClockDispositionName = 1;
+const int _MediaSource_getMasterClockName = 2;
+const int _MediaSource_setMasterClockName = 3;
+const int _MediaSource_getProducerName = 4;
+const int _MediaSource_getPullModeProducerName = 5;
+const int _MediaSource_getStatusName = 6;
+const int _MediaSource_prepareName = 7;
+
+abstract class MediaSource {
+  static const String serviceName = null;
+  dynamic getStreams([Function responseFactory = null]);
+  dynamic getClockDisposition([Function responseFactory = null]);
+  void getMasterClock(Object masterClock);
+  void setMasterClock(Object masterClock);
+  void getProducer(int streamIndex, Object producer);
+  void getPullModeProducer(int streamIndex, Object producer);
+  dynamic getStatus(int versionLastSeen,[Function responseFactory = null]);
+  dynamic prepare([Function responseFactory = null]);
+}
+
+
+class _MediaSourceProxyImpl extends bindings.Proxy {
+  _MediaSourceProxyImpl.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
+
+  _MediaSourceProxyImpl.fromHandle(core.MojoHandle handle) :
+      super.fromHandle(handle);
+
+  _MediaSourceProxyImpl.unbound() : super.unbound();
+
+  static _MediaSourceProxyImpl newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For _MediaSourceProxyImpl"));
+    return new _MediaSourceProxyImpl.fromEndpoint(endpoint);
+  }
+
+  void handleResponse(bindings.ServiceMessage message) {
+    switch (message.header.type) {
+      case _MediaSource_getStreamsName:
+        var r = MediaSourceGetStreamsResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      case _MediaSource_getClockDispositionName:
+        var r = MediaSourceGetClockDispositionResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      case _MediaSource_getStatusName:
+        var r = MediaSourceGetStatusResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      case _MediaSource_prepareName:
+        var r = MediaSourcePrepareResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      default:
+        proxyError("Unexpected message type: ${message.header.type}");
+        close(immediate: true);
+        break;
+    }
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "_MediaSourceProxyImpl($superString)";
+  }
+}
+
+
+class _MediaSourceProxyCalls implements MediaSource {
+  _MediaSourceProxyImpl _proxyImpl;
+
+  _MediaSourceProxyCalls(this._proxyImpl);
+    dynamic getStreams([Function responseFactory = null]) {
+      var params = new _MediaSourceGetStreamsParams();
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _MediaSource_getStreamsName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    dynamic getClockDisposition([Function responseFactory = null]) {
+      var params = new _MediaSourceGetClockDispositionParams();
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _MediaSource_getClockDispositionName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    void getMasterClock(Object masterClock) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _MediaSourceGetMasterClockParams();
+      params.masterClock = masterClock;
+      _proxyImpl.sendMessage(params, _MediaSource_getMasterClockName);
+    }
+    void setMasterClock(Object masterClock) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _MediaSourceSetMasterClockParams();
+      params.masterClock = masterClock;
+      _proxyImpl.sendMessage(params, _MediaSource_setMasterClockName);
+    }
+    void getProducer(int streamIndex, Object producer) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _MediaSourceGetProducerParams();
+      params.streamIndex = streamIndex;
+      params.producer = producer;
+      _proxyImpl.sendMessage(params, _MediaSource_getProducerName);
+    }
+    void getPullModeProducer(int streamIndex, Object producer) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _MediaSourceGetPullModeProducerParams();
+      params.streamIndex = streamIndex;
+      params.producer = producer;
+      _proxyImpl.sendMessage(params, _MediaSource_getPullModeProducerName);
+    }
+    dynamic getStatus(int versionLastSeen,[Function responseFactory = null]) {
+      var params = new _MediaSourceGetStatusParams();
+      params.versionLastSeen = versionLastSeen;
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _MediaSource_getStatusName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    dynamic prepare([Function responseFactory = null]) {
+      var params = new _MediaSourcePrepareParams();
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _MediaSource_prepareName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+}
+
+
+class MediaSourceProxy implements bindings.ProxyBase {
+  final bindings.Proxy impl;
+  MediaSource ptr;
+
+  MediaSourceProxy(_MediaSourceProxyImpl proxyImpl) :
+      impl = proxyImpl,
+      ptr = new _MediaSourceProxyCalls(proxyImpl);
+
+  MediaSourceProxy.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) :
+      impl = new _MediaSourceProxyImpl.fromEndpoint(endpoint) {
+    ptr = new _MediaSourceProxyCalls(impl);
+  }
+
+  MediaSourceProxy.fromHandle(core.MojoHandle handle) :
+      impl = new _MediaSourceProxyImpl.fromHandle(handle) {
+    ptr = new _MediaSourceProxyCalls(impl);
+  }
+
+  MediaSourceProxy.unbound() :
+      impl = new _MediaSourceProxyImpl.unbound() {
+    ptr = new _MediaSourceProxyCalls(impl);
+  }
+
+  factory MediaSourceProxy.connectToService(
+      bindings.ServiceConnector s, String url, [String serviceName]) {
+    MediaSourceProxy p = new MediaSourceProxy.unbound();
+    s.connectToService(url, p, serviceName);
+    return p;
+  }
+
+  static MediaSourceProxy newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For MediaSourceProxy"));
+    return new MediaSourceProxy.fromEndpoint(endpoint);
+  }
+
+  String get serviceName => MediaSource.serviceName;
+
+  Future close({bool immediate: false}) => impl.close(immediate: immediate);
+
+  Future responseOrError(Future f) => impl.responseOrError(f);
+
+  Future get errorFuture => impl.errorFuture;
+
+  int get version => impl.version;
+
+  Future<int> queryVersion() => impl.queryVersion();
+
+  void requireVersion(int requiredVersion) {
+    impl.requireVersion(requiredVersion);
+  }
+
+  String toString() {
+    return "MediaSourceProxy($impl)";
+  }
+}
+
+
+class MediaSourceStub extends bindings.Stub {
+  MediaSource _impl = null;
+
+  MediaSourceStub.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint, [this._impl])
+      : super.fromEndpoint(endpoint);
+
+  MediaSourceStub.fromHandle(core.MojoHandle handle, [this._impl])
+      : super.fromHandle(handle);
+
+  MediaSourceStub.unbound() : super.unbound();
+
+  static MediaSourceStub newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For MediaSourceStub"));
+    return new MediaSourceStub.fromEndpoint(endpoint);
+  }
+
+
+  MediaSourceGetStreamsResponseParams _MediaSourceGetStreamsResponseParamsFactory(List<MediaSourceStreamDescriptor> streams) {
+    var mojo_factory_result = new MediaSourceGetStreamsResponseParams();
+    mojo_factory_result.streams = streams;
+    return mojo_factory_result;
+  }
+  MediaSourceGetClockDispositionResponseParams _MediaSourceGetClockDispositionResponseParamsFactory(media_clock_mojom.ClockDisposition clockDisposition) {
+    var mojo_factory_result = new MediaSourceGetClockDispositionResponseParams();
+    mojo_factory_result.clockDisposition = clockDisposition;
+    return mojo_factory_result;
+  }
+  MediaSourceGetStatusResponseParams _MediaSourceGetStatusResponseParamsFactory(int version, MediaSourceStatus status) {
+    var mojo_factory_result = new MediaSourceGetStatusResponseParams();
+    mojo_factory_result.version = version;
+    mojo_factory_result.status = status;
+    return mojo_factory_result;
+  }
+  MediaSourcePrepareResponseParams _MediaSourcePrepareResponseParamsFactory() {
+    var mojo_factory_result = new MediaSourcePrepareResponseParams();
+    return mojo_factory_result;
+  }
+
+  dynamic handleMessage(bindings.ServiceMessage message) {
+    if (bindings.ControlMessageHandler.isControlMessage(message)) {
+      return bindings.ControlMessageHandler.handleMessage(this,
+                                                          0,
+                                                          message);
+    }
+    assert(_impl != null);
+    switch (message.header.type) {
+      case _MediaSource_getStreamsName:
+        var params = _MediaSourceGetStreamsParams.deserialize(
+            message.payload);
+        var response = _impl.getStreams(_MediaSourceGetStreamsResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _MediaSource_getStreamsName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _MediaSource_getStreamsName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case _MediaSource_getClockDispositionName:
+        var params = _MediaSourceGetClockDispositionParams.deserialize(
+            message.payload);
+        var response = _impl.getClockDisposition(_MediaSourceGetClockDispositionResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _MediaSource_getClockDispositionName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _MediaSource_getClockDispositionName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case _MediaSource_getMasterClockName:
+        var params = _MediaSourceGetMasterClockParams.deserialize(
+            message.payload);
+        _impl.getMasterClock(params.masterClock);
+        break;
+      case _MediaSource_setMasterClockName:
+        var params = _MediaSourceSetMasterClockParams.deserialize(
+            message.payload);
+        _impl.setMasterClock(params.masterClock);
+        break;
+      case _MediaSource_getProducerName:
+        var params = _MediaSourceGetProducerParams.deserialize(
+            message.payload);
+        _impl.getProducer(params.streamIndex, params.producer);
+        break;
+      case _MediaSource_getPullModeProducerName:
+        var params = _MediaSourceGetPullModeProducerParams.deserialize(
+            message.payload);
+        _impl.getPullModeProducer(params.streamIndex, params.producer);
+        break;
+      case _MediaSource_getStatusName:
+        var params = _MediaSourceGetStatusParams.deserialize(
+            message.payload);
+        var response = _impl.getStatus(params.versionLastSeen,_MediaSourceGetStatusResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _MediaSource_getStatusName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _MediaSource_getStatusName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case _MediaSource_prepareName:
+        var params = _MediaSourcePrepareParams.deserialize(
+            message.payload);
+        var response = _impl.prepare(_MediaSourcePrepareResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _MediaSource_prepareName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _MediaSource_prepareName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+    return null;
+  }
+
+  MediaSource get impl => _impl;
+  set impl(MediaSource d) {
+    assert(_impl == null);
+    _impl = d;
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "MediaSourceStub($superString)";
+  }
+
+  int get version => 0;
+}
+
+
diff --git a/mojo/dart/packages/mojo_services/lib/mojo/media/media_state.mojom.dart b/mojo/dart/packages/mojo_services/lib/mojo/media/media_state.mojom.dart
new file mode 100644
index 0000000..fd5a9fb
--- /dev/null
+++ b/mojo/dart/packages/mojo_services/lib/mojo/media/media_state.mojom.dart
@@ -0,0 +1,84 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library media_state_mojom;
+
+import 'dart:async';
+
+import 'package:mojo/bindings.dart' as bindings;
+import 'package:mojo/core.dart' as core;
+
+class MediaState extends bindings.MojoEnum {
+  static const MediaState fault = const MediaState._(0);
+  static const MediaState unprepared = const MediaState._(1);
+  static const MediaState paused = const MediaState._(2);
+  static const MediaState playing = const MediaState._(3);
+  static const MediaState ended = const MediaState._(4);
+
+  const MediaState._(int v) : super(v);
+
+  static const Map<String, MediaState> valuesMap = const {
+    "fault": fault,
+    "unprepared": unprepared,
+    "paused": paused,
+    "playing": playing,
+    "ended": ended,
+  };
+  static const List<MediaState> values = const [
+    fault,
+    unprepared,
+    paused,
+    playing,
+    ended,
+  ];
+
+  static MediaState valueOf(String name) => valuesMap[name];
+
+  factory MediaState(int v) {
+    switch (v) {
+      case 0:
+        return fault;
+      case 1:
+        return unprepared;
+      case 2:
+        return paused;
+      case 3:
+        return playing;
+      case 4:
+        return ended;
+      default:
+        return null;
+    }
+  }
+
+  static MediaState decode(bindings.Decoder decoder0, int offset) {
+    int v = decoder0.decodeUint32(offset);
+    MediaState result = new MediaState(v);
+    if (result == null) {
+      throw new bindings.MojoCodecError(
+          'Bad value $v for enum MediaState.');
+    }
+    return result;
+  }
+
+  String toString() {
+    switch(this) {
+      case fault:
+        return 'MediaState.fault';
+      case unprepared:
+        return 'MediaState.unprepared';
+      case paused:
+        return 'MediaState.paused';
+      case playing:
+        return 'MediaState.playing';
+      case ended:
+        return 'MediaState.ended';
+    }
+  }
+
+  int toJson() => mojoEnumValue;
+}
+
+
+
diff --git a/mojo/dart/packages/mojo_services/lib/mojo/media/media_transport.mojom.dart b/mojo/dart/packages/mojo_services/lib/mojo/media/media_transport.mojom.dart
new file mode 100644
index 0000000..507df9f
--- /dev/null
+++ b/mojo/dart/packages/mojo_services/lib/mojo/media/media_transport.mojom.dart
@@ -0,0 +1,1558 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library media_transport_mojom;
+
+import 'dart:async';
+
+import 'package:mojo/bindings.dart' as bindings;
+import 'package:mojo/core.dart' as core;
+import 'package:mojo_services/mojo/media/media_common.mojom.dart' as media_common_mojom;
+import 'package:mojo_services/mojo/media/media_pipe.mojom.dart' as media_pipe_mojom;
+import 'package:mojo_services/mojo/media/media_types.mojom.dart' as media_types_mojom;
+
+
+
+class _MediaProducerConnectParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  Object consumer = null;
+
+  _MediaProducerConnectParams() : super(kVersions.last.size);
+
+  static _MediaProducerConnectParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaProducerConnectParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaProducerConnectParams result = new _MediaProducerConnectParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.consumer = decoder0.decodeServiceInterface(8, false, MediaConsumerProxy.newFromEndpoint);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeInterface(consumer, 8, false);
+  }
+
+  String toString() {
+    return "_MediaProducerConnectParams("
+           "consumer: $consumer" ")";
+  }
+
+  Map toJson() {
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
+  }
+}
+
+
+class MediaProducerConnectResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  MediaProducerConnectResponseParams() : super(kVersions.last.size);
+
+  static MediaProducerConnectResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaProducerConnectResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaProducerConnectResponseParams result = new MediaProducerConnectResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "MediaProducerConnectResponseParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+class _MediaProducerDisconnectParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  _MediaProducerDisconnectParams() : super(kVersions.last.size);
+
+  static _MediaProducerDisconnectParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaProducerDisconnectParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaProducerDisconnectParams result = new _MediaProducerDisconnectParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "_MediaProducerDisconnectParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+class _MediaPullModeProducerGetBufferParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  _MediaPullModeProducerGetBufferParams() : super(kVersions.last.size);
+
+  static _MediaPullModeProducerGetBufferParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaPullModeProducerGetBufferParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaPullModeProducerGetBufferParams result = new _MediaPullModeProducerGetBufferParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "_MediaPullModeProducerGetBufferParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+class MediaPullModeProducerGetBufferResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  core.MojoSharedBuffer buffer = null;
+
+  MediaPullModeProducerGetBufferResponseParams() : super(kVersions.last.size);
+
+  static MediaPullModeProducerGetBufferResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaPullModeProducerGetBufferResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaPullModeProducerGetBufferResponseParams result = new MediaPullModeProducerGetBufferResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.buffer = decoder0.decodeSharedBufferHandle(8, false);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeSharedBufferHandle(buffer, 8, false);
+  }
+
+  String toString() {
+    return "MediaPullModeProducerGetBufferResponseParams("
+           "buffer: $buffer" ")";
+  }
+
+  Map toJson() {
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
+  }
+}
+
+
+class _MediaPullModeProducerPullPacketParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  media_pipe_mojom.MediaPacket toRelease = null;
+
+  _MediaPullModeProducerPullPacketParams() : super(kVersions.last.size);
+
+  static _MediaPullModeProducerPullPacketParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaPullModeProducerPullPacketParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaPullModeProducerPullPacketParams result = new _MediaPullModeProducerPullPacketParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(8, true);
+      result.toRelease = media_pipe_mojom.MediaPacket.decode(decoder1);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeStruct(toRelease, 8, true);
+  }
+
+  String toString() {
+    return "_MediaPullModeProducerPullPacketParams("
+           "toRelease: $toRelease" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["toRelease"] = toRelease;
+    return map;
+  }
+}
+
+
+class MediaPullModeProducerPullPacketResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  media_pipe_mojom.MediaPacket packet = null;
+
+  MediaPullModeProducerPullPacketResponseParams() : super(kVersions.last.size);
+
+  static MediaPullModeProducerPullPacketResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaPullModeProducerPullPacketResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaPullModeProducerPullPacketResponseParams result = new MediaPullModeProducerPullPacketResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(8, false);
+      result.packet = media_pipe_mojom.MediaPacket.decode(decoder1);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeStruct(packet, 8, false);
+  }
+
+  String toString() {
+    return "MediaPullModeProducerPullPacketResponseParams("
+           "packet: $packet" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["packet"] = packet;
+    return map;
+  }
+}
+
+
+class _MediaPullModeProducerReleasePacketParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  media_pipe_mojom.MediaPacket toRelease = null;
+
+  _MediaPullModeProducerReleasePacketParams() : super(kVersions.last.size);
+
+  static _MediaPullModeProducerReleasePacketParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaPullModeProducerReleasePacketParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaPullModeProducerReleasePacketParams result = new _MediaPullModeProducerReleasePacketParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(8, false);
+      result.toRelease = media_pipe_mojom.MediaPacket.decode(decoder1);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeStruct(toRelease, 8, false);
+  }
+
+  String toString() {
+    return "_MediaPullModeProducerReleasePacketParams("
+           "toRelease: $toRelease" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["toRelease"] = toRelease;
+    return map;
+  }
+}
+
+
+class _MediaConsumerSetBufferParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  core.MojoSharedBuffer buffer = null;
+  int size = 0;
+
+  _MediaConsumerSetBufferParams() : super(kVersions.last.size);
+
+  static _MediaConsumerSetBufferParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaConsumerSetBufferParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaConsumerSetBufferParams result = new _MediaConsumerSetBufferParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.buffer = decoder0.decodeSharedBufferHandle(8, false);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.size = decoder0.decodeUint64(16);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeSharedBufferHandle(buffer, 8, false);
+    
+    encoder0.encodeUint64(size, 16);
+  }
+
+  String toString() {
+    return "_MediaConsumerSetBufferParams("
+           "buffer: $buffer" ", "
+           "size: $size" ")";
+  }
+
+  Map toJson() {
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
+  }
+}
+
+
+class MediaConsumerSetBufferResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  MediaConsumerSetBufferResponseParams() : super(kVersions.last.size);
+
+  static MediaConsumerSetBufferResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaConsumerSetBufferResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaConsumerSetBufferResponseParams result = new MediaConsumerSetBufferResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "MediaConsumerSetBufferResponseParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+class _MediaConsumerPushPacketParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  media_pipe_mojom.MediaPacket packet = null;
+
+  _MediaConsumerPushPacketParams() : super(kVersions.last.size);
+
+  static _MediaConsumerPushPacketParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _MediaConsumerPushPacketParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _MediaConsumerPushPacketParams result = new _MediaConsumerPushPacketParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(8, false);
+      result.packet = media_pipe_mojom.MediaPacket.decode(decoder1);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeStruct(packet, 8, false);
+  }
+
+  String toString() {
+    return "_MediaConsumerPushPacketParams("
+           "packet: $packet" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["packet"] = packet;
+    return map;
+  }
+}
+
+
+class MediaConsumerPushPacketResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  MediaConsumerPushPacketResponseParams() : super(kVersions.last.size);
+
+  static MediaConsumerPushPacketResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaConsumerPushPacketResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaConsumerPushPacketResponseParams result = new MediaConsumerPushPacketResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "MediaConsumerPushPacketResponseParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+const int _MediaProducer_connectName = 0;
+const int _MediaProducer_disconnectName = 1;
+
+abstract class MediaProducer {
+  static const String serviceName = null;
+  dynamic connect(Object consumer,[Function responseFactory = null]);
+  void disconnect();
+}
+
+
+class _MediaProducerProxyImpl extends bindings.Proxy {
+  _MediaProducerProxyImpl.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
+
+  _MediaProducerProxyImpl.fromHandle(core.MojoHandle handle) :
+      super.fromHandle(handle);
+
+  _MediaProducerProxyImpl.unbound() : super.unbound();
+
+  static _MediaProducerProxyImpl newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For _MediaProducerProxyImpl"));
+    return new _MediaProducerProxyImpl.fromEndpoint(endpoint);
+  }
+
+  void handleResponse(bindings.ServiceMessage message) {
+    switch (message.header.type) {
+      case _MediaProducer_connectName:
+        var r = MediaProducerConnectResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      default:
+        proxyError("Unexpected message type: ${message.header.type}");
+        close(immediate: true);
+        break;
+    }
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "_MediaProducerProxyImpl($superString)";
+  }
+}
+
+
+class _MediaProducerProxyCalls implements MediaProducer {
+  _MediaProducerProxyImpl _proxyImpl;
+
+  _MediaProducerProxyCalls(this._proxyImpl);
+    dynamic connect(Object consumer,[Function responseFactory = null]) {
+      var params = new _MediaProducerConnectParams();
+      params.consumer = consumer;
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _MediaProducer_connectName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    void disconnect() {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _MediaProducerDisconnectParams();
+      _proxyImpl.sendMessage(params, _MediaProducer_disconnectName);
+    }
+}
+
+
+class MediaProducerProxy implements bindings.ProxyBase {
+  final bindings.Proxy impl;
+  MediaProducer ptr;
+
+  MediaProducerProxy(_MediaProducerProxyImpl proxyImpl) :
+      impl = proxyImpl,
+      ptr = new _MediaProducerProxyCalls(proxyImpl);
+
+  MediaProducerProxy.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) :
+      impl = new _MediaProducerProxyImpl.fromEndpoint(endpoint) {
+    ptr = new _MediaProducerProxyCalls(impl);
+  }
+
+  MediaProducerProxy.fromHandle(core.MojoHandle handle) :
+      impl = new _MediaProducerProxyImpl.fromHandle(handle) {
+    ptr = new _MediaProducerProxyCalls(impl);
+  }
+
+  MediaProducerProxy.unbound() :
+      impl = new _MediaProducerProxyImpl.unbound() {
+    ptr = new _MediaProducerProxyCalls(impl);
+  }
+
+  factory MediaProducerProxy.connectToService(
+      bindings.ServiceConnector s, String url, [String serviceName]) {
+    MediaProducerProxy p = new MediaProducerProxy.unbound();
+    s.connectToService(url, p, serviceName);
+    return p;
+  }
+
+  static MediaProducerProxy newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For MediaProducerProxy"));
+    return new MediaProducerProxy.fromEndpoint(endpoint);
+  }
+
+  String get serviceName => MediaProducer.serviceName;
+
+  Future close({bool immediate: false}) => impl.close(immediate: immediate);
+
+  Future responseOrError(Future f) => impl.responseOrError(f);
+
+  Future get errorFuture => impl.errorFuture;
+
+  int get version => impl.version;
+
+  Future<int> queryVersion() => impl.queryVersion();
+
+  void requireVersion(int requiredVersion) {
+    impl.requireVersion(requiredVersion);
+  }
+
+  String toString() {
+    return "MediaProducerProxy($impl)";
+  }
+}
+
+
+class MediaProducerStub extends bindings.Stub {
+  MediaProducer _impl = null;
+
+  MediaProducerStub.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint, [this._impl])
+      : super.fromEndpoint(endpoint);
+
+  MediaProducerStub.fromHandle(core.MojoHandle handle, [this._impl])
+      : super.fromHandle(handle);
+
+  MediaProducerStub.unbound() : super.unbound();
+
+  static MediaProducerStub newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For MediaProducerStub"));
+    return new MediaProducerStub.fromEndpoint(endpoint);
+  }
+
+
+  MediaProducerConnectResponseParams _MediaProducerConnectResponseParamsFactory() {
+    var mojo_factory_result = new MediaProducerConnectResponseParams();
+    return mojo_factory_result;
+  }
+
+  dynamic handleMessage(bindings.ServiceMessage message) {
+    if (bindings.ControlMessageHandler.isControlMessage(message)) {
+      return bindings.ControlMessageHandler.handleMessage(this,
+                                                          0,
+                                                          message);
+    }
+    assert(_impl != null);
+    switch (message.header.type) {
+      case _MediaProducer_connectName:
+        var params = _MediaProducerConnectParams.deserialize(
+            message.payload);
+        var response = _impl.connect(params.consumer,_MediaProducerConnectResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _MediaProducer_connectName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _MediaProducer_connectName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case _MediaProducer_disconnectName:
+        var params = _MediaProducerDisconnectParams.deserialize(
+            message.payload);
+        _impl.disconnect();
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+    return null;
+  }
+
+  MediaProducer get impl => _impl;
+  set impl(MediaProducer d) {
+    assert(_impl == null);
+    _impl = d;
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "MediaProducerStub($superString)";
+  }
+
+  int get version => 0;
+}
+
+const int _MediaPullModeProducer_getBufferName = 0;
+const int _MediaPullModeProducer_pullPacketName = 1;
+const int _MediaPullModeProducer_releasePacketName = 2;
+
+abstract class MediaPullModeProducer {
+  static const String serviceName = null;
+  dynamic getBuffer([Function responseFactory = null]);
+  dynamic pullPacket(media_pipe_mojom.MediaPacket toRelease,[Function responseFactory = null]);
+  void releasePacket(media_pipe_mojom.MediaPacket toRelease);
+}
+
+
+class _MediaPullModeProducerProxyImpl extends bindings.Proxy {
+  _MediaPullModeProducerProxyImpl.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
+
+  _MediaPullModeProducerProxyImpl.fromHandle(core.MojoHandle handle) :
+      super.fromHandle(handle);
+
+  _MediaPullModeProducerProxyImpl.unbound() : super.unbound();
+
+  static _MediaPullModeProducerProxyImpl newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For _MediaPullModeProducerProxyImpl"));
+    return new _MediaPullModeProducerProxyImpl.fromEndpoint(endpoint);
+  }
+
+  void handleResponse(bindings.ServiceMessage message) {
+    switch (message.header.type) {
+      case _MediaPullModeProducer_getBufferName:
+        var r = MediaPullModeProducerGetBufferResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      case _MediaPullModeProducer_pullPacketName:
+        var r = MediaPullModeProducerPullPacketResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      default:
+        proxyError("Unexpected message type: ${message.header.type}");
+        close(immediate: true);
+        break;
+    }
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "_MediaPullModeProducerProxyImpl($superString)";
+  }
+}
+
+
+class _MediaPullModeProducerProxyCalls implements MediaPullModeProducer {
+  _MediaPullModeProducerProxyImpl _proxyImpl;
+
+  _MediaPullModeProducerProxyCalls(this._proxyImpl);
+    dynamic getBuffer([Function responseFactory = null]) {
+      var params = new _MediaPullModeProducerGetBufferParams();
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _MediaPullModeProducer_getBufferName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    dynamic pullPacket(media_pipe_mojom.MediaPacket toRelease,[Function responseFactory = null]) {
+      var params = new _MediaPullModeProducerPullPacketParams();
+      params.toRelease = toRelease;
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _MediaPullModeProducer_pullPacketName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    void releasePacket(media_pipe_mojom.MediaPacket toRelease) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _MediaPullModeProducerReleasePacketParams();
+      params.toRelease = toRelease;
+      _proxyImpl.sendMessage(params, _MediaPullModeProducer_releasePacketName);
+    }
+}
+
+
+class MediaPullModeProducerProxy implements bindings.ProxyBase {
+  final bindings.Proxy impl;
+  MediaPullModeProducer ptr;
+
+  MediaPullModeProducerProxy(_MediaPullModeProducerProxyImpl proxyImpl) :
+      impl = proxyImpl,
+      ptr = new _MediaPullModeProducerProxyCalls(proxyImpl);
+
+  MediaPullModeProducerProxy.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) :
+      impl = new _MediaPullModeProducerProxyImpl.fromEndpoint(endpoint) {
+    ptr = new _MediaPullModeProducerProxyCalls(impl);
+  }
+
+  MediaPullModeProducerProxy.fromHandle(core.MojoHandle handle) :
+      impl = new _MediaPullModeProducerProxyImpl.fromHandle(handle) {
+    ptr = new _MediaPullModeProducerProxyCalls(impl);
+  }
+
+  MediaPullModeProducerProxy.unbound() :
+      impl = new _MediaPullModeProducerProxyImpl.unbound() {
+    ptr = new _MediaPullModeProducerProxyCalls(impl);
+  }
+
+  factory MediaPullModeProducerProxy.connectToService(
+      bindings.ServiceConnector s, String url, [String serviceName]) {
+    MediaPullModeProducerProxy p = new MediaPullModeProducerProxy.unbound();
+    s.connectToService(url, p, serviceName);
+    return p;
+  }
+
+  static MediaPullModeProducerProxy newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For MediaPullModeProducerProxy"));
+    return new MediaPullModeProducerProxy.fromEndpoint(endpoint);
+  }
+
+  String get serviceName => MediaPullModeProducer.serviceName;
+
+  Future close({bool immediate: false}) => impl.close(immediate: immediate);
+
+  Future responseOrError(Future f) => impl.responseOrError(f);
+
+  Future get errorFuture => impl.errorFuture;
+
+  int get version => impl.version;
+
+  Future<int> queryVersion() => impl.queryVersion();
+
+  void requireVersion(int requiredVersion) {
+    impl.requireVersion(requiredVersion);
+  }
+
+  String toString() {
+    return "MediaPullModeProducerProxy($impl)";
+  }
+}
+
+
+class MediaPullModeProducerStub extends bindings.Stub {
+  MediaPullModeProducer _impl = null;
+
+  MediaPullModeProducerStub.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint, [this._impl])
+      : super.fromEndpoint(endpoint);
+
+  MediaPullModeProducerStub.fromHandle(core.MojoHandle handle, [this._impl])
+      : super.fromHandle(handle);
+
+  MediaPullModeProducerStub.unbound() : super.unbound();
+
+  static MediaPullModeProducerStub newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For MediaPullModeProducerStub"));
+    return new MediaPullModeProducerStub.fromEndpoint(endpoint);
+  }
+
+
+  MediaPullModeProducerGetBufferResponseParams _MediaPullModeProducerGetBufferResponseParamsFactory(core.MojoSharedBuffer buffer) {
+    var mojo_factory_result = new MediaPullModeProducerGetBufferResponseParams();
+    mojo_factory_result.buffer = buffer;
+    return mojo_factory_result;
+  }
+  MediaPullModeProducerPullPacketResponseParams _MediaPullModeProducerPullPacketResponseParamsFactory(media_pipe_mojom.MediaPacket packet) {
+    var mojo_factory_result = new MediaPullModeProducerPullPacketResponseParams();
+    mojo_factory_result.packet = packet;
+    return mojo_factory_result;
+  }
+
+  dynamic handleMessage(bindings.ServiceMessage message) {
+    if (bindings.ControlMessageHandler.isControlMessage(message)) {
+      return bindings.ControlMessageHandler.handleMessage(this,
+                                                          0,
+                                                          message);
+    }
+    assert(_impl != null);
+    switch (message.header.type) {
+      case _MediaPullModeProducer_getBufferName:
+        var params = _MediaPullModeProducerGetBufferParams.deserialize(
+            message.payload);
+        var response = _impl.getBuffer(_MediaPullModeProducerGetBufferResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _MediaPullModeProducer_getBufferName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _MediaPullModeProducer_getBufferName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case _MediaPullModeProducer_pullPacketName:
+        var params = _MediaPullModeProducerPullPacketParams.deserialize(
+            message.payload);
+        var response = _impl.pullPacket(params.toRelease,_MediaPullModeProducerPullPacketResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _MediaPullModeProducer_pullPacketName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _MediaPullModeProducer_pullPacketName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case _MediaPullModeProducer_releasePacketName:
+        var params = _MediaPullModeProducerReleasePacketParams.deserialize(
+            message.payload);
+        _impl.releasePacket(params.toRelease);
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+    return null;
+  }
+
+  MediaPullModeProducer get impl => _impl;
+  set impl(MediaPullModeProducer d) {
+    assert(_impl == null);
+    _impl = d;
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "MediaPullModeProducerStub($superString)";
+  }
+
+  int get version => 0;
+}
+
+const int _MediaConsumer_setBufferName = 0;
+const int _MediaConsumer_pushPacketName = 1;
+
+abstract class MediaConsumer {
+  static const String serviceName = null;
+  dynamic setBuffer(core.MojoSharedBuffer buffer,int size,[Function responseFactory = null]);
+  dynamic pushPacket(media_pipe_mojom.MediaPacket packet,[Function responseFactory = null]);
+}
+
+
+class _MediaConsumerProxyImpl extends bindings.Proxy {
+  _MediaConsumerProxyImpl.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
+
+  _MediaConsumerProxyImpl.fromHandle(core.MojoHandle handle) :
+      super.fromHandle(handle);
+
+  _MediaConsumerProxyImpl.unbound() : super.unbound();
+
+  static _MediaConsumerProxyImpl newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For _MediaConsumerProxyImpl"));
+    return new _MediaConsumerProxyImpl.fromEndpoint(endpoint);
+  }
+
+  void handleResponse(bindings.ServiceMessage message) {
+    switch (message.header.type) {
+      case _MediaConsumer_setBufferName:
+        var r = MediaConsumerSetBufferResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      case _MediaConsumer_pushPacketName:
+        var r = MediaConsumerPushPacketResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      default:
+        proxyError("Unexpected message type: ${message.header.type}");
+        close(immediate: true);
+        break;
+    }
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "_MediaConsumerProxyImpl($superString)";
+  }
+}
+
+
+class _MediaConsumerProxyCalls implements MediaConsumer {
+  _MediaConsumerProxyImpl _proxyImpl;
+
+  _MediaConsumerProxyCalls(this._proxyImpl);
+    dynamic setBuffer(core.MojoSharedBuffer buffer,int size,[Function responseFactory = null]) {
+      var params = new _MediaConsumerSetBufferParams();
+      params.buffer = buffer;
+      params.size = size;
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _MediaConsumer_setBufferName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    dynamic pushPacket(media_pipe_mojom.MediaPacket packet,[Function responseFactory = null]) {
+      var params = new _MediaConsumerPushPacketParams();
+      params.packet = packet;
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _MediaConsumer_pushPacketName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+}
+
+
+class MediaConsumerProxy implements bindings.ProxyBase {
+  final bindings.Proxy impl;
+  MediaConsumer ptr;
+
+  MediaConsumerProxy(_MediaConsumerProxyImpl proxyImpl) :
+      impl = proxyImpl,
+      ptr = new _MediaConsumerProxyCalls(proxyImpl);
+
+  MediaConsumerProxy.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) :
+      impl = new _MediaConsumerProxyImpl.fromEndpoint(endpoint) {
+    ptr = new _MediaConsumerProxyCalls(impl);
+  }
+
+  MediaConsumerProxy.fromHandle(core.MojoHandle handle) :
+      impl = new _MediaConsumerProxyImpl.fromHandle(handle) {
+    ptr = new _MediaConsumerProxyCalls(impl);
+  }
+
+  MediaConsumerProxy.unbound() :
+      impl = new _MediaConsumerProxyImpl.unbound() {
+    ptr = new _MediaConsumerProxyCalls(impl);
+  }
+
+  factory MediaConsumerProxy.connectToService(
+      bindings.ServiceConnector s, String url, [String serviceName]) {
+    MediaConsumerProxy p = new MediaConsumerProxy.unbound();
+    s.connectToService(url, p, serviceName);
+    return p;
+  }
+
+  static MediaConsumerProxy newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For MediaConsumerProxy"));
+    return new MediaConsumerProxy.fromEndpoint(endpoint);
+  }
+
+  String get serviceName => MediaConsumer.serviceName;
+
+  Future close({bool immediate: false}) => impl.close(immediate: immediate);
+
+  Future responseOrError(Future f) => impl.responseOrError(f);
+
+  Future get errorFuture => impl.errorFuture;
+
+  int get version => impl.version;
+
+  Future<int> queryVersion() => impl.queryVersion();
+
+  void requireVersion(int requiredVersion) {
+    impl.requireVersion(requiredVersion);
+  }
+
+  String toString() {
+    return "MediaConsumerProxy($impl)";
+  }
+}
+
+
+class MediaConsumerStub extends bindings.Stub {
+  MediaConsumer _impl = null;
+
+  MediaConsumerStub.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint, [this._impl])
+      : super.fromEndpoint(endpoint);
+
+  MediaConsumerStub.fromHandle(core.MojoHandle handle, [this._impl])
+      : super.fromHandle(handle);
+
+  MediaConsumerStub.unbound() : super.unbound();
+
+  static MediaConsumerStub newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For MediaConsumerStub"));
+    return new MediaConsumerStub.fromEndpoint(endpoint);
+  }
+
+
+  MediaConsumerSetBufferResponseParams _MediaConsumerSetBufferResponseParamsFactory() {
+    var mojo_factory_result = new MediaConsumerSetBufferResponseParams();
+    return mojo_factory_result;
+  }
+  MediaConsumerPushPacketResponseParams _MediaConsumerPushPacketResponseParamsFactory() {
+    var mojo_factory_result = new MediaConsumerPushPacketResponseParams();
+    return mojo_factory_result;
+  }
+
+  dynamic handleMessage(bindings.ServiceMessage message) {
+    if (bindings.ControlMessageHandler.isControlMessage(message)) {
+      return bindings.ControlMessageHandler.handleMessage(this,
+                                                          0,
+                                                          message);
+    }
+    assert(_impl != null);
+    switch (message.header.type) {
+      case _MediaConsumer_setBufferName:
+        var params = _MediaConsumerSetBufferParams.deserialize(
+            message.payload);
+        var response = _impl.setBuffer(params.buffer,params.size,_MediaConsumerSetBufferResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _MediaConsumer_setBufferName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _MediaConsumer_setBufferName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case _MediaConsumer_pushPacketName:
+        var params = _MediaConsumerPushPacketParams.deserialize(
+            message.payload);
+        var response = _impl.pushPacket(params.packet,_MediaConsumerPushPacketResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _MediaConsumer_pushPacketName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _MediaConsumer_pushPacketName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+    return null;
+  }
+
+  MediaConsumer get impl => _impl;
+  set impl(MediaConsumer d) {
+    assert(_impl == null);
+    _impl = d;
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "MediaConsumerStub($superString)";
+  }
+
+  int get version => 0;
+}
+
+
diff --git a/mojo/dart/packages/mojo_services/lib/mojo/media/media_types.mojom.dart b/mojo/dart/packages/mojo_services/lib/mojo/media/media_types.mojom.dart
new file mode 100644
index 0000000..d2c0b8d
--- /dev/null
+++ b/mojo/dart/packages/mojo_services/lib/mojo/media/media_types.mojom.dart
@@ -0,0 +1,2040 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library media_types_mojom;
+
+import 'dart:async';
+
+import 'package:mojo/bindings.dart' as bindings;
+import 'package:mojo/core.dart' as core;
+
+class MediaTypeScheme extends bindings.MojoEnum {
+  static const MediaTypeScheme unknown = const MediaTypeScheme._(0);
+  static const MediaTypeScheme none = const MediaTypeScheme._(1);
+  static const MediaTypeScheme anyElementary = const MediaTypeScheme._(2);
+  static const MediaTypeScheme anyAudio = const MediaTypeScheme._(3);
+  static const MediaTypeScheme anyVideo = const MediaTypeScheme._(4);
+  static const MediaTypeScheme anySubpicture = const MediaTypeScheme._(5);
+  static const MediaTypeScheme anyText = const MediaTypeScheme._(6);
+  static const MediaTypeScheme anyMultiplexed = const MediaTypeScheme._(7);
+  static const MediaTypeScheme any = const MediaTypeScheme._(8);
+  static const MediaTypeScheme multiplexed = const MediaTypeScheme._(9);
+  static const MediaTypeScheme lpcm = const MediaTypeScheme._(10);
+  static const MediaTypeScheme compressedAudio = const MediaTypeScheme._(11);
+  static const MediaTypeScheme video = const MediaTypeScheme._(12);
+
+  const MediaTypeScheme._(int v) : super(v);
+
+  static const Map<String, MediaTypeScheme> valuesMap = const {
+    "unknown": unknown,
+    "none": none,
+    "anyElementary": anyElementary,
+    "anyAudio": anyAudio,
+    "anyVideo": anyVideo,
+    "anySubpicture": anySubpicture,
+    "anyText": anyText,
+    "anyMultiplexed": anyMultiplexed,
+    "any": any,
+    "multiplexed": multiplexed,
+    "lpcm": lpcm,
+    "compressedAudio": compressedAudio,
+    "video": video,
+  };
+  static const List<MediaTypeScheme> values = const [
+    unknown,
+    none,
+    anyElementary,
+    anyAudio,
+    anyVideo,
+    anySubpicture,
+    anyText,
+    anyMultiplexed,
+    any,
+    multiplexed,
+    lpcm,
+    compressedAudio,
+    video,
+  ];
+
+  static MediaTypeScheme valueOf(String name) => valuesMap[name];
+
+  factory MediaTypeScheme(int v) {
+    switch (v) {
+      case 0:
+        return unknown;
+      case 1:
+        return none;
+      case 2:
+        return anyElementary;
+      case 3:
+        return anyAudio;
+      case 4:
+        return anyVideo;
+      case 5:
+        return anySubpicture;
+      case 6:
+        return anyText;
+      case 7:
+        return anyMultiplexed;
+      case 8:
+        return any;
+      case 9:
+        return multiplexed;
+      case 10:
+        return lpcm;
+      case 11:
+        return compressedAudio;
+      case 12:
+        return video;
+      default:
+        return null;
+    }
+  }
+
+  static MediaTypeScheme decode(bindings.Decoder decoder0, int offset) {
+    int v = decoder0.decodeUint32(offset);
+    MediaTypeScheme result = new MediaTypeScheme(v);
+    if (result == null) {
+      throw new bindings.MojoCodecError(
+          'Bad value $v for enum MediaTypeScheme.');
+    }
+    return result;
+  }
+
+  String toString() {
+    switch(this) {
+      case unknown:
+        return 'MediaTypeScheme.unknown';
+      case none:
+        return 'MediaTypeScheme.none';
+      case anyElementary:
+        return 'MediaTypeScheme.anyElementary';
+      case anyAudio:
+        return 'MediaTypeScheme.anyAudio';
+      case anyVideo:
+        return 'MediaTypeScheme.anyVideo';
+      case anySubpicture:
+        return 'MediaTypeScheme.anySubpicture';
+      case anyText:
+        return 'MediaTypeScheme.anyText';
+      case anyMultiplexed:
+        return 'MediaTypeScheme.anyMultiplexed';
+      case any:
+        return 'MediaTypeScheme.any';
+      case multiplexed:
+        return 'MediaTypeScheme.multiplexed';
+      case lpcm:
+        return 'MediaTypeScheme.lpcm';
+      case compressedAudio:
+        return 'MediaTypeScheme.compressedAudio';
+      case video:
+        return 'MediaTypeScheme.video';
+    }
+  }
+
+  int toJson() => mojoEnumValue;
+}
+
+class LpcmSampleFormat extends bindings.MojoEnum {
+  static const LpcmSampleFormat unknown = const LpcmSampleFormat._(0);
+  static const LpcmSampleFormat any = const LpcmSampleFormat._(1);
+  static const LpcmSampleFormat unsigned8 = const LpcmSampleFormat._(2);
+  static const LpcmSampleFormat signed16 = const LpcmSampleFormat._(3);
+  static const LpcmSampleFormat signed24In32 = const LpcmSampleFormat._(4);
+  static const LpcmSampleFormat float = const LpcmSampleFormat._(5);
+
+  const LpcmSampleFormat._(int v) : super(v);
+
+  static const Map<String, LpcmSampleFormat> valuesMap = const {
+    "unknown": unknown,
+    "any": any,
+    "unsigned8": unsigned8,
+    "signed16": signed16,
+    "signed24In32": signed24In32,
+    "float": float,
+  };
+  static const List<LpcmSampleFormat> values = const [
+    unknown,
+    any,
+    unsigned8,
+    signed16,
+    signed24In32,
+    float,
+  ];
+
+  static LpcmSampleFormat valueOf(String name) => valuesMap[name];
+
+  factory LpcmSampleFormat(int v) {
+    switch (v) {
+      case 0:
+        return unknown;
+      case 1:
+        return any;
+      case 2:
+        return unsigned8;
+      case 3:
+        return signed16;
+      case 4:
+        return signed24In32;
+      case 5:
+        return float;
+      default:
+        return null;
+    }
+  }
+
+  static LpcmSampleFormat decode(bindings.Decoder decoder0, int offset) {
+    int v = decoder0.decodeUint32(offset);
+    LpcmSampleFormat result = new LpcmSampleFormat(v);
+    if (result == null) {
+      throw new bindings.MojoCodecError(
+          'Bad value $v for enum LpcmSampleFormat.');
+    }
+    return result;
+  }
+
+  String toString() {
+    switch(this) {
+      case unknown:
+        return 'LpcmSampleFormat.unknown';
+      case any:
+        return 'LpcmSampleFormat.any';
+      case unsigned8:
+        return 'LpcmSampleFormat.unsigned8';
+      case signed16:
+        return 'LpcmSampleFormat.signed16';
+      case signed24In32:
+        return 'LpcmSampleFormat.signed24In32';
+      case float:
+        return 'LpcmSampleFormat.float';
+    }
+  }
+
+  int toJson() => mojoEnumValue;
+}
+
+class AudioEncoding extends bindings.MojoEnum {
+  static const AudioEncoding unknown = const AudioEncoding._(0);
+  static const AudioEncoding any = const AudioEncoding._(1);
+  static const AudioEncoding vorbis = const AudioEncoding._(2);
+
+  const AudioEncoding._(int v) : super(v);
+
+  static const Map<String, AudioEncoding> valuesMap = const {
+    "unknown": unknown,
+    "any": any,
+    "vorbis": vorbis,
+  };
+  static const List<AudioEncoding> values = const [
+    unknown,
+    any,
+    vorbis,
+  ];
+
+  static AudioEncoding valueOf(String name) => valuesMap[name];
+
+  factory AudioEncoding(int v) {
+    switch (v) {
+      case 0:
+        return unknown;
+      case 1:
+        return any;
+      case 2:
+        return vorbis;
+      default:
+        return null;
+    }
+  }
+
+  static AudioEncoding decode(bindings.Decoder decoder0, int offset) {
+    int v = decoder0.decodeUint32(offset);
+    AudioEncoding result = new AudioEncoding(v);
+    if (result == null) {
+      throw new bindings.MojoCodecError(
+          'Bad value $v for enum AudioEncoding.');
+    }
+    return result;
+  }
+
+  String toString() {
+    switch(this) {
+      case unknown:
+        return 'AudioEncoding.unknown';
+      case any:
+        return 'AudioEncoding.any';
+      case vorbis:
+        return 'AudioEncoding.vorbis';
+    }
+  }
+
+  int toJson() => mojoEnumValue;
+}
+
+class VideoEncoding extends bindings.MojoEnum {
+  static const VideoEncoding unknown = const VideoEncoding._(0);
+  static const VideoEncoding any = const VideoEncoding._(1);
+  static const VideoEncoding theora = const VideoEncoding._(2);
+  static const VideoEncoding vp8 = const VideoEncoding._(3);
+
+  const VideoEncoding._(int v) : super(v);
+
+  static const Map<String, VideoEncoding> valuesMap = const {
+    "unknown": unknown,
+    "any": any,
+    "theora": theora,
+    "vp8": vp8,
+  };
+  static const List<VideoEncoding> values = const [
+    unknown,
+    any,
+    theora,
+    vp8,
+  ];
+
+  static VideoEncoding valueOf(String name) => valuesMap[name];
+
+  factory VideoEncoding(int v) {
+    switch (v) {
+      case 0:
+        return unknown;
+      case 1:
+        return any;
+      case 2:
+        return theora;
+      case 3:
+        return vp8;
+      default:
+        return null;
+    }
+  }
+
+  static VideoEncoding decode(bindings.Decoder decoder0, int offset) {
+    int v = decoder0.decodeUint32(offset);
+    VideoEncoding result = new VideoEncoding(v);
+    if (result == null) {
+      throw new bindings.MojoCodecError(
+          'Bad value $v for enum VideoEncoding.');
+    }
+    return result;
+  }
+
+  String toString() {
+    switch(this) {
+      case unknown:
+        return 'VideoEncoding.unknown';
+      case any:
+        return 'VideoEncoding.any';
+      case theora:
+        return 'VideoEncoding.theora';
+      case vp8:
+        return 'VideoEncoding.vp8';
+    }
+  }
+
+  int toJson() => mojoEnumValue;
+}
+
+class VideoProfile extends bindings.MojoEnum {
+  static const VideoProfile unknown = const VideoProfile._(0);
+  static const VideoProfile notApplicable = const VideoProfile._(1);
+  static const VideoProfile h264Baseline = const VideoProfile._(2);
+  static const VideoProfile h264Main = const VideoProfile._(3);
+  static const VideoProfile h264Extended = const VideoProfile._(4);
+  static const VideoProfile h264High = const VideoProfile._(5);
+  static const VideoProfile h264High10 = const VideoProfile._(6);
+  static const VideoProfile h264High422 = const VideoProfile._(7);
+  static const VideoProfile h264High444Predictive = const VideoProfile._(8);
+  static const VideoProfile h264ScalableBaseline = const VideoProfile._(9);
+  static const VideoProfile h264ScalableHigh = const VideoProfile._(10);
+  static const VideoProfile h264StereoHigh = const VideoProfile._(11);
+  static const VideoProfile h264MultiviewHigh = const VideoProfile._(12);
+
+  const VideoProfile._(int v) : super(v);
+
+  static const Map<String, VideoProfile> valuesMap = const {
+    "unknown": unknown,
+    "notApplicable": notApplicable,
+    "h264Baseline": h264Baseline,
+    "h264Main": h264Main,
+    "h264Extended": h264Extended,
+    "h264High": h264High,
+    "h264High10": h264High10,
+    "h264High422": h264High422,
+    "h264High444Predictive": h264High444Predictive,
+    "h264ScalableBaseline": h264ScalableBaseline,
+    "h264ScalableHigh": h264ScalableHigh,
+    "h264StereoHigh": h264StereoHigh,
+    "h264MultiviewHigh": h264MultiviewHigh,
+  };
+  static const List<VideoProfile> values = const [
+    unknown,
+    notApplicable,
+    h264Baseline,
+    h264Main,
+    h264Extended,
+    h264High,
+    h264High10,
+    h264High422,
+    h264High444Predictive,
+    h264ScalableBaseline,
+    h264ScalableHigh,
+    h264StereoHigh,
+    h264MultiviewHigh,
+  ];
+
+  static VideoProfile valueOf(String name) => valuesMap[name];
+
+  factory VideoProfile(int v) {
+    switch (v) {
+      case 0:
+        return unknown;
+      case 1:
+        return notApplicable;
+      case 2:
+        return h264Baseline;
+      case 3:
+        return h264Main;
+      case 4:
+        return h264Extended;
+      case 5:
+        return h264High;
+      case 6:
+        return h264High10;
+      case 7:
+        return h264High422;
+      case 8:
+        return h264High444Predictive;
+      case 9:
+        return h264ScalableBaseline;
+      case 10:
+        return h264ScalableHigh;
+      case 11:
+        return h264StereoHigh;
+      case 12:
+        return h264MultiviewHigh;
+      default:
+        return null;
+    }
+  }
+
+  static VideoProfile decode(bindings.Decoder decoder0, int offset) {
+    int v = decoder0.decodeUint32(offset);
+    VideoProfile result = new VideoProfile(v);
+    if (result == null) {
+      throw new bindings.MojoCodecError(
+          'Bad value $v for enum VideoProfile.');
+    }
+    return result;
+  }
+
+  String toString() {
+    switch(this) {
+      case unknown:
+        return 'VideoProfile.unknown';
+      case notApplicable:
+        return 'VideoProfile.notApplicable';
+      case h264Baseline:
+        return 'VideoProfile.h264Baseline';
+      case h264Main:
+        return 'VideoProfile.h264Main';
+      case h264Extended:
+        return 'VideoProfile.h264Extended';
+      case h264High:
+        return 'VideoProfile.h264High';
+      case h264High10:
+        return 'VideoProfile.h264High10';
+      case h264High422:
+        return 'VideoProfile.h264High422';
+      case h264High444Predictive:
+        return 'VideoProfile.h264High444Predictive';
+      case h264ScalableBaseline:
+        return 'VideoProfile.h264ScalableBaseline';
+      case h264ScalableHigh:
+        return 'VideoProfile.h264ScalableHigh';
+      case h264StereoHigh:
+        return 'VideoProfile.h264StereoHigh';
+      case h264MultiviewHigh:
+        return 'VideoProfile.h264MultiviewHigh';
+    }
+  }
+
+  int toJson() => mojoEnumValue;
+}
+
+class PixelFormat extends bindings.MojoEnum {
+  static const PixelFormat unknown = const PixelFormat._(0);
+  static const PixelFormat i420 = const PixelFormat._(1);
+  static const PixelFormat yv12 = const PixelFormat._(2);
+  static const PixelFormat yv16 = const PixelFormat._(3);
+  static const PixelFormat yv12A = const PixelFormat._(4);
+  static const PixelFormat yv24 = const PixelFormat._(5);
+  static const PixelFormat nv12 = const PixelFormat._(6);
+  static const PixelFormat nv21 = const PixelFormat._(7);
+  static const PixelFormat uyvy = const PixelFormat._(8);
+  static const PixelFormat yuy2 = const PixelFormat._(9);
+  static const PixelFormat argb = const PixelFormat._(10);
+  static const PixelFormat xrgb = const PixelFormat._(11);
+  static const PixelFormat rgb24 = const PixelFormat._(12);
+  static const PixelFormat rgb32 = const PixelFormat._(13);
+  static const PixelFormat mjpeg = const PixelFormat._(14);
+  static const PixelFormat mt21 = const PixelFormat._(15);
+
+  const PixelFormat._(int v) : super(v);
+
+  static const Map<String, PixelFormat> valuesMap = const {
+    "unknown": unknown,
+    "i420": i420,
+    "yv12": yv12,
+    "yv16": yv16,
+    "yv12A": yv12A,
+    "yv24": yv24,
+    "nv12": nv12,
+    "nv21": nv21,
+    "uyvy": uyvy,
+    "yuy2": yuy2,
+    "argb": argb,
+    "xrgb": xrgb,
+    "rgb24": rgb24,
+    "rgb32": rgb32,
+    "mjpeg": mjpeg,
+    "mt21": mt21,
+  };
+  static const List<PixelFormat> values = const [
+    unknown,
+    i420,
+    yv12,
+    yv16,
+    yv12A,
+    yv24,
+    nv12,
+    nv21,
+    uyvy,
+    yuy2,
+    argb,
+    xrgb,
+    rgb24,
+    rgb32,
+    mjpeg,
+    mt21,
+  ];
+
+  static PixelFormat valueOf(String name) => valuesMap[name];
+
+  factory PixelFormat(int v) {
+    switch (v) {
+      case 0:
+        return unknown;
+      case 1:
+        return i420;
+      case 2:
+        return yv12;
+      case 3:
+        return yv16;
+      case 4:
+        return yv12A;
+      case 5:
+        return yv24;
+      case 6:
+        return nv12;
+      case 7:
+        return nv21;
+      case 8:
+        return uyvy;
+      case 9:
+        return yuy2;
+      case 10:
+        return argb;
+      case 11:
+        return xrgb;
+      case 12:
+        return rgb24;
+      case 13:
+        return rgb32;
+      case 14:
+        return mjpeg;
+      case 15:
+        return mt21;
+      default:
+        return null;
+    }
+  }
+
+  static PixelFormat decode(bindings.Decoder decoder0, int offset) {
+    int v = decoder0.decodeUint32(offset);
+    PixelFormat result = new PixelFormat(v);
+    if (result == null) {
+      throw new bindings.MojoCodecError(
+          'Bad value $v for enum PixelFormat.');
+    }
+    return result;
+  }
+
+  String toString() {
+    switch(this) {
+      case unknown:
+        return 'PixelFormat.unknown';
+      case i420:
+        return 'PixelFormat.i420';
+      case yv12:
+        return 'PixelFormat.yv12';
+      case yv16:
+        return 'PixelFormat.yv16';
+      case yv12A:
+        return 'PixelFormat.yv12A';
+      case yv24:
+        return 'PixelFormat.yv24';
+      case nv12:
+        return 'PixelFormat.nv12';
+      case nv21:
+        return 'PixelFormat.nv21';
+      case uyvy:
+        return 'PixelFormat.uyvy';
+      case yuy2:
+        return 'PixelFormat.yuy2';
+      case argb:
+        return 'PixelFormat.argb';
+      case xrgb:
+        return 'PixelFormat.xrgb';
+      case rgb24:
+        return 'PixelFormat.rgb24';
+      case rgb32:
+        return 'PixelFormat.rgb32';
+      case mjpeg:
+        return 'PixelFormat.mjpeg';
+      case mt21:
+        return 'PixelFormat.mt21';
+    }
+  }
+
+  int toJson() => mojoEnumValue;
+}
+
+class ColorSpace extends bindings.MojoEnum {
+  static const ColorSpace unknown = const ColorSpace._(0);
+  static const ColorSpace notApplicable = const ColorSpace._(1);
+  static const ColorSpace jpeg = const ColorSpace._(2);
+  static const ColorSpace hdRec709 = const ColorSpace._(3);
+  static const ColorSpace sdRec601 = const ColorSpace._(4);
+
+  const ColorSpace._(int v) : super(v);
+
+  static const Map<String, ColorSpace> valuesMap = const {
+    "unknown": unknown,
+    "notApplicable": notApplicable,
+    "jpeg": jpeg,
+    "hdRec709": hdRec709,
+    "sdRec601": sdRec601,
+  };
+  static const List<ColorSpace> values = const [
+    unknown,
+    notApplicable,
+    jpeg,
+    hdRec709,
+    sdRec601,
+  ];
+
+  static ColorSpace valueOf(String name) => valuesMap[name];
+
+  factory ColorSpace(int v) {
+    switch (v) {
+      case 0:
+        return unknown;
+      case 1:
+        return notApplicable;
+      case 2:
+        return jpeg;
+      case 3:
+        return hdRec709;
+      case 4:
+        return sdRec601;
+      default:
+        return null;
+    }
+  }
+
+  static ColorSpace decode(bindings.Decoder decoder0, int offset) {
+    int v = decoder0.decodeUint32(offset);
+    ColorSpace result = new ColorSpace(v);
+    if (result == null) {
+      throw new bindings.MojoCodecError(
+          'Bad value $v for enum ColorSpace.');
+    }
+    return result;
+  }
+
+  String toString() {
+    switch(this) {
+      case unknown:
+        return 'ColorSpace.unknown';
+      case notApplicable:
+        return 'ColorSpace.notApplicable';
+      case jpeg:
+        return 'ColorSpace.jpeg';
+      case hdRec709:
+        return 'ColorSpace.hdRec709';
+      case sdRec601:
+        return 'ColorSpace.sdRec601';
+    }
+  }
+
+  int toJson() => mojoEnumValue;
+}
+
+
+
+class MediaType extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(32, 0)
+  ];
+  MediaTypeScheme scheme = null;
+  MediaTypeDetails details = null;
+
+  MediaType() : super(kVersions.last.size);
+
+  static MediaType deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaType decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaType result = new MediaType();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.scheme = MediaTypeScheme.decode(decoder0, 8);
+        if (result.scheme == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable MediaTypeScheme.');
+        }
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.details = MediaTypeDetails.decode(decoder0, 16);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeEnum(scheme, 8);
+    
+    encoder0.encodeUnion(details, 16, true);
+  }
+
+  String toString() {
+    return "MediaType("
+           "scheme: $scheme" ", "
+           "details: $details" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["scheme"] = scheme;
+    map["details"] = details;
+    return map;
+  }
+}
+
+
+class MediaTypeSet extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(32, 0)
+  ];
+  MediaTypeScheme scheme = null;
+  MediaTypeSetDetails details = null;
+
+  MediaTypeSet() : super(kVersions.last.size);
+
+  static MediaTypeSet deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MediaTypeSet decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MediaTypeSet result = new MediaTypeSet();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.scheme = MediaTypeScheme.decode(decoder0, 8);
+        if (result.scheme == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable MediaTypeScheme.');
+        }
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.details = MediaTypeSetDetails.decode(decoder0, 16);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeEnum(scheme, 8);
+    
+    encoder0.encodeUnion(details, 16, true);
+  }
+
+  String toString() {
+    return "MediaTypeSet("
+           "scheme: $scheme" ", "
+           "details: $details" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["scheme"] = scheme;
+    map["details"] = details;
+    return map;
+  }
+}
+
+
+class LpcmMediaTypeDetails extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  LpcmSampleFormat sampleFormat = null;
+  int channels = 0;
+  int framesPerSecond = 0;
+
+  LpcmMediaTypeDetails() : super(kVersions.last.size);
+
+  static LpcmMediaTypeDetails deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static LpcmMediaTypeDetails decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    LpcmMediaTypeDetails result = new LpcmMediaTypeDetails();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.sampleFormat = LpcmSampleFormat.decode(decoder0, 8);
+        if (result.sampleFormat == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable LpcmSampleFormat.');
+        }
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.channels = decoder0.decodeUint32(12);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.framesPerSecond = decoder0.decodeUint32(16);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeEnum(sampleFormat, 8);
+    
+    encoder0.encodeUint32(channels, 12);
+    
+    encoder0.encodeUint32(framesPerSecond, 16);
+  }
+
+  String toString() {
+    return "LpcmMediaTypeDetails("
+           "sampleFormat: $sampleFormat" ", "
+           "channels: $channels" ", "
+           "framesPerSecond: $framesPerSecond" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["sampleFormat"] = sampleFormat;
+    map["channels"] = channels;
+    map["framesPerSecond"] = framesPerSecond;
+    return map;
+  }
+}
+
+
+class LpcmMediaTypeSetDetails extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(32, 0)
+  ];
+  LpcmSampleFormat sampleFormat = null;
+  int minChannels = 0;
+  int maxChannels = 0;
+  int minFramesPerSecond = 0;
+  int maxFramesPerSecond = 0;
+
+  LpcmMediaTypeSetDetails() : super(kVersions.last.size);
+
+  static LpcmMediaTypeSetDetails deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static LpcmMediaTypeSetDetails decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    LpcmMediaTypeSetDetails result = new LpcmMediaTypeSetDetails();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.sampleFormat = LpcmSampleFormat.decode(decoder0, 8);
+        if (result.sampleFormat == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable LpcmSampleFormat.');
+        }
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.minChannels = decoder0.decodeUint32(12);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.maxChannels = decoder0.decodeUint32(16);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.minFramesPerSecond = decoder0.decodeUint32(20);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.maxFramesPerSecond = decoder0.decodeUint32(24);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeEnum(sampleFormat, 8);
+    
+    encoder0.encodeUint32(minChannels, 12);
+    
+    encoder0.encodeUint32(maxChannels, 16);
+    
+    encoder0.encodeUint32(minFramesPerSecond, 20);
+    
+    encoder0.encodeUint32(maxFramesPerSecond, 24);
+  }
+
+  String toString() {
+    return "LpcmMediaTypeSetDetails("
+           "sampleFormat: $sampleFormat" ", "
+           "minChannels: $minChannels" ", "
+           "maxChannels: $maxChannels" ", "
+           "minFramesPerSecond: $minFramesPerSecond" ", "
+           "maxFramesPerSecond: $maxFramesPerSecond" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["sampleFormat"] = sampleFormat;
+    map["minChannels"] = minChannels;
+    map["maxChannels"] = maxChannels;
+    map["minFramesPerSecond"] = minFramesPerSecond;
+    map["maxFramesPerSecond"] = maxFramesPerSecond;
+    return map;
+  }
+}
+
+
+class MultiplexedMediaTypeDetails extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  MediaType multiplexType = null;
+  List<MediaType> substreamTypes = null;
+
+  MultiplexedMediaTypeDetails() : super(kVersions.last.size);
+
+  static MultiplexedMediaTypeDetails deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MultiplexedMediaTypeDetails decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MultiplexedMediaTypeDetails result = new MultiplexedMediaTypeDetails();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(8, false);
+      result.multiplexType = MediaType.decode(decoder1);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(16, false);
+      {
+        var si1 = decoder1.decodeDataHeaderForPointerArray(bindings.kUnspecifiedArrayLength);
+        result.substreamTypes = new List<MediaType>(si1.numElements);
+        for (int i1 = 0; i1 < si1.numElements; ++i1) {
+          
+          var decoder2 = decoder1.decodePointer(bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i1, false);
+          result.substreamTypes[i1] = MediaType.decode(decoder2);
+        }
+      }
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeStruct(multiplexType, 8, false);
+    
+    if (substreamTypes == null) {
+      encoder0.encodeNullPointer(16, false);
+    } else {
+      var encoder1 = encoder0.encodePointerArray(substreamTypes.length, 16, bindings.kUnspecifiedArrayLength);
+      for (int i0 = 0; i0 < substreamTypes.length; ++i0) {
+        
+        encoder1.encodeStruct(substreamTypes[i0], bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i0, false);
+      }
+    }
+  }
+
+  String toString() {
+    return "MultiplexedMediaTypeDetails("
+           "multiplexType: $multiplexType" ", "
+           "substreamTypes: $substreamTypes" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["multiplexType"] = multiplexType;
+    map["substreamTypes"] = substreamTypes;
+    return map;
+  }
+}
+
+
+class MultiplexedMediaTypeSetDetails extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  MediaTypeSet multiplexTypeSet = null;
+  List<MediaTypeSet> substreamTypeSets = null;
+
+  MultiplexedMediaTypeSetDetails() : super(kVersions.last.size);
+
+  static MultiplexedMediaTypeSetDetails deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static MultiplexedMediaTypeSetDetails decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    MultiplexedMediaTypeSetDetails result = new MultiplexedMediaTypeSetDetails();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(8, false);
+      result.multiplexTypeSet = MediaTypeSet.decode(decoder1);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(16, false);
+      {
+        var si1 = decoder1.decodeDataHeaderForPointerArray(bindings.kUnspecifiedArrayLength);
+        result.substreamTypeSets = new List<MediaTypeSet>(si1.numElements);
+        for (int i1 = 0; i1 < si1.numElements; ++i1) {
+          
+          var decoder2 = decoder1.decodePointer(bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i1, false);
+          result.substreamTypeSets[i1] = MediaTypeSet.decode(decoder2);
+        }
+      }
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeStruct(multiplexTypeSet, 8, false);
+    
+    if (substreamTypeSets == null) {
+      encoder0.encodeNullPointer(16, false);
+    } else {
+      var encoder1 = encoder0.encodePointerArray(substreamTypeSets.length, 16, bindings.kUnspecifiedArrayLength);
+      for (int i0 = 0; i0 < substreamTypeSets.length; ++i0) {
+        
+        encoder1.encodeStruct(substreamTypeSets[i0], bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i0, false);
+      }
+    }
+  }
+
+  String toString() {
+    return "MultiplexedMediaTypeSetDetails("
+           "multiplexTypeSet: $multiplexTypeSet" ", "
+           "substreamTypeSets: $substreamTypeSets" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["multiplexTypeSet"] = multiplexTypeSet;
+    map["substreamTypeSets"] = substreamTypeSets;
+    return map;
+  }
+}
+
+
+class CompressedAudioMediaTypeDetails extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(32, 0)
+  ];
+  AudioEncoding encoding = null;
+  LpcmSampleFormat sampleFormat = null;
+  int channels = 0;
+  int framesPerSecond = 0;
+  String extraDataBase64 = null;
+
+  CompressedAudioMediaTypeDetails() : super(kVersions.last.size);
+
+  static CompressedAudioMediaTypeDetails deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static CompressedAudioMediaTypeDetails decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    CompressedAudioMediaTypeDetails result = new CompressedAudioMediaTypeDetails();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.encoding = AudioEncoding.decode(decoder0, 8);
+        if (result.encoding == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable AudioEncoding.');
+        }
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.sampleFormat = LpcmSampleFormat.decode(decoder0, 12);
+        if (result.sampleFormat == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable LpcmSampleFormat.');
+        }
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.channels = decoder0.decodeUint32(16);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.framesPerSecond = decoder0.decodeUint32(20);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.extraDataBase64 = decoder0.decodeString(24, false);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeEnum(encoding, 8);
+    
+    encoder0.encodeEnum(sampleFormat, 12);
+    
+    encoder0.encodeUint32(channels, 16);
+    
+    encoder0.encodeUint32(framesPerSecond, 20);
+    
+    encoder0.encodeString(extraDataBase64, 24, false);
+  }
+
+  String toString() {
+    return "CompressedAudioMediaTypeDetails("
+           "encoding: $encoding" ", "
+           "sampleFormat: $sampleFormat" ", "
+           "channels: $channels" ", "
+           "framesPerSecond: $framesPerSecond" ", "
+           "extraDataBase64: $extraDataBase64" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["encoding"] = encoding;
+    map["sampleFormat"] = sampleFormat;
+    map["channels"] = channels;
+    map["framesPerSecond"] = framesPerSecond;
+    map["extraDataBase64"] = extraDataBase64;
+    return map;
+  }
+}
+
+
+class CompressedAudioMediaTypeSetDetails extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(32, 0)
+  ];
+  AudioEncoding encoding = null;
+  LpcmSampleFormat sampleFormat = null;
+  int minChannels = 0;
+  int maxChannels = 0;
+  int minFramesPerSecond = 0;
+  int maxFramesPerSecond = 0;
+
+  CompressedAudioMediaTypeSetDetails() : super(kVersions.last.size);
+
+  static CompressedAudioMediaTypeSetDetails deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static CompressedAudioMediaTypeSetDetails decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    CompressedAudioMediaTypeSetDetails result = new CompressedAudioMediaTypeSetDetails();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.encoding = AudioEncoding.decode(decoder0, 8);
+        if (result.encoding == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable AudioEncoding.');
+        }
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.sampleFormat = LpcmSampleFormat.decode(decoder0, 12);
+        if (result.sampleFormat == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable LpcmSampleFormat.');
+        }
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.minChannels = decoder0.decodeUint32(16);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.maxChannels = decoder0.decodeUint32(20);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.minFramesPerSecond = decoder0.decodeUint32(24);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.maxFramesPerSecond = decoder0.decodeUint32(28);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeEnum(encoding, 8);
+    
+    encoder0.encodeEnum(sampleFormat, 12);
+    
+    encoder0.encodeUint32(minChannels, 16);
+    
+    encoder0.encodeUint32(maxChannels, 20);
+    
+    encoder0.encodeUint32(minFramesPerSecond, 24);
+    
+    encoder0.encodeUint32(maxFramesPerSecond, 28);
+  }
+
+  String toString() {
+    return "CompressedAudioMediaTypeSetDetails("
+           "encoding: $encoding" ", "
+           "sampleFormat: $sampleFormat" ", "
+           "minChannels: $minChannels" ", "
+           "maxChannels: $maxChannels" ", "
+           "minFramesPerSecond: $minFramesPerSecond" ", "
+           "maxFramesPerSecond: $maxFramesPerSecond" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["encoding"] = encoding;
+    map["sampleFormat"] = sampleFormat;
+    map["minChannels"] = minChannels;
+    map["maxChannels"] = maxChannels;
+    map["minFramesPerSecond"] = minFramesPerSecond;
+    map["maxFramesPerSecond"] = maxFramesPerSecond;
+    return map;
+  }
+}
+
+
+class VideoMediaTypeDetails extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(48, 0)
+  ];
+  VideoEncoding encoding = null;
+  VideoProfile profile = null;
+  PixelFormat pixelFormat = null;
+  ColorSpace colorSpace = null;
+  int width = 0;
+  int height = 0;
+  int codedWidth = 0;
+  int codedHeight = 0;
+  String extraDataBase64 = null;
+
+  VideoMediaTypeDetails() : super(kVersions.last.size);
+
+  static VideoMediaTypeDetails deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static VideoMediaTypeDetails decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    VideoMediaTypeDetails result = new VideoMediaTypeDetails();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.encoding = VideoEncoding.decode(decoder0, 8);
+        if (result.encoding == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable VideoEncoding.');
+        }
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.profile = VideoProfile.decode(decoder0, 12);
+        if (result.profile == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable VideoProfile.');
+        }
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.pixelFormat = PixelFormat.decode(decoder0, 16);
+        if (result.pixelFormat == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable PixelFormat.');
+        }
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.colorSpace = ColorSpace.decode(decoder0, 20);
+        if (result.colorSpace == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable ColorSpace.');
+        }
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.width = decoder0.decodeUint32(24);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.height = decoder0.decodeUint32(28);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.codedWidth = decoder0.decodeUint32(32);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.codedHeight = decoder0.decodeUint32(36);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.extraDataBase64 = decoder0.decodeString(40, false);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeEnum(encoding, 8);
+    
+    encoder0.encodeEnum(profile, 12);
+    
+    encoder0.encodeEnum(pixelFormat, 16);
+    
+    encoder0.encodeEnum(colorSpace, 20);
+    
+    encoder0.encodeUint32(width, 24);
+    
+    encoder0.encodeUint32(height, 28);
+    
+    encoder0.encodeUint32(codedWidth, 32);
+    
+    encoder0.encodeUint32(codedHeight, 36);
+    
+    encoder0.encodeString(extraDataBase64, 40, false);
+  }
+
+  String toString() {
+    return "VideoMediaTypeDetails("
+           "encoding: $encoding" ", "
+           "profile: $profile" ", "
+           "pixelFormat: $pixelFormat" ", "
+           "colorSpace: $colorSpace" ", "
+           "width: $width" ", "
+           "height: $height" ", "
+           "codedWidth: $codedWidth" ", "
+           "codedHeight: $codedHeight" ", "
+           "extraDataBase64: $extraDataBase64" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["encoding"] = encoding;
+    map["profile"] = profile;
+    map["pixelFormat"] = pixelFormat;
+    map["colorSpace"] = colorSpace;
+    map["width"] = width;
+    map["height"] = height;
+    map["codedWidth"] = codedWidth;
+    map["codedHeight"] = codedHeight;
+    map["extraDataBase64"] = extraDataBase64;
+    return map;
+  }
+}
+
+
+class VideoMediaTypeSetDetails extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(32, 0)
+  ];
+  VideoEncoding encoding = null;
+  int minWidth = 0;
+  int maxWidth = 0;
+  int minHeight = 0;
+  int maxHeight = 0;
+
+  VideoMediaTypeSetDetails() : super(kVersions.last.size);
+
+  static VideoMediaTypeSetDetails deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static VideoMediaTypeSetDetails decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    VideoMediaTypeSetDetails result = new VideoMediaTypeSetDetails();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.encoding = VideoEncoding.decode(decoder0, 8);
+        if (result.encoding == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable VideoEncoding.');
+        }
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.minWidth = decoder0.decodeUint32(12);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.maxWidth = decoder0.decodeUint32(16);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.minHeight = decoder0.decodeUint32(20);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.maxHeight = decoder0.decodeUint32(24);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeEnum(encoding, 8);
+    
+    encoder0.encodeUint32(minWidth, 12);
+    
+    encoder0.encodeUint32(maxWidth, 16);
+    
+    encoder0.encodeUint32(minHeight, 20);
+    
+    encoder0.encodeUint32(maxHeight, 24);
+  }
+
+  String toString() {
+    return "VideoMediaTypeSetDetails("
+           "encoding: $encoding" ", "
+           "minWidth: $minWidth" ", "
+           "maxWidth: $maxWidth" ", "
+           "minHeight: $minHeight" ", "
+           "maxHeight: $maxHeight" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["encoding"] = encoding;
+    map["minWidth"] = minWidth;
+    map["maxWidth"] = maxWidth;
+    map["minHeight"] = minHeight;
+    map["maxHeight"] = maxHeight;
+    return map;
+  }
+}
+
+
+
+enum MediaTypeDetailsTag {
+  multiplexed,
+  lpcm,
+  compressedAudio,
+  video,
+  unknown
+}
+
+class MediaTypeDetails extends bindings.Union {
+  static final _tag_to_int = const {
+    MediaTypeDetailsTag.multiplexed: 0,
+    MediaTypeDetailsTag.lpcm: 1,
+    MediaTypeDetailsTag.compressedAudio: 2,
+    MediaTypeDetailsTag.video: 3,
+  };
+
+  static final _int_to_tag = const {
+    0: MediaTypeDetailsTag.multiplexed,
+    1: MediaTypeDetailsTag.lpcm,
+    2: MediaTypeDetailsTag.compressedAudio,
+    3: MediaTypeDetailsTag.video,
+  };
+
+  var _data;
+  MediaTypeDetailsTag _tag = MediaTypeDetailsTag.unknown;
+
+  MediaTypeDetailsTag get tag => _tag;
+  MultiplexedMediaTypeDetails get multiplexed {
+    if (_tag != MediaTypeDetailsTag.multiplexed) {
+      throw new bindings.UnsetUnionTagError(_tag, MediaTypeDetailsTag.multiplexed);
+    }
+    return _data;
+  }
+
+  set multiplexed(MultiplexedMediaTypeDetails value) {
+    _tag = MediaTypeDetailsTag.multiplexed;
+    _data = value;
+  }
+  LpcmMediaTypeDetails get lpcm {
+    if (_tag != MediaTypeDetailsTag.lpcm) {
+      throw new bindings.UnsetUnionTagError(_tag, MediaTypeDetailsTag.lpcm);
+    }
+    return _data;
+  }
+
+  set lpcm(LpcmMediaTypeDetails value) {
+    _tag = MediaTypeDetailsTag.lpcm;
+    _data = value;
+  }
+  CompressedAudioMediaTypeDetails get compressedAudio {
+    if (_tag != MediaTypeDetailsTag.compressedAudio) {
+      throw new bindings.UnsetUnionTagError(_tag, MediaTypeDetailsTag.compressedAudio);
+    }
+    return _data;
+  }
+
+  set compressedAudio(CompressedAudioMediaTypeDetails value) {
+    _tag = MediaTypeDetailsTag.compressedAudio;
+    _data = value;
+  }
+  VideoMediaTypeDetails get video {
+    if (_tag != MediaTypeDetailsTag.video) {
+      throw new bindings.UnsetUnionTagError(_tag, MediaTypeDetailsTag.video);
+    }
+    return _data;
+  }
+
+  set video(VideoMediaTypeDetails value) {
+    _tag = MediaTypeDetailsTag.video;
+    _data = value;
+  }
+
+  static MediaTypeDetails decode(bindings.Decoder decoder0, int offset) {
+    int size = decoder0.decodeUint32(offset);
+    if (size == 0) {
+      return null;
+    }
+    MediaTypeDetails result = new MediaTypeDetails();
+
+    // TODO(azani): Handle unknown union member.
+    MediaTypeDetailsTag tag = _int_to_tag[decoder0.decodeUint32(offset + 4)];
+    switch (tag) {
+      case MediaTypeDetailsTag.multiplexed:
+        
+        var decoder1 = decoder0.decodePointer(offset + 8, false);
+        result.multiplexed = MultiplexedMediaTypeDetails.decode(decoder1);
+        break;
+      case MediaTypeDetailsTag.lpcm:
+        
+        var decoder1 = decoder0.decodePointer(offset + 8, false);
+        result.lpcm = LpcmMediaTypeDetails.decode(decoder1);
+        break;
+      case MediaTypeDetailsTag.compressedAudio:
+        
+        var decoder1 = decoder0.decodePointer(offset + 8, false);
+        result.compressedAudio = CompressedAudioMediaTypeDetails.decode(decoder1);
+        break;
+      case MediaTypeDetailsTag.video:
+        
+        var decoder1 = decoder0.decodePointer(offset + 8, false);
+        result.video = VideoMediaTypeDetails.decode(decoder1);
+        break;
+      default:
+        throw new bindings.MojoCodecError("Bad union tag: $tag");
+    }
+
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder0, int offset) {
+    // TODO(azani): Error when trying to encode an unknown member.
+    encoder0.encodeUint32(16, offset);
+    encoder0.encodeUint32(_tag_to_int[_tag], offset + 4);
+    switch (_tag) {
+      case MediaTypeDetailsTag.multiplexed:
+        
+        encoder0.encodeStruct(multiplexed, offset + 8, false);
+        break;
+      case MediaTypeDetailsTag.lpcm:
+        
+        encoder0.encodeStruct(lpcm, offset + 8, false);
+        break;
+      case MediaTypeDetailsTag.compressedAudio:
+        
+        encoder0.encodeStruct(compressedAudio, offset + 8, false);
+        break;
+      case MediaTypeDetailsTag.video:
+        
+        encoder0.encodeStruct(video, offset + 8, false);
+        break;
+      default:
+        throw new bindings.MojoCodecError("Bad union tag: $_tag");
+    }
+  }
+
+  String toString() {
+    String result = "MediaTypeDetails(";
+    switch (_tag) {
+      case MediaTypeDetailsTag.multiplexed:
+        result += "multiplexed";
+        break;
+      case MediaTypeDetailsTag.lpcm:
+        result += "lpcm";
+        break;
+      case MediaTypeDetailsTag.compressedAudio:
+        result += "compressedAudio";
+        break;
+      case MediaTypeDetailsTag.video:
+        result += "video";
+        break;
+      default:
+        result += "unknown";
+    }
+    result += ": $_data)";
+    return result;
+  }
+}
+
+
+enum MediaTypeSetDetailsTag {
+  multiplexed,
+  lpcm,
+  compressedAudio,
+  video,
+  unknown
+}
+
+class MediaTypeSetDetails extends bindings.Union {
+  static final _tag_to_int = const {
+    MediaTypeSetDetailsTag.multiplexed: 0,
+    MediaTypeSetDetailsTag.lpcm: 1,
+    MediaTypeSetDetailsTag.compressedAudio: 2,
+    MediaTypeSetDetailsTag.video: 3,
+  };
+
+  static final _int_to_tag = const {
+    0: MediaTypeSetDetailsTag.multiplexed,
+    1: MediaTypeSetDetailsTag.lpcm,
+    2: MediaTypeSetDetailsTag.compressedAudio,
+    3: MediaTypeSetDetailsTag.video,
+  };
+
+  var _data;
+  MediaTypeSetDetailsTag _tag = MediaTypeSetDetailsTag.unknown;
+
+  MediaTypeSetDetailsTag get tag => _tag;
+  MultiplexedMediaTypeSetDetails get multiplexed {
+    if (_tag != MediaTypeSetDetailsTag.multiplexed) {
+      throw new bindings.UnsetUnionTagError(_tag, MediaTypeSetDetailsTag.multiplexed);
+    }
+    return _data;
+  }
+
+  set multiplexed(MultiplexedMediaTypeSetDetails value) {
+    _tag = MediaTypeSetDetailsTag.multiplexed;
+    _data = value;
+  }
+  LpcmMediaTypeSetDetails get lpcm {
+    if (_tag != MediaTypeSetDetailsTag.lpcm) {
+      throw new bindings.UnsetUnionTagError(_tag, MediaTypeSetDetailsTag.lpcm);
+    }
+    return _data;
+  }
+
+  set lpcm(LpcmMediaTypeSetDetails value) {
+    _tag = MediaTypeSetDetailsTag.lpcm;
+    _data = value;
+  }
+  CompressedAudioMediaTypeSetDetails get compressedAudio {
+    if (_tag != MediaTypeSetDetailsTag.compressedAudio) {
+      throw new bindings.UnsetUnionTagError(_tag, MediaTypeSetDetailsTag.compressedAudio);
+    }
+    return _data;
+  }
+
+  set compressedAudio(CompressedAudioMediaTypeSetDetails value) {
+    _tag = MediaTypeSetDetailsTag.compressedAudio;
+    _data = value;
+  }
+  VideoMediaTypeSetDetails get video {
+    if (_tag != MediaTypeSetDetailsTag.video) {
+      throw new bindings.UnsetUnionTagError(_tag, MediaTypeSetDetailsTag.video);
+    }
+    return _data;
+  }
+
+  set video(VideoMediaTypeSetDetails value) {
+    _tag = MediaTypeSetDetailsTag.video;
+    _data = value;
+  }
+
+  static MediaTypeSetDetails decode(bindings.Decoder decoder0, int offset) {
+    int size = decoder0.decodeUint32(offset);
+    if (size == 0) {
+      return null;
+    }
+    MediaTypeSetDetails result = new MediaTypeSetDetails();
+
+    // TODO(azani): Handle unknown union member.
+    MediaTypeSetDetailsTag tag = _int_to_tag[decoder0.decodeUint32(offset + 4)];
+    switch (tag) {
+      case MediaTypeSetDetailsTag.multiplexed:
+        
+        var decoder1 = decoder0.decodePointer(offset + 8, false);
+        result.multiplexed = MultiplexedMediaTypeSetDetails.decode(decoder1);
+        break;
+      case MediaTypeSetDetailsTag.lpcm:
+        
+        var decoder1 = decoder0.decodePointer(offset + 8, false);
+        result.lpcm = LpcmMediaTypeSetDetails.decode(decoder1);
+        break;
+      case MediaTypeSetDetailsTag.compressedAudio:
+        
+        var decoder1 = decoder0.decodePointer(offset + 8, false);
+        result.compressedAudio = CompressedAudioMediaTypeSetDetails.decode(decoder1);
+        break;
+      case MediaTypeSetDetailsTag.video:
+        
+        var decoder1 = decoder0.decodePointer(offset + 8, false);
+        result.video = VideoMediaTypeSetDetails.decode(decoder1);
+        break;
+      default:
+        throw new bindings.MojoCodecError("Bad union tag: $tag");
+    }
+
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder0, int offset) {
+    // TODO(azani): Error when trying to encode an unknown member.
+    encoder0.encodeUint32(16, offset);
+    encoder0.encodeUint32(_tag_to_int[_tag], offset + 4);
+    switch (_tag) {
+      case MediaTypeSetDetailsTag.multiplexed:
+        
+        encoder0.encodeStruct(multiplexed, offset + 8, false);
+        break;
+      case MediaTypeSetDetailsTag.lpcm:
+        
+        encoder0.encodeStruct(lpcm, offset + 8, false);
+        break;
+      case MediaTypeSetDetailsTag.compressedAudio:
+        
+        encoder0.encodeStruct(compressedAudio, offset + 8, false);
+        break;
+      case MediaTypeSetDetailsTag.video:
+        
+        encoder0.encodeStruct(video, offset + 8, false);
+        break;
+      default:
+        throw new bindings.MojoCodecError("Bad union tag: $_tag");
+    }
+  }
+
+  String toString() {
+    String result = "MediaTypeSetDetails(";
+    switch (_tag) {
+      case MediaTypeSetDetailsTag.multiplexed:
+        result += "multiplexed";
+        break;
+      case MediaTypeSetDetailsTag.lpcm:
+        result += "lpcm";
+        break;
+      case MediaTypeSetDetailsTag.compressedAudio:
+        result += "compressedAudio";
+        break;
+      case MediaTypeSetDetailsTag.video:
+        result += "video";
+        break;
+      default:
+        result += "unknown";
+    }
+    result += ": $_data)";
+    return result;
+  }
+}
+
diff --git a/mojo/dart/packages/mojo_services/lib/mojo/media/rate_control.mojom.dart b/mojo/dart/packages/mojo_services/lib/mojo/media/rate_control.mojom.dart
new file mode 100644
index 0000000..08dc29b
--- /dev/null
+++ b/mojo/dart/packages/mojo_services/lib/mojo/media/rate_control.mojom.dart
@@ -0,0 +1,1069 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library rate_control_mojom;
+
+import 'dart:async';
+
+import 'package:mojo/bindings.dart' as bindings;
+import 'package:mojo/core.dart' as core;
+
+
+
+class TimelineQuad extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(32, 0)
+  ];
+  int referenceOffset = 0;
+  int targetOffset = 0;
+  int referenceDelta = 0;
+  int targetDelta = 1;
+
+  TimelineQuad() : super(kVersions.last.size);
+
+  static TimelineQuad deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static TimelineQuad decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    TimelineQuad result = new TimelineQuad();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.referenceOffset = decoder0.decodeInt64(8);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.targetOffset = decoder0.decodeInt64(16);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.referenceDelta = decoder0.decodeInt32(24);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.targetDelta = decoder0.decodeUint32(28);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeInt64(referenceOffset, 8);
+    
+    encoder0.encodeInt64(targetOffset, 16);
+    
+    encoder0.encodeInt32(referenceDelta, 24);
+    
+    encoder0.encodeUint32(targetDelta, 28);
+  }
+
+  String toString() {
+    return "TimelineQuad("
+           "referenceOffset: $referenceOffset" ", "
+           "targetOffset: $targetOffset" ", "
+           "referenceDelta: $referenceDelta" ", "
+           "targetDelta: $targetDelta" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["referenceOffset"] = referenceOffset;
+    map["targetOffset"] = targetOffset;
+    map["referenceDelta"] = referenceDelta;
+    map["targetDelta"] = targetDelta;
+    return map;
+  }
+}
+
+
+class TimelineTransform extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  static const int kLocalTimeId = 0xFFFFFFFF;
+  static const int kContextual = 0xFFFFFFFE;
+  TimelineQuad quad = null;
+  int referenceTimelineId = 0xFFFFFFFE;
+  int targetTimelineId = 0xFFFFFFFF;
+
+  TimelineTransform() : super(kVersions.last.size);
+
+  static TimelineTransform deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static TimelineTransform decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    TimelineTransform result = new TimelineTransform();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(8, false);
+      result.quad = TimelineQuad.decode(decoder1);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.referenceTimelineId = decoder0.decodeUint32(16);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.targetTimelineId = decoder0.decodeUint32(20);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeStruct(quad, 8, false);
+    
+    encoder0.encodeUint32(referenceTimelineId, 16);
+    
+    encoder0.encodeUint32(targetTimelineId, 20);
+  }
+
+  String toString() {
+    return "TimelineTransform("
+           "quad: $quad" ", "
+           "referenceTimelineId: $referenceTimelineId" ", "
+           "targetTimelineId: $targetTimelineId" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["quad"] = quad;
+    map["referenceTimelineId"] = referenceTimelineId;
+    map["targetTimelineId"] = targetTimelineId;
+    return map;
+  }
+}
+
+
+class _RateControlGetCurrentTransformParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  _RateControlGetCurrentTransformParams() : super(kVersions.last.size);
+
+  static _RateControlGetCurrentTransformParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _RateControlGetCurrentTransformParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _RateControlGetCurrentTransformParams result = new _RateControlGetCurrentTransformParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "_RateControlGetCurrentTransformParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+class RateControlGetCurrentTransformResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  TimelineTransform trans = null;
+
+  RateControlGetCurrentTransformResponseParams() : super(kVersions.last.size);
+
+  static RateControlGetCurrentTransformResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static RateControlGetCurrentTransformResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    RateControlGetCurrentTransformResponseParams result = new RateControlGetCurrentTransformResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(8, false);
+      result.trans = TimelineTransform.decode(decoder1);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeStruct(trans, 8, false);
+  }
+
+  String toString() {
+    return "RateControlGetCurrentTransformResponseParams("
+           "trans: $trans" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["trans"] = trans;
+    return map;
+  }
+}
+
+
+class _RateControlSetCurrentQuadParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  TimelineQuad quad = null;
+
+  _RateControlSetCurrentQuadParams() : super(kVersions.last.size);
+
+  static _RateControlSetCurrentQuadParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _RateControlSetCurrentQuadParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _RateControlSetCurrentQuadParams result = new _RateControlSetCurrentQuadParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(8, false);
+      result.quad = TimelineQuad.decode(decoder1);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeStruct(quad, 8, false);
+  }
+
+  String toString() {
+    return "_RateControlSetCurrentQuadParams("
+           "quad: $quad" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["quad"] = quad;
+    return map;
+  }
+}
+
+
+class _RateControlSetTargetTimelineIdParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  int id = 0;
+
+  _RateControlSetTargetTimelineIdParams() : super(kVersions.last.size);
+
+  static _RateControlSetTargetTimelineIdParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _RateControlSetTargetTimelineIdParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _RateControlSetTargetTimelineIdParams result = new _RateControlSetTargetTimelineIdParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.id = decoder0.decodeUint32(8);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeUint32(id, 8);
+  }
+
+  String toString() {
+    return "_RateControlSetTargetTimelineIdParams("
+           "id: $id" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["id"] = id;
+    return map;
+  }
+}
+
+
+class _RateControlSetRateParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  int referenceDelta = 0;
+  int targetDelta = 0;
+
+  _RateControlSetRateParams() : super(kVersions.last.size);
+
+  static _RateControlSetRateParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _RateControlSetRateParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _RateControlSetRateParams result = new _RateControlSetRateParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.referenceDelta = decoder0.decodeInt32(8);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.targetDelta = decoder0.decodeUint32(12);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeInt32(referenceDelta, 8);
+    
+    encoder0.encodeUint32(targetDelta, 12);
+  }
+
+  String toString() {
+    return "_RateControlSetRateParams("
+           "referenceDelta: $referenceDelta" ", "
+           "targetDelta: $targetDelta" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["referenceDelta"] = referenceDelta;
+    map["targetDelta"] = targetDelta;
+    return map;
+  }
+}
+
+
+class _RateControlSetRateAtReferenceTimeParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  int referenceDelta = 0;
+  int targetDelta = 0;
+  int referenceTime = 0;
+
+  _RateControlSetRateAtReferenceTimeParams() : super(kVersions.last.size);
+
+  static _RateControlSetRateAtReferenceTimeParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _RateControlSetRateAtReferenceTimeParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _RateControlSetRateAtReferenceTimeParams result = new _RateControlSetRateAtReferenceTimeParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.referenceDelta = decoder0.decodeInt32(8);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.targetDelta = decoder0.decodeUint32(12);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.referenceTime = decoder0.decodeInt64(16);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeInt32(referenceDelta, 8);
+    
+    encoder0.encodeUint32(targetDelta, 12);
+    
+    encoder0.encodeInt64(referenceTime, 16);
+  }
+
+  String toString() {
+    return "_RateControlSetRateAtReferenceTimeParams("
+           "referenceDelta: $referenceDelta" ", "
+           "targetDelta: $targetDelta" ", "
+           "referenceTime: $referenceTime" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["referenceDelta"] = referenceDelta;
+    map["targetDelta"] = targetDelta;
+    map["referenceTime"] = referenceTime;
+    return map;
+  }
+}
+
+
+class _RateControlSetRateAtTargetTimeParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  int referenceDelta = 0;
+  int targetDelta = 0;
+  int targetTime = 0;
+
+  _RateControlSetRateAtTargetTimeParams() : super(kVersions.last.size);
+
+  static _RateControlSetRateAtTargetTimeParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _RateControlSetRateAtTargetTimeParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _RateControlSetRateAtTargetTimeParams result = new _RateControlSetRateAtTargetTimeParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.referenceDelta = decoder0.decodeInt32(8);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.targetDelta = decoder0.decodeUint32(12);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.targetTime = decoder0.decodeInt64(16);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeInt32(referenceDelta, 8);
+    
+    encoder0.encodeUint32(targetDelta, 12);
+    
+    encoder0.encodeInt64(targetTime, 16);
+  }
+
+  String toString() {
+    return "_RateControlSetRateAtTargetTimeParams("
+           "referenceDelta: $referenceDelta" ", "
+           "targetDelta: $targetDelta" ", "
+           "targetTime: $targetTime" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["referenceDelta"] = referenceDelta;
+    map["targetDelta"] = targetDelta;
+    map["targetTime"] = targetTime;
+    return map;
+  }
+}
+
+
+class _RateControlCancelPendingChangesParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  _RateControlCancelPendingChangesParams() : super(kVersions.last.size);
+
+  static _RateControlCancelPendingChangesParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _RateControlCancelPendingChangesParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _RateControlCancelPendingChangesParams result = new _RateControlCancelPendingChangesParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "_RateControlCancelPendingChangesParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+const int _RateControl_getCurrentTransformName = 0;
+const int _RateControl_setCurrentQuadName = 1;
+const int _RateControl_setTargetTimelineIdName = 2;
+const int _RateControl_setRateName = 3;
+const int _RateControl_setRateAtReferenceTimeName = 4;
+const int _RateControl_setRateAtTargetTimeName = 5;
+const int _RateControl_cancelPendingChangesName = 6;
+
+abstract class RateControl {
+  static const String serviceName = null;
+  dynamic getCurrentTransform([Function responseFactory = null]);
+  void setCurrentQuad(TimelineQuad quad);
+  void setTargetTimelineId(int id);
+  void setRate(int referenceDelta, int targetDelta);
+  void setRateAtReferenceTime(int referenceDelta, int targetDelta, int referenceTime);
+  void setRateAtTargetTime(int referenceDelta, int targetDelta, int targetTime);
+  void cancelPendingChanges();
+}
+
+
+class _RateControlProxyImpl extends bindings.Proxy {
+  _RateControlProxyImpl.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
+
+  _RateControlProxyImpl.fromHandle(core.MojoHandle handle) :
+      super.fromHandle(handle);
+
+  _RateControlProxyImpl.unbound() : super.unbound();
+
+  static _RateControlProxyImpl newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For _RateControlProxyImpl"));
+    return new _RateControlProxyImpl.fromEndpoint(endpoint);
+  }
+
+  void handleResponse(bindings.ServiceMessage message) {
+    switch (message.header.type) {
+      case _RateControl_getCurrentTransformName:
+        var r = RateControlGetCurrentTransformResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      default:
+        proxyError("Unexpected message type: ${message.header.type}");
+        close(immediate: true);
+        break;
+    }
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "_RateControlProxyImpl($superString)";
+  }
+}
+
+
+class _RateControlProxyCalls implements RateControl {
+  _RateControlProxyImpl _proxyImpl;
+
+  _RateControlProxyCalls(this._proxyImpl);
+    dynamic getCurrentTransform([Function responseFactory = null]) {
+      var params = new _RateControlGetCurrentTransformParams();
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _RateControl_getCurrentTransformName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    void setCurrentQuad(TimelineQuad quad) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _RateControlSetCurrentQuadParams();
+      params.quad = quad;
+      _proxyImpl.sendMessage(params, _RateControl_setCurrentQuadName);
+    }
+    void setTargetTimelineId(int id) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _RateControlSetTargetTimelineIdParams();
+      params.id = id;
+      _proxyImpl.sendMessage(params, _RateControl_setTargetTimelineIdName);
+    }
+    void setRate(int referenceDelta, int targetDelta) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _RateControlSetRateParams();
+      params.referenceDelta = referenceDelta;
+      params.targetDelta = targetDelta;
+      _proxyImpl.sendMessage(params, _RateControl_setRateName);
+    }
+    void setRateAtReferenceTime(int referenceDelta, int targetDelta, int referenceTime) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _RateControlSetRateAtReferenceTimeParams();
+      params.referenceDelta = referenceDelta;
+      params.targetDelta = targetDelta;
+      params.referenceTime = referenceTime;
+      _proxyImpl.sendMessage(params, _RateControl_setRateAtReferenceTimeName);
+    }
+    void setRateAtTargetTime(int referenceDelta, int targetDelta, int targetTime) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _RateControlSetRateAtTargetTimeParams();
+      params.referenceDelta = referenceDelta;
+      params.targetDelta = targetDelta;
+      params.targetTime = targetTime;
+      _proxyImpl.sendMessage(params, _RateControl_setRateAtTargetTimeName);
+    }
+    void cancelPendingChanges() {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new _RateControlCancelPendingChangesParams();
+      _proxyImpl.sendMessage(params, _RateControl_cancelPendingChangesName);
+    }
+}
+
+
+class RateControlProxy implements bindings.ProxyBase {
+  final bindings.Proxy impl;
+  RateControl ptr;
+
+  RateControlProxy(_RateControlProxyImpl proxyImpl) :
+      impl = proxyImpl,
+      ptr = new _RateControlProxyCalls(proxyImpl);
+
+  RateControlProxy.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) :
+      impl = new _RateControlProxyImpl.fromEndpoint(endpoint) {
+    ptr = new _RateControlProxyCalls(impl);
+  }
+
+  RateControlProxy.fromHandle(core.MojoHandle handle) :
+      impl = new _RateControlProxyImpl.fromHandle(handle) {
+    ptr = new _RateControlProxyCalls(impl);
+  }
+
+  RateControlProxy.unbound() :
+      impl = new _RateControlProxyImpl.unbound() {
+    ptr = new _RateControlProxyCalls(impl);
+  }
+
+  factory RateControlProxy.connectToService(
+      bindings.ServiceConnector s, String url, [String serviceName]) {
+    RateControlProxy p = new RateControlProxy.unbound();
+    s.connectToService(url, p, serviceName);
+    return p;
+  }
+
+  static RateControlProxy newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For RateControlProxy"));
+    return new RateControlProxy.fromEndpoint(endpoint);
+  }
+
+  String get serviceName => RateControl.serviceName;
+
+  Future close({bool immediate: false}) => impl.close(immediate: immediate);
+
+  Future responseOrError(Future f) => impl.responseOrError(f);
+
+  Future get errorFuture => impl.errorFuture;
+
+  int get version => impl.version;
+
+  Future<int> queryVersion() => impl.queryVersion();
+
+  void requireVersion(int requiredVersion) {
+    impl.requireVersion(requiredVersion);
+  }
+
+  String toString() {
+    return "RateControlProxy($impl)";
+  }
+}
+
+
+class RateControlStub extends bindings.Stub {
+  RateControl _impl = null;
+
+  RateControlStub.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint, [this._impl])
+      : super.fromEndpoint(endpoint);
+
+  RateControlStub.fromHandle(core.MojoHandle handle, [this._impl])
+      : super.fromHandle(handle);
+
+  RateControlStub.unbound() : super.unbound();
+
+  static RateControlStub newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For RateControlStub"));
+    return new RateControlStub.fromEndpoint(endpoint);
+  }
+
+
+  RateControlGetCurrentTransformResponseParams _RateControlGetCurrentTransformResponseParamsFactory(TimelineTransform trans) {
+    var mojo_factory_result = new RateControlGetCurrentTransformResponseParams();
+    mojo_factory_result.trans = trans;
+    return mojo_factory_result;
+  }
+
+  dynamic handleMessage(bindings.ServiceMessage message) {
+    if (bindings.ControlMessageHandler.isControlMessage(message)) {
+      return bindings.ControlMessageHandler.handleMessage(this,
+                                                          0,
+                                                          message);
+    }
+    assert(_impl != null);
+    switch (message.header.type) {
+      case _RateControl_getCurrentTransformName:
+        var params = _RateControlGetCurrentTransformParams.deserialize(
+            message.payload);
+        var response = _impl.getCurrentTransform(_RateControlGetCurrentTransformResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _RateControl_getCurrentTransformName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _RateControl_getCurrentTransformName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case _RateControl_setCurrentQuadName:
+        var params = _RateControlSetCurrentQuadParams.deserialize(
+            message.payload);
+        _impl.setCurrentQuad(params.quad);
+        break;
+      case _RateControl_setTargetTimelineIdName:
+        var params = _RateControlSetTargetTimelineIdParams.deserialize(
+            message.payload);
+        _impl.setTargetTimelineId(params.id);
+        break;
+      case _RateControl_setRateName:
+        var params = _RateControlSetRateParams.deserialize(
+            message.payload);
+        _impl.setRate(params.referenceDelta, params.targetDelta);
+        break;
+      case _RateControl_setRateAtReferenceTimeName:
+        var params = _RateControlSetRateAtReferenceTimeParams.deserialize(
+            message.payload);
+        _impl.setRateAtReferenceTime(params.referenceDelta, params.targetDelta, params.referenceTime);
+        break;
+      case _RateControl_setRateAtTargetTimeName:
+        var params = _RateControlSetRateAtTargetTimeParams.deserialize(
+            message.payload);
+        _impl.setRateAtTargetTime(params.referenceDelta, params.targetDelta, params.targetTime);
+        break;
+      case _RateControl_cancelPendingChangesName:
+        var params = _RateControlCancelPendingChangesParams.deserialize(
+            message.payload);
+        _impl.cancelPendingChanges();
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+    return null;
+  }
+
+  RateControl get impl => _impl;
+  set impl(RateControl d) {
+    assert(_impl == null);
+    _impl = d;
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "RateControlStub($superString)";
+  }
+
+  int get version => 0;
+}
+
+
diff --git a/mojo/services/media/audio/interfaces/audio_server.mojom b/mojo/services/media/audio/interfaces/audio_server.mojom
index 78f2d08..1e7548f 100644
--- a/mojo/services/media/audio/interfaces/audio_server.mojom
+++ b/mojo/services/media/audio/interfaces/audio_server.mojom
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+[DartPackage="mojo_services"]
 module mojo.media;
 
 import "mojo/services/media/audio/interfaces/audio_track.mojom";
@@ -10,4 +11,3 @@
 interface AudioServer {
   CreateTrack(AudioTrack& track);
 };
-
diff --git a/mojo/services/media/audio/interfaces/audio_track.mojom b/mojo/services/media/audio/interfaces/audio_track.mojom
index 535c91c..36d95b5 100644
--- a/mojo/services/media/audio/interfaces/audio_track.mojom
+++ b/mojo/services/media/audio/interfaces/audio_track.mojom
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+[DartPackage="mojo_services"]
 module mojo.media;
 
 import "mojo/services/media/common/interfaces/media_common.mojom";
@@ -22,7 +23,7 @@
   uint64 max_frames;
 
   // Ratio of audio frames to media time ticks.
-  // 
+  //
   // Presentation time stamps on audio packets are expressed in units of media
   // time ticks.  Many users will choose to use units of audio frames to express
   // their media time, and can simply leave this ratio at the default of 1:1.
@@ -46,10 +47,10 @@
   // Set the configuration, receive a pipe to send data to in return.
   // Possible results include...
   //
-  // kOK:
+  // OK:
   //   Configuration successful, the bound pipe interface is ready to be used.
-  // 
-  // kInvalidArgs:
+  //
+  // INVALID_ARGUMENT:
   //   One or more of the configuration arguments are illegal.  For example, a
   //   value of 0 for either numerator or denominator of the audio frame to
   //   media time ratio.
@@ -57,14 +58,14 @@
   // kUnsupportedConfig:
   //   The requested configuration is not supported by this track.
   //
-  // kInsufficientResources:
+  // INSUFFICIENT_RESOURCES:
   //   Resource limitations prevent configuring the audio track is the desired
   //   way.  Perhaps there is not enough RAM to support the 2.7 days of audio
   //   buffer you requested, or perhaps there is not enough CPU power given the
   //   existing active tracks in the system to support rendering 128 channels
   //   at 1.5 MHz frame rate.
   //
-  // kBadState:
+  // BAD_STATE:
   //  The track is already configured and has pending data in its pipe.  Data
   //  needs to be flushed and the media clock must be stopped before the track
   //  may be re-configured.
@@ -74,10 +75,10 @@
   // Request the rate control interface for this AudioTrack
   // Possbile results include...
   //
-  // kOK:
+  // OK:
   //  Everything went well.
   //
-  // kBadState:
+  // BAD_STATE:
   //  Rate control interface is already bound to a different client.
   GetRateControl(RateControl& rate_control) => (MediaResult result);
 };
diff --git a/mojo/services/media/common/interfaces/BUILD.gn b/mojo/services/media/common/interfaces/BUILD.gn
index 143ead8..42faf07 100644
--- a/mojo/services/media/common/interfaces/BUILD.gn
+++ b/mojo/services/media/common/interfaces/BUILD.gn
@@ -7,8 +7,12 @@
 
 mojom("interfaces") {
   sources = [
+    "media_clock.mojom",
     "media_common.mojom",
+    "media_metadata.mojom",
     "media_pipe.mojom",
+    "media_state.mojom",
+    "media_transport.mojom",
     "media_types.mojom",
     "rate_control.mojom",
   ]
diff --git a/mojo/services/media/common/interfaces/media_clock.mojom b/mojo/services/media/common/interfaces/media_clock.mojom
new file mode 100644
index 0000000..8fdb104
--- /dev/null
+++ b/mojo/services/media/common/interfaces/media_clock.mojom
@@ -0,0 +1,32 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[DartPackage="mojo_services"]
+module mojo.media;
+
+// Expresses a component's disposition with respect to being a clock master or
+// slave.
+enum ClockDisposition {
+  // Clocks are irrelevant. Component will produce/consume on demand.
+  PASSIVE,
+
+  // Component must slave to a master clock.
+  SLAVE,
+
+  // Component can be master or slave, but being slave is preferred.
+  PREFER_SLAVE,
+
+  // Component can be master or slave, doesn't care which.
+  INDIFFERENT,
+
+  // Component can be master or slave, but master is preferred.
+  PREFER_MASTER,
+
+  // Component must be master and cannot slave to a master clock.
+  MASTER
+};
+
+interface Clock {
+  // TODO(dalesat): Define this.
+};
diff --git a/mojo/services/media/common/interfaces/media_common.mojom b/mojo/services/media/common/interfaces/media_common.mojom
index 981ea15..08ae1cc 100644
--- a/mojo/services/media/common/interfaces/media_common.mojom
+++ b/mojo/services/media/common/interfaces/media_common.mojom
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+[DartPackage="mojo_services"]
 module mojo.media;
 
 // TODO(johngro): When the new extensible MojoResult has been introduced,
diff --git a/mojo/services/media/common/interfaces/media_metadata.mojom b/mojo/services/media/common/interfaces/media_metadata.mojom
new file mode 100644
index 0000000..1cbe88c
--- /dev/null
+++ b/mojo/services/media/common/interfaces/media_metadata.mojom
@@ -0,0 +1,24 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[DartPackage="mojo_services"]
+module mojo.media;
+
+// Describes media.
+struct MediaMetadata {
+  // Duration in nanoseconds.
+  uint64 duration;
+
+  string? title;
+
+  string? artist;
+
+  string? album;
+
+  string? publisher;
+
+  string? genre;
+
+  string? composer;
+};
diff --git a/mojo/services/media/common/interfaces/media_pipe.mojom b/mojo/services/media/common/interfaces/media_pipe.mojom
index 50b2d4f..6defe0d 100644
--- a/mojo/services/media/common/interfaces/media_pipe.mojom
+++ b/mojo/services/media/common/interfaces/media_pipe.mojom
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+[DartPackage="mojo_services"]
 module mojo.media;
 
 import "mojo/services/media/common/interfaces/media_common.mojom";
@@ -24,13 +25,19 @@
 struct MediaPacket {
   const int64 kNoTimestamp = 0x7fffffffffffffff;
 
-  // Presentation Time Stamp.  Time time at which the media should be presented,
+  // Presentation Time Stamp.  Time at which the media should be presented,
   // according to the media timeline.
   int64 pts = kNoTimestamp;
 
+  // Duration represented by the packet.
+  uint64 duration;
+
+  // Indicates whether this is the last packet in the stream.
+  bool end_of_stream;
+
   // Bookkeeping to determine where this MediaPacket's payload exists in its
   // MediaPipe's shared buffer.
-  // 
+  //
   // For simple cases, only the payload field is used.  It provides the offset
   // into the shared buffer for the payload, as well as its length.  In more
   // complicated cases (circular buffer, arbitrary scatter-gather), additional
@@ -45,7 +52,7 @@
   // it is zero length.  If this is not going to change, then we should just
   // merge these two fields.
   MediaPacketRegion payload;
-  array<MediaPacketRegion> extra_payload;
+  array<MediaPacketRegion>? extra_payload;
 
   // TODO(johngro): do we need to describe the MediaType of this payload, or is
   // its type implicit based on the channel over which it is being pushed?
@@ -93,15 +100,15 @@
   // object is now available for new data.  MediaResults in the operation may
   // include...
   //
-  // kOK:
+  // OK:
   //   Media packet has been consumed without error.
-  // kBadState:
+  // BAD_STATE:
   //   The media pipe is in a bad state (perhaps uninitialized) and payloads
   //   cannot be pushed to it.
-  // kInvalidArgs:
+  // INVALID_ARGUMENT:
   //   One or more of the payload regions does not appears to go outside the
   //   shared buffer bounds.
-  // kFlushed:
+  // FLUSHED:
   //   The packet was flushed at the request of the producer.  It was not
   //   completely consumed (but may have been partially consumed)
   SendPacket(MediaPacket packet) => (MediaResult result);
@@ -112,11 +119,11 @@
   // flushing and that the pipeline is now empty.  Possible values for the
   // MediaResult parameter of the callback include...
   //
-  // kOK:
+  // OK:
   //    Pipeline has been successfully flushed.
-  // kBusy:
+  // BUSY:
   //    A flush was already in progress, this flush request was ignored.
-  // kBadState:
+  // BAD_STATE:
   //   The media pipe is in a bad state (perhaps uninitialized) and cannot be
   //   flushed
   Flush() => (MediaResult result);
diff --git a/mojo/services/media/common/interfaces/media_state.mojom b/mojo/services/media/common/interfaces/media_state.mojom
new file mode 100644
index 0000000..ca7294c
--- /dev/null
+++ b/mojo/services/media/common/interfaces/media_state.mojom
@@ -0,0 +1,25 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[DartPackage="mojo_services"]
+module mojo.media;
+
+// Expresses the overall state of a media component.
+enum MediaState {
+  // Unable to function due to error. Fault details are provided elsewhere.
+  // TODO(dalesat): Eliminate this state.
+  FAULT,
+
+  // Requires preparation in order to function.
+  UNPREPARED,
+
+  // Prepared, rate zero (paused).
+  PAUSED,
+
+  // Prepared, rate non-zero.
+  PLAYING,
+
+  // Stopped playing because end-of-stream was encountered.
+  ENDED
+};
diff --git a/mojo/services/media/common/interfaces/media_transport.mojom b/mojo/services/media/common/interfaces/media_transport.mojom
new file mode 100644
index 0000000..3847cb6
--- /dev/null
+++ b/mojo/services/media/common/interfaces/media_transport.mojom
@@ -0,0 +1,68 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[DartPackage="mojo_services"]
+module mojo.media;
+
+import "mojo/services/media/common/interfaces/media_common.mojom";
+import "mojo/services/media/common/interfaces/media_pipe.mojom";
+import "mojo/services/media/common/interfaces/media_types.mojom";
+
+// Models a stream producer. A MediaProducer allows a client to connect the
+// producer to a MediaConsumer so packets flow from the producer to the
+// consumer. Clients who want to receive packets directly from the producer
+// should use MediaPullModeProducer instead.
+//
+// The client calls Connect to connect producer and consumer. The producer then
+// calls PushPacket on the consumer to deliver packets.
+interface MediaProducer {
+  // Connects this MediaProducer to a MediaConsumer.
+  Connect(MediaConsumer consumer) => ();
+
+  // Disconnects this MediaProducer from a previously-connected MediaConsumer.
+  Disconnect();
+};
+
+// Models a stream producer. A MediaPullModeProducer allows a client to receive
+// packets directly from the producer. Clients who want to connect the producer
+// to a MediaConsumer should use MediaProducer instead.
+//
+// The client calls PullPacket to get a packet. Once the client is done with
+// the packet, it calls ReleasePacket to let the producer know that the packet
+// buffer region can be reused. Alternatively, the client can piggyback a
+// release on a PullPacket call using the to_release parameter.
+interface MediaPullModeProducer {
+  // Gets the shared buffer in which packet payload will be located.
+  GetBuffer() => (handle<shared_buffer> buffer);
+
+  // Pulls a packet from the producer. When the client is done with the
+  // packet buffer region, it should call ReleasePacket or PullPacket passing
+  // the locator. Note that the optional locator passed in PullPacket is
+  // a locator to be released and probably won't be the same locator passed
+  // back in the callback.
+  PullPacket(MediaPacket? to_release) => (MediaPacket packet);
+
+  // Signals the producer that the client is done with the buffer region.
+  ReleasePacket(MediaPacket to_release);
+};
+
+// Models a stream consumer. A MediaConsumer allows a client to send packets
+// directly to the consumer or to connect the consumer to a MediaProducer so
+// packets flow from the producer to the consumer.
+//
+// In the former scenario, the client calls PushPacket to deliver a packet. The
+// callback notifies the client that the consumer is done with the packet
+// buffer region.
+//
+// In the latter scenario, the client calls Connect on the producer to connect
+// producer and consumer. The producer then calls PushPacket on the consumer to
+// deliver packets.
+interface MediaConsumer {
+  // Sets the shared buffer in which packet payload will be located.
+  SetBuffer(handle<shared_buffer> buffer, uint64 size) => ();
+
+  // Pushes a packet to the consumer. The callback signals that the consumer
+  // is done with the packet buffer region.
+  PushPacket(MediaPacket packet) => ();
+};
diff --git a/mojo/services/media/common/interfaces/media_types.mojom b/mojo/services/media/common/interfaces/media_types.mojom
index db06447..76f2de0 100644
--- a/mojo/services/media/common/interfaces/media_types.mojom
+++ b/mojo/services/media/common/interfaces/media_types.mojom
@@ -2,59 +2,273 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+[DartPackage="mojo_services"]
 module mojo.media;
 
-enum LpcmSampleFormat {
-  UNSIGNED_8,
-  SIGNED_16,
-  SIGNED_24_IN_32,  // TODO(johngro): describe the packing for this
-};
-
-struct LpcmMediaTypeDetails {
-  LpcmSampleFormat sample_format;
-  uint8 channels;
-  uint32 frames_per_second;
-};
-
-struct LpcmMediaTypeSetDetails {
-  LpcmSampleFormat sample_format;
-  uint8 min_channels;
-  uint8 max_channels;
-  uint32 min_frames_per_second;
-  uint32 max_frames_per_second;
-};
-
-enum MediaTypeScheme {
-  LPCM,
-  // There will be more.
-};
-
-union MediaTypeDetails {
-  LpcmMediaTypeDetails lpcm;
-  // There will be more.
-};
-
+// Specifies the type of media.
 struct MediaType {
-  // Broadly identifies the media type and indicates how the details
-  // field is to be interpreted.
+  // Broadly identifies the media type and indicates how the details field is
+  // to be interpreted.
   MediaTypeScheme scheme;
 
   // Scheme-dependent details.
-  MediaTypeDetails details;
+  MediaTypeDetails? details;
+};
+
+// Specifies a set of types of media.
+// TODO(dalesat): Consider eliminating type sets.
+struct MediaTypeSet {
+  // Broadly identifies the media types and indicates how the details field is
+  // to be interpreted.
+  MediaTypeScheme scheme;
+
+  // Scheme-dependent details.
+  MediaTypeSetDetails? details;
+};
+
+// Media type schemes. A media type scheme broadly identifies a media type and
+// indicates what structure, if any, is used to specify the details of the type.
+// If a scheme XYZ has details, then there should be structure definitions for
+// XyzMediaTypeDetails and XyzMediaTypeSetDetails, and fields of those types
+// should appear in MediaTypeDetails and MediaTypeSetDetails respectively.
+// TODO(dalesat): Placeholder schemes could go away as part of eliminating
+// or simplifying type sets.
+enum MediaTypeScheme {
+  // Placeholder indicating type is unknown.
+  UNKNOWN,
+
+  // Placeholder indicating no type.
+  NONE,
+
+  // Placeholder indicating any elementary type.
+  ANY_ELEMENTARY,
+
+  // Placeholder indicating any audio type.
+  ANY_AUDIO,
+
+  // Placeholder indicating any video type.
+  ANY_VIDEO,
+
+  // Placeholder indicating any subpicture type.
+  ANY_SUBPICTURE,
+
+  // Placeholder indicating any text type.
+  ANY_TEXT,
+
+  // Placeholder indicating any multiplexed type.
+  ANY_MULTIPLEXED,
+
+  // Placeholder indicating any type.
+  ANY,
+
+  // Indicates a multiplexed type. See MultiplexedMediaTypeDetails and
+  // MultiplexedMediaTypeSetDetails.
+  MULTIPLEXED,
+
+  // Indicates LPCM audio. See LpcmMediaTypeDetails and LpcmMediaTypeSetDetails.
+  LPCM,
+
+  // Indicates compressed audio. See CompressedAudioMediaTypeDetails and
+  // CompressedAudioMediaTypeSetDetails.
+  COMPRESSED_AUDIO,
+
+  // Indicates video. See VideoMediaTypeDetails and VideoMediaTypeSetDetails.
+  // TODO(dalesat): One scheme for video won't be adequate.
+  VIDEO
+};
+
+// A union of all media type details.
+union MediaTypeDetails {
+  // Each field name should correspond to a value in MediaTypeScheme.
+  MultiplexedMediaTypeDetails multiplexed;
+  LpcmMediaTypeDetails lpcm;
+  CompressedAudioMediaTypeDetails compressed_audio;
+  VideoMediaTypeDetails video;
 };
 
 // A union of all media type set details.
 union MediaTypeSetDetails {
   // Each field name should correspond to a value in MediaTypeScheme.
+  MultiplexedMediaTypeSetDetails multiplexed;
   LpcmMediaTypeSetDetails lpcm;
+  CompressedAudioMediaTypeSetDetails compressed_audio;
+  VideoMediaTypeSetDetails video;
 };
 
-// Specifies a set of types of media.
-struct MediaTypeSet {
-  // Broadly identifies the media types and indicates how the details
-  // field is to be interpreted.
-  MediaTypeScheme scheme;
+// MediaType details for the LPCM scheme.
+struct LpcmMediaTypeDetails {
+  LpcmSampleFormat sample_format;
+  uint32 channels;
+  uint32 frames_per_second;
+  // TODO(dalesat): Channel designations.
+};
 
-  // Scheme-dependent details.
-  MediaTypeSetDetails details;
+// MediaTypeSet details for the LPCM scheme.
+struct LpcmMediaTypeSetDetails {
+  LpcmSampleFormat sample_format;
+  uint32 min_channels;
+  uint32 max_channels;
+  uint32 min_frames_per_second;
+  uint32 max_frames_per_second;
+};
+
+// Sample formats for LPCM media types.
+enum LpcmSampleFormat {
+  // Placeholder indicating sample format is unknown.
+  UNKNOWN,
+
+  // Placeholder indicating any sample format.
+  ANY,
+
+  // 8-bit unsigned samples, sample size 1 byte.
+  UNSIGNED_8,
+
+  // 16-bit signed samples, host-endian, sample size 2 bytes.
+  SIGNED_16,
+
+  // 24-bit signed samples in 32 bits, host-endian, sample size 4 bytes.
+  // TODO(johngro): describe the packing for this
+  SIGNED_24_IN_32, // Host endian
+
+  // 32-bit floating-point samples, sample size 4 bytes.
+  FLOAT
+};
+
+// Media type details for the Multiplexed scheme.
+struct MultiplexedMediaTypeDetails {
+  // Describes how the streams are multiplexed.
+  MediaType multiplex_type;
+
+  // Media type for each substream.
+  array<MediaType> substream_types;
+};
+
+// Media type set details for the Multiplexed scheme.
+struct MultiplexedMediaTypeSetDetails {
+  // Describes how the streams can be multiplexed.
+  MediaTypeSet multiplex_type_set;
+
+  // Possible substream types.
+  array<MediaTypeSet> substream_type_sets;
+};
+
+// Audio encodings.
+// TODO(dalesat): Add more audio encodings.
+enum AudioEncoding {
+  // Placeholder indicating audio encoding is unknown.
+  UNKNOWN,
+
+  // Placeholder indicating any audio encoding.
+  ANY,
+
+  VORBIS
+};
+
+// Media type details for the COMPRESSED_AUDIO scheme.
+struct CompressedAudioMediaTypeDetails {
+  AudioEncoding encoding;
+  LpcmSampleFormat sample_format;
+  uint32 channels;
+  uint32 frames_per_second;
+
+  // Encoding-specific parameter provided by demuxes and used by decoders.
+  string extra_data_base64;
+};
+
+// Media type set details for the COMPRESSED_AUDIO scheme.
+struct CompressedAudioMediaTypeSetDetails {
+  AudioEncoding encoding;
+  LpcmSampleFormat sample_format;
+  uint32 min_channels;
+  uint32 max_channels;
+  uint32 min_frames_per_second;
+  uint32 max_frames_per_second;
+};
+
+// Media type details for the VIDEO scheme.
+// TODO(dalesat): Expand and document.
+struct VideoMediaTypeDetails {
+  VideoEncoding encoding;
+  VideoProfile profile;
+  PixelFormat pixel_format;
+  ColorSpace color_space;
+  uint32 width;
+  uint32 height;
+  uint32 coded_width;
+  uint32 coded_height;
+
+  // Encoding-specific parameter provided by demuxes and used by decoders.
+  string extra_data_base64;
+};
+
+// Media type set details for the VIDEO scheme.
+// TODO(dalesat): Expand and document.
+struct VideoMediaTypeSetDetails {
+  VideoEncoding encoding;
+  uint32 min_width;
+  uint32 max_width;
+  uint32 min_height;
+  uint32 max_height;
+};
+
+// Video encodings.
+// TODO(dalesat): Add more video encodings.
+enum VideoEncoding {
+  // Placeholder indicating video encoding is unknown.
+  UNKNOWN,
+
+  // Placeholder indicating any video encoding.
+  ANY,
+
+  THEORA,
+  VP8
+};
+
+// Video profiles.
+// TODO(dalesat): Blindly copied from Chromium, revisit.
+enum VideoProfile {
+  UNKNOWN,
+  NOT_APPLICABLE,
+  H264_BASELINE,
+  H264_MAIN,
+  H264_EXTENDED,
+  H264_HIGH,
+  H264_HIGH10,
+  H264_HIGH422,
+  H264_HIGH444_PREDICTIVE,
+  H264_SCALABLE_BASELINE,
+  H264_SCALABLE_HIGH,
+  H264_STEREO_HIGH,
+  H264_MULTIVIEW_HIGH
+};
+
+// Pixel format.
+// TODO(dalesat): Blindly copied from Chromium, revisit.
+enum PixelFormat {
+  UNKNOWN,
+  I420,  // 12bpp YUV planar 1x1 Y, 2x2 UV samples, a.k.a. YU12.
+  YV12,  // 12bpp YVU planar 1x1 Y, 2x2 VU samples.
+  YV16,  // 16bpp YVU planar 1x1 Y, 2x1 VU samples.
+  YV12A,  // 20bpp YUVA planar 1x1 Y, 2x2 VU, 1x1 A samples.
+  YV24,  // 24bpp YUV planar, no subsampling.
+  NV12,  // 12bpp with Y plane followed by a 2x2 interleaved UV plane.
+  NV21,  // 12bpp with Y plane followed by a 2x2 interleaved VU plane.
+  UYVY,  // 16bpp interleaved 2x1 U, 1x1 Y, 2x1 V, 1x1 Y samples.
+  YUY2,  // 16bpp interleaved 1x1 Y, 2x1 U, 1x1 Y, 2x1 V samples.
+  ARGB,  // 32bpp ARGB, 1 plane.
+  XRGB,  // 24bpp XRGB, 1 plane.
+  RGB24,  // 24bpp BGR, 1 plane.
+  RGB32,  // 32bpp BGRA, 1 plane.
+  MJPEG,  // MJPEG compressed.
+  MT21
+};
+
+// Pixel format.
+// TODO(dalesat): Blindly copied from Chromium, revisit.
+enum ColorSpace {
+  UNKNOWN,
+  NOT_APPLICABLE,
+  JPEG,
+  HD_REC709,
+  SD_REC601
 };
diff --git a/mojo/services/media/common/interfaces/rate_control.mojom b/mojo/services/media/common/interfaces/rate_control.mojom
index 849257e..da272a2 100644
--- a/mojo/services/media/common/interfaces/rate_control.mojom
+++ b/mojo/services/media/common/interfaces/rate_control.mojom
@@ -2,9 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+[DartPackage="mojo_services"]
 module mojo.media;
 
 // TimelineQuad
+// TODO(dalesat): Rename reference -> presentation.
+// TODO(dalesat): Rename target -> reference.
 //
 // A structure which holds the four numbers needed to define a linear
 // relationship between the points in two different timelines.  The relationship
@@ -38,6 +41,8 @@
 };
 
 // TimelineTransform
+// TODO(dalesat): Rename reference -> presentation.
+// TODO(dalesat): Rename target -> reference.
 //
 // A structure which holds both a timeline quad, and a pair of identifiers which
 // define the specific timelines which are the reference and target timelines.
diff --git a/mojo/services/media/control/interfaces/BUILD.gn b/mojo/services/media/control/interfaces/BUILD.gn
new file mode 100644
index 0000000..b916269
--- /dev/null
+++ b/mojo/services/media/control/interfaces/BUILD.gn
@@ -0,0 +1,15 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/module_args/mojo.gni")
+import("$mojo_sdk_root/mojo/public/tools/bindings/mojom.gni")
+
+mojom("interfaces") {
+  sources = [
+    "media_factory.mojom",
+    "media_player.mojom",
+    "media_sink.mojom",
+    "media_source.mojom",
+  ]
+}
diff --git a/mojo/services/media/control/interfaces/media_factory.mojom b/mojo/services/media/control/interfaces/media_factory.mojom
new file mode 100644
index 0000000..826ce07
--- /dev/null
+++ b/mojo/services/media/control/interfaces/media_factory.mojom
@@ -0,0 +1,34 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[DartPackage="mojo_services"]
+module mojo.media;
+
+import "mojo/services/media/common/interfaces/media_types.mojom";
+import "mojo/services/media/control/interfaces/media_player.mojom";
+import "mojo/services/media/control/interfaces/media_sink.mojom";
+import "mojo/services/media/control/interfaces/media_source.mojom";
+
+// Exposed by the factory service to create media-related agents.
+[ServiceName="mojo::media::MediaFactory"]
+interface MediaFactory {
+  // Creates a player.
+  // TODO(dalesat): Add means of specifying destinations.
+  CreatePlayer(string origin_url, MediaPlayer& player);
+
+  // Creates a source. If allowed_media_types is supplied, conversions will be
+  // added to each stream as needed to make the media type of the stream match
+  // one of the allowed types. If a stream cannot be converted to one of the
+  // allowed types, its media type will have the scheme NONE, and the stream
+  // will not be usable.
+  CreateSource(
+      string origin_url,
+      array<MediaTypeSet>? allowed_media_types,
+      MediaSource& source);
+
+  // Creates a sink. Conversions are added to the pipeline as appropriate to
+  // convert the indicated media type to a type compatible with the
+  // destination.
+  CreateSink(string destination_url, MediaType media_type, MediaSink& sink);
+};
diff --git a/mojo/services/media/control/interfaces/media_player.mojom b/mojo/services/media/control/interfaces/media_player.mojom
new file mode 100644
index 0000000..f2497c0
--- /dev/null
+++ b/mojo/services/media/control/interfaces/media_player.mojom
@@ -0,0 +1,37 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[DartPackage="mojo_services"]
+module mojo.media;
+
+import "mojo/services/media/common/interfaces/media_metadata.mojom";
+import "mojo/services/media/common/interfaces/media_state.mojom";
+import "mojo/services/media/common/interfaces/rate_control.mojom";
+
+// Plays media.
+interface MediaPlayer {
+  // Starts playback.
+  Play();
+
+  // Pauses playback.
+  Pause();
+
+  // Gets the status. To get the status immediately, call GetStatus(0). To
+  // get updates thereafter, pass the version sent in the previous callback.
+  GetStatus(uint64 version_last_seen) =>
+      (uint64 version, MediaPlayerStatus status);
+};
+
+// MediaPlayer status information.
+struct MediaPlayerStatus {
+  // Current state of the player.
+  MediaState state;
+
+  // Transform translating local time to presentation time. Reverse translation
+  // (presentation time to local time) is only valid when media is playing.
+  TimelineTransform? timeline_transform;
+
+  // Describes the media.
+  MediaMetadata? metadata;
+};
diff --git a/mojo/services/media/control/interfaces/media_sink.mojom b/mojo/services/media/control/interfaces/media_sink.mojom
new file mode 100644
index 0000000..efaa630
--- /dev/null
+++ b/mojo/services/media/control/interfaces/media_sink.mojom
@@ -0,0 +1,53 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[DartPackage="mojo_services"]
+module mojo.media;
+
+import "mojo/services/media/common/interfaces/media_clock.mojom";
+import "mojo/services/media/common/interfaces/media_common.mojom";
+import "mojo/services/media/common/interfaces/media_state.mojom";
+import "mojo/services/media/common/interfaces/media_transport.mojom";
+import "mojo/services/media/common/interfaces/media_types.mojom";
+import "mojo/services/media/common/interfaces/rate_control.mojom";
+
+// TODO(dalesat): Define a media sink that multiplexes streams.
+
+// Consumes media streams and delivers them to specified destinations.
+interface MediaSink {
+  // TODO(dalesat): Support fanout to many destinations.
+
+  // Gets the clock disposition from the source.
+  GetClockDisposition() => (ClockDisposition clock_disposition);
+
+  // Gets a master clock if the sink can be master, null otherwise.
+  GetMasterClock(Clock& master_clock);
+
+  // Sets a master clock.
+  SetMasterClock(Clock? master_clock);
+
+  // Gets the consumer for the stream to be delivered.
+  GetConsumer(MediaConsumer& consumer);
+
+  // Gets the status. To get the status immediately, call GetStatus(0). To
+  // get updates thereafter, pass the version sent in the previous callback.
+  GetStatus(uint64 version_last_seen) =>
+      (uint64 version, MediaSinkStatus status);
+
+  // Starts playback.
+  Play();
+
+  // Pauses playback.
+  Pause();
+};
+
+// MediaSink status information.
+struct MediaSinkStatus {
+  // Current state of the sink.
+  MediaState state;
+
+  // Transform translating local time to presentation time. Reverse translation
+  // (presentation time to local time) is only valid when media is playing.
+  TimelineTransform? timeline_transform;
+};
diff --git a/mojo/services/media/control/interfaces/media_source.mojom b/mojo/services/media/control/interfaces/media_source.mojom
new file mode 100644
index 0000000..22846c0
--- /dev/null
+++ b/mojo/services/media/control/interfaces/media_source.mojom
@@ -0,0 +1,64 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[DartPackage="mojo_services"]
+module mojo.media;
+
+import "mojo/services/media/common/interfaces/media_clock.mojom";
+import "mojo/services/media/common/interfaces/media_common.mojom";
+import "mojo/services/media/common/interfaces/media_metadata.mojom";
+import "mojo/services/media/common/interfaces/media_state.mojom";
+import "mojo/services/media/common/interfaces/media_transport.mojom";
+import "mojo/services/media/common/interfaces/media_types.mojom";
+
+// Produces media streams delivered from a specified origin.
+interface MediaSource {
+  // Gets the streams produced by this source.
+  GetStreams() => (array<MediaSourceStreamDescriptor> streams);
+
+  // Gets the clock disposition from the source.
+  GetClockDisposition() => (ClockDisposition clock_disposition);
+
+  // Gets a master clock if the source can be master, null otherwise.
+  GetMasterClock(Clock& master_clock);
+
+  // Sets a master clock.
+  SetMasterClock(Clock? master_clock);
+
+  // Gets the producer for the specified stream.
+  GetProducer(uint32 stream_index, MediaProducer& producer);
+
+  // Gets the pull mode producer for the specified stream.
+  GetPullModeProducer(uint32 stream_index, MediaPullModeProducer& producer);
+
+  // Gets the status. To get the status immediately, call GetStatus(0). To
+  // get updates thereafter, pass the version sent in the previous callback.
+  GetStatus(uint64 version_last_seen) =>
+      (uint64 version, MediaSourceStatus status);
+
+  // Prepares the source.
+  // TODO(dalesat): Revisit.
+  Prepare() => ();
+};
+
+// Describes a media stream produced by a source.
+struct MediaSourceStreamDescriptor {
+  // Zero-based index.
+  uint32 index;
+
+  // Media type of the stream after conversion.
+  MediaType media_type;
+
+  // Media type of the stream before conversion (as produced by the demux).
+  MediaType original_media_type;
+};
+
+// Describes the media source.
+struct MediaSourceStatus {
+  // Current state of the source.
+  MediaState state;
+
+  // Describes the media.
+  MediaMetadata? metadata;
+};
diff --git a/mojo/services/mojo_services.gni b/mojo/services/mojo_services.gni
index 315ce1e..791d4ed 100644
--- a/mojo/services/mojo_services.gni
+++ b/mojo/services/mojo_services.gni
@@ -26,6 +26,9 @@
   "//mojo/services/keyboard/interfaces",
   "//mojo/services/location/interfaces",
   "//mojo/services/log/interfaces",
+  "//mojo/services/media/audio/interfaces",
+  "//mojo/services/media/common/interfaces",
+  "//mojo/services/media/control/interfaces",
   "//mojo/services/native_support/interfaces",
   "//mojo/services/native_viewport/interfaces",
   "//mojo/services/navigation/interfaces",
diff --git a/services/media/audio/audio_track_impl.cc b/services/media/audio/audio_track_impl.cc
index ae698cc..3c21327 100644
--- a/services/media/audio/audio_track_impl.cc
+++ b/services/media/audio/audio_track_impl.cc
@@ -22,8 +22,8 @@
 // initialization using mojom generated structs, we should switch to it.
 static const struct {
   LpcmSampleFormat sample_format;
-  uint8_t min_channels;
-  uint8_t max_channels;
+  uint32_t min_channels;
+  uint32_t max_channels;
   uint32_t min_frames_per_second;
   uint32_t max_frames_per_second;
 } kSupportedLpcmTypeSets[] = {
@@ -90,7 +90,7 @@
     const auto& s = kSupportedLpcmTypeSets[i];
     LpcmMediaTypeSetDetailsPtr lpcm_detail = LpcmMediaTypeSetDetails::New();
 
-    lpcm_detail->sample_format         = s.sample_format;
+    lpcm_detail->sample_format = s.sample_format;
     lpcm_detail->min_channels = s.min_channels;
     lpcm_detail->max_channels = s.max_channels;
     lpcm_detail->min_frames_per_second = s.min_frames_per_second;
diff --git a/services/media/audio/platform/linux/alsa_output.cc b/services/media/audio/platform/linux/alsa_output.cc
index 17c1157..e10c073 100644
--- a/services/media/audio/platform/linux/alsa_output.cc
+++ b/services/media/audio/platform/linux/alsa_output.cc
@@ -397,4 +397,3 @@
 }  // namespace audio
 }  // namespace media
 }  // namespace mojo
-
diff --git a/services/media/common/media_pipe_base.cc b/services/media/common/media_pipe_base.cc
index 8ae12b6..b80c3d6 100644
--- a/services/media/common/media_pipe_base.cc
+++ b/services/media/common/media_pipe_base.cc
@@ -101,6 +101,8 @@
   // of the shared buffer.  If any does not, this send operation is not valid.
   const MediaPacketRegionPtr* r = &packet->payload;
   size_t i = 0;
+  size_t extra_payload_size =
+      packet->extra_payload.is_null() ? 0 : packet->extra_payload.size();
   while (true) {
     if ((*r).is_null()) {
       cbk.Run(MediaResult::INVALID_ARGUMENT);
@@ -114,10 +116,11 @@
       return;
     }
 
-    if (i >= packet->extra_payload.size()) {
+    if (i >= extra_payload_size) {
       break;
     }
 
+    DCHECK(packet->extra_payload);
     r = &packet->extra_payload[i++];
   }
 
@@ -156,7 +159,6 @@
   , result_(MediaResult::OK) {
   DCHECK(packet_);
   DCHECK(packet_->payload);
-  DCHECK(packet_->extra_payload);
 }
 
 MediaPipeBase::MediaPacketState::~MediaPacketState() {
diff --git a/shell/BUILD.gn b/shell/BUILD.gn
index 54d013f..1359307 100644
--- a/shell/BUILD.gn
+++ b/shell/BUILD.gn
@@ -17,9 +17,9 @@
   testonly = true
 
   deps = [
+    ":copy_symbols",
     ":mojo_shell",
     ":tests",
-    ":copy_symbols",
   ]
 
   if (is_android) {
@@ -200,8 +200,8 @@
   deps = [
     ":child_controller_bindings",
     "//base",
-    "//base/third_party/dynamic_annotations",
     "//base:base_static",
+    "//base/third_party/dynamic_annotations",
     "//mojo/application",
     "//mojo/common",
     "//mojo/common:tracing_impl",
@@ -210,6 +210,9 @@
     "//mojo/edk/system",
     "//mojo/public/cpp/bindings",
     "//mojo/public/interfaces/application",
+    "//mojo/services/media/audio/interfaces",
+    "//mojo/services/media/common/interfaces",
+    "//mojo/services/media/control/interfaces",
     "//mojo/services/network/interfaces",
     "//mojo/services/tracing/interfaces",
     "//services/url_response_disk_cache",
@@ -416,9 +419,9 @@
       "$root_out_dir/obj/shell/bootstrap_java.dex.jar",
     ]
     deps = [
-      ":mojo_shell_child",
       ":bootstrap",
       ":bootstrap_java",
+      ":mojo_shell_child",
       "//mojo/public/tools:copy_network_service",
     ]
 
@@ -437,10 +440,10 @@
 
       deps += [
         "//services/authenticating_url_loader_interceptor",
-        "//services/java_handler",
         "//services/dart:dart_content_handler",
         "//services/device_info",
         "//services/icu_data",
+        "//services/java_handler",
         "//services/kiosk_wm",
         "//services/surfaces",
         "//services/tracing",
@@ -589,8 +592,8 @@
   deps = [
     ":parent_lib",
     "//base",
-    "//base/test:test_support",
     "//base:i18n",
+    "//base/test:test_support",
     "//mojo/common",
     "//mojo/edk/system",
     "//mojo/environment:chromium",
@@ -655,6 +658,7 @@
   ]
 
   deps = [
+    ":embed_pingable",
     "//base",
     "//mojo/application",
     "//mojo/application:test_support",
@@ -667,7 +671,6 @@
     "//mojo/services/http_server/interfaces",
     "//mojo/services/network/interfaces",
     "//shell/test:bindings",
-    ":embed_pingable",
   ]
 
   data_deps = [
diff --git a/third_party/dart-pkg/archive b/third_party/dart-pkg/archive
new file mode 160000
index 0000000..07ffd98
--- /dev/null
+++ b/third_party/dart-pkg/archive
@@ -0,0 +1 @@
+Subproject commit 07ffd98c5403b7f9ae067b57dc9487611be420f5
diff --git a/third_party/dart-pkg/args b/third_party/dart-pkg/args
new file mode 160000
index 0000000..e0e8377
--- /dev/null
+++ b/third_party/dart-pkg/args
@@ -0,0 +1 @@
+Subproject commit e0e8377412ee6cd6a5a4a8632848181c1db91f44
diff --git a/third_party/dart-pkg/box2d b/third_party/dart-pkg/box2d
new file mode 160000
index 0000000..c5e65d9
--- /dev/null
+++ b/third_party/dart-pkg/box2d
@@ -0,0 +1 @@
+Subproject commit c5e65d9546275e78ad2a1d51b459e7638f6e4323
diff --git a/third_party/dart-pkg/cassowary b/third_party/dart-pkg/cassowary
new file mode 160000
index 0000000..7e5afc5
--- /dev/null
+++ b/third_party/dart-pkg/cassowary
@@ -0,0 +1 @@
+Subproject commit 7e5afc5b3956a18636d5b37b1dcba1705865564b
diff --git a/third_party/dart-pkg/collection b/third_party/dart-pkg/collection
new file mode 160000
index 0000000..79ebc6f
--- /dev/null
+++ b/third_party/dart-pkg/collection
@@ -0,0 +1 @@
+Subproject commit 79ebc6fc2dae581cb23ad50a5c600c1b7dd132f8
diff --git a/third_party/dart-pkg/crypto b/third_party/dart-pkg/crypto
new file mode 160000
index 0000000..d4558de
--- /dev/null
+++ b/third_party/dart-pkg/crypto
@@ -0,0 +1 @@
+Subproject commit d4558dea1639e5ad2a41d045265b8ece270c2d90
diff --git a/third_party/dart-pkg/newton b/third_party/dart-pkg/newton
new file mode 160000
index 0000000..9fbe5fb
--- /dev/null
+++ b/third_party/dart-pkg/newton
@@ -0,0 +1 @@
+Subproject commit 9fbe5fbac809246f7ace4176feca13bdf731e393
diff --git a/third_party/dart-pkg/path b/third_party/dart-pkg/path
new file mode 160000
index 0000000..2f3dcde
--- /dev/null
+++ b/third_party/dart-pkg/path
@@ -0,0 +1 @@
+Subproject commit 2f3dcdec32011f1bc41194ae3640d6d9292a7096
diff --git a/third_party/dart-pkg/quiver b/third_party/dart-pkg/quiver
new file mode 160000
index 0000000..6bab7de
--- /dev/null
+++ b/third_party/dart-pkg/quiver
@@ -0,0 +1 @@
+Subproject commit 6bab7dec34189eee579178eb16d3063c8ae69031
diff --git a/third_party/dart-pkg/source_span b/third_party/dart-pkg/source_span
new file mode 160000
index 0000000..5c6c13f
--- /dev/null
+++ b/third_party/dart-pkg/source_span
@@ -0,0 +1 @@
+Subproject commit 5c6c13f62fc111adaace3aeb4a38853d64481d06
diff --git a/third_party/dart-pkg/string_scanner b/third_party/dart-pkg/string_scanner
new file mode 160000
index 0000000..9f00056
--- /dev/null
+++ b/third_party/dart-pkg/string_scanner
@@ -0,0 +1 @@
+Subproject commit 9f00056b32f41efc376adecfb696a01bc7c593d7
diff --git a/third_party/dart-pkg/vector_math b/third_party/dart-pkg/vector_math
new file mode 160000
index 0000000..6591558
--- /dev/null
+++ b/third_party/dart-pkg/vector_math
@@ -0,0 +1 @@
+Subproject commit 65915583f7aa606cb47ed265f853c18c60102b81
diff --git a/third_party/dart-pkg/yaml b/third_party/dart-pkg/yaml
new file mode 160000
index 0000000..d8c1ce7
--- /dev/null
+++ b/third_party/dart-pkg/yaml
@@ -0,0 +1 @@
+Subproject commit d8c1ce75edf051ea1d5583b24474f8656abb4920
diff --git a/third_party/ffmpeg b/third_party/ffmpeg
new file mode 160000
index 0000000..6f7f37e
--- /dev/null
+++ b/third_party/ffmpeg
@@ -0,0 +1 @@
+Subproject commit 6f7f37e8c16db3bad5624c7504e710c54bdb7bf5