OSDN Git Service

some speed ups.
[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=byte2String(b);
57         //s=s.substring(3,16);
58         return Integer.parseInt(byte2String(b).substring(3,16),2);
59     }
60     public void readTS(byte[] ts) {
61         /**
62          * 188バイトのtsから読み出したbyteを与える
63          */
64         String tsbyte = byte2String(ts);
65         //header = tsbyte.substring(0, 31);
66         payload = tsbyte.substring(32);
67         //starter = TSString2Int(tsbyte, 0, 8);
68         //transporterror = TSString2Int(tsbyte, 8, 1);
69         //payloadstart = TSString2Int(tsbyte, 9, 1);
70         //transport_priority = TSString2Int(tsbyte, 10, 1);
71         PID = TSString2Int(tsbyte, 11, 13);
72         adaptation_field = TSString2Int(tsbyte, 26, 2);
73         //continuity_counter = TSString2Int(tsbyte, 28, 4);
74         payload = "";
75         if (PID != 8191) {
76             if (adaptation_field == 1) {
77                 pointer_field = TSString2Int(tsbyte, 32, 8);
78                 payload = tsbyte.substring(40);
79             } else if (adaptation_field == 3) {
80                 adaptation_length = TSString2Int(tsbyte, 32, 8);
81                 if (adaptation_length < 184) {
82                     adaptation_length = adaptation_length * 8;
83                 }
84                 //System.out.println(adaptation_length);
85                 adaptation = tsbyte.substring(32, 40 + adaptation_length);
86                 pointer_field = TSString2Int(tsbyte, 40 + adaptation_length, 8);
87                 payload = tsbyte.substring(48 + adaptation_length);
88             }
89         }
90         if (PID == 0) {
91             pat_list_now =readPAT(payload);
92             pat_list_all.addAll(pat_list_now);
93         }
94         for (int i = 0; i < pat_list_now.size(); i++) {
95             if ((PID == pat_list_now.get(i).PID) && (PID != 0)) {
96                 pmt_list.addAll(readPMT(payload, pat_list_now.get(i).Program_TABLE));
97             }
98         }
99         tsbyte = "";
100     }
101
102     private ArrayList<PATData> readPAT(String payload_temp) {
103         /*
104          * payloadの文字列を入力して[intテーブル,int PID]のArrayListを返す。
105          */
106         int tableid;
107         int sectionlength;
108         ArrayList program_number = new ArrayList();
109         tableid = TSString2Int(payload_temp, 0, 8);
110         sectionlength = TSString2Int(payload_temp, 12, 12);//-40-32;
111         int patnum = sectionlength * 8 - 72;
112         patnum = patnum / 32;
113         byte[] test = String2Byte(payload_temp);
114         String stest = "";
115         for (int ij = 0; ij < test.length; ij++) {
116             int it = test[ij] & 0xFF;
117             String s = Integer.toBinaryString(it);
118             if (s.length() < 8) {
119                 for (int i2 = s.length(); i2 < 8; i2++) {
120                     s = "0" + s;
121                 }
122             }
123             stest = stest + s;
124         }
125         payload_temp = stest;
126         int nowbit = 64;
127         for (int i = 0; i < patnum; i++) {
128             PATData patd=new PATData();
129             patd.Program_TABLE=TSString2Int(payload_temp, 64 + 32 * i, 16);
130             patd.PID=TSString2Int(payload_temp, 32 * i + 64 + 19, 13);
131             program_number.add(patd);
132         }
133         return program_number;
134     }
135
136     private ArrayList<PMTData> readPMT(String payload_temp, int PAT_TABLE) {
137         ArrayList<PMTData> pmt_t = new ArrayList<PMTData>();
138         int tableid = TSString2Int(payload_temp, 0, 8);
139         int section_length = TSString2Int(payload_temp, 12, 12);
140         int program_info_length = TSString2Int(payload_temp, 84, 12);
141         boolean end = false;
142         int cur_point = 96 + program_info_length * 8;
143         while (end != true) {
144             int pmt_stream_type = TSString2Int(payload_temp, cur_point, 8);
145             int elementary_PID = TSString2Int(payload_temp, cur_point + 11, 13);
146             int es_length = TSString2Int(payload_temp, cur_point + 28, 12);
147             PMTData pmtd=new PMTData();
148             pmtd.Stream_Type=pmt_stream_type;
149             pmtd.Program_Table=PAT_TABLE;
150             pmtd.Elementary_PID=elementary_PID;
151             pmt_t.add(pmtd);
152             cur_point = cur_point + 40 + es_length * 8;
153             if (cur_point > section_length * 8) {
154                 end = true;
155             }
156         }
157         return pmt_t;
158     }
159
160     private int TSString2Int(String s, int begin, int length) {
161         String st = s.substring(begin, begin + length);
162         int i = Integer.parseInt(st, 2);
163         return i;
164     }
165
166     public byte[] splitPAT(byte[] ts, int p_table) {
167         /**
168          * 
169          * p_tableで指定された番組テーブルのみを取り出すPATを作る。
170          */
171         int matchnum=0;
172         byte[] tbb=new byte[ts.length-4];
173         for (int i=0;i<ts.length-4;i++){
174             tbb[i]=ts[4+i];
175             if (bPAT_payload!=null){
176                 if (ts[4+i]==bPAT_payload[i]){
177                     matchnum++;
178                 }
179             }
180         }
181         if (matchnum==ts.length-4){
182             byte[] retb=new byte[188];
183             System.arraycopy(ts,0,retb,0,4);
184             System.arraycopy(bPAT_payload,0,retb,4,184);
185             return retb;
186         }else{
187             bPAT_payload=tbb;
188         }
189         String tsbyte = byte2String(ts);
190         String tsheader = "";
191         header = tsbyte.substring(0, 31);
192         payload = tsbyte.substring(32);
193         starter = TSString2Int(tsbyte, 0, 8);
194         transporterror = TSString2Int(tsbyte, 8, 1);
195         payloadstart = TSString2Int(tsbyte, 9, 1);
196         transport_priority = TSString2Int(tsbyte, 10, 1);
197         PID = TSString2Int(tsbyte, 11, 13);
198         adaptation_field = TSString2Int(tsbyte, 26, 2);
199         continuity_counter = TSString2Int(tsbyte, 28, 4);
200         int adaptation_length_t = TSString2Int(tsbyte, 32, 8);
201         payload = "";
202         if (PID != 8191) {
203             if (adaptation_field == 1) {
204                 pointer_field = TSString2Int(tsbyte, 32, 8);
205                 tsheader = tsbyte.substring(0, 40);
206                 payload = tsbyte.substring(40);
207             } else if (adaptation_field == 3) {
208                 if (adaptation_length_t < 188) {
209                     adaptation_length_t = adaptation_length_t * 8;
210                 }
211                 tsheader = tsbyte.substring(0, 48 + adaptation_length_t);
212                 payload = tsbyte.substring(48 + adaptation_length_t);
213             }
214         }
215         if (PID == 0) {
216             //showPAT(tsbyte);
217             payload = makePAT(tsheader,payload, p_table);
218         }
219         String rets = tsheader + payload;
220         return String2Byte(rets);
221     }
222
223     private String makePAT(String tsheader,String payload_temp, int Table) {
224         int sectionlength;
225         StringBuffer sb=new StringBuffer();
226         //ArrayList program_number = new ArrayList();
227         //System.out.println("Pay:"+payload_temp);
228         //int tableid = TSString2Int(payload_temp, 0, 8);
229         sectionlength = TSString2Int(payload_temp, 12, 12);//-40-32;
230         int patnum = sectionlength * 8 - 72;
231         //String rets = "";//="00000000";//pointer field
232         //rets = rets + payload_temp.substring(0, 12);//セクション長の前まで
233         sb.append(payload_temp.substring(0,12));
234         int new_section_length = (2 * 32 + 32 + 40) / 8;
235         sb.append(Int2String(new_section_length, 12));
236         sb.append(payload_temp.substring(24, 64));
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             int[] pat = new int[2];
244             pat[0] = TSString2Int(payload_temp, 64 + 32 * i, 16);
245             pat[1] = TSString2Int(payload_temp, 32 * i + 64 + 19, 13);
246             if (pat[0] == 0) {
247                 sb.append(payload_temp.substring(64 + 32 * i, 95 + 32 * i + 1));
248                 //loop = loop+payload_temp.substring(64 + 32 * i, 95 + 32 * i + 1);
249             } else if (pat[0] == Table) {
250                 sb.append(payload_temp.substring(64 + 32 * i, 95 + 32 * i + 1));
251                 //loop = loop + payload_temp.substring(64 + 32 * i, 95 + 32 * i + 1);
252                 i = patnum;
253             }
254         }
255         String s2=tsheader.substring(tsheader.length()-8);
256         s2=s2+sb.toString();
257         String s = getCRC32(s2);
258         sb.append(s);
259         //rets = rets + s;
260         int ill3 = payload_temp.length() - sb.length();
261         for (int ir = 0; ir < ill3; ir++) {
262             sb.append("1");
263             //rets = rets + "1";
264         }
265         return sb.toString();
266     }
267     private String getCRC32(String s){
268         return getCRC32(String2Byte(s),1);
269     }
270     private String getCRC32(byte[] data,int offset) {
271         // 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
272         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};
273         int[] shift_reg = new int[32];
274         long crc = 0;
275         byte crc32[] = new byte[4];
276
277         // Initialize shift register's to '1'
278         java.util.Arrays.fill(shift_reg, 1);
279
280         // Calculate nr of data bits, summa of bits
281         int nr_bits = (data.length - offset) * 8;
282
283         for (int bit_count = 0, bit_in_byte = 0, data_bit; bit_count < nr_bits; bit_count++) {
284             // Fetch bit from bitstream
285             data_bit = (data[offset] & 0x80 >>> (bit_in_byte++)) != 0 ? 1 : 0;
286
287             if ((bit_in_byte &= 7) == 0) {
288                 offset++;
289             }
290
291             // Perform the shift and modula 2 addition
292             data_bit ^= shift_reg[31];
293
294             for (int i = 31; i > 0; i--) {
295                 shift_reg[i] = g[i] == 1 ? (shift_reg[i - 1] ^ data_bit) : shift_reg[i - 1];
296             }
297
298             shift_reg[0] = data_bit;
299         }
300
301         for (int i = 0; i < 32; i++) {
302             crc = ((crc << 1) | (shift_reg[31 - i]));
303         }
304
305         for (int i = 0; i < 4; i++) {
306             crc32[i] = (byte) (0xFF & (crc >>> ((3 - i) * 8)));
307         }
308         String s=Long2String(crc, 32);
309         return s;
310     }
311
312     private String addzero(int num){
313         switch (num){
314             case 0:
315                 return "";
316             case 1:
317                 return "0";
318             case 2:
319                 return "00";
320             case 3:
321                 return "000";
322             case 4:
323                 return "0000";
324             case 5:
325                 return "00000";
326             case 6:
327                 return "000000";
328             case 7:
329                 return "0000000";
330             case 8:
331                 return "00000000";
332             default:
333                 StringBuffer sb=new StringBuffer();
334                 for (int i=0;i<num;i++){
335                     sb.append("0");
336                 }
337                 return sb.toString();
338         }
339     }
340     private String byte2String(byte[] b) {
341         StringBuffer sb=new StringBuffer(8*b.length);
342         for (int i = 0; i < b.length; i++) {
343             StringBuffer sb2=new StringBuffer(8);
344             sb2.append(Integer.toBinaryString(b[i] & 0xFF));
345             if ((sb2.length() < 8) & (sb2.length() > 0)) {
346                 sb2.insert(0,addzero(8-sb2.length()));
347             }
348             String s3=sb2.toString();
349             sb.append(sb2);
350         }
351         return sb.toString();
352     }
353
354     private String byte2HexString(byte[] b) {
355         String ret = "";
356         for (int i = 0; i < b.length; i++) {
357             ret = ret + Integer.toHexString(b[i] & 0xFF);
358         }
359         return ret;
360     }
361
362     private boolean testCRC(String base, String ans, int begin_n, int end_n) {
363         String tests1 = base.substring(begin_n, end_n);
364         byte[] test1 = String2Byte(tests1);
365         int t32 = 0;
366         int begin = begin_n;
367         int end = end_n;
368         byte[] test2 = String2Byte(ans);
369         String tests2 = ans;
370         CRC32 crc = new CRC32();
371         crc.reset();
372         crc.update(test1);
373
374         if (crc.getValue() == Long.parseLong(tests2, 2)) {
375             System.out.print("正解が出ました。\n");
376             System.out.print("begin : " + Integer.toString(begin_n) + " end : " + Integer.toString(end_n));
377             
378             return true;
379         }
380         if (Long.parseLong(getCRC32(test1,1), 2) == Long.parseLong(tests2, 2)) {
381             System.out.print("正解が出ました。(getCRC)\n");
382             System.out.print("begin : " + Integer.toString(begin_n) + " end : " + Integer.toString(end_n));
383             return true;
384         }
385         if (Long.parseLong(getCRC32(test1,1), 2) == Long.parseLong(tests2, 2)) {
386             System.out.print("正解が出ました。(getCRC_2)\n");
387             System.out.println("begin : " + Integer.toString(begin_n) + " end : " + Integer.toString(end_n));
388             showPAT(base);
389             System.out.println("begin : " + base.substring(begin_n,begin_n+32));
390             System.out.println("near : " + base.substring(end_n-32, end_n));
391             System.out.println("near2: " + base.substring(end_n, end_n+32));
392             System.out.println("near3: " + base.substring(end_n+32, end_n+64));
393             return true;
394         }
395         return false;
396     }
397
398     private String Int2String(int num, int length) {
399         String ret = Integer.toBinaryString(num);
400         if (ret.length() < length) {
401             int it = length - ret.length();
402             for (int i = 0; i < it; i++) {
403                 ret = "0" + ret;
404             }
405         }
406         return ret;
407     }
408
409     private String Long2String(long num, int length) {
410         String ret = Long.toBinaryString(num);
411         if (ret.length() < length) {
412             int it = length - ret.length();
413             for (int i = 0; i < it; i++) {
414                 ret = "0" + ret;
415             }
416         }
417         return ret;
418     }
419
420     private byte[] String2Byte(String ts) {
421         //StringBuffer sb=new StringBuffer(ts);
422         int len = ts.length() - ts.length() % 8;
423         len = len / 8;
424         byte[] ret = new byte[len];
425         for (int i = 0; i < len; i++) {
426             String tet = ts.substring(i * 8, i * 8 + 8);
427             int itt = TSString2Int(tet, 0, 8);
428             ret[i] = (byte) itt;
429         }
430         return ret;
431     }
432
433     public ArrayList getPAT() {
434         return pat_list_all;
435     }
436
437     public void setPAT(ArrayList pat) {
438         pat_list_now = pat;
439         pat_list_all = pat;
440     }
441
442     public ArrayList getPMT() {
443         return pmt_list;
444     }
445
446     public void setPMT(ArrayList pmt) {
447         pmt_list = pmt;
448     }
449
450     public int getPID() {
451         return PID;
452     }
453
454     public void showPAT(String ts) {
455         System.out.println("先頭:" + ts.substring(0, 8));
456         System.out.println("" + ts.substring(8, 11));
457         System.out.println("PID:" + ts.substring(11, 24));
458         System.out.println("" + ts.substring(24, 32));
459         System.out.println("Adap_Len:" + ts.substring(32, 40));
460         System.out.println("TableID:" + ts.substring(40, 48));
461         System.out.println("" + ts.substring(48, 52));
462         System.out.println("len : " + ts.substring(52, 64) + "//" + Integer.toString(Integer.parseInt(ts.substring(52, 64), 2)));
463         System.out.println("TS ID:" + ts.substring(64, 80));
464         System.out.println("11:" + ts.substring(80, 82));
465         System.out.println("" + ts.substring(82, 104));
466         for (int i = 0; i < 10; i++) {
467             System.out.println(Integer.toString(i) + " : " + ts.substring(104 + 32 * i, 136 + 32 * i));
468         }
469         System.out.println("Length:" + Integer.toString(ts.length()));
470
471
472
473     }
474 }