Skip to content

Commit

Permalink
Revert "Merge pull request #197 from kaltura/BJG-MassiveBuffers"
Browse files Browse the repository at this point in the history
This reverts commit 95cbbe3, reversing
changes made to 94dce81.
  • Loading branch information
einatr committed Dec 9, 2015
1 parent c500240 commit 35ca2ae
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 98 deletions.
76 changes: 20 additions & 56 deletions HLSPlugin/src/com/kaltura/hls/HLSIndexHandler.as
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ package com.kaltura.hls
* streams that overflow the MPEG TS timestamps. Very long windows (>27 hours) may not work
* properly.
*/
public function updateSegmentTimes(segments:Vector.<HLSManifestSegment>, referenceTime:Number = NaN):Vector.<HLSManifestSegment>
public function updateSegmentTimes(segments:Vector.<HLSManifestSegment>, referenceTime:Number = 0):Vector.<HLSManifestSegment>
{
// Keep track of whatever segments we've assigned to.
var setSegments:Object = {};
Expand All @@ -199,14 +199,11 @@ package com.kaltura.hls
if(!startTimeWitnesses.hasOwnProperty(curUri))
continue;

if(false) trace("Segment #" + i + " from start witness " + startTimeWitnesses[curUri]);
//trace("Segment #" + i + " from start witness " + startTimeWitnesses[curUri]);
segments[i].startTime = startTimeWitnesses[curUri];

if(endTimeWitnesses.hasOwnProperty(curUri))
{
if(false) trace("Segment #" + i + " from end witness " + endTimeWitnesses[curUri]);
segments[i].duration = endTimeWitnesses[curUri] - segments[i].startTime;
}

setSegments[i] = 1;
}
Expand All @@ -216,12 +213,8 @@ package com.kaltura.hls
// Then fill in any unknowns scanning forward....
for(i=1; i<segments.length; i++)
{
// We have an explicit value for this one, don't change it.
if(setSegments.hasOwnProperty(i))
continue;

// If the previous one isn't known, don't propagate it forward.
if(!setSegments.hasOwnProperty(i-1))
// Skip unknowns and explicitly set values.
if(!setSegments.hasOwnProperty(i-1) || setSegments.hasOwnProperty(i))
continue;

segments[i].startTime = segments[i-1].startTime + segments[i-1].duration;
Expand All @@ -231,12 +224,8 @@ package com.kaltura.hls
// And scanning back...
for(i=segments.length-2; i>=0; i--)
{
// We have an explicit value for this one, don't change it.
if(setSegments.hasOwnProperty(i))
continue;

// If the next one isn't known, don't propagate it back.
if(!setSegments.hasOwnProperty(i+1))
// Skip unknowns and explicitly set values.
if(!setSegments.hasOwnProperty(i+1) || setSegments.hasOwnProperty(i))
continue;

segments[i].startTime = segments[i+1].startTime - segments[i].duration;
Expand All @@ -251,16 +240,12 @@ package com.kaltura.hls
}

// Dump results:
if(false)
/*trace("Last 10 manifest time reconstruction");
for(i=Math.max(0, segments.length - 100); i<segments.length; i++)
{
trace("Last 10 manifest time reconstruction");
for(i=Math.max(0, segments.length - 100); i<segments.length; i++)
{
trace("segment #" + i + " start=" + segments[i].startTime + " duration=" + segments[i].duration + "uri=" + segments[i].uri);
}
trace("Reconstructed manifest time with knowledge=" + checkAnySegmentKnowledge(segments) + " firstTime=" + (segments.length > 1 ? segments[0].startTime : -1) + " lastTime=" + (segments.length > 1 ? segments[segments.length-1].startTime : -1));

trace("segment #" + i + " start=" + segments[i].startTime + " duration=" + segments[i].duration + "uri=" + segments[i].uri);
}
trace("Reconstructed manifest time with knowledge=" + checkAnySegmentKnowledge(segments) + " firstTime=" + (segments.length > 1 ? segments[0].startTime : -1) + " lastTime=" + (segments.length > 1 ? segments[segments.length-1].startTime : -1));*/

// Done!
return segments;
Expand Down Expand Up @@ -940,12 +925,12 @@ package com.kaltura.hls
//trace("Getting live edge using targetQuality=" + targetQuality);

// Return time at least MAX_SEG_BUFFER from end of stream.
var seg:Vector.<HLSManifestSegment> = getSegmentsForQuality(targetQuality);
var seg:Vector.<HLSManifestSegment> = getSegmentsForQuality(lastQuality);
var backOff:Number = Math.min(HLSManifestParser.MAX_SEG_BUFFER + 1, seg.length - 1);
if(!seg || getManifestForQuality(targetQuality).streamEnds || backOff < 1)
if(!seg || getManifestForQuality(lastQuality).streamEnds || backOff < 1)
return Number.MAX_VALUE;
var lastSeg:HLSManifestSegment = seg[Math.max(0, seg.length - backOff)];
return lastSeg.startTime + 0.5; // Fudge to compensate for offset in capSeekToLiveEdge
return lastSeg.startTime;
}

