xref: /OK3568_Linux_fs/kernel/drivers/media/pci/ttpci/av7110_ipack.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun #include "dvb_filter.h"
3*4882a593Smuzhiyun #include "av7110_ipack.h"
4*4882a593Smuzhiyun #include <linux/string.h>	/* for memcpy() */
5*4882a593Smuzhiyun #include <linux/vmalloc.h>
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun 
av7110_ipack_reset(struct ipack * p)8*4882a593Smuzhiyun void av7110_ipack_reset(struct ipack *p)
9*4882a593Smuzhiyun {
10*4882a593Smuzhiyun 	p->found = 0;
11*4882a593Smuzhiyun 	p->cid = 0;
12*4882a593Smuzhiyun 	p->plength = 0;
13*4882a593Smuzhiyun 	p->flag1 = 0;
14*4882a593Smuzhiyun 	p->flag2 = 0;
15*4882a593Smuzhiyun 	p->hlength = 0;
16*4882a593Smuzhiyun 	p->mpeg = 0;
17*4882a593Smuzhiyun 	p->check = 0;
18*4882a593Smuzhiyun 	p->which = 0;
19*4882a593Smuzhiyun 	p->done = 0;
20*4882a593Smuzhiyun 	p->count = 0;
21*4882a593Smuzhiyun }
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun 
av7110_ipack_init(struct ipack * p,int size,void (* func)(u8 * buf,int size,void * priv))24*4882a593Smuzhiyun int av7110_ipack_init(struct ipack *p, int size,
25*4882a593Smuzhiyun 		      void (*func)(u8 *buf, int size, void *priv))
26*4882a593Smuzhiyun {
27*4882a593Smuzhiyun 	if (!(p->buf = vmalloc(size))) {
28*4882a593Smuzhiyun 		printk(KERN_WARNING "Couldn't allocate memory for ipack\n");
29*4882a593Smuzhiyun 		return -ENOMEM;
30*4882a593Smuzhiyun 	}
31*4882a593Smuzhiyun 	p->size = size;
32*4882a593Smuzhiyun 	p->func = func;
33*4882a593Smuzhiyun 	p->repack_subids = 0;
34*4882a593Smuzhiyun 	av7110_ipack_reset(p);
35*4882a593Smuzhiyun 	return 0;
36*4882a593Smuzhiyun }
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun 
av7110_ipack_free(struct ipack * p)39*4882a593Smuzhiyun void av7110_ipack_free(struct ipack *p)
40*4882a593Smuzhiyun {
41*4882a593Smuzhiyun 	vfree(p->buf);
42*4882a593Smuzhiyun }
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun 
send_ipack(struct ipack * p)45*4882a593Smuzhiyun static void send_ipack(struct ipack *p)
46*4882a593Smuzhiyun {
47*4882a593Smuzhiyun 	int off;
48*4882a593Smuzhiyun 	struct dvb_audio_info ai;
49*4882a593Smuzhiyun 	int ac3_off = 0;
50*4882a593Smuzhiyun 	int streamid = 0;
51*4882a593Smuzhiyun 	int nframes = 0;
52*4882a593Smuzhiyun 	int f = 0;
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	switch (p->mpeg) {
55*4882a593Smuzhiyun 	case 2:
56*4882a593Smuzhiyun 		if (p->count < 10)
57*4882a593Smuzhiyun 			return;
58*4882a593Smuzhiyun 		p->buf[3] = p->cid;
59*4882a593Smuzhiyun 		p->buf[4] = (u8)(((p->count - 6) & 0xff00) >> 8);
60*4882a593Smuzhiyun 		p->buf[5] = (u8)((p->count - 6) & 0x00ff);
61*4882a593Smuzhiyun 		if (p->repack_subids && p->cid == PRIVATE_STREAM1) {
62*4882a593Smuzhiyun 			off = 9 + p->buf[8];
63*4882a593Smuzhiyun 			streamid = p->buf[off];
64*4882a593Smuzhiyun 			if ((streamid & 0xf8) == 0x80) {
65*4882a593Smuzhiyun 				ai.off = 0;
66*4882a593Smuzhiyun 				ac3_off = ((p->buf[off + 2] << 8)|
67*4882a593Smuzhiyun 					   p->buf[off + 3]);
68*4882a593Smuzhiyun 				if (ac3_off < p->count)
69*4882a593Smuzhiyun 					f = dvb_filter_get_ac3info(p->buf + off + 3 + ac3_off,
70*4882a593Smuzhiyun 								   p->count - ac3_off, &ai, 0);
71*4882a593Smuzhiyun 				if (!f) {
72*4882a593Smuzhiyun 					nframes = (p->count - off - 3 - ac3_off) /
73*4882a593Smuzhiyun 						ai.framesize + 1;
74*4882a593Smuzhiyun 					p->buf[off + 2] = (ac3_off >> 8) & 0xff;
75*4882a593Smuzhiyun 					p->buf[off + 3] = (ac3_off) & 0xff;
76*4882a593Smuzhiyun 					p->buf[off + 1] = nframes;
77*4882a593Smuzhiyun 					ac3_off +=  nframes * ai.framesize - p->count;
78*4882a593Smuzhiyun 				}
79*4882a593Smuzhiyun 			}
80*4882a593Smuzhiyun 		}
81*4882a593Smuzhiyun 		p->func(p->buf, p->count, p->data);
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 		p->buf[6] = 0x80;
84*4882a593Smuzhiyun 		p->buf[7] = 0x00;
85*4882a593Smuzhiyun 		p->buf[8] = 0x00;
86*4882a593Smuzhiyun 		p->count = 9;
87*4882a593Smuzhiyun 		if (p->repack_subids && p->cid == PRIVATE_STREAM1
88*4882a593Smuzhiyun 		    && (streamid & 0xf8) == 0x80) {
89*4882a593Smuzhiyun 			p->count += 4;
90*4882a593Smuzhiyun 			p->buf[9] = streamid;
91*4882a593Smuzhiyun 			p->buf[10] = (ac3_off >> 8) & 0xff;
92*4882a593Smuzhiyun 			p->buf[11] = (ac3_off) & 0xff;
93*4882a593Smuzhiyun 			p->buf[12] = 0;
94*4882a593Smuzhiyun 		}
95*4882a593Smuzhiyun 		break;
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun 	case 1:
98*4882a593Smuzhiyun 		if (p->count < 8)
99*4882a593Smuzhiyun 			return;
100*4882a593Smuzhiyun 		p->buf[3] = p->cid;
101*4882a593Smuzhiyun 		p->buf[4] = (u8)(((p->count - 6) & 0xff00) >> 8);
102*4882a593Smuzhiyun 		p->buf[5] = (u8)((p->count - 6) & 0x00ff);
103*4882a593Smuzhiyun 		p->func(p->buf, p->count, p->data);
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun 		p->buf[6] = 0x0f;
106*4882a593Smuzhiyun 		p->count = 7;
107*4882a593Smuzhiyun 		break;
108*4882a593Smuzhiyun 	}
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 
av7110_ipack_flush(struct ipack * p)112*4882a593Smuzhiyun void av7110_ipack_flush(struct ipack *p)
113*4882a593Smuzhiyun {
114*4882a593Smuzhiyun 	if (p->plength != MMAX_PLENGTH - 6 || p->found <= 6)
115*4882a593Smuzhiyun 		return;
116*4882a593Smuzhiyun 	p->plength = p->found - 6;
117*4882a593Smuzhiyun 	p->found = 0;
118*4882a593Smuzhiyun 	send_ipack(p);
119*4882a593Smuzhiyun 	av7110_ipack_reset(p);
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 
write_ipack(struct ipack * p,const u8 * data,int count)123*4882a593Smuzhiyun static void write_ipack(struct ipack *p, const u8 *data, int count)
124*4882a593Smuzhiyun {
125*4882a593Smuzhiyun 	u8 headr[3] = { 0x00, 0x00, 0x01 };
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun 	if (p->count < 6) {
128*4882a593Smuzhiyun 		memcpy(p->buf, headr, 3);
129*4882a593Smuzhiyun 		p->count = 6;
130*4882a593Smuzhiyun 	}
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	if (p->count + count < p->size){
133*4882a593Smuzhiyun 		memcpy(p->buf+p->count, data, count);
134*4882a593Smuzhiyun 		p->count += count;
135*4882a593Smuzhiyun 	} else {
136*4882a593Smuzhiyun 		int rest = p->size - p->count;
137*4882a593Smuzhiyun 		memcpy(p->buf+p->count, data, rest);
138*4882a593Smuzhiyun 		p->count += rest;
139*4882a593Smuzhiyun 		send_ipack(p);
140*4882a593Smuzhiyun 		if (count - rest > 0)
141*4882a593Smuzhiyun 			write_ipack(p, data + rest, count - rest);
142*4882a593Smuzhiyun 	}
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 
av7110_ipack_instant_repack(const u8 * buf,int count,struct ipack * p)146*4882a593Smuzhiyun int av7110_ipack_instant_repack (const u8 *buf, int count, struct ipack *p)
147*4882a593Smuzhiyun {
148*4882a593Smuzhiyun 	int l;
149*4882a593Smuzhiyun 	int c = 0;
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 	while (c < count && (p->mpeg == 0 ||
152*4882a593Smuzhiyun 			     (p->mpeg == 1 && p->found < 7) ||
153*4882a593Smuzhiyun 			     (p->mpeg == 2 && p->found < 9))
154*4882a593Smuzhiyun 	       &&  (p->found < 5 || !p->done)) {
155*4882a593Smuzhiyun 		switch (p->found) {
156*4882a593Smuzhiyun 		case 0:
157*4882a593Smuzhiyun 		case 1:
158*4882a593Smuzhiyun 			if (buf[c] == 0x00)
159*4882a593Smuzhiyun 				p->found++;
160*4882a593Smuzhiyun 			else
161*4882a593Smuzhiyun 				p->found = 0;
162*4882a593Smuzhiyun 			c++;
163*4882a593Smuzhiyun 			break;
164*4882a593Smuzhiyun 		case 2:
165*4882a593Smuzhiyun 			if (buf[c] == 0x01)
166*4882a593Smuzhiyun 				p->found++;
167*4882a593Smuzhiyun 			else if (buf[c] == 0)
168*4882a593Smuzhiyun 				p->found = 2;
169*4882a593Smuzhiyun 			else
170*4882a593Smuzhiyun 				p->found = 0;
171*4882a593Smuzhiyun 			c++;
172*4882a593Smuzhiyun 			break;
173*4882a593Smuzhiyun 		case 3:
174*4882a593Smuzhiyun 			p->cid = 0;
175*4882a593Smuzhiyun 			switch (buf[c]) {
176*4882a593Smuzhiyun 			case PROG_STREAM_MAP:
177*4882a593Smuzhiyun 			case PRIVATE_STREAM2:
178*4882a593Smuzhiyun 			case PROG_STREAM_DIR:
179*4882a593Smuzhiyun 			case ECM_STREAM     :
180*4882a593Smuzhiyun 			case EMM_STREAM     :
181*4882a593Smuzhiyun 			case PADDING_STREAM :
182*4882a593Smuzhiyun 			case DSM_CC_STREAM  :
183*4882a593Smuzhiyun 			case ISO13522_STREAM:
184*4882a593Smuzhiyun 				p->done = 1;
185*4882a593Smuzhiyun 				fallthrough;
186*4882a593Smuzhiyun 			case PRIVATE_STREAM1:
187*4882a593Smuzhiyun 			case VIDEO_STREAM_S ... VIDEO_STREAM_E:
188*4882a593Smuzhiyun 			case AUDIO_STREAM_S ... AUDIO_STREAM_E:
189*4882a593Smuzhiyun 				p->found++;
190*4882a593Smuzhiyun 				p->cid = buf[c];
191*4882a593Smuzhiyun 				c++;
192*4882a593Smuzhiyun 				break;
193*4882a593Smuzhiyun 			default:
194*4882a593Smuzhiyun 				p->found = 0;
195*4882a593Smuzhiyun 				break;
196*4882a593Smuzhiyun 			}
197*4882a593Smuzhiyun 			break;
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 		case 4:
200*4882a593Smuzhiyun 			if (count-c > 1) {
201*4882a593Smuzhiyun 				p->plen[0] = buf[c];
202*4882a593Smuzhiyun 				c++;
203*4882a593Smuzhiyun 				p->plen[1] = buf[c];
204*4882a593Smuzhiyun 				c++;
205*4882a593Smuzhiyun 				p->found += 2;
206*4882a593Smuzhiyun 				p->plength = (p->plen[0] << 8) | p->plen[1];
207*4882a593Smuzhiyun 			} else {
208*4882a593Smuzhiyun 				p->plen[0] = buf[c];
209*4882a593Smuzhiyun 				p->found++;
210*4882a593Smuzhiyun 				return count;
211*4882a593Smuzhiyun 			}
212*4882a593Smuzhiyun 			break;
213*4882a593Smuzhiyun 		case 5:
214*4882a593Smuzhiyun 			p->plen[1] = buf[c];
215*4882a593Smuzhiyun 			c++;
216*4882a593Smuzhiyun 			p->found++;
217*4882a593Smuzhiyun 			p->plength = (p->plen[0] << 8) | p->plen[1];
218*4882a593Smuzhiyun 			break;
219*4882a593Smuzhiyun 		case 6:
220*4882a593Smuzhiyun 			if (!p->done) {
221*4882a593Smuzhiyun 				p->flag1 = buf[c];
222*4882a593Smuzhiyun 				c++;
223*4882a593Smuzhiyun 				p->found++;
224*4882a593Smuzhiyun 				if ((p->flag1 & 0xc0) == 0x80)
225*4882a593Smuzhiyun 					p->mpeg = 2;
226*4882a593Smuzhiyun 				else {
227*4882a593Smuzhiyun 					p->hlength = 0;
228*4882a593Smuzhiyun 					p->which = 0;
229*4882a593Smuzhiyun 					p->mpeg = 1;
230*4882a593Smuzhiyun 					p->flag2 = 0;
231*4882a593Smuzhiyun 				}
232*4882a593Smuzhiyun 			}
233*4882a593Smuzhiyun 			break;
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 		case 7:
236*4882a593Smuzhiyun 			if (!p->done && p->mpeg == 2) {
237*4882a593Smuzhiyun 				p->flag2 = buf[c];
238*4882a593Smuzhiyun 				c++;
239*4882a593Smuzhiyun 				p->found++;
240*4882a593Smuzhiyun 			}
241*4882a593Smuzhiyun 			break;
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun 		case 8:
244*4882a593Smuzhiyun 			if (!p->done && p->mpeg == 2) {
245*4882a593Smuzhiyun 				p->hlength = buf[c];
246*4882a593Smuzhiyun 				c++;
247*4882a593Smuzhiyun 				p->found++;
248*4882a593Smuzhiyun 			}
249*4882a593Smuzhiyun 			break;
250*4882a593Smuzhiyun 		}
251*4882a593Smuzhiyun 	}
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 	if (c == count)
254*4882a593Smuzhiyun 		return count;
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	if (!p->plength)
257*4882a593Smuzhiyun 		p->plength = MMAX_PLENGTH - 6;
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun 	if (p->done || ((p->mpeg == 2 && p->found >= 9) ||
260*4882a593Smuzhiyun 			(p->mpeg == 1 && p->found >= 7))) {
261*4882a593Smuzhiyun 		switch (p->cid) {
262*4882a593Smuzhiyun 		case AUDIO_STREAM_S ... AUDIO_STREAM_E:
263*4882a593Smuzhiyun 		case VIDEO_STREAM_S ... VIDEO_STREAM_E:
264*4882a593Smuzhiyun 		case PRIVATE_STREAM1:
265*4882a593Smuzhiyun 			if (p->mpeg == 2 && p->found == 9) {
266*4882a593Smuzhiyun 				write_ipack(p, &p->flag1, 1);
267*4882a593Smuzhiyun 				write_ipack(p, &p->flag2, 1);
268*4882a593Smuzhiyun 				write_ipack(p, &p->hlength, 1);
269*4882a593Smuzhiyun 			}
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun 			if (p->mpeg == 1 && p->found == 7)
272*4882a593Smuzhiyun 				write_ipack(p, &p->flag1, 1);
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun 			if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) &&
275*4882a593Smuzhiyun 			    p->found < 14) {
276*4882a593Smuzhiyun 				while (c < count && p->found < 14) {
277*4882a593Smuzhiyun 					p->pts[p->found - 9] = buf[c];
278*4882a593Smuzhiyun 					write_ipack(p, buf + c, 1);
279*4882a593Smuzhiyun 					c++;
280*4882a593Smuzhiyun 					p->found++;
281*4882a593Smuzhiyun 				}
282*4882a593Smuzhiyun 				if (c == count)
283*4882a593Smuzhiyun 					return count;
284*4882a593Smuzhiyun 			}
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 			if (p->mpeg == 1 && p->which < 2000) {
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 				if (p->found == 7) {
289*4882a593Smuzhiyun 					p->check = p->flag1;
290*4882a593Smuzhiyun 					p->hlength = 1;
291*4882a593Smuzhiyun 				}
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun 				while (!p->which && c < count &&
294*4882a593Smuzhiyun 				       p->check == 0xff){
295*4882a593Smuzhiyun 					p->check = buf[c];
296*4882a593Smuzhiyun 					write_ipack(p, buf + c, 1);
297*4882a593Smuzhiyun 					c++;
298*4882a593Smuzhiyun 					p->found++;
299*4882a593Smuzhiyun 					p->hlength++;
300*4882a593Smuzhiyun 				}
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 				if (c == count)
303*4882a593Smuzhiyun 					return count;
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun 				if ((p->check & 0xc0) == 0x40 && !p->which) {
306*4882a593Smuzhiyun 					p->check = buf[c];
307*4882a593Smuzhiyun 					write_ipack(p, buf + c, 1);
308*4882a593Smuzhiyun 					c++;
309*4882a593Smuzhiyun 					p->found++;
310*4882a593Smuzhiyun 					p->hlength++;
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun 					p->which = 1;
313*4882a593Smuzhiyun 					if (c == count)
314*4882a593Smuzhiyun 						return count;
315*4882a593Smuzhiyun 					p->check = buf[c];
316*4882a593Smuzhiyun 					write_ipack(p, buf + c, 1);
317*4882a593Smuzhiyun 					c++;
318*4882a593Smuzhiyun 					p->found++;
319*4882a593Smuzhiyun 					p->hlength++;
320*4882a593Smuzhiyun 					p->which = 2;
321*4882a593Smuzhiyun 					if (c == count)
322*4882a593Smuzhiyun 						return count;
323*4882a593Smuzhiyun 				}
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun 				if (p->which == 1) {
326*4882a593Smuzhiyun 					p->check = buf[c];
327*4882a593Smuzhiyun 					write_ipack(p, buf + c, 1);
328*4882a593Smuzhiyun 					c++;
329*4882a593Smuzhiyun 					p->found++;
330*4882a593Smuzhiyun 					p->hlength++;
331*4882a593Smuzhiyun 					p->which = 2;
332*4882a593Smuzhiyun 					if (c == count)
333*4882a593Smuzhiyun 						return count;
334*4882a593Smuzhiyun 				}
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun 				if ((p->check & 0x30) && p->check != 0xff) {
337*4882a593Smuzhiyun 					p->flag2 = (p->check & 0xf0) << 2;
338*4882a593Smuzhiyun 					p->pts[0] = p->check;
339*4882a593Smuzhiyun 					p->which = 3;
340*4882a593Smuzhiyun 				}
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 				if (c == count)
343*4882a593Smuzhiyun 					return count;
344*4882a593Smuzhiyun 				if (p->which > 2){
345*4882a593Smuzhiyun 					if ((p->flag2 & PTS_DTS_FLAGS) == PTS_ONLY) {
346*4882a593Smuzhiyun 						while (c < count && p->which < 7) {
347*4882a593Smuzhiyun 							p->pts[p->which - 2] = buf[c];
348*4882a593Smuzhiyun 							write_ipack(p, buf + c, 1);
349*4882a593Smuzhiyun 							c++;
350*4882a593Smuzhiyun 							p->found++;
351*4882a593Smuzhiyun 							p->which++;
352*4882a593Smuzhiyun 							p->hlength++;
353*4882a593Smuzhiyun 						}
354*4882a593Smuzhiyun 						if (c == count)
355*4882a593Smuzhiyun 							return count;
356*4882a593Smuzhiyun 					} else if ((p->flag2 & PTS_DTS_FLAGS) == PTS_DTS) {
357*4882a593Smuzhiyun 						while (c < count && p->which < 12) {
358*4882a593Smuzhiyun 							if (p->which < 7)
359*4882a593Smuzhiyun 								p->pts[p->which - 2] = buf[c];
360*4882a593Smuzhiyun 							write_ipack(p, buf + c, 1);
361*4882a593Smuzhiyun 							c++;
362*4882a593Smuzhiyun 							p->found++;
363*4882a593Smuzhiyun 							p->which++;
364*4882a593Smuzhiyun 							p->hlength++;
365*4882a593Smuzhiyun 						}
366*4882a593Smuzhiyun 						if (c == count)
367*4882a593Smuzhiyun 							return count;
368*4882a593Smuzhiyun 					}
369*4882a593Smuzhiyun 					p->which = 2000;
370*4882a593Smuzhiyun 				}
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun 			}
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun 			while (c < count && p->found < p->plength + 6) {
375*4882a593Smuzhiyun 				l = count - c;
376*4882a593Smuzhiyun 				if (l + p->found > p->plength + 6)
377*4882a593Smuzhiyun 					l = p->plength + 6 - p->found;
378*4882a593Smuzhiyun 				write_ipack(p, buf + c, l);
379*4882a593Smuzhiyun 				p->found += l;
380*4882a593Smuzhiyun 				c += l;
381*4882a593Smuzhiyun 			}
382*4882a593Smuzhiyun 			break;
383*4882a593Smuzhiyun 		}
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun 
386*4882a593Smuzhiyun 		if (p->done) {
387*4882a593Smuzhiyun 			if (p->found + count - c < p->plength + 6) {
388*4882a593Smuzhiyun 				p->found += count - c;
389*4882a593Smuzhiyun 				c = count;
390*4882a593Smuzhiyun 			} else {
391*4882a593Smuzhiyun 				c += p->plength + 6 - p->found;
392*4882a593Smuzhiyun 				p->found = p->plength + 6;
393*4882a593Smuzhiyun 			}
394*4882a593Smuzhiyun 		}
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun 		if (p->plength && p->found == p->plength + 6) {
397*4882a593Smuzhiyun 			send_ipack(p);
398*4882a593Smuzhiyun 			av7110_ipack_reset(p);
399*4882a593Smuzhiyun 			if (c < count)
400*4882a593Smuzhiyun 				av7110_ipack_instant_repack(buf + c, count - c, p);
401*4882a593Smuzhiyun 		}
402*4882a593Smuzhiyun 	}
403*4882a593Smuzhiyun 	return count;
404*4882a593Smuzhiyun }
405