3 import java.util.ArrayList;
4 import java.util.zip.CRC32;
5 import jtssplitter.data.PATData;
6 import jtssplitter.data.PMTData;
8 * To change this template, choose Tools | Templates
9 * and open the template in the editor.
16 public class Mpeg2TSPacket {
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"))
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;
48 private int staffing_byte;//
50 public Mpeg2TSPacket() {
52 public int getPIDFirst(byte[] ts){
56 //String s=byte2String(b);
57 //s=s.substring(3,16);
58 return Integer.parseInt(byte2String(b).substring(3,16),2);
60 public void readTS(byte[] ts) {
62 * 188バイトのtsから読み出したbyteを与える
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);
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;
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);
91 pat_list_now =readPAT(payload);
92 pat_list_all.addAll(pat_list_now);
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));
102 private ArrayList<PATData> readPAT(String payload_temp) {
104 * payloadの文字列を入力して[intテーブル,int PID]のArrayListを返す。
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);
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++) {
125 payload_temp = stest;
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);
133 return program_number;
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);
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;
152 cur_point = cur_point + 40 + es_length * 8;
153 if (cur_point > section_length * 8) {
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);
166 public byte[] splitPAT(byte[] ts, int p_table) {
169 * p_tableで指定された番組テーブルのみを取り出すPATを作る。
172 byte[] tbb=new byte[ts.length-4];
173 for (int i=0;i<ts.length-4;i++){
175 if (bPAT_payload!=null){
176 if (ts[4+i]==bPAT_payload[i]){
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);
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);
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;
211 tsheader = tsbyte.substring(0, 48 + adaptation_length_t);
212 payload = tsbyte.substring(48 + adaptation_length_t);
217 payload = makePAT(tsheader,payload, p_table);
219 String rets = tsheader + payload;
220 return String2Byte(rets);
223 private String makePAT(String tsheader,String payload_temp, int Table) {
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);//ループ前まで
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);
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);
255 String s2=tsheader.substring(tsheader.length()-8);
257 String s = getCRC32(s2);
260 int ill3 = payload_temp.length() - sb.length();
261 for (int ir = 0; ir < ill3; ir++) {
265 return sb.toString();
267 private String getCRC32(String s){
268 return getCRC32(String2Byte(s),1);
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];
275 byte crc32[] = new byte[4];
277 // Initialize shift register's to '1'
278 java.util.Arrays.fill(shift_reg, 1);
280 // Calculate nr of data bits, summa of bits
281 int nr_bits = (data.length - offset) * 8;
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;
287 if ((bit_in_byte &= 7) == 0) {
291 // Perform the shift and modula 2 addition
292 data_bit ^= shift_reg[31];
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];
298 shift_reg[0] = data_bit;
301 for (int i = 0; i < 32; i++) {
302 crc = ((crc << 1) | (shift_reg[31 - i]));
305 for (int i = 0; i < 4; i++) {
306 crc32[i] = (byte) (0xFF & (crc >>> ((3 - i) * 8)));
308 String s=Long2String(crc, 32);
312 private String addzero(int num){
333 StringBuffer sb=new StringBuffer();
334 for (int i=0;i<num;i++){
337 return sb.toString();
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()));
348 String s3=sb2.toString();
351 return sb.toString();
354 private String byte2HexString(byte[] b) {
356 for (int i = 0; i < b.length; i++) {
357 ret = ret + Integer.toHexString(b[i] & 0xFF);
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);
368 byte[] test2 = String2Byte(ans);
370 CRC32 crc = new CRC32();
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));
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));
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));
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));
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++) {
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++) {
420 private byte[] String2Byte(String ts) {
421 //StringBuffer sb=new StringBuffer(ts);
422 int len = ts.length() - ts.length() % 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);
433 public ArrayList getPAT() {
437 public void setPAT(ArrayList pat) {
442 public ArrayList getPMT() {
446 public void setPMT(ArrayList pmt) {
450 public int getPID() {
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));
469 System.out.println("Length:" + Integer.toString(ts.length()));