⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 av7110_ipack.c

📁 linux-2.6.15.6
💻 C
字号:
#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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -