importScripts('./jsFFMPEG.js'); let initDecoder = null; let decoderContext = null; let decodeByFFMPEG = null; let getWidth = null; let getHeight = null; let closeContext = null; let context = null; let outpic = null; let outpicptr = null; let ID = 264; let initialized = false; let firstIFrame = true; class H264Decoder { constructor() { //Module.onRuntimeInitialized = () => { console.log('h264 decoder init') initDecoder = Module.cwrap('init_jsFFmpeg', 'void', []); decoderContext = Module.cwrap('context_jsFFmpeg', 'number', ['number']); decodeByFFMPEG = Module.cwrap('decode_video_jsFFmpeg', 'number', ['number', 'array', 'number', 'number']); getWidth = Module.cwrap('get_width', 'number', ['number']); getHeight = Module.cwrap('get_height', 'number', ['number']); closeContext = Module.cwrap('close_jsFFmpeg', 'number', ['number']); initDecoder(); this.init(); initialized = true; //}; } init() { if (context !== null) { closeContext(context); context = null; } context = decoderContext(ID); } setOutputSize(size) { console.log("H264 Decoder setOutputSize"); let outpicsize = size * 1.5; outpicptr = Module._malloc(outpicsize); outpic = new Uint8Array(Module.HEAPU8.buffer, outpicptr, outpicsize); } decode(data) { if(!initialized) { console.log('未初始化完成') return null; } console.log(data.subarray(0, 100)) let frameType = ((data[4] & 0x1f) === 7 || (data[4] & 0x1f) === 5) ? 'I' : 'P'; //console.log(data[4] & 0x1f) if(frameType === 'I' && initialized) { firstIFrame = true; } if(!firstIFrame) { console.log('非 firstIFrame') return null; } let beforeDecoding = null; let decodingTime = null; let frameData = null; let bufferIdx = null; var dataHeap = null; beforeDecoding = Date.now(); decodeByFFMPEG(context, data, data.length, outpic.byteOffset); decodingTime = Date.now() - beforeDecoding; let width = getWidth(context); let height = getHeight(context); console.log(width, height) if (width > 0 && height > 0) { let copyOutput = new Uint8Array(outpic); frameData = { 'data': copyOutput, 'bufferIdx': bufferIdx, 'width': width, 'height': height, 'codecType': 'h264', 'decodingTime': decodingTime, 'frameType': frameType, }; console.log(frameData) return frameData; } // if(decodeby) { // //avcodec_decode_video2(context, outpicptr, size, data); // //console.log(Module.HEAP8.subarray(outpicptr, outpicptr+20)) // // // // var memoryData = Module._malloc(data.byteLength); // Module.HEAPU8.set(data, memoryData); // var ptr = Module._video_decode_frame(video_decoder_ctx, memoryData, data.byteLength); // Module._free(memoryData); // if(ptr === 0) { // console.error("[ERROR] no Frame Data!"); // return null; // }else { // } // }else { // try { // //outpic = Module.HEAPU8.length - data.length - 1000; // Module.HEAPU8.set(data, outpic); // console.log(data.length, data.subarray(0, 30), outpic, Module.HEAPU8.subarray(outpic)) // //let result = avcodec_decode_video2(context, outpic, size/8, data); // console.log(h264_decode_frame(context, data, data.length, outpic)); // //dataHeap = new Uint8Array(Module.HEAPU8.buffer, outpic, size); // //dataHeap.set(data); // //outpic.set(data); // //console.log(data.length, data.subarray(0, 30), outpic.byteOffset, outpic.subarray(0, 30), Module.HEAPU8.subarray(outpic.byteOffset)) // //let result = avcodec_decode_video2(context, outpic.byteOffset, 0, data); // //console.log('result: ', result) // } catch (e) { // console.log(e) // } // // } // if (!Constructor.prototype.isFirstFrame()) { // Constructor.prototype.setIsFirstFrame(true); // frameData = { // 'firstFrame': true, // }; // return frameData; // } // draw picture in canvas. //console.log(outpic) //console.log(width, height) // if (width > 0 && height > 0) { let copyOutput; // if(decodeby) { // var width = Module.HEAPU32[ptr / 4], // height = Module.HEAPU32[ptr / 4 + 1], // YimgBufferPtr = Module.HEAPU32[ptr / 4 + 2], // UimgBufferPtr = Module.HEAPU32[ptr / 4 + 3], // VimgBufferPtr = Module.HEAPU32[ptr / 4 + 4], // YimageBuffer = Module.HEAPU8.subarray(YimgBufferPtr, YimgBufferPtr + width * height), // UimageBuffer = Module.HEAPU8.subarray(UimgBufferPtr, UimgBufferPtr + width * height / 4), // VimageBuffer = Module.HEAPU8.subarray(VimgBufferPtr, VimgBufferPtr + width * height / 4); // // var ydata = new Uint8Array(YimageBuffer); // var udata = new Uint8Array(UimageBuffer); // var vdata = new Uint8Array(VimageBuffer); // // frameData = { // 'bufferIdx': bufferIdx, // 'width': width, // 'height': height, // 'codecType': 'h264', // 'decodingTime': decodingTime, // 'frameType': frameType, // YData:ydata.buffer, // UData:udata.buffer, // VData:vdata.buffer, // }; // // return frameData; // } else { // //console.log(outpic) // copyOutput = new Uint8Array(Module.HEAPU8.buffer, outpic, data.size); // //console.log(outpic) // // } } }