Esempio n. 1
0
static int decode_frame(struct aucodec_st *st, struct mbuf *dst,
			struct mbuf *src, uint16_t src_len)
{
	int ret, err;

	if (mbuf_get_left(src) < src_len) {
		DEBUG_WARNING("dec: corrupt frame %u < %u\n",
			      mbuf_get_left(src), src_len);
		return EPROTO;
	}

	/* Make sure there is enough space in the buffer */
	if (mbuf_get_space(dst) < st->fsize) {
		err = mbuf_resize(dst, dst->size + st->fsize);
		if (err)
			return err;
	}

	ret = celt_decode(st->dec, mbuf_buf(src), src_len,
			  (short *)mbuf_buf(dst), st->frame_size);
	if (CELT_OK != ret) {
		DEBUG_WARNING("celt_decode: ret=%d\n", ret);
	}

	DEBUG_INFO("decode: %u -> %u\n", src_len, st->fsize);

	if (src)
		mbuf_advance(src, src_len);

	dst->end += st->fsize;

	return 0;
}
Esempio n. 2
0
static int general_packetize(struct vidcodec_st *st, struct mbuf *mb)
{
	int err = 0;

	/* Assemble frame into smaller packets */
	while (!err) {
		size_t sz, left = mbuf_get_left(mb);
		bool last = (left < MAX_RTP_SIZE);
		if (!left)
			break;

		sz = last ? left : MAX_RTP_SIZE;

		st->mb_frag->pos = st->mb_frag->end = RTP_PRESZ;
		err = mbuf_write_mem(st->mb_frag, mbuf_buf(mb), sz);
		if (err)
			break;

		st->mb_frag->pos = RTP_PRESZ;
		err = st->sendh(last, st->mb_frag, st->arg);

		mbuf_advance(mb, sz);
	}

	return err;
}
Esempio n. 3
0
File: rtp.c Progetto: hbowden/re
/**
 * Send an RTP packet to a peer
 *
 * @param rs     RTP Socket
 * @param dst    Destination address
 * @param ext    Extension bit
 * @param marker Marker bit
 * @param pt     Payload type
 * @param ts     Timestamp
 * @param mb     Payload buffer
 *
 * @return 0 for success, otherwise errorcode
 */
int rtp_send(struct rtp_sock *rs, const struct sa *dst, bool ext,
	     bool marker, uint8_t pt, uint32_t ts, struct mbuf *mb)
{
	size_t pos;
	int err;

	if (!rs || !mb)
		return EINVAL;

	if (mb->pos < RTP_HEADER_SIZE) {
		DEBUG_WARNING("rtp_send: buffer must have space for"
			      " rtp header (pos=%u, end=%u)\n",
			      mb->pos, mb->end);
		return EBADMSG;
	}

	mbuf_advance(mb, -RTP_HEADER_SIZE);

	pos = mb->pos;

	err = rtp_encode(rs, ext, marker, pt, ts, mb);
	if (err)
		return err;

	if (rs->rtcp)
		rtcp_sess_tx_rtp(rs->rtcp, ts, mbuf_get_left(mb));

	mb->pos = pos;

	return udp_send(rs->sock_rtp, dst, mb);
}
Esempio n. 4
0
int rtp_un(srtp_t srtp, struct mbuf *mb)
{
    int err, len;
    if(srtp) {
        mbuf_advance(mb, -RTP_HEADER_SIZE);
        len = (int)mbuf_get_left(mb);
        err = srtp_unprotect(srtp, mbuf_buf(mb), &len);
        if(err) {
            printf("srtp unprotect fail %d\n", err);
            return -1;
        }
        mbuf_advance(mb, RTP_HEADER_SIZE);
        len -= RTP_HEADER_SIZE;
    } else {
        len = (int)mbuf_get_left(mb);
    }
    return len;
}
Esempio n. 5
0
/**
 * Decode an RTCP Payload-Specific Feedback Message
 *
 * @param mb  Buffer to decode
 * @param msg RTCP Message to decode into
 *
 * @return 0 for success, otherwise errorcode
 */
