3 import java.util.ArrayList;
4 import java.util.zip.CRC32;
6 * To change this template, choose Tools | Templates
7 * and open the template in the editor.
12 * @author Administrator
14 public class Mpeg2TSPacket {
17 public String payload;
18 public String adaptation;
19 //private ArrayList<TsDate> date=new ArrayList<TsDate>();
20 //date.add(new TsDate("Starter"))
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;
44 private int staffing_byte;//
46 public Mpeg2TSPacket() {
49 public void readTS(byte[] ts) {
51 * 188バイトのtsから読み出したbyteを与える
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);
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;
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);
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));
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]));
96 private ArrayList readPAT(String payload_temp) {
98 * payloadの文字列を入力して[intテーブル,int PID]のArrayListを返す。
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);
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++) {
120 payload_temp = stest;
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);
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;
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);
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;
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) {
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);
169 public byte[] splitPAT(byte[] ts, int p_table) {
172 * p_tableで指定された番組テーブルのみを取り出すPATを作る。
174 /*String tsbyte=new String();
175 for (int i=0;i<188;i++){
177 String s=Integer.toBinaryString(it);
178 if ((s.length()<8)&(s.length()>0)){
179 for (int i2=s.length();i2<8;i2++){
185 String tsbyte = byte2String(ts);
186 //System.out.println("Base");
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);
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;
209 tsheader = tsbyte.substring(0, 48 + adaptation_length_t);
210 payload = tsbyte.substring(48 + adaptation_length_t);
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));
219 String rets = tsheader + payload;
220 //System.out.println("New");
222 return Stream2Byte(rets);
225 private String makePAT(String tsheader,String payload_temp, int Table) {
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;
237 rets = rets + Int2String(new_section_length, 12);
238 rets = rets + payload_temp.substring(24, 64);//ループ前まで
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);
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);
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);
260 //byte[] sb = Stream2Byte(s2);
263 String s = getCRC32(s2);
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))));
276 long crcl = crc.getValue();
278 System.out.print("Now :" + Long2String(crc.getValue(), 32) + "\n");
279 //System.out.print("New3:"+s+"\n");
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)) {
292 //System.out.println(Integer.toString(ib)+":"+Integer.toString(ie));
298 int ill3 = payload_temp.length() - rets.length();
299 for (int ir = 0; ir < ill3; ir++) {
302 //showPAT(tsheader+rets);
305 private String getCRC32(String s){
306 return getCRC32(Stream2Byte(s),1);
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];
313 byte crc32[] = new byte[4];
315 // Initialize shift register's to '1'
316 java.util.Arrays.fill(shift_reg, 1);
318 // Calculate nr of data bits, summa of bits
319 int nr_bits = (data.length - offset) * 8;
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;
325 if ((bit_in_byte &= 7) == 0) {
329 // Perform the shift and modula 2 addition
330 data_bit ^= shift_reg[31];
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];
336 shift_reg[0] = data_bit;
339 for (int i = 0; i < 32; i++) {
340 crc = ((crc << 1) | (shift_reg[31 - i]));
343 for (int i = 0; i < 4; i++) {
344 crc32[i] = (byte) (0xFF & (crc >>> ((3 - i) * 8)));
346 String s=Long2String(crc, 32);
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;
355 return s2.toString();
357 private String byte2String(byte[] b) {
358 StringBuffer sb=new StringBuffer(8*b.length);
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)) {
366 for (int i2 = s.length(); i2 < 8; i2++) {
371 //s=addzero(8-s.length())+s;
372 //sb2.append(addzero(8-s.length()));
374 if ((sb2.length() < 8) & (sb2.length() > 0)) {
375 sb2.insert(0,addzero(8-sb2.length()));
377 String s3=sb2.toString();
381 //if (!ret.matches(sb.toString())){
382 // System.out.println("MisMatch");
385 return sb.toString();
388 *StringBuffer sb= new StringBuffer();
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 ) );
394 return sb.toString();
399 //StringBuffer sb=new StringBuffer();
401 //for (int i=0;i<cnt;i++){
402 // sb.append(Integer.toBinaryString(b[i] & 0xFF))
406 private String byte2HexString(byte[] b) {
408 for (int i = 0; i < b.length; i++) {
409 ret = ret + Integer.toHexString(b[i] & 0xFF);
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);
420 byte[] test2 = Stream2Byte(ans);
422 CRC32 crc = new CRC32();
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));
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));
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));
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));
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++) {
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++) {
472 private byte[] Stream2Byte(String ts) {
473 int len = ts.length() - ts.length() % 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);
484 public ArrayList getPAT() {
488 public void setPAT(ArrayList pat) {
493 public ArrayList getPMT() {
497 public void setPMT(ArrayList pmt) {
501 public int getPID() {
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));
520 System.out.println("Length:" + Integer.toString(ts.length()));