H265SPSParser.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. "use strict";
  2. function H265SPSParser() {
  3. var vBitCount = 0;
  4. var spsMap = null;
  5. var pSPSBytes = null;
  6. function Constructor() {
  7. vBitCount = 0;
  8. spsMap = new Map();
  9. }
  10. function get_bit(base, offset) {
  11. var vCurBytes = (vBitCount + offset) >> 3;
  12. offset = (vBitCount + offset) & 0x00000007;
  13. return (((base[(vCurBytes)])) >> (0x7 - (offset & 0x7))) & 0x1;
  14. }
  15. function read_bits(pBuf, vReadBits) {
  16. var vCurBytes = vBitCount / 8;
  17. var vCurBits = vBitCount % 8;
  18. var vOffset = 0;
  19. var vTmp = 0,
  20. vTmp2 = 0;
  21. if (vReadBits == 1) {
  22. vTmp = get_bit(pBuf, vOffset);
  23. } else {
  24. for (var i = 0; i < vReadBits; i++) {
  25. vTmp2 = get_bit(pBuf, i);
  26. vTmp = (vTmp << 1) + vTmp2;
  27. }
  28. }
  29. vBitCount += vReadBits;
  30. return vTmp;
  31. }
  32. function ue(base, offset) {
  33. var zeros = 0,
  34. vTmp = 0,
  35. vReturn = 0;
  36. var vIdx = offset;
  37. do {
  38. vTmp = get_bit(base, vIdx++);
  39. if (vTmp == 0)
  40. zeros++;
  41. } while (0 == vTmp);
  42. if (zeros == 0) {
  43. vBitCount += 1;
  44. return 0;
  45. }
  46. // insert first 1 bit
  47. vReturn = 1 << zeros;
  48. for (var i = zeros - 1; i >= 0; i-- , vIdx++) {
  49. vTmp = get_bit(base, vIdx);
  50. vReturn |= vTmp << i;
  51. }
  52. vBitCount += zeros * 2 + 1;
  53. return (vReturn - 1);
  54. }
  55. function se(base, offset) {
  56. var vReturn = ue(base, offset);
  57. if (vReturn & 0x1) {
  58. return (vReturn + 1) / 2;
  59. } else {
  60. return -vReturn / 2;
  61. }
  62. }
  63. function byte_aligned() {
  64. if ((vBitCount & 0x00000007) == 0)
  65. return 1;
  66. else
  67. return 0;
  68. }
  69. function profile_tier_level(profilePresentFlag, maxNumSubLayersMinus1) {
  70. if (profilePresentFlag) {
  71. spsMap.set("general_profile_space", read_bits(pSPSBytes, 2));
  72. spsMap.set("general_tier_flag", read_bits(pSPSBytes, 1));
  73. spsMap.set("general_profile_idc", read_bits(pSPSBytes, 5));
  74. var generalProfileCompatibilityFlag = new Array(32);
  75. for (var j = 0; j < 32; j++) {
  76. generalProfileCompatibilityFlag[j] = read_bits(pSPSBytes, 1);
  77. }
  78. spsMap.set("general_progressive_source_flag", read_bits(pSPSBytes, 1));
  79. spsMap.set("general_interlaced_source_flag", read_bits(pSPSBytes, 1));
  80. spsMap.set("general_non_packed_constraint_flag", read_bits(pSPSBytes, 1));
  81. spsMap.set("general_frame_only_constraint_flag", read_bits(pSPSBytes, 1));
  82. var generalProfileIdc = spsMap.get("general_profile_idc");
  83. if (generalProfileIdc === 4 || generalProfileCompatibilityFlag[4] ||
  84. generalProfileIdc === 5 || generalProfileCompatibilityFlag[5] ||
  85. generalProfileIdc === 6 || generalProfileCompatibilityFlag[6] ||
  86. generalProfileIdc === 7 || generalProfileCompatibilityFlag[7]) {
  87. spsMap.set("general_max_12bit_constraint_flag", read_bits(pSPSBytes, 1));
  88. spsMap.set("general_max_10bit_constraint_flag", read_bits(pSPSBytes, 1));
  89. spsMap.set("general_max_8bit_constraint_flag", read_bits(pSPSBytes, 1));
  90. spsMap.set("general_max_422chroma_constraint_flag", read_bits(pSPSBytes, 1));
  91. spsMap.set("general_max_420chroma_constraint_flag", read_bits(pSPSBytes, 1));
  92. spsMap.set("general_max_monochrome_constraint_flag", read_bits(pSPSBytes, 1));
  93. spsMap.set("general_intra_constraint_flag", read_bits(pSPSBytes, 1));
  94. spsMap.set("general_one_picture_only_constraint_flag", read_bits(pSPSBytes, 1));
  95. spsMap.set("general_lower_bit_rate_constraint_flag", read_bits(pSPSBytes, 1));
  96. spsMap.set("general_reserved_zero_34bits", read_bits(pSPSBytes, 34));
  97. } else {
  98. spsMap.set("general_reserved_zero_43bits", read_bits(pSPSBytes, 43));
  99. }
  100. if ((generalProfileIdc >= 1 && generalProfileIdc <= 5) ||
  101. generalProfileCompatibilityFlag[1] || generalProfileCompatibilityFlag[2] ||
  102. generalProfileCompatibilityFlag[3] || generalProfileCompatibilityFlag[4] ||
  103. generalProfileCompatibilityFlag[5]) {
  104. /* The number of bits in this syntax structure is not affected by this condition */
  105. spsMap.set("general_inbld_flag", read_bits(pSPSBytes, 1));
  106. } else {
  107. spsMap.set("general_reserved_zero_bit", read_bits(pSPSBytes, 1));
  108. }
  109. }
  110. spsMap.set("general_level_idc", read_bits(pSPSBytes, 8));
  111. var subLayerProfilePresentFlag = new Array(maxNumSubLayersMinus1);
  112. var subLayerLevelPresentFlag = new Array(maxNumSubLayersMinus1);
  113. for (i = 0; i < maxNumSubLayersMinus1; i++) {
  114. subLayerProfilePresentFlag[i] = read_bits(pSPSBytes, 1);
  115. subLayerLevelPresentFlag[i] = read_bits(pSPSBytes, 1);
  116. }
  117. var reservedZero2bits = new Array(8);
  118. var subLayerProfileIdc = new Array(maxNumSubLayersMinus1);
  119. if (maxNumSubLayersMinus1 > 0) {
  120. for (var i = maxNumSubLayersMinus1; i < 8; i++) {
  121. reservedZero2bits[i] = read_bits(pSPSBytes, 2);
  122. }
  123. }
  124. for (var i = 0; i < maxNumSubLayersMinus1; i++) {
  125. if (subLayerProfilePresentFlag[i]) {
  126. spsMap.set("sub_layer_profile_space", read_bits(pSPSBytes, 2));
  127. spsMap.set("sub_layer_tier_flag", read_bits(pSPSBytes, 1));
  128. subLayerProfileIdc[i] = read_bits(pSPSBytes, 5);
  129. for (var j = 0; j < 32; j++) {
  130. subLayerProfileCompatibilityFlag[i][j] = read_bits(pSPSBytes, 1);
  131. }
  132. spsMap.set("sub_layer_progressive_source_flag", read_bits(pSPSBytes, 1));
  133. spsMap.set("sub_layer_interlaced_source_flag", read_bits(pSPSBytes, 1));
  134. spsMap.set("sub_layer_non_packed_constraint_flag", read_bits(pSPSBytes, 1));
  135. spsMap.set("sub_layer_frame_only_constraint_flag", read_bits(pSPSBytes, 1));
  136. if (subLayerProfileIdc[i] === 4 || subLayerProfileCompatibilityFlag[i][4] ||
  137. subLayerProfileIdc[i] === 5 || subLayerProfileCompatibilityFlag[i][5] ||
  138. subLayerProfileIdc[i] === 6 || subLayerProfileCompatibilityFlag[i][6] ||
  139. subLayerProfileIdc[i] === 7 || subLayerProfileCompatibilityFlag[i][7]) {
  140. /* The number of bits in this syntax structure is not affected by this condition */
  141. spsMap.set("sub_layer_max_12bit_constraint_flag", read_bits(pSPSBytes, 1));
  142. spsMap.set("sub_layer_max_10bit_constraint_flag", read_bits(pSPSBytes, 1));
  143. spsMap.set("sub_layer_max_8bit_constraint_flag", read_bits(pSPSBytes, 1));
  144. spsMap.set("sub_layer_max_422chroma_constraint_flag", read_bits(pSPSBytes, 1));
  145. spsMap.set("sub_layer_max_420chroma_constraint_flag", read_bits(pSPSBytes, 1));
  146. spsMap.set("sub_layer_max_monochrome_constraint_flag", read_bits(pSPSBytes, 1));
  147. spsMap.set("sub_layer_intra_constraint_flag", read_bits(pSPSBytes, 1));
  148. spsMap.set("sub_layer_one_picture_only_constraint_flag", read_bits(pSPSBytes, 1));
  149. spsMap.set("sub_layer_lower_bit_rate_constraint_flag", read_bits(pSPSBytes, 1));
  150. spsMap.set("sub_layer_reserved_zero_34bits", read_bits(pSPSBytes, 34));
  151. } else {
  152. spsMap.set("sub_layer_reserved_zero_43bits", read_bits(pSPSBytes, 43));
  153. }
  154. if ((subLayerProfileIdc[i] >= 1 && subLayerProfileIdc[i] <= 5) ||
  155. subLayerProfileCompatibilityFlag[1] || subLayerProfileCompatibilityFlag[2] ||
  156. subLayerProfileCompatibilityFlag[3] || subLayerProfileCompatibilityFlag[4] ||
  157. subLayerProfileCompatibilityFlag[5]) {
  158. /* The number of bits in this syntax structure is not affected by this condition */
  159. spsMap.set("sub_layer_inbld_flag", read_bits(pSPSBytes, 1));
  160. } else {
  161. spsMap.set("sub_layer_reserved_zero_bit", read_bits(pSPSBytes, 1));
  162. }
  163. }
  164. if (subLayerLevelPresentFlag[i]) {
  165. spsMap.set("sub_layer_level_idc", read_bits(pSPSBytes, 8));
  166. }
  167. }
  168. }
  169. Constructor.prototype = {
  170. parse: function (spsPayload) {
  171. pSPSBytes = spsPayload;
  172. //console.log("=========================SPS START=========================");
  173. vBitCount = 0;
  174. spsMap.clear();
  175. spsMap.set("forbidden_zero_bit", read_bits(pSPSBytes, 1));
  176. spsMap.set("nal_unit_type", read_bits(pSPSBytes, 6));
  177. spsMap.set("nuh_layer_id", read_bits(pSPSBytes, 6));
  178. spsMap.set("nuh_temporal_id_plus1", read_bits(pSPSBytes, 3));
  179. spsMap.set("sps_video_parameter_set_id", read_bits(pSPSBytes, 4));
  180. if (spsMap.get("nuh_layer_id") === 0) {
  181. spsMap.set("sps_max_sub_layers_minus1", read_bits(pSPSBytes, 3));
  182. } else {
  183. spsMap.set("sps_ext_or_max_sub_layers_minus1", read_bits(pSPSBytes, 3));
  184. }
  185. var MultiLayerExtSpsFlag = (spsMap.get("nuh_layer_id") !== 0 && spsMap.get("sps_ext_or_max_sub_layers_minus1") === 7);
  186. if (!MultiLayerExtSpsFlag) {
  187. spsMap.set("sps_max_sub_layers_minus1", read_bits(pSPSBytes, 1));
  188. //profile_tier_level(1, spsMap.get("sps_max_sub_layers_minus1"));
  189. }
  190. read_bits(pSPSBytes, 84);
  191. spsMap.set("sps_seq_parameter_set_id", ue(pSPSBytes, 0));
  192. if (MultiLayerExtSpsFlag) {
  193. spsMap.set("update_rep_format_flag", read_bits(pSPSBytes, 1));
  194. if (spsMap.get("update_rep_format_flag")) {
  195. spsMap.set("sps_rep_format_idx", read_bits(pSPSBytes, 8));
  196. }
  197. } else {
  198. spsMap.set("chroma_format_idc", ue(pSPSBytes, 0));
  199. if (spsMap.get("chroma_format_idc") === 3) {
  200. spsMap.set("separate_colour_plane_flag", read_bits(pSPSBytes, 1));
  201. }
  202. spsMap.set("pic_width_in_luma_samples", ue(pSPSBytes, 0));
  203. spsMap.set("pic_height_in_luma_samples", ue(pSPSBytes, 0));
  204. spsMap.set("conformance_window_flag", read_bits(pSPSBytes, 1));
  205. if (spsMap.get("conformance_window_flag")) {
  206. spsMap.set("conf_win_left_offset", ue(pSPSBytes, 0));
  207. spsMap.set("conf_win_right_offset", ue(pSPSBytes, 0));
  208. spsMap.set("conf_win_top_offset", ue(pSPSBytes, 0));
  209. spsMap.set("conf_win_bottom_offset", ue(pSPSBytes, 0));
  210. }
  211. }
  212. //console.log("=========================SPS END=========================");
  213. return true;
  214. },
  215. getSizeInfo: function () {
  216. var width = spsMap.get("pic_width_in_luma_samples");
  217. var height = spsMap.get("pic_height_in_luma_samples");
  218. if (spsMap.get("conformance_window_flag")) {
  219. var chromaFormatIdc = spsMap.get("chroma_format_idc");
  220. var separateColourPlaneFlag = spsMap.get("separate_colour_plane_flag");
  221. if (typeof separateColourPlaneFlag === "undefined") {
  222. separateColourPlaneFlag = 0;
  223. }
  224. var subWidthC = ((1 === chromaFormatIdc) || (2 === chromaFormatIdc)) && (0 === separateColourPlaneFlag) ? 2 : 1;
  225. var subHeightC = (1 === chromaFormatIdc) && (0 === separateColourPlaneFlag) ? 2 : 1;
  226. width -= (subWidthC * spsMap.get("conf_win_right_offset") + subWidthC * spsMap.get("conf_win_left_offset"));
  227. height -= (subHeightC * spsMap.get("conf_win_bottom_offset") + subHeightC * spsMap.get("conf_win_top_offset"));
  228. }
  229. var decodeSize = width * height;
  230. var sizeInfo = {
  231. 'width': width,
  232. 'height': height,
  233. 'decodeSize': decodeSize
  234. };
  235. return sizeInfo;
  236. },
  237. getSpsValue: function (key) {
  238. return spsMap.get(key);
  239. },
  240. };
  241. return new Constructor();
  242. }