OSDN Git Service

commit local dev ver
[rec10/rec10-git.git] / epgdump / ts.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include "ts.h"
6
7 static unsigned int CalcCrc(unsigned int crc, unsigned char *buf, int len);
8 static int checkcrc(SECcache *secs);
9
10 SECcache *readTS(FILE *in, SECcache secs[], int size) {
11         static int rcount = 0;
12         static int ridx = -1;
13
14         TSpacket pk;
15   
16         unsigned char buf[1024];
17
18         int boff;
19         int len;
20         unsigned char *payptr;
21
22         int inchar;
23         int i;
24
25         /* syncバイトまで読み飛ばし */
26         if(rcount == 0) {
27                 while((inchar = fgetc(in)) != EOF) {
28                         if((inchar & 0xFF) == 0x47) {
29                                 //fseek(in, -1, SEEK_CUR);
30                                 ungetc(inchar, in);
31                                 break;
32                         }
33                 }
34                 if(inchar == EOF) {
35                         return NULL;
36                 }
37         }
38
39 retry:
40   
41         /* 戻すべき残りがあるか? */
42         if(ridx >= 0 && secs[ridx].cont) {
43                 /* バッファチェック */
44                 if((secs[ridx].cur.payload[secs[ridx].curlen] & 0xFF) == 0xFF) {
45                         secs[ridx].cont = 0;
46                         secs[ridx].seclen = 0;
47                         secs[ridx].setlen = 0;
48                         secs[ridx].curlen = 0;
49                 } else {
50                         len = secs[ridx].cur.payloadlen - secs[ridx].curlen;
51                         /* 全部設定済みチェック */
52                         if(len == 0) {
53                                 secs[ridx].cont = 0;
54                                 secs[ridx].seclen = 0;
55                                 secs[ridx].setlen = 0;
56                                 secs[ridx].curlen = 0;
57                         } else {
58                                 /* ここでseclenが跨るようにTS分割されていると困るな @@
59                                    if(secs[ridx].pid == 0x12) {
60                                    int check = secs[ridx].cur.payload[secs[ridx].curlen] & 0xFF;
61                                    if(!(check == 0x4E ||
62                                    check == 0x4F ||
63                                    (check >= 0x50 && check <= 0x6F))) {
64                                    secs[ridx].curlen -= 3;
65                                    }
66                                    }
67                                 */
68         
69                                 boff = 12;
70                                 secs[ridx].seclen = getBit(&secs[ridx].cur.payload[secs[ridx].curlen], &boff, 12) + 3; // ヘッダ
71                                 /*
72                                 if(secs[ridx].seclen > MAXSECLEN){
73                                         // セクションが MAXSECLEN より大きい時はこのセクションをスキップ
74                                         secs[ridx].cont = 0;
75                                         goto retry;
76                                 }
77                                 */
78         
79                                 /*
80                                   if(secs[ridx].seclen == 2334) {
81                                   printf("aa");
82                                   }
83                                 */
84         
85                                 /* TSデータ長-設定済みデータ長 */
86                                 if(secs[ridx].seclen > len) {
87                                         memcpy(secs[ridx].buf, &secs[ridx].cur.payload[secs[ridx].curlen], len);
88                                         secs[ridx].setlen = len;
89                                         secs[ridx].curlen = 0;
90                                         secs[ridx].cont   = 1;
91                                         /* 次のレコード読み込み */
92                                 } else {
93                                         memcpy(secs[ridx].buf, 
94                                                    &secs[ridx].cur.payload[secs[ridx].curlen], secs[ridx].seclen);
95                                         secs[ridx].setlen  = secs[ridx].seclen;
96                                         secs[ridx].curlen += secs[ridx].seclen;
97                                         secs[ridx].cont = 1;
98
99                                         /* CRCのチェック */
100                                         if(checkcrc(&(secs[ridx]))) {
101                                                 return &(secs[ridx]); /* 戻る */
102                                         }
103                                         goto retry; /* もう一回 */
104                                 }
105                         }
106                 }
107         }
108
109         int roffset = 0;
110         while(1) {
111                 if(fread(buf+roffset, 188-roffset, 1, in) != 1) {
112                         /* 残りの処理? */
113                         return NULL;
114                 }
115                 roffset = 0;
116                 rcount++;
117
118                 if((buf[0] & 0xFF) != 0x47) {
119                         /* 最初はbuf中に0x47があるかチェック */
120                         for(i = 1; i < 188; i++) {
121                                 if((buf[i] & 0xFF) == 0x47) {
122                                         break;
123                                 }
124                         }
125
126                         if(i < 188) {
127                                 /* そこから再読み込みして欲しいのでseek */
128                                 //fseek(in, (188 - i) * -1, SEEK_CUR);
129                                 roffset = i;
130                                 memmove(buf, buf + i, 188 - i);
131                                 continue;
132                         }
133
134                         while((inchar = fgetc(in)) != EOF) {
135                                 if((inchar & 0xFF) == 0x47) {
136                                         //fseek(in, -1, SEEK_CUR);
137                                         ungetc(inchar, in);
138                                         break;
139                                 }
140                         }
141                         if(inchar == EOF) {
142                                 return NULL;
143                         }
144                         continue;
145                 }
146
147                 /*
148                   if(rcount == 406502) {
149                   printf("aa");
150                   }
151                 */
152
153     
154                 pk.rcount = rcount;
155     
156                 boff = 0;
157                 pk.sync = getBit(buf, &boff, 8);
158                 pk.transport_error_indicator = getBit(buf, &boff, 1);
159                 pk.payload_unit_start_indicator = getBit(buf, &boff, 1);
160                 pk.transport_priority = getBit(buf, &boff, 1);
161                 pk.pid = getBit(buf, &boff, 13);
162                 pk.transport_scrambling_control = getBit(buf, &boff, 2);
163                 pk.adaptation_field_control = getBit(buf, &boff, 2);
164                 pk.continuity_counter = getBit(buf, &boff, 4);
165
166                 /*
167                   adaptation_field_control 2 bslbf
168                   continuity_counter 4 uimsbf
169                   if(adaptation_field_control = = '10' || adaptation_field_control = = '11'){
170                   adaptation_field()
171                   }
172                   ...
173                   adaptation_field() {
174                   adaptation_field_length 8 uimsbf
175                   if (adaptation_field_length > 0) {
176                   discontinuity_indicator....
177
178                   00 Reserved for future use by ISO/IEC
179                   01 No adaptation_field, payload only
180                   10 Adaptation_field only, no payload
181                   11 Adaptation_field followed by payload
182
183                 */
184
185                 pk.payloadlen = 184;
186
187                 if(pk.adaptation_field_control == 2) {
188                         continue;
189                 }
190
191                 if(pk.adaptation_field_control == 3) {
192                         len = getBit(buf, &boff, 8);
193                         payptr = buf + (boff / 8) + len;
194                         pk.payloadlen -= (len + 1);
195                 } else {
196                         payptr = buf + (boff / 8);
197                 }
198                 if(pk.payloadlen < 0){
199                         continue ;
200                 }
201
202                 /* 
203                    if the Transport Stream packet carries the first byte of a PSI section, the payload_unit_start_indicator value
204                    shall be '1', indicating that the first byte of the payload of this Transport Stream packet carries the pointer_field.
205                 */
206                 if(pk.payload_unit_start_indicator == 1) {
207                         /* pointer_fieldはいらない */
208                         payptr += 1;
209                         pk.payloadlen -= 1;
210                 }
211
212                 memset(pk.payload, 0xFF, sizeof(pk.payload));
213                 /* 07/07/2009 add: */
214                 //if((pk.payloadlen <= 0) || (pk.payloadlen > sizeof(pk.payload))){
215                 if( pk.payloadlen > sizeof(pk.payload) ){
216                         continue;
217                 }
218                 memcpy(pk.payload, payptr, pk.payloadlen);
219     
220                 /*
221                   if(pk.rcount == 62) {
222                   printf("62\n");
223                   }
224
225                   if(pk.rcount == 63) {
226                   printf("63\n");
227                   }
228                 */
229     
230                 /* 興味のあるpidか確認 */
231                 for(int i = 0;i < size; i++) {
232                         if(secs[i].pid == pk.pid) {
233                                 secs[i].cur = pk;
234                                 /* 途中処理中か最初か? */
235                                 if(!secs[i].cont) {
236                                         /* 最初 セクション長を調べる */
237                                         boff = 12;
238                                         secs[i].seclen = getBit(secs[i].cur.payload, &boff, 12) + 3; // ヘッダ;
239                                         /*
240                                         if(secs[i].seclen > MAXSECLEN){
241                                                 // セクション長が MAXSECLEN より長いときはこのセクションをスキップ
242                                                 secs[i].cont = 0;
243                                                 goto retry;
244                                         }
245                                         */
246                                         /*
247                                           if(secs[i].seclen == 2334) {
248                                           printf("aa");
249                                           }
250                                         */
251
252                                         if(secs[i].seclen > secs[i].cur.payloadlen) {
253                                                 memcpy(secs[i].buf, secs[i].cur.payload, secs[i].cur.payloadlen);
254                                                 secs[i].setlen = secs[i].cur.payloadlen;
255                                                 secs[i].cont = 1;
256                                                 continue;
257                                         } 
258                                         memcpy(secs[i].buf, secs[i].cur.payload, secs[i].seclen);
259                                         secs[i].setlen = secs[i].seclen;
260                                         secs[i].curlen = secs[i].seclen;
261                                         secs[i].cont = 1;
262                                         ridx = i;
263                                         /* CRCのチェック */
264                                         if(checkcrc(&(secs[ridx]))) {
265                                                 return &(secs[i]); /* 取り合えず戻る */
266                                         }
267                                         goto retry; /* 残り処理へ */
268                                 }
269                                 /* セクション長-設定済み長 */
270                                 len = secs[i].seclen - secs[i].setlen;
271                                 if(len > secs[i].cur.payloadlen) {
272                                         /* 全体転送 */
273                                         memcpy(&secs[i].buf[secs[i].setlen], 
274                                                    secs[i].cur.payload, secs[i].cur.payloadlen);
275                                         secs[i].setlen += secs[i].cur.payloadlen;
276                                         continue;
277                                 }
278                                 /* セクション長の残りを設定 */
279                                 memcpy(&secs[i].buf[secs[i].setlen], secs[i].cur.payload, len);
280                                 secs[i].setlen  = secs[i].seclen;
281                                 secs[i].curlen += len;
282                                 secs[i].cont    = 1;
283                                 ridx = i;
284                                 /* CRCのチェック */
285                                 if(checkcrc(&(secs[ridx]))) {
286                                         return &(secs[i]);
287                                 }
288                                 goto retry; /* 残り処理へ */
289                         }
290                 }
291         }
292
293         //return NULL;
294 }
295
296 /* BonTest/TsStream.cppからのパクリ */
297 unsigned int CalcCrc(unsigned int crc, unsigned char *buf, int len) {
298         unsigned int c = crc;
299         int n;
300
301         static const unsigned int CrcTable[256] = {
302                 0x00000000UL, 0x04C11DB7UL, 0x09823B6EUL, 0x0D4326D9UL, 0x130476DCUL, 0x17C56B6BUL, 0x1A864DB2UL, 0x1E475005UL, 0x2608EDB8UL, 0x22C9F00FUL, 0x2F8AD6D6UL, 0x2B4BCB61UL, 0x350C9B64UL, 0x31CD86D3UL, 0x3C8EA00AUL, 0x384FBDBDUL,
303                 0x4C11DB70UL, 0x48D0C6C7UL, 0x4593E01EUL, 0x4152FDA9UL, 0x5F15ADACUL, 0x5BD4B01BUL, 0x569796C2UL, 0x52568B75UL, 0x6A1936C8UL, 0x6ED82B7FUL, 0x639B0DA6UL, 0x675A1011UL, 0x791D4014UL, 0x7DDC5DA3UL, 0x709F7B7AUL, 0x745E66CDUL,
304                 0x9823B6E0UL, 0x9CE2AB57UL, 0x91A18D8EUL, 0x95609039UL, 0x8B27C03CUL, 0x8FE6DD8BUL, 0x82A5FB52UL, 0x8664E6E5UL, 0xBE2B5B58UL, 0xBAEA46EFUL, 0xB7A96036UL, 0xB3687D81UL, 0xAD2F2D84UL, 0xA9EE3033UL, 0xA4AD16EAUL, 0xA06C0B5DUL,
305                 0xD4326D90UL, 0xD0F37027UL, 0xDDB056FEUL, 0xD9714B49UL, 0xC7361B4CUL, 0xC3F706FBUL, 0xCEB42022UL, 0xCA753D95UL, 0xF23A8028UL, 0xF6FB9D9FUL, 0xFBB8BB46UL, 0xFF79A6F1UL, 0xE13EF6F4UL, 0xE5FFEB43UL, 0xE8BCCD9AUL, 0xEC7DD02DUL,
306                 0x34867077UL, 0x30476DC0UL, 0x3D044B19UL, 0x39C556AEUL, 0x278206ABUL, 0x23431B1CUL, 0x2E003DC5UL, 0x2AC12072UL, 0x128E9DCFUL, 0x164F8078UL, 0x1B0CA6A1UL, 0x1FCDBB16UL, 0x018AEB13UL, 0x054BF6A4UL, 0x0808D07DUL, 0x0CC9CDCAUL,
307                 0x7897AB07UL, 0x7C56B6B0UL, 0x71159069UL, 0x75D48DDEUL, 0x6B93DDDBUL, 0x6F52C06CUL, 0x6211E6B5UL, 0x66D0FB02UL, 0x5E9F46BFUL, 0x5A5E5B08UL, 0x571D7DD1UL, 0x53DC6066UL, 0x4D9B3063UL, 0x495A2DD4UL, 0x44190B0DUL, 0x40D816BAUL,
308                 0xACA5C697UL, 0xA864DB20UL, 0xA527FDF9UL, 0xA1E6E04EUL, 0xBFA1B04BUL, 0xBB60ADFCUL, 0xB6238B25UL, 0xB2E29692UL, 0x8AAD2B2FUL, 0x8E6C3698UL, 0x832F1041UL, 0x87EE0DF6UL, 0x99A95DF3UL, 0x9D684044UL, 0x902B669DUL, 0x94EA7B2AUL,
309                 0xE0B41DE7UL, 0xE4750050UL, 0xE9362689UL, 0xEDF73B3EUL, 0xF3B06B3BUL, 0xF771768CUL, 0xFA325055UL, 0xFEF34DE2UL, 0xC6BCF05FUL, 0xC27DEDE8UL, 0xCF3ECB31UL, 0xCBFFD686UL, 0xD5B88683UL, 0xD1799B34UL, 0xDC3ABDEDUL, 0xD8FBA05AUL,
310                 0x690CE0EEUL, 0x6DCDFD59UL, 0x608EDB80UL, 0x644FC637UL, 0x7A089632UL, 0x7EC98B85UL, 0x738AAD5CUL, 0x774BB0EBUL, 0x4F040D56UL, 0x4BC510E1UL, 0x46863638UL, 0x42472B8FUL, 0x5C007B8AUL, 0x58C1663DUL, 0x558240E4UL, 0x51435D53UL,
311                 0x251D3B9EUL, 0x21DC2629UL, 0x2C9F00F0UL, 0x285E1D47UL, 0x36194D42UL, 0x32D850F5UL, 0x3F9B762CUL, 0x3B5A6B9BUL, 0x0315D626UL, 0x07D4CB91UL, 0x0A97ED48UL, 0x0E56F0FFUL, 0x1011A0FAUL, 0x14D0BD4DUL, 0x19939B94UL, 0x1D528623UL,
312                 0xF12F560EUL, 0xF5EE4BB9UL, 0xF8AD6D60UL, 0xFC6C70D7UL, 0xE22B20D2UL, 0xE6EA3D65UL, 0xEBA91BBCUL, 0xEF68060BUL, 0xD727BBB6UL, 0xD3E6A601UL, 0xDEA580D8UL, 0xDA649D6FUL, 0xC423CD6AUL, 0xC0E2D0DDUL, 0xCDA1F604UL, 0xC960EBB3UL,
313                 0xBD3E8D7EUL, 0xB9FF90C9UL, 0xB4BCB610UL, 0xB07DABA7UL, 0xAE3AFBA2UL, 0xAAFBE615UL, 0xA7B8C0CCUL, 0xA379DD7BUL, 0x9B3660C6UL, 0x9FF77D71UL, 0x92B45BA8UL, 0x9675461FUL, 0x8832161AUL, 0x8CF30BADUL, 0x81B02D74UL, 0x857130C3UL,
314                 0x5D8A9099UL, 0x594B8D2EUL, 0x5408ABF7UL, 0x50C9B640UL, 0x4E8EE645UL, 0x4A4FFBF2UL, 0x470CDD2BUL, 0x43CDC09CUL, 0x7B827D21UL, 0x7F436096UL, 0x7200464FUL, 0x76C15BF8UL, 0x68860BFDUL, 0x6C47164AUL, 0x61043093UL, 0x65C52D24UL,
315                 0x119B4BE9UL, 0x155A565EUL, 0x18197087UL, 0x1CD86D30UL, 0x029F3D35UL, 0x065E2082UL, 0x0B1D065BUL, 0x0FDC1BECUL, 0x3793A651UL, 0x3352BBE6UL, 0x3E119D3FUL, 0x3AD08088UL, 0x2497D08DUL, 0x2056CD3AUL, 0x2D15EBE3UL, 0x29D4F654UL,
316                 0xC5A92679UL, 0xC1683BCEUL, 0xCC2B1D17UL, 0xC8EA00A0UL, 0xD6AD50A5UL, 0xD26C4D12UL, 0xDF2F6BCBUL, 0xDBEE767CUL, 0xE3A1CBC1UL, 0xE760D676UL, 0xEA23F0AFUL, 0xEEE2ED18UL, 0xF0A5BD1DUL, 0xF464A0AAUL, 0xF9278673UL, 0xFDE69BC4UL,
317                 0x89B8FD09UL, 0x8D79E0BEUL, 0x803AC667UL, 0x84FBDBD0UL, 0x9ABC8BD5UL, 0x9E7D9662UL, 0x933EB0BBUL, 0x97FFAD0CUL, 0xAFB010B1UL, 0xAB710D06UL, 0xA6322BDFUL, 0xA2F33668UL, 0xBCB4666DUL, 0xB8757BDAUL, 0xB5365D03UL, 0xB1F740B4UL
318         };              
319
320         for (n = 0; n < len; n++) {
321                 c = (c << 8) ^ CrcTable[((((c >> 24) & 0xFF) ^ buf[n]) & 0XFF)];
322         }
323
324         return c;
325 }
326
327
328 int checkcrc(SECcache *secs) {
329
330         /* 07/07/2009 add: 異常状態回避のため */
331         /* セクション最大長を超えることなどあり得ないはずだが... */
332         if( secs->seclen > MAXSECLEN ){
333                 /* よく分からんので破棄してやる */
334                 return 0;
335         }
336
337         /* セクションの終りに置かれる4バイトのCRC32は、
338            CRC計算の結果0になるように設定される。
339            値が発生した場合は、エラーなので対象外にする */
340         if(CalcCrc(0xffffffffU, secs->buf, secs->seclen)) {
341 //              fprintf(stderr, "tblid:0x%x CRC error\n", secs->buf[0]);
342                 return 0;
343         }
344         return 1;
345 }
346