OSDN Git Service

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