libepg.epg.section.sectionreconstructor.SectionReconstructor.java Source code

Java tutorial

Introduction

Here is the source code for libepg.epg.section.sectionreconstructor.SectionReconstructor.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.epg.section.sectionreconstructor;

import java.lang.invoke.MethodHandles;
import java.nio.ByteBuffer;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import libepg.epg.section.Section;
import libepg.epg.section.Section.CRC_STATUS;
import libepg.epg.section.TABLE_ID;
import libepg.ts.packet.TsPacket;
import libepg.ts.packet.TsPacketParcel;
import epgtools.loggerfactory.LoggerFactory;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.logging.Log;

/**
 * ??pid??TS???
 *
 * TS???????????????
 * payload_unit_start_indicator?1???TS4???(????????)????(1?)??
 *
 * 1:payload_unit_start_indicator?1?????0?????2??????payload_unit_start_indicator?1??????1<br>
 * 2:payload_unit_start_indicator?1?????0?????2??????????????<br>
 * ???+1??????<br>
 * 3:payload_unit_start_indicator?0??????????????<br>
 *
 * payload_unit_start_indicator?0???????? ????
 *
 *
 * PID ???? PSI ???? payload_unit_start_indicator ??
 * adaptation_field_control ? pointer_field ? data_byte ??????
 * ?payload_unit_start_indicator ? 1 ???? payload ?????????
 * pointer_field ???
 *
 * @author normal
 */
public final class SectionReconstructor {

    /**
     * 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, SectionReconstructor.CLASS_LOG_OUTPUT_MODE).getLOG();
    }

    private final List<TsPacketParcel> parcels;
    private final int pid;

    /**
     * @param parcels ????
     * @param pid ?pid
     * @throws IllegalArgumentException ??pid?pid?????????
     */
    public SectionReconstructor(List<TsPacketParcel> parcels, int pid) throws IllegalArgumentException {
        this.pid = pid;
        List<TsPacketParcel> tempParcels = new ArrayList<>();
        tempParcels.addAll(parcels);
        for (TsPacketParcel parcel : tempParcels) {
            if (this.pid == parcel.getPacket().getPid()) {
            } else {
                MessageFormat WRONG_PID = new MessageFormat(
                        "??Pid?Pid???????????Pid={0} ={1}");
                Object[] parameters = { Integer.toHexString(this.getPid()), parcel.getPacket().toString() };
                throw new IllegalArgumentException(WRONG_PID.format(parameters));
            }
        }
        this.parcels = Collections.unmodifiableList(tempParcels);
    }

    public int getPid() {
        return pid;
    }

    /**
     * getSectionByteArrays()??????????CRC????????
     *
     * @return ?
     */
    public synchronized Set<Section> getSections() {
        Set<byte[]> section_byte = this.getSectionByteArrays();
        Set<Section> ret = new HashSet<>();
        for (byte[] b : section_byte) {
            final Section sec;
            Section s_t = null;
            try {
                s_t = new Section(b);
            } catch (IllegalArgumentException e) {
                LOG.warn(
                        "??????????????",
                        e);
                s_t = null;
            } finally {
                sec = s_t;
            }
            if (sec != null) {
                if (sec.checkCRC() == CRC_STATUS.NO_CRC_ERROR) {
                    ret.add(sec);
                } else {
                    LOG.warn("CRC?????????????");
                }
            }
        }
        return Collections.unmodifiableSet(ret);
    }

