use of com.feeyo.mpeg2ts.TsWriter.FrameData in project feeyo-hlsserver by variflight.
the class TsWriterTest method main.
public static void main(String[] args) {
byte[] buf1 = readTsFile("/Users/zhuam/git/feeyo/feeyostreamhls/testdata/ec6d6ac2-283c-4f86-bbb3-ea4e03a214bf.ts");
//
TsReader tsReader = new TsReader();
int frameLength = 0;
int audioFrameLength = 0;
int videoFrameLength = 0;
Ts[] tsPackets = tsReader.parseTsPacket(buf1);
for (int i = 0; i < tsPackets.length; i++) {
Ts ts = tsPackets[i];
if (ts instanceof Pes) {
Pes pes = (Pes) ts;
if (pes.payload_unit_start_indicator == 1) {
frameLength++;
if (pes.stream_id == Ts.AUDIO_STREAM_ID) {
audioFrameLength++;
} else {
videoFrameLength++;
}
}
}
}
//
FrameData[] frames = new FrameData[frameLength];
int frameIdx = 0;
int currentFrameIdx = 0;
for (int i = 0; i < tsPackets.length; i++) {
Ts ts = tsPackets[i];
if (ts instanceof Pes) {
Pes pes = (Pes) ts;
if (pes.payload_unit_start_indicator == 1) {
currentFrameIdx = frameIdx;
frames[currentFrameIdx] = new FrameData();
frames[currentFrameIdx].buf = append(frames[currentFrameIdx].buf, pes.es_data, 0, pes.es_data.length);
frames[currentFrameIdx].dts = pes.dts;
frames[currentFrameIdx].pts = pes.pts;
frames[currentFrameIdx].isAudio = (pes.stream_id == Ts.AUDIO_STREAM_ID);
frameIdx++;
} else {
frames[currentFrameIdx].buf = append(frames[currentFrameIdx].buf, pes.es_data, 0, pes.es_data.length);
}
}
}
TsWriter tsWriter1 = new TsWriter();
byte[] tsFileBuf = tsWriter1.write(true, FrameDataType.MIXED, frames);
// System.out.println( bytesToHexString( tsFileBuf, 0, tsFileBuf.length));
// mix
writeTsFile("/Users/zhuam/git/feeyo/feeyostreamhls/testdata/test1.ts", tsFileBuf);
int audioFrameIndex = 0;
FrameData[] audioFrames = new FrameData[audioFrameLength];
int videoFrameIndex = 0;
FrameData[] videoFrames = new FrameData[videoFrameLength];
for (int i = 0; i < frames.length; i++) {
FrameData frame = frames[i];
if (frame.isAudio) {
audioFrames[audioFrameIndex] = frame;
audioFrameIndex++;
} else {
videoFrames[videoFrameIndex] = frame;
videoFrameIndex++;
}
}
TsWriter tsWriter2 = new TsWriter();
// long lastPts = 90000;
// for(int i = 0; i < audioFrames.length; i++) {
//
// long pts = (90000L * 1024) / 8000;
// AvStreamFrame frame = audioFrames[i];
// lastPts += pts;
// frame.pts = lastPts;
// }
byte[] tsFileBuf2 = tsWriter2.write(true, FrameDataType.AUDIO, audioFrames);
writeTsFile("/Users/zhuam/git/feeyo/feeyostreamhls/testdata/test2.ts", tsFileBuf2);
TsWriter tsWriter3 = new TsWriter();
byte[] tsFileBuf3 = tsWriter3.write(true, FrameDataType.VIDEO, videoFrames);
writeTsFile("/Users/zhuam/git/feeyo/feeyostreamhls/testdata/test3.ts", tsFileBuf3);
}
use of com.feeyo.mpeg2ts.TsWriter.FrameData in project feeyo-hlsserver by variflight.
the class TsWriterTest2 method main.
public static void main(String[] args) {
byte[] buf1 = readTsFile("/Users/zhuam/git/feeyo/feeyostreamhls/testdata/10844.ts");
//
TsReader tsReader = new TsReader();
int frameLength = 0;
Ts[] tsPackets = tsReader.parseTsPacket(buf1);
for (int i = 0; i < tsPackets.length; i++) {
Ts ts = tsPackets[i];
if (ts instanceof Pes) {
Pes pes = (Pes) ts;
if (pes.payload_unit_start_indicator == 1) {
frameLength++;
}
}
}
//
FrameData[] frames = new FrameData[frameLength];
int frameIdx = 0;
int currentFrameIdx = 0;
for (int i = 0; i < tsPackets.length; i++) {
Ts ts = tsPackets[i];
if (ts instanceof Pes) {
Pes pes = (Pes) ts;
if (pes.payload_unit_start_indicator == 1) {
currentFrameIdx = frameIdx;
frames[currentFrameIdx] = new FrameData();
frames[currentFrameIdx].buf = append(frames[currentFrameIdx].buf, pes.es_data, 0, pes.es_data.length);
frames[currentFrameIdx].dts = pes.dts;
frames[currentFrameIdx].pts = pes.pts;
frames[currentFrameIdx].isAudio = (pes.stream_id == Ts.AUDIO_STREAM_ID);
frameIdx++;
} else {
frames[currentFrameIdx].buf = append(frames[currentFrameIdx].buf, pes.es_data, 0, pes.es_data.length);
}
}
}
TsWriter tsWriter1 = new TsWriter();
byte[] tsFileBuf = tsWriter1.write(true, FrameDataType.AUDIO, frames);
// mix
writeTsFile("/Users/zhuam/git/feeyo/feeyostreamhls/testdata/test222.ts", tsFileBuf);
}
use of com.feeyo.mpeg2ts.TsWriter.FrameData 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());
}
use of com.feeyo.mpeg2ts.TsWriter.FrameData 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;
}
use of com.feeyo.mpeg2ts.TsWriter.FrameData in project feeyo-hlsserver by variflight.
the class AacTsSegmenter method process.
public FrameData process(byte[] rawData) {
if (rawData != null && rawData.length > 0) {
pts += ptsIncPerFrame;
FrameData frameData = new FrameData();
frameData.buf = rawData;
frameData.pts = pts;
frameData.dts = 0;
frameData.isAudio = true;
return frameData;
}
return null;
}