#include "dvb_filter.h"
#include "av7110_ipack.h"
#include <linux/string.h>	/* for memcpy() */
#include <linux/vmalloc.h>


void av7110_ipack_reset(struct ipack *p)
{
	p->found = 0;
	p->cid = 0;
	p->plength = 0;
	p->flag1 = 0;
	p->flag2 = 0;
	p->hlength = 0;
	p->mpeg = 0;
	p->check = 0;
	p->which = 0;
	p->done = 0;
	p->count = 0;
}


int av7110_ipack_init(struct ipack *p, int size,
		      void (*func)(u8 *buf, int size, void *priv))
{
	if (!(p->buf = vmalloc(size*sizeof(u8)))) {
		printk(KERN_WARNING "Couldn't allocate memory for ipack\n");
		return -ENOMEM;
	}
	p->size = size;
	p->func = func;
	p->repack_subids = 0;
	av7110_ipack_reset(p);
	return 0;
}


void av7110_ipack_free(struct ipack *p)
{
	vfree(p->buf);
}


static void send_ipack(struct ipack *p)
{
	int off;
	struct dvb_audio_info ai;
	int ac3_off = 0;
	int streamid = 0;
	int nframes = 0;
	int f = 0;

	switch (p->mpeg) {
	case 2:
		if (p->count < 10)
			return;
		p->buf[3] = p->cid;
		p->buf[4] = (u8)(((p->count - 6) & 0xff00) >> 8);
		p->buf[5] = (u8)((p->count - 6) & 0x00ff);
		if (p->repack_subids && p->cid == PRIVATE_STREAM1) {
			off = 9 + p->buf[8];
			streamid = p->buf[off];
			if ((streamid & 0xf8) == 0x80) {
				ai.off = 0;
				ac3_off = ((p->buf[off + 2] << 8)|
					   p->buf[off + 3]);
				if (ac3_off < p->count)
					f = dvb_filter_get_ac3info(p->buf + off + 3 + ac3_off,
								   p->count - ac3_off, &ai, 0);
				if (!f) {
					nframes = (p->count - off - 3 - ac3_off) /
						ai.framesize + 1;
					p->buf[off + 2] = (ac3_off >> 8) & 0xff;
					p->buf[off + 3] = (ac3_off) & 0xff;
					p->buf[off + 1] = nframes;
					ac3_off +=  nframes * ai.framesize - p->count;
				}
			}
		}
		p->func(p->buf, p->count, p->data);

		p->buf[6] = 0x80;
		p->buf[7] = 0x00;
		p->buf[8] = 0x00;
		p->count = 9;
		if (p->repack_subids && p->cid == PRIVATE_STREAM1
		    && (streamid & 0xf8) == 0x80) {
			p->count += 4;
			p->buf[9] = streamid;
			p->buf[10] = (ac3_off >> 8) & 0xff;
			p->buf[11] = (ac3_off) & 0xff;
			p->buf[12] = 0;
		}
		break;

	case 1:
		if (p->count < 8)
			return;
		p->buf[3] = p->cid;
		p->buf[4] = (u8)(((p->count - 6) & 0xff00) >> 8);
		p->buf[5] = (u8)((p->count - 6) & 0x00ff);
		p->func(p->buf, p->count, p->data);

		p->buf[6] = 0x0f;
		p->count = 7;
		break;
	}
}


void av7110_ipack_flush(struct ipack *p)
{
	if (p->plength != MMAX_PLENGTH - 6 || p->found <= 6)
		return;
	p->plength = p->found - 6;
	p->found = 0;
	send_ipack(p);
	av7110_ipack_reset(p);
}


static void write_ipack(struct ipack *p, const u8 *data, int count)
{
	u8 headr[3] = { 0x00, 0x00, 0x01 };

	if (p->count < 6) {
		memcpy(p->buf, headr, 3);
		p->count = 6;
	}

	if (p->count + count < p->size){
		memcpy(p->buf+p->count, data, count);
		p->count += count;
	} else {
		int rest = p->size - p->count;
		memcpy(p->buf+p->count, data, rest);
		p->count += rest;
		send_ipack(p);
		if (count - rest > 0)
			write_ipack(p, data + rest, count - rest);
	}
}


