示例#1
0
文件: rtp.c 项目: Doap/rtpproxy
rtp_parser_err_t
rtp_packet_parse(struct rtp_packet *pkt)
{
    int padding_size;
    rtp_hdr_ext_t *hdr_ext_ptr;

    padding_size = 0;

    pkt->data_size = 0;
    pkt->data_offset = 0;
    pkt->appendable = 1;
    pkt->nsamples = RTP_NSAMPLES_UNKNOWN;

    if (pkt->size < sizeof(pkt->data.header))
        return RTP_PARSER_PTOOSHRT;

    if (pkt->data.header.version != 2)
        return RTP_PARSER_IHDRVER;

    pkt->data_offset = RTP_HDR_LEN(&pkt->data.header);

    if (pkt->data.header.x != 0) {
        if (pkt->size < pkt->data_offset + sizeof(*hdr_ext_ptr))
            return RTP_PARSER_PTOOSHRTXS;
        hdr_ext_ptr = (rtp_hdr_ext_t *)&pkt->data.buf[pkt->data_offset];
        pkt->data_offset += sizeof(rtp_hdr_ext_t) +
          (ntohs(hdr_ext_ptr->length) * sizeof(hdr_ext_ptr->extension[0]));
    }

    if (pkt->size < pkt->data_offset)
        return RTP_PARSER_PTOOSHRTXH;

    if (pkt->data.header.p != 0) {
        if (pkt->data_offset == pkt->size)
            return RTP_PARSER_PTOOSHRTPS;
        padding_size = pkt->data.buf[pkt->size - 1];
        if (padding_size == 0)
            return RTP_PARSER_IPS;
    }

    if (pkt->size < pkt->data_offset + padding_size)
        return RTP_PARSER_PTOOSHRTP;

    pkt->data_size = pkt->size - pkt->data_offset - padding_size;
    pkt->ts = ntohl(pkt->data.header.ts);
    pkt->seq = ntohs(pkt->data.header.seq);

    if (pkt->data_size == 0)
        return RTP_PARSER_OK;

    pkt->nsamples = rtp_calc_samples(pkt->data.header.pt, pkt->data_size,
      &pkt->data.buf[pkt->data_offset]);
    /* 
     * G.729 comfort noise frame as the last frame causes 
     * packet to be non-appendable
     */
    if (pkt->data.header.pt == RTP_G729 && (pkt->data_size % 10) != 0)
        pkt->appendable = 0;
    return RTP_PARSER_OK;
}
示例#2
0
struct rtp_server *
rtp_server_new(const char *name, rtp_type_t codec, int loop, double dtime,
  int ptime)
{
    struct rtp_server *rp;
    int fd;
    char path[PATH_MAX + 1];

    sprintf(path, "%s.%d", name, codec);
    fd = open(path, O_RDONLY);
    if (fd == -1)
	return NULL;

    rp = rtpp_zmalloc(sizeof(*rp));
    if (rp == NULL) {
	close(fd);
	return NULL;
    }

    rp->btime = dtime;
    rp->dts = 0;
    rp->fd = fd;
    rp->loop = (loop > 0) ? loop - 1 : loop;
    rp->ptime = (ptime > 0) ? ptime : RTPS_TICKS_MIN;

    rp->rtp = (rtp_hdr_t *)rp->buf;
    rp->rtp->version = 2;
    rp->rtp->p = 0;
    rp->rtp->x = 0;
    rp->rtp->cc = 0;
    rp->rtp->mbt = 1;
    rp->rtp->pt = codec;
    rp->rtp->ts = 0;
    rp->rtp->seq = random() & 0xffff;
    rp->rtp->ssrc = random();
    rp->pload = rp->buf + RTP_HDR_LEN(rp->rtp);

    return rp;
}
示例#3
0
struct rtp_server *
rtp_server_new(const char *name, rtp_type_t codec, int loop)
{
    struct rtp_server *rp;
    int fd;
    char path[PATH_MAX + 1];

    sprintf(path, "%s.%d", name, codec);
    fd = open(path, O_RDONLY);
    if (fd == -1)
	return NULL;

    rp = malloc(sizeof(*rp));
    if (rp == NULL) {
	close(fd);
	return NULL;
    }

    memset(rp, 0, sizeof(*rp));

    rp->btime = -1;
    rp->fd = fd;
    rp->loop = (loop > 0) ? loop - 1 : loop;

    rp->rtp = (rtp_hdr_t *)rp->buf;
    rp->rtp->version = 2;
    rp->rtp->p = 0;
    rp->rtp->x = 0;
    rp->rtp->cc = 0;
    rp->rtp->m = 1;
    rp->rtp->pt = codec;
    rp->rtp->ts = 0;
    rp->rtp->seq = 0;
    rp->rtp->ssrc = random();
    rp->pload = rp->buf + RTP_HDR_LEN(rp->rtp);

    return rp;
}
示例#4
0
struct rtp_packet *
rtp_server_get(struct rtp_server *rp, double dtime, int *rval)
{
    struct rtp_packet *pkt;
    uint32_t ts;
    int rlen, rticks, bytes_per_frame, ticks_per_frame, number_of_frames;
    int hlen;

    if (rp->btime == -1)
	rp->btime = dtime;

    ts = ntohl(rp->rtp->ts);

    if (rp->btime + ((double)ts / RTPS_SRATE) > dtime) {
        *rval = RTPS_LATER;
	return (NULL);
    }

    switch (rp->rtp->pt) {
    case RTP_PCMU:
    case RTP_PCMA:
	bytes_per_frame = 8;
	ticks_per_frame = 1;
	break;

    case RTP_G729:
	/* 10 ms per 8 kbps G.729 frame */
	bytes_per_frame = 10;
	ticks_per_frame = 10;
	break;

    case RTP_G723:
	/* 30 ms per 6.3 kbps G.723 frame */
	bytes_per_frame = 24;
	ticks_per_frame = 30;
	break;

    case RTP_GSM:
	/* 20 ms per 13 kbps GSM frame */
	bytes_per_frame = 33;
	ticks_per_frame = 20;
	break;

    case RTP_G722:
	bytes_per_frame = 8;
	ticks_per_frame = 1;
	break;

    default:
	*rval = RTPS_ERROR;
        return (NULL);
    }

    number_of_frames = RTPS_TICKS_MIN / ticks_per_frame;
    if (RTPS_TICKS_MIN % ticks_per_frame != 0)
	number_of_frames++;

    rlen = bytes_per_frame * number_of_frames;
    rticks = ticks_per_frame * number_of_frames;

    pkt = rtp_packet_alloc();
    if (pkt == NULL) {
        *rval = RTPS_ENOMEM;
        return (NULL);
    }
    hlen = RTP_HDR_LEN(rp->rtp);

    if (read(rp->fd, pkt->data.buf + hlen, rlen) != rlen) {
	if (rp->loop == 0 || lseek(rp->fd, 0, SEEK_SET) == -1 ||
	  read(rp->fd, pkt->data.buf + hlen, rlen) != rlen) {
	    *rval = RTPS_EOF;
            rtp_packet_free(pkt);
            return (NULL);
        }
	if (rp->loop != -1)
	    rp->loop -= 1;
    }

    if (rp->rtp->m != 0 && ntohs(rp->rtp->seq) != 0) {
	rp->rtp->m = 0;
    }

    rp->rtp->ts = htonl(ts + (RTPS_SRATE * rticks / 1000));
    rp->rtp->seq = htons(ntohs(rp->rtp->seq) + 1);

    memcpy(&pkt->data.header, rp->rtp, hlen);

    pkt->size = hlen + rlen;
    return (pkt);
}
示例#5
0
文件: rtp.c 项目: sippy/rtpproxy
rtp_parser_err_t
rtp_packet_parse_raw(unsigned char *buf, size_t size, struct rtp_info *rinfo)
{
    int padding_size;
    rtp_hdr_ext_t *hdr_ext_ptr;
    rtp_hdr_t *header;

    header = (rtp_hdr_t *)buf;

    padding_size = 0;

    rinfo->data_size = 0;
    rinfo->data_offset = 0;
    rinfo->appendable = 1;
    rinfo->nsamples = RTP_NSAMPLES_UNKNOWN;

    if (size < sizeof(*header))
        return RTP_PARSER_PTOOSHRT;

    if (header->version != 2)
        return RTP_PARSER_IHDRVER;

    rinfo->data_offset = RTP_HDR_LEN(header);

    if (header->x != 0) {
        if (size < rinfo->data_offset + sizeof(*hdr_ext_ptr))
            return RTP_PARSER_PTOOSHRTXS;
        hdr_ext_ptr = (rtp_hdr_ext_t *)&buf[rinfo->data_offset];
        rinfo->data_offset += sizeof(rtp_hdr_ext_t) +
          (ntohs(hdr_ext_ptr->length) * sizeof(hdr_ext_ptr->extension[0]));
    }

    if (size < rinfo->data_offset)
        return RTP_PARSER_PTOOSHRTXH;

    if (header->p != 0) {
        if (rinfo->data_offset == size)
            return RTP_PARSER_PTOOSHRTPS;
        padding_size = buf[size - 1];
        if (padding_size == 0)
            return RTP_PARSER_IPS;
    }

    if (size < rinfo->data_offset + padding_size)
        return RTP_PARSER_PTOOSHRTP;

    rinfo->data_size = size - rinfo->data_offset - padding_size;
    rinfo->ts = ntohl(header->ts);
    rinfo->seq = ntohs(header->seq);
    rinfo->ssrc = ntohl(header->ssrc);
    rinfo->rtp_profile = &rtp_profiles[header->pt];

    if (rinfo->data_size == 0)
        return RTP_PARSER_OK;

    rinfo->nsamples = rtp_calc_samples(header->pt, rinfo->data_size,
      &buf[rinfo->data_offset]);
    /* 
     * G.729 comfort noise frame as the last frame causes 
     * packet to be non-appendable
     */
    if (header->pt == RTP_G729 && (rinfo->data_size % 10) != 0)
        rinfo->appendable = 0;
    return RTP_PARSER_OK;
}