int rtcp_psfb_decode(struct mbuf *mb, struct rtcp_msg *msg)
{
	size_t i, sz;

	if (!msg)
		return EINVAL;

	switch (msg->hdr.count) {

	case RTCP_PSFB_PLI:
		/* no params */
		break;

	case RTCP_PSFB_SLI:
		sz = msg->r.fb.n * sizeof(*msg->r.fb.fci.sliv);
		msg->r.fb.fci.sliv = mem_alloc(sz, NULL);
		if (!msg->r.fb.fci.sliv)
			return ENOMEM;

		if (mbuf_get_left(mb) < msg->r.fb.n * SLI_SIZE)
			return EBADMSG;
		for (i=0; i<msg->r.fb.n; i++) {
			const uint32_t v = ntohl(mbuf_read_u32(mb));

			msg->r.fb.fci.sliv[i].first  = v>>19 & 0x1fff;
			msg->r.fb.fci.sliv[i].number = v>> 6 & 0x1fff;
			msg->r.fb.fci.sliv[i].picid  = v>> 0 & 0x003f;
		}
		break;

	case RTCP_PSFB_AFB:
		sz = msg->r.fb.n * 4;

		if (mbuf_get_left(mb) < sz)
			return EBADMSG;

		msg->r.fb.fci.afb = mbuf_alloc_ref(mb);
		if (!msg->r.fb.fci.afb)
			return ENOMEM;

		msg->r.fb.fci.afb->end = msg->r.fb.fci.afb->pos + sz;
		mbuf_advance(mb, sz);
		break;

	default:
		DEBUG_NOTICE("unknown PSFB fmt %d\n", msg->hdr.count);
		break;
	}

	return 0;
}
Esempio n. 6
0
static int h263_packetize(struct videnc_state *st, struct mbuf *mb,
			  videnc_packet_h *pkth, void *arg)
{
	struct h263_strm h263_strm;
	struct h263_hdr h263_hdr;
	size_t pos;
	int err;

	/* Decode bit-stream header, used by packetizer */
	err = h263_strm_decode(&h263_strm, mb);
	if (err)
		return err;

	h263_hdr_copy_strm(&h263_hdr, &h263_strm);

	st->mb_frag->pos = st->mb_frag->end = 0;
	err = h263_hdr_encode(&h263_hdr, st->mb_frag);
	pos = st->mb_frag->pos;

	/* Assemble frame into smaller packets */
	while (!err) {
		size_t sz, left = mbuf_get_left(mb);
		bool last = (left < st->encprm.pktsize);
		if (!left)
			break;

		sz = last ? left : st->encprm.pktsize;

		st->mb_frag->pos = st->mb_frag->end = pos;
		err = mbuf_write_mem(st->mb_frag, mbuf_buf(mb), sz);
		if (err)
			break;

		st->mb_frag->pos = 0;

		err = pkth(last, NULL, 0, mbuf_buf(st->mb_frag),
			   mbuf_get_left(st->mb_frag), arg);

		mbuf_advance(mb, sz);
	}

	return err;
}
Esempio n. 7
0
static int encode_frame(struct aucodec_st *st, uint16_t *size, uint8_t *buf,
			struct mbuf *src)
{
	int len;

	/* NOTE: PCM audio in signed 16-bit format (native endian) */
	len = celt_encode(st->enc, (short *)mbuf_buf(src), st->frame_size,
			  buf, st->bytes_per_packet);
	if (len < 0) {
		DEBUG_WARNING("celt_encode: returned %d\n", len);
		return EINVAL;
	}

	DEBUG_INFO("encode: %u -> %d\n", mbuf_get_left(src), len);

	*size = len;

	mbuf_advance(src, st->fsize);

