shithub: rtmp

ref: a73d1bc55bf8d60f5cdd23c0f99080024a4c5f72
dir: rtmp/adts.c

View raw version
#include <u.h>
#include <libc.h>
#include <bio.h>
#include "adts.h"
#include "util.h"

static int ratecfg[] = {
	96000,
	88200,
	64000,
	48000,
	44100,
	32000,
	24000,
	22050,
	16000,
	12000,
	11025,
	8000,
	7350,
	-1,
	-1,
	-1,
};

int
adtsread(Biobuf *b, ADTSFrame *f)
{
	int ratei, i;
	u8int h[7];

Again:
	if(Bread(b, h, 7) != 7)
		goto err;
	if(h[0] != 0xff || (h[1]&0xf0) != 0xf0){
		werrstr("bad sync word");
		goto err;
	}

	f->sz = (h[3]&3)<<11 | h[4]<<3 | h[5]>>5;
	if(f->sz < 7){
		werrstr("frame too small (%d bytes)", f->sz);
		goto err;
	}
	if(f->sz > f->bufsz){
		f->bufsz = f->sz*2;
		f->buf = erealloc(f->buf, f->bufsz);
	}

	memmove(f->buf, h, 7);
	if(Bread(b, f->buf+7, f->sz-7) != f->sz-7)
		goto err;

	ratei = (h[2]>>2) & 7;

	if(f->sz == 7+1+4+8 && f->buf[7] == 0x04 && memcmp(f->buf+7+1, "nsec", 4) == 0){
		for(f->ns₀ = 0, i = 0; i < 8; i++)
			f->ns₀ |= (uvlong)f->buf[7+1+4+i] << (i*8);
		f->ns = 0;
		goto Again;
	}

	f->ns += 1000000000ULL * 1024ULL / ratecfg[ratei];

	return 0;

err:
	werrstr("adtsread: %r");
	return -1;
}