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