OSDN Git Service

fix no-audio bug.
[rec10/rec10-git.git] / jTsSplitter / trunk / src / jtssplitter / Mpeg2TSPacket.java
1 package jtssplitter;
2
3 import java.io.IOException;
4 import java.util.ArrayList;
5 import java.util.Arrays;
6 import java.util.logging.Level;
7 import java.util.logging.Logger;
8 import java.util.zip.CRC32;
9 import jtssplitter.data.PATData;
10 import jtssplitter.data.PMTData;
11 import jtssplitter.data.Descriptor;
12 import jtssplitter.data.EITData;
13 import jtssplitter.data.Video_stream_descriptor;
14 import java.io.ByteArrayInputStream;
15 import java.io.ByteArrayOutputStream;
16 /*
17  * To change this template, choose Tools | Templates
18  * and open the template in the editor.
19  */
20
21 /**
22  *
23  * @author gn64_jp
24  */
25 public class Mpeg2TSPacket {
26     //TSのヘッダーを格納する
27
28     public String header;
29     public String payload;
30     public String adaptation;
31     public byte[] header_byte;
32     public byte[] payload_byte;
33     public byte[] adaptation_byte;
34     public byte[] bPAT_payload = null;
35     //private ArrayList<TsDate> date=new ArrayList<TsDate>();
36     //date.add(new TsDate("Starter"))
37     public int type;//
38     private int starter;//0-7
39     private int transporterror;//本TSパケットの誤りを示す 1bit 8
40     private int payloadstart;//セクションの先頭バイトが入っているかどうか1bit 9
41     private int transport_priority;//1bit 10
42     private int PID = -1;//tsパケットの種類 13bit 11-23
43     private int transport_scrambled;//2bit 00is " not scrambled" 24-25
44     private int adaptation_field;//2bit 26-27 01:adaptation fieldなしでおk 10は絶対いる 11はペイロードはアダプテーションに続く00は予約
45     private int continuity_counter;//連続性(PIDごとの通し番号) 4bit 28-31
46     //ここからアダプテーションフィールド(最後まで)
47     private int adaptation_length;//8bit 32-39
48     private int discontinuity;//1bit
49     private int random_access;//1bit ランダムアクセスの開始場所となる
50     private int ES_priority;//1bit プライオリティ
51     private int five_flag;//5bit
52     private ArrayList<PATData> pat_list_now = new ArrayList<PATData>();//[0]:番組番号 [1]:PMT PID
53     private ArrayList<PATData> pat_list_all = new ArrayList<PATData>();
54     private ArrayList<PMTData> pmt_list = new ArrayList<PMTData>();//[0]番組番号 [1]テーブルID
55     private int pointer_field;//8bit adaptation fieldの次?
56     private String payload_s;
57     //ここからオプションフィールド
58     //PCR42 OPCR42 
59     //ここまでオプションフィールド
60     private int staffing_byte;//
61
62     public Mpeg2TSPacket() {
63     }
64
65     public int getPIDFirst(byte[] ts) {
66         byte[] b = new byte[2];
67         b[0] = ts[1];
68         b[1] = ts[2];
69         String s=byte2String2(b);
70         s=s.substring(3,16);
71         return Integer.parseInt(byte2String2(b).substring(3, 16), 2);
72     }
73     public int getPIDFirst_byte(byte[] ts) {
74         calc cal=new calc();
75         byte[] b = new byte[2];
76         b[0] = ts[1];
77         b[1] = ts[2];
78         return cal.byte2int(b,3,13);
79         //return cal.byte2int(ts,11,13);
80     }
81
82     public void readTS(byte[] ts) {
83         /**
84          * 188バイトのtsから読み出したbyteを与える
85          */
86         String tsbyte = byte2String2(ts);
87         //header = tsbyte.substring(0, 31);
88         payload = tsbyte.substring(32);
89         //starter = TSString2Int(tsbyte, 0, 8);
90         //transporterror = TSString2Int(tsbyte, 8, 1);
91         //payloadstart = TSString2Int(tsbyte, 9, 1);
92         //transport_priority = TSString2Int(tsbyte, 10, 1);
93         PID = TSString2Int(tsbyte, 11, 13);
94         adaptation_field = TSString2Int(tsbyte, 26, 2);
95         //continuity_counter = TSString2Int(tsbyte, 28, 4);
96         payload = "";
97         if (PID != 8191) {
98             if (adaptation_field == 1) {
99                 pointer_field = TSString2Int(tsbyte, 32, 8);
100                 payload = tsbyte.substring(40);
101             } else if (adaptation_field == 3) {
102                 adaptation_length = TSString2Int(tsbyte, 32, 8);
103                 if ((adaptation_length < 184) & ((tsbyte.length() - adaptation_length * 8) > 48)) {
104                     adaptation_length = adaptation_length * 8;
105                 }
106                 adaptation = tsbyte.substring(32, 40 + adaptation_length);
107                 pointer_field = TSString2Int(tsbyte, 40 + adaptation_length, 8);
108                 payload = tsbyte.substring(48 + adaptation_length);
109             }
110         }
111         if (PID == 0) {
112             pat_list_now = readPAT(payload);
113             pat_list_all.addAll(pat_list_now);
114         }
115         for (int i = 0; i < pat_list_now.size(); i++) {
116             if ((PID == pat_list_now.get(i).PID) && (PID != 0)) {
117                 pmt_list.addAll(readPMT(payload, pat_list_now.get(i).Program_TABLE));
118             }
119         }
120         tsbyte = "";
121     }
122
123     public void readTS_byte(byte[] ts) {
124         /**
125          * 188バイトのtsから読み出したbyteを与える
126          */
127         calc cal = new calc();
128         String tsbyte = byte2String2(ts);
129         //header = tsbyte.substring(0, 31);
130         payload = tsbyte.substring(32);
131         //starter = TSString2Int(tsbyte, 0, 8);
132         //transporterror = TSString2Int(tsbyte, 8, 1);
133         //payloadstart = TSString2Int(tsbyte, 9, 1);
134         //transport_priority = TSString2Int(tsbyte, 10, 1);
135         //PID = TSString2Int(tsbyte, 11, 13);
136         PID = cal.byte2int(ts, 11, 13);
137         adaptation_field = cal.byte2int(ts, 26, 2);
138         //continuity_counter = TSString2Int(tsbyte, 28, 4);
139         payload = "";
140         if (PID != 8191) {
141             if (adaptation_field == 1) {
142                 pointer_field = cal.byte2int(ts, 32, 8);
143                 payload_byte = cal.byte2subbyte(ts, 5, ts.length - 5);
144             } else if (adaptation_field == 3) {
145                 adaptation_length = cal.byte2int(ts, 32, 8);
146                 if ((adaptation_length < 184) & ((ts.length * 8 - adaptation_length * 8) > 48)) {
147                     adaptation_length = adaptation_length * 8;
148                 }
149                 adaptation_byte = cal.byte2subbyte(ts, 4, 1 + adaptation_length / 8);
150                 payload_byte = cal.byte2subbyte(ts, 6 + adaptation_length / 8, ts.length - 6 - adaptation_length / 8);
151                 pointer_field = cal.byte2int(ts, 40 + adaptation_length, 8);
152             }
153         }
154         if (payload_byte!=null){
155             if (PID == 0) {
156                 pat_list_now = readPAT_byte(payload_byte);
157                 pat_list_all.addAll(pat_list_now);
158             }
159             for (int i = 0; i < pat_list_now.size(); i++) {
160                 if ((PID == pat_list_now.get(i).PID) && (PID != 0)) {
161                     pmt_list.addAll(readPMT_byte(payload_byte, pat_list_now.get(i).Program_TABLE));
162                 }
163             }
164         }
165         tsbyte = "";
166     }
167
168     private ArrayList<PATData> readPAT(String payload_temp) {
169         /*
170          * payloadの文字列を入力して[intテーブル,int PID]のArrayListを返す。
171          */
172         int tableid;
173         int sectionlength;
174         ArrayList program_number = new ArrayList();
175         tableid = TSString2Int(payload_temp, 0, 8);
176         sectionlength = TSString2Int(payload_temp, 12, 12);//-40-32;
177         int patnum = sectionlength * 8 - 72;
178         patnum = patnum / 32;
179         byte[] test = String2Byte(payload_temp);
180         String stest = "";
181         for (int ij = 0; ij < test.length; ij++) {
182             int it = test[ij] & 0xFF;
183             String s = Integer.toBinaryString(it);
184             if (s.length() < 8) {
185                 for (int i2 = s.length(); i2 < 8; i2++) {
186                     s = "0" + s;
187                 }
188             }
189             stest = stest + s;
190         }
191         payload_temp = stest;
192         int nowbit = 64;
193         for (int i = 0; i < patnum; i++) {
194             PATData patd = new PATData();
195             patd.Program_TABLE = TSString2Int(payload_temp, 64 + 32 * i, 16);
196             patd.PID = TSString2Int(payload_temp, 32 * i + 64 + 19, 13);
197             program_number.add(patd);
198         }
199         return program_number;
200     }
201
202     private ArrayList<PATData> readPAT_byte(byte[] payload_temp) {
203         /*
204          * payloadの文字列を入力して[intテーブル,int PID]のArrayListを返す。
205          */
206         int tableid;
207         int sectionlength;
208         calc cal = new calc();
209         ArrayList program_number = new ArrayList();
210         tableid = cal.byte2int(payload_temp, 0, 8);
211         sectionlength = cal.byte2int(payload_temp, 12, 12);//-40-32;
212         int patnum = sectionlength * 8 - 72;
213         patnum = patnum / 32;
214         for (int i = 0; i < patnum; i++) {
215             PATData patd = new PATData();
216             patd.Program_TABLE = cal.byte2int(payload_temp, 64 + 32 * i, 16);
217             patd.PID = cal.byte2int(payload_temp, 32 * i + 64 + 19, 13);
218             program_number.add(patd);
219         }
220         return program_number;
221     }
222
223     private ArrayList<PMTData> readPMT(String payload_temp, int PAT_TABLE) {
224         ArrayList<PMTData> pmt_t = new ArrayList<PMTData>();
225         int tableid = TSString2Int(payload_temp, 0, 8);
226         int section_length = TSString2Int(payload_temp, 12, 12);
227         int pcr_pid = TSString2Int(payload_temp, 67, 13);
228         int program_info_length = TSString2Int(payload_temp, 84, 12);
229         boolean end = false;
230         int cur_point = 96 + program_info_length * 8;
231         if (cur_point > section_length * 8) {
232             end = true;
233         }
234         while (end != true) {
235             String gs = payload_temp.substring(cur_point + 8, cur_point + 11);
236             if (gs.matches("111") && payload_temp.length() > cur_point + 40) {
237                 int pmt_stream_type = TSString2Int(payload_temp, cur_point, 8);
238                 int elementary_PID = TSString2Int(payload_temp, cur_point + 11, 13);
239                 //System.out.println(Integer.toString(cur_point)+" :  "+Integer.toString(section_length*8));
240                 int es_length = TSString2Int(payload_temp, cur_point + 28, 12);
241                 /*if (pmt_stream_type==0x02){
242                 Descriptor des=new Descriptor();
243                 Object a=des.getDescriptors(payload_temp.substring(cur_point + 40,cur_point + 40+es_length*8));
244                 }else if(pmt_stream_type==0x0f){
245                 Descriptor des=new Descriptor();
246                 Object a=des.getDescriptors(payload_temp.substring(cur_point + 40,cur_point + 40+es_length*8));
247                 }*/
248
249
250                 PMTData pmtd = new PMTData();
251                 if ((pmt_stream_type == 0x02) || (pmt_stream_type == 0x0f)) {
252                     pmtd.Stream_Type = pmt_stream_type;
253                     pmtd.Program_Table = PAT_TABLE;
254                     pmtd.Elementary_PID = elementary_PID;
255                     pmtd.PCR_PID = pcr_pid;
256                     pmt_t.add(pmtd);
257                 }
258                 cur_point = cur_point + 40 + es_length * 8;
259                 //System.out.println(Integer.toString(cur_point)+" :  "+Integer.toString(section_length*8));
260                 if ((cur_point > section_length * 8 - 1) || (cur_point > payload_temp.length() - 11)) {
261                     end = true;
262                 }
263             } else {
264                 end = true;
265             }
266         }
267         return pmt_t;
268     }
269
270     private ArrayList<PMTData> readPMT_byte(byte[] payload_temp, int PAT_TABLE) {
271         ArrayList<PMTData> pmt_t = new ArrayList<PMTData>();
272         calc cal = new calc();
273         int tableid = cal.byte2int(payload_temp, 0, 8);
274         int section_length = cal.byte2int(payload_temp, 12, 12);
275         int pcr_pid = cal.byte2int(payload_temp, 67, 13);
276         int program_info_length = cal.byte2int(payload_temp, 84, 12);
277         boolean end = false;
278         int cur_point = 96 + program_info_length * 8;
279         if ((cur_point > section_length * 8 - 1) || (cur_point > payload_temp.length * 8 - 11)) {
280             end = true;
281         }
282         while (end != true) {
283             if (cal.byte2int(payload_temp, cur_point + 8, 3) == 7 && cal.byte2int(payload_temp, cur_point + 24, 4) == 15 && payload_temp.length * 8 > cur_point + 40) {
284                 int pmt_stream_type = cal.byte2int(payload_temp, cur_point, 8);
285                 int elementary_PID = cal.byte2int(payload_temp, cur_point + 11, 13);
286                 //System.out.println(Integer.toString(cur_point)+" :  "+Integer.toString(section_length*8));
287                 int es_length = cal.byte2int(payload_temp, cur_point + 28, 12);
288                 /*if (pmt_stream_type==0x02){
289                 Descriptor des=new Descriptor();
290                 Object a=des.getDescriptors(payload_temp.substring(cur_point + 40,cur_point + 40+es_length*8));
291                 }else if(pmt_stream_type==0x0f){
292                 Descriptor des=new Descriptor();
293                 Object a=des.getDescriptors(payload_temp.substring(cur_point + 40,cur_point + 40+es_length*8));
294                 }*/
295
296
297                 PMTData pmtd = new PMTData();
298                 if ((pmt_stream_type == 0x02) || (pmt_stream_type == 0x0f)) {
299                     pmtd.Stream_Type = pmt_stream_type;
300                     pmtd.Program_Table = PAT_TABLE;
301                     pmtd.Elementary_PID = elementary_PID;
302                     pmtd.PCR_PID = pcr_pid;
303                     pmt_t.add(pmtd);
304                 }
305                 cur_point = cur_point + 40 + es_length * 8;
306                 //System.out.println(Integer.toString(cur_point)+" :  "+Integer.toString(section_length*8));
307                 if ((cur_point > section_length * 8 - 1) || (cur_point > payload_temp.length * 8 - 11)) {
308                     end = true;
309                 }
310             } else {
311                 end = true;
312             }
313         }
314         return pmt_t;
315     }
316
317     public ArrayList<EITData> readEIT(byte[] ts) {
318         String payload_temp = getPayload(ts);
319         int tableid = TSString2Int(payload_temp, 0, 8);
320         int section_length = TSString2Int(payload_temp, 12, 12);
321         int program_number = TSString2Int(payload_temp, 24, 16);
322         boolean current_next_indicator = (TSString2Int(payload_temp, 47, 1) == 1);
323         int section_number = TSString2Int(payload_temp, 48, 8);
324         int curpoint = 112;
325         ArrayList<EITData> ret = new ArrayList<EITData>();
326         while (curpoint < 24 + section_length * 8 - 32) {
327             EITData eitd = new EITData();
328             eitd.current_newt_indicator = current_next_indicator;
329             eitd.event_id = TSString2Int(payload_temp, curpoint, 16);
330             eitd.program_number = program_number;
331             eitd.section_number = section_number;
332             int des_len = TSString2Int(payload_temp, curpoint + 84, 12);
333             Descriptor des = new Descriptor();
334             eitd.descriptors = des.getDescriptors(payload_temp.substring(curpoint + 96, curpoint + 84 + des_len * 8));
335             ret.add(eitd);
336             curpoint = curpoint + 84 + des_len * 8;
337         }
338         return ret;
339     }
340
341     private int TSString2Int(String s, int begin, int length) {
342         String st = s.substring(begin, begin + length);
343         int i = Integer.parseInt(st, 2);
344         return i;
345     }
346
347     public byte[] splitPAT_byte(byte[] ts, int p_table) {
348         /**
349          *
350          * p_tableで指定された番組テーブルのみを取り出すPATを作る。
351          */
352         int matchnum = 0;
353         byte[] tbb = new byte[ts.length - 4];
354         System.arraycopy(ts, 4, tbb, 0, tbb.length);
355         if (bPAT_payload != null) {
356             if (Arrays.equals(tbb, bPAT_payload)) {
357                 byte[] retb = new byte[188];
358                 System.arraycopy(ts, 0, retb, 0, 4);
359                 System.arraycopy(bPAT_payload, 0, retb, 4, 184);
360                 return retb;
361             }
362         }
363         calc cal = new calc();
364         String tsbyte = byte2String2(ts);
365         String tsheader = "";
366         header_byte = cal.byte2subbyte(ts, 0, 4);
367         byte[] pointer_byte=cal.byte2subbyte(ts, 4, 1);
368         payload_byte = cal.byte2subbyte(ts, 4, ts.length - 4);
369         starter = cal.byte2int(ts, 0, 8);
370         transporterror = cal.byte2int(ts, 8, 1);
371         payloadstart = cal.byte2int(ts, 9, 1);
372         transport_priority = cal.byte2int(ts, 10, 1);
373         PID = cal.byte2int(ts, 11, 13);
374         adaptation_field = cal.byte2int(ts, 26, 2);
375         continuity_counter = cal.byte2int(ts, 28, 4);
376         int adaptation_length_t = cal.byte2int(ts, 32, 8);
377         if (PID != 8191) {
378             if (adaptation_field == 1) {
379                 pointer_field = cal.byte2int(ts, 32, 8);
380                 payload_byte = cal.byte2subbyte(ts, 5, ts.length - 5);
381             } else if (adaptation_field == 3) {
382                 if (adaptation_length_t < 188) {
383                     adaptation_length_t = adaptation_length_t * 8;
384                 }
385                 payload_byte = cal.byte2subbyte(ts, 6 + adaptation_length_t / 8, ts.length - 6 - adaptation_length_t / 8);
386             }
387         }
388         if (PID == 0) {
389             //showPAT(tsbyte);
390             payload_byte = makePAT_byte(pointer_byte,payload_byte, p_table);
391             /*byte[] bpayload=cal.String2Byte(makePAT(cal.byte2String2(header_byte), cal.byte2String2(payload_byte), p_table));
392             if (!Arrays.equals(payload_byte, bpayload)){
393                 System.out.println("not match");
394             }else{
395                 System.out.println("match");
396             }*/
397             bPAT_payload = payload_byte;
398         }
399         ByteArrayOutputStream baos = new ByteArrayOutputStream(ts.length);
400         baos.write(header_byte, 0, header_byte.length);
401         baos.write(pointer_byte,0,pointer_byte.length);
402         baos.write(payload_byte, 0, payload_byte.length);
403         return baos.toByteArray();
404     }
405
406     public byte[] splitPAT(byte[] ts, int p_table) {
407         /**
408          *
409          * p_tableで指定された番組テーブルのみを取り出すPATを作る。
410          */
411         int matchnum = 0;
412         byte[] tbb = new byte[ts.length - 4];
413         System.arraycopy(ts, 4, tbb, 0, tbb.length);
414         if (bPAT_payload != null) {
415             if (Arrays.equals(tbb, bPAT_payload)) {
416                 byte[] retb = new byte[188];
417                 System.arraycopy(ts, 0, retb, 0, 4);
418                 System.arraycopy(bPAT_payload, 0, retb, 4, 184);
419                 return retb;
420             }
421         }
422         String tsbyte = byte2String2(ts);
423         String tsheader = "";
424         header = tsbyte.substring(0, 31);
425         payload = tsbyte.substring(32);
426         starter = TSString2Int(tsbyte, 0, 8);
427         transporterror = TSString2Int(tsbyte, 8, 1);
428         payloadstart = TSString2Int(tsbyte, 9, 1);
429         transport_priority = TSString2Int(tsbyte, 10, 1);
430         PID = TSString2Int(tsbyte, 11, 13);
431         adaptation_field = TSString2Int(tsbyte, 26, 2);
432         continuity_counter = TSString2Int(tsbyte, 28, 4);
433         int adaptation_length_t = TSString2Int(tsbyte, 32, 8);
434         payload = "";
435         if (PID != 8191) {
436             if (adaptation_field == 1) {
437                 pointer_field = TSString2Int(tsbyte, 32, 8);
438                 tsheader = tsbyte.substring(0, 40);
439                 payload = tsbyte.substring(40);
440             } else if (adaptation_field == 3) {
441                 if (adaptation_length_t < 188) {
442                     adaptation_length_t = adaptation_length_t * 8;
443                 }
444                 tsheader = tsbyte.substring(0, 48 + adaptation_length_t);
445                 payload = tsbyte.substring(48 + adaptation_length_t);
446             }
447         }
448         if (PID == 0) {
449             //showPAT(tsbyte);
450             payload = makePAT(tsheader, payload, p_table);
451             byte[] retb = String2Byte(payload);
452             bPAT_payload = retb;
453         }
454         String rets = tsheader + payload;
455         return String2Byte(rets);
456     }
457
458     private String makePAT(String tsheader, String payload_temp, int Table) {
459         int sectionlength;
460         StringBuffer sb = new StringBuffer();
461         //ArrayList program_number = new ArrayList();
462         //System.out.println("Pay:"+payload_temp);
463         //int tableid = TSString2Int(payload_temp, 0, 8);
464         sectionlength = TSString2Int(payload_temp, 12, 12);//-40-32;
465         int patnum = sectionlength * 8 - 72;
466         //String rets = "";//="00000000";//pointer field
467         //rets = rets + payload_temp.substring(0, 12);//セクション長の前まで
468         sb.append(payload_temp.substring(0, 12));
469         int new_section_length = (2 * 32 + 32 + 40) / 8;
470         sb.append(Int2String(new_section_length, 12));
471         sb.append(payload_temp.substring(24, 64));
472         //rets = rets + Int2String(new_section_length, 12);
473         //rets = rets + payload_temp.substring(24, 64);//ループ前まで
474         String loop = "";
475         patnum = patnum / 32;
476         //String crcnow = payload_temp.substring(64 + 32 * patnum, 64 + 32 * patnum + 32);
477         for (int i = 0; i < patnum; i++) {
478             int[] pat = new int[2];
479             pat[0] = TSString2Int(payload_temp, 64 + 32 * i, 16);
480             pat[1] = TSString2Int(payload_temp, 32 * i + 64 + 19, 13);
481             if (pat[0] == 0) {
482                 sb.append(payload_temp.substring(64 + 32 * i, 95 + 32 * i + 1));
483                 //loop = loop+payload_temp.substring(64 + 32 * i, 95 + 32 * i + 1);
484             } else if (pat[0] == Table) {
485                 sb.append(payload_temp.substring(64 + 32 * i, 95 + 32 * i + 1));
486                 //loop = loop + payload_temp.substring(64 + 32 * i, 95 + 32 * i + 1);
487                 i = patnum;
488             }
489         }
490         String s2 = tsheader.substring(tsheader.length() - 8);
491         s2 = s2 + sb.toString();
492         String s = getCRC32(s2);
493         sb.append(s);
494         //rets = rets + s;
495         int ill3 = payload_temp.length() - sb.length();
496         for (int ir = 0; ir < ill3; ir++) {
497             sb.append("1");
498             //rets = rets + "1";
499         }
500         return sb.toString();
501     }
502
503     private byte[] makePAT_byte(byte[] pointer_field, byte[] payload_temp, int Table) {
504         ByteArrayOutputStream baos = new ByteArrayOutputStream(payload_temp.length);
505         int sectionlength;
506         calc cal = new calc();
507         sectionlength = cal.byte2int(payload_temp, 12, 12); //-40-32;
508         int patnum = sectionlength * 8 - 72;
509         baos.write(payload_temp, 0, 1);
510         int new_section_length = (2 * 32 + 32 + 40) / 8;
511         baos.write(cal.joinByte((byte) cal.byte2int(payload_temp, 8, 4), (byte) (new_section_length & 0xF00), 4));
512         baos.write((byte) (new_section_length & 0xFF));
513         baos.write(payload_temp, 3, 5);
514         patnum = patnum / 32;
515         int nowt = 8;
516         for (int i = 0; i < patnum; i++) {
517             int[] pat = new int[2];
518             pat[0] = cal.byte2int(payload_temp, 64 + 32 * i, 16);
519             pat[1] = cal.byte2int(payload_temp, 32 * i + 64 + 19, 13);
520             if (pat[0] == 0) {
521                 baos.write(payload_temp, 8+4*i, 4);
522                 nowt = nowt + 4;
523             } else if (pat[0] == Table) {
524                 baos.write(payload_temp, 8+4*i, 4);
525                 nowt = nowt + 4;
526                 i = patnum;
527             }
528         }
529         ByteArrayOutputStream baoscrc=new ByteArrayOutputStream(nowt+1);
530         baoscrc.write(pointer_field[0]);
531         baoscrc.write(baos.toByteArray(), 0, baos.size());
532         byte[] crc = getCRC32_byte(baoscrc.toByteArray(), 1);
533         baos.write(crc, 0, crc.length);
534         int ill3 = payload_temp.length - baos.size();
535         for (int ir = 0; ir < ill3; ir++) {
536             baos.write(0xFF);
537             }
538         return baos.toByteArray();
539     }
540
541     private String getCRC32(String s) {
542         return getCRC32(String2Byte(s), 1);
543     }
544
545     private String getCRC32(byte[] data, int offset) {
546         // x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
547         int[] g = {1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1};
548         int[] shift_reg = new int[32];
549         long crc = 0;
550         byte crc32[] = new byte[4];
551
552         // Initialize shift register's to '1'
553         java.util.Arrays.fill(shift_reg, 1);
554
555         // Calculate nr of data bits, summa of bits
556         int nr_bits = (data.length - offset) * 8;
557
558         for (int bit_count = 0, bit_in_byte = 0, data_bit; bit_count < nr_bits; bit_count++) {
559             // Fetch bit from bitstream
560             data_bit = (data[offset] & 0x80 >>> (bit_in_byte++)) != 0 ? 1 : 0;
561
562             if ((bit_in_byte &= 7) == 0) {
563                 offset++;
564             }
565
566             // Perform the shift and modula 2 addition
567             data_bit ^= shift_reg[31];
568
569             for (int i = 31; i > 0; i--) {
570                 shift_reg[i] = g[i] == 1 ? (shift_reg[i - 1] ^ data_bit) : shift_reg[i - 1];
571             }
572
573             shift_reg[0] = data_bit;
574         }
575
576         for (int i = 0; i < 32; i++) {
577             crc = ((crc << 1) | (shift_reg[31 - i]));
578         }
579
580         for (int i = 0; i < 4; i++) {
581             crc32[i] = (byte) (0xFF & (crc >>> ((3 - i) * 8)));
582         }
583         String s = Long2String(crc, 32);
584         return s;
585     }
586
587     private byte[] getCRC32_byte(byte[] data, int offset) {
588         // x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
589         int[] g = {1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1};
590         int[] shift_reg = new int[32];
591         long crc = 0;
592         byte crc32[] = new byte[4];
593
594         // Initialize shift register's to '1'
595         java.util.Arrays.fill(shift_reg, 1);
596
597         // Calculate nr of data bits, summa of bits
598         int nr_bits = (data.length - offset) * 8;
599
600         for (int bit_count = 0, bit_in_byte = 0, data_bit; bit_count < nr_bits; bit_count++) {
601             // Fetch bit from bitstream
602             data_bit = (data[offset] & 0x80 >>> (bit_in_byte++)) != 0 ? 1 : 0;
603
604             if ((bit_in_byte &= 7) == 0) {
605                 offset++;
606             }
607
608             // Perform the shift and modula 2 addition
609             data_bit ^= shift_reg[31];
610
611             for (int i = 31; i > 0; i--) {
612                 shift_reg[i] = g[i] == 1 ? (shift_reg[i - 1] ^ data_bit) : shift_reg[i - 1];
613             }
614
615             shift_reg[0] = data_bit;
616         }
617
618         for (int i = 0; i < 32; i++) {
619             crc = ((crc << 1) | (shift_reg[31 - i]));
620         }
621
622         for (int i = 0; i < 4; i++) {
623             crc32[i] = (byte) (0xFF & (crc >>> ((3 - i) * 8)));
624         }
625         return crc32;
626     }
627
628     private String addzero(int num) {
629         switch (num) {
630             case 0:
631                 return "";
632             case 1:
633                 return "0";
634             case 2:
635                 return "00";
636             case 3:
637                 return "000";
638             case 4:
639                 return "0000";
640             case 5:
641                 return "00000";
642             case 6:
643                 return "000000";
644             case 7:
645                 return "0000000";
646             case 8:
647                 return "00000000";
648             default:
649                 StringBuffer sb = new StringBuffer();
650                 for (int i = 0; i < num; i++) {
651                     sb.append("0");
652                 }
653                 return sb.toString();
654         }
655     }
656
657     private String byte2String(byte[] b) {
658         StringBuffer sb = new StringBuffer(8 * b.length);
659         for (int i = 0; i < b.length; i++) {
660             StringBuffer sb2 = new StringBuffer(8);
661             sb2.append(Integer.toBinaryString(b[i] & 0xFF));
662             if ((sb2.length() < 8) & (sb2.length() > 0)) {
663                 sb2.insert(0, addzero(8 - sb2.length()));
664             }
665             sb.append(sb2);
666         }
667         return sb.toString();
668     }
669
670     private String byte2String2(byte[] b) {
671         int bl = b.length;
672         bl = bl - bl % 8;
673         bl = bl / 8;
674         StringBuffer sb = new StringBuffer();
675         for (int i = 0; i < bl; i++) {
676             long retl = 0;
677             for (int j = 0; j < 8; j++) {
678                 retl = retl << 8;
679                 int ri = b[i * 8 + j] & 0xFF;
680                 retl = retl + ri;
681             }
682             sb.append(Long2String(retl, 64));
683         }
684         int bl2 = b.length % 8;
685         bl2 = (bl2 - bl2 % 4) / 4;
686         for (int i = 0; i < bl2; i++) {
687             int reti = 0;
688             for (int j = 0; j < 4; j++) {
689                 reti = reti << 8;
690                 reti = reti + (b[bl * 8 + 4 * i + j] & 0xFF);
691             }
692             sb.append(Int2String(reti, 32));
693         }
694         for (int i = 0; i < (b.length % 8) % 4; i++) {
695             sb.append(Int2String(b[bl * 8 + bl2 * 4 + i] & 0xFF, 8));
696         }
697         return sb.toString();
698     }
699
700     private String byte2HexString(byte[] b) {
701         String ret = "";
702         for (int i = 0; i < b.length; i++) {
703             ret = ret + Integer.toHexString(b[i] & 0xFF);
704         }
705         return ret;
706     }
707
708     private boolean testCRC(String base, String ans, int begin_n, int end_n) {
709         String tests1 = base.substring(begin_n, end_n);
710         byte[] test1 = String2Byte(tests1);
711         int t32 = 0;
712         int begin = begin_n;
713         int end = end_n;
714         byte[] test2 = String2Byte(ans);
715         String tests2 = ans;
716         CRC32 crc = new CRC32();
717         crc.reset();
718         crc.update(test1);
719
720         if (crc.getValue() == Long.parseLong(tests2, 2)) {
721             System.out.print("正解が出ました。\n");
722             System.out.print("begin : " + Integer.toString(begin_n) + " end : " + Integer.toString(end_n));
723
724             return true;
725         }
726         if (Long.parseLong(getCRC32(test1, 1), 2) == Long.parseLong(tests2, 2)) {
727             System.out.print("正解が出ました。(getCRC)\n");
728             System.out.print("begin : " + Integer.toString(begin_n) + " end : " + Integer.toString(end_n));
729             return true;
730         }
731         if (Long.parseLong(getCRC32(test1, 1), 2) == Long.parseLong(tests2, 2)) {
732             System.out.print("正解が出ました。(getCRC_2)\n");
733             System.out.println("begin : " + Integer.toString(begin_n) + " end : " + Integer.toString(end_n));
734             showPAT(base);
735             System.out.println("begin : " + base.substring(begin_n, begin_n + 32));
736             System.out.println("near : " + base.substring(end_n - 32, end_n));
737             System.out.println("near2: " + base.substring(end_n, end_n + 32));
738             System.out.println("near3: " + base.substring(end_n + 32, end_n + 64));
739             return true;
740         }
741         return false;
742     }
743
744     private String Int2String(int num, int length) {
745         String ret = Integer.toBinaryString(num);
746         if (ret.length() < length) {
747             int it = length - ret.length();
748             for (int i = 0; i < it; i++) {
749                 ret = "0" + ret;
750             }
751         }
752         return ret;
753     }
754
755     private String Long2String(long num, int length) {
756         String ret = Long.toBinaryString(num);
757         if (ret.length() < length) {
758             int it = length - ret.length();
759             for (int i = 0; i < it; i++) {
760                 ret = "0" + ret;
761             }
762         }
763         return ret;
764     }
765
766     private byte[] String2Byte(String ts) {
767         //StringBuffer sb=new StringBuffer(ts);
768         int len = ts.length() - ts.length() % 8;
769         len = len / 8;
770         byte[] ret = new byte[len];
771         for (int i = 0; i < len; i++) {
772             String tet = ts.substring(i * 8, i * 8 + 8);
773             int itt = TSString2Int(tet, 0, 8);
774             ret[i] = (byte) itt;
775         }
776         return ret;
777     }
778
779     public ArrayList<PATData> getPAT() {
780         return pat_list_all;
781     }
782
783     public void setPAT(ArrayList pat) {
784         pat_list_now = pat;
785         pat_list_all = pat;
786     }
787
788     public ArrayList<PMTData> getPMT() {
789         return pmt_list;
790     }
791
792     public void setPMT(ArrayList pmt) {
793         pmt_list = pmt;
794     }
795
796     public int getPID() {
797         return PID;
798     }
799
800     public String getPayload(byte[] ts) {
801         /**
802          * 188バイトのtsから読み出したbyteを与える
803          */
804         String tsbyte = byte2String2(ts);
805         //header = tsbyte.substring(0, 31);
806         String ret_payload = "";
807         //starter = TSString2Int(tsbyte, 0, 8);
808         //transporterror = TSString2Int(tsbyte, 8, 1);
809         //payloadstart = TSString2Int(tsbyte, 9, 1);
810         //transport_priority = TSString2Int(tsbyte, 10, 1);
811         int pid = TSString2Int(tsbyte, 11, 13);
812         int af = TSString2Int(tsbyte, 26, 2);
813         //continuity_counter = TSString2Int(tsbyte, 28, 4);
814         if (pid != 8191) {
815             if (af == 1) {
816                 ret_payload = tsbyte.substring(40);
817             } else if (af == 3) {
818                 int al = TSString2Int(tsbyte, 32, 8);
819                 if ((al < 184) & ((tsbyte.length() - al * 8) > 48)) {
820                     al = al * 8;
821                 }
822                 ret_payload = tsbyte.substring(48 + al);
823             }
824         }
825         return ret_payload;
826     }
827
828     public byte[] getPayload_byte(byte[] ts) {
829         /**
830          * 188バイトのtsから読み出したbyteを与える
831          */
832         calc cal = new calc();
833         String tsbyte = byte2String2(ts);
834         //header = tsbyte.substring(0, 31);
835         byte[] retb = null;
836         //starter = TSString2Int(tsbyte, 0, 8);
837         //transporterror = TSString2Int(tsbyte, 8, 1);
838         //payloadstart = TSString2Int(tsbyte, 9, 1);
839         //transport_priority = TSString2Int(tsbyte, 10, 1);
840         int pid = cal.byte2int(ts, 11, 13);
841         int af = cal.byte2int(ts, 26, 2);
842         //continuity_counter = TSString2Int(tsbyte, 28, 4);
843         if (pid != 8191) {
844             if (af == 1) {
845                 retb = cal.byte2subbyte(ts, 5, ts.length - 5);
846             } else if (af == 3) {
847                 int al = cal.byte2int(ts, 32, 8);
848                 if ((al < 184) & ((ts.length * 8 - al * 8) > 48)) {
849                     al = al * 8;
850                 }
851                 retb = cal.byte2subbyte(ts, 6 + al / 8, ts.length - 6 - al / 8);
852             }
853         }
854         return retb;
855     }
856
857     public ArrayList<PMTData> readPMT(byte[] ts, int TABLE_NUM) {
858         String payloadt = getPayload(ts);
859         return readPMT(payloadt, TABLE_NUM);
860     }
861
862     public ArrayList<PMTData> readPMTglobal_byte(byte[] ts, int TABLE_NUM) {
863         byte[] payloadt = getPayload_byte(ts);
864         return readPMT_byte(payloadt, TABLE_NUM);
865     }
866
867     public void showPAT(String ts) {
868         System.out.println("先頭:" + ts.substring(0, 8));
869         System.out.println("" + ts.substring(8, 11));
870         System.out.println("PID:" + ts.substring(11, 24));
871         System.out.println("" + ts.substring(24, 32));
872         System.out.println("Adap_Len:" + ts.substring(32, 40));
873         System.out.println("TableID:" + ts.substring(40, 48));
874         System.out.println("" + ts.substring(48, 52));
875         System.out.println("len : " + ts.substring(52, 64) + "//" + Integer.toString(Integer.parseInt(ts.substring(52, 64), 2)));
876         System.out.println("TS ID:" + ts.substring(64, 80));
877         System.out.println("11:" + ts.substring(80, 82));
878         System.out.println("" + ts.substring(82, 104));
879         for (int i = 0; i < 10; i++) {
880             System.out.println(Integer.toString(i) + " : " + ts.substring(104 + 32 * i, 136 + 32 * i));
881         }
882         System.out.println("Length:" + Integer.toString(ts.length()));
883
884
885
886     }
887 }