1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <linux/kernel.h> |
3 | #include <linux/module.h> |
4 | #include <linux/string.h> |
5 | #include "dvb_filter.h" |
6 | |
7 | static u32 freq[4] = {480, 441, 320, 0}; |
8 | |
9 | static unsigned int ac3_bitrates[32] = |
10 | {32,40,48,56,64,80,96,112,128,160,192,224,256,320,384,448,512,576,640, |
11 | 0,0,0,0,0,0,0,0,0,0,0,0,0}; |
12 | |
13 | static u32 ac3_frames[3][32] = |
14 | {{64,80,96,112,128,160,192,224,256,320,384,448,512,640,768,896,1024, |
15 | 1152,1280,0,0,0,0,0,0,0,0,0,0,0,0,0}, |
16 | {69,87,104,121,139,174,208,243,278,348,417,487,557,696,835,975,1114, |
17 | 1253,1393,0,0,0,0,0,0,0,0,0,0,0,0,0}, |
18 | {96,120,144,168,192,240,288,336,384,480,576,672,768,960,1152,1344, |
19 | 1536,1728,1920,0,0,0,0,0,0,0,0,0,0,0,0,0}}; |
20 | |
21 | int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr) |
22 | { |
23 | u8 *headr; |
24 | int found = 0; |
25 | int c = 0; |
26 | u8 frame = 0; |
27 | int fr = 0; |
28 | |
29 | while ( !found && c < count){ |
30 | u8 *b = mbuf+c; |
31 | |
32 | if ( b[0] == 0x0b && b[1] == 0x77 ) |
33 | found = 1; |
34 | else { |
35 | c++; |
36 | } |
37 | } |
38 | |
39 | if (!found) return -1; |
40 | if (pr) |
41 | printk(KERN_DEBUG "Audiostream: AC3" ); |
42 | |
43 | ai->off = c; |
44 | if (c+5 >= count) return -1; |
45 | |
46 | ai->layer = 0; // 0 for AC3 |
47 | headr = mbuf+c+2; |
48 | |
49 | frame = (headr[2]&0x3f); |
50 | ai->bit_rate = ac3_bitrates[frame >> 1]*1000; |
51 | |
52 | if (pr) |
53 | printk(KERN_CONT " BRate: %d kb/s" , (int) ai->bit_rate/1000); |
54 | |
55 | ai->frequency = (headr[2] & 0xc0 ) >> 6; |
56 | fr = (headr[2] & 0xc0 ) >> 6; |
57 | ai->frequency = freq[fr]*100; |
58 | if (pr) |
59 | printk(KERN_CONT " Freq: %d Hz\n" , (int) ai->frequency); |
60 | |
61 | ai->framesize = ac3_frames[fr][frame >> 1]; |
62 | if ((frame & 1) && (fr == 1)) ai->framesize++; |
63 | ai->framesize = ai->framesize << 1; |
64 | if (pr) |
65 | printk(KERN_DEBUG " Framesize %d\n" , (int) ai->framesize); |
66 | |
67 | return 0; |
68 | } |
69 | |
70 | void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid, |
71 | dvb_filter_pes2ts_cb_t *cb, void *priv) |
72 | { |
73 | unsigned char *buf=p2ts->buf; |
74 | |
75 | buf[0]=0x47; |
76 | buf[1]=(pid>>8); |
77 | buf[2]=pid&0xff; |
78 | p2ts->cc=0; |
79 | p2ts->cb=cb; |
80 | p2ts->priv=priv; |
81 | } |
82 | |
83 | int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes, |
84 | int len, int payload_start) |
85 | { |
86 | unsigned char *buf=p2ts->buf; |
87 | int ret=0, rest; |
88 | |
89 | //len=6+((pes[4]<<8)|pes[5]); |
90 | |
91 | if (payload_start) |
92 | buf[1]|=0x40; |
93 | else |
94 | buf[1]&=~0x40; |
95 | while (len>=184) { |
96 | buf[3]=0x10|((p2ts->cc++)&0x0f); |
97 | memcpy(buf+4, pes, 184); |
98 | if ((ret=p2ts->cb(p2ts->priv, buf))) |
99 | return ret; |
100 | len-=184; pes+=184; |
101 | buf[1]&=~0x40; |
102 | } |
103 | if (!len) |
104 | return 0; |
105 | buf[3]=0x30|((p2ts->cc++)&0x0f); |
106 | rest=183-len; |
107 | if (rest) { |
108 | buf[5]=0x00; |
109 | if (rest-1) |
110 | memset(buf+6, 0xff, rest-1); |
111 | } |
112 | buf[4]=rest; |
113 | memcpy(buf+5+rest, pes, len); |
114 | return p2ts->cb(p2ts->priv, buf); |
115 | } |
116 | |