H2642.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. importScripts('./jsFFMPEG.js');
  2. let initDecoder = null;
  3. let decoderContext = null;
  4. let decodeByFFMPEG = null;
  5. let getWidth = null;
  6. let getHeight = null;
  7. let closeContext = null;
  8. let context = null;
  9. let outpic = null;
  10. let outpicptr = null;
  11. let ID = 264;
  12. let initialized = false;
  13. let firstIFrame = true;
  14. class H264Decoder {
  15. constructor() {
  16. //Module.onRuntimeInitialized = () => {
  17. console.log('h264 decoder init')
  18. initDecoder = Module.cwrap('init_jsFFmpeg', 'void', []);
  19. decoderContext = Module.cwrap('context_jsFFmpeg', 'number', ['number']);
  20. decodeByFFMPEG = Module.cwrap('decode_video_jsFFmpeg', 'number', ['number', 'array', 'number', 'number']);
  21. getWidth = Module.cwrap('get_width', 'number', ['number']);
  22. getHeight = Module.cwrap('get_height', 'number', ['number']);
  23. closeContext = Module.cwrap('close_jsFFmpeg', 'number', ['number']);
  24. initDecoder();
  25. this.init();
  26. initialized = true;
  27. //};
  28. }
  29. init() {
  30. if (context !== null) {
  31. closeContext(context);
  32. context = null;
  33. }
  34. context = decoderContext(ID);
  35. }
  36. setOutputSize(size) {
  37. console.log("H264 Decoder setOutputSize");
  38. let outpicsize = size * 1.5;
  39. outpicptr = Module._malloc(outpicsize);
  40. outpic = new Uint8Array(Module.HEAPU8.buffer, outpicptr, outpicsize);
  41. }
  42. decode(data) {
  43. if(!initialized) {
  44. console.log('未初始化完成')
  45. return null;
  46. }
  47. console.log(data.subarray(0, 100))
  48. let frameType = ((data[4] & 0x1f) === 7 || (data[4] & 0x1f) === 5) ? 'I' : 'P';
  49. //console.log(data[4] & 0x1f)
  50. if(frameType === 'I' && initialized) {
  51. firstIFrame = true;
  52. }
  53. if(!firstIFrame) {
  54. console.log('非 firstIFrame')
  55. return null;
  56. }
  57. let beforeDecoding = null;
  58. let decodingTime = null;
  59. let frameData = null;
  60. let bufferIdx = null;
  61. var dataHeap = null;
  62. beforeDecoding = Date.now();
  63. decodeByFFMPEG(context, data, data.length, outpic.byteOffset);
  64. decodingTime = Date.now() - beforeDecoding;
  65. let width = getWidth(context);
  66. let height = getHeight(context);
  67. console.log(width, height)
  68. if (width > 0 && height > 0) {
  69. let copyOutput = new Uint8Array(outpic);
  70. frameData = {
  71. 'data': copyOutput,
  72. 'bufferIdx': bufferIdx,
  73. 'width': width,
  74. 'height': height,
  75. 'codecType': 'h264',
  76. 'decodingTime': decodingTime,
  77. 'frameType': frameType,
  78. };
  79. console.log(frameData)
  80. return frameData;
  81. }
  82. // if(decodeby) {
  83. // //avcodec_decode_video2(context, outpicptr, size, data);
  84. // //console.log(Module.HEAP8.subarray(outpicptr, outpicptr+20))
  85. //
  86. // //
  87. // var memoryData = Module._malloc(data.byteLength);
  88. // Module.HEAPU8.set(data, memoryData);
  89. // var ptr = Module._video_decode_frame(video_decoder_ctx, memoryData, data.byteLength);
  90. // Module._free(memoryData);
  91. // if(ptr === 0) {
  92. // console.error("[ERROR] no Frame Data!");
  93. // return null;
  94. // }else {
  95. // }
  96. // }else {
  97. // try {
  98. // //outpic = Module.HEAPU8.length - data.length - 1000;
  99. // Module.HEAPU8.set(data, outpic);
  100. // console.log(data.length, data.subarray(0, 30), outpic, Module.HEAPU8.subarray(outpic))
  101. // //let result = avcodec_decode_video2(context, outpic, size/8, data);
  102. // console.log(h264_decode_frame(context, data, data.length, outpic));
  103. // //dataHeap = new Uint8Array(Module.HEAPU8.buffer, outpic, size);
  104. // //dataHeap.set(data);
  105. // //outpic.set(data);
  106. // //console.log(data.length, data.subarray(0, 30), outpic.byteOffset, outpic.subarray(0, 30), Module.HEAPU8.subarray(outpic.byteOffset))
  107. // //let result = avcodec_decode_video2(context, outpic.byteOffset, 0, data);
  108. // //console.log('result: ', result)
  109. // } catch (e) {
  110. // console.log(e)
  111. // }
  112. //
  113. // }
  114. // if (!Constructor.prototype.isFirstFrame()) {
  115. // Constructor.prototype.setIsFirstFrame(true);
  116. // frameData = {
  117. // 'firstFrame': true,
  118. // };
  119. // return frameData;
  120. // }
  121. // draw picture in canvas.
  122. //console.log(outpic)
  123. //console.log(width, height)
  124. // if (width > 0 && height > 0) {
  125. let copyOutput;
  126. // if(decodeby) {
  127. // var width = Module.HEAPU32[ptr / 4],
  128. // height = Module.HEAPU32[ptr / 4 + 1],
  129. // YimgBufferPtr = Module.HEAPU32[ptr / 4 + 2],
  130. // UimgBufferPtr = Module.HEAPU32[ptr / 4 + 3],
  131. // VimgBufferPtr = Module.HEAPU32[ptr / 4 + 4],
  132. // YimageBuffer = Module.HEAPU8.subarray(YimgBufferPtr, YimgBufferPtr + width * height),
  133. // UimageBuffer = Module.HEAPU8.subarray(UimgBufferPtr, UimgBufferPtr + width * height / 4),
  134. // VimageBuffer = Module.HEAPU8.subarray(VimgBufferPtr, VimgBufferPtr + width * height / 4);
  135. //
  136. // var ydata = new Uint8Array(YimageBuffer);
  137. // var udata = new Uint8Array(UimageBuffer);
  138. // var vdata = new Uint8Array(VimageBuffer);
  139. //
  140. // frameData = {
  141. // 'bufferIdx': bufferIdx,
  142. // 'width': width,
  143. // 'height': height,
  144. // 'codecType': 'h264',
  145. // 'decodingTime': decodingTime,
  146. // 'frameType': frameType,
  147. // YData:ydata.buffer,
  148. // UData:udata.buffer,
  149. // VData:vdata.buffer,
  150. // };
  151. //
  152. // return frameData;
  153. // } else {
  154. // //console.log(outpic)
  155. // copyOutput = new Uint8Array(Module.HEAPU8.buffer, outpic, data.size);
  156. // //console.log(outpic)
  157. //
  158. // }
  159. }
  160. }