shithub: mcfs

ref: 21b0ea38419d431dc8d9492df9761c348df3558b
dir: mcfs/aac.c

View raw version
#include <u.h>
#include <libc.h>
#include <bio.h>
#include "common.h"
#include "packet.h"

int
aacpacket(Biobuf *out, Packetctx *ctx, Packet *p, int np, uvlong ts)
{
	int i, chanc, ratei, objt, sz;
	u16int x;

	USED(ts);
	if(ctx->frid == 0){ /* set up ADTS */
		if(ctx->codec.priv.sz < 2){
			/* FIXME we could reconstruct it from codec mapping and Audio element */
			werrstr("no codec private data to construct ADTS");
			return -1;
		}
		x = ctx->codec.priv.data[0]<<8 | ctx->codec.priv.data[1];
		chanc = (x>>3) & 0xf;
		ratei = (x>>7) & 0xf;
		objt = x>>11;
		if(objt > 4){
			werrstr("AAC object type %d, can't write ADTS", objt);
			return -1;
		}
		sz = 0; /* will be filled in later */
		ctx->adts[0] = 0xff; /* syncword */
		ctx->adts[1] = 0xf1; /* syncword, mpeg4, no crc */
		ctx->adts[2] = (objt-1)<<6 | ratei<<2 | chanc>>2; /* object type, rate, channel config */
		ctx->adts[3] = (chanc&3)<<6 | (sz>>11)&3; /* channel config, frame length */
		ctx->adts[4] = sz>>3; /* frame length */
		ctx->adts[5] = (sz&7)<<5 | 0x1f; /* frame length, fullness */
		ctx->adts[6] = 0xfc; /* fullness, number of frames */
	}
	for(i = 0; i < np; i++, p++){
		sz = 7+p->sz;
		ctx->adts[3] = ctx->adts[3]&~3 | (sz>>11)&3; /* channels, frame length */
		ctx->adts[4] = sz>>3; /* frame length */
		ctx->adts[5] = (sz&7)<<5 | 0x1f; /* frame length, fullness */
		if(Bwrite(out, ctx->adts, 7) != 7 || Bwrite(out, p->data, p->sz) != p->sz)
			goto err;
	}
	ctx->frid++;

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