Пример #1
0
bool
SipccSdpAttributeList::LoadMsidSemantics(sdp_t* sdp, uint16_t level,
                                         SdpErrorHolder& errorHolder)
{
  auto msidSemantics = MakeUnique<SdpMsidSemanticAttributeList>();

  for (uint16_t i = 1; i < UINT16_MAX; ++i) {
    sdp_attr_t* attr = sdp_find_attr(sdp, level, 0, SDP_ATTR_MSID_SEMANTIC, i);

    if (!attr) {
      break;
    }

    sdp_msid_semantic_t* msid_semantic = &(attr->attr.msid_semantic);
    std::vector<std::string> msids;
    for (size_t i = 0; i < SDP_MAX_MEDIA_STREAMS; ++i) {
      if (!msid_semantic->msids[i]) {
        break;
      }

      msids.push_back(msid_semantic->msids[i]);
    }

    msidSemantics->PushEntry(msid_semantic->semantic, msids);
  }

  if (!msidSemantics->mMsidSemantics.empty()) {
    SetAttribute(msidSemantics.release());
  }
  return true;
}
Пример #2
0
void
SipccSdpAttributeList::LoadMsids(sdp_t* sdp, uint16_t level,
                                 SdpErrorHolder& errorHolder)
{
  uint16_t attrCount = 0;
  if (sdp_attr_num_instances(sdp, level, 0, SDP_ATTR_MSID, &attrCount) !=
      SDP_SUCCESS) {
    MOZ_ASSERT(false, "Unable to get count of msid attributes");
    errorHolder.AddParseError(0, "Unable to get count of msid attributes");
    return;
  }
  auto msids = MakeUnique<SdpMsidAttributeList>();
  for (uint16_t i = 1; i <= attrCount; ++i) {
    uint32_t lineNumber = sdp_attr_line_number(sdp, SDP_ATTR_MSID, level, 0, i);

    const char* identifier = sdp_attr_get_msid_identifier(sdp, level, 0, i);
    if (!identifier) {
      errorHolder.AddParseError(lineNumber, "msid attribute with bad identity");
      continue;
    }

    const char* appdata = sdp_attr_get_msid_appdata(sdp, level, 0, i);
    if (!appdata) {
      errorHolder.AddParseError(lineNumber, "msid attribute with bad appdata");
      continue;
    }

    msids->PushEntry(identifier, appdata);
  }

  if (!msids->mMsids.empty()) {
    SetAttribute(msids.release());
  }
}
Пример #3
0
bool
SipccSdpAttributeList::LoadSctpmap(sdp_t* sdp, uint16_t level,
                                   SdpErrorHolder& errorHolder)
{
  auto sctpmap = MakeUnique<SdpSctpmapAttributeList>();
  for (uint16_t i = 0; i < UINT16_MAX; ++i) {
    sdp_attr_t* attr = sdp_find_attr(sdp, level, 0, SDP_ATTR_SCTPMAP, i + 1);

    if (!attr) {
      break;
    }

    // Yeah, this is a little weird, but for now we'll just store this as a
    // payload type.
    uint16_t payloadType = attr->attr.sctpmap.port;
    uint16_t streams = attr->attr.sctpmap.streams;
    const char* name = attr->attr.sctpmap.protocol;

    std::ostringstream osPayloadType;
    osPayloadType << payloadType;
    sctpmap->PushEntry(osPayloadType.str(), name, streams);
  }

  if (!sctpmap->mSctpmaps.empty()) {
    SetAttribute(sctpmap.release());
  }

  return true;
}
Пример #4
0
bool
SipccSdpAttributeList::LoadRtpmap(sdp_t* sdp, uint16_t level,
                                  SdpErrorHolder& errorHolder)
{
  auto rtpmap = MakeUnique<SdpRtpmapAttributeList>();
  uint16_t count;
  sdp_result_e result =
      sdp_attr_num_instances(sdp, level, 0, SDP_ATTR_RTPMAP, &count);
  if (result != SDP_SUCCESS) {
    MOZ_ASSERT(false, "Unable to get rtpmap size");
    errorHolder.AddParseError(sdp_get_media_line_number(sdp, level),
                              "Unable to get rtpmap size");
    return false;
  }
  for (uint16_t i = 0; i < count; ++i) {
    uint16_t pt = sdp_attr_get_rtpmap_payload_type(sdp, level, 0, i + 1);
    const char* ccName = sdp_attr_get_rtpmap_encname(sdp, level, 0, i + 1);

    if (!ccName) {
      // Probably no rtpmap attribute for a pt in an m-line
      errorHolder.AddParseError(sdp_get_media_line_number(sdp, level),
                                "No rtpmap attribute for payload type");
      continue;
    }

    std::string name(ccName);

    SdpRtpmapAttributeList::CodecType codec =
        GetCodecType(sdp_get_known_payload_type(sdp, level, pt));

    uint32_t clock = sdp_attr_get_rtpmap_clockrate(sdp, level, 0, i + 1);
    uint16_t channels = 0;

    // sipcc gives us a channels value of "1" for video
    if (sdp_get_media_type(sdp, level) == SDP_MEDIA_AUDIO) {
      channels = sdp_attr_get_rtpmap_num_chan(sdp, level, 0, i + 1);
    }

    std::ostringstream osPayloadType;
    osPayloadType << pt;
    rtpmap->PushEntry(osPayloadType.str(), codec, name, clock, channels);
  }

  if (!rtpmap->mRtpmaps.empty()) {
    SetAttribute(rtpmap.release());
  }

  return true;
}
Пример #5
0
void
SipccSdpAttributeList::LoadSsrc(sdp_t* sdp, uint16_t level)
{
  auto ssrcs = MakeUnique<SdpSsrcAttributeList>();

  for (uint16_t i = 1; i < UINT16_MAX; ++i) {
    sdp_attr_t* attr = sdp_find_attr(sdp, level, 0, SDP_ATTR_SSRC, i);

    if (!attr) {
      break;
    }

    sdp_ssrc_t* ssrc = &(attr->attr.ssrc);
    ssrcs->PushEntry(ssrc->ssrc, ssrc->attribute);
  }

  if (!ssrcs->mSsrcs.empty()) {
    SetAttribute(ssrcs.release());
  }
}
Пример #6
0
void
SipccSdpAttributeList::LoadExtmap(sdp_t* sdp, uint16_t level,
                                  SdpErrorHolder& errorHolder)
{
  auto extmaps = MakeUnique<SdpExtmapAttributeList>();

  for (uint16_t i = 1; i < UINT16_MAX; ++i) {
    sdp_attr_t* attr = sdp_find_attr(sdp, level, 0, SDP_ATTR_EXTMAP, i);

    if (!attr) {
      break;
    }

    sdp_extmap_t* extmap = &(attr->attr.extmap);

    SdpDirectionAttribute::Direction dir = SdpDirectionAttribute::kSendrecv;

    if (extmap->media_direction_specified) {
      ConvertDirection(extmap->media_direction, &dir);
    }

    extmaps->PushEntry(extmap->id, dir, extmap->media_direction_specified,
                       extmap->uri, extmap->extension_attributes);
  }

  if (!extmaps->mExtmaps.empty()) {
    if (!AtSessionLevel() &&
        mSessionLevel->HasAttribute(SdpAttribute::kExtmapAttribute)) {
      uint32_t lineNumber =
          sdp_attr_line_number(sdp, SDP_ATTR_EXTMAP, level, 0, 1);
      errorHolder.AddParseError(
          lineNumber, "extmap attributes in both session and media level");
    }
    SetAttribute(extmaps.release());
  }
}
Пример #7
0
void
SipccSdpAttributeList::LoadRtcpFb(sdp_t* sdp, uint16_t level,
                                  SdpErrorHolder& errorHolder)
{
  auto rtcpfbs = MakeUnique<SdpRtcpFbAttributeList>();

  for (uint16_t i = 1; i < UINT16_MAX; ++i) {
    sdp_attr_t* attr = sdp_find_attr(sdp, level, 0, SDP_ATTR_RTCP_FB, i);

    if (!attr) {
      break;
    }

    sdp_fmtp_fb_t* rtcpfb = &attr->attr.rtcp_fb;

    SdpRtcpFbAttributeList::Type type;
    std::string parameter;

    // Set type and parameter
    switch (rtcpfb->feedback_type) {
      case SDP_RTCP_FB_ACK:
        type = SdpRtcpFbAttributeList::kAck;
        switch (rtcpfb->param.ack) {
          // TODO: sipcc doesn't seem to support ack with no following token.
          // Issue 189.
          case SDP_RTCP_FB_ACK_RPSI:
            parameter = SdpRtcpFbAttributeList::rpsi;
            break;
          case SDP_RTCP_FB_ACK_APP:
            parameter = SdpRtcpFbAttributeList::app;
            break;
          default:
            // Type we don't care about, ignore.
            continue;
        }
        break;
      case SDP_RTCP_FB_CCM:
        type = SdpRtcpFbAttributeList::kCcm;
        switch (rtcpfb->param.ccm) {
          case SDP_RTCP_FB_CCM_FIR:
            parameter = SdpRtcpFbAttributeList::fir;
            break;
          case SDP_RTCP_FB_CCM_TMMBR:
            parameter = SdpRtcpFbAttributeList::tmmbr;
            break;
          case SDP_RTCP_FB_CCM_TSTR:
            parameter = SdpRtcpFbAttributeList::tstr;
            break;
          case SDP_RTCP_FB_CCM_VBCM:
            parameter = SdpRtcpFbAttributeList::vbcm;
            break;
          default:
            // Type we don't care about, ignore.
            continue;
        }
        break;
      case SDP_RTCP_FB_NACK:
        type = SdpRtcpFbAttributeList::kNack;
        switch (rtcpfb->param.nack) {
          case SDP_RTCP_FB_NACK_BASIC:
            break;
          case SDP_RTCP_FB_NACK_SLI:
            parameter = SdpRtcpFbAttributeList::sli;
            break;
          case SDP_RTCP_FB_NACK_PLI:
            parameter = SdpRtcpFbAttributeList::pli;
            break;
          case SDP_RTCP_FB_NACK_RPSI:
            parameter = SdpRtcpFbAttributeList::rpsi;
            break;
          case SDP_RTCP_FB_NACK_APP:
            parameter = SdpRtcpFbAttributeList::app;
            break;
          default:
            // Type we don't care about, ignore.
            continue;
        }
        break;
      case SDP_RTCP_FB_TRR_INT: {
        type = SdpRtcpFbAttributeList::kTrrInt;
        std::ostringstream os;
        os << rtcpfb->param.trr_int;
        parameter = os.str();
      } break;
      case SDP_RTCP_FB_REMB: {
        type = SdpRtcpFbAttributeList::kRemb;
      } break;
      default:
        // Type we don't care about, ignore.
        continue;
    }

    std::stringstream osPayloadType;
    if (rtcpfb->payload_num == UINT16_MAX) {
      osPayloadType << "*";
    } else {
      osPayloadType << rtcpfb->payload_num;
    }

    std::string pt(osPayloadType.str());
    std::string extra(rtcpfb->extra);

    rtcpfbs->PushEntry(pt, type, parameter, extra);
  }

  if (!rtcpfbs->mFeedbacks.empty()) {
    SetAttribute(rtcpfbs.release());
  }
}
Пример #8
0
void
SipccSdpAttributeList::LoadFmtp(sdp_t* sdp, uint16_t level)
{
  auto fmtps = MakeUnique<SdpFmtpAttributeList>();

  for (uint16_t i = 1; i < UINT16_MAX; ++i) {
    sdp_attr_t* attr = sdp_find_attr(sdp, level, 0, SDP_ATTR_FMTP, i);

    if (!attr) {
      break;
    }

    sdp_fmtp_t* fmtp = &(attr->attr.fmtp);

    // Get the payload type
    std::stringstream osPayloadType;
    // payload_num is the number in the fmtp attribute, verbatim
    osPayloadType << fmtp->payload_num;

    // Get parsed form of parameters, if supported
    UniquePtr<SdpFmtpAttributeList::Parameters> parameters;

    rtp_ptype codec = sdp_get_known_payload_type(sdp, level, fmtp->payload_num);

    switch (codec) {
      case RTP_H264_P0:
      case RTP_H264_P1: {
        SdpFmtpAttributeList::H264Parameters* h264Parameters(
            new SdpFmtpAttributeList::H264Parameters);

        sstrncpy(h264Parameters->sprop_parameter_sets, fmtp->parameter_sets,
                 sizeof(h264Parameters->sprop_parameter_sets));

        h264Parameters->level_asymmetry_allowed =
            !!(fmtp->level_asymmetry_allowed);

        h264Parameters->packetization_mode = fmtp->packetization_mode;
        sscanf(fmtp->profile_level_id, "%x", &h264Parameters->profile_level_id);
        h264Parameters->max_mbps = fmtp->max_mbps;
        h264Parameters->max_fs = fmtp->max_fs;
        h264Parameters->max_cpb = fmtp->max_cpb;
        h264Parameters->max_dpb = fmtp->max_dpb;
        h264Parameters->max_br = fmtp->max_br;

        parameters.reset(h264Parameters);
      } break;
      case RTP_VP9: {
        SdpFmtpAttributeList::VP8Parameters* vp9Parameters(
            new SdpFmtpAttributeList::VP8Parameters(
              SdpRtpmapAttributeList::kVP9));

        vp9Parameters->max_fs = fmtp->max_fs;
        vp9Parameters->max_fr = fmtp->max_fr;

        parameters.reset(vp9Parameters);
      } break;
      case RTP_VP8: {
        SdpFmtpAttributeList::VP8Parameters* vp8Parameters(
            new SdpFmtpAttributeList::VP8Parameters(
              SdpRtpmapAttributeList::kVP8));

        vp8Parameters->max_fs = fmtp->max_fs;
        vp8Parameters->max_fr = fmtp->max_fr;

        parameters.reset(vp8Parameters);
      } break;
      case RTP_RED: {
        SdpFmtpAttributeList::RedParameters* redParameters(
            new SdpFmtpAttributeList::RedParameters);
        for (int i = 0;
             i < SDP_FMTP_MAX_REDUNDANT_ENCODINGS && fmtp->redundant_encodings[i];
             ++i) {
          redParameters->encodings.push_back(fmtp->redundant_encodings[i]);
        }

        parameters.reset(redParameters);
      } break;
      case RTP_OPUS: {
        SdpFmtpAttributeList::OpusParameters* opusParameters(
            new SdpFmtpAttributeList::OpusParameters);
        opusParameters->maxplaybackrate = fmtp->maxplaybackrate;
        opusParameters->stereo = fmtp->stereo;
        opusParameters->useInBandFec = fmtp->useinbandfec;
        parameters.reset(opusParameters);
      } break;
      default: {
      }
    }

    fmtps->PushEntry(osPayloadType.str(), Move(parameters));
  }

  if (!fmtps->mFmtps.empty()) {
    SetAttribute(fmtps.release());
  }
}
Пример #9
0
void
SipccSdpAttributeList::LoadFmtp(sdp_t* sdp, uint16_t level)
{
  auto fmtps = MakeUnique<SdpFmtpAttributeList>();

  for (uint16_t i = 1; i < UINT16_MAX; ++i) {
    sdp_attr_t* attr = sdp_find_attr(sdp, level, 0, SDP_ATTR_FMTP, i);

    if (!attr) {
      break;
    }

    sdp_fmtp_t* fmtp = &(attr->attr.fmtp);

    // Get the payload type
    std::stringstream osPayloadType;
    // payload_num is the number in the fmtp attribute, verbatim
    osPayloadType << fmtp->payload_num;

    // Get the serialized form of the parameters
    flex_string fs;
    flex_string_init(&fs);

    // Very lame, but we need direct access so we can get the serialized form
    sdp_result_e sdpres = sdp_build_attr_fmtp_params(sdp, fmtp, &fs);

    if (sdpres != SDP_SUCCESS) {
      flex_string_free(&fs);
      continue;
    }

    std::string paramsString(fs.buffer);
    flex_string_free(&fs);

    // Get parsed form of parameters, if supported
    UniquePtr<SdpFmtpAttributeList::Parameters> parameters;

    rtp_ptype codec = sdp_get_known_payload_type(sdp, level, fmtp->payload_num);

    switch (codec) {
      case RTP_H264_P0:
      case RTP_H264_P1: {
        SdpFmtpAttributeList::H264Parameters* h264Parameters(
            new SdpFmtpAttributeList::H264Parameters);

        sstrncpy(h264Parameters->sprop_parameter_sets, fmtp->parameter_sets,
                 sizeof(h264Parameters->sprop_parameter_sets));

        h264Parameters->level_asymmetry_allowed =
            !!(fmtp->level_asymmetry_allowed);

        h264Parameters->packetization_mode = fmtp->packetization_mode;
// Copied from VcmSIPCCBinding
#ifdef _WIN32
        sscanf_s(fmtp->profile_level_id, "%x",
                 &h264Parameters->profile_level_id, sizeof(unsigned*));
#else
        sscanf(fmtp->profile_level_id, "%xu",
               &h264Parameters->profile_level_id);
#endif
        h264Parameters->max_mbps = fmtp->max_mbps;
        h264Parameters->max_fs = fmtp->max_fs;
        h264Parameters->max_cpb = fmtp->max_cpb;
        h264Parameters->max_dpb = fmtp->max_dpb;
        h264Parameters->max_br = fmtp->max_br;

        parameters.reset(h264Parameters);
      } break;
      case RTP_VP9: {
        SdpFmtpAttributeList::VP8Parameters* vp9Parameters(
            new SdpFmtpAttributeList::VP8Parameters(
              SdpRtpmapAttributeList::kVP9));

        vp9Parameters->max_fs = fmtp->max_fs;
        vp9Parameters->max_fr = fmtp->max_fr;

        parameters.reset(vp9Parameters);
      } break;
      case RTP_VP8: {
        SdpFmtpAttributeList::VP8Parameters* vp8Parameters(
            new SdpFmtpAttributeList::VP8Parameters(
              SdpRtpmapAttributeList::kVP8));

        vp8Parameters->max_fs = fmtp->max_fs;
        vp8Parameters->max_fr = fmtp->max_fr;

        parameters.reset(vp8Parameters);
      } break;
      default: {
      }
    }

    fmtps->PushEntry(osPayloadType.str(), paramsString, Move(parameters));
  }

  if (!fmtps->mFmtps.empty()) {
    SetAttribute(fmtps.release());
  }
}