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;
12 * To change this template, choose Tools | Templates
13 * and open the template in the editor.
20 public class Mpeg2TSPacket {
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"))
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;
51 private int staffing_byte;//
53 public Mpeg2TSPacket() {
55 public int getPIDFirst(byte[] ts){
59 //String s=byte2String2(b);
60 //s=s.substring(3,16);
62 return Integer.parseInt(byte2String2(b).substring(3,16),2);
64 public void readTS(byte[] ts) {
66 * 188バイトのtsから読み出したbyteを与える
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);
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;
88 adaptation = tsbyte.substring(32, 40 + adaptation_length);
89 pointer_field = TSString2Int(tsbyte, 40 + adaptation_length, 8);
90 payload = tsbyte.substring(48 + adaptation_length);
94 pat_list_now =readPAT(payload);
95 pat_list_all.addAll(pat_list_now);
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));
105 private ArrayList<PATData> readPAT(String payload_temp) {
107 * payloadの文字列を入力して[intテーブル,int PID]のArrayListを返す。
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);
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++) {
128 payload_temp = stest;
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);
136 return program_number;
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);
146 int cur_point = 96 + program_info_length * 8;
147 if (cur_point>section_length*8){
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));
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;
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)) {
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);
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));
204 curpoint=curpoint+84+des_len*8;
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);
214 public byte[] splitPAT(byte[] ts, int p_table) {
217 * p_tableで指定された番組テーブルのみを取り出すPATを作る。
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);
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);
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;
252 tsheader = tsbyte.substring(0, 48 + adaptation_length_t);
253 payload = tsbyte.substring(48 + adaptation_length_t);
258 payload = makePAT(tsheader,payload, p_table);
259 byte[] retb=String2Byte(payload);
262 String rets = tsheader + payload;
263 return String2Byte(rets);
266 private String makePAT(String tsheader,String payload_temp, int Table) {
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);//ループ前まで
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);
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);
298 String s2=tsheader.substring(tsheader.length()-8);
300 String s = getCRC32(s2);
303 int ill3 = payload_temp.length() - sb.length();
304 for (int ir = 0; ir < ill3; ir++) {
308 return sb.toString();
310 private String getCRC32(String s){
311 return getCRC32(String2Byte(s),1);
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];
318 byte crc32[] = new byte[4];
320 // Initialize shift register's to '1'
321 java.util.Arrays.fill(shift_reg, 1);
323 // Calculate nr of data bits, summa of bits
324 int nr_bits = (data.length - offset) * 8;
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;
330 if ((bit_in_byte &= 7) == 0) {
334 // Perform the shift and modula 2 addition
335 data_bit ^= shift_reg[31];
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];
341 shift_reg[0] = data_bit;
344 for (int i = 0; i < 32; i++) {
345 crc = ((crc << 1) | (shift_reg[31 - i]));
348 for (int i = 0; i < 4; i++) {
349 crc32[i] = (byte) (0xFF & (crc >>> ((3 - i) * 8)));
351 String s=Long2String(crc, 32);
355 private String addzero(int num){
376 StringBuffer sb=new StringBuffer();
377 for (int i=0;i<num;i++){
380 return sb.toString();
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()));
393 return sb.toString();
395 private String byte2String2(byte[] b){
399 StringBuffer sb=new StringBuffer();
400 for (int i=0;i<bl;i++){
402 for (int j=0;j<8;j++){
404 int ri=b[i*8+j]&0xFF;
407 sb.append(Long2String(retl,64));
411 for (int i=0;i<bl2;i++){
413 for (int j=0;j<4;j++){
415 reti=reti+(b[bl*8+4*i+j]&0xFF);
417 sb.append(Int2String(reti,32));
419 for (int i=0;i<(b.length%8)%4;i++){
420 sb.append(Int2String(b[bl*8+bl2*4+i]&0xFF,8));
422 return sb.toString();
425 private String byte2HexString(byte[] b) {
427 for (int i = 0; i < b.length; i++) {
428 ret = ret + Integer.toHexString(b[i] & 0xFF);
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);
439 byte[] test2 = String2Byte(ans);
441 CRC32 crc = new CRC32();
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));
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));
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));
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));
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++) {
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++) {
491 private byte[] String2Byte(String ts) {
492 //StringBuffer sb=new StringBuffer(ts);
493 int len = ts.length() - ts.length() % 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);
504 public ArrayList<PATData> getPAT() {
508 public void setPAT(ArrayList pat) {
513 public ArrayList<PMTData> getPMT() {
517 public void setPMT(ArrayList pmt) {
521 public int getPID() {
524 public String getPayload(byte[] ts){
526 * 188バイトのtsから読み出したbyteを与える
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);
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)) {
546 ret_payload = tsbyte.substring(48 + al);
551 public ArrayList<PMTData> readPMT(byte[] ts,int TABLE_NUM){
552 String payload=getPayload(ts);
553 return readPMT(payload, TABLE_NUM);
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));
570 System.out.println("Length:" + Integer.toString(ts.length()));