videoBuffer.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. "use strict";
  2. var VideoBufferNode = (function() {
  3. function Constructor(data, width, height, codecType, frameType, timeStamp) {
  4. BufferNode.call(this, data);
  5. this.width = width;
  6. this.height = height;
  7. this.codecType = codecType;
  8. this.frameType = frameType;
  9. this.timeStamp = timeStamp;
  10. }
  11. return Constructor;
  12. })();
  13. function VideoBufferList() {
  14. var MAX_LENGTH = 0,
  15. BUFFERING = 0,
  16. bufferFullCallback = null;
  17. function Constructor() {
  18. BufferList.call(this);
  19. MAX_LENGTH = 360;
  20. BUFFERING = 240;
  21. bufferFullCallback = null;
  22. }
  23. Constructor.prototype = inherit(BufferList, {
  24. push: function(data, width, height, codecType, frameType, timeStamp) {
  25. var node = new VideoBufferNode(data, width, height, codecType, frameType, timeStamp);
  26. if (this._length > 0) {
  27. this.tail.next = node;
  28. node.previous = this.tail;
  29. this.tail = node;
  30. } else {
  31. this.head = node;
  32. this.tail = node;
  33. }
  34. this._length += 1;
  35. (bufferFullCallback !== null && this._length >= BUFFERING) ? bufferFullCallback(): 0; //PLAYBACK bufferFull
  36. // console.log("VideoBufferList after push node count is " + this._length + " frameType is " + frameType);
  37. return node;
  38. },
  39. pop: function() {
  40. // console.log("before pop node count is " + this._length + " MINBUFFER is " + MINBUFFER);
  41. var node = null;
  42. if (this._length > 1) {
  43. node = this.head;
  44. this.head = this.head.next;
  45. if (this.head !== null) {
  46. this.head.previous = null;
  47. // 2nd use-case: there is no second node
  48. } else {
  49. this.tail = null;
  50. }
  51. this._length -= 1;
  52. }
  53. return node;
  54. },
  55. setMaxLength: function(length) {
  56. MAX_LENGTH = length;
  57. if (MAX_LENGTH > 360) {
  58. MAX_LENGTH = 360;
  59. } else if (MAX_LENGTH < 30) {
  60. MAX_LENGTH = 30;
  61. }
  62. },
  63. setBUFFERING: function(interval) {
  64. BUFFERING = interval;
  65. if (BUFFERING > 240) {
  66. BUFFERING = 240;
  67. } else if (BUFFERING < 6) {
  68. BUFFERING = 6;
  69. }
  70. },
  71. setBufferFullCallback: function(callback) {
  72. bufferFullCallback = callback;
  73. // console.log("setBufferFullCallback MAX_LENGTH is " + MAX_LENGTH );
  74. },
  75. searchTimestamp: function(frameTimestamp) {
  76. // console.log("searchTimestamp frameTimestamp = " + frameTimestamp.timestamp + " frameTimestamp usec = " + frameTimestamp.timestamp_usec);
  77. var currentNode = this.head,
  78. length = this._length,
  79. count = 1,
  80. message = {
  81. failure: 'Failure: non-existent node in this list.'
  82. };
  83. // 1st use-case: an invalid position
  84. if (length === 0 || frameTimestamp <= 0 || currentNode === null) {
  85. throw new Error(message.failure);
  86. }
  87. // 2nd use-case: a valid position
  88. while (currentNode !== null &&
  89. (currentNode.timeStamp.timestamp !== frameTimestamp.timestamp ||
  90. currentNode.timeStamp.timestamp_usec !== frameTimestamp.timestamp_usec)) {
  91. // console.log("currentNode Timestamp = " + currentNode.timeStamp.timestamp + " Timestamp usec = " + currentNode.timeStamp.timestamp_usec);
  92. currentNode = currentNode.next;
  93. count++;
  94. }
  95. if (length < count) {
  96. currentNode = null;
  97. } else {
  98. this.curIdx = count;
  99. // 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);
  100. }
  101. return currentNode;
  102. },
  103. findIFrame: function(isForward) {
  104. var currentNode = this.head,
  105. length = this._length,
  106. count = 1,
  107. message = {
  108. failure: 'Failure: non-existent node in this list.'
  109. };
  110. // 1st use-case: an invalid position
  111. if (length === 0) {
  112. throw new Error(message.failure);
  113. }
  114. // 2nd use-case: a valid position
  115. while (count < this.curIdx) {
  116. currentNode = currentNode.next;
  117. count++;
  118. }
  119. if (isForward === true) {
  120. while (currentNode.frameType !== "I") {
  121. currentNode = currentNode.next;
  122. count++;
  123. }
  124. } else {
  125. while (currentNode.frameType !== "I") {
  126. currentNode = currentNode.previous;
  127. count--;
  128. }
  129. }
  130. if (length < count) {
  131. currentNode = null;
  132. } else {
  133. this.curIdx = count;
  134. // console.log('findIFrame curIdx ' + this.curIdx + ' count ' + count + ' _length ' + this._length);
  135. }
  136. return currentNode;
  137. }
  138. });
  139. return new Constructor();
  140. }