/**
   * Notifies this <tt>Conference</tt> that the ordered list of <tt>Endpoint</tt>s of {@link
   * #speechActivity} i.e. the dominant speaker history has changed.
   *
   * <p>This instance notifies the video <tt>Channel</tt>s about the change so that they may update
   * their last-n lists and report to this instance which <tt>Endpoint</tt>s are to be asked for
   * video keyframes.
   */
  private void speechActivityEndpointsChanged() {
    List<Endpoint> endpoints = null;

    for (Content content : getContents()) {
      if (MediaType.VIDEO.equals(content.getMediaType())) {
        Set<Endpoint> endpointsToAskForKeyframes = null;

        endpoints = speechActivity.getEndpoints();
        for (Channel channel : content.getChannels()) {
          if (!(channel instanceof RtpChannel)) continue;

          RtpChannel rtpChannel = (RtpChannel) channel;
          List<Endpoint> channelEndpointsToAskForKeyframes =
              rtpChannel.speechActivityEndpointsChanged(endpoints);

          if ((channelEndpointsToAskForKeyframes != null)
              && !channelEndpointsToAskForKeyframes.isEmpty()) {
            if (endpointsToAskForKeyframes == null) {
              endpointsToAskForKeyframes = new HashSet<>();
            }
            endpointsToAskForKeyframes.addAll(channelEndpointsToAskForKeyframes);
          }
        }

        if ((endpointsToAskForKeyframes != null) && !endpointsToAskForKeyframes.isEmpty()) {
          content.askForKeyframes(endpointsToAskForKeyframes);
        }
      }
    }
  }
예제 #2
0
  /**
   * Return a set of all items with type CNAME from the RTCP SDES packet <tt>pkt</tt>.
   *
   * @param pkt the packet to parse for CNAME items.
   * @retur a set of all items with type CNAME from the RTCP SDES packet <tt>pkt</tt>.
   */
  private Set<CNAMEItem> getCnameItems(RawPacket pkt) {
    Set<CNAMEItem> ret = new HashSet<CNAMEItem>();

    byte[] buf = pkt.getBuffer();
    int off = pkt.getOffset();
    int len = pkt.getLength();

    // first item
    int ptr = 4;

    while (ptr + 6 < len) // an item is at least 6B: 4B ssrc, 1B type, 1B len
    {
      int type = buf[off + ptr + 4];
      int len2 = buf[off + ptr + 5];
      if (ptr + 6 + len2 >= len) // not enough buffer for the whole item
      break;

      if (type == 1) // CNAME
      {
        CNAMEItem item = new CNAMEItem();
        item.ssrc = readUnsignedIntAsLong(buf, off + ptr);
        item.cname = readString(buf, off + ptr + 6, len2);
        ret.add(item);
      }

      ptr += 6 + len2;
    }

    return ret;
  }
예제 #3
0
 private void handleRtpPacket(RawPacket pkt) {
   if (pkt != null && pkt.getPayloadType() == vp8PayloadType) {
     int ssrc = pkt.getSSRC();
     if (!activeVideoSsrcs.contains(ssrc & 0xffffffffL)) {
       synchronized (activeVideoSsrcs) {
         if (!activeVideoSsrcs.contains(ssrc & 0xffffffffL)) {
           activeVideoSsrcs.add(ssrc & 0xffffffffL);
           rtcpFeedbackSender.sendFIR(ssrc);
         }
       }
     }
   }
 }
예제 #4
0
 private void nudge() {
   for (Iterator<RecorderEvent> iter = pendingEvents.iterator(); iter.hasNext(); ) {
     RecorderEvent ev = iter.next();
     long instant = getSynchronizer().getLocalTime(ev.getSsrc(), ev.getRtpTimestamp());
     if (instant != -1) {
       iter.remove();
       ev.setInstant(instant);
       handler.handleEvent(ev);
     }
   }
 }
예제 #5
0
 @Override
 public boolean handleEvent(RecorderEvent ev) {
   if (ev == null) return true;
   if (RecorderEvent.Type.RECORDING_STARTED.equals(ev.getType())) {
     long instant = getSynchronizer().getLocalTime(ev.getSsrc(), ev.getRtpTimestamp());
     if (instant != -1) {
       ev.setInstant(instant);
       return handler.handleEvent(ev);
     } else {
       pendingEvents.add(ev);
       return true;
     }
   }
   return handler.handleEvent(ev);
 }