Fixed TS-output (=HLS) related SIGABRT problem
This commit is contained in:
parent
24006648f9
commit
425e98c6fd
2 changed files with 86 additions and 79 deletions
|
@ -1,9 +1,9 @@
|
||||||
#include "output_ts_base.h"
|
#include "output_ts_base.h"
|
||||||
|
#include <mist/bitfields.h>
|
||||||
|
|
||||||
namespace Mist {
|
namespace Mist {
|
||||||
TSOutput::TSOutput(Socket::Connection & conn) : TS_BASECLASS(conn){
|
TSOutput::TSOutput(Socket::Connection & conn) : TS_BASECLASS(conn){
|
||||||
packCounter=0;
|
packCounter=0;
|
||||||
haveAvcc = false;
|
|
||||||
ts_from = 0;
|
ts_from = 0;
|
||||||
setBlocking(true);
|
setBlocking(true);
|
||||||
sendRepeatingHeaders = 0;
|
sendRepeatingHeaders = 0;
|
||||||
|
@ -48,7 +48,7 @@ namespace Mist {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int tmp = packData.fillFree(data, dataLen);
|
size_t tmp = packData.fillFree(data, dataLen);
|
||||||
data += tmp;
|
data += tmp;
|
||||||
dataLen -= tmp;
|
dataLen -= tmp;
|
||||||
} while(dataLen);
|
} while(dataLen);
|
||||||
|
@ -67,8 +67,9 @@ namespace Mist {
|
||||||
firstPack = true;
|
firstPack = true;
|
||||||
|
|
||||||
char * dataPointer = 0;
|
char * dataPointer = 0;
|
||||||
unsigned int dataLen = 0;
|
unsigned int tmpDataLen = 0;
|
||||||
thisPacket.getString("data", dataPointer, dataLen); //data
|
thisPacket.getString("data", dataPointer, tmpDataLen); //data
|
||||||
|
uint64_t dataLen = tmpDataLen;
|
||||||
//apple compatibility timestamp correction
|
//apple compatibility timestamp correction
|
||||||
if (appleCompat){
|
if (appleCompat){
|
||||||
packTime -= ts_from;
|
packTime -= ts_from;
|
||||||
|
@ -80,98 +81,106 @@ namespace Mist {
|
||||||
std::string bs;
|
std::string bs;
|
||||||
//prepare bufferstring
|
//prepare bufferstring
|
||||||
if (video){
|
if (video){
|
||||||
unsigned int extraSize = 0;
|
if (Trk.codec == "H264"){
|
||||||
//dataPointer[4] & 0x1f is used to check if this should be done later: fillPacket("\000\000\000\001\011\360", 6);
|
unsigned int extraSize = 0;
|
||||||
if (Trk.codec == "H264" && (dataPointer[4] & 0x1f) != 0x09){
|
//dataPointer[4] & 0x1f is used to check if this should be done later: fillPacket("\000\000\000\001\011\360", 6);
|
||||||
extraSize += 6;
|
if (Trk.codec == "H264" && (dataPointer[4] & 0x1f) != 0x09){
|
||||||
}
|
extraSize += 6;
|
||||||
if (keyframe){
|
}
|
||||||
if (Trk.codec == "H264"){
|
if (keyframe){
|
||||||
if (!haveAvcc){
|
if (Trk.codec == "H264"){
|
||||||
|
MP4::AVCC avccbox;
|
||||||
avccbox.setPayload(Trk.init);
|
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;
|
|
||||||
|
|
||||||
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 (i + 4 < (unsigned int)dataLen){
|
|
||||||
if (nalLead){
|
unsigned int watKunnenWeIn1Ding = 65490-13;
|
||||||
fillPacket("\000\000\000\001"+4-nalLead,nalLead, firstPack, video, keyframe, pkgPid, contPkg);
|
unsigned int splitCount = (dataLen+extraSize) / watKunnenWeIn1Ding;
|
||||||
i += nalLead;
|
unsigned int currPack = 0;
|
||||||
alreadySent += nalLead;
|
uint64_t ThisNaluSize = 0;
|
||||||
nalLead = 0;
|
unsigned int i = 0;
|
||||||
}
|
unsigned int nalLead = 0;
|
||||||
if (!ThisNaluSize){
|
uint64_t offset = thisPacket.getInt("offset") * 90;
|
||||||
ThisNaluSize = (dataPointer[i] << 24) + (dataPointer[i+1] << 16) + (dataPointer[i+2] << 8) + dataPointer[i+3];
|
|
||||||
if (ThisNaluSize + i + 4 > (unsigned int)dataLen){
|
while (currPack <= splitCount){
|
||||||
DEBUG_MSG(DLVL_WARN, "Too big NALU detected (%u > %d) - skipping!", ThisNaluSize + i + 4, dataLen);
|
unsigned int alreadySent = 0;
|
||||||
break;
|
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 (alreadySent + 4 > watKunnenWeIn1Ding){
|
if (keyframe){
|
||||||
nalLead = 4 - (watKunnenWeIn1Ding-alreadySent);
|
if (Trk.codec == "H264"){
|
||||||
fillPacket("\000\000\000\001",watKunnenWeIn1Ding-alreadySent, firstPack, video, keyframe, pkgPid, contPkg);
|
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 = 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;
|
i += watKunnenWeIn1Ding-alreadySent;
|
||||||
|
ThisNaluSize -= watKunnenWeIn1Ding-alreadySent;
|
||||||
alreadySent += watKunnenWeIn1Ding-alreadySent;
|
alreadySent += watKunnenWeIn1Ding-alreadySent;
|
||||||
}else{
|
}else{
|
||||||
fillPacket("\000\000\000\001",4, firstPack, video, keyframe, pkgPid, contPkg);
|
fillPacket(dataPointer+i,ThisNaluSize, firstPack, video, keyframe, pkgPid, contPkg);
|
||||||
alreadySent += 4;
|
alreadySent += ThisNaluSize;
|
||||||
i += 4;
|
i += ThisNaluSize;
|
||||||
|
ThisNaluSize = 0;
|
||||||
|
}
|
||||||
|
if (alreadySent == watKunnenWeIn1Ding){
|
||||||
|
packData.addStuffing();
|
||||||
|
fillPacket(0, 0, firstPack, video, keyframe, pkgPid, contPkg);
|
||||||
|
firstPack = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (alreadySent + ThisNaluSize > watKunnenWeIn1Ding){
|
currPack++;
|
||||||
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++;
|
}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"){
|
}else if (Trk.type == "audio"){
|
||||||
long unsigned int tempLen = dataLen;
|
long unsigned int tempLen = dataLen;
|
||||||
if (Trk.codec == "AAC"){
|
if (Trk.codec == "AAC"){
|
||||||
tempLen += 7;
|
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);
|
fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg);
|
||||||
if (Trk.codec == "AAC"){
|
if (Trk.codec == "AAC"){
|
||||||
bs = TS::getAudioHeader(dataLen, Trk.init);
|
bs = TS::getAudioHeader(dataLen, Trk.init);
|
||||||
|
|
|
@ -25,8 +25,6 @@ namespace Mist {
|
||||||
int contSDT;
|
int contSDT;
|
||||||
unsigned int packCounter; ///\todo update constructors?
|
unsigned int packCounter; ///\todo update constructors?
|
||||||
TS::Packet packData;
|
TS::Packet packData;
|
||||||
bool haveAvcc;
|
|
||||||
MP4::AVCC avccbox;
|
|
||||||
bool appleCompat;
|
bool appleCompat;
|
||||||
uint64_t sendRepeatingHeaders; ///< Amount of ms between PAT/PMT. Zero means do not repeat.
|
uint64_t sendRepeatingHeaders; ///< Amount of ms between PAT/PMT. Zero means do not repeat.
|
||||||
uint64_t lastHeaderTime; ///< Timestamp last PAT/PMT were sent.
|
uint64_t lastHeaderTime; ///< Timestamp last PAT/PMT were sent.
|
||||||
|
|
Loading…
Add table
Reference in a new issue