static int vorbis_parse(rtp_ssrc * ssrc, rtp_frame * fr, rtp_buff * config) { rtp_pkt *pkt; size_t len; rtp_vorbis *vorb = ssrc->rtp_sess->ptdefs[fr->pt]->priv; config->data = vorb->conf[0].conf; config->len = vorb->conf[0].len; // get the current packet if (!(pkt = rtp_get_pkt(ssrc, &len))) return RTP_BUFF_EMPTY; /*fprintf(stderr, "ID: %d, Type: %d, Off: %d\n", RTP_XIPH_ID(pkt), RTP_XIPH_T(pkt), vorb->offset);*/ // if I don't have previous work if (!vorb->pkts) { // get the number of packets stuffed in the rtp vorb->pkts = RTP_XIPH_PKTS(pkt); /*fprintf(stderr, "Pkt: %d\n", vorb->pkts);*/ // some error checking if (vorb->pkts > 0 && ( (RTP_XIPH_F(pkt)) || (RTP_XIPH_T(pkt) !=0) )) { /*fprintf(stderr, "ERRORE\n");*/ return RTP_PARSE_ERROR; } if (RTP_XIPH_F(pkt)) return frag_parse(vorb, pkt, fr, config, ssrc); vorb->offset = 4; // single packet, easy case if (vorb->pkts == 1) { /*fprintf(stderr, "SINGL\n");*/ return single_parse(vorb, pkt, fr, config, ssrc); } } // keep parsing the current rtp packet /*fprintf(stderr, "PACK\n");*/ return pack_parse(vorb, pkt, fr, config, ssrc); }
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; }