decoder.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. var isFinish = false;
  2. var isSwitchSharpness = false;
  3. var h264Queue = [];
  4. var ret;
  5. var maxWidth = 1080;
  6. var maxHeight = 1920;
  7. var globalYuvPtr = undefined;
  8. var golbalYuvData;//全局,只分配一次
  9. var renderCount = 0;
  10. function doSomeInit() {
  11. var allocSize = maxWidth * maxHeight * 3;
  12. golbalYuvData = new Uint8Array(allocSize);
  13. }
  14. self.Module = {
  15. onRuntimeInitialized: function () {
  16. isFinish = true;
  17. doSomeInit();
  18. ret = Module._openDecoder();
  19. if (!ret) {
  20. console.log("打开编码器成功");
  21. }
  22. }
  23. };
  24. self.importScripts("ffmpeghelper.js");
  25. self.addEventListener('message', function (e) {
  26. var msg = e.data;
  27. if (msg.type == "rawData") {
  28. var buffer = e.data.data;
  29. if (buffer[0] !== 0xff) { // 音频解码
  30. if (isSwitchSharpness) {
  31. var type = buffer[4] & 0x1f;
  32. if (type == 7 || type == 8) {
  33. console.log("视频类型:" + type);
  34. isSwitchSharpness = false;
  35. h264Queue.push(buffer);
  36. }
  37. } else {
  38. h264Queue.push(buffer);
  39. }
  40. }
  41. }
  42. if (msg.type == "switchSharpness") { // 分辨率切换实现
  43. isSwitchSharpness = true;
  44. closeDecoder();
  45. var ret = Module._openDecoder();//再次开启解码器
  46. var timeFlag = setInterval(decodeVideo, 1);
  47. console.log("切换解码器成功");
  48. }
  49. }, false);
  50. function PrintfLog(str) {
  51. var curTime = new Date().getTime();
  52. var objData = {
  53. cmd: 0,
  54. data: str,
  55. time: curTime
  56. };
  57. self.postMessage(objData);
  58. }
  59. function doRequestIFrame() {
  60. var objData = {
  61. cmd: 5,
  62. };
  63. self.postMessage(objData);
  64. }
  65. function decodeVideo() {
  66. if (h264Queue.length > 0 && isFinish) {
  67. decodeH264(h264Queue.shift());
  68. }
  69. }
  70. var timeFlag = setInterval(decodeVideo, 1);
  71. //实现C 端到js yuv数据赋值, 并分配给opengl 渲染
  72. /*yuvData, 存放yuv数据的数组
  73. * inputYuvPtr C++
  74. */
  75. function dispatchYuvData(yuvData, inputYuvPtr, videoWidth, videoHeight, copyLen) {
  76. for (i = 0; i < copyLen; i++) {
  77. yuvData[i] = Module.HEAPU8[(inputYuvPtr) + i];
  78. }
  79. var curTime = new Date().getTime();
  80. var objData = {
  81. cmd: 1,
  82. data: yuvData,
  83. time: curTime,
  84. width: videoWidth,
  85. height: videoHeight
  86. };
  87. self.postMessage(objData);
  88. }
  89. function decodeH264(data) {
  90. var frameWidth = 0;
  91. var frameHeight = 0;
  92. var inputPtr = Module._malloc(data.length); //输入数据
  93. for (i = 0; i < data.length; i++) {
  94. Module.HEAPU8[(inputPtr) + i] = data[i]; //转换为堆数据
  95. }
  96. var time = new Date().getTime();
  97. var allocSize = maxWidth * maxHeight * 3 / 2;
  98. if (globalYuvPtr == undefined) {
  99. globalYuvPtr = Module._malloc(allocSize);
  100. }
  101. var ret = Module._feedData(inputPtr, data.length, globalYuvPtr);
  102. if (ret >= 0)//解码成功才考虑渲染
  103. {
  104. frameWidth = Module._getVideoWidth();//拿到解码器宽、高
  105. frameHeight = Module._getVideoHeight();
  106. var curCost = new Date().getTime() - time;
  107. var copyLen = frameWidth * frameHeight * 3 / 2;//只拷贝必须的长度
  108. if (renderCount > 1)//第一帧因为画面时全绿色的不渲染
  109. {
  110. dispatchYuvData(golbalYuvData, globalYuvPtr, frameWidth, frameHeight, copyLen);
  111. } else {
  112. renderCount++;
  113. }
  114. }
  115. Module._free(inputPtr);
  116. }
  117. function closeDecoder() {
  118. clearInterval(timeFlag);//关闭原有定时器
  119. Module._closeDecoder();
  120. renderCount = 0;
  121. if (globalYuvPtr != undefined) {
  122. Module._free(globalYuvPtr);
  123. globalYuvPtr = undefined;
  124. }
  125. console.log("此时buffer长度: %d", h264Queue.length);
  126. while (h264Queue.lengh > 0) {
  127. h264Queue.shift();
  128. }
  129. }