Search in sources :

Example 1 with AvcResult

use of com.feeyo.hls.ts.segmenter.H264TsSegmenter.AvcResult in project feeyo-hlsserver by variflight.

the class AacH264MixedTsSegmenter method writeFrame.

private void writeFrame() {
    if (isTailAvc)
        return;
    while (!avcResultDeque.isEmpty()) {
        AvcResult result = avcResultDeque.pop();
        for (FrameData avcFrame : result.avcFrames) avcFrameCache.offer(avcFrame);
        if (result.isTailAvc) {
            isTailAvc = true;
            break;
        }
    }
    while (!aacFrameCache.isEmpty() && !avcFrameCache.isEmpty()) {
        FrameData avcFrame = avcFrameCache.peek();
        if (aacFrameCache.peek().pts < avcFrame.pts) {
            FrameData frameData = aacFrameCache.pop();
            byte[] aacTsSegment = tsWriter.write(isFirstAacPes, FrameDataType.MIXED, frameData);
            if (aacTsSegment != null) {
                tsSegmentLen += aacTsSegment.length;
                tsSecs[tsSecsPtr++] = aacTsSegment;
            }
            isFirstAacPes = false;
            maxAacPts = maxAacPts > frameData.pts ? maxAacPts : frameData.pts;
            mixPts = mixPts > maxAacPts ? mixPts : maxAacPts;
        } else {
            FrameData frameData = avcFrameCache.pop();
            byte[] avcTsSegment = tsWriter.write(isFirstAvcPes, FrameDataType.MIXED, frameData);
            if (avcTsSegment != null) {
                tsSegmentLen += avcTsSegment.length;
                tsSecs[tsSecsPtr++] = avcTsSegment;
            }
            isFirstAvcPes = false;
            maxAvcPts = maxAvcPts > frameData.pts ? maxAvcPts : frameData.pts;
            mixPts = mixPts > maxAvcPts ? mixPts : maxAvcPts;
        }
    }
    waitAac = (aacFrameCache.isEmpty() && maxAacPts + aacTsSegmenter.getPtsIncPerFrame() < maxAvcPts + h264TsSegmenter.getPtsIncPerFrame());
}
Also used : AvcResult(com.feeyo.hls.ts.segmenter.H264TsSegmenter.AvcResult) FrameData(com.feeyo.mpeg2ts.TsWriter.FrameData)

Example 2 with AvcResult

use of com.feeyo.hls.ts.segmenter.H264TsSegmenter.AvcResult in project feeyo-hlsserver by variflight.

the class AacH264MixedTsSegmenter method segment.

/**
 * @param V5PacketType.AAC_STREAM -> rawData is a full-frame accData
 * 		  V5PacketType.H264_STREAM -> rawData is h264 byte dataStream
 */
