Home | History | Annotate | Download | only in media
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 
      6 
      7 /**
      8  * Get the ssrc if |report| is an ssrc report.
      9  *
     10  * @param {!Object} report The object contains id, type, and stats, where stats
     11  *     is the object containing timestamp and values, which is an array of
     12  *     strings, whose even index entry is the name of the stat, and the odd
     13  *     index entry is the value.
     14  * @return {?string} The ssrc.
     15  */
     16 function GetSsrcFromReport(report) {
     17   if (report.type != 'ssrc') {
     18     console.warn("Trying to get ssrc from non-ssrc report.");
     19     return null;
     20   }
     21 
     22   // If the 'ssrc' name-value pair exists, return the value; otherwise, return
     23   // the report id.
     24   // The 'ssrc' name-value pair only exists in an upcoming Libjingle change. Old
     25   // versions use id to refer to the ssrc.
     26   //
     27   // TODO(jiayl): remove the fallback to id once the Libjingle change is rolled
     28   // to Chrome.
     29   if (report.stats && report.stats.values) {
     30     for (var i = 0; i < report.stats.values.length - 1; i += 2) {
     31       if (report.stats.values[i] == 'ssrc') {
     32         return report.stats.values[i + 1];
     33       }
     34     }
     35   }
     36   return report.id;
     37 };
     38 
     39 /**
     40  * SsrcInfoManager stores the ssrc stream info extracted from SDP.
     41  */
     42 var SsrcInfoManager = (function() {
     43   'use strict';
     44 
     45   /**
     46    * @constructor
     47    */
     48   function SsrcInfoManager() {
     49     /**
     50      * Map from ssrc id to an object containing all the stream properties.
     51      * @type {!Object.<string, !Object.<string>>}
     52      * @private
     53      */
     54     this.streamInfoContainer_ = {};
     55 
     56     /**
     57      * The string separating attibutes in an SDP.
     58      * @type {string}
     59      * @const
     60      * @private
     61      */
     62     this.ATTRIBUTE_SEPARATOR_ = /[\r,\n]/;
     63 
     64     /**
     65      * The regex separating fields within an ssrc description.
     66      * @type {RegExp}
     67      * @const
     68      * @private
     69      */
     70     this.FIELD_SEPARATOR_REGEX_ = / .*:/;
     71 
     72     /**
     73      * The prefix string of an ssrc description.
     74      * @type {string}
     75      * @const
     76      * @private
     77      */
     78     this.SSRC_ATTRIBUTE_PREFIX_ = 'a=ssrc:';
     79 
     80     /**
     81      * The className of the ssrc info parent element.
     82      * @type {string}
     83      * @const
     84      */
     85     this.SSRC_INFO_BLOCK_CLASS = 'ssrc-info-block';
     86   }
     87 
     88   SsrcInfoManager.prototype = {
     89     /**
     90      * Extracts the stream information from |sdp| and saves it.
     91      * For example:
     92      *     a=ssrc:1234 msid:abcd
     93      *     a=ssrc:1234 label:hello
     94      *
     95      * @param {string} sdp The SDP string.
     96      */
     97     addSsrcStreamInfo: function(sdp) {
     98       var attributes = sdp.split(this.ATTRIBUTE_SEPARATOR_);
     99       for (var i = 0; i < attributes.length; ++i) {
    100         // Check if this is a ssrc attribute.
    101         if (attributes[i].indexOf(this.SSRC_ATTRIBUTE_PREFIX_) != 0)
    102           continue;
    103 
    104         var nextFieldIndex = attributes[i].search(this.FIELD_SEPARATOR_REGEX_);
    105 
    106         if (nextFieldIndex == -1)
    107           continue;
    108 
    109         var ssrc = attributes[i].substring(this.SSRC_ATTRIBUTE_PREFIX_.length,
    110                                            nextFieldIndex);
    111         if (!this.streamInfoContainer_[ssrc])
    112           this.streamInfoContainer_[ssrc] = {};
    113 
    114         // Make |rest| starting at the next field.
    115         var rest = attributes[i].substring(nextFieldIndex + 1);
    116         var name, value;
    117         while (rest.length > 0) {
    118           nextFieldIndex = rest.search(this.FIELD_SEPARATOR_REGEX_);
    119           if (nextFieldIndex == -1)
    120             nextFieldIndex = rest.length;
    121 
    122           // The field name is the string before the colon.
    123           name = rest.substring(0, rest.indexOf(':'));
    124           // The field value is from after the colon to the next field.
    125           value = rest.substring(rest.indexOf(':') + 1, nextFieldIndex);
    126           this.streamInfoContainer_[ssrc][name] = value;
    127 
    128           // Move |rest| to the start of the next field.
    129           rest = rest.substring(nextFieldIndex + 1);
    130         }
    131       }
    132     },
    133 
    134     /**
    135      * @param {string} sdp The ssrc id.
    136      * @return {!Object.<string>} The object containing the ssrc infomation.
    137      */
    138     getStreamInfo: function(ssrc) {
    139       return this.streamInfoContainer_[ssrc];
    140     },
    141 
    142     /**
    143      * Populate the ssrc information into |parentElement|, each field as a
    144      * DIV element.
    145      *
    146      * @param {!Element} parentElement The parent element for the ssrc info.
    147      * @param {string} ssrc The ssrc id.
    148      */
    149     populateSsrcInfo: function(parentElement, ssrc) {
    150       if (!this.streamInfoContainer_[ssrc])
    151         return;
    152 
    153       parentElement.className = this.SSRC_INFO_BLOCK_CLASS;
    154 
    155       var fieldElement;
    156       for (var property in this.streamInfoContainer_[ssrc]) {
    157         fieldElement = document.createElement('div');
    158         parentElement.appendChild(fieldElement);
    159         fieldElement.textContent =
    160             property + ':' + this.streamInfoContainer_[ssrc][property];
    161       }
    162     }
    163   };
    164 
    165   return SsrcInfoManager;
    166 })();
    167