Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package libepg.ts.packet; import libepg.util.bytearray.ByteConverter; import java.lang.invoke.MethodHandles; import java.text.MessageFormat; import java.util.Arrays; import org.apache.commons.codec.binary.Hex; import org.apache.commons.logging.Log; import epgtools.loggerfactory.LoggerFactory; import libepg.util.bytearray.ByteDataBlock; /** * TS?????? */ public class TsPacket { /** * false????????????? */ public static final boolean CLASS_LOG_OUTPUT_MODE = true; private static final Log LOG; static { final Class<?> myClass = MethodHandles.lookup().lookupClass(); LOG = new LoggerFactory(myClass, TsPacket.CLASS_LOG_OUTPUT_MODE).getLOG(); } /** * ?(TS???1??) */ public static final int TS_SYNC_BYTE = 0x47; /** * TS??? */ public static enum TS_PACKET_BYTE_LENGTH { /** * TS */ PACKET_LENGTH(188), /** * TS */ HEADER_LENGTH(4); private final int byteLength; private TS_PACKET_BYTE_LENGTH(int length) { this.byteLength = length; } /** * @return TS??? */ public int getByteLength() { return byteLength; } } private final ByteDataBlock data; /** * TS??? * * @param data TS? * @throws IllegalArgumentException ?188?????? */ public TsPacket(final byte[] data) throws IllegalArgumentException { byte[] temp = Arrays.copyOf(data, data.length); if (temp.length != TsPacket.TS_PACKET_BYTE_LENGTH.PACKET_LENGTH.getByteLength()) { MessageFormat msg = new MessageFormat( "????????={0} ?={1}"); Object[] parameters = { temp.length, Hex.encodeHexString(temp) }; throw new IllegalArgumentException(msg.format(parameters)); } this.data = new ByteDataBlock(temp); } /** * ????????<br> * ???????????????<br> * * @return ???true?????false * * @see TsPacket#getSync_byte() * @see TsPacket#getTransport_error_indicator() * @see TsPacket#getPayload_unit_start_indicator() * @see TsPacket#getTransport_priority() * @see TsPacket#getPid() * @see TsPacket#getTransport_scrambling_control() * @see TsPacket#getAdaptation_field_control() * @see TsPacket#getContinuity_counter() * */ public synchronized boolean checkHeader() { try { this.getSync_byte(); this.getTransport_error_indicator(); this.getPayload_unit_start_indicator(); this.getTransport_priority(); this.getPid(); this.getTransport_scrambling_control(); this.getAdaptation_field_control(); this.getContinuity_counter(); return true; } catch (IllegalStateException ex) { LOG.warn(ex); return false; } } /** * ??? * * @return ? */ public synchronized byte[] getData() { return data.getData(); } /** * sync_byte(?) * * @return * @throws IllegalStateException ????(0x47)???? */ public synchronized int getSync_byte() throws IllegalStateException { int temp = ByteConverter.byteToInt(this.data.getData()[0]); if (temp == TsPacket.TS_SYNC_BYTE) { return temp; } else { MessageFormat msg = new MessageFormat("?????={0}"); Object[] parameters = { Integer.toHexString(temp) }; throw new IllegalStateException(msg.format(parameters)); } } /** * transport_error_indicator(?) * 1???????1?????TS????? * * @return ? * @throws IllegalStateException ????(0,1)???? */ public synchronized int getTransport_error_indicator() throws IllegalStateException { int temp; temp = ByteConverter.byteToInt(this.data.getData()[1]); temp = temp >>> 7; if ((temp == 0) || (temp == 1)) { return temp; } else { MessageFormat msg = new MessageFormat( "?????={0}"); Object[] parameters = { temp }; throw new IllegalStateException(msg.format(parameters)); } } /** * ? */ public static enum PAYLOAD_UNIT_START_INDICATOR { /** * ?=1<br> * ????PES?????PIS???<br> */ START_PES_OR_START_SECTION(1), /** * ?=0 <br> * ????PES???????PIS??????<br> */ NOT_START_POINT(0); private final int value; private PAYLOAD_UNIT_START_INDICATOR(int value) { this.value = value; } /** * @return ? */ public int getValue() { return value; } } /** * payload_unit_start_indicator()<br> * 1??????PES?????PIS???????????(?)<br> * ??0??????????1?????<br> * ??(ID)?0xFF????<br> * * @return ????? * @throws IllegalStateException ????(0,1)???? */ public synchronized PAYLOAD_UNIT_START_INDICATOR getPayload_unit_start_indicator() throws IllegalStateException { int temp; temp = ByteConverter.byteToInt(this.data.getData()[1]); temp = temp & 0x40; temp = temp >>> 6; switch (temp) { case 0: return TsPacket.PAYLOAD_UNIT_START_INDICATOR.NOT_START_POINT; case 1: return TsPacket.PAYLOAD_UNIT_START_INDICATOR.START_PES_OR_START_SECTION; } MessageFormat msg = new MessageFormat( "?????={0}"); Object[] parameters = { temp }; throw new IllegalStateException(msg.format(parameters)); } /** * transport_priority(?) ??PID????????1?? * * @return * @throws IllegalStateException ????(0,1)???? */ public synchronized int getTransport_priority() throws IllegalStateException { int temp; temp = ByteConverter.byteToInt(this.data.getData()[1]); temp = temp & 0x20; temp = temp >>> 5; if ((temp == 0) || (temp == 1)) { return temp; } else { MessageFormat msg = new MessageFormat("??????={0}"); Object[] parameters = { temp }; throw new IllegalStateException(msg.format(parameters)); } } /** * PID(ID) * * @return * @throws IllegalStateException ????(0x00000x1FFF?)???? */ public synchronized int getPid() throws IllegalStateException { byte[] t = new byte[2]; System.arraycopy(this.data.getData(), 1, t, 0, t.length); int temp = ByteConverter.bytesToInt(t); temp = temp & 0x1FFF; if ((temp >= 0x0000) && (temp <= 0x1FFF)) { return temp; } else { MessageFormat msg = new MessageFormat("PID(ID)?????={0}"); Object[] parameters = { temp }; throw new IllegalStateException(msg.format(parameters)); } } /** * ? */ public static enum TRANSPORT_SCRAMBLING_CONTROL { /** * ?? */ NOT_SCRAMBLED(0), /** * */ RESERVED(1), /** * ?? */ SCRAMBLED_BY_EVEN_KEY(2), /** * ? */ SCRAMBLED_BY_ODD_KEY(3); private final int value; private TRANSPORT_SCRAMBLING_CONTROL(int value) { this.value = value; } /** * @return ?? */ public int getValue() { return value; } } /** * transport_scrambling_control(?) * * @return * @throws IllegalStateException ????(03?)???? */ public synchronized TRANSPORT_SCRAMBLING_CONTROL getTransport_scrambling_control() throws IllegalStateException { int temp; temp = ByteConverter.byteToInt(this.data.getData()[3]); temp = temp >>> 6; switch (temp) { case 0: return TsPacket.TRANSPORT_SCRAMBLING_CONTROL.NOT_SCRAMBLED; case 1: return TsPacket.TRANSPORT_SCRAMBLING_CONTROL.RESERVED; case 2: return TsPacket.TRANSPORT_SCRAMBLING_CONTROL.SCRAMBLED_BY_EVEN_KEY; case 3: return TsPacket.TRANSPORT_SCRAMBLING_CONTROL.SCRAMBLED_BY_ODD_KEY; } MessageFormat msg = new MessageFormat( "??????={0}"); Object[] parameters = { temp }; throw new IllegalStateException(msg.format(parameters)); } /** * ? */ public static enum ADAPTATION_FIELD_CONTROL { /** * 0:????? */ RESERVED(0), /** * 1:?????? */ ONLY_PAYLOAD(1), /** * 2:?????? ? */ ONLY_ADAPTATION_FIELD(2), /** * 3:?(??) */ BOTH_EXIST(3); private final int fieldControl; private ADAPTATION_FIELD_CONTROL(int fieldControl) { this.fieldControl = fieldControl; } /** * Get the value of fieldControl * * @return the value of fieldControl */ public int getFieldControl() { return fieldControl; } } /** * adaptation_field_control() * * @return ????? * @throws IllegalStateException ????(0,1,2,3)???? */ public synchronized ADAPTATION_FIELD_CONTROL getAdaptation_field_control() throws IllegalStateException { int temp; temp = ByteConverter.byteToInt(this.data.getData()[3]); temp = temp & 0x30; temp = temp >>> 4; switch (temp) { case 0: return TsPacket.ADAPTATION_FIELD_CONTROL.RESERVED; case 1: return TsPacket.ADAPTATION_FIELD_CONTROL.ONLY_PAYLOAD; case 2: return TsPacket.ADAPTATION_FIELD_CONTROL.ONLY_ADAPTATION_FIELD; case 3: return TsPacket.ADAPTATION_FIELD_CONTROL.BOTH_EXIST; } MessageFormat msg = new MessageFormat( "?????={0}"); Object[] parameters = { temp }; throw new IllegalStateException(msg.format(parameters)); } /** * continuity_control() MPEG-2 TS???????<br> * 015???MPEG-2 TS?1??????? <br> * ?????????? MPEG-2 TS???????0??<br> * ???TS????????????????????<br> * ??2??????<br> * * @return ? * @throws IllegalStateException ????(015?)???? */ public synchronized int getContinuity_counter() throws IllegalStateException { int temp; temp = ByteConverter.byteToInt(this.data.getData()[3]); temp = temp & 0x0F; if ((temp >= 0) && (temp <= 15)) { return temp; } else { MessageFormat msg = new MessageFormat("?????={0}"); Object[] parameters = { temp }; throw new IllegalStateException(msg.format(parameters)); } } /** * ?????????(?)?<br> * * @return ?????0 * */ private int getAdaptation_length() { switch (this.getAdaptation_field_control()) { case ONLY_ADAPTATION_FIELD: case BOTH_EXIST: //? int temp = ByteConverter.byteToInt(this.data.getData()[4]); // LOG.debug(temp); // LOG.debug(TsPacket.TS_PACKET_BYTE_LENGTH.PACKET_LENGTH.getByteLength() - TsPacket.TS_PACKET_BYTE_LENGTH.HEADER_LENGTH.getByteLength()); // LOG.debug(TsPacket.TS_PACKET_BYTE_LENGTH.PACKET_LENGTH.getByteLength() - temp); if ((temp < (TsPacket.TS_PACKET_BYTE_LENGTH.PACKET_LENGTH.getByteLength() - TsPacket.TS_PACKET_BYTE_LENGTH.HEADER_LENGTH.getByteLength())) && (TsPacket.TS_PACKET_BYTE_LENGTH.PACKET_LENGTH.getByteLength() - temp) > 6) { } else { //???????????????????? //?????????????????8???(FF????????) temp = temp / 8; } return temp; default: return 0; } } /** * (??)?5???????<br> * 5??(?)?6??????<br> * * @return ????byte[] ={0}; */ public synchronized byte[] getAdaptation_field() { byte dummy[] = { 0 }; int field_length = this.getAdaptation_length(); if (field_length > 0) { //???? field_length++; byte[] buf = new byte[field_length]; System.arraycopy(this.data.getData(), 4, buf, 0, buf.length); return buf; } else { return dummy; } } /** * * @return * */ private int getPayload_length() { //?????0? if (getAdaptation_field_control() == TsPacket.ADAPTATION_FIELD_CONTROL.ONLY_ADAPTATION_FIELD) { return 0; } else { int length = 0; switch (this.getAdaptation_field_control()) { case ONLY_PAYLOAD: //?? length = this.data.length() - TsPacket.TS_PACKET_BYTE_LENGTH.HEADER_LENGTH.getByteLength(); break; case BOTH_EXIST: //?? length = this.data.length() - TsPacket.TS_PACKET_BYTE_LENGTH.HEADER_LENGTH.getByteLength() - this.getAdaptation_length(); break; } return length; } } /** * * @return ??????????byte [] ={0}; */ public synchronized byte[] getPayload() { byte dummy[] = { 0 }; int field_length = this.getPayload_length(); if (field_length > 0) { byte[] buf = new byte[field_length]; switch (this.getAdaptation_field_control()) { case ONLY_PAYLOAD: //?? System.arraycopy(this.data.getData(), 4, buf, 0, buf.length); break; case BOTH_EXIST: //?? System.arraycopy(this.data.getData(), 4 + this.getAdaptation_length(), buf, 0, buf.length); break; } return buf; } else { return dummy; } } /** * ?????? * * @return ??? */ private static final MessageFormat PACKET_DESC = new MessageFormat("? = {0}\n" + "? = {1}\n" + "? = {2}\n" + " = {3}\n" + "? = {4}\n" + "ID = {5}\n" + "? = {6}\n" + " = {7}\n" + " = {8}\n" + " = {9}\n" + " = {10}\n" + " = {11}\n" + "? = {12}\n"); @Override public String toString() { Object[] parameters = { this.data.toString(), Integer.toHexString(this.getSync_byte()), this.getTransport_error_indicator(), this.getPayload_unit_start_indicator(), this.getTransport_priority(), Integer.toHexString(this.getPid()), this.getTransport_scrambling_control(), this.getAdaptation_field_control(), this.getContinuity_counter(), this.getAdaptation_length(), Hex.encodeHexString(this.getAdaptation_field()), Hex.encodeHexString(this.getPayload()), this.hashCode() }; return PACKET_DESC.format(parameters); } /** * @return * ?????????????????????????????????????true */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final TsPacket other = (TsPacket) obj; return this.data.equals(other.data); } @Override public int hashCode() { int hash = 7; return 79 * hash + this.data.hashCode(); } }