Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions dash.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -988,11 +988,7 @@ declare namespace dashjs {
stallThreshold?: number,
lowLatencyStallThreshold?: number,
useAppendWindow?: boolean,
setStallState?: boolean
videoFramesNotAdvancing?: {
enabled?: boolean
thresholdInSeconds?: number,
},
setStallState?: boolean
avoidCurrentTimeRangePruning?: boolean
useChangeTypeForTrackSwitch?: boolean
mediaSourceDurationInfinity?: boolean
Expand Down Expand Up @@ -1582,7 +1578,6 @@ declare namespace dashjs {
PLAYBACK_SEEKED: 'playbackSeeked';
PLAYBACK_SEEKING: 'playbackSeeking';
PLAYBACK_STALLED: 'playbackStalled';
PLAYBACK_FROZEN: 'playbackFrozen'
PLAYBACK_STARTED: 'playbackStarted';
PLAYBACK_TIME_UPDATED: 'playbackTimeUpdated';
PLAYBACK_VOLUME_CHANGED: 'playbackVolumeChanged';
Expand Down Expand Up @@ -2514,7 +2509,6 @@ declare namespace dashjs {
CORRUPT_MEDIA_OTHER: 'M01';
BASE_URL_CHANGED: 'F00';
BECAME_REPORTER: 'S00';
PLAYBACK_FROZEN: 'P00';
}

export interface Metrics {
Expand Down Expand Up @@ -4318,7 +4312,6 @@ declare namespace dashjs {
PLAYBACK_SEEKED: 'playbackSeeked';
PLAYBACK_SEEKING: 'playbackSeeking';
PLAYBACK_STALLED: 'playbackStalled';
PLAYBACK_FROZEN: 'playbackFrozen'
PLAYBACK_STARTED: 'playbackStarted';
PLAYBACK_TIME_UPDATED: 'playbackTimeUpdated';
PLAYBACK_WAITING: 'playbackWaiting';
Expand Down
9 changes: 1 addition & 8 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -988,11 +988,7 @@ declare namespace dashjs {
stallThreshold?: number,
lowLatencyStallThreshold?: number,
useAppendWindow?: boolean,
setStallState?: boolean
videoFramesNotAdvancing?: {
enabled?: boolean
thresholdInSeconds?: number,
},
setStallState?: boolean
avoidCurrentTimeRangePruning?: boolean
useChangeTypeForTrackSwitch?: boolean
mediaSourceDurationInfinity?: boolean
Expand Down Expand Up @@ -1582,7 +1578,6 @@ declare namespace dashjs {
PLAYBACK_SEEKED: 'playbackSeeked';
PLAYBACK_SEEKING: 'playbackSeeking';
PLAYBACK_STALLED: 'playbackStalled';
PLAYBACK_FROZEN: 'playbackFrozen'
PLAYBACK_STARTED: 'playbackStarted';
PLAYBACK_TIME_UPDATED: 'playbackTimeUpdated';
PLAYBACK_VOLUME_CHANGED: 'playbackVolumeChanged';
Expand Down Expand Up @@ -2514,7 +2509,6 @@ declare namespace dashjs {
CORRUPT_MEDIA_OTHER: 'M01';
BASE_URL_CHANGED: 'F00';
BECAME_REPORTER: 'S00';
PLAYBACK_FROZEN: 'P00';
}

export interface Metrics {
Expand Down Expand Up @@ -4318,7 +4312,6 @@ declare namespace dashjs {
PLAYBACK_SEEKED: 'playbackSeeked';
PLAYBACK_SEEKING: 'playbackSeeking';
PLAYBACK_STALLED: 'playbackStalled';
PLAYBACK_FROZEN: 'playbackFrozen'
PLAYBACK_STARTED: 'playbackStarted';
PLAYBACK_TIME_UPDATED: 'playbackTimeUpdated';
PLAYBACK_WAITING: 'playbackWaiting';
Expand Down
13 changes: 0 additions & 13 deletions src/core/Settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,6 @@ import Events from './events/Events';
* lowLatencyStallThreshold: 0.3,
* useAppendWindow: true,
* setStallState: true,
* videoFramesNotAdvancing: {
* enabled: false
* thresholdInSeconds: 5,
* },
* avoidCurrentTimeRangePruning: false,
* useChangeTypeForTrackSwitch: true,
* mediaSourceDurationInfinity: true,
Expand Down Expand Up @@ -359,11 +355,6 @@ import Events from './events/Events';
* @property {module:Settings~SyntheticStallSettings} [syntheticStallEvents]
* Specified if we fire manual stall events once the stall threshold is reached
*
* @property {number} [videoFramesNotAdvancing={enabled:false,thresholdInSeconds:5}]
* Controls a mechanism for handling situations where the player is playing but stops advancing its total frame count to handle https://issues.chromium.org/issues/41243192.
*
* The 'enabled' property signifies whether we attempt to handle the bug should it occur by seeking to the current time.
* The 'thresholdInSeconds' a time in seconds that determines how long the issue must be occuring before the handler is triggered, it can be used to control the sensitivity of the mechanism.
* @property {boolean} [avoidCurrentTimeRangePruning=false]
* Avoids pruning of the buffered range that contains the current playback time.
*
Expand Down Expand Up @@ -999,10 +990,6 @@ function Settings() {
lowLatencyStallThreshold: 0.3,
useAppendWindow: true,
setStallState: true,
videoFramesNotAdvancing: {
enabled: false,
thresholdInSeconds: 5
},
avoidCurrentTimeRangePruning: false,
useChangeTypeForTrackSwitch: true,
mediaSourceDurationInfinity: true,
Expand Down
6 changes: 0 additions & 6 deletions src/streaming/MediaPlayerEvents.js
Original file line number Diff line number Diff line change
Expand Up @@ -376,12 +376,6 @@ class MediaPlayerEvents extends EventsBase {
*/
this.PLAYBACK_STALLED = 'playbackStalled';

/**
* Sent when a stall in playback has occured but the reason for it is unclear.
* @event MediaPlayerEvents#PLAYBACK_FROZEN
*/
this.PLAYBACK_FROZEN = `playbackFrozen`;

/**
* Sent when playback of the media starts after having been paused;
* that is, when playback is resumed after a prior pause event.
Expand Down
68 changes: 2 additions & 66 deletions src/streaming/controllers/StreamController.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ function StreamController() {
autoPlay, isStreamSwitchingInProgress, hasMediaError, hasInitialisationError, mediaSource, videoModel,
playbackController, serviceDescriptionController, mediaPlayerModel, customParametersModel, isPaused,
initialPlayback, initialSteeringRequest, playbackEndedTimerInterval, bufferSinks, preloadingStreams,
supportsChangeType, settings, totalVideoFramesAtLastPlaybackProgress, timeAtLastPlaybackProgress, videoFramesNotAdvancingTriggered,
supportsChangeType, settings,
firstLicenseIsFetched, waitForPlaybackStartTimeout, providedStartTime, errorInformation;

function setup() {
Expand Down Expand Up @@ -796,78 +796,17 @@ function StreamController() {
}
}
}

/**
* Checks whether the browser environment is WebKit based or not
* @private
*/
function isWebKit() {
return typeof window.webkitConvertPointFromNodeToPage === 'function' || false
}

/**
* Evaluates whether video frames have potentially stopped advancing, added to address https://issues.chromium.org/issues/41243192
* @private
*/
function checkIfVideoFramesNotAdvancing(event) {

const playbackQuality = videoModel.getPlaybackQuality();

if(videoModel.isSeeking()){
totalVideoFramesAtLastPlaybackProgress = 0
}

const isEnded = event.timeToEnd ? event.timeToEnd <= 0 : false;

const isVideoFramesNotAdvancing = !isWebKit()
&& playbackQuality
&& typeof playbackQuality.totalVideoFrames === 'number'
&& !isEnded
&& timeAtLastPlaybackProgress !== 0
&& event.time > settings.get().streaming.buffer.videoFramesNotAdvancing.thresholdInSeconds // We should be at least one threshold into the video before triggering
&& !videoModel.isPaused()
&& !videoModel.isStalled()
&& !videoModel.isSeeking()
&& videoModel.getReadyState() >= Constants.VIDEO_ELEMENT_READY_STATES.HAVE_ENOUGH_DATA
&& playbackQuality.totalVideoFrames > 0 // Handles devices (some TVs), where Video Quality API, totalVideoFrames always returns 0.
&& playbackQuality.totalVideoFrames < 2147483647 //Handles devices, where Video Quality API, totalVideoFrames can return the max value of a 32 bit signed integer becuase the implementation uses totalVideoFrames = mediaTime * framerate.
&& playbackQuality.totalVideoFrames !== playbackQuality.droppedVideoFrames // Handles devices (some TVs), where Video Quality API, totalVideoFrames always equals the number of dropped frames.
&& playbackQuality.totalVideoFrames === totalVideoFramesAtLastPlaybackProgress // Total frames should advance with time progression, if not something is wrong. On some some TVs the total video frames is reset if the decoder is reinitialised.

if(isVideoFramesNotAdvancing){
if((timeAtLastPlaybackProgress + settings.get().streaming.buffer.videoFramesNotAdvancing.thresholdInSeconds < event.time) && !videoFramesNotAdvancingTriggered){
eventBus.trigger(Events.PLAYBACK_FROZEN,{
cause:'Frames have stopped advancing, Chromium bug #41243192',
totalVideoFrames: playbackQuality.totalVideoFrames,
mediaTime: event.time
});
if(settings.get().streaming.buffer.videoFramesNotAdvancing.enabled){
logger.warn('Video playback has frozen, attempting to recover by seeking to current time')
videoModel.setCurrentTime(videoModel.getTime()-0.0001,false)
}
videoFramesNotAdvancingTriggered = true
}
}
else{
timeAtLastPlaybackProgress = event.time
videoFramesNotAdvancingTriggered = false
if(typeof playbackQuality.totalVideoFrames === 'number'){
totalVideoFramesAtLastPlaybackProgress = playbackQuality.totalVideoFrames
}
}
}

/**
* When the playback time is updated we add the droppedFrames metric to the dash metric object
* @private
*/
function _onPlaybackTimeUpdated(event) {
function _onPlaybackTimeUpdated() {

if (hasVideoTrack()) {
const playbackQuality = videoModel.getPlaybackQuality();
if (playbackQuality) {
dashMetrics.addDroppedFrames(playbackQuality);
checkIfVideoFramesNotAdvancing(event)
}
}
}
Expand Down Expand Up @@ -1623,9 +1562,6 @@ function StreamController() {
supportsChangeType = false;
preloadingStreams = [];
waitForPlaybackStartTimeout = null;
totalVideoFramesAtLastPlaybackProgress = 0;
timeAtLastPlaybackProgress = 0;
videoFramesNotAdvancingTriggered = false;
errorInformation = {
counts: {
mediaErrorDecode: 0
Expand Down
8 changes: 0 additions & 8 deletions src/streaming/metrics/utils/DVBErrorsTranslator.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,6 @@ function DVBErrorsTranslator(config) {
});
}

function onPlaybackStallCauseUnknown() {
report({
errorcode: DVBErrors.PLAYBACK_FROZEN
});
}

function handleHttpMetric(vo) {
if ((vo.responsecode === 0) || // connection failure - unknown
(vo.responsecode == null) || // Generated on .catch() and when uninitialized
Expand Down Expand Up @@ -149,7 +143,6 @@ function DVBErrorsTranslator(config) {
eventBus.on(Events.METRIC_ADDED, onMetricEvent, instance);
eventBus.on(Events.METRIC_UPDATED, onMetricEvent, instance);
eventBus.on(Events.PLAYBACK_ERROR, onPlaybackError, instance);
eventBus.on(Events.PLAYBACK_FROZEN, onPlaybackStallCauseUnknown, instance);
eventBus.on(
MetricsReportingEvents.BECAME_REPORTING_PLAYER,
onBecameReporter,
Expand All @@ -167,7 +160,6 @@ function DVBErrorsTranslator(config) {
eventBus.off(Events.METRIC_ADDED, onMetricEvent, instance);
eventBus.off(Events.METRIC_UPDATED, onMetricEvent, instance);
eventBus.off(Events.PLAYBACK_ERROR, onPlaybackError, instance);
eventBus.off(Events.PLAYBACK_FROZEN, onPlaybackStallCauseUnknown, instance);
eventBus.off(
MetricsReportingEvents.BECAME_REPORTING_PLAYER,
onBecameReporter,
Expand Down
2 changes: 0 additions & 2 deletions src/streaming/metrics/vo/DVBErrors.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ class DVBErrors {
// Corrupt media – Not otherwise specified "M01"
// Changing Base URL in use due to errors "F00"
// Becoming an error reporting Player "S00"
// Playback error has occured, the cause is unknown "P00"

this.terror = null;
// Real-Time - Date and time at which error occurred in UTC,
Expand Down Expand Up @@ -94,6 +93,5 @@ DVBErrors.CORRUPT_MEDIA_ISOBMFF = 'M00';
DVBErrors.CORRUPT_MEDIA_OTHER = 'M01';
DVBErrors.BASE_URL_CHANGED = 'F00';
DVBErrors.BECAME_REPORTER = 'S00';
DVBErrors.PLAYBACK_FROZEN = 'P00';

export default DVBErrors;