Re: Proposal-ORTC Sender / Receiver Capabilities Based Model

I agree on keeping things simple. I have watched the draft grow during 
refinement which is normal but the original goal was to implement 
low-level object primitives that can be abstracted using a plethora of 
JS libraries.

If the base ORTC library becomes too large it will raise the bar to the 
extent where only a few libraries actually fully integrate with it 
which I believe misses the goal of designing an API we seek to see 
widely adopted.

Christoph


On May 9, 2014 02:14:03 PM EDT, Peter Thatcher <pthatcher@google.com> wrote:

> OK, I've had to read through the recent threads and this proposal fairly
> thoroughly.  My thoughts are:
>
> 1.  Most, maybe all, of this, like createParameters and filterParameters in
> the first place, is convenience and could be implemented in a JS library.
>  For such things, we should set a high bar for value vs. cost.
>
> 2.  This adds a huge amount of extra complexity (cost) to the API surface.
>  We'd go from having Parameters and Capabilities to having Capabilities,
> Parameters, Preferences, Options, Settings, and Details.  Your first
> advantage listed is "simplicity".  I must humbly disagree.  I think this is
> all very complex.  However, if this is simplicity from your perspective,
> then I have good news: you can implement most (all?) of it in JS as a
> library :).
>
> 3.  Most of what you are trying to do seams to be to make it easy to create
> an SVC setup.  In other words, SVC/simulcast without touching
> RtpParameters.  As far as I know, then only use case for SVC/simulcast is
> for multiway video.  Multiway video *is not a simple use case* and I don't
> think we should be adding lots of convenience stuff to the API to cover
> that use case.  We should certainly make it possible to do multiway video
> (provide the power), and certainly JS libraries on top can make it easier
> (provide the convenience), but the convenience functions built into the
> API, such as createParameters and filterParameters, can only cover a
> certain set of simple use cases.  Multiway video is beyond what those can
> provide, unless there's a really simple way of doing it (so that the value
> outweighs the cost).
>
> 4.  Having a simplified "here's the kind of thing I'm looking for" as an
> optional parameter to createParameters might be worth it (more value than
> cost), but I think it would need to be very simple.  I think that might be
> worth exploring in a much more limited capacity.
>
>
> tl;dr: I see a lot of complexity and not a lot of benefit.   The idea of
> adding an extra parameter to createParameters might be worth it in a much
> more simple version.
>
>
> On Wed, May 7, 2014 at 9:13 PM, Robin Raymond <robin@hookflash.com> wrote:
>
>>
>> I am contributing a proposal on how to resolve an issue discovered in the
>> usage of "parameters". While the details can always be tweaked, I think it
>> successfully resolves much of the concern around the level and knowledge
>> required to configure a "parameters" object for anything other than the
>> basic use cases.
>>
>> In response to this posting:
>> http://lists.w3.org/Archives/Public/public-ortc/2014May/0007.html
>>
>> This also addresses the issue of exchanging detailed parameters over the
>> wire and instead base parameters based on capabilities.
>>
>> I am going to copy the entire proposal below to official contribute the
>> proposal but for the sake of readability I am also including a link to the
>> google doc(s).
>>
>> Proposal-ORTC Sender / Receiver Capabilities Based Model
>>
>> https://docs.google.com/document/d/1htyRaNjXTE_O1GhD8TcLCNXFvVsgszpE8Lqgp3OCHlU/edit?usp=sharing
>>
>> Proposal-ORTC Sender / Receiver Use Case [Usage Comparison Analysis]
>>
>> https://docs.google.com/document/d/1hdhCHj-gpwv06vIbAftxMG3oZtz7A-nuYsuwQEkTat4/edit?usp=sharing
>>
>>
>>
>>
>> Proposal-ORTC Sender / Receiver Capabilities Based Model
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> *Introduction After attempting to write out some use cases using the
>> existing RTCRtpSender and RTCRtpReciever objects and parameters for ORTC,
>> some issues were discovered. Specifically, the application developer would
>> need to have a fair amount of knowledge on exactly how to tweak low level
>> parameters for anything beyond very simple use cases. For example, setting
>> up an SVC (Scalable Video Codec) would have required knowing about what
>> codecs support SVC, how the layering is setup for particular codecs, and
>> finally setting up specific geometric (or temporal) attributes and layering
>> relationship details by an application developer.As a result of the lack of
>> easily configuration of RTP features, the idea came out to give the
>> application developer "preferences" where the developer could choose what
>> they want desire with high level knobs and dials and let the engine (which
>> has explicit knowledge of each codec) configure the low level "parameters"
>> details according to a developer's wishes. The engine could then return the
>> closest set of preferences that could be achieved given the capabilities of
>> the engine and the developer can then choose to proceed or not setting up
>> media flows using these preferences and constructed parameters.Another
>> important discovery was made in the process of defining "preferences". If
>> two ORTC engines were given the same set of preferences and the
>> capabilities of both sender and receiver, each engine could be made to
>> construct "compatible" sender and receiver "parameters" details without
>> ever exchanging the parameter details over the wire. This small realization
>> about generating "parameters" from capabilities for local consumption by an
>> engine has a huge impact. This generation removes the need for an engine to
>> understand and filter settings that it may not understand created by
>> another engine of unknown origin, which may use proprietary and/or custom
>> settings. A simple "ignore capabilities you don't understand" rule could
>> replace complex and cumbersome rules that would be otherwise required if
>> "parameters" were to be sent over the wire and later filtered using a set
>> of capabilities.Parameters can be generated based on the union of sender
>> and receiver capabilities along with application developer preferences
>> being used as a guideline on how to create the parameters. The engine will
>> do it’s best to fulfill the preferences and it will return the parameters
>> that are possible given the union of the capabilities.Two different engines
>> must be able to compute compatible parameters given all the same
>> preferences and capabilities. Fortunately, any two engines that understand
>> the same capabilities can easily follow the same rules to generate
>> compatible parameters. While the parameters created on the sender and
>> receiver are required to be "compatible", they need not be identical. The
>> application developer should call "createParameters(...)" on sender to
>> create parameters suitable for the sender. The application developer should
>> call "createParameters(...)" on the receiver to create params suitable for
>> a receiver. The calculated “parameters” for both sender and 
>> receiver have
>> to be compatible only to the extent that whatever a sender produces a
>> receiver must be capable of decoding.The application developer has the
>> option to tweak the detailed parameters output by "createParameters(...)"
>> but should only do so with extreme caution. The resultant parameters output
>> by "createParameters(...)" are only meant for local consumption by the
>> local sender / receiver “start” methods.  Sending these created 
>> parameters
>> over the wire is discouraged because implementations may produce objects
>> which may not be entirely understable by the remote party, even though the
>> media sent on the wire will be compatible. Differences from Current Sender
>> / Receiver APIBoth models and APIs are more similar than they are
>> different. The subtle differences make important behavioural usage
>> implications.Both models send and receive based upon "parameter" settings.
>> The difference is in how the "parameters" are generated. The new model
>> generates the "parameters" based on an exchange of capabilities and the
>> application developer is given convenient 'knobs' called "preferences" to
>> perform most common use cases. The "parameters" in the new model are
>> intended for local consumption only and the application developer is not
>> required (and actively discouraged) from marshalling these "parameters"
>> over the wire. The new model proposes marshaling and exchanging
>> "capabilities" and optionally "preferences" and then generating compatible
>> "parameters" based on those exchanges.In both models, the application
>> developer may choose to tweak low level parameters should specific
>> compatibilities be required. But the "preferences" model allows most
>> application developers to completely ignore the low level
>> parameters.Advantages of the New Capabilities ModelOverall the proposed
>> capabilities based API has strong advantages. Main advantages are: 1.
>> Simplicity in setup based on "preferences" for the application developer2.
>> Less brittle designs/implementations since low level parameters are not
>> exchanged, filtered, and interpreted by different browser engines3. Much
>> less knowledge (and often no pre-knowledge) is required for the application
>> developer to take full advantage of a browser's capabilities RTCRtpSender /
>> RTCRtpReceiverinterface RTCRtpSender {  // ...  static RTCRtpParameters
>> createParameters(    MediaStreamTrack track,    Capabilities receiverCaps,
>>    optional (RTCRtpAudioPreferences or              RTCRtpVideoPreferences
>> or              RTCRtpSimulcastPreferences) prefs,    optional Capabilities
>> senderCaps   // optional as system can obtain this information  );  void
>> start(RTCRtpParameters params);  // ...); interface RTCRtpReceiver {  //
>> ...  static RTCRtpParameters createParameters(    DOMString kind,
>>    Capabilities senderCaps,    optional (RTCRtpAudioPreferences or
>>              RTCRtpVideoPreferences or
>>              RTCRtpSimulcastPreferences) prefs,    optional Capabilities
>> receiverCaps // optional as system can obtain this information  );  void
>> start(RTCRtpParameters params);  //...); RTCRtpMediaPreferences// This is
>> the base dictionary used for both audio and video preferences and
>> represents// the set of common preferences that are available for both
>> media types.dictionary RTCRtpMediaPreferences {    // If not specified,
>> system will choose value. If specified, this receiverId will    // be
>> applied to primary SSRC “as is”. If more than one SSRC is needed 
>> to encode
>>    // the stream (e.g. FEC, RTX, MST, simulcast), where the meaning of the
>> RTP packet    // with that alternative SSRC cannot be determined by the
>> media flow itself, the    // alternative SSRCs will construct a receiverId
>> value based upon this receiverId    // value.    DOMString
>>            receiverId;    // This is the primary SSRC to use. Should
>> alternative SSRCs be required (e.g. FEC,    // RTX, MST, simulcast), all
>> other SSRCs should be assigned sequentially starting    // from the chosen
>> SSRC value.    unsigned int         ssrc;    // For a sender, force the
>> chosen codec to be the codec within the RTCRtpCapabilities    // with this
>> name. If possible to choose this codec, the system will confirm by    //
>> choosing this codec in the result from "createParameters(...)".    // This
>> value has no meaning for a receiver since a receiver must be capable    //
>> of receiving any of the compatible codecs within the union
>> RTCRtpCapabilities.    // A non specified value indicates the system will
>> choose the preferred sending    // codec.    DOMString
>>            codecName;   // This value indicates the relative importance of
>> the media being sent with a   // sender versus other media being sent. The
>> logic is that all sent media with   // the same priority will be treated as
>> having an equal priority. Those with   // a greater value will be given a
>> greater priority and those with a lower value   // will be given a lower
>> priority. The value is relative meaning a value of 2.0   // should be given
>> roughly 2 times the priority vs a 1.0 value and a value of 4.0   // should
>> be given roughly 4 times the priority vs a 1.0 value.   double
>>                relativePriority = 1.0;   // This value indicates the
>> maximum bit rate the media is allowed to output as   // a combined whole
>> (including all layers, FEC, RTX, etc). The system will filter   // out
>> codecs that are not capable of delivering below this bit rate unless no
>>   // codec is possible in which case the system will chose the minimal
>> codec bit rate   // possible and will override with a different maximum bit
>> rate in the result of   // "createParameters(...)".   double
>>                maxBitrate;              // engine, keep under this rate
>>   // These values indicates the preferred treatment of FEC/RTX for the RTP
>> packets. For   // audio, some audio codecs have built in FEC/RTX mechanisms
>> in which case if the   // codec is capable, the codec should enable its
>> FEC/RTX mode if value is set to all   // for that codec rather than
>> creating an additional RTP flow.   RTCRtpRecoveryOptions fec = "none";
>>   RTCRtpRecoveryOptions rtx = "none";}; enum RTCRtpRecoveryOptions {
>>   "all",     // apply to all layers   "base",    // only apply for base
>> (audio will treat "base" as equivalent to "all")   "none"     // do not
>> apply to any layer}; RTCRtpAudioPreferencesdictionary
>> RTCRtpAudioPreferences : RTCRtpMediaPreferences {   // If not 0, tells the
>> engine to pick and configure codecs that are capable of   // the minimum of
>> channels (if possible). If not possible, the minimum number of   //
>> channels will be returned in the result of "createParameters(...)".
>>   unsigned int         minChannels = 0;   // If not 0, tells the engine to
>> pick a codec and configure codecs which are   // capable of delivering the
>> minimum Hz rate as indicated. If not possible, the   // minimum Hz rate
>> will be returned in the result of "createParameters(...)"   unsigned int
>>         minHzRate = 0;   // The engine will choose and configure the codecs
>> best able to deliver the level   // of fidelity requested.
>>   RTCRtpAudioFidelity  fidelity = "speech";}; enum RTCRtpAudioFidelity {
>>  "speech",   // speech only is expected so Hz range only need to support
>> the vocal range  "music",    // music is expected, choose stereo compatible
>> and minimal 32000 Hz  "movie"     // music / sound effects expected, choose
>> surround and highest Hz available }; RTCRtpVideoPreferences (and
>> related)dictionary RTCRtpVideoPreferences : RTCRtpMediaPreferences {   //
>> minFrameRate, minScale, and minQuality each indicate that the engine must
>> do   // it's best effort to keep the frame rate, scale or quality above a
>> certain minimal   // level. When using SVC, these values will hint at the
>> requirements typically needed   // for the base layer.   //   //
>> minFrameRate is specified in frames per second.   double     minFrameRate =
>> 0;    // please engine, keep equal or above this rate   // minScale is a
>> relative value from 0.0 to 1.0 where 1.0 represents full input stream   //
>> width/height is requested and 0.0 represents no minimize size is requested.
>>   // The value of minScale is multiplied by the source video window width
>> and height   // to calculate a minimal width and height that is relative to
>> source size.   double     minScale = 0;        // please engine, keep equal
>> or above this scale   // Alternatively, a specific fixed minimal width and
>> height can be requested.   double     minWidth = 0;        // please
>> engine, keep above X pixels wide   double     minHeight = 0;       //
>> please engine, keep above Y pixels high   // minQuality is a relative value
>> from 0.0 to 1.0 where 1.0 means maximum output   // quality is requested
>> for a given codec and 0.0 allows any minimal codec quality   // output is
>> deemed acceptable.   double     minQuality = 0;      // please engine, keep
>> equal or above this quality   // The engine needs values to help decide
>> what to sacrifice when network conditions   // are not ideal. The
>> frameRatePriority, scalePriority, and qualityPriority indicate   // the
>> relative importance of each aspect of the video relative to the other (or
>>   // 0.0 which means the video aspect has no significance (with exclusion
>> to the minimum   // above). The values are relative to each other thus a
>> value of 2.0 vs 1.0 has   // roughly 2 times the importance and a value of
>> 4.0 vs 1.0 has roughly 4 times the   // importance (relatively speaking).
>>   double    frameRatePriority = 1.0; // priority of frame rate   double
>>    scalePriority = 1.0;     // priority of scale   double
>>    qualityPriority = 1.0;   // priority of quality   // If a type of SVC
>> layering is desired, the frameRateScalabilityOptions,   //
>> scalingScalabilityOptions, and qualityScalabilityOptions should be set to a
>>   // non-null value for each SCV type desired. The details of the   //
>> RTCRtpScalabilityOptions dictionary will indicate the desired details for
>>   // each individual SVC type requested.   //   // Default of null
>> indicates no SVC of specific type is requested.   RTCRtpScalabilityOptions?
>> frameRateScalabilityOptions = null;   RTCRtpScalabilityOptions?
>> scalingScalabilityOptions = null;   RTCRtpScalabilityOptions?
>> qualityScalabilityOptions = null;}; dictionary RTCRtpScalabilityOptions {
>>   // If the alternative value other than the default value of null is
>> specified, this   // indicates to the engine the precise number of layers
>> desired (if possible for a   // given codec to deliver these layers). If
>> null, the engine is free to choose   // the default layering statically or
>> dynamically dependent upon the codec   // capabilities.   unsigned int?
>>     layers = null;}; RTCRtpSimulcastPreferencesdictionary
>> RTCRtpSimulcastPreferences {   // This value indicates the maximum bit rate
>> all media is allowed to output as   // a combined for all simulcast
>> streams.   double?               maxBitrate = null;           // engine,
>> keep under this rate   sequence<RTCRtpVideoPreferences> simulcastStreams;};
>> RTCRtpParameters// Typically this object is constructed by the RTCRtpSender
>> for local consumption by// the RTCRtpSender and by the RTCRtpReceiver for
>> local consumption by a RTCRtpReceiver. // This is a "shotgun" object,
>> meaning the developer is given the power of a "shotgun"// pointed at their
>> feet and they can mess with this object at their own peril should// they
>> need to modify it for unusual compatibility reasons. Normal use cases
>> should not// require modifying the values within this structure and
>> marshalling this structure for// remote consumption by another browser
>> engine is highly discouraged.dictionary RTCRtpParameters {   // When
>> returned as a result, the system will express the actual chosen preferences
>>   // possible to best fulfill the preferences given the capabilities. In
>> other words,   // the developer can't always get what they want; but if
>> they try sometimes, they will   // get what they need.
>>   (RTCRtpAudioPreferences or    RTCRtpVideoPreferences or
>>    RTCRtpSimulcastPreferences) preferences;   // the capabilities of both
>> sender and receiver [value "as is" when passed   //
>> "createParameters(...)]"   RTCRtcCapabilities senderCapabilities;
>>   RTCRtcCapabilities receiverCapabilities;   // This value contains all the
>> particularly low level details of how the engine   // will encode the media
>> on the wire.   (RTCRtpParameterAudioDetails or
>>    RTCRtpParameterVideoDetails or    RTCRtpParameterSimulcastDetails)
>>  details;   // The chosen RTP features based upon the union of the
>> capabilities.   Settings rtpFeatures;   // The chosen RTP extensions and
>> configurations based upon the union of   // the capabilities.
>>   sequence<RTCRtpHeaderExtensionParameters>? headerExtensions = null;};
>> RTCRtpParameterDetails// This is the base dictionary of common parameters
>> needed for both audio and video media// types. Audio and video will each
>> have their own set of specific parameters depending// upon the media
>> type.dictionary RTCRtpParameterDetails {   DOMString        receiverId =
>> "";    // use this receiver ID for RTP stream ("" = N/A)   unsigned int
>>     ssrc = null;        // using this SSRC for RTP stream   DOMString
>>        fecReceiverId = ""; // use this receiver ID for FEC RTP ("" = N/A)
>>   unsigned int?    fecSsrc = null;     // using this SSRC for FEC (null =
>> N/A)   Settings         fec;                // modes of operation related
>> to FEC   DOMString        rtxReceiverId = ""; // use this receiver ID for
>> RTX RTP ("" = N/A)   unsigned int?    rtxSsrc = null;     // using this
>> SSRC for FEC (null = N/A)   Settings         rtx;                // modes
>> of operation related to RTX   // null for a sender. For a receiver, this
>> must contain the source SSRC to   // use for RTCP Receiver Reports (RRs).
>>   unsigned int?    rtcpSsrc = null;   // If true, the engine will mux RTCP
>> with RTP on the same RTCIceTransport. If false,   // the engine will send
>> RTCP reports on the associated RTCP RTCIceTransport component.   boolean
>>          rtcpMux = true;}; RTCRtpParameterAudioDetails (and
>> related)dictionary RTCRtpParameterAudioDetails : RTCRtpParameterDetails {
>>   // Contains a list of audio codec options per possible to use codecs. The
>> order   // of the codecs is in preferred order.
>>   sequence<RTCRtpParameterAudioCodecDetails> codecDetails;}; dictionary
>> RTCRtpParameterCodecDetails {   // The name of the codec as related to the
>> codec name(s) contained within the codecs   // listed within the
>> RTCRtpCapabilities dictionaries.   DOMString       codecName;   unsigned
>> byte   payloadType;       // actual payload type sent on wire   Settings
>>        formatsParameters; // detailed settings chosen for related codec};
>> dictionary RTCRtpParameterAudioCodecDetails : RTCRtpParameterCodecDetails {
>>   // nothing anything required at this time?}; RTCRtpParameterVideoDetails
>> (and related)dictionary RTCRtpParameterVideoDetails :
>> RTCRtpParameterDetails {   double           scale = 1.0;        // 0..1
>> relative scale from source   double           frameRate = 1.0;    // 0..1
>> relative frame rate from source   double           quality = 1.0;      //
>> 0..1 relative quality from source   // Contains a list of video codec
>> options per possible to use codecs. The order   // of the codecs is in
>> preferred order.   sequence<RTCRtpParameterVideoCodecDetails>
>> codecDetails;}; dictionary RTCRtpParameterVideoCodecDetails :
>> RTCRtpParameterCodecDetails {   // When layering is used, this value
>> contains a sequence containing the layer   // information as needed for the
>> related codec.   sequence<RTCRtpParameterVideoLayerDetails>? layers =
>> null;}; dictionary RTCRtpParameterVideoLayerDetails {   // Value is set if
>> required for describing the dependency tree information for   // the
>> codec's layers.   DOMString              layerId = "";   // Value is null
>> for the base layer or if dependencies are not needed to be   // described
>> (as may be the case for dynamic SCV codecs). If set, the value   //
>> contains a list of layers this layer is dependent upon (thus allowing a
>>   // dependency tree/graph to be created).   sequence<DOMString>?
>>   layerIdDependencies = null;   RTCRtpScalabilityType? layerScalabilityType
>> = null;  // null would be for base   DOMString              receiverId =
>> "";  // use this receiver ID in layer ("" = N/A)   unsigned int?
>>          ssrc = null;      // if layer uses its own SSRC (null = N/A)
>>   double?                frameRate = null; // framerate for layer (for
>> temporal SVC)   double?                scale = null;     // scale applied
>> to layer (for spatial SVC)   double?                quality = null;   //
>> quality applied to layer (for quality SVC)   DOMString
>>              fecReceiverId = ""; // receiver ID for FEC RTP ("" = N/A)
>>   unsigned int?          fecSsrc = null;     // using this SSRC for FEC
>> (null = N/A)   Settings               fec;                // modes of
>> operation related to FEC   DOMString              rtxReceiverId = ""; //
>> receiver ID for RTX RTP ("" = N/A)   unsigned int?          rtxSsrc = null;
>>     // using this SSRC for FEC (null = N/A)   Settings               rtx;
>>                // modes of operation related to RTX}; enum
>> RTCRtpScalabilityType {   "temporal",   "spatial",   "quality"};
>> RTCRtpParameterSimulcastDetails (and related)dictionary
>> RTCRtpParameterSimulcastDetails {   // This sequence contains the details
>> of each simulcasted stream when simulcasting   // is used or will contain
>> exactly 1 video stream details when not simulcasting.
>>   sequence<RTCRtpParameterVideoDetails>? simulcastStreams;}; RTCRtpCodec
>> Dictionary Tweakdictionary RTCRtpCodec {    DOMString     name = "";    //
>> Added to be able to pick payload type based upon sender or receiver so they
>> match    // when creating both the sender and receiver parameters.
>>    unsigned byte preferredPayloadType;    unsigned int? clockRate = null;
>>    unsigned int? numChannels = 1;    Capabilities  formats;}; *Proposal-ORTC
>> Sender / Receiver Use Case [Usage Comparison Analysis]
>>
>> Introduction
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> *After attempting to work through examples of code usage using the current
>> ORTC sender/receiver API, some issues, concerns and deficiencies were
>> discovered. A retuning of the current model was made to attempt to address
>> those findings. The differences are illustrated below in code examples
>> based on various use cases.In the first set of use cases for simple
>> application usages, there are no advantages to a capabilities model (aside
>> from the reduction of complexity an engine might need to implement). As the
>> use cases become more involved, advantages begin to show. In the final
>> example which illustrates using SVC, the clear advantage of capabilities
>> and preferences can be demonstrated. Use CasesAlice wishes to send media to
>> BobCurrent Parameter Based APIStep 1: (Alice)var track =
>> myObtainMediaTrack();var senderCaps = RTCRtpSender.getCapabilities();var
>> senderParams = RTCRtpSender.createParameters(track,
>> senderCaps);mysignal(senderParams); Step 2: (Bob)var senderParams =
>> mysignal();var receiverCaps = RTPRtcReceiver.getCapabilities();var
>> receiverParams = RTPRtcReceiver.filterParameters(senderParams,
>> receiverCaps);var receiver = new
>> RTCRtpReceiver(...);receiver.start(receiverParams);
>> mysignal(receiverParams); Step 3: (Alice)var receiverParams =
>> mysignal();var senderParams = RTPRtcSender.filterParameters(receiverParams,
>> senderCaps);var sender = new RTCRtpSender(...);sender.start(senderParams);
>> CommentsBecause sender (i.e. Alice) sent her parameters that contained
>> specific SSRC (and possibly receiver ID) information in the her sender
>> parameters, the receiver will latch based upon exact SSRC matching.Proposed
>> Capabilities Based APIStep 1: (Alice)var senderCaps =
>> RTCRtpSender.getCapbilities();mysignal(senderCaps); Step 2: (Bob)var
>> senderCaps = signal();var receiverParams =
>> RTCRtpReceiver.createParameters("video", senderCaps);var receiver = new
>> RTCRtpReceiver(...);receiver.start(receiverParams);
>> mysignal(receiverParams.receiverCapabilities); Step 3: (Alice)var track =
>> myObtainMediaTrack();var receiverCaps = mysignal();var senderParams =
>> RTCRtpSender.createParameters(track, receiverCaps);var sender = new
>> RTCRtpSender(...);sender.start(senderParams); CommentsReceiver (Bob) can
>> match an incoming stream because the payload types will match and therefore
>> the incoming stream will latch to the receiver based on payload type alone.
>> Alice wishes to send media to Bob Using Unhandled EventingCurrent Parameter
>> Based APIStep 1: (Alice)var track = myObtainMediaTrack();var senderCaps =
>> RTCRtpSender.getCapabilities();var senderParams =
>> RTCRtpSender.createParameters(track, senderCaps);mysignal(senderParams);
>> Step 2: (Bob)var senderParams = mysignal();var receiverCaps =
>> RTPRtcReceiver.getCapabilities();var templateReceiverParams =
>> RTPRtcReceiver.filterParameters(senderParams,
>> receiverCaps);templateReceiverParams.encodings[0].receiverId =
>> "";templateReceiverParams.encodings[0].ssrc = null;var listener =
>> RTCRtpListener(...);listener.onunhandledrtp = function(event) {  var
>> receiver = new RTCRtpReceiver(...);
>>  receiver.start(templateReceiverParams);} mysignal(receiverParams); Step 3:
>> (Alice)var receiverParams = mysignal();var senderParams =
>> RTPRtcSender.filterParameters(receiverParams, senderCaps);var sender = new
>> RTCRtpSender(...);sender.start(senderParams); CommentsBecause sender (i.e.
>> Alice) sent her parameters that contained specific SSRC (and possibly
>> receiver ID) information in the her sender parameters, the receiver must
>> override the template receiver params and remove the exact SSRC to attach
>> the incoming stream by payload type.Proposed Capabilities Based APIStep 1:
>> (Alice)var senderCaps = RTCRtpSender.getCapbilities();mysignal(senderCaps);
>> Step 2: (Bob)var senderCaps = signal();var listener =
>> RTCRtpListener(...);listener.onunhandledrtp = function(event) {  var
>> receiverParams = RTCRtpReceiver.createParameters("video", senderCaps);  var
>> receiver = new RTCRtpReceiver(...);  receiver.start(receiverParams);}
>> mysignal(receiverParams.receiverCapabilities); Step 3: (Alice)var track =
>> myObtainMediaTrack();var receiverCaps = mysignal();var senderParams =
>> RTCRtpSender.createParameters(track, receiverCaps);var sender = new
>> RTCRtpSender(...);sender.start(senderParams); CommentsReceiver (Bob) can
>> match an incoming stream because the payload types will match and therefore
>> the incoming stream will latch to the receiver based on payload type
>> alone.Alice / Bob simultaneously exchange information in parallelTo avoid
>> requiring a sequential offer / answer exchange, Alice and Bob wish to
>> simultaneously exchange their RTC information to receiver media from the
>> other party.Current Parameter Based APIStep 1: (Alice / Bob)// [Alice]var
>> aliceTrack = myObtainMediaTrack();var aliceSenderCaps =
>> RTCRtpSender.getCapabilities();var aliceSenderParams =
>> RTCRtpSender.createParameters(aliceTrack, aliceSenderCaps);var
>> aliceReceiverCaps = RTCRtpReceiver.getCapabilities();var
>> aliceReceiverParams = RTCRtpReceiver.createParameters("video",
>> aliceReceiverCaps);mysignal(aliceSenderParams);
>> mysignal(aliceReceiverParams); // [Bob]var bobTrack =
>> myObtainMediaTrack();var bobSenderCaps = RTCRtpSender.getCapabilities();var
>> bobSenderParams = RTCRtpSender.createParameters(bobTrack,
>> bobSenderCaps);var bobReceiverCaps = RTCRtpReceiver.getCapabilities();var
>> bobReceiverParams = RTCRtpReceiver.createParameters("video",
>> bobReceiverCaps);mysignal(bobSenderParams); mysignal(bobReceiverParams);
>> Step 2: (Alice / Bob)// [Alice]var bobSenderParams = mysignal();var
>> bobReceiverParams = mysignal();bobSenderParmas =
>> RTCRtpReceiver.filterParams(bobSenderParams,
>> aliceReceiverCaps);bobSenderParmas.encodings[0].receiverId =
>> "";bobSenderParmas.encodings[0].ssrc = null;bobSenderParams =
>> myFixPayloadTypes(bobSenderParmas, aliceReceiverParams);var aliceReceiver =
>> new RTCRtpReceiver(...);aliceReceiver.receive(bobSenderParams);
>> bobReceiverParams = RTCRtpSender.filterParams(bobReceiverParams,
>> aliceSenderCaps);var aliceSender = new
>> RTCRtpSender(...);aliceSender.send(bobReceiverParams); // [Bob]var
>> aliceSenderParams = mysignal();var aliceReceiverParams =
>> mysignal();aliceSenderParmas =
>> RTCRtpReceiver.filterParams(aliceSenderParams,
>> bobReceiverCaps);aliceSenderParmas.encodings[0].receiverId =
>> "";aliceSenderParmas.encodings[0].ssrc = null;aliceSenderParams =
>> myFixPayloadTypes(aliceSenderParmas, bobReceiverParams);var bobReceiver =
>> new RTCRtpReceiver(...);bobReceiver.receive(aliceSenderParams);
>> aliceReceiverParams = RTCRtpSender.filterParams(aliceReceiverParams,
>> aliceSenderCaps);var bobSender = new
>> RTCRtpSender(...);bobSender.send(aliceReceiverParams);
>> //--------------------------------- // [Alice and Bob need this
>> method]function myFixPayloadTypes(senderParams, originalReceiverParams) {
>>   // TODO: loop through sender params and then secondarily loop through
>>   // original receiver params and set the sender payload type based upon
>>   // what is found in the receiver params.   // ...   return
>> myFixedSenderParams;} CommentsThe sender includes exact SSRC information
>> and signals that to the remote receiver. The issue is the actual sender is
>> going to base it's sending params upon the receiver params of the remote
>> party which do not contain a specific SSRC (or contains a different SSRC).
>> Thus the SSRC has to be stripped from the received sender params or they
>> will not match and the receiver won't latch onto the incoming stream as the
>> latching must occur by payload type instead.The secondary problem is that
>> the sender is actually using the payload types as defined by the remote
>> party's receiver but the receiver is basing the payload types based upon
>> the remote party's sender. This means the payload types might mismatch and
>> the latching based on payload types may not occur. To fix this problem the
>> web developer has to fix either the sender's payload types or the
>> receiver's payload type.Proposed Capabilities Based APIStep 1: (Alice /
>> Bob)// [Alice]var aliceSenderCaps = RTCRtpSender.getCapbilities();var
>> aliceReceiverCaps =
>> RTCRtpReceiver.getCapabilities();mysignal(aliceSenderCaps);
>> mysignal(aliceReceiverCaps); // [Bob]var bobSenderCaps =
>> RTCRtpSender.getCapbilities();var bobReceiverCaps =
>> RTCRtpReceiver.getCapabilities();mysignal(bobSenderCaps);
>> mysignal(bobReceiverCaps); Step 2: (Alice / Bob)// [Alice]var bobSenderCaps
>> = mysignal();var bobReceiverCaps = mysignal();var aliceTrack =
>> myObtainMediaTrack();var aliceReceiverParams =
>> RTCRtpReceiver.createParameters("video", bobSenderCaps);var aliceReceiver =
>> new RTCRtpReceiver(...);aliceReceiver.receiver(aliceReceiverParams); var
>> aliceSenderParams = RTCRtpSender.createParameters(aliceTrack,
>> bobReceiverCaps);var aliceSender = new
>> RTCRtpSender(...);aliceSender.send(aliceSenderParams); // [Bob]var
>> aliceSenderCaps = mysignal();var aliceReceiverCaps = mysignal();var
>> bobTrack = myObtainMediaTrack();var bobReceiverParams =
>> RTCRtpReceiver.createParameters("video", aliceSenderCaps);var bobReceiver =
>> new RTCRtpReceiver(...);bobReceiver.receiver(bobReceiverParams); var
>> bobSenderParams = RTCRtpSender.createParameters(bobTrack,
>> aliceReceiverCaps);var bobSender = new
>> RTCRtpSender(...);bobSender.send(bobSenderParams); CommentsThe receiver is
>> able to latch onto the sender based on payload type alone. Unlike the
>> current API, there's no need to strip SSRCs and no need to fiddle and fix
>> the payload type. The code is cleaner and clearer as to what's going on and
>> does not presume the application level programmer has to know why payload
>> types need to match or why SSRCs need to be stripped.Alice wants to use a
>> SVC (Scalable Video Codec) to send to BobThis is for illustration purposes
>> only. Typical benefits of SVC are greater in conference scenarios rather
>> than traditional point to point scenarios. However, this scenario can
>> presume that an intermedia conferencing bridge would be between Alice and
>> Bob.Current Parameter Based APIStep 1: (Alice)var senderCaps =
>> RTCRtpSender.getCapabilities();mySignal(senderCaps); Step 2: (Bob)var
>> senderCaps = mysignal();var receiverCaps =
>> RTPRtcReceiver.getCapabilities();var receiverParams =
>> RTPRtcReceiver.createParameters("video", receiverCaps);var receiverParams =
>> RTPRtcReceiver.filterParams(senderCaps);var receiverParams =
>> mySetupSVC(receiverParams);var receiver = new
>> RTCRtpReceiver(...);receiver.start(receiverParams);
>> mysignal(receiverParams); function mySetupSVC(receiverParams) {  // 1.
>> search the receiver params for a codec capable of SVC based on
>> pre-knowledge  //    of the codec types  // 2. setup SVC params based on
>> codec's capabilities    // TODO - step 1 - code needs to be added here to
>> do this logic  var chosenCodec = "h264svc"; // hard code for now  // TODO:
>> Not sure this code is even right. How does this layer scale even work?  //
>> How is temporal and spatial layering defined together? Don't see a knob for
>>  // setting up temporal SVC…  receiverParams.receiverId = "foo";
>>  receiverParams.encodings[0] = {    "codecName": chosenCodec,    "scale":
>> 0.125,    "encodingId": "0"  };  receiverParams.encodings[1] = {
>>    "scale": 0.25,    "dependencyEncodingIds": {"0"}  };
>>  receiverParams.encodings[2] = {    "scale": 0.5,
>>    "dependencyEncodingIds": {"0", "1"}  };} Step 3: (Alice)var
>> receiverParams = mysignal();var senderParams =
>> RTPRtcSender.filterParameters(receiverParams, senderCaps);var track =
>> myObtainMediaTrack();var sender = new RTCRtpSender(track,
>> ...);sender.start(senderParams); CommentsThe application developer has to
>> have a ton of presumed knowledge about available codecs, codec capabilities
>> and needs to have a deep understanding of how the engine interprets the
>> layering information. The sender cannot setup the SVC parameters desired
>> because it doesn't know the receiver capabilities.The sample above may not
>> work for SVC codecs which put each layer on a unique SSRC because the
>> receiver did not necessarily pre-dictate the expected SSRCs on each layer
>> so the application developer would have to handle this situation too and
>> assign SSRCs for each layer manually based on knowledge that the codec
>> behaves in this manner.The method to setup temporal or quality SVC is
>> unclear. Appropriate parameter knobs for the application developer appear
>> to be missing.Proposed Capabilities Based APIStep 1: (Alice)var senderCaps
>> = RTCRtpSender.getCapbilities();var senderPrefs = {  "receiverId": "foo",
>>  "frameRateScalabilityOptions": {"layers": 2},
>>  "scalingScalabilityOptions": {"layers": 2},}; mysignal(senderCaps);
>> mysignal(senderPrefs); Step 2: (Bob)var senderCaps = signal();var
>> senderPrefs = signal();var receiverParams =
>> RTCRtpReceiver.createParameters("video", senderCaps, senderPrefs);var
>> receiver = new RTCRtpReceiver(...);receiver.start(receiverParams);
>> mysignal(receiverParams.receiverCapabilities); Step 3: (Alice)var track =
>> myObtainMediaTrack();var receiverCaps = mysignal();var senderParams =
>> RTCRtpSender.createParameters(track, receiverCaps, senderPrefs);var sender
>> = new RTCRtpSender(track, ...);sender.start(senderParams); CommentsThe
>> application developer doesn't require pre-knowledge of the codecs. The
>> developer can quickly and easily specify the types of SVC properties
>> desired with much simpler knobs. The developer doesn't have to worry if a
>> codec is assigning each layer a unique SSRC or not of if the layering ends
>> up being dynamic or not.ConclusionOverall the proposed capabilities based
>> API has strong advantages. Main advantages are: 1. Simplicity in setup
>> based on "preferences" for the application developer2. Less brittle
>> designs/implementations since low level parameters are not exchanged,
>> filtered, and interpreted by different browser engines3. Much less
>> knowledge (and often no pre-knowledge) is required for the application
>> developer to take full advantage of a browser's capabilitiesThere's no
>> strong reason to maintain the current API. The biggest difference will be
>> that browsers will need to generate compatible parameters based on
>> capabilities but that also comes at a big advantage of the browser engines
>> not needing to interpreting and filtering low level parameters from other
>> browser engines. Both new and current use low level parameters to receive
>> or send information so that design aspect remains unchanged.Advantages of
>> Current Parameter Based API 1. Browser engines do not need to generate
>> parameter from capabilities in a "compatible" manner (although low level
>> parameters do need to be filtered in a "compatible" manner so this is not a
>> strong advantage).Disadvantages of Current Parameter Based API 1.
>> Application developer needs pre-knowledge of SVC codecs to be able to chose
>> and setup their properties based upon pre-knowledge of codec capabilities2.
>> Application developer needs deep understanding of how layering works to
>> setup the layering properties correctly3. Browser engines need to agree on
>> how to filter low level parameters based upon capabilities in a consistent
>> manner across browsers to ensure compatibility4. Browser engines need to
>> agree how to interpret low level parameter objects that were generated by
>> other browsers (or other applications)5. Low level parameter based
>> exchanges introduce greater brittleness between browsers since extending
>> the parameters details could mean breaking existing implementations
>> (instead of capabilities which are typically ignored when not understood)6.
>> Less innovation / greater brittleness for anything that requires parameter
>> object extensions since many browsers as well as applications will be
>> fiddling, exchanging, and filtering these low level parameter objects.7.
>> Simulcasting with layering doesn't appear to be supported or it's not
>> obvious how to set up those scenarios.8. Unclear how to mix and match
>> different SVC modes (e.g. temporal, spatial, and quality)9. The application
>> developer is uncertain based upon their preferences what the browser engine
>> is capable of delivering (without deep understanding of all codecs and
>> their properties).10. Header extensions will need manual setup by the
>> application developer despite not knowing that codecs or the engines might
>> need certain extensions to take advantage of codec features or browser
>> engine features.Advantages Proposed Capabilities Based API 1. Application
>> developer can easily setup SVC without needing detailed understanding2.
>> Typical and even advanced use cases do not require a deep understand of RTC
>> to be able to take advantages of capabilities3. Less brittle
>> implementations as low level parameter objects are only consumed local by
>> the browsers that generate them or only in situations where specific
>> compatibilities with legacy systems are required which the default
>> generated low level properties read would not be compatible.4. Simulcast
>> with layering is supported5. Easy for application developer to mix and
>> match different SVC modes (e.g. temporal, spatial, and quality)6. Easy to
>> extend support for alternative SVC scalability modes (e.g. colour depth,
>> sharpness, ROI)7. Application developer knows what the browser engine is
>> capable of delivering given a set of preferences (from resultant
>> preferences as returned from "createParameters(...)" 8. Header extensions
>> can be automatically set up based on needs and capabilities of the
>> browser's RTP engines and codecs.Disadvantages Proposed Capabilities Based
>> API 1. Browser engines need to agree on how to compute "compatible"
>> parameters for a given codec and media preferences. The rules for
>> generation of parameters must be clear.Equal Capabilities of Current and
>> Proposed Based API 1. Application developer can always tweak low level
>> properties on an "as needed" basis for compatibility2. Both new and current
>> proposals send and receive based on lower level parameters (this does not
>> change).*
>>
>>
>>
>>
>>

Received on Friday, 9 May 2014 18:29:56 UTC