private priorityPolicy()

in src/videodownlinkbandwidthpolicy/VideoPriorityBasedPolicy.ts [1010:1108]


  private priorityPolicy(
    rates: PolicyRates,
    remoteInfos: VideoStreamDescription[],
    chosenStreams: VideoStreamDescription[]
  ): VideoStreamDescription {
    let upgradeStream: VideoStreamDescription;
    const videoPreferences: VideoPreferences = this.getCurrentVideoPreferences();

    const highestPriority = videoPreferences.highestPriority();
    let nextPriority;
    let priority = highestPriority;
    while (priority !== -1) {
      nextPriority = -1;
      for (const preference of videoPreferences) {
        if (preference.priority === priority) {
          // First subscribe to at least low rate
          for (const info of remoteInfos) {
            if (info.attendeeId === preference.attendeeId) {
              if (!chosenStreams.some(stream => stream.groupId === info.groupId)) {
                if (rates.chosenTotalBitrate + info.avgBitrateKbps <= rates.targetDownlinkBitrate) {
                  chosenStreams.push(info);
                  rates.chosenTotalBitrate += info.avgBitrateKbps;
                } else if (rates.deltaToNextUpgrade === 0) {
                  // Keep track of step to next upgrade
                  rates.deltaToNextUpgrade = info.avgBitrateKbps;
                  upgradeStream = info;
                }
              }
            }
          }
        } else {
          if (preference.priority > priority) {
            nextPriority = preference.priority;
            break;
          }
        }
      }

      // Now try to upgrade all attendee's with this priority
      for (const preference of videoPreferences) {
        if (preference.priority === priority) {
          for (const info of remoteInfos) {
            if (info.attendeeId === preference.attendeeId) {
              const index = chosenStreams.findIndex(
                stream =>
                  stream.groupId === info.groupId &&
                  stream.maxBitrateKbps <= info.maxBitrateKbps &&
                  stream.avgBitrateKbps < info.avgBitrateKbps
              );
              if (index !== -1) {
                const increaseKbps = info.avgBitrateKbps - chosenStreams[index].avgBitrateKbps;
                if (
                  this.hasSimulcastStreams(remoteInfos, info.attendeeId, info.groupId) &&
                  this.canUpgrade(
                    info.avgBitrateKbps,
                    preference.targetSize,
                    preference.targetSizeToBitrateKbps(preference.targetSize),
                    info.attendeeId.endsWith(ContentShareConstants.Modality)
                  )
                ) {
                  this.logger.info(
                    `bwe: attendee: ${info.attendeeId} group: ${
                      info.groupId
                    } has simulcast and can upgrade avgBitrate: ${
                      info.avgBitrateKbps
                    } target: ${preference.targetSizeToBitrateKbps(
                      preference.targetSize
                    )} targetTotalBitrate: ${rates.targetDownlinkBitrate}`
                  );
                  if (rates.chosenTotalBitrate + increaseKbps <= rates.targetDownlinkBitrate) {
                    rates.chosenTotalBitrate += increaseKbps;
                    chosenStreams[index] = info;
                  } else if (rates.deltaToNextUpgrade === 0) {
                    // Keep track of step to next upgrade
                    rates.deltaToNextUpgrade = increaseKbps;
                    upgradeStream = info;
                  }
                } else {
                  this.logger.info('bwe: cannot upgrade stream quality beyond target size');
                }
              }
            }
          }
        } else {
          if (preference.priority > priority) {
            break;
          }
        }
      }

      // If we haven't subscribed to the highest rate of the top priority videos then
      // do not subscribe to any other sources
      if (priority === highestPriority && rates.deltaToNextUpgrade !== 0) {
        break;
      }
      priority = nextPriority;
    }
    return upgradeStream;
  }