Example #1
0
static int mpa_parse(rtp_ssrc * stm_src, rtp_frame * fr, rtp_buff * config)
{
    rtp_mpa *mpa_priv;
    rtp_pkt *pkt;
    size_t pkt_len;        // size of RTP packet, rtp header included.
    mpa_frm mpa;
    uint8_t *mpa_data;

    if (!fr)
        return RTP_IN_PRM_ERR;

    mpa_priv = stm_src->privs[fr->pt];

    // XXX should we check if payload/mime-type are compatible with parser?

    if (!(pkt = rtp_get_pkt(stm_src, &pkt_len)))
        return RTP_BUFF_EMPTY;

    // discard pkt if it's fragmented and the first fragment was lost
    while (RTP_MPA_PKT(pkt)->frag_offset) {
        rtp_rm_pkt(stm_src);
        if (!(pkt = rtp_get_pkt(stm_src, &pkt_len)))
            return RTP_BUFF_EMPTY;
        else if (RTP_PKT_PT(pkt) != fr->pt)
            return RTP_PARSE_ERROR;
    }

    mpa_data = RTP_MPA_PKT(pkt)->data;

    nms_printf(NMSML_DBG3, "--- fr->len: %d-%d\n", pkt_len,
           RTP_PAYLOAD_SIZE(pkt, pkt_len));
    pkt_len = RTP_MPA_DATA_LEN(pkt, pkt_len);    // now pkt_len is only the payload len (excluded mpa subheader)
    nms_printf(NMSML_DBG3, "--- fr->len: %d\n", pkt_len);
    if (mpa_sync(&mpa_data, &pkt_len))
        return RTP_PARSE_ERROR;

    if (mpa_decode_header(mpa_data, &mpa))
        return RTP_PARSE_ERROR;

    /* XXX if the frame is not fragmented we could use directly the data contained in bufferpool
     * instead of memcpy the frame in a newly allocated space */
    // init private struct if this is the first time we're called
    if (!mpa_priv) {
        nms_printf(NMSML_DBG3,
               "[rtp_mpa] allocating new private struct...");
        if (!
            (stm_src->privs[fr->pt] = mpa_priv =
             malloc(sizeof(rtp_mpa))))
            return RTP_ERRALLOC;
        mpa_priv->data_size = max(DEFAULT_MPA_DATA_FRAME, mpa.frm_len);
        if (!(mpa_priv->data = malloc(mpa_priv->data_size)))
            return RTP_ERRALLOC;
        nms_printf(NMSML_DBG3, "done\n");
    } else if ((RTP_MPA_FRAG_OFFSET(pkt) + pkt_len) > mpa_priv->data_size) {
        nms_printf(NMSML_DBG3, "[rtp_mpa] reallocating data...");
        mpa_priv->data_size += max(DEFAULT_MPA_DATA_FRAME, pkt_len);
        if (!(mpa_priv->data = realloc(mpa_priv->data,  mpa_priv->data_size)))
            return RTP_ERRALLOC;
        nms_printf(NMSML_DBG3, "done\n");
    }
    fr->data = mpa_priv->data;

    for (fr->len = 0;
         pkt && (fr->len < mpa.frm_len) &&
         (fr->timestamp == RTP_PKT_TS(pkt));
         fr->len += pkt_len,
         rtp_rm_pkt(stm_src), (pkt =
                   rtp_get_pkt(stm_src, &pkt_len)), pkt_len =
         RTP_MPA_DATA_LEN(pkt, pkt_len)) {
        // pkt consistency checks
        if (RTP_MPA_FRAG_OFFSET(pkt) + pkt_len <= mpa_priv->data_size) {
            nms_printf(NMSML_DBG3,
                   "copying %d byte of data to offset: %d\n",
                   pkt_len, RTP_MPA_FRAG_OFFSET(pkt));
            memcpy(fr->data + RTP_MPA_FRAG_OFFSET(pkt), mpa_data,
                   pkt_len);
        }
    }
    nms_printf(NMSML_DBG3, "fr->len: %d\n", fr->len);

    return RTP_FILL_OK;
}
static int h263_parse(rtp_ssrc * ssrc, rtp_frame * fr, rtp_buff * config)
{
        rtp_pkt *pkt;
        uint8_t *buf;
        rtp_h263 *priv = ssrc->rtp_sess->ptdefs[fr->pt]->priv;
        size_t len; /* payload size, minus additional headers,
                 * plus the 2 zeroed bytes
                 */
        size_t start = 2; /* how many bytes we are going to skip from the start */
        int err = RTP_FILL_OK;
        int p_bit;

        if (!(pkt = rtp_get_pkt(ssrc, &len)))
                return RTP_BUFF_EMPTY;

        buf = RTP_PKT_DATA(pkt);
        len = RTP_PAYLOAD_SIZE(pkt, len);

        if (priv->len && (RTP_PKT_TS(pkt) != priv->timestamp)) {
                //incomplete packet without final fragment
                priv->len = 0;
                return RTP_PKT_UNKNOWN;
        }

        p_bit = buf[0] & 0x4;

        if (p_bit) { // p bit - we overwrite the first 2 bytes with zero
                start = 0;
        }

        if (!priv->len && !p_bit) {
                //incomplete packet without initial fragment
                rtp_rm_pkt(ssrc);
                return RTP_PKT_UNKNOWN;
        }

        if (buf[0]&0x2) // v bit - skip one more
                ++start;

        start += (buf[1]>>3)|((buf[0]&0x1)<<5); // plen - skip that many bytes

        len -= start;

        if (nms_alloc_data(&priv->data, &priv->data_size, len + priv->len)) {
                return RTP_ERRALLOC;
        }
        nms_append_data(priv->data, priv->len, buf + start, len);

        if (p_bit) // p bit - we overwrite the first 2 bytes with zero
                memset(priv->data + priv->len, 0, 2);

        priv->len += len;

        if (!RTP_PKT_MARK(pkt)) {
                priv->timestamp = RTP_PKT_TS(pkt);
                err = EAGAIN;
        } else {
                fr->data = priv->data;
                fr->len  = priv->len;
                priv->len = 0;
        }

        memset(config, 0, sizeof(rtp_buff));

        rtp_rm_pkt(ssrc);
        return err;
}