OSDN Git Service

make it faster.
[rec10/rec10-git.git] / jTsSplitter / trunk / src / jtssplitter / Mpeg2TSPacket.java
1 package jtssplitter;
2
3 import java.util.ArrayList;
4 import java.util.zip.CRC32;
5 /*
6  * To change this template, choose Tools | Templates
7  * and open the template in the editor.
8  */
9
10 /**
11  *
12  * @author Administrator
13  */
14 public class Mpeg2TSPacket {
15
16     public String header;
17     public String payload;
18     public String adaptation;
19     //private ArrayList<TsDate> date=new ArrayList<TsDate>();
20     //date.add(new TsDate("Starter"))
21     public int type;//
22     private int starter;//0-7
23     private int transporterror;//本TSパケットの誤りを示す 1bit 8
24     private int payloadstart;//セクションの先頭バイトが入っているかどうか1bit 9
25     private int transport_priority;//1bit 10
26     private int PID = -1;//tsパケットの種類 13bit 11-23
27     private int transport_scrambled;//2bit 00is " not scrambled" 24-25
28     private int adaptation_field;//2bit 26-27 01:adaptation fieldなしでおk 10は絶対いる 11はペイロードはアダプテーションに続く00は予約
29     private int continuity_counter;//連続性(PIDごとの通し番号) 4bit 28-31
30     //ここからアダプテーションフィールド(最後まで)
31     private int adaptation_length;//8bit 32-39
32     private int discontinuity;//1bit
33     private int random_access;//1bit ランダムアクセスの開始場所となる
34     private int ES_priority;//1bit プライオリティ
35     private int five_flag;//5bit
36     private ArrayList pat_list_now = new ArrayList();//[0]:番組番号 [1]:PMT PID
37     private ArrayList pat_list_all = new ArrayList();
38     private ArrayList pmt_list = new ArrayList();//[0]番組番号 [1]テーブルID
39     private int pointer_field;//8bit adaptation fieldの次?
40     private String payload_s;
41     //ここからオプションフィールド
42     //PCR42 OPCR42 
43     //ここまでオプションフィールド
44     private int staffing_byte;//
45
46     public Mpeg2TSPacket() {
47     }
48
49     public void readTS(byte[] ts) {
50         /**
51          * 188バイトのtsから読み出したbyteを与える
52          */
53         String tsbyte = byte2String(ts);
54         //header = tsbyte.substring(0, 31);
55         payload = tsbyte.substring(32);
56         //starter = TSString2Int(tsbyte, 0, 8);
57         //transporterror = TSString2Int(tsbyte, 8, 1);
58         //payloadstart = TSString2Int(tsbyte, 9, 1);
59         //transport_priority = TSString2Int(tsbyte, 10, 1);
60         PID = TSString2Int(tsbyte, 11, 13);
61         adaptation_field = TSString2Int(tsbyte, 26, 2);
62         //continuity_counter = TSString2Int(tsbyte, 28, 4);
63         payload = "";
64         if (PID != 8191) {
65             if (adaptation_field == 1) {
66                 pointer_field = TSString2Int(tsbyte, 32, 8);
67                 payload = tsbyte.substring(40);
68             } else if (adaptation_field == 3) {
69                 adaptation_length = TSString2Int(tsbyte, 32, 8);
70                 if (adaptation_length < 184) {
71                     adaptation_length = adaptation_length * 8;
72                 }
73                 //System.out.println(adaptation_length);
74                 adaptation = tsbyte.substring(32, 40 + adaptation_length);
75                 pointer_field = TSString2Int(tsbyte, 40 + adaptation_length, 8);
76                 payload = tsbyte.substring(48 + adaptation_length);
77             }
78         }
79         if (PID == 0) {
80             //System.out.print("Pointer field ? : "+pointer_field+"\n");
81             pat_list_now = readPAT(payload);
82             pat_list_all.addAll(pat_list_now);
83             //System.out.print("ここから変更済み\n");
84             //readPAT(changePAT(payload));
85         }
86         for (int i = 0; i < pat_list_now.size(); i++) {
87             int[] pid_temp = (int[]) pat_list_now.get(i);
88             if ((PID == pid_temp[1]) && (PID != 0)) {
89                 //System.out.println("PMT PID : 0x"+Integer.toHexString(PID));
90                 pmt_list.addAll(readPMT(payload, pid_temp[0]));
91             }
92         }
93         tsbyte = "";
94     }
95
96     private ArrayList readPAT(String payload_temp) {
97         /*
98          * payloadの文字列を入力して[intテーブル,int PID]のArrayListを返す。
99          */
100         int tableid;
101         int sectionlength;
102         ArrayList program_number = new ArrayList();
103         tableid = TSString2Int(payload_temp, 0, 8);
104         sectionlength = TSString2Int(payload_temp, 12, 12);//-40-32;
105         //int patnum=sectionlength*8-32;
106         int patnum = sectionlength * 8 - 72;
107         patnum = patnum / 32;
108         byte[] test = Stream2Byte(payload_temp);
109         String stest = "";
110         for (int ij = 0; ij < test.length; ij++) {
111             int it = test[ij] & 0xFF;
112             String s = Integer.toBinaryString(it);
113             if (s.length() < 8) {
114                 for (int i2 = s.length(); i2 < 8; i2++) {
115                     s = "0" + s;
116                 }
117             }
118             stest = stest + s;
119         }
120         payload_temp = stest;
121         int nowbit = 64;
122         //System.out.print(Integer.toString(patnum)+"\n");
123         for (int i = 0; i < patnum; i++) {
124             //System.out.print(payload_temp.substring(64+32*i,95+32*i+1)+"\n");
125             int[] pat = new int[2];
126             pat[0] = TSString2Int(payload_temp, 64 + 32 * i, 16);
127             pat[1] = TSString2Int(payload_temp, 32 * i + 64 + 19, 13);
128             //System.out.print("TABLE : "+Integer.toString(pat[0])+"\n");
129             //System.out.print("PMT PID : "+Integer.toString(pat[1])+"\n");
130             program_number.add(pat);
131         }
132         //System.out.print("TABLEID : "+Integer.toString(tableid)+" LENGTH = "+Integer.toString(sectionlength)+"\n");
133         //System.out.print(Integer.toBinaryString(TSString2Int(payload_temp,65,32))+"\n");
134         return program_number;
135     }
136
137     private ArrayList readPMT(String payload_temp, int PAT_TABLE) {
138         ArrayList pmt_t = new ArrayList();
139         int tableid = TSString2Int(payload_temp, 0, 8);
140         int section_length = TSString2Int(payload_temp, 12, 12);
141         int program_info_length = TSString2Int(payload_temp, 84, 12);
142         boolean end = false;
143         int cur_point = 96 + program_info_length * 8;
144         while (end != true) {
145             int pmt_stream_type = TSString2Int(payload_temp, cur_point, 8);
146             int elementary_PID = TSString2Int(payload_temp, cur_point + 11, 13);
147             int es_length = TSString2Int(payload_temp, cur_point + 28, 12);
148             int[] pmt = new int[3];
149             pmt[0] = pmt_stream_type;
150             pmt[1] = elementary_PID;
151             pmt[2] = PAT_TABLE;
152             pmt_t.add(pmt);
153             System.out.print("Table : 0x" + Integer.toHexString(tableid) + " | Stream_type : 0x" + Integer.toHexString(pmt_stream_type) + " |elementary PID : 0x" + Integer.toHexString(elementary_PID) + "\n");
154             cur_point = cur_point + 40 + es_length * 8;
155             if (cur_point > section_length * 8) {
156                 end = true;
157             }
158         }
159         return pmt_t;
160     }
161
162     private int TSString2Int(String s, int begin, int length) {
163         //System.out.print(Integer.toString(begin)+"//"+Integer.toString(length)+"\n");
164         String st = s.substring(begin, begin + length);
165         int i = Integer.parseInt(st, 2);
166         return i;
167     }
168
169     public byte[] splitPAT(byte[] ts, int p_table) {
170         /**
171          * 
172          * p_tableで指定された番組テーブルのみを取り出すPATを作る。
173          */
174         /*String tsbyte=new String();
175         for (int i=0;i<188;i++){
176         int it=ts[i]& 0xFF;
177         String s=Integer.toBinaryString(it);
178         if ((s.length()<8)&(s.length()>0)){
179         for (int i2=s.length();i2<8;i2++){
180         s="0"+s;
181         }
182         }
183         tsbyte=tsbyte+s;
184         }*/
185         String tsbyte = byte2String(ts);
186         //System.out.println("Base");
187         //(tsbyte);
188         String tsheader = "";
189         header = tsbyte.substring(0, 31);
190         payload = tsbyte.substring(32);
191         starter = TSString2Int(tsbyte, 0, 8);
192         transporterror = TSString2Int(tsbyte, 8, 1);
193         payloadstart = TSString2Int(tsbyte, 9, 1);
194         transport_priority = TSString2Int(tsbyte, 10, 1);
195         PID = TSString2Int(tsbyte, 11, 13);
196         adaptation_field = TSString2Int(tsbyte, 26, 2);
197         continuity_counter = TSString2Int(tsbyte, 28, 4);
198         int adaptation_length_t = TSString2Int(tsbyte, 32, 8);
199         payload = "";
200         if (PID != 8191) {
201             if (adaptation_field == 1) {
202                 pointer_field = TSString2Int(tsbyte, 32, 8);
203                 tsheader = tsbyte.substring(0, 40);
204                 payload = tsbyte.substring(40);
205             } else if (adaptation_field == 3) {
206                 if (adaptation_length_t < 188) {
207                     adaptation_length_t = adaptation_length_t * 8;
208                 }
209                 tsheader = tsbyte.substring(0, 48 + adaptation_length_t);
210                 payload = tsbyte.substring(48 + adaptation_length_t);
211             }
212         }
213         if (PID == 0) {
214             //System.out.print("Pointer field ? : "+pointer_field+"\n");
215             payload = makePAT(tsheader,payload, p_table);
216             //System.out.print("ここから変更済み\n");
217             //readPAT(changePAT(payload));
218         }
219         String rets = tsheader + payload;
220         //System.out.println("New");
221         //showPAT(rets);
222         return Stream2Byte(rets);
223     }
224
225     private String makePAT(String tsheader,String payload_temp, int Table) {
226         int tableid;
227         int sectionlength;
228         ArrayList program_number = new ArrayList();
229         tableid = TSString2Int(payload_temp, 0, 8);
230         sectionlength = TSString2Int(payload_temp, 12, 12);//-40-32;
231         int patnum = sectionlength * 8 - 72;
232         String rets = "";//="00000000";//pointer field
233         rets = rets + payload_temp.substring(0, 12);//セクション長の前まで
234         int new_section_length = (2 * 32 + 32 + 40) / 8;
235         //int new_section_length = (5 * 32 + 32 + 40) / 8;
236
237         rets = rets + Int2String(new_section_length, 12);
238         rets = rets + payload_temp.substring(24, 64);//ループ前まで
239         String loop = "";
240         patnum = patnum / 32;
241         String crcnow = payload_temp.substring(64 + 32 * patnum, 64 + 32 * patnum + 32);
242         for (int i = 0; i < patnum; i++) {
243             //System.out.print(payload_temp.substring(64+32*i,95+32*i+1)+"\n");
244             int[] pat = new int[2];
245             pat[0] = TSString2Int(payload_temp, 64 + 32 * i, 16);
246             pat[1] = TSString2Int(payload_temp, 32 * i + 64 + 19, 13);
247             if (pat[0] == 0) {
248                 loop = loop+payload_temp.substring(64 + 32 * i, 95 + 32 * i + 1);
249             } else if (pat[0] == Table) {
250                 loop = loop + payload_temp.substring(64 + 32 * i, 95 + 32 * i + 1);
251                 i = patnum;
252             }
253         }
254         rets = rets + loop;
255         //rets=rets+payload_temp.substring(64,64+32*patnum);
256         //rets=payload_temp.substring(0,64+(32*patnum));
257         //CRC32 crc = new CRC32();
258         String s2=tsheader.substring(tsheader.length()-8);
259         s2=s2+rets;
260         //byte[] sb = Stream2Byte(s2);
261         //crc.reset();
262         //crc.update(sb);
263         String s = getCRC32(s2);
264         rets = rets + s;
265
266         ////////////////////
267         
268         //rets=header+payload_temp.substring(0,64+(32*patnum));
269         //String st=header.substring(header.length()-8)+payload_temp.substring(0,64+(32*patnum));
270         //System.out.print("Collect0:" + crcnow + "\n");
271         //System.out.print("Now0:" + getCRC32(st)+ "\n");
272         //sb = Stream2Byte(tsheader + (payload_temp.substring(0, 64 + (32 * patnum))));
273         /*
274         crc.reset();
275         crc.update(sb);
276         long crcl = crc.getValue();
277
278         System.out.print("Now     :" + Long2String(crc.getValue(), 32) + "\n");
279         //System.out.print("New3:"+s+"\n");
280         //
281         //
282
283         String sss = tsheader + payload_temp;
284         //System.out.print("Data:\n"+sss);
285         for (int ib = 0; ib < sss.length() - 1; ib++) {
286             for (int ie = ib + 1; ie < sss.length(); ie++) {
287                 if (testCRC(sss, crcnow, ib, ie)) {
288                     ib = sss.length();
289                     ie = sss.length();
290
291                 }
292                 //System.out.println(Integer.toString(ib)+":"+Integer.toString(ie));
293             }
294         }
295
296         */
297         ////
298         int ill3 = payload_temp.length() - rets.length();
299         for (int ir = 0; ir < ill3; ir++) {
300             rets = rets + "1";
301         }
302         //showPAT(tsheader+rets);
303         return rets;
304     }
305     private String getCRC32(String s){
306         return getCRC32(Stream2Byte(s),1);
307     }
308     private String getCRC32(byte[] data,int offset) {
309         // 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
310         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};
311         int[] shift_reg = new int[32];
312         long crc = 0;
313         byte crc32[] = new byte[4];
314
315         // Initialize shift register's to '1'
316         java.util.Arrays.fill(shift_reg, 1);
317
318         // Calculate nr of data bits, summa of bits
319         int nr_bits = (data.length - offset) * 8;
320
321         for (int bit_count = 0, bit_in_byte = 0, data_bit; bit_count < nr_bits; bit_count++) {
322             // Fetch bit from bitstream
323             data_bit = (data[offset] & 0x80 >>> (bit_in_byte++)) != 0 ? 1 : 0;
324
325             if ((bit_in_byte &= 7) == 0) {
326                 offset++;
327             }
328
329             // Perform the shift and modula 2 addition
330             data_bit ^= shift_reg[31];
331
332             for (int i = 31; i > 0; i--) {
333                 shift_reg[i] = g[i] == 1 ? (shift_reg[i - 1] ^ data_bit) : shift_reg[i - 1];
334             }
335
336             shift_reg[0] = data_bit;
337         }
338
339         for (int i = 0; i < 32; i++) {
340             crc = ((crc << 1) | (shift_reg[31 - i]));
341         }
342
343         for (int i = 0; i < 4; i++) {
344             crc32[i] = (byte) (0xFF & (crc >>> ((3 - i) * 8)));
345         }
346         String s=Long2String(crc, 32);
347         return s;
348     }
349
350     private String addzero(int num){
351         StringBuffer s2=new StringBuffer();
352         for (int i2 = 0; i2 < num; i2++) {
353             s2.append("0");// = "0" + s2;
354         }
355         return s2.toString();
356     }
357     private String byte2String(byte[] b) {
358         StringBuffer sb=new StringBuffer(8*b.length);
359         //String ret = "";
360         for (int i = 0; i < b.length; i++) {
361             StringBuffer sb2=new StringBuffer(8);
362             //String s = Integer.toBinaryString(b[i] & 0xFF);
363             sb2.append(Integer.toBinaryString(b[i] & 0xFF));
364             //if ((s.length() < 8) & (s.length() > 0)) {
365                 /*String s2="";
366                 for (int i2 = s.length(); i2 < 8; i2++) {
367                     s2 = "0" + s2;
368                 }
369                 s=s2+s;
370                  */
371                 //s=addzero(8-s.length())+s;
372                 //sb2.append(addzero(8-s.length()));
373             //}
374             if ((sb2.length() < 8) & (sb2.length() > 0)) {
375                 sb2.insert(0,addzero(8-sb2.length()));
376             }
377             String s3=sb2.toString();
378         //    ret = ret + s ;
379             sb.append(sb2);
380         }
381         //if (!ret.matches(sb.toString())){
382         //    System.out.println("MisMatch");
383         //}
384         //return ret;
385         return sb.toString();
386         /*
387          *
388          *StringBuffer sb= new StringBuffer();
389         int cnt= b.length;
390         for(int i= 0; i< cnt; i++){
391             sb.append(Integer.toHexString( (b[i]>> 4) & 0x0F ) );
392             sb.append(Integer.toHexString( b[i] & 0x0F ) );
393         }
394         return sb.toString();
395          *
396          *
397          *
398          */
399          //StringBuffer sb=new StringBuffer();
400          //int cnt=b.length;
401          //for (int i=0;i<cnt;i++){
402          //    sb.append(Integer.toBinaryString(b[i] & 0xFF))
403          //}
404     }
405
406     private String byte2HexString(byte[] b) {
407         String ret = "";
408         for (int i = 0; i < b.length; i++) {
409             ret = ret + Integer.toHexString(b[i] & 0xFF);
410         }
411         return ret;
412     }
413
414     private boolean testCRC(String base, String ans, int begin_n, int end_n) {
415         String tests1 = base.substring(begin_n, end_n);
416         byte[] test1 = Stream2Byte(tests1);
417         int t32 = 0;
418         int begin = begin_n;
419         int end = end_n;
420         byte[] test2 = Stream2Byte(ans);
421         String tests2 = ans;
422         CRC32 crc = new CRC32();
423         crc.reset();
424         crc.update(test1);
425
426         if (crc.getValue() == Long.parseLong(tests2, 2)) {
427             System.out.print("正解が出ました。\n");
428             System.out.print("begin : " + Integer.toString(begin_n) + " end : " + Integer.toString(end_n));
429             
430             return true;
431         }
432         if (Long.parseLong(getCRC32(test1,1), 2) == Long.parseLong(tests2, 2)) {
433             System.out.print("正解が出ました。(getCRC)\n");
434             System.out.print("begin : " + Integer.toString(begin_n) + " end : " + Integer.toString(end_n));
435             return true;
436         }
437         if (Long.parseLong(getCRC32(test1,1), 2) == Long.parseLong(tests2, 2)) {
438             System.out.print("正解が出ました。(getCRC_2)\n");
439             System.out.println("begin : " + Integer.toString(begin_n) + " end : " + Integer.toString(end_n));
440             showPAT(base);
441             System.out.println("begin : " + base.substring(begin_n,begin_n+32));
442             System.out.println("near : " + base.substring(end_n-32, end_n));
443             System.out.println("near2: " + base.substring(end_n, end_n+32));
444             System.out.println("near3: " + base.substring(end_n+32, end_n+64));
445             return true;
446         }
447         return false;
448     }
449
450     private String Int2String(int num, int length) {
451         String ret = Integer.toBinaryString(num);
452         if (ret.length() < length) {
453             int it = length - ret.length();
454             for (int i = 0; i < it; i++) {
455                 ret = "0" + ret;
456             }
457         }
458         return ret;
459     }
460
461     private String Long2String(long num, int length) {
462         String ret = Long.toBinaryString(num);
463         if (ret.length() < length) {
464             int it = length - ret.length();
465             for (int i = 0; i < it; i++) {
466                 ret = "0" + ret;
467             }
468         }
469         return ret;
470     }
471
472     private byte[] Stream2Byte(String ts) {
473         int len = ts.length() - ts.length() % 8;
474         len = len / 8;
475         byte[] ret = new byte[len];
476         for (int i = 0; i < len; i++) {
477             String tet = ts.substring(i * 8, i * 8 + 8);
478             int itt = TSString2Int(tet, 0, 8);
479             ret[i] = (byte) itt;
480         }
481         return ret;
482     }
483
484     public ArrayList getPAT() {
485         return pat_list_all;
486     }
487
488     public void setPAT(ArrayList pat) {
489         pat_list_now = pat;
490         pat_list_all = pat;
491     }
492
493     public ArrayList getPMT() {
494         return pmt_list;
495     }
496
497     public void setPMT(ArrayList pmt) {
498         pmt_list = pmt;
499     }
500
501     public int getPID() {
502         return PID;
503     }
504
505     public void showPAT(String ts) {
506         System.out.println("先頭:" + ts.substring(0, 8));
507         System.out.println("" + ts.substring(8, 11));
508         System.out.println("PID:" + ts.substring(11, 24));
509         System.out.println("" + ts.substring(24, 32));
510         System.out.println("Adap_Len:" + ts.substring(32, 40));
511         System.out.println("TableID:" + ts.substring(40, 48));
512         System.out.println("" + ts.substring(48, 52));
513         System.out.println("len : " + ts.substring(52, 64) + "//" + Integer.toString(Integer.parseInt(ts.substring(52, 64), 2)));
514         System.out.println("TS ID:" + ts.substring(64, 80));
515         System.out.println("11:" + ts.substring(80, 82));
516         System.out.println("" + ts.substring(82, 104));
517         for (int i = 0; i < 10; i++) {
518             System.out.println(Integer.toString(i) + " : " + ts.substring(104 + 32 * i, 136 + 32 * i));
519         }
520         System.out.println("Length:" + Integer.toString(ts.length()));
521
522
523
524     }
525 }