3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import jtssplitter.data.PATData;
6 import jtssplitter.data.PMTData;
7 import jtssplitter.data.Descriptor;
8 import jtssplitter.data.EITData;
9 import java.io.ByteArrayOutputStream;
11 * To change this template, choose Tools | Templates
12 * and open the template in the editor.
19 public class Mpeg2TSPacket {
23 public String payload;
24 public String adaptation;
25 public byte[] header_byte;
26 public byte[] payload_byte;
27 public byte[] adaptation_byte;
28 public byte[] bPAT_payload = null;
29 //private ArrayList<TsDate> date=new ArrayList<TsDate>();
30 //date.add(new TsDate("Starter"))
32 private int starter;//0-7
33 private int transporterror;//本TSパケットの誤りを示す 1bit 8
34 private int payloadstart;//セクションの先頭バイトが入っているかどうか1bit 9
35 private int transport_priority;//1bit 10
36 private int PID = -1;//tsパケットの種類 13bit 11-23
37 private int transport_scrambled;//2bit 00is " not scrambled" 24-25
38 private int adaptation_field;//2bit 26-27 01:adaptation fieldなしでおk 10は絶対いる 11はペイロードはアダプテーションに続く00は予約
39 private int continuity_counter;//連続性(PIDごとの通し番号) 4bit 28-31
40 //ここからアダプテーションフィールド(最後まで)
41 private int adaptation_length;//8bit 32-39
42 private int discontinuity;//1bit
43 private int random_access;//1bit ランダムアクセスの開始場所となる
44 private int ES_priority;//1bit プライオリティ
45 private int five_flag;//5bit
46 private ArrayList<PATData> pat_list_now = new ArrayList<PATData>();//[0]:番組番号 [1]:PMT PID
47 private ArrayList<PATData> pat_list_all = new ArrayList<PATData>();
48 private ArrayList<PMTData> pmt_list = new ArrayList<PMTData>();//[0]番組番号 [1]テーブルID
49 private int pointer_field;//8bit adaptation fieldの次?
50 private String payload_s;
54 private int staffing_byte;//
56 public Mpeg2TSPacket() {
59 public int getPIDFirst_byte(byte[] ts) {
60 calc cal = new calc();
61 byte[] b = new byte[2];
64 return cal.byte2int(b, 3, 13);
65 //return cal.byte2int(ts,11,13);
68 public void readTS_byte(byte[] ts) {
70 * 188バイトのtsから読み出したbyteを与える
72 calc cal = new calc();
73 String tsbyte = byte2String2(ts);
74 boolean begin_payload_unit = cal.byte2int(ts, 9, 1) == 1;
75 //header = tsbyte.substring(0, 31);
76 payload = tsbyte.substring(32);
77 //starter = TSString2Int(tsbyte, 0, 8);
78 //transporterror = TSString2Int(tsbyte, 8, 1);
79 //payloadstart = TSString2Int(tsbyte, 9, 1);
80 //transport_priority = TSString2Int(tsbyte, 10, 1);
81 //PID = TSString2Int(tsbyte, 11, 13);
82 PID = cal.byte2int(ts, 11, 13);
83 adaptation_field = cal.byte2int(ts, 26, 2);
84 //continuity_counter = TSString2Int(tsbyte, 28, 4);
87 if (adaptation_field == 1) {
88 if (begin_payload_unit) {
89 pointer_field = cal.byte2int(ts, 32, 8);
90 if ((ts.length - 5 - pointer_field) < (5 + pointer_field)) {
93 payload_byte = cal.byte2subbyte(ts, 5 + pointer_field, ts.length - 5 - pointer_field);
96 payload_byte = cal.byte2subbyte(ts, 4, ts.length - 4);
98 } else if (adaptation_field == 3) {
99 adaptation_length = cal.byte2int(ts, 32, 8);
100 if ((adaptation_length < 184) & ((ts.length * 8 - adaptation_length * 8) > 48)) {
101 adaptation_length = adaptation_length * 8;
103 adaptation_byte = cal.byte2subbyte(ts, 4, 1 + adaptation_length / 8);
104 if (begin_payload_unit) {
105 pointer_field = cal.byte2int(ts, 40 + adaptation_length, 8);
106 if ((ts.length - 6 - (adaptation_length / 8) - pointer_field) < (6 + (adaptation_length / 8) + pointer_field)) {
109 payload_byte = cal.byte2subbyte(ts, 6 + (adaptation_length / 8) + pointer_field, ts.length - 6 - (adaptation_length / 8) - pointer_field);
112 payload_byte = cal.byte2subbyte(ts, 5 + adaptation_length / 8, ts.length - 5 - adaptation_length / 8);
118 if (payload_byte != null) {
119 if ((PID == 0) && (begin_payload_unit)) {
120 //cal.showPAT(tsbyte);
121 pat_list_now = readPAT_byte(payload_byte);
122 pat_list_all.addAll(pat_list_now);
124 for (int i = 0; i < pat_list_now.size(); i++) {
125 if ((PID == pat_list_now.get(i).PID) && (PID != 0)) {
126 pmt_list.addAll(readPMT_byte(payload_byte, pat_list_now.get(i).Program_TABLE));
133 private ArrayList<PATData> readPAT_byte(byte[] payload_temp) {
135 * payloadの文字列を入力して[intテーブル,int PID]のArrayListを返す。
139 calc cal = new calc();
140 ArrayList program_number = new ArrayList();
141 tableid = cal.byte2int(payload_temp, 0, 8);
142 sectionlength = cal.byte2int(payload_temp, 12, 12);//-40-32;
143 int patnum = sectionlength * 8 - 72;
144 patnum = patnum / 32;
145 for (int i = 0; i < patnum; i++) {
146 if (payload_temp.length * 8 > 64 + 32 * i + 96) {
147 if (cal.byte2int(payload_temp, 64 + 32 * i + 16, 3) == 7) {
148 PATData patd = new PATData();
149 patd.Program_TABLE = cal.byte2int(payload_temp, 64 + 32 * i, 16);
150 patd.PID = cal.byte2int(payload_temp, 32 * i + 64 + 19, 13);
151 program_number.add(patd);
155 return program_number;
157 private ArrayList<PMTData> readPMT_byte(byte[] payload_temp, int PAT_TABLE) {
158 ArrayList<PMTData> pmt_t = new ArrayList<PMTData>();
159 calc cal = new calc();
160 int tableid = cal.byte2int(payload_temp, 0, 8);
161 int section_length = cal.byte2int(payload_temp, 12, 12);
162 int pcr_pid = cal.byte2int(payload_temp, 67, 13);
163 int program_info_length = cal.byte2int(payload_temp, 84, 12);
165 int cur_point = 96 + program_info_length * 8;
166 if ((cur_point > section_length * 8 - 1) || (cur_point > payload_temp.length * 8 - 11)) {
169 while (end != true) {
170 if (cal.byte2int(payload_temp, cur_point + 8, 3) == 7 && cal.byte2int(payload_temp, cur_point + 24, 4) == 15 && payload_temp.length * 8 > cur_point + 40) {
171 int pmt_stream_type = cal.byte2int(payload_temp, cur_point, 8);
172 int elementary_PID = cal.byte2int(payload_temp, cur_point + 11, 13);
173 //System.out.println(Integer.toString(cur_point)+" : "+Integer.toString(section_length*8));
174 int es_length = cal.byte2int(payload_temp, cur_point + 28, 12);
175 /*if (pmt_stream_type==0x02){
176 Descriptor des=new Descriptor();
177 Object a=des.getDescriptors(payload_temp.substring(cur_point + 40,cur_point + 40+es_length*8));
178 }else if(pmt_stream_type==0x0f){
179 Descriptor des=new Descriptor();
180 Object a=des.getDescriptors(payload_temp.substring(cur_point + 40,cur_point + 40+es_length*8));
184 PMTData pmtd = new PMTData();
185 if ((pmt_stream_type == 0x02) || (pmt_stream_type == 0x0f)) {
186 pmtd.Stream_Type = pmt_stream_type;
187 pmtd.Program_Table = PAT_TABLE;
188 pmtd.Elementary_PID = elementary_PID;
189 pmtd.PCR_PID = pcr_pid;
192 cur_point = cur_point + 40 + es_length * 8;
193 //System.out.println(Integer.toString(cur_point)+" : "+Integer.toString(section_length*8));
194 if ((cur_point > section_length * 8 - 1) || (cur_point > payload_temp.length * 8 - 11)) {
204 public ArrayList<EITData> readEIT(byte[] ts) {
205 String payload_temp = getPayload(ts);
206 int tableid = TSString2Int(payload_temp, 0, 8);
207 int section_length = TSString2Int(payload_temp, 12, 12);
208 int program_number = TSString2Int(payload_temp, 24, 16);
209 boolean current_next_indicator = (TSString2Int(payload_temp, 47, 1) == 1);
210 int section_number = TSString2Int(payload_temp, 48, 8);
212 ArrayList<EITData> ret = new ArrayList<EITData>();
213 while (curpoint < 24 + section_length * 8 - 32) {
214 EITData eitd = new EITData();
215 eitd.current_newt_indicator = current_next_indicator;
216 eitd.event_id = TSString2Int(payload_temp, curpoint, 16);
217 eitd.program_number = program_number;
218 eitd.section_number = section_number;
219 int des_len = TSString2Int(payload_temp, curpoint + 84, 12);
220 Descriptor des = new Descriptor();
221 eitd.descriptors = des.getDescriptors(payload_temp.substring(curpoint + 96, curpoint + 84 + des_len * 8));
223 curpoint = curpoint + 84 + des_len * 8;
228 private int TSString2Int(String s, int begin, int length) {
229 String st = s.substring(begin, begin + length);
230 int i = Integer.parseInt(st, 2);
234 public byte[] splitPAT_byte(byte[] ts, int p_table) {
237 * p_tableで指定された番組テーブルのみを取り出すPATを作る。
239 byte[] tbb = new byte[ts.length - 4];
240 System.arraycopy(ts, 4, tbb, 0, tbb.length);
241 if (bPAT_payload != null) {
242 if (Arrays.equals(tbb, bPAT_payload)) {
243 byte[] retb = new byte[188];
244 System.arraycopy(ts, 0, retb, 0, 4);
245 System.arraycopy(bPAT_payload, 0, retb, 4, 184);
249 calc cal = new calc();
250 header_byte = cal.byte2subbyte(ts, 0, 4);
251 byte[] pointer_byte = cal.byte2subbyte(ts, 4, 1);
252 payload_byte = cal.byte2subbyte(ts, 4, ts.length - 4);
253 starter = cal.byte2int(ts, 0, 8);
254 boolean begin_payload_unit = cal.byte2int(ts, 9, 1) == 1;
255 transporterror = cal.byte2int(ts, 8, 1);
256 payloadstart = cal.byte2int(ts, 9, 1);
257 transport_priority = cal.byte2int(ts, 10, 1);
258 PID = cal.byte2int(ts, 11, 13);
259 adaptation_field = cal.byte2int(ts, 26, 2);
260 continuity_counter = cal.byte2int(ts, 28, 4);
261 if (adaptation_field == 1) {
262 if (begin_payload_unit) {
263 pointer_field = cal.byte2int(ts, 32, 8);
264 if ((ts.length - 5 - pointer_field) < (5 + pointer_field)) {
267 payload_byte = cal.byte2subbyte(ts, 5 + pointer_field, ts.length - 5 - pointer_field);
270 payload_byte = cal.byte2subbyte(ts, 4, ts.length - 4);
272 } else if (adaptation_field == 3) {
273 adaptation_length = cal.byte2int(ts, 32, 8);
274 if ((adaptation_length < 184) & ((ts.length * 8 - adaptation_length * 8) > 48)) {
275 adaptation_length = adaptation_length * 8;
277 adaptation_byte = cal.byte2subbyte(ts, 4, 1 + adaptation_length / 8);
278 if (begin_payload_unit) {
279 pointer_field = cal.byte2int(ts, 40 + adaptation_length, 8);
280 if ((ts.length - 6 - (adaptation_length / 8) - pointer_field) < (6 + (adaptation_length / 8) + pointer_field)) {
283 payload_byte = cal.byte2subbyte(ts, 6 + (adaptation_length / 8) + pointer_field, ts.length - 6 - (adaptation_length / 8) - pointer_field);
286 payload_byte = cal.byte2subbyte(ts, 5 + adaptation_length / 8, ts.length - 5 - adaptation_length / 8);
291 if ((PID == 0) && (begin_payload_unit) && (payload_byte != null)) {
292 byte[] new_pointer=new byte[1];
294 payload_byte = makePAT_byte(new_pointer, payload_byte, p_table);
295 //payload_byte = makePAT_byte(pointer_byte, payload_byte, p_table);
296 bPAT_payload = payload_byte;
298 if ((payload_byte != null)&& (begin_payload_unit)) {
299 ByteArrayOutputStream baos = new ByteArrayOutputStream(ts.length);
300 baos.write(header_byte, 0, header_byte.length);
301 baos.write(pointer_byte, 0, pointer_byte.length);
302 baos.write(payload_byte, 0, payload_byte.length);
303 for (int ir = 0; ir < 188-baos.size(); ir++) {
306 return baos.toByteArray();
312 private byte[] makePAT_byte(byte[] pointer_field, byte[] payload_temp, int Table) {
313 ByteArrayOutputStream baos = new ByteArrayOutputStream(payload_temp.length);
315 calc cal = new calc();
316 sectionlength = cal.byte2int(payload_temp, 12, 12); //-40-32;
317 int patnum = sectionlength * 8 - 72;
318 baos.write(payload_temp, 0, 1);
319 int new_section_length = (2 * 32 + 32 + 40) / 8;
320 baos.write(cal.joinByte((byte) cal.byte2int(payload_temp, 8, 4), (byte) (new_section_length & 0xF00), 4));
321 baos.write((byte) (new_section_length & 0xFF));
322 baos.write(payload_temp, 3, 5);
323 patnum = patnum / 32;
325 for (int i = 0; i < patnum; i++) {
326 int[] pat = new int[2];
327 pat[0] = cal.byte2int(payload_temp, 64 + 32 * i, 16);
328 pat[1] = cal.byte2int(payload_temp, 32 * i + 64 + 19, 13);
330 baos.write(payload_temp, 8 + 4 * i, 4);
332 } else if (pat[0] == Table) {
333 baos.write(payload_temp, 8 + 4 * i, 4);
338 ByteArrayOutputStream baoscrc = new ByteArrayOutputStream(nowt + 1);
339 baoscrc.write(pointer_field[0]);
340 baoscrc.write(baos.toByteArray(), 0, baos.size());
341 byte[] crc = getCRC32_byte(baoscrc.toByteArray(), 1);
342 baos.write(crc, 0, crc.length);
343 int ill3 = payload_temp.length - baos.size();
344 for (int ir = 0; ir < ill3; ir++) {
347 return baos.toByteArray();
350 private String getCRC32(String s) {
351 return getCRC32(String2Byte(s), 1);
354 private String getCRC32(byte[] data, int offset) {
355 // 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
356 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};
357 int[] shift_reg = new int[32];
359 byte crc32[] = new byte[4];
361 // Initialize shift register's to '1'
362 java.util.Arrays.fill(shift_reg, 1);
364 // Calculate nr of data bits, summa of bits
365 int nr_bits = (data.length - offset) * 8;
367 for (int bit_count = 0, bit_in_byte = 0, data_bit; bit_count < nr_bits; bit_count++) {
368 // Fetch bit from bitstream
369 data_bit = (data[offset] & 0x80 >>> (bit_in_byte++)) != 0 ? 1 : 0;
371 if ((bit_in_byte &= 7) == 0) {
375 // Perform the shift and modula 2 addition
376 data_bit ^= shift_reg[31];
378 for (int i = 31; i > 0; i--) {
379 shift_reg[i] = g[i] == 1 ? (shift_reg[i - 1] ^ data_bit) : shift_reg[i - 1];
382 shift_reg[0] = data_bit;
385 for (int i = 0; i < 32; i++) {
386 crc = ((crc << 1) | (shift_reg[31 - i]));
389 for (int i = 0; i < 4; i++) {
390 crc32[i] = (byte) (0xFF & (crc >>> ((3 - i) * 8)));
392 String s = Long2String(crc, 32);
396 private byte[] getCRC32_byte(byte[] data, int offset) {
397 // 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
398 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};
399 int[] shift_reg = new int[32];
401 byte crc32[] = new byte[4];
403 // Initialize shift register's to '1'
404 java.util.Arrays.fill(shift_reg, 1);
406 // Calculate nr of data bits, summa of bits
407 int nr_bits = (data.length - offset) * 8;
409 for (int bit_count = 0, bit_in_byte = 0, data_bit; bit_count < nr_bits; bit_count++) {
410 // Fetch bit from bitstream
411 data_bit = (data[offset] & 0x80 >>> (bit_in_byte++)) != 0 ? 1 : 0;
413 if ((bit_in_byte &= 7) == 0) {
417 // Perform the shift and modula 2 addition
418 data_bit ^= shift_reg[31];
420 for (int i = 31; i > 0; i--) {
421 shift_reg[i] = g[i] == 1 ? (shift_reg[i - 1] ^ data_bit) : shift_reg[i - 1];
424 shift_reg[0] = data_bit;
427 for (int i = 0; i < 32; i++) {
428 crc = ((crc << 1) | (shift_reg[31 - i]));
431 for (int i = 0; i < 4; i++) {
432 crc32[i] = (byte) (0xFF & (crc >>> ((3 - i) * 8)));
437 private String addzero(int num) {
458 StringBuffer sb = new StringBuffer();
459 for (int i = 0; i < num; i++) {
462 return sb.toString();
466 private String byte2String2(byte[] b) {
470 StringBuffer sb = new StringBuffer();
471 for (int i = 0; i < bl; i++) {
473 for (int j = 0; j < 8; j++) {
475 int ri = b[i * 8 + j] & 0xFF;
478 sb.append(Long2String(retl, 64));
480 int bl2 = b.length % 8;
481 bl2 = (bl2 - bl2 % 4) / 4;
482 for (int i = 0; i < bl2; i++) {
484 for (int j = 0; j < 4; j++) {
486 reti = reti + (b[bl * 8 + 4 * i + j] & 0xFF);
488 sb.append(Int2String(reti, 32));
490 for (int i = 0; i < (b.length % 8) % 4; i++) {
491 sb.append(Int2String(b[bl * 8 + bl2 * 4 + i] & 0xFF, 8));
493 return sb.toString();
496 private String Int2String(int num, int length) {
497 String ret = Integer.toBinaryString(num);
498 if (ret.length() < length) {
499 int it = length - ret.length();
500 for (int i = 0; i < it; i++) {
507 private String Long2String(long num, int length) {
508 String ret = Long.toBinaryString(num);
509 if (ret.length() < length) {
510 int it = length - ret.length();
511 for (int i = 0; i < it; i++) {
518 private byte[] String2Byte(String ts) {
519 //StringBuffer sb=new StringBuffer(ts);
520 int len = ts.length() - ts.length() % 8;
522 byte[] ret = new byte[len];
523 for (int i = 0; i < len; i++) {
524 String tet = ts.substring(i * 8, i * 8 + 8);
525 int itt = TSString2Int(tet, 0, 8);
531 public ArrayList<PATData> getPAT() {
535 public void setPAT(ArrayList pat) {
540 public ArrayList<PMTData> getPMT() {
544 public void setPMT(ArrayList pmt) {
548 public int getPID() {
552 public String getPayload(byte[] ts) {
554 * 188バイトのtsから読み出したbyteを与える
556 String tsbyte = byte2String2(ts);
557 //header = tsbyte.substring(0, 31);
558 String ret_payload = "";
559 //starter = TSString2Int(tsbyte, 0, 8);
560 //transporterror = TSString2Int(tsbyte, 8, 1);
561 //payloadstart = TSString2Int(tsbyte, 9, 1);
562 //transport_priority = TSString2Int(tsbyte, 10, 1);
563 int pid = TSString2Int(tsbyte, 11, 13);
564 int af = TSString2Int(tsbyte, 26, 2);
565 //continuity_counter = TSString2Int(tsbyte, 28, 4);
568 ret_payload = tsbyte.substring(40);
569 } else if (af == 3) {
570 int al = TSString2Int(tsbyte, 32, 8);
571 if ((al < 184) & ((tsbyte.length() - al * 8) > 48)) {
574 ret_payload = tsbyte.substring(48 + al);
580 public byte[] getPayload_byte(byte[] ts) {
582 * 188バイトのtsから読み出したbyteを与える
584 calc cal = new calc();
585 String tsbyte = byte2String2(ts);
586 //header = tsbyte.substring(0, 31);
588 //starter = TSString2Int(tsbyte, 0, 8);
589 //transporterror = TSString2Int(tsbyte, 8, 1);
590 //payloadstart = TSString2Int(tsbyte, 9, 1);
591 //transport_priority = TSString2Int(tsbyte, 10, 1);
592 int pid = cal.byte2int(ts, 11, 13);
593 int af = cal.byte2int(ts, 26, 2);
594 //continuity_counter = TSString2Int(tsbyte, 28, 4);
597 retb = cal.byte2subbyte(ts, 5, ts.length - 5);
598 } else if (af == 3) {
599 int al = cal.byte2int(ts, 32, 8);
600 if ((al < 184) & ((ts.length * 8 - al * 8) > 48)) {
603 retb = cal.byte2subbyte(ts, 6 + al / 8, ts.length - 6 - al / 8);
609 public ArrayList<PMTData> readPMTglobal_byte(byte[] ts, int TABLE_NUM) {
610 byte[] payloadt = getPayload_byte(ts);
611 return readPMT_byte(payloadt, TABLE_NUM);
614 public void showPAT(String ts) {
615 System.out.println("先頭:" + ts.substring(0, 8));
616 System.out.println("" + ts.substring(8, 11));
617 System.out.println("PID:" + ts.substring(11, 24));
618 System.out.println("" + ts.substring(24, 32));
619 System.out.println("Adap_Len:" + ts.substring(32, 40));
620 System.out.println("TableID:" + ts.substring(40, 48));
621 System.out.println("" + ts.substring(48, 52));
622 System.out.println("len : " + ts.substring(52, 64) + "//" + Integer.toString(Integer.parseInt(ts.substring(52, 64), 2)));
623 System.out.println("TS ID:" + ts.substring(64, 80));
624 System.out.println("11:" + ts.substring(80, 82));
625 System.out.println("" + ts.substring(82, 104));
626 for (int i = 0; i < 10; i++) {
627 System.out.println(Integer.toString(i) + " : " + ts.substring(104 + 32 * i, 136 + 32 * i));
629 System.out.println("Length:" + Integer.toString(ts.length()));