	return 0;
}
Esempio n. 8
0
static int general_packetize(struct mbuf *mb, size_t pktsize,
			     videnc_packet_h *pkth, void *arg)
{
	int err = 0;

	/* Assemble frame into smaller packets */
	while (!err) {
		size_t sz, left = mbuf_get_left(mb);
		bool last = (left < pktsize);
		if (!left)
			break;

		sz = last ? left : pktsize;

		err = pkth(last, NULL, 0, mbuf_buf(mb), sz, arg);

		mbuf_advance(mb, sz);
	}

	return err;
}
Esempio n. 9
0
int h265_decode(struct viddec_state *vds, struct vidframe *frame,
		bool marker, uint16_t seq, struct mbuf *mb)
{
	static const uint8_t nal_seq[3] = {0, 0, 1};
	int err, ret, got_picture, i;
	struct h265_nal hdr;
	AVPacket avpkt;
	enum vidfmt fmt;

	if (!vds || !frame || !mb)
		return EINVAL;

	err = h265_nal_decode(&hdr, mbuf_buf(mb));
	if (err)
		return err;

	mbuf_advance(mb, H265_HDR_SIZE);

#if 1
	debug("h265: decode: %s type=%2d  %s\n",
		  h265_is_keyframe(hdr.nal_unit_type) ? "<KEY>" : "     ",
		  hdr.nal_unit_type,
		  h265_nalunit_name(hdr.nal_unit_type));
#endif


	if (vds->frag && hdr.nal_unit_type != H265_NAL_FU) {
		debug("h265: lost fragments; discarding previous NAL\n");
		fragment_rewind(vds);
		vds->frag = false;
	}

	/* handle NAL types */
	if (0 <= hdr.nal_unit_type && hdr.nal_unit_type <= 40) {

		mb->pos -= H265_HDR_SIZE;

		err  = mbuf_write_mem(vds->mb, nal_seq, 3);
		err |= mbuf_write_mem(vds->mb, mbuf_buf(mb),mbuf_get_left(mb));
		if (err)
			goto out;
	}
	else if (H265_NAL_FU == hdr.nal_unit_type) {

		struct fu fu;

		err = fu_decode(&fu, mb);
		if (err)
			return err;

		if (fu.s) {
			if (vds->frag) {
				debug("h265: lost fragments; ignoring NAL\n");
				fragment_rewind(vds);
			}

			vds->frag_start = vds->mb->pos;
			vds->frag = true;

			hdr.nal_unit_type = fu.type;

			err  = mbuf_write_mem(vds->mb, nal_seq, 3);
			err = h265_nal_encode_mbuf(vds->mb, &hdr);
			if (err)
				goto out;
		}
		else {
			if (!vds->frag) {
				debug("h265: ignoring fragment\n");
				return 0;
			}

			if (seq_diff(vds->frag_seq, seq) != 1) {
				debug("h265: lost fragments detected\n");
				fragment_rewind(vds);
				vds->frag = false;
				return 0;
			}
		}

		err = mbuf_write_mem(vds->mb, mbuf_buf(mb), mbuf_get_left(mb));
		if (err)
			goto out;

		if (fu.e)
			vds->frag = false;

		vds->frag_seq = seq;
	}
	else {
		warning("h265: unknown NAL type %u\n", hdr.nal_unit_type);
		return ENOSYS;
	}

	if (!marker) {

		if (vds->mb->end > DECODE_MAXSZ) {
			warning("h265: decode buffer size exceeded\n");
			err = ENOMEM;
			goto out;
		}

		return 0;
	}

	if (vds->frag) {
		err = EPROTO;
		goto out;
	}

	av_init_packet(&avpkt);
	avpkt.data = vds->mb->buf;
	avpkt.size = (int)vds->mb->end;

	ret = avcodec_decode_video2(vds->ctx, vds->pict, &got_picture, &avpkt);
	if (ret < 0) {
		debug("h265: decode error\n");
		err = EPROTO;
		goto out;
	}

	if (!got_picture) {
		/* debug("h265: no picture\n"); */
		goto out;
	}

	switch (vds->pict->format) {

	case PIX_FMT_YUV420P:
		fmt = VID_FMT_YUV420P;
		break;

#if 0
	case PIX_FMT_YUV444P:
		fmt = VID_FMT_YUV444;
		break;
#endif

	default:
		warning("h265: decode: bad pixel format (%i) (%s)\n",
			vds->pict->format,
			av_get_pix_fmt_name(vds->pict->format));
		goto out;
	}

	for (i=0; i<4; i++) {
		frame->data[i]     = vds->pict->data[i];
		frame->linesize[i] = vds->pict->linesize[i];
	}

	frame->size.w = vds->ctx->width;
	frame->size.h = vds->ctx->height;
	frame->fmt    = fmt;

 out:
	mbuf_rewind(vds->mb);
	vds->frag = false;

	return err;
}
Esempio n. 10
0
File: pkt.c Progetto: kaija/libre
/**
 * Decode one RTCP message from a buffer
 *
 * @param msgp Pointer to allocated RTCP Message
 * @param mb   Buffer to decode from
 *
 * @return 0 for success, otherwise errorcode
 */
