EBML input fixup
This commit is contained in:
parent
320c8ab29f
commit
61bb14a368
2 changed files with 47 additions and 61 deletions
|
@ -5,9 +5,6 @@
|
|||
|
||||
namespace Mist{
|
||||
|
||||
uint16_t maxEBMLFrameOffset = 0;
|
||||
bool frameOffsetKnown = false;
|
||||
|
||||
InputEBML::InputEBML(Util::Config *cfg) : Input(cfg){
|
||||
timeScale = 1.0;
|
||||
capa["name"] = "EBML";
|
||||
|
@ -161,10 +158,6 @@ namespace Mist{
|
|||
if (myMeta.inputLocalVars.isMember("timescale")){
|
||||
timeScale = ((double)myMeta.inputLocalVars["timescale"].asInt()) / 1000000.0;
|
||||
}
|
||||
if (myMeta.inputLocalVars.isMember("maxframeoffset")){
|
||||
maxEBMLFrameOffset = myMeta.inputLocalVars["maxframeoffset"].asInt();
|
||||
frameOffsetKnown = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -392,8 +385,7 @@ namespace Mist{
|
|||
B.isKeyframe() && !isAudio, isVideo);
|
||||
}
|
||||
}
|
||||
while (TP.hasPackets() && (isVideo || frameOffsetKnown)){
|
||||
frameOffsetKnown = true;
|
||||
while (TP.hasPackets()){
|
||||
packetData &C = TP.getPacketData(isVideo);
|
||||
myMeta.update(C.time, C.offset, C.track, C.dsize, C.bpos, C.key);
|
||||
TP.remove();
|
||||
|
@ -413,8 +405,6 @@ namespace Mist{
|
|||
}
|
||||
}
|
||||
|
||||
myMeta.inputLocalVars["maxframeoffset"] = maxEBMLFrameOffset;
|
||||
|
||||
bench = Util::getMicros(bench);
|
||||
INFO_MSG("Header generated in %llu ms", bench / 1000);
|
||||
packBuf.clear();
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
namespace Mist{
|
||||
|
||||
|
||||
extern uint16_t maxEBMLFrameOffset;
|
||||
extern bool frameOffsetKnown;
|
||||
#define PKT_COUNT 64
|
||||
|
||||
class packetData{
|
||||
|
@ -40,44 +38,46 @@ namespace Mist{
|
|||
class trackPredictor{
|
||||
public:
|
||||
packetData pkts[PKT_COUNT];
|
||||
uint64_t frameOffset;
|
||||
uint16_t smallestFrame;
|
||||
uint64_t lastTime;
|
||||
uint64_t ctr;
|
||||
uint64_t rem;
|
||||
uint64_t frameOffset;///The static average offset between transmit time and display time
|
||||
bool frameOffsetKnown;///Whether the average frame offset is known
|
||||
uint16_t smallestFrame;///low-ball estimate of time per frame
|
||||
uint64_t lastTime;///last send transmit timestamp
|
||||
uint64_t ctr;///ingested frame count
|
||||
uint64_t rem;///removed frame count
|
||||
uint64_t maxOffset;///maximum offset for this track
|
||||
uint64_t lowestTime;///First timestamp to enter the buffer
|
||||
trackPredictor(){
|
||||
smallestFrame = 0xFFFF;
|
||||
frameOffsetKnown = false;
|
||||
frameOffset = 0;
|
||||
maxOffset = 0;
|
||||
flush();
|
||||
}
|
||||
bool hasPackets(bool finished = false){
|
||||
if (finished){
|
||||
if (finished || frameOffsetKnown){
|
||||
return (ctr - rem > 0);
|
||||
}else{
|
||||
return frameOffsetKnown ? (ctr - rem > 1) : (ctr - rem > 12);
|
||||
return (ctr - rem > 12);
|
||||
}
|
||||
}
|
||||
/// Clears all internal values, for reuse as-new.
|
||||
void flush(){
|
||||
frameOffset = 0;
|
||||
smallestFrame = 0;
|
||||
lastTime = 0;
|
||||
ctr = 0;
|
||||
rem = 0;
|
||||
lowestTime = 0;
|
||||
}
|
||||
packetData & getPacketData(bool mustCalcOffsets){
|
||||
frameOffsetKnown = true;
|
||||
//grab the next packet to output
|
||||
packetData & p = pkts[rem % PKT_COUNT];
|
||||
//Substract the max frame offset, so we know all offsets are positive, no matter what.
|
||||
//if it's not the first and we're calculating offsets, see if we need an offset
|
||||
if (!mustCalcOffsets){
|
||||
p.time += maxEBMLFrameOffset;
|
||||
DONTEVEN_MSG("Outputting %llu + %llu (%llu -> %llu)", p.time, maxEBMLFrameOffset, rem, rem % PKT_COUNT);
|
||||
frameOffsetKnown = true;
|
||||
return p;
|
||||
}else{
|
||||
}
|
||||
if (rem && !p.key){
|
||||
p.offset = p.time + maxEBMLFrameOffset - (lastTime + smallestFrame);
|
||||
if (p.offset > (maxEBMLFrameOffset + frameOffset + smallestFrame)){
|
||||
uint64_t diff = p.offset - (maxEBMLFrameOffset + frameOffset + smallestFrame);
|
||||
p.offset = p.time - (lastTime + smallestFrame) + frameOffset;
|
||||
if (p.offset > maxOffset){
|
||||
uint64_t diff = p.offset - maxOffset;
|
||||
p.offset -= diff;
|
||||
lastTime += diff;
|
||||
}
|
||||
|
@ -85,34 +85,30 @@ namespace Mist{
|
|||
//we assume it's just time stamp drift due to lack of precision.
|
||||
p.time = (lastTime + smallestFrame);
|
||||
}else{
|
||||
p.time -= frameOffset?frameOffset + smallestFrame:0;
|
||||
p.offset = maxEBMLFrameOffset + frameOffset + smallestFrame;
|
||||
if (!frameOffsetKnown){
|
||||
for (uint64_t i = 1; i < ctr; ++i){
|
||||
uint64_t timeDiff = pkts[i%PKT_COUNT].time - lowestTime;
|
||||
uint64_t timeExpt = smallestFrame*i;
|
||||
if (timeDiff > timeExpt && maxOffset < timeDiff-timeExpt){
|
||||
maxOffset = timeDiff-timeExpt;
|
||||
}
|
||||
if (timeDiff < timeExpt && frameOffset < timeExpt-timeDiff){
|
||||
frameOffset = timeExpt - timeDiff;
|
||||
}
|
||||
}
|
||||
maxOffset += frameOffset;
|
||||
HIGH_MSG("smallestFrame=%" PRIu16 ", frameOffset=%" PRIu64 ", maxOffset=%" PRIu64, smallestFrame, frameOffset, maxOffset);
|
||||
frameOffsetKnown = true;
|
||||
}
|
||||
p.offset = frameOffset;
|
||||
}
|
||||
lastTime = p.time;
|
||||
DONTEVEN_MSG("Outputting%s %llu + %llu, offset %llu (%llu -> %llu), display at %llu", (p.key?" (KEY)":""), p.time, frameOffset, p.offset, rem, rem % PKT_COUNT, p.time+p.offset);
|
||||
INSANE_MSG("Outputting%s %llu+%llu (#%llu, Max=%llu), display at %llu", (p.key?"KEY":""), p.time, p.offset, rem, maxOffset, p.time+p.offset);
|
||||
return p;
|
||||
}
|
||||
void add(uint64_t packTime, uint64_t packOffset, uint64_t packTrack, uint64_t packDataSize, uint64_t packBytePos, bool isKeyframe, bool isVideo, void * dataPtr = 0){
|
||||
//If no packets have been removed yet and there is more than one packet, calculate frameOffset
|
||||
if (!rem && ctr && packTime < pkts[0].time){
|
||||
frameOffset = pkts[0].time - packTime;
|
||||
INSANE_MSG("Setting frameOffset to %llu", frameOffset);
|
||||
}
|
||||
if (isVideo && ctr && ctr >= rem){
|
||||
int32_t currOffset = packTime - pkts[(ctr-1)%PKT_COUNT].time;
|
||||
if (!frameOffsetKnown && currOffset < 0 && -currOffset < 8 * smallestFrame &&
|
||||
-currOffset * 2 > maxEBMLFrameOffset && ctr < PKT_COUNT / 2){
|
||||
maxEBMLFrameOffset = -currOffset * 2;
|
||||
INFO_MSG("Max frame offset is now %u", maxEBMLFrameOffset);
|
||||
}
|
||||
if (currOffset < 0){currOffset *= -1;}
|
||||
if (!smallestFrame || currOffset < smallestFrame){
|
||||
smallestFrame = currOffset;
|
||||
HIGH_MSG("Smallest frame is now %u", smallestFrame);
|
||||
}
|
||||
}
|
||||
DONTEVEN_MSG("Ingesting %llu (%llu -> %llu)", packTime, ctr, ctr % PKT_COUNT);
|
||||
if (!ctr){lowestTime = packTime;}
|
||||
if (packTime > lowestTime && packTime - lowestTime < smallestFrame){smallestFrame = packTime - lowestTime;}
|
||||
pkts[ctr % PKT_COUNT].set(packTime, packOffset, packTrack, packDataSize, packBytePos, isKeyframe, dataPtr);
|
||||
++ctr;
|
||||
if (ctr == PKT_COUNT-1){frameOffsetKnown = true;}
|
||||
|
|
Loading…
Add table
Reference in a new issue