1 // SPDX-License-Identifier: GPL-2.0
2 #include "dvb_filter.h"
3 #include "av7110_ipack.h"
4 #include <linux/string.h> /* for memcpy() */
5 #include <linux/vmalloc.h>
8 void av7110_ipack_reset(struct ipack
*p
)
24 int av7110_ipack_init(struct ipack
*p
, int size
,
25 void (*func
)(u8
*buf
, int size
, void *priv
))
27 if (!(p
->buf
= vmalloc(size
*sizeof(u8
)))) {
28 printk(KERN_WARNING
"Couldn't allocate memory for ipack\n");
34 av7110_ipack_reset(p
);
39 void av7110_ipack_free(struct ipack
*p
)
45 static void send_ipack(struct ipack
*p
)
48 struct dvb_audio_info ai
;
59 p
->buf
[4] = (u8
)(((p
->count
- 6) & 0xff00) >> 8);
60 p
->buf
[5] = (u8
)((p
->count
- 6) & 0x00ff);
61 if (p
->repack_subids
&& p
->cid
== PRIVATE_STREAM1
) {
63 streamid
= p
->buf
[off
];
64 if ((streamid
& 0xf8) == 0x80) {
66 ac3_off
= ((p
->buf
[off
+ 2] << 8)|
68 if (ac3_off
< p
->count
)
69 f
= dvb_filter_get_ac3info(p
->buf
+ off
+ 3 + ac3_off
,
70 p
->count
- ac3_off
, &ai
, 0);
72 nframes
= (p
->count
- off
- 3 - ac3_off
) /
74 p
->buf
[off
+ 2] = (ac3_off
>> 8) & 0xff;
75 p
->buf
[off
+ 3] = (ac3_off
) & 0xff;
76 p
->buf
[off
+ 1] = nframes
;
77 ac3_off
+= nframes
* ai
.framesize
- p
->count
;
81 p
->func(p
->buf
, p
->count
, p
->data
);
87 if (p
->repack_subids
&& p
->cid
== PRIVATE_STREAM1
88 && (streamid
& 0xf8) == 0x80) {
91 p
->buf
[10] = (ac3_off
>> 8) & 0xff;
92 p
->buf
[11] = (ac3_off
) & 0xff;
101 p
->buf
[4] = (u8
)(((p
->count
- 6) & 0xff00) >> 8);
102 p
->buf
[5] = (u8
)((p
->count
- 6) & 0x00ff);
103 p
->func(p
->buf
, p
->count
, p
->data
);
112 void av7110_ipack_flush(struct ipack
*p
)
114 if (p
->plength
!= MMAX_PLENGTH
- 6 || p
->found
<= 6)
116 p
->plength
= p
->found
- 6;
119 av7110_ipack_reset(p
);
123 static void write_ipack(struct ipack
*p
, const u8
*data
, int count
)
125 u8 headr
[3] = { 0x00, 0x00, 0x01 };
128 memcpy(p
->buf
, headr
, 3);
132 if (p
->count
+ count
< p
->size
){
133 memcpy(p
->buf
+p
->count
, data
, count
);
136 int rest
= p
->size
- p
->count
;
137 memcpy(p
->buf
+p
->count
, data
, rest
);
140 if (count
- rest
> 0)
141 write_ipack(p
, data
+ rest
, count
- rest
);
146 int av7110_ipack_instant_repack (const u8
*buf
, int count
, struct ipack
*p
)
151 while (c
< count
&& (p
->mpeg
== 0 ||
152 (p
->mpeg
== 1 && p
->found
< 7) ||
153 (p
->mpeg
== 2 && p
->found
< 9))
154 && (p
->found
< 5 || !p
->done
)) {
167 else if (buf
[c
] == 0)
176 case PROG_STREAM_MAP
:
177 case PRIVATE_STREAM2
:
178 case PROG_STREAM_DIR
:
181 case PADDING_STREAM
:
183 case ISO13522_STREAM
:
186 case PRIVATE_STREAM1
:
187 case VIDEO_STREAM_S
... VIDEO_STREAM_E
:
188 case AUDIO_STREAM_S
... AUDIO_STREAM_E
:
206 p
->plength
= (p
->plen
[0] << 8) | p
->plen
[1];
217 p
->plength
= (p
->plen
[0] << 8) | p
->plen
[1];
224 if ((p
->flag1
& 0xc0) == 0x80)
236 if (!p
->done
&& p
->mpeg
== 2) {
244 if (!p
->done
&& p
->mpeg
== 2) {
257 p
->plength
= MMAX_PLENGTH
- 6;
259 if (p
->done
|| ((p
->mpeg
== 2 && p
->found
>= 9) ||
260 (p
->mpeg
== 1 && p
->found
>= 7))) {
262 case AUDIO_STREAM_S
... AUDIO_STREAM_E
:
263 case VIDEO_STREAM_S
... VIDEO_STREAM_E
:
264 case PRIVATE_STREAM1
:
265 if (p
->mpeg
== 2 && p
->found
== 9) {
266 write_ipack(p
, &p
->flag1
, 1);
267 write_ipack(p
, &p
->flag2
, 1);
268 write_ipack(p
, &p
->hlength
, 1);
271 if (p
->mpeg
== 1 && p
->found
== 7)
272 write_ipack(p
, &p
->flag1
, 1);
274 if (p
->mpeg
== 2 && (p
->flag2
& PTS_ONLY
) &&
276 while (c
< count
&& p
->found
< 14) {
277 p
->pts
[p
->found
- 9] = buf
[c
];
278 write_ipack(p
, buf
+ c
, 1);
286 if (p
->mpeg
== 1 && p
->which
< 2000) {
293 while (!p
->which
&& c
< count
&&
296 write_ipack(p
, buf
+ c
, 1);
305 if ((p
->check
& 0xc0) == 0x40 && !p
->which
) {
307 write_ipack(p
, buf
+ c
, 1);
316 write_ipack(p
, buf
+ c
, 1);
327 write_ipack(p
, buf
+ c
, 1);
336 if ((p
->check
& 0x30) && p
->check
!= 0xff) {
337 p
->flag2
= (p
->check
& 0xf0) << 2;
338 p
->pts
[0] = p
->check
;
345 if ((p
->flag2
& PTS_DTS_FLAGS
) == PTS_ONLY
) {
346 while (c
< count
&& p
->which
< 7) {
347 p
->pts
[p
->which
- 2] = buf
[c
];
348 write_ipack(p
, buf
+ c
, 1);
356 } else if ((p
->flag2
& PTS_DTS_FLAGS
) == PTS_DTS
) {
357 while (c
< count
&& p
->which
< 12) {
359 p
->pts
[p
->which
- 2] = buf
[c
];
360 write_ipack(p
, buf
+ c
, 1);
374 while (c
< count
&& p
->found
< p
->plength
+ 6) {
376 if (l
+ p
->found
> p
->plength
+ 6)
377 l
= p
->plength
+ 6 - p
->found
;
378 write_ipack(p
, buf
+ c
, l
);
387 if (p
->found
+ count
- c
< p
->plength
+ 6) {
388 p
->found
+= count
- c
;
391 c
+= p
->plength
+ 6 - p
->found
;
392 p
->found
= p
->plength
+ 6;
396 if (p
->plength
&& p
->found
== p
->plength
+ 6) {
398 av7110_ipack_reset(p
);
400 av7110_ipack_instant_repack(buf
+ c
, count
- c
, p
);