public override function getFileForTime(time:Number, quality:int):HTTPStreamRequest
Expand Down Expand Up @@ -1513,32 +1498,13 @@ package com.kaltura.hls

private function getSegmentsForQuality( quality:int ):Vector.<HLSManifestSegment>
{
var result:Vector.<HLSManifestSegment> = null;

if ( !manifest )
if ( !manifest ) return new Vector.<HLSManifestSegment>;
if ( manifest.streams.length < 1 || manifest.streams[0].manifest == null )
{
// No manifest found, return dummy.
result = new Vector.<HLSManifestSegment>();
return updateSegmentTimes(manifest.segments);
}
else if ( manifest.streams.length < 1 || manifest.streams[0].manifest == null )
{
// No substreams, just return the main list.
result = manifest.segments;
}
else if ( quality >= manifest.streams.length )
{
// Invalid quality, return substream 0.
trace("getSegmentsForQuality - Got invalid quality level " + quality + " returning level 0.");
result = manifest.streams[0].manifest.segments;
}
else
{
// Return the desired stream.
result = manifest.streams[quality].manifest.segments;
}

// Always update the segment times.
return updateSegmentTimes(result);
else if ( quality >= manifest.streams.length ) return updateSegmentTimes(manifest.streams[0].manifest.segments);
else return updateSegmentTimes(manifest.streams[quality].manifest.segments);
}

