OSDN Git Service

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