summaryrefslogtreecommitdiff
path: root/modules/avcodec/h263.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/avcodec/h263.c')
-rw-r--r--modules/avcodec/h263.c176
1 files changed, 176 insertions, 0 deletions
diff --git a/modules/avcodec/h263.c b/modules/avcodec/h263.c
new file mode 100644
index 0000000..7e29ecd
--- /dev/null
+++ b/modules/avcodec/h263.c
@@ -0,0 +1,176 @@
+/**
+ * @file h263.c H.263 video codec (RFC 4629)
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+#include <re.h>
+#include <rem.h>
+#include <baresip.h>
+#include <libavcodec/avcodec.h>
+#ifdef USE_X264
+#include <x264.h>
+#endif
+#include "h26x.h"
+#include "avcodec.h"
+
+
+int h263_hdr_encode(const struct h263_hdr *hdr, struct mbuf *mb)
+{
+ uint32_t v; /* host byte order */
+
+ v = hdr->f<<31 | hdr->p<<30 | hdr->sbit<<27 | hdr->ebit<<24;
+ v |= hdr->src<<21 | hdr->i<<20 | hdr->u<<19 | hdr->s<<18 | hdr->a<<17;
+ v |= hdr->r<<13 | hdr->dbq<<11 | hdr->trb<<8 | hdr->tr<<0;
+
+ return mbuf_write_u32(mb, htonl(v));
+}
+
+
+enum h263_mode h263_hdr_mode(const struct h263_hdr *hdr)
+{
+ if (!hdr->f) {
+ return H263_MODE_A;
+ }
+ else {
+ if (!hdr->p)
+ return H263_MODE_B;
+ else
+ return H263_MODE_C;
+ }
+}
+
+
+int h263_hdr_decode(struct h263_hdr *hdr, struct mbuf *mb)
+{
+ uint32_t v;
+
+ if (!hdr)
+ return EINVAL;
+ if (mbuf_get_left(mb) < H263_HDR_SIZE_MODEA)
+ return EBADMSG;
+
+ v = ntohl(mbuf_read_u32(mb));
+
+ /* Common */
+ hdr->f = v>>31 & 0x1;
+ hdr->p = v>>30 & 0x1;
+ hdr->sbit = v>>27 & 0x7;
+ hdr->ebit = v>>24 & 0x7;
+ hdr->src = v>>21 & 0x7;
+
+ switch (h263_hdr_mode(hdr)) {
+
+ case H263_MODE_A:
+ hdr->i = v>>20 & 0x1;
+ hdr->u = v>>19 & 0x1;
+ hdr->s = v>>18 & 0x1;
+ hdr->a = v>>17 & 0x1;
+ hdr->r = v>>13 & 0xf;
+ hdr->dbq = v>>11 & 0x3;
+ hdr->trb = v>>8 & 0x7;
+ hdr->tr = v>>0 & 0xff;
+ break;
+
+ case H263_MODE_B:
+ hdr->quant = v>>16 & 0x1f;
+ hdr->gobn = v>>11 & 0x1f;
+ hdr->mba = v>>2 & 0x1ff;
+
+ if (mbuf_get_left(mb) < 4)
+ return EBADMSG;
+
+ v = ntohl(mbuf_read_u32(mb));
+
+ hdr->i = v>>31 & 0x1;
+ hdr->u = v>>30 & 0x1;
+ hdr->s = v>>29 & 0x1;
+ hdr->a = v>>28 & 0x1;
+ hdr->hmv1 = v>>21 & 0x7f;
+ hdr->vmv1 = v>>14 & 0x7f;
+ hdr->hmv2 = v>>7 & 0x7f;
+ hdr->vmv2 = v>>0 & 0x7f;
+ break;
+
+ case H263_MODE_C:
+ /* NOTE: Mode C is optional, only parts decoded */
+ if (mbuf_get_left(mb) < 8)
+ return EBADMSG;
+
+ v = ntohl(mbuf_read_u32(mb));
+ hdr->i = v>>31 & 0x1;
+ hdr->u = v>>30 & 0x1;
+ hdr->s = v>>29 & 0x1;
+ hdr->a = v>>28 & 0x1;
+
+ (void)mbuf_read_u32(mb); /* ignore */
+ break;
+ }
+
+ return 0;
+}
+
+
+/** Find PSC (Picture Start Code) in bit-stream */
+const uint8_t *h263_strm_find_psc(const uint8_t *p, uint32_t size)
+{
+ const uint8_t *end = p + size - 1;
+
+ for (; p < end; p++) {
+ if (p[0] == 0x00 && p[1] == 0x00)
+ return p;
+ }
+
+ return NULL;
+}
+
+
+int h263_strm_decode(struct h263_strm *s, struct mbuf *mb)
+{
+ const uint8_t *p;
+
+ if (mbuf_get_left(mb) < 6)
+ return EINVAL;
+
+ p = mbuf_buf(mb);
+
+ s->psc[0] = p[0];
+ s->psc[1] = p[1];
+
+ s->temp_ref = (p[2]<<6 & 0xc0) | (p[3]>>2 & 0x3f);
+
+ s->split_scr = p[4]>>7 & 0x1;
+ s->doc_camera = p[4]>>6 & 0x1;
+ s->pic_frz_rel = p[4]>>5 & 0x1;
+ s->src_fmt = p[4]>>2 & 0x7;
+ s->pic_type = p[4]>>1 & 0x1;
+ s->umv = p[4]>>0 & 0x1;
+
+ s->sac = p[5]>>7 & 0x1;
+ s->apm = p[5]>>6 & 0x1;
+ s->pb = p[5]>>5 & 0x1;
+ s->pquant = p[5]>>0 & 0x1f;
+
+ s->cpm = p[6]>>7 & 0x1;
+ s->pei = p[6]>>6 & 0x1;
+
+ return 0;
+}
+
+
+/** Copy H.263 bit-stream to H.263 RTP payload header */
+void h263_hdr_copy_strm(struct h263_hdr *hdr, const struct h263_strm *s)
+{
+ hdr->f = 0; /* Mode A */
+ hdr->p = 0;
+ hdr->sbit = 0;
+ hdr->ebit = 0;
+ hdr->src = s->src_fmt;
+ hdr->i = s->pic_type;
+ hdr->u = s->umv;
+ hdr->s = s->sac;
+ hdr->a = s->apm;
+ hdr->r = 0;
+ hdr->dbq = 0; /* No PB-frames */
+ hdr->trb = 0; /* No PB-frames */
+ hdr->tr = s->temp_ref;
+}