superxxd
2 years ago
37 changed files with 13575 additions and 4226 deletions
@ -0,0 +1,11 @@ |
|||
开启浏览器HEVC |
|||
|
|||
[https://github.com/StaZhu/enable-chromium-hevc-hardware-decoding]() |
|||
|
|||
[FFmpeg-Plus-OpenGL with ffmpeg 4.0 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/559313629) |
|||
|
|||
[Video TEST PAGE HEVC (ibytedtos.com)](https://lf-tk-sg.ibytedtos.com/obj/tcs-client-sg/resources/video_demo_hevc.html) |
|||
|
|||
[https://github.com/Bilibili/flv.js]() |
|||
|
|||
[https://w3c.github.io/media-source/]() |
@ -0,0 +1,127 @@ |
|||
var bReAudio=false; |
|||
var audioDC=null; |
|||
|
|||
const AUDIO_START_STR="audio start"; |
|||
const AUDIO_END_STR="audio end" |
|||
const AUDIO_DECODEC_TYPE_STR="decodctype"; |
|||
// const PACKET_LEN_STR="Packetslen";
|
|||
// const PACKET_COUNT_STR="packets";
|
|||
// const AUDIO_PACKET_PTS="audiopts";
|
|||
// const AUDIO_PACKET_REM_STR="rem";
|
|||
var decodctype=""; |
|||
var audiopts=0; |
|||
var audiodata=null; |
|||
var audiodatalen=0; |
|||
var audiopacket=0; |
|||
var audioreceivet1=new Date().getTime(); |
|||
function initAudioDC(pc) { |
|||
console.log("initAACDC",Date()); |
|||
audioDC = pc.createDataChannel("audiodc"); |
|||
|
|||
audioDC.onmessage = function (event) { |
|||
// console.log(bReAudio,":",event.data)
|
|||
if(bReAudio){ |
|||
if(isString(event.data)) { |
|||
console.log("reveive: "+event.data) |
|||
if(event.data.indexOf(AUDIO_END_STR)!=-1){ |
|||
bReAudio=false; |
|||
console.log("frame ok",":",event.data," len:"+audiodatalen) |
|||
if(audiodatalen>0){ |
|||
// const framepacket=new Uint8Array(audiodata)
|
|||
const audiot2 = new Date().getTime()-audioreceivet1; |
|||
console.log("receive time:"+audiot2+" len:"+audiodatalen); |
|||
mseCallback(audiodata); |
|||
//scriptNodeCallback(audiodata,len);
|
|||
// var data={
|
|||
// audiopts: audiopts,
|
|||
// size: audiodatalen,
|
|||
// decodctype: decodctype,
|
|||
// packet: audiodata
|
|||
// };
|
|||
// var req = {
|
|||
// t: ksendPlayerAudioFrameReq,
|
|||
// l: audiodatalen,
|
|||
// d: data
|
|||
// };
|
|||
// player.postMessage(req,[req.d.packet]);
|
|||
|
|||
audiodata=null; |
|||
audiodatalen=0; |
|||
audiopacket=0; |
|||
audioreceivet1=new Date().getTime(); |
|||
} |
|||
|
|||
return; |
|||
} |
|||
}else{ |
|||
if (audiodata != null) { |
|||
|
|||
audiodata=appendBuffer(audiodata,event.data); |
|||
} else if (event.data.byteLength < expectLength) { |
|||
audiodata = event.data.slice(0); |
|||
|
|||
} else { |
|||
|
|||
audiodata=event.data; |
|||
|
|||
} |
|||
|
|||
audiodatalen+=event.data.byteLength; |
|||
audiopacket++; |
|||
console.log("packet: "+audiopacket+": t len"+audiodatalen) |
|||
return; |
|||
} |
|||
|
|||
} |
|||
if(isString(event.data)) { |
|||
let startstring = event.data |
|||
console.log("reveive: "+startstring) |
|||
if(startstring.indexOf(AUDIO_START_STR)!=-1){ |
|||
// console.log(event.data );
|
|||
const startarray=startstring.split(","); |
|||
// startstr := "audio start ,decodctype:" + decodctypestr + ",Packetslen:" + strconv.Itoa(glength) + ",packets:" + strconv.Itoa(count) + ",rem:" + strconv.Itoa(rem)
|
|||
|
|||
for(let i=0;i<startarray.length;i++){ |
|||
const parakv=startarray[i].split(":"); |
|||
if(parakv!==null){ |
|||
switch(parakv[0]){ |
|||
case AUDIO_START_STR: |
|||
break; |
|||
case PACKET_PTS: |
|||
audiopts=parseInt(parakv[1]) |
|||
break; |
|||
case AUDIO_DECODEC_TYPE_STR: |
|||
decodctype=parakv[1] |
|||
break; |
|||
|
|||
} |
|||
|
|||
} |
|||
} |
|||
// string.split(":")
|
|||
bReAudio=true; |
|||
audiopacket=0; |
|||
return; |
|||
} |
|||
} |
|||
}; |
|||
|
|||
audioDC.onopen = function () { |
|||
console.log("audio datachannel open"); |
|||
// setAudioDecoder(1) //mse 0 contex
|
|||
// playAudio();
|
|||
// var req = {
|
|||
// t: kInitPlayerReq,
|
|||
// };
|
|||
// player.postMessage(req);
|
|||
|
|||
bWorking = true; |
|||
|
|||
}; |
|||
|
|||
audioDC.onclose = function () { |
|||
console.log("audio datachannel close"); |
|||
bWorking=false; |
|||
|
|||
}; |
|||
} |
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
@ -0,0 +1,405 @@ |
|||
self.Module = { |
|||
onRuntimeInitialized: function () { |
|||
onWasmLoaded(); |
|||
}, |
|||
|
|||
}; |
|||
|
|||
self.importScripts("common.js"); |
|||
|
|||
self.importScripts("videodec_simd_noems6_h265.js") |
|||
|
|||
|
|||
var pts=0; |
|||
|
|||
H265Frame =[]; |
|||
AUDIOFrame =[]; |
|||
function Decoder(){ |
|||
// this.timer=null;
|
|||
this.decodeTimer = null; |
|||
this.wasmLoaded = false; |
|||
this.vtype = 'hevc' |
|||
this.format = 'annexb' |
|||
this.extraData = "" |
|||
this.tmpReqQue = []; |
|||
this.decodestatus=false; |
|||
this.lastpts = 0; |
|||
} |
|||
Decoder.prototype.cacheReq = function (req) { |
|||
if (req) { |
|||
this.tmpReqQue.push(req); |
|||
} |
|||
}; |
|||
Decoder.prototype.onWasmLoaded = function () { |
|||
console.log("Wasm loaded."); |
|||
this.wasmLoaded = true; |
|||
while (this.tmpReqQue.length > 0) { |
|||
var req = this.tmpReqQue.shift(); |
|||
this.processReq(req); |
|||
} |
|||
} |
|||
Decoder.prototype.initDecoder = function () { |
|||
|
|||
var ret=0; |
|||
//void VideoDecoder::setCodec(string vtype, string format, string extra)
|
|||
Module._codecInit() |
|||
console.log("initDecoder return " + ret + "."); |
|||
|
|||
var objData = { |
|||
t: kInitDecoderRsp, |
|||
e: ret |
|||
}; |
|||
self.postMessage(objData); |
|||
}; |
|||
|
|||
Decoder.prototype.uninitDecoder = function () { |
|||
var ret = 0;//Module._uninitDecoder();
|
|||
Module._clear(); |
|||
console.log("Uninit ffmpeg decoder return " + ret + "."); |
|||
|
|||
}; |
|||
// var data={
|
|||
// pts: pts,
|
|||
// size: size,
|
|||
// iskeyframe: isKeyFrame,
|
|||
// packet: h265data
|
|||
// };
|
|||
// var req = {
|
|||
// t: ksendPlayerVideoFrameReq,
|
|||
// l: h265datalen,
|
|||
// d: data
|
|||
// };
|
|||
const MIN_H265FRAME_FOR_DECODE=0 |
|||
var decodet1=new Date().getTime(); |
|||
Decoder.prototype.decode=function(){ |
|||
if(H265Frame.length>MIN_H265FRAME_FOR_DECODE){ |
|||
// this.decodestatus=true;
|
|||
decodet1=new Date().getTime(); |
|||
var typedArray=H265Frame[0];//new Uint8Array(H265Frame[0]);
|
|||
var packet=typedArray.d; |
|||
var size = typedArray.size; |
|||
// console.log("decode len: " + size)
|
|||
console.log("decode pts:",typedArray.pts," packet len:",size," H265Frame total",H265Frame.length) |
|||
var cacheBuffer = Module._malloc(size); |
|||
Module.HEAPU8.set(packet, cacheBuffer); |
|||
//void VideoDecoder::decode(string input, unsigned int isKeyFrame, unsigned int timestamp)
|
|||
Module._decode(cacheBuffer,size,typedArray.iskeyframe,typedArray.pts); |
|||
if (cacheBuffer != null) { |
|||
Module._free(cacheBuffer); |
|||
cacheBuffer = null; |
|||
} |
|||
H265Frame.shift(); |
|||
|
|||
} |
|||
|
|||
} |
|||
Decoder.prototype.startDecoding = function (interval) { |
|||
console.log("Start decoding."); |
|||
if (this.decodeTimer) { |
|||
clearInterval(this.decodeTimer); |
|||
} |
|||
this.decodeTimer = setInterval(this.decode, 0);//interval);
|
|||
}; |
|||
|
|||
Decoder.prototype.pauseDecoding = function () { |
|||
console.log("Pause decoding."); |
|||
if (this.decodeTimer) { |
|||
clearInterval(this.decodeTimer); |
|||
this.decodeTimer = null; |
|||
} |
|||
}; |
|||
// Decoder.prototype.startdecode=function(){
|
|||
// // this.timer = requestAnimationFrame(function fn() {
|
|||
// // // if(this.decodertimer++>=60)
|
|||
// // this.decodertimer=0;
|
|||
// // this.decode();
|
|||
// // requestAnimationFrame(fn);
|
|||
// // })
|
|||
|
|||
// // move = parseInt(getComputedStyle(box).left);
|
|||
// // if (move < 800) {
|
|||
// // box.style.left = move + 8 + 'px';
|
|||
// // requestAnimationFrame(fn);
|
|||
// // } else {
|
|||
// // cancelAnimationFrame(timer);
|
|||
// }
|
|||
Decoder.prototype.displayVideoFrame = function displayVideoFrame(obj){ |
|||
// var obj = {
|
|||
// data: data,
|
|||
// width,
|
|||
// height
|
|||
// }
|
|||
var objData = { |
|||
t: kVideoFrame, |
|||
s: pts, |
|||
d: obj |
|||
}; |
|||
self.postMessage(objData, [objData.d.data.buffer]); |
|||
const t2 = new Date().getTime()-decodet1; |
|||
console.log("end decode time:"+t2+" len:"+size);//+" data:"+typedArray.toString(16));
|
|||
// decodet1=new Date().getTime();
|
|||
// displayVideoFrame(obj);
|
|||
} |
|||
IsGreyData = function(data) { |
|||
var isgray=false; |
|||
var len=data.length<100?data.length:100; |
|||
for(var i=0; i<len;i++){ |
|||
isgray=data[i]===128?true:false; |
|||
} |
|||
return isgray; |
|||
} |
|||
Decoder.prototype.decode_seq=function() { |
|||
//void(*VideoCallback)(unsigned char* data,int width, int height, long pts);
|
|||
var videoCallback = Module.addFunction(function (yuvArray, width, height, pts) { |
|||
let size = width*height; |
|||
let halfSize = size>>2; |
|||
|
|||
let yPtr = HEAPU32[(yuvArray>>2)]; |
|||
let uPtr = HEAPU32[(yuvArray>>2) + 1]; |
|||
let vPtr = HEAPU32[(yuvArray>>2) + 2]; |
|||
|
|||
let yBuf = HEAPU8.subarray(yPtr, yPtr + size); |
|||
let uBuf = HEAPU8.subarray(uPtr, uPtr + halfSize); |
|||
let vBuf = HEAPU8.subarray(vPtr, vPtr + halfSize); |
|||
|
|||
// let datas = [Uint8Array.from(yBuf), Uint8Array.from(uBuf), Uint8Array.from(vBuf)];
|
|||
let datas = new Uint8Array(yBuf.length + uBuf.length + vBuf.length) |
|||
|
|||
// let out_u = HEAPU8.subarray(addr_u, addr_u + (stride_u * height) / 2)
|
|||
// let out_v = HEAPU8.subarray(addr_v, addr_v + (stride_v * height) / 2)
|
|||
// let buf_y = new Uint8Array(out_y)
|
|||
// let buf_u = new Uint8Array(out_u)
|
|||
// let buf_v = new Uint8Array(out_v)
|
|||
// let data = new Uint8Array(buf_y.length + buf_u.length + buf_v.length)
|
|||
datas.set(yBuf, 0) |
|||
datas.set(uBuf, yBuf.length) |
|||
datas.set(vBuf, yBuf.length + uBuf.length) |
|||
|
|||
|
|||
var obj = { |
|||
s: pts, |
|||
data: datas, |
|||
width, |
|||
height, |
|||
|
|||
} |
|||
var objData = { |
|||
t: kVideoFrame, |
|||
d: obj |
|||
}; |
|||
self.postMessage(objData, [objData.d.data.buffer]); |
|||
const t2 = new Date().getTime()-decodet1; |
|||
console.log("end decode simd time:"+t2,"pts",pts);//+" data:"+typedArray.toString(16));
|
|||
},'viiii') |
|||
this.vtype="hevc"; |
|||
this.format="annexb"; |
|||
this.extraData=""; |
|||
Module._setCodec(this.vtype,this.format,this.extraData,videoCallback); |
|||
// var ret = Module._openDecoder(decoder_type, videoCallback, LOG_LEVEL_WASM)
|
|||
// if(ret == 0) {
|
|||
console.log("openDecoder success"); |
|||
// } else {
|
|||
// console.error("openDecoder failed with error", ret);
|
|||
// // return;
|
|||
// }
|
|||
var objData = { |
|||
t: kOpenDecoderRsp, |
|||
e: 0 |
|||
}; |
|||
self.postMessage(objData); |
|||
} |
|||
// Decoder.prototype.onVideoInfo=function(width,height){
|
|||
// this.width=width;
|
|||
// this.height=height;
|
|||
// var objData={
|
|||
// t: kVideoInfo,
|
|||
// width: width,
|
|||
// height: height
|
|||
// };
|
|||
|
|||
// self.postMessage(objData);
|
|||
|
|||
// }
|
|||
// Decoder.prototype.onYUVData = function (yuvArray,pts){
|
|||
// let size = this.width*this.height;
|
|||
// let halfSize = size>>2;
|
|||
|
|||
// let yPtr = HEAPU32[(yuvArray>>2)];
|
|||
// let uPtr = HEAPU32[(yuvArray>>2) + 1];
|
|||
// let vPtr = HEAPU32[(yuvArray>>2) + 2];
|
|||
|
|||
// let yBuf = HEAPU8.subarray(yPtr, yPtr + size);
|
|||
// let uBuf = HEAPU8.subarray(uPtr, uPtr + halfSize);
|
|||
// let vBuf = HEAPU8.subarray(vPtr, vPtr + halfSize);
|
|||
|
|||
// let datas = [Uint8Array.from(yBuf), Uint8Array.from(uBuf), Uint8Array.from(vBuf)];
|
|||
|
|||
// // let vFrame = {
|
|||
// // pixelType:'I420',
|
|||
// // datas: datas,
|
|||
// // width: this.width,
|
|||
// // height: this.height,
|
|||
// // pts: pts
|
|||
// // };
|
|||
// // let out_u = HEAPU8.subarray(addr_u, addr_u + (stride_u * height) / 2)
|
|||
// // let out_v = HEAPU8.subarray(addr_v, addr_v + (stride_v * height) / 2)
|
|||
// // let buf_y = new Uint8Array(out_y)
|
|||
// // let buf_u = new Uint8Array(out_u)
|
|||
// // let buf_v = new Uint8Array(out_v)
|
|||
// // let data = new Uint8Array(buf_y.length + buf_u.length + buf_v.length)
|
|||
// // data.set(buf_y, 0)
|
|||
// // data.set(buf_u, buf_y.length)
|
|||
// // data.set(buf_v, buf_y.length + buf_u.length)
|
|||
|
|||
// var obj = {
|
|||
// data: datas,
|
|||
// width,
|
|||
// height
|
|||
// }
|
|||
// var objData = {
|
|||
// t: kVideoFrame,
|
|||
// s: pts,
|
|||
// d: obj
|
|||
// };
|
|||
// self.postMessage(objData, [objData.d.data.buffer]);
|
|||
// const t2 = new Date().getTime()-decodet1;
|
|||
// console.log("decode time:"+t2);//+" data:"+typedArray.toString(16));
|
|||
// }
|
|||
function findMinFrame(H265Frame){ |
|||
var min=50000; |
|||
var index=0; |
|||
for(var i=0;i<H265Frame.length;i++){ |
|||
if((H265Frame[i].iskeyframe!==true)){ |
|||
if(H265Frame[i].size<min){ |
|||
min=H265Frame[i].size |
|||
index=i |
|||
} |
|||
} |
|||
} |
|||
return index |
|||
} |
|||
Decoder.prototype.sendFrame = function(data,type){ |
|||
// if(data.pts<=this.lastpts){
|
|||
// return;
|
|||
// }
|
|||
this.lastpts=data.pts; |
|||
var typedArray = { |
|||
pts: data.pts, |
|||
iskeyframe: data.iskeyframe, |
|||
size: data.size, |
|||
// d: data.packet//
|
|||
d: data.packet//new Uint8Array(data.packet)
|
|||
} |
|||
console.log("sendFrame pts:",typedArray.pts) |
|||
// if(H265Frame.length>MAX_FRAME_SIZE){
|
|||
// H265Frame.shift();
|
|||
// }
|
|||
|
|||
if(type==="VIDEO"){ |
|||
if(H265Frame.length>MAX_FRAME_SIZE){ |
|||
var index=findMinFrame(H265Frame) |
|||
H265Frame = H265Frame.splice(index, 1) |
|||
// for(var i=0;i<H265Frame.length;i++)
|
|||
// if((H265Frame[i].iskeyframe!==true)){
|
|||
// // &&(H265Frame[i].size<MAX_DELETE_FRAME_SIZE)
|
|||
// H265Frame = H265Frame.splice(i, 1)
|
|||
|
|||
// break
|
|||
// //break;
|
|||
// // H265Frame.shift();
|
|||
// }
|
|||
} |
|||
H265Frame.push(typedArray) |
|||
}else if(type==="AUDIO"){ |
|||
AUDIOFrame.push(typedArray) |
|||
} |
|||
|
|||
} |
|||
Decoder.prototype.closeDecoder = function () { |
|||
console.log("closeDecoder."); |
|||
if (this.decodeTimer) { |
|||
clearInterval(this.decodeTimer); |
|||
this.decodeTimer = null; |
|||
console.log("Decode timer stopped."); |
|||
} |
|||
|
|||
// var ret = Module._closeDecoder();
|
|||
console.log("Close ffmpeg decoder return " + ret + "."); |
|||
|
|||
var objData = { |
|||
t: kCloseDecoderRsp, |
|||
e: 0 |
|||
}; |
|||
self.postMessage(objData); |
|||
}; |
|||
Decoder.prototype.processReq = function (req) { |
|||
// console.log("processReq " + req.t + ".");
|
|||
switch (req.t) { |
|||
case kInitDecoderReq: |
|||
this.initDecoder(); |
|||
break; |
|||
case kUninitDecoderReq: |
|||
this.uninitDecoder(); |
|||
break; |
|||
case kOpenDecoderReq: |
|||
this.decode_seq(); |
|||
break; |
|||
case kCloseDecoderReq: |
|||
this.closeDecoder(); |
|||
break; |
|||
case kStartDecodingReq: |
|||
this.startDecoding(req.i); |
|||
break; |
|||
case kPauseDecodingReq: |
|||
this.pauseDecoding(); |
|||
break; |
|||
case kFeedDataReq: |
|||
this.sendFrame(req.d,req.type); |
|||
break; |
|||
// case kSeekToReq:
|
|||
// this.seekTo(req.ms);
|
|||
// break;
|
|||
default: |
|||
this.logger.logError("Unsupport messsage " + req.t); |
|||
} |
|||
}; |
|||
|
|||
self.decoder = new Decoder; |
|||
|
|||
self.onmessage = function (evt) { |
|||
if (!self.decoder) { |
|||
console.log("[ER] Decoder not initialized!"); |
|||
return; |
|||
} |
|||
|
|||
var req = evt.data; |
|||
if (!self.decoder.wasmLoaded) { |
|||
self.decoder.cacheReq(req); |
|||
console.log("Temp cache req " + req.t + "."); |
|||
return; |
|||
} |
|||
|
|||
self.decoder.processReq(req); |
|||
}; |
|||
|
|||
function onWasmLoaded() { |
|||
if (self.decoder) { |
|||
self.decoder.onWasmLoaded(); |
|||
} else { |
|||
console.log("[ER] No decoder!"); |
|||
} |
|||
} |
|||
function onVideoInfo(width,height){ |
|||
if (self.decoder) { |
|||
self.decoder.onVideoInfo(width,height); |
|||
} else { |
|||
console.log("[ER] No decoder!"); |
|||
} |
|||
} |
|||
function onYUVData (yuvArray,pts){ |
|||
if (self.decoder) { |
|||
self.decoder.onYUVData(yuvArray,pts); |
|||
} else { |
|||
console.log("[ER] No decoder!"); |
|||
} |
|||
} |
@ -0,0 +1,600 @@ |
|||
//https://juejin.cn/post/7050496511288803336
|
|||
// mergeInto(LibraryManager.library,{
|
|||
// onHeader: function(header){
|
|||
// return jsonHeader(header);
|
|||
// },
|
|||
|
|||
// onMediaInfo: function(mediaInfo) {
|
|||
// console.log("onMediaInfo"+mediaInfo.toString(16));
|
|||
// //Module.postMessage({ type: "mediaInfo", data: mediaInfo });
|
|||
// },
|
|||
// onAudioDataSize: function(data) {
|
|||
// // Module.audioBufferSize = data.size;
|
|||
// // Module.audioBuffer = Module._malloc(Module.audioBufferSize);
|
|||
// // Module._codecSetAudioBuffer(Module.audioBuffer);
|
|||
// },
|
|||
// onAudioData: function(data) {
|
|||
// // var timestamp = data.timestamp;
|
|||
// // Module.audioTimestamps.push(timestamp);
|
|||
|
|||
// // var u8s = Module.HEAPU8.subarray(
|
|||
// // Module.audioBuffer,
|
|||
// // Module.audioBuffer + Module.audioBufferSize
|
|||
// // );
|
|||
|
|||
// // var output = null;
|
|||
// // if (supportSharedBuffer) {
|
|||
// // output = new Uint8Array(new SharedArrayBuffer(u8s.byteLength));
|
|||
// // output.set(u8s);
|
|||
// // } else {
|
|||
// // output = new Uint8Array(u8s);
|
|||
// // }
|
|||
|
|||
// // Module._free(Module.audioBuffer);
|
|||
// // Module.audioBuffer = null;
|
|||
// // Module.postMessage(
|
|||
// // {
|
|||
// // type: "audio",
|
|||
// // data: {
|
|||
// // buffer: output.buffer,
|
|||
// // timestamp: timestamp
|
|||
// // }
|
|||
// // },
|
|||
// // supportSharedBuffer ? undefined : [output.buffer]
|
|||
// // );
|
|||
// },
|
|||
// onVideoDataSize: function(data) {
|
|||
// console.log("onVideoDataSize"+data.toString(16));
|
|||
// // if (Module.videoBuffer == null) {
|
|||
// // Module.videoBufferSize = data.size;
|
|||
// // Module.videoBuffer = Module._malloc(Module.videoBufferSize);
|
|||
// // if (supportSharedBuffer) {
|
|||
// // Module.videoSharedBuffer = new SharedArrayBuffer(data.size);
|
|||
// // }
|
|||
// // }
|
|||
// // Module._codecSetVideoBuffer(Module.videoBuffer);
|
|||
// },
|
|||
// onVideoData: function(data) {
|
|||
// console.log("onVideoData"+data.toString(16));
|
|||
// // var timestamp = data.timestamp;
|
|||
// // Module.videoTimestamps.push(timestamp);
|
|||
|
|||
// // var u8s = Module.HEAPU8.subarray(
|
|||
// // Module.videoBuffer,
|
|||
// // Module.videoBuffer + Module.videoBufferSize
|
|||
// // );
|
|||
|
|||
// // var output = null;
|
|||
// // if (supportSharedBuffer) {
|
|||
// // output = new Uint8Array(Module.videoSharedBuffer);
|
|||
// // output.set(u8s);
|
|||
// // } else {
|
|||
// // output = new Uint8Array(u8s);
|
|||
// // }
|
|||
|
|||
// // Module.postMessage(
|
|||
// // {
|
|||
// // type: "video",
|
|||
// // data: {
|
|||
// // buffer: output.buffer,
|
|||
// // timestamp: timestamp,
|
|||
// // width: data.width,
|
|||
// // height: data.height,
|
|||
// // stride0: data.stride0,
|
|||
// // stride1: data.stride1
|
|||
// // }
|
|||
// // },
|
|||
// // supportSharedBuffer ? undefined : [output.buffer]
|
|||
// // );
|
|||
// },
|
|||
// onComplete: function() {
|
|||
// console.log("onComplete");
|
|||
// // Module.postMessage({ type: "complete" });
|
|||
// }
|
|||
// })
|
|||
var Module = {}; |
|||
self.importScripts("common.js"); |
|||
self.importScripts("videodec_wx_h265.js"); |
|||
self.importScripts("raw-parser.js"); |
|||
|
|||
var isWorker = typeof importScripts == "function"; |
|||
var bridgeName = "__CODE_BRIDGE__" + +new Date(); |
|||
(isWorker ? self : window)[bridgeName] = { |
|||
onHeader: function(header) { |
|||
onHeader(header); |
|||
// Module.postMessage({ type: "header", data: header });
|
|||
}, |
|||
onMediaInfo: function(mediaInfo) { |
|||
onMediaInfo(mediaInfo); |
|||
// Module.postMessage({ type: "mediaInfo", data: mediaInfo });
|
|||
}, |
|||
onAudioDataSize: function(data) { |
|||
onAudioDataSize(data); |
|||
// Module.audioBufferSize = data.size;
|
|||
// Module.audioBuffer = Module._malloc(Module.audioBufferSize);
|
|||
// Module._codecSetAudioBuffer(Module.audioBuffer);
|
|||
}, |
|||
onAudioData: function(data) { |
|||
onVideoData(data); |
|||
// var timestamp = data.timestamp;
|
|||
// Module.audioTimestamps.push(timestamp);
|
|||
|
|||
// var u8s = Module.HEAPU8.subarray(
|
|||
// Module.audioBuffer,
|
|||
// Module.audioBuffer + Module.audioBufferSize
|
|||
// );
|
|||
|
|||
// var output = null;
|
|||
// if (supportSharedBuffer) {
|
|||
// output = new Uint8Array(new SharedArrayBuffer(u8s.byteLength));
|
|||
// output.set(u8s);
|
|||
// } else {
|
|||
// output = new Uint8Array(u8s);
|
|||
// }
|
|||
|
|||
// Module._free(Module.audioBuffer);
|
|||
// Module.audioBuffer = null;
|
|||
// Module.postMessage(
|
|||
// {
|
|||
// type: "audio",
|
|||
// data: {
|
|||
// buffer: output.buffer,
|
|||
// timestamp: timestamp
|
|||
// }
|
|||
// },
|
|||
// supportSharedBuffer ? undefined : [output.buffer]
|
|||
// );
|
|||
}, |
|||
onVideoDataSize: function(data) { |
|||
onAudioDataSize(data); |
|||
// if (Module.videoBuffer == null) {
|
|||
// Module.videoBufferSize = data.size;
|
|||
// Module.videoBuffer = Module._malloc(Module.videoBufferSize);
|
|||
// if (supportSharedBuffer) {
|
|||
// Module.videoSharedBuffer = new SharedArrayBuffer(data.size);
|
|||
// }
|
|||
// }
|
|||
// Module._codecSetVideoBuffer(Module.videoBuffer);
|
|||
}, |
|||
onVideoData: function(data) { |
|||
onVideoData(data); |
|||
// var timestamp = data.timestamp;
|
|||
// Module.videoTimestamps.push(timestamp);
|
|||
|
|||
// var u8s = Module.HEAPU8.subarray(
|
|||
// Module.videoBuffer,
|
|||
// Module.videoBuffer + Module.videoBufferSize
|
|||
// );
|
|||
|
|||
// var output = null;
|
|||
// if (supportSharedBuffer) {
|
|||
// output = new Uint8Array(Module.videoSharedBuffer);
|
|||
// output.set(u8s);
|
|||
// } else {
|
|||
// output = new Uint8Array(u8s);
|
|||
// }
|
|||
|
|||
// Module.postMessage(
|
|||
// {
|
|||
// type: "video",
|
|||
// data: {
|
|||
// buffer: output.buffer,
|
|||
// timestamp: timestamp,
|
|||
// width: data.width,
|
|||
// height: data.height,
|
|||
// stride0: data.stride0,
|
|||
// stride1: data.stride1
|
|||
// }
|
|||
// },
|
|||
// supportSharedBuffer ? undefined : [output.buffer]
|
|||
// );
|
|||
}, |
|||
onComplete: function() { |
|||
onComplete(); |
|||
// Module.postMessage({ type: "complete" });
|
|||
} |
|||
}; |
|||
// var decoder_type = DECODER_H265;
|
|||
var ptsIdx=0; |
|||
|
|||
H265Frame =[]; |
|||
function Decoder(){ |
|||
// this.timer=null;
|
|||
this.decodeTimer = null; |
|||
this.rawParserObj = null; |
|||
this.wasmLoaded = false; |
|||
this.tmpReqQue = []; |
|||
this.destroied = false; |
|||
// this.poddecoder = null;
|
|||
this.supportSharedBuffer = false; |
|||
this.bridgeName = "__CODE_BRIDGE__" + +new Date(); |
|||
this.audioTimestamps = [] |
|||
this.videoTimestamps = [] |
|||
this.audioBufferSize = 0 |
|||
this.videoBufferSize = 0 |
|||
this.audioBuffer = null |
|||
this.videoBuffer = null |
|||
this.videoSharedBuffer =null; |
|||
// var supportSharedBuffer = false;
|
|||
try { |
|||
this.supportSharedBuffer = !!new SharedArrayBuffer(0); |
|||
} catch (e) { |
|||
// nothing to do...
|
|||
} |
|||
// this.token = "base64:QXV0aG9yOmNoYW5neWFubG9uZ3xudW1iZXJ3b2xmLEdpdGh1YjpodHRwczovL2dpdGh1Yi5jb20vbnVtYmVyd29sZixFbWFpbDpwb3JzY2hlZ3QyM0Bmb3htYWlsLmNvbSxRUTo1MzEzNjU4NzIsSG9tZVBhZ2U6aHR0cDovL3h2aWRlby52aWRlbyxEaXNjb3JkOm51bWJlcndvbGYjODY5NCx3ZWNoYXI6bnVtYmVyd29sZjExLEJlaWppbmcsV29ya0luOkJhaWR1";
|
|||
// this.version = '100.2.0';
|
|||
} |
|||
|
|||
Decoder.prototype.cacheReq = function (req) { |
|||
if (req) { |
|||
this.tmpReqQue.push(req); |
|||
} |
|||
}; |
|||
Decoder.prototype.onWasmLoaded = function () { |
|||
console.log("Wasm loaded."); |
|||
this.wasmLoaded = true; |
|||
while (this.tmpReqQue.length > 0) { |
|||
var req = this.tmpReqQue.shift(); |
|||
this.processReq(req); |
|||
} |
|||
} |
|||
Decoder.prototype.initDecoder = function () { |
|||
// var ret = Module._initDecoder(fileSize, this.coreLogLevel);
|
|||
var ret=0; |
|||
console.log("initDecoder return " + ret + "."); |
|||
try { |
|||
this.supportSharedBuffer = !!new SharedArrayBuffer(0); |
|||
} catch (e) { |
|||
// nothing to do...
|
|||
} |
|||
// this.bridgeName = "__CODE_BRIDGE__" + +new Date();
|
|||
Module._codecInit(); |
|||
var callbackStr = bridgeName.split(""); |
|||
callbackStr = callbackStr |
|||
.map(function(v) { |
|||
return v.charCodeAt(0); |
|||
}) |
|||
.concat(0); |
|||
|
|||
var callbackStrData = Module._malloc(callbackStr.length - 1); |
|||
Module.HEAPU8.set(callbackStr, callbackStrData); |
|||
Module._codecSetBridgeName(callbackStrData); |
|||
|
|||
var objData = { |
|||
t: kInitDecoderRsp, |
|||
e: ret |
|||
}; |
|||
self.postMessage(objData); |
|||
}; |
|||
|
|||
Decoder.prototype.openDecoder = function () { |
|||
|
|||
var objData = { |
|||
t: kOpenDecoderRsp, |
|||
e: 0 |
|||
}; |
|||
self.postMessage(objData); |
|||
|
|||
} |
|||
Decoder.prototype.uninitDecoder = function () { |
|||
var ret = 0;//Module._uninitDecoder();
|
|||
Module._codecFree(); |
|||
console.log("Uninit ffmpeg decoder return " + ret + "."); |
|||
|
|||
}; |
|||
|
|||
Decoder.prototype.onHeader = function(header) { |
|||
console.log("onHeader",header); |
|||
// Module.postMessage({ type: "header", data: header });
|
|||
}; |
|||
Decoder.prototype.onMediaInfo = function(mediaInfo) { |
|||
console.log("onMediaInfo",mediaInfo); |
|||
// Module.postMessage({ type: "mediaInfo", data: mediaInfo });
|
|||
}; |
|||
Decoder.prototype.onAudioDataSize = function(data) { |
|||
console.log("onAudioDataSize",data); |
|||
this.audioBufferSize = data.size; |
|||
this.audioBuffer = Module._malloc(this.audioBufferSize); |
|||
Module._codecSetAudioBuffer(this.audioBuffer); |
|||
}; |
|||
Decoder.prototype.onAudioData = function(data) { |
|||
var timestamp = data.timestamp; |
|||
this.audioTimestamps.push(timestamp); |
|||
|
|||
var u8s = Module.HEAPU8.subarray( |
|||
this.audioBuffer, |
|||
this.audioBuffer +this.audioBufferSize |
|||
); |
|||
|
|||
var output = null; |
|||
if (supportSharedBuffer) { |
|||
output = new Uint8Array(new SharedArrayBuffer(u8s.byteLength)); |
|||
output.set(u8s); |
|||
} else { |
|||
output = new Uint8Array(u8s); |
|||
} |
|||
|
|||
Module._free(this.audioBuffer); |
|||
this.audioBuffer = null; |
|||
// Module.postMessage(
|
|||
// {
|
|||
// type: "audio",
|
|||
// data: {
|
|||
// buffer: output.buffer,
|
|||
// timestamp: timestamp
|
|||
// }
|
|||
// },
|
|||
// supportSharedBuffer ? undefined : [output.buffer]
|
|||
// );
|
|||
}; |
|||
Decoder.prototype.onVideoDataSize = function(data){ |
|||
console.log("onAudioDataSize",data); |
|||
if (this.videoBuffer == null) { |
|||
this.videoBufferSize = data.size; |
|||
this.videoBuffer = Module._malloc(this.videoBufferSize); |
|||
if (this.supportSharedBuffer) { |
|||
this.videoSharedBuffer = new SharedArrayBuffer(data.size); |
|||
} |
|||
} |
|||
Module._codecSetVideoBuffer(this.videoBuffer); |
|||
} |
|||
Decoder.prototype.onVideoData = function(data) { |
|||
var timestamp = data.timestamp; |
|||
this.videoTimestamps.push(timestamp); |
|||
|
|||
var u8s = Module.HEAPU8.subarray( |
|||
this.videoBuffer, |
|||
this.videoBuffer + this.videoBufferSize |
|||
); |
|||
|
|||
var output = null; |
|||
if (this.supportSharedBuffer) { |
|||
output = new Uint8Array(this.videoSharedBuffer); |
|||
output.set(u8s); |
|||
} else { |
|||
output = new Uint8Array(u8s); |
|||
} |
|||
|
|||
// Module.postMessage(
|
|||
// {
|
|||
// type: "video",
|
|||
// data: {
|
|||
// buffer: output.buffer,
|
|||
// timestamp: timestamp,
|
|||
// width: data.width,
|
|||
// height: data.height,
|
|||
// stride0: data.stride0,
|
|||
// stride1: data.stride1
|
|||
// }
|
|||
// },
|
|||
// supportSharedBuffer ? undefined : [output.buffer]
|
|||
// );
|
|||
var obj = { |
|||
data: output, |
|||
width: data.width, |
|||
height: data.height, |
|||
} |
|||
var objData = { |
|||
t: kprodVideoFrame, |
|||
s: timestamp, |
|||
stride0: data.stride0, |
|||
stride1: data.stride1, |
|||
d: obj |
|||
}; |
|||
self.postMessage(objData, [objData.d.data.buffer]); |
|||
}; |
|||
|
|||
Decoder.prototype.onComplete=function() { |
|||
console.log("onComplete"); |
|||
// Module.postMessage({ type: "complete" });
|
|||
} |
|||
var decodet1=new Date().getTime(); |
|||
Decoder.prototype.decodeVideo=function(){ |
|||
if(H265Frame.length>0){ |
|||
decodet1=new Date().getTime(); |
|||
// var typedArray= H265Frame.shift();//H265Frame[0];//new Uint8Array(H265Frame[0]);
|
|||
var typedArray=H265Frame[0];//new Uint8Array(H265Frame[0]);
|
|||
var packet=typedArray.d; |
|||
var size = typedArray.size; |
|||
console.log("decode len: " + size) |
|||
var cacheBuffer = Module._malloc(size); |
|||
Module.HEAPU8.set(packet, cacheBuffer); |
|||
// var size = typedArray.length
|
|||
// var cacheBuffer = Module._malloc(size);
|
|||
// Module.HEAPU8.set(typedArray, cacheBuffer);
|
|||
|
|||
// this.audioTimestamps = [];
|
|||
// this.videoTimestamps = [];
|
|||
Module._codecDecode(cacheBuffer, size); |
|||
// this.decode(cacheBuffer)
|
|||
|
|||
if (cacheBuffer != null) { |
|||
Module._free(cacheBuffer); |
|||
cacheBuffer = null; |
|||
} |
|||
|
|||
|
|||
} |
|||
|
|||
|
|||
} |
|||
// Decoder.prototype.decodeVideo = function(){ // 对外api,解码一段数据
|
|||
|
|||
// }
|
|||
|
|||
// Decoder.prototype.decode = function(buffer){ // 对外api,解码一段数据
|
|||
// var buffer = new Uint8Array(data.buffer);
|
|||
// var data = Module._malloc(buffer.length);
|
|||
// Module.HEAPU8.set(buffer, data);
|
|||
|
|||
// var now = +new Date();
|
|||
// Module.audioTimestamps = [];
|
|||
// Module.videoTimestamps = [];
|
|||
// Module._codecDecode(data, buffer.length);
|
|||
// // h265decode(buffer);
|
|||
// // if(Module){
|
|||
|
|||
// // // Module.postMessage({
|
|||
// // // type: 'decode',
|
|||
// // // buffer: buffer,
|
|||
// // // });
|
|||
// // }
|
|||
// }
|
|||
|
|||
Decoder.prototype.destroy = function(){ // 对外api,销毁解码器
|
|||
this.destroied = true; |
|||
// if(Module){
|
|||
// // window.URL.revokeObjectURL(this.url);
|
|||
// Module.postMessage({type: 'destroy'});
|
|||
// }
|
|||
} |
|||
|
|||
|
|||
Decoder.prototype.startDecoding = function (interval) { |
|||
console.log("Start decoding."); |
|||
if (this.decodeTimer) { |
|||
clearInterval(this.decodeTimer); |
|||
} |
|||
this.decodeTimer = setInterval(this.decodeVideo, 0);//interval);
|
|||
}; |
|||
|
|||
Decoder.prototype.pauseDecoding = function () { |
|||
console.log("Pause decoding."); |
|||
if (this.decodeTimer) { |
|||
clearInterval(this.decodeTimer); |
|||
this.decodeTimer = null; |
|||
} |
|||
}; |
|||
|
|||
Decoder.prototype.sendVideoFrame = function(data,len){ |
|||
|
|||
var typedArray = new Uint8Array(data); |
|||
if(H265Frame.length>MAX_FRAME_SIZE){ |
|||
H265Frame.shift(); |
|||
} |
|||
H265Frame.push(typedArray) |
|||
|
|||
} |
|||
Decoder.prototype.closeDecoder = function () { |
|||
console.log("closeDecoder."); |
|||
if (this.decodeTimer) { |
|||
clearInterval(this.decodeTimer); |
|||
this.decodeTimer = null; |
|||
console.log("Decode timer stopped."); |
|||
} |
|||
|
|||
// var ret = Module._closeDecoder();
|
|||
console.log("Close ffmpeg decoder return " + ret + "."); |
|||
|
|||
var objData = { |
|||
t: kCloseDecoderRsp, |
|||
e: 0 |
|||
}; |
|||
self.postMessage(objData); |
|||
}; |
|||
Decoder.prototype.processReq = function (req) { |
|||
// console.log("processReq " + req.t + ".");
|
|||
switch (req.t) { |
|||
case kInitDecoderReq: |
|||
this.initDecoder(); |
|||
break; |
|||
case kUninitDecoderReq: |
|||
this.uninitDecoder(); |
|||
break; |
|||
case kOpenDecoderReq: |
|||
this.openDecoder(); |
|||
break; |
|||
case kCloseDecoderReq: |
|||
this.closeDecoder(); |
|||
break; |
|||
case kStartDecodingReq: |
|||
this.startDecoding(req.i); |
|||
break; |
|||
case kPauseDecodingReq: |
|||
this.pauseDecoding(); |
|||
break; |
|||
case kFeedDataReq: |
|||
this.sendVideoFrame(req.d); |
|||
break; |
|||
// case kSeekToReq:
|
|||
// this.seekTo(req.ms);
|
|||
// break;
|
|||
default: |
|||
this.logger.logError("Unsupport messsage " + req.t); |
|||
} |
|||
}; |
|||
|
|||
self.decoder = new Decoder; |
|||
|
|||
self.onmessage = function (evt) { |
|||
if (!self.decoder) { |
|||
console.log("[ER] Decoder not initialized!"); |
|||
return; |
|||
} |
|||
|
|||
var req = evt.data; |
|||
if (!self.decoder.wasmLoaded) { |
|||
self.decoder.cacheReq(req); |
|||
console.log("Temp cache req " + req.t + "."); |
|||
return; |
|||
} |
|||
|
|||
self.decoder.processReq(req); |
|||
}; |
|||
|
|||
function onWasmLoaded() { |
|||
if (self.decoder) { |
|||
self.decoder.onWasmLoaded(); |
|||
} else { |
|||
console.log("[ER] No decoder!"); |
|||
} |
|||
} |
|||
function onHeader(header){ |
|||
if (self.decoder) { |
|||
self.decoder.onHeader(header); |
|||
} else { |
|||
console.log("[ER] No decoder!"); |
|||
} |
|||
} |
|||
function onMediaInfo(mediaInfo){ |
|||
if (self.decoder) { |
|||
self.decoder.onMediaInfo(mediaInfo); |
|||
} else { |
|||
console.log("[ER] No decoder!"); |
|||
} |
|||
} |
|||
function onVideoDataSize(data) { |
|||
if (self.decoder) { |
|||
self.decoder.onVideoDataSize(data); |
|||
} else { |
|||
console.log("[ER] No decoder!"); |
|||
} |
|||
} |
|||
function onVideoData(data) { |
|||
if (self.decoder) { |
|||
self.decoder.onVideoData(data); |
|||
} else { |
|||
console.log("[ER] No decoder!"); |
|||
} |
|||
} |
|||
function onAudioDataSize(data) { |
|||
if (self.decoder) { |
|||
self.decoder.onAudioDataSize(data); |
|||
} else { |
|||
console.log("[ER] No decoder!"); |
|||
} |
|||
} |
|||
function onAudioData(data) { |
|||
if (self.decoder) { |
|||
self.decoder.onAudioData(data); |
|||
} else { |
|||
console.log("[ER] No decoder!"); |
|||
} |
|||
} |
|||
function onComplete() { |
|||
if (self.decoder) { |
|||
self.decoder.onComplete(); |
|||
} else { |
|||
console.log("[ER] No decoder!"); |
|||
} |
|||
} |
@ -1,160 +0,0 @@ |
|||
|
|||
//webrtc datachannel send h265 jpeg
|
|||
var h265DC; |
|||
var bWorking=false; |
|||
var h265data=null; |
|||
var h265datalen=0; |
|||
var packet=0; |
|||
var expectLength = 4; |
|||
// var bserialopen = false
|
|||
function isString(str){ |
|||
return (typeof str=='string')&&str.constructor==String; |
|||
} |
|||
// function reportData (len, seq, data) {
|
|||
// var objData = {
|
|||
// t: kFileData,
|
|||
// s: start,
|
|||
// e: end,
|
|||
// d: data,
|
|||
// q: seq
|
|||
// };
|
|||
// postMessage(objData, [objData.d]);
|
|||
// };
|
|||
function hexToStr(hex,encoding) { |
|||
var trimedStr = hex.trim(); |
|||
var rawStr = trimedStr.substr(0, 2).toLowerCase() === "0x" ? trimedStr.substr(2) : trimedStr; |
|||
var len = rawStr.length; |
|||
if (len % 2 !== 0) { |
|||
alert("Illegal Format ASCII Code!"); |
|||
return ""; |
|||
} |
|||
var curCharCode; |
|||
var resultStr = []; |
|||
for (var i = 0; i < len; i = i + 2) { |
|||
curCharCode = parseInt(rawStr.substr(i, 2), 16); |
|||
resultStr.push(curCharCode); |
|||
} |
|||
// encoding为空时默认为utf-8
|
|||
var bytesView = new Uint8Array(resultStr); |
|||
var str = new TextDecoder(encoding).decode(bytesView); |
|||
return str; |
|||
} |
|||
|
|||
function dump_hex(h265data,h265datalen){ |
|||
// console.log(h265data.toString());
|
|||
var str="0x" |
|||
for (var i = 0; i < h265datalen; i ++ ) { |
|||
var byte =h265data.slice(i,i+1)[0]; |
|||
|
|||
str+=byte.toString(16) |
|||
str+=" " |
|||
// console.log((h265datalen+i).toString(16)+" ");
|
|||
} |
|||
console.log(str); |
|||
} |
|||
function appendBuffer (buffer1, buffer2) { |
|||
var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength); |
|||
tmp.set(new Uint8Array(buffer1), 0); |
|||
tmp.set(new Uint8Array(buffer2), buffer1.byteLength); |
|||
return tmp.buffer; |
|||
}; |
|||
function reportStream(size){ |
|||
|
|||
} |
|||
|
|||
function stopH265(){ |
|||
if(h265DC!==null){ |
|||
h265DC.close(); |
|||
} |
|||
} |
|||
var receivet1=new Date().getTime(); |
|||
var bRecH265=false; |
|||
function initH265DC(pc,player) { |
|||
console.log("initH265DC",Date()); |
|||
h265DC = pc.createDataChannel("h265"); |
|||
|
|||
// var ctx = canvas.getContext("2d");
|
|||
|
|||
h265DC.onmessage = function (event) { |
|||
// console.log(bRecH265,":",event.data)
|
|||
if(bRecH265){ |
|||
if(isString(event.data)) { |
|||
if(event.data.indexOf("h265 end")!=-1){ |
|||
bRecH265=false; |
|||
console.log(bRecH265,":",event.data) |
|||
if(h265datalen>0){ |
|||
|
|||
const t2 = new Date().getTime()-receivet1; |
|||
console.log("receive time:"+t2+" len:"+h265datalen); |
|||
var req = { |
|||
t: ksendPlayerVideoFrameReq, |
|||
l: h265datalen, |
|||
d: h265data |
|||
}; |
|||
player.postMessage(req,[req.d]); |
|||
|
|||
h265data=null; |
|||
h265datalen=0; |
|||
packet=0; |
|||
receivet1=new Date().getTime(); |
|||
} |
|||
|
|||
return; |
|||
} |
|||
}else{ |
|||
if (h265data != null) { |
|||
|
|||
h265data=appendBuffer(h265data,event.data); |
|||
} else if (event.data.byteLength < expectLength) { |
|||
h265data = event.data.slice(0); |
|||
|
|||
} else { |
|||
|
|||
h265data=event.data; |
|||
|
|||
} |
|||
|
|||
h265datalen+=event.data.byteLength; |
|||
packet++; |
|||
console.log("reveive: "+packet+": t len"+h265datalen) |
|||
return; |
|||
} |
|||
|
|||
} |
|||
if(isString(event.data)) { |
|||
if(event.data.indexOf("h265 start")!=-1){ |
|||
// console.log(event.data );
|
|||
bRecH265=true; |
|||
packet=0; |
|||
return; |
|||
} |
|||
} |
|||
}; |
|||
|
|||
h265DC.onopen = function () { |
|||
console.log("h265 datachannel open"); |
|||
|
|||
// var req = {
|
|||
// t: kInitPlayerReq,
|
|||
// };
|
|||
// player.postMessage(req);
|
|||
|
|||
bWorking = true; |
|||
|
|||
}; |
|||
|
|||
h265DC.onclose = function () { |
|||
console.log("h265 datachannel close"); |
|||
bWorking=false; |
|||
|
|||
}; |
|||
} |
|||
|
|||
function handleUpdates(canvas, dc) { |
|||
setInterval(function () { |
|||
if (bWorking){ |
|||
dc.send(JSON.stringify({ type: "h265" })); // frame update request
|
|||
} |
|||
}, 500); |
|||
}; |
|||
|
@ -0,0 +1,284 @@ |
|||
|
|||
//webrtc datachannel send h265 jpeg
|
|||
|
|||
// var packetkv={
|
|||
// key
|
|||
// }
|
|||
// func GetFrameTypeName(frametype uint16) (string, error) {
|
|||
// switch frametype {
|
|||
// case NALU_H265_VPS:
|
|||
// return "H265_FRAME_VPS", nil
|
|||
// case NALU_H265_SPS:
|
|||
// return "H265_FRAME_SPS", nil
|
|||
// case NALU_H265_PPS:
|
|||
// return "H265_FRAME_PPS", nil
|
|||
// case NALU_H265_SEI:
|
|||
// return "H265_FRAME_SEI", nil
|
|||
// case NALU_H265_IFRAME:
|
|||
// return "H265_FRAME_I", nil
|
|||
// case NALU_H265_PFRAME:
|
|||
// return "H265_FRAME_P", nil
|
|||
// default:
|
|||
// return "", errors.New("frametype unsupport")
|
|||
// }
|
|||
// }
|
|||
const START_STR="h265 start"; |
|||
const FRAME_TYPE_STR="FrameType"; |
|||
const PACKET_LEN_STR="Packetslen"; |
|||
const PACKET_COUNT_STR="packets"; |
|||
const PACKET_PTS="pts"; |
|||
const PACKET_REM_STR="rem"; |
|||
const KEY_FRAME_TYPE="H265_FRAME_I" |
|||
var frameType=""; |
|||
var isKeyFrame=false; |
|||
var pts=0; |
|||
var h265DC; |
|||
// var h265DC=new Array();
|
|||
// var h265DC2;
|
|||
// var h265DC3;
|
|||
// var h265DC4;
|
|||
var bWorking=false; |
|||
var h265dataFrame=[]; |
|||
var h265data; |
|||
// var h265data2=null;
|
|||
// var h265data3=null;
|
|||
// var h265data4=null;
|
|||
var dataIndex=0; |
|||
|
|||
var h265datalen=0; |
|||
var packet=0; |
|||
var expectLength = 4; |
|||
var bFindFirstKeyFrame=false; |
|||
//var packetLens=0;
|
|||
|
|||
|
|||
// startstr := "h265 start ,FrameType:" + frametypestr + ",Packetslen:" + strconv.Itoa(glength) + ",packets:" + strconv.Itoa(count) + ",rem:" + strconv.Itoa(rem)
|
|||
// var bserialopen = false
|
|||
function isString(str){ |
|||
return (typeof str=='string')&&str.constructor==String; |
|||
} |
|||
// function reportData (len, seq, data) {
|
|||
// var objData = {
|
|||
// t: kFileData,
|
|||
// s: start,
|
|||
// e: end,
|
|||
// d: data,
|
|||
// q: seq
|
|||
// };
|
|||
// postMessage(objData, [objData.d]);
|
|||
// };
|
|||
function hexToStr(hex,encoding) { |
|||
var trimedStr = hex.trim(); |
|||
var rawStr = trimedStr.substr(0, 2).toLowerCase() === "0x" ? trimedStr.substr(2) : trimedStr; |
|||
var len = rawStr.length; |
|||
if (len % 2 !== 0) { |
|||
alert("Illegal Format ASCII Code!"); |
|||
return ""; |
|||
} |
|||
var curCharCode; |
|||
var resultStr = []; |
|||
for (var i = 0; i < len; i = i + 2) { |
|||
curCharCode = parseInt(rawStr.substr(i, 2), 16); |
|||
resultStr.push(curCharCode); |
|||
} |
|||
// encoding为空时默认为utf-8
|
|||
var bytesView = new Uint8Array(resultStr); |
|||
var str = new TextDecoder(encoding).decode(bytesView); |
|||
return str; |
|||
} |
|||
function deepCopy(arr) { |
|||
const newArr = [] |
|||
for(let i in arr) { |
|||
console.log(arr[i]) |
|||
if (typeof arr[i] === 'object') { |
|||
newArr[i] = deepCopy(arr[i]) |
|||
} else { |
|||
newArr[i] = arr[i] |
|||
} |
|||
} |
|||
console.log(newArr) |
|||
return newArr |
|||
|
|||
} |
|||
|
|||
function dump_hex(h265data,h265datalen){ |
|||
// console.log(h265data.toString());
|
|||
var str="0x" |
|||
for (var i = 0; i < h265datalen; i ++ ) { |
|||
var byte =h265data.slice(i,i+1)[0]; |
|||
|
|||
str+=byte.toString(16) |
|||
str+=" " |
|||
// console.log((h265datalen+i).toString(16)+" ");
|
|||
} |
|||
console.log(str); |
|||
} |
|||
function appendBuffer (buffer1, buffer2) { |
|||
var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength); |
|||
tmp.set(new Uint8Array(buffer1), 0); |
|||
tmp.set(new Uint8Array(buffer2), buffer1.byteLength); |
|||
return tmp.buffer; |
|||
}; |
|||
function reportStream(size){ |
|||
|
|||
} |
|||
|
|||
function stopH265(){ |
|||
if(h265DC!==null){ |
|||
h265DC.close(); |
|||
} |
|||
} |
|||
var receivet1=new Date().getTime(); |
|||
var bRecH265=false; |
|||
function initH265DC(pc,player) { |
|||
console.log("initH265DC",Date()); |
|||
h265DC = pc.createDataChannel("h265"); |
|||
|
|||
// var ctx = canvas.getContext("2d");
|
|||
|
|||
h265DC.onmessage = function (event) { |
|||
// console.log(bRecH265,":",event.data)
|
|||
if(bRecH265){ |
|||
if(isString(event.data)) { |
|||
console.log("reveive: "+event.data) |
|||
if(event.data.indexOf("h265 end")!=-1){ |
|||
bRecH265=false; |
|||
// console.log("frame ok",":",event.data," len:"+h265datalen)
|
|||
if(h265datalen>0){ |
|||
// const framepacket=new Uint8Array(h265data)
|
|||
const t2 = new Date().getTime()-receivet1; |
|||
/* |
|||
return "H265_FRAME_VPS", nil |
|||
case NALU_H265_SPS: |
|||
return "H265_FRAME_SPS", nil |
|||
case NALU_H265_PPS: |
|||
return "H265_FRAME_PPS", nil |
|||
case NALU_H265_SEI: |
|||
return "H265_FRAME_SEI", nil |
|||
case NALU_H265_IFRAME: |
|||
return "H265_FRAME_I", nil |
|||
case NALU_H265_PFRAME: |
|||
return "H265_FRAME_P", nil |
|||
*/ |
|||
if(frameType==="H265_FRAME_VPS"||frameType==="H265_FRAME_SPS"||frameType==="H265_FRAME_PPS"||frameType==="H265_FRAME_SEI"||frameType==="H265_FRAME_P") |
|||
console.log("receive time:"+t2+" len:"+h265datalen); |
|||
if(frameType==="H265_FRAME_P"&&!bFindFirstKeyFrame){ |
|||
return |
|||
} |
|||
bFindFirstKeyFrame=true; |
|||
// h265dataFrame.push(new Uint8Array(h265data))
|
|||
var dataFrame=new Uint8Array(h265data)//deepCopy(h265data)//h265dataFrame.shift()
|
|||
var data={ |
|||
pts: pts, |
|||
size: h265datalen, |
|||
iskeyframe: isKeyFrame, |
|||
packet: dataFrame//
|
|||
// new Uint8Array(h265data)//h265data//new Uint8Array(h265data)
|
|||
}; |
|||
var req = { |
|||
t: ksendPlayerVideoFrameReq, |
|||
l: h265datalen, |
|||
d: data |
|||
}; |
|||
player.postMessage(req,[req.d.packet.buffer]); |
|||
|
|||
h265data=null; |
|||
h265datalen=0; |
|||
packet=0; |
|||
receivet1=new Date().getTime(); |
|||
} |
|||
|
|||
return; |
|||
} |
|||
}else{ |
|||
if (h265data != null) { |
|||
|
|||
h265data=appendBuffer(h265data,event.data); |
|||
} else if (event.data.byteLength < expectLength) { |
|||
h265data = event.data.slice(0); |
|||
|
|||
} else { |
|||
|
|||
h265data=event.data; |
|||
|
|||
} |
|||
|
|||
h265datalen+=event.data.byteLength; |
|||
packet++; |
|||
console.log("packet: "+packet+": t len"+h265datalen) |
|||
return; |
|||
} |
|||
|
|||
} |
|||
if(isString(event.data)) { |
|||
let startstring = event.data |
|||
// console.log("reveive: "+startstring)
|
|||
if(startstring.indexOf("h265 start")!=-1){ |
|||
console.log(event.data ); |
|||
const startarray=startstring.split(","); |
|||
// startstr := "h265 start ,FrameType:" + frametypestr + ",Packetslen:" + strconv.Itoa(glength) + ",packets:" + strconv.Itoa(count) + ",rem:" + strconv.Itoa(rem)
|
|||
|
|||
for(let i=0;i<startarray.length;i++){ |
|||
const parakv=startarray[i].split(":"); |
|||
if(parakv!==null){ |
|||
switch(parakv[0]){ |
|||
case START_STR: |
|||
break; |
|||
case PACKET_PTS: |
|||
pts=parseInt(parakv[1]) |
|||
break; |
|||
case FRAME_TYPE_STR: |
|||
frameType=parakv[1] |
|||
if(frameType.indexOf(KEY_FRAME_TYPE)!==-1){ |
|||
isKeyFrame=true; |
|||
}else{ |
|||
isKeyFrame=false; |
|||
} |
|||
break; |
|||
case PACKET_LEN_STR: |
|||
break; |
|||
case PACKET_COUNT_STR: |
|||
break; |
|||
case PACKET_REM_STR: |
|||
break; |
|||
} |
|||
|
|||
} |
|||
} |
|||
// string.split(":")
|
|||
bRecH265=true; |
|||
packet=0; |
|||
return; |
|||
} |
|||
} |
|||
}; |
|||
|
|||
h265DC.onopen = function () { |
|||
console.log("h265 datachannel open"); |
|||
|
|||
// var req = {
|
|||
// t: kInitPlayerReq,
|
|||
// };
|
|||
// player.postMessage(req);
|
|||
|
|||
bWorking = true; |
|||
|
|||
}; |
|||
|
|||
h265DC.onclose = function () { |
|||
console.log("h265 datachannel close"); |
|||
bWorking=false; |
|||
|
|||
}; |
|||
} |
|||
|
|||
function handleUpdates(canvas, dc) { |
|||
setInterval(function () { |
|||
if (bWorking){ |
|||
dc.send(JSON.stringify({ type: "h265" })); // frame update request
|
|||
} |
|||
}, 500); |
|||
}; |
|||
|
|||
|
|||
|
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,484 +0,0 @@ |
|||
// var isWorker = typeof importScripts == "function";
|
|||
// var bridgeName = "__CODE_BRIDGE__" + +new Date();
|
|||
// self.Module = {
|
|||
// onRuntimeInitialized: function () {
|
|||
// onWasmLoaded();
|
|||
// },
|
|||
// // onVideoDataSize: function () {
|
|||
// // onVideoDataSize();
|
|||
// // },
|
|||
// // onVideoData: function () {
|
|||
// // onVideoData();
|
|||
// // },
|
|||
// // onAudioDataSize: function () {
|
|||
// // onAudioDataSize();
|
|||
// // },
|
|||
// // onAudioData: function () {
|
|||
// // onAudioData();
|
|||
// // },
|
|||
// // };
|
|||
// // var isWorker = typeof importScripts == "function";
|
|||
// // var bridgeName = "__CODE_BRIDGE__" + +new Date();
|
|||
// // [bridgeName] = {
|
|||
// onHeader: function(header) {
|
|||
// //Module.postMessage({ type: "header", data: header });
|
|||
// },
|
|||
// onMediaInfo: function(mediaInfo) {
|
|||
// console.log("onMediaInfo"+mediaInfo.toString(16));
|
|||
// //Module.postMessage({ type: "mediaInfo", data: mediaInfo });
|
|||
// },
|
|||
// onAudioDataSize: function(data) {
|
|||
// // Module.audioBufferSize = data.size;
|
|||
// // Module.audioBuffer = Module._malloc(Module.audioBufferSize);
|
|||
// // Module._codecSetAudioBuffer(Module.audioBuffer);
|
|||
// },
|
|||
// onAudioData: function(data) {
|
|||
// // var timestamp = data.timestamp;
|
|||
// // Module.audioTimestamps.push(timestamp);
|
|||
|
|||
// // var u8s = Module.HEAPU8.subarray(
|
|||
// // Module.audioBuffer,
|
|||
// // Module.audioBuffer + Module.audioBufferSize
|
|||
// // );
|
|||
|
|||
// // var output = null;
|
|||
// // if (supportSharedBuffer) {
|
|||
// // output = new Uint8Array(new SharedArrayBuffer(u8s.byteLength));
|
|||
// // output.set(u8s);
|
|||
// // } else {
|
|||
// // output = new Uint8Array(u8s);
|
|||
// // }
|
|||
|
|||
// // Module._free(Module.audioBuffer);
|
|||
// // Module.audioBuffer = null;
|
|||
// // Module.postMessage(
|
|||
// // {
|
|||
// // type: "audio",
|
|||
// // data: {
|
|||
// // buffer: output.buffer,
|
|||
// // timestamp: timestamp
|
|||
// // }
|
|||
// // },
|
|||
// // supportSharedBuffer ? undefined : [output.buffer]
|
|||
// // );
|
|||
// },
|
|||
// onVideoDataSize: function(data) {
|
|||
// console.log("onVideoDataSize"+data.toString(16));
|
|||
// // if (Module.videoBuffer == null) {
|
|||
// // Module.videoBufferSize = data.size;
|
|||
// // Module.videoBuffer = Module._malloc(Module.videoBufferSize);
|
|||
// // if (supportSharedBuffer) {
|
|||
// // Module.videoSharedBuffer = new SharedArrayBuffer(data.size);
|
|||
// // }
|
|||
// // }
|
|||
// // Module._codecSetVideoBuffer(Module.videoBuffer);
|
|||
// },
|
|||
// onVideoData: function(data) {
|
|||
// console.log("onVideoData"+data.toString(16));
|
|||
// // var timestamp = data.timestamp;
|
|||
// // Module.videoTimestamps.push(timestamp);
|
|||
|
|||
// // var u8s = Module.HEAPU8.subarray(
|
|||
// // Module.videoBuffer,
|
|||
// // Module.videoBuffer + Module.videoBufferSize
|
|||
// // );
|
|||
|
|||
// // var output = null;
|
|||
// // if (supportSharedBuffer) {
|
|||
// // output = new Uint8Array(Module.videoSharedBuffer);
|
|||
// // output.set(u8s);
|
|||
// // } else {
|
|||
// // output = new Uint8Array(u8s);
|
|||
// // }
|
|||
|
|||
// // Module.postMessage(
|
|||
// // {
|
|||
// // type: "video",
|
|||
// // data: {
|
|||
// // buffer: output.buffer,
|
|||
// // timestamp: timestamp,
|
|||
// // width: data.width,
|
|||
// // height: data.height,
|
|||
// // stride0: data.stride0,
|
|||
// // stride1: data.stride1
|
|||
// // }
|
|||
// // },
|
|||
// // supportSharedBuffer ? undefined : [output.buffer]
|
|||
// // );
|
|||
// },
|
|||
// onComplete: function() {
|
|||
// console.log("onComplete");
|
|||
// // Module.postMessage({ type: "complete" });
|
|||
// }
|
|||
// };
|
|||
var Module = {}; |
|||
self.importScripts("common.js"); |
|||
self.importScripts("glue.js"); |
|||
self.importScripts("prod.h265.wasm.js"); |
|||
|
|||
// var decoder_type = DECODER_H265;
|
|||
var ptsIdx=0; |
|||
|
|||
H265Frame =[]; |
|||
function Decoder(){ |
|||
// this.timer=null;
|
|||
this.decodeTimer = null; |
|||
this.rawParserObj = null; |
|||
this.wasmLoaded = false; |
|||
this.tmpReqQue = []; |
|||
this.destroied = false; |
|||
// this.poddecoder = null;
|
|||
// this.supportSharedBuffer = false;
|
|||
// this.bridgeName = "__CODE_BRIDGE__" + +new Date();
|
|||
// this.audioTimestamps = []
|
|||
// this.videoTimestamps = []
|
|||
// this.audioBufferSize = 0
|
|||
// this.videoBufferSize = 0
|
|||
// this.audioBuffer = null
|
|||
// this.videoBuffer = null
|
|||
// this.videoSharedBuffer =null;
|
|||
// this.token = "base64:QXV0aG9yOmNoYW5neWFubG9uZ3xudW1iZXJ3b2xmLEdpdGh1YjpodHRwczovL2dpdGh1Yi5jb20vbnVtYmVyd29sZixFbWFpbDpwb3JzY2hlZ3QyM0Bmb3htYWlsLmNvbSxRUTo1MzEzNjU4NzIsSG9tZVBhZ2U6aHR0cDovL3h2aWRlby52aWRlbyxEaXNjb3JkOm51bWJlcndvbGYjODY5NCx3ZWNoYXI6bnVtYmVyd29sZjExLEJlaWppbmcsV29ya0luOkJhaWR1";
|
|||
// this.version = '100.2.0';
|
|||
} |
|||
|
|||
Decoder.prototype.cacheReq = function (req) { |
|||
if (req) { |
|||
this.tmpReqQue.push(req); |
|||
} |
|||
}; |
|||
Decoder.prototype.onWasmLoaded = function () { |
|||
console.log("Wasm loaded."); |
|||
this.wasmLoaded = true; |
|||
while (this.tmpReqQue.length > 0) { |
|||
var req = this.tmpReqQue.shift(); |
|||
this.processReq(req); |
|||
} |
|||
} |
|||
Decoder.prototype.initDecoder = function () { |
|||
// var ret = Module._initDecoder(fileSize, this.coreLogLevel);
|
|||
var ret=0; |
|||
console.log("initDecoder return " + ret + "."); |
|||
// try {
|
|||
// this.supportSharedBuffer = !!new SharedArrayBuffer(0);
|
|||
// } catch (e) {
|
|||
// // nothing to do...
|
|||
// }
|
|||
// // this.bridgeName = "__CODE_BRIDGE__" + +new Date();
|
|||
// Module._codecInit();
|
|||
// var callbackStr = bridgeName.split("");
|
|||
// callbackStr = callbackStr
|
|||
// .map(function(v) {
|
|||
// return v.charCodeAt(0);
|
|||
// })
|
|||
// .concat(0);
|
|||
|
|||
// var callbackStrData = Module._malloc(callbackStr.length - 1);
|
|||
// Module.HEAPU8.set(callbackStr, callbackStrData);
|
|||
// Module._codecSetBridgeName(callbackStrData);
|
|||
|
|||
var objData = { |
|||
t: kInitDecoderRsp, |
|||
e: ret |
|||
}; |
|||
self.postMessage(objData); |
|||
}; |
|||
|
|||
Decoder.prototype.openDecoder = function () { |
|||
|
|||
var objData = { |
|||
t: kOpenDecoderRsp, |
|||
e: 0 |
|||
}; |
|||
self.postMessage(objData); |
|||
|
|||
} |
|||
Decoder.prototype.uninitDecoder = function () { |
|||
var ret = 0;//Module._uninitDecoder();
|
|||
// Module._codecFree();
|
|||
console.log("Uninit ffmpeg decoder return " + ret + "."); |
|||
|
|||
}; |
|||
|
|||
// Decoder.prototype.onHeader = function(header) {
|
|||
|
|||
// // Module.postMessage({ type: "header", data: header });
|
|||
// };
|
|||
// Decoder.prototype.onMediaInfo = function(mediaInfo) {
|
|||
// // Module.postMessage({ type: "mediaInfo", data: mediaInfo });
|
|||
// };
|
|||
// Decoder.prototype.onAudioDataSize = function(data) {
|
|||
// this.audioBufferSize = data.size;
|
|||
// this.audioBuffer = Module._malloc(this.audioBufferSize);
|
|||
// Module._codecSetAudioBuffer(this.audioBuffer);
|
|||
// };
|
|||
// Decoder.prototype.onAudioData = function(data) {
|
|||
// var timestamp = data.timestamp;
|
|||
// this.audioTimestamps.push(timestamp);
|
|||
|
|||
// var u8s = Module.HEAPU8.subarray(
|
|||
// this.audioBuffer,
|
|||
// this.audioBuffer +this.audioBufferSize
|
|||
// );
|
|||
|
|||
// var output = null;
|
|||
// if (supportSharedBuffer) {
|
|||
// output = new Uint8Array(new SharedArrayBuffer(u8s.byteLength));
|
|||
// output.set(u8s);
|
|||
// } else {
|
|||
// output = new Uint8Array(u8s);
|
|||
// }
|
|||
|
|||
// Module._free(this.audioBuffer);
|
|||
// this.audioBuffer = null;
|
|||
// // Module.postMessage(
|
|||
// // {
|
|||
// // type: "audio",
|
|||
// // data: {
|
|||
// // buffer: output.buffer,
|
|||
// // timestamp: timestamp
|
|||
// // }
|
|||
// // },
|
|||
// // supportSharedBuffer ? undefined : [output.buffer]
|
|||
// // );
|
|||
// };
|
|||
// Decoder.prototype.onVideoDataSize = function(data){
|
|||
// if (this.videoBuffer == null) {
|
|||
// this.videoBufferSize = data.size;
|
|||
// this.videoBuffer = Module._malloc(this.videoBufferSize);
|
|||
// if (this.supportSharedBuffer) {
|
|||
// this.videoSharedBuffer = new SharedArrayBuffer(data.size);
|
|||
// }
|
|||
// }
|
|||
// Module._codecSetVideoBuffer(this.videoBuffer);
|
|||
// }
|
|||
// Decoder.prototype.onVideoData = function(data) {
|
|||
// var timestamp = data.timestamp;
|
|||
// this.videoTimestamps.push(timestamp);
|
|||
|
|||
// var u8s = Module.HEAPU8.subarray(
|
|||
// this.videoBuffer,
|
|||
// this.videoBuffer + this.videoBufferSize
|
|||
// );
|
|||
|
|||
// var output = null;
|
|||
// if (supportSharedBuffer) {
|
|||
// output = new Uint8Array(this.videoSharedBuffer);
|
|||
// output.set(u8s);
|
|||
// } else {
|
|||
// output = new Uint8Array(u8s);
|
|||
// }
|
|||
|
|||
// // Module.postMessage(
|
|||
// // {
|
|||
// // type: "video",
|
|||
// // data: {
|
|||
// // buffer: output.buffer,
|
|||
// // timestamp: timestamp,
|
|||
// // width: data.width,
|
|||
// // height: data.height,
|
|||
// // stride0: data.stride0,
|
|||
// // stride1: data.stride1
|
|||
// // }
|
|||
// // },
|
|||
// // supportSharedBuffer ? undefined : [output.buffer]
|
|||
// // );
|
|||
// var obj = {
|
|||
// data: output,
|
|||
// width: data.width,
|
|||
// height: data.height,
|
|||
// }
|
|||
// var objData = {
|
|||
// t: kprodVideoFrame,
|
|||
// s: timestamp,
|
|||
// stride0: data.stride0,
|
|||
// stride1: data.stride1,
|
|||
// d: obj
|
|||
// };
|
|||
// self.postMessage(objData, [objData.d.data.buffer]);
|
|||
// };
|
|||
|
|||
// Decoder.prototype.onComplete=function() {
|
|||
// // Module.postMessage({ type: "complete" });
|
|||
// }
|
|||
var decodet1=new Date().getTime(); |
|||
Decoder.prototype.decodeVideo=function(){ |
|||
if(H265Frame.length>0){ |
|||
decodet1=new Date().getTime(); |
|||
var typedArray= H265Frame.shift();//H265Frame[0];//new Uint8Array(H265Frame[0]);
|
|||
h265decode(typedArray); |
|||
// if(Module){
|
|||
// Module.postMessage({
|
|||
// type: 'decode',
|
|||
// buffer: typedArray,
|
|||
// });
|
|||
// }
|
|||
// var size = typedArray.length
|
|||
// var cacheBuffer = Module._malloc(size);
|
|||
// Module.HEAPU8.set(typedArray, cacheBuffer);
|
|||
|
|||
// this.audioTimestamps = [];
|
|||
// this.videoTimestamps = [];
|
|||
// Module._codecDecode(cacheBuffer, size);
|
|||
// this.decode(typedArray)
|
|||
|
|||
// if (cacheBuffer != null) {
|
|||
// Module._free(cacheBuffer);
|
|||
// cacheBuffer = null;
|
|||
// }
|
|||
|
|||
|
|||
} |
|||
|
|||
|
|||
} |
|||
// Decoder.prototype.decodeVideo = function(){ // 对外api,解码一段数据
|
|||
|
|||
// }
|
|||
|
|||
Decoder.prototype.decode = function(buffer){ // 对外api,解码一段数据
|
|||
h265decode(buffer); |
|||
// if(Module){
|
|||
|
|||
// // Module.postMessage({
|
|||
// // type: 'decode',
|
|||
// // buffer: buffer,
|
|||
// // });
|
|||
// }
|
|||
} |
|||
|
|||
Decoder.prototype.destroy = function(){ // 对外api,销毁解码器
|
|||
this.destroied = true; |
|||
if(Module){ |
|||
// window.URL.revokeObjectURL(this.url);
|
|||
Module.postMessage({type: 'destroy'}); |
|||
} |
|||
} |
|||
|
|||
|
|||
Decoder.prototype.startDecoding = function (interval) { |
|||
console.log("Start decoding."); |
|||
if (this.decodeTimer) { |
|||
clearInterval(this.decodeTimer); |
|||
} |
|||
this.decodeTimer = setInterval(this.decodeVideo, 0);//interval);
|
|||
}; |
|||
|
|||
Decoder.prototype.pauseDecoding = function () { |
|||
console.log("Pause decoding."); |
|||
if (this.decodeTimer) { |
|||
clearInterval(this.decodeTimer); |
|||
this.decodeTimer = null; |
|||
} |
|||
}; |
|||
|
|||
Decoder.prototype.sendVideoFrame = function(data,len){ |
|||
|
|||
var typedArray = new Uint8Array(data); |
|||
if(H265Frame.length>MAX_FRAME_SIZE){ |
|||
H265Frame.shift(); |
|||
} |
|||
H265Frame.push(typedArray) |
|||
|
|||
} |
|||
Decoder.prototype.closeDecoder = function () { |
|||
console.log("closeDecoder."); |
|||
if (this.decodeTimer) { |
|||
clearInterval(this.decodeTimer); |
|||
this.decodeTimer = null; |
|||
console.log("Decode timer stopped."); |
|||
} |
|||
|
|||
// var ret = Module._closeDecoder();
|
|||
console.log("Close ffmpeg decoder return " + ret + "."); |
|||
|
|||
var objData = { |
|||
t: kCloseDecoderRsp, |
|||
e: 0 |
|||
}; |
|||
self.postMessage(objData); |
|||
}; |
|||
Decoder.prototype.processReq = function (req) { |
|||
// console.log("processReq " + req.t + ".");
|
|||
switch (req.t) { |
|||
case kInitDecoderReq: |
|||
this.initDecoder(); |
|||
break; |
|||
case kUninitDecoderReq: |
|||
this.uninitDecoder(); |
|||
break; |
|||
case kOpenDecoderReq: |
|||
this.openDecoder(); |
|||
break; |
|||
case kCloseDecoderReq: |
|||
this.closeDecoder(); |
|||
break; |
|||
case kStartDecodingReq: |
|||
this.startDecoding(req.i); |
|||
break; |
|||
case kPauseDecodingReq: |
|||
this.pauseDecoding(); |
|||
break; |
|||
case kFeedDataReq: |
|||
this.sendVideoFrame(req.d); |
|||
break; |
|||
// case kSeekToReq:
|
|||
// this.seekTo(req.ms);
|
|||
// break;
|
|||
default: |
|||
this.logger.logError("Unsupport messsage " + req.t); |
|||
} |
|||
}; |
|||
|
|||
self.decoder = new Decoder; |
|||
|
|||
self.onmessage = function (evt) { |
|||
if (!self.decoder) { |
|||
console.log("[ER] Decoder not initialized!"); |
|||
return; |
|||
} |
|||
|
|||
var req = evt.data; |
|||
if (!self.decoder.wasmLoaded) { |
|||
self.decoder.cacheReq(req); |
|||
console.log("Temp cache req " + req.t + "."); |
|||
return; |
|||
} |
|||
|
|||
self.decoder.processReq(req); |
|||
}; |
|||
|
|||
function onWasmLoaded() { |
|||
if (self.decoder) { |
|||
self.decoder.onWasmLoaded(); |
|||
} else { |
|||
console.log("[ER] No decoder!"); |
|||
} |
|||
} |
|||
// function onVideoDataSize() {
|
|||
// if (self.decoder) {
|
|||
// self.decoder.onVideoDataSize();
|
|||
// } else {
|
|||
// console.log("[ER] No decoder!");
|
|||
// }
|
|||
// }
|
|||
// function onVideoData() {
|
|||
// if (self.decoder) {
|
|||
// self.decoder.onVideoData();
|
|||
// } else {
|
|||
// console.log("[ER] No decoder!");
|
|||
// }
|
|||
// }
|
|||
// function onAudioDataSize() {
|
|||
// if (self.decoder) {
|
|||
// self.decoder.onAudioDataSize();
|
|||
// } else {
|
|||
// console.log("[ER] No decoder!");
|
|||
// }
|
|||
// }
|
|||
// function onAudioData() {
|
|||
// if (self.decoder) {
|
|||
// self.decoder.onAudioData();
|
|||
// } else {
|
|||
// console.log("[ER] No decoder!");
|
|||
// }
|
|||
// }
|
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because it is too large
Binary file not shown.
File diff suppressed because it is too large
Binary file not shown.
Loading…
Reference in new issue