libepg.ts.packet.TsPacket.java Source code

Java tutorial

Introduction

Here is the source code for libepg.ts.packet.TsPacket.java

Source

/*
 * 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();
    }

}