int rtcp_decode(struct rtcp_msg **msgp, struct mbuf *mb)
{
	struct rtcp_msg *msg = NULL;
	size_t start, i, sz, count, rem;
	int err;

	if (!msgp)
		return EINVAL;
	if (mbuf_get_left(mb) < RTCP_HDR_SIZE)
		return EBADMSG;

	msg = mem_zalloc(sizeof(*msg), rtcp_destructor);
	if (!msg)
		return ENOMEM;

	start = mb->pos;

	/* decode and check header */
	err = rtcp_hdr_decode(mb, &msg->hdr);
	if (err)
		goto out;

	if (msg->hdr.version != RTCP_VERSION)
		goto badmsg;

	/* check length and remaining */
	rem = msg->hdr.length * sizeof(uint32_t);
	if (mbuf_get_left(mb) < rem)
		goto badmsg;

	count = msg->hdr.count;

	switch (msg->hdr.pt) {

	case RTCP_SR:
		if (mbuf_get_left(mb) < (RTCP_SRC_SIZE + RTCP_SR_SIZE))
			goto badmsg;
		msg->r.sr.ssrc     = ntohl(mbuf_read_u32(mb));
		msg->r.sr.ntp_sec  = ntohl(mbuf_read_u32(mb));
		msg->r.sr.ntp_frac = ntohl(mbuf_read_u32(mb));
		msg->r.sr.rtp_ts   = ntohl(mbuf_read_u32(mb));
		msg->r.sr.psent    = ntohl(mbuf_read_u32(mb));
		msg->r.sr.osent    = ntohl(mbuf_read_u32(mb));

		err = rtcp_rr_alloc(&msg->r.sr.rrv, count);
		if (err)
			goto out;
		for (i=0; i<count && !err; i++)
			err = rtcp_rr_decode(mb, &msg->r.sr.rrv[i]);
		break;

	case RTCP_RR:
		if (mbuf_get_left(mb) < RTCP_SRC_SIZE)
			goto badmsg;
		msg->r.rr.ssrc = ntohl(mbuf_read_u32(mb));

		err = rtcp_rr_alloc(&msg->r.rr.rrv, count);
		if (err)
			goto out;
		for (i=0; i<count && !err; i++)
			err = rtcp_rr_decode(mb, &msg->r.rr.rrv[i]);
		break;

	case RTCP_SDES:
		if (count == 0)
			break;

		sz = count * sizeof(*msg->r.sdesv);
		msg->r.sdesv = mem_zalloc(sz, NULL);
		if (!msg->r.sdesv) {
			err = ENOMEM;
			goto out;
		}

		for (i=0; i<msg->hdr.count && !err; i++)
			err = rtcp_sdes_decode(mb, &msg->r.sdesv[i]);
		break;

	case RTCP_BYE:
		sz = count * sizeof(*msg->r.bye.srcv);
		msg->r.bye.srcv = mem_alloc(sz, NULL);
		if (!msg->r.bye.srcv) {
			err = ENOMEM;
			goto out;
		}
		if (mbuf_get_left(mb) < sz)
			goto badmsg;
		for (i=0; i<count; i++)
			msg->r.bye.srcv[i] = ntohl(mbuf_read_u32(mb));

		/* decode reason (optional) */
		if (rem > count*sizeof(uint32_t)) {
			const size_t len = mbuf_read_u8(mb);
			if (mbuf_get_left(mb) < len)
				goto badmsg;

			err = mbuf_strdup(mb, &msg->r.bye.reason, len);
		}
		break;

	case RTCP_APP:
		if (mbuf_get_left(mb) < RTCP_APP_SIZE)
			goto badmsg;
		msg->r.app.src = ntohl(mbuf_read_u32(mb));
		(void)mbuf_read_mem(mb, (uint8_t *)msg->r.app.name,
				    sizeof(msg->r.app.name));
		if (rem > RTCP_APP_SIZE) {
			msg->r.app.data_len = rem - RTCP_APP_SIZE;
			msg->r.app.data = mem_alloc(msg->r.app.data_len, NULL);
			if (!msg->r.app.data) {
				err = ENOMEM;
				goto out;
			}
			if (mbuf_get_left(mb) < msg->r.app.data_len)
				goto badmsg;
			(void)mbuf_read_mem(mb, msg->r.app.data,
					    msg->r.app.data_len);
		}
		break;

	case RTCP_FIR:
		if (mbuf_get_left(mb) < RTCP_FIR_SIZE)
			goto badmsg;
		msg->r.fir.ssrc = ntohl(mbuf_read_u32(mb));
		break;

	case RTCP_NACK:
		if (mbuf_get_left(mb) < RTCP_NACK_SIZE)
			goto badmsg;
		msg->r.nack.ssrc = ntohl(mbuf_read_u32(mb));
		msg->r.nack.fsn  = ntohs(mbuf_read_u16(mb));
		msg->r.nack.blp  = ntohs(mbuf_read_u16(mb));
		break;

	case RTCP_RTPFB:
		if (mbuf_get_left(mb) < RTCP_FB_SIZE)
			goto badmsg;
		msg->r.fb.ssrc_packet = ntohl(mbuf_read_u32(mb));
		msg->r.fb.ssrc_media = ntohl(mbuf_read_u32(mb));
		msg->r.fb.n = msg->hdr.length - 2;

		err = rtcp_rtpfb_decode(mb, msg);
		break;

	case RTCP_PSFB:
		if (mbuf_get_left(mb) < RTCP_FB_SIZE)
			goto badmsg;
		msg->r.fb.ssrc_packet = ntohl(mbuf_read_u32(mb));
		msg->r.fb.ssrc_media = ntohl(mbuf_read_u32(mb));
		msg->r.fb.n = msg->hdr.length - 2;

		err = rtcp_psfb_decode(mb, msg);
		break;

	default:
		/* unknown message type */
		mbuf_advance(mb, rem);
		break;
	}
	if (err)
		goto out;

	/* slurp padding */
	while ((mb->pos - start) & 0x3 && mbuf_get_left(mb))
		++mb->pos;

 out:
	if (err)
		mem_deref(msg);
	else
		*msgp = msg;

	return err;

 badmsg:
	mem_deref(msg);
	return EBADMSG;
}