private function getManifestForQuality( quality:int):HLSManifestParser
Expand Down Expand Up @@ -1847,18 +1813,16 @@ package com.kaltura.hls
*/
private function onBestEffortDownloadComplete(event:HTTPStreamingEvent):void
{
var downloader:HLSHTTPStreamDownloader = event.downloader as HLSHTTPStreamDownloader;

if(_bestEffortDownloaderMonitor == null ||
_bestEffortDownloaderMonitor != event.target as IEventDispatcher)
{
// we're receiving an event for a download we abandoned
trace("Got event for abandoned best effort download! Attempting to close downloader.");
if(downloader) downloader.close();
trace("Got event for abandoned best effort download!");
return;
}

// If we have 512kb of the segment and it's a progress event, we can probably get a timestamp.
var downloader:HLSHTTPStreamDownloader = event.downloader as HLSHTTPStreamDownloader;
if(downloader.totalAvailableBytes < 512*1024 && downloader.isComplete == false && event.type == HTTPStreamingEvent.DOWNLOAD_PROGRESS)
return;

Expand Down
4 changes: 2 additions & 2 deletions HLSPlugin/src/com/kaltura/hls/m2ts/PESProcessor.as
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ package com.kaltura.hls.m2ts
protected var pendingBuffers:Vector.<Object> = new Vector.<Object>();
protected var pendingLastConvertedIndex:int = 0;

public var lastPTS:Number = NaN, lastDTS:Number = NaN;
public var lastPTS:Number = 0, lastDTS:Number = 0;

/**
* Given a MPEG timestamp we've seen previously, determine if the new timestamp
Expand Down Expand Up @@ -74,7 +74,7 @@ package com.kaltura.hls.m2ts
transcoder.clear(clearAACConfig);

// Reset PTS/DTS reference.
lastPTS = lastDTS = NaN;
lastPTS = lastDTS = 0;
}

private function parseProgramAssociationTable(bytes:ByteArray, cursor:uint):Boolean
Expand Down
68 changes: 28 additions & 40 deletions HLSPlugin/src/org/osmf/net/httpstreaming/HLSHTTPNetStream.as
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,9 @@ package org.osmf.net.httpstreaming
// This code is optimized because it is frequently called and causes
// (on FF FP 17 debug) one second frame drop events when too slow.

if(isNaN(_initialTime))
return _lastValidTimeTime;

var startTime:int = getTimer();

// Do we need to expire the cache?
Expand Down Expand Up @@ -498,6 +501,7 @@ package org.osmf.net.httpstreaming
}

_timeCache_streamStartAbsoluteTime = indexHandler.streamStartAbsoluteTime;

_timeCache_LastUpdatedTimestamp = startTime;
}

Expand All @@ -507,12 +511,9 @@ package org.osmf.net.httpstreaming
//trace(" super.time (" + super.time + ") + " + _initialTime + " = " + potentialNewTime);

// If we are VOD, then offset time so 0 seconds is the start of the stream.
if(indexHandler)
{
var lastMan:HLSManifestParser = indexHandler.getLastSequenceManifest();
if(lastMan && lastMan.streamEnds == true && _timeCache_streamStartAbsoluteTime)
potentialNewTime -= _timeCache_streamStartAbsoluteTime;
}
var lastMan:HLSManifestParser = indexHandler.getLastSequenceManifest();
if(lastMan && lastMan.streamEnds == true && _timeCache_streamStartAbsoluteTime)
potentialNewTime -= _timeCache_streamStartAbsoluteTime;

// Take into account any cached live edge offset.
if(_timeCache_liveEdge != Number.MAX_VALUE)
Expand Down Expand Up @@ -1116,9 +1117,6 @@ package org.osmf.net.httpstreaming
indexHandler.bumpedTime = false;
}

// Clear time cache to ensure accurate time reporting.
_timeCache_LastUpdatedTimestamp = NaN;

// Netstream seek in data generation mode only clears the buffer.
// It does not matter what value you pass to it. However, netstream
// apparently doesn't do that if the value given is larger than
Expand Down Expand Up @@ -1207,7 +1205,7 @@ package org.osmf.net.httpstreaming
setState(HTTPStreamingState.SEEK);
break;
}

// start the recovery process if we need to recover and our buffer is getting too low
if (recoveryDelayTimer.running && recoveryDelayTimer.currentCount >= 1)
{
Expand Down Expand Up @@ -1248,7 +1246,7 @@ package org.osmf.net.httpstreaming
if (
(_state != HTTPStreamingState.PLAY) // we are no longer in play mode
|| (bytes == null) // or we don't have any additional data
|| (processed >= OSMFSettings.hdsBytesProcessingLimit && isNaN(_enhancedSeekTarget)) // or we have processed enough data
|| (processed >= OSMFSettings.hdsBytesProcessingLimit) // or we have processed enough data
)
{
keepProcessing = false;
Expand Down Expand Up @@ -1879,11 +1877,7 @@ package org.osmf.net.httpstreaming
{
// we need to parse the initial bytes
_flvParserProcessed = 0;
inBytes.position = 0;

// Apply sanity to any seek values.
capSeekToLiveEdge();

inBytes.position = 0;
_flvParser.parse(inBytes, true, onTag);
processed += _flvParserProcessed;
if(!_flvParserDone)
Expand Down Expand Up @@ -1960,21 +1954,12 @@ package org.osmf.net.httpstreaming
return timestampCastHelper;
}

private var _capSeekToLiveEdge_LastRunTime:Number = 0;

protected function capSeekToLiveEdge():void
{
var curTime:int = getTimer();
if(curTime - _capSeekToLiveEdge_LastRunTime < 1000)
return;

// Make sure we don't go past the live edge even if it changes while seeking.
if(!indexHandler || !indexHandler.isLiveEdgeValid)
return;

// Met prereqs so we don't have to check as much now.
_capSeekToLiveEdge_LastRunTime = curTime;

var liveEdgeValue:Number = indexHandler.liveEdge;
//trace("Seeing live edge of " + liveEdgeValue);

Expand All @@ -1998,6 +1983,7 @@ package org.osmf.net.httpstreaming
*/
private function onTag(tag:FLVTag):Boolean
{
capSeekToLiveEdge();

if(_enhancedSeekTarget == Number.MAX_VALUE)
{
Expand All @@ -2018,19 +2004,23 @@ package org.osmf.net.httpstreaming
logger.debug("Saw tag @ " + realTimestamp + " timestamp=" + tag.timestamp + " currentTime=" + currentTime + " _seekTime=" + _seekTime + " _enhancedSeekTarget="+ _enhancedSeekTarget + " dataSize=" + tag.dataSize);
}

if (_playForDuration >= 0 && !isNaN(_initialTime))
if (_playForDuration >= 0)
{
if (currentTime > (_initialTime + _playForDuration))
if (_initialTime >= 0) // until we know this, we don't know where to stop, and if we're enhanced-seeking then we need that logic to be what sets this up
{
setState(HTTPStreamingState.STOP);
_flvParserDone = true;
if (!isNaN(_seekTime))
if (currentTime > (_initialTime + _playForDuration))
{
_seekTime = _playForDuration + _initialTime; // FMS behavior... the time is always the final time, even if we seek to past it
// XXX actually, FMS actually lets exactly one frame though at that point and that's why the time gets to be what it is
// XXX that we don't exactly mimic that is also why setting a duration of zero doesn't do what FMS does (plays exactly that one still frame)

setState(HTTPStreamingState.STOP);
_flvParserDone = true;
if (_seekTime < 0)
{
_seekTime = _playForDuration + _initialTime; // FMS behavior... the time is always the final time, even if we seek to past it
// XXX actually, FMS actually lets exactly one frame though at that point and that's why the time gets to be what it is
// XXX that we don't exactly mimic that is also why setting a duration of zero doesn't do what FMS does (plays exactly that one still frame)
}
return false;
}
return false;
}
}

Expand All @@ -2039,8 +2029,7 @@ package org.osmf.net.httpstreaming
// Note if we have encountered an I-frame.
var sawIFrame:Boolean = isTagIFrame(tag as FLVTagVideo);

if (currentTime < _enhancedSeekTarget
|| (_enhancedSeekTags != null && _enhancedSeekSawIFrame == false))
if (currentTime < _enhancedSeekTarget || (_enhancedSeekTags != null && _enhancedSeekSawIFrame == false))
{
CONFIG::LOGGING
{
Expand Down Expand Up @@ -2105,8 +2094,7 @@ package org.osmf.net.httpstreaming
super.pause();

_initialTime = NaN;
_timeCache_LastUpdatedTimestamp = NaN;


var codecID:int;
var haveSeenVideoTag:Boolean = false;

Expand All @@ -2132,7 +2120,6 @@ package org.osmf.net.httpstreaming
haveSeenVideoTag = true;
}

// Copy timestamp unmodified.
vTag.timestamp = tag.timestamp;

var bytes:ByteArray = new ByteArray();
Expand Down Expand Up @@ -2166,6 +2153,7 @@ package org.osmf.net.httpstreaming

// Update the last written time so we don't RESET_SEEK inappropriately.
lastWrittenTime = wrapTagTimestampToFLVTimestamp(tag.timestamp) / 1000.0;

}

// and append this one
Expand Down Expand Up @@ -2663,7 +2651,7 @@ package org.osmf.net.httpstreaming
// Skip totally implausible tags - we need to splice which means the splice must happen after
// tags we have fed into the flash decoder.
if(!scanningForIFrame &&
pendingTags.length > 0 && realTimestamp < wrapTagTimestampToFLVTimestamp(pendingTags[0].timestamp) - 64)
pendingTags.length > 0 && realTimestamp < wrapTagTimestampToFLVTimestamp(pendingTags[0].timestamp))
{
scanningForIFrame = true;

Expand Down

0 comments on commit 35ca2ae

Please sign in to comment.