    /**
     * ??????? ??????????????????
     *
     * @return ???
     *
     */
    public synchronized Set<byte[]> getSectionByteArrays() {

        Set<byte[]> ret = new TreeSet<>((byte[] left, byte[] right) -> {
            for (int i = 0, j = 0; i < left.length && j < right.length; i++, j++) {
                int a = (left[i] & 0xff);
                int b = (right[j] & 0xff);
                if (a != b) {
                    return a - b;
                }
            }
            return left.length - right.length;
        });

        boolean first_start_indicator_found = false;

        ByteBuffer buf = null;

        PayLoadSplitter splitter = new PayLoadSplitter();

        for (TsPacketParcel parcel : parcels) {

            splitter.setPacket(parcel.getPacket());
            Map<PayLoadSplitter.PAYLOAD_PART_KEY, byte[]> t_map = splitter.getSplittedPayLoad();

            if ((buf == null)
                    || (parcel.isMissingJustBefore() == TsPacketParcel.MISSING_PACKET_FLAG.MISSING_JUST_BEFORE)) {
                if (LOG.isTraceEnabled()) {
                    LOG.trace(
                            "?????????????????????????");
                }
                if (buf == null) {
                    buf = ByteBuffer.allocate(TABLE_ID.MAX_SECTION_LENGTH.BYTE_4093.getMaxSectionLength());
                } else {
                    buf.clear();
                }
            }
            if (LOG.isTraceEnabled()) {
                LOG.trace("?=" + Hex.encodeHexString(buf.array()));
            }
            if ((first_start_indicator_found == false) && (parcel.getPacket()
                    .getPayload_unit_start_indicator() == TsPacket.PAYLOAD_UNIT_START_INDICATOR.START_PES_OR_START_SECTION)) {
                if (LOG.isTraceEnabled()) {
                    LOG.trace("??");
                }
                first_start_indicator_found = true;
            }

            if (first_start_indicator_found == false) {
                if (LOG.isTraceEnabled()) {
                    LOG.trace(
                            "?????????");
                }
            } else if (parcel.getPacket()
                    .getPayload_unit_start_indicator() == TsPacket.PAYLOAD_UNIT_START_INDICATOR.START_PES_OR_START_SECTION) {
                if (LOG.isTraceEnabled()) {
                    LOG.trace(
                            "??????????");
                }
                if (buf.position() == 0) {
                    if (LOG.isTraceEnabled()) {
                        LOG.trace(
                                "??0=?????????->??2?????????????+1?????");
                    }
                    byte[] temp_array = null;
                    if (t_map.size() == 1) {
                        temp_array = t_map.get(PayLoadSplitter.PAYLOAD_PART_KEY.PAYLOAD_AFTER_2_BYTE);
                    } else {
                        temp_array = t_map.get(PayLoadSplitter.PAYLOAD_PART_KEY.NEXT_POINTER);
                    }
                    buf.put(temp_array);
                } else {
                    if (LOG.isTraceEnabled()) {
                        LOG.trace(
                                "??0????=???????->??2???????????\n???????????????+1?????");
                    }
                    byte[] temp_array = null;
                    if (t_map.containsKey(PayLoadSplitter.PAYLOAD_PART_KEY.PAYLOAD_AFTER_2_BYTE)) {
                        if (LOG.isTraceEnabled()) {
                            LOG.trace(
                                    "???????????????");
                        }

                        this.addToReturnObject(buf, ret);

                        buf.clear();

                        temp_array = t_map.get(PayLoadSplitter.PAYLOAD_PART_KEY.PAYLOAD_AFTER_2_BYTE);
                        buf.put(temp_array);
                    } else {
                        if (LOG.isTraceEnabled()) {
                            LOG.trace(
                                    "??????????????????");
                        }
                        temp_array = t_map.get(PayLoadSplitter.PAYLOAD_PART_KEY.PREV_POINTER);
                        buf.put(temp_array);

                        this.addToReturnObject(buf, ret);

                        buf.clear();

                        temp_array = t_map.get(PayLoadSplitter.PAYLOAD_PART_KEY.NEXT_POINTER);
                        buf.put(temp_array);
                    }
                }
            } else {
                if (LOG.isTraceEnabled()) {
                    LOG.trace(
                            "?????->????->??????");
                }
                buf.put(t_map.get(PayLoadSplitter.PAYLOAD_PART_KEY.ALL_PAYLOAD));
            }
        }

        return Collections.unmodifiableSet(ret);
    }

    /**
     * ??????????????????
     * ByteBuffer?array()????????????????????
     *
     */
    private synchronized void addToReturnObject(ByteBuffer buf, Set<byte[]> dest) {
        byte[] BeforeCutDown = buf.array();
        byte[] AfterCutDown = new byte[buf.position()];
        System.arraycopy(BeforeCutDown, 0, AfterCutDown, 0, AfterCutDown.length);
        if (LOG.isTraceEnabled()) {
            MessageFormat msg1 = new MessageFormat("\n??={0}\n?={1}");
            Object[] parameters1 = { Hex.encodeHexString(BeforeCutDown), Hex.encodeHexString(AfterCutDown) };
            LOG.trace(msg1.format(parameters1));
        }
        if (dest.add(AfterCutDown)) {
            if (LOG.isTraceEnabled()) {
                MessageFormat msg2 = new MessageFormat("\n???={0}");
                Object[] parameters2 = { Hex.encodeHexString(AfterCutDown) };
                LOG.trace(msg2.format(parameters2));
            }
        } else if (LOG.isTraceEnabled()) {
            MessageFormat msg3 = new MessageFormat("\n???????={0}");
            Object[] parameters3 = { Hex.encodeHexString(AfterCutDown) };
            LOG.trace(msg3.format(parameters3));
        }
    }

}