"use strict"; var VideoBufferNode = (function() { function Constructor(data, width, height, codecType, frameType, timeStamp) { BufferNode.call(this, data); this.width = width; this.height = height; this.codecType = codecType; this.frameType = frameType; this.timeStamp = timeStamp; } return Constructor; })(); function VideoBufferList() { var MAX_LENGTH = 0, BUFFERING = 0, bufferFullCallback = null; function Constructor() { BufferList.call(this); MAX_LENGTH = 360; BUFFERING = 240; bufferFullCallback = null; } Constructor.prototype = inherit(BufferList, { push: function(data, width, height, codecType, frameType, timeStamp) { var node = new VideoBufferNode(data, width, height, codecType, frameType, timeStamp); if (this._length > 0) { this.tail.next = node; node.previous = this.tail; this.tail = node; } else { this.head = node; this.tail = node; } this._length += 1; (bufferFullCallback !== null && this._length >= BUFFERING) ? bufferFullCallback(): 0; //PLAYBACK bufferFull // console.log("VideoBufferList after push node count is " + this._length + " frameType is " + frameType); return node; }, pop: function() { // console.log("before pop node count is " + this._length + " MINBUFFER is " + MINBUFFER); var node = null; if (this._length > 1) { node = this.head; this.head = this.head.next; if (this.head !== null) { this.head.previous = null; // 2nd use-case: there is no second node } else { this.tail = null; } this._length -= 1; } return node; }, setMaxLength: function(length) { MAX_LENGTH = length; if (MAX_LENGTH > 360) { MAX_LENGTH = 360; } else if (MAX_LENGTH < 30) { MAX_LENGTH = 30; } }, setBUFFERING: function(interval) { BUFFERING = interval; if (BUFFERING > 240) { BUFFERING = 240; } else if (BUFFERING < 6) { BUFFERING = 6; } }, setBufferFullCallback: function(callback) { bufferFullCallback = callback; // console.log("setBufferFullCallback MAX_LENGTH is " + MAX_LENGTH ); }, searchTimestamp: function(frameTimestamp) { // console.log("searchTimestamp frameTimestamp = " + frameTimestamp.timestamp + " frameTimestamp usec = " + frameTimestamp.timestamp_usec); var currentNode = this.head, length = this._length, count = 1, message = { failure: 'Failure: non-existent node in this list.' }; // 1st use-case: an invalid position if (length === 0 || frameTimestamp <= 0 || currentNode === null) { throw new Error(message.failure); } // 2nd use-case: a valid position while (currentNode !== null && (currentNode.timeStamp.timestamp !== frameTimestamp.timestamp || currentNode.timeStamp.timestamp_usec !== frameTimestamp.timestamp_usec)) { // console.log("currentNode Timestamp = " + currentNode.timeStamp.timestamp + " Timestamp usec = " + currentNode.timeStamp.timestamp_usec); currentNode = currentNode.next; count++; } if (length < count) { currentNode = null; } else { this.curIdx = count; // console.log("searchTimestamp curIdx = " + this.curIdx + " currentNode.timeStamp.timestamp = " + currentNode.timeStamp.timestamp + " currentNode.timestamp_usec = " + currentNode.timeStamp.timestamp_usec + " frameTimestamp = " + frameTimestamp.timestamp + " frameTimestamp usec = " + frameTimestamp.timestamp_usec); } return currentNode; }, findIFrame: function(isForward) { var currentNode = this.head, length = this._length, count = 1, message = { failure: 'Failure: non-existent node in this list.' }; // 1st use-case: an invalid position if (length === 0) { throw new Error(message.failure); } // 2nd use-case: a valid position while (count < this.curIdx) { currentNode = currentNode.next; count++; } if (isForward === true) { while (currentNode.frameType !== "I") { currentNode = currentNode.next; count++; } } else { while (currentNode.frameType !== "I") { currentNode = currentNode.previous; count--; } } if (length < count) { currentNode = null; } else { this.curIdx = count; // console.log('findIFrame curIdx ' + this.curIdx + ' count ' + count + ' _length ' + this._length); } return currentNode; } }); return new Constructor(); }