From 425e98c6fd46ae977ac37f840c56cd05c9c27288 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Thu, 1 Nov 2018 16:25:10 +0100 Subject: [PATCH] Fixed TS-output (=HLS) related SIGABRT problem --- src/output/output_ts_base.cpp | 163 ++++++++++++++++++---------------- src/output/output_ts_base.h | 2 - 2 files changed, 86 insertions(+), 79 deletions(-) diff --git a/src/output/output_ts_base.cpp b/src/output/output_ts_base.cpp index ff0c47bd..6df6cff9 100644 --- a/src/output/output_ts_base.cpp +++ b/src/output/output_ts_base.cpp @@ -1,9 +1,9 @@ #include "output_ts_base.h" +#include namespace Mist { TSOutput::TSOutput(Socket::Connection & conn) : TS_BASECLASS(conn){ packCounter=0; - haveAvcc = false; ts_from = 0; setBlocking(true); sendRepeatingHeaders = 0; @@ -48,7 +48,7 @@ namespace Mist { } } - int tmp = packData.fillFree(data, dataLen); + size_t tmp = packData.fillFree(data, dataLen); data += tmp; dataLen -= tmp; } while(dataLen); @@ -67,8 +67,9 @@ namespace Mist { firstPack = true; char * dataPointer = 0; - unsigned int dataLen = 0; - thisPacket.getString("data", dataPointer, dataLen); //data + unsigned int tmpDataLen = 0; + thisPacket.getString("data", dataPointer, tmpDataLen); //data + uint64_t dataLen = tmpDataLen; //apple compatibility timestamp correction if (appleCompat){ packTime -= ts_from; @@ -80,98 +81,106 @@ namespace Mist { std::string bs; //prepare bufferstring if (video){ - unsigned int extraSize = 0; - //dataPointer[4] & 0x1f is used to check if this should be done later: fillPacket("\000\000\000\001\011\360", 6); - if (Trk.codec == "H264" && (dataPointer[4] & 0x1f) != 0x09){ - extraSize += 6; - } - if (keyframe){ - if (Trk.codec == "H264"){ - if (!haveAvcc){ + if (Trk.codec == "H264"){ + unsigned int extraSize = 0; + //dataPointer[4] & 0x1f is used to check if this should be done later: fillPacket("\000\000\000\001\011\360", 6); + if (Trk.codec == "H264" && (dataPointer[4] & 0x1f) != 0x09){ + extraSize += 6; + } + if (keyframe){ + if (Trk.codec == "H264"){ + MP4::AVCC avccbox; avccbox.setPayload(Trk.init); - haveAvcc = true; + bs = avccbox.asAnnexB(); + extraSize += bs.size(); } - bs = avccbox.asAnnexB(); - extraSize += bs.size(); } - } - - unsigned int watKunnenWeIn1Ding = 65490-13; - unsigned int splitCount = (dataLen+extraSize) / watKunnenWeIn1Ding; - unsigned int currPack = 0; - unsigned int ThisNaluSize = 0; - unsigned int i = 0; - unsigned int nalLead = 0; - uint64_t offset = thisPacket.getInt("offset") * 90; + + unsigned int watKunnenWeIn1Ding = 65490-13; + unsigned int splitCount = (dataLen+extraSize) / watKunnenWeIn1Ding; + unsigned int currPack = 0; + uint64_t ThisNaluSize = 0; + unsigned int i = 0; + unsigned int nalLead = 0; + uint64_t offset = thisPacket.getInt("offset") * 90; - while (currPack <= splitCount){ - unsigned int alreadySent = 0; - bs = TS::Packet::getPESVideoLeadIn((currPack != splitCount ? watKunnenWeIn1Ding : dataLen+extraSize - currPack*watKunnenWeIn1Ding), packTime, offset, !currPack, Trk.bps); - fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg); - if (!currPack){ - if (Trk.codec == "H264" && (dataPointer[4] & 0x1f) != 0x09){ - //End of previous nal unit, if not already present - fillPacket("\000\000\000\001\011\360", 6, firstPack, video, keyframe, pkgPid, contPkg); - alreadySent += 6; - } - if (keyframe){ - if (Trk.codec == "H264"){ - bs = avccbox.asAnnexB(); - fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg); - alreadySent += bs.size(); + while (currPack <= splitCount){ + unsigned int alreadySent = 0; + bs = TS::Packet::getPESVideoLeadIn((currPack != splitCount ? watKunnenWeIn1Ding : dataLen+extraSize - currPack*watKunnenWeIn1Ding), packTime, offset, !currPack, Trk.bps); + fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg); + if (!currPack){ + if (Trk.codec == "H264" && (dataPointer[4] & 0x1f) != 0x09){ + //End of previous nal unit, if not already present + fillPacket("\000\000\000\001\011\360", 6, firstPack, video, keyframe, pkgPid, contPkg); + alreadySent += 6; + } + if (keyframe){ + if (Trk.codec == "H264"){ + MP4::AVCC avccbox; + avccbox.setPayload(Trk.init); + bs = avccbox.asAnnexB(); + fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg); + alreadySent += bs.size(); + } } } - } - while (i + 4 < (unsigned int)dataLen){ - if (nalLead){ - fillPacket("\000\000\000\001"+4-nalLead,nalLead, firstPack, video, keyframe, pkgPid, contPkg); - i += nalLead; - alreadySent += nalLead; - nalLead = 0; - } - if (!ThisNaluSize){ - ThisNaluSize = (dataPointer[i] << 24) + (dataPointer[i+1] << 16) + (dataPointer[i+2] << 8) + dataPointer[i+3]; - if (ThisNaluSize + i + 4 > (unsigned int)dataLen){ - DEBUG_MSG(DLVL_WARN, "Too big NALU detected (%u > %d) - skipping!", ThisNaluSize + i + 4, dataLen); - break; + while (i + 4 < (unsigned int)dataLen){ + if (nalLead){ + fillPacket("\000\000\000\001"+4-nalLead,nalLead, firstPack, video, keyframe, pkgPid, contPkg); + i += nalLead; + alreadySent += nalLead; + nalLead = 0; } - if (alreadySent + 4 > watKunnenWeIn1Ding){ - nalLead = 4 - (watKunnenWeIn1Ding-alreadySent); - fillPacket("\000\000\000\001",watKunnenWeIn1Ding-alreadySent, firstPack, video, keyframe, pkgPid, contPkg); + if (!ThisNaluSize){ + ThisNaluSize = Bit::btohl(dataPointer + i); + if (ThisNaluSize + i + 4 > dataLen){ + WARN_MSG("Too big NALU detected (%" PRIu64 " > %" PRIu64 ") - skipping!", ThisNaluSize + i + 4, dataLen); + break; + } + if (alreadySent + 4 > watKunnenWeIn1Ding){ + nalLead = 4 - (watKunnenWeIn1Ding-alreadySent); + fillPacket("\000\000\000\001",watKunnenWeIn1Ding-alreadySent, firstPack, video, keyframe, pkgPid, contPkg); + i += watKunnenWeIn1Ding-alreadySent; + alreadySent += watKunnenWeIn1Ding-alreadySent; + }else{ + fillPacket("\000\000\000\001",4, firstPack, video, keyframe, pkgPid, contPkg); + alreadySent += 4; + i += 4; + } + } + if (alreadySent + ThisNaluSize > watKunnenWeIn1Ding){ + fillPacket(dataPointer+i,watKunnenWeIn1Ding-alreadySent, firstPack, video, keyframe, pkgPid, contPkg); i += watKunnenWeIn1Ding-alreadySent; + ThisNaluSize -= watKunnenWeIn1Ding-alreadySent; alreadySent += watKunnenWeIn1Ding-alreadySent; }else{ - fillPacket("\000\000\000\001",4, firstPack, video, keyframe, pkgPid, contPkg); - alreadySent += 4; - i += 4; + fillPacket(dataPointer+i,ThisNaluSize, firstPack, video, keyframe, pkgPid, contPkg); + alreadySent += ThisNaluSize; + i += ThisNaluSize; + ThisNaluSize = 0; + } + if (alreadySent == watKunnenWeIn1Ding){ + packData.addStuffing(); + fillPacket(0, 0, firstPack, video, keyframe, pkgPid, contPkg); + firstPack = true; + break; } } - if (alreadySent + ThisNaluSize > watKunnenWeIn1Ding){ - fillPacket(dataPointer+i,watKunnenWeIn1Ding-alreadySent, firstPack, video, keyframe, pkgPid, contPkg); - i += watKunnenWeIn1Ding-alreadySent; - ThisNaluSize -= watKunnenWeIn1Ding-alreadySent; - alreadySent += watKunnenWeIn1Ding-alreadySent; - }else{ - fillPacket(dataPointer+i,ThisNaluSize, firstPack, video, keyframe, pkgPid, contPkg); - alreadySent += ThisNaluSize; - i += ThisNaluSize; - ThisNaluSize = 0; - } - if (alreadySent == watKunnenWeIn1Ding){ - packData.addStuffing(); - fillPacket(0, 0, firstPack, video, keyframe, pkgPid, contPkg); - firstPack = true; - break; - } + currPack++; } - currPack++; + }else{ + uint64_t offset = thisPacket.getInt("offset") * 90; + bs = TS::Packet::getPESVideoLeadIn(0, packTime, offset, true, Trk.bps); + fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg); + + fillPacket(dataPointer, dataLen, firstPack, video, keyframe, pkgPid, contPkg); } }else if (Trk.type == "audio"){ long unsigned int tempLen = dataLen; if (Trk.codec == "AAC"){ tempLen += 7; } - bs = TS::Packet::getPESAudioLeadIn(tempLen, packTime, Trk.bps);// myMeta.tracks[thisPacket.getTrackId()].rate / 1000 ); + bs = TS::Packet::getPESAudioLeadIn(tempLen, packTime, Trk.bps); fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg); if (Trk.codec == "AAC"){ bs = TS::getAudioHeader(dataLen, Trk.init); diff --git a/src/output/output_ts_base.h b/src/output/output_ts_base.h index 37e3a4eb..d1b041ef 100644 --- a/src/output/output_ts_base.h +++ b/src/output/output_ts_base.h @@ -25,8 +25,6 @@ namespace Mist { int contSDT; unsigned int packCounter; ///\todo update constructors? TS::Packet packData; - bool haveAvcc; - MP4::AVCC avccbox; bool appleCompat; uint64_t sendRepeatingHeaders; ///< Amount of ms between PAT/PMT. Zero means do not repeat. uint64_t lastHeaderTime; ///< Timestamp last PAT/PMT were sent.