@Override
protected byte[] segment(byte rawDataType, byte[] rawData, byte[] reserved) {
    if (reserved.length != 8) {
        LOGGER.error("## Reserved area doesn't contain index!");
        return null;
    }
    if (ctime == 0) {
        headFrameType = rawDataType;
        ctime = System.currentTimeMillis();
    }
    // from 0
    long index = ByteUtil.bytesToLong(reserved[0], reserved[1], reserved[2], reserved[3], reserved[4], reserved[5], reserved[6], reserved[7]);
    switch(rawDataType) {
        case V5PacketType.AAC_STREAM:
            if (headFrameType != V5PacketType.AAC_STREAM && !syncPtsBase) {
                aacTsSegmenter.setPts((System.currentTimeMillis() - ctime) * 90);
                syncPtsBase = true;
            }
            if (index == preAacIndex + 1) {
                preAacIndex++;
                skipAac = false;
                FrameData aacFrame = aacTsSegmenter.process(rawData);
                if (aacFrame != null)
                    aacFrameCache.offer(aacFrame);
                preAacCTime = System.currentTimeMillis();
            } else if (index > preAacIndex + 1) {
                try {
                    while (!aacLocking.compareAndSet(false, true)) {
                    }
                    aacRawCache.add(new RawItem(rawData, index));
                    Collections.sort(aacRawCache, new RawDescComparator());
                    skipAac = true;
                } finally {
                    aacLocking.set(false);
                }
            }
            while (!aacRawCache.isEmpty() && aacRawCache.get(0).index == preAacIndex + 1) {
                preAacIndex++;
                skipAac = false;
                FrameData aacFrame = aacTsSegmenter.process(aacRawCache.remove(0).rawData);
                if (aacFrame != null)
                    aacFrameCache.offer(aacFrame);
                preAacCTime = System.currentTimeMillis();
            }
            if (waitAac)
                writeFrame();
            break;
        case V5PacketType.H264_STREAM:
            try {
                while (!avcLocking.compareAndSet(false, true)) {
                }
                if (headFrameType != V5PacketType.H264_STREAM && !syncPtsBase) {
                    h264TsSegmenter.setPts((System.currentTimeMillis() - ctime) * 90);
                    syncPtsBase = true;
                }
                if (index == preAvcIndex + 1) {
                    skipAvc = false;
                    preAvcIndex = index;
                    AvcResult avcResult = h264TsSegmenter.process(rawData);
                    if (avcResult != null)
                        avcResultDeque.offer(avcResult);
                    preAvcCTime = System.currentTimeMillis();
                } else if (index > preAvcIndex + 1) {
                    avcRawCache.add(new RawItem(rawData, index));
                    Collections.sort(avcRawCache, new RawDescComparator());
                    skipAvc = true;
                }
                while (!avcRawCache.isEmpty() && avcRawCache.get(0).index == preAvcIndex + 1) {
                    preAvcIndex++;
                    skipAvc = false;
                    AvcResult avcResult = h264TsSegmenter.process(avcRawCache.remove(0).rawData);
                    if (avcResult != null)
                        avcResultDeque.offer(avcResult);
                    preAvcCTime = System.currentTimeMillis();
                }
                if (isTailAvc && !waitAac) {
                    if (tsSecs[0] == null)
                        return null;
                    tsSegTime = (mixPts - ptsBase) / 90000F;
                    isTailAvc = false;
                    // Consider video in 10 seconds.
                    if (!isLowTenSec && tsSecs[0] != null && tsSegTime < 10F && System.currentTimeMillis() - ctime > 60 * 1000) {
                        isLowTenSec = true;
                        return write2Ts();
                    }
                    return tsSecs[0] == null || tsSegTime < 10F ? null : write2Ts();
                }
                while (!avcResultDeque.isEmpty()) {
                    writeFrame();
                    if (isTailAvc && !waitAac) {
                        while (!avcFrameCache.isEmpty()) {
                            if (avcFrameCache.isEmpty())
                                break;
                            while (!waitAac) {
                                if (avcFrameCache.isEmpty())
                                    break;
                                FrameData frameData = avcFrameCache.pop();
                                byte[] aacTsSegment = tsWriter.write(isFirstAvcPes, FrameDataType.MIXED, frameData);
                                if (aacTsSegment != null) {
                                    tsSegmentLen += aacTsSegment.length;
                                    tsSecs[tsSecsPtr++] = aacTsSegment;
                                }
                                isFirstAvcPes = false;
                                mixPts = mixPts > frameData.pts ? mixPts : frameData.pts;
                                waitAac = (aacFrameCache.isEmpty() && maxAacPts + aacTsSegmenter.getPtsIncPerFrame() < maxAvcPts + h264TsSegmenter.getPtsIncPerFrame());
                            }
                        }
                        tsSegTime = (mixPts - ptsBase) / 90000F;
                        isTailAvc = false;
                        // Consider video in 10 seconds.
                        if (!isLowTenSec && tsSecs[0] != null && tsSegTime < 10F && System.currentTimeMillis() - ctime > 60 * 1000) {
                            isLowTenSec = true;
                            return write2Ts();
                        }
                        return tsSegTime < 10F ? null : write2Ts();
                    }
                }
            } finally {
                avcLocking.set(false);
            }
            break;
    }
    return null;
}
Also used : AvcResult(com.feeyo.hls.ts.segmenter.H264TsSegmenter.AvcResult) FrameData(com.feeyo.mpeg2ts.TsWriter.FrameData)

Aggregations

AvcResult (com.feeyo.hls.ts.segmenter.H264TsSegmenter.AvcResult)2 FrameData (com.feeyo.mpeg2ts.TsWriter.FrameData)2