int av7110_ipack_instant_repack (const u8 *buf, int count, struct ipack *p)
{
	int l;
	int c = 0;

	while (c < count && (p->mpeg == 0 ||
			     (p->mpeg == 1 && p->found < 7) ||
			     (p->mpeg == 2 && p->found < 9))
	       &&  (p->found < 5 || !p->done)) {
		switch (p->found) {
		case 0:
		case 1:
			if (buf[c] == 0x00)
				p->found++;
			else
				p->found = 0;
			c++;
			break;
		case 2:
			if (buf[c] == 0x01)
				p->found++;
			else if (buf[c] == 0)
				p->found = 2;
			else
				p->found = 0;
			c++;
			break;
		case 3:
			p->cid = 0;
			switch (buf[c]) {
			case PROG_STREAM_MAP:
			case PRIVATE_STREAM2:
			case PROG_STREAM_DIR:
			case ECM_STREAM     :
			case EMM_STREAM     :
			case PADDING_STREAM :
			case DSM_CC_STREAM  :
			case ISO13522_STREAM:
				p->done = 1;
				/* fall through */
			case PRIVATE_STREAM1:
			case VIDEO_STREAM_S ... VIDEO_STREAM_E:
			case AUDIO_STREAM_S ... AUDIO_STREAM_E:
				p->found++;
				p->cid = buf[c];
				c++;
				break;
			default:
				p->found = 0;
				break;
			}
			break;

		case 4:
			if (count-c > 1) {
				p->plen[0] = buf[c];
				c++;
				p->plen[1] = buf[c];
				c++;
				p->found += 2;
				p->plength = (p->plen[0] << 8) | p->plen[1];
			} else {
				p->plen[0] = buf[c];
				p->found++;
				return count;
			}
			break;
		case 5:
			p->plen[1] = buf[c];
			c++;
			p->found++;
			p->plength = (p->plen[0] << 8) | p->plen[1];
			break;
		case 6:
			if (!p->done) {
				p->flag1 = buf[c];
				c++;
				p->found++;
				if ((p->flag1 & 0xc0) == 0x80)
					p->mpeg = 2;
				else {
					p->hlength = 0;
					p->which = 0;
					p->mpeg = 1;
					p->flag2 = 0;
				}
			}
			break;

		case 7:
			if (!p->done && p->mpeg == 2) {
				p->flag2 = buf[c];
				c++;
				p->found++;
			}
			break;

		case 8:
			if (!p->done && p->mpeg == 2) {
				p->hlength = buf[c];
				c++;
				p->found++;
			}
			break;
		}
	}

	if (c == count)
		return count;

	if (!p->plength)
		p->plength = MMAX_PLENGTH - 6;

	if (p->done || ((p->mpeg == 2 && p->found >= 9) ||
			(p->mpeg == 1 && p->found >= 7))) {
		switch (p->cid) {
		case AUDIO_STREAM_S ... AUDIO_STREAM_E:
		case VIDEO_STREAM_S ... VIDEO_STREAM_E:
		case PRIVATE_STREAM1:
			if (p->mpeg == 2 && p->found == 9) {
				write_ipack(p, &p->flag1, 1);
				write_ipack(p, &p->flag2, 1);
				write_ipack(p, &p->hlength, 1);
			}

			if (p->mpeg == 1 && p->found == 7)
				write_ipack(p, &p->flag1, 1);

			if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) &&
			    p->found < 14) {
				while (c < count && p->found < 14) {
					p->pts[p->found - 9] = buf[c];
					write_ipack(p, buf + c, 1);
					c++;
					p->found++;
				}
				if (c == count)
					return count;
			}

			if (p->mpeg == 1 && p->which < 2000) {

				if (p->found == 7) {
					p->check = p->flag1;
					p->hlength = 1;
				}

				while (!p->which && c < count &&
				       p->check == 0xff){
					p->check = buf[c];
					write_ipack(p, buf + c, 1);
					c++;
					p->found++;
					p->hlength++;
				}

				if (c == count)
					return count;

				if ((p->check & 0xc0) == 0x40 && !p->which) {
					p->check = buf[c];
					write_ipack(p, buf + c, 1);
					c++;
					p->found++;
					p->hlength++;

					p->which = 1;
					if (c == count)
						return count;
					p->check = buf[c];
					write_ipack(p, buf + c, 1);
					c++;
					p->found++;
					p->hlength++;
					p->which = 2;
					if (c == count)
						return count;
				}

				if (p->which == 1) {
					p->check = buf[c];
					write_ipack(p, buf + c, 1);
					c++;
					p->found++;
					p->hlength++;
					p->which = 2;
					if (c == count)
						return count;
				}

				if ((p->check & 0x30) && p->check != 0xff) {
					p->flag2 = (p->check & 0xf0) << 2;
					p->pts[0] = p->check;
					p->which = 3;
				}

				if (c == count)
					return count;
				if (p->which > 2){
					if ((p->flag2 & PTS_DTS_FLAGS) == PTS_ONLY) {
						while (c < count && p->which < 7) {
							p->pts[p->which - 2] = buf[c];
							write_ipack(p, buf + c, 1);
							c++;
							p->found++;
							p->which++;
							p->hlength++;
						}
						if (c == count)
							return count;
					} else if ((p->flag2 & PTS_DTS_FLAGS) == PTS_DTS) {
						while (c < count && p->which < 12) {
							if (p->which < 7)
								p->pts[p->which - 2] = buf[c];
							write_ipack(p, buf + c, 1);
							c++;
							p->found++;
							p->which++;
							p->hlength++;
						}
						if (c == count)
							return count;
					}
					p->which = 2000;
				}

			}

			while (c < count && p->found < p->plength + 6) {
				l = count - c;
				if (l + p->found > p->plength + 6)
					l = p->plength + 6 - p->found;
				write_ipack(p, buf + c, l);
				p->found += l;
				c += l;
			}
			break;
		}


		if (p->done) {
			if (p->found + count - c < p->plength + 6) {
				p->found += count - c;
				c = count;
			} else {
				c += p->plength + 6 - p->found;
				p->found = p->plength + 6;
			}
		}

		if (p->plength && p->found == p->plength + 6) {
			send_ipack(p);
			av7110_ipack_reset(p);
			if (c < count)
				av7110_ipack_instant_repack(buf + c, count - c, p);
		}
	}
	return count;
}
